Commit 3a42926c authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

MDEV-18204 Fix rocksdb incremental backup

Fix incremental prepare to copy #rocksdb subdirectory from the
incremental dir.
parent 40b4f9c9
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
--plugin-load=$HA_ROCKSDB_SO
\ No newline at end of file
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'
--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;
......@@ -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 @@ static int my_win_unlink(const char *name)
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;
}
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