3030#include < algorithm>
3131#include < functional>
3232#include < optional>
33- #include < variant>
3433
3534/*
3635 Implementation of functions declatred in ma_backup.h:
3938
4039namespace
4140{
42- /* Utility class to implement the "backup step" interface when
43- processing several lists. It implements the logic where an item
44- is processed (copied) from the first list which has available
45- items, and a "remaining" counter accumulates the number of
46- items remaining to be processed on all lists, regardless of
47- whether an item from that list was processed or not. */
48- class Copy_from_list
49- {
50- int m_remaining {0 };
51- bool m_copy_done;
52- public:
53- Copy_from_list (bool copy_done= false ) noexcept
54- : m_copy_done(copy_done)
55- {
56- }
57-
58- bool copy_done () const noexcept
59- {
60- return m_copy_done;
61- }
62-
63- int remaining () const noexcept
64- {
65- return m_remaining;
66- }
67-
68- template <typename T, typename Fn>
69- bool operator ()(const T &list, std::atomic<size_t > &copied,
70- Fn copy_action) noexcept
71- {
72- if (!m_copy_done)
73- {
74- size_t idx= copied.fetch_add (1 , std::memory_order_relaxed);
75- if (idx < list.size ())
76- {
77- if (copy_action (list[idx]) != 0 )
78- return true ;
79- m_copy_done= true ;
80- m_remaining+= static_cast <int >(list.size () - idx - 1U );
81- }
82- }
83- else
84- {
85- size_t current_copied= copied.load (std::memory_order_relaxed);
86- if (current_copied < list.size ())
87- m_remaining+= static_cast <int >(list.size () - current_copied);
88- }
89- return false ;
90- }
91- };
92-
93-
9441 class Aria_backup
9542 {
9643 public:
@@ -148,18 +95,11 @@ namespace
14895 is in progress. */
14996 int dml_safe_copy_step (const backup_sink *sink) noexcept
15097 {
151- Copy_from_list copy_from_list;
152- auto copy_table_action= [this , sink](const table_ref &table) noexcept
153- {
154- return copy_table (sink, table);
155- };
156- if (copy_from_list (dml_safe_table_list, dml_safe_tables_copied,
157- copy_table_action) != 0 )
158- return -1 ;
159- if (copy_from_list (unsafe_tables_list, unsafe_tables_copied,
160- copy_table_action) != 0 )
161- return -1 ;
162- return copy_from_list.remaining ();
98+ return copy_from_list_step (flat_table_list, tables_copied,
99+ [this , sink](const table_ref &table) noexcept
100+ {
101+ return copy_table (sink, table);
102+ });
163103 }
164104
165105 /* Copy an entity that is not safe to copy if there are concurrent
@@ -173,8 +113,6 @@ namespace
173113 */
174114 int unsafe_copy_step (const backup_sink *sink) noexcept
175115 {
176- bool copy_done= false ;
177-
178116 /* If control file is always the first file copied and there is only
179117 one, it is never included in the "steps remaining" calculation.
180118 Should the order be changed, the calculation needs to be updated for
@@ -186,19 +124,18 @@ namespace
186124 {
187125 if (copy_control_file (sink) != 0 )
188126 return -1 ;
189- copy_done= true ;
127+ size_t current_copied= log_files_copied.load (std::memory_order_relaxed);
128+ return (current_copied < log_files.size ()) ?
129+ static_cast <int >(log_files.size () - current_copied) :
130+ 0 ;
190131 }
191132 }
192133
193- Copy_from_list copy_from_list (copy_done);
194- if (copy_from_list (log_files, log_files_copied,
195- [this , sink](const std::string &path) noexcept
196- {
197- return copy_log_file (sink, path.c_str ());
198- }) != 0 )
199- return -1 ;
200-
201- return copy_from_list.remaining ();
134+ return copy_from_list_step (log_files, log_files_copied,
135+ [this , sink](const std::string &path) noexcept
136+ {
137+ return copy_log_file (sink, path.c_str ());
138+ });
202139 }
203140
204141 int end (bool /* abort*/ ) noexcept
@@ -222,10 +159,8 @@ namespace
222159 using dir_contents = std::vector<std::string>;
223160 using database_dir = std::pair<dir_name, dir_contents>;
224161 using database_dirs = std::vector<database_dir>;
225- /* Transactional tables with checksum */
226- database_dirs dml_safe_tables;
227- /* All other Aria tables */
228- database_dirs unsafe_tables;
162+ /* Collection of tables to be backed up. */
163+ database_dirs tables;
229164 /* Aria log files */
230165 std::vector<std::string> log_files;
231166
@@ -238,11 +173,8 @@ namespace
238173 using table_ref= std::pair<dir_ref, tablename_ref>;
239174 using table_list= std::vector<table_ref>;
240175
241- /* Flattened versions of dml_safe_tables and unsafe_tables. */
242- table_list dml_safe_table_list;
243- table_list unsafe_tables_list;
244- std::atomic<size_t > dml_safe_tables_copied {0 };
245- std::atomic<size_t > unsafe_tables_copied {0 };
176+ table_list flat_table_list;
177+ std::atomic<size_t > tables_copied {0 };
246178 std::atomic<size_t > log_files_copied {0 };
247179 std::atomic<bool > control_file_copied {false };
248180
@@ -267,9 +199,8 @@ namespace
267199 Dir_scan db_dir (dir_name, MYF (0 ));
268200 if (db_dir.is_error ())
269201 return 1 ;
270- dir_contents safe;
271- dir_contents unsafe;
272- int error= db_dir.for_each ([this , &safe, &unsafe, dir_name]
202+ dir_contents dir_tables;
203+ int error= db_dir.for_each ([&dir_tables]
273204 (const fileinfo &fi)
274205 {
275206 const LEX_CSTRING filename {fi.name , strlen (fi.name )};
@@ -282,30 +213,16 @@ namespace
282213 {
283214 if (!is_tmp_table (filename))
284215 {
285- auto is_safe = is_safe_table (dir_name, filename.str );
286- if (std::holds_alternative<bool >(is_safe))
287- {
288- std::string table_name (filename.str , base_filename_len);
289- if (std::get<bool >(is_safe))
290- safe.push_back (std::move (table_name));
291- else
292- unsafe.push_back (std::move (table_name));
293- }
294- else
295- {
296- return std::get<int >(is_safe);
297- }
216+ dir_tables.emplace_back (filename.str , base_filename_len);
298217 }
299218 }
300219 }
301220 return 0 ;
302221 });
303222 if (!error)
304223 {
305- if (!safe.empty ())
306- dml_safe_tables.emplace_back (dir_name, std::move (safe));
307- if (!unsafe.empty ())
308- unsafe_tables.emplace_back (dir_name, std::move (unsafe));
224+ if (!dir_tables.empty ())
225+ tables.emplace_back (dir_name, std::move (dir_tables));
309226 }
310227 return error;
311228 }
@@ -317,8 +234,7 @@ namespace
317234
318235 void flatten_table_lists () noexcept
319236 {
320- flatten_table_list (dml_safe_tables, dml_safe_table_list);
321- flatten_table_list (unsafe_tables, unsafe_tables_list);
237+ flatten_table_list (tables, flat_table_list);
322238 }
323239
324240 static void flatten_table_list (const database_dirs& dirs, table_list& list) noexcept
@@ -350,59 +266,26 @@ namespace
350266
351267 bool ensure_target_dirs () noexcept
352268 {
353- using string = std::string;
354- std::vector<const string*> dirs;
355- for (const database_dir &dir : dml_safe_tables)
356- dirs.push_back (&dir.first );
357- for (const database_dir &dir : unsafe_tables)
358- dirs.push_back (&dir.first );
359- std::sort (dirs.begin (), dirs.end (),
360- [](const string *a, const string *b) { return *a < *b; });
361- auto dirs_end = std::unique (dirs.begin (), dirs.end (),
362- [](const string *a, const string *b) { return *a == *b; });
363- for (auto it = dirs.begin (); it != dirs_end; ++it)
364- {
365- if (ensure_target_subdir ((*it)->c_str ()))
269+ for (const database_dir &dir : tables)
270+ if (::ensure_target_subdir (&target, dir.first .c_str ()) != 0 )
366271 return true ;
367- }
368272 return false ;
369273 }
370274
371- /*
372- Create directory in the target directory if it does not exist.
373- Return 0 on success, non-0 on failure. Set errno in case of failure
374- */
375- int ensure_target_subdir (const char * name) noexcept
376- {
377- return ::ensure_target_subdir (&target, name);
378- }
379-
380- /* Returns result or error code. */
381- std::variant<bool , int > is_safe_table (const char * dir_name, const char * myi_file_name)
275+ template <typename T, typename Fn>
276+ static int copy_from_list_step (const std::vector<T> &list,
277+ std::atomic<size_t > &copied,
278+ Fn copy_action)
382279 {
383- ARIA_TABLE_CAPABILITIES cap;
384- std::string path= build_path (dir_name, myi_file_name);
385- File fd= my_open (path.c_str (), O_RDONLY , MYF (MY_WME ));
386- if (fd < 0 )
280+ size_t idx= copied.fetch_add (1 , std::memory_order_relaxed);
281+ if (idx < list.size ())
387282 {
388- my_error (ER_CANT_OPEN_FILE , MYF (0 ), path.c_str (), my_errno);
389- return my_errno;
390- }
391- std::variant<bool , int > result;
392- mysql_mutex_lock (&THR_LOCK_maria);
393- int fail = aria_get_capabilities (fd, myi_file_name, &cap);
394- if (fail)
395- {
396- my_error (ER_FILE_CORRUPT , MYF (0 ), path.c_str ());
397- result= fail;
398- goto end;
283+ if (copy_action (list[idx]) != 0 )
284+ return -1 ;
285+ return static_cast <int >(list.size () - idx - 1U );
399286 }
400- result = cap.transactional && cap.checksum ;
401- aria_free_capabilities (&cap);
402- end:
403- mysql_mutex_unlock (&THR_LOCK_maria);
404- my_close (fd, MYF (0 ));
405- return result;
287+
288+ return 0 ;
406289 }
407290
408291 int copy_table (const backup_sink *sink, const table_ref& table) noexcept
0 commit comments