AOF: discard if we lost EXEC when loading aof

This commit is contained in:
zhaozhao.zz 2018-08-02 14:59:28 +08:00 committed by antirez
parent e0d4c66aff
commit e6f287d59f
2 changed files with 14 additions and 3 deletions

View File

@ -677,6 +677,7 @@ int loadAppendOnlyFile(char *filename) {
int old_aof_state = server.aof_state;
long loops = 0;
off_t valid_up_to = 0; /* Offset of latest well-formed command loaded. */
off_t valid_before_multi = 0; /* Offset before MULTI command loaded. */
if (fp == NULL) {
serverLog(LL_WARNING,"Fatal error: can't open the append log file for reading: %s",strerror(errno));
@ -781,9 +782,15 @@ int loadAppendOnlyFile(char *filename) {
exit(1);
}
if (cmd == server.multiCommand) valid_before_multi = valid_up_to;
/* Run the command in the context of a fake client */
fakeClient->cmd = cmd;
cmd->proc(fakeClient);
if (fakeClient->flags & CLIENT_MULTI && fakeClient->cmd->proc != execCommand) {
queueMultiCommand(fakeClient);
} else {
cmd->proc(fakeClient);
}
/* The fake client should not have a reply */
serverAssert(fakeClient->bufpos == 0 && listLength(fakeClient->reply) == 0);
@ -801,7 +808,11 @@ int loadAppendOnlyFile(char *filename) {
* If the client is in the middle of a MULTI/EXEC, handle it as it was
* a short read, even if technically the protocol is correct: we want
* to remove the unprocessed tail and continue. */
if (fakeClient->flags & CLIENT_MULTI) goto uxeof;
if (fakeClient->flags & CLIENT_MULTI) {
serverLog(LL_WARNING,"!!! Warning: we lost EXEC in the middle of transaction, discard !!!");
valid_up_to = valid_before_multi;
goto uxeof;
}
loaded_ok: /* DB loaded, cleanup and return C_OK to the caller. */
fclose(fp);

View File

@ -158,7 +158,7 @@ void execCommand(client *c) {
must_propagate = 1;
}
call(c,CMD_CALL_FULL);
call(c,server.loading ? CMD_CALL_NONE : CMD_CALL_FULL);
/* Commands may alter argc/argv, restore mstate. */
c->mstate.commands[j].argc = c->argc;