Skip to content

[2026.10.7] Backport: SSI cross-leaf write-skew fix - #247

Closed
gburd wants to merge 2 commits into
lts/2026.10.7from
backport/2026.10.7/ssi-crosspage
Closed

gburd wants to merge 2 commits into
lts/2026.10.7from
backport/2026.10.7/ssi-crosspage

Conversation

@gburd

@gburd gburd commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator

[2026.10.7] Backport: SSI cross-leaf write-skew fix

Backport of the SSI serializability fix from master (PR #246) to the LTS line.

The bug

On a multi-level B-tree, DB_TXN_SERIALIZABLE silently admitted a write
skew
between records on different leaf pages (both transactions committed a
non-serializable history, no error). Reproduced on this LTS line by the lead and
by test/isolation/ssi_multiread_skew. Root cause: __lock_get_internal's SSI
SIREAD scan dropped a transaction's own SIREAD marker when it write-locked a
page it had only read a different key on (page-granularity). Fix: keep the
marker, skip it for self-conflict.

Cherry-pick

(cherry picked from commit cced5c481a3cbc89e5e3ce135de82bdd22f17ea4)

One hunk in src/lock/lock.c. No region/ABI/on-disk/log format change; nothing
frozen moves.

LTS gates

  • L1 (region signature unchanged): base 0xe67a9de8 == fixed 0xe67a9de8
    (Debian, identical --enable-diagnostic --enable-test --enable-tcl configure,
    same host).
  • L2 (handle sizes / .text): run_handle_sizes.sh PASS (6/6); .text
    differs only in lock.o (36007 → 35655), the one fixed object.
  • L3 (FAIL-before / PASS-after): ssi_multiread_skew → 40/40 skews on the
    base tag, 0/40 with the fix, at every B-tree depth and both timings.
  • L4 (cherry-pick trailer): present (above).
  • Gate 8 (soak — the fix touches SIREAD marker lifetime): PASS, resources
    within tolerance.
  • Isolation tier run.sh green (scenarios 0-unexpected at both levels × both
    partition counts; cross-leaf gate 0/40 at both partition counts; GC-pressure;
    crash-pivot).

Draft — for lead review and merge.

libdb-agent added 2 commits November 2, 2026 19:19
…page

Fixes a silent write-skew miss under DB_TXN_SERIALIZABLE: on a multi-level
B-tree, two transactions whose read and write records sit on different leaves
could both commit a non-serializable history, with no error returned.

Root cause: __lock_get_internal's SIREAD scan had a branch that, when a writer
write-locked an object on which it already held its OWN SIREAD marker, REMOVED
that marker ("upgrading my own read to a write"). Conflict detection is at PAGE
granularity, so holding a WRITE lock on a page does NOT mean the transaction
wrote the record it had read there: a point update of key X write-locks X's
leaf, and the B-tree write descent can also write-lock a different leaf that
carries the transaction's SIREAD from an earlier read of key Y. Dropping that
marker erased the record of "this transaction read key Y", so a later writer of
Y's page by another transaction found no marker and never recorded the
rw-antidependency -- both transactions committed a write skew.

Fix: keep the transaction's own SIREAD marker and merely skip it for
self-conflict purposes (a transaction never forms an rw-edge with itself). The
marker persists exactly like any committed reader's and is reclaimed by the
normal GC (__lock_sicommit at commit, __lock_siclean_obj once its snapshot is no
longer visible), which also balances si_ref -- so the issue-#137 accounting the
old eager drop maintained is preserved by the ordinary path, not lost.

FAIL-before / PASS-after gate: test/isolation/ssi_multiread_skew (0/40 skews at
every tree depth and timing after this change; 20-40/40 before). No format/ABI
change. Backport candidate for lts/2026.10.7.

Workstream S1.

(cherry picked from commit cced5c4)
Add test/isolation/ssi_multiread_skew.c (the deterministic FAIL-before/
PASS-after gate for the cross-leaf SSI write-skew fix) and wire it into the
isolation tier's SSI gates and test/MANIFEST. It must PASS at every B-tree
depth and both commit timings.

Companion to the cherry-picked engine fix on this branch.
@github-actions

github-actions Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Coccinelle convention checks

No new violations. ✅

Resolved since baseline (3) -- update dist/cocci/baseline.txt to lock these in.
rule_mutex_unbalanced|MUTEX_UNBALANCED|src/btree/bt_curadj.c|return (ret);
rule_mutex_unbalanced|MUTEX_UNBALANCED|src/crypto/mersenne/mt19937db.c|return (ret);
rule_mutex_unbalanced|MUTEX_UNBALANCED|src/mp/mp_register.c|return (ret);

@github-actions

github-actions Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

ABI diff vs v2026.10.7.1 (libabigail — authoritative)

abidiff exit bitmask: 0

Removed exported symbols (nm -D, _NNNN version suffix normalized)

None.


Advisory: libabigail/nm is the authoritative binary-ABI check; Coccinelle is complementary source-level early warning. See dist/cocci/README.md.

@gburd

gburd commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator Author

Lead: see #246. The lock.c fix is good to backport, but the second SSI miss, write skew with many records per leaf, is pre-existing on this line too. Hold this PR until S2 lands the second fix, so LTS ships both together.

gburd added a commit that referenced this pull request Nov 3, 2026
Update the qualification verdict now that the second miss is fixed:
- verdict -> production-ready on B-tree (both the cross-leaf miss and the
  lazy-read_lsn / skipped-scan second miss are closed);
- deliverable (a) -> PASS, with the before/after cycle-checker numbers and the
  note that the old CYC_VALPAD=1500 default hid the bug (overflow values put
  every key on one leaf);
- false-abort (d): state the cost plainly -- realistic multi-leaf ~1.0% -> ~2.4%
  (genuine edges the old code missed), dense single-leaf high but all legitimate;
  the fix rests on page-granularity MVCC only ever ADDING aborts;
- #247 (cross-leaf-only LTS backport) is superseded by the combined LTS backport.
@gburd

gburd commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator Author

Superseded by #258.

This PR backported only the cross-leaf write-skew fix (cced5c481). The lead's review of #246 found a second, distinct SSI write-skew miss, also pre-existing on this LTS line. #258 is the single backport branch (backport/2026.10.7/ssi-second-miss) that cherry-picks -x both the cross-leaf fix and the second-miss fix (boundary >=/< + the SIREAD scan on waited/re-granted/upgraded WRITE grants), with gates L1–L4 and soak all green.

Recommend closing this PR in favour of #258. (Leaving the branch for the lead to close/delete per the backport cleanup rule.)

@gburd

gburd commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator Author

Superseded by #258, which carries this PR's lock.c fix (cherry-picked with -x) plus the second-miss and livelock fixes and their progress gates.

@gburd gburd closed this Nov 3, 2026
gburd added a commit that referenced this pull request Nov 3, 2026
…-miss

[2026.10.7] Backport: SSI write-skew fixes (both misses) — supersedes #247
@gburd
gburd deleted the backport/2026.10.7/ssi-crosspage branch November 4, 2026 03:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant