summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Bostic <keith.bostic@mongodb.com>2016-09-24 19:13:23 -0400
committerMichael Cahill <michael.cahill@mongodb.com>2016-09-25 09:13:23 +1000
commitfca6813c068a38cd3c6ea7bb9d3525a827ff0c54 (patch)
treef77a66f10d8d8a778b0b069c8a03a0b1690cdee0
parentd85e1890639ed51bd72841ef3143e696b32c1ba6 (diff)
downloadmongo-fca6813c068a38cd3c6ea7bb9d3525a827ff0c54.tar.gz
WT-2924 Ensure we are doing eviction when threads are waiting for it (#3061)
* Set WT_CACHE_EVICT_XXX when setting WT_CACHE_EVICT_XXX_HARD (the byte count checks can race, so we have to explicitly set both). * Make WT_CACHE.pages_evict volatile: loops in __evict_pass() and __wt_cache_eviction_worker() read the value and depend on it being updated when subsequently read.
-rw-r--r--src/evict/evict_lru.c31
-rw-r--r--src/include/btree.i2
-rw-r--r--src/include/cache.h2
3 files changed, 18 insertions, 17 deletions
diff --git a/src/evict/evict_lru.c b/src/evict/evict_lru.c
index fcea343c2a1..3be7a124a1d 100644
--- a/src/evict/evict_lru.c
+++ b/src/evict/evict_lru.c
@@ -456,13 +456,13 @@ __evict_update_work(WT_SESSION_IMPL *session)
if (bytes_inuse > (cache->eviction_target * bytes_max) / 100)
F_SET(cache, WT_CACHE_EVICT_CLEAN);
if (__wt_eviction_clean_needed(session, NULL))
- F_SET(cache, WT_CACHE_EVICT_CLEAN_HARD);
+ F_SET(cache, WT_CACHE_EVICT_CLEAN | WT_CACHE_EVICT_CLEAN_HARD);
dirty_inuse = __wt_cache_dirty_leaf_inuse(cache);
if (dirty_inuse > (cache->eviction_dirty_target * bytes_max) / 100)
F_SET(cache, WT_CACHE_EVICT_DIRTY);
if (__wt_eviction_dirty_needed(session, NULL))
- F_SET(cache, WT_CACHE_EVICT_DIRTY_HARD);
+ F_SET(cache, WT_CACHE_EVICT_DIRTY | WT_CACHE_EVICT_DIRTY_HARD);
/*
* If application threads are blocked by the total volume of data in
@@ -1774,22 +1774,9 @@ __wt_cache_eviction_worker(WT_SESSION_IMPL *session, bool busy, u_int pct_full)
/* Wake the eviction server if we need to do work. */
__wt_evict_server_wake(session);
- /*
- * If we're busy, either because of the transaction check we just did,
- * or because our caller is waiting on a longer-than-usual event (such
- * as a page read), limit the work to a single eviction and return. If
- * that's not the case, we can do more.
- */
init_evict_count = cache->pages_evict;
for (;;) {
- /* Check if we have become busy. */
- if (!busy && txn_state->snap_min != WT_TXN_NONE &&
- txn_global->current != txn_global->oldest_id)
- busy = true;
-
- max_pages_evicted = busy ? 5 : 20;
-
/*
* A pathological case: if we're the oldest transaction in the
* system and the eviction server is stuck trying to find space,
@@ -1802,6 +1789,20 @@ __wt_cache_eviction_worker(WT_SESSION_IMPL *session, bool busy, u_int pct_full)
return (WT_ROLLBACK);
}
+ /*
+ * Check if we have become busy.
+ *
+ * If we're busy (because of the transaction check we just did
+ * or because our caller is waiting on a longer-than-usual event
+ * such as a page read), and the cache level drops below 100%,
+ * limit the work to 5 evictions and return. If that's not the
+ * case, we can do more.
+ */
+ if (!busy && txn_state->snap_min != WT_TXN_NONE &&
+ txn_global->current != txn_global->oldest_id)
+ busy = true;
+ max_pages_evicted = busy ? 5 : 20;
+
/* See if eviction is still needed. */
if (!__wt_eviction_needed(session, busy, &pct_full) ||
(pct_full < 100 &&
diff --git a/src/include/btree.i b/src/include/btree.i
index 6e32c1bc195..a9ce4f754a9 100644
--- a/src/include/btree.i
+++ b/src/include/btree.i
@@ -406,7 +406,7 @@ __wt_cache_page_evict(WT_SESSION_IMPL *session, WT_PAGE *page)
/* Update pages and bytes evicted. */
(void)__wt_atomic_add64(&cache->bytes_evict, page->memory_footprint);
- (void)__wt_atomic_add64(&cache->pages_evict, 1);
+ (void)__wt_atomic_addv64(&cache->pages_evict, 1);
}
/*
diff --git a/src/include/cache.h b/src/include/cache.h
index fceba6536c2..b24b625aec4 100644
--- a/src/include/cache.h
+++ b/src/include/cache.h
@@ -66,7 +66,7 @@ struct __wt_cache {
uint64_t bytes_dirty_leaf;
uint64_t pages_dirty_leaf;
uint64_t bytes_evict; /* Bytes/pages discarded by eviction */
- uint64_t pages_evict;
+ volatile uint64_t pages_evict;
uint64_t pages_evicted; /* Pages evicted during a pass */
uint64_t bytes_image; /* Bytes of disk images */
uint64_t bytes_inmem; /* Bytes/pages in memory */