diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2013-03-13 13:08:48 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2013-03-13 13:08:48 +1100 |
commit | 9b980cb70e04b766beaab510bcdee12ca0a375e4 (patch) | |
tree | 5e7cf16dc224ce38443beb2227aa815d5b2fe233 | |
parent | adb56742e2e9a88232c0dd215e8901a6a5ffc19a (diff) | |
download | mongo-9b980cb70e04b766beaab510bcdee12ca0a375e4.tar.gz |
Avoid polling global transaction state if nothing has changed.
-rw-r--r-- | src/btree/rec_track.c | 7 | ||||
-rw-r--r-- | src/include/txn.h | 5 | ||||
-rw-r--r-- | src/txn/txn.c | 54 |
3 files changed, 35 insertions, 31 deletions
diff --git a/src/btree/rec_track.c b/src/btree/rec_track.c index 92e98212b65..c01c87e609e 100644 --- a/src/btree/rec_track.c +++ b/src/btree/rec_track.c @@ -67,7 +67,7 @@ static int __rec_track_extend(WT_SESSION_IMPL *session, WT_PAGE *page) { WT_PAGE_MODIFY *mod; - size_t bytes_allocated; + size_t bytes_allocated, newlen; mod = page->modify; @@ -81,9 +81,10 @@ __rec_track_extend(WT_SESSION_IMPL *session, WT_PAGE *page) * page. */ bytes_allocated = mod->track_entries * sizeof(*mod->track); + newlen = WT_MAX(2 * mod->track_entries, mod->track_entries + 20); WT_RET(__wt_realloc(session, &bytes_allocated, - (mod->track_entries + 20) * sizeof(*mod->track), &mod->track)); - mod->track_entries += 20; + newlen * sizeof(*mod->track), &mod->track)); + mod->track_entries = newlen; return (0); } diff --git a/src/include/txn.h b/src/include/txn.h index 813ecfb793e..75a33f6924a 100644 --- a/src/include/txn.h +++ b/src/include/txn.h @@ -49,6 +49,7 @@ struct __wt_txn_state { struct __wt_txn_global { volatile wt_txnid_t current; /* Current transaction ID. */ + volatile uint32_t gen; /* Completed transaction genertion */ WT_TXN_STATE *states; /* Per-session transaction states */ }; @@ -79,6 +80,10 @@ struct __wt_txn { */ wt_txnid_t oldest_snap_min; + /* Saved global state, to avoid scans. */ + wt_txnid_t last_id; + uint32_t last_gen, last_oldest_gen; + /* * Arrays of txn IDs in WT_UPDATE or WT_REF structures created or * modified by this transaction. diff --git a/src/txn/txn.c b/src/txn/txn.c index 7ee269525e3..fb7eeb6742a 100644 --- a/src/txn/txn.c +++ b/src/txn/txn.c @@ -79,6 +79,12 @@ __wt_txn_get_oldest(WT_SESSION_IMPL *session) conn = S2C(session); txn = &session->txn; txn_global = &conn->txn_global; + + /* If nothing has changed since last time, we're done. */ + if (txn->last_oldest_gen == txn_global->gen) + return; + txn->last_oldest_gen = txn_global->gen; + oldest_snap_min = (txn->id != WT_TXN_NONE) ? txn->id : txn_global->current; @@ -114,9 +120,16 @@ __wt_txn_get_snapshot( txn_global = &conn->txn_global; txn_state = &txn_global->states[session->id]; + /* If nothing has changed since last time, we're done. */ + if (txn->last_id == txn_global->current && + txn->last_gen == txn_global->gen) + return; + do { /* Take a copy of the current session ID. */ - current_id = oldest_snap_min = txn_global->current; + txn->last_gen = txn->last_oldest_gen = txn_global->gen; + txn->last_id = oldest_snap_min = current_id = + txn_global->current; /* Copy the array of concurrent transactions. */ WT_ORDERED_READ(session_cnt, conn->session_cnt); @@ -153,39 +166,19 @@ __wt_txn_get_snapshot( /* * __wt_txn_get_evict_snapshot -- * Set up a snapshot in the current transaction for eviction. - * No changes that are invisible to any active transaction can be evicted. + * Only changes that visible to all active transactions can be evicted. */ void __wt_txn_get_evict_snapshot(WT_SESSION_IMPL *session) { - WT_CONNECTION_IMPL *conn; - WT_TXN_GLOBAL *txn_global; - WT_TXN_STATE *s; - wt_txnid_t current_id, id, oldest_snap_min; - uint32_t i, session_cnt; - - conn = S2C(session); - txn_global = &conn->txn_global; - - do { - /* Take a copy of the current session ID. */ - current_id = oldest_snap_min = txn_global->current; + WT_TXN *txn; - /* Walk the array of concurrent transactions. */ - WT_ORDERED_READ(session_cnt, conn->session_cnt); - for (i = 0, s = txn_global->states; i < session_cnt; i++, s++) - if ((id = s->snap_min) != WT_TXN_NONE && - TXNID_LT(id, oldest_snap_min)) - oldest_snap_min = id; + txn = &session->txn; - /* - * Ensure the snapshot reads are scheduled before re-checking - * the global current ID. - */ - WT_READ_BARRIER(); - } while (current_id != txn_global->current); + __wt_txn_get_oldest(session); + __txn_sort_snapshot( + session, 0, txn->oldest_snap_min, txn->oldest_snap_min); - __txn_sort_snapshot(session, 0, oldest_snap_min, oldest_snap_min); /* * Note that we carefully don't update the global table with this * snap_min value: there is already a running transaction in this @@ -249,7 +242,6 @@ __wt_txn_begin(WT_SESSION_IMPL *session, const char *cfg[]) txn->id = WT_ATOMIC_ADD(txn_global->current, 1); } while (txn->id == WT_TXN_NONE || txn->id == WT_TXN_ABORTED); WT_PUBLISH(txn_state->id, txn->id); - oldest_snap_min = txn->id; /* * If we are starting a snapshot isolation transaction, get @@ -260,6 +252,9 @@ __wt_txn_begin(WT_SESSION_IMPL *session, const char *cfg[]) * visible. */ if (txn->isolation == TXN_ISO_SNAPSHOT) { + txn->last_gen = txn->last_oldest_gen = txn_global->gen; + oldest_snap_min = txn->id; + /* Copy the array of concurrent transactions. */ WT_ORDERED_READ(session_cnt, conn->session_cnt); for (i = n = 0, s = txn_global->states; @@ -319,6 +314,9 @@ __wt_txn_release(WT_SESSION_IMPL *session) __wt_txn_release_snapshot(session); txn->isolation = session->isolation; F_CLR(txn, TXN_ERROR | TXN_OLDEST | TXN_RUNNING); + + /* Update the global generation number. */ + ++S2C(session)->txn_global.gen; } /* |