summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2019-02-18 18:56:32 +0100
committerVladislav Vaintroub <wlad@mariadb.com>2019-02-18 18:59:05 +0100
commit3a42926c88f8c3c582a7af7e482f6aded0c74f89 (patch)
tree9a4e292f32e3a34a3c428507b8c96d3455bf70b1
parent40b4f9c907e58a4b65677cc9e5b3f5deca8b7cb3 (diff)
downloadmariadb-git-3a42926c88f8c3c582a7af7e482f6aded0c74f89.tar.gz
MDEV-18204 Fix rocksdb incremental backup
Fix incremental prepare to copy #rocksdb subdirectory from the incremental dir.
-rw-r--r--client/mysqltest.cc59
-rw-r--r--extra/mariabackup/backup_copy.cc13
-rw-r--r--include/my_sys.h1
-rw-r--r--mysql-test/suite/mariabackup/incremental_rocksdb.opt1
-rw-r--r--mysql-test/suite/mariabackup/incremental_rocksdb.result19
-rw-r--r--mysql-test/suite/mariabackup/incremental_rocksdb.test38
-rw-r--r--mysys/my_delete.c60
7 files changed, 133 insertions, 58 deletions
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 00bea466912..1a6c22573e0 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -4019,63 +4019,6 @@ void do_mkdir(struct st_command *command)
}
-/*
- Remove directory recursively.
-*/
-static int rmtree(const char *dir)
-{
- char path[FN_REFLEN];
- char sep[]={ FN_LIBCHAR, 0 };
- int err=0;
-
- MY_DIR *dir_info= my_dir(dir, MYF(MY_DONT_SORT | MY_WANT_STAT));
- if (!dir_info)
- return 1;
-
- for (uint i= 0; i < dir_info->number_of_files; i++)
- {
- FILEINFO *file= dir_info->dir_entry + i;
- /* Skip "." and ".." */
- if (!strcmp(file->name, ".") || !strcmp(file->name, ".."))
- continue;
-
- strxnmov(path, sizeof(path), dir, sep, file->name, NULL);
-
- if (!MY_S_ISDIR(file->mystat->st_mode))
- {
- err= my_delete(path, 0);
-#ifdef _WIN32
- /*
- On Windows, check and possible reset readonly attribute.
- my_delete(), or DeleteFile does not remove theses files.
- */
- if (err)
- {
- DWORD attr= GetFileAttributes(path);
- if (attr != INVALID_FILE_ATTRIBUTES &&
- (attr & FILE_ATTRIBUTE_READONLY))
- {
- SetFileAttributes(path, attr &~ FILE_ATTRIBUTE_READONLY);
- err= my_delete(path, 0);
- }
- }
-#endif
- }
- else
- err= rmtree(path);
-
- if(err)
- break;
- }
-
- my_dirend(dir_info);
-
- if (!err)
- err= rmdir(dir);
-
- return err;
-}
-
/*
SYNOPSIS
@@ -4103,7 +4046,7 @@ void do_rmdir(struct st_command *command)
DBUG_VOID_RETURN;
DBUG_PRINT("info", ("removing directory: %s", ds_dirname.str));
- if (rmtree(ds_dirname.str))
+ if (my_rmtree(ds_dirname.str, MYF(0)))
handle_command_error(command, 1, errno);
dynstr_free(&ds_dirname);
diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc
index b0ad000cb90..bd2f28baa92 100644
--- a/extra/mariabackup/backup_copy.cc
+++ b/extra/mariabackup/backup_copy.cc
@@ -1635,6 +1635,19 @@ ibx_copy_incremental_over_full()
}
+ if (directory_exists(ROCKSDB_BACKUP_DIR, false)) {
+ if (my_rmtree(ROCKSDB_BACKUP_DIR, MYF(0))) {
+ die("Can't remove " ROCKSDB_BACKUP_DIR);
+ }
+ }
+ snprintf(path, sizeof(path), "%s/" ROCKSDB_BACKUP_DIR, xtrabackup_incremental_dir);
+ if (directory_exists(path, false)) {
+ if (my_mkdir(ROCKSDB_BACKUP_DIR, 0777, MYF(0))) {
+ die("my_mkdir failed for " ROCKSDB_BACKUP_DIR);
+ }
+ copy_or_move_dir(path, ROCKSDB_BACKUP_DIR, true, true);
+ }
+
cleanup:
if (it != NULL) {
datadir_iter_free(it);
diff --git a/include/my_sys.h b/include/my_sys.h
index 3d233f8b6a6..50a659239b3 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -627,6 +627,7 @@ extern int (*mysys_test_invalid_symlink)(const char *filename);
extern int my_copy(const char *from,const char *to,myf MyFlags);
extern int my_delete(const char *name,myf MyFlags);
+extern int my_rmtree(const char *name, myf Myflags);
extern int my_getwd(char * buf,size_t size,myf MyFlags);
extern int my_setwd(const char *dir,myf MyFlags);
extern int my_lock(File fd,int op,my_off_t start, my_off_t length,myf MyFlags);
diff --git a/mysql-test/suite/mariabackup/incremental_rocksdb.opt b/mysql-test/suite/mariabackup/incremental_rocksdb.opt
new file mode 100644
index 00000000000..e582413e5b5
--- /dev/null
+++ b/mysql-test/suite/mariabackup/incremental_rocksdb.opt
@@ -0,0 +1 @@
+--plugin-load=$HA_ROCKSDB_SO \ No newline at end of file
diff --git a/mysql-test/suite/mariabackup/incremental_rocksdb.result b/mysql-test/suite/mariabackup/incremental_rocksdb.result
new file mode 100644
index 00000000000..4e5b9c43389
--- /dev/null
+++ b/mysql-test/suite/mariabackup/incremental_rocksdb.result
@@ -0,0 +1,19 @@
+call mtr.add_suppression("InnoDB: New log files created");
+CREATE TABLE t(i INT PRIMARY KEY) ENGINE ROCKSDB;
+INSERT INTO t VALUES(1);
+# Create full backup , modify table, then create incremental/differential backup
+DROP TABLE t;
+CREATE TABLE t2(i INT PRIMARY KEY) ENGINE ROCKSDB;
+INSERT INTO t2 VALUES(2);
+# Prepare full backup, apply incremental one
+# Restore and check results
+# shutdown server
+# remove datadir
+# xtrabackup move back
+# restart server
+SELECT * FROM t2;
+i
+2
+DROP TABLE t2;
+DROP TABLE t;
+ERROR 42S02: Unknown table 'test.t'
diff --git a/mysql-test/suite/mariabackup/incremental_rocksdb.test b/mysql-test/suite/mariabackup/incremental_rocksdb.test
new file mode 100644
index 00000000000..32bce885c32
--- /dev/null
+++ b/mysql-test/suite/mariabackup/incremental_rocksdb.test
@@ -0,0 +1,38 @@
+--source include/have_rocksdb.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 t(i INT PRIMARY KEY) ENGINE ROCKSDB;
+INSERT INTO t VALUES(1);
+
+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
+DROP TABLE t;
+CREATE TABLE t2(i INT PRIMARY KEY) ENGINE ROCKSDB;
+INSERT INTO t2 VALUES(2);
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$incremental_dir --incremental-basedir=$basedir;
+
+--disable_result_log
+echo # Prepare full backup, apply incremental one;
+exec $XTRABACKUP --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
+
+SELECT * FROM t2;
+DROP TABLE t2;
+--error ER_BAD_TABLE_ERROR
+DROP TABLE t;
+
+# Cleanup
+rmdir $basedir;
+rmdir $incremental_dir;
+
diff --git a/mysys/my_delete.c b/mysys/my_delete.c
index 0faf6079d98..cff107508d4 100644
--- a/mysys/my_delete.c
+++ b/mysys/my_delete.c
@@ -18,6 +18,7 @@
#include <my_sys.h>
#ifdef _WIN32
+#include <direct.h> /* rmdir */
static int my_win_unlink(const char *name);
#endif
@@ -160,3 +161,62 @@ error:
DBUG_RETURN(-1);
}
#endif
+
+/*
+ Remove directory recursively.
+*/
+int my_rmtree(const char *dir, myf MyFlags)
+{
+ char path[FN_REFLEN];
+ char sep[] = { FN_LIBCHAR, 0 };
+ int err = 0;
+
+ MY_DIR *dir_info = my_dir(dir, MYF(MY_DONT_SORT | MY_WANT_STAT));
+ if (!dir_info)
+ return 1;
+
+ for (uint i = 0; i < dir_info->number_of_files; i++)
+ {
+ FILEINFO *file = dir_info->dir_entry + i;
+ /* Skip "." and ".." */
+ if (!strcmp(file->name, ".") || !strcmp(file->name, ".."))
+ continue;
+
+ strxnmov(path, sizeof(path), dir, sep, file->name, NULL);
+
+ if (!MY_S_ISDIR(file->mystat->st_mode))
+ {
+ err = my_delete(path, MyFlags);
+#ifdef _WIN32
+ /*
+ On Windows, check and possible reset readonly attribute.
+ my_delete(), or DeleteFile does not remove theses files.
+ */
+ if (err)
+ {
+ DWORD attr = GetFileAttributes(path);
+ if (attr != INVALID_FILE_ATTRIBUTES &&
+ (attr & FILE_ATTRIBUTE_READONLY))
+ {
+ SetFileAttributes(path, attr &~FILE_ATTRIBUTE_READONLY);
+ err = my_delete(path, MyFlags);
+ }
+ }
+#endif
+ }
+ else
+ err = my_rmtree(path, MyFlags);
+
+ if (err)
+ break;
+ }
+
+ my_dirend(dir_info);
+
+ if (!err)
+ err = rmdir(dir);
+
+ return err;
+}
+
+