pingcap / pingcap/tidb

[ddl] Converting AUTO_ID_CACHE=1 AUTO_INCREMENT to AUTO_RANDOM can reuse primary keys and silently replace rows

Open
#70,091 1 comment 0 reactions 0 assignees View on GitHub
affects-7.5 affects-8.1 affects-8.5 component/ddl found-by-ai severity/critical type/bug
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.