Fix rdb fd leak (#579)

* close tempfile when done bgsave

* declare getTempFileName

* open close child pipes in correct place

* assert no existing child pipe when opening new child pipe
This commit is contained in:
Malavan Sotheeswaran 2023-03-02 13:51:47 -05:00 committed by GitHub
parent a9995d2e54
commit c2077a2fbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 5 additions and 3 deletions

View File

@ -42,6 +42,7 @@ typedef struct {
* RDB / AOF saving process from the child to the parent (for instance * RDB / AOF saving process from the child to the parent (for instance
* the amount of copy on write memory used) */ * the amount of copy on write memory used) */
void openChildInfoPipe(void) { void openChildInfoPipe(void) {
serverAssert(g_pserver->child_info_pipe[0] == -1);
if (pipe(g_pserver->child_info_pipe) == -1) { if (pipe(g_pserver->child_info_pipe) == -1) {
/* On error our two file descriptors should be still set to -1, /* On error our two file descriptors should be still set to -1,
* but we call anyway closeChildInfoPipe() since can't hurt. */ * but we call anyway closeChildInfoPipe() since can't hurt. */

View File

@ -1490,7 +1490,7 @@ int rdbSaveFile(char *filename, const redisDbPersistentDataSnapshot **rgpdb, rdb
rio rdb; rio rdb;
int error = 0; int error = 0;
snprintf(tmpfile,sizeof(tmpfile),"temp-%d-%d.rdb", getpid(), g_pserver->rdbThreadVars.tmpfileNum); getTempFileName(tmpfile, g_pserver->rdbThreadVars.tmpfileNum);
fp = fopen(tmpfile,"w"); fp = fopen(tmpfile,"w");
if (!fp) { if (!fp) {
char *cwdp = getcwd(cwd,MAXPATHLEN); char *cwdp = getcwd(cwd,MAXPATHLEN);
@ -1660,12 +1660,14 @@ int launchRdbSaveThread(pthread_t &child, rdbSaveInfo *rsi)
pthread_attr_t tattr; pthread_attr_t tattr;
pthread_attr_init(&tattr); pthread_attr_init(&tattr);
pthread_attr_setstacksize(&tattr, 1 << 23); // 8 MB pthread_attr_setstacksize(&tattr, 1 << 23); // 8 MB
openChildInfoPipe();
if (pthread_create(&child, &tattr, rdbSaveThread, args)) { if (pthread_create(&child, &tattr, rdbSaveThread, args)) {
pthread_attr_destroy(&tattr); pthread_attr_destroy(&tattr);
for (int idb = 0; idb < cserver.dbnum; ++idb) for (int idb = 0; idb < cserver.dbnum; ++idb)
g_pserver->db[idb]->endSnapshot(args->rgpdb[idb]); g_pserver->db[idb]->endSnapshot(args->rgpdb[idb]);
args->~rdbSaveThreadArgs(); args->~rdbSaveThreadArgs();
zfree(args); zfree(args);
closeChildInfoPipe();
return C_ERR; return C_ERR;
} }
pthread_attr_destroy(&tattr); pthread_attr_destroy(&tattr);
@ -1683,13 +1685,11 @@ int rdbSaveBackground(rdbSaveInfo *rsi) {
g_pserver->dirty_before_bgsave = g_pserver->dirty; g_pserver->dirty_before_bgsave = g_pserver->dirty;
g_pserver->lastbgsave_try = time(NULL); g_pserver->lastbgsave_try = time(NULL);
openChildInfoPipe();
start = ustime(); start = ustime();
latencyStartMonitor(g_pserver->rdb_save_latency); latencyStartMonitor(g_pserver->rdb_save_latency);
if (launchRdbSaveThread(child, rsi) != C_OK) { if (launchRdbSaveThread(child, rsi) != C_OK) {
closeChildInfoPipe();
g_pserver->lastbgsave_status = C_ERR; g_pserver->lastbgsave_status = C_ERR;
serverLog(LL_WARNING,"Can't save in background: fork: %s", serverLog(LL_WARNING,"Can't save in background: fork: %s",
strerror(errno)); strerror(errno));

View File

@ -151,6 +151,7 @@ int rdbLoad(rdbSaveInfo *rsi, int rdbflags);
int rdbLoadFile(const char *filename, rdbSaveInfo *rsi, int rdbflags); int rdbLoadFile(const char *filename, rdbSaveInfo *rsi, int rdbflags);
int rdbSaveBackground(rdbSaveInfo *rsi); int rdbSaveBackground(rdbSaveInfo *rsi);
int rdbSaveToSlavesSockets(rdbSaveInfo *rsi); int rdbSaveToSlavesSockets(rdbSaveInfo *rsi);
void getTempFileName(char tmpfile[], int tmpfileNum);
void rdbRemoveTempFile(pid_t childpid, int from_signal); void rdbRemoveTempFile(pid_t childpid, int from_signal);
int rdbSave(const redisDbPersistentDataSnapshot **rgpdb, rdbSaveInfo *rsi); int rdbSave(const redisDbPersistentDataSnapshot **rgpdb, rdbSaveInfo *rsi);
int rdbSaveFile(char *filename, const redisDbPersistentDataSnapshot **rgpdb, rdbSaveInfo *rsi); int rdbSaveFile(char *filename, const redisDbPersistentDataSnapshot **rgpdb, rdbSaveInfo *rsi);