ddl: region pre-split paths mishandle scatter scope and global group IDs
- Dominant language
- Go
- Stars
- 40.5k
- Forks
- 6.2k
- PR merge metrics
- PR metrics pending
Description
## Bug Report
Please answer these questions before submitting the issue. Thanks!
### 1. Minimal reproduce step (Required)
Two existing Region pre-split paths mishandle `tidb_scatter_region`. Both are already reachable with `split-table = true`; enabling explicit split configuration when `split-table = false` also exposes them.
#### Case 1: partition pre-split confuses the global scatter group with a physical table ID
Start TiDB with a storage engine that supports Region splitting, then run:
```sql
SET SESSION tidb_scatter_region = 'global';
CREATE TABLE p (
a BIGINT,
b BIGINT,
KEY li(a),
UNIQUE KEY gi(b) GLOBAL
) SHARD_ROW_ID_BITS = 2 PRE_SPLIT_REGIONS = 2
PARTITION BY HASH(a) PARTITIONS 2;
```
Inspect the Region split requests or resulting PD Region boundaries. In `splitPartitionTableRegion`, `getScatterConfig(..., 'global')` returns `GlobalScatterGroupID` (`-1`), which is then passed to `splitIndexRegion` as its `physicalTableID` argument.
#### Case 2: persistent split policies use the DDL worker session's scatter scope
On a cluster with multiple TiKV stores, run:
```sql
SET SESSION tidb_scatter_region = 'table';
CREATE TABLE t (a BIGINT PRIMARY KEY);
ALTER TABLE t SPLIT BETWEEN (0) AND (10000) REGIONS 4;
SHOW TABLE t REGIONS;
```
Inspect the `LEADER_STORE_ID` values and PD scatter requests immediately after the DDL. The same problem affects policy reapplication during `TRUNCATE TABLE`, `ADD PARTITION`, and `TRUNCATE PARTITION`.
### 2. What did you expect to see? (Required)
- Case 1: index split keys use the real logical/physical table IDs, while every split request uses global scatter group `-1` only as its scatter-group ID. Global indexes are included and no split key is created under table ID `-1`.
- Case 2: the `tidb_scatter_region` value captured from the submitting session in the DDL job is used by all policy split requests. `table` and `global` should schedule the corresponding PD scatter operations.
### 3. What did you see instead (Required)
- Case 1: `splitPartitionTableRegion` passes the global scatter-group ID `-1` as `splitIndexRegion`'s physical table ID. This skips global indexes, selects local indexes, and encodes spurious local-index split keys under table ID `-1`. For nonpartitioned tables, index keys are correct but index Regions use the physical table ID as their scatter group instead of global group `-1`.
- Case 2: worker-side policy operations recover the correct scope from the DDL job for the outer synchronous/wait decision, but `applySplitPoliciesForTable` ignores it and reads `ScatterRegion` from the internal pooled DDL session. A session-level `table` or `global` request therefore normally calls `SplitRegions` with `scatter=false`; the outer path can still wait as if scattering had been requested.
### 4. What is your TiDB version? (Required)
Reproduced by code inspection on current master / PR #70919:
```text
v9.0.0-beta.2.pre-2204-g20a593131d
```
The defects predate PR #70919:
- Case 1 traces to `9971301fbc3991528d2c11aed87151171f7df5ac` (`ddl: let partition table pre split index regions`, #59547).
- Case 2 traces to `35d50f2b1277c3eb6280e84d923a46fb2a627a4d` (`ddl: support region split policy`, #65133).
### Analysis
- `splitIndexRegion` currently uses one integer for both physical key encoding/index selection and the scatter-group ID. These values must be passed separately.
- `applySplitPoliciesForTable` should receive the captured `scatterScope` explicitly instead of consulting the DDL worker session.
- Existing Region-count tests do not validate the split keys, PD scatter flag, or scatter group, so both problems can pass while producing the requested number of Regions.
Contributor guide
Research direction
Start with splitPartitionTableRegion and splitIndexRegion to trace physical table IDs separately from scatter-group IDs, then inspect applySplitPoliciesForTable and the existing Region-count tests. Verify the partition and persistent-policy paths, including TRUNCATE and ADD PARTITION cases, by checking split keys, PD scatter flags, scatter groups, and the captured session scope.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, sql
- Domain
- databases, distributed-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 64/100