From 58a03eca6705378ae8d29ffcc9d59794132acb14 Mon Sep 17 00:00:00 2001 From: Wang Yuan Date: Sun, 30 May 2021 16:57:36 +0800 Subject: [PATCH] Make full use of aofrwblock's buf (#8975) Make aof rewrite buffer memory size more accurate, before, there may be 20% deviation with its real memory usage. The implication are both lower memory usage, and also a more accurate INFO. --- src/aof.c | 26 ++++++++++++++++++++++++-- src/evict.c | 2 +- src/object.c | 2 +- src/server.h | 1 + 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/aof.c b/src/aof.c index f4209c6c51..3d0c3b95b4 100644 --- a/src/aof.c +++ b/src/aof.c @@ -61,6 +61,11 @@ void aofClosePipes(void); typedef struct aofrwblock { unsigned long used, free, pos; + /* Note that 'buf' must be the last field of aofrwblock struct, because + * memory allocator may give us more memory than our apply for reducing + * fragments, but we want to make full use of given memory, i.e. we may + * access the memory after 'buf'. To avoid make others fields corrupt, + * 'buf' must be the last one. */ char buf[AOF_RW_BUF_BLOCK_SIZE]; } aofrwblock; @@ -89,6 +94,22 @@ unsigned long aofRewriteBufferSize(void) { return size; } +/* This function is different from aofRewriteBufferSize, to get memory usage, + * we should also count all other fields(except 'buf') of aofrwblock and the + * last block's free size. */ +unsigned long aofRewriteBufferMemoryUsage(void) { + unsigned long size = aofRewriteBufferSize(); + + listNode *ln = listLast(server.aof_rewrite_buf_blocks); + if (ln != NULL) { + aofrwblock *block = listNodeValue(ln); + size += block->free; + size += (offsetof(aofrwblock,buf) * + listLength(server.aof_rewrite_buf_blocks)); + } + return size; +} + /* Event handler used to send data to the child process doing the AOF * rewrite. We send pieces of our AOF differences buffer so that the final * write when the child finishes the rewrite will be small. */ @@ -144,9 +165,10 @@ void aofRewriteBufferAppend(unsigned char *s, unsigned long len) { if (len) { /* First block to allocate, or need another block. */ int numblocks; + size_t usable_size; - block = zmalloc(sizeof(*block)); - block->free = AOF_RW_BUF_BLOCK_SIZE; + block = zmalloc_usable(sizeof(*block), &usable_size); + block->free = usable_size-offsetof(aofrwblock,buf); block->used = 0; block->pos = 0; listAddNodeTail(server.aof_rewrite_buf_blocks,block); diff --git a/src/evict.c b/src/evict.c index 2f94f59420..227e15a8df 100644 --- a/src/evict.c +++ b/src/evict.c @@ -342,7 +342,7 @@ size_t freeMemoryGetNotCountedMemory(void) { } } if (server.aof_state != AOF_OFF) { - overhead += sdsAllocSize(server.aof_buf)+aofRewriteBufferSize(); + overhead += sdsAllocSize(server.aof_buf)+aofRewriteBufferMemoryUsage(); } return overhead; } diff --git a/src/object.c b/src/object.c index c7b25ffd4f..8e8ba77858 100644 --- a/src/object.c +++ b/src/object.c @@ -1011,7 +1011,7 @@ struct redisMemOverhead *getMemoryOverheadData(void) { mem = 0; if (server.aof_state != AOF_OFF) { mem += sdsZmallocSize(server.aof_buf); - mem += aofRewriteBufferSize(); + mem += aofRewriteBufferMemoryUsage(); } mh->aof_buffer = mem; mem_total+=mem; diff --git a/src/server.h b/src/server.h index 52778d1ed8..7da2f5684d 100644 --- a/src/server.h +++ b/src/server.h @@ -2077,6 +2077,7 @@ int startAppendOnly(void); void backgroundRewriteDoneHandler(int exitcode, int bysignal); void aofRewriteBufferReset(void); unsigned long aofRewriteBufferSize(void); +unsigned long aofRewriteBufferMemoryUsage(void); ssize_t aofReadDiffFromParent(void); void killAppendOnlyChild(void); void restartAOFAfterSYNC();