-
Type: Bug
-
Resolution: Fixed
-
Priority: Major - P3
-
Affects Version/s: None
-
Component/s: Transactions
-
Storage Engines
-
8
-
BermudaTriangle- 2023-09-05, TheMoon-StorEng - 2023-09-19, NachoCheese - 2023-10-03, Joker - StorEng - 2023-10-17, Asparagus-StorEng - 2023-10-31, c(3x10^8)-StorEng - 2023-11-14, 2023-11-28 - Anthill Tiger, 2023-12-12 - Heisenbug, 2024-01-09 - I Grew Tired
static inline bool __wt_txn_upd_visible_all(WT_SESSION_IMPL *session, WT_UPDATE *upd) { if (upd->prepare_state == WT_PREPARE_LOCKED || upd->prepare_state == WT_PREPARE_INPROGRESS) return (false); /* * This function is used to determine when an update is obsolete: that should take into account * the durable timestamp which is greater than or equal to the start timestamp. */ return (__wt_txn_visible_all(session, upd->txnid, upd->durable_ts)); }
Here we are not ensuring we always read the prepared state before reading the durable_ts by inserting a read barrier. It is possible the compiler and cpu reorders the read and reads a very old value for durable_ts before reading the prepared state. This can leads to data corruption by prematurely discarding the updates.
We should do a proper review of the code and fix it in other places to ensure we always read the prepared state before the timestamps.