summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extra/mariabackup/xtrabackup.cc70
-rw-r--r--mysql-test/suite/mariabackup/nolock_ddl_during_backup_end.result2
-rw-r--r--mysql-test/suite/mariabackup/nolock_ddl_during_backup_end.test14
3 files changed, 81 insertions, 5 deletions
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index d506228e8c6..9d453e5f9ad 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -588,7 +588,7 @@ std::string filename_to_spacename(const byte *filename, size_t len)
@param[in] len length of name, in bytes
@param[in] new_name new file name (NULL if not rename)
@param[in] new_len length of new_name, in bytes (0 if NULL) */
-void backup_file_op(ulint space_id, const byte* flags,
+static void backup_file_op(ulint space_id, const byte* flags,
const byte* name, ulint len,
const byte* new_name, ulint new_len)
{
@@ -616,19 +616,71 @@ void backup_file_op(ulint space_id, const byte* flags,
}
+/*
+ This callback is called if DDL operation is detected,
+ at the end of backup
+
+ Normally, DDL operations are blocked due to FTWRL,
+ but in rare cases of --no-lock, they are not.
+
+ We will abort backup in this case.
+*/
+static void backup_file_op_fail(ulint space_id, const byte* flags,
+ const byte* name, ulint len,
+ const byte* new_name, ulint new_len)
+{
+ ut_a(opt_no_lock);
+ bool fail;
+ if (flags) {
+ msg("DDL tracking : create %zu \"%.*s\": %x\n",
+ space_id, int(len), name, mach_read_from_4(flags));
+ std::string spacename = filename_to_spacename(name, len);
+ fail = !check_if_skip_table(spacename.c_str());
+ }
+ else if (new_name) {
+ msg("DDL tracking : rename %zu \"%.*s\",\"%.*s\"\n",
+ space_id, int(len), name, int(new_len), new_name);
+ std::string spacename = filename_to_spacename(name, len);
+ std::string new_spacename = filename_to_spacename(new_name, new_len);
+ fail = !check_if_skip_table(spacename.c_str()) || !check_if_skip_table(new_spacename.c_str());
+ }
+ else {
+ std::string spacename = filename_to_spacename(name, len);
+ fail = !check_if_skip_table(spacename.c_str());
+ msg("DDL tracking : delete %zu \"%.*s\"\n", space_id, int(len), name);
+ }
+ if (fail) {
+ msg("ERROR : DDL operation detected in the late phase of backup."
+ "Backup is inconsistent. Remove --no-lock option to fix.\n");
+ exit(EXIT_FAILURE);
+ }
+}
+
+
/** Callback whenever MLOG_INDEX_LOAD happens.
@param[in] space_id space id to check */
static void backup_optimized_ddl_op(ulint space_id)
{
- // TODO : handle incremental
- if (xtrabackup_incremental)
- return;
-
pthread_mutex_lock(&backup_mutex);
ddl_tracker.optimized_ddl.insert(space_id);
pthread_mutex_unlock(&backup_mutex);
}
+/*
+ Optimized DDL callback at the end of backup that
+ run with --no-lock. Usually aborts the backup.
+*/
+static void backup_optimized_ddl_op_fail(ulint space_id) {
+ ut_a(opt_no_lock);
+ msg("DDL tracking : optimized DDL on space %zu\n");
+ if (ddl_tracker.tables_in_backup.find(space_id) != ddl_tracker.tables_in_backup.end()) {
+ msg("ERROR : Optimized DDL operation detected in the late phase of backup."
+ "Backup is inconsistent. Remove --no-lock option to fix.\n");
+ exit(EXIT_FAILURE);
+ }
+}
+
+
/** Callback whenever MLOG_TRUNCATE happens. */
static void backup_truncate_fail()
{
@@ -4383,6 +4435,14 @@ void backup_fix_ddl(void)
std::set<std::string> dropped_tables;
std::map<std::string, std::string> renamed_tables;
+ /* Disable further DDL on backed up tables (only needed for --no-lock).*/
+ pthread_mutex_lock(&backup_mutex);
+ log_file_op = backup_file_op_fail;
+ log_optimized_ddl_op = backup_optimized_ddl_op_fail;
+ pthread_mutex_unlock(&backup_mutex);
+
+ DBUG_MARIABACKUP_EVENT("backup_fix_ddl",0);
+
for (space_id_to_name_t::iterator iter = ddl_tracker.tables_in_backup.begin();
iter != ddl_tracker.tables_in_backup.end();
iter++) {
diff --git a/mysql-test/suite/mariabackup/nolock_ddl_during_backup_end.result b/mysql-test/suite/mariabackup/nolock_ddl_during_backup_end.result
new file mode 100644
index 00000000000..1bd3052b708
--- /dev/null
+++ b/mysql-test/suite/mariabackup/nolock_ddl_during_backup_end.result
@@ -0,0 +1,2 @@
+CREATE TABLE t1(i int) ENGINE=INNODB;
+# xtrabackup backup
diff --git a/mysql-test/suite/mariabackup/nolock_ddl_during_backup_end.test b/mysql-test/suite/mariabackup/nolock_ddl_during_backup_end.test
new file mode 100644
index 00000000000..f6bc51bd9a6
--- /dev/null
+++ b/mysql-test/suite/mariabackup/nolock_ddl_during_backup_end.test
@@ -0,0 +1,14 @@
+--source include/have_debug.inc
+let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
+mkdir $targetdir;
+
+CREATE TABLE t1(i int) ENGINE=INNODB;
+
+# this will table and populate it, after backup has list of tables to be copied
+--let backup_fix_ddl=BEGIN NOT ATOMIC DROP TABLE test.t1;DO SLEEP(10000); END
+echo # xtrabackup backup;
+--disable_result_log
+error 1;
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --no-lock --dbug=+d,mariabackup_events;
+--enable_result_log
+rmdir $targetdir;