diff options
Diffstat (limited to 'src/third_party/wiredtiger/src/include/txn_inline.h')
-rw-r--r-- | src/third_party/wiredtiger/src/include/txn_inline.h | 82 |
1 files changed, 53 insertions, 29 deletions
diff --git a/src/third_party/wiredtiger/src/include/txn_inline.h b/src/third_party/wiredtiger/src/include/txn_inline.h index 629906d8ef1..0433a252d63 100644 --- a/src/third_party/wiredtiger/src/include/txn_inline.h +++ b/src/third_party/wiredtiger/src/include/txn_inline.h @@ -71,24 +71,32 @@ static inline void __wt_txn_timestamp_flags(WT_SESSION_IMPL *session) { WT_BTREE *btree; + WT_DATA_HANDLE *dhandle; - if (session->dhandle == NULL) + dhandle = session->dhandle; + if (dhandle == NULL) return; btree = S2BT(session); if (btree == NULL) return; - if (FLD_ISSET(btree->assert_flags, WT_ASSERT_COMMIT_TS_ALWAYS)) - F_SET(session->txn, WT_TXN_TS_COMMIT_ALWAYS); - if (FLD_ISSET(btree->assert_flags, WT_ASSERT_COMMIT_TS_KEYS)) - F_SET(session->txn, WT_TXN_TS_COMMIT_KEYS); - if (FLD_ISSET(btree->assert_flags, WT_ASSERT_COMMIT_TS_NEVER)) - F_SET(session->txn, WT_TXN_TS_COMMIT_NEVER); - if (FLD_ISSET(btree->assert_flags, WT_ASSERT_DURABLE_TS_ALWAYS)) - F_SET(session->txn, WT_TXN_TS_DURABLE_ALWAYS); - if (FLD_ISSET(btree->assert_flags, WT_ASSERT_DURABLE_TS_KEYS)) - F_SET(session->txn, WT_TXN_TS_DURABLE_KEYS); - if (FLD_ISSET(btree->assert_flags, WT_ASSERT_DURABLE_TS_NEVER)) - F_SET(session->txn, WT_TXN_TS_DURABLE_NEVER); + + if (!FLD_ISSET(dhandle->ts_flags, WT_DHANDLE_ASSERT_TS_WRITE)) + return; + + if (FLD_ISSET(dhandle->ts_flags, WT_DHANDLE_TS_ALWAYS)) + F_SET(session->txn, WT_TXN_TS_WRITE_ALWAYS); + if (FLD_ISSET(dhandle->ts_flags, WT_DHANDLE_TS_KEY_CONSISTENT)) + F_SET(session->txn, WT_TXN_TS_WRITE_KEY_CONSISTENT); + if (FLD_ISSET(dhandle->ts_flags, WT_DHANDLE_TS_MIXED_MODE)) + F_SET(session->txn, WT_TXN_TS_WRITE_MIXED_MODE); + if (FLD_ISSET(dhandle->ts_flags, WT_DHANDLE_TS_NEVER)) + F_SET(session->txn, WT_TXN_TS_WRITE_NEVER); + if (FLD_ISSET(dhandle->ts_flags, WT_DHANDLE_TS_ORDERED)) + F_SET(session->txn, WT_TXN_TS_WRITE_ORDERED); + + /* Remember if any type of verbose tracking is encountered by the transaction. */ + if (FLD_ISSET(dhandle->ts_flags, WT_DHANDLE_VERB_TS_WRITE)) + F_SET(session->txn, WT_TXN_VERB_TS_WRITE); } /* @@ -836,7 +844,7 @@ __wt_txn_read_upd_list( WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_UPDATE *upd, WT_UPDATE **prepare_updp) { WT_VISIBLE_TYPE upd_visible; - uint8_t type; + uint8_t prepare_state, type; if (prepare_updp != NULL) *prepare_updp = NULL; @@ -848,6 +856,7 @@ __wt_txn_read_upd_list( if (type == WT_UPDATE_RESERVE) continue; + WT_ORDERED_READ(prepare_state, upd->prepare_state); /* * If the cursor is configured to ignore tombstones, copy the timestamps from the tombstones * to the stop time window of the update value being returned to the caller. Caller can @@ -860,8 +869,8 @@ __wt_txn_read_upd_list( cbt->upd_value->tw.durable_stop_ts = upd->durable_ts; cbt->upd_value->tw.stop_ts = upd->start_ts; cbt->upd_value->tw.stop_txn = upd->txnid; - cbt->upd_value->tw.prepare = upd->prepare_state == WT_PREPARE_INPROGRESS || - upd->prepare_state == WT_PREPARE_LOCKED; + cbt->upd_value->tw.prepare = + prepare_state == WT_PREPARE_INPROGRESS || prepare_state == WT_PREPARE_LOCKED; continue; } @@ -870,18 +879,20 @@ __wt_txn_read_upd_list( if (upd_visible == WT_VISIBLE_TRUE) break; + /* + * Save the prepared update to help us detect if we race with prepared commit or rollback + * irrespective of update visibility. + */ + if ((prepare_state == WT_PREPARE_INPROGRESS || prepare_state == WT_PREPARE_LOCKED) && + prepare_updp != NULL && *prepare_updp == NULL && + F_ISSET(upd, WT_UPDATE_PREPARE_RESTORED_FROM_DS)) + *prepare_updp = upd; + if (upd_visible == WT_VISIBLE_PREPARE) { /* Ignore the prepared update, if transaction configuration says so. */ - if (F_ISSET(session->txn, WT_TXN_IGNORE_PREPARE)) { - /* - * Save the prepared update to help us detect if we race with prepared commit or - * rollback. - */ - if (prepare_updp != NULL && *prepare_updp == NULL && - F_ISSET(upd, WT_UPDATE_PREPARE_RESTORED_FROM_DS)) - *prepare_updp = upd; + if (F_ISSET(session->txn, WT_TXN_IGNORE_PREPARE)) continue; - } + return (WT_PREPARE_CONFLICT); } } @@ -992,9 +1003,11 @@ retry: } /* If there's no visible update in the update chain or ondisk, check the history store file. */ - if (F_ISSET(S2C(session), WT_CONN_HS_OPEN) && !F_ISSET(S2BT(session), WT_BTREE_HS)) + if (F_ISSET(S2C(session), WT_CONN_HS_OPEN) && !F_ISSET(S2BT(session), WT_BTREE_HS)) { + __wt_timing_stress(session, WT_TIMING_STRESS_HS_SEARCH); WT_RET(__wt_hs_find_upd(session, key, cbt->iface.value_format, recno, cbt->upd_value, false, &cbt->upd_value->buf, &tw)); + } /* * Retry if we race with prepared commit or rollback. If we race with prepared rollback, the @@ -1209,10 +1222,10 @@ __wt_txn_search_check(WT_SESSION_IMPL *session) * Same if it should never have a read timestamp. */ if (!F_ISSET(S2C(session), WT_CONN_RECOVERING) && - FLD_ISSET(btree->assert_flags, WT_ASSERT_READ_TS_ALWAYS) && + FLD_ISSET(btree->dhandle->ts_flags, WT_DHANDLE_ASSERT_TS_READ_ALWAYS) && !F_ISSET(txn, WT_TXN_SHARED_TS_READ)) WT_RET_MSG(session, EINVAL, "read_timestamp required and none set on this transaction"); - if (FLD_ISSET(btree->assert_flags, WT_ASSERT_READ_TS_NEVER) && + if (FLD_ISSET(btree->dhandle->ts_flags, WT_DHANDLE_ASSERT_TS_READ_NEVER) && F_ISSET(txn, WT_TXN_SHARED_TS_READ)) WT_RET_MSG( session, EINVAL, "no read_timestamp required and timestamp set on this transaction"); @@ -1224,7 +1237,8 @@ __wt_txn_search_check(WT_SESSION_IMPL *session) * Check if the current transaction can update an item. */ static inline int -__wt_txn_update_check(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_UPDATE *upd) +__wt_txn_update_check( + WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_UPDATE *upd, wt_timestamp_t *prev_tsp) { WT_DECL_RET; WT_TIME_WINDOW tw; @@ -1277,6 +1291,16 @@ __wt_txn_update_check(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_UPDATE ret = __wt_txn_rollback_required(session, "conflict between concurrent operations"); } + if (prev_tsp != NULL && upd != NULL) { + /* + * The durable timestamp must be greater than or equal to the commit timestamp unless it is + * an in-progress prepared update. + * + * FIXME-WT-7020: We should be able to assert this but we're seeing some fallout in format. + * We should investigate why and assert the above statement. + */ + *prev_tsp = upd->durable_ts; + } if (ignore_prepare_set) F_SET(txn, WT_TXN_IGNORE_PREPARE); return (ret); |