diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2013-05-24 11:40:36 +1000 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2013-05-24 11:40:36 +1000 |
commit | 1441654cebff4f46ba2f3448a0b41963276e9d24 (patch) | |
tree | a96647ef8a7a7501e74b12c16577d14e99d7ce37 | |
parent | 7af5ca6253426a88e97ae6825e8084c75f5f22b2 (diff) | |
download | mongo-1441654cebff4f46ba2f3448a0b41963276e9d24.tar.gz |
Yet another rearrangement of the forced eviction code. Now check the first time we read a page in a transaction. That way, it shouldn't contain updates from the current transaction that prevent eviction.
-rw-r--r-- | src/btree/bt_page.c | 16 | ||||
-rw-r--r-- | src/include/btree.i | 7 | ||||
-rw-r--r-- | src/include/extern.h | 4 | ||||
-rw-r--r-- | src/include/txn.h | 5 | ||||
-rw-r--r-- | src/txn/txn.c | 12 |
5 files changed, 28 insertions, 16 deletions
diff --git a/src/btree/bt_page.c b/src/btree/bt_page.c index ace833f8e26..5e43c53d6cd 100644 --- a/src/btree/bt_page.c +++ b/src/btree/bt_page.c @@ -30,8 +30,12 @@ __wt_page_in_func( { WT_DECL_RET; WT_PAGE *page; + WT_PAGE_MODIFY *mod; + WT_TXN *txn; int busy, oldgen; + txn = &session->txn; + for (oldgen = 0;;) { switch (ref->state) { case WT_REF_DISK: @@ -79,9 +83,17 @@ __wt_page_in_func( * updates. This should be extremely unlikely in real * applications, wait for eviction of the page to avoid * the issue. + * + * Also, make sure the page isn't too big. Only do + * this check once per transaction: it is not a common + * case, and we don't want to get stuck if it isn't + * possible to evict the page. */ - if (page->modify != NULL && - __wt_txn_ancient(session, page->modify->first_id)) { + if ((mod = page->modify) != NULL && + (__wt_txn_ancient(session, mod->first_id) || + (!F_ISSET(txn, TXN_FORCE_EVICT) && + __wt_eviction_page_force(session, page)))) { + F_SET(txn, TXN_FORCE_EVICT); page->read_gen = WT_READ_GEN_OLDEST; WT_RET(__wt_page_release(session, page)); break; diff --git a/src/include/btree.i b/src/include/btree.i index ed3031471bc..3d49972043f 100644 --- a/src/include/btree.i +++ b/src/include/btree.i @@ -445,11 +445,10 @@ __wt_page_release(WT_SESSION_IMPL *session, WT_PAGE *page) return (0); /* - * Try to immediately evict pages if they require forced eviction or - * have the special "oldest" read generation. + * Try to immediately evict pages if they have the special "oldest" + * read generation. */ - if ((page->read_gen == WT_READ_GEN_OLDEST || - __wt_eviction_page_force(session, page)) && + if (page->read_gen == WT_READ_GEN_OLDEST && WT_ATOMIC_CAS(page->ref->state, WT_REF_MEM, WT_REF_LOCKED)) { if ((ret = __wt_hazard_clear(session, page)) != 0) { page->ref->state = WT_REF_MEM; diff --git a/src/include/extern.h b/src/include/extern.h index ce7a96efb76..f9d4d5d3bbe 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -1239,10 +1239,10 @@ extern void __wt_stat_clear_connection_stats(void *stats_arg); extern int __wt_txnid_cmp(const void *v1, const void *v2); extern void __wt_txn_release_snapshot(WT_SESSION_IMPL *session); extern void __wt_txn_get_oldest(WT_SESSION_IMPL *session); -extern void __wt_txn_get_snapshot( WT_SESSION_IMPL *session, +extern void __wt_txn_get_snapshot(WT_SESSION_IMPL *session, wt_txnid_t my_id, wt_txnid_t max_id, - int force); + int committing); extern void __wt_txn_get_evict_snapshot(WT_SESSION_IMPL *session); extern int __wt_txn_begin(WT_SESSION_IMPL *session, const char *cfg[]); extern void __wt_txn_release(WT_SESSION_IMPL *session); diff --git a/src/include/txn.h b/src/include/txn.h index 80e0a05668a..6d022c2d078 100644 --- a/src/include/txn.h +++ b/src/include/txn.h @@ -98,7 +98,8 @@ struct __wt_txn { #define TXN_AUTOCOMMIT 0x01 #define TXN_ERROR 0x02 -#define TXN_OLDEST 0x04 -#define TXN_RUNNING 0x08 +#define TXN_FORCE_EVICT 0x04 +#define TXN_OLDEST 0x08 +#define TXN_RUNNING 0x10 uint32_t flags; }; diff --git a/src/txn/txn.c b/src/txn/txn.c index 70c7bd2bdfb..6bc860d7329 100644 --- a/src/txn/txn.c +++ b/src/txn/txn.c @@ -116,8 +116,8 @@ __wt_txn_get_oldest(WT_SESSION_IMPL *session) * Set up a snapshot in the current transaction, without allocating an ID. */ void -__wt_txn_get_snapshot( - WT_SESSION_IMPL *session, wt_txnid_t my_id, wt_txnid_t max_id, int force) +__wt_txn_get_snapshot(WT_SESSION_IMPL *session, + wt_txnid_t my_id, wt_txnid_t max_id, int committing) { WT_CONNECTION_IMPL *conn; WT_TXN *txn; @@ -132,7 +132,7 @@ __wt_txn_get_snapshot( txn_state = &txn_global->states[session->id]; /* If nothing has changed since last time, we're done. */ - if (!force && txn->last_id == txn_global->current && + if (!committing && txn->last_id == txn_global->current && txn->last_gen == txn_global->gen) { WT_ASSERT(session, TXNID_LE(txn->oldest_snap_min, txn->snap_min)); @@ -151,7 +151,7 @@ __wt_txn_get_snapshot( for (i = n = 0, s = txn_global->states; i < session_cnt; i++, s++) { - if ((id = s->id) != WT_TXN_NONE && + if (!committing && (id = s->id) != WT_TXN_NONE && TXNID_LT(id, oldest_snap_min)) oldest_snap_min = id; /* @@ -182,7 +182,7 @@ __wt_txn_get_snapshot( oldest_snap_min); id = (my_id == WT_TXN_NONE || TXNID_LT(txn->snap_min, my_id)) ? txn->snap_min : my_id; - WT_ASSERT(session, TXNID_LE(oldest_snap_min, id)); + WT_ASSERT(session, committing || TXNID_LE(oldest_snap_min, id)); txn_state->snap_min = id; } @@ -340,7 +340,7 @@ __wt_txn_release(WT_SESSION_IMPL *session) if (session->ncursors == 0) __wt_txn_release_snapshot(session); txn->isolation = session->isolation; - F_CLR(txn, TXN_ERROR | TXN_OLDEST | TXN_RUNNING); + F_CLR(txn, TXN_ERROR | TXN_FORCE_EVICT | TXN_OLDEST | TXN_RUNNING); /* Update the global generation number. */ ++txn_global->gen; |