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