MySQL 8.0.31
Source Code Documentation
clone0clone.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 2017, 2022, Oracle and/or its affiliates.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License, version 2.0, as published by the
7Free Software Foundation.
8
9This program is also distributed with certain software (including but not
10limited to OpenSSL) that is licensed under separate terms, as designated in a
11particular file or component or in included license documentation. The authors
12of MySQL hereby grant you an additional permission to link the program and
13your derivative works with the separately licensed software that they have
14included with MySQL.
15
16This program is distributed in the hope that it will be useful, but WITHOUT
17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19for more details.
20
21You should have received a copy of the GNU General Public License along with
22this program; if not, write to the Free Software Foundation, Inc.,
2351 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
25*****************************************************************************/
26
27/** @file include/clone0clone.h
28 Innodb Clone System
29
30 *******************************************************/
31
32#ifndef CLONE_CLONE_INCLUDE
33#define CLONE_CLONE_INCLUDE
34
35#include <chrono>
36#include "db0err.h"
37#include "mysql/plugin.h" // thd_killed()
38#include "sql/handler.h"
39#include "univ.i"
40#include "ut0mutex.h"
41
42#include "clone0api.h"
43#include "clone0desc.h"
44#include "clone0repl.h"
45#include "clone0snapshot.h"
46
47#include <tuple>
48
49/** Directory under data directory for all clone status files. */
50#define CLONE_FILES_DIR OS_FILE_PREFIX "clone" OS_PATH_SEPARATOR_STR
51
52/** Clone in progress file name length. */
53const size_t CLONE_INNODB_FILE_LEN = 64;
54
55#ifdef UNIV_DEBUG
56/** Clone simulate recovery error file name. */
58 CLONE_FILES_DIR OS_FILE_PREFIX "status_crash_point";
59#endif
60
61/** Clone in progress file name. */
63 CLONE_FILES_DIR OS_FILE_PREFIX "status_in_progress";
64
65/** Clone error file name. */
67 CLONE_FILES_DIR OS_FILE_PREFIX "status_error";
68
69/** Clone fix up file name. Present when clone needs table fix up. */
72
73/** Clone recovery status. */
75 CLONE_FILES_DIR OS_FILE_PREFIX "status_recovery";
76
77/** Clone file name for list of files cloned in place. */
80
81/** Clone file name for list of files to be replaced. */
83 CLONE_FILES_DIR OS_FILE_PREFIX "replace_files";
84
85/** Clone file name for list of old files to be removed. */
88
89/** Clone file name for list of temp files renamed by ddl. */
92
93/** Clone file extension for files to be replaced. */
95
96/** Clone file extension for saved old files. */
97const char CLONE_INNODB_SAVED_FILE_EXTN[] = "." OS_FILE_PREFIX "clone_save";
98
99/** Clone file extension for temporary renamed file. */
100const char CLONE_INNODB_DDL_FILE_EXTN[] = "." OS_FILE_PREFIX "clone_ddl";
101
102using Clone_Msec = std::chrono::milliseconds;
104using Clone_Min = std::chrono::minutes;
105
106/** Default sleep time while waiting: 100 ms */
108
109/** Default alert interval in multiple of sleep time: 5 seconds */
111
112/** Default timeout in multiple of sleep time: 30 minutes */
114
115/** Clone system state */
121
122using Clone_Sys_State = std::atomic<Clone_System_State>;
123
124/** Clone Handle State */
131
132/** Clone task state */
134
135/** Maximum number of concurrent snapshots */
136const int MAX_SNAPSHOTS = 1;
137
138/** Maximum number of concurrent clones */
139const int MAX_CLONES = 1;
140
141/** Clone system array size */
143
144/** Snapshot system array size */
146
147/** Task for clone operation. Multiple task can concurrently work
148on a clone operation. */
150 /** Task Meta data */
152
153 /** Task state */
155
156 /** Serial descriptor byte string */
158
159 /** Serial descriptor allocated length */
161
162 /** If task is currently pinning file. Before opening
163 the file we must have a pin on file metadata. */
165
166 /** Current file descriptor */
168
169 /** Current file index */
171
172 /** Data files are read using OS buffer cache */
174
175 /** If master task */
177
178 /** If task has associated session */
180
181#ifdef UNIV_DEBUG
182 /** Ignore debug sync point */
184
185 /** Counter to restart in different state */
187#endif /* UNIV_DEBUG */
188
189 /** Allocated buffer */
191
192 /** Allocated buffer length */
194
195 /** Data transferred for current chunk in bytes */
196 uint32_t m_data_size;
197};
198
199class Clone_Handle;
200
201/** Task manager for manging the tasks for a clone operation */
203 public:
204 /** Initialize task manager for clone handle
205 @param[in] snapshot snapshot */
206 void init(Clone_Snapshot *snapshot);
207
208 /** Get task state mutex
209 @return state mutex */
210 ib_mutex_t *get_mutex() { return (&m_state_mutex); }
211
212 /** Handle any error raised by concurrent tasks.
213 @param[in] raise_error raise error if true
214 @return error code */
215 int handle_error_other_task(bool raise_error);
216
217 /** Set error number
218 @param[in] err error number
219 @param[in] file_name associated file name if any */
220 void set_error(int err, const char *file_name) {
222
223 ib::info(ER_IB_CLONE_OPERATION) << "Clone Set Error code: " << err
224 << " Saved Error code: " << m_saved_error;
225
226 /* Override any network error as we should not be waiting for restart
227 if other errors have occurred. */
230
231 if (file_name != nullptr) {
233 }
234 }
235
237 }
238
239 /** Add a task to task manager
240 @param[in] thd server THD object
241 @param[in] ref_loc reference locator from remote
242 @param[in] loc_len locator length in bytes
243 @param[out] task_id task identifier
244 @return error code */
245 int add_task(THD *thd, const byte *ref_loc, uint loc_len, uint &task_id);
246
247 /** Drop task from task manager
248 @param[in] thd server THD object
249 @param[in] task_id current task ID
250 @param[out] is_master true, if master task
251 @return true if needs to wait for re-start */
252 bool drop_task(THD *thd, uint task_id, bool &is_master);
253
254 /** Check if chunk is already reserved.
255 @param[in] chunk_num chunk number
256 @return true, iff chunk is reserved. */
257 bool is_chunk_reserved(uint32_t chunk_num) {
258 return m_chunk_info.m_reserved_chunks[chunk_num];
259 }
260
261 /** Reset chunk information for task
262 @param[in] task current task */
265
266 /* Reset current processing chunk */
267 task->m_task_meta.m_chunk_num = 0;
268 task->m_task_meta.m_block_num = 0;
269
270 if (task->m_data_size > 0) {
274
275 auto &monitor = m_clone_snapshot->get_clone_monitor();
276
277 monitor.update_work(task->m_data_size);
278 }
279
280 task->m_data_size = 0;
281 }
282
283 /** Get task by index
284 @param[in] index task index
285 @return task */
287 auto task = (m_clone_tasks + index);
288 ut_ad(task->m_task_state == CLONE_TASK_ACTIVE);
289
290 return (task);
291 }
292
293 /** Reserve next chunk from task manager. Called by individual tasks.
294 @param[in] task requesting task
295 @param[out] ret_chunk reserved chunk number
296 @param[out] ret_block start block number
297 '0' if no more chunk.
298 @return error code */
299 int reserve_next_chunk(Clone_Task *task, uint32_t &ret_chunk,
300 uint32_t &ret_block);
301
302 /** Set current chunk and block information
303 @param[in,out] task requesting task
304 @param[in] new_meta updated task metadata
305 @return error code */
306 int set_chunk(Clone_Task *task, Clone_Task_Meta *new_meta);
307
308 /** Track any incomplete chunks handled by the task
309 @param[in,out] task current task */
311
312 /** Initialize task manager for current state */
313 void init_state();
314
315 /** Reinitialize state using locator
316 @param[in] loc locator from remote client
317 @param[in] loc_len locator length in bytes */
318 void reinit_copy_state(const byte *loc, uint loc_len);
319
320 /** Reinitialize state using locator
321 @param[in] ref_loc current locator
322 @param[in] ref_len current locator length
323 @param[out] new_loc new locator to be sent to remote server
324 @param[out] new_len length of new locator
325 @param[in,out] alloc_len allocated length for locator buffer */
326 void reinit_apply_state(const byte *ref_loc, uint ref_len, byte *&new_loc,
327 uint &new_len, uint &alloc_len);
328
329 /** Reset state transition information */
334 }
335
336 /** Reset error information */
337 void reset_error() {
338 m_saved_error = 0;
339 m_err_file_name.assign("Clone File");
340 }
341
342 /** Get current clone state
343 @return clone state */
345
346 /** Check if in state transition
347 @return true if state transition is in progress */
349
350 /** Get attached snapshot
351 @return snapshot */
353
354 /** Move to next snapshot state. Each task must call this after
355 no more chunk is left in current state. The state can be changed
356 only after all tasks have finished transferring the reserved chunks.
357 @param[in] task clone task
358 @param[in] state_desc descriptor for next state
359 @param[in] new_state next state to move to
360 @param[in] cbk alert callback for long wait
361 @param[out] num_wait unfinished tasks in current state
362 @return error code */
363 int change_state(Clone_Task *task, Clone_Desc_State *state_desc,
364 Snapshot_State new_state, Clone_Alert_Func cbk,
365 uint &num_wait);
366
367 /** Check if state transition is over and all tasks moved to next state
368 @param[in] task requesting task
369 @param[in] new_state next state to move to
370 @param[in] exit_on_wait exit from transition if needs to wait
371 @param[in] in_err input error if already occurred
372 @param[out] num_wait number of tasks to move to next state
373 @return error code */
374 int check_state(Clone_Task *task, Snapshot_State new_state, bool exit_on_wait,
375 int in_err, uint32_t &num_wait);
376
377 /** Check if needs to send state metadata once
378 @param[in] task current task
379 @return true if needs to send state metadata */
381 if (task->m_is_master && m_send_state_meta) {
382 m_send_state_meta = false;
383 return (true);
384 }
385
386 return (false);
387 }
388
389 /** @return true if file metadata is transferred */
392 }
393
394 /** Set sub-state: all file metadata is transferred */
396
397 /** Mark state finished for current task
398 @param[in] task current task
399 @return error code */
400 int finish_state(Clone_Task *task);
401
402 /** Set acknowledged state
403 @param[in] state_desc State descriptor */
404 void ack_state(const Clone_Desc_State *state_desc);
405
406 /** Wait for acknowledgement
407 @param[in] clone parent clone handle
408 @param[in] task current task
409 @param[in] callback user callback interface
410 @return error code */
411 int wait_ack(Clone_Handle *clone, Clone_Task *task, Ha_clone_cbk *callback);
412
413 /** Check if state ACK is needed
414 @param[in] state_desc State descriptor
415 @return true if need to wait for ACK from remote */
416 bool check_ack(const Clone_Desc_State *state_desc) {
417 bool ret = true;
418
420
421 /* Check if state is already acknowledged */
422 if (m_ack_state == state_desc->m_state) {
424 ret = false;
426 }
427
429
430 return (ret);
431 }
432
433 /** Check if clone is restarted after failure
434 @return true if restarted */
435 bool is_restarted() { return (m_restart_count > 0); }
436
437 /** Allocate buffers for current task
438 @param[in,out] task current task
439 @return error code */
440 int alloc_buffer(Clone_Task *task);
441
442#ifdef UNIV_DEBUG
443 /** Check if needs to wait for debug sync point
444 @param[in] chunk_num chunk number to process
445 @param[in] task current task
446 @return true, if clone needs to check and wait */
447 bool debug_sync_check(uint32_t chunk_num, Clone_Task *task);
448
449 /** Wait during clone operation
450 @param[in] chunk_num chunk number to process
451 @param[in] task current task */
452 void debug_wait(uint chunk_num, Clone_Task *task);
453
454 /** Wait before sending DDL metadata. */
455 void debug_wait_ddl_meta();
456
457 /** Force restart clone operation by raising network error
458 @param[in] task current task
459 @param[in] in_err any err that has occurred
460 @param[in] restart_count restart counter
461 @return error code */
462 int debug_restart(Clone_Task *task, int in_err, int restart_count);
463
464 /** @return clone master task. */
466#endif /* UNIV_DEBUG */
467
468 private:
469 /** Check if we need to wait before adding current task
470 @param[in] ref_loc reference locator from remote
471 @param[in] loc_len reference locator length
472 @return true, if needs to wait */
473 bool wait_before_add(const byte *ref_loc, uint loc_len);
474
475 private:
476 /** Check if network error
477 @param[in] err error code
478 @return true if network error */
480 if (err == ER_NET_ERROR_ON_WRITE || err == ER_NET_READ_ERROR ||
481 err == ER_NET_WRITE_INTERRUPTED || err == ER_NET_READ_INTERRUPTED ||
482 err == ER_NET_WAIT_ERROR) {
483 return (true);
484 }
485 return (false);
486 }
487
488 /** Reserve free task from task manager and initialize
489 @param[in] thd server THD object
490 @param[out] task_id initialized task ID */
491 void reserve_task(THD *thd, uint &task_id);
492
493 /** Check if we should process incomplete chunk next. Incomplete
494 chunks could be there after a re-start from network failure. We always
495 process the chunks in order and need to choose accordingly.
496 @return if need to process incomplete chunk next. */
498 /* 1. Check if there is any incomplete chunk. */
499 auto &chunks = m_chunk_info.m_incomplete_chunks;
500 if (chunks.empty()) {
501 return (false);
502 }
503
504 /* 2. Check if all complete chunks are processed. */
505 auto min_complete_chunk = m_chunk_info.m_min_unres_chunk;
506 if (min_complete_chunk > m_chunk_info.m_total_chunks) {
507 return (true);
508 }
509
510 /* 3. Compare the minimum chunk number for complete and incomplete chunk */
511 auto it = chunks.begin();
512 auto min_incomplete_chunk = it->first;
513
514 ut_ad(min_complete_chunk != min_incomplete_chunk);
515 return (min_incomplete_chunk < min_complete_chunk);
516 }
517
518 /** Get next in complete chunk if any
519 @param[out] block_num first block number in chunk
520 @return incomplete chunk number */
521 uint32_t get_next_incomplete_chunk(uint32_t &block_num);
522
523 /** Get next unreserved chunk
524 @return chunk number */
525 uint32_t get_next_chunk();
526
527 private:
528 /** Mutex synchronizing access by concurrent tasks */
529 ib_mutex_t m_state_mutex;
530
531 /** Finished and incomplete chunk information */
533
534 /** Clone task array */
536
537 /** Current number of tasks */
539
540 /** Number of tasks finished current state */
542
543 /** Number of tasks in transit state */
545
546 /** Number of times clone is restarted */
548
549 /** Acknowledged state from client */
551
552 /** Current state for clone */
554
555 /** Next state: used during state transfer */
557
558 /* Sub state: File metadata is transferred */
560
561 /** Send state metadata before starting: Used for restart */
563
564 /** Save any error raised by a task */
566
567 /** File name related to the saved error */
568 std::string m_err_file_name;
569
570 /** Attached snapshot handle */
572};
573
574/** Clone Handle for copying or applying data */
576 public:
577 /** Construct clone handle
578 @param[in] handle_type clone handle type
579 @param[in] clone_version clone version
580 @param[in] clone_index index in clone array */
581 Clone_Handle(Clone_Handle_Type handle_type, uint clone_version,
582 uint clone_index);
583
584 /** Destructor: Detach from snapshot */
586
587 /** Initialize clone handle
588 @param[in] ref_loc reference locator
589 @param[in] ref_len reference locator length
590 @param[in] type clone type
591 @param[in] data_dir data directory for apply
592 @return error code */
593 int init(const byte *ref_loc, uint ref_len, Ha_clone_type type,
594 const char *data_dir);
595
596 /** Attach to the clone handle */
597 void attach() { ++m_ref_count; }
598
599 /** Detach from the clone handle
600 @return reference count */
602 ut_a(m_ref_count > 0);
603 --m_ref_count;
604
605 return (m_ref_count);
606 }
607
608 /** Get locator for the clone handle.
609 @param[out] loc_len serialized locator length
610 @return serialized clone locator */
611 byte *get_locator(uint &loc_len);
612
613 /** @return clone data directory */
614 const char *get_datadir() const { return (m_clone_dir); }
615
616 /** @return true, if clone is replacing current data directory. */
617 bool replace_datadir() const {
618 return (!is_copy_clone() && m_clone_dir == nullptr);
619 }
620
621 /** Build locator descriptor for the clone handle
622 @param[out] loc_desc locator descriptor */
623 void build_descriptor(Clone_Desc_Locator *loc_desc);
624
625 /** Add a task to clone handle
626 @param[in] thd server THD object
627 @param[in] ref_loc reference locator from remote
628 @param[in] ref_len reference locator length
629 @param[out] task_id task identifier
630 @return error code */
631 int add_task(THD *thd, const byte *ref_loc, uint ref_len, uint &task_id) {
632 return (m_clone_task_manager.add_task(thd, ref_loc, ref_len, task_id));
633 }
634
635 /** Drop task from clone handle
636 @param[in] thd server THD object
637 @param[in] task_id current task ID
638 @param[out] is_master true, if master task
639 @return true if needs to wait for re-start */
640 bool drop_task(THD *thd, uint task_id, bool &is_master);
641
642 /** Save current error number
643 @param[in] err error number */
644 void save_error(int err) {
645 if (err != 0) {
647 }
648 }
649
650 /** Check for error from other tasks and DDL
651 @param[in,out] thd session THD
652 @return error code */
653 int check_error(THD *thd) {
654 bool has_thd = (thd != nullptr);
656 /* Save any error reported */
658 return (err);
659 }
660
661 /** @return true if any task is interrupted */
664 return (err == ER_QUERY_INTERRUPTED);
665 }
666
667 /** Get clone handle index in clone array
668 @return array index */
670
671 /** Get clone data descriptor version
672 @return version */
674
675 /** @return active snapshot */
677
678 /** Check if it is copy clone
679 @return true if copy clone handle */
681
682 /** Check if clone type matches
683 @param[in] other_handle_type type to match with
684 @return true if type matches with clone handle type */
685 bool match_hdl_type(Clone_Handle_Type other_handle_type) {
686 return (m_clone_handle_type == other_handle_type);
687 }
688
689 /** Set current clone state
690 @param[in] state clone handle state */
692
693 /** Set clone to ABORT state end any attached snapshot. */
694 void set_abort();
695
696 /** Check if clone state is active
697 @return true if in active state */
699
700 /** Check if clone is initialized
701 @return true if in initial state */
703
704 /** Check if clone is idle waiting for restart
705 @return true if clone is in idle state */
707
708 /** Check if clone is aborted
709 @return true if clone is aborted */
711
712 /** Restart copy after a network failure
713 @param[in] thd server THD object
714 @param[in] loc locator with copy state from remote client
715 @param[in] loc_len locator length in bytes
716 @return error code */
717 int restart_copy(THD *thd, const byte *loc, uint loc_len);
718
719 /** Build locator with current state and restart apply
720 @param[in] thd server THD object
721 @param[in,out] loc loctor with current state information
722 @param[in,out] loc_len locator length in bytes
723 @return error code */
724 int restart_apply(THD *thd, const byte *&loc, uint &loc_len);
725
726 /** Transfer snapshot data via callback
727 @param[in] task_id current task ID
728 @param[in] callback user callback interface
729 @return error code */
730 int copy(uint task_id, Ha_clone_cbk *callback);
731
732 /** Apply snapshot data received via callback
733 @param[in] thd server THD
734 @param[in] task_id current task ID
735 @param[in] callback user callback interface
736 @return error code */
737 int apply(THD *thd, uint task_id, Ha_clone_cbk *callback);
738
739 /** Send keep alive while during long wait
740 @param[in] task task that is sending the information
741 @param[in] callback callback interface
742 @return error code */
743 int send_keep_alive(Clone_Task *task, Ha_clone_cbk *callback);
744
745 /** @return true iff DDL should abort running clone. */
746 bool abort_by_ddl() const { return m_abort_ddl; }
747
748 /** Allow concurrent DDL to abort clone. */
749 void set_ddl_abort() { m_abort_ddl = true; }
750
751#ifdef UNIV_DEBUG
752 /** Close master task file if open and unpin. */
753 void close_master_file();
754#endif /* UNIV_DEBUG */
755
756 private:
757 /** Check if enough space is there to clone.
758 @param[in] task current task
759 @return error if not enough space */
760 int check_space(const Clone_Task *task);
761
762 /** Create clone data directory.
763 @return error code */
765
766 /** Display clone progress
767 @param[in] cur_chunk current chunk number
768 @param[in] max_chunk total number of chunks
769 @param[in,out] percent_done percentage completed
770 @param[in,out] disp_time last displayed time */
771 void display_progress(uint32_t cur_chunk, uint32_t max_chunk,
772 uint32_t &percent_done,
773 std::chrono::steady_clock::time_point &disp_time);
774
775 /** Create a tablespace file and initialize.
776 @param[in] file_ctx file information
777 @param[in] file_type file type (data, log etc.)
778 @param[in] init true, if needs to write initial pages.
779 @return error code */
780 int file_create_init(const Clone_file_ctx *file_ctx, ulint file_type,
781 bool init);
782
783 using File_init_cbk = std::function<dberr_t(pfs_os_file_t)>;
784
785 /** Open file for the task
786 @param[in] task clone task
787 @param[in] file_ctx file information
788 @param[in] file_type file type (data, log etc.)
789 @param[in] create_file create if not present
790 @param[in] init_cbk callback to fill initial data
791 @return error code */
792 int open_file(Clone_Task *task, const Clone_file_ctx *file_ctx,
793 ulint file_type, bool create_file, File_init_cbk &init_cbk);
794
795 /** Close file for the task
796 @param[in] task clone task
797 @return error code */
798 int close_file(Clone_Task *task);
799
800 /** Check and pin a file context if not already pinned.
801 @param[in,out] task clone task
802 @param[in,out] file_ctx snapshot file context
803 @param[out] handle_deleted true, iff caller needs to handle
804 deleted file state
805 @return error code */
806 int check_and_pin_file(Clone_Task *task, Clone_file_ctx *file_ctx,
807 bool &handle_deleted);
808
809 /** Unpin and close currently pinned file.
810 @param[in,out] task clone task
811 @return error code */
813
814 /** Check if the task pins a file context.
815 @param[in] task clone task
816 @param[in] file_ctx snapshot file context
817 @return true, if task pins the file, other file. */
818 std::tuple<bool, bool> pins_file(const Clone_Task *task,
819 const Clone_file_ctx *file_ctx);
820
821 /** Callback providing the file reference and data length to copy
822 @param[in] cbk callback interface
823 @param[in] task clone task
824 @param[in] len data length
825 @param[in] buf_cbk invoke buffer callback
826 @param[in] offset file offset
827 @param[in] location location where func invoked
828 @return error code */
829 int file_callback(Ha_clone_cbk *cbk, Clone_Task *task, uint len, bool buf_cbk,
830 uint64_t offset
831#ifdef UNIV_PFS_IO
832 ,
833 ut::Location location
834#endif /* UNIV_PFS_IO */
835 );
836
837 /** Move to next state
838 @param[in] task clone task
839 @param[in] callback callback interface
840 @param[in] state_desc descriptor for next state to move to
841 @return error code */
842 int move_to_next_state(Clone_Task *task, Ha_clone_cbk *callback,
843 Clone_Desc_State *state_desc);
844
845 /** Send current state information via callback
846 @param[in] task task that is sending the information
847 @param[in] callback callback interface
848 @param[in] is_start if it is the start of current state
849 @return error code */
850 int send_state_metadata(Clone_Task *task, Ha_clone_cbk *callback,
851 bool is_start);
852
853 /** Send current task information via callback
854 @param[in] task task that is sending the information
855 @param[in] callback callback interface
856 @return error code */
857 int send_task_metadata(Clone_Task *task, Ha_clone_cbk *callback);
858
859 /** Send all DDL metadata generated.
860 @param[in] task task that is sending the information
861 @param[in] callback callback interface
862 @return error code */
863 int send_all_ddl_metadata(Clone_Task *task, Ha_clone_cbk *callback);
864
865 /** Send all file information via callback
866 @param[in] task task that is sending the information
867 @param[in] callback callback interface
868 @return error code */
869 int send_all_file_metadata(Clone_Task *task, Ha_clone_cbk *callback);
870
871 /** Send current file information via callback
872 @param[in] task task that is sending the information
873 @param[in] file_meta file meta information
874 @param[in] is_redo true if redo file
875 @param[in] callback callback interface
876 @return error code */
877 int send_file_metadata(Clone_Task *task, const Clone_File_Meta *file_meta,
878 bool is_redo, Ha_clone_cbk *callback);
879
880 /** Send cloned data via callback
881 @param[in] task task that is sending the information
882 @param[in] file_ctx file information
883 @param[in] offset file offset
884 @param[in] buffer data buffer or NULL if send from file
885 @param[in] size data buffer size
886 @param[in] new_file_size updated file size from page 0
887 @param[in] callback callback interface
888 @return error code */
889 int send_data(Clone_Task *task, const Clone_file_ctx *file_ctx,
890 uint64_t offset, byte *buffer, uint32_t size,
891 uint64_t new_file_size, Ha_clone_cbk *callback);
892
893 /** Process a data chunk and send data blocks via callback
894 @param[in] task task that is sending the information
895 @param[in] chunk_num chunk number to process
896 @param[in] block_num start block number
897 @param[in] callback callback interface
898 @return error code */
899 int process_chunk(Clone_Task *task, uint32_t chunk_num, uint32_t block_num,
900 Ha_clone_cbk *callback);
901
902 /** Create apply task based on task metadata in callback
903 @param[in] task current task
904 @param[in] callback callback interface
905 @return error code */
906 int apply_task_metadata(Clone_Task *task, Ha_clone_cbk *callback);
907
908 /** Move to next state based on state metadata and set
909 state information
910 @param[in] task current task
911 @param[in,out] callback callback interface
912 @param[in,out] state_desc clone state descriptor
913 @return error code */
914 int ack_state_metadata(Clone_Task *task, Ha_clone_cbk *callback,
915 Clone_Desc_State *state_desc);
916
917 /** Notify state change via callback.
918 @param[in] task current task
919 @param[in,out] callback callback interface
920 @param[in,out] state_desc clone state descriptor */
921 void notify_state_change(Clone_Task *task, Ha_clone_cbk *callback,
922 Clone_Desc_State *state_desc);
923
924 /** Move to next state based on state metadata and set
925 state information
926 @param[in] task current task
927 @param[in] callback callback interface
928 @return error code */
929 int apply_state_metadata(Clone_Task *task, Ha_clone_cbk *callback);
930
931 /** Create file metadata based on callback
932 @param[in] task current task
933 @param[in] callback callback interface
934 @return error code */
935 int apply_file_metadata(Clone_Task *task, Ha_clone_cbk *callback);
936
937 /** Apply DDL delete to existing file to update chunk and block information.
938 @param[in,out] task task performing the operation
939 @param[in,out] file_ctx current file context
940 @param[in] new_meta new file metadata
941 @return error code */
942 int apply_file_delete(Clone_Task *task, Clone_file_ctx *file_ctx,
943 const Clone_File_Meta *new_meta);
944
945 /** Apply DDL changes to file at the end of FILE_COPY stage.
946 @param[in] new_meta new file metadata
947 @param[in,out] file_ctx current file context
948 @return error code. */
949 int apply_ddl(const Clone_File_Meta *new_meta, Clone_file_ctx *file_ctx);
950
951 /** Set compression type based on local capability.
952 @param[in,out] file_ctx file context
953 @return error code. */
954 int set_compression(Clone_file_ctx *file_ctx);
955
956 /** Fix the file name and meta information for all files that are renamed
957 with DDL extension.
958 @param[in] task current task
959 @return error code. */
960 int fix_all_renamed(const Clone_Task *task);
961
962 /** Apply data received via callback
963 @param[in] task current task
964 @param[in] callback callback interface
965 @return error code */
966 int apply_data(Clone_Task *task, Ha_clone_cbk *callback);
967
968 /** Receive data from callback and apply
969 @param[in] task task that is receiving the information
970 @param[in] offset file offset for applying data
971 @param[in] file_size updated file size
972 @param[in] size data length in bytes
973 @param[in] callback callback interface
974 @return error code */
975 int receive_data(Clone_Task *task, uint64_t offset, uint64_t file_size,
976 uint32_t size, Ha_clone_cbk *callback);
977
978 /** Read compressed length from the page
979 @param[in] buffer data buffer
980 @param[in] len buffer length
981 @param[in] block_size block size
982 @param[out] compressed_len compressed length
983 @return true for compressed page false otherwise. */
984 bool read_compressed_len(unsigned char *buffer, uint32_t len,
985 uint32_t block_size, uint32_t &compressed_len);
986
987 /** Write pages to file and punch holes
988 @param[in] file_meta clone file metadata
989 @param[in] buffer data buffer
990 @param[in] len buffer length
991 @param[in] file file descriptor
992 @param[in] start_off starting offset in file
993 @return error code */
994 int sparse_file_write(Clone_File_Meta *file_meta, unsigned char *buffer,
995 uint32_t len, pfs_os_file_t file, uint64_t start_off);
996
997 /** Modify page encryption attribute and/or punch hole.
998 @param[in] task task that is applying data
999 @param[in] offset file offset for applying data
1000 @param[in,out] buffer data to apply
1001 @param[in] buf_len data buffer length
1002 @return error code */
1003 int modify_and_write(const Clone_Task *task, uint64_t offset,
1004 unsigned char *buffer, uint32_t buf_len);
1005
1006 private:
1007 /** Clone handle type: Copy, Apply */
1009
1010 /** Clone handle state */
1012
1013 /** Fixed locator for version negotiation. */
1015
1016 /** Serialized locator */
1018
1019 /** Locator length in bytes */
1021
1022 /** Serialized Restart locator */
1024
1025 /** Restart locator length in bytes */
1027
1028 /** Clone descriptor version in use */
1030
1031 /** Index in global array */
1033
1034 /** Unique clone identifier */
1035 uint64_t m_clone_id;
1036
1037 /** Reference count */
1039
1040 /** Allow restart of clone operation after network failure */
1042
1043 /** If concurrent DDL should abort clone. */
1045
1046 /** Clone data directory */
1047 const char *m_clone_dir;
1048
1049 /** Clone task manager */
1051};
1052
1053/** Clone System */
1055 public:
1056 /** RAII style wrapper to enter and exit wait stage. */
1058 public:
1059 /** Constructor to change the THD information string.
1060 @param[in] new_info new information string */
1061 explicit Wait_stage(const char *new_info);
1062
1063 /** Destructor to revert back the old information string. */
1064 ~Wait_stage();
1065
1066 private:
1067 /** Saved old THD information string. */
1068 const char *m_saved_info;
1069 };
1070
1072 public:
1073 /** Constructor to get and pin clone handle. */
1074 explicit Acquire_clone();
1075
1076 /** Destructor to release and free clone handle if necessary. */
1078
1079 /** Get current clone snapshot. */
1081
1082 private:
1083 /** Acquired clone handle */
1085 };
1086
1087 /** Construct clone system */
1088 Clone_Sys();
1089
1090 /** Destructor: Call during system shutdown */
1091 ~Clone_Sys();
1092
1093 /** Create and add a new clone handle to clone system
1094 @param[in] loc locator
1095 @param[in] hdl_type handle type
1096 @param[out] clone_hdl clone handle
1097 @return error code */
1098 int add_clone(const byte *loc, Clone_Handle_Type hdl_type,
1099 Clone_Handle *&clone_hdl);
1100
1101 /** drop a clone handle from clone system
1102 @param[in] clone_handle Clone handle */
1104
1105 /** Find if a clone is already running for the reference locator
1106 @param[in] ref_loc reference locator
1107 @param[in] loc_len reference locator length
1108 @param[in] hdl_type clone type
1109 @return clone handle if found, NULL otherwise */
1110 Clone_Handle *find_clone(const byte *ref_loc, uint loc_len,
1111 Clone_Handle_Type hdl_type);
1112
1113 /** Get the clone handle from locator by index
1114 @param[in] loc locator
1115 @param[in] loc_len locator length in bytes
1116 @return clone handle */
1117 Clone_Handle *get_clone_by_index(const byte *loc, uint loc_len);
1118
1119 /** Get or create a snapshot for clone and attach
1120 @param[in] hdl_type handle type
1121 @param[in] clone_type clone type
1122 @param[in] snapshot_id snapshot identifier
1123 @param[in] is_pfs_monitor true, if needs PFS monitoring
1124 @param[out] snapshot clone snapshot
1125 @return error code */
1126 int attach_snapshot(Clone_Handle_Type hdl_type, Ha_clone_type clone_type,
1127 uint64_t snapshot_id, bool is_pfs_monitor,
1128 Clone_Snapshot *&snapshot);
1129
1130 /** Detach clone handle from snapshot
1131 @param[in] snapshot snapshot
1132 @param[in] hdl_type handle type */
1133 void detach_snapshot(Clone_Snapshot *snapshot, Clone_Handle_Type hdl_type);
1134
1135 /** Mark clone state to abort if no active clone. If force is set,
1136 abort all active clones and set state to abort.
1137 @param[in] force force active clones to abort
1138 @return true if global state is set to abort successfully */
1139 bool mark_abort(bool force);
1140
1141 /** Mark clone state to active if no other abort request */
1142 void mark_active();
1143
1144 /** Mark to indicate that new clone operations should wait. */
1145 void mark_wait();
1146
1147 /** Free the wait marker. */
1148 void mark_free();
1149
1150#ifdef UNIV_DEBUG
1151 /** Debug wait while starting clone and waiting for free marker. */
1153
1154 /** Close donor master task file if open and unpin. */
1156#endif /* UNIV_DEBUG */
1157
1158 /** Wait for marker to get freed.
1159 @param[in,out] thd user session
1160 @return, error if timeout */
1161 int wait_for_free(THD *thd);
1162
1163 /** Begin restricted state during some critical ddl phase.
1164 @param[in] type ddl notification type
1165 @param[in] space tablespace ID for which notification is sent
1166 @param[in] no_wait return with error if needs to wait
1167 @param[in] check_intr check for interrupt during wait
1168 @param[out] blocked_state blocked state when state change is blocked
1169 @param[out] error mysql error code
1170 @return true iff clone needs to wait for state change. */
1171 bool begin_ddl_state(Clone_notify::Type type, space_id_t space, bool no_wait,
1172 bool check_intr, uint32_t &blocked_state, int &error);
1173
1174 /** End restricted state during some critical ddl phase.
1175 @param[in] type ddl notification type
1176 @param[in] space tablespace ID for which notification is sent
1177 @param[in] blocked_state blocked state when state change is blocked */
1179 uint32_t blocked_state);
1180
1181 /** Get next unique ID
1182 @return unique ID */
1183 uint64_t get_next_id();
1184
1185 /** Get clone sys mutex
1186 @return clone system mutex */
1187 ib_mutex_t *get_mutex() { return (&m_clone_sys_mutex); }
1188
1189 /** Clone System state */
1191
1192 /** Number of active abort requests */
1194
1195 /** Number of active wait requests */
1197
1198 /** Function to check wait condition
1199 @param[in] is_alert print alert message
1200 @param[out] result true, if condition is satisfied
1201 @return error code */
1202 using Wait_Cond_Cbk_Func = std::function<int(bool is_alert, bool &result)>;
1203
1204 /** Wait till the condition is satisfied or timeout.
1205 @param[in] sleep_time sleep time in milliseconds
1206 @param[in] timeout total time to wait in seconds
1207 @param[in] alert_interval alert interval in seconds
1208 @param[in] func callback function for condition check
1209 @param[in] mutex release during sleep and re-acquire
1210 @param[out] is_timeout true if timeout
1211 @return error code returned by callback function. */
1212 static int wait(Clone_Msec sleep_time, Clone_Sec timeout,
1213 Clone_Sec alert_interval, Wait_Cond_Cbk_Func &&func,
1214 ib_mutex_t *mutex, bool &is_timeout) {
1215 int err = 0;
1216 bool wait = true;
1217 is_timeout = false;
1218
1219 int loop_count = 0;
1220 auto alert_count = static_cast<int>(alert_interval / sleep_time);
1221 auto total_count = static_cast<int>(timeout / sleep_time);
1222
1223 /* Call function once before waiting. */
1224 err = func(false, wait);
1225
1226 /* Start with 1 ms sleep and increase up to target sleep time. */
1227 Clone_Msec cur_sleep_time{1};
1228
1229 while (!is_timeout && wait && err == 0) {
1230 /* Release input mutex */
1231 if (mutex != nullptr) {
1232 ut_ad(mutex_own(mutex));
1233 mutex_exit(mutex);
1234 }
1235
1236 /* Limit sleep time to what is passed by caller. */
1237 if (cur_sleep_time > sleep_time) {
1238 cur_sleep_time = sleep_time;
1239 }
1240
1241 std::this_thread::sleep_for(cur_sleep_time);
1242
1243 if (cur_sleep_time < sleep_time) {
1244 /* Double sleep time in each iteration till we reach target. */
1245 cur_sleep_time *= 2;
1246 } else {
1247 /* Increment count once we have reached target sleep time. */
1248 ++loop_count;
1249 }
1250
1251 /* Acquire input mutex back */
1252 if (mutex != nullptr) {
1253 mutex_enter(mutex);
1254 }
1255
1256 /* We have not yet reached the target sleep time. */
1257 if (loop_count == 0) {
1258 err = func(false, wait);
1259 continue;
1260 }
1261
1262 auto alert = (alert_count > 0) ? (loop_count % alert_count == 0) : true;
1263
1264 err = func(alert, wait);
1265
1266 is_timeout = (loop_count > total_count);
1267 }
1268 return (err);
1269 }
1270
1271 /** Wait till the condition is satisfied or default timeout.
1272 @param[in] func callback function for condition check
1273 @param[in] mutex release during sleep and re-acquire
1274 @param[out] is_timeout true if timeout
1275 @return error code returned by callback function. */
1276 static int wait_default(Wait_Cond_Cbk_Func &&func, ib_mutex_t *mutex,
1277 bool &is_timeout) {
1280 std::forward<Wait_Cond_Cbk_Func>(func), mutex, is_timeout));
1281 }
1282
1283 /** Check if any active clone is running.
1284 @param[in] print_alert print alert message
1285 @return true, if concurrent clone in progress */
1286 bool check_active_clone(bool print_alert);
1287
1288 /** Check if any active clone is running.
1289 @return (true, handle) if concurrent clone in progress */
1290 std::tuple<bool, Clone_Handle *> check_active_clone();
1291
1292 /** @return GTID persistor */
1294
1295 /** Remember that all innodb spaces are initialized after last startup. */
1297
1298 /** @return true if all innodb spaces are initialized. */
1299 bool is_space_initialized() const { return m_space_initialized.load(); }
1300
1301 private:
1302 /** Find free index to allocate new clone handle.
1303 @param[in] hdl_type clone handle type
1304 @param[out] free_index free index in array
1305 @return error code */
1306 int find_free_index(Clone_Handle_Type hdl_type, uint &free_index);
1307
1308 /** Handle restricted state during critical ddl phase.
1309 @param[in] type ddl notification type
1310 @param[in] space tablespace ID for which notification is sent
1311 @param[in] begin true, if beginning state
1312 false, if ending
1313 @return true iff clone needs to wait for state change. */
1315
1316 private:
1317 /** Array of clone handles */
1319
1320 /** Number of copy clones */
1322
1323 /** Number of apply clones */
1325
1326 /** Array of clone snapshots */
1328
1329 /** Number of copy snapshots */
1331
1332 /** Number of apply snapshots */
1334
1335 /** Clone system mutex */
1337
1338 /** Clone unique ID generator */
1340
1341 /** If all innodb tablespaces are initialized. */
1342 std::atomic<bool> m_space_initialized;
1343
1344 /** GTID persister */
1346};
1347
1348/** Clone system global */
1349extern Clone_Sys *clone_sys;
1350
1351#endif /* CLONE_CLONE_INCLUDE */
uint32_t space_id_t
Tablespace identifier.
Definition: api0api.h:50
Clone Handle for copying or applying data.
Definition: clone0clone.h:575
int send_file_metadata(Clone_Task *task, const Clone_File_Meta *file_meta, bool is_redo, Ha_clone_cbk *callback)
Send current file information via callback.
Definition: clone0copy.cc:1133
bool match_hdl_type(Clone_Handle_Type other_handle_type)
Check if clone type matches.
Definition: clone0clone.h:685
int sparse_file_write(Clone_File_Meta *file_meta, unsigned char *buffer, uint32_t len, pfs_os_file_t file, uint64_t start_off)
Write pages to file and punch holes.
Definition: clone0apply.cc:1265
void close_master_file()
Close master task file if open and unpin.
Definition: clone0clone.cc:686
void build_descriptor(Clone_Desc_Locator *loc_desc)
Build locator descriptor for the clone handle.
Definition: clone0clone.cc:2082
int set_compression(Clone_file_ctx *file_ctx)
Set compression type based on local capability.
Definition: clone0apply.cc:1008
int receive_data(Clone_Task *task, uint64_t offset, uint64_t file_size, uint32_t size, Ha_clone_cbk *callback)
Receive data from callback and apply.
Definition: clone0apply.cc:1391
int send_state_metadata(Clone_Task *task, Ha_clone_cbk *callback, bool is_start)
Send current state information via callback.
Definition: clone0copy.cc:1039
void notify_state_change(Clone_Task *task, Ha_clone_cbk *callback, Clone_Desc_State *state_desc)
Notify state change via callback.
Definition: clone0apply.cc:698
byte * m_clone_locator
Serialized locator.
Definition: clone0clone.h:1017
bool is_active()
Check if clone state is active.
Definition: clone0clone.h:698
int copy(uint task_id, Ha_clone_cbk *callback)
Transfer snapshot data via callback.
Definition: clone0copy.cc:1311
bool is_copy_clone() const
Check if it is copy clone.
Definition: clone0clone.h:680
uint m_clone_desc_version
Clone descriptor version in use.
Definition: clone0clone.h:1029
void display_progress(uint32_t cur_chunk, uint32_t max_chunk, uint32_t &percent_done, std::chrono::steady_clock::time_point &disp_time)
Display clone progress.
Definition: clone0copy.cc:1294
int apply_data(Clone_Task *task, Ha_clone_cbk *callback)
Apply data received via callback.
Definition: clone0apply.cc:1515
int process_chunk(Clone_Task *task, uint32_t chunk_num, uint32_t block_num, Ha_clone_cbk *callback)
Process a data chunk and send data blocks via callback.
Definition: clone0copy.cc:1438
uint m_restart_loc_len
Restart locator length in bytes.
Definition: clone0clone.h:1026
int ack_state_metadata(Clone_Task *task, Ha_clone_cbk *callback, Clone_Desc_State *state_desc)
Move to next state based on state metadata and set state information.
Definition: clone0apply.cc:708
int open_file(Clone_Task *task, const Clone_file_ctx *file_ctx, ulint file_type, bool create_file, File_init_cbk &init_cbk)
Open file for the task.
Definition: clone0clone.cc:2225
bool is_interrupted()
Definition: clone0clone.h:662
int apply_file_delete(Clone_Task *task, Clone_file_ctx *file_ctx, const Clone_File_Meta *new_meta)
Apply DDL delete to existing file to update chunk and block information.
Definition: clone0apply.cc:729
std::tuple< bool, bool > pins_file(const Clone_Task *task, const Clone_file_ctx *file_ctx)
Check if the task pins a file context.
Definition: clone0copy.cc:1751
int send_data(Clone_Task *task, const Clone_file_ctx *file_ctx, uint64_t offset, byte *buffer, uint32_t size, uint64_t new_file_size, Ha_clone_cbk *callback)
Send cloned data via callback.
Definition: clone0copy.cc:1199
uint m_clone_arr_index
Index in global array.
Definition: clone0clone.h:1032
void set_state(Clone_Handle_State state)
Set current clone state.
Definition: clone0clone.h:691
int close_and_unpin_file(Clone_Task *task)
Unpin and close currently pinned file.
Definition: clone0copy.cc:1723
int move_to_next_state(Clone_Task *task, Ha_clone_cbk *callback, Clone_Desc_State *state_desc)
Move to next state.
Definition: clone0clone.cc:2131
void set_abort()
Set clone to ABORT state end any attached snapshot.
Definition: clone0clone.cc:2211
int check_and_pin_file(Clone_Task *task, Clone_file_ctx *file_ctx, bool &handle_deleted)
Check and pin a file context if not already pinned.
Definition: clone0copy.cc:1687
bool drop_task(THD *thd, uint task_id, bool &is_master)
Drop task from clone handle.
Definition: clone0clone.cc:2098
int restart_copy(THD *thd, const byte *loc, uint loc_len)
Restart copy after a network failure.
Definition: clone0copy.cc:1619
int apply(THD *thd, uint task_id, Ha_clone_cbk *callback)
Apply snapshot data received via callback.
Definition: clone0apply.cc:1558
int fix_all_renamed(const Clone_Task *task)
Fix the file name and meta information for all files that are renamed with DDL extension.
Definition: clone0apply.cc:935
int check_space(const Clone_Task *task)
Check if enough space is there to clone.
Definition: clone0apply.cc:551
bool abort_by_ddl() const
Definition: clone0clone.h:746
int close_file(Clone_Task *task)
Close file for the task.
Definition: clone0clone.cc:2318
bool is_idle()
Check if clone is idle waiting for restart.
Definition: clone0clone.h:706
bool m_abort_ddl
If concurrent DDL should abort clone.
Definition: clone0clone.h:1044
bool replace_datadir() const
Definition: clone0clone.h:617
bool is_init()
Check if clone is initialized.
Definition: clone0clone.h:702
void attach()
Attach to the clone handle.
Definition: clone0clone.h:597
void set_ddl_abort()
Allow concurrent DDL to abort clone.
Definition: clone0clone.h:749
int apply_file_metadata(Clone_Task *task, Ha_clone_cbk *callback)
Create file metadata based on callback.
Definition: clone0apply.cc:1121
int send_all_ddl_metadata(Clone_Task *task, Ha_clone_cbk *callback)
Send all DDL metadata generated.
Definition: clone0copy.cc:1768
uint detach()
Detach from the clone handle.
Definition: clone0clone.h:601
int restart_apply(THD *thd, const byte *&loc, uint &loc_len)
Build locator with current state and restart apply.
Definition: clone0apply.cc:1607
byte * get_locator(uint &loc_len)
Get locator for the clone handle.
Definition: clone0clone.cc:2058
int apply_ddl(const Clone_File_Meta *new_meta, Clone_file_ctx *file_ctx)
Apply DDL changes to file at the end of FILE_COPY stage.
Definition: clone0apply.cc:796
~Clone_Handle()
Destructor: Detach from snapshot.
Definition: clone0clone.cc:1939
int modify_and_write(const Clone_Task *task, uint64_t offset, unsigned char *buffer, uint32_t buf_len)
Modify page encryption attribute and/or punch hole.
Definition: clone0apply.cc:1332
int apply_state_metadata(Clone_Task *task, Ha_clone_cbk *callback)
Move to next state based on state metadata and set state information.
Definition: clone0apply.cc:590
int send_all_file_metadata(Clone_Task *task, Ha_clone_cbk *callback)
Send all file information via callback.
Definition: clone0copy.cc:1105
uint m_ref_count
Reference count.
Definition: clone0clone.h:1038
const char * m_clone_dir
Clone data directory.
Definition: clone0clone.h:1047
uint m_locator_length
Locator length in bytes.
Definition: clone0clone.h:1020
Clone_Task_Manager m_clone_task_manager
Clone task manager.
Definition: clone0clone.h:1050
bool read_compressed_len(unsigned char *buffer, uint32_t len, uint32_t block_size, uint32_t &compressed_len)
Read compressed length from the page.
Definition: clone0apply.cc:1244
int apply_task_metadata(Clone_Task *task, Ha_clone_cbk *callback)
Create apply task based on task metadata in callback.
Definition: clone0apply.cc:532
byte * m_restart_loc
Serialized Restart locator.
Definition: clone0clone.h:1023
int create_clone_directory()
Create clone data directory.
Definition: clone0clone.cc:1949
void save_error(int err)
Save current error number.
Definition: clone0clone.h:644
const char * get_datadir() const
Definition: clone0clone.h:614
int send_keep_alive(Clone_Task *task, Ha_clone_cbk *callback)
Send keep alive while during long wait.
Definition: clone0copy.cc:1013
int send_task_metadata(Clone_Task *task, Ha_clone_cbk *callback)
Send current task information via callback.
Definition: clone0copy.cc:992
Clone_Snapshot * get_snapshot()
Definition: clone0clone.h:676
Clone_Handle_State m_clone_handle_state
Clone handle state.
Definition: clone0clone.h:1011
uint get_version()
Get clone data descriptor version.
Definition: clone0clone.h:673
Clone_Handle_Type m_clone_handle_type
Clone handle type: Copy, Apply.
Definition: clone0clone.h:1008
int file_callback(Ha_clone_cbk *cbk, Clone_Task *task, uint len, bool buf_cbk, uint64_t offset, ut::Location location)
Callback providing the file reference and data length to copy.
Definition: clone0clone.cc:2337
bool m_allow_restart
Allow restart of clone operation after network failure.
Definition: clone0clone.h:1041
int file_create_init(const Clone_file_ctx *file_ctx, ulint file_type, bool init)
Create a tablespace file and initialize.
Definition: clone0apply.cc:1057
uint64_t m_clone_id
Unique clone identifier.
Definition: clone0clone.h:1035
std::function< dberr_t(pfs_os_file_t)> File_init_cbk
Definition: clone0clone.h:783
Clone_Handle(Clone_Handle_Type handle_type, uint clone_version, uint clone_index)
Construct clone handle.
Definition: clone0clone.cc:1908
int init(const byte *ref_loc, uint ref_len, Ha_clone_type type, const char *data_dir)
Initialize clone handle.
Definition: clone0clone.cc:1993
uint get_index()
Get clone handle index in clone array.
Definition: clone0clone.h:669
int add_task(THD *thd, const byte *ref_loc, uint ref_len, uint &task_id)
Add a task to clone handle.
Definition: clone0clone.h:631
bool is_abort()
Check if clone is aborted.
Definition: clone0clone.h:710
int check_error(THD *thd)
Check for error from other tasks and DDL.
Definition: clone0clone.h:653
byte m_version_locator[CLONE_DESC_MAX_BASE_LEN]
Fixed locator for version negotiation.
Definition: clone0clone.h:1014
void update_work(uint size)
Update the progress of the clone operation.
Definition: clone0monitor.h:122
Dynamic database snapshot: Holds metadata and handle to data.
Definition: clone0snapshot.h:262
Clone_Monitor & get_clone_monitor()
Get performance schema accounting object used to monitor stage progress.
Definition: clone0snapshot.h:347
Definition: clone0clone.h:1071
Acquire_clone()
Constructor to get and pin clone handle.
Definition: clone0clone.cc:386
~Acquire_clone()
Destructor to release and free clone handle if necessary.
Definition: clone0clone.cc:394
Clone_Handle * m_clone
Acquired clone handle.
Definition: clone0clone.h:1084
Clone_Snapshot * get_snapshot()
Get current clone snapshot.
Definition: clone0clone.cc:401
RAII style wrapper to enter and exit wait stage.
Definition: clone0clone.h:1057
Wait_stage(const char *new_info)
Constructor to change the THD information string.
Definition: clone0api.cc:2791
const char * m_saved_info
Saved old THD information string.
Definition: clone0clone.h:1068
~Wait_stage()
Destructor to revert back the old information string.
Definition: clone0api.cc:2801
Clone System.
Definition: clone0clone.h:1054
void debug_wait_clone_begin()
Debug wait while starting clone and waiting for free marker.
Definition: clone0clone.cc:519
Clone_Handle * m_clone_arr[CLONE_ARR_SIZE]
Array of clone handles.
Definition: clone0clone.h:1318
uint m_num_snapshots
Number of copy snapshots.
Definition: clone0clone.h:1330
Clone_Handle * find_clone(const byte *ref_loc, uint loc_len, Clone_Handle_Type hdl_type)
Find if a clone is already running for the reference locator.
Definition: clone0clone.cc:84
void end_ddl_state(Clone_notify::Type type, space_id_t space, uint32_t blocked_state)
End restricted state during some critical ddl phase.
Definition: clone0clone.cc:615
void mark_wait()
Mark to indicate that new clone operations should wait.
Definition: clone0clone.cc:506
void drop_clone(Clone_Handle *clone_handle)
drop a clone handle from clone system
Definition: clone0clone.cc:266
uint m_num_apply_clones
Number of apply clones.
Definition: clone0clone.h:1324
static uint s_clone_wait_count
Number of active wait requests.
Definition: clone0clone.h:1196
ib_mutex_t * get_mutex()
Get clone sys mutex.
Definition: clone0clone.h:1187
int add_clone(const byte *loc, Clone_Handle_Type hdl_type, Clone_Handle *&clone_hdl)
Create and add a new clone handle to clone system.
Definition: clone0clone.cc:228
uint m_num_clones
Number of copy clones.
Definition: clone0clone.h:1321
static int wait(Clone_Msec sleep_time, Clone_Sec timeout, Clone_Sec alert_interval, Wait_Cond_Cbk_Func &&func, ib_mutex_t *mutex, bool &is_timeout)
Wait till the condition is satisfied or timeout.
Definition: clone0clone.h:1212
~Clone_Sys()
Destructor: Call during system shutdown.
Definition: clone0clone.cc:63
bool is_space_initialized() const
Definition: clone0clone.h:1299
uint64_t get_next_id()
Get next unique ID.
Definition: clone0clone.cc:640
bool begin_ddl_state(Clone_notify::Type type, space_id_t space, bool no_wait, bool check_intr, uint32_t &blocked_state, int &error)
Begin restricted state during some critical ddl phase.
Definition: clone0clone.cc:584
Clone_Snapshot * m_snapshot_arr[SNAPSHOT_ARR_SIZE]
Array of clone snapshots.
Definition: clone0clone.h:1327
int wait_for_free(THD *thd)
Wait for marker to get freed.
Definition: clone0clone.cc:526
void mark_free()
Free the wait marker.
Definition: clone0clone.cc:512
bool handle_ddl_state(Clone_notify::Type type, space_id_t space, bool begin)
Handle restricted state during critical ddl phase.
void mark_active()
Mark clone state to active if no other abort request.
Definition: clone0clone.cc:495
bool mark_abort(bool force)
Mark clone state to abort if no active clone.
Definition: clone0clone.cc:439
Clone_persist_gtid & get_gtid_persistor()
Definition: clone0clone.h:1293
uint m_num_apply_snapshots
Number of apply snapshots.
Definition: clone0clone.h:1333
uint64_t m_clone_id_generator
Clone unique ID generator.
Definition: clone0clone.h:1339
std::atomic< bool > m_space_initialized
If all innodb tablespaces are initialized.
Definition: clone0clone.h:1342
std::function< int(bool is_alert, bool &result)> Wait_Cond_Cbk_Func
Function to check wait condition.
Definition: clone0clone.h:1202
std::tuple< bool, Clone_Handle * > check_active_clone()
Check if any active clone is running.
Definition: clone0clone.cc:420
static uint s_clone_abort_count
Number of active abort requests.
Definition: clone0clone.h:1193
Clone_persist_gtid m_gtid_persister
GTID persister.
Definition: clone0clone.h:1345
ib_mutex_t m_clone_sys_mutex
Clone system mutex.
Definition: clone0clone.h:1336
static int wait_default(Wait_Cond_Cbk_Func &&func, ib_mutex_t *mutex, bool &is_timeout)
Wait till the condition is satisfied or default timeout.
Definition: clone0clone.h:1276
int find_free_index(Clone_Handle_Type hdl_type, uint &free_index)
Find free index to allocate new clone handle.
Definition: clone0clone.cc:129
static Clone_Sys_State s_clone_sys_state
Clone System state.
Definition: clone0clone.h:1190
Clone_Sys()
Construct clone system.
Definition: clone0clone.cc:51
void close_donor_master_file()
Close donor master task file if open and unpin.
Definition: clone0clone.cc:691
Clone_Handle * get_clone_by_index(const byte *loc, uint loc_len)
Get the clone handle from locator by index.
Definition: clone0clone.cc:291
int attach_snapshot(Clone_Handle_Type hdl_type, Ha_clone_type clone_type, uint64_t snapshot_id, bool is_pfs_monitor, Clone_Snapshot *&snapshot)
Get or create a snapshot for clone and attach.
Definition: clone0clone.cc:308
void set_space_initialized()
Remember that all innodb spaces are initialized after last startup.
Definition: clone0clone.h:1296
void detach_snapshot(Clone_Snapshot *snapshot, Clone_Handle_Type hdl_type)
Detach clone handle from snapshot.
Definition: clone0clone.cc:360
Task manager for manging the tasks for a clone operation.
Definition: clone0clone.h:202
bool is_restart_metadata(Clone_Task *task)
Check if needs to send state metadata once.
Definition: clone0clone.h:380
int alloc_buffer(Clone_Task *task)
Allocate buffers for current task.
Definition: clone0clone.cc:857
int set_chunk(Clone_Task *task, Clone_Task_Meta *new_meta)
Set current chunk and block information.
Definition: clone0clone.cc:1274
uint32_t get_next_chunk()
Get next unreserved chunk.
Definition: clone0clone.cc:1184
int finish_state(Clone_Task *task)
Mark state finished for current task.
Definition: clone0clone.cc:1686
bool drop_task(THD *thd, uint task_id, bool &is_master)
Drop task from task manager.
Definition: clone0clone.cc:1107
void reset_transition()
Reset state transition information.
Definition: clone0clone.h:330
bool is_restarted()
Check if clone is restarted after failure.
Definition: clone0clone.h:435
void reinit_apply_state(const byte *ref_loc, uint ref_len, byte *&new_loc, uint &new_len, uint &alloc_len)
Reinitialize state using locator.
Definition: clone0clone.cc:1387
bool m_transferred_file_meta
Definition: clone0clone.h:559
int wait_ack(Clone_Handle *clone, Clone_Task *task, Ha_clone_cbk *callback)
Wait for acknowledgement.
Definition: clone0clone.cc:1625
Chunk_Info m_chunk_info
Finished and incomplete chunk information.
Definition: clone0clone.h:532
Clone_Snapshot * get_snapshot()
Get attached snapshot.
Definition: clone0clone.h:352
bool m_send_state_meta
Send state metadata before starting: Used for restart.
Definition: clone0clone.h:562
int change_state(Clone_Task *task, Clone_Desc_State *state_desc, Snapshot_State new_state, Clone_Alert_Func cbk, uint &num_wait)
Move to next snapshot state.
Definition: clone0clone.cc:1766
uint m_num_tasks_finished
Number of tasks finished current state.
Definition: clone0clone.h:541
bool is_network_error(int err)
Check if network error.
Definition: clone0clone.h:479
int check_state(Clone_Task *task, Snapshot_State new_state, bool exit_on_wait, int in_err, uint32_t &num_wait)
Check if state transition is over and all tasks moved to next state.
Definition: clone0clone.cc:1861
void init_state()
Initialize task manager for current state.
Definition: clone0clone.cc:1592
void reset_error()
Reset error information.
Definition: clone0clone.h:337
void ack_state(const Clone_Desc_State *state_desc)
Set acknowledged state.
Definition: clone0clone.cc:1614
Clone_Snapshot * m_clone_snapshot
Attached snapshot handle.
Definition: clone0clone.h:571
int handle_error_other_task(bool raise_error)
Handle any error raised by concurrent tasks.
Definition: clone0clone.cc:916
uint32_t get_next_incomplete_chunk(uint32_t &block_num)
Get next in complete chunk if any.
Definition: clone0clone.cc:1225
std::string m_err_file_name
File name related to the saved error.
Definition: clone0clone.h:568
bool process_inclomplete_chunk()
Check if we should process incomplete chunk next.
Definition: clone0clone.h:497
void reserve_task(THD *thd, uint &task_id)
Reserve free task from task manager and initialize.
Definition: clone0clone.cc:820
uint m_num_tasks_transit
Number of tasks in transit state.
Definition: clone0clone.h:544
Clone_Task m_clone_tasks[CLONE_MAX_TASKS]
Clone task array.
Definition: clone0clone.h:535
int m_saved_error
Save any error raised by a task.
Definition: clone0clone.h:565
void reinit_copy_state(const byte *loc, uint loc_len)
Reinitialize state using locator.
Definition: clone0clone.cc:1495
uint m_num_tasks
Current number of tasks.
Definition: clone0clone.h:538
void debug_wait(uint chunk_num, Clone_Task *task)
Wait during clone operation.
Definition: clone0clone.cc:700
ib_mutex_t * get_mutex()
Get task state mutex.
Definition: clone0clone.h:210
int debug_restart(Clone_Task *task, int in_err, int restart_count)
Force restart clone operation by raising network error.
Definition: clone0clone.cc:729
void set_error(int err, const char *file_name)
Set error number.
Definition: clone0clone.h:220
Snapshot_State m_ack_state
Acknowledged state from client.
Definition: clone0clone.h:550
void add_incomplete_chunk(Clone_Task *task)
Track any incomplete chunks handled by the task.
Definition: clone0clone.cc:1321
bool is_chunk_reserved(uint32_t chunk_num)
Check if chunk is already reserved.
Definition: clone0clone.h:257
Clone_Task * find_master_task()
Definition: clone0clone.cc:674
Clone_Task * get_task_by_index(uint index)
Get task by index.
Definition: clone0clone.h:286
bool is_file_metadata_transferred() const
Definition: clone0clone.h:390
bool check_ack(const Clone_Desc_State *state_desc)
Check if state ACK is needed.
Definition: clone0clone.h:416
void set_file_meta_transferred()
Set sub-state: all file metadata is transferred.
Definition: clone0clone.h:395
void debug_wait_ddl_meta()
Wait before sending DDL metadata.
Definition: clone0clone.cc:662
Snapshot_State m_next_state
Next state: used during state transfer.
Definition: clone0clone.h:556
uint m_restart_count
Number of times clone is restarted.
Definition: clone0clone.h:547
int add_task(THD *thd, const byte *ref_loc, uint loc_len, uint &task_id)
Add a task to task manager.
Definition: clone0clone.cc:1031
bool in_transit_state()
Check if in state transition.
Definition: clone0clone.h:348
Snapshot_State m_current_state
Current state for clone.
Definition: clone0clone.h:553
void init(Clone_Snapshot *snapshot)
Initialize task manager for clone handle.
Definition: clone0clone.cc:760
Snapshot_State get_state()
Get current clone state.
Definition: clone0clone.h:344
bool wait_before_add(const byte *ref_loc, uint loc_len)
Check if we need to wait before adding current task.
Definition: clone0clone.cc:993
ib_mutex_t m_state_mutex
Mutex synchronizing access by concurrent tasks.
Definition: clone0clone.h:529
void reset_chunk(Clone_Task *task)
Reset chunk information for task.
Definition: clone0clone.h:263
int reserve_next_chunk(Clone_Task *task, uint32_t &ret_chunk, uint32_t &ret_block)
Reserve next chunk from task manager.
Definition: clone0clone.cc:1245
bool debug_sync_check(uint32_t chunk_num, Clone_Task *task)
Check if needs to wait for debug sync point.
Definition: clone0clone.cc:647
Type
Notification type.
Definition: clone0api.h:181
Persist GTID along with transaction commit.
Definition: clone0repl.h:68
Definition: handler.h:1010
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_class.h:922
A utility class which, if inherited from, prevents the descendant class from being copied,...
Definition: ut0class_life_cycle.h:40
Innodb Clone Interface.
Clone_System_State
Clone system state.
Definition: clone0clone.h:116
@ CLONE_SYS_ACTIVE
Definition: clone0clone.h:118
@ CLONE_SYS_ABORT
Definition: clone0clone.h:119
@ CLONE_SYS_INACTIVE
Definition: clone0clone.h:117
const char CLONE_INNODB_DDL_FILE_EXTN[]
Clone file extension for temporary renamed file.
Definition: clone0clone.h:100
Clone_Sys * clone_sys
Clone system global.
Definition: clone0clone.cc:40
const int CLONE_ARR_SIZE
Clone system array size.
Definition: clone0clone.h:142
const char CLONE_INNODB_RECOVERY_FILE[]
Clone recovery status.
Definition: clone0clone.h:74
const char CLONE_INNODB_OLD_FILES[]
Clone file name for list of old files to be removed.
Definition: clone0clone.h:86
const Clone_Msec CLONE_DEF_SLEEP
Default sleep time while waiting: 100 ms.
Definition: clone0clone.h:107
Clone_Handle_State
Clone Handle State.
Definition: clone0clone.h:125
@ CLONE_STATE_INIT
Definition: clone0clone.h:126
@ CLONE_STATE_IDLE
Definition: clone0clone.h:128
@ CLONE_STATE_ABORT
Definition: clone0clone.h:129
@ CLONE_STATE_ACTIVE
Definition: clone0clone.h:127
const char CLONE_INNODB_RECOVERY_CRASH_POINT[]
Clone simulate recovery error file name.
Definition: clone0clone.h:57
std::atomic< Clone_System_State > Clone_Sys_State
Definition: clone0clone.h:122
const char CLONE_INNODB_REPLACED_FILES[]
Clone file name for list of files to be replaced.
Definition: clone0clone.h:82
const char CLONE_INNODB_ERROR_FILE[]
Clone error file name.
Definition: clone0clone.h:66
Clone_Task_State
Clone task state.
Definition: clone0clone.h:133
@ CLONE_TASK_INACTIVE
Definition: clone0clone.h:133
@ CLONE_TASK_ACTIVE
Definition: clone0clone.h:133
const char CLONE_INNODB_DDL_FILES[]
Clone file name for list of temp files renamed by ddl.
Definition: clone0clone.h:90
const int MAX_SNAPSHOTS
Maximum number of concurrent snapshots.
Definition: clone0clone.h:136
std::chrono::milliseconds Clone_Msec
Definition: clone0clone.h:102
std::chrono::minutes Clone_Min
Definition: clone0clone.h:104
#define CLONE_FILES_DIR
Directory under data directory for all clone status files.
Definition: clone0clone.h:50
const char CLONE_INNODB_SAVED_FILE_EXTN[]
Clone file extension for saved old files.
Definition: clone0clone.h:97
std::chrono::seconds Clone_Sec
Definition: clone0clone.h:103
const char CLONE_INNODB_IN_PROGRESS_FILE[]
Clone in progress file name.
Definition: clone0clone.h:62
const int SNAPSHOT_ARR_SIZE
Snapshot system array size.
Definition: clone0clone.h:145
const int MAX_CLONES
Maximum number of concurrent clones.
Definition: clone0clone.h:139
const char CLONE_INNODB_REPLACED_FILE_EXTN[]
Clone file extension for files to be replaced.
Definition: clone0clone.h:94
const Clone_Min CLONE_DEF_TIMEOUT
Default timeout in multiple of sleep time: 30 minutes.
Definition: clone0clone.h:113
const char CLONE_INNODB_NEW_FILES[]
Clone file name for list of files cloned in place.
Definition: clone0clone.h:78
const char CLONE_INNODB_FIXUP_FILE[]
Clone fix up file name.
Definition: clone0clone.h:70
const size_t CLONE_INNODB_FILE_LEN
Clone in progress file name length.
Definition: clone0clone.h:53
const Clone_Sec CLONE_DEF_ALERT_INTERVAL
Default alert interval in multiple of sleep time: 5 seconds.
Definition: clone0clone.h:110
Innodb clone descriptors.
const int CLONE_MAX_TASKS
Maximum number of concurrent tasks for each clone.
Definition: clone0desc.h:50
Snapshot_State
Snapshot state transfer during clone.
Definition: clone0desc.h:92
@ CLONE_SNAPSHOT_DONE
Snapshot state at end after finishing transfer.
Definition: clone0desc.h:109
@ CLONE_SNAPSHOT_NONE
Invalid state.
Definition: clone0desc.h:94
@ CLONE_SNAPSHOT_INIT
Initialize state when snapshot object is created.
Definition: clone0desc.h:97
const uint32_t CLONE_DESC_MAX_BASE_LEN
Maximum base length for any serialized descriptor.
Definition: clone0desc.h:44
std::function< int()> Clone_Alert_Func
Function to alert caller for long wait.
Definition: clone0monitor.h:42
GTID persistence interface.
Database Physical Snapshot.
Clone_Handle_Type
Clone handle type.
Definition: clone0snapshot.h:238
@ CLONE_HDL_COPY
Clone Handle for COPY.
Definition: clone0snapshot.h:240
Clone_handler * clone_handle
Clone handler global.
Definition: clone_handler.cc:57
Global error codes for the database.
dberr_t
Definition: db0err.h:38
static int is_timeout(int e)
Definition: my_thread.h:56
static size_t file_size
Definition: mysql_config_editor.cc:70
Log info(cout, "NOTE")
Definition: os0file.h:85
static Value err()
Create a Value object that represents an error condition.
Definition: json_binary.cc:909
std::string file_name(Log_file_id file_id)
Provides name of the log file with the given file id, e.g.
Definition: log0pre_8_0_30.cc:93
static bool timeout(bool(*wait_condition)())
Timeout function.
Definition: log0meb.cc:495
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:418
#define OS_FILE_PREFIX
Prefix all files and directory created under data directory with special string so that it never conf...
Definition: os0file.h:67
static File create_file(THD *thd, char *path, sql_exchange *exchange, IO_CACHE *cache)
Definition: query_result.cc:204
required string type
Definition: replication_group_member_actions.proto:33
Ha_clone_type
Clone operation types.
Definition: handler.h:958
Incomplete Chunk information.
Definition: clone0desc.h:317
uint32_t m_min_unres_chunk
Minimum chunk number that is not reserved yet.
Definition: clone0desc.h:328
Chnunk_Bitmap m_reserved_chunks
Information about chunks completed.
Definition: clone0desc.h:319
uint32_t m_total_chunks
Chunks for current state.
Definition: clone0desc.h:325
Chunk_Map m_incomplete_chunks
Information about unfinished chunks.
Definition: clone0desc.h:322
CLONE_DESC_LOCATOR: Descriptor for a task for clone operation.
Definition: clone0desc.h:361
CLONE_DESC_STATE: Descriptor for current snapshot state.
Definition: clone0desc.h:438
Snapshot_State m_state
Current snapshot State.
Definition: clone0desc.h:443
Clone file information.
Definition: clone0desc.h:485
Task information in clone operation.
Definition: clone0desc.h:173
uint m_block_num
Current block number that is already transferred.
Definition: clone0desc.h:181
uint m_chunk_num
Current chunk number reserved by the task.
Definition: clone0desc.h:178
Task for clone operation.
Definition: clone0clone.h:149
bool m_file_cache
Data files are read using OS buffer cache.
Definition: clone0clone.h:173
uint m_current_file_index
Current file index.
Definition: clone0clone.h:170
uint32_t m_data_size
Data transferred for current chunk in bytes.
Definition: clone0clone.h:196
int m_debug_counter
Counter to restart in different state.
Definition: clone0clone.h:186
Clone_Task_Meta m_task_meta
Task Meta data.
Definition: clone0clone.h:151
uint m_alloc_len
Serial descriptor allocated length.
Definition: clone0clone.h:160
pfs_os_file_t m_current_file_des
Current file descriptor.
Definition: clone0clone.h:167
uint m_buffer_alloc_len
Allocated buffer length.
Definition: clone0clone.h:193
byte * m_current_buffer
Allocated buffer.
Definition: clone0clone.h:190
bool m_is_master
If master task.
Definition: clone0clone.h:176
bool m_pinned_file
If task is currently pinning file.
Definition: clone0clone.h:164
bool m_has_thd
If task has associated session.
Definition: clone0clone.h:179
bool m_ignore_sync
Ignore debug sync point.
Definition: clone0clone.h:183
Clone_Task_State m_task_state
Task state.
Definition: clone0clone.h:154
byte * m_serial_desc
Serial descriptor byte string.
Definition: clone0clone.h:157
Definition: clone0snapshot.h:48
Common file descriptor for file IO instrumentation with PFS on windows and other platforms.
Definition: os0file.h:172
Definition: result.h:29
Definition: ut0core.h:32
double seconds()
Definition: task.cc:309
unsigned int uint
Definition: uca-dump.cc:29
Version control for database, common definitions, and include files.
unsigned long int ulint
Definition: univ.i:407
#define UNIV_PFS_IO
Definition: univ.i:140
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:68
#define ut_a(EXPR)
Abort execution if EXPR does not evaluate to nonzero.
Definition: ut0dbg.h:56
Policy based mutexes.
#define mutex_own(M)
Checks that the current thread owns the mutex.
Definition: ut0mutex.h:164
#define mutex_exit(M)
Definition: ut0mutex.h:122
#define mutex_enter(M)
Definition: ut0mutex.h:116
static ORDER * clone(THD *thd, ORDER *order)
Shallow clone the list of ORDER objects using mem_root and return the cloned list.
Definition: window.cc:83