diff --git a/doc/command-line-flags.md b/doc/command-line-flags.md index ac491b268..7d5b16d82 100644 --- a/doc/command-line-flags.md +++ b/doc/command-line-flags.md @@ -289,6 +289,12 @@ Defaults to 1000 (1 second). Configures the HTTP throttler check timeout in mill Makes the _old_ table include a timestamp value. The _old_ table is what the original table is renamed to at the end of a successful migration. For example, if the table is `gh_ost_test`, then the _old_ table would normally be `_gh_ost_test_del`. With `--timestamp-old-table` it would be, for example, `_gh_ost_test_20170221103147_del`. +### optimizer-switch + +Default is "prefer_ordering_index=on", this allow to override a `SET GLOBAL optimizer_switch=key=value` by one set on the session with `SET SESSION optimizer_switch=key=value`. +You can find values on https://dev.mysql.com/doc/refman/8.0/en/switchable-optimizations.html. +Example: `--optimizer-switch="prefer_ordering_index=off"`. + ### tungsten See [`tungsten`](cheatsheet.md#tungsten) on the cheatsheet. diff --git a/go/base/context.go b/go/base/context.go index 63b6d6da7..fd42b2504 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 aac5a9b99..582afd22c 100644 --- a/go/cmd/gh-ost/main.go +++ b/go/cmd/gh-ost/main.go @@ -140,6 +140,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", "prefer_ordering_index=on", "optimizer_switch param") 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 fa374a70f..4e2d433d8 100644 --- a/go/logic/applier.go +++ b/go/logic/applier.go @@ -48,6 +48,15 @@ func newDmlBuildResultError(err error) *dmlBuildResult { } } +func (this *Applier) setOptimizerSwitch() error { + if this.migrationContext.OptimizerSwitch == "" { + return nil + } + optimizerString := fmt.Sprintf("SET SESSION optimizer_switch=%q", this.migrationContext.OptimizerSwitch) + _, err := this.db.Exec(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. @@ -99,6 +108,10 @@ func (this *Applier) InitDBConnections() (err error) { this.connectionConfig.ImpliedKey = impliedKey } } + err = this.setOptimizerSwitch() + if err != nil { + return err + } if err := this.readTableColumns(); err != nil { return err }