Commit 0ddbec40 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-23335 MariaBackup Incremental Does Not Reflect Dropped/Created Databases

parent 489b5569
......@@ -57,6 +57,9 @@ Street, Fifth Floor, Boston, MA 02110-1335 USA
#include "backup_copy.h"
#include "backup_mysql.h"
#include <btr0btr.h>
#ifdef _WIN32
#include <direct.h> /* rmdir */
#endif
#define ROCKSDB_BACKUP_DIR "#rocksdb"
......@@ -1623,7 +1626,49 @@ bool backup_finish()
return(true);
}
bool
/*
Drop all empty database directories in the base backup
that do not exists in the icremental backup.
This effectively re-plays all DROP DATABASE statements happened
in between base backup and incremental backup creation time.
Note, only checking if base_dir/db/ is empty is not enough,
because inc_dir/db/db.opt might have been dropped for some reasons,
which may also result into empty base_dir/db/.
Only the fact that at the same time:
- base_dir/db/ exists
- inc_dir/db/ does not exist
means that DROP DATABASE happened.
*/
static void
ibx_incremental_drop_databases(const char *base_dir,
const char *inc_dir)
{
datadir_node_t node;
datadir_node_init(&node);
datadir_iter_t *it = datadir_iter_new(base_dir);
while (datadir_iter_next(it, &node)) {
if (node.is_empty_dir) {
char path[FN_REFLEN];
snprintf(path, sizeof(path), "%s/%s",
inc_dir, node.filepath_rel);
if (!directory_exists(path, false)) {
msg("Removing %s", node.filepath);
rmdir(node.filepath);
}
}
}
datadir_iter_free(it);
datadir_node_free(&node);
}
static bool
ibx_copy_incremental_over_full()
{
const char *ext_list[] = {"frm", "isl", "MYD", "MYI", "MAD", "MAI",
......@@ -1706,6 +1751,8 @@ ibx_copy_incremental_over_full()
}
copy_or_move_dir(path, ROCKSDB_BACKUP_DIR, true, true);
}
ibx_incremental_drop_databases(xtrabackup_target_dir,
xtrabackup_incremental_dir);
}
......
call mtr.add_suppression("InnoDB: New log files created");
#
# Start of 10.3 tests
#
#
# MDEV-23335 MariaBackup Incremental Does Not Reflect Dropped/Created Databases
#
CREATE DATABASE db1;
CREATE DATABASE db2;
CREATE TABLE db1.t1 (a INT) ENGINE=MyISAM;
CREATE TABLE db1.t2 (a INT) ENGINE=InnoDB;
# Create base backup
DROP DATABASE db1;
# Create incremental backup
# Remove incremental_dir/db2/db.opt file to make incremental_dir/db2/ empty
# Prepare base backup, apply incremental one
# shutdown server
# remove datadir
# xtrabackup move back
# restart server
# Expect no 'db1' in the output, because it was really dropped.
# Expect 'db2' in the ouput, because it was not dropped!
# (its incremental directory was emptied only)
SHOW DATABASES LIKE 'db%';
Database (db%)
db2
DROP DATABASE db2;
#
# End of 10.3 tests
#
--source include/have_innodb.inc
call mtr.add_suppression("InnoDB: New log files created");
--echo #
--echo # Start of 10.3 tests
--echo #
--echo #
--echo # MDEV-23335 MariaBackup Incremental Does Not Reflect Dropped/Created Databases
--echo #
--let $datadir=`SELECT @@datadir`
--let $basedir=$MYSQLTEST_VARDIR/tmp/backup
--let $incremental_dir=$MYSQLTEST_VARDIR/tmp/backup_inc1
# Create two databases:
# - db1 is dropped normally below
# - db2 is used to cover a corner case: its db.opt file is removed
# Incremental backup contains:
# - no directory for db1
# - an empty directory for db2 (after we remove db2/db.opt)
CREATE DATABASE db1;
CREATE DATABASE db2;
# Add some tables to db1
CREATE TABLE db1.t1 (a INT) ENGINE=MyISAM;
CREATE TABLE db1.t2 (a INT) ENGINE=InnoDB;
--echo # Create base backup
--disable_result_log
--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir
--enable_result_log
DROP DATABASE db1;
--echo # Create incremental backup
--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$incremental_dir --incremental-basedir=$basedir
--echo # Remove incremental_dir/db2/db.opt file to make incremental_dir/db2/ empty
--remove_file $incremental_dir/db2/db.opt
--echo # Prepare base backup, apply incremental one
--disable_result_log
--exec $XTRABACKUP --prepare --target-dir=$basedir
--exec $XTRABACKUP --prepare --target-dir=$basedir --incremental-dir=$incremental_dir
--enable_result_log
--let $targetdir=$basedir
--source include/restart_and_restore.inc
--enable_result_log
--echo # Expect no 'db1' in the output, because it was really dropped.
--echo # Expect 'db2' in the ouput, because it was not dropped!
--echo # (its incremental directory was emptied only)
SHOW DATABASES LIKE 'db%';
DROP DATABASE db2;
--rmdir $basedir
--rmdir $incremental_dir
--echo #
--echo # End of 10.3 tests
--echo #
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