pingcap / pingcap/tidb

[txn] Non-transactional DML silently uses stale tx_read_ts split range and misses current rows

Open
#70,024 1 comment 0 reactions 0 assignees View on GitHub
affects-7.5 affects-8.1 affects-8.5 component/executor found-by-ai severity/critical sig/transaction type/bug
Dominant language
Go
Stars
40.5k
Forks
6.2k
PR merge metrics
PR metrics pending

Description

## Bug Report

> Evidence status: confirmed.

### 1. Minimal reproduce step (Required)

```sql
CREATE TABLE t(a INT PRIMARY KEY,b INT);
INSERT INTO t VALUES(1,10);
SET @ts=NOW(6);
DO SLEEP(1.3);
INSERT INTO t VALUES(2,20);
SET TRANSACTION READ ONLY AS OF TIMESTAMP @ts;
BATCH ON a LIMIT 1 UPDATE t SET b=b+100;
SET @@tx_read_ts='';
SELECT GROUP_CONCAT(CONCAT(a,':',b) ORDER BY a) FROM t;
```

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

Because SET TRANSACTION READ ONLY AS OF TIMESTAMP makes the next transaction read-only/stale, a write statement should be rejected like ordinary UPDATE; alternatively, NT-DML must clear every stale-read input before deriving split ranges so both current rows are updated.

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

The statement reports one successful job and leaves row 2 unchanged: 1:110,2:20. Ordinary UPDATE under the same tx_read_ts returns ERROR 1105 only support read-only statement during read-only staleness transactions; NT-DML without tx_read_ts updates both rows to 1:110,2:120.

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

Confirmed on testbed 8220955 with TiDB v9.0.0-beta.2.pre-1895-g5c9198e948.

Likely root cause and fix direction

HandleNonTransactionalDML clears SessionVars.ReadStaleness, but not the transaction read timestamp set by SET TRANSACTION READ ONLY AS OF TIMESTAMP. buildShardJobs runs the split-range SELECT through se.Execute, so staleReadProcessor consumes TxnReadTS and enumerates only stale rows. Later split DML jobs run and commit those stale-derived ranges.

Contributor guide

Open the contributing guide

Research direction

Start with HandleNonTransactionalDML and buildShardJobs, then trace the split-range SELECT through se.Execute to see how SET TRANSACTION READ ONLY AS OF TIMESTAMP affects range enumeration. Reproduce the SQL example and verify that the write is rejected or that both current rows are updated, including coverage for the stale transaction read timestamp path.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, sql
Domain
databases, distributed-systems
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.