diff --git a/src/aof.c b/src/aof.c index 2f543ba7c..2698650d6 100644 --- a/src/aof.c +++ b/src/aof.c @@ -634,6 +634,7 @@ int loadAppendOnlyFile(char *filename) { goto readerr; } if (buf[0] != '*') goto fmterr; + if (buf[1] == '\0') goto readerr; argc = atoi(buf+1); if (argc < 1) goto fmterr; @@ -643,7 +644,7 @@ int loadAppendOnlyFile(char *filename) { if (buf[0] != '$') goto fmterr; len = strtol(buf+1,NULL,10); argsds = sdsnewlen(NULL,len); - if (len && fread(argsds,len,1,fp) == 0) goto fmterr; + if (len && fread(argsds,len,1,fp) == 0) goto readerr; argv[j] = createObject(REDIS_STRING,argsds); if (fread(buf,2,1,fp) == 0) goto readerr; /* discard CRLF */ } @@ -675,6 +676,7 @@ int loadAppendOnlyFile(char *filename) { * If the client is in the middle of a MULTI/EXEC, log error and quit. */ if (fakeClient->flags & REDIS_MULTI) goto uxeof; +loaded_ok: /* DB loaded, cleanup and return REDIS_OK to the caller. */ fclose(fp); freeFakeClient(fakeClient); server.aof_state = old_aof_state; @@ -690,7 +692,13 @@ readerr: /* Read error. If feof(fp) is true, fall through to unexpected EOF. */ } uxeof: /* Unexpected AOF end of file. */ - redisLog(REDIS_WARNING,"Unexpected end of file reading the append only file"); + if (server.aof_load_truncated) { + redisLog(REDIS_WARNING,"!!! Warning: short read while loading the AOF file !!!"); + redisLog(REDIS_WARNING, + "AOF loaded anyway because aof-load-truncated is enabled"); + goto loaded_ok; + } + redisLog(REDIS_WARNING,"Unexpected end of file reading the append only file. You can: 1) Make a backup of your AOF file, then use ./redis-check-aof --fix . 2) Alternatively you can set the 'aof-load-truncated' configuration option to yes and restart the server."); exit(1); fmterr: /* Format error. */ @@ -1290,7 +1298,7 @@ void aofRemoveTempFile(pid_t childpid) { unlink(tmpfile); } -/* Update the server.aof_current_size filed explicitly using stat(2) +/* Update the server.aof_current_size field explicitly using stat(2) * to check the size of the file. This is useful after a rewrite or after * a restart, normally the size is updated just adding the write length * to the current length, that is much faster. */ diff --git a/src/redis.c b/src/redis.c index e58ceb047..4fd2b4d9e 100644 --- a/src/redis.c +++ b/src/redis.c @@ -1419,6 +1419,7 @@ void initServerConfig(void) { server.aof_selected_db = -1; /* Make sure the first time will not match */ server.aof_flush_postponed_start = 0; server.aof_rewrite_incremental_fsync = REDIS_DEFAULT_AOF_REWRITE_INCREMENTAL_FSYNC; + server.aof_load_truncated = REDIS_DEFAULT_AOF_LOAD_TRUNCATED; server.pidfile = zstrdup(REDIS_DEFAULT_PID_FILE); server.rdb_filename = zstrdup(REDIS_DEFAULT_RDB_FILENAME); server.aof_filename = zstrdup(REDIS_DEFAULT_AOF_FILENAME); diff --git a/src/redis.h b/src/redis.h index c352cd79a..61cd737bf 100644 --- a/src/redis.h +++ b/src/redis.h @@ -120,6 +120,7 @@ typedef long long mstime_t; /* millisecond time type. */ #define REDIS_DEFAULT_MAXMEMORY_SAMPLES 5 #define REDIS_DEFAULT_AOF_FILENAME "appendonly.aof" #define REDIS_DEFAULT_AOF_NO_FSYNC_ON_REWRITE 0 +#define REDIS_DEFAULT_AOF_LOAD_TRUNCATED 1 #define REDIS_DEFAULT_ACTIVE_REHASHING 1 #define REDIS_DEFAULT_AOF_REWRITE_INCREMENTAL_FSYNC 1 #define REDIS_DEFAULT_MIN_SLAVES_TO_WRITE 0 @@ -739,6 +740,7 @@ struct redisServer { int aof_rewrite_incremental_fsync;/* fsync incrementally while rewriting? */ int aof_last_write_status; /* REDIS_OK or REDIS_ERR */ int aof_last_write_errno; /* Valid if aof_last_write_status is ERR */ + int aof_load_truncated; /* Don't stop on unexpected AOF EOF. */ /* AOF pipes used to communicate between parent and child during rewrite. */ int aof_pipe_write_data_to_child; int aof_pipe_read_data_from_parent;