Open Tema opened 8 months ago
This behavior arises due to some ambiguity in semantics when mixing current read and snapshot read scenarios.
For example, in TiDB, suppose txn_1
uses an update statement with current read. This corresponds to KV operations such as deleting row 1 and inserting row 2 into TiDB's memory, while also locking both rows. Now, when executing select * from t
, which is a snapshot read, it needs to merge the results from the memory write with the snapshot read. Depending on the timestamp used for the snapshot read, the final result may be 0 (from TiKV snapshot) and 2 (from memory). However, this issue does not occur when using select for update
.
There are some known issues related to the mixed usages of snapshot read and current read, for example https://github.com/pingcap/tidb/issues/44200
MySQL exhibits similar behavior:
This corresponds to KV operations such as deleting row 1 and inserting row 2 into TiDB's memory
Now, when executing select * from t, which is a snapshot read, it needs to merge the results from the memory write with the snapshot read.
If update is indeed represented as delete and insert, then it looks like the initial snapshot data is merged with insert row result only, but not with delete row result.
Bug Report
I was playing with TiDB transactions and discovered an interesting artifact which I can’t explain. Basically in case of parallel updates the transaction was able to see both original row and the updated one together returned by a single SELECT statement.
1. Minimal reproduce step (Required)
Create table:
Start one transaction:
Update in the separate transaction:
Update same table in the original transaction:
2. What did you expect to see? (Required)
Original transaction should see only updated value:
I actually observe this, but only after
commit
statement.3. What did you see instead (Required)
Original transaction see both values:
4. What is your TiDB version? (Required)