@@ -2530,17 +2530,24 @@ xb_get_copy_action(const char *dflt)
2530
2530
return (action);
2531
2531
}
2532
2532
2533
- /* TODO: We may tune the behavior (e.g. by fil_aio)*/
2534
2533
2535
- static
2536
- my_bool
2537
- xtrabackup_copy_datafile (fil_node_t * node, uint thread_n, const char *dest_name=0 , ulonglong max_size=ULLONG_MAX)
2534
+ /* * Copy innodb data file to the specified destination.
2535
+
2536
+ @param[in] node file node of a tablespace
2537
+ @param[in] thread_n thread id, used in the text of diagnostic messages
2538
+ @param[in] dest_name destination file name
2539
+ @param[in] write_filter write filter to copy data, can be pass-through filter
2540
+ for full backup, pages filter for incremental backup, etc.
2541
+
2542
+ @return FALSE on success and TRUE on error */
2543
+ static my_bool xtrabackup_copy_datafile (fil_node_t *node, uint thread_n,
2544
+ const char *dest_name,
2545
+ const xb_write_filt_t &write_filter)
2538
2546
{
2539
2547
char dst_name[FN_REFLEN];
2540
2548
ds_file_t *dstfile = NULL ;
2541
2549
xb_fil_cur_t cursor;
2542
2550
xb_fil_cur_result_t res;
2543
- xb_write_filt_t *write_filter = NULL ;
2544
2551
xb_write_filt_ctxt_t write_filt_ctxt;
2545
2552
const char *action;
2546
2553
xb_read_filt_t *read_filter;
@@ -2584,7 +2591,7 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
2584
2591
read_filter = &rf_bitmap;
2585
2592
}
2586
2593
2587
- res = xb_fil_cur_open (&cursor, read_filter, node, thread_n,max_size );
2594
+ res = xb_fil_cur_open (&cursor, read_filter, node, thread_n, ULLONG_MAX );
2588
2595
if (res == XB_FIL_CUR_SKIP) {
2589
2596
goto skip;
2590
2597
} else if (res == XB_FIL_CUR_ERROR) {
@@ -2595,18 +2602,11 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
2595
2602
sizeof dst_name - 1 );
2596
2603
dst_name[sizeof dst_name - 1 ] = ' \0 ' ;
2597
2604
2598
- /* Setup the page write filter */
2599
- if (xtrabackup_incremental) {
2600
- write_filter = &wf_incremental;
2601
- } else {
2602
- write_filter = &wf_write_through;
2603
- }
2604
-
2605
2605
memset (&write_filt_ctxt, 0 , sizeof (xb_write_filt_ctxt_t ));
2606
- ut_a (write_filter-> process != NULL );
2606
+ ut_a (write_filter. process != NULL );
2607
2607
2608
- if (write_filter-> init != NULL &&
2609
- !write_filter-> init (&write_filt_ctxt, dst_name, &cursor)) {
2608
+ if (write_filter. init != NULL &&
2609
+ !write_filter. init (&write_filt_ctxt, dst_name, &cursor)) {
2610
2610
msg (thread_n, " mariabackup: error: failed to initialize page write filter." );
2611
2611
goto error;
2612
2612
}
@@ -2627,7 +2627,7 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
2627
2627
2628
2628
/* The main copy loop */
2629
2629
while ((res = xb_fil_cur_read (&cursor)) == XB_FIL_CUR_SUCCESS) {
2630
- if (!write_filter-> process (&write_filt_ctxt, dstfile)) {
2630
+ if (!write_filter. process (&write_filt_ctxt, dstfile)) {
2631
2631
goto error;
2632
2632
}
2633
2633
}
@@ -2636,8 +2636,8 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
2636
2636
goto error;
2637
2637
}
2638
2638
2639
- if (write_filter-> finalize
2640
- && !write_filter-> finalize (&write_filt_ctxt, dstfile)) {
2639
+ if (write_filter. finalize
2640
+ && !write_filter. finalize (&write_filt_ctxt, dstfile)) {
2641
2641
goto error;
2642
2642
}
2643
2643
@@ -2651,8 +2651,8 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
2651
2651
if (ds_close (dstfile)) {
2652
2652
rc = TRUE ;
2653
2653
}
2654
- if (write_filter && write_filter-> deinit ) {
2655
- write_filter-> deinit (&write_filt_ctxt);
2654
+ if (write_filter. deinit ) {
2655
+ write_filter. deinit (&write_filt_ctxt);
2656
2656
}
2657
2657
return (rc);
2658
2658
@@ -2661,8 +2661,8 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
2661
2661
if (dstfile != NULL ) {
2662
2662
ds_close (dstfile);
2663
2663
}
2664
- if (write_filter && write_filter-> deinit ) {
2665
- write_filter-> deinit (&write_filt_ctxt);;
2664
+ if (write_filter. deinit ) {
2665
+ write_filter. deinit (&write_filt_ctxt);;
2666
2666
}
2667
2667
msg (thread_n, " mariabackup: xtrabackup_copy_datafile() failed." );
2668
2668
return (TRUE ); /* ERROR*/
@@ -2672,8 +2672,8 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
2672
2672
if (dstfile != NULL ) {
2673
2673
ds_close (dstfile);
2674
2674
}
2675
- if (write_filter && write_filter-> deinit ) {
2676
- write_filter-> deinit (&write_filt_ctxt);
2675
+ if (write_filter. deinit ) {
2676
+ write_filter. deinit (&write_filt_ctxt);
2677
2677
}
2678
2678
msg (thread_n," Warning: We assume the table was dropped during xtrabackup execution and ignore the tablespace %s" , node_name);
2679
2679
return (FALSE );
@@ -2970,9 +2970,9 @@ DECLARE_THREAD(data_copy_thread_func)(
2970
2970
while ((node = datafiles_iter_next (ctxt->it )) != NULL ) {
2971
2971
DBUG_MARIABACKUP_EVENT (" before_copy" , node->space ->name );
2972
2972
/* copy the datafile */
2973
- if (xtrabackup_copy_datafile (node, num)) {
2973
+ if (xtrabackup_copy_datafile (node, num, NULL ,
2974
+ xtrabackup_incremental ? wf_incremental : wf_write_through))
2974
2975
die (" failed to copy datafile." );
2975
- }
2976
2976
2977
2977
DBUG_MARIABACKUP_EVENT (" after_copy" , node->space ->name );
2978
2978
@@ -4570,7 +4570,7 @@ void backup_fix_ddl(void)
4570
4570
continue ;
4571
4571
std::string dest_name (node->space ->name );
4572
4572
dest_name.append (" .new" );
4573
- xtrabackup_copy_datafile (node, 0 , dest_name.c_str ()/* , do_full_copy ? ULONGLONG_MAX:UNIV_PAGE_SIZE */ );
4573
+ xtrabackup_copy_datafile (node, 0 , dest_name.c_str (), wf_write_through );
4574
4574
}
4575
4575
4576
4576
datafiles_iter_free (it);
@@ -5130,22 +5130,66 @@ static void rename_force(const char *from, const char *to) {
5130
5130
rename_file (from,to);
5131
5131
}
5132
5132
5133
- /* During prepare phase, rename ".new" files , that were created in backup_fix_ddl(),
5134
- to ".ibd".*/
5135
- static ibool prepare_handle_new_files (
5136
- const char * data_home_dir, /* !<in: path to datadir */
5137
- const char * db_name, /* !<in: database name */
5138
- const char * file_name, /* !<in: file name with suffix */
5139
- void *)
5140
- {
5141
5133
5134
+ /* * During prepare phase, rename ".new" files, that were created in
5135
+ backup_fix_ddl() and backup_optimized_ddl_op(), to ".ibd". In the case of
5136
+ incremental backup, i.e. of arg argument is set, move ".new" files to
5137
+ destination directory and rename them to ".ibd", remove existing ".ibd.delta"
5138
+ and ".idb.meta" files in incremental directory to avoid applying delta to
5139
+ ".ibd" file.
5140
+
5141
+ @param[in] data_home_dir path to datadir
5142
+ @param[in] db_name database name
5143
+ @param[in] file_name file name with suffix
5144
+ @param[in] arg destination path, used in incremental backup to notify, that
5145
+ *.new file must be moved to destibation directory
5146
+
5147
+ @return true */
5148
+ static ibool prepare_handle_new_files (const char *data_home_dir,
5149
+ const char *db_name,
5150
+ const char *file_name, void *arg)
5151
+ {
5152
+ const char *dest_dir = static_cast <const char *>(arg);
5142
5153
std::string src_path = std::string (data_home_dir) + ' /' + std::string (db_name) + ' /' + file_name;
5143
- std::string dest_path = src_path;
5154
+ /* Copy "*.new" files from incremental to base dir for incremental backup */
5155
+ std::string dest_path=
5156
+ dest_dir ? std::string (dest_dir) + ' /' + std::string (db_name) +
5157
+ ' /' + file_name : src_path;
5144
5158
5145
5159
size_t index = dest_path.find (" .new" );
5146
5160
DBUG_ASSERT (index != std::string::npos);
5147
- dest_path.replace (index, 4 , " .ibd" );
5161
+ dest_path.replace (index, strlen ( " .ibd " ) , " .ibd" );
5148
5162
rename_force (src_path.c_str (),dest_path.c_str ());
5163
+
5164
+ if (dest_dir) {
5165
+ /* remove delta and meta files to avoid delta applying for new file */
5166
+ index = src_path.find (" .new" );
5167
+ DBUG_ASSERT (index != std::string::npos);
5168
+ src_path.replace (index, std::string::npos, " .ibd.delta" );
5169
+ if (access (src_path.c_str (), R_OK) == 0 ) {
5170
+ msg (" Removing %s" , src_path.c_str ());
5171
+ if (my_delete (src_path.c_str (), MYF (MY_WME)))
5172
+ die (" Can't remove %s, errno %d" , src_path.c_str (), errno);
5173
+ }
5174
+ src_path.replace (index, std::string::npos, " .ibd.meta" );
5175
+ if (access (src_path.c_str (), R_OK) == 0 ) {
5176
+ msg (" Removing %s" , src_path.c_str ());
5177
+ if (my_delete (src_path.c_str (), MYF (MY_WME)))
5178
+ die (" Can't remove %s, errno %d" , src_path.c_str (), errno);
5179
+ }
5180
+
5181
+ /* add table name to the container to avoid it's deletion at the end of
5182
+ prepare */
5183
+ std::string table_name = std::string (db_name) + ' /'
5184
+ + std::string (file_name, file_name + strlen (file_name) - strlen (" .new" ));
5185
+ xb_filter_entry_t *table = static_cast <xb_filter_entry_t *>
5186
+ (malloc (sizeof (xb_filter_entry_t ) + table_name.size () + 1 ));
5187
+ table->name = ((char *)table) + sizeof (xb_filter_entry_t );
5188
+ strcpy (table->name , table_name.c_str ());
5189
+ HASH_INSERT (xb_filter_entry_t , name_hash, inc_dir_tables_hash,
5190
+ ut_fold_string (table->name ), table);
5191
+ }
5192
+
5149
5193
return TRUE ;
5150
5194
}
5151
5195
@@ -5182,17 +5226,18 @@ rm_if_not_found(
5182
5226
return (TRUE );
5183
5227
}
5184
5228
5185
- /* ***********************************************************************
5186
- Function enumerates files in datadir (provided by path) which are matched
5229
+ /* * Function enumerates files in datadir (provided by path) which are matched
5187
5230
by provided suffix. For each entry callback is called.
5231
+
5232
+ @param[in] path datadir path
5233
+ @param[in] suffix suffix to match against
5234
+ @param[in] func callback
5235
+ @param[in] func_arg arguments for the above callback
5236
+
5188
5237
@return FALSE if callback for some entry returned FALSE */
5189
- static
5190
- ibool
5191
- xb_process_datadir (
5192
- const char * path, /* !<in: datadir path */
5193
- const char * suffix, /* !<in: suffix to match
5194
- against */
5195
- handle_datadir_entry_func_t func) /* !<in: callback */
5238
+ static ibool xb_process_datadir (const char *path, const char *suffix,
5239
+ handle_datadir_entry_func_t func,
5240
+ void *func_arg = NULL )
5196
5241
{
5197
5242
ulint ret;
5198
5243
char dbpath[OS_FILE_MAX_PATH+1 ];
@@ -5227,7 +5272,7 @@ xb_process_datadir(
5227
5272
suffix)) {
5228
5273
if (!func (
5229
5274
path, NULL ,
5230
- fileinfo.name , NULL ))
5275
+ fileinfo.name , func_arg ))
5231
5276
{
5232
5277
os_file_closedir (dbdir);
5233
5278
return (FALSE );
@@ -5291,7 +5336,7 @@ xb_process_datadir(
5291
5336
if (!func (
5292
5337
path,
5293
5338
dbinfo.name ,
5294
- fileinfo.name , NULL ))
5339
+ fileinfo.name , func_arg ))
5295
5340
{
5296
5341
os_file_closedir (dbdir);
5297
5342
os_file_closedir (dir);
@@ -5451,6 +5496,12 @@ static bool xtrabackup_prepare_func(char** argv)
5451
5496
5452
5497
fil_path_to_mysql_datadir = " ." ;
5453
5498
5499
+ ut_ad (xtrabackup_incremental == xtrabackup_incremental_dir);
5500
+ if (xtrabackup_incremental) {
5501
+ inc_dir_tables_hash = hash_create (1000 );
5502
+ ut_ad (inc_dir_tables_hash);
5503
+ }
5504
+
5454
5505
/* Fix DDL for prepare. Process .del,.ren, and .new files.
5455
5506
The order in which files are processed, is important
5456
5507
(see MDEV-18185, MDEV-18201)
@@ -5462,6 +5513,8 @@ static bool xtrabackup_prepare_func(char** argv)
5462
5513
if (xtrabackup_incremental_dir) {
5463
5514
xb_process_datadir (xtrabackup_incremental_dir, " .new.meta" , prepare_handle_new_files);
5464
5515
xb_process_datadir (xtrabackup_incremental_dir, " .new.delta" , prepare_handle_new_files);
5516
+ xb_process_datadir (xtrabackup_incremental_dir, " .new" ,
5517
+ prepare_handle_new_files, (void *)" ." );
5465
5518
}
5466
5519
else {
5467
5520
xb_process_datadir (" ." , " .new" , prepare_handle_new_files);
@@ -5545,8 +5598,6 @@ static bool xtrabackup_prepare_func(char** argv)
5545
5598
goto error_cleanup;
5546
5599
}
5547
5600
5548
- inc_dir_tables_hash = hash_create (1000 );
5549
-
5550
5601
ok = xtrabackup_apply_deltas ();
5551
5602
5552
5603
xb_data_files_close ();
0 commit comments