MDEV-9566 Prepare xtradb for xtrabackup
These changes are comparable to Percona's modifications in innodb in the Percona Xtrabackup repository. - If functions are used in backup as well as in innodb, make them non-static. - Define IS_XTRABACKUP() macro for special handling of innodb running inside backup. - Extend some functions for backup. fil_space_for_table_exists_in_mem() gets additional parameter 'remove_from_data_dict_if_does_not_exist', for partial backups fil_load_single_table_tablespaces() gets an optional parameter predicate which tells whether to load tablespace based on database or table name, also for partial backups. srv_undo_tablespaces_init() gets an optional parameter 'backup_mode' - Allow single redo log file (for backup "prepare") - Do not read doublewrite buffer pages in backup, they are outdated - Add function fil_remove_invalid_table_from_data_dict(), to remove non-existing tables from data dictionary in case of partial backups. - On Windows, fix file share modes when opening tablespaces, to allow mariabackup to read tablespaces while server is online. - Avoid access to THDVARs in backup, because innodb plugin is not loaded, and THDVAR would crash in this case.
This commit is contained in:
parent
f06ab0fc99
commit
9c4b7cad27
@ -722,7 +722,6 @@ 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 +1530,6 @@ 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(
|
||||
/*===================*/
|
||||
|
@ -2864,7 +2864,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
|
||||
success = buf_flush_list(PCT_IO(100), LSN_MAX, &n_flushed);
|
||||
buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
|
||||
|
||||
} while (!success || n_flushed > 0);
|
||||
} while (!success || n_flushed > 0 || (IS_XTRABACKUP() && buf_get_n_pending_read_ios() > 0));
|
||||
|
||||
/* Some sanity checks */
|
||||
ut_a(srv_get_active_thread_type() == SRV_NONE);
|
||||
|
@ -955,11 +955,8 @@ buf_read_ibuf_merge_pages(
|
||||
|
||||
tablespace_deleted:
|
||||
/* We have deleted or are deleting the single-table
|
||||
tablespace: remove the entries for that page */
|
||||
|
||||
ibuf_merge_or_delete_for_page(NULL, space_ids[i],
|
||||
page_nos[i],
|
||||
zip_size, FALSE);
|
||||
tablespace: remove the entries for tablespace. */
|
||||
ibuf_delete_for_discarded_space(space_ids[i]);
|
||||
break;
|
||||
case DB_DECRYPTION_FAILED:
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
|
@ -945,6 +945,10 @@ dict_insert_tablespace_and_filepath(
|
||||
return(err);
|
||||
}
|
||||
|
||||
/* Set by Xtrabackup */
|
||||
my_bool (*dict_check_if_skip_table)(const char* name) = 0;
|
||||
|
||||
|
||||
/********************************************************************//**
|
||||
This function looks at each table defined in SYS_TABLES. It checks the
|
||||
tablespace for any table with a space_id > 0. It looks up the tablespace
|
||||
@ -1064,6 +1068,9 @@ loop:
|
||||
|
||||
bool is_temp = false;
|
||||
bool discarded = false;
|
||||
bool print_error_if_does_not_exist;
|
||||
bool remove_from_data_dict_if_does_not_exist;
|
||||
|
||||
ib_uint32_t flags2 = static_cast<ib_uint32_t>(
|
||||
mach_read_from_4(field));
|
||||
|
||||
@ -1089,6 +1096,19 @@ loop:
|
||||
goto loop;
|
||||
}
|
||||
|
||||
|
||||
ut_a(!IS_XTRABACKUP() || dict_check_if_skip_table);
|
||||
|
||||
if (is_temp || discarded ||
|
||||
(IS_XTRABACKUP() && dict_check_if_skip_table(name))) {
|
||||
print_error_if_does_not_exist = false;
|
||||
}
|
||||
else {
|
||||
print_error_if_does_not_exist = true;
|
||||
}
|
||||
|
||||
remove_from_data_dict_if_does_not_exist = IS_XTRABACKUP() && !(is_temp || discarded);
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
switch (dict_check) {
|
||||
@ -1096,8 +1116,8 @@ loop:
|
||||
/* All tablespaces should have been found in
|
||||
fil_load_single_table_tablespaces(). */
|
||||
if (fil_space_for_table_exists_in_mem(
|
||||
space_id, name, !(is_temp || discarded),
|
||||
false, NULL, 0, flags)
|
||||
space_id, name, print_error_if_does_not_exist,
|
||||
remove_from_data_dict_if_does_not_exist , false, NULL, 0, flags)
|
||||
&& !(is_temp || discarded)) {
|
||||
/* If user changes the path of .ibd files in
|
||||
*.isl files before doing crash recovery ,
|
||||
@ -1130,7 +1150,7 @@ loop:
|
||||
trx_resurrect_table_locks(). */
|
||||
if (fil_space_for_table_exists_in_mem(
|
||||
space_id, name, false,
|
||||
false, NULL, 0, flags)) {
|
||||
false, false, NULL, 0, flags)) {
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
@ -2383,7 +2403,7 @@ err_exit:
|
||||
table->file_unreadable = true;
|
||||
|
||||
} else if (!fil_space_for_table_exists_in_mem(
|
||||
table->space, name, false, true, heap,
|
||||
table->space, name, false, IS_XTRABACKUP(), true, heap,
|
||||
table->id, table->flags)) {
|
||||
|
||||
if (DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY)) {
|
||||
|
@ -67,6 +67,7 @@ static ulint srv_data_read, srv_data_written;
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#include "row0mysql.h"
|
||||
#include "trx0purge.h"
|
||||
|
||||
MYSQL_PLUGIN_IMPORT extern my_bool lower_case_file_system;
|
||||
|
||||
@ -369,7 +370,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(
|
||||
/*==================*/
|
||||
@ -1574,12 +1574,13 @@ fil_space_create(
|
||||
|
||||
if (!fil_system->space_id_reuse_warned) {
|
||||
fil_system->space_id_reuse_warned = TRUE;
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_WARN,
|
||||
"Allocated tablespace %lu, old maximum "
|
||||
"was %lu",
|
||||
(ulong) id,
|
||||
(ulong) fil_system->max_assigned_id);
|
||||
if (!IS_XTRABACKUP()) {
|
||||
ib_logf(IB_LOG_LEVEL_WARN,
|
||||
"Allocated tablespace %lu, old maximum "
|
||||
"was %lu",
|
||||
(ulong)id,
|
||||
(ulong)fil_system->max_assigned_id);
|
||||
}
|
||||
}
|
||||
|
||||
fil_system->max_assigned_id = id;
|
||||
@ -2413,6 +2414,19 @@ fil_read_first_page(
|
||||
const char* check_msg = NULL;
|
||||
fil_space_crypt_t* cdata;
|
||||
|
||||
if (IS_XTRABACKUP() && srv_backup_mode) {
|
||||
/* Files smaller than page size may occur
|
||||
in xtrabackup, when server creates new file
|
||||
but has not yet written into it, or wrote only
|
||||
partially. Checks size here, to avoid exit in os_file_read.
|
||||
This file will be skipped by xtrabackup if it is too small.
|
||||
*/
|
||||
os_offset_t file_size;
|
||||
file_size = os_file_get_size(data_file);
|
||||
if (file_size < FIL_IBD_FILE_INITIAL_SIZE*UNIV_PAGE_SIZE) {
|
||||
return "File size is less than minimum";
|
||||
}
|
||||
}
|
||||
buf = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE));
|
||||
|
||||
/* Align the memory for a possible read from a raw device */
|
||||
@ -2443,7 +2457,9 @@ fil_read_first_page(
|
||||
}
|
||||
}
|
||||
|
||||
check_msg = fil_check_first_page(page, *space_id, *flags);
|
||||
if (!(IS_XTRABACKUP() && srv_backup_mode)) {
|
||||
check_msg = fil_check_first_page(page, *space_id, *flags);
|
||||
}
|
||||
}
|
||||
|
||||
flushed_lsn = mach_read_from_8(page +
|
||||
@ -3137,7 +3153,7 @@ fil_delete_tablespace(
|
||||
err = DB_IO_ERROR;
|
||||
}
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
if (err == DB_SUCCESS && !IS_XTRABACKUP()) {
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/* Write a log record about the deletion of the .ibd
|
||||
file, so that mysqlbackup can replay it in the
|
||||
@ -3536,7 +3552,7 @@ skip_second_rename:
|
||||
mutex_exit(&fil_system->mutex);
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
if (success && !recv_recovery_on) {
|
||||
if (success && !recv_recovery_on && !IS_XTRABACKUP()) {
|
||||
mtr_t mtr;
|
||||
|
||||
mtr_start(&mtr);
|
||||
@ -3782,7 +3798,18 @@ fil_create_new_single_table_tablespace(
|
||||
ibool success;
|
||||
/* TRUE if a table is created with CREATE TEMPORARY TABLE */
|
||||
bool is_temp = !!(flags2 & DICT_TF2_TEMPORARY);
|
||||
bool has_data_dir = FSP_FLAGS_HAS_DATA_DIR(flags) != 0;
|
||||
|
||||
|
||||
/* For XtraBackup recovery we force remote tablespaces to be local,
|
||||
i.e. never execute the code path corresponding to has_data_dir == true.
|
||||
We don't create .isl files either, because we rely on innobackupex to
|
||||
copy them under a global lock, and use them to copy remote tablespaces
|
||||
to their proper locations on --copy-back.
|
||||
|
||||
See also MySQL bug #72022: dir_path is always NULL for remote
|
||||
tablespaces when a MLOG_FILE_CREATE* log record is replayed (the remote
|
||||
directory is not available from MLOG_FILE_CREATE*). */
|
||||
bool has_data_dir = FSP_FLAGS_HAS_DATA_DIR(flags) != 0 && !IS_XTRABACKUP();
|
||||
ulint atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(flags);
|
||||
fil_space_crypt_t *crypt_data = NULL;
|
||||
|
||||
@ -3964,6 +3991,7 @@ fil_create_new_single_table_tablespace(
|
||||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
if (!IS_XTRABACKUP())
|
||||
{
|
||||
mtr_t mtr;
|
||||
ulint mlog_file_flag = 0;
|
||||
@ -4004,6 +4032,138 @@ error_exit_3:
|
||||
return(err);
|
||||
}
|
||||
|
||||
#include "pars0pars.h"
|
||||
#include "que0que.h"
|
||||
#include "dict0priv.h"
|
||||
static
|
||||
void
|
||||
fil_remove_invalid_table_from_data_dict(const char *name)
|
||||
{
|
||||
trx_t* trx;
|
||||
pars_info_t* info = NULL;
|
||||
|
||||
trx = trx_allocate_for_mysql();
|
||||
trx_start_for_ddl(trx, TRX_DICT_OP_TABLE);
|
||||
|
||||
ut_ad(mutex_own(&dict_sys->mutex));
|
||||
|
||||
trx->op_info = "removing invalid table from data dictionary";
|
||||
|
||||
info = pars_info_create();
|
||||
|
||||
pars_info_add_str_literal(info, "table_name", name);
|
||||
|
||||
que_eval_sql(info,
|
||||
"PROCEDURE DROP_TABLE_PROC () IS\n"
|
||||
"sys_foreign_id CHAR;\n"
|
||||
"table_id CHAR;\n"
|
||||
"index_id CHAR;\n"
|
||||
"foreign_id CHAR;\n"
|
||||
"found INT;\n"
|
||||
|
||||
"DECLARE CURSOR cur_fk IS\n"
|
||||
"SELECT ID FROM SYS_FOREIGN\n"
|
||||
"WHERE FOR_NAME = :table_name\n"
|
||||
"AND TO_BINARY(FOR_NAME)\n"
|
||||
" = TO_BINARY(:table_name)\n"
|
||||
"LOCK IN SHARE MODE;\n"
|
||||
|
||||
"DECLARE CURSOR cur_idx IS\n"
|
||||
"SELECT ID FROM SYS_INDEXES\n"
|
||||
"WHERE TABLE_ID = table_id\n"
|
||||
"LOCK IN SHARE MODE;\n"
|
||||
|
||||
"BEGIN\n"
|
||||
"SELECT ID INTO table_id\n"
|
||||
"FROM SYS_TABLES\n"
|
||||
"WHERE NAME = :table_name\n"
|
||||
"LOCK IN SHARE MODE;\n"
|
||||
"IF (SQL % NOTFOUND) THEN\n"
|
||||
" RETURN;\n"
|
||||
"END IF;\n"
|
||||
"found := 1;\n"
|
||||
"SELECT ID INTO sys_foreign_id\n"
|
||||
"FROM SYS_TABLES\n"
|
||||
"WHERE NAME = 'SYS_FOREIGN'\n"
|
||||
"LOCK IN SHARE MODE;\n"
|
||||
"IF (SQL % NOTFOUND) THEN\n"
|
||||
" found := 0;\n"
|
||||
"END IF;\n"
|
||||
"IF (:table_name = 'SYS_FOREIGN') THEN\n"
|
||||
" found := 0;\n"
|
||||
"END IF;\n"
|
||||
"IF (:table_name = 'SYS_FOREIGN_COLS') THEN\n"
|
||||
" found := 0;\n"
|
||||
"END IF;\n"
|
||||
"OPEN cur_fk;\n"
|
||||
"WHILE found = 1 LOOP\n"
|
||||
" FETCH cur_fk INTO foreign_id;\n"
|
||||
" IF (SQL % NOTFOUND) THEN\n"
|
||||
" found := 0;\n"
|
||||
" ELSE\n"
|
||||
" DELETE FROM SYS_FOREIGN_COLS\n"
|
||||
" WHERE ID = foreign_id;\n"
|
||||
" DELETE FROM SYS_FOREIGN\n"
|
||||
" WHERE ID = foreign_id;\n"
|
||||
" END IF;\n"
|
||||
"END LOOP;\n"
|
||||
"CLOSE cur_fk;\n"
|
||||
"found := 1;\n"
|
||||
"OPEN cur_idx;\n"
|
||||
"WHILE found = 1 LOOP\n"
|
||||
" FETCH cur_idx INTO index_id;\n"
|
||||
" IF (SQL % NOTFOUND) THEN\n"
|
||||
" found := 0;\n"
|
||||
" ELSE\n"
|
||||
" DELETE FROM SYS_FIELDS\n"
|
||||
" WHERE INDEX_ID = index_id;\n"
|
||||
" DELETE FROM SYS_INDEXES\n"
|
||||
" WHERE ID = index_id\n"
|
||||
" AND TABLE_ID = table_id;\n"
|
||||
" END IF;\n"
|
||||
"END LOOP;\n"
|
||||
"CLOSE cur_idx;\n"
|
||||
"DELETE FROM SYS_COLUMNS\n"
|
||||
"WHERE TABLE_ID = table_id;\n"
|
||||
"DELETE FROM SYS_TABLES\n"
|
||||
"WHERE NAME = :table_name;\n"
|
||||
"END;\n"
|
||||
, FALSE, trx);
|
||||
|
||||
/* SYS_DATAFILES and SYS_TABLESPACES do not necessarily exist
|
||||
on XtraBackup recovery. See comments around
|
||||
dict_create_or_check_foreign_constraint_tables() in
|
||||
innobase_start_or_create_for_mysql(). */
|
||||
if (dict_table_get_low("SYS_DATAFILES") != NULL) {
|
||||
info = pars_info_create();
|
||||
|
||||
pars_info_add_str_literal(info, "table_name", name);
|
||||
|
||||
que_eval_sql(info,
|
||||
"PROCEDURE DROP_TABLE_PROC () IS\n"
|
||||
"space_id INT;\n"
|
||||
|
||||
"BEGIN\n"
|
||||
"SELECT SPACE INTO space_id\n"
|
||||
"FROM SYS_TABLES\n"
|
||||
"WHERE NAME = :table_name;\n"
|
||||
"IF (SQL % NOTFOUND) THEN\n"
|
||||
" RETURN;\n"
|
||||
"END IF;\n"
|
||||
"DELETE FROM SYS_TABLESPACES\n"
|
||||
"WHERE SPACE = space_id;\n"
|
||||
"DELETE FROM SYS_DATAFILES\n"
|
||||
"WHERE SPACE = space_id;\n"
|
||||
"END;\n"
|
||||
, FALSE, trx);
|
||||
}
|
||||
|
||||
trx_commit_for_mysql(trx);
|
||||
|
||||
trx_free_for_mysql(trx);
|
||||
}
|
||||
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/********************************************************************//**
|
||||
Report information about a bad tablespace. */
|
||||
@ -4144,8 +4304,10 @@ fil_open_single_table_tablespace(
|
||||
in the default location. If it is remote, it should not be here. */
|
||||
def.filepath = fil_make_ibd_name(tablename, false);
|
||||
|
||||
/* The path_in was read from SYS_DATAFILES. */
|
||||
if (path_in) {
|
||||
/* The path_in was read from SYS_DATAFILES.
|
||||
We skip SYS_DATAFILES validation and remote tablespaces discovery for
|
||||
XtraBackup, as all tablespaces are local for XtraBackup recovery. */
|
||||
if (path_in && !IS_XTRABACKUP()) {
|
||||
if (strcmp(def.filepath, path_in)) {
|
||||
dict.filepath = mem_strdup(path_in);
|
||||
/* possibility of multiple files. */
|
||||
@ -4287,12 +4449,19 @@ fil_open_single_table_tablespace(
|
||||
/* The following call prints an error message */
|
||||
os_file_get_last_error(true);
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
ib_logf(IS_XTRABACKUP() ? IB_LOG_LEVEL_WARN : IB_LOG_LEVEL_ERROR,
|
||||
"Could not find a valid tablespace file for '%s'. "
|
||||
"See " REFMAN "innodb-troubleshooting-datadict.html "
|
||||
"for how to resolve the issue.",
|
||||
tablename);
|
||||
if (IS_XTRABACKUP() && fix_dict) {
|
||||
ib_logf(IB_LOG_LEVEL_WARN,
|
||||
"It will be removed from the data dictionary.");
|
||||
|
||||
if (purge_sys) {
|
||||
fil_remove_invalid_table_from_data_dict(tablename);
|
||||
}
|
||||
}
|
||||
err = DB_CORRUPTION;
|
||||
|
||||
goto cleanup_and_exit;
|
||||
@ -4717,6 +4886,11 @@ check_first_page:
|
||||
}
|
||||
|
||||
if (!fsp->success) {
|
||||
if (IS_XTRABACKUP()) {
|
||||
/* Do not attempt restore from doublewrite buffer
|
||||
in Xtrabackup, this does not work.*/
|
||||
return;
|
||||
}
|
||||
if (!restore_attempted) {
|
||||
if (!fil_user_tablespace_find_space_id(fsp)) {
|
||||
return;
|
||||
@ -4784,6 +4958,10 @@ fil_load_single_table_tablespace(
|
||||
os_offset_t size;
|
||||
fil_space_t* space;
|
||||
|
||||
fsp_open_info* fsp;
|
||||
ulong minimum_size;
|
||||
ibool file_space_create_success;
|
||||
|
||||
memset(&def, 0, sizeof(def));
|
||||
memset(&remote, 0, sizeof(remote));
|
||||
|
||||
@ -4839,6 +5017,7 @@ fil_load_single_table_tablespace(
|
||||
# endif /* !UNIV_HOTBACKUP */
|
||||
#endif
|
||||
|
||||
|
||||
/* Check for a link file which locates a remote tablespace. */
|
||||
remote.success = fil_open_linked_file(
|
||||
tablename, &remote.filepath, &remote.file, FALSE);
|
||||
@ -4849,6 +5028,17 @@ fil_load_single_table_tablespace(
|
||||
if (!remote.success) {
|
||||
os_file_close(remote.file);
|
||||
mem_free(remote.filepath);
|
||||
|
||||
if (srv_backup_mode && (remote.id == ULINT_UNDEFINED
|
||||
|| remote.id == 0)) {
|
||||
|
||||
/* Ignore files that have uninitialized space
|
||||
IDs on the backup stage. This means that a
|
||||
tablespace has just been created and we will
|
||||
replay the corresponding log records on
|
||||
prepare. */
|
||||
goto func_exit_after_close;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4863,6 +5053,18 @@ fil_load_single_table_tablespace(
|
||||
fil_validate_single_table_tablespace(tablename, &def);
|
||||
if (!def.success) {
|
||||
os_file_close(def.file);
|
||||
|
||||
if (IS_XTRABACKUP() && srv_backup_mode && (def.id == ULINT_UNDEFINED
|
||||
|| def.id == 0)) {
|
||||
|
||||
/* Ignore files that have uninitialized space
|
||||
IDs on the backup stage. This means that a
|
||||
tablespace has just been created and we will
|
||||
replay the corresponding log records on
|
||||
prepare. */
|
||||
|
||||
goto func_exit_after_close;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4948,7 +5150,7 @@ will_not_choose:
|
||||
/* At this point, only one tablespace is open */
|
||||
ut_a(def.success == !remote.success);
|
||||
|
||||
fsp_open_info* fsp = def.success ? &def : &remote;
|
||||
fsp = def.success ? &def : &remote;
|
||||
|
||||
/* Get and test the file size. */
|
||||
size = os_file_get_size(fsp->file);
|
||||
@ -4967,19 +5169,14 @@ will_not_choose:
|
||||
|
||||
/* Every .ibd file is created >= 4 pages in size. Smaller files
|
||||
cannot be ok. */
|
||||
ulong minimum_size = FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE;
|
||||
minimum_size = FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE;
|
||||
if (size < minimum_size) {
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"The size of single-table tablespace file %s "
|
||||
"is only " UINT64PF ", should be at least %lu!",
|
||||
fsp->filepath, size, minimum_size);
|
||||
os_file_close(fsp->file);
|
||||
goto no_good_file;
|
||||
#else
|
||||
fsp->id = ULINT_UNDEFINED;
|
||||
fsp->flags = 0;
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
}
|
||||
|
||||
#ifdef UNIV_HOTBACKUP
|
||||
@ -5050,6 +5247,7 @@ will_not_choose:
|
||||
}
|
||||
mutex_exit(&fil_system->mutex);
|
||||
#endif /* UNIV_HOTBACKUP */
|
||||
|
||||
/* Adjust the memory-based flags that would normally be set by
|
||||
dict_tf_to_fsp_flags(). In recovery, we have no data dictionary. */
|
||||
if (FSP_FLAGS_HAS_PAGE_COMPRESSION(fsp->flags)) {
|
||||
@ -5060,7 +5258,7 @@ will_not_choose:
|
||||
/* We will leave atomic_writes at ATOMIC_WRITES_DEFAULT.
|
||||
That will be adjusted in fil_space_for_table_exists_in_mem(). */
|
||||
|
||||
ibool file_space_create_success = fil_space_create(
|
||||
file_space_create_success = fil_space_create(
|
||||
tablename, fsp->id, fsp->flags, FIL_TABLESPACE,
|
||||
fsp->crypt_data, false);
|
||||
|
||||
@ -5088,13 +5286,56 @@ will_not_choose:
|
||||
}
|
||||
|
||||
func_exit:
|
||||
os_file_close(fsp->file);
|
||||
/* We reuse file handles on the backup stage in XtraBackup to avoid
|
||||
inconsistencies between the file name and the actual tablespace contents
|
||||
if a DDL occurs between a fil_load_single_table_tablespaces() call and
|
||||
the actual copy operation. */
|
||||
if (IS_XTRABACKUP() && srv_backup_mode && !srv_close_files) {
|
||||
|
||||
fil_node_t* node;
|
||||
fil_space_t* space;
|
||||
|
||||
mutex_enter(&fil_system->mutex);
|
||||
|
||||
space = fil_space_get_by_id(fsp->id);
|
||||
|
||||
if (space) {
|
||||
node = UT_LIST_GET_LAST(space->chain);
|
||||
|
||||
/* The handle will be closed by xtrabackup in
|
||||
xtrabackup_copy_datafile(). We set node->open to TRUE to
|
||||
make sure no one calls fil_node_open_file()
|
||||
(i.e. attempts to reopen the tablespace by name) during
|
||||
the backup stage. */
|
||||
|
||||
node->open = TRUE;
|
||||
node->handle = fsp->file;
|
||||
|
||||
/* The following is copied from fil_node_open_file() to
|
||||
pass fil_system validaty checks. We cannot use
|
||||
fil_node_open_file() directly, as that would re-open the
|
||||
file by name and create another file handle. */
|
||||
|
||||
fil_system->n_open++;
|
||||
fil_n_file_opened++;
|
||||
|
||||
if (fil_space_belongs_in_lru(space)) {
|
||||
|
||||
/* Put the node to the LRU list */
|
||||
UT_LIST_ADD_FIRST(LRU, fil_system->LRU, node);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_exit(&fil_system->mutex);
|
||||
}
|
||||
else {
|
||||
os_file_close(fsp->file);
|
||||
}
|
||||
|
||||
|
||||
#ifdef UNIV_HOTBACKUP
|
||||
func_exit_after_close:
|
||||
#else
|
||||
ut_ad(!mutex_own(&fil_system->mutex));
|
||||
#endif
|
||||
|
||||
mem_free(tablename);
|
||||
if (remote.success) {
|
||||
mem_free(remote.filepath);
|
||||
@ -5108,7 +5349,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
|
||||
UNIV_INTERN
|
||||
int
|
||||
fil_file_readdir_next_file(
|
||||
/*=======================*/
|
||||
@ -5149,7 +5390,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;
|
||||
@ -5224,14 +5465,20 @@ fil_load_single_table_tablespaces(void)
|
||||
goto next_file_item;
|
||||
}
|
||||
|
||||
/* We found a symlink or a file */
|
||||
/* We found a symlink or a file
|
||||
|
||||
Ignore .isl files on XtraBackup
|
||||
recovery, all tablespaces must be local. */
|
||||
if (strlen(fileinfo.name) > 4
|
||||
&& (0 == strcmp(fileinfo.name
|
||||
+ strlen(fileinfo.name) - 4,
|
||||
".ibd")
|
||||
|| 0 == strcmp(fileinfo.name
|
||||
+ strlen(fileinfo.name) - 4,
|
||||
".isl"))) {
|
||||
|| ((!IS_XTRABACKUP() || srv_backup_mode)
|
||||
&& 0 == strcmp(fileinfo.name
|
||||
+ strlen(fileinfo.name) - 4,
|
||||
".isl")))
|
||||
&& (!pred ||
|
||||
pred(dbinfo.name, fileinfo.name))) {
|
||||
/* The name ends in .ibd or .isl;
|
||||
try opening the file */
|
||||
fil_load_single_table_tablespace(
|
||||
@ -5387,6 +5634,9 @@ fil_space_for_table_exists_in_mem(
|
||||
information to the .err log if a
|
||||
matching tablespace is not found from
|
||||
memory */
|
||||
bool remove_from_data_dict_if_does_not_exist,
|
||||
/*!< in: remove from the data dictionary
|
||||
if tablespace does not exist */
|
||||
bool adjust_space, /*!< in: whether to adjust space id
|
||||
when find table space mismatch */
|
||||
mem_heap_t* heap, /*!< in: heap memory */
|
||||
@ -5457,6 +5707,11 @@ fil_space_for_table_exists_in_mem(
|
||||
if (fnamespace == NULL) {
|
||||
if (print_error_if_does_not_exist) {
|
||||
fil_report_missing_tablespace(name, id);
|
||||
if (IS_XTRABACKUP() && remove_from_data_dict_if_does_not_exist) {
|
||||
ib_logf(IB_LOG_LEVEL_WARN,
|
||||
"It will be removed from "
|
||||
"the data dictionary.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ut_print_timestamp(stderr);
|
||||
@ -6119,7 +6374,7 @@ _fil_io(
|
||||
/* Check that at least the start offset is within the bounds of a
|
||||
single-table tablespace, including rollback tablespaces. */
|
||||
if (UNIV_UNLIKELY(node->size <= block_offset)
|
||||
&& space->id != 0 && space->purpose == FIL_TABLESPACE) {
|
||||
&& space->id != 0 && space->purpose == FIL_TABLESPACE) {
|
||||
|
||||
fil_report_invalid_page_access(
|
||||
block_offset, space_id, space->name, byte_offset,
|
||||
|
@ -284,7 +284,8 @@ 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[] = {
|
||||
UNIV_INTERN
|
||||
const char* innodb_checksum_algorithm_names[] = {
|
||||
"CRC32",
|
||||
"STRICT_CRC32",
|
||||
"INNODB",
|
||||
@ -296,7 +297,8 @@ 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 = {
|
||||
UNIV_INTERN
|
||||
TYPELIB innodb_checksum_algorithm_typelib = {
|
||||
array_elements(innodb_checksum_algorithm_names) - 1,
|
||||
"innodb_checksum_algorithm_typelib",
|
||||
innodb_checksum_algorithm_names,
|
||||
@ -2013,7 +2015,9 @@ thd_supports_xa(
|
||||
THD* thd) /*!< in: thread handle, or NULL to query
|
||||
the global innodb_supports_xa */
|
||||
{
|
||||
return(THDVAR(thd, support_xa));
|
||||
/* THDVAR cannot be used in xtrabackup,
|
||||
plugin variables for innodb are not loaded. */
|
||||
return (thd || !IS_XTRABACKUP())? THDVAR(thd, support_xa): FALSE;
|
||||
}
|
||||
|
||||
/** Get the value of innodb_tmpdir.
|
||||
@ -2046,7 +2050,9 @@ thd_fake_changes(
|
||||
THD* thd) /*!< in: thread handle, or NULL to query
|
||||
the global innodb_supports_xa */
|
||||
{
|
||||
return(THDVAR((THD*) thd, fake_changes));
|
||||
/* THDVAR cannot be used in xtrabackup,
|
||||
plugin variables for innodb are not loaded */
|
||||
return (thd || !IS_XTRABACKUP())? THDVAR((THD*) thd, fake_changes) : FALSE ;
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
@ -2086,7 +2092,10 @@ thd_flush_log_at_trx_commit(
|
||||
/*================================*/
|
||||
void* thd)
|
||||
{
|
||||
return(THDVAR((THD*) thd, flush_log_at_trx_commit));
|
||||
/* THDVAR cannot be used in xtrabackup,
|
||||
plugin variables for innodb are not loaded,
|
||||
this makes xtrabackup crash when trying to use them. */
|
||||
return (thd || !IS_XTRABACKUP())? THDVAR((THD*)thd, flush_log_at_trx_commit) : FALSE;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
@ -3053,7 +3062,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(
|
||||
/*============================*/
|
||||
@ -21951,22 +21960,27 @@ ib_logf(
|
||||
str = static_cast<char*>(malloc(BUFSIZ));
|
||||
my_vsnprintf(str, BUFSIZ, format, args);
|
||||
#endif /* __WIN__ */
|
||||
|
||||
switch(level) {
|
||||
case IB_LOG_LEVEL_INFO:
|
||||
sql_print_information("InnoDB: %s", str);
|
||||
break;
|
||||
case IB_LOG_LEVEL_WARN:
|
||||
sql_print_warning("InnoDB: %s", str);
|
||||
break;
|
||||
case IB_LOG_LEVEL_ERROR:
|
||||
sql_print_error("InnoDB: %s", str);
|
||||
sd_notifyf(0, "STATUS=InnoDB: Error: %s", str);
|
||||
break;
|
||||
case IB_LOG_LEVEL_FATAL:
|
||||
sql_print_error("InnoDB: %s", str);
|
||||
sd_notifyf(0, "STATUS=InnoDB: Fatal: %s", str);
|
||||
break;
|
||||
if (!IS_XTRABACKUP()) {
|
||||
switch (level) {
|
||||
case IB_LOG_LEVEL_INFO:
|
||||
sql_print_information("InnoDB: %s", str);
|
||||
break;
|
||||
case IB_LOG_LEVEL_WARN:
|
||||
sql_print_warning("InnoDB: %s", str);
|
||||
break;
|
||||
case IB_LOG_LEVEL_ERROR:
|
||||
sql_print_error("InnoDB: %s", str);
|
||||
sd_notifyf(0, "STATUS=InnoDB: Error: %s", str);
|
||||
break;
|
||||
case IB_LOG_LEVEL_FATAL:
|
||||
sql_print_error("InnoDB: %s", str);
|
||||
sd_notifyf(0, "STATUS=InnoDB: Fatal: %s", str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Don't use server logger for XtraBackup, just print to stderr. */
|
||||
fprintf(stderr, "InnoDB: %s\n", str);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
@ -136,6 +136,7 @@ extern fil_addr_t fil_addr_null;
|
||||
|
||||
#define FIL_PAGE_DATA 38 /*!< start of the data on the page */
|
||||
/* Following are used when page compression is used */
|
||||
|
||||
#define FIL_PAGE_COMPRESSED_SIZE 2 /*!< Number of bytes used to store
|
||||
actual payload data size on
|
||||
compressed pages. */
|
||||
@ -1042,7 +1043,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,
|
||||
@ -1081,6 +1082,9 @@ fil_space_for_table_exists_in_mem(
|
||||
information to the .err log if a
|
||||
matching tablespace is not found from
|
||||
memory */
|
||||
bool remove_from_data_dict_if_does_not_exist,
|
||||
/*!< in: remove from the data dictionary
|
||||
if tablespace does not exist */
|
||||
bool adjust_space, /*!< in: whether to adjust space id
|
||||
when find table space mismatch */
|
||||
mem_heap_t* heap, /*!< in: heap memory */
|
||||
|
@ -499,7 +499,9 @@ as enum type because the configure option takes unsigned integer type. */
|
||||
extern ulong srv_innodb_stats_method;
|
||||
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
extern ibool srv_log_archive_on;
|
||||
extern bool srv_log_archive_on;
|
||||
extern bool srv_archive_recovery;
|
||||
extern ib_uint64_t srv_archive_recovery_limit_lsn;
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
|
||||
extern char* srv_file_flush_method_str;
|
||||
@ -550,6 +552,14 @@ extern ulong srv_pass_corrupt_table;
|
||||
|
||||
extern ulong srv_log_checksum_algorithm;
|
||||
|
||||
extern bool srv_apply_log_only;
|
||||
|
||||
extern bool srv_backup_mode;
|
||||
extern bool srv_close_files;
|
||||
extern bool srv_xtrabackup;
|
||||
|
||||
#define IS_XTRABACKUP() (srv_xtrabackup)
|
||||
|
||||
extern my_bool srv_force_primary_key;
|
||||
|
||||
/* Helper macro to support srv_pass_corrupt_table checks. If 'cond' is FALSE,
|
||||
|
@ -336,8 +336,9 @@ trx_sys_update_wsrep_checkpoint(
|
||||
trx_sysf_t* sys_header, /*!< in: sys_header */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
|
||||
void
|
||||
/** Read WSREP checkpoint XID from sys header. */
|
||||
/** Read WSREP checkpoint XID from sys header.
|
||||
@return true on success, false on error. */
|
||||
bool
|
||||
trx_sys_read_wsrep_checkpoint(
|
||||
XID* xid); /*!< out: WSREP XID */
|
||||
#endif /* WITH_WSREP */
|
||||
|
@ -635,7 +635,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;
|
||||
|
@ -2629,7 +2629,7 @@ loop:
|
||||
start_lsn += len;
|
||||
buf += len;
|
||||
|
||||
if (recv_sys->report(ut_time())) {
|
||||
if (recv_sys && recv_sys->report(ut_time())) {
|
||||
ib_logf(IB_LOG_LEVEL_INFO, "Read redo log up to LSN=" LSN_PF,
|
||||
start_lsn);
|
||||
sd_notifyf(0, "STATUS=Read redo log up to LSN=" LSN_PF,
|
||||
|
@ -692,7 +692,6 @@ recv_synchronize_groups(
|
||||
/***********************************************************************//**
|
||||
Checks the consistency of the checkpoint info
|
||||
@return TRUE if ok */
|
||||
static
|
||||
ibool
|
||||
recv_check_cp_is_consistent(
|
||||
/*========================*/
|
||||
@ -722,7 +721,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(
|
||||
/*=====================*/
|
||||
@ -3474,6 +3473,7 @@ recv_recovery_from_checkpoint_finish(void)
|
||||
#ifdef __WIN__
|
||||
if (recv_writer_thread_handle) {
|
||||
CloseHandle(recv_writer_thread_handle);
|
||||
recv_writer_thread_handle = 0;
|
||||
}
|
||||
#endif /* __WIN__ */
|
||||
|
||||
@ -3700,6 +3700,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);
|
||||
|
@ -130,7 +130,7 @@ UNIV_INTERN os_ib_mutex_t os_file_seek_mutexes[OS_FILE_N_SEEK_MUTEXES];
|
||||
#define OS_AIO_MERGE_N_CONSECUTIVE 64
|
||||
|
||||
#ifdef WITH_INNODB_DISALLOW_WRITES
|
||||
#define WAIT_ALLOW_WRITES() os_event_wait(srv_allow_writes_event)
|
||||
#define WAIT_ALLOW_WRITES() if (!IS_XTRABACKUP()) os_event_wait(srv_allow_writes_event)
|
||||
#else
|
||||
#define WAIT_ALLOW_WRITES() do { } while (0)
|
||||
#endif /* WITH_INNODB_DISALLOW_WRITES */
|
||||
@ -1001,7 +1001,6 @@ os_file_lock(
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/****************************************************************//**
|
||||
Creates the seek mutexes used in positioned reads and writes. */
|
||||
static
|
||||
void
|
||||
os_io_init_simple(void)
|
||||
/*===================*/
|
||||
@ -1640,6 +1639,10 @@ os_file_create_simple_no_error_handling_func(
|
||||
return((os_file_t) -1);
|
||||
}
|
||||
|
||||
if (IS_XTRABACKUP()) {
|
||||
share_mode |= FILE_SHARE_DELETE | FILE_SHARE_WRITE;
|
||||
}
|
||||
|
||||
file = CreateFile((LPCTSTR) name,
|
||||
access,
|
||||
share_mode,
|
||||
@ -1921,7 +1924,10 @@ os_file_create_func(
|
||||
|
||||
create_mode &= ~OS_FILE_ON_ERROR_NO_EXIT;
|
||||
create_mode &= ~OS_FILE_ON_ERROR_SILENT;
|
||||
|
||||
if (srv_backup_mode){
|
||||
/* Permit others to write, while I'm reading. */
|
||||
share_mode |= FILE_SHARE_WRITE;
|
||||
}
|
||||
if (create_mode == OS_FILE_OPEN_RAW) {
|
||||
|
||||
ut_a(!srv_read_only_mode);
|
||||
@ -3525,7 +3531,7 @@ os_file_get_status(
|
||||
fh = CreateFile(
|
||||
(LPCTSTR) path, // File to open
|
||||
access,
|
||||
0, // No sharing
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
NULL, // Default security
|
||||
OPEN_EXISTING, // Existing file only
|
||||
FILE_ATTRIBUTE_NORMAL, // Normal file
|
||||
|
@ -4483,8 +4483,9 @@ row_drop_table_for_mysql(
|
||||
if (!is_temp
|
||||
&& !fil_space_for_table_exists_in_mem(
|
||||
space_id, tablename,
|
||||
print_msg, false, NULL, 0,
|
||||
print_msg, IS_XTRABACKUP() && print_msg, false, NULL, 0,
|
||||
table_flags)) {
|
||||
|
||||
/* This might happen if we are dropping a
|
||||
discarded tablespace */
|
||||
err = DB_SUCCESS;
|
||||
|
@ -203,7 +203,7 @@ performance killer causing calling thread to context switch. Besides, Innodb
|
||||
is preallocating large number (often millions) of os_events. With kernel event
|
||||
objects it takes a big chunk out of non-paged pool, which is better suited
|
||||
for tasks like IO than for storing idle event objects. */
|
||||
UNIV_INTERN ibool srv_use_native_conditions = FALSE;
|
||||
UNIV_INTERN ibool srv_use_native_conditions = TRUE;
|
||||
#endif /* __WIN__ */
|
||||
|
||||
UNIV_INTERN ulint srv_n_data_files = 0;
|
||||
@ -366,7 +366,9 @@ readahead request. */
|
||||
UNIV_INTERN ulong srv_read_ahead_threshold = 56;
|
||||
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
UNIV_INTERN ibool srv_log_archive_on = FALSE;
|
||||
UNIV_INTERN bool srv_log_archive_on;
|
||||
UNIV_INTERN bool srv_archive_recovery;
|
||||
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
|
||||
@ -522,6 +524,12 @@ UNIV_INTERN ulong srv_doublewrite_batch_size = 120;
|
||||
|
||||
UNIV_INTERN ulong srv_replication_delay = 0;
|
||||
|
||||
UNIV_INTERN bool srv_apply_log_only;
|
||||
|
||||
UNIV_INTERN bool srv_backup_mode;
|
||||
UNIV_INTERN bool srv_close_files;
|
||||
UNIV_INTERN bool srv_xtrabackup;
|
||||
|
||||
UNIV_INTERN ulong srv_pass_corrupt_table = 0; /* 0:disable 1:enable */
|
||||
|
||||
UNIV_INTERN ulong srv_log_checksum_algorithm =
|
||||
|
@ -140,7 +140,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(
|
||||
/*======================*/
|
||||
@ -1080,8 +1080,10 @@ skip_size_check:
|
||||
/* This is the earliest location where we can load
|
||||
the double write buffer. */
|
||||
if (i == 0) {
|
||||
/* XtraBackup never loads corrupted pages from
|
||||
the doublewrite buffer */
|
||||
buf_dblwr_init_or_load_pages(
|
||||
files[i], srv_data_file_names[i], true);
|
||||
files[i], srv_data_file_names[i], !IS_XTRABACKUP());
|
||||
}
|
||||
|
||||
bool retry = true;
|
||||
@ -1365,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
|
||||
@ -1424,7 +1429,7 @@ srv_undo_tablespaces_init(
|
||||
we build the undo_tablespace_ids ourselves since they don't
|
||||
already exist. */
|
||||
|
||||
if (!create_new_db) {
|
||||
if (!create_new_db && !backup_mode) {
|
||||
n_undo_tablespaces = trx_rseg_get_n_undo_tablespaces(
|
||||
undo_tablespace_ids);
|
||||
} else {
|
||||
@ -2318,11 +2323,11 @@ innobase_start_or_create_for_mysql(void)
|
||||
max_flushed_lsn = min_flushed_lsn
|
||||
= log_get_lsn();
|
||||
goto files_checked;
|
||||
} else if (i < 2) {
|
||||
/* must have at least 2 log files */
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Only one log file found.");
|
||||
return(err);
|
||||
} else if (i < 2 && !IS_XTRABACKUP()) {
|
||||
/* must have at least 2 log files */
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Only one log file found.");
|
||||
return(err);
|
||||
}
|
||||
|
||||
/* opened all files */
|
||||
@ -2416,6 +2421,7 @@ files_checked:
|
||||
|
||||
err = srv_undo_tablespaces_init(
|
||||
create_new_db,
|
||||
FALSE,
|
||||
srv_undo_tablespaces,
|
||||
&srv_undo_tablespaces_open);
|
||||
|
||||
@ -2689,6 +2695,17 @@ files_checked:
|
||||
dict_check_tablespaces_and_store_max_id(dict_check);
|
||||
}
|
||||
|
||||
if (IS_XTRABACKUP()
|
||||
&& !srv_backup_mode
|
||||
&& srv_read_only_mode
|
||||
&& srv_log_file_size_requested != srv_log_file_size) {
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_WARN,
|
||||
"Log files size mismatch, ignored in readonly mode");
|
||||
srv_log_file_size_requested = srv_log_file_size;
|
||||
}
|
||||
|
||||
|
||||
if (!srv_force_recovery
|
||||
&& !recv_sys->found_corrupt_log
|
||||
&& (srv_log_file_size_requested != srv_log_file_size
|
||||
@ -3323,7 +3340,8 @@ innobase_shutdown_for_mysql(void)
|
||||
|
||||
srv_was_started = FALSE;
|
||||
srv_start_has_been_called = FALSE;
|
||||
|
||||
/* reset io_tid_i, in case current process does second innodb start (xtrabackup might do that).*/
|
||||
io_tid_i = 0;
|
||||
return(DB_SUCCESS);
|
||||
}
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
@ -397,7 +397,7 @@ trx_sys_update_wsrep_checkpoint(
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
trx_sys_read_wsrep_checkpoint(XID* xid)
|
||||
/*===================================*/
|
||||
{
|
||||
@ -418,7 +418,7 @@ trx_sys_read_wsrep_checkpoint(XID* xid)
|
||||
xid->formatID = -1;
|
||||
trx_sys_update_wsrep_checkpoint(xid, sys_header, &mtr);
|
||||
mtr_commit(&mtr);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
xid->formatID = (int)mach_read_from_4(
|
||||
@ -435,6 +435,7 @@ trx_sys_read_wsrep_checkpoint(XID* xid)
|
||||
XIDDATASIZE);
|
||||
|
||||
mtr_commit(&mtr);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* WITH_WSREP */
|
||||
@ -1330,14 +1331,17 @@ trx_sys_close(void)
|
||||
trx_purge_sys_close();
|
||||
|
||||
/* Free the double write data structures. */
|
||||
buf_dblwr_free();
|
||||
if (buf_dblwr) {
|
||||
buf_dblwr_free();
|
||||
}
|
||||
|
||||
ut_a(UT_LIST_GET_LEN(trx_sys->ro_trx_list) == 0);
|
||||
|
||||
/* Only prepared transactions may be left in the system. Free them. */
|
||||
ut_a(UT_LIST_GET_LEN(trx_sys->rw_trx_list) == trx_sys->n_prepared_trx
|
||||
|| srv_read_only_mode
|
||||
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
|
||||
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO
|
||||
|| (IS_XTRABACKUP() && srv_apply_log_only));
|
||||
|
||||
|
||||
while ((trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list)) != NULL) {
|
||||
trx_free_prepared(trx);
|
||||
@ -1368,10 +1372,12 @@ trx_sys_close(void)
|
||||
UT_LIST_REMOVE(view_list, trx_sys->view_list, prev_view);
|
||||
}
|
||||
|
||||
ut_a(UT_LIST_GET_LEN(trx_sys->view_list) == 0);
|
||||
ut_a(UT_LIST_GET_LEN(trx_sys->ro_trx_list) == 0);
|
||||
ut_a(UT_LIST_GET_LEN(trx_sys->rw_trx_list) == 0);
|
||||
ut_a(UT_LIST_GET_LEN(trx_sys->mysql_trx_list) == 0);
|
||||
if (!IS_XTRABACKUP() || !srv_apply_log_only) {
|
||||
ut_a(UT_LIST_GET_LEN(trx_sys->view_list) == 0);
|
||||
ut_a(UT_LIST_GET_LEN(trx_sys->ro_trx_list) == 0);
|
||||
ut_a(UT_LIST_GET_LEN(trx_sys->rw_trx_list) == 0);
|
||||
ut_a(UT_LIST_GET_LEN(trx_sys->mysql_trx_list) == 0);
|
||||
}
|
||||
|
||||
mutex_free(&trx_sys->mutex);
|
||||
|
||||
@ -1418,6 +1424,9 @@ ulint
|
||||
trx_sys_any_active_transactions(void)
|
||||
/*=================================*/
|
||||
{
|
||||
if (IS_XTRABACKUP() && srv_apply_log_only) {
|
||||
return(0);
|
||||
}
|
||||
mutex_enter(&trx_sys->mutex);
|
||||
|
||||
ulint total_trx = UT_LIST_GET_LEN(trx_sys->mysql_trx_list);
|
||||
|
@ -721,9 +721,16 @@ trx_resurrect_insert(
|
||||
|
||||
if (srv_force_recovery == 0) {
|
||||
|
||||
trx->state = TRX_STATE_PREPARED;
|
||||
trx_sys->n_prepared_trx++;
|
||||
trx_sys->n_prepared_recovered_trx++;
|
||||
/* XtraBackup should rollback prepared XA
|
||||
transactions */
|
||||
if (IS_XTRABACKUP()) {
|
||||
trx->state = TRX_STATE_ACTIVE;
|
||||
}
|
||||
else {
|
||||
trx->state = TRX_STATE_PREPARED;
|
||||
trx_sys->n_prepared_trx++;
|
||||
trx_sys->n_prepared_recovered_trx++;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Since innodb_force_recovery"
|
||||
@ -790,13 +797,16 @@ trx_resurrect_update_in_prepared_state(
|
||||
|
||||
if (srv_force_recovery == 0) {
|
||||
if (trx_state_eq(trx, TRX_STATE_NOT_STARTED)) {
|
||||
trx_sys->n_prepared_trx++;
|
||||
trx_sys->n_prepared_recovered_trx++;
|
||||
if (!IS_XTRABACKUP()) {
|
||||
trx_sys->n_prepared_trx++;
|
||||
trx_sys->n_prepared_recovered_trx++;
|
||||
}
|
||||
} else {
|
||||
ut_ad(trx_state_eq(trx, TRX_STATE_PREPARED));
|
||||
}
|
||||
|
||||
trx->state = TRX_STATE_PREPARED;
|
||||
/* XtraBackup should rollback prepared XA
|
||||
transactions */
|
||||
trx->state = IS_XTRABACKUP()?TRX_STATE_ACTIVE: TRX_STATE_PREPARED;
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Since innodb_force_recovery"
|
||||
|
Loading…
x
Reference in New Issue
Block a user