diff --git a/redis.conf b/redis.conf index 9209ed35bad68257fe995e958b7b9486fde337f8..24c1b7a4e228bf6022ea0bac70476a098473e6c7 100644 --- a/redis.conf +++ b/redis.conf @@ -529,6 +529,30 @@ no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb +# An AOF file may be found to be truncated at the end during the Redis +# startup process, when the AOF data gets loaded back into memory. +# This may happen when the system where Redis is running +# crashes, especially when an ext4 filesystem is mounted without the +# data=ordered option (however this can't happen when Redis itself +# crashes or aborts but the operating system still works correctly). +# +# Redis can either exit with an error when this happens, or load as much +# data as possible (the default now) and start if the AOF file is found +# to be truncated at the end. The following option controls this behavior. +# +# If aof-load-truncated is set to yes, a truncated AOF file is loaded and +# the Redis server starts emitting a log to inform the user of the event. +# Otherwise if the option is set to no, the server aborts with an error +# and refuses to start. When the option is set to no, the user requires +# to fix the AOF file using the "redis-check-aof" utility before to restart +# the server. +# +# Note that if the AOF file will be found to be corrupted in the middle +# the server will still exit with an error. This option only applies when +# Redis will try to read more data from the AOF file but not enough bytes +# will be found. +aof-load-truncated yes + ################################ LUA SCRIPTING ############################### # Max execution time of a Lua script in milliseconds. diff --git a/src/config.c b/src/config.c index ea0b77916699f9b4f5b822f4b8780ecc6d59b5d3..7bc3a07536c35daae5c263cce4d1118e6d297bf8 100644 --- a/src/config.c +++ b/src/config.c @@ -355,7 +355,12 @@ void loadServerConfigFromString(char *config) { } else if (!strcasecmp(argv[0],"aof-rewrite-incremental-fsync") && argc == 2) { - if ((server.aof_rewrite_incremental_fsync = yesnotoi(argv[1])) == -1) { + if ((server.aof_rewrite_incremental_fsync = + yesnotoi(argv[1])) == -1) { + err = "argument must be 'yes' or 'no'"; goto loaderr; + } + } else if (!strcasecmp(argv[0],"aof-load-truncated") && argc == 2) { + if ((server.aof_load_truncated = yesnotoi(argv[1])) == -1) { err = "argument must be 'yes' or 'no'"; goto loaderr; } } else if (!strcasecmp(argv[0],"requirepass") && argc == 2) { @@ -673,6 +678,11 @@ void configSetCommand(redisClient *c) { if (yn == -1) goto badfmt; server.aof_rewrite_incremental_fsync = yn; + } else if (!strcasecmp(c->argv[2]->ptr,"aof-load-truncated")) { + int yn = yesnotoi(o->ptr); + + if (yn == -1) goto badfmt; + server.aof_load_truncated = yn; } else if (!strcasecmp(c->argv[2]->ptr,"save")) { int vlen, j; sds *v = sdssplitlen(o->ptr,sdslen(o->ptr)," ",1,&vlen); @@ -990,6 +1000,8 @@ void configGetCommand(redisClient *c) { server.repl_disable_tcp_nodelay); config_get_bool_field("aof-rewrite-incremental-fsync", server.aof_rewrite_incremental_fsync); + config_get_bool_field("aof-load-truncated", + server.aof_load_truncated); /* Everything we can't handle with macros follows. */ @@ -1752,6 +1764,7 @@ int rewriteConfig(char *path) { rewriteConfigClientoutputbufferlimitOption(state); rewriteConfigNumericalOption(state,"hz",server.hz,REDIS_DEFAULT_HZ); rewriteConfigYesNoOption(state,"aof-rewrite-incremental-fsync",server.aof_rewrite_incremental_fsync,REDIS_DEFAULT_AOF_REWRITE_INCREMENTAL_FSYNC); + rewriteConfigYesNoOption(state,"aof-load-truncated",server.aof_load_truncated,REDIS_DEFAULT_AOF_LOAD_TRUNCATED); if (server.sentinel_mode) rewriteConfigSentinelOption(state); /* Step 3: remove all the orphaned lines in the old file, that is, lines