From 2893a181554525164cfec6c609e1da8c483b16ff Mon Sep 17 00:00:00 2001 From: tporadowski Date: Tue, 26 Jan 2021 23:20:45 +0100 Subject: [PATCH] [6.0] src/evict.c --- src/evict.c | 49 +++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/src/evict.c b/src/evict.c index b6687ecc..b5ccdfcd 100644 --- a/src/evict.c +++ b/src/evict.c @@ -41,7 +41,7 @@ /* To improve the quality of the LRU approximation we take a set of keys * that are good candidate for eviction across freeMemoryIfNeeded() calls. * - * Entries inside the eviciton pool are taken ordered by idle time, putting + * Entries inside the eviction pool are taken ordered by idle time, putting * greater idle times to the right (ascending order). * * When an LFU policy is used instead, a reverse frequency indication is used @@ -78,7 +78,7 @@ unsigned int getLRUClock(void) { unsigned int LRU_CLOCK(void) { unsigned int lruclock; if (1000/server.hz <= LRU_CLOCK_RESOLUTION) { - atomicGet(server.lruclock,lruclock); + lruclock = server.lruclock; } else { lruclock = getLRUClock(); } @@ -246,7 +246,7 @@ void evictionPoolPopulate(int dbid, dict *sampledict, dict *keydict, struct evic /* Try to reuse the cached SDS string allocated in the pool entry, * because allocating and deallocating this object is costly * (according to the profiler, not my fantasy. Remember: - * premature optimizbla bla bla bla. */ + * premature optimization bla bla bla. */ int klen = sdslen(key); if (klen > EVPOOL_CACHED_SDS_SIZE) { pool[k].key = sdsdup(key); @@ -350,7 +350,7 @@ PORT_ULONG LFUDecrAndReturn(robj *o) { WIN_PORT_FIX } /* ---------------------------------------------------------------------------- - * The external API for eviction: freeMemroyIfNeeded() is called by the + * The external API for eviction: freeMemoryIfNeeded() is called by the * server when there is data to add in order to make space if needed. * --------------------------------------------------------------------------*/ @@ -449,17 +449,19 @@ int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *lev * * The function returns C_OK if we are under the memory limit or if we * were over the limit, but the attempt to free memory was successful. - * Otehrwise if we are over the memory limit, but not enough memory + * Otherwise if we are over the memory limit, but not enough memory * was freed to return back under the limit, the function returns C_ERR. */ int freeMemoryIfNeeded(void) { + int keys_freed = 0; /* By default replicas should ignore maxmemory * and just be masters exact copies. */ if (server.masterhost && server.repl_slave_ignore_maxmemory) return C_OK; size_t mem_reported, mem_tofree, mem_freed; - mstime_t latency, eviction_latency; + mstime_t latency, eviction_latency, lazyfree_latency; PORT_LONGLONG delta; int slaves = listLength(server.slaves); + int result = C_ERR; /* When clients are paused the dataset should be static not just from the * POV of clients not being able to write, but also from the POV of @@ -470,12 +472,12 @@ int freeMemoryIfNeeded(void) { mem_freed = 0; + latencyStartMonitor(latency); if (server.maxmemory_policy == MAXMEMORY_NO_EVICTION) goto cant_free; /* We need to free memory, but policy forbids. */ - latencyStartMonitor(latency); while (mem_freed < mem_tofree) { - int j, k, i, keys_freed = 0; + int j, k, i; static unsigned int next_db = 0; sds bestkey = NULL; int bestdbid; @@ -576,9 +578,9 @@ int freeMemoryIfNeeded(void) { dbAsyncDelete(db,keyobj); else dbSyncDelete(db,keyobj); + signalModifiedKey(NULL,db,keyobj); latencyEndMonitor(eviction_latency); latencyAddSampleIfNeeded("eviction-del",eviction_latency); - latencyRemoveNestedEvent(latency,eviction_latency); delta -= (PORT_LONGLONG) zmalloc_used_memory(); mem_freed += delta; server.stat_evictedkeys++; @@ -606,28 +608,31 @@ int freeMemoryIfNeeded(void) { mem_freed = mem_tofree; } } - } - - if (!keys_freed) { - latencyEndMonitor(latency); - latencyAddSampleIfNeeded("eviction-cycle",latency); + } else { goto cant_free; /* nothing to free... */ } } - latencyEndMonitor(latency); - latencyAddSampleIfNeeded("eviction-cycle",latency); - return C_OK; + result = C_OK; cant_free: /* We are here if we are not able to reclaim memory. There is only one * last thing we can try: check if the lazyfree thread has jobs in queue * and wait... */ - while(bioPendingJobsOfType(BIO_LAZY_FREE)) { - if (((mem_reported - zmalloc_used_memory()) + mem_freed) >= mem_tofree) - break; - usleep(1000); + if (result != C_OK) { + latencyStartMonitor(lazyfree_latency); + while(bioPendingJobsOfType(BIO_LAZY_FREE)) { + if (getMaxmemoryState(NULL,NULL,NULL,NULL) == C_OK) { + result = C_OK; + break; + } + usleep(1000); + } + latencyEndMonitor(lazyfree_latency); + latencyAddSampleIfNeeded("eviction-lazyfree",lazyfree_latency); } - return C_ERR; + latencyEndMonitor(latency); + latencyAddSampleIfNeeded("eviction-cycle",latency); + return result; } /* This is a wrapper for freeMemoryIfNeeded() that only really calls the