Support limiting prefixes probed for MySQL to constrain runtime - #38164
Conversation
f3a2461 to
90dc1b3
Compare
90dc1b3 to
f3a000c
Compare
48cfbb4 to
f071ccd
Compare
f071ccd to
1d68e03
Compare
1d68e03 to
ecefb45
Compare
ecefb45 to
f5d757b
Compare
f5d757b to
9304f11
Compare
9304f11 to
bcc67c6
Compare
bcc67c6 to
1b0861e
Compare
a097f1c to
c33afc9
Compare
ublubu
left a comment
There was a problem hiding this comment.
Looks like it bounds the probing and tests some of the cases it guards against. 👍
| /// cover them. | ||
| struct MockDb { | ||
| keys: Vec<String>, | ||
| requests: usize, |
There was a problem hiding this comment.
What sort of requests is this counting? Asking because some operations cost 1, while others cost 2.
There was a problem hiding this comment.
The 1 and 2 here map to the number of underlying requests made to mysql. In the actual implementation one method makes two calls while the other makes one so I wanted to make sure the number of individual requests was bounded in about the way I expected (less than 4 requests per prefix).
| let budget = 20; | ||
| let boundaries = partition(&mut db, 16, count, 10, budget).await?; | ||
| assert!( | ||
| db.requests <= 80, // 4x budget |
There was a problem hiding this comment.
Limiting the probes to 20 prefixes makes sense. Where does the 4x upper bound come from?
There was a problem hiding this comment.
We make up to 4 requests per prefix -- one to get the first key matching the current prefix (only once per parent amortized across children) , two to get the next, and then one to estimate the size.
c33afc9 to
e54c103
Compare
e54c103 to
aff95e4
Compare
Bound the prefix partitioner to a per-table probe query budget scaled to the estimated row count, 2500 requests per billion rows by default via the mysql_source_snapshot_partition_requests_per_billion_rows dyncfg, with a floor of 256 so small tables can afford their handful of splits. Probes run sequentially, so this caps the wall-clock that partitioning can add to snapshot start in proportion to the snapshot work it optimizes. An exhausted budget stops splitting early and leaves coarser buckets, never incorrect ones. Adds a mock test asserting the partitioner never exceeds its budget and still returns a valid ordered boundary list when truncated.
aff95e4 to
4384c69
Compare
Motivation
Part of SS-97.
In degenerate cases with high cardinality of first characters, many short prefixes (i.e. "a", "aa", "aaa", "aaaa"...), or unexpected bugs, we want to ensure partitioning terminates in a reasonable amount of time.
Description
Bounds the partitioner's probe traffic with a request budget derived from the table's estimated row count, via the new
mysql_source_snapshot_partition_requests_per_billion_rowsdyncfg (floored at 256 requests). When the budget runs out the walk stops splitting and emits coarser partitions, so cost is capped without losing correctness. The budget also serves as the hard bound on the walk for degenerate key spaces.Adds mock tests for budget-bounded probing and for termination on non-advancing prefixes.
🤖 Generated with Claude Code