mariadb/mysql-test/suite/mariabackup/alter_copy_excluded.test
Marko Mäkelä f778a5d5e2 MDEV-25854: Remove garbage tables after restoring a backup
In commit 1c5ae99194 (MDEV-25666)
we had changed Mariabackup so that it would no longer skip files
whose names start with #sql. This turned out to be wrong.
Because operations on such named files are not protected by any
locks in the server, it is not safe to copy them.

Not copying the files may make the InnoDB data dictionary
inconsistent with the file system. So, we must do something
in InnoDB to adjust for that.

If InnoDB is being started up without the redo log (ib_logfile0)
or with a zero-length log file, we will assume that the server
was restored from a backup, and adjust things as follows:

dict_check_sys_tables(), fil_ibd_open(): Do not complain about
missing #sql files if they would be dropped a little later.

dict_stats_update_if_needed(): Never add #sql tables to
the recomputing queue. This avoids a potential race condition when
dropping the garbage tables.

drop_garbage_tables_after_restore(): Try to drop any garbage tables.

innodb_ddl_recovery_done(): Invoke drop_garbage_tables_after_restore()
if srv_start_after_restore (a new flag) was set and we are not in
read-only mode (innodb_read_only=ON or innodb_force_recovery>3).

The tests and dbug_mariabackup_event() instrumentation
were developed by Vladislav Vaintroub, who also reviewed this.
2021-06-17 13:46:16 +03:00

65 lines
2.2 KiB
Text

--source include/have_innodb.inc
--source include/have_debug.inc
# The test demonstrates that intermediate tables (ALTER TABLE...ALGORITHM=COPY)
# will not be included in a backup.
echo # xtrabackup backup;
let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
CREATE TABLE t1(i int) ENGINE=InnoDB;
INSERT into t1 values(1);
connect con2, localhost, root,,;
connection con2;
SET debug_sync='copy_data_between_tables_before_reset_backup_lock SIGNAL go WAIT_FOR after_backup_stage_block_commit' ;
DELIMITER |;
send SET debug_sync='now WAIT_FOR after_backup_stage_start';ALTER TABLE test.t1 FORCE, algorithm=COPY;|
DELIMITER ;|
connection default;
# Setup mariabackup events
# - After BACKUP STAGE START , let concurrent ALTER run, wand wait for it to create temporary tables
# - After BACKUP STAGE COMMIT, check that temporary files are in the database
let after_backup_stage_start=SET debug_sync='now SIGNAL after_backup_stage_start WAIT_FOR go';
DELIMITER |;
# The following query only works if there are innodb "intermediate" tables
# in the system tables , which we want to prove there
let after_backup_stage_block_commit=
IF (SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.innodb_sys_tablespaces WHERE name like '%/#sql%') THEN
SET debug_sync='now SIGNAL after_backup_stage_block_commit';
END IF|
DELIMITER ;|
--disable_result_log
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --dbug=+d,mariabackup_events;
--enable_result_log
# There should be no temp files in the backup.
--list_files $targetdir/test #sql*
connection con2;
#Wait for ALTER to finish, cleanup
reap;
SET debug_sync='RESET';
disconnect con2;
connection default;
echo # xtrabackup prepare;
--disable_result_log
exec $XTRABACKUP --prepare --target-dir=$targetdir;
-- source include/restart_and_restore.inc
--enable_result_log
# Check there are no temp tablespaces in sys_tablespaces, after backup
SELECT COUNT(*) AS expect_0 FROM INFORMATION_SCHEMA.innodb_sys_tablespaces WHERE name like '%/#sql%';
SELECT * FROM t1;
DROP TABLE t1;
# Restart once again to clear first_start_after_backup flag
# This is to catch potential warnings, since "missing file" for #sql is suppressed
# during the first start after backup
--source include/restart_mysqld.inc
rmdir $targetdir;