Commit 922e7bad authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

MDEV-16791 mariabackup : Support DDL commands during backup

parent 9a4998a3
...@@ -1388,6 +1388,30 @@ backup_files(const char *from, bool prep_mode) ...@@ -1388,6 +1388,30 @@ backup_files(const char *from, bool prep_mode)
return(ret); return(ret);
} }
void backup_fix_ddl(void);
#define LSN_PREFIX_IN_SHOW_STATUS "\nLog sequence number "
static lsn_t get_current_lsn(MYSQL *connection) {
MYSQL_RES *res = xb_mysql_query(connection, "SHOW ENGINE INNODB STATUS", true, false);
if (!res)
return 0;
MYSQL_ROW row = mysql_fetch_row(res);
DBUG_ASSERT(row);
if (row) {
const char *p = strstr(row[2],LSN_PREFIX_IN_SHOW_STATUS);
DBUG_ASSERT(p);
if (p)
{
p += sizeof(LSN_PREFIX_IN_SHOW_STATUS) - 1;
return (lsn_t)strtoll(p, NULL, 10);
}
}
mysql_free_result(res);
return 0;
}
lsn_t server_lsn_after_lock;
extern void backup_wait_for_lsn(lsn_t lsn);
/** Start --backup */ /** Start --backup */
bool backup_start() bool backup_start()
{ {
...@@ -1407,6 +1431,7 @@ bool backup_start() ...@@ -1407,6 +1431,7 @@ bool backup_start()
if (!lock_tables(mysql_connection)) { if (!lock_tables(mysql_connection)) {
return(false); return(false);
} }
server_lsn_after_lock = get_current_lsn(mysql_connection);
} }
if (!backup_files(fil_path_to_mysql_datadir, false)) { if (!backup_files(fil_path_to_mysql_datadir, false)) {
...@@ -1421,6 +1446,10 @@ bool backup_start() ...@@ -1421,6 +1446,10 @@ bool backup_start()
rocksdb_create_checkpoint(); rocksdb_create_checkpoint();
} }
msg_ts("Waiting for log copy thread to read lsn %llu\n", (ulonglong)server_lsn_after_lock);
backup_wait_for_lsn(server_lsn_after_lock);
backup_fix_ddl();
// There is no need to stop slave thread before coping non-Innodb data when // There is no need to stop slave thread before coping non-Innodb data when
// --no-lock option is used because --no-lock option requires that no DDL or // --no-lock option is used because --no-lock option requires that no DDL or
// DML to non-transaction tables can occur. // DML to non-transaction tables can occur.
...@@ -2230,6 +2259,7 @@ static void rocksdb_lock_checkpoint() ...@@ -2230,6 +2259,7 @@ static void rocksdb_lock_checkpoint()
msg_ts("Could not obtain rocksdb checkpont lock\n"); msg_ts("Could not obtain rocksdb checkpont lock\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
mysql_free_result(res);
} }
static void rocksdb_unlock_checkpoint() static void rocksdb_unlock_checkpoint()
......
...@@ -1794,7 +1794,12 @@ mdl_lock_table(ulint space_id) ...@@ -1794,7 +1794,12 @@ mdl_lock_table(ulint space_id)
std::ostringstream lock_query; std::ostringstream lock_query;
lock_query << "SELECT 1 FROM " << full_table_name << " LIMIT 0"; lock_query << "SELECT 1 FROM " << full_table_name << " LIMIT 0";
msg_ts("Locking MDL for %s\n", full_table_name.c_str()); msg_ts("Locking MDL for %s\n", full_table_name.c_str());
xb_mysql_query(mdl_con, lock_query.str().c_str(), false, true); if (mysql_query(mdl_con, lock_query.str().c_str())) {
msg_ts("Warning : locking MDL failed for space id %zu, name %s\n", space_id, full_table_name.c_str());
} else {
MYSQL_RES *r = mysql_store_result(mdl_con);
mysql_free_result(r);
}
} }
pthread_mutex_unlock(&mdl_lock_con_mutex); pthread_mutex_unlock(&mdl_lock_con_mutex);
......
...@@ -108,6 +108,9 @@ Write to a datasink file. ...@@ -108,6 +108,9 @@ Write to a datasink file.
int int
ds_write(ds_file_t *file, const void *buf, size_t len) ds_write(ds_file_t *file, const void *buf, size_t len)
{ {
if (len == 0) {
return 0;
}
return file->datasink->write(file, (const uchar *)buf, len); return file->datasink->write(file, (const uchar *)buf, len);
} }
......
...@@ -131,14 +131,15 @@ Open a source file cursor and initialize the associated read filter. ...@@ -131,14 +131,15 @@ Open a source file cursor and initialize the associated read filter.
be skipped and XB_FIL_CUR_ERROR on error. */ be skipped and XB_FIL_CUR_ERROR on error. */
xb_fil_cur_result_t xb_fil_cur_result_t
xb_fil_cur_open( xb_fil_cur_open(
/*============*/ /*============*/
xb_fil_cur_t* cursor, /*!< out: source file cursor */ xb_fil_cur_t* cursor, /*!< out: source file cursor */
xb_read_filt_t* read_filter, /*!< in/out: the read filter */ xb_read_filt_t* read_filter, /*!< in/out: the read filter */
fil_node_t* node, /*!< in: source tablespace node */ fil_node_t* node, /*!< in: source tablespace node */
uint thread_n) /*!< thread number for diagnostics */ uint thread_n, /*!< thread number for diagnostics */
ulonglong max_file_size)
{ {
bool success; bool success;
int err;
/* Initialize these first so xb_fil_cur_close() handles them correctly /* Initialize these first so xb_fil_cur_close() handles them correctly
in case of error */ in case of error */
cursor->orig_buf = NULL; cursor->orig_buf = NULL;
...@@ -173,7 +174,7 @@ xb_fil_cur_open( ...@@ -173,7 +174,7 @@ xb_fil_cur_open(
"tablespace %s\n", "tablespace %s\n",
thread_n, cursor->abs_path); thread_n, cursor->abs_path);
return(XB_FIL_CUR_ERROR); return(XB_FIL_CUR_SKIP);
} }
mutex_enter(&fil_system->mutex); mutex_enter(&fil_system->mutex);
...@@ -194,14 +195,31 @@ xb_fil_cur_open( ...@@ -194,14 +195,31 @@ xb_fil_cur_open(
cursor->node = node; cursor->node = node;
cursor->file = node->handle; cursor->file = node->handle;
#ifdef _WIN32
if (stat(cursor->abs_path, &cursor->statinfo)) { HANDLE hDup;
msg("[%02u] mariabackup: error: cannot stat %s\n", DuplicateHandle(GetCurrentProcess(),cursor->file.m_file,
GetCurrentProcess(), &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
int filenr = _open_osfhandle((intptr_t)hDup, 0);
if (filenr < 0) {
err = EINVAL;
}
else {
err = _fstat64(filenr, &cursor->statinfo);
close(filenr);
}
#else
err = fstat(cursor->file.m_file, &cursor->statinfo);
#endif
if (max_file_size < (ulonglong)cursor->statinfo.st_size) {
cursor->statinfo.st_size = (ulonglong)max_file_size;
}
if (err) {
msg("[%02u] mariabackup: error: cannot fstat %s\n",
thread_n, cursor->abs_path); thread_n, cursor->abs_path);
xb_fil_cur_close(cursor); xb_fil_cur_close(cursor);
return(XB_FIL_CUR_ERROR); return(XB_FIL_CUR_SKIP);
} }
if (srv_file_flush_method == SRV_O_DIRECT if (srv_file_flush_method == SRV_O_DIRECT
...@@ -374,7 +392,9 @@ xb_fil_cur_close( ...@@ -374,7 +392,9 @@ xb_fil_cur_close(
/*=============*/ /*=============*/
xb_fil_cur_t *cursor) /*!< in/out: source file cursor */ xb_fil_cur_t *cursor) /*!< in/out: source file cursor */
{ {
cursor->read_filter->deinit(&cursor->read_filter_ctxt); if (cursor->read_filter) {
cursor->read_filter->deinit(&cursor->read_filter_ctxt);
}
free(cursor->orig_buf); free(cursor->orig_buf);
......
...@@ -57,7 +57,7 @@ struct xb_fil_cur_t { ...@@ -57,7 +57,7 @@ struct xb_fil_cur_t {
ulint space_size; /*!< space size in pages */ ulint space_size; /*!< space size in pages */
/** TODO: remove this default constructor */ /** TODO: remove this default constructor */
xb_fil_cur_t() : page_size(0), read_filter_ctxt() {} xb_fil_cur_t() : page_size(0), read_filter(0), read_filter_ctxt() {}
/** @return whether this is not a file-per-table tablespace */ /** @return whether this is not a file-per-table tablespace */
bool is_system() const bool is_system() const
...@@ -86,7 +86,8 @@ xb_fil_cur_open( ...@@ -86,7 +86,8 @@ xb_fil_cur_open(
xb_fil_cur_t* cursor, /*!< out: source file cursor */ xb_fil_cur_t* cursor, /*!< out: source file cursor */
xb_read_filt_t* read_filter, /*!< in/out: the read filter */ xb_read_filt_t* read_filter, /*!< in/out: the read filter */
fil_node_t* node, /*!< in: source tablespace node */ fil_node_t* node, /*!< in: source tablespace node */
uint thread_n); /*!< thread number for diagnostics */ uint thread_n, /*!< thread number for diagnostics */
ulonglong max_file_size = ULLONG_MAX);
/************************************************************************ /************************************************************************
Reads and verifies the next block of pages from the source Reads and verifies the next block of pages from the source
......
This diff is collapsed.
# xtrabackup backup
# xtrabackup prepare
# shutdown server
# remove datadir
# xtrabackup move back
# restart server
SELECT COUNT(*) from t1;
COUNT(*)
10000
DROP TABLE t1;
--source include/have_debug.inc
let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
mkdir $targetdir;
# this will table and populate it, after backup has list of tables to be copied
--let after_load_tablespaces =CREATE TABLE test.t1 ENGINE=INNODB SELECT UUID() from test.seq_1_to_10000
echo # xtrabackup backup;
--disable_result_log
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --dbug=+d,mariabackup_events;
--enable_result_log
--let after_load_tables=
echo # xtrabackup prepare;
--disable_result_log
exec $XTRABACKUP --prepare --target-dir=$targetdir;
-- source include/restart_and_restore.inc
--enable_result_log
# Check that new table is there after restore.
SELECT COUNT(*) from t1;
DROP TABLE t1;
rmdir $targetdir;
# xtrabackup backup
# xtrabackup prepare
DROP TABLE t;
# shutdown server
# remove datadir
# xtrabackup move back
# restart server
SELECT * FROM t;
i
DROP TABLE t;
--source include/have_debug.inc
let $table_data_dir=$MYSQLTEST_VARDIR/tmp/ddir;
let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
mkdir $table_data_dir;
--replace_result $table_data_dir table_data_dir
--let after_load_tablespaces=CREATE TABLE test.t(i int) ENGINE=INNODB DATA DIRECTORY='$table_data_dir'
echo # xtrabackup backup;
let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
--disable_result_log
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --dbug=+d,mariabackup_events;
--enable_result_log
--source include/shutdown_mysqld.inc
echo # xtrabackup prepare;
--disable_result_log
exec $XTRABACKUP --prepare --target-dir=$targetdir;
--source include/start_mysqld.inc
DROP TABLE t;
rmdir $table_data_dir;
-- source include/restart_and_restore.inc
--enable_result_log
SELECT * FROM t;
DROP TABLE t;
rmdir $targetdir;
rmdir $table_data_dir;
unsupported_redo : MDEV-16791 allows optimized redo
\ No newline at end of file
CREATE TABLE t1 (i int) ENGINE=INNODB;
CREATE TABLE t2 (i int) ENGINE=INNODB;
CREATE TABLE t3 (i int) ENGINE=INNODB;
# xtrabackup prepare
# shutdown server
# remove datadir
# xtrabackup move back
# restart server
CREATE TABLE t1(i int);
DROP TABLE t1;
CREATE TABLE t2(i int);
DROP TABLE t2;
DROP TABLE t3;
--source include/have_debug.inc
let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
CREATE TABLE t1 (i int) ENGINE=INNODB;
CREATE TABLE t2 (i int) ENGINE=INNODB;
CREATE TABLE t3 (i int) ENGINE=INNODB;
--let before_copy_test_t1=DROP TABLE test.t1
--let after_copy_test_t2=DROP TABLE test.t2;
--disable_result_log
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --dbug=+d,mariabackup_events;
--enable_result_log
echo # xtrabackup prepare;
--disable_result_log
exec $XTRABACKUP --prepare --target-dir=$targetdir;
-- source include/restart_and_restore.inc
--enable_result_log
#check that the table t1 does not exist in backup
CREATE TABLE t1(i int);
DROP TABLE t1;
CREATE TABLE t2(i int);
DROP TABLE t2;
DROP TABLE t3;
rmdir $targetdir;
call mtr.add_suppression("InnoDB: New log files created");
CREATE TABLE t1(i INT PRIMARY KEY) ENGINE INNODB;
CREATE TABLE t2(i INT PRIMARY KEY) ENGINE INNODB;
CREATE TABLE t3(i INT) ENGINE INNODB;
# Create full backup , modify table, then create incremental/differential backup
INSERT into t1 values(1);
# Prepare full backup, apply incremental one
# Restore and check results
# shutdown server
# remove datadir
# xtrabackup move back
# restart server
CREATE TABLE t1(i int);
DROP TABLE t1;
SELECT * from t1_renamed;
i
1
DROP TABLE t1_renamed;
CREATE TABLE t2(i INT PRIMARY KEY) ENGINE INNODB;
DROP TABLE t2;
DROP TABLE t3;
DROP TABLE t4;
--source include/have_debug.inc
call mtr.add_suppression("InnoDB: New log files created");
let $basedir=$MYSQLTEST_VARDIR/tmp/backup;
let $incremental_dir=$MYSQLTEST_VARDIR/tmp/backup_inc1;
CREATE TABLE t1(i INT PRIMARY KEY) ENGINE INNODB;
CREATE TABLE t2(i INT PRIMARY KEY) ENGINE INNODB;
CREATE TABLE t3(i INT) ENGINE INNODB;
echo # Create full backup , modify table, then create incremental/differential backup;
--disable_result_log
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir;
--enable_result_log
INSERT into t1 values(1);
--let after_load_tablespaces=CREATE TABLE test.t4 ENGINE=INNODB SELECT UUID() from test.seq_1_to_10000
--let after_copy_test_t1=RENAME TABLE test.t1 TO test.t1_renamed
--let after_copy_test_t2=DROP TABLE test.t2
--let after_copy_test_t3=CREATE INDEX a_i ON test.t3(i);
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$incremental_dir --incremental-basedir=$basedir --dbug=+d,mariabackup_events;
--let after_load_tablespaces=
--disable_result_log
echo # Prepare full backup, apply incremental one;
exec $XTRABACKUP --apply-log-only --prepare --target-dir=$basedir;
exec $XTRABACKUP --prepare --target-dir=$basedir --incremental-dir=$incremental_dir ;
echo # Restore and check results;
let $targetdir=$basedir;
-- source include/restart_and_restore.inc
--enable_result_log
# Test that t1 does not exist, but t1_renamed does
CREATE TABLE t1(i int);
DROP TABLE t1;
SELECT * from t1_renamed;
DROP TABLE t1_renamed;
# Test that t2 does not exist;
CREATE TABLE t2(i INT PRIMARY KEY) ENGINE INNODB;
DROP TABLE t2;
DROP TABLE t3;
DROP TABLE t4;
# Cleanup
rmdir $basedir;
rmdir $incremental_dir;
CREATE TABLE t1(i INT PRIMARY KEY auto_increment, a int) ENGINE INNODB;
INSERT INTO t1(a) SELECT * from seq_1_to_10000;
# xtrabackup backup
t1.frm
t1.ibd
t1.new
# xtrabackup prepare
# shutdown server
# remove datadir
# xtrabackup move back
# restart server
SELECT COUNT(*) from t1;
COUNT(*)
10000
DROP TABLE t1;
--source include/have_debug.inc
CREATE TABLE t1(i INT PRIMARY KEY auto_increment, a int) ENGINE INNODB;
INSERT INTO t1(a) SELECT * from seq_1_to_10000;
let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
let after_copy_test_t1=CREATE INDEX a_ind ON test.t1(a) ALGORITHM=INPLACE;
echo # xtrabackup backup;
--disable_result_log
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --dbug=+d,mariabackup_events;
--enable_result_log
--list_files $targetdir/test t1*
--let before_copy_test_t1=
echo # xtrabackup prepare;
--disable_result_log
exec $XTRABACKUP --prepare --target-dir=$targetdir;
-- source include/restart_and_restore.inc
--enable_result_log
# Check that new table is there after restore.
SELECT COUNT(*) from t1;
DROP TABLE t1;
rmdir $targetdir;
CREATE TABLE t1(i int) ENGINE=INNODB;
CREATE TABLE t2(i int) ENGINE=INNODB;
CREATE TABLE t3(a CHAR(36)) ENGINE INNODB;
INSERT INTO t3 SELECT UUID() FROM seq_1_to_1000;
# xtrabackup backup
# xtrabackup prepare
# shutdown server
# remove datadir
# xtrabackup move back
# restart server
SELECT COUNT(*) from t1;
COUNT(*)
100
SELECT COUNT(*) from t2;
COUNT(*)
1000
SELECT COUNT(*) from t3;
COUNT(*)
1000
DROP INDEX index_a ON t3;
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
--source include/have_debug.inc
let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
mkdir $targetdir;
CREATE TABLE t1(i int) ENGINE=INNODB;
CREATE TABLE t2(i int) ENGINE=INNODB;
CREATE TABLE t3(a CHAR(36)) ENGINE INNODB;
INSERT INTO t3 SELECT UUID() FROM seq_1_to_1000;
# this will table and populate it, after backup has list of tables to be copied
--let before_copy_test_t1=BEGIN NOT ATOMIC DROP TABLE test.t1;CREATE TABLE test.t1 ENGINE=INNODB SELECT UUID() from test.seq_1_to_100; END
--let after_copy_test_t2=BEGIN NOT ATOMIC DROP TABLE test.t2;CREATE TABLE test.t2 ENGINE=INNODB SELECT UUID() from test.seq_1_to_1000; END
--let after_copy_test_t3=ALTER TABLE test.t3 ADD INDEX index_a(a),ALGORITHM=COPY
echo # xtrabackup backup;
--disable_result_log
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --close-files --dbug=+d,mariabackup_events;
--enable_result_log
--let after_load_tables=
echo # xtrabackup prepare;
--disable_result_log
exec $XTRABACKUP --prepare --target-dir=$targetdir;
-- source include/restart_and_restore.inc
--enable_result_log
# Check that new table is there after restore.
SELECT COUNT(*) from t1;
SELECT COUNT(*) from t2;
SELECT COUNT(*) from t3;
DROP INDEX index_a ON t3;
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
rmdir $targetdir;
CREATE TABLE t1(i int) ENGINE INNODB;
INSERT into t1 values(1);
CREATE TABLE t2(i int) ENGINE INNODB;
INSERT INTO t2 values(2);
CREATE TABLE t3(i int) ENGINE INNODB;
CREATE TABLE t4(i int) ENGINE INNODB;
CREATE TABLE a(a int) ENGINE INNODB;
INSERT INTO a values(1);
CREATE TABLE b(b CHAR(1)) ENGINE INNODB;
INSERT INTO b VALUES('b');
CREATE TABLE a1(a1 int) ENGINE INNODB;
INSERT INTO a1 VALUES(1);
CREATE TABLE b1(b1 CHAR(2)) ENGINE INNODB;
INSERT INTO b1 VALUES('b1');
# xtrabackup prepare
# shutdown server
# remove datadir
# xtrabackup move back
# restart server
CREATE TABLE t1(i int);
DROP TABLE t1;
SELECT * from t1_renamed;
i
1
DROP TABLE t1_renamed;
CREATE TABLE t2(i int);
DROP TABLE t2;
SELECT * from t2_renamed;
i
2
DROP TABLE t2_renamed;
SELECT * from t3;
i
3
DROP TABLE t3;
SELECT * from t4;
i
DROP TABLE t4;
CREATE TABLE tmp(i int);
DROP TABLE tmp;
SELECT * FROM a;
b
b
SELECT * FROM b;
a
1
SELECT * FROM a1;
b1
b1
SELECT * FROM b1;
a1
1
DROP TABLE a,b,a1,b1;
--source include/have_debug.inc
let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
mkdir $targetdir;
CREATE TABLE t1(i int) ENGINE INNODB;
INSERT into t1 values(1);
CREATE TABLE t2(i int) ENGINE INNODB;
INSERT INTO t2 values(2);
CREATE TABLE t3(i int) ENGINE INNODB;
CREATE TABLE t4(i int) ENGINE INNODB;
CREATE TABLE a(a int) ENGINE INNODB;
INSERT INTO a values(1);
CREATE TABLE b(b CHAR(1)) ENGINE INNODB;
INSERT INTO b VALUES('b');
CREATE TABLE a1(a1 int) ENGINE INNODB;
INSERT INTO a1 VALUES(1);
CREATE TABLE b1(b1 CHAR(2)) ENGINE INNODB;
INSERT INTO b1 VALUES('b1');
# Test renames before of after copying tablespaces
--let before_copy_test_t1=RENAME TABLE test.t1 TO test.t1_renamed
--let after_copy_test_t2=RENAME TABLE test.t2 TO test.t2_renamed
--let after_copy_test_t3=BEGIN NOT ATOMIC RENAME TABLE test.t3 TO test.t3_tmp; INSERT INTO test.t3_tmp VALUES(3); RENAME TABLE test.t3_tmp TO test.t3; END
--let before_copy_test_t4=RENAME TABLE test.t4 TO test.t4_tmp
--let after_copy_test_t4=RENAME TABLE test.t4_tmp TO test.t4
# Test circular renames
--let before_copy_test_b=RENAME TABLE test.a to test.tmp, test.b to test.a, test.tmp to test.b
--let after_copy_test_b1=RENAME TABLE test.a1 to test.tmp, test.b1 to test.a1, test.tmp to test.b1
--disable_result_log
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --dbug=+d,mariabackup_events;
--enable_result_log
--let before_copy_test_t1=''
--let after_copy_test_t2=''
--let before_copy_test_a=''
--let after_copy_test_a1=''
echo # xtrabackup prepare;
--disable_result_log
exec $XTRABACKUP --prepare --target-dir=$targetdir;
-- source include/restart_and_restore.inc
--enable_result_log
# the table was renamed from t1 to t1_renamed
# make sure t1 does not exist, and t1_renamed does.
CREATE TABLE t1(i int);
DROP TABLE t1;
SELECT * from t1_renamed;
DROP TABLE t1_renamed;
CREATE TABLE t2(i int);
DROP TABLE t2;
SELECT * from t2_renamed;
DROP TABLE t2_renamed;
#rename to itself
SELECT * from t3;
DROP TABLE t3;
SELECT * from t4;
DROP TABLE t4;
# For circular renames , make sure intermediate tables do not exist
CREATE TABLE tmp(i int);
DROP TABLE tmp;
SELECT * FROM a;
SELECT * FROM b;
SELECT * FROM a1;
SELECT * FROM b1;
DROP TABLE a,b,a1,b1;
rmdir $targetdir;
CREATE TABLE t1(i int) ENGINE INNODB; CREATE TABLE t1(i int) ENGINE INNODB;
FOUND 1 /failed to execute query SELECT 1 FROM/ in backup.log # xtrabackup prepare
# shutdown server
# remove datadir
# xtrabackup move back
# restart server
CREATE TABLE t1(i int);
DROP TABLE t1;
SELECT * from t2;
i
DROP TABLE t2; DROP TABLE t2;
--source include/have_debug.inc --source include/have_debug.inc
let $targetdir=$MYSQLTEST_VARDIR/backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
mkdir $targetdir; mkdir $targetdir;
CREATE TABLE t1(i int) ENGINE INNODB; CREATE TABLE t1(i int) ENGINE INNODB;
--error 1 exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --lock-ddl-per-table --dbug=+d,rename_during_mdl_lock_table;
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --lock-ddl-per-table --dbug=+d,rename_during_mdl_lock_table 2>$targetdir/backup.log;
let SEARCH_FILE=$targetdir/backup.log; echo # xtrabackup prepare;
let SEARCH_PATTERN=failed to execute query SELECT 1 FROM; --disable_result_log
source include/search_pattern_in_file.inc; exec $XTRABACKUP --prepare --target-dir=$targetdir;
-- source include/restart_and_restore.inc
--enable_result_log
# the table was renamed from t1 to t2
# make sure t1 does not exist, and t2 does
CREATE TABLE t1(i int);
DROP TABLE t1;
SELECT * from t2;
DROP TABLE t2; DROP TABLE t2;
rmdir $targetdir; rmdir $targetdir;
--innodb --loose-changed_page_bitmaps --innodb-sys-tables --innodb-flush-log-at-trx-commit=2 --innodb --loose-changed_page_bitmaps --innodb-sys-tables --innodb-flush-log-at-trx-commit=2 --sequence
/***************************************************************************** /*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation. Copyright (c) 2017, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -153,9 +153,21 @@ bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t store, bool apply); ...@@ -153,9 +153,21 @@ bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t store, bool apply);
/** Moves the parsing buffer data left to the buffer start. */ /** Moves the parsing buffer data left to the buffer start. */
void recv_sys_justify_left_parsing_buf(); void recv_sys_justify_left_parsing_buf();
/** Backup function checks whether the space id belongs to /** Report optimized DDL operation (without redo log), corresponding to MLOG_INDEX_LOAD.
the skip table list given in the mariabackup option. */ @param[in] space_id tablespace identifier
extern bool(*check_if_backup_includes)(ulint space_id); */
extern void(*log_optimized_ddl_op)(ulint space_id);
/** 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)
@param[in] name file name (not NUL-terminated)
@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) */
extern void (*log_file_op)(ulint space_id, const byte* flags,
const byte* name, ulint len,
const byte* new_name, ulint new_len);
/** Block of log record data */ /** Block of log record data */
struct recv_data_t{ struct recv_data_t{
......
...@@ -169,9 +169,21 @@ typedef std::map< ...@@ -169,9 +169,21 @@ typedef std::map<
static recv_spaces_t recv_spaces; static recv_spaces_t recv_spaces;
/** Backup function checks whether the space id belongs to /** Report optimized DDL operation (without redo log), corresponding to MLOG_INDEX_LOAD.
the skip table list given in the mariabackup option. */ @param[in] space_id tablespace identifier
bool(*check_if_backup_includes)(ulint space_id); */
void (*log_optimized_ddl_op)(ulint space_id);
/** 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)
@param[in] name file name (not NUL-terminated)
@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 (*log_file_op)(ulint space_id, const byte* flags,
const byte* name, ulint len,
const byte* new_name, ulint new_len);
/** Process a file name from a MLOG_FILE_* record. /** Process a file name from a MLOG_FILE_* record.
@param[in,out] name file name @param[in,out] name file name
...@@ -381,9 +393,13 @@ fil_name_parse( ...@@ -381,9 +393,13 @@ fil_name_parse(
fil_name_process( fil_name_process(
reinterpret_cast<char*>(ptr), len, space_id, true); reinterpret_cast<char*>(ptr), len, space_id, true);
/* fall through */
break;
case MLOG_FILE_CREATE2: case MLOG_FILE_CREATE2:
if (log_file_op) {
log_file_op(space_id,
type == MLOG_FILE_CREATE2 ? ptr - 4 : NULL,
ptr, len, NULL, 0);
}
break; break;
case MLOG_FILE_RENAME2: case MLOG_FILE_RENAME2:
if (corrupt) { if (corrupt) {
...@@ -424,6 +440,11 @@ fil_name_parse( ...@@ -424,6 +440,11 @@ fil_name_parse(
reinterpret_cast<char*>(new_name), new_len, reinterpret_cast<char*>(new_name), new_len,
space_id, false); space_id, false);
if (log_file_op) {
log_file_op(space_id, NULL,
ptr, len, new_name, new_len);
}
if (!apply) { if (!apply) {
break; break;
} }
...@@ -2503,11 +2524,8 @@ bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t store, bool apply) ...@@ -2503,11 +2524,8 @@ bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t store, bool apply)
/* fall through */ /* fall through */
case MLOG_INDEX_LOAD: case MLOG_INDEX_LOAD:
if (type == MLOG_INDEX_LOAD) { if (type == MLOG_INDEX_LOAD) {
if (check_if_backup_includes if (log_optimized_ddl_op) {
&& !check_if_backup_includes(space)) { log_optimized_ddl_op(space);
ut_ad(srv_operation
== SRV_OPERATION_BACKUP);
return true;
} }
} }
/* fall through */ /* fall through */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment