diff options
Diffstat (limited to 'src/evict')
-rw-r--r-- | src/evict/evict_page.c | 33 |
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; |