diff options
author | Michael Cahill <michael.cahill@mongodb.com> | 2016-09-16 14:20:37 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-09-16 14:20:37 +1000 |
commit | d318b8a5370f7182beeab4124cee04fdce271608 (patch) | |
tree | 80eb6f40e9bf72439cdf7c9634bbb665ac0ed13c | |
parent | 0bf6b4d9ffc468920c3432bf77da1da940576af4 (diff) | |
download | mongo-d318b8a5370f7182beeab4124cee04fdce271608.tar.gz |
WT-2910 When running in-memory, only evict dirty pages. (#3044)
* Don't relax the clean / dirty requirements when we get aggressive: if application threads are blocked by the dirty limit, evicting a clean page doesn't unblock them so there's no point trying.
* Sanity check dirty eviction limits: once the cache is full, we should evict both clean and dirty pages.
-rw-r--r-- | src/conn/conn_cache.c | 14 | ||||
-rw-r--r-- | src/evict/evict_lru.c | 33 |
2 files changed, 42 insertions, 5 deletions
diff --git a/src/conn/conn_cache.c b/src/conn/conn_cache.c index 7e94e9e87dc..6788b1f7f47 100644 --- a/src/conn/conn_cache.c +++ b/src/conn/conn_cache.c @@ -56,6 +56,13 @@ __cache_config_local(WT_SESSION_IMPL *session, bool shared, const char *cfg[]) cache->eviction_dirty_target = (u_int)cval.val; /* + * Don't allow the dirty target to be larger than the overall + * target. + */ + if (cache->eviction_dirty_target > cache->eviction_target) + cache->eviction_dirty_target = cache->eviction_target; + + /* * Sanity check the checkpoint target: don't allow a value * lower than the dirty target. */ @@ -68,6 +75,13 @@ __cache_config_local(WT_SESSION_IMPL *session, bool shared, const char *cfg[]) WT_RET(__wt_config_gets( session, cfg, "eviction_dirty_trigger", &cval)); cache->eviction_dirty_trigger = (u_int)cval.val; + + /* + * Don't allow the dirty trigger to be larger than the overall + * trigger or we can get stuck with a cache full of dirty data. + */ + if (cache->eviction_dirty_trigger > cache->eviction_trigger) + cache->eviction_dirty_trigger = cache->eviction_trigger; } WT_RET(__wt_config_gets(session, cfg, "eviction.threads_max", &cval)); diff --git a/src/evict/evict_lru.c b/src/evict/evict_lru.c index cc4d8ea1e08..843249b695d 100644 --- a/src/evict/evict_lru.c +++ b/src/evict/evict_lru.c @@ -468,6 +468,14 @@ __evict_update_work(WT_SESSION_IMPL *session) F_SET(cache, WT_CACHE_EVICT_DIRTY_HARD); /* + * If application threads are blocked by the total volume of data in + * cache, try dirty pages as well. + */ + if (__wt_cache_aggressive(session) && + F_ISSET(cache, WT_CACHE_EVICT_CLEAN_HARD)) + F_SET(cache, WT_CACHE_EVICT_DIRTY); + + /* * Scrub dirty pages and keep them in cache if we are less than half * way to the clean or dirty trigger. */ @@ -477,6 +485,18 @@ __evict_update_work(WT_SESSION_IMPL *session) bytes_max) / 200) F_SET(cache, WT_CACHE_EVICT_SCRUB); + /* + * With an in-memory cache, we only do dirty eviction in order to scrub + * pages. + */ + if (F_ISSET(conn, WT_CONN_IN_MEMORY)) { + if (F_ISSET(cache, WT_CACHE_EVICT_CLEAN)) + F_SET(cache, WT_CACHE_EVICT_DIRTY); + if (F_ISSET(cache, WT_CACHE_EVICT_CLEAN_HARD)) + F_SET(cache, WT_CACHE_EVICT_DIRTY_HARD); + F_CLR(cache, WT_CACHE_EVICT_CLEAN | WT_CACHE_EVICT_CLEAN_HARD); + } + WT_STAT_CONN_SET(session, cache_eviction_state, F_MASK(cache, WT_CACHE_EVICT_MASK)); @@ -1348,7 +1368,7 @@ __evict_walk_file(WT_SESSION_IMPL *session, ret = __wt_tree_walk_count( session, &btree->evict_ref, &refs_walked, walk_flags)) { /* - * Check whether we're finding a good ration of candidates vs + * Check whether we're finding a good ratio of candidates vs * pages seen. Some workloads create "deserts" in trees where * no good eviction candidates can be found. Abandon the walk * if we get into that situation. @@ -1402,20 +1422,23 @@ __evict_walk_file(WT_SESSION_IMPL *session, continue; } + /* Pages that are empty or from dead trees are also good. */ if (__wt_page_is_empty(page) || - F_ISSET(session->dhandle, WT_DHANDLE_DEAD) || - __wt_cache_aggressive(session)) + F_ISSET(session->dhandle, WT_DHANDLE_DEAD)) goto fast; /* Skip clean pages if appropriate. */ - if (!modified && (F_ISSET(conn, WT_CONN_IN_MEMORY) || - !F_ISSET(cache, WT_CACHE_EVICT_CLEAN))) + if (!modified && !F_ISSET(cache, WT_CACHE_EVICT_CLEAN)) continue; /* Skip dirty pages if appropriate. */ if (modified && !F_ISSET(cache, WT_CACHE_EVICT_DIRTY)) continue; + /* If eviction gets aggressive, anything else is fair game. */ + if (__wt_cache_aggressive(session)) + goto fast; + /* Limit internal pages to 50% of the total. */ if (WT_PAGE_IS_INTERNAL(page) && internal_pages >= (int)(evict - start) / 2) |