diff options
Diffstat (limited to 'src/third_party/wiredtiger/src/lsm/lsm_work_unit.c')
-rw-r--r-- | src/third_party/wiredtiger/src/lsm/lsm_work_unit.c | 94 |
1 files changed, 88 insertions, 6 deletions
diff --git a/src/third_party/wiredtiger/src/lsm/lsm_work_unit.c b/src/third_party/wiredtiger/src/lsm/lsm_work_unit.c index 6f18f4fb152..a283670eba6 100644 --- a/src/third_party/wiredtiger/src/lsm/lsm_work_unit.c +++ b/src/third_party/wiredtiger/src/lsm/lsm_work_unit.c @@ -313,6 +313,37 @@ __wt_lsm_chunk_visible_all( } /* + * __lsm_set_chunk_evictable -- + * Enable eviction in an LSM chunk. + */ +static int +__lsm_set_chunk_evictable( + WT_SESSION_IMPL *session, WT_LSM_CHUNK *chunk, bool need_handle) +{ + WT_BTREE *btree; + WT_DECL_RET; + + if (chunk->evict_enabled != 0) + return (0); + + /* See if we win the race to enable eviction. */ + if (__wt_atomic_cas32(&chunk->evict_enabled, 0, 1)) { + if (need_handle) + WT_RET(__wt_session_get_dhandle( + session, chunk->uri, NULL, NULL, 0)); + btree = session->dhandle->handle; + if (btree->evict_disabled_open) { + btree->evict_disabled_open = false; + __wt_evict_file_exclusive_off(session); + } + + if (need_handle) + WT_TRET(__wt_session_release_dhandle(session)); + } + return (ret); +} + +/* * __lsm_checkpoint_chunk -- * Checkpoint an LSM chunk, separated out to make locking easier. */ @@ -340,7 +371,6 @@ int __wt_lsm_checkpoint_chunk(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, WT_LSM_CHUNK *chunk) { - WT_BTREE *btree; WT_DECL_RET; WT_TXN_ISOLATION saved_isolation; bool flush_set, release_dhandle; @@ -375,6 +405,14 @@ __wt_lsm_checkpoint_chunk(WT_SESSION_IMPL *session, WT_RET(__wt_txn_update_oldest( session, WT_TXN_OLDEST_STRICT | WT_TXN_OLDEST_WAIT)); if (!__wt_lsm_chunk_visible_all(session, chunk)) { + /* + * If there is cache pressure consider making a chunk evictable + * to avoid the cache getting stuck when history is required. + */ + if (__wt_eviction_needed(session, false, false, NULL)) + WT_ERR(__wt_lsm_manager_push_entry( + session, WT_LSM_WORK_ENABLE_EVICT, 0, lsm_tree)); + __wt_verbose(session, WT_VERB_LSM, "LSM worker %s: running transaction, return", chunk->uri); @@ -446,11 +484,7 @@ __wt_lsm_checkpoint_chunk(WT_SESSION_IMPL *session, * Enable eviction on the live chunk so it doesn't block the cache. * Future reads should direct to the on-disk chunk anyway. */ - btree = session->dhandle->handle; - if (btree->evict_disabled_open) { - btree->evict_disabled_open = false; - __wt_evict_file_exclusive_off(session); - } + WT_ERR(__lsm_set_chunk_evictable(session, chunk, false)); release_dhandle = false; WT_ERR(__wt_session_release_dhandle(session)); @@ -481,6 +515,54 @@ err: if (flush_set) } /* + * __wt_lsm_work_enable_evict -- + * LSM usually pins live chunks in memory - preferring to force them + * out via a checkpoint when they are no longer required. For applications + * that keep data pinned for a long time this can lead to the cache + * being pinned full. This work unit detects that case, and enables + * regular eviction in chunks that can be correctly evicted. + */ +int +__wt_lsm_work_enable_evict(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) +{ + WT_DECL_RET; + WT_LSM_CHUNK *chunk; + WT_LSM_WORKER_COOKIE cookie; + u_int i; + + WT_CLEAR(cookie); + + /* Only do this if there is cache pressure */ + if (!__wt_eviction_needed(session, false, false, NULL)) + return (0); + + WT_RET(__lsm_copy_chunks(session, lsm_tree, &cookie, false)); + + /* + * Turn on eviction in chunks that have had some chance to + * checkpoint if there is cache pressure. + */ + for (i = 0; cookie.nchunks > 2 && i < cookie.nchunks - 2; i++) { + chunk = cookie.chunk_array[i]; + + /* + * Skip if the chunk isn't on disk yet, or if it's still in + * cache for a reason other than transaction visibility. + */ + if (!F_ISSET(chunk, WT_LSM_CHUNK_ONDISK) || + chunk->evict_enabled != 0 || + __wt_lsm_chunk_visible_all(session, chunk)) + continue; + + WT_ERR(__lsm_set_chunk_evictable(session, chunk, true)); + } + +err: __lsm_unpin_chunks(session, &cookie); + __wt_free(session, cookie.chunk_array); + return (ret); +} + +/* * __lsm_bloom_create -- * Create a bloom filter for a chunk of the LSM tree that has been * checkpointed but not yet been merged. |