mirror of
https://github.com/fluencelabs/redis
synced 2025-03-17 16:10:50 +00:00
Better handling of background saving process killed or crashed
This commit is contained in:
parent
c3cb078d46
commit
a3b21203d2
3
TODO
3
TODO
@ -1,12 +1,11 @@
|
||||
BEFORE REDIS 1.0.0-rc1
|
||||
|
||||
* Add number of keys for every DB in INFO
|
||||
* Cover most of the source code with test-redis.tcl
|
||||
* Remove tmp-.... files when saving child exits in the wrong way, to do so use tmp-pid.rdb as filename so that the parent can rebuild the file name just from the child pid.
|
||||
|
||||
AFTER 1.0 stable release
|
||||
|
||||
* Max command payload bytes configurable, with a pretty large default.
|
||||
* Add a command to inspect the currently selected DB index
|
||||
* Consistent hashing implemented in all the client libraries having an user base
|
||||
* SORT: Don't copy the list into a vector when BY argument is constant.
|
||||
* SORT ... STORE keyname. Instead to return the SORTed data set it into key.
|
||||
|
37
redis.c
37
redis.c
@ -327,10 +327,11 @@ static int deleteIfVolatile(redisDb *db, robj *key);
|
||||
static int deleteKey(redisDb *db, robj *key);
|
||||
static time_t getExpire(redisDb *db, robj *key);
|
||||
static int setExpire(redisDb *db, robj *key, time_t when);
|
||||
static void updateSalvesWaitingBgsave(int bgsaveerr);
|
||||
static void updateSlavesWaitingBgsave(int bgsaveerr);
|
||||
static void freeMemoryIfNeeded(void);
|
||||
static int processCommand(redisClient *c);
|
||||
static void setupSigSegvAction(void);
|
||||
static void rdbRemoveTempFile(pid_t childpid);
|
||||
|
||||
static void authCommand(redisClient *c);
|
||||
static void pingCommand(redisClient *c);
|
||||
@ -778,10 +779,11 @@ static int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientD
|
||||
} else {
|
||||
redisLog(REDIS_WARNING,
|
||||
"Background saving terminated by signal");
|
||||
rdbRemoveTempFile(server.bgsavechildpid);
|
||||
}
|
||||
server.bgsaveinprogress = 0;
|
||||
server.bgsavechildpid = -1;
|
||||
updateSalvesWaitingBgsave(exitcode == 0 ? REDIS_OK : REDIS_ERR);
|
||||
updateSlavesWaitingBgsave(exitcode == 0 ? REDIS_OK : REDIS_ERR);
|
||||
}
|
||||
} else {
|
||||
/* If there is not a background saving in progress check if
|
||||
@ -1900,7 +1902,7 @@ static int rdbSave(char *filename) {
|
||||
int j;
|
||||
time_t now = time(NULL);
|
||||
|
||||
snprintf(tmpfile,256,"temp-%d.%ld.rdb",(int)time(NULL),(long int)random());
|
||||
snprintf(tmpfile,256,"temp-%d.rdb", (int) getpid());
|
||||
fp = fopen(tmpfile,"w");
|
||||
if (!fp) {
|
||||
redisLog(REDIS_WARNING, "Failed saving the DB: %s", strerror(errno));
|
||||
@ -2027,6 +2029,13 @@ static int rdbSaveBackground(char *filename) {
|
||||
return REDIS_OK; /* unreached */
|
||||
}
|
||||
|
||||
static void rdbRemoveTempFile(pid_t childpid) {
|
||||
char tmpfile[256];
|
||||
|
||||
snprintf(tmpfile,256,"temp-%d.rdb", (int) childpid);
|
||||
unlink(tmpfile);
|
||||
}
|
||||
|
||||
static int rdbLoadType(FILE *fp) {
|
||||
unsigned char type;
|
||||
if (fread(&type,1,1,fp) == 0) return -1;
|
||||
@ -2544,11 +2553,15 @@ static void bgsaveCommand(redisClient *c) {
|
||||
|
||||
static void shutdownCommand(redisClient *c) {
|
||||
redisLog(REDIS_WARNING,"User requested shutdown, saving DB...");
|
||||
/* Kill the saving child if there is a background saving in progress.
|
||||
We want to avoid race conditions, for instance our saving child may
|
||||
overwrite the synchronous saving did by SHUTDOWN. */
|
||||
if (server.bgsaveinprogress) {
|
||||
redisLog(REDIS_WARNING,"There is a live saving child. Killing it!");
|
||||
signal(SIGCHLD, SIG_IGN);
|
||||
kill(server.bgsavechildpid,SIGKILL);
|
||||
rdbRemoveTempFile(server.bgsavechildpid);
|
||||
}
|
||||
/* SYNC SAVE */
|
||||
if (rdbSave(server.dbfilename) == REDIS_OK) {
|
||||
if (server.daemonize)
|
||||
unlink(server.pidfile);
|
||||
@ -2556,7 +2569,10 @@ static void shutdownCommand(redisClient *c) {
|
||||
redisLog(REDIS_WARNING,"Server exit now, bye bye...");
|
||||
exit(1);
|
||||
} else {
|
||||
signal(SIGCHLD, SIG_DFL);
|
||||
/* Ooops.. error saving! The best we can do is to continue operating.
|
||||
* Note that if there was a background saving process, in the next
|
||||
* cron() Redis will be notified that the background saving aborted,
|
||||
* handling special stuff like slaves pending for synchronization... */
|
||||
redisLog(REDIS_WARNING,"Error trying to save the DB, can't exit");
|
||||
addReplySds(c,sdsnew("-ERR can't quit, problems saving the DB\r\n"));
|
||||
}
|
||||
@ -3939,7 +3955,13 @@ static void sendBulkToSlave(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||
}
|
||||
}
|
||||
|
||||
static void updateSalvesWaitingBgsave(int bgsaveerr) {
|
||||
/* This function is called at the end of every backgrond saving.
|
||||
* The argument bgsaveerr is REDIS_OK if the background saving succeeded
|
||||
* otherwise REDIS_ERR is passed to the function.
|
||||
*
|
||||
* The goal of this function is to handle slaves waiting for a successful
|
||||
* background saving in order to perform non-blocking synchronization. */
|
||||
static void updateSlavesWaitingBgsave(int bgsaveerr) {
|
||||
listNode *ln;
|
||||
int startbgsave = 0;
|
||||
|
||||
@ -4183,7 +4205,7 @@ static struct redisFunctionSym symsTable[] = {
|
||||
{"deleteKey", (unsigned long)deleteKey},
|
||||
{"getExpire", (unsigned long)getExpire},
|
||||
{"setExpire", (unsigned long)setExpire},
|
||||
{"updateSalvesWaitingBgsave", (unsigned long)updateSalvesWaitingBgsave},
|
||||
{"updateSlavesWaitingBgsave", (unsigned long)updateSlavesWaitingBgsave},
|
||||
{"freeMemoryIfNeeded", (unsigned long)freeMemoryIfNeeded},
|
||||
{"authCommand", (unsigned long)authCommand},
|
||||
{"pingCommand", (unsigned long)pingCommand},
|
||||
@ -4246,6 +4268,7 @@ static struct redisFunctionSym symsTable[] = {
|
||||
{"processCommand", (unsigned long)processCommand},
|
||||
{"setupSigSegvAction", (unsigned long)setupSigSegvAction},
|
||||
{"readQueryFromClient", (unsigned long)readQueryFromClient},
|
||||
{"rdbRemoveTempFile", (unsigned long)rdbRemoveTempFile},
|
||||
{NULL,0}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user