Repository navigation
fix(tables): drop the per-table row-order lock from inserts - #8811
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Collaborator
Author
|
@greptile review |
Collaborator
Author
|
@greptile review |
Contributor
|
TheodoreSpeaks
force-pushed
the
fix/drop-row-order-lock
branch
from
October 8, 2026 21:57
ed00ebc to
1329fb9
Compare
Appends mint keys in a random slot after the last key, so concurrent appends never share a key and a batch stays contiguous. Positions are left best-effort and may repeat; the run dispatcher finishes a tied position before advancing its cursor. Positional inserts skip tied keys. Concurrent replaces stay serialized by the table's unique lock, which every replace already takes.
…ub the job queue locally
TheodoreSpeaks
force-pushed
the
fix/drop-row-order-lock
branch
from
October 8, 2026 22:13
1329fb9 to
f334574
Compare
4 of 5 tasks
5 of 10 tasks
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
user_table_rows_pos). It was held until commit, so one insert stuck waiting on synchronous replication made every other insert to that table wait behind it and fail at the 3 slock_timeout. With fix(tables): log row writes to the change log instead of locking the table definition row #8765, a row write no longer holds any lock shared by the whole table.appendKeysmints inside the integer range after the last key, narrowed to a random sub-range (32 random halvings). Two appends that read the same last key never collide, a batch stays contiguous instead of interleaving with another writer's, and keys don't grow across appends (8–9 characters after 2,000 sequential appends).max + 1, read without a lock, so concurrent appends can share one. The run dispatcher pages on(position, id). When a window is full, it also takes the remaining rows at the last position, so a tie split across windows is never skipped. No schema or API change: the cursor is still the last position processed.a >= b. A position past the last row now appends; it used to minta0and land the row near the top.lockUniqueValuesalready serializes same-value upserts before the lookup.lockUniqueColumns, which every replace takes exclusively, even on tables with no unique columns. An insert that commits during a replace survives it, the same outcome as running right after it.order_keybackfill script migration and the collation repair script still take the old lock. Neither concurrent appends nor these scripts are protected by it any more; the scripts only rewrite tables without valid keys.Benchmark
Local Postgres, 48 concurrent writers on one table through the real row services, 10 s per scenario, with a 20 ms commit delay per transaction to stand in for the replication wait (locks still held). Successful ops/s, p99, failures:
Live row count matched
COUNT(*)in every run. Absolute numbers vary between runs; read the columns relative to each other.Type of Change
Testing
New integration tests, each red on the pre-change code:
dispatcher.integration.ts): rows that share positions across a window boundary each run exactly once. Before: tied rows skipped.The unique-value race tests used the order lock to pause inserts mid-flight. They now pause on a definition row held
FOR UPDATE, which an insert's foreign-key check waits on after its unique check. The obsolete lock-order unit tests are removed.Table + TTL integration suites: migrated 161 passed, push-provisioned 131 passed. Table unit tests 987 passed.
lint:checkandcheck:auditspass.Checklist
🤖 Generated with Claude Code
https://claude.ai/code/session_01CJxC2fgucGVpT59RV5Z7xv