summaryrefslogtreecommitdiff
path: root/extra/mariabackup/xtrabackup.cc
diff options
context:
space:
mode:
Diffstat (limited to 'extra/mariabackup/xtrabackup.cc')
-rw-r--r--extra/mariabackup/xtrabackup.cc153
1 files changed, 102 insertions, 51 deletions
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index b32c9d9b523..15c9d0d0d8d 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -2529,17 +2529,24 @@ xb_get_copy_action(const char *dflt)
return(action);
}
-/* TODO: We may tune the behavior (e.g. by fil_aio)*/
-static
-my_bool
-xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=0, ulonglong max_size=ULLONG_MAX)
+/** Copy innodb data file to the specified destination.
+
+@param[in] node file node of a tablespace
+@param[in] thread_n thread id, used in the text of diagnostic messages
+@param[in] dest_name destination file name
+@param[in] write_filter write filter to copy data, can be pass-through filter
+for full backup, pages filter for incremental backup, etc.
+
+@return FALSE on success and TRUE on error */
+static my_bool xtrabackup_copy_datafile(fil_node_t *node, uint thread_n,
+ const char *dest_name,
+ const xb_write_filt_t &write_filter)
{
char dst_name[FN_REFLEN];
ds_file_t *dstfile = NULL;
xb_fil_cur_t cursor;
xb_fil_cur_result_t res;
- xb_write_filt_t *write_filter = NULL;
xb_write_filt_ctxt_t write_filt_ctxt;
const char *action;
xb_read_filt_t *read_filter;
@@ -2583,7 +2590,7 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
read_filter = &rf_bitmap;
}
- res = xb_fil_cur_open(&cursor, read_filter, node, thread_n,max_size);
+ res = xb_fil_cur_open(&cursor, read_filter, node, thread_n, ULLONG_MAX);
if (res == XB_FIL_CUR_SKIP) {
goto skip;
} else if (res == XB_FIL_CUR_ERROR) {
@@ -2594,18 +2601,11 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
sizeof dst_name - 1);
dst_name[sizeof dst_name - 1] = '\0';
- /* Setup the page write filter */
- if (xtrabackup_incremental) {
- write_filter = &wf_incremental;
- } else {
- write_filter = &wf_write_through;
- }
-
memset(&write_filt_ctxt, 0, sizeof(xb_write_filt_ctxt_t));
- ut_a(write_filter->process != NULL);
+ ut_a(write_filter.process != NULL);
- if (write_filter->init != NULL &&
- !write_filter->init(&write_filt_ctxt, dst_name, &cursor)) {
+ if (write_filter.init != NULL &&
+ !write_filter.init(&write_filt_ctxt, dst_name, &cursor)) {
msg (thread_n, "mariabackup: error: failed to initialize page write filter.");
goto error;
}
@@ -2626,7 +2626,7 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
/* The main copy loop */
while ((res = xb_fil_cur_read(&cursor)) == XB_FIL_CUR_SUCCESS) {
- if (!write_filter->process(&write_filt_ctxt, dstfile)) {
+ if (!write_filter.process(&write_filt_ctxt, dstfile)) {
goto error;
}
}
@@ -2635,8 +2635,8 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
goto error;
}
- if (write_filter->finalize
- && !write_filter->finalize(&write_filt_ctxt, dstfile)) {
+ if (write_filter.finalize
+ && !write_filter.finalize(&write_filt_ctxt, dstfile)) {
goto error;
}
@@ -2650,8 +2650,8 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
if (ds_close(dstfile)) {
rc = TRUE;
}
- if (write_filter && write_filter->deinit) {
- write_filter->deinit(&write_filt_ctxt);
+ if (write_filter.deinit) {
+ write_filter.deinit(&write_filt_ctxt);
}
return(rc);
@@ -2660,8 +2660,8 @@ error:
if (dstfile != NULL) {
ds_close(dstfile);
}
- if (write_filter && write_filter->deinit) {
- write_filter->deinit(&write_filt_ctxt);;
+ if (write_filter.deinit) {
+ write_filter.deinit(&write_filt_ctxt);;
}
msg(thread_n, "mariabackup: xtrabackup_copy_datafile() failed.");
return(TRUE); /*ERROR*/
@@ -2671,8 +2671,8 @@ skip:
if (dstfile != NULL) {
ds_close(dstfile);
}
- if (write_filter && write_filter->deinit) {
- write_filter->deinit(&write_filt_ctxt);
+ if (write_filter.deinit) {
+ write_filter.deinit(&write_filt_ctxt);
}
msg(thread_n,"Warning: We assume the table was dropped during xtrabackup execution and ignore the tablespace %s", node_name);
return(FALSE);
@@ -2968,9 +2968,9 @@ DECLARE_THREAD(data_copy_thread_func)(
while ((node = datafiles_iter_next(ctxt->it)) != NULL) {
DBUG_MARIABACKUP_EVENT("before_copy", node->space->name);
/* copy the datafile */
- if(xtrabackup_copy_datafile(node, num)) {
+ if (xtrabackup_copy_datafile(node, num, NULL,
+ xtrabackup_incremental ? wf_incremental : wf_write_through))
die("failed to copy datafile.");
- }
DBUG_MARIABACKUP_EVENT("after_copy", node->space->name);
@@ -4578,7 +4578,7 @@ void backup_fix_ddl(void)
continue;
std::string dest_name(node->space->name);
dest_name.append(".new");
- xtrabackup_copy_datafile(node, 0, dest_name.c_str()/*, do_full_copy ? ULONGLONG_MAX:UNIV_PAGE_SIZE */);
+ xtrabackup_copy_datafile(node, 0, dest_name.c_str(), wf_write_through);
}
datafiles_iter_free(it);
@@ -5140,22 +5140,66 @@ static void rename_force(const char *from, const char *to) {
rename_file(from,to);
}
-/* During prepare phase, rename ".new" files , that were created in backup_fix_ddl(),
- to ".ibd".*/
-static ibool prepare_handle_new_files(
- const char* data_home_dir, /*!<in: path to datadir */
- const char* db_name, /*!<in: database name */
- const char* file_name, /*!<in: file name with suffix */
- void *)
-{
+/** During prepare phase, rename ".new" files, that were created in
+backup_fix_ddl() and backup_optimized_ddl_op(), to ".ibd". In the case of
+incremental backup, i.e. of arg argument is set, move ".new" files to
+destination directory and rename them to ".ibd", remove existing ".ibd.delta"
+and ".idb.meta" files in incremental directory to avoid applying delta to
+".ibd" file.
+
+@param[in] data_home_dir path to datadir
+@param[in] db_name database name
+@param[in] file_name file name with suffix
+@param[in] arg destination path, used in incremental backup to notify, that
+*.new file must be moved to destibation directory
+
+@return true */
+static ibool prepare_handle_new_files(const char *data_home_dir,
+ const char *db_name,
+ const char *file_name, void *arg)
+{
+ const char *dest_dir = static_cast<const char *>(arg);
std::string src_path = std::string(data_home_dir) + '/' + std::string(db_name) + '/' + file_name;
- std::string dest_path = src_path;
+ /* Copy "*.new" files from incremental to base dir for incremental backup */
+ std::string dest_path=
+ dest_dir ? std::string(dest_dir) + '/' + std::string(db_name) +
+ '/' + file_name : src_path;
size_t index = dest_path.find(".new");
DBUG_ASSERT(index != std::string::npos);
- dest_path.replace(index, 4, ".ibd");
+ dest_path.replace(index, strlen(".ibd"), ".ibd");
rename_force(src_path.c_str(),dest_path.c_str());
+
+ if (dest_dir) {
+ /* remove delta and meta files to avoid delta applying for new file */
+ index = src_path.find(".new");
+ DBUG_ASSERT(index != std::string::npos);
+ src_path.replace(index, std::string::npos, ".ibd.delta");
+ if (access(src_path.c_str(), R_OK) == 0) {
+ msg("Removing %s", src_path.c_str());
+ if (my_delete(src_path.c_str(), MYF(MY_WME)))
+ die("Can't remove %s, errno %d", src_path.c_str(), errno);
+ }
+ src_path.replace(index, std::string::npos, ".ibd.meta");
+ if (access(src_path.c_str(), R_OK) == 0) {
+ msg("Removing %s", src_path.c_str());
+ if (my_delete(src_path.c_str(), MYF(MY_WME)))
+ die("Can't remove %s, errno %d", src_path.c_str(), errno);
+ }
+
+ /* add table name to the container to avoid it's deletion at the end of
+ prepare */
+ std::string table_name = std::string(db_name) + '/'
+ + std::string(file_name, file_name + strlen(file_name) - strlen(".new"));
+ xb_filter_entry_t *table = static_cast<xb_filter_entry_t *>
+ (malloc(sizeof(xb_filter_entry_t) + table_name.size() + 1));
+ table->name = ((char*)table) + sizeof(xb_filter_entry_t);
+ strcpy(table->name, table_name.c_str());
+ HASH_INSERT(xb_filter_entry_t, name_hash, inc_dir_tables_hash,
+ ut_fold_string(table->name), table);
+ }
+
return TRUE;
}
@@ -5192,17 +5236,18 @@ rm_if_not_found(
return(TRUE);
}
-/************************************************************************
-Function enumerates files in datadir (provided by path) which are matched
+/** Function enumerates files in datadir (provided by path) which are matched
by provided suffix. For each entry callback is called.
+
+@param[in] path datadir path
+@param[in] suffix suffix to match against
+@param[in] func callback
+@param[in] func_arg arguments for the above callback
+
@return FALSE if callback for some entry returned FALSE */
-static
-ibool
-xb_process_datadir(
- const char* path, /*!<in: datadir path */
- const char* suffix, /*!<in: suffix to match
- against */
- handle_datadir_entry_func_t func) /*!<in: callback */
+static ibool xb_process_datadir(const char *path, const char *suffix,
+ handle_datadir_entry_func_t func,
+ void *func_arg = NULL)
{
ulint ret;
char dbpath[OS_FILE_MAX_PATH+2];
@@ -5237,7 +5282,7 @@ xb_process_datadir(
suffix)) {
if (!func(
path, NULL,
- fileinfo.name, NULL))
+ fileinfo.name, func_arg))
{
os_file_closedir(dbdir);
return(FALSE);
@@ -5301,7 +5346,7 @@ next_file_item_1:
if (!func(
path,
dbinfo.name,
- fileinfo.name, NULL))
+ fileinfo.name, func_arg))
{
os_file_closedir(dbdir);
os_file_closedir(dir);
@@ -5461,6 +5506,12 @@ static bool xtrabackup_prepare_func(char** argv)
fil_path_to_mysql_datadir = ".";
+ ut_ad(xtrabackup_incremental == xtrabackup_incremental_dir);
+ if (xtrabackup_incremental) {
+ inc_dir_tables_hash = hash_create(1000);
+ ut_ad(inc_dir_tables_hash);
+ }
+
/* Fix DDL for prepare. Process .del,.ren, and .new files.
The order in which files are processed, is important
(see MDEV-18185, MDEV-18201)
@@ -5472,6 +5523,8 @@ static bool xtrabackup_prepare_func(char** argv)
if (xtrabackup_incremental_dir) {
xb_process_datadir(xtrabackup_incremental_dir, ".new.meta", prepare_handle_new_files);
xb_process_datadir(xtrabackup_incremental_dir, ".new.delta", prepare_handle_new_files);
+ xb_process_datadir(xtrabackup_incremental_dir, ".new",
+ prepare_handle_new_files, (void *)".");
}
else {
xb_process_datadir(".", ".new", prepare_handle_new_files);
@@ -5555,8 +5608,6 @@ static bool xtrabackup_prepare_func(char** argv)
goto error_cleanup;
}
- inc_dir_tables_hash = hash_create(1000);
-
ok = xtrabackup_apply_deltas();
xb_data_files_close();