diff options
author | antirez <antirez@gmail.com> | 2016-08-11 15:42:28 +0200 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2016-08-11 15:42:28 +0200 |
commit | 543e25efa6e25e96f976f68ed16aa0c2ff6fa91b (patch) | |
tree | 61cbc55634a70ecfb7410734ecf42cca810abcd9 | |
parent | f1c32f0dcbe850ccc057ee1fd834c7b4f3eb0aff (diff) | |
download | redis-543e25efa6e25e96f976f68ed16aa0c2ff6fa91b.tar.gz |
RDB AOF preamble: WIP 4 (Mixed RDB/AOF loading).
-rw-r--r-- | src/aof.c | 38 | ||||
-rw-r--r-- | src/rdb.h | 1 |
2 files changed, 33 insertions, 6 deletions
@@ -616,19 +616,23 @@ int loadAppendOnlyFile(char *filename) { struct redis_stat sb; int old_aof_state = server.aof_state; long loops = 0; - off_t valid_up_to = 0; /* Offset of the latest well-formed command loaded. */ + off_t valid_up_to = 0; /* Offset of latest well-formed command loaded. */ + if (fp == NULL) { + serverLog(LL_WARNING,"Fatal error: can't open the append log file for reading: %s",strerror(errno)); + exit(1); + } + + /* Handle a zero-length AOF file as a special case. An emtpy AOF file + * is a valid AOF because an empty server with AOF enabled will create + * a zero length file at startup, that will remain like that if no write + * operation is received. */ if (fp && redis_fstat(fileno(fp),&sb) != -1 && sb.st_size == 0) { server.aof_current_size = 0; fclose(fp); return C_ERR; } - if (fp == NULL) { - serverLog(LL_WARNING,"Fatal error: can't open the append log file for reading: %s",strerror(errno)); - exit(1); - } - /* Temporarily disable AOF, to prevent EXEC from feeding a MULTI * to the same file we're about to read. */ server.aof_state = AOF_OFF; @@ -636,6 +640,28 @@ int loadAppendOnlyFile(char *filename) { fakeClient = createFakeClient(); startLoading(fp); + /* Check if this AOF file has an RDB preamble. In that case we need to + * load the RDB file and later continue loading the AOF tail. */ + char sig[5]; /* "REDIS" */ + if (fread(sig,1,5,fp) != 5 || memcmp(sig,"REDIS",5) != 0) { + /* No RDB preamble, seek back at 0 offset. */ + if (fseek(fp,0,SEEK_SET) == -1) goto readerr; + } else { + /* RDB preamble. Pass loading the RDB functions. */ + rio rdb; + + serverLog(LL_NOTICE,"Reading RDB preamble from AOF file..."); + if (fseek(fp,0,SEEK_SET) == -1) goto readerr; + rioInitWithFile(&rdb,fp); + if (rdbLoadRio(&rdb) != C_OK) { + serverLog(LL_WARNING,"Error reading the RDB preamble of the AOF file, AOF loading aborted"); + goto readerr; + } else { + serverLog(LL_NOTICE,"Reading the remaining AOF tail..."); + } + } + + /* Read the actual AOF file, in REPL format, command by command. */ while(1) { int argc, j; unsigned long len; @@ -134,5 +134,6 @@ ssize_t rdbSaveRawString(rio *rdb, unsigned char *s, size_t len); void *rdbGenericLoadStringObject(rio *rdb, int flags, size_t *lenptr); int rdbSaveBinaryDoubleValue(rio *rdb, double val); int rdbLoadBinaryDoubleValue(rio *rdb, double *val); +int rdbLoadRio(rio *rdb); #endif |