From d499039a18fcc9f4f5bf8818b22c9480585ecf0b Mon Sep 17 00:00:00 2001 From: Cyril LEVIS Date: Tue, 27 Dec 2022 10:04:25 +0100 Subject: [PATCH] feat: add an optimizer switch params to migration context to be able to pass for example: `--optimizer-switch="prefer_ordering_index=on"` --- go/base/context.go | 1 + go/cmd/gh-ost/main.go | 1 + go/logic/applier.go | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/go/base/context.go b/go/base/context.go index e3472f5bd..f8dc6a045 100644 --- a/go/base/context.go +++ b/go/base/context.go @@ -209,6 +209,7 @@ type MigrationContext struct { CutOverCompleteFlag int64 InCutOverCriticalSectionFlag int64 PanicAbort chan error + OptimizerSwitch string OriginalTableColumnsOnApplier *sql.ColumnList OriginalTableColumns *sql.ColumnList diff --git a/go/cmd/gh-ost/main.go b/go/cmd/gh-ost/main.go index 3daf24441..7712ee7d0 100644 --- a/go/cmd/gh-ost/main.go +++ b/go/cmd/gh-ost/main.go @@ -139,6 +139,7 @@ func main() { criticalLoad := flag.String("critical-load", "", "Comma delimited status-name=threshold, same format as --max-load. When status exceeds threshold, app panics and quits") flag.Int64Var(&migrationContext.CriticalLoadIntervalMilliseconds, "critical-load-interval-millis", 0, "When 0, migration immediately bails out upon meeting critical-load. When non-zero, a second check is done after given interval, and migration only bails out if 2nd check still meets critical load") flag.Int64Var(&migrationContext.CriticalLoadHibernateSeconds, "critical-load-hibernate-seconds", 0, "When non-zero, critical-load does not panic and bail out; instead, gh-ost goes into hibernation for the specified duration. It will not read/write anything from/to any server") + flag.StringVar(&migrationContext.OptimizerSwitch, "optimizer-switch", "", "Optimizer switch params, eg: prefer_ordering_index=on") quiet := flag.Bool("quiet", false, "quiet") verbose := flag.Bool("verbose", false, "verbose") debug := flag.Bool("debug", false, "debug mode (very verbose)") diff --git a/go/logic/applier.go b/go/logic/applier.go index ad6368e61..72ab932a8 100644 --- a/go/logic/applier.go +++ b/go/logic/applier.go @@ -49,6 +49,15 @@ func newDmlBuildResultError(err error) *dmlBuildResult { } } +func (this *Applier) setOptimizer(tx *gosql.Tx) error { + if this.migrationContext.OptimizerSwitch == "" { + return nil + } + optimizerString := fmt.Sprintf("set session optimizer_switch=%q", this.migrationContext.OptimizerSwitch) + _, err := tx.Query(optimizerString) + return err +} + // Applier connects and writes the applier-server, which is the server where migration // happens. This is typically the master, but could be a replica when `--test-on-replica` or // `--execute-on-replica` are given. @@ -477,6 +486,11 @@ func (this *Applier) readMigrationMinValues(tx *gosql.Tx, uniqueKey *sql.UniqueK return err } + err = this.setOptimizer(tx) + if err != nil { + return err + } + rows, err := tx.Query(query) if err != nil { return err @@ -502,6 +516,11 @@ func (this *Applier) readMigrationMaxValues(tx *gosql.Tx, uniqueKey *sql.UniqueK return err } + err = this.setOptimizer(tx) + if err != nil { + return err + } + rows, err := tx.Query(query) if err != nil { return err