cockroachdb / cockroachdb/cockroach

sql: `SELECT ... FOR UPDATE` results in `WriteTooOldErr` under read-committed isolation

Open
#145,377 6 comments 0 reactions 0 assignees View on GitHub
A-read-committed branch-master branch-release-23.2 branch-release-24.1 branch-release-24.3 branch-release-25.1 branch-release-25.2 C-bug O-support P-3 T-sql-queries
Dominant language
Go
Stars
32.5k
Forks
4.1k
PR merge metrics
PR metrics pending

Description

Under read-committed isolation, it's possible for a SFU statement to error with `WriteTooOldError`. The error message mentions automatic retries. This is surprising behavior because we would expect the SFU to block until a lock on a row can be acquired, not retry and eventually error.

I've built a simple reproduction. It uses a schema and concurrent transactions of the form:

```sql
CREATE TABLE t (k INT PRIMARY KEY, v INT);
INSERT INTO t VALUES (1, 1);

BEGIN;
SELECT 1; -- I think this could be any SQL statement, or multiple.
SELECT * FROM t WHERE k = 1 AND v > 0 FOR UPDATE;
UPDATE t SET v = v + 1 WHERE k = 1;
COMMIT;
```

See the reproduction here: https://gist.github.com/mgartner/bd034885fec505df4d532a268e101116

The query plan of the SFU, under read-committed isolation, looks like:

```
• lookup join (semi)
│ table: t@t_pkey
│ equality: (k) = (k)
│ equality cols are key
│ locking strength: for update
│ locking durability: guaranteed

└── • filter
│ filter: v > 0

└── • scan
missing stats
table: t@t_pkey
spans: [/1 - /1]
```

The locks are acquired in the lookup join. The scan at the bottom is non-locking. This ensures that we don't lock rows that do not satisfy the `v > 0` filter.

The locking lookup-join internally results in a `WriteTooOldError` when another transaction has written the row at a timestamp after the timestamp of the scan. This force the SFU to be automatically retried. When the number of retries exceeds `max_retries_for_read_committed` (with a default of 10), the SFU statement results in an error.

Jira issue: CRDB-49877

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.