diff --git a/src/config.c b/src/config.c index 8a2690a0..9f51bba8 100644 --- a/src/config.c +++ b/src/config.c @@ -1248,7 +1248,7 @@ void configSetCommand(client *c) { if (server.maxmemory < zmalloc_used_memory()) { serverLog(LL_WARNING,"WARNING: the new maxmemory value set via CONFIG SET is smaller than the current memory usage. This will result in key eviction and/or the inability to accept new write commands depending on the maxmemory-policy."); } - freeMemoryIfNeeded(); + freeMemoryIfNeededAndSafe(); } } config_set_memory_field( "proto-max-bulk-len",server.proto_max_bulk_len) { diff --git a/src/evict.c b/src/evict.c index 980a91f7..773916ce 100644 --- a/src/evict.c +++ b/src/evict.c @@ -445,14 +445,8 @@ int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *lev * was freed to return back under the limit, the function returns C_ERR. */ int freeMemoryIfNeeded(void) { /* By default replicas should ignore maxmemory - * and just be masters exact copies. - * - * And don't care about mem if loading. */ - if (server.loading || - (server.masterhost && server.repl_slave_ignore_maxmemory)) - { - return C_OK; - } + * 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; @@ -628,3 +622,14 @@ cant_free: return C_ERR; } +/* This is a wrapper for freeMemoryIfNeeded() that only really calls the + * function if right now there are the conditions to do so safely: + * + * - There must be no script in timeout condition. + * - Nor we are loading data right now. + * + */ +int freeMemoryIfNeededAndSafe(void) { + if (server.lua_timedout || server.loading) return C_OK; + return freeMemoryIfNeeded(); +} diff --git a/src/server.c b/src/server.c index 28a79455..9371b2ba 100644 --- a/src/server.c +++ b/src/server.c @@ -2613,7 +2613,7 @@ int processCommand(client *c) { * condition, to avoid mixing the propagation of scripts with the * propagation of DELs due to eviction. */ if (server.maxmemory && !server.lua_timedout) { - int out_of_memory = freeMemoryIfNeeded() == C_ERR; + int out_of_memory = freeMemoryIfNeededAndSafe() == C_ERR; /* freeMemoryIfNeeded may flush slave output buffers. This may result * into a slave, that may be the active client, to be freed. */ if (server.current_client == NULL) return C_ERR; diff --git a/src/server.h b/src/server.h index a87fd975..da4c6d45 100644 --- a/src/server.h +++ b/src/server.h @@ -1702,6 +1702,7 @@ int zslLexValueLteMax(sds value, zlexrangespec *spec); int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *level); size_t freeMemoryGetNotCountedMemory(); int freeMemoryIfNeeded(void); +int freeMemoryIfNeededAndSafe(void); int processCommand(client *c); void setupSignalHandlers(void); struct redisCommand *lookupCommand(sds name);