srv0start.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:48k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /************************************************************************
  2. Starts the InnoDB database server
  3. (c) 1996-2000 Innobase Oy
  4. Created 2/16/1996 Heikki Tuuri
  5. *************************************************************************/
  6. #include "os0proc.h"
  7. #include "sync0sync.h"
  8. #include "ut0mem.h"
  9. #include "mem0mem.h"
  10. #include "mem0pool.h"
  11. #include "data0data.h"
  12. #include "data0type.h"
  13. #include "dict0dict.h"
  14. #include "buf0buf.h"
  15. #include "buf0flu.h"
  16. #include "buf0rea.h"
  17. #include "os0file.h"
  18. #include "os0thread.h"
  19. #include "fil0fil.h"
  20. #include "fsp0fsp.h"
  21. #include "rem0rec.h"
  22. #include "rem0cmp.h"
  23. #include "mtr0mtr.h"
  24. #include "log0log.h"
  25. #include "log0recv.h"
  26. #include "page0page.h"
  27. #include "page0cur.h"
  28. #include "trx0trx.h"
  29. #include "dict0boot.h"
  30. #include "dict0load.h"
  31. #include "trx0sys.h"
  32. #include "dict0crea.h"
  33. #include "btr0btr.h"
  34. #include "btr0pcur.h"
  35. #include "btr0cur.h"
  36. #include "btr0sea.h"
  37. #include "rem0rec.h"
  38. #include "srv0srv.h"
  39. #include "que0que.h"
  40. #include "usr0sess.h"
  41. #include "lock0lock.h"
  42. #include "trx0roll.h"
  43. #include "trx0purge.h"
  44. #include "row0ins.h"
  45. #include "row0sel.h"
  46. #include "row0upd.h"
  47. #include "row0row.h"
  48. #include "row0mysql.h"
  49. #include "lock0lock.h"
  50. #include "ibuf0ibuf.h"
  51. #include "pars0pars.h"
  52. #include "btr0sea.h"
  53. #include "srv0start.h"
  54. #include "que0que.h"
  55. /* Log sequence number immediately after startup */
  56. dulint srv_start_lsn;
  57. /* Log sequence number at shutdown */
  58. dulint srv_shutdown_lsn;
  59. #ifdef HAVE_DARWIN_THREADS
  60. # include <sys/utsname.h>
  61. ibool srv_have_fullfsync = FALSE;
  62. #endif
  63. ibool srv_start_raw_disk_in_use  = FALSE;
  64. static ibool srv_start_has_been_called  = FALSE;
  65. ulint           srv_sizeof_trx_t_in_ha_innodb_cc;
  66. ibool           srv_startup_is_before_trx_rollback_phase = FALSE;
  67. ibool           srv_is_being_started = FALSE;
  68. static ibool srv_was_started      = FALSE;
  69. /* At a shutdown the value first climbs to SRV_SHUTDOWN_CLEANUP
  70. and then to SRV_SHUTDOWN_LAST_PHASE */
  71. ulint srv_shutdown_state = 0;
  72. ibool measure_cont = FALSE;
  73. static os_file_t files[1000];
  74. static mutex_t ios_mutex;
  75. static ulint ios;
  76. static ulint n[SRV_MAX_N_IO_THREADS + 5];
  77. static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 5];
  78. /* We use this mutex to test the return value of pthread_mutex_trylock
  79.    on successful locking. HP-UX does NOT return 0, though Linux et al do. */
  80. static os_fast_mutex_t srv_os_test_mutex;
  81. /* Name of srv_monitor_file */
  82. static char* srv_monitor_file_name;
  83. #define SRV_N_PENDING_IOS_PER_THREAD  OS_AIO_N_PENDING_IOS_PER_THREAD
  84. #define SRV_MAX_N_PENDING_SYNC_IOS 100
  85. /* Avoid warnings when using purify */
  86. #ifdef HAVE_purify
  87. static int inno_bcmp(register const char *s1, register const char *s2,
  88.                      register uint len)
  89. {
  90.   while (len-- != 0 && *s1++ == *s2++) ;
  91.   return len+1;
  92. }
  93. #define memcmp(A,B,C) inno_bcmp((A),(B),(C))
  94. #endif
  95. /*************************************************************************
  96. Reads the data files and their sizes from a character string given in
  97. the .cnf file. */
  98. ibool
  99. srv_parse_data_file_paths_and_sizes(
  100. /*================================*/
  101. /* out: TRUE if ok, FALSE if parsing
  102. error */
  103. char* str, /* in: the data file path string */
  104. char*** data_file_names, /* out, own: array of data file
  105. names */
  106. ulint** data_file_sizes, /* out, own: array of data file sizes
  107. in megabytes */
  108. ulint** data_file_is_raw_partition,/* out, own: array of flags
  109. showing which data files are raw
  110. partitions */
  111. ulint* n_data_files, /* out: number of data files */
  112. ibool* is_auto_extending, /* out: TRUE if the last data file is
  113. auto-extending */
  114. ulint* max_auto_extend_size) /* out: max auto extend size for the
  115. last file if specified, 0 if not */
  116. {
  117. char* input_str;
  118. char* endp;
  119. char* path;
  120. ulint size;
  121. ulint i = 0;
  122. *is_auto_extending = FALSE;
  123. *max_auto_extend_size = 0;
  124. input_str = str;
  125. /* First calculate the number of data files and check syntax:
  126. path:size[M | G];path:size[M | G]... . Note that a Windows path may
  127. contain a drive name and a ':'. */
  128. while (*str != '') {
  129. path = str;
  130. while ((*str != ':' && *str != '')
  131.        || (*str == ':'
  132.    && (*(str + 1) == '\' || *(str + 1) == '/'
  133.      || *(str + 1) == ':'))) {
  134. str++;
  135. }
  136. if (*str == '') {
  137. return(FALSE);
  138. }
  139. str++;
  140. size = strtoul(str, &endp, 10);
  141. str = endp;
  142. if (*str != 'M' && *str != 'G') {
  143. size = size / (1024 * 1024);
  144. } else if (*str == 'G') {
  145.         size = size * 1024;
  146. str++;
  147. } else {
  148.         str++;
  149. }
  150.         if (0 == memcmp(str, ":autoextend", (sizeof ":autoextend") - 1)) {
  151. str += (sizeof ":autoextend") - 1;
  152.          if (0 == memcmp(str, ":max:", (sizeof ":max:") - 1)) {
  153. str += (sizeof ":max:") - 1;
  154. size = strtoul(str, &endp, 10);
  155. str = endp;
  156. if (*str != 'M' && *str != 'G') {
  157. size = size / (1024 * 1024);
  158. } else if (*str == 'G') {
  159.          size = size * 1024;
  160. str++;
  161. } else {
  162.          str++;
  163. }
  164. }
  165. if (*str != '') {
  166. return(FALSE);
  167. }
  168. }
  169.         if (strlen(str) >= 6
  170.    && *str == 'n'
  171.    && *(str + 1) == 'e' 
  172.            && *(str + 2) == 'w') {
  173.    str += 3;
  174. }
  175.         if (*str == 'r' && *(str + 1) == 'a' && *(str + 2) == 'w') {
  176.    str += 3;
  177. }
  178. if (size == 0) {
  179. return(FALSE);
  180. }
  181. i++;
  182. if (*str == ';') {
  183. str++;
  184. } else if (*str != '') {
  185. return(FALSE);
  186. }
  187. }
  188. *data_file_names = (char**)ut_malloc(i * sizeof(void*));
  189. *data_file_sizes = (ulint*)ut_malloc(i * sizeof(ulint));
  190. *data_file_is_raw_partition = (ulint*)ut_malloc(i * sizeof(ulint));
  191. *n_data_files = i;
  192. /* Then store the actual values to our arrays */
  193. str = input_str;
  194. i = 0;
  195. while (*str != '') {
  196. path = str;
  197. /* Note that we must step over the ':' in a Windows path;
  198. a Windows path normally looks like C:ibdataibdata1:1G, but
  199. a Windows raw partition may have a specification like
  200. \.C::1Gnewraw or \.PHYSICALDRIVE2:1Gnewraw */
  201. while ((*str != ':' && *str != '')
  202.        || (*str == ':'
  203.    && (*(str + 1) == '\' || *(str + 1) == '/'
  204.         || *(str + 1) == ':'))) {
  205. str++;
  206. }
  207. if (*str == ':') {
  208. /* Make path a null-terminated string */
  209. *str = '';
  210. str++;
  211. }
  212. size = strtoul(str, &endp, 10);
  213. str = endp;
  214. if ((*str != 'M') && (*str != 'G')) {
  215. size = size / (1024 * 1024);
  216. } else if (*str == 'G') {
  217.         size = size * 1024;
  218. str++;
  219. } else {
  220.         str++;
  221. }
  222. (*data_file_names)[i] = path;
  223. (*data_file_sizes)[i] = size;
  224.         if (0 == memcmp(str, ":autoextend", (sizeof ":autoextend") - 1)) {
  225. *is_auto_extending = TRUE;
  226. str += (sizeof ":autoextend") - 1;
  227.          if (0 == memcmp(str, ":max:", (sizeof ":max:") - 1)) {
  228. str += (sizeof ":max:") - 1;
  229. size = strtoul(str, &endp, 10);
  230. str = endp;
  231. if (*str != 'M' && *str != 'G') {
  232. size = size / (1024 * 1024);
  233. } else if (*str == 'G') {
  234.          size = size * 1024;
  235. str++;
  236. } else {
  237.          str++;
  238. }
  239. *max_auto_extend_size = size;
  240. }
  241. if (*str != '') {
  242. return(FALSE);
  243. }
  244. }
  245. (*data_file_is_raw_partition)[i] = 0;
  246.         if (strlen(str) >= 6
  247.    && *str == 'n'
  248.    && *(str + 1) == 'e' 
  249.            && *(str + 2) == 'w') {
  250.    str += 3;
  251.    (*data_file_is_raw_partition)[i] = SRV_NEW_RAW;
  252. }
  253. if (*str == 'r' && *(str + 1) == 'a' && *(str + 2) == 'w') {
  254.   str += 3;
  255.   
  256.    if ((*data_file_is_raw_partition)[i] == 0) {
  257.      (*data_file_is_raw_partition)[i] = SRV_OLD_RAW;
  258.    }   
  259. }
  260. i++;
  261. if (*str == ';') {
  262. str++;
  263. }
  264. }
  265. return(TRUE);
  266. }
  267. /*************************************************************************
  268. Reads log group home directories from a character string given in
  269. the .cnf file. */
  270. ibool
  271. srv_parse_log_group_home_dirs(
  272. /*==========================*/
  273. /* out: TRUE if ok, FALSE if parsing
  274. error */
  275. char* str, /* in: character string */
  276. char*** log_group_home_dirs) /* out, own: log group home dirs */
  277. {
  278. char* input_str;
  279. char* path;
  280. ulint i = 0;
  281. input_str = str;
  282. /* First calculate the number of directories and check syntax:
  283. path;path;... */
  284. while (*str != '') {
  285. path = str;
  286. while (*str != ';' && *str != '') {
  287. str++;
  288. }
  289. i++;
  290. if (*str == ';') {
  291. str++;
  292. } else if (*str != '') {
  293. return(FALSE);
  294. }
  295. }
  296. *log_group_home_dirs = (char**) ut_malloc(i * sizeof(void*));
  297. /* Then store the actual values to our array */
  298. str = input_str;
  299. i = 0;
  300. while (*str != '') {
  301. path = str;
  302. while (*str != ';' && *str != '') {
  303. str++;
  304. }
  305. if (*str == ';') {
  306. *str = '';
  307. str++;
  308. }
  309. (*log_group_home_dirs)[i] = path;
  310. i++;
  311. }
  312. return(TRUE);
  313. }
  314. /************************************************************************
  315. I/o-handler thread function. */
  316. static
  317. #ifndef __WIN__
  318. void*
  319. #else
  320. ulint
  321. #endif
  322. io_handler_thread(
  323. /*==============*/
  324. void* arg)
  325. {
  326. ulint segment;
  327. ulint i;
  328. segment = *((ulint*)arg);
  329. #ifdef UNIV_DEBUG_THREAD_CREATION
  330. fprintf(stderr, "Io handler thread %lu starts, id %lun", segment,
  331. os_thread_pf(os_thread_get_curr_id()));
  332. #endif
  333. for (i = 0;; i++) {
  334. fil_aio_wait(segment);
  335. mutex_enter(&ios_mutex);
  336. ios++;
  337. mutex_exit(&ios_mutex);
  338. }
  339. /* We count the number of threads in os_thread_exit(). A created
  340. thread should always use that to exit and not use return() to exit.
  341. The thread actually never comes here because it is exited in an
  342. os_event_wait(). */
  343. os_thread_exit(NULL);
  344. #ifndef __WIN__
  345. return(NULL); /* Not reached */
  346. #else
  347. return(0);
  348. #endif
  349. }
  350. #ifdef __WIN__
  351. #define SRV_PATH_SEPARATOR '\'
  352. #else
  353. #define SRV_PATH_SEPARATOR '/'
  354. #endif
  355. /*************************************************************************
  356. Normalizes a directory path for Windows: converts slashes to backslashes. */
  357. void
  358. srv_normalize_path_for_win(
  359. /*=======================*/
  360. char* str __attribute__((unused))) /* in/out: null-terminated
  361.    character string */
  362. {
  363. #ifdef __WIN__
  364. for (; *str; str++) {
  365. if (*str == '/') {
  366. *str = '\';
  367. }
  368. }
  369. #endif
  370. }
  371. /*************************************************************************
  372. Adds a slash or a backslash to the end of a string if it is missing
  373. and the string is not empty. */
  374. static
  375. char*
  376. srv_add_path_separator_if_needed(
  377. /*=============================*/
  378. /* out: string which has the separator if the
  379. string is not empty */
  380. char* str) /* in: null-terminated character string */
  381. {
  382. char* out_str;
  383. ulint len = ut_strlen(str);
  384. if (len == 0 || str[len - 1] == SRV_PATH_SEPARATOR) {
  385. return(str);
  386. }
  387. out_str = ut_malloc(len + 2);
  388. memcpy(out_str, str, len);
  389. out_str[len] = SRV_PATH_SEPARATOR;
  390. out_str[len + 1] = 0;
  391. return(out_str);
  392. }
  393. /*************************************************************************
  394. Calculates the low 32 bits when a file size which is given as a number
  395. database pages is converted to the number of bytes. */
  396. static
  397. ulint
  398. srv_calc_low32(
  399. /*===========*/
  400. /* out: low 32 bytes of file size when
  401. expressed in bytes */
  402. ulint file_size) /* in: file size in database pages */
  403. {
  404. return(0xFFFFFFFFUL & (file_size << UNIV_PAGE_SIZE_SHIFT));
  405. }
  406. /*************************************************************************
  407. Calculates the high 32 bits when a file size which is given as a number
  408. database pages is converted to the number of bytes. */
  409. static
  410. ulint
  411. srv_calc_high32(
  412. /*============*/
  413. /* out: high 32 bytes of file size when
  414. expressed in bytes */
  415. ulint file_size) /* in: file size in database pages */
  416. {
  417. return(file_size >> (32 - UNIV_PAGE_SIZE_SHIFT));
  418. }
  419. /*************************************************************************
  420. Creates or opens the log files and closes them. */
  421. static
  422. ulint
  423. open_or_create_log_file(
  424. /*====================*/
  425. /* out: DB_SUCCESS or error code */
  426.         ibool   create_new_db,          /* in: TRUE if we should create a
  427.                                         new database */
  428. ibool* log_file_created, /* out: TRUE if new log file
  429. created */
  430. ibool log_file_has_been_opened,/* in: TRUE if a log file has been
  431. opened before: then it is an error
  432. to try to create another log file */
  433. ulint k, /* in: log group number */
  434. ulint i) /* in: log file number in group */
  435. {
  436. ibool ret;
  437. ulint size;
  438. ulint size_high;
  439. char name[10000];
  440. UT_NOT_USED(create_new_db);
  441. *log_file_created = FALSE;
  442. srv_normalize_path_for_win(srv_log_group_home_dirs[k]);
  443. srv_log_group_home_dirs[k] = srv_add_path_separator_if_needed(
  444. srv_log_group_home_dirs[k]);
  445. ut_a(strlen(srv_log_group_home_dirs[k]) <
  446. (sizeof name) - 10 - sizeof "ib_logfile");
  447. sprintf(name, "%s%s%lu", srv_log_group_home_dirs[k], "ib_logfile", (ulong) i);
  448. files[i] = os_file_create(name, OS_FILE_CREATE, OS_FILE_NORMAL,
  449. OS_LOG_FILE, &ret);
  450. if (ret == FALSE) {
  451. if (os_file_get_last_error(FALSE) != OS_FILE_ALREADY_EXISTS
  452. #ifdef UNIV_AIX
  453.     /* AIX 5.1 after security patch ML7 may have errno set
  454. to 0 here, which causes our function to return 100;
  455. work around that AIX problem */
  456.    && os_file_get_last_error(FALSE) != 100
  457. #endif
  458. ) {
  459. fprintf(stderr,
  460. "InnoDB: Error in creating or opening %sn", name);
  461. return(DB_ERROR);
  462. }
  463. files[i] = os_file_create(name, OS_FILE_OPEN, OS_FILE_AIO,
  464. OS_LOG_FILE, &ret);
  465. if (!ret) {
  466. fprintf(stderr,
  467. "InnoDB: Error in opening %sn", name);
  468. return(DB_ERROR);
  469. }
  470. ret = os_file_get_size(files[i], &size, &size_high);
  471. ut_a(ret);
  472. if (size != srv_calc_low32(srv_log_file_size)
  473.     || size_high != srv_calc_high32(srv_log_file_size)) {
  474.     
  475. fprintf(stderr,
  476. "InnoDB: Error: log file %s is of different size %lu %lu bytesn"
  477. "InnoDB: than specified in the .cnf file %lu %lu bytes!n",
  478. name, (ulong) size_high, (ulong) size,
  479. (ulong) srv_calc_high32(srv_log_file_size),
  480. (ulong) srv_calc_low32(srv_log_file_size));
  481. return(DB_ERROR);
  482. }
  483. } else {
  484. *log_file_created = TRUE;
  485.      ut_print_timestamp(stderr);
  486. fprintf(stderr,
  487. "  InnoDB: Log file %s did not exist: new to be createdn",
  488. name);
  489. if (log_file_has_been_opened) {
  490. return(DB_ERROR);
  491. }
  492. fprintf(stderr, "InnoDB: Setting log file %s size to %lu MBn",
  493.              name, (ulong) srv_log_file_size
  494. >> (20 - UNIV_PAGE_SIZE_SHIFT));
  495. fprintf(stderr,
  496.     "InnoDB: Database physically writes the file full: wait...n");
  497. ret = os_file_set_size(name, files[i],
  498. srv_calc_low32(srv_log_file_size),
  499. srv_calc_high32(srv_log_file_size));
  500. if (!ret) {
  501. fprintf(stderr,
  502. "InnoDB: Error in creating %s: probably out of disk spacen",
  503. name);
  504. return(DB_ERROR);
  505. }
  506. }
  507. ret = os_file_close(files[i]);
  508. ut_a(ret);
  509. if (i == 0) {
  510. /* Create in memory the file space object
  511. which is for this log group */
  512. fil_space_create(name,
  513. 2 * k + SRV_LOG_SPACE_FIRST_ID, FIL_LOG);
  514. }
  515. ut_a(fil_validate());
  516. fil_node_create(name, srv_log_file_size,
  517. 2 * k + SRV_LOG_SPACE_FIRST_ID, FALSE);
  518. #ifdef UNIV_LOG_ARCHIVE
  519. /* If this is the first log group, create the file space object
  520. for archived logs.
  521. Under MySQL, no archiving ever done. */
  522. if (k == 0 && i == 0) {
  523. arch_space_id = 2 * k + 1 + SRV_LOG_SPACE_FIRST_ID;
  524.      fil_space_create("arch_log_space", arch_space_id, FIL_LOG);
  525. } else {
  526. arch_space_id = ULINT_UNDEFINED;
  527. }
  528. #endif /* UNIV_LOG_ARCHIVE */
  529. if (i == 0) {
  530. log_group_init(k, srv_n_log_files,
  531. srv_log_file_size * UNIV_PAGE_SIZE,
  532. 2 * k + SRV_LOG_SPACE_FIRST_ID,
  533. SRV_LOG_SPACE_FIRST_ID + 1); /* dummy arch
  534. space id */
  535. }
  536. return(DB_SUCCESS);
  537. }
  538. /*************************************************************************
  539. Creates or opens database data files and closes them. */
  540. static
  541. ulint
  542. open_or_create_data_files(
  543. /*======================*/
  544. /* out: DB_SUCCESS or error code */
  545. ibool* create_new_db, /* out: TRUE if new database should be
  546. created */
  547. #ifdef UNIV_LOG_ARCHIVE
  548. ulint* min_arch_log_no,/* out: min of archived log numbers in data
  549. files */
  550. ulint* max_arch_log_no,/* out: */
  551. #endif /* UNIV_LOG_ARCHIVE */
  552. dulint* min_flushed_lsn,/* out: min of flushed lsn values in data
  553. files */
  554. dulint* max_flushed_lsn,/* out: */
  555. ulint* sum_of_new_sizes)/* out: sum of sizes of the new files added */
  556. {
  557. ibool ret;
  558. ulint i;
  559. ibool one_opened = FALSE;
  560. ibool one_created = FALSE;
  561. ulint size;
  562. ulint size_high;
  563. ulint rounded_size_pages;
  564. char name[10000];
  565. if (srv_n_data_files >= 1000) {
  566. fprintf(stderr, "InnoDB: can only have < 1000 data filesn"
  567. "InnoDB: you have defined %lun",
  568. (ulong) srv_n_data_files);
  569. return(DB_ERROR);
  570. }
  571. *sum_of_new_sizes = 0;
  572. *create_new_db = FALSE;
  573. srv_normalize_path_for_win(srv_data_home);
  574. srv_data_home = srv_add_path_separator_if_needed(srv_data_home);
  575. for (i = 0; i < srv_n_data_files; i++) {
  576. srv_normalize_path_for_win(srv_data_file_names[i]);
  577. ut_a(strlen(srv_data_home) + strlen(srv_data_file_names[i])
  578. < (sizeof name) - 1);
  579. sprintf(name, "%s%s", srv_data_home, srv_data_file_names[i]);
  580. if (srv_data_file_is_raw_partition[i] == 0) {
  581. /* First we try to create the file: if it already
  582. exists, ret will get value FALSE */
  583. files[i] = os_file_create(name, OS_FILE_CREATE,
  584. OS_FILE_NORMAL, OS_DATA_FILE, &ret);
  585. if (ret == FALSE && os_file_get_last_error(FALSE) !=
  586. OS_FILE_ALREADY_EXISTS
  587. #ifdef UNIV_AIX
  588.     /* AIX 5.1 after security patch ML7 may have
  589. errno set to 0 here, which causes our function
  590. to return 100; work around that AIX problem */
  591.         && os_file_get_last_error(FALSE) != 100
  592. #endif
  593. ) {
  594. fprintf(stderr,
  595. "InnoDB: Error in creating or opening %sn",
  596. name);
  597. return(DB_ERROR);
  598. }
  599. } else if (srv_data_file_is_raw_partition[i] == SRV_NEW_RAW) {
  600. /* The partition is opened, not created; then it is
  601. written over */
  602. srv_start_raw_disk_in_use = TRUE;
  603. srv_created_new_raw = TRUE;
  604. files[i] = os_file_create(
  605. name, OS_FILE_OPEN_RAW, OS_FILE_NORMAL,
  606. OS_DATA_FILE, &ret);
  607. if (!ret) {
  608. fprintf(stderr,
  609. "InnoDB: Error in opening %sn", name);
  610. return(DB_ERROR);
  611. }
  612. } else if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) {
  613. srv_start_raw_disk_in_use = TRUE;
  614. ret = FALSE;
  615. } else {
  616. ut_a(0);
  617. }
  618. if (ret == FALSE) {
  619. /* We open the data file */
  620. if (one_created) {
  621. fprintf(stderr,
  622. "InnoDB: Error: data files can only be added at the endn");
  623. fprintf(stderr,
  624. "InnoDB: of a tablespace, but data file %s existed beforehand.n",
  625. name);
  626. return(DB_ERROR);
  627. }
  628. if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) {
  629. files[i] = os_file_create(
  630. name, OS_FILE_OPEN_RAW, OS_FILE_NORMAL,
  631.  OS_DATA_FILE, &ret);
  632. } else if (i == 0) {
  633. files[i] = os_file_create(
  634. name, OS_FILE_OPEN_RETRY,
  635. OS_FILE_NORMAL,
  636. OS_DATA_FILE, &ret);
  637. } else {
  638. files[i] = os_file_create(
  639. name, OS_FILE_OPEN, OS_FILE_NORMAL,
  640.  OS_DATA_FILE, &ret);
  641. }
  642. if (!ret) {
  643. fprintf(stderr,
  644. "InnoDB: Error in opening %sn", name);
  645. os_file_get_last_error(TRUE);
  646. return(DB_ERROR);
  647. }
  648. if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) {
  649. goto skip_size_check;
  650. }
  651. ret = os_file_get_size(files[i], &size, &size_high);
  652. ut_a(ret);
  653. /* Round size downward to megabytes */
  654. rounded_size_pages = (size / (1024 * 1024)
  655. + 4096 * size_high)
  656.      << (20 - UNIV_PAGE_SIZE_SHIFT);
  657. if (i == srv_n_data_files - 1
  658.     && srv_auto_extend_last_data_file) {
  659. if (srv_data_file_sizes[i] >
  660.      rounded_size_pages
  661.         || (srv_last_file_size_max > 0
  662.            && srv_last_file_size_max <
  663.             rounded_size_pages)) {
  664.             
  665. fprintf(stderr,
  666. "InnoDB: Error: auto-extending data file %s is of a different sizen"
  667. "InnoDB: %lu pages (rounded down to MB) than specified in the .cnf file:n"
  668. "InnoDB: initial %lu pages, max %lu (relevant if non-zero) pages!n",
  669.   name, (ulong) rounded_size_pages,
  670.   (ulong) srv_data_file_sizes[i],
  671.   (ulong) srv_last_file_size_max);
  672. return(DB_ERROR);
  673. }
  674.           
  675. srv_data_file_sizes[i] = rounded_size_pages;
  676. }
  677. if (rounded_size_pages != srv_data_file_sizes[i]) {
  678. fprintf(stderr,
  679. "InnoDB: Error: data file %s is of a different sizen"
  680. "InnoDB: %lu pages (rounded down to MB)n"
  681. "InnoDB: than specified in the .cnf file %lu pages!n", name,
  682.        (ulong) rounded_size_pages,
  683.        (ulong) srv_data_file_sizes[i]);
  684. return(DB_ERROR);
  685. }
  686. skip_size_check:
  687. fil_read_flushed_lsn_and_arch_log_no(files[i],
  688. one_opened,
  689. #ifdef UNIV_LOG_ARCHIVE
  690. min_arch_log_no, max_arch_log_no,
  691. #endif /* UNIV_LOG_ARCHIVE */
  692. min_flushed_lsn, max_flushed_lsn);
  693. one_opened = TRUE;
  694. } else {
  695.         /* We created the data file and now write it full of
  696. zeros */
  697. one_created = TRUE;
  698. if (i > 0) {
  699.      ut_print_timestamp(stderr);
  700. fprintf(stderr, 
  701. "  InnoDB: Data file %s did not exist: new to be createdn",
  702. name);
  703. } else {
  704. fprintf(stderr, 
  705.   "InnoDB: The first specified data file %s did not exist:n"
  706. "InnoDB: a new database to be created!n", name);
  707. *create_new_db = TRUE;
  708. }
  709.      ut_print_timestamp(stderr);
  710. fprintf(stderr, 
  711. "  InnoDB: Setting file %s size to %lu MBn",
  712.        name, (ulong) (srv_data_file_sizes[i]
  713.       >> (20 - UNIV_PAGE_SIZE_SHIFT)));
  714. fprintf(stderr,
  715. "InnoDB: Database physically writes the file full: wait...n");
  716. ret = os_file_set_size(name, files[i],
  717. srv_calc_low32(srv_data_file_sizes[i]),
  718. srv_calc_high32(srv_data_file_sizes[i]));
  719. if (!ret) {
  720. fprintf(stderr, 
  721. "InnoDB: Error in creating %s: probably out of disk spacen", name);
  722. return(DB_ERROR);
  723. }
  724. *sum_of_new_sizes = *sum_of_new_sizes
  725. + srv_data_file_sizes[i];
  726. }
  727. ret = os_file_close(files[i]);
  728. ut_a(ret);
  729. if (i == 0) {
  730. fil_space_create(name, 0, FIL_TABLESPACE);
  731. }
  732. ut_a(fil_validate());
  733. if (srv_data_file_is_raw_partition[i]) {
  734.         fil_node_create(name, srv_data_file_sizes[i], 0, TRUE);
  735. } else {
  736.         fil_node_create(name, srv_data_file_sizes[i], 0,
  737. FALSE);
  738. }
  739. }
  740. ios = 0;
  741. mutex_create(&ios_mutex);
  742. mutex_set_level(&ios_mutex, SYNC_NO_ORDER_CHECK);
  743. return(DB_SUCCESS);
  744. }
  745. /********************************************************************
  746. Starts InnoDB and creates a new database if database files
  747. are not found and the user wants. Server parameters are
  748. read from a file of name "srv_init" in the ib_home directory. */
  749. int
  750. innobase_start_or_create_for_mysql(void)
  751. /*====================================*/
  752. /* out: DB_SUCCESS or error code */
  753. {
  754. buf_pool_t* ret;
  755. ibool create_new_db;
  756. ibool log_file_created;
  757. ibool log_created = FALSE;
  758. ibool log_opened = FALSE;
  759. dulint min_flushed_lsn;
  760. dulint max_flushed_lsn;
  761. #ifdef UNIV_LOG_ARCHIVE
  762. ulint min_arch_log_no;
  763. ulint max_arch_log_no;
  764. #endif /* UNIV_LOG_ARCHIVE */
  765. ulint   sum_of_new_sizes;
  766. ulint sum_of_data_file_sizes;
  767. ulint tablespace_size_in_header;
  768. ulint err;
  769. ulint i;
  770. ibool srv_file_per_table_original_value  = srv_file_per_table;
  771. mtr_t   mtr;
  772. #ifdef HAVE_DARWIN_THREADS
  773. # ifdef F_FULLFSYNC
  774. /* This executable has been compiled on Mac OS X 10.3 or later.
  775. Assume that F_FULLFSYNC is available at run-time. */
  776. srv_have_fullfsync = TRUE;
  777. # else /* F_FULLFSYNC */
  778. /* This executable has been compiled on Mac OS X 10.2
  779. or earlier.  Determine if the executable is running
  780. on Mac OS X 10.3 or later. */
  781. struct utsname utsname;
  782. if (uname(&utsname)) {
  783. fputs("InnoDB: cannot determine Mac OS X version!n", stderr);
  784. } else {
  785. srv_have_fullfsync = strcmp(utsname.release, "7.") >= 0;
  786. }
  787. if (!srv_have_fullfsync) {
  788. fputs(
  789. "InnoDB: On Mac OS X, fsync() may be broken on internal drives,n"
  790. "InnoDB: making transactions unsafe!n", stderr);
  791. }
  792. # endif /* F_FULLFSYNC */
  793. #endif /* HAVE_DARWIN_THREADS */
  794. if (sizeof(ulint) != sizeof(void*)) {
  795. fprintf(stderr,
  796. "InnoDB: Error: size of InnoDB's ulint is %lu, but size of void* is %lu.n"
  797. "InnoDB: The sizes should be the same so that on a 64-bit platform you cann"
  798. "InnoDB: allocate more than 4 GB of memory.",
  799. (ulong)sizeof(ulint), (ulong)sizeof(void*));
  800. }
  801. srv_file_per_table = FALSE; /* system tables are created in tablespace
  802. 0 */
  803. #ifdef UNIV_DEBUG
  804. fprintf(stderr,
  805. "InnoDB: !!!!!!!!!!!!!! UNIV_DEBUG switched on !!!!!!!!!!!!!!!n"); 
  806. #endif
  807. #ifdef UNIV_SYNC_DEBUG
  808. fprintf(stderr,
  809. "InnoDB: !!!!!!!!!!!!!! UNIV_SYNC_DEBUG switched on !!!!!!!!!!!!!!!n"); 
  810. #endif
  811. #ifdef UNIV_SEARCH_DEBUG
  812. fprintf(stderr,
  813. "InnoDB: !!!!!!!!!!!!!! UNIV_SEARCH_DEBUG switched on !!!!!!!!!!!!!!!n"); 
  814. #endif
  815. #ifdef UNIV_MEM_DEBUG
  816. fprintf(stderr,
  817. "InnoDB: !!!!!!!!!!!!!! UNIV_MEM_DEBUG switched on !!!!!!!!!!!!!!!n"); 
  818. #endif
  819. #ifdef UNIV_SIMULATE_AWE
  820. fprintf(stderr,
  821. "InnoDB: !!!!!!!!!!!!!! UNIV_SIMULATE_AWE switched on !!!!!!!!!!!!!!!!!n");
  822. #endif
  823.         if (srv_sizeof_trx_t_in_ha_innodb_cc != (ulint)sizeof(trx_t)) {
  824.         fprintf(stderr,
  825.   "InnoDB: Error: trx_t size is %lu in ha_innodb.cc but %lu in srv0start.cn"
  826.   "InnoDB: Check that pthread_mutex_t is defined in the same way in thesen"
  827.   "InnoDB: compilation modules. Cannot continue.n",
  828.  (ulong)  srv_sizeof_trx_t_in_ha_innodb_cc,
  829.  (ulong) sizeof(trx_t));
  830. return(DB_ERROR);
  831. }
  832. /* Since InnoDB does not currently clean up all its internal data
  833.    structures in MySQL Embedded Server Library server_end(), we
  834.    print an error message if someone tries to start up InnoDB a
  835.    second time during the process lifetime. */
  836. if (srv_start_has_been_called) {
  837.         fprintf(stderr,
  838. "InnoDB: Error:startup called second time during the process lifetime.n"
  839. "InnoDB: In the MySQL Embedded Server Library you cannot call server_init()n"
  840. "InnoDB: more than once during the process lifetime.n");
  841. }
  842. srv_start_has_been_called = TRUE;
  843. log_do_write = TRUE;
  844. /* yydebug = TRUE; */
  845. srv_is_being_started = TRUE;
  846.         srv_startup_is_before_trx_rollback_phase = TRUE;
  847. os_aio_use_native_aio = FALSE;
  848. #if !defined(__WIN2000__) && !defined(UNIV_SIMULATE_AWE)
  849. if (srv_use_awe) {
  850.         fprintf(stderr,
  851. "InnoDB: Error: You have specified innodb_buffer_pool_awe_mem_mbn"
  852. "InnoDB: in my.cnf, but AWE can only be used in Windows 2000 and later.n"
  853. "InnoDB: To use AWE, InnoDB must be compiled with __WIN2000__ defined.n");
  854.         return(DB_ERROR);
  855. }
  856. #endif
  857. #ifdef __WIN__
  858. if (os_get_os_version() == OS_WIN95
  859.     || os_get_os_version() == OS_WIN31
  860.     || os_get_os_version() == OS_WINNT) {
  861.    /* On Win 95, 98, ME, Win32 subsystem for Windows 3.1,
  862. and NT use simulated aio. In NT Windows provides async i/o,
  863. but when run in conjunction with InnoDB Hot Backup, it seemed
  864. to corrupt the data files. */
  865.    os_aio_use_native_aio = FALSE;
  866. } else {
  867.    /* On Win 2000 and XP use async i/o */
  868.    os_aio_use_native_aio = TRUE;
  869. }
  870. #endif
  871.         if (srv_file_flush_method_str == NULL) {
  872.          /* These are the default options */
  873. srv_unix_file_flush_method = SRV_UNIX_FDATASYNC;
  874. srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
  875. #ifndef __WIN__        
  876. } else if (0 == ut_strcmp(srv_file_flush_method_str, "fdatasync")) {
  877.    srv_unix_file_flush_method = SRV_UNIX_FDATASYNC;
  878. } else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DSYNC")) {
  879.    srv_unix_file_flush_method = SRV_UNIX_O_DSYNC;
  880. } else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DIRECT")) {
  881.    srv_unix_file_flush_method = SRV_UNIX_O_DIRECT;
  882. } else if (0 == ut_strcmp(srv_file_flush_method_str, "littlesync")) {
  883.    srv_unix_file_flush_method = SRV_UNIX_LITTLESYNC;
  884. } else if (0 == ut_strcmp(srv_file_flush_method_str, "nosync")) {
  885.    srv_unix_file_flush_method = SRV_UNIX_NOSYNC;
  886. #else
  887. } else if (0 == ut_strcmp(srv_file_flush_method_str, "normal")) {
  888.    srv_win_file_flush_method = SRV_WIN_IO_NORMAL;
  889.    os_aio_use_native_aio = FALSE;
  890. } else if (0 == ut_strcmp(srv_file_flush_method_str, "unbuffered")) {
  891.    srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
  892.    os_aio_use_native_aio = FALSE;
  893. } else if (0 == ut_strcmp(srv_file_flush_method_str,
  894. "async_unbuffered")) {
  895.    srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
  896. #endif
  897. } else {
  898.    fprintf(stderr, 
  899.            "InnoDB: Unrecognized value %s for innodb_flush_methodn",
  900.            srv_file_flush_method_str);
  901.    return(DB_ERROR);
  902. }
  903. /* Note that the call srv_boot() also changes the values of
  904. srv_pool_size etc. to the units used by InnoDB internally */
  905.         /* Set the maximum number of threads which can wait for a semaphore
  906.         inside InnoDB: this is the 'sync wait array' size, as well as the
  907. maximum number of threads that can wait in the 'srv_conc array' for
  908. their time to enter InnoDB. */
  909. #if defined(__WIN__) || defined(__NETWARE__)
  910. /* Create less event semaphores because Win 98/ME had difficulty creating
  911. 40000 event semaphores.
  912. Comment from Novell, Inc.: also, these just take a lot of memory on
  913. NetWare. */
  914.         srv_max_n_threads = 1000;
  915. #else
  916.         if (srv_pool_size >= 1000 * 1024) {
  917.                                   /* Here we still have srv_pool_size counted
  918.                                   in kilobytes (in 4.0 this was in bytes)
  919.   srv_boot() converts the value to
  920.                                   pages; if buffer pool is less than 1000 MB,
  921.                                   assume fewer threads. */
  922.                 srv_max_n_threads = 50000;
  923.         } else if (srv_pool_size >= 8 * 1024) {
  924.                 srv_max_n_threads = 10000;
  925.         } else {
  926. srv_max_n_threads = 1000;       /* saves several MB of memory,
  927.                                                 especially in 64-bit
  928.                                                 computers */
  929.         }
  930. #endif
  931. err = srv_boot(); /* This changes srv_pool_size to units of a page */
  932. if (err != DB_SUCCESS) {
  933. return((int) err);
  934. }
  935. mutex_create(&srv_monitor_file_mutex);
  936. mutex_set_level(&srv_monitor_file_mutex, SYNC_NO_ORDER_CHECK);
  937. if (srv_innodb_status) {
  938. srv_monitor_file_name = mem_alloc(
  939. strlen(fil_path_to_mysql_datadir) +
  940. 20 + sizeof "/innodb_status.");
  941. sprintf(srv_monitor_file_name, "%s/innodb_status.%lu",
  942. fil_path_to_mysql_datadir, os_proc_get_number());
  943. srv_monitor_file = fopen(srv_monitor_file_name, "w+");
  944. if (!srv_monitor_file) {
  945. fprintf(stderr, "InnoDB: unable to create %s: %sn",
  946. srv_monitor_file_name, strerror(errno));
  947. return(DB_ERROR);
  948. }
  949. } else {
  950. srv_monitor_file_name = NULL;
  951. srv_monitor_file = os_file_create_tmpfile();
  952. if (!srv_monitor_file) {
  953. return(DB_ERROR);
  954. }
  955. }
  956. /* Restrict the maximum number of file i/o threads */
  957. if (srv_n_file_io_threads > SRV_MAX_N_IO_THREADS) {
  958. srv_n_file_io_threads = SRV_MAX_N_IO_THREADS;
  959. }
  960. if (!os_aio_use_native_aio) {
  961.   /* In simulated aio we currently have use only for 4 threads */
  962. srv_n_file_io_threads = 4;
  963. os_aio_init(8 * SRV_N_PENDING_IOS_PER_THREAD
  964. * srv_n_file_io_threads,
  965. srv_n_file_io_threads,
  966. SRV_MAX_N_PENDING_SYNC_IOS);
  967. } else {
  968. os_aio_init(SRV_N_PENDING_IOS_PER_THREAD
  969. * srv_n_file_io_threads,
  970. srv_n_file_io_threads,
  971. SRV_MAX_N_PENDING_SYNC_IOS);
  972. }
  973. fil_init(srv_max_n_open_files);
  974. if (srv_use_awe) {
  975. fprintf(stderr,
  976. "InnoDB: Using AWE: Memory window is %lu MB and AWE memory is %lu MBn",
  977. (ulong) (srv_awe_window_size / ((1024 * 1024) / UNIV_PAGE_SIZE)),
  978. (ulong) (srv_pool_size / ((1024 * 1024) / UNIV_PAGE_SIZE)));
  979. /* We must disable adaptive hash indexes because they do not
  980. tolerate remapping of pages in AWE */
  981. srv_use_adaptive_hash_indexes = FALSE;
  982. ret = buf_pool_init(srv_pool_size, srv_pool_size,
  983. srv_awe_window_size);
  984. } else {
  985. ret = buf_pool_init(srv_pool_size, srv_pool_size,
  986. srv_pool_size);
  987. }
  988. if (ret == NULL) {
  989. fprintf(stderr,
  990. "InnoDB: Fatal error: cannot allocate the memory for the buffer pooln");
  991. return(DB_ERROR);
  992. }
  993. fsp_init();
  994. log_init();
  995. lock_sys_create(srv_lock_table_size);
  996. /* Create i/o-handler threads: */
  997. for (i = 0; i < srv_n_file_io_threads; i++) {
  998. n[i] = i;
  999. os_thread_create(io_handler_thread, n + i, thread_ids + i);
  1000.      }
  1001. #ifdef UNIV_LOG_ARCHIVE
  1002. if (0 != ut_strcmp(srv_log_group_home_dirs[0], srv_arch_dir)) {
  1003. fprintf(stderr,
  1004. "InnoDB: Error: you must set the log group home dir in my.cnf then"
  1005. "InnoDB: same as log arch dir.n");
  1006. return(DB_ERROR);
  1007. }
  1008. #endif /* UNIV_LOG_ARCHIVE */
  1009. if (srv_n_log_files * srv_log_file_size >= 262144) {
  1010. fprintf(stderr,
  1011. "InnoDB: Error: combined size of log files must be < 4 GBn");
  1012. return(DB_ERROR);
  1013. }
  1014. sum_of_new_sizes = 0;
  1015. for (i = 0; i < srv_n_data_files; i++) {
  1016. #ifndef __WIN__
  1017. if (sizeof(off_t) < 5 && srv_data_file_sizes[i] >= 262144) {
  1018.   fprintf(stderr,
  1019. "InnoDB: Error: file size must be < 4 GB with this MySQL binaryn"
  1020. "InnoDB: and operating system combination, in some OS's < 2 GBn");
  1021.    return(DB_ERROR);
  1022. }
  1023. #endif
  1024. sum_of_new_sizes += srv_data_file_sizes[i];
  1025. }
  1026. if (sum_of_new_sizes < 640) {
  1027.   fprintf(stderr,
  1028.   "InnoDB: Error: tablespace size must be at least 10 MBn");
  1029.   return(DB_ERROR);
  1030. }
  1031. err = open_or_create_data_files(&create_new_db,
  1032. #ifdef UNIV_LOG_ARCHIVE
  1033. &min_arch_log_no, &max_arch_log_no,
  1034. #endif /* UNIV_LOG_ARCHIVE */
  1035. &min_flushed_lsn, &max_flushed_lsn,
  1036. &sum_of_new_sizes);
  1037. if (err != DB_SUCCESS) {
  1038.         fprintf(stderr,
  1039. "InnoDB: Could not open or create data files.n"
  1040. "InnoDB: If you tried to add new data files, and it failed here,n"
  1041. "InnoDB: you should now edit innodb_data_file_path in my.cnf backn"
  1042. "InnoDB: to what it was, and remove the new ibdata files InnoDB createdn"
  1043. "InnoDB: in this failed attempt. InnoDB only wrote those files full ofn"
  1044. "InnoDB: zeros, but did not yet use them in any way. But be careful: do notn"
  1045. "InnoDB: remove old data files which contain your precious data!n");
  1046. return((int) err);
  1047. }
  1048. #ifdef UNIV_LOG_ARCHIVE
  1049. srv_normalize_path_for_win(srv_arch_dir);
  1050. srv_arch_dir = srv_add_path_separator_if_needed(srv_arch_dir);
  1051. #endif /* UNIV_LOG_ARCHIVE */
  1052. for (i = 0; i < srv_n_log_files; i++) {
  1053. err = open_or_create_log_file(create_new_db, &log_file_created,
  1054.      log_opened, 0, i);
  1055. if (err != DB_SUCCESS) {
  1056. return((int) err);
  1057. }
  1058. if (log_file_created) {
  1059. log_created = TRUE;
  1060. } else {
  1061. log_opened = TRUE;
  1062. }
  1063. if ((log_opened && create_new_db)
  1064.      || (log_opened && log_created)) {
  1065. fprintf(stderr, 
  1066. "InnoDB: Error: all log files must be created at the same time.n"
  1067. "InnoDB: All log files must be created also in database creation.n"
  1068. "InnoDB: If you want bigger or smaller log files, shut down then"
  1069. "InnoDB: database and make sure there were no errors in shutdown.n"
  1070. "InnoDB: Then delete the existing log files. Edit the .cnf filen"
  1071. "InnoDB: and start the database again.n");
  1072. return(DB_ERROR);
  1073. }
  1074. }
  1075. /* Open all log files and data files in the system tablespace: we
  1076. keep them open until database shutdown */
  1077. fil_open_log_and_system_tablespace_files();
  1078. if (log_created && !create_new_db
  1079. #ifdef UNIV_LOG_ARCHIVE
  1080. && !srv_archive_recovery
  1081. #endif /* UNIV_LOG_ARCHIVE */
  1082. ) {
  1083. if (ut_dulint_cmp(max_flushed_lsn, min_flushed_lsn) != 0
  1084. #ifdef UNIV_LOG_ARCHIVE
  1085. || max_arch_log_no != min_arch_log_no
  1086. #endif /* UNIV_LOG_ARCHIVE */
  1087. ) {
  1088. fprintf(stderr, 
  1089. "InnoDB: Cannot initialize created log files becausen"
  1090. "InnoDB: data files were not in sync with each othern"
  1091. "InnoDB: or the data files are corrupt.n");
  1092. return(DB_ERROR);
  1093. }
  1094. if (ut_dulint_cmp(max_flushed_lsn, ut_dulint_create(0, 1000))
  1095.     < 0) {
  1096.      fprintf(stderr,
  1097. "InnoDB: Cannot initialize created log files becausen"
  1098. "InnoDB: data files are corrupt, or new data files weren"
  1099. "InnoDB: created when the database was started previousn"
  1100. "InnoDB: time but the database was not shut downn"
  1101. "InnoDB: normally after that.n");
  1102. return(DB_ERROR);
  1103. }
  1104. mutex_enter(&(log_sys->mutex));
  1105. #ifdef UNIV_LOG_ARCHIVE
  1106. /* Do not + 1 arch_log_no because we do not use log
  1107. archiving */
  1108. recv_reset_logs(max_flushed_lsn, max_arch_log_no, TRUE);
  1109. #else
  1110. recv_reset_logs(max_flushed_lsn, TRUE);
  1111. #endif /* UNIV_LOG_ARCHIVE */
  1112. mutex_exit(&(log_sys->mutex));
  1113. }
  1114. if (create_new_db) {
  1115. mtr_start(&mtr);
  1116. fsp_header_init(0, sum_of_new_sizes, &mtr);
  1117. mtr_commit(&mtr);
  1118. trx_sys_create();
  1119. dict_create();
  1120.                 srv_startup_is_before_trx_rollback_phase = FALSE;
  1121. #ifdef UNIV_LOG_ARCHIVE
  1122. } else if (srv_archive_recovery) {
  1123. fprintf(stderr,
  1124. "InnoDB: Starting archive recovery from a backup...n");
  1125. err = recv_recovery_from_archive_start(
  1126. min_flushed_lsn,
  1127. srv_archive_recovery_limit_lsn,
  1128. min_arch_log_no);
  1129. if (err != DB_SUCCESS) {
  1130. return(DB_ERROR);
  1131. }
  1132. /* Since ibuf init is in dict_boot, and ibuf is needed
  1133. in any disk i/o, first call dict_boot */
  1134. dict_boot();
  1135. trx_sys_init_at_db_start();
  1136.                 srv_startup_is_before_trx_rollback_phase = FALSE;
  1137. /* Initialize the fsp free limit global variable in the log
  1138. system */
  1139. fsp_header_get_free_limit(0);
  1140. recv_recovery_from_archive_finish();
  1141. #endif /* UNIV_LOG_ARCHIVE */
  1142. } else {
  1143. /* We always try to do a recovery, even if the database had
  1144. been shut down normally: this is the normal startup path */
  1145. err = recv_recovery_from_checkpoint_start(LOG_CHECKPOINT,
  1146. ut_dulint_max,
  1147. min_flushed_lsn,
  1148. max_flushed_lsn);
  1149. if (err != DB_SUCCESS) {
  1150. return(DB_ERROR);
  1151. }
  1152. /* Since the insert buffer init is in dict_boot, and the
  1153. insert buffer is needed in any disk i/o, first we call
  1154. dict_boot(). Note that trx_sys_init_at_db_start() only needs
  1155. to access space 0, and the insert buffer at this stage already
  1156. works for space 0. */
  1157. dict_boot();
  1158. trx_sys_init_at_db_start();
  1159. if (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE) {
  1160. /* The following call is necessary for the insert
  1161. buffer to work with multiple tablespaces. We must
  1162. know the mapping between space id's and .ibd file
  1163. names.
  1164. In a crash recovery, we check that the info in data
  1165. dictionary is consistent with what we already know
  1166. about space id's from the call of
  1167. fil_load_single_table_tablespaces().
  1168. In a normal startup, we create the space objects for
  1169. every table in the InnoDB data dictionary that has
  1170. an .ibd file.
  1171. We also determine the maximum tablespace id used.
  1172. TODO: We may have incomplete transactions in the
  1173. data dictionary tables. Does that harm the scanning of
  1174. the data dictionary below? */
  1175. dict_check_tablespaces_and_store_max_id(
  1176. recv_needed_recovery);
  1177. }
  1178.                 srv_startup_is_before_trx_rollback_phase = FALSE;
  1179. /* Initialize the fsp free limit global variable in the log
  1180. system */
  1181. fsp_header_get_free_limit(0);
  1182. /* recv_recovery_from_checkpoint_finish needs trx lists which
  1183. are initialized in trx_sys_init_at_db_start(). */
  1184. recv_recovery_from_checkpoint_finish();
  1185. }
  1186. if (!create_new_db && sum_of_new_sizes > 0) {
  1187. /* New data file(s) were added */
  1188. mtr_start(&mtr);
  1189. fsp_header_inc_size(0, sum_of_new_sizes, &mtr);
  1190. mtr_commit(&mtr);
  1191. }
  1192. if (recv_needed_recovery) {
  1193.      ut_print_timestamp(stderr);
  1194. fprintf(stderr,
  1195.         "  InnoDB: Flushing modified pages from the buffer pool...n");
  1196. }
  1197. log_make_checkpoint_at(ut_dulint_max, TRUE);
  1198. #ifdef UNIV_LOG_ARCHIVE
  1199. /* Archiving is always off under MySQL */
  1200. if (!srv_log_archive_on) {
  1201. ut_a(DB_SUCCESS == log_archive_noarchivelog());
  1202. } else {
  1203. mutex_enter(&(log_sys->mutex));
  1204. start_archive = FALSE;
  1205. if (log_sys->archiving_state == LOG_ARCH_OFF) {
  1206. start_archive = TRUE;
  1207. }
  1208. mutex_exit(&(log_sys->mutex));
  1209. if (start_archive) {
  1210. ut_a(DB_SUCCESS == log_archive_archivelog());
  1211. }
  1212. }
  1213. #endif /* UNIV_LOG_ARCHIVE */
  1214. if (srv_measure_contention) {
  1215.    /* os_thread_create(&test_measure_cont, NULL, thread_ids +
  1216.                                    SRV_MAX_N_IO_THREADS); */
  1217. }
  1218. /* fprintf(stderr, "Max allowed record size %lun",
  1219. page_get_free_space_of_empty() / 2); */
  1220. /* Create the thread which watches the timeouts for lock waits
  1221. and prints InnoDB monitor info */
  1222. os_thread_create(&srv_lock_timeout_and_monitor_thread, NULL,
  1223. thread_ids + 2 + SRV_MAX_N_IO_THREADS);
  1224. /* Create the thread which warns of long semaphore waits */
  1225. os_thread_create(&srv_error_monitor_thread, NULL,
  1226. thread_ids + 3 + SRV_MAX_N_IO_THREADS);
  1227. srv_was_started = TRUE;
  1228. srv_is_being_started = FALSE;
  1229. #ifdef UNIV_DEBUG
  1230.         /* Wait a while so that the created threads have time to suspend
  1231. themselves before we switch sync debugging on; otherwise a thread may
  1232. execute mutex_enter() before the checks are on, and mutex_exit() after
  1233. the checks are on, which will cause an assertion failure in sync
  1234. debug. */
  1235.         os_thread_sleep(3000000);
  1236. #endif
  1237. sync_order_checks_on = TRUE;
  1238.         if (srv_use_doublewrite_buf && trx_doublewrite == NULL) {
  1239. /* Create the doublewrite buffer to a new tablespace */
  1240. trx_sys_create_doublewrite_buf();
  1241. }
  1242. err = dict_create_or_check_foreign_constraint_tables();
  1243. if (err != DB_SUCCESS) {
  1244. return((int)DB_ERROR);
  1245. }
  1246. /* Create the master thread which does purge and other utility
  1247. operations */
  1248. os_thread_create(&srv_master_thread, NULL, thread_ids + 1 +
  1249. SRV_MAX_N_IO_THREADS);
  1250. /* buf_debug_prints = TRUE; */
  1251. sum_of_data_file_sizes = 0;
  1252. for (i = 0; i < srv_n_data_files; i++) {
  1253. sum_of_data_file_sizes += srv_data_file_sizes[i];
  1254. }
  1255. tablespace_size_in_header = fsp_header_get_tablespace_size(0);
  1256. if (!srv_auto_extend_last_data_file
  1257. && sum_of_data_file_sizes != tablespace_size_in_header) {
  1258. fprintf(stderr,
  1259. "InnoDB: Error: tablespace size stored in header is %lu pages, butn"
  1260. "InnoDB: the sum of data file sizes is %lu pagesn",
  1261.   (ulong) tablespace_size_in_header,
  1262. (ulong) sum_of_data_file_sizes);
  1263. if (srv_force_recovery == 0
  1264.     && sum_of_data_file_sizes < tablespace_size_in_header) {
  1265. /* This is a fatal error, the tail of a tablespace is
  1266. missing */
  1267. fprintf(stderr,
  1268. "InnoDB: Cannot start InnoDB. The tail of the system tablespace isn"
  1269. "InnoDB: missing. Have you edited innodb_data_file_path in my.cnf in ann"
  1270. "InnoDB: inappropriate way, removing ibdata files from there?n"
  1271. "InnoDB: You can set innodb_force_recovery=1 in my.cnf to forcen"
  1272. "InnoDB: a startup if you are trying to recover a badly corrupt database.n");
  1273. return(DB_ERROR);
  1274. }
  1275. }
  1276. if (srv_auto_extend_last_data_file
  1277. && sum_of_data_file_sizes < tablespace_size_in_header) {
  1278. fprintf(stderr,
  1279. "InnoDB: Error: tablespace size stored in header is %lu pages, butn"
  1280. "InnoDB: the sum of data file sizes is only %lu pagesn",
  1281.   (ulong) tablespace_size_in_header,
  1282. (ulong) sum_of_data_file_sizes);
  1283. if (srv_force_recovery == 0) {
  1284. fprintf(stderr,
  1285. "InnoDB: Cannot start InnoDB. The tail of the system tablespace isn"
  1286. "InnoDB: missing. Have you edited innodb_data_file_path in my.cnf in ann"
  1287. "InnoDB: inappropriate way, removing ibdata files from there?n"
  1288. "InnoDB: You can set innodb_force_recovery=1 in my.cnf to forcen"
  1289. "InnoDB: a startup if you are trying to recover a badly corrupt database.n");
  1290. return(DB_ERROR);
  1291. }
  1292. }
  1293. /* Check that os_fast_mutexes work as expected */
  1294. os_fast_mutex_init(&srv_os_test_mutex);
  1295. if (0 != os_fast_mutex_trylock(&srv_os_test_mutex)) {
  1296.         fprintf(stderr,
  1297. "InnoDB: Error: pthread_mutex_trylock returns an unexpected value onn"
  1298. "InnoDB: success! Cannot continue.n");
  1299.         exit(1);
  1300. }
  1301. os_fast_mutex_unlock(&srv_os_test_mutex);
  1302.         os_fast_mutex_lock(&srv_os_test_mutex);
  1303. os_fast_mutex_unlock(&srv_os_test_mutex);
  1304. os_fast_mutex_free(&srv_os_test_mutex);
  1305. if (srv_print_verbose_log) {
  1306.    ut_print_timestamp(stderr);
  1307.    fprintf(stderr,
  1308. "  InnoDB: Started; log sequence number %lu %lun",
  1309. (ulong) ut_dulint_get_high(srv_start_lsn),
  1310. (ulong) ut_dulint_get_low(srv_start_lsn));
  1311. }
  1312. if (srv_force_recovery > 0) {
  1313. fprintf(stderr,
  1314. "InnoDB: !!! innodb_force_recovery is set to %lu !!!n",
  1315. (ulong) srv_force_recovery);
  1316. }
  1317. fflush(stderr);
  1318. if (trx_doublewrite_must_reset_space_ids) {
  1319. /* Actually, we did not change the undo log format between
  1320. 4.0 and 4.1.1, and we would not need to run purge to
  1321. completion. Note also that the purge algorithm in 4.1.1
  1322. can process the the history list again even after a full
  1323. purge, because our algorithm does not cut the end of the
  1324. history list in all cases so that it would become empty
  1325. after a full purge. That mean that we may purge 4.0 type
  1326. undo log even after this phase.
  1327. The insert buffer record format changed between 4.0 and
  1328. 4.1.1. It is essential that the insert buffer is emptied
  1329. here! */
  1330. fprintf(stderr,
  1331. "InnoDB: You are upgrading to an InnoDB version which allows multiplen"
  1332. "InnoDB: tablespaces. Wait that purge and insert buffer merge run ton"
  1333. "InnoDB: completion...n");
  1334. for (;;) {
  1335. os_thread_sleep(1000000);
  1336. if (0 == strcmp(srv_main_thread_op_info,
  1337. "waiting for server activity")) {
  1338. ut_a(ibuf_is_empty());
  1339. break;
  1340. }
  1341. }
  1342. fprintf(stderr,
  1343. "InnoDB: Full purge and insert buffer merge completed.n");
  1344.         trx_sys_mark_upgraded_to_multiple_tablespaces();
  1345. fprintf(stderr,
  1346. "InnoDB: You have now successfully upgraded to the multiple tablespacesn"
  1347. "InnoDB: format. You should NOT DOWNGRADE to an earlier version ofn"
  1348. "InnoDB: InnoDB! But if you absolutely need to downgrade, seen"
  1349. "InnoDB: http://dev.mysql.com/doc/mysql/en/Multiple_tablespaces.htmln"
  1350. "InnoDB: for instructions.n");
  1351. }
  1352. if (srv_force_recovery == 0) {
  1353. /* In the insert buffer we may have even bigger tablespace
  1354. id's, because we may have dropped those tablespaces, but
  1355. insert buffer merge has not had time to clean the records from
  1356. the ibuf tree. */
  1357. ibuf_update_max_tablespace_id();
  1358. }
  1359. srv_file_per_table = srv_file_per_table_original_value;
  1360. return((int) DB_SUCCESS);
  1361. }
  1362. /********************************************************************
  1363. Shuts down the InnoDB database. */
  1364. int
  1365. innobase_shutdown_for_mysql(void) 
  1366. /*=============================*/
  1367. /* out: DB_SUCCESS or error code */
  1368. {
  1369. ulint   i;
  1370. #ifdef __NETWARE__
  1371. extern ibool panic_shutdown;
  1372. #endif
  1373.         if (!srv_was_started) {
  1374.    if (srv_is_being_started) {
  1375.      ut_print_timestamp(stderr);
  1376.              fprintf(stderr, 
  1377. "  InnoDB: Warning: shutting down a not properly startedn"
  1378. "                 InnoDB: or created database!n");
  1379.    }
  1380.    return(DB_SUCCESS);
  1381. }
  1382. /* 1. Flush the buffer pool to disk, write the current lsn to
  1383. the tablespace header(s), and copy all log data to archive.
  1384. The step 1 is the real InnoDB shutdown. The remaining steps 2 - ...
  1385. just free data structures after the shutdown. */
  1386. #ifdef __NETWARE__
  1387. if(!panic_shutdown)
  1388. #endif 
  1389. logs_empty_and_mark_files_at_shutdown();
  1390. if (srv_conc_n_threads != 0) {
  1391. fprintf(stderr,
  1392. "InnoDB: Warning: query counter shows %ld queries stilln"
  1393. "InnoDB: inside InnoDB at shutdownn",
  1394. srv_conc_n_threads);
  1395. }
  1396. /* 2. Make all threads created by InnoDB to exit */
  1397. srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS;
  1398. /* All threads end up waiting for certain events. Put those events
  1399. to the signaled state. Then the threads will exit themselves in
  1400. os_thread_event_wait(). */
  1401. for (i = 0; i < 1000; i++) {
  1402.         /* NOTE: IF YOU CREATE THREADS IN INNODB, YOU MUST EXIT THEM
  1403.         HERE OR EARLIER */
  1404. /* a. Let the lock timeout thread exit */
  1405. os_event_set(srv_lock_timeout_thread_event);
  1406. /* b. srv error monitor thread exits automatically, no need
  1407. to do anything here */
  1408. /* c. We wake the master thread so that it exits */
  1409. srv_wake_master_thread();
  1410. /* d. Exit the i/o threads */
  1411. os_aio_wake_all_threads_at_shutdown();
  1412. os_mutex_enter(os_sync_mutex);
  1413. if (os_thread_count == 0) {
  1414.         /* All the threads have exited or are just exiting;
  1415. NOTE that the threads may not have completed their
  1416. exit yet. Should we use pthread_join() to make sure
  1417. they have exited? Now we just sleep 0.1 seconds and
  1418. hope that is enough! */
  1419. os_mutex_exit(os_sync_mutex);
  1420. os_thread_sleep(100000);
  1421. break;
  1422. }
  1423. os_mutex_exit(os_sync_mutex);
  1424. os_thread_sleep(100000);
  1425. }
  1426. if (i == 1000) {
  1427.         fprintf(stderr,
  1428. "InnoDB: Warning: %lu threads created by InnoDB had not exited at shutdown!n",
  1429.       (ulong) os_thread_count);
  1430. }
  1431. if (srv_monitor_file) {
  1432. fclose(srv_monitor_file);
  1433. srv_monitor_file = 0;
  1434. if (srv_monitor_file_name) {
  1435. unlink(srv_monitor_file_name);
  1436. mem_free(srv_monitor_file_name);
  1437. }
  1438. }
  1439. mutex_free(&srv_monitor_file_mutex);
  1440. /* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside
  1441. them */
  1442. sync_close();
  1443. /* 4. Free the os_conc_mutex and all os_events and os_mutexes */
  1444. srv_free();
  1445. os_sync_free();
  1446. /* 5. Free all allocated memory and the os_fast_mutex created in
  1447. ut0mem.c */
  1448. ut_free_all_mem();
  1449. if (os_thread_count != 0
  1450.     || os_event_count != 0
  1451.     || os_mutex_count != 0
  1452.     || os_fast_mutex_count != 0) {
  1453.         fprintf(stderr,
  1454. "InnoDB: Warning: some resources were not cleaned up in shutdown:n"
  1455. "InnoDB: threads %lu, events %lu, os_mutexes %lu, os_fast_mutexes %lun",
  1456. (ulong) os_thread_count, (ulong) os_event_count,
  1457. (ulong) os_mutex_count, (ulong) os_fast_mutex_count);
  1458. }
  1459. if (dict_foreign_err_file) {
  1460. fclose(dict_foreign_err_file);
  1461. }
  1462. if (lock_latest_err_file) {
  1463. fclose(lock_latest_err_file);
  1464. }
  1465. if (srv_print_verbose_log) {
  1466.         ut_print_timestamp(stderr);
  1467.         fprintf(stderr,
  1468. "  InnoDB: Shutdown completed; log sequence number %lu %lun",
  1469.        (ulong) ut_dulint_get_high(srv_shutdown_lsn),
  1470.        (ulong) ut_dulint_get_low(srv_shutdown_lsn));
  1471. }
  1472. return((int) DB_SUCCESS);
  1473. }
  1474. #ifdef __NETWARE__
  1475. void set_panic_flag_for_netware()
  1476. {
  1477. extern ibool panic_shutdown;
  1478. panic_shutdown = TRUE;
  1479. }
  1480. #endif