summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@mongodb.com>2017-08-17 14:04:31 +1000
committerAlex Gorrod <alexander.gorrod@mongodb.com>2017-08-17 14:04:31 +1000
commit2a2efab3a69df3979e88c2fe424d512c19b420d6 (patch)
treec88f05e38d8387307518a565a2ebe03d4db6f73f
parent146ad045334f9f0f4b951b92971da40ed1c4232f (diff)
downloadmongo-2a2efab3a69df3979e88c2fe424d512c19b420d6.tar.gz
WT-3465 Avoid locks when reading 8-byte timestamps. (#3589)
-rw-r--r--src/include/txn.h1
-rw-r--r--src/include/txn.i13
-rw-r--r--src/txn/txn.c18
-rw-r--r--src/txn/txn_rollback_to_stable.c19
-rw-r--r--src/txn/txn_timestamp.c16
5 files changed, 33 insertions, 34 deletions
diff --git a/src/include/txn.h b/src/include/txn.h
index f3e377b3380..e0513a82892 100644
--- a/src/include/txn.h
+++ b/src/include/txn.h
@@ -69,7 +69,6 @@ struct __wt_named_snapshot {
struct __wt_txn_state {
WT_CACHE_LINE_PAD_BEGIN
- WT_RWLOCK rwlock;
volatile uint64_t id;
volatile uint64_t pinned_id;
volatile uint64_t metadata_pinned;
diff --git a/src/include/txn.i b/src/include/txn.i
index df0bd872a6c..b37163bd78f 100644
--- a/src/include/txn.i
+++ b/src/include/txn.i
@@ -11,6 +11,8 @@ static inline void __wt_txn_read_last(WT_SESSION_IMPL *session);
#ifdef HAVE_TIMESTAMPS
#if WT_TIMESTAMP_SIZE == 8
+#define WT_WITH_TIMESTAMP_READLOCK(session, l, e) e
+
/*
* __wt_timestamp_cmp --
* Compare two timestamps.
@@ -61,6 +63,12 @@ __wt_timestamp_set_zero(wt_timestamp_t *ts)
ts->val = 0;
}
#else
+#define WT_WITH_TIMESTAMP_READLOCK(s, l, e) do { \
+ __wt_readlock((s), (l)); \
+ e; \
+ __wt_readunlock((s), (l)); \
+} while (0)
+
/*
* __wt_timestamp_cmp --
* Compare two timestamps.
@@ -314,9 +322,8 @@ __wt_txn_visible_all(
if (!txn_global->has_pinned_timestamp || timestamp == NULL)
return (true);
- __wt_readlock(session, &txn_global->rwlock);
- cmp = __wt_timestamp_cmp(timestamp, &txn_global->pinned_timestamp);
- __wt_readunlock(session, &txn_global->rwlock);
+ WT_WITH_TIMESTAMP_READLOCK(session, &txn_global->rwlock,
+ cmp = __wt_timestamp_cmp(timestamp, &txn_global->pinned_timestamp));
/*
* We can discard updates with timestamps less than or equal to the
diff --git a/src/txn/txn.c b/src/txn/txn.c
index 2aec962d885..09efb2924bf 100644
--- a/src/txn/txn.c
+++ b/src/txn/txn.c
@@ -445,12 +445,11 @@ __wt_txn_config(WT_SESSION_IMPL *session, const char *cfg[])
WT_RET(__wt_txn_parse_timestamp(
session, "read", &txn->read_timestamp, &cval));
- __wt_readlock(session, &txn_global->rwlock);
- __wt_timestamp_set(
- &oldest_timestamp, &txn_global->oldest_timestamp);
- __wt_timestamp_set(
- &stable_timestamp, &txn_global->stable_timestamp);
- __wt_readunlock(session, &txn_global->rwlock);
+ WT_WITH_TIMESTAMP_READLOCK(session, &txn_global->rwlock,
+ __wt_timestamp_set(
+ &oldest_timestamp, &txn_global->oldest_timestamp);
+ __wt_timestamp_set(
+ &stable_timestamp, &txn_global->stable_timestamp));
if (__wt_timestamp_cmp(
&txn->read_timestamp, &oldest_timestamp) < 0)
WT_RET_MSG(session, EINVAL,
@@ -743,10 +742,9 @@ __wt_txn_commit(WT_SESSION_IMPL *session, const char *cfg[])
#ifdef HAVE_TIMESTAMPS
/* First check if we've already committed something in the future. */
if (update_timestamp) {
- __wt_readlock(session, &txn_global->rwlock);
- __wt_timestamp_set(
- &prev_commit_timestamp, &txn_global->commit_timestamp);
- __wt_readunlock(session, &txn_global->rwlock);
+ WT_WITH_TIMESTAMP_READLOCK(session, &txn_global->rwlock,
+ __wt_timestamp_set(
+ &prev_commit_timestamp, &txn_global->commit_timestamp));
update_timestamp = __wt_timestamp_cmp(
&txn->commit_timestamp, &prev_commit_timestamp) > 0;
}
diff --git a/src/txn/txn_rollback_to_stable.c b/src/txn/txn_rollback_to_stable.c
index c9c3d3247c4..e19bbc73bb3 100644
--- a/src/txn/txn_rollback_to_stable.c
+++ b/src/txn/txn_rollback_to_stable.c
@@ -38,9 +38,9 @@ __txn_rollback_to_stable_lookaside_fixup(WT_SESSION_IMPL *session)
* violate protocol.
*/
txn_global = &conn->txn_global;
- __wt_readlock(session, &txn_global->rwlock);
- __wt_timestamp_set(&rollback_timestamp, &txn_global->stable_timestamp);
- __wt_readunlock(session, &txn_global->rwlock);
+ WT_WITH_TIMESTAMP_READLOCK(session, &txn_global->rwlock,
+ __wt_timestamp_set(
+ &rollback_timestamp, &txn_global->stable_timestamp));
__wt_las_cursor(session, &cursor, &session_flags);
@@ -347,9 +347,9 @@ __txn_rollback_to_stable_btree(
* updated while rolling back, accessing it without a lock would
* violate protocol.
*/
- __wt_readlock(session, &txn_global->rwlock);
- __wt_timestamp_set(&rollback_timestamp, &txn_global->stable_timestamp);
- __wt_readunlock(session, &txn_global->rwlock);
+ WT_WITH_TIMESTAMP_READLOCK(session, &txn_global->rwlock,
+ __wt_timestamp_set(
+ &rollback_timestamp, &txn_global->stable_timestamp));
/*
* Ensure the eviction server is out of the file - we don't
@@ -373,13 +373,10 @@ static int
__txn_rollback_to_stable_check(WT_SESSION_IMPL *session)
{
WT_TXN_GLOBAL *txn_global;
- bool stable_set, txn_active;
+ bool txn_active;
txn_global = &S2C(session)->txn_global;
- __wt_readlock(session, &txn_global->rwlock);
- stable_set = !__wt_timestamp_iszero(&txn_global->stable_timestamp);
- __wt_readunlock(session, &txn_global->rwlock);
- if (!stable_set)
+ if (!txn_global->has_stable_timestamp)
WT_RET_MSG(session, EINVAL,
"rollback_to_stable requires a stable timestamp");
diff --git a/src/txn/txn_timestamp.c b/src/txn/txn_timestamp.c
index a947a0167ef..275ef941490 100644
--- a/src/txn/txn_timestamp.c
+++ b/src/txn/txn_timestamp.c
@@ -196,10 +196,9 @@ __txn_global_query_timestamp(
if (WT_STRING_MATCH("all_committed", cval.str, cval.len)) {
if (!txn_global->has_commit_timestamp)
return (WT_NOTFOUND);
- __wt_readlock(session, &txn_global->rwlock);
- __wt_timestamp_set(&ts, &txn_global->commit_timestamp);
+ WT_WITH_TIMESTAMP_READLOCK(session, &txn_global->rwlock,
+ __wt_timestamp_set(&ts, &txn_global->commit_timestamp));
WT_ASSERT(session, !__wt_timestamp_iszero(&ts));
- __wt_readunlock(session, &txn_global->rwlock);
/* Compare with the oldest running transaction. */
__wt_readlock(session, &txn_global->commit_timestamp_rwlock);
@@ -234,9 +233,8 @@ __txn_global_query_timestamp(
} else if (WT_STRING_MATCH("stable", cval.str, cval.len)) {
if (!txn_global->has_stable_timestamp)
return (WT_NOTFOUND);
- __wt_readlock(session, &txn_global->rwlock);
- __wt_timestamp_set(&ts, &txn_global->stable_timestamp);
- __wt_readunlock(session, &txn_global->rwlock);
+ WT_WITH_TIMESTAMP_READLOCK(session, &txn_global->rwlock,
+ __wt_timestamp_set(&ts, &txn_global->stable_timestamp));
} else
WT_RET_MSG(session, EINVAL,
"unknown timestamp query %.*s", (int)cval.len, cval.str);
@@ -290,9 +288,9 @@ __wt_txn_update_pinned_timestamp(WT_SESSION_IMPL *session)
if (txn_global->oldest_is_pinned)
return (0);
- __wt_readlock(session, &txn_global->rwlock);
- __wt_timestamp_set(&oldest_timestamp, &txn_global->oldest_timestamp);
- __wt_readunlock(session, &txn_global->rwlock);
+ WT_WITH_TIMESTAMP_READLOCK(session, &txn_global->rwlock,
+ __wt_timestamp_set(
+ &oldest_timestamp, &txn_global->oldest_timestamp));
/* Scan to find the global pinned timestamp. */
if ((ret = __txn_global_query_timestamp(