Skip to content

storage: String interpolation - #37903

Draft
peterdukelarsen wants to merge 3 commits into
MaterializeInc:mainfrom
peterdukelarsen:pl/mysql-snapshot-pk-interpolation
Draft

storage: String interpolation#37903
peterdukelarsen wants to merge 3 commits into
MaterializeInc:mainfrom
peterdukelarsen:pl/mysql-snapshot-pk-interpolation

Conversation

@peterdukelarsen

Copy link
Copy Markdown
Contributor

Motivation

Computing partition boundaries by scanning the table in MySQL is expensive enough that we aren't seeing improvements in snapshot performance. Instead, we want to compute cheap partition boundaries.

Description

Verification

How do you know this change is correct? Describe new or existing automated
tests, or manual steps you took.

peterdukelarsen and others added 3 commits July 24, 2026 17:42
Flip the mysql_source_snapshot_parallelism dyncfg default from true to
false, so new deployments use the legacy single-worker-per-table
snapshot unless the flag is enabled. Parallel PK-range snapshotting
stays available behind the flag and is now rolled out selectively via
LaunchDarkly rather than being on everywhere by default.

CI continues to run with the flag enabled through the mzcompose default
system parameters, so the parallel path keeps its test coverage.
Replace the OFFSET-walk boundary sampling for parallel MySQL snapshots
with interpolation between MIN and MAX of the primary key. The old walk
cost a full index pass per table up front. The new computation is two
index dives plus integer math, at the price of scoping support down to
single-column string-like primary keys with a binary collation
(ascii_bin, latin1_bin, utf8mb4_bin, utf8mb4_0900_bin), where MySQL's
comparison order matches the digit order the math preserves. Integer
primary keys now take the single-worker fallback.

Keys are mapped to digit strings (bytes for single-byte charsets, code
points with the surrogate gap collapsed for utf8mb4), interpolated as
fixed-precision integers after stripping the shared prefix, and shipped
as hex literals with a charset introducer. All boundaries share one
digit length, so their order is unaffected by PAD SPACE vs NO PAD. The
leader additionally verifies boundary order with MySQL before
broadcasting and falls back if the check fails, and the existing
worker-side re-validation still guards against collation-change races.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Before counting a table for the snapshot size gauge, read the
optimizer's row estimate from information_schema.tables. Tables
estimated above mysql_source_snapshot_exact_count_max_rows (default 1M)
report the estimate directly instead of paying an O(rows) COUNT(*)
index walk. The gauge only drives progress reporting, so an estimate is
a fair trade on large tables, and small tables keep exact counts so
statistics tests stay deterministic.

The threshold is a dyncfg so tests can force the estimated path:
mysql-cdc/statistics.td lowers it below a 1000-row table and asserts
the gauge lands in a sane band while the staged count stays exact, and
parallel-workload flips it between 0 and the default.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant