diff options
author | Alex Gorrod <alexg@wiredtiger.com> | 2012-12-21 15:39:12 +1100 |
---|---|---|
committer | Alex Gorrod <alexg@wiredtiger.com> | 2012-12-21 15:39:12 +1100 |
commit | b1b453abd45d488d439974aa97cc162b57885248 (patch) | |
tree | 43a146069eea3f7ffc4cb2891b21694d245a296b | |
parent | 573de639a54101b0fc2749040441f835fff36399 (diff) | |
download | mongo-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.c | 12 | ||||
-rw-r--r-- | src/include/cache.h | 6 | ||||
-rw-r--r-- | src/include/cache.i | 13 | ||||
-rw-r--r-- | src/support/hazard.c | 11 |
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 |