Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MDEV-36304 InnoDB: Missing FILE_CREATE, FILE_DELETE or FILE_MODIFY error during mariabackup --prepare #3908

Open
wants to merge 1 commit into
base: 11.4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions extra/mariabackup/xtrabackup.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2694,6 +2694,35 @@ static bool innodb_init()

/* ================= common ================= */

/** Read the backup_info file during prepare to know whether
it is working on partial backup target directory */
static
void xtrabackup_read_backup_info_file(const char *dir,
const char *name) noexcept
{
char filename[FN_REFLEN];
snprintf(filename, sizeof(filename), "%s/%s", dir, name);
FILE *fp= fopen(filename, "r");
char key[8], value;
if (!fp)
{
msg("Error: cannot open %s", filename);
return;
}

while (!feof(fp))
{
if (fscanf(fp, "%7s = %c\n", key, &value) == 2)
if (strcmp(key, "partial") == 0)
{
if (value == 'Y')
srv_prepare_partial_backup= true;
break;
}
}
fclose(fp);
}

/***********************************************************************
Read backup meta info.
@return TRUE on success, FALSE on failure. */
Expand Down Expand Up @@ -6796,6 +6825,7 @@ static bool xtrabackup_prepare_func(char** argv)
return(false);
}

xtrabackup_read_backup_info_file(xtrabackup_target_dir, MB_INFO);
if (!strcmp(metadata_type, "full-backuped")) {
if (xtrabackup_incremental) {
msg("error: applying incremental backup "
Expand Down
15 changes: 15 additions & 0 deletions mysql-test/suite/mariabackup/partial_backup_prepare.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
CREATE TABLE t1(i INT) ENGINE INNODB;
CREATE TABLE t2(i INT) ENGINE INNODB;
INSERT INTO t1 VALUES(1);
INSERT INTO t2 VALUES(2);
set global innodb_log_checkpoint_now = 1;
INSERT INTO t1 select * from seq_1_to_1024;
INSERT INTO t2 select * from seq_1_to_1024;
# restart
# xtrabackup backup
# xtrabackup prepare
t1.cfg
ALTER TABLE t1 DISCARD TABLESPACE;
ALTER TABLE t1 IMPORT TABLESPACE;
SELECT * FROM t1;
DROP TABLE t1, t2;
37 changes: 37 additions & 0 deletions mysql-test/suite/mariabackup/partial_backup_prepare.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
--source include/have_innodb.inc
--source include/have_sequence.inc
--source include/have_debug.inc
--source include/not_embedded.inc

CREATE TABLE t1(i INT) ENGINE INNODB;
CREATE TABLE t2(i INT) ENGINE INNODB;

INSERT INTO t1 VALUES(1);
INSERT INTO t2 VALUES(2);

let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
let $backup_log=$MYSQLTEST_VARDIR/tmp/backup.log;
let $prepare_log=$MYSQLTEST_VARDIR/tmp/prepare.log;
set global innodb_log_checkpoint_now = 1;
INSERT INTO t1 select * from seq_1_to_1024;
INSERT INTO t2 select * from seq_1_to_1024;
--source include/restart_mysqld.inc
echo # xtrabackup backup;
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --dbug=+d,use_old_checkpoint --skip-innodb-log-checkpoint-now --backup "--tables=test.*1" --target-dir=$targetdir --parallel=10 > $backup_log 2>&1;

echo # xtrabackup prepare;
--disable_result_log
exec $XTRABACKUP --prepare --export --target-dir=$targetdir --dbug=+d,partial_backup_test > $prepare_log 2>&1;

list_files $targetdir/test *.cfg;

let $MYSQLD_DATADIR= `select @@datadir`;
ALTER TABLE t1 DISCARD TABLESPACE;
copy_file $targetdir/test/t1.ibd $MYSQLD_DATADIR/test/t1.ibd;
copy_file $targetdir/test/t1.cfg $MYSQLD_DATADIR/test/t1.cfg;
ALTER TABLE t1 IMPORT TABLESPACE;
SELECT * FROM t1;
DROP TABLE t1, t2;
remove_file $backup_log;
remove_file $prepare_log;
rmdir $targetdir;
2 changes: 2 additions & 0 deletions storage/innobase/include/srv0srv.h
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,8 @@ extern enum srv_operation_mode srv_operation;
/** whether this is the server's first start after mariabackup --prepare */
extern bool srv_start_after_restore;

extern bool srv_prepare_partial_backup;

extern my_bool srv_print_innodb_monitor;
extern my_bool srv_print_innodb_lock_monitor;
extern ibool srv_print_verbose_log;
Expand Down
37 changes: 36 additions & 1 deletion storage/innobase/log/log0recv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1175,7 +1175,6 @@ static void fil_name_process(const char *name, ulint len, uint32_t space_id,
|| f.name != fname.name) {
reload:
fil_space_t* space;

/* Check if the tablespace file exists and contains
the space_id. If not, ignore the file after displaying
a note. Abort if there are multiple files with the
Expand Down Expand Up @@ -1232,6 +1231,18 @@ static void fil_name_process(const char *name, ulint len, uint32_t space_id,
break;
}

/* In case of prepare on partial backup,
InnoDB can't find some tablespace on target
directory. If InnoDB encounters redo log
for the tablespace before FILE_* record then
InnoDB should rename the file name in
recv_spaces from "" to name which encountered
during FILE_* record */
if (srv_prepare_partial_backup &&
strcmp(fname.name.c_str(), "") == 0) {
f.name= fname.name;
}

if (srv_force_recovery
|| srv_operation == SRV_OPERATION_RESTORE) {
/* Without innodb_force_recovery,
Expand All @@ -1249,6 +1260,17 @@ static void fil_name_process(const char *name, ulint len, uint32_t space_id,
int(fname.name.size()),
fname.name.data(), space_id);
}

DBUG_EXECUTE_IF("partial_backup_test",
char *exist=
strstr(const_cast<char*>(name),
"t2.ibd");
static uint32_t n_exist= 0;
if (exist && n_exist == 0)
{
n_exist++;
recv_spaces.erase(space_id);
});
break;

case FIL_LOAD_DEFER:
Expand Down Expand Up @@ -1751,13 +1773,26 @@ dberr_t recv_sys_t::find_checkpoint()
continue;
}

DBUG_EXECUTE_IF("use_old_checkpoint",
if (log_sys.next_checkpoint_lsn > 0) {
if (checkpoint_lsn > log_sys.next_checkpoint_lsn)
goto skip_lsn;
else goto assign_lsn;
}
);
if (checkpoint_lsn >= log_sys.next_checkpoint_lsn)
{
#ifndef DBUG_OFF
assign_lsn:
#endif /* !DBUG_OFF */
log_sys.next_checkpoint_lsn= checkpoint_lsn;
log_sys.next_checkpoint_no= field == log_t::CHECKPOINT_1;
lsn= end_lsn;
}
}
#ifndef DBUG_OFF
skip_lsn:
#endif /* !DBUG_OFF */
if (!log_sys.next_checkpoint_lsn)
goto got_no_checkpoint;
if (!memcmp(creator, "Backup ", 7))
Expand Down
3 changes: 3 additions & 0 deletions storage/innobase/srv/srv0srv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,9 @@ enum srv_operation_mode srv_operation;
/** whether this is the server's first start after mariabackup --prepare */
bool srv_start_after_restore;

/** Whether mariabackup --prepare working on partial backup target */
bool srv_prepare_partial_backup;

/* Set the following to 0 if you want InnoDB to write messages on
stderr on startup/shutdown. Not enabled on the embedded server. */
ibool srv_print_verbose_log;
Expand Down