@@ -588,7 +588,7 @@ std::string filename_to_spacename(const byte *filename, size_t len)
588
588
@param[in] len length of name, in bytes
589
589
@param[in] new_name new file name (NULL if not rename)
590
590
@param[in] new_len length of new_name, in bytes (0 if NULL) */
591
- void backup_file_op (ulint space_id, const byte* flags,
591
+ static void backup_file_op (ulint space_id, const byte* flags,
592
592
const byte* name, ulint len,
593
593
const byte* new_name, ulint new_len)
594
594
{
@@ -616,19 +616,71 @@ void backup_file_op(ulint space_id, const byte* flags,
616
616
}
617
617
618
618
619
+ /*
620
+ This callback is called if DDL operation is detected,
621
+ at the end of backup
622
+
623
+ Normally, DDL operations are blocked due to FTWRL,
624
+ but in rare cases of --no-lock, they are not.
625
+
626
+ We will abort backup in this case.
627
+ */
628
+ static void backup_file_op_fail (ulint space_id, const byte* flags,
629
+ const byte* name, ulint len,
630
+ const byte* new_name, ulint new_len)
631
+ {
632
+ ut_a (opt_no_lock);
633
+ bool fail;
634
+ if (flags) {
635
+ msg (" DDL tracking : create %zu \" %.*s\" : %x\n " ,
636
+ space_id, int (len), name, mach_read_from_4 (flags));
637
+ std::string spacename = filename_to_spacename (name, len);
638
+ fail = !check_if_skip_table (spacename.c_str ());
639
+ }
640
+ else if (new_name) {
641
+ msg (" DDL tracking : rename %zu \" %.*s\" ,\" %.*s\"\n " ,
642
+ space_id, int (len), name, int (new_len), new_name);
643
+ std::string spacename = filename_to_spacename (name, len);
644
+ std::string new_spacename = filename_to_spacename (new_name, new_len);
645
+ fail = !check_if_skip_table (spacename.c_str ()) || !check_if_skip_table (new_spacename.c_str ());
646
+ }
647
+ else {
648
+ std::string spacename = filename_to_spacename (name, len);
649
+ fail = !check_if_skip_table (spacename.c_str ());
650
+ msg (" DDL tracking : delete %zu \" %.*s\"\n " , space_id, int (len), name);
651
+ }
652
+ if (fail) {
653
+ msg (" ERROR : DDL operation detected in the late phase of backup."
654
+ " Backup is inconsistent. Remove --no-lock option to fix.\n " );
655
+ exit (EXIT_FAILURE);
656
+ }
657
+ }
658
+
659
+
619
660
/* * Callback whenever MLOG_INDEX_LOAD happens.
620
661
@param[in] space_id space id to check */
621
662
static void backup_optimized_ddl_op (ulint space_id)
622
663
{
623
- // TODO : handle incremental
624
- if (xtrabackup_incremental)
625
- return ;
626
-
627
664
pthread_mutex_lock (&backup_mutex);
628
665
ddl_tracker.optimized_ddl .insert (space_id);
629
666
pthread_mutex_unlock (&backup_mutex);
630
667
}
631
668
669
+ /*
670
+ Optimized DDL callback at the end of backup that
671
+ run with --no-lock. Usually aborts the backup.
672
+ */
673
+ static void backup_optimized_ddl_op_fail (ulint space_id) {
674
+ ut_a (opt_no_lock);
675
+ msg (" DDL tracking : optimized DDL on space %zu\n " );
676
+ if (ddl_tracker.tables_in_backup .find (space_id) != ddl_tracker.tables_in_backup .end ()) {
677
+ msg (" ERROR : Optimized DDL operation detected in the late phase of backup."
678
+ " Backup is inconsistent. Remove --no-lock option to fix.\n " );
679
+ exit (EXIT_FAILURE);
680
+ }
681
+ }
682
+
683
+
632
684
/* * Callback whenever MLOG_TRUNCATE happens. */
633
685
static void backup_truncate_fail ()
634
686
{
@@ -4383,6 +4435,14 @@ void backup_fix_ddl(void)
4383
4435
std::set<std::string> dropped_tables;
4384
4436
std::map<std::string, std::string> renamed_tables;
4385
4437
4438
+ /* Disable further DDL on backed up tables (only needed for --no-lock).*/
4439
+ pthread_mutex_lock (&backup_mutex);
4440
+ log_file_op = backup_file_op_fail;
4441
+ log_optimized_ddl_op = backup_optimized_ddl_op_fail;
4442
+ pthread_mutex_unlock (&backup_mutex);
4443
+
4444
+ DBUG_MARIABACKUP_EVENT (" backup_fix_ddl" ,0 );
4445
+
4386
4446
for (space_id_to_name_t ::iterator iter = ddl_tracker.tables_in_backup .begin ();
4387
4447
iter != ddl_tracker.tables_in_backup .end ();
4388
4448
iter++) {
0 commit comments