Skip to content

analyze table before cutover - #1419

Open
wangzihuacool wants to merge 2 commits into
github:masterfrom
wangzihuacool:master
Open

analyze table before cutover#1419
wangzihuacool wants to merge 2 commits into
github:masterfrom
wangzihuacool:master

Conversation

@wangzihuacool

Copy link
Copy Markdown
Contributor

Related issue: #1418

Description:
analyze ghost table before cutover to avoid table statistics not timely updated.

@meiji163

Copy link
Copy Markdown
Contributor

LGTM

@shaohk

shaohk commented May 30, 2024

Copy link
Copy Markdown
Contributor

When the modified table is a partition table, the execution time of the ANALYZE command will increase as the number of partitions increases. When the ANALYZE statement is synchronized to the replica, it may cause replication lag.

@meiji163

Copy link
Copy Markdown
Contributor

When the ANALYZE statement is synchronized to the replica, it may cause replication lag.

Maybe make this feature a optional flag then? What do you think @timvaillancourt ?

@timvaillancourt timvaillancourt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@timvaillancourt

Copy link
Copy Markdown
Collaborator

When the modified table is a partition table, the execution time of the ANALYZE command will increase as the number of partitions increases. When the ANALYZE statement is synchronized to the replica, it may cause replication lag.

@meiji163 considering this (I didn't think of it) I suggest this is an optional flag for now and we can have opt-in users report on performance

@wangzihuacool can you add an optional flag and doc/command-line-flags.md update for this one?

@Zorgon66

This comment was marked as spam.

ericyan pushed a commit that referenced this pull request Aug 7, 2026
Add --analyze-ghost-table-before-cutover. When set, cutOver() runs an
explicit ANALYZE TABLE on the ghost table after the postpone gate releases
— before atomicCutOver() takes the source lock and before --test-on-replica
stops replication — logs the elapsed milliseconds on success, and aborts
the migration (fatal) if the ANALYZE fails, rather than swap in a table
with stale InnoDB statistics.

The abort exits synchronously (Log.Fatale), not via a retriable return — a
plain return re-runs cutOver() and the ANALYZE up to --default-retries.
Because ANALYZE TABLE reports table-level failures (missing table,
storage-engine errors) as Msg_type Error rows in its result set while
succeeding at the protocol level, the result rows are inspected and
cut-over is refused unless ANALYZE reports status OK with no Error rows;
privilege-style failures surface as statement errors on the same abort
path.

Without this, a 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, flipping plans until statistics are recomputed. Issue
#1418 / PR #1419 propose an ANALYZE for the same reason; this variant
corrects two defects there — the ANALYZE runs after the postpone gate (so a
postponed cut-over still gets fresh statistics) and a failed ANALYZE aborts
instead of being ignored. Opt-in, matching the maintainers' ask on #1419
(ANALYZE cost grows with partition count, and the statement replicates).

The result-row inspection is extracted as classifyAnalyzeTableResult, a
pure, DB-free function, and covered by:
- TestClassifyAnalyzeTableResult: a table test over status-OK, case
  folding, an error row (alone and alongside a status-OK row), a status-OK
  row followed by a later error row (rows are scanned fully, not
  short-circuited), a non-OK status, and an empty result. Each refusal
  asserts the underlying cause via ErrorContains.
- ApplierTestSuite.TestAnalyzeGhostTable (real MySQL): happy path; the
  fail-open regression (dropping the ghost table makes ANALYZE return an
  Error row with no statement error, which the row inspection must refuse);
  and the statement-error branch (a closed connection is refused via the
  distinct error path).

Also fixes a pre-existing suite bug surfaced while adding the test above:
testify's suite runner calls TearDownSuite() (capital D), but the applier,
migrator, and streamer suites all spelled it TeardownSuite(), so the method
never matched the interface and the MySQL testcontainer was never
terminated. Renamed in all three suites.

Co-authored-by: wangzihuacool <wangzihuacool@163.com>
Signed-off-by: Vandhana Selvaprakash <vandhana.selvaprakash@airtable.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants