pingcap / pingcap/tidb

[ddl] TIMESTAMP partial index membership depends on writer time zone and causes wrong DELETE

Open
#70,099 1 comment 0 reactions 0 assignees View on GitHub
component/ddl found-by-ai may-affects-7.5 may-affects-8.1 may-affects-8.5 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 nightly ed2376acc6; current TiDB master 05b396fb66; TiKV nightly 730be34f95

**Steps**

Create t(id primary key,k,ts TIMESTAMP,unique index uk(k) where ts >= '2025-01-01 00:00:00'). In time_zone=-08:00 insert (1,7,'2024-12-31 12:00:00'). In time_zone=+08:00 insert (2,7,'2025-01-01 04:00:00'). These are one UTC instant. Under +08:00, IGNORE INDEX returns ids 1,2 but USE INDEX(uk) returns id 2. ADMIN CHECK returns 8223. DELETE with the same predicate and k=7 uses uk Point_Get, reports one affected row, and leaves id 1 although its predicate evaluates true.

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

One schema predicate over one canonical stored TIMESTAMP must have one membership result independent of the writer session. The second logical unique member must be rejected, table and index row sets must agree, and matched DELETE must remove every preimage row.

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

Both inserts succeed. In the +08:00 observer session both rows render as 2025-01-01 04:00:00, satisfy the predicate, and have k=7, but only id 2 has an index key. ADMIN CHECK reports missing handle 1. DELETE reports success with ROW_COUNT()=1 and leaves id 1 with predicate=true.

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

TiDB nightly ed2376acc6; current TiDB master 05b396fb66; TiKV nightly 730be34f95

Likely root cause and fix direction

**Likely root cause**

Partial-index conditions are parsed and evaluated through process-global indexConditionECtx, while the TIMESTAMP datum supplied by the mutation path has already been shaped into the writer session wall-clock representation. Persisted index-key presence therefore varies by writer context. Planner implication later treats the syntactically matching predicate as proof that the partial index is complete.

**Fix direction**

Evaluate schema-owned predicates over canonical TIMESTAMP values with frozen schema semantics. Use the same semantic representation in mutation, backfill/check, and optimizer implication paths. Until then, reject TIMESTAMP partial-index predicates or avoid using them as complete access paths across time zones.

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the time-zone-dependent partial-index case in the issue and inspect the process-global indexConditionECtx. Trace how TIMESTAMP values and schema predicates are handled in mutation, backfill/check, and optimizer implication paths. Done means the repro's table and index membership agree across writer time zones, duplicate membership is rejected, and DELETE removes every matching row.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, sql
Domain
databases
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.