Skip to content

storage/mysql: enable primary-key snapshot parallelism by default - #38656

Merged
peterdukelarsen merged 1 commit into
MaterializeInc:mainfrom
peterdukelarsen:plarsen/mysql-snapshot-parallelism-default
Sep 4, 2026
Merged

storage/mysql: enable primary-key snapshot parallelism by default#38656
peterdukelarsen merged 1 commit into
MaterializeInc:mainfrom
peterdukelarsen:plarsen/mysql-snapshot-parallelism-default

Conversation

@peterdukelarsen

@peterdukelarsen peterdukelarsen commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Motivation

Part of SS-438

Flips the mysql_source_snapshot_parallelism dyncfg default from false to true, so MySQL source snapshots of tables with a supported single-column primary key are split into per-worker PK ranges out of the box. Tables without a suitable PK continue to fall back to a single-worker whole-table read.

CI has been exercising the enabled path via the mzcompose system parameter override (which also randomizes the flag so the fallback path stays covered). This brings the production default in line with what is tested. The flag remains available to disable splitting for a replica if needed.

Tips for reviewer

One-line default change. The existing test/mysql-cdc/mysql-cdc.td coverage explicitly sets the flag to false for the fallback case and relies on the enabled path elsewhere, so no test changes are needed.

🤖 Generated with Claude Code

Flip the mysql_source_snapshot_parallelism dyncfg default from false to true so
MySQL source snapshots of tables with a supported single-column primary key are
split into per-worker PK ranges out of the box. CI has been exercising the
enabled path via the mzcompose system parameter override; this brings
production in line with what is tested.
@peterdukelarsen
peterdukelarsen requested a review from a team as a code owner September 4, 2026 15:01
@def-

def- commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

QA LLM Review

1. MEDIUM -- PK-sampling probe connections skip the wait_timeout guard that every other snapshot connection gets

src/storage/src/source/mysql/snapshot.rs:365

The pooled connections sample_pk_bounds opens are the only snapshot-phase connections that never run SET @@session.wait_timeout, and this default flip is what makes them live long enough for that to matter. On an upstream with a low global wait_timeout, a probe connection that finishes its table early and sits in the pool while a slower table's prefix walk runs can be reaped by the server; the next use of it fails and aborts the whole snapshot as a transient error, which then repeats on every retry.

Details

set_wait_timeout (snapshot.rs:1163) exists precisely for this: "so a lowered global value cannot reap the connection while it sits idle during snapshot setup", backed by DEFAULT_SNAPSHOT_WAIT_TIMEOUT = 48h. It is applied to the leader's lock connection (snapshot.rs:471) and to each worker's snapshot connection (snapshot.rs:832). The probe pool at snapshot.rs:362-378 sets only max_execution_time.

Why the flip matters: with the flag off, a probe connection's work is SELECT table_rows plus (for tables under mysql_source_snapshot_exact_count_max_rows) a COUNT(*), which takes seconds. With it on, an eligible table additionally runs partition_table, which probe.rs itself budgets at up to 5000 prefix probes of a few queries each, and compute_sampled_splits documents as able to "take minutes". buffer_unordered(worker_count) reuses connections immediately while tables remain, so the exposure is the tail: once fewer tables remain than the pool holds, the surplus connections idle for the full duration of the slowest walk. They are then only touched by conn.disconnect().await? at snapshot.rs:443, whose write_command_data + stream.close() on a peer-closed socket propagates an IO error through ? as a TransientError.

Fix: carry snapshot_wait_timeout into the pooled connection setup, next to the existing max_execution_time read:

 let max_execution_time = config
     .config
     .parameters
     .mysql_source_timeouts
     .snapshot_max_execution_time;
+let wait_timeout = config
+    .config
+    .parameters
+    .mysql_source_timeouts
+    .snapshot_wait_timeout;
 None => {
     let mut conn = connection_config
         .connect(task_name, ssh_tunnel_manager)
         .await?;
+    if let Some(timeout) = wait_timeout {
+        set_wait_timeout(&mut *conn, timeout).await?;
+    }
     if let Some(timeout) = max_execution_time {

@peterdukelarsen
peterdukelarsen merged commit cc09d0a into MaterializeInc:main Sep 4, 2026
86 checks passed
@peterdukelarsen
peterdukelarsen deleted the plarsen/mysql-snapshot-parallelism-default branch September 4, 2026 17:08
@peterdukelarsen

Copy link
Copy Markdown
Contributor Author

I don't think the wait_timeout edge case here is very severe. Probes don't have that long of a long runtime -- the wait_timeout was set up when we were expecting to spend 8 hours finding boundary samples.

peterdukelarsen added a commit that referenced this pull request Sep 4, 2026
…8662)

### Motivation

Primary-key based snapshot parallelism for MySQL sources is being
enabled by default in
#38656, so the docs
should no longer mark it as a private preview feature.

Removes the `private-preview` shortcode from the MySQL snapshot
parallelism page and the two inline `private-preview-inline` markers on
the MySQL ingestion overview and the shared snapshotting parallelism
headless snippet.

The historical v26.39 release note entry that described the feature as
private preview is left as is, since it records what was true at the
time of that release.

### Tips for reviewer

Docs only. Will defer to @kay-kim on when we want to merge. Should be
enabled via launch darkly Monday and then enabled by default for
self-managed with v26.41.


🤖 Generated with [Claude Code](https://claude.com/claude-code)
bosconi pushed a commit that referenced this pull request Sep 5, 2026
Adds the rc.2 increment to the v26.41.0 section: MySQL primary-key
snapshot parallelism is now on by default (#38656).

Provisional dates are unchanged from rc.1 (Cloud 2026-09-10,
Self-Managed 2026-09-11), so the operator-compatibility row needs no
update this snapshot.
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.

3 participants