mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
985ede9203
The problem: When incremental backup is taken, delta files are created for innodb tables which are marked as new tables during innodb ddl tracking. When such tablespace is tried to be opened during prepare in xb_delta_open_matching_space(), it is "created", i.e. xb_space_create_file() is invoked, instead of opening, even if a tablespace with the same name exists in the base backup directory. xb_space_create_file() writes page 0 header the tablespace. This header does not contain crypt data, as mariabackup does not have any information about crypt data in delta file metadata for tablespaces. After delta file is applied, recovery process is started. As the sequence of recovery for different pages is not defined, there can be the situation when crypt data redo log event is executed after some other page is read for recovery. When some page is read for recovery, it's decrypted using crypt data stored in tablespace header in page 0, if there is no crypt data, the page is not decryped and does not pass corruption test. This causes error for incremental backup --prepare for encrypted tablespaces. The error is not stable because crypt data redo log event updates crypt data on page 0, and recovery for different pages can be executed in undefined order. The fix: When delta file is created, the corresponding write filter copies only the pages which LSN is greater then some incremental LSN. When new file is created during incremental backup, the LSN of all it's pages must be greater then incremental LSN, so there is no need to create delta for such table, we can just copy it completely. The fix is to copy the whole file which was tracked during incremental backup with innodb ddl tracker, and copy it to base directory during --prepare instead of delta applying. There is also DBUG_EXECUTE_IF() in innodb code to avoid writing redo log record for crypt data updating on page 0 to make the test case stable. Note: The issue is not reproducible in 10.5 as optimized DDL's are deprecated in 10.5. But the fix is still useful because it allows to decrease data copy size during backup, as delta file contains some extra info. The test case should be removed for 10.5 as it will always pass.
66 lines
2.2 KiB
Text
66 lines
2.2 KiB
Text
#
|
|
# If MDEV-20755 bug is no fixed, incremental prepare will fail.
|
|
#
|
|
--source include/have_debug.inc
|
|
--source include/have_file_key_management.inc
|
|
|
|
--let $base_dir=$MYSQLTEST_VARDIR/tmp/backup
|
|
--let $inc_dir=$MYSQLTEST_VARDIR/tmp/backup_inc
|
|
|
|
SET @old_innodb_log_optimize_ddl=@@global.innodb_log_optimize_ddl;
|
|
SET GLOBAL innodb_log_optimize_ddl=ON;
|
|
|
|
# Disable pages flushing to allow redo log records to be executed on --prepare.
|
|
SET @old_debug_dbug=@@global.debug_dbug;
|
|
SET GLOBAL debug_dbug="+d,ib_log_checkpoint_avoid";
|
|
SET @old_innodb_page_cleaner_disabled_debug=@@global.innodb_page_cleaner_disabled_debug;
|
|
SET GLOBAL innodb_page_cleaner_disabled_debug=ON;
|
|
|
|
CREATE TABLE t1 (c INT) ENGINE=InnoDB;
|
|
INSERT INTO t1 VALUES (1);
|
|
|
|
--echo # backup
|
|
--disable_result_log
|
|
--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$base_dir
|
|
--enable_result_log
|
|
|
|
# Do not log crypt data to avoid it's execution on --prepare.
|
|
SET GLOBAL debug_dbug="+d,ib_do_not_log_crypt_data";
|
|
INSERT INTO t1 VALUES (2);
|
|
|
|
--disable_result_log
|
|
|
|
# Execute OPTIMIZE TABLE after the table is copied to execute optimized ddl
|
|
# callback during backup, which, in turns, will create t1.new file in backup
|
|
# directory.
|
|
--let after_copy_test_t1=OPTIMIZE TABLE test.t1;
|
|
|
|
--echo # incremental backup
|
|
--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$inc_dir --incremental-basedir=$base_dir --dbug=+d,mariabackup_events
|
|
|
|
--echo # prepare
|
|
--exec $XTRABACKUP --prepare --target-dir=$base_dir
|
|
|
|
# If the tablespace is created during delta tablespace open procedure, then
|
|
# crypt data will be not written, and page corruption test will not pass
|
|
# when some redo log event is executed, and --prepare will fail.
|
|
--echo # incremental prepare
|
|
--exec $XTRABACKUP --prepare --target-dir=$base_dir --incremental-dir=$inc_dir
|
|
|
|
--enable_result_log
|
|
|
|
SET GLOBAL innodb_log_optimize_ddl=@old_innodb_log_optimize_ddl;
|
|
SET GLOBAL innodb_page_cleaner_disabled_debug=@old_innodb_page_cleaner_disabled_debug;
|
|
SET GLOBAL debug_dbug=@old_debug_dbug;
|
|
|
|
--echo # Restore and check results
|
|
--let $targetdir=$base_dir
|
|
--source include/restart_and_restore.inc
|
|
--enable_result_log
|
|
|
|
SELECT count(*) FROM t1;
|
|
|
|
# Cleanup
|
|
DROP TABLE t1;
|
|
--rmdir $base_dir
|
|
--rmdir $inc_dir
|