Kill the background saving process before performing SHUTDOWN to avoid races

This commit is contained in:
antirez 2009-06-05 22:52:30 +02:00
parent 33c08b3916
commit 9f3c422c72
3 changed files with 25 additions and 15 deletions

View File

@ -425,15 +425,6 @@ int main(int argc, char **argv) {
}
do {
prepareForBenchmark();
c = createClient();
if (!c) exit(1);
c->obuf = sdscat(c->obuf,"PING\r\n");
c->replytype = REPLY_RETCODE;
createMissingClients(c);
aeMain(config.el);
endBenchmark("PING");
prepareForBenchmark();
c = createClient();
if (!c) exit(1);
@ -488,6 +479,15 @@ int main(int argc, char **argv) {
aeMain(config.el);
endBenchmark("LPOP");
prepareForBenchmark();
c = createClient();
if (!c) exit(1);
c->obuf = sdscat(c->obuf,"PING\r\n");
c->replytype = REPLY_RETCODE;
createMissingClients(c);
aeMain(config.el);
endBenchmark("PING");
printf("\n");
} while(config.loop);

View File

@ -27,7 +27,7 @@
<div class="narrow">
<h1><a name="LREM _key_ _count_ _value_">LREM _key_ _count_ _value_</a></h1>
<i>Time complexity: O(N) (with N being the length of the list)</i><blockquote>Remove the first <i>count</i> occurrences of the <i>value</i> element from the list.If <i>count</i> is zero all the elements are removed. If <i>count</i> is negativeelements are removed from tail to head, instead to go from head to tailthat is the normal behaviour. So for example LREM with count -2 and_hello_ as value to remove against the list (a,b,c,hello,x,hello,hello) willlave the list (a,b,c,hello,x). The number of removed elements is returnedas an integer, see below for more information aboht the returned value.</blockquote>
<i>Time complexity: O(N) (with N being the length of the list)</i><blockquote>Remove the first <i>count</i> occurrences of the <i>value</i> element from the list.If <i>count</i> is zero all the elements are removed. If <i>count</i> is negativeelements are removed from tail to head, instead to go from head to tailthat is the normal behaviour. So for example LREM with count -2 and_hello_ as value to remove against the list (a,b,c,hello,x,hello,hello) willlave the list (a,b,c,hello,x). The number of removed elements is returnedas an integer, see below for more information about the returned value.Note that non existing keys are considered like empty lists by LREM, so LREMagainst non existing keys will always return 0.</blockquote>
<h2><a name="Return value">Return value</a></h2><a href="ReplyTypes.html">Integer Reply</a>, specifically:<br/><br/><pre class="codeblock python" name="code">
The number of removed elements if the operation succeeded
</pre><h2><a name="See also">See also</a></h2>

20
redis.c
View File

@ -240,6 +240,7 @@ struct redisServer {
int daemonize;
char *pidfile;
int bgsaveinprogress;
pid_t bgsavechildpid;
struct saveparam *saveparams;
int saveparamslen;
char *logfile;
@ -748,16 +749,21 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
/* XXX: TODO handle the case of the saving child killed */
if (wait4(-1,&statloc,WNOHANG,NULL)) {
int exitcode = WEXITSTATUS(statloc);
if (exitcode == 0) {
int bysignal = WIFSIGNALED(statloc);
if (!bysignal && exitcode == 0) {
redisLog(REDIS_NOTICE,
"Background saving terminated with success");
server.dirty = 0;
server.lastsave = time(NULL);
} else if (!bysignal && exitcode != 0) {
redisLog(REDIS_WARNING, "Background saving error");
} else {
redisLog(REDIS_WARNING,
"Background saving error");
"Background saving terminated by signal");
}
server.bgsaveinprogress = 0;
server.bgsavechildpid = -1;
updateSalvesWaitingBgsave(exitcode == 0 ? REDIS_OK : REDIS_ERR);
}
} else {
@ -919,6 +925,7 @@ static void initServer() {
}
server.cronloops = 0;
server.bgsaveinprogress = 0;
server.bgsavechildpid = -1;
server.lastsave = time(NULL);
server.dirty = 0;
server.usedmemory = 0;
@ -1983,6 +1990,7 @@ static int rdbSaveBackground(char *filename) {
}
redisLog(REDIS_NOTICE,"Background saving started by pid %d",childpid);
server.bgsaveinprogress = 1;
server.bgsavechildpid = childpid;
return REDIS_OK;
}
return REDIS_OK; /* unreached */
@ -2505,11 +2513,13 @@ static void bgsaveCommand(redisClient *c) {
static void shutdownCommand(redisClient *c) {
redisLog(REDIS_WARNING,"User requested shutdown, saving DB...");
/* XXX: TODO kill the child if there is a bgsave in progress */
if (server.bgsaveinprogress) {
redisLog(REDIS_WARNING,"There is a live saving child. Killing it!");
kill(server.bgsavechildpid,SIGKILL);
}
if (rdbSave(server.dbfilename) == REDIS_OK) {
if (server.daemonize) {
if (server.daemonize)
unlink(server.pidfile);
}
redisLog(REDIS_WARNING,"%zu bytes used at exit",zmalloc_used_memory());
redisLog(REDIS_WARNING,"Server exit now, bye bye...");
exit(1);