Skip to content

Commit 76aafdb

Browse files
MDEV-38041: MariaBackup fails during rollback of inplace FTS alter table
Problem: ======== When an inplace ALTER operation is rolled back, InnoDB drops intermediate tables and their associated FTS internal tables. However, MariaBackup's DDL tracking can incorrectly report this as a backup failure. The issue occurs because backup_set_alter_copy_lock() downgrades the MDL_BACKUP_DDL lock before the inplace phase of ALTER, allowing FTS internal tables to be dropped during the later phases of backup when DDL tracking is still active. Solution: ======== backup_file_op_fail(): Ignore delete operations on FTS internal tables when not using --no-lock option, preventing false positive backup failures.
1 parent eb5712b commit 76aafdb

File tree

4 files changed

+71
-1
lines changed

4 files changed

+71
-1
lines changed

extra/mariabackup/backup_copy.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,6 +1462,7 @@ bool backup_start(ds_ctxt *ds_data, ds_ctxt *ds_meta,
14621462

14631463
corrupted_pages.backup_fix_ddl(ds_data, ds_meta);
14641464

1465+
DBUG_MARIABACKUP_EVENT("after_backup_fix_ddl", {});
14651466
// There is no need to stop slave thread before coping non-Innodb data when
14661467
// --no-lock option is used because --no-lock option requires that no DDL or
14671468
// DML to non-transaction tables can occur.

extra/mariabackup/xtrabackup.cc

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,19 @@ static void backup_file_op_fail(uint32_t space_id, int type,
10721072
filename_to_spacename(name, len).c_str());
10731073
msg("DDL tracking : delete %" PRIu32 " \"%.*s\"",
10741074
space_id, int(len), name);
1075-
error= "delete";
1075+
if (fail && !opt_no_lock &&
1076+
check_if_fts_table(
1077+
filename_to_spacename(name, len).c_str())) {
1078+
/* Ignore the FTS internal table because InnoDB does
1079+
drop intermediate table and their associative FTS
1080+
internal table as a part of inplace rollback operation.
1081+
backup_set_alter_copy_lock() downgrades the
1082+
MDL_BACKUP_DDL before inplace phase of alter.
1083+
This leads to the FTS internal table being
1084+
dropped in the late phase of backup. */
1085+
fail = false;
1086+
}
1087+
error= "delete";
10761088
break;
10771089
default:
10781090
ut_ad(0);

mysql-test/suite/mariabackup/alter_copy_race.result

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,21 @@ SELECT * FROM t1;
2222
i
2323
1
2424
DROP TABLE t1;
25+
#
26+
# MDEV-38041 MariaBackup fails during rollback of
27+
# inplace FTS alter table
28+
#
29+
CREATE TABLE t1(f1 int, f2 char(100), fulltext(f2)) ENGINE=InnoDB;
30+
INSERT into t1 values(1, "MariaDB"), (1, "MySQL");
31+
connect con2, localhost, root,,;
32+
set lock_wait_timeout=1;
33+
SET debug_sync='copy_data_between_tables_before_reset_backup_lock SIGNAL go WAIT_FOR after_backup_stage_block_commit';
34+
SET debug_sync='alter_table_after_temp_table_drop SIGNAL temp_table_dropped';
35+
SET debug_sync='now WAIT_FOR after_backup_stage_start';ALTER TABLE test.t1 ADD PRIMARY KEY(f1), algorithm=COPY;|
36+
connection default;
37+
connection con2;
38+
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
39+
SET debug_sync='RESET';
40+
disconnect con2;
41+
connection default;
42+
DROP TABLE t1;

mysql-test/suite/mariabackup/alter_copy_race.test

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,42 @@ exec $XTRABACKUP --prepare --target-dir=$targetdir;
4949
SELECT * FROM t1;
5050
DROP TABLE t1;
5151
rmdir $targetdir;
52+
53+
--echo #
54+
--echo # MDEV-38041 MariaBackup fails during rollback of
55+
--echo # inplace FTS alter table
56+
--echo #
57+
58+
let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
59+
60+
CREATE TABLE t1(f1 int, f2 char(100), fulltext(f2)) ENGINE=InnoDB;
61+
INSERT into t1 values(1, "MariaDB"), (1, "MySQL");
62+
63+
connect con2, localhost, root,,;
64+
set lock_wait_timeout=1;
65+
SET debug_sync='copy_data_between_tables_before_reset_backup_lock SIGNAL go WAIT_FOR after_backup_stage_block_commit';
66+
SET debug_sync='alter_table_after_temp_table_drop SIGNAL temp_table_dropped';
67+
DELIMITER |;
68+
send SET debug_sync='now WAIT_FOR after_backup_stage_start';ALTER TABLE test.t1 ADD PRIMARY KEY(f1), algorithm=COPY;|
69+
DELIMITER ;|
70+
connection default;
71+
72+
# setup mariabackup events
73+
let backup_fix_ddl=;
74+
let after_backup_stage_start=SET debug_sync='now SIGNAL after_backup_stage_start WAIT_FOR go';
75+
let after_backup_stage_block_commit=SET debug_sync='now SIGNAL after_backup_stage_block_commit';
76+
let after_backup_fix_ddl=SET debug_sync='now WAIT_FOR temp_table_dropped';
77+
let $backup_log=$MYSQLTEST_VARDIR/tmp/backup.log;
78+
--disable_result_log
79+
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --dbug=+d,mariabackup_events > $backup_log 2>&1;
80+
--enable_result_log
81+
82+
connection con2;
83+
--error ER_DUP_ENTRY
84+
reap;
85+
SET debug_sync='RESET';
86+
disconnect con2;
87+
88+
connection default;
89+
DROP TABLE t1;
90+
rmdir $targetdir;

0 commit comments

Comments
 (0)