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