summaryrefslogtreecommitdiff
path: root/src/evict.c
diff options
context:
space:
mode:
authorzhaozhao.zz <zhaozhao.zz@alibaba-inc.com>2022-09-18 22:46:24 +0800
committerGitHub <noreply@github.com>2022-09-18 17:46:24 +0300
commit464aa04188c42c82f411ac7d43fabf0f6038c98e (patch)
tree3e8585c0522b1390f31b020dcb772ca79370c512 /src/evict.c
parentd144dc927a6ea10cd5dcbdb2eacd58e929dedcfe (diff)
downloadredis-464aa04188c42c82f411ac7d43fabf0f6038c98e.tar.gz
fix infinite sleep in performEvictions when have lazyfree jobs (#11237)
This bug is introduced in #7653. (Redis 6.2.0) When `server.maxmemory_eviction_tenacity` is 100, `eviction_time_limit_us` is `ULONG_MAX`, and if we cannot find the best key to delete (e.g. maxmemory-policy is `volatile-lru` and all keys with ttl have been evicted), in `cant_free` redis will sleep forever if some items are being freed in the lazyfree thread.
Diffstat (limited to 'src/evict.c')
-rw-r--r--src/evict.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/evict.c b/src/evict.c
index 3c767a557..45ec95f1f 100644
--- a/src/evict.c
+++ b/src/evict.c
@@ -595,7 +595,7 @@ int performEvictions(void) {
{
struct evictionPoolEntry *pool = EvictionPoolLRU;
- while(bestkey == NULL) {
+ while (bestkey == NULL) {
unsigned long total_keys = 0, keys;
/* We don't want to make local-db choices when expiring keys,
@@ -738,12 +738,18 @@ cant_free:
/* At this point, we have run out of evictable items. It's possible
* that some items are being freed in the lazyfree thread. Perform a
* short wait here if such jobs exist, but don't wait long. */
- if (bioPendingJobsOfType(BIO_LAZY_FREE)) {
- usleep(eviction_time_limit_us);
+ mstime_t lazyfree_latency;
+ latencyStartMonitor(lazyfree_latency);
+ while (bioPendingJobsOfType(BIO_LAZY_FREE) &&
+ elapsedUs(evictionTimer) < eviction_time_limit_us) {
if (getMaxmemoryState(NULL,NULL,NULL,NULL) == C_OK) {
result = EVICT_OK;
+ break;
}
+ usleep(eviction_time_limit_us < 1000 ? eviction_time_limit_us : 1000);
}
+ latencyEndMonitor(lazyfree_latency);
+ latencyAddSampleIfNeeded("eviction-lazyfree",lazyfree_latency);
}
serverAssert(server.core_propagates); /* This function should not be re-entrant */