BR: checksum-pitr loadPitrIdMap swallows mysql.tidb_pitr_id_map query failures (checked error slot not used; silent skip with empty filter)

Open Beginner friendly
#70,770 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
go, mysql
Domain
databases

Research direction

Start in br/pkg/task/operator/checksum_table.go at loadPitrIdMap and trace the empty-filter path through RunPitrChecksumTable. Reproduce a failing mysql.tidb_pitr_id_map query with br pitr checksum table; done means the real query failure is reported and the check cannot silently succeed with an empty request list.

Written by the indexing model from the issue text.

Description

affects-26.3 component/br found-by-ai impact/wrong-result severity/major type/bug

Bug Report

Please answer these questions before submitting your issue. Thanks!

1. Minimal reproduce step (Required)
  1. Prepare a TiDB cluster and a BR binary built from any version since #64383 (2025-12).
  2. Make the query to mysql.tidb_pitr_id_map fail — e.g. revoke the privilege needed for the restricted SQL on that table, or make PD/TiKV unavailable during the check.
  3. Run br pitr checksum table with a filter matching no table (empty-result path).
2. What did you expect to see? (Required)

The command fails with an error pointing at the real query failure.

3. What did you see instead (Required)

The failure is silently swallowed. loadPitrIdMap (br/pkg/task/operator/checksum_table.go) checks the fresh query error errSQL but returns errors.Annotate(err, ...) where err is a stale CreateSession error slot — provably nil at that point (the if err != nil return above already consumed it). errors.Annotate(nil, msg) returns nil, so a failed query returns (nil, nil):

  • with a non-empty filter: a misleading no db map found by db name error later (blames missing id-map data instead of the real failure);
  • with an empty filter: RunPitrChecksumTable sees err==nil, the request list stays empty, runChecksum succeeds — the PITR data-integrity check is skipped entirely with exit 0.

Root cause:

rows, _, errSQL := execCtx.ExecRestrictedSQL(...)
if errSQL != nil {
    return nil, errors.Annotate(err, "failed to get pitr id map from mysql.tidb_pitr_id_map") // wraps stale `err` (nil)
}

Production reachability: medium — trigger is any failure of the mysql.tidb_pitr_id_map query during checksum-pitr (permissions drift, PD/TiKV unavailability, upgrade windows); the silent-skip branch additionally needs the filter to match no table. Consequence: silent skip of the PITR data-integrity check with exit 0.

4. What is your TiDB version? (Required)
Code-verified on pinned ca95cc55e1b and master 16c97eb67f9 (identical code); introduced by pingcap/tidb#64383 (2025-12-03); no upstream fix.
Dominant language
Go
Stars
40.6k
Forks
6.2k
Avg merge
3d 3h
Merged PRs (30d)
168

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from pingcap/tidb

All issues in pingcap/tidb

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.