Unlocked WT_DHANDLE_OUTDATED flag update in __wti_conn_dhandle_outdated races dhandle close

XMLWordPrintableJSON

    • Storage Engines - Foundations
    • 336.213
    • None
    • None

      Problem

      __wti_conn_dhandle_outdated() sets WT_DHANDLE_OUTDATED on a dhandle while holding only the handle-list read lock and a handle reference - no dhandle lock.
      dhandle->flags updates are plain non-atomic read-modify-writes, so this store races writers that update the same flags word under the dhandle write lock: __wt_conn_dhandle_close() (F_SET(WT_DHANDLE_DEAD), F_CLR(WT_DHANDLE_OPEN)) and the sweep expire path.
      Either side's bit can be lost or a cleared bit resurrected.

      This is a real issue: __wti_conn_dhandle_outdated() runs on every follower checkpoint pickup, concurrent with sweep expiring OUTDATED handles on a 5-second grace period.

      Impact

      A lost WT_DHANDLE_DEAD or resurrected WT_DHANDLE_OPEN bit breaks the invariants the find/expire/discard protocol relies on, allowing a closed or destroyed handle to be treated as live.

      Suggested fix

      • Take the dhandle write lock around the flag update in __wti_conn_dhandle_outdated() (rare path, cost irrelevant) and skip WT_DHANDLE_DEAD handles.
      • Hardening, same lifetime-fragility family: __wt_schema_close_layered() frees and NULLs layered->key_format / value_format / ingest_uri / stable_uri on every close, while readers dereference them with no protection beyond the handle appearing open. The fields are re-derived identically on reopen; keep them until __wt_schema_destroy_layered().

            Assignee:
            Ivan Kochin
            Reporter:
            Yury Ershov
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: