li3zhi4 opened a new pull request, #11746:
URL: https://github.com/apache/seatunnel/pull/11746

   ## Why
   
   The JDBC source splits a table into chunks using **only the first column of 
the primary key** (`ChunkSplitter.findSplitKey()` returns the first supported 
PK column). For tables with a **composite primary key**, this:
   
   1. **Loses parallelism entirely when the first column has (almost) one 
distinct value**: the chunk loop hits `min.equals(max)` and returns a single 
full-table chunk — a large table is read by one reader.
   2. **Collapses to severely skewed chunks when the first column has low 
cardinality / many duplicates**: `nextChunkEnd()` keeps calling `queryMin` to 
skip duplicated boundary values; chunk count collapses and one chunk dominates 
the job duration.
   3. `DynamicChunkSplitter` on `dev` has zero multi-column (`Composite`) 
methods — the entire splitter is single-column.
   
   ## Scope
   
   - **`connector-jdbc` only** — this is a separate module with its own 
splitter (`ChunkSplitter` / `DynamicChunkSplitter`), independent from the CDC 
splitter.
   - The **CDC-side** composite-key support (base multi-column API + MySQL 
first implementation) is a **separate PR** — see the `[Connector-CDC]` issue; 
do not bundle both modules here.
   - Single-column behavior for single-column keys is unchanged (backward 
compatible).
   
   ## What changed
   
   ### `ChunkSplitter.java`
   
   - `findSplitKey()`: return all supported primary-key columns as the split 
key (multi-column `SeaTunnelRowType`) when the PK is composite; user-set 
`partition_column` still wins. Single-column PK keeps the exact current result.
   
   ### `DynamicChunkSplitter.java`
   
   - Add multi-column `queryMinMaxComposite` / `queryNextChunkMaxComposite` / 
`queryMinComposite` and `createCompositeSplit`:
     - tuple comparisons **expanded into OR/AND form** (`col1 > ? OR (col1 = ? 
AND col2 >= ?)`) so the composite index can be used (a row-constructor `(a,b) 
>= (?,?)` frequently cannot);
     - `ORDER BY ... LIMIT chunkSize` boundary walking (each call scans at most 
`chunkSize` rows);
     - half-open `(start, end]` tuple boundary semantics per chunk.
   - Wire the composite path into the split generation when the split key is 
multi-column (`createDynamicSplits` branches on `splitKey.getTotalFields() > 
1`).
   - `createDynamicSplitQuerySQL` / `prepareDynamicSplitStatement`: composite 
branches (`buildCompositeCondition` / `prepareCompositeStatement`) vs. the 
unchanged single-column paths.
   
   ## File changes
   
   | File | Change |
   |---|---|
   | `connector-jdbc/.../source/ChunkSplitter.java` | multi-column 
`findSplitKey` (composite PK, dynamic splitter only) |
   | `connector-jdbc/.../source/DynamicChunkSplitter.java` | 
`queryMinMaxComposite` / `queryNextChunkMaxComposite` / `queryMinComposite` / 
`createCompositeSplit` / `buildCompositeCondition` / 
`prepareCompositeStatement` + wiring |
   | `connector-jdbc/src/test/.../source/CompositeKeyChunkSplitterTest.java` | 
new unit tests (composite `findSplitKey`, single-column regression, tuple SQL 
shape first/middle/last, user-query wrapping, config parsing) |
   | `seatunnel-e2e/.../connector-jdbc-e2e-part-7/.../JdbcMysqlSplitIT.java` | 
new `testCompositeKeySplit` e2e (composite-PK table, first column repeats, 
asserts multi-chunk + `Object[]` tuple boundaries) |
   
   ## Verification
   
   - **Unit tests** (all pass): `CompositeKeyChunkSplitterTest` 5/5, 
`DynamicChunkSplitterTest` 5/5 (regression).
   - **`mvn spotless:check`**: passes on both modules.
   - **Official E2E (Zeta + Testcontainers, MySQL 8.0.43)**: 
`JdbcMysqlSplitIT#testCompositeKeySplit` passes — composite-PK table (order_id, 
line_no), first column repeats 0/1/2, splits into multiple chunks with 
`Object[]` tuple boundaries; single-column numeric/string/date split paths in 
the same IT still pass (regression).
   
   ## Checklist
   
   - [x] Ported onto `dev` + unit tests pass
   - [x] `mvn spotless:check` passes
   - [x] Official E2E passes (Zeta + Testcontainers)
   - [x] Issue(s) referenced: #11741
   - [ ] Docs updated if needed (JDBC connector doc: split-key behavior for 
composite PK)
   
   ## Note for upstream rebase
   
   `connector-jdbc` splitter on `dev` is single-column and self-contained 
(`ChunkSplitter` abstract class + `DynamicChunkSplitter`); no cross-module 
dependency on the CDC changes, so this PR can be reviewed/merged independently.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to