summaryrefslogtreecommitdiff
path: root/src/childinfo.c
diff options
context:
space:
mode:
authorOran Agra <oran@redislabs.com>2022-11-09 10:02:18 +0200
committerGitHub <noreply@github.com>2022-11-09 10:02:18 +0200
commitccaef5c923a14dc183c50530f52ada0fda012179 (patch)
treef8af010a6549d77db8d90465fbff65459a557d51 /src/childinfo.c
parentf92899185367ab08a084c501ba54759390c92e63 (diff)
downloadredis-ccaef5c923a14dc183c50530f52ada0fda012179.tar.gz
diskless master, avoid bgsave child hung when fork parent crashes (#11463)
During a diskless sync, if the master main process crashes, the child would have hung in `write`. This fix closes the read fd on the child side, so that if the parent crashes, the child will get a write error and exit. This change also fixes disk-based replication, BGSAVE and AOFRW. In that case the child wouldn't have been hang, it would have just kept running until done which may be pointless. There is a certain degree of risk here. in case there's a BGSAVE child that could maybe succeed and the parent dies for some reason, the old code would have let the child keep running and maybe succeed and avoid data loss. On the other hand, if the parent is restarted, it would have loaded an old rdb file (or none), and then the child could reach the end and rename the rdb file (data conflicting with what the parent has), or also have a race with another BGSAVE child that the new parent started. Note that i removed a comment saying a write error will be ignored in the child and handled by the parent (this comment was very old and i don't think relevant).
Diffstat (limited to 'src/childinfo.c')
-rw-r--r--src/childinfo.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/src/childinfo.c b/src/childinfo.c
index 015987c84..e5184ff8b 100644
--- a/src/childinfo.c
+++ b/src/childinfo.c
@@ -112,7 +112,9 @@ void sendChildInfoGeneric(childInfoType info_type, size_t keys, double progress,
ssize_t wlen = sizeof(data);
if (write(server.child_info_pipe[1], &data, wlen) != wlen) {
- /* Nothing to do on error, this will be detected by the other side. */
+ /* Failed writing to parent, it could have been killed, exit. */
+ serverLog(LL_WARNING,"Child failed reporting info to parent, exiting. %s", strerror(errno));
+ exit(1);
}
}