Skip to content

Commit a62f9e0

Browse files
committed
Add --test-on-replica-manual-replication-control flag
This will wait indefinitely for the replication status to change. This allows us to run test schema changes in RDS without needing custom RDS commands in gh-ost.
1 parent 88eb2d6 commit a62f9e0

File tree

3 files changed

+48
-12
lines changed

3 files changed

+48
-12
lines changed

go/base/context.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,14 @@ type MigrationContext struct {
8282
ServeSocketFile string
8383
ServeTCPPort int64
8484

85-
Noop bool
86-
TestOnReplica bool
87-
MigrateOnReplica bool
88-
OkToDropTable bool
89-
InitiallyDropOldTable bool
90-
InitiallyDropGhostTable bool
91-
CutOverType CutOver
85+
Noop bool
86+
TestOnReplica bool
87+
MigrateOnReplica bool
88+
ManualReplicationControl bool
89+
OkToDropTable bool
90+
InitiallyDropOldTable bool
91+
InitiallyDropGhostTable bool
92+
CutOverType CutOver
9293

9394
TableEngine string
9495
RowsEstimate int64

go/cmd/gh-ost/main.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ func main() {
6060
flag.BoolVar(&migrationContext.SkipRenamedColumns, "skip-renamed-columns", false, "in case your `ALTER` statement renames columns, gh-ost will note that and offer its interpretation of the rename. By default gh-ost does not proceed to execute. This flag tells gh-ost to skip the renamed columns, i.e. to treat what gh-ost thinks are renamed columns as unrelated columns. NOTE: you may lose column data")
6161

6262
executeFlag := flag.Bool("execute", false, "actually execute the alter & migrate the table. Default is noop: do some tests and exit")
63+
testOnReplicaWithManualReplicationControl := flag.Bool("test-on-replica-manual-replication-control", false, "Same as --test-on-replica, but waits for replication to be stopped, instead of stopping it automatically. (Useful in RDS.)")
6364
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")
6465
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)")
6566

@@ -149,6 +150,13 @@ func main() {
149150
if migrationContext.SwitchToRowBinlogFormat && migrationContext.AssumeRBR {
150151
log.Fatalf("--switch-to-rbr and --assume-rbr are mutually exclusive")
151152
}
153+
if *testOnReplicaWithManualReplicationControl {
154+
if migrationContext.TestOnReplica {
155+
log.Fatalf("--test-on-replica-manual-replication-control and --test-on-replica are mutually exclusive")
156+
}
157+
migrationContext.TestOnReplica = true
158+
migrationContext.ManualReplicationControl = true
159+
}
152160
switch *cutOver {
153161
case "atomic", "default", "":
154162
migrationContext.CutOverType = base.CutOverAtomic

go/logic/applier.go

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -566,14 +566,41 @@ func (this *Applier) StartSlaveSQLThread() error {
566566
return nil
567567
}
568568

569+
func (this *Applier) isReplicationStopped() bool {
570+
query := `show slave status`
571+
replicationStopped := false
572+
573+
err := sqlutils.QueryRowsMap(this.db, query, func(rowMap sqlutils.RowMap) error {
574+
replicationStopped = rowMap["Slave_IO_Running"].String == "No" && rowMap["Slave_SQL_Running"].String == "No"
575+
return nil
576+
})
577+
578+
if err != nil {
579+
return false
580+
}
581+
return replicationStopped
582+
}
583+
569584
// StopReplication is used by `--test-on-replica` and stops replication.
570585
func (this *Applier) StopReplication() error {
571-
if err := this.StopSlaveIOThread(); err != nil {
572-
return err
573-
}
574-
if err := this.StopSlaveSQLThread(); err != nil {
575-
return err
586+
if this.migrationContext.ManualReplicationControl {
587+
for {
588+
log.Info("Waiting for replication to stop...")
589+
if this.isReplicationStopped() {
590+
log.Info("Replication stopped.")
591+
break
592+
}
593+
time.Sleep(5 * time.Second)
594+
}
595+
} else {
596+
if err := this.StopSlaveIOThread(); err != nil {
597+
return err
598+
}
599+
if err := this.StopSlaveSQLThread(); err != nil {
600+
return err
601+
}
576602
}
603+
577604
readBinlogCoordinates, executeBinlogCoordinates, err := mysql.GetReplicationBinlogCoordinates(this.db)
578605
if err != nil {
579606
return err

0 commit comments

Comments
 (0)