[ddl] Failed multi-schema AUTO_RANDOM conversion can make a cold TiDB overwrite existing 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 05b396fb66 and nightly ed2376acc6; Classic real TiKV; default auto-ID cache; MDL ON
**Steps**
Create a default-cache clustered AUTO_INCREMENT table with 64 rows and duplicate business values. Enable tidb_allow_remove_auto_inc in the DDL session. Run one ALTER that converts the key to AUTO_RANDOM(1) and adds a unique index on the duplicate column. After the expected 1062, start a second same-version TiDB against the same PD/TiKV. Run generated INSERT, then generated REPLACE, and fresh-read the old id=2 payload.
### 2. What did you expect to see? (Required)
A failed composite DDL restores a self-consistent pre-DDL schema and every allocator owner. A cold TiDB generates an ID above the durable high-water mark, and no preexisting payload is removed.
### 3. What did you see instead? (Required)
On current master 05b396fb66 and nightly ed2376acc6, the ALTER returns 1062 and parent history is rollback done, but SHOW CREATE contains AUTO_INCREMENT and AUTO_RANDOM together. A cold TiDB INSERT collides at id=1. Its next REPLACE returns LAST_INSERT_ID=2 and ROW_COUNT=2, replacing the old id=2 payload. A fresh session sees the old payload count 0 and ADMIN CHECK succeeds.
### 4. What is your TiDB version? (Required)
TiDB master 05b396fb66 and nightly ed2376acc6; Classic real TiKV; default auto-ID cache; MDL ON
Likely root cause and fix direction
**Likely root cause**
onModifyColumn calls checkAndApplyAutoRandomBits while the proxy subjob is still revertible. The apply step sets AutoRandomBits, rebases AutoRandom, and deletes the RowID accessor. The parent later saves/restores TableInfo and subjob state, but cannot compensate the allocator migration. Its saved snapshot already combines table AutoRandomBits with the old AUTO_INCREMENT column flag, so cold allocator reconstruction selects the deleted/reset RowID owner.
**Fix direction**
Reject this conversion inside multi-schema change as a safe short-term fix. A complete fix must stage allocator migration until all siblings can cross the parent commit boundary, or make the migration and TableInfo publication one atomic operation with exact rollback compensation. Add warm/cold RED and failed-index/successful-conversion GREEN controls.
Contributor guide
Research direction
Start at onModifyColumn and trace checkAndApplyAutoRandomBits through the multi-schema rollback path, including TableInfo and allocator restoration. Reproduce the failed composite DDL, then run the warm/cold RED cases and failed-index/successful-conversion GREEN controls; done means rollback leaves a consistent schema and allocator state without overwriting existing rows.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- databases, distributed-systems
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100