-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[db] Audit usage of "ON CONFLICT DO NOTHING RETURNING ..." #1168
Comments
Avoiding |
Maybe? The top answer in the linked Stackoverflow post explains a bunch of unfortunate side effects of that, though some of those may not apply in CockroachDB. I feel like we had a chunk of code for doing exactly this a long time ago. Does that ring a bell? |
I googled "ON CONFLICT DO NOTHING RETURNING" and found this; I'm assuming this is what you're referencing? This answer mentions:
I do not recall of any code to help in this case of "insert or read the record idempotently". Their proposal of:
Definitely could also work, and avoid the write contention. They mention:
FWIW, in our case, we would expect exactly one duplicate. I do think avoiding any increased write traffic seems like a good goal, but implementing this CTE, including all the necessary type-casting, will probably take a good deal of time to implement for a general case. In the meantime, if these calls are used anywhere that idempotency is expected (e.g., all our saga calls), it's producing wrong results. We can avoid the |
Yeah, sorry, I should have been clearer. This is the link I was talking about. It's the one you included in this issue description.
Ah, I think I was thinking of
👍 |
I looked at this implementation to see if I could re-use it, but AFAICT it's doing two operations:
So it's not atomic, and I think there's a comment about this: omicron/omicron-nexus/src/db/sql_operations.rs Lines 670 to 674 in 40f1d2f
(I'm not sure how sagas should help enforce atomicity?) This operation is easy to do in diesel today; it's basically just: let result = diesel::insert_into(table)
.values(values)
.on_conflict(...)
.do_nothing()
.get_result_async()
.await?;
match result {
Err(NotFound) => {
return table.filter(id.eq(id)).get_result_async().await;
}
_ => return result;
} But I think it's the "making it a single atomic operation" part that would be tricky. |
- Makes use of oxidecomputer/steno#88 to test idempotency of instance creation actions + undo actions - Fixes all the ways in which it was *not* idempotent, including... - (Action) Inserting the same network interface failed with a VPC subnet error, instead of an "already exists" error. - (Action) Inserting the instance record twice fell victim to #1168 - (Undo) Deleting the instance record failed to execute twice, as it could not find the instance record for the second invocation. Part of #2094
Crucible changes: Per client, queue-based backpressure (#1186) A builder for the Downstairs Downstairs struct. (#1152) Update Rust to v1.76.0 (#1153) Deactivate the read only parent after a scrub (#1180) Start byte-based backpressure earlier (#1179) Tweak CI scripts to fix warnings (#1178) Make `gw_ds_complete` less public (#1175) Verify extent under repair is valid after copying files (#1159) Remove individual panic setup, use global panic settings (#1174) [smf] Use new zone network config service (#1096) Move a few methods into downstairs (#1160) Remove extra clone in upstairs read (#1163) Make `crucible-downstairs` not depend on upstairs (#1165) Update Rust crate rusqlite to 0.31 (#1171) Update Rust crate reedline to 0.29.0 (#1170) Update Rust crate clap to 4.5 (#1169) Update Rust crate indicatif to 0.17.8 (#1168) Update progenitor to bc0bb4b (#1164) Do not 500 on snapshot delete for deleted region (#1162) Drop jobs from Offline downstairs. (#1157) `Mutex<Work>` → `Work` (#1156) Added a contributing.md (#1158) Remove ExtentFlushClose::source_downstairs (#1154) Remove unnecessary mutexes from Downstairs (#1132) Propolis changes: PHD: improve Windows reliability (#651) Update progenitor and omicron deps Clean up VMM resource on server shutdown Remove Inventory mechanism Update vergen dependency Properly handle pre/post illumos#16183 fixups PHD: add `pfexec` to xtask phd-runner invocation (#647) PHD: add Windows Server 2016 adapter & improve WS2016/2019 reliability (#646) PHD: use `clap` for more `cargo xtask phd` args (#645) PHD: several `cargo xtask phd` CLI fixes (#642) PHD: Use ZFS clones for file-backed disks (#640) PHD: improve ctrl-c handling (#634)
Crucible changes: Per client, queue-based backpressure (#1186) A builder for the Downstairs Downstairs struct. (#1152) Update Rust to v1.76.0 (#1153) Deactivate the read only parent after a scrub (#1180) Start byte-based backpressure earlier (#1179) Tweak CI scripts to fix warnings (#1178) Make `gw_ds_complete` less public (#1175) Verify extent under repair is valid after copying files (#1159) Remove individual panic setup, use global panic settings (#1174) [smf] Use new zone network config service (#1096) Move a few methods into downstairs (#1160) Remove extra clone in upstairs read (#1163) Make `crucible-downstairs` not depend on upstairs (#1165) Update Rust crate rusqlite to 0.31 (#1171) Update Rust crate reedline to 0.29.0 (#1170) Update Rust crate clap to 4.5 (#1169) Update Rust crate indicatif to 0.17.8 (#1168) Update progenitor to bc0bb4b (#1164) Do not 500 on snapshot delete for deleted region (#1162) Drop jobs from Offline downstairs. (#1157) `Mutex<Work>` → `Work` (#1156) Added a contributing.md (#1158) Remove ExtentFlushClose::source_downstairs (#1154) Remove unnecessary mutexes from Downstairs (#1132) Propolis changes: PHD: improve Windows reliability (#651) Update progenitor and omicron deps Clean up VMM resource on server shutdown Remove Inventory mechanism Update vergen dependency Properly handle pre/post illumos#16183 fixups PHD: add `pfexec` to xtask phd-runner invocation (#647) PHD: add Windows Server 2016 adapter & improve WS2016/2019 reliability (#646) PHD: use `clap` for more `cargo xtask phd` args (#645) PHD: several `cargo xtask phd` CLI fixes (#642) PHD: Use ZFS clones for file-backed disks (#640) PHD: improve ctrl-c handling (#634) Co-authored-by: Alan Hanson <alan@oxide.computer>
(here's some background that covers this use-case)
There are a handful of spots in the datastore where we:
Example:
omicron/nexus/src/db/datastore.rs
Lines 880 to 884 in 3ae28c7
This is valid SQL, but it's a little suspect:
NotFound
error from the database.This means that, especially in situations where we expect idempotency, this statement may return different results if invoked multiple times.
The text was updated successfully, but these errors were encountered: