summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dist/api_data.py30
-rw-r--r--dist/flags.py4
-rw-r--r--dist/stat_data.py2
-rw-r--r--src/btree/bt_curnext.c2
-rw-r--r--src/btree/bt_curprev.c2
-rw-r--r--src/btree/bt_discard.c4
-rw-r--r--src/btree/bt_page.c1
-rw-r--r--src/btree/bt_read.c14
-rw-r--r--src/btree/bt_split.c2
-rw-r--r--src/btree/bt_walk.c2
-rw-r--r--src/btree/row_srch.c2
-rw-r--r--src/conn/conn_cache.c25
-rw-r--r--src/evict/evict_lru.c331
-rw-r--r--src/evict/evict_page.c114
-rw-r--r--src/include/btree.i109
-rw-r--r--src/include/cache.h25
-rw-r--r--src/include/cache.i63
-rw-r--r--src/include/cursor.i2
-rw-r--r--src/include/extern.h2
-rw-r--r--src/include/flags.h10
-rw-r--r--src/include/stat.h2
-rw-r--r--src/include/wiredtiger.in328
-rw-r--r--src/support/stat.c6
-rw-r--r--src/txn/txn_ckpt.c3
-rw-r--r--tools/wtstats/stat_data.py4
25 files changed, 607 insertions, 482 deletions
diff --git a/dist/api_data.py b/dist/api_data.py
index 90b1c8378a2..960f800a44d 100644
--- a/dist/api_data.py
+++ b/dist/api_data.py
@@ -388,6 +388,21 @@ connection_runtime_config = [
]),
Config('error_prefix', '', r'''
prefix string for error messages'''),
+ Config('eviction', '', r'''
+ eviction configuration options.''',
+ type='category', subconfig=[
+ Config('threads_max', '1', r'''
+ maximum number of threads WiredTiger will start to help evict
+ pages from cache. The number of threads started will vary
+ depending on the current eviction load. Each eviction worker
+ thread uses a session from the configured session_max''',
+ min=1, max=20),
+ Config('threads_min', '1', r'''
+ minimum number of threads WiredTiger will start to help evict
+ pages from cache. The number of threads currently running will
+ vary depending on the current eviction load''',
+ min=1, max=20),
+ ]),
Config('eviction_dirty_target', '80', r'''
continue evicting until the cache has less dirty memory than the
value, as a percentage of the total cache size. Dirty pages will
@@ -472,21 +487,6 @@ connection_runtime_config = [
Config('lsm_merge', 'true', r'''
merge LSM chunks where possible (deprecated)''',
type='boolean', undoc=True),
- Config('eviction', '', r'''
- eviction configuration options.''',
- type='category', subconfig=[
- Config('threads_max', '1', r'''
- maximum number of threads WiredTiger will start to help evict
- pages from cache. The number of threads started will vary
- depending on the current eviction load. Each eviction worker
- thread uses a session from the configured session_max''',
- min=1, max=20),
- Config('threads_min', '1', r'''
- minimum number of threads WiredTiger will start to help evict
- pages from cache. The number of threads currently running will
- vary depending on the current eviction load''',
- min=1, max=20),
- ]),
Config('shared_cache', '', r'''
shared cache configuration options. A database should configure
either a cache_size or a shared_cache not both. Enabling a
diff --git a/dist/flags.py b/dist/flags.py
index b5f36fb707a..b661fa348fa 100644
--- a/dist/flags.py
+++ b/dist/flags.py
@@ -37,10 +37,12 @@ flags = {
'READ_WONT_NEED',
],
'rec_write' : [
+ 'EVICTING',
+ 'EVICT_CLEAN',
'EVICT_IN_MEMORY',
+ 'EVICT_INMEM_SPLIT',
'EVICT_LOOKASIDE',
'EVICT_UPDATE_RESTORE',
- 'EVICTING',
'VISIBILITY_ERR',
],
'txn_log_checkpoint' : [
diff --git a/dist/stat_data.py b/dist/stat_data.py
index 2dc828d8afb..4721f3e629f 100644
--- a/dist/stat_data.py
+++ b/dist/stat_data.py
@@ -168,10 +168,12 @@ connection_stats = [
# Cache and eviction statistics
##########################################
CacheStat('cache_bytes_dirty', 'tracked dirty bytes in the cache', 'no_clear,no_scale,size'),
+ CacheStat('cache_bytes_image', 'bytes belonging to page images in the cache', 'no_clear,no_scale,size'),
CacheStat('cache_bytes_internal', 'tracked bytes belonging to internal pages in the cache', 'no_clear,no_scale,size'),
CacheStat('cache_bytes_inuse', 'bytes currently in the cache', 'no_clear,no_scale,size'),
CacheStat('cache_bytes_leaf', 'tracked bytes belonging to leaf pages in the cache', 'no_clear,no_scale,size'),
CacheStat('cache_bytes_max', 'maximum bytes configured', 'no_clear,no_scale,size'),
+ CacheStat('cache_bytes_other', 'bytes not belonging to page images in the cache', 'no_clear,no_scale,size'),
CacheStat('cache_bytes_overflow', 'tracked bytes belonging to overflow pages in the cache', 'no_clear,no_scale,size'),
CacheStat('cache_bytes_read', 'bytes read into cache', 'size'),
CacheStat('cache_bytes_write', 'bytes written from cache', 'size'),
diff --git a/src/btree/bt_curnext.c b/src/btree/bt_curnext.c
index 70b3ba56e31..5e6c3c7e9de 100644
--- a/src/btree/bt_curnext.c
+++ b/src/btree/bt_curnext.c
@@ -661,7 +661,7 @@ __wt_btcur_next(WT_CURSOR_BTREE *cbt, bool truncating)
if (page != NULL &&
(cbt->page_deleted_count > WT_BTREE_DELETE_THRESHOLD ||
(newpage && cbt->page_deleted_count > 0)))
- __wt_page_evict_soon(page);
+ __wt_page_evict_soon(session, cbt->ref);
cbt->page_deleted_count = 0;
WT_ERR(__wt_tree_walk(session, &cbt->ref, flags));
diff --git a/src/btree/bt_curprev.c b/src/btree/bt_curprev.c
index 872f648446c..c92ef41626b 100644
--- a/src/btree/bt_curprev.c
+++ b/src/btree/bt_curprev.c
@@ -619,7 +619,7 @@ __wt_btcur_prev(WT_CURSOR_BTREE *cbt, bool truncating)
if (page != NULL &&
(cbt->page_deleted_count > WT_BTREE_DELETE_THRESHOLD ||
(newpage && cbt->page_deleted_count > 0)))
- __wt_page_evict_soon(page);
+ __wt_page_evict_soon(session, cbt->ref);
cbt->page_deleted_count = 0;
WT_ERR(__wt_tree_walk(session, &cbt->ref, flags));
diff --git a/src/btree/bt_discard.c b/src/btree/bt_discard.c
index a00bb7dc2b5..965aec16fc2 100644
--- a/src/btree/bt_discard.c
+++ b/src/btree/bt_discard.c
@@ -131,8 +131,10 @@ __wt_page_out(WT_SESSION_IMPL *session, WT_PAGE **pagep)
/* Discard any disk image. */
dsk = (WT_PAGE_HEADER *)page->dsk;
- if (F_ISSET_ATOMIC(page, WT_PAGE_DISK_ALLOC))
+ if (F_ISSET_ATOMIC(page, WT_PAGE_DISK_ALLOC)) {
+ __wt_cache_page_image_decr(session, dsk->mem_size);
__wt_overwrite_and_free_len(session, dsk, dsk->mem_size);
+ }
/* Discard any mapped image. */
if (F_ISSET_ATOMIC(page, WT_PAGE_DISK_MAPPED))
diff --git a/src/btree/bt_page.c b/src/btree/bt_page.c
index 00ec8aa4494..89e5f428628 100644
--- a/src/btree/bt_page.c
+++ b/src/btree/bt_page.c
@@ -219,6 +219,7 @@ __wt_page_inmem(WT_SESSION_IMPL *session, WT_REF *ref,
/* Update the page's in-memory size and the cache statistics. */
__wt_cache_page_inmem_incr(session, page, size);
+ __wt_cache_page_image_incr(session, dsk->mem_size);
/* Link the new internal page to the parent. */
if (ref != NULL) {
diff --git a/src/btree/bt_read.c b/src/btree/bt_read.c
index 086500c8b2f..23aa86a3e40 100644
--- a/src/btree/bt_read.c
+++ b/src/btree/bt_read.c
@@ -296,7 +296,7 @@ err: WT_TRET(__wt_las_cursor_close(session, &cursor, session_flags));
* __evict_force_check --
* Check if a page matches the criteria for forced eviction.
*/
-static int
+static bool
__evict_force_check(WT_SESSION_IMPL *session, WT_REF *ref)
{
WT_BTREE *btree;
@@ -307,26 +307,26 @@ __evict_force_check(WT_SESSION_IMPL *session, WT_REF *ref)
/* Leaf pages only. */
if (WT_PAGE_IS_INTERNAL(page))
- return (0);
+ return (false);
/*
* It's hard to imagine a page with a huge memory footprint that has
* never been modified, but check to be sure.
*/
if (page->modify == NULL)
- return (0);
+ return (false);
/* Pages are usually small enough, check that first. */
if (page->memory_footprint < btree->splitmempage)
- return (0);
+ return (false);
else if (page->memory_footprint < btree->maxmempage)
return (__wt_leaf_page_can_split(session, page));
/* Trigger eviction on the next page release. */
- __wt_page_evict_soon(page);
+ __wt_page_evict_soon(session, ref);
/* Bump the oldest ID, we're about to do some visibility checks. */
- WT_RET(__wt_txn_update_oldest(session, 0));
+ (void)__wt_txn_update_oldest(session, 0);
/* If eviction cannot succeed, don't try. */
return (__wt_page_can_evict(session, ref, NULL));
@@ -595,7 +595,7 @@ __wt_page_in_func(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t flags
page = ref->page;
if (page->read_gen == WT_READGEN_NOTSET) {
if (evict_soon)
- __wt_page_evict_soon(page);
+ __wt_page_evict_soon(session, ref);
else
__wt_cache_read_gen_new(session, page);
} else if (!LF_ISSET(WT_READ_NO_GEN))
diff --git a/src/btree/bt_split.c b/src/btree/bt_split.c
index 0461f695e74..b58c44f3170 100644
--- a/src/btree/bt_split.c
+++ b/src/btree/bt_split.c
@@ -794,7 +794,7 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new,
*/
if (result_entries == 0) {
empty_parent = true;
- __wt_page_evict_soon(parent);
+ __wt_page_evict_soon(session, parent->pg_intl_parent_ref);
goto err;
}
diff --git a/src/btree/bt_walk.c b/src/btree/bt_walk.c
index bb8a750d848..330480f7f86 100644
--- a/src/btree/bt_walk.c
+++ b/src/btree/bt_walk.c
@@ -386,7 +386,7 @@ restart: /*
* eviction.
*/
if (empty_internal && pindex->entries > 1) {
- __wt_page_evict_soon(ref->page);
+ __wt_page_evict_soon(session, ref);
empty_internal = false;
}
diff --git a/src/btree/row_srch.c b/src/btree/row_srch.c
index 4afcd74520f..d4e82c458d4 100644
--- a/src/btree/row_srch.c
+++ b/src/btree/row_srch.c
@@ -775,7 +775,7 @@ __wt_row_random_leaf(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt)
* traversing the skip list each time accumulates to real time.
*/
if (samples > 5000)
- __wt_page_evict_soon(page);
+ __wt_page_evict_soon(session, cbt->ref);
return (0);
}
diff --git a/src/conn/conn_cache.c b/src/conn/conn_cache.c
index aaed18f0323..4fccac88bc1 100644
--- a/src/conn/conn_cache.c
+++ b/src/conn/conn_cache.c
@@ -176,6 +176,10 @@ __wt_cache_create(WT_SESSION_IMPL *session, const char *cfg[])
&cache->evict_queues[i].evict_lock, "cache eviction"));
}
+ /* Ensure there is always a non-NULL current queue. */
+ cache->evict_current_queue =
+ &cache->evict_queues[WT_EVICT_URGENT_QUEUE + 1];
+
/*
* We get/set some values in the cache statistics (rather than have
* two copies), configure them.
@@ -213,21 +217,25 @@ __wt_cache_stats_update(WT_SESSION_IMPL *session)
WT_STAT_SET(session, stats, cache_bytes_max, conn->cache_size);
WT_STAT_SET(session, stats, cache_bytes_inuse, inuse);
-
WT_STAT_SET(session, stats, cache_overhead, cache->overhead_pct);
- WT_STAT_SET(
- session, stats, cache_pages_inuse, __wt_cache_pages_inuse(cache));
+
WT_STAT_SET(
session, stats, cache_bytes_dirty, __wt_cache_dirty_inuse(cache));
- WT_STAT_SET(session, stats,
- cache_eviction_maximum_page_size, cache->evict_max_page_size);
- WT_STAT_SET(session, stats, cache_pages_dirty, cache->pages_dirty);
-
+ WT_STAT_SET(
+ session, stats, cache_bytes_image, __wt_cache_bytes_image(cache));
+ WT_STAT_SET(
+ session, stats, cache_pages_inuse, __wt_cache_pages_inuse(cache));
WT_STAT_SET(
session, stats, cache_bytes_internal, cache->bytes_internal);
+ WT_STAT_SET(session, stats, cache_bytes_leaf, leaf);
+ WT_STAT_SET(
+ session, stats, cache_bytes_other, __wt_cache_bytes_other(cache));
WT_STAT_SET(
session, stats, cache_bytes_overflow, cache->bytes_overflow);
- WT_STAT_SET(session, stats, cache_bytes_leaf, leaf);
+
+ WT_STAT_SET(session, stats,
+ cache_eviction_maximum_page_size, cache->evict_max_page_size);
+ WT_STAT_SET(session, stats, cache_pages_dirty, cache->pages_dirty);
/*
* The number of files with active walks ~= number of hazard pointers
@@ -286,6 +294,7 @@ __wt_cache_destroy(WT_SESSION_IMPL *session)
__wt_spin_destroy(session, &cache->evict_queues[i].evict_lock);
__wt_free(session, cache->evict_queues[i].evict_queue);
}
+
__wt_free(session, conn->cache);
return (ret);
}
diff --git a/src/evict/evict_lru.c b/src/evict/evict_lru.c
index 7eb35b6554e..4be1aab8181 100644
--- a/src/evict/evict_lru.c
+++ b/src/evict/evict_lru.c
@@ -529,6 +529,9 @@ __evict_update_work(WT_SESSION_IMPL *session)
if (!F_ISSET(conn, WT_CONN_EVICTION_RUN))
return (false);
+ if (cache->evict_queues[WT_EVICT_URGENT_QUEUE].evict_current != NULL)
+ goto done;
+
/*
* Setup the number of refs to consider in each handle, depending
* on how many handles are open. We want to consider less candidates
@@ -549,7 +552,7 @@ __evict_update_work(WT_SESSION_IMPL *session)
bytes_max = conn->cache_size + 1;
bytes_inuse = __wt_cache_bytes_inuse(cache);
if (bytes_inuse > (cache->eviction_target * bytes_max) / 100) {
- FLD_SET(cache->state, WT_EVICT_PASS_ALL);
+ FLD_SET(cache->state, WT_EVICT_STATE_ALL);
goto done;
}
@@ -562,19 +565,7 @@ __evict_update_work(WT_SESSION_IMPL *session)
dirty_inuse = __wt_cache_dirty_inuse(cache);
if (dirty_inuse > (cache->eviction_dirty_target * bytes_max) / 100) {
- FLD_SET(cache->state, WT_EVICT_PASS_DIRTY);
- goto done;
- }
-
- /*
- * Evict pages with oldest generation (which would otherwise block
- * application threads), set regardless of whether we have reached
- * the eviction trigger.
- */
- if (F_ISSET(cache, WT_CACHE_WOULD_BLOCK)) {
- FLD_SET(cache->state, WT_EVICT_PASS_WOULD_BLOCK);
-
- F_CLR(cache, WT_CACHE_WOULD_BLOCK);
+ FLD_SET(cache->state, WT_EVICT_STATE_DIRTY);
goto done;
}
@@ -583,7 +574,7 @@ __evict_update_work(WT_SESSION_IMPL *session)
done: if (F_ISSET(cache, WT_CACHE_STUCK)) {
WT_STAT_FAST_CONN_SET(session,
cache_eviction_aggressive_set, 1);
- FLD_SET(cache->state, WT_EVICT_PASS_AGGRESSIVE);
+ FLD_SET(cache->state, WT_EVICT_STATE_AGGRESSIVE);
}
return (true);
}
@@ -643,15 +634,15 @@ __evict_pass(WT_SESSION_IMPL *session)
if (loop > 10) {
WT_STAT_FAST_CONN_SET(session,
cache_eviction_aggressive_set, 1);
- FLD_SET(cache->state, WT_EVICT_PASS_AGGRESSIVE);
+ FLD_SET(cache->state, WT_EVICT_STATE_AGGRESSIVE);
}
/*
* Start a worker if we have capacity and we haven't reached
* the eviction targets.
*/
- if (FLD_ISSET(cache->state, WT_EVICT_PASS_ALL |
- WT_EVICT_PASS_DIRTY | WT_EVICT_PASS_WOULD_BLOCK) &&
+ if (FLD_ISSET(cache->state,
+ WT_EVICT_STATE_ALL | WT_EVICT_STATE_DIRTY) &&
conn->evict_workers < conn->evict_workers_max) {
WT_RET(__wt_verbose(session, WT_VERB_EVICTSERVER,
"Starting evict worker: %"PRIu32"\n",
@@ -692,15 +683,12 @@ __evict_pass(WT_SESSION_IMPL *session)
* Mark the cache as stuck if we need space
* and aren't evicting any pages.
*/
- if (!FLD_ISSET(cache->state,
- WT_EVICT_PASS_WOULD_BLOCK)) {
- F_SET(cache, WT_CACHE_STUCK);
- WT_STAT_FAST_CONN_INCR(
- session, cache_eviction_slow);
- WT_RET(__wt_verbose(
- session, WT_VERB_EVICTSERVER,
- "unable to reach eviction goal"));
- }
+ F_SET(cache, WT_CACHE_STUCK);
+ WT_STAT_FAST_CONN_INCR(
+ session, cache_eviction_slow);
+ WT_RET(__wt_verbose(
+ session, WT_VERB_EVICTSERVER,
+ "unable to reach eviction goal"));
break;
}
} else {
@@ -923,27 +911,29 @@ __evict_lru_walk(WT_SESSION_IMPL *session)
{
WT_CACHE *cache;
WT_DECL_RET;
- WT_EVICT_QUEUE *evict_queue;
+ WT_EVICT_QUEUE *queue;
uint64_t read_gen_oldest;
uint32_t candidates, entries, queue_index;
cache = S2C(session)->cache;
- queue_index = cache->evict_queue_fill++ % WT_EVICT_QUEUE_MAX;
- evict_queue = &cache->evict_queues[queue_index];
+ /* Fill the next queue (that isn't the urgent queue). */
+ queue_index =
+ 1 + (cache->evict_queue_fill++ % (WT_EVICT_QUEUE_MAX - 1));
+ queue = &cache->evict_queues[queue_index];
/* Get some more pages to consider for eviction. */
if ((ret = __evict_walk(cache->walk_session, queue_index)) != 0)
return (ret == EBUSY ? 0 : ret);
/* Sort the list into LRU order and restart. */
- __wt_spin_lock(session, &evict_queue->evict_lock);
+ __wt_spin_lock(session, &queue->evict_lock);
- entries = evict_queue->evict_entries;
- qsort(evict_queue->evict_queue,
+ entries = queue->evict_entries;
+ qsort(queue->evict_queue,
entries, sizeof(WT_EVICT_ENTRY), __evict_lru_cmp);
- while (entries > 0 && evict_queue->evict_queue[entries - 1].ref == NULL)
+ while (entries > 0 && queue->evict_queue[entries - 1].ref == NULL)
--entries;
/*
@@ -953,9 +943,9 @@ __evict_lru_walk(WT_SESSION_IMPL *session)
*/
while (entries > WT_EVICT_WALK_BASE)
__evict_list_clear(session,
- &evict_queue->evict_queue[--entries]);
+ &queue->evict_queue[--entries]);
- evict_queue->evict_entries = entries;
+ queue->evict_entries = entries;
if (entries == 0) {
/*
@@ -963,23 +953,19 @@ __evict_lru_walk(WT_SESSION_IMPL *session)
* Make sure application threads don't read past the end of the
* candidate list, or they may race with the next walk.
*/
- evict_queue->evict_candidates = 0;
- __wt_spin_unlock(session, &evict_queue->evict_lock);
- __wt_spin_lock(session, &cache->evict_queue_lock);
- cache->evict_current = NULL;
- cache->evict_current_queue = NULL;
- __wt_spin_unlock(session, &cache->evict_queue_lock);
+ queue->evict_candidates = 0;
+ queue->evict_current = NULL;
+ __wt_spin_unlock(session, &queue->evict_lock);
return (0);
}
/* Decide how many of the candidates we're going to try and evict. */
- if (FLD_ISSET(cache->state,
- WT_EVICT_PASS_AGGRESSIVE | WT_EVICT_PASS_WOULD_BLOCK)) {
+ if (FLD_ISSET(cache->state, WT_EVICT_STATE_AGGRESSIVE)) {
/*
* Take all candidates if we only gathered pages with an oldest
* read generation set.
*/
- evict_queue->evict_candidates = entries;
+ queue->evict_candidates = entries;
} else {
/*
* Find the oldest read generation we have in the queue, used
@@ -989,7 +975,7 @@ __evict_lru_walk(WT_SESSION_IMPL *session)
read_gen_oldest = WT_READGEN_OLDEST;
for (candidates = 0; candidates < entries; ++candidates) {
read_gen_oldest =
- evict_queue->evict_queue[candidates].score;
+ queue->evict_queue[candidates].score;
if (read_gen_oldest != WT_READGEN_OLDEST)
break;
}
@@ -1003,9 +989,9 @@ __evict_lru_walk(WT_SESSION_IMPL *session)
* all of them.
*/
if (read_gen_oldest == WT_READGEN_OLDEST)
- evict_queue->evict_candidates = entries;
+ queue->evict_candidates = entries;
else if (candidates > entries / 2)
- evict_queue->evict_candidates = candidates;
+ queue->evict_candidates = candidates;
else {
/*
* Take all of the urgent pages plus a third of
@@ -1018,24 +1004,25 @@ __evict_lru_walk(WT_SESSION_IMPL *session)
* normal when populating an empty file, don't exclude
* it.
*/
- evict_queue->evict_candidates =
+ queue->evict_candidates =
1 + candidates + ((entries - candidates) - 1) / 3;
cache->read_gen_oldest = read_gen_oldest;
}
}
- __wt_spin_unlock(session, &evict_queue->evict_lock);
+ queue->evict_current = queue->evict_queue;
+ __wt_spin_unlock(session, &queue->evict_lock);
+
/*
* Now we can set the next queue.
*/
__wt_spin_lock(session, &cache->evict_queue_lock);
- if (cache->evict_current == NULL)
+ if (cache->evict_current_queue->evict_current == NULL)
WT_STAT_FAST_CONN_INCR(session, cache_eviction_queue_empty);
else
WT_STAT_FAST_CONN_INCR(session, cache_eviction_queue_not_empty);
- cache->evict_current = evict_queue->evict_queue;
- cache->evict_current_queue = evict_queue;
+ cache->evict_current_queue = queue;
__wt_spin_unlock(session, &cache->evict_queue_lock);
/*
@@ -1059,7 +1046,7 @@ __evict_walk(WT_SESSION_IMPL *session, uint32_t queue_index)
WT_CONNECTION_IMPL *conn;
WT_DATA_HANDLE *dhandle;
WT_DECL_RET;
- WT_EVICT_QUEUE *evict_queue;
+ WT_EVICT_QUEUE *queue;
u_int max_entries, prev_slot, retries, slot, start_slot, spins;
bool dhandle_locked, incr;
@@ -1074,8 +1061,8 @@ __evict_walk(WT_SESSION_IMPL *session, uint32_t queue_index)
* Set the starting slot in the queue and the maximum pages added
* per walk.
*/
- evict_queue = &cache->evict_queues[queue_index];
- start_slot = slot = evict_queue->evict_entries;
+ queue = &cache->evict_queues[queue_index];
+ start_slot = slot = queue->evict_entries;
max_entries = WT_MIN(slot + WT_EVICT_WALK_INCR, cache->evict_slots);
retry: while (slot < max_entries && ret == 0) {
@@ -1146,7 +1133,7 @@ retry: while (slot < max_entries && ret == 0) {
*/
if ((btree->checkpointing != WT_CKPT_OFF ||
btree->evict_priority != 0) &&
- !FLD_ISSET(cache->state, WT_EVICT_PASS_AGGRESSIVE))
+ !FLD_ISSET(cache->state, WT_EVICT_STATE_AGGRESSIVE))
continue;
/* Skip files if we have used all available hazard pointers. */
@@ -1221,40 +1208,49 @@ retry: while (slot < max_entries && ret == 0) {
if (cache->pass_intr == 0 && ret == 0 &&
slot < max_entries && (retries < 2 ||
(retries < 10 &&
- !FLD_ISSET(cache->state, WT_EVICT_PASS_WOULD_BLOCK) &&
- (slot == evict_queue->evict_entries || slot > start_slot)))) {
+ (slot == queue->evict_entries || slot > start_slot)))) {
start_slot = slot;
++retries;
goto retry;
}
- evict_queue->evict_entries = slot;
+ queue->evict_entries = slot;
return (ret);
}
/*
- * __evict_init_candidate --
+ * __evict_push_candidate --
* Initialize a WT_EVICT_ENTRY structure with a given page.
*/
-static void
-__evict_init_candidate(WT_SESSION_IMPL *session,
- WT_EVICT_QUEUE *evict_queue, WT_EVICT_ENTRY *evict, WT_REF *ref)
+static bool
+__evict_push_candidate(WT_SESSION_IMPL *session,
+ WT_EVICT_QUEUE *queue, WT_EVICT_ENTRY *evict, WT_REF *ref)
{
u_int slot;
+ uint8_t orig_flags, new_flags;
+
+ /*
+ * Threads can race to queue a page (e.g., an ordinary LRU walk can
+ * race with a page being queued for urgent eviction.
+ */
+ orig_flags = new_flags = ref->page->flags_atomic;
+ FLD_SET(new_flags, WT_PAGE_EVICT_LRU);
+ if (orig_flags == new_flags ||
+ !__wt_atomic_cas8(&ref->page->flags_atomic, orig_flags, new_flags))
+ return (false);
/* Keep track of the maximum slot we are using. */
- slot = (u_int)(evict - evict_queue->evict_queue);
- if (slot >= evict_queue->evict_max)
- evict_queue->evict_max = slot + 1;
+ slot = (u_int)(evict - queue->evict_queue);
+ if (slot >= queue->evict_max)
+ queue->evict_max = slot + 1;
if (evict->ref != NULL)
__evict_list_clear(session, evict);
+
evict->btree = S2BT(session);
evict->ref = ref;
evict->score = __evict_read_gen(evict);
-
- /* Mark the page on the list; set last to flush the other updates. */
- F_SET_ATOMIC(ref->page, WT_PAGE_EVICT_LRU);
+ return (true);
}
/*
@@ -1270,7 +1266,7 @@ __evict_walk_file(WT_SESSION_IMPL *session,
WT_CONNECTION_IMPL *conn;
WT_DECL_RET;
WT_EVICT_ENTRY *end, *evict, *start;
- WT_EVICT_QUEUE *evict_queue;
+ WT_EVICT_QUEUE *queue;
WT_PAGE *page;
WT_PAGE_MODIFY *mod;
WT_REF *ref;
@@ -1283,7 +1279,7 @@ __evict_walk_file(WT_SESSION_IMPL *session,
conn = S2C(session);
btree = S2BT(session);
cache = conn->cache;
- evict_queue = &cache->evict_queues[queue_index];
+ queue = &cache->evict_queues[queue_index];
internal_pages = restarts = 0;
enough = false;
@@ -1291,11 +1287,11 @@ __evict_walk_file(WT_SESSION_IMPL *session,
* Figure out how many slots to fill from this tree.
* Note that some care is taken in the calculation to avoid overflow.
*/
- start = evict_queue->evict_queue + *slotp;
+ start = queue->evict_queue + *slotp;
remaining_slots = max_entries - *slotp;
btree_inuse = __wt_btree_bytes_inuse(session);
cache_inuse = __wt_cache_bytes_inuse(cache);
- total_slots = max_entries - evict_queue->evict_entries;
+ total_slots = max_entries - queue->evict_entries;
/*
* The target number of pages for this tree is proportional to the
@@ -1395,25 +1391,17 @@ __evict_walk_file(WT_SESSION_IMPL *session,
goto fast;
}
if (__wt_page_is_empty(page) ||
- F_ISSET(session->dhandle, WT_DHANDLE_DEAD))
+ F_ISSET(session->dhandle, WT_DHANDLE_DEAD) ||
+ FLD_ISSET(cache->state, WT_EVICT_STATE_AGGRESSIVE))
goto fast;
/* Skip clean pages if appropriate. */
if (!modified && (F_ISSET(conn, WT_CONN_IN_MEMORY) ||
- FLD_ISSET(cache->state, WT_EVICT_PASS_DIRTY)))
- continue;
-
- /*
- * If we are only trickling out pages marked for definite
- * eviction, skip anything that isn't marked.
- */
- if (FLD_ISSET(cache->state, WT_EVICT_PASS_WOULD_BLOCK) &&
- page->memory_footprint < btree->splitmempage)
+ FLD_ISSET(cache->state, WT_EVICT_STATE_DIRTY)))
continue;
- /* Limit internal pages to 50% unless we get aggressive. */
+ /* Limit internal pages to 50% of the total. */
if (WT_PAGE_IS_INTERNAL(page) &&
- !FLD_ISSET(cache->state, WT_EVICT_PASS_AGGRESSIVE) &&
internal_pages >= (int)(evict - start) / 2)
continue;
@@ -1437,8 +1425,7 @@ fast: /* If the page can't be evicted, give up. */
* configure lookaside table writes in reconciliation, allowing
* us to evict pages we can't usually evict.
*/
- if (!FLD_ISSET(cache->state,
- WT_EVICT_PASS_AGGRESSIVE | WT_EVICT_PASS_WOULD_BLOCK)) {
+ if (!FLD_ISSET(cache->state, WT_EVICT_STATE_AGGRESSIVE)) {
/*
* If the page is clean but has modifications that
* appear too new to evict, skip it.
@@ -1449,7 +1436,8 @@ fast: /* If the page can't be evicted, give up. */
}
WT_ASSERT(session, evict->ref == NULL);
- __evict_init_candidate(session, evict_queue, evict, ref);
+ if (!__evict_push_candidate(session, queue, evict, ref))
+ continue;
++evict;
if (WT_PAGE_IS_INTERNAL(page))
@@ -1506,19 +1494,21 @@ __evict_check_entry_size(WT_SESSION_IMPL *session, WT_EVICT_ENTRY *entry)
cache = S2C(session)->cache;
- if (cache->pages_evict == 0)
+ if (cache->pages_evict == 0 || cache->bytes_evict < WT_MEGABYTE)
return (true);
max = (cache->bytes_evict / cache->pages_evict) * 4;
if ((ref = entry->ref) != NULL) {
if ((page = ref->page) == NULL)
return (true);
+
/*
- * If this page is more than four times the average evicted page
- * size then return false. Return true in all other cases.
- * XXX Should we care here if the page is dirty? Probably...
+ * If this page is dirty and more than four times the average
+ * evicted page size then return false. Return true in all
+ * other cases.
*/
- if (page->memory_footprint > max) {
+ if (__wt_page_is_modified(page) &&
+ page->memory_footprint > max) {
WT_STAT_FAST_CONN_INCR(
session, cache_eviction_server_toobig);
return (false);
@@ -1537,72 +1527,82 @@ __evict_get_ref(
{
WT_CACHE *cache;
WT_EVICT_ENTRY *evict;
- WT_EVICT_QUEUE *evict_queue;
+ WT_EVICT_QUEUE *queue, *urgent_queue;
uint32_t candidates;
cache = S2C(session)->cache;
+ urgent_queue = &cache->evict_queues[WT_EVICT_URGENT_QUEUE];
*btreep = NULL;
*refp = NULL;
- /*
- * Avoid the LRU lock if no pages are available.
- */
+ /* Avoid the LRU lock if no pages are available. */
WT_STAT_FAST_CONN_INCR(session, cache_eviction_get_ref);
- if (cache->evict_current == NULL) {
+ if (cache->evict_current_queue->evict_current == NULL &&
+ urgent_queue->evict_current == NULL) {
WT_STAT_FAST_CONN_INCR(session, cache_eviction_get_ref_empty);
return (WT_NOTFOUND);
}
__wt_spin_lock(session, &cache->evict_queue_lock);
+
+ /* Check the urgent queue first. */
+ queue = urgent_queue->evict_current != NULL &&
+ (FLD_ISSET(cache->state, WT_EVICT_STATE_AGGRESSIVE) ||
+ (F_ISSET(session, WT_SESSION_INTERNAL) &&
+ (!is_server || S2C(session)->evict_workers <= 1))) ?
+ urgent_queue : cache->evict_current_queue;
+
+ __wt_spin_unlock(session, &cache->evict_queue_lock);
+
/*
- * Verify there are still pages available.
+ * Only evict half of the pages before looking for more. The remainder
+ * are left to eviction workers (if configured), or application threads
+ * if necessary.
*/
- if (cache->evict_current == NULL) {
- __wt_spin_unlock(session, &cache->evict_queue_lock);
- WT_STAT_FAST_CONN_INCR(session, cache_eviction_get_ref_empty2);
- return (WT_NOTFOUND);
- }
+ candidates = queue->evict_candidates;
+ if (is_server && queue != urgent_queue && candidates > 1)
+ candidates /= 2;
/*
- * We got the queue lock, which should be fast, and now we want to
- * get the lock on the individual queue. We know that the shared
- * queue fields cannot change now.
+ * We got the queue lock, which should be fast, and chose a queue.
+ * Now we want to get the lock on the individual queue.
*/
- evict_queue = cache->evict_current_queue;
for (;;) {
- if (__wt_spin_trylock(session, &evict_queue->evict_lock) == 0)
- break;
- if (!F_ISSET(session, WT_SESSION_INTERNAL)) {
- __wt_spin_unlock(session, &cache->evict_queue_lock);
+ /* Verify there are still pages available. */
+ if (queue->evict_current == NULL ||
+ (queue->evict_current - queue->evict_queue) >= candidates) {
+ WT_STAT_FAST_CONN_INCR(
+ session, cache_eviction_get_ref_empty2);
return (WT_NOTFOUND);
}
- __wt_yield();
+ if (!is_server)
+ __wt_spin_lock(session, &queue->evict_lock);
+ else if (__wt_spin_trylock(
+ session, &queue->evict_lock) != 0)
+ continue;
+ break;
}
- /*
- * Only evict half of the pages before looking for more. The remainder
- * are left to eviction workers (if configured), or application threads
- * if necessary.
- */
- candidates = evict_queue->evict_candidates;
- if (is_server && candidates > 1)
- candidates /= 2;
-
/* Get the next page queued for eviction. */
- for (evict = cache->evict_current;
- evict >= evict_queue->evict_queue &&
- evict < evict_queue->evict_queue + candidates;
+ for (evict = queue->evict_current;
+ evict >= queue->evict_queue &&
+ evict < queue->evict_queue + candidates;
++evict) {
if (evict->ref == NULL)
continue;
WT_ASSERT(session, evict->btree != NULL);
+
/*
- * If the server is helping out and encounters an entry that
- * is too large, it stops helping. Evicting a very large
- * page in the server thread could stall eviction from finding
- * new work.
+ * If the server is helping out and encounters an entry that is
+ * too large, it stops helping. Evicting a very large page in
+ * the server thread could stall eviction from finding new
+ * work.
+ *
+ * However, we can't skip entries in the urgent queue or they
+ * may never be found again.
*/
- if (is_server && S2C(session)->evict_workers > 1 &&
+ if (is_server && queue != urgent_queue &&
+ S2C(session)->evict_workers > 1 &&
!__evict_check_entry_size(session, evict))
continue;
@@ -1634,14 +1634,14 @@ __evict_get_ref(
break;
}
- /* Clear the current pointer if there are no more candidates. */
- if (evict == NULL || evict + 1 >=
- evict_queue->evict_queue + evict_queue->evict_candidates)
- cache->evict_current = NULL;
- else
- cache->evict_current = evict + 1;
- __wt_spin_unlock(session, &evict_queue->evict_lock);
- __wt_spin_unlock(session, &cache->evict_queue_lock);
+ /* Move to the next item. */
+ if (evict != NULL && evict + 1 <
+ queue->evict_queue + queue->evict_candidates)
+ queue->evict_current = evict + 1;
+ else /* Clear the current pointer if there are no more candidates. */
+ queue->evict_current = NULL;
+
+ __wt_spin_unlock(session, &queue->evict_lock);
return ((*refp == NULL) ? WT_NOTFOUND : 0);
}
@@ -1799,6 +1799,59 @@ __wt_cache_eviction_worker(WT_SESSION_IMPL *session, bool busy, u_int pct_full)
}
/*
+ * __wt_page_evict_soon --
+ * Set a page to be evicted as soon as possible.
+ */
+int
+__wt_page_evict_soon(WT_SESSION_IMPL *session, WT_REF *ref)
+{
+ WT_CACHE *cache;
+ WT_EVICT_ENTRY *evict;
+ WT_EVICT_QUEUE *urgent_queue;
+ WT_PAGE *page;
+ bool queued;
+
+ page = ref->page;
+ page->read_gen = WT_READGEN_OLDEST;
+ if (F_ISSET_ATOMIC(page, WT_PAGE_EVICT_LRU) ||
+ F_ISSET(S2BT(session), WT_BTREE_NO_EVICTION))
+ return (0);
+
+ /* Append to the urgent queue if we can. */
+ cache = S2C(session)->cache;
+ urgent_queue = &cache->evict_queues[WT_EVICT_URGENT_QUEUE];
+ queued = false;
+
+ __wt_spin_lock(session, &cache->evict_queue_lock);
+ if (F_ISSET_ATOMIC(page, WT_PAGE_EVICT_LRU) ||
+ F_ISSET(S2BT(session), WT_BTREE_NO_EVICTION))
+ goto done;
+
+ __wt_spin_lock(session, &urgent_queue->evict_lock);
+ if (urgent_queue->evict_current == NULL) {
+ urgent_queue->evict_current = urgent_queue->evict_queue;
+ urgent_queue->evict_candidates = 0;
+ }
+ evict = urgent_queue->evict_queue + urgent_queue->evict_candidates;
+ if (evict < urgent_queue->evict_queue + WT_EVICT_QUEUE_MAX &&
+ __evict_push_candidate(session, urgent_queue, evict, ref)) {
+ ++urgent_queue->evict_candidates;
+ queued = true;
+ }
+ __wt_spin_unlock(session, &urgent_queue->evict_lock);
+
+done: __wt_spin_unlock(session, &cache->evict_queue_lock);
+ if (queued) {
+ if (S2C(session)->evict_workers > 1)
+ WT_RET(__wt_cond_signal(
+ session, cache->evict_waiter_cond));
+ else
+ WT_RET(__wt_evict_server_wake(session));
+ }
+ return (0);
+}
+
+/*
* __wt_evict_priority_set --
* Set a tree's eviction priority.
*/
diff --git a/src/evict/evict_page.c b/src/evict/evict_page.c
index 305b81fe69e..f5c900684a3 100644
--- a/src/evict/evict_page.c
+++ b/src/evict/evict_page.c
@@ -10,7 +10,7 @@
static int __evict_page_clean_update(WT_SESSION_IMPL *, WT_REF *, bool);
static int __evict_page_dirty_update(WT_SESSION_IMPL *, WT_REF *, bool);
-static int __evict_review(WT_SESSION_IMPL *, WT_REF *, bool *, bool);
+static int __evict_review(WT_SESSION_IMPL *, WT_REF *, uint32_t *, bool);
/*
* __evict_exclusive_clear --
@@ -46,6 +46,55 @@ __evict_exclusive(WT_SESSION_IMPL *session, WT_REF *ref)
}
/*
+ * __wt_page_release_evict --
+ * Release a reference to a page, and attempt to immediately evict it.
+ */
+int
+__wt_page_release_evict(WT_SESSION_IMPL *session, WT_REF *ref)
+{
+ WT_BTREE *btree;
+ WT_DECL_RET;
+ WT_PAGE *page;
+ bool locked, too_big;
+
+ btree = S2BT(session);
+ page = ref->page;
+
+ /*
+ * Take some care with order of operations: if we release the hazard
+ * reference without first locking the page, it could be evicted in
+ * between.
+ */
+ locked = __wt_atomic_casv32(&ref->state, WT_REF_MEM, WT_REF_LOCKED);
+ if ((ret = __wt_hazard_clear(session, page)) != 0 || !locked) {
+ if (locked)
+ ref->state = WT_REF_MEM;
+ return (ret == 0 ? EBUSY : ret);
+ }
+
+ (void)__wt_atomic_addv32(&btree->evict_busy, 1);
+
+ too_big = page->memory_footprint > btree->splitmempage;
+ if ((ret = __wt_evict(session, ref, false)) == 0) {
+ if (too_big)
+ WT_STAT_FAST_CONN_INCR(session, cache_eviction_force);
+ else
+ /*
+ * If the page isn't too big, we are evicting it because
+ * it had a chain of deleted entries that make traversal
+ * expensive.
+ */
+ WT_STAT_FAST_CONN_INCR(
+ session, cache_eviction_force_delete);
+ } else
+ WT_STAT_FAST_CONN_INCR(session, cache_eviction_force_fail);
+
+ (void)__wt_atomic_subv32(&btree->evict_busy, 1);
+
+ return (ret);
+}
+
+/*
* __wt_evict --
* Evict a page.
*/
@@ -56,7 +105,8 @@ __wt_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool closing)
WT_DECL_RET;
WT_PAGE *page;
WT_PAGE_MODIFY *mod;
- bool clean_page, forced_eviction, inmem_split, tree_dead;
+ uint32_t flags;
+ bool clean_page, tree_dead;
conn = S2C(session);
@@ -64,8 +114,6 @@ __wt_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool closing)
WT_ASSERT(session, !WT_SESSION_IS_CHECKPOINT(session));
page = ref->page;
- forced_eviction = page->read_gen == WT_READGEN_OLDEST;
- inmem_split = false;
tree_dead = F_ISSET(session->dhandle, WT_DHANDLE_DEAD);
WT_RET(__wt_verbose(session, WT_VERB_EVICT,
@@ -78,14 +126,14 @@ __wt_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool closing)
* to make this check for clean pages, too: while unlikely eviction
* would choose an internal page with children, it's not disallowed.
*/
- WT_ERR(__evict_review(session, ref, &inmem_split, closing));
+ WT_ERR(__evict_review(session, ref, &flags, closing));
/*
* If there was an in-memory split, the tree has been left in the state
* we want: there is nothing more to do.
*/
- if (inmem_split)
- goto done;
+ if (LF_ISSET(WT_EVICT_INMEM_SPLIT))
+ return (0);
/*
* Update the page's modification reference, reconciliation might have
@@ -113,7 +161,7 @@ __wt_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool closing)
/* Update the reference and discard the page. */
if (__wt_ref_is_root(ref))
__wt_ref_out(session, ref);
- else if (tree_dead || (clean_page && !F_ISSET(conn, WT_CONN_IN_MEMORY)))
+ else if (tree_dead || (clean_page && !LF_ISSET(WT_EVICT_IN_MEMORY)))
/*
* Pages that belong to dead trees never write back to disk
* and can't support page splits.
@@ -139,14 +187,9 @@ err: if (!closing)
WT_STAT_FAST_DATA_INCR(session, cache_eviction_fail);
}
-done: if (((inmem_split && ret == 0) || (forced_eviction && ret == EBUSY)) &&
- !F_ISSET(conn->cache, WT_CACHE_WOULD_BLOCK)) {
- F_SET(conn->cache, WT_CACHE_WOULD_BLOCK);
- WT_TRET(__wt_evict_server_wake(session));
- }
-
return (ret);
}
+
/*
* __evict_delete_ref --
* Mark a page reference deleted and check if the parent can reverse
@@ -210,13 +253,6 @@ __evict_page_clean_update(WT_SESSION_IMPL *session, WT_REF *ref, bool closing)
WT_DECL_RET;
/*
- * If doing normal system eviction, but only in the service of reducing
- * the number of dirty pages, leave the clean page in cache.
- */
- if (!closing && __wt_eviction_dirty_target(session))
- return (EBUSY);
-
- /*
* Discard the page and update the reference structure; if the page has
* an address, it's a disk page; if it has no address, it's a deleted
* page re-instantiated (for example, by searching) and never written.
@@ -291,17 +327,6 @@ __evict_page_dirty_update(WT_SESSION_IMPL *session, WT_REF *ref, bool closing)
break;
case WT_PM_REC_REPLACE: /* 1-for-1 page swap */
/*
- * If doing normal system eviction, but only in the service of
- * reducing the number of dirty pages, leave the clean page in
- * cache. Only do this when replacing a page with another one,
- * because when a page splits into multiple pages, we want to
- * push it out of cache (and read it back in, when needed), we
- * would rather have more, smaller pages than fewer large pages.
- */
- if (!closing && __wt_eviction_dirty_target(session))
- return (EBUSY);
-
- /*
* Update the parent to reference the replacement page.
*
* Publish: a barrier to ensure the structure fields are set
@@ -351,13 +376,19 @@ __evict_child_check(WT_SESSION_IMPL *session, WT_REF *parent)
*/
static int
__evict_review(
- WT_SESSION_IMPL *session, WT_REF *ref, bool *inmem_splitp, bool closing)
+ WT_SESSION_IMPL *session, WT_REF *ref, uint32_t *flagsp, bool closing)
{
+ WT_CACHE *cache;
WT_DECL_RET;
WT_PAGE *page;
uint32_t flags;
bool modified;
+ flags = WT_EVICTING;
+ if (closing)
+ LF_SET(WT_VISIBILITY_ERR);
+ *flagsp = flags;
+
/*
* Get exclusive access to the page if our caller doesn't have the tree
* locked down.
@@ -423,8 +454,9 @@ __evict_review(
WT_RET(__wt_txn_update_oldest(
session, WT_TXN_OLDEST_STRICT));
- if (!__wt_page_can_evict(session, ref, inmem_splitp))
+ if (!__wt_page_can_evict(session, ref, flagsp))
return (EBUSY);
+ flags = *flagsp;
/*
* Check for an append-only workload needing an in-memory
@@ -433,7 +465,7 @@ __evict_review(
* the page stays in memory and the tree is left in the desired
* state: avoid the usual cleanup.
*/
- if (*inmem_splitp)
+ if (LF_ISSET(WT_EVICT_INMEM_SPLIT))
return (__wt_split_insert(session, ref));
}
@@ -464,17 +496,17 @@ __evict_review(
* Don't set the update-restore or lookaside table flags for internal
* pages, they don't have update lists that can be saved and restored.
*/
- flags = WT_EVICTING;
- if (closing)
- LF_SET(WT_VISIBILITY_ERR);
- else if (!WT_PAGE_IS_INTERNAL(page)) {
+ cache = S2C(session)->cache;
+ if (!closing && !WT_PAGE_IS_INTERNAL(page)) {
if (F_ISSET(S2C(session), WT_CONN_IN_MEMORY))
LF_SET(WT_EVICT_IN_MEMORY | WT_EVICT_UPDATE_RESTORE);
- else if (page->read_gen == WT_READGEN_OLDEST)
+ else if (page->read_gen == WT_READGEN_OLDEST ||
+ page->memory_footprint > S2BT(session)->splitmempage)
LF_SET(WT_EVICT_UPDATE_RESTORE);
- else if (F_ISSET(S2C(session)->cache, WT_CACHE_STUCK))
+ else if (F_ISSET(cache, WT_CACHE_STUCK))
LF_SET(WT_EVICT_LOOKASIDE);
}
+ *flagsp = flags;
WT_RET(__wt_reconcile(session, ref, NULL, flags));
diff --git a/src/include/btree.i b/src/include/btree.i
index 84f2eff1b1b..c7950b4ea26 100644
--- a/src/include/btree.i
+++ b/src/include/btree.i
@@ -285,6 +285,34 @@ __wt_cache_dirty_decr(WT_SESSION_IMPL *session, WT_PAGE *page)
}
/*
+ * __wt_cache_page_image_decr --
+ * Decrement a page image's size to the cache.
+ */
+static inline void
+__wt_cache_page_image_decr(WT_SESSION_IMPL *session, uint32_t size)
+{
+ WT_CACHE *cache;
+
+ cache = S2C(session)->cache;
+
+ __wt_cache_decr_check_uint64(
+ session, &cache->bytes_image, size, "WT_CACHE.image_inmem");
+}
+
+/*
+ * __wt_cache_page_image_incr --
+ * Increment a page image's size to the cache.
+ */
+static inline void
+__wt_cache_page_image_incr(WT_SESSION_IMPL *session, uint32_t size)
+{
+ WT_CACHE *cache;
+
+ cache = S2C(session)->cache;
+ (void)__wt_atomic_add64(&cache->bytes_image, size);
+}
+
+/*
* __wt_cache_page_evict --
* Evict pages from the cache.
*/
@@ -343,16 +371,6 @@ __wt_update_list_memsize(WT_UPDATE *upd)
}
/*
- * __wt_page_evict_soon --
- * Set a page to be evicted as soon as possible.
- */
-static inline void
-__wt_page_evict_soon(WT_PAGE *page)
-{
- page->read_gen = WT_READGEN_OLDEST;
-}
-
-/*
* __wt_page_modify_init --
* A page is about to be modified, allocate the modification structure.
*/
@@ -1124,23 +1142,27 @@ __wt_leaf_page_can_split(WT_SESSION_IMPL *session, WT_PAGE *page)
* Check whether a page can be evicted.
*/
static inline bool
-__wt_page_can_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool *inmem_splitp)
+__wt_page_can_evict(
+ WT_SESSION_IMPL *session, WT_REF *ref, uint32_t *evict_flagsp)
{
WT_BTREE *btree;
WT_PAGE *page;
WT_PAGE_MODIFY *mod;
bool modified;
- if (inmem_splitp != NULL)
- *inmem_splitp = false;
+ if (evict_flagsp != NULL)
+ *evict_flagsp = WT_EVICTING;
btree = S2BT(session);
page = ref->page;
mod = page->modify;
/* Pages that have never been modified can always be evicted. */
- if (mod == NULL)
+ if (mod == NULL) {
+ if (evict_flagsp != NULL)
+ FLD_SET(*evict_flagsp, WT_EVICT_CLEAN);
return (true);
+ }
/*
* Check for in-memory splits before other eviction tests. If the page
@@ -1149,8 +1171,8 @@ __wt_page_can_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool *inmem_splitp)
* won't be written or discarded from the cache.
*/
if (__wt_leaf_page_can_split(session, page)) {
- if (inmem_splitp != NULL)
- *inmem_splitp = true;
+ if (evict_flagsp != NULL)
+ FLD_SET(*evict_flagsp, WT_EVICT_INMEM_SPLIT);
return (true);
}
@@ -1189,6 +1211,10 @@ __wt_page_can_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool *inmem_splitp)
F_ISSET_ATOMIC(page, WT_PAGE_SPLIT_BLOCK))
return (false);
+ /* If the cache is stuck, try anything else. */
+ if (F_ISSET(S2C(session)->cache, WT_CACHE_STUCK))
+ return (true);
+
/*
* If the oldest transaction hasn't changed since the last time
* this page was written, it's unlikely we can make progress.
@@ -1197,7 +1223,6 @@ __wt_page_can_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool *inmem_splitp)
* attempt to avoid repeated attempts to evict the same page.
*/
if (modified &&
- !F_ISSET(S2C(session)->cache, WT_CACHE_STUCK) &&
(mod->last_oldest_id == __wt_txn_oldest_id(session) ||
!__wt_txn_visible_all(session, mod->update_txn)))
return (false);
@@ -1206,56 +1231,6 @@ __wt_page_can_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool *inmem_splitp)
}
/*
- * __wt_page_release_evict --
- * Release a reference to a page, and attempt to immediately evict it.
- */
-static inline int
-__wt_page_release_evict(WT_SESSION_IMPL *session, WT_REF *ref)
-{
- WT_BTREE *btree;
- WT_DECL_RET;
- WT_PAGE *page;
- bool locked, too_big;
-
- btree = S2BT(session);
- page = ref->page;
-
- /*
- * Take some care with order of operations: if we release the hazard
- * reference without first locking the page, it could be evicted in
- * between.
- */
- locked = __wt_atomic_casv32(
- &ref->state, WT_REF_MEM, WT_REF_LOCKED) ? true : false;
- if ((ret = __wt_hazard_clear(session, page)) != 0 || !locked) {
- if (locked)
- ref->state = WT_REF_MEM;
- return (ret == 0 ? EBUSY : ret);
- }
-
- (void)__wt_atomic_addv32(&btree->evict_busy, 1);
-
- too_big = page->memory_footprint > btree->maxmempage;
- if ((ret = __wt_evict(session, ref, false)) == 0) {
- if (too_big)
- WT_STAT_FAST_CONN_INCR(session, cache_eviction_force);
- else
- /*
- * If the page isn't too big, we are evicting it because
- * it had a chain of deleted entries that make traversal
- * expensive.
- */
- WT_STAT_FAST_CONN_INCR(
- session, cache_eviction_force_delete);
- } else
- WT_STAT_FAST_CONN_INCR(session, cache_eviction_force_fail);
-
- (void)__wt_atomic_subv32(&btree->evict_busy, 1);
-
- return (ret);
-}
-
-/*
* __wt_page_release --
* Release a reference to a page.
*/
diff --git a/src/include/cache.h b/src/include/cache.h
index bfbb65878f8..dbc4074330a 100644
--- a/src/include/cache.h
+++ b/src/include/cache.h
@@ -26,7 +26,9 @@ struct __wt_evict_entry {
uint64_t score; /* Relative eviction priority */
};
-#define WT_EVICT_QUEUE_MAX 2
+#define WT_EVICT_URGENT_QUEUE 0 /* Urgent queue index */
+#define WT_EVICT_QUEUE_MAX 3 /* Urgent plus two ordinary queues */
+
/*
* WT_EVICT_QUEUE --
* Encapsulation of an eviction candidate queue.
@@ -34,6 +36,7 @@ struct __wt_evict_entry {
struct __wt_evict_queue {
WT_SPINLOCK evict_lock; /* Eviction LRU queue */
WT_EVICT_ENTRY *evict_queue; /* LRU pages being tracked */
+ WT_EVICT_ENTRY *evict_current; /* LRU current page to be evicted */
uint32_t evict_candidates; /* LRU list pages to evict */
uint32_t evict_entries; /* LRU entries in the queue */
volatile uint32_t evict_max; /* LRU maximum eviction slot used */
@@ -70,15 +73,16 @@ struct __wt_cache {
* be exact, they can't be garbage, we track what comes in and what goes
* out and calculate the difference as needed.
*/
+ uint64_t bytes_dirty; /* Bytes/pages currently dirty */
+ uint64_t pages_dirty;
+ uint64_t bytes_evict; /* Bytes/pages discarded by eviction */
+ 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 */
uint64_t pages_inmem;
uint64_t bytes_internal; /* Bytes of internal pages */
uint64_t bytes_overflow; /* Bytes of overflow pages */
- uint64_t bytes_evict; /* Bytes/pages discarded by eviction */
- uint64_t pages_evict;
- uint64_t pages_evicted; /* Pages evicted during a pass */
- uint64_t bytes_dirty; /* Bytes/pages currently dirty */
- uint64_t pages_dirty;
uint64_t bytes_read; /* Bytes read into memory */
uint64_t app_waits; /* User threads waited for cache */
@@ -121,7 +125,6 @@ struct __wt_cache {
WT_SPINLOCK evict_queue_lock; /* Eviction current queue lock */
WT_EVICT_QUEUE evict_queues[WT_EVICT_QUEUE_MAX];
WT_EVICT_QUEUE *evict_current_queue;/* LRU current queue in use */
- WT_EVICT_ENTRY *evict_current; /* LRU current page to be evicted */
uint32_t evict_queue_fill; /* LRU eviction queue index to fill */
uint32_t evict_slots; /* LRU list eviction slots */
WT_DATA_HANDLE
@@ -145,10 +148,9 @@ struct __wt_cache {
/*
* Work state.
*/
-#define WT_EVICT_PASS_AGGRESSIVE 0x01
-#define WT_EVICT_PASS_ALL 0x02
-#define WT_EVICT_PASS_DIRTY 0x04
-#define WT_EVICT_PASS_WOULD_BLOCK 0x08
+#define WT_EVICT_STATE_AGGRESSIVE 0x01
+#define WT_EVICT_STATE_ALL 0x02
+#define WT_EVICT_STATE_DIRTY 0x04
uint32_t state;
/*
* Pass interrupt counter.
@@ -162,7 +164,6 @@ struct __wt_cache {
#define WT_CACHE_POOL_RUN 0x02 /* Cache pool thread running */
#define WT_CACHE_STUCK 0x04 /* Eviction server is stuck */
#define WT_CACHE_WALK_REVERSE 0x08 /* Scan backwards for candidates */
-#define WT_CACHE_WOULD_BLOCK 0x10 /* Pages that would block apps */
uint32_t flags;
};
diff --git a/src/include/cache.i b/src/include/cache.i
index 72c8307756d..105dfd7202f 100644
--- a/src/include/cache.i
+++ b/src/include/cache.i
@@ -113,6 +113,50 @@ __wt_cache_dirty_inuse(WT_CACHE *cache)
}
/*
+ * __wt_cache_bytes_image --
+ * Return the number of page image bytes in use.
+ */
+static inline uint64_t
+__wt_cache_bytes_image(WT_CACHE *cache)
+{
+ uint64_t bytes_image;
+
+ bytes_image = cache->bytes_image;
+ if (cache->overhead_pct != 0)
+ bytes_image +=
+ (bytes_image * (uint64_t)cache->overhead_pct) / 100;
+
+ return (bytes_image);
+}
+
+/*
+ * __wt_cache_bytes_other --
+ * Return the number of bytes in use not for page images.
+ */
+static inline uint64_t
+__wt_cache_bytes_other(WT_CACHE *cache)
+{
+ uint64_t bytes_image, bytes_inmem, bytes_other;
+
+ bytes_image = cache->bytes_image;
+ bytes_inmem = cache->bytes_inmem;
+
+ /*
+ * The reads above could race with changes to the values, so protect
+ * against underflow.
+ */
+ if (bytes_image > bytes_inmem)
+ return (0);
+
+ bytes_other = bytes_inmem - bytes_image;
+ if (cache->overhead_pct != 0)
+ bytes_other +=
+ (bytes_other * (uint64_t)cache->overhead_pct) / 100;
+
+ return (bytes_other);
+}
+
+/*
* __wt_session_can_wait --
* Return if a session available for a potentially slow operation.
*/
@@ -139,17 +183,6 @@ __wt_session_can_wait(WT_SESSION_IMPL *session)
}
/*
- * __wt_eviction_dirty_target --
- * Return if the eviction server is running to reduce the number of dirty
- * pages (versus running to discard pages from the cache).
- */
-static inline bool
-__wt_eviction_dirty_target(WT_SESSION_IMPL *session)
-{
- return (FLD_ISSET(S2C(session)->cache->state, WT_EVICT_PASS_DIRTY));
-}
-
-/*
* __wt_eviction_needed --
* Return if an application thread should do eviction, and the cache full
* percentage as a side-effect.
@@ -186,14 +219,6 @@ __wt_eviction_needed(WT_SESSION_IMPL *session, u_int *pct_fullp)
pct_full = (u_int)((100 * bytes_inuse) / bytes_max);
if (pct_fullp != NULL)
*pct_fullp = pct_full;
- /*
- * If the connection is closing we do not need eviction from an
- * application thread. The eviction subsystem is already closed.
- * We return here because some callers depend on the percent full
- * having been filled in.
- */
- if (F_ISSET(conn, WT_CONN_CLOSING))
- return (false);
if (pct_full > cache->eviction_trigger)
return (true);
diff --git a/src/include/cursor.i b/src/include/cursor.i
index 553dd03f958..c7b6fdd88bc 100644
--- a/src/include/cursor.i
+++ b/src/include/cursor.i
@@ -120,7 +120,7 @@ __curfile_leave(WT_CURSOR_BTREE *cbt)
*/
if (cbt->ref != NULL &&
cbt->page_deleted_count > WT_BTREE_DELETE_THRESHOLD)
- __wt_page_evict_soon(cbt->ref->page);
+ __wt_page_evict_soon(session, cbt->ref);
cbt->page_deleted_count = 0;
/*
diff --git a/src/include/extern.h b/src/include/extern.h
index b0c0f6eccad..2340f1d66a0 100644
--- a/src/include/extern.h
+++ b/src/include/extern.h
@@ -346,9 +346,11 @@ extern int __wt_evict_destroy(WT_SESSION_IMPL *session);
extern int __wt_evict_file_exclusive_on(WT_SESSION_IMPL *session);
extern void __wt_evict_file_exclusive_off(WT_SESSION_IMPL *session);
extern int __wt_cache_eviction_worker(WT_SESSION_IMPL *session, bool busy, u_int pct_full);
+extern int __wt_page_evict_soon(WT_SESSION_IMPL *session, WT_REF *ref);
extern void __wt_evict_priority_set(WT_SESSION_IMPL *session, uint64_t v);
extern void __wt_evict_priority_clear(WT_SESSION_IMPL *session);
extern int __wt_cache_dump(WT_SESSION_IMPL *session, const char *ofile);
+extern int __wt_page_release_evict(WT_SESSION_IMPL *session, WT_REF *ref);
extern int __wt_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool closing);
extern int __wt_log_ckpt(WT_SESSION_IMPL *session, WT_LSN *ckp_lsn);
extern int __wt_log_flush_lsn(WT_SESSION_IMPL *session, WT_LSN *lsn, bool start);
diff --git a/src/include/flags.h b/src/include/flags.h
index f134af69d29..2145174ca6f 100644
--- a/src/include/flags.h
+++ b/src/include/flags.h
@@ -22,9 +22,11 @@
#define WT_CONN_SERVER_SWEEP 0x00020000
#define WT_CONN_WAS_BACKUP 0x00040000
#define WT_EVICTING 0x00000001
-#define WT_EVICT_IN_MEMORY 0x00000002
-#define WT_EVICT_LOOKASIDE 0x00000004
-#define WT_EVICT_UPDATE_RESTORE 0x00000008
+#define WT_EVICT_CLEAN 0x00000002
+#define WT_EVICT_INMEM_SPLIT 0x00000004
+#define WT_EVICT_IN_MEMORY 0x00000008
+#define WT_EVICT_LOOKASIDE 0x00000010
+#define WT_EVICT_UPDATE_RESTORE 0x00000020
#define WT_LOGSCAN_FIRST 0x00000001
#define WT_LOGSCAN_FROM_CKP 0x00000002
#define WT_LOGSCAN_ONE 0x00000004
@@ -100,7 +102,7 @@
#define WT_VERB_VERIFY 0x00800000
#define WT_VERB_VERSION 0x01000000
#define WT_VERB_WRITE 0x02000000
-#define WT_VISIBILITY_ERR 0x00000010
+#define WT_VISIBILITY_ERR 0x00000040
/*
* flags section: END
* DO NOT EDIT: automatically built by dist/flags.py.
diff --git a/src/include/stat.h b/src/include/stat.h
index 054d154f053..f64e3ce57a4 100644
--- a/src/include/stat.h
+++ b/src/include/stat.h
@@ -275,7 +275,9 @@ struct __wt_connection_stats {
int64_t block_byte_write;
int64_t block_map_read;
int64_t block_byte_map_read;
+ int64_t cache_bytes_image;
int64_t cache_bytes_inuse;
+ int64_t cache_bytes_other;
int64_t cache_bytes_read;
int64_t cache_bytes_write;
int64_t cache_eviction_checkpoint;
diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in
index 859b76d1367..4903185625a 100644
--- a/src/include/wiredtiger.in
+++ b/src/include/wiredtiger.in
@@ -4260,336 +4260,340 @@ extern int wiredtiger_extension_terminate(WT_CONNECTION *connection);
#define WT_STAT_CONN_BLOCK_MAP_READ 1028
/*! block-manager: mapped bytes read */
#define WT_STAT_CONN_BLOCK_BYTE_MAP_READ 1029
+/*! cache: bytes belonging to page images in the cache */
+#define WT_STAT_CONN_CACHE_BYTES_IMAGE 1030
/*! cache: bytes currently in the cache */
-#define WT_STAT_CONN_CACHE_BYTES_INUSE 1030
+#define WT_STAT_CONN_CACHE_BYTES_INUSE 1031
+/*! cache: bytes not belonging to page images in the cache */
+#define WT_STAT_CONN_CACHE_BYTES_OTHER 1032
/*! cache: bytes read into cache */
-#define WT_STAT_CONN_CACHE_BYTES_READ 1031
+#define WT_STAT_CONN_CACHE_BYTES_READ 1033
/*! cache: bytes written from cache */
-#define WT_STAT_CONN_CACHE_BYTES_WRITE 1032
+#define WT_STAT_CONN_CACHE_BYTES_WRITE 1034
/*! cache: checkpoint blocked page eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_CHECKPOINT 1033
+#define WT_STAT_CONN_CACHE_EVICTION_CHECKPOINT 1035
/*! cache: eviction calls to get a page */
-#define WT_STAT_CONN_CACHE_EVICTION_GET_REF 1034
+#define WT_STAT_CONN_CACHE_EVICTION_GET_REF 1036
/*! cache: eviction calls to get a page found queue empty */
-#define WT_STAT_CONN_CACHE_EVICTION_GET_REF_EMPTY 1035
+#define WT_STAT_CONN_CACHE_EVICTION_GET_REF_EMPTY 1037
/*! cache: eviction calls to get a page found queue empty after locking */
-#define WT_STAT_CONN_CACHE_EVICTION_GET_REF_EMPTY2 1036
+#define WT_STAT_CONN_CACHE_EVICTION_GET_REF_EMPTY2 1038
/*! cache: eviction currently operating in aggressive mode */
-#define WT_STAT_CONN_CACHE_EVICTION_AGGRESSIVE_SET 1037
+#define WT_STAT_CONN_CACHE_EVICTION_AGGRESSIVE_SET 1039
/*! cache: eviction server candidate queue empty when topping up */
-#define WT_STAT_CONN_CACHE_EVICTION_QUEUE_EMPTY 1038
+#define WT_STAT_CONN_CACHE_EVICTION_QUEUE_EMPTY 1040
/*! cache: eviction server candidate queue not empty when topping up */
-#define WT_STAT_CONN_CACHE_EVICTION_QUEUE_NOT_EMPTY 1039
+#define WT_STAT_CONN_CACHE_EVICTION_QUEUE_NOT_EMPTY 1041
/*! cache: eviction server evicting pages */
-#define WT_STAT_CONN_CACHE_EVICTION_SERVER_EVICTING 1040
+#define WT_STAT_CONN_CACHE_EVICTION_SERVER_EVICTING 1042
/*! cache: eviction server populating queue, but not evicting pages */
-#define WT_STAT_CONN_CACHE_EVICTION_SERVER_NOT_EVICTING 1041
+#define WT_STAT_CONN_CACHE_EVICTION_SERVER_NOT_EVICTING 1043
/*! cache: eviction server skipped very large page */
-#define WT_STAT_CONN_CACHE_EVICTION_SERVER_TOOBIG 1042
+#define WT_STAT_CONN_CACHE_EVICTION_SERVER_TOOBIG 1044
/*! cache: eviction server slept, because we did not make progress with
* eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_SERVER_SLEPT 1043
+#define WT_STAT_CONN_CACHE_EVICTION_SERVER_SLEPT 1045
/*! cache: eviction server unable to reach eviction goal */
-#define WT_STAT_CONN_CACHE_EVICTION_SLOW 1044
+#define WT_STAT_CONN_CACHE_EVICTION_SLOW 1046
/*! cache: eviction worker thread evicting pages */
-#define WT_STAT_CONN_CACHE_EVICTION_WORKER_EVICTING 1045
+#define WT_STAT_CONN_CACHE_EVICTION_WORKER_EVICTING 1047
/*! cache: failed eviction of pages that exceeded the in-memory maximum */
-#define WT_STAT_CONN_CACHE_EVICTION_FORCE_FAIL 1046
+#define WT_STAT_CONN_CACHE_EVICTION_FORCE_FAIL 1048
/*! cache: files with active eviction walks */
-#define WT_STAT_CONN_CACHE_EVICTION_WALKS_ACTIVE 1047
+#define WT_STAT_CONN_CACHE_EVICTION_WALKS_ACTIVE 1049
/*! cache: files with new eviction walks started */
-#define WT_STAT_CONN_CACHE_EVICTION_WALKS_STARTED 1048
+#define WT_STAT_CONN_CACHE_EVICTION_WALKS_STARTED 1050
/*! cache: hazard pointer blocked page eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_HAZARD 1049
+#define WT_STAT_CONN_CACHE_EVICTION_HAZARD 1051
/*! cache: hazard pointer check calls */
-#define WT_STAT_CONN_CACHE_HAZARD_CHECKS 1050
+#define WT_STAT_CONN_CACHE_HAZARD_CHECKS 1052
/*! cache: hazard pointer check entries walked */
-#define WT_STAT_CONN_CACHE_HAZARD_WALKS 1051
+#define WT_STAT_CONN_CACHE_HAZARD_WALKS 1053
/*! cache: hazard pointer maximum array length */
-#define WT_STAT_CONN_CACHE_HAZARD_MAX 1052
+#define WT_STAT_CONN_CACHE_HAZARD_MAX 1054
/*! cache: in-memory page passed criteria to be split */
-#define WT_STAT_CONN_CACHE_INMEM_SPLITTABLE 1053
+#define WT_STAT_CONN_CACHE_INMEM_SPLITTABLE 1055
/*! cache: in-memory page splits */
-#define WT_STAT_CONN_CACHE_INMEM_SPLIT 1054
+#define WT_STAT_CONN_CACHE_INMEM_SPLIT 1056
/*! cache: internal pages evicted */
-#define WT_STAT_CONN_CACHE_EVICTION_INTERNAL 1055
+#define WT_STAT_CONN_CACHE_EVICTION_INTERNAL 1057
/*! cache: internal pages split during eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_INTERNAL 1056
+#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_INTERNAL 1058
/*! cache: leaf pages split during eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_LEAF 1057
+#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_LEAF 1059
/*! cache: lookaside table insert calls */
-#define WT_STAT_CONN_CACHE_LOOKASIDE_INSERT 1058
+#define WT_STAT_CONN_CACHE_LOOKASIDE_INSERT 1060
/*! cache: lookaside table remove calls */
-#define WT_STAT_CONN_CACHE_LOOKASIDE_REMOVE 1059
+#define WT_STAT_CONN_CACHE_LOOKASIDE_REMOVE 1061
/*! cache: maximum bytes configured */
-#define WT_STAT_CONN_CACHE_BYTES_MAX 1060
+#define WT_STAT_CONN_CACHE_BYTES_MAX 1062
/*! cache: maximum page size at eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_MAXIMUM_PAGE_SIZE 1061
+#define WT_STAT_CONN_CACHE_EVICTION_MAXIMUM_PAGE_SIZE 1063
/*! cache: modified pages evicted */
-#define WT_STAT_CONN_CACHE_EVICTION_DIRTY 1062
+#define WT_STAT_CONN_CACHE_EVICTION_DIRTY 1064
/*! cache: modified pages evicted by application threads */
-#define WT_STAT_CONN_CACHE_EVICTION_APP_DIRTY 1063
+#define WT_STAT_CONN_CACHE_EVICTION_APP_DIRTY 1065
/*! cache: page split during eviction deepened the tree */
-#define WT_STAT_CONN_CACHE_EVICTION_DEEPEN 1064
+#define WT_STAT_CONN_CACHE_EVICTION_DEEPEN 1066
/*! cache: page written requiring lookaside records */
-#define WT_STAT_CONN_CACHE_WRITE_LOOKASIDE 1065
+#define WT_STAT_CONN_CACHE_WRITE_LOOKASIDE 1067
/*! cache: pages currently held in the cache */
-#define WT_STAT_CONN_CACHE_PAGES_INUSE 1066
+#define WT_STAT_CONN_CACHE_PAGES_INUSE 1068
/*! cache: pages evicted because they exceeded the in-memory maximum */
-#define WT_STAT_CONN_CACHE_EVICTION_FORCE 1067
+#define WT_STAT_CONN_CACHE_EVICTION_FORCE 1069
/*! cache: pages evicted because they had chains of deleted items */
-#define WT_STAT_CONN_CACHE_EVICTION_FORCE_DELETE 1068
+#define WT_STAT_CONN_CACHE_EVICTION_FORCE_DELETE 1070
/*! cache: pages evicted by application threads */
-#define WT_STAT_CONN_CACHE_EVICTION_APP 1069
+#define WT_STAT_CONN_CACHE_EVICTION_APP 1071
/*! cache: pages queued for eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED 1070
+#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED 1072
/*! cache: pages queued for urgent eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED_OLDEST 1071
+#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED_OLDEST 1073
/*! cache: pages read into cache */
-#define WT_STAT_CONN_CACHE_READ 1072
+#define WT_STAT_CONN_CACHE_READ 1074
/*! cache: pages read into cache requiring lookaside entries */
-#define WT_STAT_CONN_CACHE_READ_LOOKASIDE 1073
+#define WT_STAT_CONN_CACHE_READ_LOOKASIDE 1075
/*! cache: pages requested from the cache */
-#define WT_STAT_CONN_CACHE_PAGES_REQUESTED 1074
+#define WT_STAT_CONN_CACHE_PAGES_REQUESTED 1076
/*! cache: pages seen by eviction walk */
-#define WT_STAT_CONN_CACHE_EVICTION_PAGES_SEEN 1075
+#define WT_STAT_CONN_CACHE_EVICTION_PAGES_SEEN 1077
/*! cache: pages selected for eviction unable to be evicted */
-#define WT_STAT_CONN_CACHE_EVICTION_FAIL 1076
+#define WT_STAT_CONN_CACHE_EVICTION_FAIL 1078
/*! cache: pages walked for eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_WALK 1077
+#define WT_STAT_CONN_CACHE_EVICTION_WALK 1079
/*! cache: pages written from cache */
-#define WT_STAT_CONN_CACHE_WRITE 1078
+#define WT_STAT_CONN_CACHE_WRITE 1080
/*! cache: pages written requiring in-memory restoration */
-#define WT_STAT_CONN_CACHE_WRITE_RESTORE 1079
+#define WT_STAT_CONN_CACHE_WRITE_RESTORE 1081
/*! cache: percentage overhead */
-#define WT_STAT_CONN_CACHE_OVERHEAD 1080
+#define WT_STAT_CONN_CACHE_OVERHEAD 1082
/*! cache: tracked bytes belonging to internal pages in the cache */
-#define WT_STAT_CONN_CACHE_BYTES_INTERNAL 1081
+#define WT_STAT_CONN_CACHE_BYTES_INTERNAL 1083
/*! cache: tracked bytes belonging to leaf pages in the cache */
-#define WT_STAT_CONN_CACHE_BYTES_LEAF 1082
+#define WT_STAT_CONN_CACHE_BYTES_LEAF 1084
/*! cache: tracked bytes belonging to overflow pages in the cache */
-#define WT_STAT_CONN_CACHE_BYTES_OVERFLOW 1083
+#define WT_STAT_CONN_CACHE_BYTES_OVERFLOW 1085
/*! cache: tracked dirty bytes in the cache */
-#define WT_STAT_CONN_CACHE_BYTES_DIRTY 1084
+#define WT_STAT_CONN_CACHE_BYTES_DIRTY 1086
/*! cache: tracked dirty pages in the cache */
-#define WT_STAT_CONN_CACHE_PAGES_DIRTY 1085
+#define WT_STAT_CONN_CACHE_PAGES_DIRTY 1087
/*! cache: unmodified pages evicted */
-#define WT_STAT_CONN_CACHE_EVICTION_CLEAN 1086
+#define WT_STAT_CONN_CACHE_EVICTION_CLEAN 1088
/*! connection: auto adjusting condition resets */
-#define WT_STAT_CONN_COND_AUTO_WAIT_RESET 1087
+#define WT_STAT_CONN_COND_AUTO_WAIT_RESET 1089
/*! connection: auto adjusting condition wait calls */
-#define WT_STAT_CONN_COND_AUTO_WAIT 1088
+#define WT_STAT_CONN_COND_AUTO_WAIT 1090
/*! connection: files currently open */
-#define WT_STAT_CONN_FILE_OPEN 1089
+#define WT_STAT_CONN_FILE_OPEN 1091
/*! connection: memory allocations */
-#define WT_STAT_CONN_MEMORY_ALLOCATION 1090
+#define WT_STAT_CONN_MEMORY_ALLOCATION 1092
/*! connection: memory frees */
-#define WT_STAT_CONN_MEMORY_FREE 1091
+#define WT_STAT_CONN_MEMORY_FREE 1093
/*! connection: memory re-allocations */
-#define WT_STAT_CONN_MEMORY_GROW 1092
+#define WT_STAT_CONN_MEMORY_GROW 1094
/*! connection: pthread mutex condition wait calls */
-#define WT_STAT_CONN_COND_WAIT 1093
+#define WT_STAT_CONN_COND_WAIT 1095
/*! connection: pthread mutex shared lock read-lock calls */
-#define WT_STAT_CONN_RWLOCK_READ 1094
+#define WT_STAT_CONN_RWLOCK_READ 1096
/*! connection: pthread mutex shared lock write-lock calls */
-#define WT_STAT_CONN_RWLOCK_WRITE 1095
+#define WT_STAT_CONN_RWLOCK_WRITE 1097
/*! connection: total fsync I/Os */
-#define WT_STAT_CONN_FSYNC_IO 1096
+#define WT_STAT_CONN_FSYNC_IO 1098
/*! connection: total read I/Os */
-#define WT_STAT_CONN_READ_IO 1097
+#define WT_STAT_CONN_READ_IO 1099
/*! connection: total write I/Os */
-#define WT_STAT_CONN_WRITE_IO 1098
+#define WT_STAT_CONN_WRITE_IO 1100
/*! cursor: cursor create calls */
-#define WT_STAT_CONN_CURSOR_CREATE 1099
+#define WT_STAT_CONN_CURSOR_CREATE 1101
/*! cursor: cursor insert calls */
-#define WT_STAT_CONN_CURSOR_INSERT 1100
+#define WT_STAT_CONN_CURSOR_INSERT 1102
/*! cursor: cursor next calls */
-#define WT_STAT_CONN_CURSOR_NEXT 1101
+#define WT_STAT_CONN_CURSOR_NEXT 1103
/*! cursor: cursor prev calls */
-#define WT_STAT_CONN_CURSOR_PREV 1102
+#define WT_STAT_CONN_CURSOR_PREV 1104
/*! cursor: cursor remove calls */
-#define WT_STAT_CONN_CURSOR_REMOVE 1103
+#define WT_STAT_CONN_CURSOR_REMOVE 1105
/*! cursor: cursor reset calls */
-#define WT_STAT_CONN_CURSOR_RESET 1104
+#define WT_STAT_CONN_CURSOR_RESET 1106
/*! cursor: cursor restarted searches */
-#define WT_STAT_CONN_CURSOR_RESTART 1105
+#define WT_STAT_CONN_CURSOR_RESTART 1107
/*! cursor: cursor search calls */
-#define WT_STAT_CONN_CURSOR_SEARCH 1106
+#define WT_STAT_CONN_CURSOR_SEARCH 1108
/*! cursor: cursor search near calls */
-#define WT_STAT_CONN_CURSOR_SEARCH_NEAR 1107
+#define WT_STAT_CONN_CURSOR_SEARCH_NEAR 1109
/*! cursor: cursor update calls */
-#define WT_STAT_CONN_CURSOR_UPDATE 1108
+#define WT_STAT_CONN_CURSOR_UPDATE 1110
/*! cursor: truncate calls */
-#define WT_STAT_CONN_CURSOR_TRUNCATE 1109
+#define WT_STAT_CONN_CURSOR_TRUNCATE 1111
/*! data-handle: connection data handles currently active */
-#define WT_STAT_CONN_DH_CONN_HANDLE_COUNT 1110
+#define WT_STAT_CONN_DH_CONN_HANDLE_COUNT 1112
/*! data-handle: connection sweep candidate became referenced */
-#define WT_STAT_CONN_DH_SWEEP_REF 1111
+#define WT_STAT_CONN_DH_SWEEP_REF 1113
/*! data-handle: connection sweep dhandles closed */
-#define WT_STAT_CONN_DH_SWEEP_CLOSE 1112
+#define WT_STAT_CONN_DH_SWEEP_CLOSE 1114
/*! data-handle: connection sweep dhandles removed from hash list */
-#define WT_STAT_CONN_DH_SWEEP_REMOVE 1113
+#define WT_STAT_CONN_DH_SWEEP_REMOVE 1115
/*! data-handle: connection sweep time-of-death sets */
-#define WT_STAT_CONN_DH_SWEEP_TOD 1114
+#define WT_STAT_CONN_DH_SWEEP_TOD 1116
/*! data-handle: connection sweeps */
-#define WT_STAT_CONN_DH_SWEEPS 1115
+#define WT_STAT_CONN_DH_SWEEPS 1117
/*! data-handle: session dhandles swept */
-#define WT_STAT_CONN_DH_SESSION_HANDLES 1116
+#define WT_STAT_CONN_DH_SESSION_HANDLES 1118
/*! data-handle: session sweep attempts */
-#define WT_STAT_CONN_DH_SESSION_SWEEPS 1117
+#define WT_STAT_CONN_DH_SESSION_SWEEPS 1119
/*! log: busy returns attempting to switch slots */
-#define WT_STAT_CONN_LOG_SLOT_SWITCH_BUSY 1118
+#define WT_STAT_CONN_LOG_SLOT_SWITCH_BUSY 1120
/*! log: consolidated slot closures */
-#define WT_STAT_CONN_LOG_SLOT_CLOSES 1119
+#define WT_STAT_CONN_LOG_SLOT_CLOSES 1121
/*! log: consolidated slot join races */
-#define WT_STAT_CONN_LOG_SLOT_RACES 1120
+#define WT_STAT_CONN_LOG_SLOT_RACES 1122
/*! log: consolidated slot join transitions */
-#define WT_STAT_CONN_LOG_SLOT_TRANSITIONS 1121
+#define WT_STAT_CONN_LOG_SLOT_TRANSITIONS 1123
/*! log: consolidated slot joins */
-#define WT_STAT_CONN_LOG_SLOT_JOINS 1122
+#define WT_STAT_CONN_LOG_SLOT_JOINS 1124
/*! log: consolidated slot unbuffered writes */
-#define WT_STAT_CONN_LOG_SLOT_UNBUFFERED 1123
+#define WT_STAT_CONN_LOG_SLOT_UNBUFFERED 1125
/*! log: log bytes of payload data */
-#define WT_STAT_CONN_LOG_BYTES_PAYLOAD 1124
+#define WT_STAT_CONN_LOG_BYTES_PAYLOAD 1126
/*! log: log bytes written */
-#define WT_STAT_CONN_LOG_BYTES_WRITTEN 1125
+#define WT_STAT_CONN_LOG_BYTES_WRITTEN 1127
/*! log: log files manually zero-filled */
-#define WT_STAT_CONN_LOG_ZERO_FILLS 1126
+#define WT_STAT_CONN_LOG_ZERO_FILLS 1128
/*! log: log flush operations */
-#define WT_STAT_CONN_LOG_FLUSH 1127
+#define WT_STAT_CONN_LOG_FLUSH 1129
/*! log: log force write operations */
-#define WT_STAT_CONN_LOG_FORCE_WRITE 1128
+#define WT_STAT_CONN_LOG_FORCE_WRITE 1130
/*! log: log force write operations skipped */
-#define WT_STAT_CONN_LOG_FORCE_WRITE_SKIP 1129
+#define WT_STAT_CONN_LOG_FORCE_WRITE_SKIP 1131
/*! log: log records compressed */
-#define WT_STAT_CONN_LOG_COMPRESS_WRITES 1130
+#define WT_STAT_CONN_LOG_COMPRESS_WRITES 1132
/*! log: log records not compressed */
-#define WT_STAT_CONN_LOG_COMPRESS_WRITE_FAILS 1131
+#define WT_STAT_CONN_LOG_COMPRESS_WRITE_FAILS 1133
/*! log: log records too small to compress */
-#define WT_STAT_CONN_LOG_COMPRESS_SMALL 1132
+#define WT_STAT_CONN_LOG_COMPRESS_SMALL 1134
/*! log: log release advances write LSN */
-#define WT_STAT_CONN_LOG_RELEASE_WRITE_LSN 1133
+#define WT_STAT_CONN_LOG_RELEASE_WRITE_LSN 1135
/*! log: log scan operations */
-#define WT_STAT_CONN_LOG_SCANS 1134
+#define WT_STAT_CONN_LOG_SCANS 1136
/*! log: log scan records requiring two reads */
-#define WT_STAT_CONN_LOG_SCAN_REREADS 1135
+#define WT_STAT_CONN_LOG_SCAN_REREADS 1137
/*! log: log server thread advances write LSN */
-#define WT_STAT_CONN_LOG_WRITE_LSN 1136
+#define WT_STAT_CONN_LOG_WRITE_LSN 1138
/*! log: log server thread write LSN walk skipped */
-#define WT_STAT_CONN_LOG_WRITE_LSN_SKIP 1137
+#define WT_STAT_CONN_LOG_WRITE_LSN_SKIP 1139
/*! log: log sync operations */
-#define WT_STAT_CONN_LOG_SYNC 1138
+#define WT_STAT_CONN_LOG_SYNC 1140
/*! log: log sync time duration (usecs) */
-#define WT_STAT_CONN_LOG_SYNC_DURATION 1139
+#define WT_STAT_CONN_LOG_SYNC_DURATION 1141
/*! log: log sync_dir operations */
-#define WT_STAT_CONN_LOG_SYNC_DIR 1140
+#define WT_STAT_CONN_LOG_SYNC_DIR 1142
/*! log: log sync_dir time duration (usecs) */
-#define WT_STAT_CONN_LOG_SYNC_DIR_DURATION 1141
+#define WT_STAT_CONN_LOG_SYNC_DIR_DURATION 1143
/*! log: log write operations */
-#define WT_STAT_CONN_LOG_WRITES 1142
+#define WT_STAT_CONN_LOG_WRITES 1144
/*! log: logging bytes consolidated */
-#define WT_STAT_CONN_LOG_SLOT_CONSOLIDATED 1143
+#define WT_STAT_CONN_LOG_SLOT_CONSOLIDATED 1145
/*! log: maximum log file size */
-#define WT_STAT_CONN_LOG_MAX_FILESIZE 1144
+#define WT_STAT_CONN_LOG_MAX_FILESIZE 1146
/*! log: number of pre-allocated log files to create */
-#define WT_STAT_CONN_LOG_PREALLOC_MAX 1145
+#define WT_STAT_CONN_LOG_PREALLOC_MAX 1147
/*! log: pre-allocated log files not ready and missed */
-#define WT_STAT_CONN_LOG_PREALLOC_MISSED 1146
+#define WT_STAT_CONN_LOG_PREALLOC_MISSED 1148
/*! log: pre-allocated log files prepared */
-#define WT_STAT_CONN_LOG_PREALLOC_FILES 1147
+#define WT_STAT_CONN_LOG_PREALLOC_FILES 1149
/*! log: pre-allocated log files used */
-#define WT_STAT_CONN_LOG_PREALLOC_USED 1148
+#define WT_STAT_CONN_LOG_PREALLOC_USED 1150
/*! log: records processed by log scan */
-#define WT_STAT_CONN_LOG_SCAN_RECORDS 1149
+#define WT_STAT_CONN_LOG_SCAN_RECORDS 1151
/*! log: total in-memory size of compressed records */
-#define WT_STAT_CONN_LOG_COMPRESS_MEM 1150
+#define WT_STAT_CONN_LOG_COMPRESS_MEM 1152
/*! log: total log buffer size */
-#define WT_STAT_CONN_LOG_BUFFER_SIZE 1151
+#define WT_STAT_CONN_LOG_BUFFER_SIZE 1153
/*! log: total size of compressed records */
-#define WT_STAT_CONN_LOG_COMPRESS_LEN 1152
+#define WT_STAT_CONN_LOG_COMPRESS_LEN 1154
/*! log: written slots coalesced */
-#define WT_STAT_CONN_LOG_SLOT_COALESCED 1153
+#define WT_STAT_CONN_LOG_SLOT_COALESCED 1155
/*! log: yields waiting for previous log file close */
-#define WT_STAT_CONN_LOG_CLOSE_YIELDS 1154
+#define WT_STAT_CONN_LOG_CLOSE_YIELDS 1156
/*! reconciliation: fast-path pages deleted */
-#define WT_STAT_CONN_REC_PAGE_DELETE_FAST 1155
+#define WT_STAT_CONN_REC_PAGE_DELETE_FAST 1157
/*! reconciliation: page reconciliation calls */
-#define WT_STAT_CONN_REC_PAGES 1156
+#define WT_STAT_CONN_REC_PAGES 1158
/*! reconciliation: page reconciliation calls for eviction */
-#define WT_STAT_CONN_REC_PAGES_EVICTION 1157
+#define WT_STAT_CONN_REC_PAGES_EVICTION 1159
/*! reconciliation: pages deleted */
-#define WT_STAT_CONN_REC_PAGE_DELETE 1158
+#define WT_STAT_CONN_REC_PAGE_DELETE 1160
/*! reconciliation: split bytes currently awaiting free */
-#define WT_STAT_CONN_REC_SPLIT_STASHED_BYTES 1159
+#define WT_STAT_CONN_REC_SPLIT_STASHED_BYTES 1161
/*! reconciliation: split objects currently awaiting free */
-#define WT_STAT_CONN_REC_SPLIT_STASHED_OBJECTS 1160
+#define WT_STAT_CONN_REC_SPLIT_STASHED_OBJECTS 1162
/*! session: open cursor count */
-#define WT_STAT_CONN_SESSION_CURSOR_OPEN 1161
+#define WT_STAT_CONN_SESSION_CURSOR_OPEN 1163
/*! session: open session count */
-#define WT_STAT_CONN_SESSION_OPEN 1162
+#define WT_STAT_CONN_SESSION_OPEN 1164
/*! thread-state: active filesystem fsync calls */
-#define WT_STAT_CONN_FSYNC_ACTIVE 1163
+#define WT_STAT_CONN_FSYNC_ACTIVE 1165
/*! thread-state: active filesystem read calls */
-#define WT_STAT_CONN_READ_ACTIVE 1164
+#define WT_STAT_CONN_READ_ACTIVE 1166
/*! thread-state: active filesystem write calls */
-#define WT_STAT_CONN_WRITE_ACTIVE 1165
+#define WT_STAT_CONN_WRITE_ACTIVE 1167
/*! thread-yield: page acquire busy blocked */
-#define WT_STAT_CONN_PAGE_BUSY_BLOCKED 1166
+#define WT_STAT_CONN_PAGE_BUSY_BLOCKED 1168
/*! thread-yield: page acquire eviction blocked */
-#define WT_STAT_CONN_PAGE_FORCIBLE_EVICT_BLOCKED 1167
+#define WT_STAT_CONN_PAGE_FORCIBLE_EVICT_BLOCKED 1169
/*! thread-yield: page acquire locked blocked */
-#define WT_STAT_CONN_PAGE_LOCKED_BLOCKED 1168
+#define WT_STAT_CONN_PAGE_LOCKED_BLOCKED 1170
/*! thread-yield: page acquire read blocked */
-#define WT_STAT_CONN_PAGE_READ_BLOCKED 1169
+#define WT_STAT_CONN_PAGE_READ_BLOCKED 1171
/*! thread-yield: page acquire time sleeping (usecs) */
-#define WT_STAT_CONN_PAGE_SLEEP 1170
+#define WT_STAT_CONN_PAGE_SLEEP 1172
/*! transaction: number of named snapshots created */
-#define WT_STAT_CONN_TXN_SNAPSHOTS_CREATED 1171
+#define WT_STAT_CONN_TXN_SNAPSHOTS_CREATED 1173
/*! transaction: number of named snapshots dropped */
-#define WT_STAT_CONN_TXN_SNAPSHOTS_DROPPED 1172
+#define WT_STAT_CONN_TXN_SNAPSHOTS_DROPPED 1174
/*! transaction: transaction begins */
-#define WT_STAT_CONN_TXN_BEGIN 1173
+#define WT_STAT_CONN_TXN_BEGIN 1175
/*! transaction: transaction checkpoint currently running */
-#define WT_STAT_CONN_TXN_CHECKPOINT_RUNNING 1174
+#define WT_STAT_CONN_TXN_CHECKPOINT_RUNNING 1176
/*! transaction: transaction checkpoint generation */
-#define WT_STAT_CONN_TXN_CHECKPOINT_GENERATION 1175
+#define WT_STAT_CONN_TXN_CHECKPOINT_GENERATION 1177
/*! transaction: transaction checkpoint max time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MAX 1176
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MAX 1178
/*! transaction: transaction checkpoint min time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MIN 1177
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MIN 1179
/*! transaction: transaction checkpoint most recent time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_RECENT 1178
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_RECENT 1180
/*! transaction: transaction checkpoint total time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_TOTAL 1179
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_TOTAL 1181
/*! transaction: transaction checkpoints */
-#define WT_STAT_CONN_TXN_CHECKPOINT 1180
+#define WT_STAT_CONN_TXN_CHECKPOINT 1182
/*! transaction: transaction failures due to cache overflow */
-#define WT_STAT_CONN_TXN_FAIL_CACHE 1181
+#define WT_STAT_CONN_TXN_FAIL_CACHE 1183
/*! transaction: transaction fsync calls for checkpoint after allocating
* the transaction ID */
-#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST 1182
+#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST 1184
/*! transaction: transaction fsync calls for checkpoint before allocating
* the transaction ID */
-#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_PRE 1183
+#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_PRE 1185
/*! transaction: transaction fsync duration for checkpoint after
* allocating the transaction ID (usecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST_DURATION 1184
+#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST_DURATION 1186
/*! transaction: transaction fsync duration for checkpoint before
* allocating the transaction ID (usecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_PRE_DURATION 1185
+#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_PRE_DURATION 1187
/*! transaction: transaction range of IDs currently pinned */
-#define WT_STAT_CONN_TXN_PINNED_RANGE 1186
+#define WT_STAT_CONN_TXN_PINNED_RANGE 1188
/*! transaction: transaction range of IDs currently pinned by a checkpoint */
-#define WT_STAT_CONN_TXN_PINNED_CHECKPOINT_RANGE 1187
+#define WT_STAT_CONN_TXN_PINNED_CHECKPOINT_RANGE 1189
/*! transaction: transaction range of IDs currently pinned by named
* snapshots */
-#define WT_STAT_CONN_TXN_PINNED_SNAPSHOT_RANGE 1188
+#define WT_STAT_CONN_TXN_PINNED_SNAPSHOT_RANGE 1190
/*! transaction: transaction sync calls */
-#define WT_STAT_CONN_TXN_SYNC 1189
+#define WT_STAT_CONN_TXN_SYNC 1191
/*! transaction: transactions committed */
-#define WT_STAT_CONN_TXN_COMMIT 1190
+#define WT_STAT_CONN_TXN_COMMIT 1192
/*! transaction: transactions rolled back */
-#define WT_STAT_CONN_TXN_ROLLBACK 1191
+#define WT_STAT_CONN_TXN_ROLLBACK 1193
/*!
* @}
diff --git a/src/support/stat.c b/src/support/stat.c
index ba9651a3e51..74770dbeea1 100644
--- a/src/support/stat.c
+++ b/src/support/stat.c
@@ -548,7 +548,9 @@ static const char * const __stats_connection_desc[] = {
"block-manager: bytes written",
"block-manager: mapped blocks read",
"block-manager: mapped bytes read",
+ "cache: bytes belonging to page images in the cache",
"cache: bytes currently in the cache",
+ "cache: bytes not belonging to page images in the cache",
"cache: bytes read into cache",
"cache: bytes written from cache",
"cache: checkpoint blocked page eviction",
@@ -770,7 +772,9 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats)
stats->block_byte_write = 0;
stats->block_map_read = 0;
stats->block_byte_map_read = 0;
+ /* not clearing cache_bytes_image */
/* not clearing cache_bytes_inuse */
+ /* not clearing cache_bytes_other */
stats->cache_bytes_read = 0;
stats->cache_bytes_write = 0;
stats->cache_eviction_checkpoint = 0;
@@ -984,7 +988,9 @@ __wt_stat_connection_aggregate(
to->block_byte_write += WT_STAT_READ(from, block_byte_write);
to->block_map_read += WT_STAT_READ(from, block_map_read);
to->block_byte_map_read += WT_STAT_READ(from, block_byte_map_read);
+ to->cache_bytes_image += WT_STAT_READ(from, cache_bytes_image);
to->cache_bytes_inuse += WT_STAT_READ(from, cache_bytes_inuse);
+ to->cache_bytes_other += WT_STAT_READ(from, cache_bytes_other);
to->cache_bytes_read += WT_STAT_READ(from, cache_bytes_read);
to->cache_bytes_write += WT_STAT_READ(from, cache_bytes_write);
to->cache_eviction_checkpoint +=
diff --git a/src/txn/txn_ckpt.c b/src/txn/txn_ckpt.c
index 51d26b9aed6..3a6e1832f34 100644
--- a/src/txn/txn_ckpt.c
+++ b/src/txn/txn_ckpt.c
@@ -400,6 +400,9 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[])
session, cfg, __wt_checkpoint_get_handles, NULL))));
WT_ERR(ret);
+ /* Reset the maximum page size seen by eviction. */
+ conn->cache->evict_max_page_size = 0;
+
/*
* Update the global oldest ID so we do all possible cleanup.
*
diff --git a/tools/wtstats/stat_data.py b/tools/wtstats/stat_data.py
index 2bea123fc91..d06f1035adf 100644
--- a/tools/wtstats/stat_data.py
+++ b/tools/wtstats/stat_data.py
@@ -3,7 +3,9 @@
no_scale_per_second_list = [
'async: current work queue length',
'async: maximum work queue length',
+ 'cache: bytes belonging to page images in the cache',
'cache: bytes currently in the cache',
+ 'cache: bytes not belonging to page images in the cache',
'cache: eviction currently operating in aggressive mode',
'cache: files with active eviction walks',
'cache: hazard pointer maximum array length',
@@ -75,7 +77,9 @@ no_scale_per_second_list = [
]
no_clear_list = [
'async: maximum work queue length',
+ 'cache: bytes belonging to page images in the cache',
'cache: bytes currently in the cache',
+ 'cache: bytes not belonging to page images in the cache',
'cache: eviction currently operating in aggressive mode',
'cache: files with active eviction walks',
'cache: maximum bytes configured',