MDEV-13564: Refuse MLOG_TRUNCATE in mariabackup
The MySQL 5.7 TRUNCATE TABLE is inherently incompatible with hot backup, because it is creating and deleting a separate log file, and it is not writing redo log for all changes of the InnoDB data dictionary tables. Refuse to create a corrupted backup if the unsafe form of TRUNCATE was executed. Note: Undo log tablespace truncation cannot be detected easily. Also it is incompatible with backup, for similar reasons. xtrabackup_backup_func(): "Subscribe to" the log events before the first invocation of xtrabackup_copy_logfile(). recv_parse_or_apply_log_rec_body(): If the function pointer log_truncate is set, invoke it to report MLOG_TRUNCATE.
This commit is contained in:
parent
1b49c89429
commit
d6f7fd6016
@ -358,9 +358,8 @@ struct ddl_tracker_t {
|
||||
/* For DDL operation found in redo log, */
|
||||
space_id_to_name_t id_to_name;
|
||||
};
|
||||
const space_id_t REMOVED_SPACE_ID = ULINT_MAX;
|
||||
static ddl_tracker_t ddl_tracker;
|
||||
|
||||
static ddl_tracker_t ddl_tracker;
|
||||
|
||||
/* Whether xtrabackup_binlog_info should be created on recovery */
|
||||
static bool recover_binlog_info;
|
||||
@ -618,9 +617,8 @@ void backup_file_op(ulint space_id, const byte* flags,
|
||||
|
||||
|
||||
/** Callback whenever MLOG_INDEX_LOAD happens.
|
||||
@param[in] space_id space id to check
|
||||
@return false */
|
||||
void backup_optimized_ddl_op(ulint space_id)
|
||||
@param[in] space_id space id to check */
|
||||
static void backup_optimized_ddl_op(ulint space_id)
|
||||
{
|
||||
// TODO : handle incremental
|
||||
if (xtrabackup_incremental)
|
||||
@ -631,6 +629,15 @@ void backup_optimized_ddl_op(ulint space_id)
|
||||
pthread_mutex_unlock(&backup_mutex);
|
||||
}
|
||||
|
||||
/** Callback whenever MLOG_TRUNCATE happens. */
|
||||
static void backup_truncate_fail()
|
||||
{
|
||||
msg("mariabackup: Incompatible TRUNCATE operation detected.%s\n",
|
||||
opt_lock_ddl_per_table
|
||||
? ""
|
||||
: " Use --lock-ddl-per-table to lock all tables before backup.");
|
||||
}
|
||||
|
||||
/* ======== Date copying thread context ======== */
|
||||
|
||||
typedef struct {
|
||||
@ -4240,12 +4247,13 @@ fail_before_log_copying_thread_start:
|
||||
/* copy log file by current position */
|
||||
log_copy_scanned_lsn = checkpoint_lsn_start;
|
||||
recv_sys->recovered_lsn = log_copy_scanned_lsn;
|
||||
log_optimized_ddl_op = backup_optimized_ddl_op;
|
||||
log_truncate = backup_truncate_fail;
|
||||
|
||||
if (xtrabackup_copy_logfile())
|
||||
goto fail_before_log_copying_thread_start;
|
||||
|
||||
log_copying_stop = os_event_create(0);
|
||||
log_optimized_ddl_op = backup_optimized_ddl_op;
|
||||
os_thread_create(log_copying_thread, NULL, &log_copying_thread_id);
|
||||
|
||||
/* FLUSH CHANGED_PAGE_BITMAPS call */
|
||||
|
@ -0,0 +1,4 @@
|
||||
CREATE TABLE t1 ENGINE=InnoDB SELECT 1;
|
||||
DROP TABLE t1;
|
||||
SET GLOBAL innodb_log_checkpoint_now=1;
|
||||
SET GLOBAL innodb_log_checkpoint_now=DEFAULT;
|
19
mysql-test/suite/mariabackup/truncate_during_backup.test
Normal file
19
mysql-test/suite/mariabackup/truncate_during_backup.test
Normal file
@ -0,0 +1,19 @@
|
||||
--source include/have_debug.inc
|
||||
let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
|
||||
mkdir $targetdir;
|
||||
|
||||
CREATE TABLE t1 ENGINE=InnoDB SELECT 1;
|
||||
|
||||
--let after_load_tablespaces=TRUNCATE test.t1
|
||||
|
||||
--disable_result_log
|
||||
--error 1
|
||||
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --dbug=+d,mariabackup_events;
|
||||
--enable_result_log
|
||||
|
||||
--let after_load_tablespaces=
|
||||
|
||||
DROP TABLE t1;
|
||||
SET GLOBAL innodb_log_checkpoint_now=1;
|
||||
SET GLOBAL innodb_log_checkpoint_now=DEFAULT;
|
||||
rmdir $targetdir;
|
@ -153,10 +153,15 @@ bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t store, bool apply);
|
||||
/** Moves the parsing buffer data left to the buffer start. */
|
||||
void recv_sys_justify_left_parsing_buf();
|
||||
|
||||
/** Report optimized DDL operation (without redo log), corresponding to MLOG_INDEX_LOAD.
|
||||
/** Report optimized DDL operation (without redo log),
|
||||
corresponding to MLOG_INDEX_LOAD.
|
||||
@param[in] space_id tablespace identifier
|
||||
*/
|
||||
extern void(*log_optimized_ddl_op)(ulint space_id);
|
||||
extern void (*log_optimized_ddl_op)(ulint space_id);
|
||||
|
||||
/** Report backup-unfriendly TRUNCATE operation (with separate log file),
|
||||
corresponding to MLOG_TRUNCATE. */
|
||||
extern void (*log_truncate)();
|
||||
|
||||
/** Report an operation to create, delete, or rename a file during backup.
|
||||
@param[in] space_id tablespace identifier
|
||||
|
@ -169,11 +169,16 @@ typedef std::map<
|
||||
|
||||
static recv_spaces_t recv_spaces;
|
||||
|
||||
/** Report optimized DDL operation (without redo log), corresponding to MLOG_INDEX_LOAD.
|
||||
/** Report optimized DDL operation (without redo log),
|
||||
corresponding to MLOG_INDEX_LOAD.
|
||||
@param[in] space_id tablespace identifier
|
||||
*/
|
||||
void (*log_optimized_ddl_op)(ulint space_id);
|
||||
|
||||
/** Report backup-unfriendly TRUNCATE operation (with separate log file),
|
||||
corresponding to MLOG_TRUNCATE. */
|
||||
void (*log_truncate)();
|
||||
|
||||
/** Report an operation to create, delete, or rename a file during backup.
|
||||
@param[in] space_id tablespace identifier
|
||||
@param[in] flags tablespace flags (NULL if not create)
|
||||
@ -1196,6 +1201,12 @@ recv_parse_or_apply_log_rec_body(
|
||||
}
|
||||
return(ptr + 8);
|
||||
case MLOG_TRUNCATE:
|
||||
if (log_truncate) {
|
||||
ut_ad(srv_operation != SRV_OPERATION_NORMAL);
|
||||
log_truncate();
|
||||
recv_sys->found_corrupt_fs = true;
|
||||
return NULL;
|
||||
}
|
||||
return(truncate_t::parse_redo_entry(ptr, end_ptr, space_id));
|
||||
|
||||
default:
|
||||
|
Loading…
x
Reference in New Issue
Block a user