__txn_oldest_scan does not update oldest_session when last_running pins oldest_id

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Fixed
    • Priority: Minor - P4
    • WT12.0.0, 9.1.0-rc0
    • Affects Version/s: None
    • Component/s: Logging
    • None
    • Environment:
      GCC 13, Ubuntu 24.04
    • Storage Engines - Transactions
    • 264.291
    • None
    • 1

      During transaction table scanning, __txn_oldest_scan (txn.c line 407) calculates the global oldest transaction ID required (oldest_id) by finding the minimum of active running transaction IDs (last_running, tracked from s->id) and active read snapshot pinned IDs (s->pinned_id). While oldest_session is updated when scanning s->pinned_id < oldest_id inside the loop, the loop does not record the session associated with last_running. When last_running < oldest_id evaluates to true after the loop (line 477), oldest_id is updated to last_running, but oldest_session is not updated. If no session holds a pinned read snapshot, oldest_session remains NULL, causing __wt_txn_update_oldest (line 588) to silently evaluate oldest_session != NULL to false and suppress diagnostic verbose transaction logging (WT_VERB_TRANSACTION). Alternatively, if another session holds a higher pinned read snapshot, oldest_session points to the wrong session, falsely attributing the oldest transaction ID.

      For ReProduce;
      A catch2 unit test (test_txn_oldest_scan.cpp) reproduces the bug and verifies the fix. (I added before/after outputs on JIRA).
      In a scenario where Session 1 has an active write transaction ID (s->id) without an active read snapshot (s->pinned_id == WT_TXN_NONE), __txn_oldest_scan returns oldest_session == nullptr without the fix, causing CHECK(oldest_session == session1) to fail.
      With the fix, __txn_oldest_scan correctly identifies Session 1 and the test passes.

      Proposed Fix
      The fix tracks last_running_session alongside last_running during transaction array traversal in __txn_oldest_scan (txn.c), and assigns oldest_session = last_running_session; inside the if (last_running < oldest_id) block on line 478.

        1. after_fix_output.txt
          0.2 kB
        2. before_fix_output.txt
          0.9 kB

            Assignee:
            Kenan Ali
            Reporter:
            Tuna KARABACAK (EXT)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: