summaryrefslogtreecommitdiff
path: root/src/aof.c
diff options
context:
space:
mode:
authorzhaozhao.zz <zhaozhao.zz@alibaba-inc.com>2018-08-02 14:59:28 +0800
committerzhaozhao.zz <zhaozhao.zz@alibaba-inc.com>2018-08-03 23:30:34 +0800
commiteb87da6127c605be06073903a0bbaff792b90d70 (patch)
treeeae0f46a553494a96f98a1e25fdf0af3ee575a3f /src/aof.c
parent39c70e728b5af0c50989ffbc05e568099f3e081b (diff)
downloadredis-eb87da6127c605be06073903a0bbaff792b90d70.tar.gz
AOF: discard if we lost EXEC when loading aof
Diffstat (limited to 'src/aof.c')
-rw-r--r--src/aof.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/aof.c b/src/aof.c
index f8f26bdfe..0c7f28269 100644
--- a/src/aof.c
+++ b/src/aof.c
@@ -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);