diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 5673c94fb0e..d9397b001b7 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -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 */ diff --git a/mysql-test/suite/mariabackup/truncate_during_backup.result b/mysql-test/suite/mariabackup/truncate_during_backup.result new file mode 100644 index 00000000000..f9d5c785749 --- /dev/null +++ b/mysql-test/suite/mariabackup/truncate_during_backup.result @@ -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; diff --git a/mysql-test/suite/mariabackup/truncate_during_backup.test b/mysql-test/suite/mariabackup/truncate_during_backup.test new file mode 100644 index 00000000000..c01a74588e7 --- /dev/null +++ b/mysql-test/suite/mariabackup/truncate_during_backup.test @@ -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; diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h index 6716b1cbd0d..28a4327ec4d 100644 --- a/storage/innobase/include/log0recv.h +++ b/storage/innobase/include/log0recv.h @@ -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 diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index ee4d627261a..c623b884628 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -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: