Revert reverts a migration that previously completed by applying all DML events that happened after the original cutover, then doing another cutover to swap the tables back. The steps are similar to Migrate(), but without row copying.
()
| 683 | // after the original cutover, then doing another cutover to swap the tables back. |
| 684 | // The steps are similar to Migrate(), but without row copying. |
| 685 | func (mgtr *Migrator) Revert() error { |
| 686 | mgtr.migrationContext.Log.Infof("Reverting %s.%s from %s.%s", |
| 687 | sql.EscapeName(mgtr.migrationContext.DatabaseName), sql.EscapeName(mgtr.migrationContext.OriginalTableName), |
| 688 | sql.EscapeName(mgtr.migrationContext.DatabaseName), sql.EscapeName(mgtr.migrationContext.OldTableName)) |
| 689 | mgtr.migrationContext.StartTime = time.Now() |
| 690 | mgtr.migrationContext.SetLastHeartbeatOnChangelogTime(mgtr.migrationContext.StartTime) |
| 691 | |
| 692 | // Ensure context is cancelled on exit (cleanup) |
| 693 | defer mgtr.migrationContext.CancelContext() |
| 694 | |
| 695 | var err error |
| 696 | if mgtr.migrationContext.Hostname, err = os.Hostname(); err != nil { |
| 697 | return err |
| 698 | } |
| 699 | |
| 700 | go mgtr.listenOnPanicAbort() |
| 701 | |
| 702 | if err := mgtr.hooksExecutor.OnStartup(); err != nil { |
| 703 | return err |
| 704 | } |
| 705 | if err := mgtr.validateAlterStatement(); err != nil { |
| 706 | return err |
| 707 | } |
| 708 | defer mgtr.teardown() |
| 709 | |
| 710 | if err := mgtr.initiateInspector(); err != nil { |
| 711 | return err |
| 712 | } |
| 713 | if err := mgtr.checkAbort(); err != nil { |
| 714 | return err |
| 715 | } |
| 716 | if err := mgtr.initiateApplier(); err != nil { |
| 717 | return err |
| 718 | } |
| 719 | if err := mgtr.checkAbort(); err != nil { |
| 720 | return err |
| 721 | } |
| 722 | if err := mgtr.createFlagFiles(); err != nil { |
| 723 | return err |
| 724 | } |
| 725 | if err := mgtr.inspector.inspectOriginalAndGhostTables(); err != nil { |
| 726 | return err |
| 727 | } |
| 728 | if err := mgtr.applier.prepareQueries(); err != nil { |
| 729 | return err |
| 730 | } |
| 731 | |
| 732 | lastCheckpoint, err := mgtr.applier.ReadLastCheckpoint() |
| 733 | if err != nil { |
| 734 | return mgtr.migrationContext.Log.Errorf("no checkpoint found, unable to revert: %+v", err) |
| 735 | } |
| 736 | if !lastCheckpoint.IsCutover { |
| 737 | return mgtr.migrationContext.Log.Errorf("last checkpoint is not after cutover, unable to revert: coords=%+v time=%+v", lastCheckpoint.LastTrxCoords, lastCheckpoint.Timestamp) |
| 738 | } |
| 739 | mgtr.migrationContext.InitialStreamerCoords = lastCheckpoint.LastTrxCoords |
| 740 | mgtr.migrationContext.TotalRowsCopied = lastCheckpoint.RowsCopied |
| 741 | mgtr.migrationContext.MigrationIterationRangeMinValues = lastCheckpoint.IterationRangeMin |
| 742 | mgtr.migrationContext.MigrationIterationRangeMaxValues = lastCheckpoint.IterationRangeMax |