diff options
author | Alex Gorrod <alexander.gorrod@mongodb.com> | 2015-07-01 17:58:06 +1000 |
---|---|---|
committer | Michael Cahill <michael.cahill@mongodb.com> | 2015-07-02 13:37:37 +1000 |
commit | 7a9e1bdade725fd59a0fd87ca77c7dd66aeba1ec (patch) | |
tree | caa348cb25b880993b55a4e6efa599c173de4a11 /src/include | |
parent | 9f72da7968f828753276aaf92afbb0c82f75a3b4 (diff) | |
download | mongo-7a9e1bdade725fd59a0fd87ca77c7dd66aeba1ec.tar.gz |
WT-1982 Fix a window where reconciliation could go back in transaction time.
(cherry picked from commit cd1704d6c4d84c5db8ae6b471c658945ffa226f9)
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/btmem.h | 5 | ||||
-rw-r--r-- | src/include/txn.h | 5 | ||||
-rw-r--r-- | src/include/txn.i | 30 |
3 files changed, 22 insertions, 18 deletions
diff --git a/src/include/btmem.h b/src/include/btmem.h index 77ad31fc3f6..23b17ef2cd3 100644 --- a/src/include/btmem.h +++ b/src/include/btmem.h @@ -194,6 +194,11 @@ struct __wt_page_modify { /* The largest update transaction ID (approximate). */ uint64_t update_txn; +#ifdef HAVE_DIAGNOSTIC + /* Check that transaction time moves forward. */ + uint64_t last_oldest_id; +#endif + /* Dirty bytes added to the cache. */ size_t bytes_dirty; diff --git a/src/include/txn.h b/src/include/txn.h index dbaa11309ab..d2b369a41c4 100644 --- a/src/include/txn.h +++ b/src/include/txn.h @@ -25,6 +25,9 @@ #define WT_SESSION_TXN_STATE(s) (&S2C(s)->txn_global.states[(s)->id]) +#define WT_SESSION_IS_CHECKPOINT(s) \ + ((s)->id != 0 && (s)->id == S2C(s)->txn_global.checkpoint_id) + struct WT_COMPILER_TYPE_ALIGN(WT_CACHE_LINE_ALIGNMENT) __wt_txn_state { volatile uint64_t id; volatile uint64_t snap_min; @@ -54,7 +57,7 @@ struct __wt_txn_global { */ volatile uint32_t checkpoint_id; /* Checkpoint's session ID */ volatile uint64_t checkpoint_gen; - volatile uint64_t checkpoint_snap_min; + volatile uint64_t checkpoint_pinned; WT_TXN_STATE *states; /* Per-session transaction states */ }; diff --git a/src/include/txn.i b/src/include/txn.i index f0b0534ff4a..a9b19ca1ff5 100644 --- a/src/include/txn.i +++ b/src/include/txn.i @@ -98,8 +98,8 @@ __wt_txn_oldest_id(WT_SESSION_IMPL *session) { WT_BTREE *btree; WT_TXN_GLOBAL *txn_global; - uint64_t checkpoint_snap_min, oldest_id; - uint32_t checkpoint_id; + uint64_t checkpoint_pinned, oldest_id; + uint32_t checkpoint_gen; txn_global = &S2C(session)->txn_global; btree = S2BT_SAFE(session); @@ -108,9 +108,9 @@ __wt_txn_oldest_id(WT_SESSION_IMPL *session) * Take a local copy of these IDs in case they are updated while we are * checking visibility. */ - checkpoint_id = txn_global->checkpoint_id; - checkpoint_snap_min = txn_global->checkpoint_snap_min; - oldest_id = txn_global->oldest_id; + WT_ORDERED_READ(oldest_id, txn_global->oldest_id); + WT_ORDERED_READ(checkpoint_gen, txn_global->checkpoint_gen); + WT_ORDERED_READ(checkpoint_pinned, txn_global->checkpoint_pinned); /* * Checkpoint transactions often fall behind ordinary application @@ -122,17 +122,13 @@ __wt_txn_oldest_id(WT_SESSION_IMPL *session) * checkpoint, or this handle is up to date with the active checkpoint * then it's safe to ignore the checkpoint ID in the visibility check. */ - if (checkpoint_snap_min != WT_TXN_NONE && - checkpoint_id != session->id && (btree == NULL || - btree->checkpoint_gen != txn_global->checkpoint_gen) && - TXNID_LT(checkpoint_snap_min, oldest_id)) - /* - * Use the checkpoint ID for the visibility check if it is the - * oldest ID in the system. - */ - oldest_id = checkpoint_snap_min; + if (checkpoint_pinned == WT_TXN_NONE || + TXNID_LT(oldest_id, checkpoint_pinned) || + WT_SESSION_IS_CHECKPOINT(session) || + (btree != NULL && btree->checkpoint_gen == checkpoint_gen)) + return (oldest_id); - return (oldest_id); + return (checkpoint_pinned); } /* @@ -340,7 +336,7 @@ __wt_txn_id_check(WT_SESSION_IMPL *session) if (!F_ISSET(txn, TXN_HAS_ID)) { conn = S2C(session); txn_global = &conn->txn_global; - txn_state = &txn_global->states[session->id]; + txn_state = WT_SESSION_TXN_STATE(session); WT_ASSERT(session, txn_state->id == WT_TXN_NONE); @@ -432,7 +428,7 @@ __wt_txn_cursor_op(WT_SESSION_IMPL *session) txn = &session->txn; txn_global = &S2C(session)->txn_global; - txn_state = &txn_global->states[session->id]; + txn_state = WT_SESSION_TXN_STATE(session); /* * If there is no transaction running (so we don't have an ID), and no |