oxidecomputer / oxidecomputer/omicron
[nexus] Audit transactions which may have incorrect serialization assumptions
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 572
- Forks
- 97
- Avg merge
- 2d 12h
- Merged PRs (30d)
- 96
Description
As highlighted by https://github.com/oxidecomputer/omicron/pull/6229#discussion_r1777381312 , the following situation may be a problem with CockroachDB:
- Interactive transaction starts, issues a
SELECTfor one or more rows from the database - The value of that row is accessed and considered, somehow
- Concurrently, that row is modified by another operation (concurrent transaction, CTE,
UPDATE,DELETE, etc). - The original transaction commits without updating the original row, but assuming it has not been changed.
- No error is returned, the transaction completes "successfully", even though the assumption of immutability of that row has been violated.
In this scenario, a row was read by a transaction, and modified before the transaction committed. According to Cockroachdb's documentation, this is legal:
“CockroachDB doesn’t allow stale reads”... “No stale reads” means that, once a write transaction committed, every read transaction starting afterwards will see it.
Note that in this situation, the read transaction started before the subsequent write transaction, so the read was not considered stale. That being said, the value read by the transaction did get modified before it was committed.
This issue tracks taking a look at our usage of interactive transactions, for the following pattern:
- A
SELECTstatement is issued without a correspondingFOR UPDATElock - The result of that
SELECTstatement influences the rest of the transaction, in some way. Examples could be: Influencing a conditional in Rust code, using the result to populate a subsequentUPDATEorINSERT, etc. - The original rows being
SELECT-ed are not themselves modified by the transaction. - If the transaction makes the assumption that the
SELECT-ed rows must not be modified before the transaction callsCOMMIT, then this is a potential problem.
An example of this issue was that highlighted within https://github.com/oxidecomputer/omicron/pull/6229, where we had roughly the following problem:
- In a Transaction:
SELECTthe latest blueprint target, confirms it is equal to value X. Perform a database modification, assuming that theSELECT-ed blueprint target has not been modified. - Concurrently, another operation may occur, which modified the "latest target blueprint".
In this example, the following may occur:
- Txn:
SELECTthe blueprint target, sees value "X" - Another operation modified the blueprint target to "X + 1"
- Txn: Modify the DB, issue
COMMIT. No error is observed, it is not known that the target changed mid-operation.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the discussion in PR #6229 and the repository's interactive transaction usage. Search for SELECT statements without FOR UPDATE whose results influence later transaction work while the selected rows are not modified. Done means the relevant cases have been audited and any unsafe serialization assumptions are identified and addressed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100