summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Bostic <keith@wiredtiger.com>2016-03-06 13:52:23 -0500
committerKeith Bostic <keith@wiredtiger.com>2016-03-06 13:52:23 -0500
commit45ffd7785f27d2cefc429f8edbeb1d0db1901796 (patch)
treeb427de8b5141c3bc3fdbc3966f2756b88db2a57b /src
parentf91fbe07e483c8fae5159c6036d4caa181777b2a (diff)
downloadmongo-45ffd7785f27d2cefc429f8edbeb1d0db1901796.tar.gz
WT-2391: De-prioritize eviction from indexes
With commit 7f84e3b it's unlikely for a page to NOT have a read generation, it only happens if a reader configured with WT_READ_NO_GEN set were to read a page into cache, and that won't happen because those readers set either WT_READ_CACHE or WT_READ_WONT_NEED. The eviction code still has special code to handle pages without a read generation set, and it maintains a "oldest page generation" value to support that. However, the oldest page generation value isn't really right -- it's simply that page generation value from the first slot in the queue, which can be special (for example, if the page generation was set to WT_READGEN_OLDEST because the page was empty). Add a test in the page-read code to set the page generation if it's never been set, regardless of WT_READ_NO_GEN. Remove the eviction code to maintain an "oldest page generation". Leave the eviction code to handle WT_READGEN_NOTSET (it can still see that value if there's a race), but change it to set the page read generation to the "standard" value instead of trying anything fancy. That ensure that if there's a bug (we read the page but for some reason never set the page generation), the page won't stay in that state forever.
Diffstat (limited to 'src')
-rw-r--r--src/btree/bt_read.c17
-rw-r--r--src/evict/evict_lru.c11
-rw-r--r--src/include/cache.h2
-rw-r--r--src/include/cache.i13
4 files changed, 16 insertions, 27 deletions
diff --git a/src/btree/bt_read.c b/src/btree/bt_read.c
index ac9faef4ff2..fd84ad8c7c8 100644
--- a/src/btree/bt_read.c
+++ b/src/btree/bt_read.c
@@ -575,18 +575,23 @@ __wt_page_in_func(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t flags
}
/*
- * If we read the page and we are configured to not
- * trash the cache, set the oldest read generation so
- * the page is forcibly evicted as soon as possible.
+ * If we read the page and are configured to not trash
+ * the cache, and no other thread has already used the
+ * page, set the oldest read generation so the page is
+ * forcibly evicted as soon as possible.
*
- * Otherwise, update the page's read generation.
+ * Otherwise, if we read the page, or, if configured to
+ * update the page's read generation and the page isn't
+ * already flagged for forced eviction, update the page
+ * read generation.
*/
page = ref->page;
if (oldgen && page->read_gen == WT_READGEN_NOTSET)
__wt_page_evict_soon(page);
- else if (!LF_ISSET(WT_READ_NO_GEN) &&
+ else if (page->read_gen == WT_READGEN_NOTSET ||
+ (!LF_ISSET(WT_READ_NO_GEN) &&
page->read_gen != WT_READGEN_OLDEST &&
- page->read_gen < __wt_cache_read_gen(session))
+ page->read_gen < __wt_cache_read_gen(session)))
page->read_gen =
__wt_cache_read_gen_bump(session);
skip_evict:
diff --git a/src/evict/evict_lru.c b/src/evict/evict_lru.c
index 884c08a02df..581637f1396 100644
--- a/src/evict/evict_lru.c
+++ b/src/evict/evict_lru.c
@@ -933,9 +933,6 @@ __evict_lru_walk(WT_SESSION_IMPL *session)
WT_ASSERT(session, cache->evict_queue[0].ref != NULL);
- /* Track the oldest read generation we have in the queue. */
- cache->read_gen_oldest = cache->evict_queue[0].ref->page->read_gen;
-
if (FLD_ISSET(cache->state,
WT_EVICT_PASS_AGGRESSIVE | WT_EVICT_PASS_WOULD_BLOCK))
/*
@@ -1312,11 +1309,13 @@ __evict_walk_file(WT_SESSION_IMPL *session, u_int *slotp)
continue;
/*
- * If this page has never been considered for eviction, set its
- * read generation to somewhere in the middle of the LRU list.
+ * It's possible (but unlikely) to visit a page without a read
+ * generation, if we race with the read instantiating the page.
+ * Be safe and set the page's read generation here to ensure a
+ * bug doesn't somehow leave a page without a read generation.
*/
if (page->read_gen == WT_READGEN_NOTSET)
- page->read_gen = __wt_cache_read_gen_new(session);
+ page->read_gen = __wt_cache_read_gen_bump(session);
fast: /* If the page can't be evicted, give up. */
if (!__wt_page_can_evict(session, ref, NULL))
diff --git a/src/include/cache.h b/src/include/cache.h
index a3961d6043e..fb221fd9af5 100644
--- a/src/include/cache.h
+++ b/src/include/cache.h
@@ -76,8 +76,6 @@ struct __wt_cache {
* Read information.
*/
uint64_t read_gen; /* Page read generation (LRU) */
- uint64_t read_gen_oldest; /* The oldest read generation that
- eviction knows about */
/*
* Eviction thread information.
diff --git a/src/include/cache.i b/src/include/cache.i
index ee13eee84c5..46809598d5c 100644
--- a/src/include/cache.i
+++ b/src/include/cache.i
@@ -46,19 +46,6 @@ __wt_cache_read_gen_bump(WT_SESSION_IMPL *session)
}
/*
- * __wt_cache_read_gen_new --
- * Get the read generation for a new page in memory.
- */
-static inline uint64_t
-__wt_cache_read_gen_new(WT_SESSION_IMPL *session)
-{
- WT_CACHE *cache;
-
- cache = S2C(session)->cache;
- return (__wt_cache_read_gen(session) + cache->read_gen_oldest) / 2;
-}
-
-/*
* __wt_cache_pages_inuse --
* Return the number of pages in use.
*/