diff options
author | Keith Bostic <keith@wiredtiger.com> | 2016-03-06 13:52:23 -0500 |
---|---|---|
committer | Keith Bostic <keith@wiredtiger.com> | 2016-03-06 13:52:23 -0500 |
commit | 45ffd7785f27d2cefc429f8edbeb1d0db1901796 (patch) | |
tree | b427de8b5141c3bc3fdbc3966f2756b88db2a57b /src | |
parent | f91fbe07e483c8fae5159c6036d4caa181777b2a (diff) | |
download | mongo-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.c | 17 | ||||
-rw-r--r-- | src/evict/evict_lru.c | 11 | ||||
-rw-r--r-- | src/include/cache.h | 2 | ||||
-rw-r--r-- | src/include/cache.i | 13 |
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. */ |