pingcap / pingcap/tidb

Prepared plan cache incorrectly references renamed table after DROP

Open
#71,041 0 comments 0 reactions 0 assignees View on GitHub
affects-25.10 affects-26.3 affects-7.5 affects-8.1 affects-8.5 component/server report/customer severity/major 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)

The following SQL reproduces the issue when prepared plan cache is enabled (the default behavior should also be tested):

```sql
USE test;
DROP TABLE IF EXISTS t, bak;
CREATE TABLE t (id INT, c INT);
INSERT INTO t VALUES (1, 1);
PREPARE s FROM 'SELECT * FROM t WHERE id = ?';
SET @a = 1;
EXECUTE s USING @a;
RENAME TABLE t TO bak;
CREATE TABLE t (id INT);
EXECUTE s USING @a;
DROP TABLE bak;
EXECUTE s USING @a;
```

The first execution after creating the replacement `t` succeeds. The final execution after dropping `bak` fails. The same sequence works in MySQL and worked in TiDB v6.5.11.

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

The final `EXECUTE s USING @a` should succeed and query the replacement table `t` (returning an empty result because it has no matching row).

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

The final execution returns:

```text
ERROR 8113 (HY000): Schema change caused error: [schema:1146]Table 'test.bak' doesn't exist
```

This is incorrect because the prepared SQL references `t`, not `bak`, and `bak` was only the old table name.

Likely cause: plan-cache table metadata is refreshed to the renamed table `bak` by table ID, but after re-resolving the prepared SQL to the newly created `t`, the cached table descriptor is not reconciled. Dropping `bak` then causes a stale-name lookup.

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

- Correct behavior: v6.5.11
- Incorrect behavior: current `origin/master` and `pingkai/master` (tested at the time of filing)
- Suspected introduction: metadata-lock-aware prepared plan-cache changes around commit `84e2926684` (`*: add metadata lock when using the plan cache (#51897) (#52957)`).

Contributor guide

Open the contributing guide

Research direction

Start with the provided SQL reproduction, enabling and then comparing prepared plan-cache behavior with the default setting. Read the metadata-lock-aware plan-cache changes around commit 84e2926684 and trace how the renamed and replacement tables are resolved. Done means the final EXECUTE uses the replacement table t after bak is dropped, matching the expected empty result.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, sql
Domain
databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.