diff options
Diffstat (limited to 'storage/xtradb/srv/srv0start.c')
-rw-r--r-- | storage/xtradb/srv/srv0start.c | 250 |
1 files changed, 196 insertions, 54 deletions
diff --git a/storage/xtradb/srv/srv0start.c b/storage/xtradb/srv/srv0start.c index dcc13ea17b6..7b5581a24f0 100644 --- a/storage/xtradb/srv/srv0start.c +++ b/storage/xtradb/srv/srv0start.c @@ -1,7 +1,8 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved. Copyright (c) 2008, Google Inc. +Copyright (c) 2009, Percona Inc. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -9,6 +10,13 @@ briefly in the InnoDB documentation. The contributions by Google are incorporated with their permission, and subject to the conditions contained in the file COPYING.Google. +Portions of this file contain modifications contributed and copyrighted +by Percona Inc.. Those modifications are +gratefully acknowledged and are described briefly in the InnoDB +documentation. The contributions by Percona Inc. are incorporated with +their permission, and subject to the conditions contained in the file +COPYING.Percona. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. @@ -22,32 +30,6 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *****************************************************************************/ -/*********************************************************************** - -Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved. -Copyright (c) 2009, Percona Inc. - -Portions of this file contain modifications contributed and copyrighted -by Percona Inc.. Those modifications are -gratefully acknowledged and are described briefly in the InnoDB -documentation. The contributions by Percona Inc. are incorporated with -their permission, and subject to the conditions contained in the file -COPYING.Percona. - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -***********************************************************************/ /********************************************************************//** @file srv/srv0start.c @@ -105,6 +87,7 @@ Created 2/16/1996 Heikki Tuuri # include "btr0pcur.h" # include "thr0loc.h" # include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */ +# include "zlib.h" /* for ZLIB_VERSION */ /** Log sequence number immediately after startup */ UNIV_INTERN ib_uint64_t srv_start_lsn; @@ -143,9 +126,9 @@ static mutex_t ios_mutex; static ulint ios; /** io_handler_thread parameters for thread identification */ -static ulint n[SRV_MAX_N_IO_THREADS + 5 + 64]; +static ulint n[SRV_MAX_N_IO_THREADS + 6 + 64]; /** io_handler_thread identifiers */ -static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 5 + 64]; +static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6 + 64]; /** We use this mutex to test the return value of pthread_mutex_trylock on successful locking. HP-UX does NOT return 0, though Linux et al do. */ @@ -728,6 +711,7 @@ open_or_create_data_files( /*======================*/ ibool* create_new_db, /*!< out: TRUE if new database should be created */ + ibool* create_new_doublewrite_file, #ifdef UNIV_LOG_ARCHIVE ulint* min_arch_log_no,/*!< out: min of archived log numbers in data files */ @@ -760,6 +744,7 @@ open_or_create_data_files( *sum_of_new_sizes = 0; *create_new_db = FALSE; + *create_new_doublewrite_file = FALSE; srv_normalize_path_for_win(srv_data_home); @@ -992,6 +977,142 @@ skip_size_check: srv_data_file_is_raw_partition[i] != 0); } + /* special file for doublewrite buffer */ + if (srv_doublewrite_file) + { + srv_normalize_path_for_win(srv_doublewrite_file); + + fprintf(stderr, + "InnoDB: Notice: innodb_doublewrite_file is specified.\n" + "InnoDB: This is for expert only. Don't use if you don't understand what is it 'WELL'.\n" + "InnoDB: ### Don't specify older file than the last checkpoint ###\n" + "InnoDB: otherwise the older doublewrite buffer will break your data during recovery!\n"); + + strcpy(name, srv_doublewrite_file); + + /* First we try to create the file: if it already + exists, ret will get value FALSE */ + + files[i] = os_file_create(name, OS_FILE_CREATE, + OS_FILE_NORMAL, + OS_DATA_FILE, &ret); + + if (ret == FALSE && os_file_get_last_error(FALSE) + != OS_FILE_ALREADY_EXISTS +#ifdef UNIV_AIX + /* AIX 5.1 after security patch ML7 may have + errno set to 0 here, which causes our function + to return 100; work around that AIX problem */ + && os_file_get_last_error(FALSE) != 100 +#endif + ) { + fprintf(stderr, + "InnoDB: Error in creating" + " or opening %s\n", + name); + + return(DB_ERROR); + } + + if (ret == FALSE) { + /* We open the data file */ + + files[i] = os_file_create( + name, OS_FILE_OPEN, OS_FILE_NORMAL, + OS_DATA_FILE, &ret); + + if (!ret) { + fprintf(stderr, + "InnoDB: Error in opening %s\n", name); + os_file_get_last_error(TRUE); + + return(DB_ERROR); + } + + ret = os_file_get_size(files[i], &size, &size_high); + ut_a(ret); + /* Round size downward to megabytes */ + + rounded_size_pages + = (size / (1024 * 1024) + 4096 * size_high) + << (20 - UNIV_PAGE_SIZE_SHIFT); + + if (rounded_size_pages != TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 9) { + + fprintf(stderr, + "InnoDB: Warning: doublewrite buffer file %s" + " is of a different size\n" + "InnoDB: %lu pages" + " (rounded down to MB)\n" + "InnoDB: than intended size" + " %lu pages...\n", + name, + (ulong) rounded_size_pages, + (ulong) TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 9); + } + + fil_read_flushed_lsn_and_arch_log_no( + files[i], one_opened, +#ifdef UNIV_LOG_ARCHIVE + min_arch_log_no, max_arch_log_no, +#endif /* UNIV_LOG_ARCHIVE */ + min_flushed_lsn, max_flushed_lsn); + one_opened = TRUE; + } else { + /* We created the data file and now write it full of + zeros */ + + *create_new_doublewrite_file = TRUE; + + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Doublewrite buffer file %s did not" + " exist: new to be created\n", + name); + + if (*create_new_db == FALSE) { + fprintf(stderr, + "InnoDB: Warning: Previous version's ibdata files may cause crash.\n" + " If you use that, please use the ibdata files of this version.\n"); + } + + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Setting file %s size to %lu MB\n", + name, + (ulong) ((TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 9) + >> (20 - UNIV_PAGE_SIZE_SHIFT))); + + fprintf(stderr, + "InnoDB: Database physically writes the" + " file full: wait...\n"); + + ret = os_file_set_size( + name, files[i], + srv_calc_low32(TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 9), + srv_calc_high32(TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 9)); + + if (!ret) { + fprintf(stderr, + "InnoDB: Error in creating %s:" + " probably out of disk space\n", name); + + return(DB_ERROR); + } + } + + ret = os_file_close(files[i]); + ut_a(ret); + + fil_space_create(name, TRX_DOUBLEWRITE_SPACE, 0, FIL_TABLESPACE); + + ut_a(fil_validate()); + + fil_node_create(name, TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 9, TRX_DOUBLEWRITE_SPACE, FALSE); + + i++; + } + ios = 0; mutex_create(&ios_mutex, SYNC_NO_ORDER_CHECK); @@ -1010,6 +1131,7 @@ innobase_start_or_create_for_mysql(void) { buf_pool_t* ret; ibool create_new_db; + ibool create_new_doublewrite_file; ibool log_file_created; ibool log_created = FALSE; ibool log_opened = FALSE; @@ -1074,7 +1196,11 @@ innobase_start_or_create_for_mysql(void) #ifdef UNIV_IBUF_DEBUG fprintf(stderr, "InnoDB: !!!!!!!! UNIV_IBUF_DEBUG switched on !!!!!!!!!\n" - "InnoDB: Crash recovery will fail with UNIV_IBUF_DEBUG\n"); +# ifdef UNIV_IBUF_COUNT_DEBUG + "InnoDB: !!!!!!!! UNIV_IBUF_COUNT_DEBUG switched on !!!!!!!!!\n" + "InnoDB: Crash recovery will fail with UNIV_IBUF_COUNT_DEBUG\n" +# endif + ); #endif #ifdef UNIV_SYNC_DEBUG @@ -1101,7 +1227,15 @@ innobase_start_or_create_for_mysql(void) "InnoDB: The InnoDB memory heap is disabled\n"); } - fprintf(stderr, "InnoDB: %s\n", IB_ATOMICS_STARTUP_MSG); + fputs("InnoDB: " IB_ATOMICS_STARTUP_MSG + "\nInnoDB: Compressed tables use zlib " ZLIB_VERSION +#ifdef UNIV_ZIP_DEBUG + " with validation" +#endif /* UNIV_ZIP_DEBUG */ +#ifdef UNIV_ZIP_COPY + " and extra copying" +#endif /* UNIV_ZIP_COPY */ + "\n" , stderr); /* Since InnoDB does not currently clean up all its internal data structures in MySQL Embedded Server Library server_end(), we @@ -1388,6 +1522,7 @@ innobase_start_or_create_for_mysql(void) } err = open_or_create_data_files(&create_new_db, + &create_new_doublewrite_file, #ifdef UNIV_LOG_ARCHIVE &min_arch_log_no, &max_arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ @@ -1504,6 +1639,14 @@ innobase_start_or_create_for_mysql(void) trx_sys_file_format_init(); + if (create_new_doublewrite_file) { + mtr_start(&mtr); + fsp_header_init(TRX_DOUBLEWRITE_SPACE, TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 9, &mtr); + mtr_commit(&mtr); + + trx_sys_dummy_create(TRX_DOUBLEWRITE_SPACE); + } + if (create_new_db) { mtr_start(&mtr); fsp_header_init(0, sum_of_new_sizes, &mtr); @@ -1596,6 +1739,14 @@ innobase_start_or_create_for_mysql(void) dict_boot(); trx_sys_init_at_db_start(); + /* Initialize the fsp free limit global variable in the log + system */ + fsp_header_get_free_limit(); + + /* recv_recovery_from_checkpoint_finish needs trx lists which + are initialized in trx_sys_init_at_db_start(). */ + + recv_recovery_from_checkpoint_finish(); if (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE) { /* The following call is necessary for the insert buffer to work with multiple tablespaces. We must @@ -1611,26 +1762,14 @@ innobase_start_or_create_for_mysql(void) every table in the InnoDB data dictionary that has an .ibd file. - We also determine the maximum tablespace id used. - - TODO: We may have incomplete transactions in the - data dictionary tables. Does that harm the scanning of - the data dictionary below? */ + We also determine the maximum tablespace id used. */ dict_check_tablespaces_and_store_max_id( recv_needed_recovery); } srv_startup_is_before_trx_rollback_phase = FALSE; - - /* Initialize the fsp free limit global variable in the log - system */ - fsp_header_get_free_limit(); - - /* recv_recovery_from_checkpoint_finish needs trx lists which - are initialized in trx_sys_init_at_db_start(). */ - - recv_recovery_from_checkpoint_finish(); + recv_recovery_rollback_active(); /* It is possible that file_format tag has never been set. In this case we initialize it to minimum @@ -1679,15 +1818,18 @@ innobase_start_or_create_for_mysql(void) /* fprintf(stderr, "Max allowed record size %lu\n", page_get_free_space_of_empty() / 2); */ - /* Create the thread which watches the timeouts for lock waits - and prints InnoDB monitor info */ - - os_thread_create(&srv_lock_timeout_and_monitor_thread, NULL, + /* Create the thread which watches the timeouts for lock waits */ + os_thread_create(&srv_lock_timeout_thread, NULL, thread_ids + 2 + SRV_MAX_N_IO_THREADS); /* Create the thread which warns of long semaphore waits */ os_thread_create(&srv_error_monitor_thread, NULL, thread_ids + 3 + SRV_MAX_N_IO_THREADS); + + /* Create the thread which prints InnoDB monitor info */ + os_thread_create(&srv_monitor_thread, NULL, + thread_ids + 4 + SRV_MAX_N_IO_THREADS); + srv_is_being_started = FALSE; if (trx_doublewrite == NULL) { @@ -1712,13 +1854,13 @@ innobase_start_or_create_for_mysql(void) ulint i; os_thread_create(&srv_purge_thread, NULL, thread_ids - + (4 + SRV_MAX_N_IO_THREADS)); + + (5 + SRV_MAX_N_IO_THREADS)); for (i = 0; i < srv_use_purge_thread - 1; i++) { - n[5 + i + SRV_MAX_N_IO_THREADS] = i; /* using as index for arrays in purge_sys */ + n[6 + i + SRV_MAX_N_IO_THREADS] = i; /* using as index for arrays in purge_sys */ os_thread_create(&srv_purge_worker_thread, - n + (5 + i + SRV_MAX_N_IO_THREADS), - thread_ids + (5 + i + SRV_MAX_N_IO_THREADS)); + n + (6 + i + SRV_MAX_N_IO_THREADS), + thread_ids + (6 + i + SRV_MAX_N_IO_THREADS)); } } #ifdef UNIV_DEBUG @@ -1821,7 +1963,7 @@ innobase_start_or_create_for_mysql(void) if (srv_print_verbose_log) { ut_print_timestamp(stderr); fprintf(stderr, - " InnoDB Plugin %s started; " + " Percona XtraDB (http://www.percona.com) %s started; " "log sequence number %llu\n", INNODB_VERSION_STR, srv_start_lsn); } |