Add --chunk-concurrent-size for parallel row-copy#1688
Conversation
4e3c02d to
18f91e8
Compare
Port of PR github#1398 by @shaohk: allows multiple row-copy chunks to execute in parallel within each iteration using errgroup. Key changes: - Add IterationRangeValues struct for thread-safe range passing - Serialize range calculation with CalculateNextIterationRangeEndValuesLock - Rewrite iterateChunks to spawn N goroutines per queue item via errgroup - Return SQL warnings from ApplyIterationInsertQuery (eliminates race on shared MigrationLastInsertSQLWarnings field) - Increase DB connection pool when concurrency > default pool size - Add --chunk-concurrent-size CLI flag (default 1, no behavior change) Co-authored-by: shaohk <shaohk@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
18f91e8 to
de32943
Compare
|
There's a problem with concurrent chunk copying: during the chunk operation, executing SELECT ... INSERT will hold the auto-increment lock on the target table, which puts a ceiling on the concurrency gains you can achieve. |
|
Thanks @shaohk — you're right to flag this, and since most tables do have an The AUTO-INC ceiling depends on
So I'd frame it as: the hard serialization you're describing applies under mode 0/1; under mode 2 it becomes soft contention. That said — even under mode 2, parallel copy doesn't scale linearly, and the dominant cap is actually in gh-ost's own loop rather than MySQL. The next-chunk boundary calculation ( I think the right things to do here are (1) document that Does that match what you were seeing? |
Summary
Port of #1398 by @shaohk to current master, with correctness improvements.
Adds
--chunk-concurrent-sizeflag that allows multiple row-copy chunks to execute in parallel within each iteration usingerrgroup. Default is 1 (no behavior change).Motivation
On large tables with fast storage (NVMe/SSD), the single-threaded row-copy loop can become a bottleneck. This flag enables parallel chunk copying to improve migration throughput.
Performance Results
1M rows,
ADD COLUMN extra_col INT DEFAULT 0, Docker MySQL 8.0, chunk-size=1000:Benefits scale with table size and storage throughput.
Key Design Decisions
concurrency=1matches master's retry semantics exactly (range calc inside retry loop for hook-based chunk size reduction);concurrency>1pre-calculates ranges under mutex for safe parallel executionCalculateNextIterationRangeEndValues(advanceCursor bool)protected by mutex, returns*IterationRangeValuesstruct with isolated Min/Max per goroutineMigrationLastInsertSQLWarningsfield)--chunk-concurrent-sizeexceeds default pool sizeChanges from original #1398
ApplyIterationInsertQueryreturns SQL warnings instead of writing to shared fieldIncludeMinValueshandling for first iterationcontext.Background())Testing
TestRetryBatchCopyWithHookspasses (hook-based chunk size reduction works correctly)Checklist
doc/command-line-flags.md)Based on work by @shaohk in #1398.