From de5646f1a9aaf45f1b43d98623b40c95fb98ebce Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sat, 22 Oct 2016 14:10:12 +0000 Subject: [PATCH] Prepare XtraDB to be used with xtrabackup. The changes are deliberately kept minimal - some functions are made global instead of static (they will be used in xtrabackup later on) - functions got additional parameter, deliberately unused for now : fil_load_single_tablespaces srv_undo_tablespaces_init - Global variables added, also unused for now : srv_archive_recovery srv_archive_recovery_limit_lsn srv_apply_log_only srv_backup_mode srv_close_files - To make xtrabackup link with sql.lib on Windows, added some missing source files to sql.lib - Fixed os_thread_ret_t to be DWORD on Windows --- sql/CMakeLists.txt | 9 ++- storage/xtradb/btr/btr0btr.cc | 4 +- storage/xtradb/fil/fil0fil.cc | 5 +- storage/xtradb/handler/ha_innodb.cc | 6 +- storage/xtradb/include/fil0fil.h | 2 +- storage/xtradb/include/srv0srv.h | 7 ++ storage/xtradb/include/univ.i | 2 +- storage/xtradb/log/log0recv.cc | 99 ++++++++++++++++++++++++++++- storage/xtradb/os/os0file.cc | 1 - storage/xtradb/srv/srv0srv.cc | 7 ++ storage/xtradb/srv/srv0start.cc | 10 ++- 11 files changed, 135 insertions(+), 17 deletions(-) diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index ec7e9207f38..1cc83ea2bf1 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -77,6 +77,12 @@ IF(SSL_DEFINES) ADD_DEFINITIONS(${SSL_DEFINES}) ENDIF() +IF(WIN32) + SET(NT_SERVICE_SOURCES nt_servc.cc nt_servc.h ) +ELSE() + SET(NT_SERVICE_SOURCES) +ENDIF() + SET (SQL_SOURCE ../sql-common/client.c compat56.cc derror.cc des_key_file.cc discover.cc ../libmysql/errmsg.c field.cc field_conv.cc @@ -143,6 +149,7 @@ SET (SQL_SOURCE ${GEN_SOURCES} ${GEN_DIGEST_SOURCES} ${MYSYS_LIBWRAP_SOURCE} + ${NT_SERVICE_SOURCES} ) IF (CMAKE_SYSTEM_NAME MATCHES "Linux" OR @@ -172,7 +179,7 @@ TARGET_LINK_LIBRARIES(sql ${MYSQLD_STATIC_PLUGIN_LIBS} ${LIBSYSTEMD}) IF(WIN32) - SET(MYSQLD_SOURCE main.cc nt_servc.cc nt_servc.h message.rc) + SET(MYSQLD_SOURCE main.cc message.rc) TARGET_LINK_LIBRARIES(sql psapi) ELSE() SET(MYSQLD_SOURCE main.cc ${DTRACE_PROBES_ALL}) diff --git a/storage/xtradb/btr/btr0btr.cc b/storage/xtradb/btr/btr0btr.cc index bce81f95ead..bf6d850f3f0 100644 --- a/storage/xtradb/btr/btr0btr.cc +++ b/storage/xtradb/btr/btr0btr.cc @@ -722,7 +722,7 @@ btr_root_fseg_validate( /**************************************************************//** Gets the root node of a tree and x- or s-latches it. @return root page, x- or s-latched */ -static + buf_block_t* btr_root_block_get( /*===============*/ @@ -1531,7 +1531,7 @@ btr_node_ptr_set_child_page_no( /************************************************************//** Returns the child page of a node pointer and x-latches it. @return child page, x-latched */ -static + buf_block_t* btr_node_ptr_get_child( /*===================*/ diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index 93df92e6e63..ff1416fb160 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -379,7 +379,6 @@ fil_node_get_space_id( /*******************************************************************//** Returns the table space by a given name, NULL if not found. */ -UNIV_INLINE fil_space_t* fil_space_get_by_name( /*==================*/ @@ -4785,7 +4784,7 @@ directory. We retry 100 times if os_file_readdir_next_file() returns -1. The idea is to read as much good data as we can and jump over bad data. @return 0 if ok, -1 if error even after the retries, 1 if at the end of the directory */ -static + int fil_file_readdir_next_file( /*=======================*/ @@ -4826,7 +4825,7 @@ space id is != 0. @return DB_SUCCESS or error number */ UNIV_INTERN dberr_t -fil_load_single_table_tablespaces(void) +fil_load_single_table_tablespaces(ibool (*pred)(const char*, const char*)) /*===================================*/ { int ret; diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 320b900d019..a7c68ddf8c9 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -284,7 +284,7 @@ static TYPELIB innodb_stats_method_typelib = { /** Possible values for system variables "innodb_checksum_algorithm" and "innodb_log_checksum_algorithm". */ -static const char* innodb_checksum_algorithm_names[] = { +const char* innodb_checksum_algorithm_names[] = { "CRC32", "STRICT_CRC32", "INNODB", @@ -296,7 +296,7 @@ static const char* innodb_checksum_algorithm_names[] = { /** Used to define an enumerate type of the system variables innodb_checksum_algorithm and innodb_log_checksum_algorithm. */ -static TYPELIB innodb_checksum_algorithm_typelib = { +TYPELIB innodb_checksum_algorithm_typelib = { array_elements(innodb_checksum_algorithm_names) - 1, "innodb_checksum_algorithm_typelib", innodb_checksum_algorithm_names, @@ -3016,7 +3016,7 @@ trx_is_started( /****************************************************************//** Update log_checksum_algorithm_ptr with a pointer to the function corresponding to a given checksum algorithm. */ -static + void innodb_log_checksum_func_update( /*============================*/ diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h index 95011ae6125..476a5c69e54 100644 --- a/storage/xtradb/include/fil0fil.h +++ b/storage/xtradb/include/fil0fil.h @@ -868,7 +868,7 @@ space id is != 0. @return DB_SUCCESS or error number */ UNIV_INTERN dberr_t -fil_load_single_table_tablespaces(void); +fil_load_single_table_tablespaces(ibool (*pred)(const char*, const char*)=0); /*===================================*/ /*******************************************************************//** Returns TRUE if a single-table tablespace does not exist in the memory cache, diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h index f60cfde1264..92482529763 100644 --- a/storage/xtradb/include/srv0srv.h +++ b/storage/xtradb/include/srv0srv.h @@ -489,6 +489,8 @@ extern ulong srv_innodb_stats_method; #ifdef UNIV_LOG_ARCHIVE extern ibool srv_log_archive_on; +extern ibool srv_archive_recovery; +extern ib_uint64_t srv_archive_recovery_limit_lsn; #endif /* UNIV_LOG_ARCHIVE */ extern char* srv_file_flush_method_str; @@ -541,6 +543,11 @@ extern ulong srv_pass_corrupt_table; extern ulong srv_log_checksum_algorithm; +extern ibool srv_apply_log_only; + +extern ibool srv_backup_mode; +extern ibool srv_close_files; + extern my_bool srv_force_primary_key; /* Helper macro to support srv_pass_corrupt_table checks. If 'cond' is FALSE, diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index a42b8b8bc25..556aba62658 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -647,7 +647,7 @@ functions. */ #ifdef __WIN__ #define usleep(a) Sleep((a)/1000) -typedef ulint os_thread_ret_t; +typedef DWORD os_thread_ret_t; #define OS_THREAD_DUMMY_RETURN return(0) #else typedef void* os_thread_ret_t; diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc index 092c2ed88dc..35558b6f9f2 100644 --- a/storage/xtradb/log/log0recv.cc +++ b/storage/xtradb/log/log0recv.cc @@ -713,7 +713,6 @@ recv_synchronize_groups( /***********************************************************************//** Checks the consistency of the checkpoint info @return TRUE if ok */ -static ibool recv_check_cp_is_consistent( /*========================*/ @@ -743,7 +742,7 @@ recv_check_cp_is_consistent( /********************************************************//** Looks for the maximum consistent checkpoint from the log groups. @return error code or DB_SUCCESS */ -static MY_ATTRIBUTE((nonnull, warn_unused_result)) +MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t recv_find_max_checkpoint( /*=====================*/ @@ -3784,6 +3783,102 @@ recv_reset_log_files_for_backup( } #endif /* UNIV_HOTBACKUP */ +/******************************************************//** +Checks the 4-byte checksum to the trailer checksum field of a log +block. We also accept a log block in the old format before +InnoDB-3.23.52 where the checksum field contains the log block number. +@return TRUE if ok, or if the log block may be in the format of InnoDB +version predating 3.23.52 */ +UNIV_INTERN +ibool +log_block_checksum_is_ok_or_old_format( +/*===================================*/ + const byte* block) /*!< in: pointer to a log block */ +{ +#ifdef UNIV_LOG_DEBUG + return(TRUE); +#endif /* UNIV_LOG_DEBUG */ + + ulint block_checksum = log_block_get_checksum(block); + + if (UNIV_LIKELY(srv_log_checksum_algorithm == + SRV_CHECKSUM_ALGORITHM_NONE || + log_block_calc_checksum(block) == block_checksum)) { + + return(TRUE); + } + + if (srv_log_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32 || + srv_log_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB || + srv_log_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_NONE) { + + const char* algo = NULL; + + ib_logf(IB_LOG_LEVEL_ERROR, + "log block checksum mismatch: expected " ULINTPF ", " + "calculated checksum " ULINTPF, + block_checksum, + log_block_calc_checksum(block)); + + if (block_checksum == LOG_NO_CHECKSUM_MAGIC) { + + algo = "none"; + } else if (block_checksum == + log_block_calc_checksum_crc32(block)) { + + algo = "crc32"; + } else if (block_checksum == + log_block_calc_checksum_innodb(block)) { + + algo = "innodb"; + } + + if (algo) { + + const char* current_algo; + + current_algo = buf_checksum_algorithm_name( + (srv_checksum_algorithm_t) + srv_log_checksum_algorithm); + + ib_logf(IB_LOG_LEVEL_ERROR, + "current InnoDB log checksum type: %s, " + "detected log checksum type: %s", + current_algo, + algo); + } + + ib_logf(IB_LOG_LEVEL_FATAL, + "STRICT method was specified for innodb_log_checksum, " + "so we intentionally assert here."); + } + + ut_ad(srv_log_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_CRC32 || + srv_log_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_INNODB); + + if (block_checksum == LOG_NO_CHECKSUM_MAGIC || + block_checksum == log_block_calc_checksum_crc32(block) || + block_checksum == log_block_calc_checksum_innodb(block)) { + + return(TRUE); + } + + if (log_block_get_hdr_no(block) == block_checksum) { + + /* We assume the log block is in the format of + InnoDB version < 3.23.52 and the block is ok */ +#if 0 + fprintf(stderr, + "InnoDB: Scanned old format < InnoDB-3.23.52" + " log block number %lu\n", + log_block_get_hdr_no(block)); +#endif + return(TRUE); + } + + return(FALSE); +} + void recv_dblwr_t::add(byte* page) { pages.push_back(page); diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index 007b100285d..e8f4bfc8c24 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -1010,7 +1010,6 @@ os_file_lock( #ifndef UNIV_HOTBACKUP /****************************************************************//** Creates the seek mutexes used in positioned reads and writes. */ -static void os_io_init_simple(void) /*===================*/ diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc index f9c75ffe576..1a7f67e562e 100644 --- a/storage/xtradb/srv/srv0srv.cc +++ b/storage/xtradb/srv/srv0srv.cc @@ -375,6 +375,8 @@ UNIV_INTERN ulong srv_read_ahead_threshold = 56; #ifdef UNIV_LOG_ARCHIVE UNIV_INTERN ibool srv_log_archive_on = FALSE; +UNIV_INTERN ibool srv_archive_recovery = 0; +UNIV_INTERN ib_uint64_t srv_archive_recovery_limit_lsn; #endif /* UNIV_LOG_ARCHIVE */ /* This parameter is used to throttle the number of insert buffers that are @@ -534,6 +536,11 @@ UNIV_INTERN ulong srv_doublewrite_batch_size = 120; UNIV_INTERN ulong srv_replication_delay = 0; +UNIV_INTERN ibool srv_apply_log_only = FALSE; + +UNIV_INTERN ibool srv_backup_mode = FALSE; +UNIV_INTERN ibool srv_close_files = TRUE; + UNIV_INTERN ulong srv_pass_corrupt_table = 0; /* 0:disable 1:enable */ UNIV_INTERN ulong srv_log_checksum_algorithm = diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc index 6b1e8c39b38..6381b5b837f 100644 --- a/storage/xtradb/srv/srv0start.cc +++ b/storage/xtradb/srv/srv0start.cc @@ -136,7 +136,7 @@ SRV_SHUTDOWN_CLEANUP and then to SRV_SHUTDOWN_LAST_PHASE, and so on */ UNIV_INTERN enum srv_shutdown_state srv_shutdown_state = SRV_SHUTDOWN_NONE; /** Files comprising the system tablespace */ -static os_file_t files[1000]; +os_file_t files[1000]; /** io_handler_thread parameters for thread identification */ static ulint n[SRV_MAX_N_IO_THREADS]; @@ -826,7 +826,7 @@ open_log_file( /*********************************************************************//** Creates or opens database data files and closes them. @return DB_SUCCESS or error code */ -static MY_ATTRIBUTE((nonnull, warn_unused_result)) +MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t open_or_create_data_files( /*======================*/ @@ -1367,12 +1367,15 @@ srv_undo_tablespace_open( /******************************************************************** Opens the configured number of undo tablespaces. @return DB_SUCCESS or error code */ -static dberr_t srv_undo_tablespaces_init( /*======================*/ ibool create_new_db, /*!< in: TRUE if new db being created */ + ibool backup_mode, /*!< in: TRUE disables reading + the system tablespace (used in + XtraBackup), FALSE is passed on + recovery. */ const ulint n_conf_tablespaces, /*!< in: configured undo tablespaces */ ulint* n_opened) /*!< out: number of UNDO @@ -2415,6 +2418,7 @@ files_checked: err = srv_undo_tablespaces_init( create_new_db, + FALSE, srv_undo_tablespaces, &srv_undo_tablespaces_open);