freeMemoryIfNeeded() small refactoring.

Related to issue #5686 and PR #5689.
This commit is contained in:
antirez 2018-12-12 11:37:15 +01:00
parent 7ae184bfea
commit 129f2d2746
4 changed files with 16 additions and 10 deletions

View File

@ -1248,7 +1248,7 @@ void configSetCommand(client *c) {
if (server.maxmemory < zmalloc_used_memory()) { 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."); 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( } config_set_memory_field(
"proto-max-bulk-len",server.proto_max_bulk_len) { "proto-max-bulk-len",server.proto_max_bulk_len) {

View File

@ -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. */ * was freed to return back under the limit, the function returns C_ERR. */
int freeMemoryIfNeeded(void) { int freeMemoryIfNeeded(void) {
/* By default replicas should ignore maxmemory /* By default replicas should ignore maxmemory
* and just be masters exact copies. * and just be masters exact copies. */
* if (server.masterhost && server.repl_slave_ignore_maxmemory) return C_OK;
* And don't care about mem if loading. */
if (server.loading ||
(server.masterhost && server.repl_slave_ignore_maxmemory))
{
return C_OK;
}
size_t mem_reported, mem_tofree, mem_freed; size_t mem_reported, mem_tofree, mem_freed;
mstime_t latency, eviction_latency; mstime_t latency, eviction_latency;
@ -628,3 +622,14 @@ cant_free:
return C_ERR; 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();
}

View File

@ -2613,7 +2613,7 @@ int processCommand(client *c) {
* condition, to avoid mixing the propagation of scripts with the * condition, to avoid mixing the propagation of scripts with the
* propagation of DELs due to eviction. */ * propagation of DELs due to eviction. */
if (server.maxmemory && !server.lua_timedout) { 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 /* freeMemoryIfNeeded may flush slave output buffers. This may result
* into a slave, that may be the active client, to be freed. */ * into a slave, that may be the active client, to be freed. */
if (server.current_client == NULL) return C_ERR; if (server.current_client == NULL) return C_ERR;

View File

@ -1702,6 +1702,7 @@ int zslLexValueLteMax(sds value, zlexrangespec *spec);
int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *level); int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *level);
size_t freeMemoryGetNotCountedMemory(); size_t freeMemoryGetNotCountedMemory();
int freeMemoryIfNeeded(void); int freeMemoryIfNeeded(void);
int freeMemoryIfNeededAndSafe(void);
int processCommand(client *c); int processCommand(client *c);
void setupSignalHandlers(void); void setupSignalHandlers(void);
struct redisCommand *lookupCommand(sds name); struct redisCommand *lookupCommand(sds name);