Skip to content

parallel-workload: add a correctness oracle for read-then-write - #37918

Merged
aljoscha merged 1 commit into
mainfrom
aljoscha/occ-01-pw-oracle
Jul 29, 2026
Merged

parallel-workload: add a correctness oracle for read-then-write#37918
aljoscha merged 1 commit into
mainfrom
aljoscha/occ-01-pw-oracle

Conversation

@aljoscha

@aljoscha aljoscha commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Motivation

Part 1 of 7 in a stack that moves DELETE, UPDATE and INSERT ... SELECT
off the coordinator onto the session task, using optimistic concurrency
control. Design doc:
20260210_incremental_occ_read_then_write.md
(lands in part 6).

That change replaces mutual exclusion on a table with conflict detection
after the fact, so the interesting failure mode is a lost update: two
concurrent mutations both read the same snapshot and one silently
overwrites the other. Parallel workload had no way to notice that. It
checks for panics and unexpected errors, and its existing assertions do not
constrain the value a table ends up with.

Description

ReadThenWriteCounter is a dedicated single-row table that every worker
increments with a read-then-write UPDATE, next to a Python-side tally of
how each attempt ended: definitely committed, definitely not committed, or
undecided. At the end of a run the counter's value has to satisfy
committed <= v <= committed + unknown. The lower bound catches a lost
write, the upper bound catches a write reported as failed that committed
anyway.

The oracle says nothing about how a read-then-write is sequenced, so it
holds for the coordinator's lock-based path as much as for anything that
replaces it. That is deliberate. It has to be able to pass today before it
is evidence about anything, and it stays useful after this stack lands.

InsertSelectAction covers the read-dependent INSERT. A constant VALUES
list is a blind write, so only a source query over a persisted collection
reaches the read-then-write branch, and pointing it at its own target is the
most contended shape such a statement can have.

Verification

Ran parallel workload against the current lock-based path with the oracle
enabled. Nightly runs it as part of the existing parallel workload suites.

@def- def- left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit more specific than #34779, but seems ok for now, especially since that PR can't be merged yet. Later I'd like to integrate them.

Has this found any actual bugs or is it more of a precaution?

@aljoscha

Copy link
Copy Markdown
Contributor Author

This is a bit more specific than #34779, but seems ok for now, especially since that PR can't be merged yet. Later I'd like to integrate them.

Has this found any actual bugs or is it more of a precaution?

It has found bugs during iteration yes. But 100% would be good if we can integrate into a broader thing

@aljoscha aljoscha added the ci-nightly PR CI control: also trigger Nightly label Jul 29, 2026
@aljoscha
aljoscha force-pushed the aljoscha/occ-01-pw-oracle branch from 1032317 to 74cb929 Compare July 29, 2026 09:46
The workload could tell us that concurrent DML does not panic the server
or raise an unexpected error, but nothing checked that the writes it
issued actually happened. A run where every UPDATE silently did nothing
looked exactly like a healthy one.

ReadThenWriteCounter gives it an oracle. Every worker increments the same
row of a dedicated single-row table, and each attempt is recorded as
definitely committed, definitely not committed, or undecided, based on the
error text. At the end of the run the counter's value has to satisfy
committed <= v <= committed + unknown. Both bounds carry weight: the
lower one catches a lost write, the upper one catches a write that was
reported as failed but committed anyway.

The oracle says nothing about how a read-then-write is sequenced, so it
holds for the coordinator's lock-based path as much as for anything that
replaces it. That is the point: it has to be able to pass before it is
evidence about anything.

Attempts run over pg wire only. On the HTTP and WS paths a client-side
timeout or a dropped response leaves the outcome undecided far more
often, which widens the bound until it stops proving anything.

InsertSelectAction covers the read-dependent INSERT. A constant VALUES
list is a blind write, so only a source query over a persisted collection
exercises the read-then-write branch.
@aljoscha
aljoscha force-pushed the aljoscha/occ-01-pw-oracle branch from 74cb929 to 90ef255 Compare July 29, 2026 10:57
@aljoscha
aljoscha merged commit 9b96675 into main Jul 29, 2026
20 checks passed
@aljoscha
aljoscha deleted the aljoscha/occ-01-pw-oracle branch July 29, 2026 11:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-nightly PR CI control: also trigger Nightly

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants