summaryrefslogtreecommitdiff
path: root/src/evict/evict_page.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/evict/evict_page.c')
-rw-r--r--src/evict/evict_page.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/src/evict/evict_page.c b/src/evict/evict_page.c
index 53b22953669..5ef6a6370b0 100644
--- a/src/evict/evict_page.c
+++ b/src/evict/evict_page.c
@@ -156,7 +156,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 && !LF_ISSET(WT_EVICT_IN_MEMORY)))
+ else if ((clean_page && !LF_ISSET(WT_EVICT_IN_MEMORY)) || tree_dead)
/*
* Pages that belong to dead trees never write back to disk
* and can't support page splits.
@@ -315,9 +315,10 @@ __evict_page_dirty_update(WT_SESSION_IMPL *session, WT_REF *ref, bool closing)
* write. Take advantage of the fact we have exclusive access
* to the page and rewrite it in memory.
*/
- if (mod->mod_multi_entries == 1)
+ if (mod->mod_multi_entries == 1) {
+ WT_ASSERT(session, closing == false);
WT_RET(__wt_split_rewrite(session, ref));
- else
+ } else
WT_RET(__wt_split_multi(session, ref, closing));
break;
case WT_PM_REC_REPLACE: /* 1-for-1 page swap */
@@ -476,10 +477,15 @@ __evict_review(
* If we have an exclusive lock (we're discarding the tree), assert
* there are no updates we cannot read.
*
- * Otherwise, if the page we're evicting is a leaf page marked for
- * forced eviction, set the update-restore flag, so reconciliation will
- * write blocks it can write and create a list of skipped updates for
- * blocks it cannot write. This is how forced eviction of active, huge
+ * Don't set any other flags for internal pages: they don't have update
+ * lists to be saved and restored, nor can we re-create them in memory.
+ *
+ * For leaf pages:
+ *
+ * If an in-memory configuration or the page is being forcibly evicted,
+ * set the update-restore flag, so reconciliation will write blocks it
+ * can write and create a list of skipped updates for blocks it cannot
+ * write, along with disk images. This is how eviction of active, huge
* pages works: we take a big page and reconcile it into blocks, some of
* which we write and discard, the rest of which we re-create as smaller
* in-memory pages, (restoring the updates that stopped us from writing
@@ -490,20 +496,27 @@ __evict_review(
* allowing the eviction of pages we'd otherwise have to retain in cache
* to support older readers.
*
- * 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.
+ * Finally, if we don't need to do eviction at the moment, create disk
+ * images of split pages in order to re-instantiate them.
*/
cache = S2C(session)->cache;
if (closing)
LF_SET(WT_VISIBILITY_ERR);
else if (!WT_PAGE_IS_INTERNAL(page)) {
if (F_ISSET(S2C(session), WT_CONN_IN_MEMORY))
- LF_SET(WT_EVICT_IN_MEMORY | WT_EVICT_UPDATE_RESTORE);
+ LF_SET(WT_EVICT_IN_MEMORY |
+ WT_EVICT_UPDATE_RESTORE | WT_EVICT_SCRUB);
else if (page->read_gen == WT_READGEN_OLDEST ||
page->memory_footprint > S2BT(session)->splitmempage)
LF_SET(WT_EVICT_UPDATE_RESTORE);
else if (F_ISSET(cache, WT_CACHE_STUCK))
LF_SET(WT_EVICT_LOOKASIDE);
+ /*
+ * If we aren't trying to free space in the cache, just
+ * scrub the page and keep it around.
+ */
+ if (cache->state != WT_EVICT_STATE_ALL)
+ LF_SET(WT_EVICT_SCRUB);
}
*flagsp = flags;