diff options
author | Keith Bostic <keith@wiredtiger.com> | 2015-08-11 16:57:51 -0400 |
---|---|---|
committer | Keith Bostic <keith@wiredtiger.com> | 2015-08-11 16:57:51 -0400 |
commit | 8d07d73c833eb898d4d59c685ed25a0c32c22470 (patch) | |
tree | 885b6ed7b8ca49dee5e2672873b399bb31b9fe75 | |
parent | e1053a70517e5cb703dfc2d7cffebeadaa45d3b3 (diff) | |
download | mongo-8d07d73c833eb898d4d59c685ed25a0c32c22470.tar.gz |
Restore the previous tests for how likely eviction is: the lookaside
file records are only written when eviction gets aggressive, so the
previous tests for how likely eviction is remain relevant, but may
need modification depending on whether or not eviction is aggressive.
-rw-r--r-- | src/evict/evict_lru.c | 54 | ||||
-rw-r--r-- | src/include/btmem.h | 3 | ||||
-rw-r--r-- | src/include/btree.i | 19 | ||||
-rw-r--r-- | src/reconcile/rec_write.c | 6 |
4 files changed, 62 insertions, 20 deletions
diff --git a/src/evict/evict_lru.c b/src/evict/evict_lru.c index dd2f58c43fa..0207798bdb9 100644 --- a/src/evict/evict_lru.c +++ b/src/evict/evict_lru.c @@ -1196,26 +1196,44 @@ fast: /* If the page can't be evicted, give up. */ continue; /* - * If the oldest transaction hasn't changed since the last time - * this page was written, it's unlikely we can make progress (an - * heuristic to avoid repeated attempts to evict the same page). - * Similarly, if the most recent update on the page is not yet - * committed, eviction will fail. + * Additional tests if eviction is likely to succeed. * - * If eviction is stuck, or we are helping with forced eviction, - * try anyway: maybe a transaction that was running last time we - * wrote the page has since rolled back, or we can help get the - * checkpoint completed sooner. - * - * Note: take care with ordering: if we detected that the page - * is modified above, we expect mod != NULL. + * If eviction is stuck or we are helping with forced eviction, + * try anyway: maybe a transaction that was running last time + * we wrote the page has since rolled back, or we can help the + * checkpoint complete sooner. Additionally, being stuck will + * configure lookaside file writes in reconciliation, allowing + * us to evict pages we can't usually evict. */ - mod = page->modify; - if (modified && !FLD_ISSET(cache->state, - WT_EVICT_PASS_AGGRESSIVE | WT_EVICT_PASS_WOULD_BLOCK) && - (!__wt_txn_committed(session, mod->update_txn) || - mod->disk_snap_min == conn->txn_global.oldest_id)) - continue; + if (!FLD_ISSET(cache->state, + WT_EVICT_PASS_AGGRESSIVE | WT_EVICT_PASS_WOULD_BLOCK)) { + /* + * Note: take care with ordering: if we detected that + * the page is modified above, we expect mod != NULL. + */ + mod = page->modify; + + /* + * If the page is clean but has modifications that + * appear too new to evict, skip it. + */ + if (!modified && mod != NULL && + !__wt_txn_visible_all(session, mod->rec_max_txn)) + continue; + + /* + * If the oldest transaction hasn't changed since the + * last time this page was written, it's unlikely we + * can make progress. Similarly, if the most recent + * update on the page is not yet globally visible, + * eviction will fail. These heuristics attempt to + * avoid repeated attempts to evict the same page. + */ + if (modified && + (mod->disk_snap_min == conn->txn_global.oldest_id || + !__wt_txn_visible_all(session, mod->update_txn))) + continue; + } WT_ASSERT(session, evict->ref == NULL); __evict_init_candidate(session, evict, ref); diff --git a/src/include/btmem.h b/src/include/btmem.h index 5f713877373..a813dce48a0 100644 --- a/src/include/btmem.h +++ b/src/include/btmem.h @@ -209,6 +209,9 @@ struct __wt_page_modify { /* Avoid checking for obsolete updates during checkpoints. */ uint64_t obsolete_check_txn; + /* The largest transaction ID seen on the page by reconciliation. */ + uint64_t rec_max_txn; + /* The largest update transaction ID (approximate). */ uint64_t update_txn; diff --git a/src/include/btree.i b/src/include/btree.i index 58a66738aa2..40858175ca4 100644 --- a/src/include/btree.i +++ b/src/include/btree.i @@ -975,6 +975,7 @@ __wt_page_can_evict(WT_SESSION_IMPL *session, WT_BTREE *btree; WT_PAGE_MODIFY *mod; WT_TXN_GLOBAL *txn_global; + uint64_t txnid; if (inmem_splitp != NULL) *inmem_splitp = 0; @@ -1044,9 +1045,23 @@ __wt_page_can_evict(WT_SESSION_IMPL *session, * for existing hazard pointers, the checkpoint thread reconciling an * internal page acquires hazard pointers on child pages it reads, and * is blocked by the exclusive lock. - * - * KEITH: this comment should move to somewhere else. */ + if (page->read_gen != WT_READGEN_OLDEST) { + /* + * If eviction is stuck, we'll use the lookaside file and so + * only care if all changes on the page are committed. + */ + if (__wt_eviction_aggressive(session)) { + if (__wt_page_is_modified(page) && + !__wt_txn_committed(session, mod->update_txn)) + return (0); + } else { + if (!__wt_txn_visible_all(session, + __wt_page_is_modified(page) ? + mod->update_txn : mod->rec_max_txn)) + return (0); + } + } /* * If the page was recently split in-memory, don't force it out: we diff --git a/src/reconcile/rec_write.c b/src/reconcile/rec_write.c index 2ccbe1a1ab1..81cd2e673e9 100644 --- a/src/reconcile/rec_write.c +++ b/src/reconcile/rec_write.c @@ -5506,6 +5506,12 @@ err: __wt_scr_free(session, &tkey); return (EBUSY); } else { /* + * Track the page's maximum transaction ID (used to decide if + * we're likely to be able to evict this page in the future). + */ + mod->rec_max_txn = r->max_txn; + + /* * Track the tree's maximum transaction ID (used to decide if * it's safe to discard the tree). Reconciliation for eviction * is multi-threaded, only update the tree's maximum transaction |