summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Gorrod <alexg@wiredtiger.com>2012-12-21 15:39:12 +1100
committerAlex Gorrod <alexg@wiredtiger.com>2012-12-21 15:39:12 +1100
commitb1b453abd45d488d439974aa97cc162b57885248 (patch)
tree43a146069eea3f7ffc4cb2891b21694d245a296b
parent573de639a54101b0fc2749040441f835fff36399 (diff)
downloadmongo-b1b453abd45d488d439974aa97cc162b57885248.tar.gz
Add code in to prioritize eviction of pages that are larger
than a certain threshold. This avoids taking a performance hit when a huge page needs to be reconciled.
-rw-r--r--src/btree/bt_evict.c12
-rw-r--r--src/include/cache.h6
-rw-r--r--src/include/cache.i13
-rw-r--r--src/support/hazard.c11
4 files changed, 40 insertions, 2 deletions
diff --git a/src/btree/bt_evict.c b/src/btree/bt_evict.c
index 02edeabbf47..305ce5ec834 100644
--- a/src/btree/bt_evict.c
+++ b/src/btree/bt_evict.c
@@ -40,9 +40,14 @@ __evict_read_gen(const WT_EVICT_ENTRY *entry)
{
uint64_t read_gen;
+ /* Never prioritize empty slots. */
if (entry->page == NULL)
return (UINT64_MAX);
+ /* Always prioritize pages selected by force. */
+ if (__wt_eviction_page_force(entry->btree, entry->page))
+ return (0);
+
read_gen = entry->page->read_gen + entry->btree->evict_priority;
if (entry->page->type == WT_PAGE_ROW_INT ||
entry->page->type == WT_PAGE_COL_INT)
@@ -279,11 +284,14 @@ __evict_worker(WT_SESSION_IMPL *session)
bytes_inuse = __wt_cache_bytes_inuse(cache);
dirty_inuse = __wt_cache_dirty_bytes(cache);
bytes_max = conn->cache_size;
- if (bytes_inuse < (cache->eviction_target * bytes_max) / 100 &&
+ if (F_ISSET(cache, WT_EVICT_FORCE_PASS) ||
+ (bytes_inuse < (cache->eviction_target * bytes_max) / 100 &&
dirty_inuse <
- (cache->eviction_dirty_target * bytes_max) / 100)
+ (cache->eviction_dirty_target * bytes_max) / 100))
break;
+ F_CLR(cache, WT_EVICT_FORCE_PASS);
+
/* Figure out how much we will focus on dirty pages. */
if (dirty_inuse >
(cache->eviction_dirty_target * bytes_max) / 100)
diff --git a/src/include/cache.h b/src/include/cache.h
index a70721a5a09..11ddc542411 100644
--- a/src/include/cache.h
+++ b/src/include/cache.h
@@ -73,6 +73,12 @@ struct __wt_cache {
uint32_t cp_skip_count; /* Post change stabilization */
uint32_t disabled_eviction; /* Disabled clean / dirty eviction */
+
+ /*
+ * Flags.
+ */
+#define WT_EVICT_FORCE_PASS 0x01 /* Ignore the eviction trigger */
+ uint32_t flags;
};
/*
diff --git a/src/include/cache.i b/src/include/cache.i
index 73ffe1a4dba..be9cc92dd16 100644
--- a/src/include/cache.i
+++ b/src/include/cache.i
@@ -40,6 +40,19 @@ __wt_eviction_check(WT_SESSION_IMPL *session, int *read_lockoutp, int wake)
}
/*
+ * __wt_eviction_page_force --
+ * Return if a page should be a high priority for eviction. The method
+ * does not use a session handle, since it is called from the eviction
+ * sort routine, that does not have a session easily available.
+ */
+static inline int
+__wt_eviction_page_force(WT_BTREE *btree, WT_PAGE *page)
+{
+ return (!WT_PAGE_IS_ROOT(page) && __wt_page_is_modified(page) &&
+ (page->memory_footprint > 20 * btree->maxleafpage));
+}
+
+/*
* __wt_cache_full_check --
* Wait for there to be space in the cache before a read or update.
*/
diff --git a/src/support/hazard.c b/src/support/hazard.c
index 7eb0cf4e5bc..829d0d9cb23 100644
--- a/src/support/hazard.c
+++ b/src/support/hazard.c
@@ -149,6 +149,17 @@ __wt_hazard_clear(WT_SESSION_IMPL *session, WT_PAGE *page)
--hp)
if (hp->page == page) {
/*
+ * Trigger eviction if we want to force the page out.
+ * The page won't necessarily be chosen for eviction
+ * every time, but it will be eventually.
+ */
+ if (__wt_eviction_page_force(btree, page)) {
+ F_SET(S2C(session)->cache,
+ WT_EVICT_FORCE_PASS);
+ __wt_evict_server_wake(session);
+ }
+
+ /*
* We don't publish the hazard pointer clear in the
* general case. It's not required for correctness;
* it gives the page server thread faster access to the