pingcap / pingcap/tidb

`br restore` didn't rewrite KV for global index

Open
#71,052 0 comments 0 reactions 0 assignees View on GitHub
component/tablepartition found-by-ai may-affects-25.10 may-affects-26.3 may-affects-7.5 may-affects-8.1 may-affects-8.5 severity/critical sig/sql-infra type/bug
Dominant language
Go
Stars
40.5k
Forks
6.2k
PR merge metrics
PR metrics pending

Description

## Bug Report

Please answer these questions before submitting your issue. Thanks!

### 1. Minimal reproduce step (Required)

1. Start a TiDB v8.5.7 cluster with BR and create a partitioned table with a global index:

```sql
CREATE DATABASE br_global_idx;
USE br_global_idx;
CREATE TABLE t (
id INT PRIMARY KEY,
a INT,
b INT,
INDEX idx_a(a) GLOBAL,
UNIQUE KEY uk_a(a) GLOBAL
) PARTITION BY RANGE(id) (
PARTITION p0 VALUES LESS THAN (10000001),
PARTITION p1 VALUES LESS THAN MAXVALUE
);
INSERT INTO t VALUES
(1,1,101),(1000,1000,10007),(10000001,10000001,201),(10001000,10001000,202);
SELECT table_name,tidb_table_id
FROM information_schema.tables
WHERE table_schema='br_global_idx' AND table_name='t';
SELECT table_name,partition_name,tidb_partition_id
FROM information_schema.partitions
WHERE table_schema='br_global_idx' AND table_name='t';
```

2. Back up the database, drop it, and restore it. Keep checksum enabled:

```bash
br backup full --pd 127.0.0.1:2379 \
--storage local:///tmp/br-global-index-backup \
--filter 'br_global_idx.*' --checksum=true

mysql -h 127.0.0.1 -P 4000 -u root -e 'DROP DATABASE br_global_idx'

br restore full --pd 127.0.0.1:2379 \
--storage local:///tmp/br-global-index-backup \
--filter 'br_global_idx.*' --checksum=true
```

3. Query `information_schema.tables` and `information_schema.partitions` again. The restored table and partitions have new IDs, but decoding the restored global-index values with `tikv-ctl` shows that their embedded partition IDs are still the old IDs.

4. Let GC/delete-range remove the dropped table's old physical partition ranges, or remove those old ranges with `tikv-ctl unsafe_destroy_range`, and compare index access with a table scan:

```sql
USE br_global_idx;
SELECT id,a,b FROM t USE INDEX(idx_a) WHERE a=1000;
SELECT id,a,b FROM t IGNORE INDEX(idx_a,uk_a) WHERE id=1000;

ADMIN CHECK TABLE t;
SET @@tidb_enable_fast_table_check=0;
ADMIN CHECK TABLE t;
```

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

BR should rewrite every table and partition identifier carried by a global-index entry. After restore and cleanup of the old table ranges, index access and table access should return the same rows, and `ADMIN CHECK TABLE` should pass.

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

BR exits successfully and its checksum passes, but each restored global-index value still embeds the old physical partition ID. While the dropped table's old ranges remain, the problem can be masked because index lookup accidentally finds the old record. After those ranges are removed, the index lookup returns no row while the table scan still returns `(1000,1000,10007)`. The default fast `ADMIN CHECK TABLE` reports success; with `tidb_enable_fast_table_check=0`, it reports an index/record mismatch such as error 8134. This leaves a persistent global-index/table inconsistency after a normal backup, drop, and restore sequence.

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

```text
Release Version: v8.5.7
Edition: Community
Git Commit Hash: 202b7f47286a1109b5c957401d34c9358d130ae0
Git Branch: HEAD
UTC Build Time: 2026-07-09 23:07:02
GoVersion: go1.25.10
Race Enabled: false
Check Table Before Drop: false
Store: tikv
```

Contributor guide

Open the contributing guide

Research direction

Start with the `br backup full` and `br restore full` reproduction, then inspect the BR restore path responsible for rewriting table and partition IDs and its checksum handling. Use `tikv-ctl` to decode restored global-index values, remove the old ranges, and rerun the index query and both `ADMIN CHECK TABLE` modes; done means global-index and table access agree and the non-fast check passes.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.