[ddl] Converting AUTO_ID_CACHE=1 AUTO_INCREMENT to AUTO_RANDOM can reuse primary keys and silently replace rows
- Dominant language
- Go
- Stars
- 40.5k
- Forks
- 6.2k
- PR merge metrics
- PR metrics pending
Description
## Bug Report
### 1. Minimal reproduce step (Required)
**Environment**
TiDB master 231dad5225 and nightly ed2376acc6; Classic real TiKV; MDL ON; AUTO_ID_CACHE=1
**Steps**
Create a clustered AUTO_INCREMENT primary-key table with AUTO_ID_CACHE=1 and insert IDs 1 through 64. Set tidb_allow_remove_auto_inc=1 and ALTER the column to BIGINT AUTO_RANDOM(1). Execute generated REPLACE statements without specifying the ID. Compare the original payload count and the generated IDs. Run the same matrix on a table with the default auto-ID cache as a control.
### 2. What did you expect to see? (Required)
The conversion transfers the high-water mark from the allocator that owned AUTO_INCREMENT. Every generated AUTO_RANDOM incremental component is above the old owner high-water mark, all REPLACE statements insert one row, and all original rows remain.
### 3. What did you see instead? (Required)
On unmodified current master, with the current-master TiDB explicitly verified as DDL owner, 12 of 24 generated REPLACE statements reused IDs 1,5,9,10,12,14,15,16,19,20,21,22 and returned affected_rows=2. The final table had 76 rows: 52 original rows and 24 replacement rows. ADMIN CHECK TABLE succeeded. The default-cache control preserved all original rows.
### 4. What is your TiDB version? (Required)
TiDB master 231dad5225 and nightly ed2376acc6; Classic real TiKV; MDL ON; AUTO_ID_CACHE=1
Likely root cause and fix direction
**Likely root cause**
checkNewAutoRandomBits selects IncrementID when TableInfo.SepAutoInc is true, but applyNewAutoRandomBits unconditionally reads, rebases from, and deletes the RowID accessor. AUTO_ID_CACHE=1 stores AUTO_INCREMENT in the separated IncrementID allocator, so the conversion reads an unrelated zero RowID base and initializes AUTO_RANDOM near zero.
**Fix direction**
When converting from AUTO_INCREMENT, select the old accessor using the same SepAutoInc rule as checkNewAutoRandomBits. Rebase AUTO_RANDOM from that owner and delete exactly that old accessor. Add RED/GREEN coverage that verifies which TiDB is the DDL owner.
Contributor guide
Research direction
Start with the reported AUTO_ID_CACHE=1 reproduction and compare it with the default-cache control. Trace checkNewAutoRandomBits and applyNewAutoRandomBits, following the SepAutoInc choice, accessor rebasing, and deletion described in the issue. Done means conversion preserves all original rows, generated IDs are above the old high-water mark, and RED/GREEN coverage verifies the TiDB DDL owner.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100