pingcap / pingcap/tidb

[ddl] Multi-table RENAME can silently bind a foreign key to the wrong parent

Open
#70,087 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 231dad5225f0; one TiDB plus one real TiKV; foreign keys and metadata locking enabled

**Steps**

Enable foreign keys; create parent p1, unrelated p2/p3, and child c1 referencing p1; insert p1(1), p3(3), c1(1,1); execute RENAME TABLE p1 TO tmp, p2 TO p1, tmp TO p2, p3 TO tmp. Query REFERENTIAL_CONSTRAINTS, insert c1(3,3), delete p2(1), and compare child rows against p2 and tmp.

### 2. What did you expect to see? (Required)

The foreign key follows the original p1 table object to its final name p2. Existing c1(1,1) remains valid, c1(3,3) is rejected, and deleting p2(1) is blocked.

### 3. What did you see instead? (Required)

The foreign key references tmp, which is the original p3 object at statement completion. c1(3,3) succeeds, deleting p2(1) succeeds, c1(1,1) is orphaned, and ADMIN CHECK TABLE succeeds.

### 4. What is your TiDB version? (Required)

TiDB master 231dad5225f0; one TiDB plus one real TiKV; foreign keys and metadata locking enabled

Likely root cause and fix direction

**Likely root cause**

onRenameTables iterates over RenameTableInfos while adjustForeignKeyChildTableInfoAfterRenameTable queries the pre-statement InfoSchema referred-FK map for each old name. The first rename mutates a loaded child FK to an intermediate name. A later rename of that intermediate name sees no entry in the frozen map and returns early, so the edge does not follow the table object. Reusing the name for another table turns the stale edge into a valid reference to the wrong object.

**Fix direction**

Represent the full rename permutation by table ID or maintain an evolving referred-FK graph across the batch. Persist all affected loaded child tables after the batch and add a reused-intermediate-name regression matrix.

Contributor guide

Open the contributing guide

Research direction

Start by tracing onRenameTables and adjustForeignKeyChildTableInfoAfterRenameTable, then reproduce the multi-table rename sequence with foreign keys and metadata locking enabled. Check REFERENTIAL_CONSTRAINTS and the stated inserts and delete to verify that the foreign key follows the original table object through the full rename permutation. Done means the wrong-parent binding is prevented and a reused-intermediate-name regression matrix covers the case.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, sql
Domain
backend, 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.