summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2016-08-11 15:42:28 +0200
committerantirez <antirez@gmail.com>2016-08-11 15:42:28 +0200
commit543e25efa6e25e96f976f68ed16aa0c2ff6fa91b (patch)
tree61cbc55634a70ecfb7410734ecf42cca810abcd9
parentf1c32f0dcbe850ccc057ee1fd834c7b4f3eb0aff (diff)
downloadredis-543e25efa6e25e96f976f68ed16aa0c2ff6fa91b.tar.gz
RDB AOF preamble: WIP 4 (Mixed RDB/AOF loading).
-rw-r--r--src/aof.c38
-rw-r--r--src/rdb.h1
2 files changed, 33 insertions, 6 deletions
diff --git a/src/aof.c b/src/aof.c
index 104d8fe39..5523066b5 100644
--- a/src/aof.c
+++ b/src/aof.c
@@ -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;
diff --git a/src/rdb.h b/src/rdb.h
index 2c9a99850..cd1d65392 100644
--- a/src/rdb.h
+++ b/src/rdb.h
@@ -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