Skip to content

Commit 7d0ec9c

Browse files
author
Shlomi Noach
committed
added --migrate-on-replica flag; runs complete migration on replica
1 parent 574c372 commit 7d0ec9c

File tree

3 files changed

+15
-5
lines changed

3 files changed

+15
-5
lines changed

go/base/context.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ type MigrationContext struct {
7474

7575
Noop bool
7676
TestOnReplica bool
77+
MigrateOnReplica bool
7778
OkToDropTable bool
7879
InitiallyDropOldTable bool
7980
InitiallyDropGhostTable bool

go/cmd/gh-ost/main.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ func main() {
5757
flag.BoolVar(&migrationContext.NullableUniqueKeyAllowed, "allow-nullable-unique-key", false, "allow gh-ost to migrate based on a unique key with nullable columns. As long as no NULL values exist, this should be OK. If NULL values exist in chosen key, data may be corrupted. Use at your own risk!")
5858

5959
executeFlag := flag.Bool("execute", false, "actually execute the alter & migrate the table. Default is noop: do some tests and exit")
60-
flag.BoolVar(&migrationContext.TestOnReplica, "test-on-replica", false, "Have the migration run on a replica, not on the master. At the end of migration tables are not swapped; gh-ost issues `STOP SLAVE` and you can compare the two tables for building trust")
60+
flag.BoolVar(&migrationContext.TestOnReplica, "test-on-replica", false, "Have the migration run on a replica, not on the master. At the end of migration replication is stopped, and tables are swapped and immediately swap-revert. Replication remains stopped and you can compare the two tables for building trust")
61+
flag.BoolVar(&migrationContext.MigrateOnReplica, "migrate-on-replica", false, "Have the migration run on a replica, not on the master. This will do the full migration on the replica including cut-over (as opposed to --test-on-replica)")
62+
6163
flag.BoolVar(&migrationContext.OkToDropTable, "ok-to-drop-table", false, "Shall the tool drop the old table at end of operation. DROPping tables can be a long locking operation, which is why I'm not doing it by default. I'm an online tool, yes?")
6264
flag.BoolVar(&migrationContext.InitiallyDropOldTable, "initially-drop-old-table", false, "Drop a possibly existing OLD table (remains from a previous run?) before beginning operation. Default is to panic and abort if such table exists")
6365
flag.BoolVar(&migrationContext.InitiallyDropGhostTable, "initially-drop-ghost-table", false, "Drop a possibly existing Ghost table (remains from a previous run?) before beginning operation. Default is to panic and abort if such table exists")
@@ -127,6 +129,13 @@ func main() {
127129
if migrationContext.AllowedRunningOnMaster && migrationContext.TestOnReplica {
128130
log.Fatalf("--allow-on-master and --test-on-replica are mutually exclusive")
129131
}
132+
if migrationContext.AllowedRunningOnMaster && migrationContext.MigrateOnReplica {
133+
log.Fatalf("--allow-on-master and --migrate-on-replica are mutually exclusive")
134+
}
135+
if migrationContext.MigrateOnReplica && migrationContext.TestOnReplica {
136+
log.Fatalf("--migrate-on-replica and --test-on-replica are mutually exclusive")
137+
}
138+
130139
switch *cutOver {
131140
case "safe", "default", "":
132141
migrationContext.CutOverType = base.CutOverSafe

go/logic/migrator.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func (this *Migrator) shouldThrottle() (result bool, reason string) {
118118
if time.Duration(lag) > time.Duration(this.migrationContext.MaxLagMillisecondsThrottleThreshold)*time.Millisecond {
119119
return true, fmt.Sprintf("lag=%fs", time.Duration(lag).Seconds())
120120
}
121-
if this.migrationContext.TestOnReplica && (atomic.LoadInt64(&this.allEventsUpToLockProcessedInjectedFlag) == 0) {
121+
if (this.migrationContext.TestOnReplica || this.migrationContext.MigrateOnReplica) && (atomic.LoadInt64(&this.allEventsUpToLockProcessedInjectedFlag) == 0) {
122122
replicationLag, err := mysql.GetMaxReplicationLag(this.migrationContext.InspectorConnectionConfig, this.migrationContext.ThrottleControlReplicaKeys, this.migrationContext.ReplictionLagQuery)
123123
if err != nil {
124124
return true, err.Error()
@@ -666,11 +666,11 @@ func (this *Migrator) initiateInspector() (err error) {
666666
if this.migrationContext.ApplierConnectionConfig, err = this.inspector.getMasterConnectionConfig(); err != nil {
667667
return err
668668
}
669-
if this.migrationContext.TestOnReplica {
669+
if this.migrationContext.TestOnReplica || this.migrationContext.MigrateOnReplica {
670670
if this.migrationContext.InspectorIsAlsoApplier() {
671-
return fmt.Errorf("Instructed to --test-on-replica, but the server we connect to doesn't seem to be a replica")
671+
return fmt.Errorf("Instructed to --test-on-replica or --migrate-on-replica, but the server we connect to doesn't seem to be a replica")
672672
}
673-
log.Infof("--test-on-replica given. Will not execute on master %+v but rather on replica %+v itself",
673+
log.Infof("--test-on-replica or --migrate-on-replica given. Will not execute on master %+v but rather on replica %+v itself",
674674
this.migrationContext.ApplierConnectionConfig.Key, this.migrationContext.InspectorConnectionConfig.Key,
675675
)
676676
this.migrationContext.ApplierConnectionConfig = this.migrationContext.InspectorConnectionConfig.Duplicate()

0 commit comments

Comments
 (0)