summaryrefslogtreecommitdiff
path: root/items.c
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2017-01-02 12:14:17 -0800
committerdormando <dormando@rydia.net>2017-01-22 19:56:08 -0800
commite308807389190ea94d0df603359297101229fbc6 (patch)
tree5f3871873b496ba550ba5662faa9c8a57a7d00e7 /items.c
parent9d51fdd2deda4a6f2dea411343b8ae3c7242a923 (diff)
downloadmemcached-e308807389190ea94d0df603359297101229fbc6.tar.gz
LRU maint test fix for second mystery
If an LRU is too large, ACTIVE processing was elided on purpose. However it's very easy for even moderate write pressure to pass a large number of ACTIVE items into COLD. This combined with not removing items from COLD immediately (fixed in another commit) could easily cause very active items to be evicted along with inactive ones. With the speedup of the processing thread (with some low-fruit still), it should be fine to quickly flip items in place. This opens up a problem under extreme write pressure which overwhelms the background thread, or extreme re-scanning of large numbers of items. It might still be valuable to do pressure release or direct reclaim pulling if COLD gets too large. Performance tests should be done to find the threshold and experiment.
Diffstat (limited to 'items.c')
-rw-r--r--items.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/items.c b/items.c
index 0264c32..d3d240f 100644
--- a/items.c
+++ b/items.c
@@ -958,20 +958,20 @@ static int lru_pull_tail(const int orig_id, const int cur_lru,
case WARM_LRU:
if (limit == 0)
limit = total_bytes * settings.warm_lru_pct / 100;
- if (sizes_bytes[id] > limit) {
+ /* Rescue ACTIVE items aggressively */
+ if ((search->it_flags & ITEM_ACTIVE) != 0) {
+ itemstats[id].moves_within_lru++;
+ search->it_flags &= ~ITEM_ACTIVE;
+ do_item_update_nolock(search);
+ do_item_remove(search);
+ item_trylock_unlock(hold_lock);
+ } else if (sizes_bytes[id] > limit) {
itemstats[id].moves_to_cold++;
move_to_lru = COLD_LRU;
do_item_unlink_q(search);
it = search;
removed++;
break;
- } else if ((search->it_flags & ITEM_ACTIVE) != 0) {
- /* Only allow ACTIVE relinking if we're not too large. */
- itemstats[id].moves_within_lru++;
- search->it_flags &= ~ITEM_ACTIVE;
- do_item_update_nolock(search);
- do_item_remove(search);
- item_trylock_unlock(hold_lock);
} else {
/* Don't want to move to COLD, not active, bail out */
it = search;