From b5a20a4f916435d4bf8deb0bb3ec52493723aa42 Mon Sep 17 00:00:00 2001 From: Alex Cope Date: Fri, 7 Jul 2023 07:37:07 -0700 Subject: [PATCH] modify --- src/evict.cpp | 18 ++++++++++++++---- src/server.h | 5 ++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/evict.cpp b/src/evict.cpp index 6c211e444..cf5046567 100644 --- a/src/evict.cpp +++ b/src/evict.cpp @@ -414,8 +414,13 @@ size_t freeMemoryGetNotCountedMemory(void) { * memory currently used. May be > 1 if we are over the memory * limit. * (Populated both for C_ERR and C_OK) + * + * 'reason' the reason why the memory limit was exceeded + * EVICT_REASON_USER: reported user memory exceeded maxmemory + * EVICT_REASON_SYS: available system memory under configurable threshold + * (Populated when C_ERR is returned) */ -int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *level, bool fQuickCycle, bool fPreSnapshot) { +int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *level, int *reason, bool fQuickCycle, bool fPreSnapshot) { size_t mem_reported, mem_used, mem_tofree; /* Check if we are over the memory usage limit. If we are not, no need @@ -480,6 +485,8 @@ int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *lev if (logical) *logical = mem_used; if (tofree) *tofree = mem_tofree; + if (reason) *reason = sys_available_mem_buffer < 0 ? EVICT_REASON_SYS : EVICT_REASON_USER; + return C_ERR; } @@ -668,10 +675,11 @@ int performEvictions(bool fPreSnapshot) { const bool fEvictToStorage = !cserver.delete_on_evict && g_pserver->db[0]->FStorageProvider(); int result = EVICT_FAIL; int ckeysFailed = 0; + int evictReason; std::unique_ptr splazy = std::make_unique(); - if (getMaxmemoryState(&mem_reported,NULL,&mem_tofree,NULL,false,fPreSnapshot) == C_OK) + if (getMaxmemoryState(&mem_reported,NULL,&mem_tofree,NULL,&evictReason,false,fPreSnapshot) == C_OK) return EVICT_OK; if (g_pserver->maxmemory_policy == MAXMEMORY_NO_EVICTION) @@ -854,7 +862,9 @@ int performEvictions(bool fPreSnapshot) { * across the dbAsyncDelete() call, while the thread can * release the memory all the time. */ if (g_pserver->lazyfree_lazy_eviction) { - updateSysAvailableMemory(); + if (evictReason == EVICT_REASON_SYS) { + updateSysAvailableMemory(); + } if (getMaxmemoryState(NULL,NULL,NULL,NULL) == C_OK) { break; } @@ -885,7 +895,7 @@ int performEvictions(bool fPreSnapshot) { } cant_free: - if (mem_freed > 0) { + if (mem_freed > 0 && evictReason == EVICT_REASON_SYS) { updateSysAvailableMemory(); } diff --git a/src/server.h b/src/server.h index 475ef3ad3..5d415265c 100644 --- a/src/server.h +++ b/src/server.h @@ -3378,7 +3378,7 @@ int zslLexValueGteMin(sds value, zlexrangespec *spec); int zslLexValueLteMax(sds value, zlexrangespec *spec); /* Core functions */ -int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *level, bool fQuickCycle = false, bool fPreSnapshot=false); +int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *level, int *reason=NULL, bool fQuickCycle=false, bool fPreSnapshot=false); size_t freeMemoryGetNotCountedMemory(); int overMaxmemoryAfterAlloc(size_t moremem); int processCommand(client *c, int callFlags); @@ -3662,6 +3662,9 @@ unsigned long LFUDecrAndReturn(robj_roptr o); #define EVICT_RUNNING 1 #define EVICT_FAIL 2 int performEvictions(bool fPreSnapshot); +#define EVICT_REASON_NONE 0 +#define EVICT_REASON_USER 1 +#define EVICT_REASON_SYS 2 /* meminfo.cpp -- get memory info from /proc/memoryinfo for linux distros */ size_t getMemAvailable();