00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00041 #include "ut0mem.h"
00042 #include "mem0mem.h"
00043 #include "data0data.h"
00044 #include "data0type.h"
00045 #include "dict0dict.h"
00046 #include "buf0buf.h"
00047 #include "os0file.h"
00048 #include "os0thread.h"
00049 #include "fil0fil.h"
00050 #include "fsp0fsp.h"
00051 #include "rem0rec.h"
00052 #include "mtr0mtr.h"
00053 #include "log0log.h"
00054 #include "log0recv.h"
00055 #include "page0page.h"
00056 #include "page0cur.h"
00057 #include "trx0trx.h"
00058 #include "trx0sys.h"
00059 #include "btr0btr.h"
00060 #include "btr0cur.h"
00061 #include "rem0rec.h"
00062 #include "ibuf0ibuf.h"
00063 #include "srv0start.h"
00064 #include "srv0srv.h"
00065 #ifndef UNIV_HOTBACKUP
00066 # include "os0proc.h"
00067 # include "sync0sync.h"
00068 # include "buf0flu.h"
00069 # include "buf0rea.h"
00070 # include "dict0boot.h"
00071 # include "dict0load.h"
00072 # include "que0que.h"
00073 # include "usr0sess.h"
00074 # include "lock0lock.h"
00075 # include "trx0roll.h"
00076 # include "trx0purge.h"
00077 # include "lock0lock.h"
00078 # include "pars0pars.h"
00079 # include "btr0sea.h"
00080 # include "rem0cmp.h"
00081 # include "dict0crea.h"
00082 # include "row0ins.h"
00083 # include "row0sel.h"
00084 # include "row0upd.h"
00085 # include "row0row.h"
00086 # include "row0mysql.h"
00087 # include "btr0pcur.h"
00088 # include "thr0loc.h"
00089 # include "os0sync.h"
00090 # include "zlib.h"
00091 #include "xtrabackup_api.h"
00092
00093 #include <errno.h>
00094 #include <unistd.h>
00095
00096 #include <drizzled/gettext.h>
00097 #include <drizzled/errmsg_print.h>
00098
00100 UNIV_INTERN ib_uint64_t srv_start_lsn;
00102 UNIV_INTERN ib_uint64_t srv_shutdown_lsn;
00103
00104 #ifdef HAVE_DARWIN_THREADS
00105 # include <sys/utsname.h>
00107 UNIV_INTERN ibool srv_have_fullfsync = FALSE;
00108 #endif
00109
00111 UNIV_INTERN ibool srv_start_raw_disk_in_use = FALSE;
00112
00115 UNIV_INTERN ibool srv_startup_is_before_trx_rollback_phase = FALSE;
00117 UNIV_INTERN ibool srv_is_being_started = FALSE;
00119 UNIV_INTERN ibool srv_was_started = FALSE;
00121 static ibool srv_start_has_been_called = FALSE;
00122
00125 UNIV_INTERN enum srv_shutdown_state srv_shutdown_state = SRV_SHUTDOWN_NONE;
00126
00128 static os_file_t files[1000];
00129
00131 static ulint n[SRV_MAX_N_IO_THREADS + 7];
00133 static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 7];
00134
00137 static os_fast_mutex_t srv_os_test_mutex;
00138
00140 static char* srv_monitor_file_name;
00141 #endif
00142
00144 #define SRV_N_PENDING_IOS_PER_THREAD OS_AIO_N_PENDING_IOS_PER_THREAD
00145 #define SRV_MAX_N_PENDING_SYNC_IOS 100
00146
00147 #ifdef UNIV_PFS_THREAD
00148
00149 UNIV_INTERN mysql_pfs_key_t io_handler_thread_key;
00150 UNIV_INTERN mysql_pfs_key_t srv_lock_timeout_thread_key;
00151 UNIV_INTERN mysql_pfs_key_t srv_error_monitor_thread_key;
00152 UNIV_INTERN mysql_pfs_key_t srv_monitor_thread_key;
00153 UNIV_INTERN mysql_pfs_key_t srv_master_thread_key;
00154 #endif
00155
00156
00160 static
00161 char*
00162 srv_parse_megabytes(
00163
00164 char* str,
00165 ulint* megs)
00166 {
00167 char* endp;
00168 ulint size;
00169
00170 size = strtoul(str, &endp, 10);
00171
00172 str = endp;
00173
00174 switch (*str) {
00175 case 'G': case 'g':
00176 size *= 1024;
00177
00178 case 'M': case 'm':
00179 str++;
00180 break;
00181 default:
00182 size /= 1024 * 1024;
00183 break;
00184 }
00185
00186 *megs = size;
00187 return(str);
00188 }
00189
00190
00194 UNIV_INTERN
00195 ibool
00196 srv_parse_data_file_paths_and_sizes(
00197
00198 char* str)
00199 {
00200 char* input_str;
00201 char* path;
00202 ulint size;
00203 ulint i = 0;
00204
00205 srv_auto_extend_last_data_file = FALSE;
00206 srv_last_file_size_max = 0;
00207 srv_data_file_names = NULL;
00208 srv_data_file_sizes = NULL;
00209 srv_data_file_is_raw_partition = NULL;
00210
00211 input_str = str;
00212
00213
00214
00215
00216
00217 while (*str != '\0') {
00218 path = str;
00219
00220 while ((*str != ':' && *str != '\0')
00221 || (*str == ':'
00222 && (*(str + 1) == '\\' || *(str + 1) == '/'
00223 || *(str + 1) == ':'))) {
00224 str++;
00225 }
00226
00227 if (*str == '\0') {
00228 return(FALSE);
00229 }
00230
00231 str++;
00232
00233 str = srv_parse_megabytes(str, &size);
00234
00235 if (0 == strncmp(str, ":autoextend",
00236 (sizeof ":autoextend") - 1)) {
00237
00238 str += (sizeof ":autoextend") - 1;
00239
00240 if (0 == strncmp(str, ":max:",
00241 (sizeof ":max:") - 1)) {
00242
00243 str += (sizeof ":max:") - 1;
00244
00245 str = srv_parse_megabytes(str, &size);
00246 }
00247
00248 if (*str != '\0') {
00249
00250 return(FALSE);
00251 }
00252 }
00253
00254 if (strlen(str) >= 6
00255 && *str == 'n'
00256 && *(str + 1) == 'e'
00257 && *(str + 2) == 'w') {
00258 str += 3;
00259 }
00260
00261 if (*str == 'r' && *(str + 1) == 'a' && *(str + 2) == 'w') {
00262 str += 3;
00263 }
00264
00265 if (size == 0) {
00266 return(FALSE);
00267 }
00268
00269 i++;
00270
00271 if (*str == ';') {
00272 str++;
00273 } else if (*str != '\0') {
00274
00275 return(FALSE);
00276 }
00277 }
00278
00279 if (i == 0) {
00280
00281
00282
00283 return(FALSE);
00284 }
00285
00286 srv_data_file_names = static_cast<char **>(malloc(i * sizeof *srv_data_file_names));
00287 srv_data_file_sizes = static_cast<ulint *>(malloc(i * sizeof *srv_data_file_sizes));
00288 srv_data_file_is_raw_partition = static_cast<ulint *>(malloc(
00289 i * sizeof *srv_data_file_is_raw_partition));
00290
00291 srv_n_data_files = i;
00292
00293
00294
00295 str = input_str;
00296 i = 0;
00297
00298 while (*str != '\0') {
00299 path = str;
00300
00301
00302
00303
00304
00305
00306 while ((*str != ':' && *str != '\0')
00307 || (*str == ':'
00308 && (*(str + 1) == '\\' || *(str + 1) == '/'
00309 || *(str + 1) == ':'))) {
00310 str++;
00311 }
00312
00313 if (*str == ':') {
00314
00315 *str = '\0';
00316 str++;
00317 }
00318
00319 str = srv_parse_megabytes(str, &size);
00320
00321 srv_data_file_names[i] = path;
00322 srv_data_file_sizes[i] = size;
00323
00324 if (0 == strncmp(str, ":autoextend",
00325 (sizeof ":autoextend") - 1)) {
00326
00327 srv_auto_extend_last_data_file = TRUE;
00328
00329 str += (sizeof ":autoextend") - 1;
00330
00331 if (0 == strncmp(str, ":max:",
00332 (sizeof ":max:") - 1)) {
00333
00334 str += (sizeof ":max:") - 1;
00335
00336 str = srv_parse_megabytes(
00337 str, &srv_last_file_size_max);
00338 }
00339
00340 if (*str != '\0') {
00341
00342 return(FALSE);
00343 }
00344 }
00345
00346 (srv_data_file_is_raw_partition)[i] = 0;
00347
00348 if (strlen(str) >= 6
00349 && *str == 'n'
00350 && *(str + 1) == 'e'
00351 && *(str + 2) == 'w') {
00352 str += 3;
00353 (srv_data_file_is_raw_partition)[i] = SRV_NEW_RAW;
00354 }
00355
00356 if (*str == 'r' && *(str + 1) == 'a' && *(str + 2) == 'w') {
00357 str += 3;
00358
00359 if ((srv_data_file_is_raw_partition)[i] == 0) {
00360 (srv_data_file_is_raw_partition)[i] = SRV_OLD_RAW;
00361 }
00362 }
00363
00364 i++;
00365
00366 if (*str == ';') {
00367 str++;
00368 }
00369 }
00370
00371 return(TRUE);
00372 }
00373
00374
00378 UNIV_INTERN
00379 ibool
00380 srv_parse_log_group_home_dirs(
00381
00382 char* str)
00383 {
00384 char* input_str;
00385 char* path;
00386 ulint i = 0;
00387
00388 srv_log_group_home_dirs = NULL;
00389
00390 input_str = str;
00391
00392
00393
00394
00395 while (*str != '\0') {
00396 path = str;
00397
00398 while (*str != ';' && *str != '\0') {
00399 str++;
00400 }
00401
00402 i++;
00403
00404 if (*str == ';') {
00405 str++;
00406 } else if (*str != '\0') {
00407
00408 return(FALSE);
00409 }
00410 }
00411
00412 if (i != 1) {
00413
00414
00415
00416 return(FALSE);
00417 }
00418
00419 srv_log_group_home_dirs = static_cast<char **>(malloc(i * sizeof *srv_log_group_home_dirs));
00420
00421
00422
00423 str = input_str;
00424 i = 0;
00425
00426 while (*str != '\0') {
00427 path = str;
00428
00429 while (*str != ';' && *str != '\0') {
00430 str++;
00431 }
00432
00433 if (*str == ';') {
00434 *str = '\0';
00435 str++;
00436 }
00437
00438 srv_log_group_home_dirs[i] = path;
00439
00440 i++;
00441 }
00442
00443 return(TRUE);
00444 }
00445
00446
00449 UNIV_INTERN
00450 void
00451 srv_free_paths_and_sizes(void)
00452
00453 {
00454 free(srv_data_file_names);
00455 srv_data_file_names = NULL;
00456 free(srv_data_file_sizes);
00457 srv_data_file_sizes = NULL;
00458 free(srv_data_file_is_raw_partition);
00459 srv_data_file_is_raw_partition = NULL;
00460 free(srv_log_group_home_dirs);
00461 srv_log_group_home_dirs = NULL;
00462 }
00463
00464 #ifndef UNIV_HOTBACKUP
00465
00468 extern "C"
00469 os_thread_ret_t
00470 io_handler_thread(void* arg);
00471
00472 extern "C"
00473 os_thread_ret_t
00474 io_handler_thread(
00475
00476 void* arg)
00478 {
00479 ulint segment;
00480
00481 segment = *((ulint*)arg);
00482
00483 #ifdef UNIV_DEBUG_THREAD_CREATION
00484 fprintf(stderr, "Io handler thread %lu starts, id %lu\n", segment,
00485 os_thread_pf(os_thread_get_curr_id()));
00486 #endif
00487
00488 #ifdef UNIV_PFS_THREAD
00489 pfs_register_thread(io_handler_thread_key);
00490 #endif
00491
00492 while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) {
00493 fil_aio_wait(segment);
00494 }
00495
00496
00497
00498
00499
00500 return 0;
00501 }
00502 #endif
00503
00504 #ifdef __WIN__
00505 #define SRV_PATH_SEPARATOR '\\'
00506 #else
00507 #define SRV_PATH_SEPARATOR '/'
00508 #endif
00509
00510
00512 UNIV_INTERN
00513 void
00514 srv_normalize_path_for_win(
00515
00516 char* )
00518 {
00519 #ifdef __WIN__
00520 for (; *str; str++) {
00521
00522 if (*str == '/') {
00523 *str = '\\';
00524 }
00525 }
00526 #endif
00527 }
00528
00529 #ifndef UNIV_HOTBACKUP
00530
00534 static
00535 ulint
00536 srv_calc_low32(
00537
00538 ulint file_size)
00539 {
00540 return(0xFFFFFFFFUL & (file_size << UNIV_PAGE_SIZE_SHIFT));
00541 }
00542
00543
00547 static
00548 ulint
00549 srv_calc_high32(
00550
00551 ulint file_size)
00552 {
00553 return(file_size >> (32 - UNIV_PAGE_SIZE_SHIFT));
00554 }
00555
00556
00559 ulint
00560 open_or_create_log_file(
00561
00562 ibool create_new_db,
00564 ibool* log_file_created,
00566 ibool log_file_has_been_opened,
00569 ulint k,
00570 ulint i)
00571 {
00572 ibool ret;
00573 ulint size;
00574 ulint size_high;
00575 char name[10000];
00576 ulint dirnamelen;
00577
00578 UT_NOT_USED(create_new_db);
00579
00580 *log_file_created = FALSE;
00581
00582 srv_normalize_path_for_win(srv_log_group_home_dirs[k]);
00583
00584 dirnamelen = strlen(srv_log_group_home_dirs[k]);
00585 ut_a(dirnamelen < (sizeof name) - 10 - sizeof "ib_logfile");
00586 memcpy(name, srv_log_group_home_dirs[k], dirnamelen);
00587
00588
00589 if (dirnamelen && name[dirnamelen - 1] != SRV_PATH_SEPARATOR) {
00590 name[dirnamelen++] = SRV_PATH_SEPARATOR;
00591 }
00592
00593 sprintf(name + dirnamelen, "%s%lu", "ib_logfile", (ulong) i);
00594
00595 files[i] = os_file_create(innodb_file_log_key, name,
00596 OS_FILE_CREATE, OS_FILE_NORMAL,
00597 OS_LOG_FILE, &ret);
00598 if (ret == FALSE) {
00599 if (os_file_get_last_error(FALSE) != OS_FILE_ALREADY_EXISTS
00600 #ifdef UNIV_AIX
00601
00602
00603
00604 && os_file_get_last_error(FALSE) != 100
00605 #endif
00606 ) {
00607 drizzled::errmsg_printf(drizzled::error::ERROR,
00608 "InnoDB: Error in creating or opening %s", name);
00609
00610 return(DB_ERROR);
00611 }
00612
00613 files[i] = os_file_create(innodb_file_log_key, name,
00614 OS_FILE_OPEN, OS_FILE_AIO,
00615 OS_LOG_FILE, &ret);
00616 if (!ret) {
00617 drizzled::errmsg_printf(drizzled::error::ERROR,
00618 "InnoDB: Error in opening %s.", name);
00619
00620 return(DB_ERROR);
00621 }
00622
00623 ret = os_file_get_size(files[i], &size, &size_high);
00624 ut_a(ret);
00625
00626 if (size != srv_calc_low32(srv_log_file_size)
00627 || size_high != srv_calc_high32(srv_log_file_size)) {
00628
00629 drizzled::errmsg_printf(drizzled::error::ERROR,
00630 "InnoDB: Error: log file %s is of different size %lu %lu bytes than specified in the .cnf"
00631 " file %lu %lu bytes!",
00632 name, (ulong) size_high, (ulong) size,
00633 (ulong) srv_calc_high32(srv_log_file_size),
00634 (ulong) srv_calc_low32(srv_log_file_size));
00635
00636 return(DB_ERROR);
00637 }
00638 } else {
00639 *log_file_created = TRUE;
00640
00641 drizzled::errmsg_printf(drizzled::error::INFO,
00642 "InnoDB: Log file %s did not exist: new to be created",
00643 name);
00644 if (log_file_has_been_opened) {
00645
00646 return(DB_ERROR);
00647 }
00648
00649 drizzled::errmsg_printf(drizzled::error::INFO,
00650 "InnoDB: Setting log file %s size to %lu MB",
00651 name, (ulong) srv_log_file_size
00652 >> (20 - UNIV_PAGE_SIZE_SHIFT));
00653
00654 drizzled::errmsg_printf(drizzled::error::INFO,
00655 "InnoDB: Database physically writes the file full: wait...\n");
00656
00657 ret = os_file_set_size(name, files[i],
00658 srv_calc_low32(srv_log_file_size),
00659 srv_calc_high32(srv_log_file_size));
00660 if (!ret) {
00661 drizzled::errmsg_printf(drizzled::error::ERROR,
00662 "InnoDB: Error in creating %s: probably out of disk space",
00663 name);
00664
00665 return(DB_ERROR);
00666 }
00667 }
00668
00669 ret = os_file_close(files[i]);
00670 ut_a(ret);
00671
00672 if (i == 0) {
00673
00674
00675
00676 fil_space_create(name,
00677 2 * k + SRV_LOG_SPACE_FIRST_ID, 0, FIL_LOG);
00678 }
00679
00680 ut_a(fil_validate());
00681
00682 fil_node_create(name, srv_log_file_size,
00683 2 * k + SRV_LOG_SPACE_FIRST_ID, FALSE);
00684 #ifdef UNIV_LOG_ARCHIVE
00685
00686
00687
00688
00689 if (k == 0 && i == 0) {
00690 arch_space_id = 2 * k + 1 + SRV_LOG_SPACE_FIRST_ID;
00691
00692 fil_space_create("arch_log_space", arch_space_id, 0, FIL_LOG);
00693 } else {
00694 arch_space_id = ULINT_UNDEFINED;
00695 }
00696 #endif
00697 if (i == 0) {
00698 log_group_init(k, srv_n_log_files,
00699 srv_log_file_size * UNIV_PAGE_SIZE,
00700 2 * k + SRV_LOG_SPACE_FIRST_ID,
00701 SRV_LOG_SPACE_FIRST_ID + 1);
00702
00703 }
00704
00705 return(DB_SUCCESS);
00706 }
00707
00708
00711 ulint
00712 open_or_create_data_files(
00713
00714 ibool* create_new_db,
00716 #ifdef UNIV_LOG_ARCHIVE
00717 ulint* min_arch_log_no,
00719 ulint* max_arch_log_no,
00721 #endif
00722 ib_uint64_t* min_flushed_lsn,
00724 ib_uint64_t* max_flushed_lsn,
00726 ulint* sum_of_new_sizes)
00728 {
00729 ibool ret;
00730 ulint i;
00731 ibool one_opened = FALSE;
00732 ibool one_created = FALSE;
00733 ulint size;
00734 ulint size_high;
00735 ulint rounded_size_pages;
00736 char name[10000];
00737
00738 if (srv_n_data_files >= 1000) {
00739 drizzled::errmsg_printf(drizzled::error::ERROR,
00740 "InnoDB: can only have < 1000 data files you have defined %lu",
00741 (ulong) srv_n_data_files);
00742 return(DB_ERROR);
00743 }
00744
00745 *sum_of_new_sizes = 0;
00746
00747 *create_new_db = FALSE;
00748
00749 srv_normalize_path_for_win(srv_data_home);
00750
00751 for (i = 0; i < srv_n_data_files; i++) {
00752 ulint dirnamelen;
00753
00754 srv_normalize_path_for_win(srv_data_file_names[i]);
00755 dirnamelen = strlen(srv_data_home);
00756
00757 ut_a(dirnamelen + strlen(srv_data_file_names[i])
00758 < (sizeof name) - 1);
00759 memcpy(name, srv_data_home, dirnamelen);
00760
00761 if (dirnamelen && name[dirnamelen - 1] != SRV_PATH_SEPARATOR) {
00762 name[dirnamelen++] = SRV_PATH_SEPARATOR;
00763 }
00764
00765 strcpy(name + dirnamelen, srv_data_file_names[i]);
00766
00767 if (srv_data_file_is_raw_partition[i] == 0) {
00768
00769
00770
00771
00772 files[i] = os_file_create(innodb_file_data_key,
00773 name, OS_FILE_CREATE,
00774 OS_FILE_NORMAL,
00775 OS_DATA_FILE, &ret);
00776
00777 if (ret == FALSE && os_file_get_last_error(FALSE)
00778 != OS_FILE_ALREADY_EXISTS
00779 #ifdef UNIV_AIX
00780
00781
00782
00783 && os_file_get_last_error(FALSE) != 100
00784 #endif
00785 ) {
00786 drizzled::errmsg_printf(drizzled::error::ERROR,
00787 "InnoDB: Error in creating or opening %s",
00788 name);
00789
00790 return(DB_ERROR);
00791 }
00792 } else if (srv_data_file_is_raw_partition[i] == SRV_NEW_RAW) {
00793
00794
00795
00796 srv_start_raw_disk_in_use = TRUE;
00797 srv_created_new_raw = TRUE;
00798
00799 files[i] = os_file_create(innodb_file_data_key,
00800 name, OS_FILE_OPEN_RAW,
00801 OS_FILE_NORMAL,
00802 OS_DATA_FILE, &ret);
00803 if (!ret) {
00804 drizzled::errmsg_printf(drizzled::error::ERROR,
00805 "InnoDB: Error in opening %s", name);
00806
00807 return(DB_ERROR);
00808 }
00809 } else if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) {
00810 srv_start_raw_disk_in_use = TRUE;
00811
00812 ret = FALSE;
00813 } else {
00814 ut_a(0);
00815 }
00816
00817 if (ret == FALSE) {
00818
00819
00820 if (one_created) {
00821 drizzled::errmsg_printf(drizzled::error::ERROR,
00822 "InnoDB: Error: data files can only be added at the end of a tablespace, but"
00823 " data file %s existed beforehand.",
00824 name);
00825 return(DB_ERROR);
00826 }
00827
00828 if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) {
00829 files[i] = os_file_create(
00830 innodb_file_data_key,
00831 name, OS_FILE_OPEN_RAW,
00832 OS_FILE_NORMAL, OS_DATA_FILE, &ret);
00833 } else if (i == 0) {
00834 files[i] = os_file_create(
00835 innodb_file_data_key,
00836 name, OS_FILE_OPEN_RETRY,
00837 OS_FILE_NORMAL, OS_DATA_FILE, &ret);
00838 } else {
00839 files[i] = os_file_create(
00840 innodb_file_data_key,
00841 name, OS_FILE_OPEN, OS_FILE_NORMAL,
00842 OS_DATA_FILE, &ret);
00843 }
00844
00845 if (!ret) {
00846 drizzled::errmsg_printf(drizzled::error::ERROR,
00847 "InnoDB: Error in opening %s", name);
00848 os_file_get_last_error(TRUE);
00849
00850 return(DB_ERROR);
00851 }
00852
00853 if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) {
00854
00855 goto skip_size_check;
00856 }
00857
00858 ret = os_file_get_size(files[i], &size, &size_high);
00859 ut_a(ret);
00860
00861
00862 rounded_size_pages
00863 = (size / (1024 * 1024) + 4096 * size_high)
00864 << (20 - UNIV_PAGE_SIZE_SHIFT);
00865
00866 if (i == srv_n_data_files - 1
00867 && srv_auto_extend_last_data_file) {
00868
00869 if (srv_data_file_sizes[i] > rounded_size_pages
00870 || (srv_last_file_size_max > 0
00871 && srv_last_file_size_max
00872 < rounded_size_pages)) {
00873
00874 drizzled::errmsg_printf(drizzled::error::ERROR,
00875 "InnoDB: Error: auto-extending data file %s is of a different size. "
00876 "%lu pages (rounded down to MB) than specified in the .cnf file: "
00877 "initial %lu pages, max %lu (relevant if non-zero) pages!",
00878 name,
00879 (ulong) rounded_size_pages,
00880 (ulong) srv_data_file_sizes[i],
00881 (ulong)
00882 srv_last_file_size_max);
00883
00884 return(DB_ERROR);
00885 }
00886
00887 srv_data_file_sizes[i] = rounded_size_pages;
00888 }
00889
00890 if (rounded_size_pages != srv_data_file_sizes[i]) {
00891
00892 drizzled::errmsg_printf(drizzled::error::ERROR,
00893 "InnoDB: Error: data file %s is of a different size. "
00894 "%lu pages (rounded down to MB). "
00895 "Than specified in the .cnf file %lu pages!",
00896 name,
00897 (ulong) rounded_size_pages,
00898 (ulong) srv_data_file_sizes[i]);
00899
00900 return(DB_ERROR);
00901 }
00902 skip_size_check:
00903 fil_read_flushed_lsn_and_arch_log_no(
00904 files[i], one_opened,
00905 #ifdef UNIV_LOG_ARCHIVE
00906 min_arch_log_no, max_arch_log_no,
00907 #endif
00908 min_flushed_lsn, max_flushed_lsn);
00909 one_opened = TRUE;
00910 } else {
00911
00912
00913
00914 one_created = TRUE;
00915
00916 if (i > 0) {
00917 drizzled::errmsg_printf(drizzled::error::INFO,
00918 " InnoDB: Data file %s did not exist: new to be created",
00919 name);
00920 } else {
00921 drizzled::errmsg_printf(drizzled::error::INFO,
00922 "InnoDB: The first specified data file %s did not exist. A new database to be created!", name);
00923 *create_new_db = TRUE;
00924 }
00925
00926 drizzled::errmsg_printf(drizzled::error::INFO,
00927 " InnoDB: Setting file %s size to %lu MB",
00928 name, (ulong) (srv_data_file_sizes[i]
00929 >> (20 - UNIV_PAGE_SIZE_SHIFT)));
00930
00931 drizzled::errmsg_printf(drizzled::error::INFO,
00932 "InnoDB: Database physically writes the file full: wait...");
00933
00934 ret = os_file_set_size(
00935 name, files[i],
00936 srv_calc_low32(srv_data_file_sizes[i]),
00937 srv_calc_high32(srv_data_file_sizes[i]));
00938
00939 if (!ret) {
00940 drizzled::errmsg_printf(drizzled::error::ERROR,
00941 "InnoDB: Error in creating %s: probably out of disk space", name);
00942
00943 return(DB_ERROR);
00944 }
00945
00946 *sum_of_new_sizes = *sum_of_new_sizes
00947 + srv_data_file_sizes[i];
00948 }
00949
00950 ret = os_file_close(files[i]);
00951 ut_a(ret);
00952
00953 if (i == 0) {
00954 fil_space_create(name, 0, 0, FIL_TABLESPACE);
00955 }
00956
00957 ut_a(fil_validate());
00958
00959 fil_node_create(name, srv_data_file_sizes[i], 0,
00960 srv_data_file_is_raw_partition[i] != 0);
00961 }
00962
00963 return(DB_SUCCESS);
00964 }
00965
00966
00967
00968
00969
00970 UNIV_INTERN
00971 int
00972 innobase_start_or_create_for_mysql(void)
00973
00974 {
00975 ibool create_new_db;
00976 ibool log_file_created;
00977 ibool log_created = FALSE;
00978 ibool log_opened = FALSE;
00979 ib_uint64_t min_flushed_lsn;
00980 ib_uint64_t max_flushed_lsn;
00981 #ifdef UNIV_LOG_ARCHIVE
00982 ulint min_arch_log_no;
00983 ulint max_arch_log_no;
00984 #endif
00985 ulint sum_of_new_sizes;
00986 ulint sum_of_data_file_sizes;
00987 ulint tablespace_size_in_header;
00988 ulint err;
00989 ulint i;
00990 ulint io_limit;
00991 my_bool srv_file_per_table_original_value
00992 = srv_file_per_table;
00993 mtr_t mtr;
00994 #ifdef HAVE_DARWIN_THREADS
00995 # ifdef F_FULLFSYNC
00996
00997
00998 srv_have_fullfsync = TRUE;
00999 # else
01000
01001
01002
01003 struct utsname utsname;
01004 if (uname(&utsname)) {
01005 fputs(_("InnoDB: cannot determine Mac OS X version!\n"), stderr);
01006 } else {
01007 srv_have_fullfsync = strcmp(utsname.release, "7.") >= 0;
01008 }
01009 if (!srv_have_fullfsync) {
01010 fputs(_("InnoDB: On Mac OS X, fsync() may be"
01011 " broken on internal drives,\n"
01012 "InnoDB: making transactions unsafe!\n"), stderr);
01013 }
01014 # endif
01015 #endif
01016
01017 if (sizeof(ulint) != sizeof(void*)) {
01018 drizzled::errmsg_printf(drizzled::error::WARN,
01019 _("InnoDB: Error: size of InnoDB's ulint is %lu, but size of void* is %lu. "
01020 "The sizes should be the same so that on a 64-bit platform you can. Allocate more than 4 GB of memory."),
01021 (ulong)sizeof(ulint), (ulong)sizeof(void*));
01022 }
01023
01024
01025
01026
01027
01028 srv_file_per_table = FALSE;
01029 #ifdef UNIV_DEBUG
01030 drizzled::errmsg_printf(drizzled::error::INFO,
01031 _("InnoDB: !!!!!!!! UNIV_DEBUG switched on !!!!!!!!!\n"));
01032 #endif
01033
01034 #ifdef UNIV_IBUF_DEBUG
01035 drizzled::errmsg_printf(drizzled::error::INFO,
01036 _("InnoDB: !!!!!!!! UNIV_IBUF_DEBUG switched on !!!!!!!!!\n"
01037 # ifdef UNIV_IBUF_COUNT_DEBUG
01038 "InnoDB: !!!!!!!! UNIV_IBUF_COUNT_DEBUG switched on !!!!!!!!!\n"
01039 "InnoDB: Crash recovery will fail with UNIV_IBUF_COUNT_DEBUG\n"
01040 # endif
01041 ));
01042 #endif
01043
01044 #ifdef UNIV_SYNC_DEBUG
01045 drizzled::errmsg_printf(drizzled::error::INFO,
01046 _("InnoDB: !!!!!!!! UNIV_SYNC_DEBUG switched on !!!!!!!!!\n"));
01047 #endif
01048
01049 #ifdef UNIV_SEARCH_DEBUG
01050 drizzled::errmsg_printf(drizzled::error::INFO,
01051 _("InnoDB: !!!!!!!! UNIV_SEARCH_DEBUG switched on !!!!!!!!!\n"));
01052 #endif
01053
01054 #ifdef UNIV_LOG_LSN_DEBUG
01055 drizzled::errmsg_printf(drizzled::error::INFO,
01056 _("InnoDB: !!!!!!!! UNIV_LOG_LSN_DEBUG switched on !!!!!!!!!\n"));
01057 #endif
01058 #ifdef UNIV_MEM_DEBUG
01059 drizzled::errmsg_printf(drizzled::error::INFO,
01060 _("InnoDB: !!!!!!!! UNIV_MEM_DEBUG switched on !!!!!!!!!\n"));
01061 #endif
01062
01063 if (UNIV_LIKELY(srv_use_sys_malloc))
01064 {
01065 drizzled::errmsg_printf(drizzled::error::INFO, _("InnoDB: The InnoDB memory heap is disabled\n"));
01066 }
01067
01068 drizzled::errmsg_printf(drizzled::error::INFO, "InnoDB: " IB_ATOMICS_STARTUP_MSG
01069 "\nInnoDB: Compressed tables use zlib " ZLIB_VERSION
01070 #ifdef UNIV_ZIP_DEBUG
01071 " with validation"
01072 #endif
01073 #ifdef UNIV_ZIP_COPY
01074 " and extra copying"
01075 #endif
01076 " ");
01077
01078
01079
01080
01081
01082
01083
01084 if (srv_start_has_been_called) {
01085 drizzled::errmsg_printf(drizzled::error::ERROR,
01086 "InnoDB: Error: startup called second time during the process lifetime.\n");
01087 }
01088
01089 srv_start_has_been_called = TRUE;
01090
01091 #ifdef UNIV_DEBUG
01092 log_do_write = TRUE;
01093 #endif
01094
01095
01096 srv_is_being_started = TRUE;
01097 srv_startup_is_before_trx_rollback_phase = TRUE;
01098
01099 #ifdef __WIN__
01100 switch (os_get_os_version()) {
01101 case OS_WIN95:
01102 case OS_WIN31:
01103 case OS_WINNT:
01104
01105
01106
01107
01108
01109 srv_use_native_aio = FALSE;
01110 break;
01111
01112 case OS_WIN2000:
01113 case OS_WINXP:
01114
01115 srv_use_native_aio = TRUE;
01116 break;
01117
01118 default:
01119
01120 srv_use_native_aio = TRUE;
01121 srv_use_native_conditions = TRUE;
01122 break;
01123 }
01124
01125 #elif defined(LINUX_NATIVE_AIO)
01126
01127 if (srv_use_native_aio) {
01128 drizzled::errmsg_printf(drizzled::error::INFO,
01129 _("InnoDB: Using Linux native AIO"));
01130 }
01131 #else
01132
01133
01134
01135 srv_use_native_aio = FALSE;
01136
01137 #endif
01138
01139 if (srv_file_flush_method_str == NULL) {
01140
01141
01142 srv_unix_file_flush_method = SRV_UNIX_FSYNC;
01143
01144 srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
01145 #ifndef __WIN__
01146 } else if (0 == ut_strcmp(srv_file_flush_method_str, "fsync")) {
01147 srv_unix_file_flush_method = SRV_UNIX_FSYNC;
01148
01149 } else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DSYNC")) {
01150 srv_unix_file_flush_method = SRV_UNIX_O_DSYNC;
01151
01152 } else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DIRECT")) {
01153 srv_unix_file_flush_method = SRV_UNIX_O_DIRECT;
01154
01155 } else if (0 == ut_strcmp(srv_file_flush_method_str, "ALL_O_DIRECT")) {
01156 srv_unix_file_flush_method = SRV_UNIX_ALL_O_DIRECT;
01157
01158 } else if (0 == ut_strcmp(srv_file_flush_method_str, "littlesync")) {
01159 srv_unix_file_flush_method = SRV_UNIX_LITTLESYNC;
01160
01161 } else if (0 == ut_strcmp(srv_file_flush_method_str, "nosync")) {
01162 srv_unix_file_flush_method = SRV_UNIX_NOSYNC;
01163 #else
01164 } else if (0 == ut_strcmp(srv_file_flush_method_str, "normal")) {
01165 srv_win_file_flush_method = SRV_WIN_IO_NORMAL;
01166 srv_use_native_aio = FALSE;
01167
01168 } else if (0 == ut_strcmp(srv_file_flush_method_str, "unbuffered")) {
01169 srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
01170 srv_use_native_aio = FALSE;
01171
01172 } else if (0 == ut_strcmp(srv_file_flush_method_str,
01173 "async_unbuffered")) {
01174 srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
01175 #endif
01176 } else {
01177 drizzled::errmsg_printf(drizzled::error::ERROR,
01178 "InnoDB: Unrecognized value %s for innodb_flush_method",
01179 srv_file_flush_method_str);
01180 return(DB_ERROR);
01181 }
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191 if (srv_buf_pool_size >= 1000 * 1024 * 1024) {
01192
01193
01194
01195 srv_max_n_threads = 50000;
01196
01197 } else if (srv_buf_pool_size >= 8 * 1024 * 1024) {
01198
01199 srv_buf_pool_instances = 1;
01200 srv_max_n_threads = 10000;
01201 } else {
01202 srv_buf_pool_instances = 1;
01203 srv_max_n_threads = 1000;
01204
01205
01206 }
01207
01208 err = srv_boot();
01209
01210 if (err != DB_SUCCESS) {
01211
01212 return((int) err);
01213 }
01214
01215 mutex_create(srv_monitor_file_mutex_key,
01216 &srv_monitor_file_mutex, SYNC_NO_ORDER_CHECK);
01217
01218 if (srv_innodb_status) {
01219 srv_monitor_file_name = static_cast<char *>(mem_alloc(
01220 strlen(fil_path_to_mysql_datadir)
01221 + 20 + sizeof "/innodb_status."));
01222 sprintf(srv_monitor_file_name, "%s/innodb_status.%lu",
01223 fil_path_to_mysql_datadir, os_proc_get_number());
01224 srv_monitor_file = fopen(srv_monitor_file_name, "w+");
01225 if (!srv_monitor_file) {
01226 drizzled::errmsg_printf(drizzled::error::ERROR,
01227 "InnoDB: unable to create %s: %s\n", srv_monitor_file_name, strerror(errno));
01228 return(DB_ERROR);
01229 }
01230 } else {
01231 srv_monitor_file_name = NULL;
01232 srv_monitor_file = os_file_create_tmpfile();
01233 if (!srv_monitor_file) {
01234 return(DB_ERROR);
01235 }
01236 }
01237
01238 mutex_create(srv_dict_tmpfile_mutex_key,
01239 &srv_dict_tmpfile_mutex, SYNC_DICT_OPERATION);
01240
01241 srv_dict_tmpfile = os_file_create_tmpfile();
01242 if (!srv_dict_tmpfile) {
01243 return(DB_ERROR);
01244 }
01245
01246 mutex_create(srv_misc_tmpfile_mutex_key,
01247 &srv_misc_tmpfile_mutex, SYNC_ANY_LATCH);
01248
01249 srv_misc_tmpfile = os_file_create_tmpfile();
01250 if (!srv_misc_tmpfile) {
01251 return(DB_ERROR);
01252 }
01253
01254
01255
01256
01257
01258
01259 srv_n_file_io_threads = 2 + srv_n_read_io_threads
01260 + srv_n_write_io_threads;
01261
01262 ut_a(srv_n_file_io_threads <= SRV_MAX_N_IO_THREADS);
01263
01264
01265
01266 if (!srv_use_native_aio) {
01267 io_limit = 8 * SRV_N_PENDING_IOS_PER_THREAD;
01268 } else {
01269 io_limit = SRV_N_PENDING_IOS_PER_THREAD;
01270 }
01271
01272 os_aio_init(io_limit,
01273 srv_n_read_io_threads,
01274 srv_n_write_io_threads,
01275 SRV_MAX_N_PENDING_SYNC_IOS);
01276
01277 fil_init(srv_file_per_table ? 50000 : 5000,
01278 srv_max_n_open_files);
01279
01280
01281
01282 if (srv_buf_pool_size >= 1024 * 1024 * 1024) {
01283 drizzled::errmsg_printf(drizzled::error::INFO, "InnoDB: Initializing buffer pool, size = %.1fG",
01284 ((double) srv_buf_pool_size) / (1024 * 1024 * 1024));
01285 } else {
01286 drizzled::errmsg_printf(drizzled::error::INFO, "InnoDB: Initializing buffer pool, size = %.1fM",
01287 ((double) srv_buf_pool_size) / (1024 * 1024));
01288 }
01289
01290 err = buf_pool_init(srv_buf_pool_size, srv_buf_pool_instances);
01291
01292 drizzled::errmsg_printf(drizzled::error::INFO, "InnoDB: Completed initialization of buffer pool");
01293
01294 if (err != DB_SUCCESS) {
01295 drizzled::errmsg_printf(drizzled::error::ERROR, "InnoDB: Fatal error: cannot allocate the memory for the buffer pool");
01296
01297 return(DB_ERROR);
01298 }
01299
01300 #ifdef UNIV_DEBUG
01301
01302
01303
01304 if (srv_buf_pool_size <= 5 * 1024 * 1024) {
01305
01306 drizzled::errmsg_printf(drizzled::error::WARN, "InnoDB: Warning: Small buffer pool size "
01307 "(%luM), the flst_validate() debug function "
01308 "can cause a deadlock if the buffer pool fills up.\n",
01309 srv_buf_pool_size / 1024 / 1024);
01310 }
01311 #endif
01312
01313 fsp_init();
01314 log_init();
01315
01316 lock_sys_create(srv_lock_table_size);
01317
01318
01319
01320 for (i = 0; i < srv_n_file_io_threads; i++) {
01321 n[i] = i;
01322
01323 os_thread_create(io_handler_thread, n + i, thread_ids + i);
01324 }
01325
01326 #ifdef UNIV_LOG_ARCHIVE
01327 if (0 != ut_strcmp(srv_log_group_home_dirs[0], srv_arch_dir)) {
01328 drizzled::errmsg_printf(drizzled::error::ERROR,
01329 "InnoDB: Error: you must set the log group home dir in my.cnf the same as log arch dir.");
01330
01331 return(DB_ERROR);
01332 }
01333 #endif
01334
01335 if (sizeof(ulint) == 4
01336 && srv_n_log_files * srv_log_file_size
01337 >= (1UL << (32 - UNIV_PAGE_SIZE_SHIFT))) {
01338 drizzled::errmsg_printf(drizzled::error::ERROR,
01339 "InnoDB: Error: combined size of log files must be < 4 GB on 32-bit systems\n");
01340
01341 return(DB_ERROR);
01342 }
01343
01344 sum_of_new_sizes = 0;
01345
01346 for (i = 0; i < srv_n_data_files; i++) {
01347 #ifndef __WIN__
01348 if (sizeof(off_t) < 5 && srv_data_file_sizes[i] >= (1UL << (32 - UNIV_PAGE_SIZE_SHIFT))) {
01349 drizzled::errmsg_printf(drizzled::error::ERROR,
01350 "InnoDB: Error: file size must be < 4 GB with this MySQL binary and operating system combination,"
01351 " in some OS's < 2 GB\n");
01352
01353 return(DB_ERROR);
01354 }
01355 #endif
01356 sum_of_new_sizes += srv_data_file_sizes[i];
01357 }
01358
01359 if (sum_of_new_sizes < 10485760 / UNIV_PAGE_SIZE) {
01360 drizzled::errmsg_printf(drizzled::error::ERROR, "InnoDB: Error: tablespace size must be at least 10 MB");
01361
01362 return(DB_ERROR);
01363 }
01364
01365 err = open_or_create_data_files(&create_new_db,
01366 #ifdef UNIV_LOG_ARCHIVE
01367 &min_arch_log_no, &max_arch_log_no,
01368 #endif
01369 &min_flushed_lsn, &max_flushed_lsn,
01370 &sum_of_new_sizes);
01371 if (err != DB_SUCCESS) {
01372 drizzled::errmsg_printf(drizzled::error::ERROR,
01373 "InnoDB: Could not open or create data files.\n"
01374 "InnoDB: If you tried to add new data files, and it failed here,\n"
01375 "InnoDB: you should now edit innodb_data_file_path in my.cnf back\n"
01376 "InnoDB: to what it was, and remove the new ibdata files InnoDB created\n"
01377 "InnoDB: in this failed attempt. InnoDB only wrote those files full of\n"
01378 "InnoDB: zeros, but did not yet use them in any way. But be careful: do not\n"
01379 "InnoDB: remove old data files which contain your precious data!\n");
01380
01381 return((int) err);
01382 }
01383
01384 #ifdef UNIV_LOG_ARCHIVE
01385 srv_normalize_path_for_win(srv_arch_dir);
01386 srv_arch_dir = srv_add_path_separator_if_needed(srv_arch_dir);
01387 #endif
01388
01389 for (i = 0; i < srv_n_log_files; i++) {
01390 err = open_or_create_log_file(create_new_db, &log_file_created,
01391 log_opened, 0, i);
01392 if (err != DB_SUCCESS) {
01393
01394 return((int) err);
01395 }
01396
01397 if (log_file_created) {
01398 log_created = TRUE;
01399 } else {
01400 log_opened = TRUE;
01401 }
01402 if ((log_opened && create_new_db)
01403 || (log_opened && log_created)) {
01404 drizzled::errmsg_printf(drizzled::error::ERROR,
01405 "InnoDB: Error: all log files must be created at the same time.\n"
01406 "InnoDB: All log files must be created also in database creation.\n"
01407 "InnoDB: If you want bigger or smaller log files, shut down the\n"
01408 "InnoDB: database and make sure there were no errors in shutdown.\n"
01409 "InnoDB: Then delete the existing log files. Edit the .cnf file\n"
01410 "InnoDB: and start the database again.\n");
01411
01412 return(DB_ERROR);
01413 }
01414 }
01415
01416
01417
01418
01419 fil_open_log_and_system_tablespace_files();
01420
01421 if (log_created && !create_new_db
01422 #ifdef UNIV_LOG_ARCHIVE
01423 && !srv_archive_recovery
01424 #endif
01425 ) {
01426 if (max_flushed_lsn != min_flushed_lsn
01427 #ifdef UNIV_LOG_ARCHIVE
01428 || max_arch_log_no != min_arch_log_no
01429 #endif
01430 ) {
01431 drizzled::errmsg_printf(drizzled::error::ERROR,
01432 "InnoDB: Cannot initialize created log files because\n"
01433 "InnoDB: data files were not in sync with each other\n"
01434 "InnoDB: or the data files are corrupt.\n");
01435
01436 return(DB_ERROR);
01437 }
01438
01439 if (max_flushed_lsn < (ib_uint64_t) 1000) {
01440 drizzled::errmsg_printf(drizzled::error::ERROR,
01441 "InnoDB: Cannot initialize created log files because\n"
01442 "InnoDB: data files are corrupt, or new data files were\n"
01443 "InnoDB: created when the database was started previous\n"
01444 "InnoDB: time but the database was not shut down\n"
01445 "InnoDB: normally after that.\n");
01446
01447 return(DB_ERROR);
01448 }
01449
01450 mutex_enter(&(log_sys->mutex));
01451
01452 #ifdef UNIV_LOG_ARCHIVE
01453
01454
01455 recv_reset_logs(max_flushed_lsn, max_arch_log_no, TRUE);
01456 #else
01457 recv_reset_logs(max_flushed_lsn, TRUE);
01458 #endif
01459
01460 mutex_exit(&(log_sys->mutex));
01461 }
01462
01463 trx_sys_file_format_init();
01464
01465 if (create_new_db) {
01466 mtr_start(&mtr);
01467
01468 fsp_header_init(0, sum_of_new_sizes, &mtr);
01469
01470 mtr_commit(&mtr);
01471
01472
01473
01474
01475
01476 trx_sys_create();
01477
01478 dict_create();
01479
01480 srv_startup_is_before_trx_rollback_phase = FALSE;
01481
01482 #ifdef UNIV_LOG_ARCHIVE
01483 } else if (srv_archive_recovery) {
01484 drizzled::errmsg_printf(drizzled::error::INFO,
01485 "InnoDB: Starting archive recovery from a backup...");
01486 err = recv_recovery_from_archive_start(
01487 min_flushed_lsn, srv_archive_recovery_limit_lsn,
01488 min_arch_log_no);
01489 if (err != DB_SUCCESS) {
01490
01491 return(DB_ERROR);
01492 }
01493
01494
01495
01496 dict_boot();
01497
01498 trx_sys_init_at_db_start();
01499
01500 srv_startup_is_before_trx_rollback_phase = FALSE;
01501
01502
01503
01504 fsp_header_get_free_limit();
01505
01506 recv_recovery_from_archive_finish();
01507 #endif
01508 } else {
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522 err = trx_sys_file_format_max_check(
01523 srv_max_file_format_at_startup);
01524
01525 if (err != DB_SUCCESS) {
01526 return(err);
01527 }
01528
01529
01530
01531
01532
01533
01534 buf_pool_invalidate();
01535
01536
01537
01538
01539 err = recv_recovery_from_checkpoint_start(LOG_CHECKPOINT,
01540 IB_ULONGLONG_MAX,
01541 min_flushed_lsn,
01542 max_flushed_lsn);
01543 if (err != DB_SUCCESS) {
01544
01545 return(DB_ERROR);
01546 }
01547
01548
01549
01550
01551
01552
01553
01554 dict_boot();
01555 trx_sys_init_at_db_start();
01556
01557
01558
01559 fsp_header_get_free_limit();
01560
01561
01562
01563
01564 recv_recovery_from_checkpoint_finish();
01565
01566 if (srv_apply_log_only)
01567 goto skip_processes;
01568
01569 if (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE) {
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586 dict_check_tablespaces_and_store_max_id(
01587 recv_needed_recovery);
01588 }
01589
01590 srv_startup_is_before_trx_rollback_phase = FALSE;
01591 recv_recovery_rollback_active();
01592
01593
01594
01595
01596
01597
01598 trx_sys_file_format_tag_init();
01599 }
01600
01601 if (!create_new_db && sum_of_new_sizes > 0) {
01602
01603 mtr_start(&mtr);
01604
01605 fsp_header_inc_size(0, sum_of_new_sizes, &mtr);
01606
01607 mtr_commit(&mtr);
01608
01609
01610
01611
01612
01613 log_buffer_flush_to_disk();
01614 }
01615
01616 #ifdef UNIV_LOG_ARCHIVE
01617
01618 if (!srv_log_archive_on) {
01619 ut_a(DB_SUCCESS == log_archive_noarchivelog());
01620 } else {
01621 mutex_enter(&(log_sys->mutex));
01622
01623 start_archive = FALSE;
01624
01625 if (log_sys->archiving_state == LOG_ARCH_OFF) {
01626 start_archive = TRUE;
01627 }
01628
01629 mutex_exit(&(log_sys->mutex));
01630
01631 if (start_archive) {
01632 ut_a(DB_SUCCESS == log_archive_archivelog());
01633 }
01634 }
01635 #endif
01636
01637
01638
01639
01640 if (trx_doublewrite == NULL) {
01641
01642
01643 trx_sys_create_doublewrite_buf();
01644 }
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659 trx_sys_create_rsegs(TRX_SYS_N_RSEGS - 1);
01660
01661
01662 os_thread_create(&srv_lock_timeout_thread, NULL,
01663 thread_ids + 2 + SRV_MAX_N_IO_THREADS);
01664
01665
01666 os_thread_create(&srv_error_monitor_thread, NULL,
01667 thread_ids + 3 + SRV_MAX_N_IO_THREADS);
01668
01669
01670 os_thread_create(&srv_monitor_thread, NULL,
01671 thread_ids + 4 + SRV_MAX_N_IO_THREADS);
01672
01673
01674 os_thread_create(&srv_LRU_dump_restore_thread, NULL,
01675 thread_ids + 5 + SRV_MAX_N_IO_THREADS);
01676
01677 srv_is_being_started = FALSE;
01678
01679 err = dict_create_or_check_foreign_constraint_tables();
01680
01681 if (err != DB_SUCCESS) {
01682 return((int)DB_ERROR);
01683 }
01684
01685
01686
01687
01688 os_thread_create(&srv_master_thread, NULL, thread_ids
01689 + (1 + SRV_MAX_N_IO_THREADS));
01690
01691
01692 ut_a(srv_n_purge_threads == 0 || srv_n_purge_threads == 1);
01693
01694
01695
01696 if (srv_n_purge_threads == 1) {
01697 os_thread_create(&srv_purge_thread, NULL, NULL);
01698 }
01699
01700 #ifdef UNIV_DEBUG
01701
01702 #endif
01703 sum_of_data_file_sizes = 0;
01704
01705 for (i = 0; i < srv_n_data_files; i++) {
01706 sum_of_data_file_sizes += srv_data_file_sizes[i];
01707 }
01708
01709 tablespace_size_in_header = fsp_header_get_tablespace_size();
01710
01711 if (!srv_auto_extend_last_data_file
01712 && sum_of_data_file_sizes != tablespace_size_in_header) {
01713
01714 drizzled::errmsg_printf(drizzled::error::ERROR,
01715 "InnoDB: Error: tablespace size stored in header is %lu pages, but the sum of data file sizes is %lu pages.",
01716 (ulong) tablespace_size_in_header,
01717 (ulong) sum_of_data_file_sizes);
01718
01719 if (srv_force_recovery == 0
01720 && sum_of_data_file_sizes < tablespace_size_in_header) {
01721
01722
01723
01724 drizzled::errmsg_printf(drizzled::error::ERROR,
01725 "InnoDB: Cannot start InnoDB. The tail of the system tablespace is "
01726 "missing. Have you edited innodb_data_file_path in my.cnf in an "
01727 "inappropriate way, removing ibdata files from there? "
01728 "You can set innodb_force_recovery=1 in my.cnf to force "
01729 "a startup if you are trying to recover a badly corrupt database.");
01730
01731 return(DB_ERROR);
01732 }
01733 }
01734
01735 if (srv_auto_extend_last_data_file
01736 && sum_of_data_file_sizes < tablespace_size_in_header) {
01737
01738 drizzled::errmsg_printf(drizzled::error::ERROR,
01739 "InnoDB: Error: tablespace size stored in header is %lu pages, but the sum of data file sizes"
01740 " is only %lu pages\n",
01741 (ulong) tablespace_size_in_header,
01742 (ulong) sum_of_data_file_sizes);
01743
01744 if (srv_force_recovery == 0) {
01745
01746 drizzled::errmsg_printf(drizzled::error::ERROR,
01747 "InnoDB: Cannot start InnoDB. The tail of the system tablespace is "
01748 "missing. Have you edited innodb_data_file_path in my.cnf in an "
01749 "inappropriate way, removing ibdata files from there? "
01750 "You can set innodb_force_recovery=1 in my.cnf to force "
01751 "a startup if you are trying to recover a badly corrupt database.\n");
01752
01753 return(DB_ERROR);
01754 }
01755 }
01756
01757
01758 os_fast_mutex_init(&srv_os_test_mutex);
01759
01760 if (0 != os_fast_mutex_trylock(&srv_os_test_mutex)) {
01761 drizzled::errmsg_printf(drizzled::error::ERROR,
01762 "InnoDB: Error: pthread_mutex_trylock returns an unexpected value on success! Cannot continue.\n");
01763 exit(1);
01764 }
01765
01766 os_fast_mutex_unlock(&srv_os_test_mutex);
01767
01768 os_fast_mutex_lock(&srv_os_test_mutex);
01769
01770 os_fast_mutex_unlock(&srv_os_test_mutex);
01771
01772 os_fast_mutex_free(&srv_os_test_mutex);
01773
01774 if (srv_print_verbose_log) {
01775 drizzled::errmsg_printf(drizzled::error::INFO,
01776 "InnoDB %s started; log sequence number %"PRIu64"\n",
01777 INNODB_VERSION_STR, srv_start_lsn);
01778 }
01779
01780 if (srv_force_recovery > 0) {
01781 drizzled::errmsg_printf(drizzled::error::ERROR,
01782 "InnoDB: !!! innodb_force_recovery is set to %lu !!!\n",
01783 (ulong) srv_force_recovery);
01784 }
01785
01786 if (trx_doublewrite_must_reset_space_ids) {
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800 drizzled::errmsg_printf(drizzled::error::INFO,
01801 "InnoDB: You are upgrading to an InnoDB version which allows multiple. "
01802 "tablespaces. Wait that purge and insert buffer merge run to completion...");
01803 for (;;) {
01804 os_thread_sleep(1000000);
01805
01806 if (0 == strcmp(srv_main_thread_op_info,
01807 "waiting for server activity")) {
01808
01809 ut_a(ibuf_is_empty());
01810
01811 break;
01812 }
01813 }
01814 drizzled::errmsg_printf(drizzled::error::INFO,
01815 "InnoDB: Full purge and insert buffer merge completed.");
01816
01817 trx_sys_mark_upgraded_to_multiple_tablespaces();
01818
01819 drizzled::errmsg_printf(drizzled::error::INFO,
01820 "InnoDB: You have now successfully upgraded"
01821 " to the multiple tablespaces\n"
01822 "InnoDB: format. You should NOT DOWNGRADE"
01823 " to an earlier version of\n"
01824 "InnoDB: InnoDB! But if you absolutely need to"
01825 " downgrade, see\n"
01826 "InnoDB: " REFMAN "multiple-tablespaces.html\n"
01827 "InnoDB: for instructions.\n");
01828 }
01829
01830 if (srv_force_recovery == 0) {
01831
01832
01833
01834
01835
01836 ibuf_update_max_tablespace_id();
01837 }
01838
01839 skip_processes:
01840 srv_file_per_table = srv_file_per_table_original_value;
01841
01842 srv_was_started = TRUE;
01843
01844 return((int) DB_SUCCESS);
01845 }
01846
01847
01850 UNIV_INTERN
01851 int
01852 innobase_shutdown_for_mysql(void)
01853
01854 {
01855 ulint i;
01856 if (!srv_was_started) {
01857 if (srv_is_being_started) {
01858 drizzled::errmsg_printf(drizzled::error::ERROR,
01859 "InnoDB: Warning: shutting down a not properly started or created database!");
01860 }
01861
01862 return(DB_SUCCESS);
01863 }
01864
01865
01866
01867
01868
01869
01870
01871 if (srv_fast_shutdown == 2) {
01872 drizzled::errmsg_printf(drizzled::error::INFO,
01873 "InnoDB: MySQL has requested a very fast shutdown without flushing "
01874 "the InnoDB buffer pool to data files. At the next mysqld startup "
01875 "InnoDB will do a crash recovery!");
01876 }
01877
01878 logs_empty_and_mark_files_at_shutdown();
01879
01880 if (srv_conc_n_threads != 0) {
01881 drizzled::errmsg_printf(drizzled::error::WARN,
01882 "InnoDB: Warning: query counter shows %ld queries still InnoDB: inside InnoDB at shutdown.",
01883 srv_conc_n_threads);
01884 }
01885
01886
01887
01888 srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS;
01889
01890
01891
01892
01893
01894 if (srv_fast_shutdown == 2) {
01895 return(DB_SUCCESS);
01896 }
01897
01898
01899
01900
01901
01902 for (i = 0; i < 1000; i++) {
01903
01904
01905
01906
01907 os_event_set(srv_lock_timeout_thread_event);
01908
01909
01910
01911
01912
01913 srv_wake_master_thread();
01914
01915
01916 srv_wake_purge_thread();
01917
01918
01919
01920 os_aio_wake_all_threads_at_shutdown();
01921
01922 os_mutex_enter(os_sync_mutex);
01923
01924 if (os_thread_count == 0) {
01925
01926
01927
01928
01929
01930
01931
01932
01933 os_mutex_exit(os_sync_mutex);
01934
01935 os_thread_sleep(100000);
01936
01937 break;
01938 }
01939
01940 os_mutex_exit(os_sync_mutex);
01941
01942 os_thread_sleep(100000);
01943 }
01944
01945 if (i == 1000) {
01946 drizzled::errmsg_printf(drizzled::error::WARN,
01947 "InnoDB: Warning: %lu threads created by InnoDB had not exited at shutdown!",
01948 (ulong) os_thread_count);
01949 }
01950
01951 if (srv_monitor_file) {
01952 fclose(srv_monitor_file);
01953 srv_monitor_file = 0;
01954 if (srv_monitor_file_name) {
01955 unlink(srv_monitor_file_name);
01956 mem_free(srv_monitor_file_name);
01957 }
01958 }
01959 if (srv_dict_tmpfile) {
01960 fclose(srv_dict_tmpfile);
01961 srv_dict_tmpfile = 0;
01962 }
01963
01964 if (srv_misc_tmpfile) {
01965 fclose(srv_misc_tmpfile);
01966 srv_misc_tmpfile = 0;
01967 }
01968
01969
01970
01971 btr_search_disable();
01972
01973 ibuf_close();
01974 log_shutdown();
01975 lock_sys_close();
01976 thr_local_close();
01977 trx_sys_file_format_close();
01978 trx_sys_close();
01979
01980 mutex_free(&srv_monitor_file_mutex);
01981 mutex_free(&srv_dict_tmpfile_mutex);
01982 mutex_free(&srv_misc_tmpfile_mutex);
01983 dict_close();
01984 btr_search_sys_free();
01985
01986
01987
01988 os_aio_free();
01989 sync_close();
01990 srv_free();
01991 fil_close();
01992
01993
01994
01995 os_sync_free();
01996
01997
01998
01999 pars_lexer_close();
02000 log_mem_free();
02001 buf_pool_free(srv_buf_pool_instances);
02002 mem_close();
02003
02004
02005
02006
02007 ut_free_all_mem();
02008
02009 if (os_thread_count != 0
02010 || os_event_count != 0
02011 || os_mutex_count != 0
02012 || os_fast_mutex_count != 0) {
02013 drizzled::errmsg_printf(drizzled::error::WARN,
02014 "InnoDB: Warning: some resources were not cleaned up in shutdown:\n"
02015 "InnoDB: threads %lu, events %lu, os_mutexes %lu, os_fast_mutexes %lu\n",
02016 (ulong) os_thread_count, (ulong) os_event_count,
02017 (ulong) os_mutex_count, (ulong) os_fast_mutex_count);
02018 }
02019
02020 if (dict_foreign_err_file) {
02021 fclose(dict_foreign_err_file);
02022 }
02023 if (lock_latest_err_file) {
02024 fclose(lock_latest_err_file);
02025 }
02026
02027 if (srv_print_verbose_log) {
02028 drizzled::errmsg_printf(drizzled::error::INFO,
02029 "InnoDB: Shutdown completed log sequence number %"PRIu64,
02030 srv_shutdown_lsn);
02031 }
02032
02033 srv_was_started = FALSE;
02034 srv_start_has_been_called = FALSE;
02035
02036 return((int) DB_SUCCESS);
02037 }
02038 #endif