2 * Copyright (c) 2009-2012, Salvatore Sanfilippo <antirez at gmail dot com>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Redis nor the names of its contributors may be used
14 * to endorse or promote products derived from this software without
15 * specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
31 #include "lzf.h" /* LZF compression library */
33 #include "endianconv.h"
36 #include <sys/types.h>
38 #include <sys/resource.h>
40 #include <arpa/inet.h>
43 static int rdbWriteRaw(rio
*rdb
, void *p
, size_t len
) {
44 if (rdb
&& rioWrite(rdb
,p
,len
) == 0)
49 int rdbSaveType(rio
*rdb
, unsigned char type
) {
50 return rdbWriteRaw(rdb
,&type
,1);
53 /* Load a "type" in RDB format, that is a one byte unsigned integer.
54 * This function is not only used to load object types, but also special
55 * "types" like the end-of-file type, the EXPIRE type, and so forth. */
56 int rdbLoadType(rio
*rdb
) {
58 if (rioRead(rdb
,&type
,1) == 0) return -1;
62 time_t rdbLoadTime(rio
*rdb
) {
64 if (rioRead(rdb
,&t32
,4) == 0) return -1;
68 int rdbSaveMillisecondTime(rio
*rdb
, long long t
) {
69 int64_t t64
= (int64_t) t
;
70 return rdbWriteRaw(rdb
,&t64
,8);
73 long long rdbLoadMillisecondTime(rio
*rdb
) {
75 if (rioRead(rdb
,&t64
,8) == 0) return -1;
76 return (long long)t64
;
79 /* Saves an encoded length. The first two bits in the first byte are used to
80 * hold the encoding type. See the REDIS_RDB_* definitions for more information
81 * on the types of encoding. */
82 int rdbSaveLen(rio
*rdb
, uint32_t len
) {
87 /* Save a 6 bit len */
88 buf
[0] = (len
&0xFF)|(REDIS_RDB_6BITLEN
<<6);
89 if (rdbWriteRaw(rdb
,buf
,1) == -1) return -1;
91 } else if (len
< (1<<14)) {
92 /* Save a 14 bit len */
93 buf
[0] = ((len
>>8)&0xFF)|(REDIS_RDB_14BITLEN
<<6);
95 if (rdbWriteRaw(rdb
,buf
,2) == -1) return -1;
98 /* Save a 32 bit len */
99 buf
[0] = (REDIS_RDB_32BITLEN
<<6);
100 if (rdbWriteRaw(rdb
,buf
,1) == -1) return -1;
102 if (rdbWriteRaw(rdb
,&len
,4) == -4) return -1;
108 /* Load an encoded length. The "isencoded" argument is set to 1 if the length
109 * is not actually a length but an "encoding type". See the REDIS_RDB_ENC_*
110 * definitions in rdb.h for more information. */
111 uint32_t rdbLoadLen(rio
*rdb
, int *isencoded
) {
112 unsigned char buf
[2];
116 if (isencoded
) *isencoded
= 0;
117 if (rioRead(rdb
,buf
,1) == 0) return REDIS_RDB_LENERR
;
118 type
= (buf
[0]&0xC0)>>6;
119 if (type
== REDIS_RDB_ENCVAL
) {
120 /* Read a 6 bit encoding type. */
121 if (isencoded
) *isencoded
= 1;
123 } else if (type
== REDIS_RDB_6BITLEN
) {
124 /* Read a 6 bit len. */
126 } else if (type
== REDIS_RDB_14BITLEN
) {
127 /* Read a 14 bit len. */
128 if (rioRead(rdb
,buf
+1,1) == 0) return REDIS_RDB_LENERR
;
129 return ((buf
[0]&0x3F)<<8)|buf
[1];
131 /* Read a 32 bit len. */
132 if (rioRead(rdb
,&len
,4) == 0) return REDIS_RDB_LENERR
;
137 /* Encodes the "value" argument as integer when it fits in the supported ranges
138 * for encoded types. If the function successfully encodes the integer, the
139 * representation is stored in the buffer pointer to by "enc" and the string
140 * length is returned. Otherwise 0 is returned. */
141 int rdbEncodeInteger(long long value
, unsigned char *enc
) {
142 if (value
>= -(1<<7) && value
<= (1<<7)-1) {
143 enc
[0] = (REDIS_RDB_ENCVAL
<<6)|REDIS_RDB_ENC_INT8
;
146 } else if (value
>= -(1<<15) && value
<= (1<<15)-1) {
147 enc
[0] = (REDIS_RDB_ENCVAL
<<6)|REDIS_RDB_ENC_INT16
;
149 enc
[2] = (value
>>8)&0xFF;
151 } else if (value
>= -((long long)1<<31) && value
<= ((long long)1<<31)-1) {
152 enc
[0] = (REDIS_RDB_ENCVAL
<<6)|REDIS_RDB_ENC_INT32
;
154 enc
[2] = (value
>>8)&0xFF;
155 enc
[3] = (value
>>16)&0xFF;
156 enc
[4] = (value
>>24)&0xFF;
163 /* Loads an integer-encoded object with the specified encoding type "enctype".
164 * If the "encode" argument is set the function may return an integer-encoded
165 * string object, otherwise it always returns a raw string object. */
166 robj
*rdbLoadIntegerObject(rio
*rdb
, int enctype
, int encode
) {
167 unsigned char enc
[4];
170 if (enctype
== REDIS_RDB_ENC_INT8
) {
171 if (rioRead(rdb
,enc
,1) == 0) return NULL
;
172 val
= (signed char)enc
[0];
173 } else if (enctype
== REDIS_RDB_ENC_INT16
) {
175 if (rioRead(rdb
,enc
,2) == 0) return NULL
;
176 v
= enc
[0]|(enc
[1]<<8);
178 } else if (enctype
== REDIS_RDB_ENC_INT32
) {
180 if (rioRead(rdb
,enc
,4) == 0) return NULL
;
181 v
= enc
[0]|(enc
[1]<<8)|(enc
[2]<<16)|(enc
[3]<<24);
184 val
= 0; /* anti-warning */
185 redisPanic("Unknown RDB integer encoding type");
188 return createStringObjectFromLongLong(val
);
190 return createObject(REDIS_STRING
,sdsfromlonglong(val
));
193 /* String objects in the form "2391" "-100" without any space and with a
194 * range of values that can fit in an 8, 16 or 32 bit signed value can be
195 * encoded as integers to save space */
196 int rdbTryIntegerEncoding(char *s
, size_t len
, unsigned char *enc
) {
198 char *endptr
, buf
[32];
200 /* Check if it's possible to encode this value as a number */
201 value
= strtoll(s
, &endptr
, 10);
202 if (endptr
[0] != '\0') return 0;
203 ll2string(buf
,32,value
);
205 /* If the number converted back into a string is not identical
206 * then it's not possible to encode the string as integer */
207 if (strlen(buf
) != len
|| memcmp(buf
,s
,len
)) return 0;
209 return rdbEncodeInteger(value
,enc
);
212 int rdbSaveLzfStringObject(rio
*rdb
, unsigned char *s
, size_t len
) {
213 size_t comprlen
, outlen
;
218 /* We require at least four bytes compression for this to be worth it */
219 if (len
<= 4) return 0;
221 if ((out
= zmalloc(outlen
+1)) == NULL
) return 0;
222 comprlen
= lzf_compress(s
, len
, out
, outlen
);
227 /* Data compressed! Let's save it on disk */
228 byte
= (REDIS_RDB_ENCVAL
<<6)|REDIS_RDB_ENC_LZF
;
229 if ((n
= rdbWriteRaw(rdb
,&byte
,1)) == -1) goto writeerr
;
232 if ((n
= rdbSaveLen(rdb
,comprlen
)) == -1) goto writeerr
;
235 if ((n
= rdbSaveLen(rdb
,len
)) == -1) goto writeerr
;
238 if ((n
= rdbWriteRaw(rdb
,out
,comprlen
)) == -1) goto writeerr
;
249 robj
*rdbLoadLzfStringObject(rio
*rdb
) {
250 unsigned int len
, clen
;
251 unsigned char *c
= NULL
;
254 if ((clen
= rdbLoadLen(rdb
,NULL
)) == REDIS_RDB_LENERR
) return NULL
;
255 if ((len
= rdbLoadLen(rdb
,NULL
)) == REDIS_RDB_LENERR
) return NULL
;
256 if ((c
= zmalloc(clen
)) == NULL
) goto err
;
257 if ((val
= sdsnewlen(NULL
,len
)) == NULL
) goto err
;
258 if (rioRead(rdb
,c
,clen
) == 0) goto err
;
259 if (lzf_decompress(c
,clen
,val
,len
) == 0) goto err
;
261 return createObject(REDIS_STRING
,val
);
268 /* Save a string objet as [len][data] on disk. If the object is a string
269 * representation of an integer value we try to save it in a special form */
270 int rdbSaveRawString(rio
*rdb
, unsigned char *s
, size_t len
) {
274 /* Try integer encoding */
276 unsigned char buf
[5];
277 if ((enclen
= rdbTryIntegerEncoding((char*)s
,len
,buf
)) > 0) {
278 if (rdbWriteRaw(rdb
,buf
,enclen
) == -1) return -1;
283 /* Try LZF compression - under 20 bytes it's unable to compress even
284 * aaaaaaaaaaaaaaaaaa so skip it */
285 if (server
.rdb_compression
&& len
> 20) {
286 n
= rdbSaveLzfStringObject(rdb
,s
,len
);
287 if (n
== -1) return -1;
289 /* Return value of 0 means data can't be compressed, save the old way */
293 if ((n
= rdbSaveLen(rdb
,len
)) == -1) return -1;
296 if (rdbWriteRaw(rdb
,s
,len
) == -1) return -1;
302 /* Save a long long value as either an encoded string or a string. */
303 int rdbSaveLongLongAsStringObject(rio
*rdb
, long long value
) {
304 unsigned char buf
[32];
306 int enclen
= rdbEncodeInteger(value
,buf
);
308 return rdbWriteRaw(rdb
,buf
,enclen
);
310 /* Encode as string */
311 enclen
= ll2string((char*)buf
,32,value
);
312 redisAssert(enclen
< 32);
313 if ((n
= rdbSaveLen(rdb
,enclen
)) == -1) return -1;
315 if ((n
= rdbWriteRaw(rdb
,buf
,enclen
)) == -1) return -1;
321 /* Like rdbSaveStringObjectRaw() but handle encoded objects */
322 int rdbSaveStringObject(rio
*rdb
, robj
*obj
) {
323 /* Avoid to decode the object, then encode it again, if the
324 * object is alrady integer encoded. */
325 if (obj
->encoding
== REDIS_ENCODING_INT
) {
326 return rdbSaveLongLongAsStringObject(rdb
,(long)obj
->ptr
);
328 redisAssertWithInfo(NULL
,obj
,obj
->encoding
== REDIS_ENCODING_RAW
);
329 return rdbSaveRawString(rdb
,obj
->ptr
,sdslen(obj
->ptr
));
333 robj
*rdbGenericLoadStringObject(rio
*rdb
, int encode
) {
338 len
= rdbLoadLen(rdb
,&isencoded
);
341 case REDIS_RDB_ENC_INT8
:
342 case REDIS_RDB_ENC_INT16
:
343 case REDIS_RDB_ENC_INT32
:
344 return rdbLoadIntegerObject(rdb
,len
,encode
);
345 case REDIS_RDB_ENC_LZF
:
346 return rdbLoadLzfStringObject(rdb
);
348 redisPanic("Unknown RDB encoding type");
352 if (len
== REDIS_RDB_LENERR
) return NULL
;
353 val
= sdsnewlen(NULL
,len
);
354 if (len
&& rioRead(rdb
,val
,len
) == 0) {
358 return createObject(REDIS_STRING
,val
);
361 robj
*rdbLoadStringObject(rio
*rdb
) {
362 return rdbGenericLoadStringObject(rdb
,0);
365 robj
*rdbLoadEncodedStringObject(rio
*rdb
) {
366 return rdbGenericLoadStringObject(rdb
,1);
369 /* Save a double value. Doubles are saved as strings prefixed by an unsigned
370 * 8 bit integer specifing the length of the representation.
371 * This 8 bit integer has special values in order to specify the following
377 int rdbSaveDoubleValue(rio
*rdb
, double val
) {
378 unsigned char buf
[128];
384 } else if (!isfinite(val
)) {
386 buf
[0] = (val
< 0) ? 255 : 254;
388 #if (DBL_MANT_DIG >= 52) && (LLONG_MAX == 0x7fffffffffffffffLL)
389 /* Check if the float is in a safe range to be casted into a
390 * long long. We are assuming that long long is 64 bit here.
391 * Also we are assuming that there are no implementations around where
392 * double has precision < 52 bit.
394 * Under this assumptions we test if a double is inside an interval
395 * where casting to long long is safe. Then using two castings we
396 * make sure the decimal part is zero. If all this is true we use
397 * integer printing function that is much faster. */
398 double min
= -4503599627370495; /* (2^52)-1 */
399 double max
= 4503599627370496; /* -(2^52) */
400 if (val
> min
&& val
< max
&& val
== ((double)((long long)val
)))
401 ll2string((char*)buf
+1,sizeof(buf
),(long long)val
);
404 snprintf((char*)buf
+1,sizeof(buf
)-1,"%.17g",val
);
405 buf
[0] = strlen((char*)buf
+1);
408 return rdbWriteRaw(rdb
,buf
,len
);
411 /* For information about double serialization check rdbSaveDoubleValue() */
412 int rdbLoadDoubleValue(rio
*rdb
, double *val
) {
416 if (rioRead(rdb
,&len
,1) == 0) return -1;
418 case 255: *val
= R_NegInf
; return 0;
419 case 254: *val
= R_PosInf
; return 0;
420 case 253: *val
= R_Nan
; return 0;
422 if (rioRead(rdb
,buf
,len
) == 0) return -1;
424 sscanf(buf
, "%lg", val
);
429 /* Save the object type of object "o". */
430 int rdbSaveObjectType(rio
*rdb
, robj
*o
) {
433 return rdbSaveType(rdb
,REDIS_RDB_TYPE_STRING
);
435 if (o
->encoding
== REDIS_ENCODING_ZIPLIST
)
436 return rdbSaveType(rdb
,REDIS_RDB_TYPE_LIST_ZIPLIST
);
437 else if (o
->encoding
== REDIS_ENCODING_LINKEDLIST
)
438 return rdbSaveType(rdb
,REDIS_RDB_TYPE_LIST
);
440 redisPanic("Unknown list encoding");
442 if (o
->encoding
== REDIS_ENCODING_INTSET
)
443 return rdbSaveType(rdb
,REDIS_RDB_TYPE_SET_INTSET
);
444 else if (o
->encoding
== REDIS_ENCODING_HT
)
445 return rdbSaveType(rdb
,REDIS_RDB_TYPE_SET
);
447 redisPanic("Unknown set encoding");
449 if (o
->encoding
== REDIS_ENCODING_ZIPLIST
)
450 return rdbSaveType(rdb
,REDIS_RDB_TYPE_ZSET_ZIPLIST
);
451 else if (o
->encoding
== REDIS_ENCODING_SKIPLIST
)
452 return rdbSaveType(rdb
,REDIS_RDB_TYPE_ZSET
);
454 redisPanic("Unknown sorted set encoding");
456 if (o
->encoding
== REDIS_ENCODING_ZIPLIST
)
457 return rdbSaveType(rdb
,REDIS_RDB_TYPE_HASH_ZIPLIST
);
458 else if (o
->encoding
== REDIS_ENCODING_HT
)
459 return rdbSaveType(rdb
,REDIS_RDB_TYPE_HASH
);
461 redisPanic("Unknown hash encoding");
463 redisPanic("Unknown object type");
465 return -1; /* avoid warning */
468 /* Use rdbLoadType() to load a TYPE in RDB format, but returns -1 if the
469 * type is not specifically a valid Object Type. */
470 int rdbLoadObjectType(rio
*rdb
) {
472 if ((type
= rdbLoadType(rdb
)) == -1) return -1;
473 if (!rdbIsObjectType(type
)) return -1;
477 /* Save a Redis object. Returns -1 on error, 0 on success. */
478 int rdbSaveObject(rio
*rdb
, robj
*o
) {
481 if (o
->type
== REDIS_STRING
) {
482 /* Save a string value */
483 if ((n
= rdbSaveStringObject(rdb
,o
)) == -1) return -1;
485 } else if (o
->type
== REDIS_LIST
) {
486 /* Save a list value */
487 if (o
->encoding
== REDIS_ENCODING_ZIPLIST
) {
488 size_t l
= ziplistBlobLen((unsigned char*)o
->ptr
);
490 if ((n
= rdbSaveRawString(rdb
,o
->ptr
,l
)) == -1) return -1;
492 } else if (o
->encoding
== REDIS_ENCODING_LINKEDLIST
) {
497 if ((n
= rdbSaveLen(rdb
,listLength(list
))) == -1) return -1;
500 listRewind(list
,&li
);
501 while((ln
= listNext(&li
))) {
502 robj
*eleobj
= listNodeValue(ln
);
503 if ((n
= rdbSaveStringObject(rdb
,eleobj
)) == -1) return -1;
507 redisPanic("Unknown list encoding");
509 } else if (o
->type
== REDIS_SET
) {
510 /* Save a set value */
511 if (o
->encoding
== REDIS_ENCODING_HT
) {
513 dictIterator
*di
= dictGetIterator(set
);
516 if ((n
= rdbSaveLen(rdb
,dictSize(set
))) == -1) return -1;
519 while((de
= dictNext(di
)) != NULL
) {
520 robj
*eleobj
= dictGetKey(de
);
521 if ((n
= rdbSaveStringObject(rdb
,eleobj
)) == -1) return -1;
524 dictReleaseIterator(di
);
525 } else if (o
->encoding
== REDIS_ENCODING_INTSET
) {
526 size_t l
= intsetBlobLen((intset
*)o
->ptr
);
528 if ((n
= rdbSaveRawString(rdb
,o
->ptr
,l
)) == -1) return -1;
531 redisPanic("Unknown set encoding");
533 } else if (o
->type
== REDIS_ZSET
) {
534 /* Save a sorted set value */
535 if (o
->encoding
== REDIS_ENCODING_ZIPLIST
) {
536 size_t l
= ziplistBlobLen((unsigned char*)o
->ptr
);
538 if ((n
= rdbSaveRawString(rdb
,o
->ptr
,l
)) == -1) return -1;
540 } else if (o
->encoding
== REDIS_ENCODING_SKIPLIST
) {
542 dictIterator
*di
= dictGetIterator(zs
->dict
);
545 if ((n
= rdbSaveLen(rdb
,dictSize(zs
->dict
))) == -1) return -1;
548 while((de
= dictNext(di
)) != NULL
) {
549 robj
*eleobj
= dictGetKey(de
);
550 double *score
= dictGetVal(de
);
552 if ((n
= rdbSaveStringObject(rdb
,eleobj
)) == -1) return -1;
554 if ((n
= rdbSaveDoubleValue(rdb
,*score
)) == -1) return -1;
557 dictReleaseIterator(di
);
559 redisPanic("Unknown sorted set encoding");
561 } else if (o
->type
== REDIS_HASH
) {
562 /* Save a hash value */
563 if (o
->encoding
== REDIS_ENCODING_ZIPLIST
) {
564 size_t l
= ziplistBlobLen((unsigned char*)o
->ptr
);
566 if ((n
= rdbSaveRawString(rdb
,o
->ptr
,l
)) == -1) return -1;
569 } else if (o
->encoding
== REDIS_ENCODING_HT
) {
570 dictIterator
*di
= dictGetIterator(o
->ptr
);
573 if ((n
= rdbSaveLen(rdb
,dictSize((dict
*)o
->ptr
))) == -1) return -1;
576 while((de
= dictNext(di
)) != NULL
) {
577 robj
*key
= dictGetKey(de
);
578 robj
*val
= dictGetVal(de
);
580 if ((n
= rdbSaveStringObject(rdb
,key
)) == -1) return -1;
582 if ((n
= rdbSaveStringObject(rdb
,val
)) == -1) return -1;
585 dictReleaseIterator(di
);
588 redisPanic("Unknown hash encoding");
592 redisPanic("Unknown object type");
597 /* Return the length the object will have on disk if saved with
598 * the rdbSaveObject() function. Currently we use a trick to get
599 * this length with very little changes to the code. In the future
600 * we could switch to a faster solution. */
601 off_t
rdbSavedObjectLen(robj
*o
) {
602 int len
= rdbSaveObject(NULL
,o
);
603 redisAssertWithInfo(NULL
,o
,len
!= -1);
607 /* Save a key-value pair, with expire time, type, key, value.
608 * On error -1 is returned.
609 * On success if the key was actaully saved 1 is returned, otherwise 0
610 * is returned (the key was already expired). */
611 int rdbSaveKeyValuePair(rio
*rdb
, robj
*key
, robj
*val
,
612 long long expiretime
, long long now
)
614 /* Save the expire time */
615 if (expiretime
!= -1) {
616 /* If this key is already expired skip it */
617 if (expiretime
< now
) return 0;
618 if (rdbSaveType(rdb
,REDIS_RDB_OPCODE_EXPIRETIME_MS
) == -1) return -1;
619 if (rdbSaveMillisecondTime(rdb
,expiretime
) == -1) return -1;
622 /* Save type, key, value */
623 if (rdbSaveObjectType(rdb
,val
) == -1) return -1;
624 if (rdbSaveStringObject(rdb
,key
) == -1) return -1;
625 if (rdbSaveObject(rdb
,val
) == -1) return -1;
629 /* Save the DB on disk. Return REDIS_ERR on error, REDIS_OK on success */
630 int rdbSave(char *filename
) {
631 dictIterator
*di
= NULL
;
636 long long now
= mstime();
641 snprintf(tmpfile
,256,"temp-%d.rdb", (int) getpid());
642 fp
= fopen(tmpfile
,"w");
644 redisLog(REDIS_WARNING
, "Failed opening .rdb for saving: %s",
649 rioInitWithFile(&rdb
,fp
);
650 if (server
.rdb_checksum
)
651 rdb
.update_cksum
= rioGenericUpdateChecksum
;
652 snprintf(magic
,sizeof(magic
),"REDIS%04d",REDIS_RDB_VERSION
);
653 if (rdbWriteRaw(&rdb
,magic
,9) == -1) goto werr
;
655 for (j
= 0; j
< server
.dbnum
; j
++) {
656 redisDb
*db
= server
.db
+j
;
658 if (dictSize(d
) == 0) continue;
659 di
= dictGetSafeIterator(d
);
665 /* Write the SELECT DB opcode */
666 if (rdbSaveType(&rdb
,REDIS_RDB_OPCODE_SELECTDB
) == -1) goto werr
;
667 if (rdbSaveLen(&rdb
,j
) == -1) goto werr
;
669 /* Iterate this DB writing every entry */
670 while((de
= dictNext(di
)) != NULL
) {
671 sds keystr
= dictGetKey(de
);
672 robj key
, *o
= dictGetVal(de
);
675 initStaticStringObject(key
,keystr
);
676 expire
= getExpire(db
,&key
);
677 if (rdbSaveKeyValuePair(&rdb
,&key
,o
,expire
,now
) == -1) goto werr
;
679 dictReleaseIterator(di
);
681 di
= NULL
; /* So that we don't release it again on error. */
684 if (rdbSaveType(&rdb
,REDIS_RDB_OPCODE_EOF
) == -1) goto werr
;
686 /* CRC64 checksum. It will be zero if checksum computation is disabled, the
687 * loading code skips the check in this case. */
689 memrev64ifbe(&cksum
);
690 rioWrite(&rdb
,&cksum
,8);
692 /* Make sure data will not remain on the OS's output buffers */
697 /* Use RENAME to make sure the DB file is changed atomically only
698 * if the generate DB file is ok. */
699 if (rename(tmpfile
,filename
) == -1) {
700 redisLog(REDIS_WARNING
,"Error moving temp DB file on the final destination: %s", strerror(errno
));
704 redisLog(REDIS_NOTICE
,"DB saved on disk");
706 server
.lastsave
= time(NULL
);
707 server
.lastbgsave_status
= REDIS_OK
;
713 redisLog(REDIS_WARNING
,"Write error saving DB on disk: %s", strerror(errno
));
714 if (di
) dictReleaseIterator(di
);
718 int rdbSaveBackground(char *filename
) {
722 if (server
.rdb_child_pid
!= -1) return REDIS_ERR
;
724 server
.dirty_before_bgsave
= server
.dirty
;
727 if ((childpid
= fork()) == 0) {
731 if (server
.ipfd
> 0) close(server
.ipfd
);
732 if (server
.sofd
> 0) close(server
.sofd
);
733 retval
= rdbSave(filename
);
734 if (retval
== REDIS_OK
) {
735 size_t private_dirty
= zmalloc_get_private_dirty();
738 redisLog(REDIS_NOTICE
,
739 "RDB: %lu MB of memory used by copy-on-write",
740 private_dirty
/(1024*1024));
743 exitFromChild((retval
== REDIS_OK
) ? 0 : 1);
746 server
.stat_fork_time
= ustime()-start
;
747 if (childpid
== -1) {
748 redisLog(REDIS_WARNING
,"Can't save in background: fork: %s",
752 redisLog(REDIS_NOTICE
,"Background saving started by pid %d",childpid
);
753 server
.rdb_save_time_start
= time(NULL
);
754 server
.rdb_child_pid
= childpid
;
755 updateDictResizePolicy();
758 return REDIS_OK
; /* unreached */
761 void rdbRemoveTempFile(pid_t childpid
) {
764 snprintf(tmpfile
,256,"temp-%d.rdb", (int) childpid
);
768 /* Load a Redis object of the specified type from the specified file.
769 * On success a newly allocated object is returned, otherwise NULL. */
770 robj
*rdbLoadObject(int rdbtype
, rio
*rdb
) {
775 redisLog(REDIS_DEBUG
,"LOADING OBJECT %d (at %d)\n",rdbtype
,rioTell(rdb
));
776 if (rdbtype
== REDIS_RDB_TYPE_STRING
) {
777 /* Read string value */
778 if ((o
= rdbLoadEncodedStringObject(rdb
)) == NULL
) return NULL
;
779 o
= tryObjectEncoding(o
);
780 } else if (rdbtype
== REDIS_RDB_TYPE_LIST
) {
781 /* Read list value */
782 if ((len
= rdbLoadLen(rdb
,NULL
)) == REDIS_RDB_LENERR
) return NULL
;
784 /* Use a real list when there are too many entries */
785 if (len
> server
.list_max_ziplist_entries
) {
786 o
= createListObject();
788 o
= createZiplistObject();
791 /* Load every single element of the list */
793 if ((ele
= rdbLoadEncodedStringObject(rdb
)) == NULL
) return NULL
;
795 /* If we are using a ziplist and the value is too big, convert
796 * the object to a real list. */
797 if (o
->encoding
== REDIS_ENCODING_ZIPLIST
&&
798 ele
->encoding
== REDIS_ENCODING_RAW
&&
799 sdslen(ele
->ptr
) > server
.list_max_ziplist_value
)
800 listTypeConvert(o
,REDIS_ENCODING_LINKEDLIST
);
802 if (o
->encoding
== REDIS_ENCODING_ZIPLIST
) {
803 dec
= getDecodedObject(ele
);
804 o
->ptr
= ziplistPush(o
->ptr
,dec
->ptr
,sdslen(dec
->ptr
),REDIS_TAIL
);
808 ele
= tryObjectEncoding(ele
);
809 listAddNodeTail(o
->ptr
,ele
);
812 } else if (rdbtype
== REDIS_RDB_TYPE_SET
) {
813 /* Read list/set value */
814 if ((len
= rdbLoadLen(rdb
,NULL
)) == REDIS_RDB_LENERR
) return NULL
;
816 /* Use a regular set when there are too many entries. */
817 if (len
> server
.set_max_intset_entries
) {
818 o
= createSetObject();
819 /* It's faster to expand the dict to the right size asap in order
820 * to avoid rehashing */
821 if (len
> DICT_HT_INITIAL_SIZE
)
822 dictExpand(o
->ptr
,len
);
824 o
= createIntsetObject();
827 /* Load every single element of the list/set */
828 for (i
= 0; i
< len
; i
++) {
830 if ((ele
= rdbLoadEncodedStringObject(rdb
)) == NULL
) return NULL
;
831 ele
= tryObjectEncoding(ele
);
833 if (o
->encoding
== REDIS_ENCODING_INTSET
) {
834 /* Fetch integer value from element */
835 if (isObjectRepresentableAsLongLong(ele
,&llval
) == REDIS_OK
) {
836 o
->ptr
= intsetAdd(o
->ptr
,llval
,NULL
);
838 setTypeConvert(o
,REDIS_ENCODING_HT
);
839 dictExpand(o
->ptr
,len
);
843 /* This will also be called when the set was just converted
844 * to regular hash table encoded set */
845 if (o
->encoding
== REDIS_ENCODING_HT
) {
846 dictAdd((dict
*)o
->ptr
,ele
,NULL
);
851 } else if (rdbtype
== REDIS_RDB_TYPE_ZSET
) {
852 /* Read list/set value */
854 size_t maxelelen
= 0;
857 if ((zsetlen
= rdbLoadLen(rdb
,NULL
)) == REDIS_RDB_LENERR
) return NULL
;
858 o
= createZsetObject();
861 /* Load every single element of the list/set */
865 zskiplistNode
*znode
;
867 if ((ele
= rdbLoadEncodedStringObject(rdb
)) == NULL
) return NULL
;
868 ele
= tryObjectEncoding(ele
);
869 if (rdbLoadDoubleValue(rdb
,&score
) == -1) return NULL
;
871 /* Don't care about integer-encoded strings. */
872 if (ele
->encoding
== REDIS_ENCODING_RAW
&&
873 sdslen(ele
->ptr
) > maxelelen
)
874 maxelelen
= sdslen(ele
->ptr
);
876 znode
= zslInsert(zs
->zsl
,score
,ele
);
877 dictAdd(zs
->dict
,ele
,&znode
->score
);
878 incrRefCount(ele
); /* added to skiplist */
881 /* Convert *after* loading, since sorted sets are not stored ordered. */
882 if (zsetLength(o
) <= server
.zset_max_ziplist_entries
&&
883 maxelelen
<= server
.zset_max_ziplist_value
)
884 zsetConvert(o
,REDIS_ENCODING_ZIPLIST
);
885 } else if (rdbtype
== REDIS_RDB_TYPE_HASH
) {
889 len
= rdbLoadLen(rdb
, NULL
);
890 if (len
== REDIS_RDB_LENERR
) return NULL
;
892 o
= createHashObject();
894 /* Too many entries? Use an hash table. */
895 if (len
> server
.hash_max_ziplist_entries
)
896 hashTypeConvert(o
, REDIS_ENCODING_HT
);
898 /* Load every field and value into the ziplist */
899 while (o
->encoding
== REDIS_ENCODING_ZIPLIST
&& len
> 0) {
903 /* Load raw strings */
904 field
= rdbLoadStringObject(rdb
);
905 if (field
== NULL
) return NULL
;
906 redisAssert(field
->encoding
== REDIS_ENCODING_RAW
);
907 value
= rdbLoadStringObject(rdb
);
908 if (value
== NULL
) return NULL
;
909 redisAssert(field
->encoding
== REDIS_ENCODING_RAW
);
911 /* Add pair to ziplist */
912 o
->ptr
= ziplistPush(o
->ptr
, field
->ptr
, sdslen(field
->ptr
), ZIPLIST_TAIL
);
913 o
->ptr
= ziplistPush(o
->ptr
, value
->ptr
, sdslen(value
->ptr
), ZIPLIST_TAIL
);
914 /* Convert to hash table if size threshold is exceeded */
915 if (sdslen(field
->ptr
) > server
.hash_max_ziplist_value
||
916 sdslen(value
->ptr
) > server
.hash_max_ziplist_value
)
920 hashTypeConvert(o
, REDIS_ENCODING_HT
);
927 /* Load remaining fields and values into the hash table */
928 while (o
->encoding
== REDIS_ENCODING_HT
&& len
> 0) {
932 /* Load encoded strings */
933 field
= rdbLoadEncodedStringObject(rdb
);
934 if (field
== NULL
) return NULL
;
935 value
= rdbLoadEncodedStringObject(rdb
);
936 if (value
== NULL
) return NULL
;
938 field
= tryObjectEncoding(field
);
939 value
= tryObjectEncoding(value
);
941 /* Add pair to hash table */
942 ret
= dictAdd((dict
*)o
->ptr
, field
, value
);
943 redisAssert(ret
== REDIS_OK
);
946 /* All pairs should be read by now */
947 redisAssert(len
== 0);
949 } else if (rdbtype
== REDIS_RDB_TYPE_HASH_ZIPMAP
||
950 rdbtype
== REDIS_RDB_TYPE_LIST_ZIPLIST
||
951 rdbtype
== REDIS_RDB_TYPE_SET_INTSET
||
952 rdbtype
== REDIS_RDB_TYPE_ZSET_ZIPLIST
||
953 rdbtype
== REDIS_RDB_TYPE_HASH_ZIPLIST
)
955 robj
*aux
= rdbLoadStringObject(rdb
);
957 if (aux
== NULL
) return NULL
;
958 o
= createObject(REDIS_STRING
,NULL
); /* string is just placeholder */
959 o
->ptr
= zmalloc(sdslen(aux
->ptr
));
960 memcpy(o
->ptr
,aux
->ptr
,sdslen(aux
->ptr
));
963 /* Fix the object encoding, and make sure to convert the encoded
964 * data type into the base type if accordingly to the current
965 * configuration there are too many elements in the encoded data
966 * type. Note that we only check the length and not max element
967 * size as this is an O(N) scan. Eventually everything will get
970 case REDIS_RDB_TYPE_HASH_ZIPMAP
:
971 /* Convert to ziplist encoded hash. This must be deprecated
972 * when loading dumps created by Redis 2.4 gets deprecated. */
974 unsigned char *zl
= ziplistNew();
975 unsigned char *zi
= zipmapRewind(o
->ptr
);
976 unsigned char *fstr
, *vstr
;
977 unsigned int flen
, vlen
;
978 unsigned int maxlen
= 0;
980 while ((zi
= zipmapNext(zi
, &fstr
, &flen
, &vstr
, &vlen
)) != NULL
) {
981 if (flen
> maxlen
) maxlen
= flen
;
982 if (vlen
> maxlen
) maxlen
= vlen
;
983 zl
= ziplistPush(zl
, fstr
, flen
, ZIPLIST_TAIL
);
984 zl
= ziplistPush(zl
, vstr
, vlen
, ZIPLIST_TAIL
);
989 o
->type
= REDIS_HASH
;
990 o
->encoding
= REDIS_ENCODING_ZIPLIST
;
992 if (hashTypeLength(o
) > server
.hash_max_ziplist_entries
||
993 maxlen
> server
.hash_max_ziplist_value
)
995 hashTypeConvert(o
, REDIS_ENCODING_HT
);
999 case REDIS_RDB_TYPE_LIST_ZIPLIST
:
1000 o
->type
= REDIS_LIST
;
1001 o
->encoding
= REDIS_ENCODING_ZIPLIST
;
1002 if (ziplistLen(o
->ptr
) > server
.list_max_ziplist_entries
)
1003 listTypeConvert(o
,REDIS_ENCODING_LINKEDLIST
);
1005 case REDIS_RDB_TYPE_SET_INTSET
:
1006 o
->type
= REDIS_SET
;
1007 o
->encoding
= REDIS_ENCODING_INTSET
;
1008 if (intsetLen(o
->ptr
) > server
.set_max_intset_entries
)
1009 setTypeConvert(o
,REDIS_ENCODING_HT
);
1011 case REDIS_RDB_TYPE_ZSET_ZIPLIST
:
1012 o
->type
= REDIS_ZSET
;
1013 o
->encoding
= REDIS_ENCODING_ZIPLIST
;
1014 if (zsetLength(o
) > server
.zset_max_ziplist_entries
)
1015 zsetConvert(o
,REDIS_ENCODING_SKIPLIST
);
1017 case REDIS_RDB_TYPE_HASH_ZIPLIST
:
1018 o
->type
= REDIS_HASH
;
1019 o
->encoding
= REDIS_ENCODING_ZIPLIST
;
1020 if (hashTypeLength(o
) > server
.hash_max_ziplist_entries
)
1021 hashTypeConvert(o
, REDIS_ENCODING_HT
);
1024 redisPanic("Unknown encoding");
1028 redisPanic("Unknown object type");
1033 /* Mark that we are loading in the global state and setup the fields
1034 * needed to provide loading stats. */
1035 void startLoading(FILE *fp
) {
1040 server
.loading_start_time
= time(NULL
);
1041 if (fstat(fileno(fp
), &sb
) == -1) {
1042 server
.loading_total_bytes
= 1; /* just to avoid division by zero */
1044 server
.loading_total_bytes
= sb
.st_size
;
1048 /* Refresh the loading progress info */
1049 void loadingProgress(off_t pos
) {
1050 server
.loading_loaded_bytes
= pos
;
1051 if (server
.stat_peak_memory
< zmalloc_used_memory())
1052 server
.stat_peak_memory
= zmalloc_used_memory();
1055 /* Loading finished */
1056 void stopLoading(void) {
1060 int rdbLoad(char *filename
) {
1063 redisDb
*db
= server
.db
+0;
1065 long long expiretime
, now
= mstime();
1070 fp
= fopen(filename
,"r");
1075 rioInitWithFile(&rdb
,fp
);
1076 if (server
.rdb_checksum
)
1077 rdb
.update_cksum
= rioGenericUpdateChecksum
;
1078 if (rioRead(&rdb
,buf
,9) == 0) goto eoferr
;
1080 if (memcmp(buf
,"REDIS",5) != 0) {
1082 redisLog(REDIS_WARNING
,"Wrong signature trying to load DB from file");
1086 rdbver
= atoi(buf
+5);
1087 if (rdbver
< 1 || rdbver
> REDIS_RDB_VERSION
) {
1089 redisLog(REDIS_WARNING
,"Can't handle RDB format version %d",rdbver
);
1099 /* Serve the clients from time to time */
1100 if (!(loops
++ % 1000)) {
1101 loadingProgress(rioTell(&rdb
));
1102 aeProcessEvents(server
.el
, AE_FILE_EVENTS
|AE_DONT_WAIT
);
1106 if ((type
= rdbLoadType(&rdb
)) == -1) goto eoferr
;
1107 if (type
== REDIS_RDB_OPCODE_EXPIRETIME
) {
1108 if ((expiretime
= rdbLoadTime(&rdb
)) == -1) goto eoferr
;
1109 /* We read the time so we need to read the object type again. */
1110 if ((type
= rdbLoadType(&rdb
)) == -1) goto eoferr
;
1111 /* the EXPIRETIME opcode specifies time in seconds, so convert
1112 * into milliesconds. */
1114 } else if (type
== REDIS_RDB_OPCODE_EXPIRETIME_MS
) {
1115 /* Milliseconds precision expire times introduced with RDB
1117 if ((expiretime
= rdbLoadMillisecondTime(&rdb
)) == -1) goto eoferr
;
1118 /* We read the time so we need to read the object type again. */
1119 if ((type
= rdbLoadType(&rdb
)) == -1) goto eoferr
;
1122 if (type
== REDIS_RDB_OPCODE_EOF
)
1125 /* Handle SELECT DB opcode as a special case */
1126 if (type
== REDIS_RDB_OPCODE_SELECTDB
) {
1127 if ((dbid
= rdbLoadLen(&rdb
,NULL
)) == REDIS_RDB_LENERR
)
1129 if (dbid
>= (unsigned)server
.dbnum
) {
1130 redisLog(REDIS_WARNING
,"FATAL: Data file was created with a Redis server configured to handle more than %d databases. Exiting\n", server
.dbnum
);
1133 db
= server
.db
+dbid
;
1137 if ((key
= rdbLoadStringObject(&rdb
)) == NULL
) goto eoferr
;
1139 if ((val
= rdbLoadObject(type
,&rdb
)) == NULL
) goto eoferr
;
1140 /* Check if the key already expired. This function is used when loading
1141 * an RDB file from disk, either at startup, or when an RDB was
1142 * received from the master. In the latter case, the master is
1143 * responsible for key expiry. If we would expire keys here, the
1144 * snapshot taken by the master may not be reflected on the slave. */
1145 if (server
.masterhost
== NULL
&& expiretime
!= -1 && expiretime
< now
) {
1150 /* Add the new object in the hash table */
1153 /* Set the expire time if needed */
1154 if (expiretime
!= -1) setExpire(db
,key
,expiretime
);
1158 /* Verify the checksum if RDB version is >= 5 */
1159 if (rdbver
>= 5 && server
.rdb_checksum
) {
1160 uint64_t cksum
, expected
= rdb
.cksum
;
1162 if (rioRead(&rdb
,&cksum
,8) == 0) goto eoferr
;
1163 memrev64ifbe(&cksum
);
1165 redisLog(REDIS_WARNING
,"RDB file was saved with checksum disabled: no check performed.");
1166 } else if (cksum
!= expected
) {
1167 redisLog(REDIS_WARNING
,"Wrong RDB checksum. Aborting now.");
1176 eoferr
: /* unexpected end of file is handled here with a fatal exit */
1177 redisLog(REDIS_WARNING
,"Short read or OOM loading DB. Unrecoverable error, aborting now.");
1179 return REDIS_ERR
; /* Just to avoid warning */
1182 /* A background saving child (BGSAVE) terminated its work. Handle this. */
1183 void backgroundSaveDoneHandler(int exitcode
, int bysignal
) {
1184 if (!bysignal
&& exitcode
== 0) {
1185 redisLog(REDIS_NOTICE
,
1186 "Background saving terminated with success");
1187 server
.dirty
= server
.dirty
- server
.dirty_before_bgsave
;
1188 server
.lastsave
= time(NULL
);
1189 server
.lastbgsave_status
= REDIS_OK
;
1190 } else if (!bysignal
&& exitcode
!= 0) {
1191 redisLog(REDIS_WARNING
, "Background saving error");
1192 server
.lastbgsave_status
= REDIS_ERR
;
1194 redisLog(REDIS_WARNING
,
1195 "Background saving terminated by signal %d", bysignal
);
1196 rdbRemoveTempFile(server
.rdb_child_pid
);
1197 server
.lastbgsave_status
= REDIS_ERR
;
1199 server
.rdb_child_pid
= -1;
1200 server
.rdb_save_time_last
= time(NULL
)-server
.rdb_save_time_start
;
1201 server
.rdb_save_time_start
= -1;
1202 /* Possibly there are slaves waiting for a BGSAVE in order to be served
1203 * (the first stage of SYNC is a bulk transfer of dump.rdb) */
1204 updateSlavesWaitingBgsave(exitcode
== 0 ? REDIS_OK
: REDIS_ERR
);
1207 void saveCommand(redisClient
*c
) {
1208 if (server
.rdb_child_pid
!= -1) {
1209 addReplyError(c
,"Background save already in progress");
1212 if (rdbSave(server
.rdb_filename
) == REDIS_OK
) {
1213 addReply(c
,shared
.ok
);
1215 addReply(c
,shared
.err
);
1219 void bgsaveCommand(redisClient
*c
) {
1220 if (server
.rdb_child_pid
!= -1) {
1221 addReplyError(c
,"Background save already in progress");
1222 } else if (server
.aof_child_pid
!= -1) {
1223 addReplyError(c
,"Can't BGSAVE while AOF log rewriting is in progress");
1224 } else if (rdbSaveBackground(server
.rdb_filename
) == REDIS_OK
) {
1225 addReplyStatus(c
,"Background saving started");
1227 addReply(c
,shared
.err
);