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

PXB-3320 : prepare_handle_del_files() fails to delete the .meta and .… #1584

Merged
Merged
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
53 changes: 35 additions & 18 deletions storage/innobase/xtrabackup/src/xtrabackup.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5539,6 +5539,18 @@ static bool xtrabackup_apply_delta(
return false;
}

// Function to check if a string ends with another string
static bool ends_with(const string &full_string, const string &ext) {
// Check if the ending string is longer than the full
// string
if (ext.size() > full_string.size()) return false;

// Compare the ending of the full string with the target
// ending
return full_string.compare(full_string.size() - ext.size(), ext.size(),
ext) == 0;
}

/************************************************************************
Scan .meta files and build std::unordered_map<space_id, meta_path>.
This map is later used to delete the .delta and .meta file for a dropped
Expand All @@ -5559,6 +5571,12 @@ static bool xtrabackup_scan_meta(

ut_a(xtrabackup_incremental);

// We dont want to add .new.meta to meta_map, as they are meant to be replace
// the old version of the file.
if (ends_with(entry.file_name, ".new.meta")) {
return true;
}

if (!xb_read_delta_metadata(meta_path.c_str(), &info)) {
goto error;
}
Expand Down Expand Up @@ -5790,28 +5808,27 @@ static bool prepare_handle_del_files(
ut::free(space_name);
return false;
}
}

os_file_delete(0, del_file.c_str());
if (xtrabackup_incremental) {
auto [exists, meta_file] = is_in_meta_map(fil_space->id);
if (exists) {
// create .delta path from .meta
std::string delta_file =
meta_file.substr(0, strlen(meta_file.c_str()) - strlen(".meta")) +
".delta";
xb::info() << "Deleting incremental meta file: " << meta_file;
delete_force(meta_file);
xb::info() << "Deleting incremental delta file: " << delta_file;
delete_force(delta_file);
}
if (xtrabackup_incremental) {
auto [exists, meta_file] = is_in_meta_map(space_id);
if (exists) {
// create .delta path from .meta
std::string delta_file =
meta_file.substr(0, strlen(meta_file.c_str()) - strlen(".meta")) +
".delta";
xb::info() << "Deleting incremental meta file: " << meta_file;
delete_force(meta_file);
xb::info() << "Deleting incremental delta file: " << delta_file;
delete_force(delta_file);
}
return true;
} else {
// if table was already deleted then return true
os_file_delete(0, del_file.c_str());
return true;
}

xb::info() << "prepare_handle_del_files: deleting " << del_file.c_str();
os_file_delete(0, del_file.c_str());
return true;
}

/************************************************************************
Callback to handle datadir entry. Deletes entry if it has no matching
fil_space in fil_system directory.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
###############################################################################
# PXB-3320: prepare_handle_del_files() fails to delete the .meta and .delta files
# for deleted tablespaces in incremental backup directory
###############################################################################

. inc/common.sh

require_debug_pxb_version
start_server

innodb_wait_for_flush_all

xtrabackup --backup --target-dir=$topdir/backup_base --lock-ddl=REDUCED

innodb_wait_for_flush_all

$MYSQL $MYSQL_ARGS -Ns -e "CREATE TABLE t2(a INT)" test

xtrabackup --backup --target-dir=$topdir/backup_inc --incremental-basedir=$topdir/backup_base \
--debug-sync="ddl_tracker_before_lock_ddl" --lock-ddl=REDUCED \
2> >( tee $topdir/backup_inc.log)&

job_pid=$!
pid_file=$topdir/backup_inc/xtrabackup_debug_sync
wait_for_xb_to_suspend $pid_file
xb_pid=`cat $pid_file`
echo "backup pid is $job_pid"

# Generate redo on table than delete it
$MYSQL $MYSQL_ARGS -Ns -e "INSERT INTO test.t2 VALUES (1); DROP TABLE test.t2;" test

# Resume the xtrabackup process
vlog "Resuming xtrabackup"
kill -SIGCONT $xb_pid
run_cmd wait $job_pid

xtrabackup --prepare --apply-log-only --target-dir=$topdir/backup_base
xtrabackup --prepare --target-dir=$topdir/backup_base --incremental-dir=$topdir/backup_inc

# Ensure that t2.ibd shouldn't be present
FILE=$topdir/backup_base/test/t2.ibd
[ ! -f $FILE ] || die "$FILE exists. It should have been deleted by prepare. Server has dropped the table during incremental"

record_db_state test
stop_server
rm -rf $mysql_datadir/*
xtrabackup --copy-back --target-dir=$topdir/backup_base
start_server
verify_db_state test
rm -rf $topdir/backup_base
rm -rf $topdir/backup_inc
rm $topdir/backup_inc.log
Loading