Disable rehash when redis has child process (#8007)

In redisFork(), we don't set child pid, so updateDictResizePolicy()
doesn't take effect, that isn't friendly for copy-on-write.

The bug was introduced this in redis 6.0: 56258c6
This commit is contained in:
Wang Yuan 2020-11-03 23:16:11 +08:00 committed by GitHub
parent f210e197f3
commit 89c78a9808
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 27 additions and 1 deletions

View File

@ -1715,6 +1715,7 @@ int rewriteAppendOnlyFileBackground(void) {
server.aof_rewrite_scheduled = 0; server.aof_rewrite_scheduled = 0;
server.aof_rewrite_time_start = time(NULL); server.aof_rewrite_time_start = time(NULL);
server.aof_child_pid = childpid; server.aof_child_pid = childpid;
updateDictResizePolicy();
/* We set appendseldb to -1 in order to force the next call to the /* We set appendseldb to -1 in order to force the next call to the
* feedAppendOnlyFile() to issue a SELECT command, so the differences * feedAppendOnlyFile() to issue a SELECT command, so the differences
* accumulated by the parent into server.aof_rewrite_buf will start * accumulated by the parent into server.aof_rewrite_buf will start

View File

@ -7001,6 +7001,7 @@ int RM_Fork(RedisModuleForkDoneHandler cb, void *user_data) {
server.module_child_pid = childpid; server.module_child_pid = childpid;
moduleForkInfo.done_handler = cb; moduleForkInfo.done_handler = cb;
moduleForkInfo.done_handler_user_data = user_data; moduleForkInfo.done_handler_user_data = user_data;
updateDictResizePolicy();
serverLog(LL_VERBOSE, "Module fork started pid: %d ", childpid); serverLog(LL_VERBOSE, "Module fork started pid: %d ", childpid);
} }
return childpid; return childpid;

View File

@ -1412,6 +1412,7 @@ int rdbSaveBackground(char *filename, rdbSaveInfo *rsi) {
server.rdb_save_time_start = time(NULL); server.rdb_save_time_start = time(NULL);
server.rdb_child_pid = childpid; server.rdb_child_pid = childpid;
server.rdb_child_type = RDB_CHILD_TYPE_DISK; server.rdb_child_type = RDB_CHILD_TYPE_DISK;
updateDictResizePolicy();
return C_OK; return C_OK;
} }
return C_OK; /* unreached */ return C_OK; /* unreached */
@ -2618,6 +2619,7 @@ int rdbSaveToSlavesSockets(rdbSaveInfo *rsi) {
server.rdb_save_time_start = time(NULL); server.rdb_save_time_start = time(NULL);
server.rdb_child_pid = childpid; server.rdb_child_pid = childpid;
server.rdb_child_type = RDB_CHILD_TYPE_SOCKET; server.rdb_child_type = RDB_CHILD_TYPE_SOCKET;
updateDictResizePolicy();
close(rdb_pipe_write); /* close write in parent so that it can detect the close on the child. */ close(rdb_pipe_write); /* close write in parent so that it can detect the close on the child. */
if (aeCreateFileEvent(server.el, server.rdb_pipe_read, AE_READABLE, rdbPipeReadHandler,NULL) == AE_ERR) { if (aeCreateFileEvent(server.el, server.rdb_pipe_read, AE_READABLE, rdbPipeReadHandler,NULL) == AE_ERR) {
serverPanic("Unrecoverable error creating server.rdb_pipe_read file event."); serverPanic("Unrecoverable error creating server.rdb_pipe_read file event.");

View File

@ -2052,6 +2052,9 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
} }
} }
} }
/* Just for the sake of defensive programming, to avoid forgeting to
* call this function when need. */
updateDictResizePolicy();
/* AOF postponed flush: Try at every cron cycle if the slow fsync /* AOF postponed flush: Try at every cron cycle if the slow fsync
@ -5072,7 +5075,6 @@ int redisFork(int purpose) {
if (childpid == -1) { if (childpid == -1) {
return -1; return -1;
} }
updateDictResizePolicy();
} }
return childpid; return childpid;
} }

View File

@ -250,3 +250,23 @@ start_server {tags {"other"}} {
r save r save
} {OK} } {OK}
} }
start_server {tags {"other"}} {
test {Don't rehash if redis has child proecess} {
r config set save ""
r config set rdb-key-save-delay 1000000
populate 4096 "" 1
r bgsave
r mset k1 v1 k2 v2
# Hash table should not rehash
assert_no_match "*table size: 8192*" [r debug HTSTATS 9]
exec kill -9 [get_child_pid 0]
after 200
# Hash table should rehash since there is no child process,
# size is power of two and over 4098, so it is 16384
r set k3 v3
assert_match "*table size: 16384*" [r debug HTSTATS 9]
}
}