diff options
author | Luke Chen <luke.chen@mongodb.com> | 2018-07-03 12:07:37 +1000 |
---|---|---|
committer | Luke Chen <luke.chen@mongodb.com> | 2018-07-03 12:07:37 +1000 |
commit | b76457d9aa0188e1d2369851506b9d4d927024cb (patch) | |
tree | f93ea10b6ea968ed52d08d9b714c506bf6b2de28 /src/third_party/wiredtiger/src/lsm/lsm_work_unit.c | |
parent | 925a113194e00e193318486f576d14e6c3e27ea1 (diff) | |
download | mongo-b76457d9aa0188e1d2369851506b9d4d927024cb.tar.gz |
Import wiredtiger: 27f8e047911ff31500fecf4ea760e688ec541b97 from branch mongodb-4.2
ref: a8a6314182..27f8e04791
for: 4.1.1
WT-3839 Document the undefined behavior when a range truncate overlaps with inserts
WT-3917 Enhance WT_CURSOR::reserve documentation around commit visibility
WT-4024 Fix a race between split and next/prev
WT-4067 Enhance LSM to not pin as much history in cache
WT-4111 Improve checkpoint scrubbing algorithm
WT-4125 Ensure that subsequent checkpoints with stable timestamp don't read too much
WT-4136 Add a new timing stress flag that yields during tree search
WT-4138 Add an option to timeout waiting for space in the cache
WT-4140 Cursor walk limits quick eviction page selection unnecessarily.
WT-4141 Enhance checkpoint with timestamps to unblock eviction sooner
WT-4145 Only include the checkpoint timestamp during checkpoints
WT-4146 Coverity 1393639, unused variable
WT-4152 Save return value for later comparison in transaction code
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. |