-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: Cursors
-
Security Level: Public (Available to anyone on the web)
-
Storage Engines - Foundations
-
351.339
-
None
-
None
Issue Summary
The __curstat_size_only function in src/schema/schema_stat.c implements a fast path for statistics:table: cursors, avoiding schema and table list locks by directly stat-ing the underlying file. However, a TOCTOU race exists between the two filesystem calls:
WT_ERR(__wt_fs_exist(session, namebuf.data, &exist)); // stat() → true if (exist) { WT_ERR(__wt_fs_size(session, namebuf.data, &filesize)); // stat() → ENOENT if drop races }
If a concurrent table drop unlinks the file between _wt_fs_exist and wt_fs_size, the second stat() returns ENOENT. Contrary to the comment at line 93, this failure does not result in falling back to the slow path. Instead, WT_ERR propagates the error out of curstat_size_only, and WT_RET in the caller _wt_curstat_table_init returns it immediately, so the slow path at line 145 is never reached. The error surfaces as a hard failure to callers of open_cursor("statistics:table:X").
Context
- The race is present in both standard and disaggregated storage modes.
- In disaggregated mode, a separate bug causes table: URI creation to incorrectly produce a bare .wt file (tracked elsewhere), increasing the likelihood of this race.
Proposed Solution
- Replace WT_ERR(__wt_fs_size(...)) with an explicit check that resets ret to 0 on any error and jumps to err:, leaving was_fast = false so the caller proceeds to the slow path as intended.
Original Slack thread: Slack Thread
This ticket was generated by AI from a Slack thread.
- related to
-
WT-17301 Investigate why we are having .wt files in a disagg mdb run
-
- Open
-