You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: doc/command-line-flags.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,6 +6,10 @@ A more in-depth discussion of various `gh-ost` command line flags: implementatio
6
6
7
7
Add this flag when executing on Aliyun RDS.
8
8
9
+
### analyze-ghost-table-before-cutover
10
+
11
+
Run an explicit `ANALYZE TABLE` on the ghost table immediately before cut-over — after a postponed cut-over is released, before the atomic swap takes its locks — and abort the migration if the `ANALYZE` fails, rather than swap in a table with stale InnoDB statistics. Without it, the freshly swapped table can briefly serve traffic with a near-zero row estimate, which the optimizer may cost as a free full scan on hot query paths. This is the same rationale as issue #1418 / PR #1419; this flag is a corrected variant: the `ANALYZE` runs after the postpone gate releases (so a postponed cut-over still gets fresh statistics) and a failed `ANALYZE` aborts the migration instead of being ignored. Opt-in; intended for small, non-partitioned tables that are non-empty at copy (`ANALYZE TABLE` cost grows with partition count, and its statement replicates to replicas).
12
+
9
13
### allow-zero-in-date
10
14
11
15
Allows the user to make schema changes that include a zero date or zero in date (e.g. adding a `datetime default '0000-00-00 00:00:00'` column), even if global `sql_mode` on MySQL has `NO_ZERO_IN_DATE,NO_ZERO_DATE`.
Copy file name to clipboardExpand all lines: go/cmd/gh-ost/main.go
+1Lines changed: 1 addition & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -167,6 +167,7 @@ func main() {
167
167
flag.BoolVar(&migrationContext.Resume, "resume", false, "Attempt to resume migration from checkpoint")
168
168
flag.BoolVar(&migrationContext.Revert, "revert", false, "Attempt to revert completed migration")
169
169
flag.StringVar(&migrationContext.OldTableName, "old-table", "", "The name of the old table when using --revert, e.g. '_mytable_del'")
170
+
flag.BoolVar(&migrationContext.AnalyzeGhostTableBeforeCutOver, "analyze-ghost-table-before-cutover", false, "Run ANALYZE TABLE on the ghost table immediately before cut-over; abort the migration (fatal) if the ANALYZE fails, rather than swapping in a table with stale statistics. Opt-in; intended for small, non-partitioned tables that are non-empty at copy. Default false")
170
171
171
172
maxLoad:=flag.String("max-load", "", "Comma delimited status-name=threshold. e.g: 'Threads_running=100,Threads_connected=500'. When status exceeds threshold, app throttles writes")
172
173
criticalLoad:=flag.String("critical-load", "", "Comma delimited status-name=threshold, same format as --max-load. When status exceeds threshold, app panics and quits")
returnfmt.Errorf("ANALYZE TABLE on ghost %s did not report status OK; refusing cut-over: %s", sql.EscapeName(tableName), strings.Join(resultErrors, "; "))
556
+
}
557
+
returnnil
558
+
}
559
+
560
+
// AnalyzeGhostTable runs an explicit ANALYZE TABLE on the ghost table, forcing a
561
+
// synchronous InnoDB persistent-statistics recompute before cut-over. Without it the
562
+
// freshly swapped table can serve traffic with a near-zero row estimate, which the
563
+
// optimizer costs as a free full scan — the failure mode motivating upstream #1419.
564
+
// No row-count assertion follows the ANALYZE: on a freshly built, compact ghost a
565
+
// successful ANALYZE yields correct statistics by construction, and a row count
566
+
// cannot prove plan safety — plan checks belong to the orchestrating layer, which
567
+
// knows the table's context. The caller must treat a returned error as fatal,
0 commit comments