-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: Layered Tables
-
None
-
Storage Engines - Foundations
-
184.344
-
None
-
None
The step-down walk clears WT_LAYERED_TABLE_STEP_DOWN_CREATED (conn_layered.c:1269) before it publishes the follower role (conn_layered.c:1306). A cursor operation reads the role first and the flag second, so an operation racing the walk can observe the stale leader role together with the already-cleared flag. In a transaction that began before the step-down timestamp was set (txn->stepdown_ts_set == false), none of the ingest-routing conditions in __clayered_enter_flags then hold: not a follower, no per-transaction timestamp mark, no STEP_DOWN_CREATED flag. The operation gets no ingest cursor, and the stable open fails because a step-down-created table has no stable constituent (the failure is correctly ignored by __clayered_ignore_missing_stable).
The lookup then runs with neither constituent and trips the diagnostic assertion in __clayered_lookup (cur_layered.c:2422):
__clayered_lookup, 2422: WiredTiger assertion failed: 'op->stable != ((void *)0)' __wt_abort, 29: aborting WiredTiger library
The reader is fully within contract: an explicit snapshot read transaction is allowed to continue across a step-down. Every read it makes on this table should simply return WT_NOTFOUND — the table was created after its snapshot, so nothing in ingest is visible to it — and that is exactly what release builds return through the lazy-open path. Diagnostic builds abort the node instead.
Possible fixes:
- Remove the assertion and check that every clayered read function works with no constituent at all.
- Return WT_ROLLBACK when the stable constituent is found missing and a role shift is observed.
- Retry __clayered_enter so the operation resolves the current role.
- related to
-
WT-18259 Investigate reads racing an async step-down against the stable table being marked read-only and outdated
-
- Closed
-