summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/evict/evict_lru.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/wiredtiger/src/evict/evict_lru.c')
-rw-r--r--src/third_party/wiredtiger/src/evict/evict_lru.c92
1 files changed, 32 insertions, 60 deletions
diff --git a/src/third_party/wiredtiger/src/evict/evict_lru.c b/src/third_party/wiredtiger/src/evict/evict_lru.c
index 397306e6aa6..931216376b9 100644
--- a/src/third_party/wiredtiger/src/evict/evict_lru.c
+++ b/src/third_party/wiredtiger/src/evict/evict_lru.c
@@ -18,7 +18,7 @@ static int __evict_server(WT_SESSION_IMPL *, bool *);
static void __evict_tune_workers(WT_SESSION_IMPL *session);
static int __evict_walk(WT_SESSION_IMPL *, WT_EVICT_QUEUE *);
static int __evict_walk_tree(
- WT_SESSION_IMPL *, WT_EVICT_QUEUE *, u_int, u_int *, uint64_t *);
+ WT_SESSION_IMPL *, WT_EVICT_QUEUE *, u_int, u_int *);
#define WT_EVICT_HAS_WORKERS(s) \
(S2C(s)->evict_threads.current_threads > 1)
@@ -1399,19 +1399,19 @@ __evict_walk_choose_dhandle(
u_int dh_bucket_count, rnd_bucket, rnd_dh;
conn = S2C(session);
- *dhandle_p = NULL;
WT_ASSERT(session, __wt_rwlock_islocked(session, &conn->dhandle_lock));
- /* Nothing to do if the dhandle list is empty. */
- if (TAILQ_EMPTY(&conn->dhqh))
- return;
+#undef RANDOM_DH_SELECTION_ENABLED
+
+#ifdef RANDOM_DH_SELECTION_ENABLED
+ *dhandle_p = NULL;
/*
- * If we do not have a lot of dhandles, most hash buckets will be empty.
+ * If we don't have many dhandles, most hash buckets will be empty.
* Just pick a random dhandle from the list in that case.
*/
- if (conn->dhandle_count < 10 * WT_HASH_ARRAY_SIZE) {
+ if (conn->dhandle_count < WT_HASH_ARRAY_SIZE / 4) {
rnd_dh = __wt_random(&session->rnd) % conn->dhandle_count;
dhandle = TAILQ_FIRST(&conn->dhqh);
for (; rnd_dh > 0; rnd_dh--)
@@ -1435,6 +1435,18 @@ __evict_walk_choose_dhandle(
dhandle = TAILQ_FIRST(&conn->dhhash[rnd_bucket]);
for (; rnd_dh > 0; rnd_dh--)
dhandle = TAILQ_NEXT(dhandle, hashq);
+#else
+ /* Just step through dhandles. */
+ dhandle = *dhandle_p;
+ if (dhandle != NULL)
+ dhandle = TAILQ_NEXT(dhandle, q);
+ if (dhandle == NULL)
+ dhandle = TAILQ_FIRST(&conn->dhqh);
+
+ WT_UNUSED(dh_bucket_count);
+ WT_UNUSED(rnd_bucket);
+ WT_UNUSED(rnd_dh);
+#endif
*dhandle_p = dhandle;
}
@@ -1452,9 +1464,8 @@ __evict_walk(WT_SESSION_IMPL *session, WT_EVICT_QUEUE *queue)
WT_DATA_HANDLE *dhandle;
WT_DECL_RET;
WT_TRACK_OP_DECL;
- uint64_t loop_count;
- uint64_t pages_seen_file, pages_seen_interim, pages_seen_total;
- u_int max_entries, retries, slot, start_slot, total_candidates;
+ u_int loop_count, max_entries, retries, slot, start_slot;
+ u_int total_candidates;
bool dhandle_locked, incr;
WT_TRACK_OP_INIT(session);
@@ -1480,31 +1491,14 @@ __evict_walk(WT_SESSION_IMPL *session, WT_EVICT_QUEUE *queue)
total_candidates = (u_int)(F_ISSET(cache, WT_CACHE_EVICT_CLEAN) ?
__wt_cache_pages_inuse(cache) : cache->pages_dirty_leaf);
max_entries = WT_MIN(max_entries, 1 + total_candidates / 2);
- pages_seen_interim = pages_seen_total = 0;
retry: loop_count = 0;
- while (slot < max_entries) {
- loop_count++;
-
+ while (slot < max_entries && loop_count++ < conn->dhandle_count) {
/* We're done if shutting down or reconfiguring. */
if (F_ISSET(conn, WT_CONN_CLOSING) ||
F_ISSET(conn, WT_CONN_RECONFIGURING))
break;
- /* If we have seen enough pages in this walk, we're done. */
- if (pages_seen_total > WT_EVICT_WALK_INCR * 100)
- break;
-
- /*
- * If we are not finding pages at all, we're done.
- * Every 100th iteration, check if we made progress.
- */
- if (loop_count % 100 == 0) {
- if (pages_seen_interim == pages_seen_total)
- break;
- pages_seen_interim = pages_seen_total;
- }
-
/*
* If another thread is waiting on the eviction server to clear
* the walk point in a tree, give up.
@@ -1620,9 +1614,8 @@ retry: loop_count = 0;
*/
cache->walk_tree = dhandle;
WT_WITH_DHANDLE(session, dhandle,
- ret = __evict_walk_tree(session, queue,
- max_entries, &slot, &pages_seen_file));
- pages_seen_total += pages_seen_file;
+ ret = __evict_walk_tree(
+ session, queue, max_entries, &slot));
WT_ASSERT(session, __wt_session_gen(
session, WT_GEN_SPLIT) == 0);
@@ -1713,22 +1706,14 @@ __evict_push_candidate(WT_SESSION_IMPL *session,
* Calculate how many pages to queue for a given tree.
*/
static uint32_t
-__evict_walk_target(WT_SESSION_IMPL *session, u_int max_entries)
+__evict_walk_target(WT_SESSION_IMPL *session)
{
WT_CACHE *cache;
uint64_t btree_inuse, bytes_per_slot, cache_inuse;
uint32_t target_pages_clean, target_pages_dirty, target_pages;
- uint32_t total_slots;
cache = S2C(session)->cache;
target_pages_clean = target_pages_dirty = 0;
- total_slots = max_entries;
-
- /*
- * The number of times we should fill the queue by the end of
- * considering all trees.
- */
-#define QUEUE_FILLS_PER_PASS 10
/*
* The minimum number of pages we should consider per tree.
@@ -1744,7 +1729,7 @@ __evict_walk_target(WT_SESSION_IMPL *session, u_int max_entries)
if (F_ISSET(cache, WT_CACHE_EVICT_CLEAN)) {
btree_inuse = __wt_btree_bytes_evictable(session);
cache_inuse = __wt_cache_bytes_inuse(cache);
- bytes_per_slot = 1 + cache_inuse / total_slots;
+ bytes_per_slot = 1 + cache_inuse / cache->evict_slots;
target_pages_clean = (uint32_t)(
(btree_inuse + bytes_per_slot / 2) / bytes_per_slot);
}
@@ -1752,20 +1737,12 @@ __evict_walk_target(WT_SESSION_IMPL *session, u_int max_entries)
if (F_ISSET(cache, WT_CACHE_EVICT_DIRTY)) {
btree_inuse = __wt_btree_dirty_leaf_inuse(session);
cache_inuse = __wt_cache_dirty_leaf_inuse(cache);
- bytes_per_slot = 1 + cache_inuse / total_slots;
+ bytes_per_slot = 1 + cache_inuse / cache->evict_slots;
target_pages_dirty = (uint32_t)(
(btree_inuse + bytes_per_slot / 2) / bytes_per_slot);
}
- /*
- * Weight the number of target pages by the number of times we want to
- * fill the cache per pass through all the trees. Note that we don't
- * build this into the calculation above because we don't want to favor
- * small trees, so round to a whole number of slots (zero for small
- * trees) before multiplying.
- */
- target_pages = WT_MAX(target_pages_clean, target_pages_dirty) *
- QUEUE_FILLS_PER_PASS;
+ target_pages = WT_MAX(target_pages_clean, target_pages_dirty);
/*
* Walk trees with a small fraction of the cache in case there are so
@@ -1800,8 +1777,8 @@ __evict_walk_target(WT_SESSION_IMPL *session, u_int max_entries)
* Get a few page eviction candidates from a single underlying file.
*/
static int
-__evict_walk_tree(WT_SESSION_IMPL *session, WT_EVICT_QUEUE *queue,
- u_int max_entries, u_int *slotp, uint64_t *pages_seen_p)
+__evict_walk_tree(WT_SESSION_IMPL *session,
+ WT_EVICT_QUEUE *queue, u_int max_entries, u_int *slotp)
{
WT_BTREE *btree;
WT_CACHE *cache;
@@ -1821,7 +1798,6 @@ __evict_walk_tree(WT_SESSION_IMPL *session, WT_EVICT_QUEUE *queue,
last_parent = NULL;
restarts = 0;
give_up = urgent_queued = false;
- *pages_seen_p = 0;
/*
* Figure out how many slots to fill from this tree.
@@ -1830,12 +1806,10 @@ __evict_walk_tree(WT_SESSION_IMPL *session, WT_EVICT_QUEUE *queue,
start = queue->evict_queue + *slotp;
remaining_slots = max_entries - *slotp;
if (btree->evict_walk_progress >= btree->evict_walk_target) {
- btree->evict_walk_target =
- __evict_walk_target(session, max_entries);
+ btree->evict_walk_target = __evict_walk_target(session);
btree->evict_walk_progress = 0;
}
- target_pages = WT_MIN(btree->evict_walk_target / QUEUE_FILLS_PER_PASS,
- btree->evict_walk_target - btree->evict_walk_progress);
+ target_pages = btree->evict_walk_target - btree->evict_walk_progress;
if (target_pages > remaining_slots)
target_pages = remaining_slots;
@@ -2194,8 +2168,6 @@ fast: /* If the page can't be evicted, give up. */
btree->evict_ref = ref;
}
- *pages_seen_p = pages_seen;
-
WT_STAT_CONN_INCRV(session, cache_eviction_walk, refs_walked);
WT_STAT_CONN_INCRV(session, cache_eviction_pages_seen, pages_seen);
WT_STAT_DATA_INCRV(session, cache_eviction_pages_seen, pages_seen);