@@ -628,64 +628,57 @@ func (s *Spec) CheckTableExistsByName(tableName string) (bool, error) {
628
628
}
629
629
630
630
// mysql> BACKUP SNAPSHOT ccr.snapshot_20230605 TO `__keep_on_local__` ON ( src_1 ) PROPERTIES ("type" = "full");
631
- func (s * Spec ) CreateSnapshot (tables []string ) ( string , error ) {
631
+ func (s * Spec ) CreateSnapshot (snapshotName string , tables []string ) error {
632
632
if tables == nil {
633
633
tables = make ([]string , 0 )
634
634
}
635
635
if len (tables ) == 0 {
636
636
tables = append (tables , s .Table )
637
637
}
638
638
639
- var snapshotName string
640
639
var tableRefs string
641
640
if len (tables ) == 1 {
642
- // snapshot name format "ccrs_${table}_${timestamp}"
643
641
// table refs = table
644
- snapshotName = fmt .Sprintf ("ccrs_%s_%s_%d" , s .Database , s .Table , time .Now ().Unix ())
645
642
tableRefs = utils .FormatKeywordName (tables [0 ])
646
643
} else {
647
- // snapshot name format "ccrs_${db}_${timestamp}"
648
644
// table refs = tables.join(", ")
649
- snapshotName = fmt .Sprintf ("ccrs_%s_%d" , s .Database , time .Now ().Unix ())
650
645
tableRefs = "`" + strings .Join (tables , "`,`" ) + "`"
651
646
}
652
647
653
648
// means source is a empty db, table number is 0
654
649
if tableRefs == "``" {
655
- return "" , xerror .Errorf (xerror .Normal , "source db is empty! you should have at least one table" )
650
+ return xerror .Errorf (xerror .Normal , "source db is empty! you should have at least one table" )
656
651
}
657
652
658
653
db , err := s .Connect ()
659
654
if err != nil {
660
- return "" , err
655
+ return err
661
656
}
662
657
663
658
backupSnapshotSql := fmt .Sprintf ("BACKUP SNAPSHOT %s.%s TO `__keep_on_local__` ON ( %s ) PROPERTIES (\" type\" = \" full\" )" , utils .FormatKeywordName (s .Database ), utils .FormatKeywordName (snapshotName ), tableRefs )
664
659
log .Infof ("create snapshot %s.%s, backup snapshot sql: %s" , s .Database , snapshotName , backupSnapshotSql )
665
660
_ , err = db .Exec (backupSnapshotSql )
666
661
if err != nil {
667
- return "" , xerror .Wrapf (err , xerror .Normal , "backup snapshot %s failed, sql: %s" , snapshotName , backupSnapshotSql )
662
+ return xerror .Wrapf (err , xerror .Normal , "backup snapshot %s failed, sql: %s" , snapshotName , backupSnapshotSql )
668
663
}
669
664
670
- return snapshotName , nil
665
+ return nil
671
666
}
672
667
673
668
// mysql> BACKUP SNAPSHOT ccr.snapshot_20230605 TO `__keep_on_local__` ON (src_1 PARTITION (`p1`)) PROPERTIES ("type" = "full");
674
- func (s * Spec ) CreatePartialSnapshot (table string , partitions []string ) ( string , error ) {
669
+ func (s * Spec ) CreatePartialSnapshot (snapshotName , table string , partitions []string ) error {
675
670
if len (table ) == 0 {
676
- return "" , xerror .Errorf (xerror .Normal , "source db is empty! you should have at least one table" )
671
+ return xerror .Errorf (xerror .Normal , "source db is empty! you should have at least one table" )
677
672
}
678
673
679
- // snapshot name format "ccrp_${table}_${timestamp}"
680
674
// table refs = table
681
- snapshotName := fmt .Sprintf ("ccrp_%s_%s_%d" , s .Database , s .Table , time .Now ().Unix ())
682
675
tableRef := utils .FormatKeywordName (table )
683
676
684
677
log .Infof ("create partial snapshot %s.%s" , s .Database , snapshotName )
685
678
686
679
db , err := s .Connect ()
687
680
if err != nil {
688
- return "" , err
681
+ return err
689
682
}
690
683
691
684
partitionRefs := ""
@@ -698,10 +691,10 @@ func (s *Spec) CreatePartialSnapshot(table string, partitions []string) (string,
698
691
log .Debugf ("backup partial snapshot sql: %s" , backupSnapshotSql )
699
692
_ , err = db .Exec (backupSnapshotSql )
700
693
if err != nil {
701
- return "" , xerror .Wrapf (err , xerror .Normal , "backup partial snapshot %s failed, sql: %s" , snapshotName , backupSnapshotSql )
694
+ return xerror .Wrapf (err , xerror .Normal , "backup partial snapshot %s failed, sql: %s" , snapshotName , backupSnapshotSql )
702
695
}
703
696
704
- return snapshotName , nil
697
+ return nil
705
698
}
706
699
707
700
// TODO: Add TaskErrMsg
@@ -757,103 +750,102 @@ func (s *Spec) CheckBackupFinished(snapshotName string) (bool, error) {
757
750
}
758
751
}
759
752
760
- func (s * Spec ) CancelBackupIfExists () error {
761
- log .Debugf ("cancel backup job if exists, database: %s" , s .Database )
753
+ // Get the valid (running or finished) backup job with a unique prefix to indicate
754
+ // if a backup job needs to be issued again.
755
+ func (s * Spec ) GetValidBackupJob (snapshotNamePrefix string ) (string , error ) {
756
+ log .Debugf ("get valid backup job if exists, database: %s, label prefix: %s" , s .Database , snapshotNamePrefix )
762
757
763
758
db , err := s .Connect ()
764
759
if err != nil {
765
- return err
760
+ return "" , err
766
761
}
767
762
768
- query := fmt .Sprintf ("SHOW BACKUP FROM %s" , utils .FormatKeywordName (s .Database ))
763
+ query := fmt .Sprintf ("SHOW BACKUP FROM %s WHERE SnapshotName LIKE \" %s%%\" " ,
764
+ utils .FormatKeywordName (s .Database ), snapshotNamePrefix )
769
765
log .Infof ("show backup state sql: %s" , query )
770
766
rows , err := db .Query (query )
771
767
if err != nil {
772
- return xerror .Wrap (err , xerror .Normal , "query backup state failed" )
768
+ return "" , xerror .Wrap (err , xerror .Normal , "query backup state failed" )
773
769
}
774
770
defer rows .Close ()
775
771
772
+ labels := make ([]string , 0 )
776
773
for rows .Next () {
777
774
rowParser := utils .NewRowParser ()
778
775
if err := rowParser .Parse (rows ); err != nil {
779
- return xerror .Wrap (err , xerror .Normal , "scan backup state failed" )
776
+ return "" , xerror .Wrap (err , xerror .Normal , "scan backup state failed" )
780
777
}
781
778
782
779
info , err := parseBackupInfo (rowParser )
783
780
if err != nil {
784
- return xerror .Wrap (err , xerror .Normal , "scan backup state failed" )
781
+ return "" , xerror .Wrap (err , xerror .Normal , "scan backup state failed" )
785
782
}
786
783
787
784
log .Infof ("check snapshot %s backup state [%v], create time: %s" ,
788
785
info .SnapshotName , info .StateStr , info .CreateTime )
789
786
790
- // Only cancel the running backup job issued by syncer
791
- if ! isSyncerIssuedJob (info .SnapshotName , s .Database ) {
787
+ if info .State == BackupStateCancelled {
792
788
continue
793
789
}
794
790
795
- if info .State == BackupStateFinished || info .State == BackupStateCancelled {
796
- continue
797
- }
791
+ labels = append (labels , info .SnapshotName )
792
+ }
798
793
799
- cancelSql := fmt .Sprintf ("CANCEL BACKUP FROM %s" , s .Database )
800
- log .Infof ("cancel backup sql: %s, snapshot: %s" , cancelSql , info .SnapshotName )
801
- if _ , err = db .Exec (cancelSql ); err != nil {
802
- return xerror .Wrapf (err , xerror .Normal ,
803
- "cancel backup job %s failed, database: %s" , info .SnapshotName , s .Database )
804
- }
794
+ // Return the last one. Assume that the result of `SHOW BACKUP` is ordered by CreateTime in ascending order.
795
+ if len (labels ) != 0 {
796
+ return labels [len (labels )- 1 ], nil
805
797
}
806
- return nil
798
+
799
+ return "" , nil
807
800
}
808
801
809
- func (s * Spec ) CancelRestoreIfExists (srcDbName string ) error {
810
- log .Debugf ("cancel restore job if exists, src db: %s" , srcDbName )
802
+ // Get the valid (running or finished) restore job with a unique prefix to indicate
803
+ // if a restore job needs to be issued again.
804
+ func (s * Spec ) GetValidRestoreJob (snapshotNamePrefix string ) (string , error ) {
805
+ log .Debugf ("get valid restore job if exists, label prefix: %s" , snapshotNamePrefix )
811
806
812
807
db , err := s .Connect ()
813
808
if err != nil {
814
- return err
809
+ return "" , err
815
810
}
816
811
817
- query := fmt .Sprintf ("SHOW RESTORE FROM %s" , utils .FormatKeywordName (s .Database ))
818
- log .Debugf ("show restore state sql: %s" , query )
812
+ query := fmt .Sprintf ("SHOW RESTORE FROM %s WHERE Label LIKE \" %s%%\" " ,
813
+ utils .FormatKeywordName (s .Database ), snapshotNamePrefix )
814
+ log .Infof ("show restore state sql: %s" , query )
819
815
rows , err := db .Query (query )
820
816
if err != nil {
821
- return xerror .Wrap (err , xerror .Normal , "query restore state failed" )
817
+ return "" , xerror .Wrap (err , xerror .Normal , "query restore state failed" )
822
818
}
823
819
defer rows .Close ()
824
820
821
+ labels := make ([]string , 0 )
825
822
for rows .Next () {
826
823
rowParser := utils .NewRowParser ()
827
824
if err := rowParser .Parse (rows ); err != nil {
828
- return xerror .Wrap (err , xerror .Normal , "scan restore state failed" )
825
+ return "" , xerror .Wrap (err , xerror .Normal , "scan restore state failed" )
829
826
}
830
827
831
828
info , err := parseRestoreInfo (rowParser )
832
829
if err != nil {
833
- return xerror .Wrap (err , xerror .Normal , "scan restore state failed" )
830
+ return "" , xerror .Wrap (err , xerror .Normal , "scan restore state failed" )
834
831
}
835
832
836
833
log .Infof ("check snapshot %s restore state: [%v], create time: %s" ,
837
834
info .Label , info .StateStr , info .CreateTime )
838
835
839
- // Only cancel the running restore job issued by syncer
840
- if ! isSyncerIssuedJob (info .Label , srcDbName ) {
836
+ if info .State == RestoreStateFinished {
841
837
continue
842
838
}
843
839
844
- if info .State == RestoreStateCancelled || info .State == RestoreStateFinished {
845
- continue
846
- }
847
-
848
- cancelSql := fmt .Sprintf ("CANCEL RESTORE FROM %s" , utils .FormatKeywordName (s .Database ))
849
- log .Infof ("cancel restore sql: %s, running snapshot %s" , cancelSql , info .Label )
840
+ labels = append (labels , info .Label )
841
+ }
850
842
851
- _ , err = db .Exec (cancelSql )
852
- if err != nil {
853
- return xerror .Wrapf (err , xerror .Normal , "cancel running restore failed, snapshot %s" , info .Label )
854
- }
843
+ // Return the last one. Assume that the result of `SHOW BACKUP` is ordered by CreateTime in ascending order.
844
+ if len (labels ) != 0 {
845
+ return labels [len (labels )- 1 ], nil
855
846
}
856
- return nil
847
+
848
+ return "" , nil
857
849
}
858
850
859
851
// TODO: Add TaskErrMsg
@@ -1240,9 +1232,3 @@ func correctAddPartitionSql(addPartitionSql string, addPartition *record.AddPart
1240
1232
}
1241
1233
return addPartitionSql
1242
1234
}
1243
-
1244
- func isSyncerIssuedJob (label , dbName string ) bool {
1245
- fullSyncPrefix := fmt .Sprintf ("ccrs_%s" , dbName )
1246
- partialSyncPrefix := fmt .Sprintf ("ccrp_%s" , dbName )
1247
- return strings .HasPrefix (label , fullSyncPrefix ) || strings .HasPrefix (label , partialSyncPrefix )
1248
- }
0 commit comments