summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/include/txn_inline.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/wiredtiger/src/include/txn_inline.h')
-rw-r--r--src/third_party/wiredtiger/src/include/txn_inline.h82
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);