Skip to content

Mysql string primary key partitioner - #38093

Open
peterdukelarsen wants to merge 7 commits into
pl/mysql-key-probes-testsfrom
pl/mysql-pk-partitioner
Open

Mysql string primary key partitioner#38093
peterdukelarsen wants to merge 7 commits into
pl/mysql-key-probes-testsfrom
pl/mysql-pk-partitioner

Conversation

@peterdukelarsen

@peterdukelarsen peterdukelarsen commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Motivation

Part of SS-97.

Working on a faster way to identify partition boundaries for string primary keys.

Description

Adds code for partitioning the primary keys of a table with a single-column string primary key.

The core idea for partitioning without needing to understand MySQL's string sort order rules is to walk through string prefixes, in order, estimating the sizes and refining as you go based on table size estimates.

We're doing a BFS here so in the future if we want to exit early (which is planned for a subsequent PR) we have a better shot of useful partitioning.


Recreated from #38047 with an in-repo head branch so this PR can join the GitHub stack.

Discovers boundaries that split a table string primary key space into
per-worker ranges of roughly equal estimated row counts. Ranges the
optimizer estimates too large are recursively subdivided at each
distinct key prefix one character longer, probing through KeyProber,
then accumulated into per-worker buckets, so discovery costs EXPLAIN
index dives instead of an O(rows) index pass. Inaccurate estimates
skew bucket sizes but never correctness: any ordered boundary list
partitions the key space.

All key ordering happens server-side under the column collation. The
walk guards against non-advancing prefixes and caps children per split
so a misbehaving server cannot hang it. KeyProber steps past exact
keys shorter than the prefix length, so a lone short key among keys
extending it cannot leave a range unsplittable.

Also documents the caller contracts on like_prefix_pattern and
explain_row_estimate.
Drop MAX_DEPTH, MAX_CHILDREN_PER_SPLIT, and the non-advancing prefix
guard. On healthy data the walk terminates because child ranges shrink
and fresh estimates track them. The pathological cases (phantom
estimates, misbehaving servers) will be bounded by the per-table
request budget once it lands, rather than by per-mechanism caps.

Reformulate bucket sizing as a per-worker share divided by
BUCKETS_PER_WORKER, dropping the double-to-8 bucket floor for small
worker counts.
partition() becomes a composition of three stages: bucket_target_rows
(pure sizing math), split_into_ranges (the only stage touching
PartitionDb), and assign_boundaries (pure bucket accumulation). The
pure stages are now directly unit-testable and the signatures document
the data flow.
Rename the sizing knobs to say what they mean
(TARGET_RANGES_PER_WORKER, min_rows_per_worker,
target_max_rows_per_range), trim module and function docs to the
essentials, and stop deduplicating repeated boundary ends. Duplicate
ends only arise from non-advancing servers, and the snapshot layer
validates boundary monotonicity server-side before using boundaries.
The trait is the partitioner-owned seam over the concrete KeyProber, a
distinct name keeps it from shadowing the prober it wraps.
@linear-code

linear-code Bot commented Aug 6, 2026

Copy link
Copy Markdown

SS-97

partition_table_by_pk_prefix becomes partition_table, the trait
methods take the probe names they delegate to, and Range names its
exclusive lower bound prefix.
@peterdukelarsen
peterdukelarsen force-pushed the pl/mysql-pk-partitioner branch 2 times, most recently from 8753eb8 to 50b66ec Compare August 6, 2026 23:36
@peterdukelarsen
peterdukelarsen marked this pull request as ready for review August 7, 2026 00:03
@peterdukelarsen
peterdukelarsen requested a review from a team as a code owner August 7, 2026 00:03
@peterdukelarsen
peterdukelarsen requested a review from a team August 7, 2026 00:03
@peterdukelarsen
peterdukelarsen force-pushed the pl/mysql-pk-partitioner branch 4 times, most recently from c42ed7c to 6cdaec2 Compare August 8, 2026 00:08
Simplify children_prefixes into a clean prefix walk that accepts skipping
exact keys shorter than the probe depth. Split breadth first with a coarse
target of 1/max(workers, 8) of the table, restore key order via per-parent
ordinal sort keys instead of client-side key comparison, and fold boundary
assignment into compute_boundaries. Estimates are u64 end to end and a
missing optimizer estimate is now a named MissingRowEstimate error raised
inside estimate_range_rows.
@peterdukelarsen
peterdukelarsen force-pushed the pl/mysql-pk-partitioner branch from 6cdaec2 to fe76d04 Compare August 8, 2026 01:44
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