From 2a582f3d252c8011fa5f3b95359c07f83b7c437e Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Tue, 3 Nov 2026 20:52:32 -0500 Subject: [PATCH] mp: an SSI abort while dirtying a page is not an error to report __memp_dirty, upgrading a snapshot page to a writable copy, refetches the page with __memp_fget. For a snapshot-safe txn that fetch can return DB_SNAPSHOT_CONFLICT (SSI mechanism (b) in __memp_si_rwconflict). __memp_dirty skipped "BDB3010 error getting a page for writing" only for DB_LOCK_DEADLOCK, so every such SSI abort also printed that message, though the caller aborts the txn normally and nothing is lost. It shows up after the SSI write-skew fixes, which raise the abort rate on contended workloads. ssi_livelock on FreeBSD 14.5 x86_64 printed it 30-89 times in 3 s; every txn that printed it returned DB_SNAPSHOT_CONFLICT or DB_SNAPSHOT_UNSAFE and aborted, and no txn returned any other code. Skip the message for the two SSI codes as for a deadlock. The return value is unchanged. --- src/mp/mp_fset.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/mp/mp_fset.c b/src/mp/mp_fset.c index 654b0764f7..2afdbd8890 100644 --- a/src/mp/mp_fset.c +++ b/src/mp/mp_fset.c @@ -87,7 +87,13 @@ __memp_dirty(dbmfp, addrp, ip, txn, priority, flags) } if ((ret = __memp_fget(dbmfp, &pgno, ip, txn, flags, addrp)) != 0) { - if (ret != DB_LOCK_DEADLOCK) + /* + * A deadlock or an SSI abort is an ordinary outcome the + * caller resolves by aborting the txn; only report a real + * failure to get the page. + */ + if (ret != DB_LOCK_DEADLOCK && + ret != DB_SNAPSHOT_CONFLICT && ret != DB_SNAPSHOT_UNSAFE) __db_errx(env, DB_STR_A("3010", "%s: error getting a page for writing", "%s"), __memp_fn(dbmfp));