2 #include "lzf.h" /* LZF compression library */
8 #include <sys/resource.h>
10 #include <arpa/inet.h>
13 static int rdbWriteRaw(rio
*rdb
, void *p
, size_t len
) {
14 if (rdb
&& rioWrite(rdb
,p
,len
) == 0)
19 int rdbSaveType(rio
*rdb
, unsigned char type
) {
20 return rdbWriteRaw(rdb
,&type
,1);
23 int rdbLoadType(rio
*rdb
) {
25 if (rioRead(rdb
,&type
,1) == 0) return -1;
29 int rdbSaveTime(rio
*rdb
, time_t t
) {
30 int32_t t32
= (int32_t) t
;
31 return rdbWriteRaw(rdb
,&t32
,4);
34 time_t rdbLoadTime(rio
*rdb
) {
36 if (rioRead(rdb
,&t32
,4) == 0) return -1;
40 int rdbSaveMillisecondTime(rio
*rdb
, long long t
) {
41 int64_t t64
= (int64_t) t
;
42 return rdbWriteRaw(rdb
,&t64
,8);
45 long long rdbLoadMillisecondTime(rio
*rdb
) {
47 if (rioRead(rdb
,&t64
,8) == 0) return -1;
48 return (long long)t64
;
51 /* Saves an encoded length. The first two bits in the first byte are used to
52 * hold the encoding type. See the REDIS_RDB_* definitions for more information
53 * on the types of encoding. */
54 int rdbSaveLen(rio
*rdb
, uint32_t len
) {
59 /* Save a 6 bit len */
60 buf
[0] = (len
&0xFF)|(REDIS_RDB_6BITLEN
<<6);
61 if (rdbWriteRaw(rdb
,buf
,1) == -1) return -1;
63 } else if (len
< (1<<14)) {
64 /* Save a 14 bit len */
65 buf
[0] = ((len
>>8)&0xFF)|(REDIS_RDB_14BITLEN
<<6);
67 if (rdbWriteRaw(rdb
,buf
,2) == -1) return -1;
70 /* Save a 32 bit len */
71 buf
[0] = (REDIS_RDB_32BITLEN
<<6);
72 if (rdbWriteRaw(rdb
,buf
,1) == -1) return -1;
74 if (rdbWriteRaw(rdb
,&len
,4) == -4) return -1;
80 /* Load an encoded length. The "isencoded" argument is set to 1 if the length
81 * is not actually a length but an "encoding type". See the REDIS_RDB_ENC_*
82 * definitions in rdb.h for more information. */
83 uint32_t rdbLoadLen(rio
*rdb
, int *isencoded
) {
88 if (isencoded
) *isencoded
= 0;
89 if (rioRead(rdb
,buf
,1) == 0) return REDIS_RDB_LENERR
;
90 type
= (buf
[0]&0xC0)>>6;
91 if (type
== REDIS_RDB_ENCVAL
) {
92 /* Read a 6 bit encoding type. */
93 if (isencoded
) *isencoded
= 1;
95 } else if (type
== REDIS_RDB_6BITLEN
) {
96 /* Read a 6 bit len. */
98 } else if (type
== REDIS_RDB_14BITLEN
) {
99 /* Read a 14 bit len. */
100 if (rioRead(rdb
,buf
+1,1) == 0) return REDIS_RDB_LENERR
;
101 return ((buf
[0]&0x3F)<<8)|buf
[1];
103 /* Read a 32 bit len. */
104 if (rioRead(rdb
,&len
,4) == 0) return REDIS_RDB_LENERR
;
109 /* Encodes the "value" argument as integer when it fits in the supported ranges
110 * for encoded types. If the function successfully encodes the integer, the
111 * representation is stored in the buffer pointer to by "enc" and the string
112 * length is returned. Otherwise 0 is returned. */
113 int rdbEncodeInteger(long long value
, unsigned char *enc
) {
114 if (value
>= -(1<<7) && value
<= (1<<7)-1) {
115 enc
[0] = (REDIS_RDB_ENCVAL
<<6)|REDIS_RDB_ENC_INT8
;
118 } else if (value
>= -(1<<15) && value
<= (1<<15)-1) {
119 enc
[0] = (REDIS_RDB_ENCVAL
<<6)|REDIS_RDB_ENC_INT16
;
121 enc
[2] = (value
>>8)&0xFF;
123 } else if (value
>= -((long long)1<<31) && value
<= ((long long)1<<31)-1) {
124 enc
[0] = (REDIS_RDB_ENCVAL
<<6)|REDIS_RDB_ENC_INT32
;
126 enc
[2] = (value
>>8)&0xFF;
127 enc
[3] = (value
>>16)&0xFF;
128 enc
[4] = (value
>>24)&0xFF;
135 /* Loads an integer-encoded object with the specified encoding type "enctype".
136 * If the "encode" argument is set the function may return an integer-encoded
137 * string object, otherwise it always returns a raw string object. */
138 robj
*rdbLoadIntegerObject(rio
*rdb
, int enctype
, int encode
) {
139 unsigned char enc
[4];
142 if (enctype
== REDIS_RDB_ENC_INT8
) {
143 if (rioRead(rdb
,enc
,1) == 0) return NULL
;
144 val
= (signed char)enc
[0];
145 } else if (enctype
== REDIS_RDB_ENC_INT16
) {
147 if (rioRead(rdb
,enc
,2) == 0) return NULL
;
148 v
= enc
[0]|(enc
[1]<<8);
150 } else if (enctype
== REDIS_RDB_ENC_INT32
) {
152 if (rioRead(rdb
,enc
,4) == 0) return NULL
;
153 v
= enc
[0]|(enc
[1]<<8)|(enc
[2]<<16)|(enc
[3]<<24);
156 val
= 0; /* anti-warning */
157 redisPanic("Unknown RDB integer encoding type");
160 return createStringObjectFromLongLong(val
);
162 return createObject(REDIS_STRING
,sdsfromlonglong(val
));
165 /* String objects in the form "2391" "-100" without any space and with a
166 * range of values that can fit in an 8, 16 or 32 bit signed value can be
167 * encoded as integers to save space */
168 int rdbTryIntegerEncoding(char *s
, size_t len
, unsigned char *enc
) {
170 char *endptr
, buf
[32];
172 /* Check if it's possible to encode this value as a number */
173 value
= strtoll(s
, &endptr
, 10);
174 if (endptr
[0] != '\0') return 0;
175 ll2string(buf
,32,value
);
177 /* If the number converted back into a string is not identical
178 * then it's not possible to encode the string as integer */
179 if (strlen(buf
) != len
|| memcmp(buf
,s
,len
)) return 0;
181 return rdbEncodeInteger(value
,enc
);
184 int rdbSaveLzfStringObject(rio
*rdb
, unsigned char *s
, size_t len
) {
185 size_t comprlen
, outlen
;
190 /* We require at least four bytes compression for this to be worth it */
191 if (len
<= 4) return 0;
193 if ((out
= zmalloc(outlen
+1)) == NULL
) return 0;
194 comprlen
= lzf_compress(s
, len
, out
, outlen
);
199 /* Data compressed! Let's save it on disk */
200 byte
= (REDIS_RDB_ENCVAL
<<6)|REDIS_RDB_ENC_LZF
;
201 if ((n
= rdbWriteRaw(rdb
,&byte
,1)) == -1) goto writeerr
;
204 if ((n
= rdbSaveLen(rdb
,comprlen
)) == -1) goto writeerr
;
207 if ((n
= rdbSaveLen(rdb
,len
)) == -1) goto writeerr
;
210 if ((n
= rdbWriteRaw(rdb
,out
,comprlen
)) == -1) goto writeerr
;
221 robj
*rdbLoadLzfStringObject(rio
*rdb
) {
222 unsigned int len
, clen
;
223 unsigned char *c
= NULL
;
226 if ((clen
= rdbLoadLen(rdb
,NULL
)) == REDIS_RDB_LENERR
) return NULL
;
227 if ((len
= rdbLoadLen(rdb
,NULL
)) == REDIS_RDB_LENERR
) return NULL
;
228 if ((c
= zmalloc(clen
)) == NULL
) goto err
;
229 if ((val
= sdsnewlen(NULL
,len
)) == NULL
) goto err
;
230 if (rioRead(rdb
,c
,clen
) == 0) goto err
;
231 if (lzf_decompress(c
,clen
,val
,len
) == 0) goto err
;
233 return createObject(REDIS_STRING
,val
);
240 /* Save a string objet as [len][data] on disk. If the object is a string
241 * representation of an integer value we try to save it in a special form */
242 int rdbSaveRawString(rio
*rdb
, unsigned char *s
, size_t len
) {
246 /* Try integer encoding */
248 unsigned char buf
[5];
249 if ((enclen
= rdbTryIntegerEncoding((char*)s
,len
,buf
)) > 0) {
250 if (rdbWriteRaw(rdb
,buf
,enclen
) == -1) return -1;
255 /* Try LZF compression - under 20 bytes it's unable to compress even
256 * aaaaaaaaaaaaaaaaaa so skip it */
257 if (server
.rdb_compression
&& len
> 20) {
258 n
= rdbSaveLzfStringObject(rdb
,s
,len
);
259 if (n
== -1) return -1;
261 /* Return value of 0 means data can't be compressed, save the old way */
265 if ((n
= rdbSaveLen(rdb
,len
)) == -1) return -1;
268 if (rdbWriteRaw(rdb
,s
,len
) == -1) return -1;
274 /* Save a long long value as either an encoded string or a string. */
275 int rdbSaveLongLongAsStringObject(rio
*rdb
, long long value
) {
276 unsigned char buf
[32];
278 int enclen
= rdbEncodeInteger(value
,buf
);
280 return rdbWriteRaw(rdb
,buf
,enclen
);
282 /* Encode as string */
283 enclen
= ll2string((char*)buf
,32,value
);
284 redisAssert(enclen
< 32);
285 if ((n
= rdbSaveLen(rdb
,enclen
)) == -1) return -1;
287 if ((n
= rdbWriteRaw(rdb
,buf
,enclen
)) == -1) return -1;
293 /* Like rdbSaveStringObjectRaw() but handle encoded objects */
294 int rdbSaveStringObject(rio
*rdb
, robj
*obj
) {
295 /* Avoid to decode the object, then encode it again, if the
296 * object is alrady integer encoded. */
297 if (obj
->encoding
== REDIS_ENCODING_INT
) {
298 return rdbSaveLongLongAsStringObject(rdb
,(long)obj
->ptr
);
300 redisAssertWithInfo(NULL
,obj
,obj
->encoding
== REDIS_ENCODING_RAW
);
301 return rdbSaveRawString(rdb
,obj
->ptr
,sdslen(obj
->ptr
));
305 robj
*rdbGenericLoadStringObject(rio
*rdb
, int encode
) {
310 len
= rdbLoadLen(rdb
,&isencoded
);
313 case REDIS_RDB_ENC_INT8
:
314 case REDIS_RDB_ENC_INT16
:
315 case REDIS_RDB_ENC_INT32
:
316 return rdbLoadIntegerObject(rdb
,len
,encode
);
317 case REDIS_RDB_ENC_LZF
:
318 return rdbLoadLzfStringObject(rdb
);
320 redisPanic("Unknown RDB encoding type");
324 if (len
== REDIS_RDB_LENERR
) return NULL
;
325 val
= sdsnewlen(NULL
,len
);
326 if (len
&& rioRead(rdb
,val
,len
) == 0) {
330 return createObject(REDIS_STRING
,val
);
333 robj
*rdbLoadStringObject(rio
*rdb
) {
334 return rdbGenericLoadStringObject(rdb
,0);
337 robj
*rdbLoadEncodedStringObject(rio
*rdb
) {
338 return rdbGenericLoadStringObject(rdb
,1);
341 /* Save a double value. Doubles are saved as strings prefixed by an unsigned
342 * 8 bit integer specifing the length of the representation.
343 * This 8 bit integer has special values in order to specify the following
349 int rdbSaveDoubleValue(rio
*rdb
, double val
) {
350 unsigned char buf
[128];
356 } else if (!isfinite(val
)) {
358 buf
[0] = (val
< 0) ? 255 : 254;
360 #if (DBL_MANT_DIG >= 52) && (LLONG_MAX == 0x7fffffffffffffffLL)
361 /* Check if the float is in a safe range to be casted into a
362 * long long. We are assuming that long long is 64 bit here.
363 * Also we are assuming that there are no implementations around where
364 * double has precision < 52 bit.
366 * Under this assumptions we test if a double is inside an interval
367 * where casting to long long is safe. Then using two castings we
368 * make sure the decimal part is zero. If all this is true we use
369 * integer printing function that is much faster. */
370 double min
= -4503599627370495; /* (2^52)-1 */
371 double max
= 4503599627370496; /* -(2^52) */
372 if (val
> min
&& val
< max
&& val
== ((double)((long long)val
)))
373 ll2string((char*)buf
+1,sizeof(buf
),(long long)val
);
376 snprintf((char*)buf
+1,sizeof(buf
)-1,"%.17g",val
);
377 buf
[0] = strlen((char*)buf
+1);
380 return rdbWriteRaw(rdb
,buf
,len
);
383 /* For information about double serialization check rdbSaveDoubleValue() */
384 int rdbLoadDoubleValue(rio
*rdb
, double *val
) {
388 if (rioRead(rdb
,&len
,1) == 0) return -1;
390 case 255: *val
= R_NegInf
; return 0;
391 case 254: *val
= R_PosInf
; return 0;
392 case 253: *val
= R_Nan
; return 0;
394 if (rioRead(rdb
,buf
,len
) == 0) return -1;
396 sscanf(buf
, "%lg", val
);
401 /* Save the object type of object "o". */
402 int rdbSaveObjectType(rio
*rdb
, robj
*o
) {
405 return rdbSaveType(rdb
,REDIS_RDB_TYPE_STRING
);
407 if (o
->encoding
== REDIS_ENCODING_ZIPLIST
)
408 return rdbSaveType(rdb
,REDIS_RDB_TYPE_LIST_ZIPLIST
);
409 else if (o
->encoding
== REDIS_ENCODING_LINKEDLIST
)
410 return rdbSaveType(rdb
,REDIS_RDB_TYPE_LIST
);
412 redisPanic("Unknown list encoding");
414 if (o
->encoding
== REDIS_ENCODING_INTSET
)
415 return rdbSaveType(rdb
,REDIS_RDB_TYPE_SET_INTSET
);
416 else if (o
->encoding
== REDIS_ENCODING_HT
)
417 return rdbSaveType(rdb
,REDIS_RDB_TYPE_SET
);
419 redisPanic("Unknown set encoding");
421 if (o
->encoding
== REDIS_ENCODING_ZIPLIST
)
422 return rdbSaveType(rdb
,REDIS_RDB_TYPE_ZSET_ZIPLIST
);
423 else if (o
->encoding
== REDIS_ENCODING_SKIPLIST
)
424 return rdbSaveType(rdb
,REDIS_RDB_TYPE_ZSET
);
426 redisPanic("Unknown sorted set encoding");
428 if (o
->encoding
== REDIS_ENCODING_ZIPLIST
)
429 return rdbSaveType(rdb
,REDIS_RDB_TYPE_HASH_ZIPLIST
);
430 else if (o
->encoding
== REDIS_ENCODING_HT
)
431 return rdbSaveType(rdb
,REDIS_RDB_TYPE_HASH
);
433 redisPanic("Unknown hash encoding");
435 redisPanic("Unknown object type");
437 return -1; /* avoid warning */
440 /* Load object type. Return -1 when the byte doesn't contain an object type. */
441 int rdbLoadObjectType(rio
*rdb
) {
443 if ((type
= rdbLoadType(rdb
)) == -1) return -1;
444 if (!rdbIsObjectType(type
)) return -1;
448 /* Save a Redis object. Returns -1 on error, 0 on success. */
449 int rdbSaveObject(rio
*rdb
, robj
*o
) {
452 if (o
->type
== REDIS_STRING
) {
453 /* Save a string value */
454 if ((n
= rdbSaveStringObject(rdb
,o
)) == -1) return -1;
456 } else if (o
->type
== REDIS_LIST
) {
457 /* Save a list value */
458 if (o
->encoding
== REDIS_ENCODING_ZIPLIST
) {
459 size_t l
= ziplistBlobLen((unsigned char*)o
->ptr
);
461 if ((n
= rdbSaveRawString(rdb
,o
->ptr
,l
)) == -1) return -1;
463 } else if (o
->encoding
== REDIS_ENCODING_LINKEDLIST
) {
468 if ((n
= rdbSaveLen(rdb
,listLength(list
))) == -1) return -1;
471 listRewind(list
,&li
);
472 while((ln
= listNext(&li
))) {
473 robj
*eleobj
= listNodeValue(ln
);
474 if ((n
= rdbSaveStringObject(rdb
,eleobj
)) == -1) return -1;
478 redisPanic("Unknown list encoding");
480 } else if (o
->type
== REDIS_SET
) {
481 /* Save a set value */
482 if (o
->encoding
== REDIS_ENCODING_HT
) {
484 dictIterator
*di
= dictGetIterator(set
);
487 if ((n
= rdbSaveLen(rdb
,dictSize(set
))) == -1) return -1;
490 while((de
= dictNext(di
)) != NULL
) {
491 robj
*eleobj
= dictGetKey(de
);
492 if ((n
= rdbSaveStringObject(rdb
,eleobj
)) == -1) return -1;
495 dictReleaseIterator(di
);
496 } else if (o
->encoding
== REDIS_ENCODING_INTSET
) {
497 size_t l
= intsetBlobLen((intset
*)o
->ptr
);
499 if ((n
= rdbSaveRawString(rdb
,o
->ptr
,l
)) == -1) return -1;
502 redisPanic("Unknown set encoding");
504 } else if (o
->type
== REDIS_ZSET
) {
505 /* Save a sorted set value */
506 if (o
->encoding
== REDIS_ENCODING_ZIPLIST
) {
507 size_t l
= ziplistBlobLen((unsigned char*)o
->ptr
);
509 if ((n
= rdbSaveRawString(rdb
,o
->ptr
,l
)) == -1) return -1;
511 } else if (o
->encoding
== REDIS_ENCODING_SKIPLIST
) {
513 dictIterator
*di
= dictGetIterator(zs
->dict
);
516 if ((n
= rdbSaveLen(rdb
,dictSize(zs
->dict
))) == -1) return -1;
519 while((de
= dictNext(di
)) != NULL
) {
520 robj
*eleobj
= dictGetKey(de
);
521 double *score
= dictGetVal(de
);
523 if ((n
= rdbSaveStringObject(rdb
,eleobj
)) == -1) return -1;
525 if ((n
= rdbSaveDoubleValue(rdb
,*score
)) == -1) return -1;
528 dictReleaseIterator(di
);
530 redisPanic("Unknown sorted set encoding");
532 } else if (o
->type
== REDIS_HASH
) {
533 /* Save a hash value */
534 if (o
->encoding
== REDIS_ENCODING_ZIPLIST
) {
535 size_t l
= ziplistBlobLen((unsigned char*)o
->ptr
);
537 if ((n
= rdbSaveRawString(rdb
,o
->ptr
,l
)) == -1) return -1;
540 } else if (o
->encoding
== REDIS_ENCODING_HT
) {
541 dictIterator
*di
= dictGetIterator(o
->ptr
);
544 if ((n
= rdbSaveLen(rdb
,dictSize((dict
*)o
->ptr
))) == -1) return -1;
547 while((de
= dictNext(di
)) != NULL
) {
548 robj
*key
= dictGetKey(de
);
549 robj
*val
= dictGetVal(de
);
551 if ((n
= rdbSaveStringObject(rdb
,key
)) == -1) return -1;
553 if ((n
= rdbSaveStringObject(rdb
,val
)) == -1) return -1;
556 dictReleaseIterator(di
);
559 redisPanic("Unknown hash encoding");
563 redisPanic("Unknown object type");
568 /* Return the length the object will have on disk if saved with
569 * the rdbSaveObject() function. Currently we use a trick to get
570 * this length with very little changes to the code. In the future
571 * we could switch to a faster solution. */
572 off_t
rdbSavedObjectLen(robj
*o
) {
573 int len
= rdbSaveObject(NULL
,o
);
574 redisAssertWithInfo(NULL
,o
,len
!= -1);
578 /* Save a key-value pair, with expire time, type, key, value.
579 * On error -1 is returned.
580 * On success if the key was actaully saved 1 is returned, otherwise 0
581 * is returned (the key was already expired). */
582 int rdbSaveKeyValuePair(rio
*rdb
, robj
*key
, robj
*val
,
583 long long expiretime
, long long now
)
585 /* Save the expire time */
586 if (expiretime
!= -1) {
587 /* If this key is already expired skip it */
588 if (expiretime
< now
) return 0;
589 if (rdbSaveType(rdb
,REDIS_RDB_OPCODE_EXPIRETIME_MS
) == -1) return -1;
590 if (rdbSaveMillisecondTime(rdb
,expiretime
) == -1) return -1;
593 /* Save type, key, value */
594 if (rdbSaveObjectType(rdb
,val
) == -1) return -1;
595 if (rdbSaveStringObject(rdb
,key
) == -1) return -1;
596 if (rdbSaveObject(rdb
,val
) == -1) return -1;
600 /* Save the DB on disk. Return REDIS_ERR on error, REDIS_OK on success */
601 int rdbSave(char *filename
) {
602 dictIterator
*di
= NULL
;
606 long long now
= mstime();
610 snprintf(tmpfile
,256,"temp-%d.rdb", (int) getpid());
611 fp
= fopen(tmpfile
,"w");
613 redisLog(REDIS_WARNING
, "Failed opening .rdb for saving: %s",
618 rioInitWithFile(&rdb
,fp
);
619 if (rdbWriteRaw(&rdb
,"REDIS0003",9) == -1) goto werr
;
621 for (j
= 0; j
< server
.dbnum
; j
++) {
622 redisDb
*db
= server
.db
+j
;
624 if (dictSize(d
) == 0) continue;
625 di
= dictGetSafeIterator(d
);
631 /* Write the SELECT DB opcode */
632 if (rdbSaveType(&rdb
,REDIS_RDB_OPCODE_SELECTDB
) == -1) goto werr
;
633 if (rdbSaveLen(&rdb
,j
) == -1) goto werr
;
635 /* Iterate this DB writing every entry */
636 while((de
= dictNext(di
)) != NULL
) {
637 sds keystr
= dictGetKey(de
);
638 robj key
, *o
= dictGetVal(de
);
641 initStaticStringObject(key
,keystr
);
642 expire
= getExpire(db
,&key
);
643 if (rdbSaveKeyValuePair(&rdb
,&key
,o
,expire
,now
) == -1) goto werr
;
645 dictReleaseIterator(di
);
648 if (rdbSaveType(&rdb
,REDIS_RDB_OPCODE_EOF
) == -1) goto werr
;
650 /* Make sure data will not remain on the OS's output buffers */
655 /* Use RENAME to make sure the DB file is changed atomically only
656 * if the generate DB file is ok. */
657 if (rename(tmpfile
,filename
) == -1) {
658 redisLog(REDIS_WARNING
,"Error moving temp DB file on the final destination: %s", strerror(errno
));
662 redisLog(REDIS_NOTICE
,"DB saved on disk");
664 server
.lastsave
= time(NULL
);
670 redisLog(REDIS_WARNING
,"Write error saving DB on disk: %s", strerror(errno
));
671 if (di
) dictReleaseIterator(di
);
675 int rdbSaveBackground(char *filename
) {
679 if (server
.rdb_child_pid
!= -1) return REDIS_ERR
;
681 server
.dirty_before_bgsave
= server
.dirty
;
684 if ((childpid
= fork()) == 0) {
688 if (server
.ipfd
> 0) close(server
.ipfd
);
689 if (server
.sofd
> 0) close(server
.sofd
);
690 retval
= rdbSave(filename
);
691 _exit((retval
== REDIS_OK
) ? 0 : 1);
694 server
.stat_fork_time
= ustime()-start
;
695 if (childpid
== -1) {
696 redisLog(REDIS_WARNING
,"Can't save in background: fork: %s",
700 redisLog(REDIS_NOTICE
,"Background saving started by pid %d",childpid
);
701 server
.rdb_child_pid
= childpid
;
702 updateDictResizePolicy();
705 return REDIS_OK
; /* unreached */
708 void rdbRemoveTempFile(pid_t childpid
) {
711 snprintf(tmpfile
,256,"temp-%d.rdb", (int) childpid
);
715 /* Load a Redis object of the specified type from the specified file.
716 * On success a newly allocated object is returned, otherwise NULL. */
717 robj
*rdbLoadObject(int rdbtype
, rio
*rdb
) {
722 redisLog(REDIS_DEBUG
,"LOADING OBJECT %d (at %d)\n",rdbtype
,rdb
->tell(rdb
));
723 if (rdbtype
== REDIS_RDB_TYPE_STRING
) {
724 /* Read string value */
725 if ((o
= rdbLoadEncodedStringObject(rdb
)) == NULL
) return NULL
;
726 o
= tryObjectEncoding(o
);
727 } else if (rdbtype
== REDIS_RDB_TYPE_LIST
) {
728 /* Read list value */
729 if ((len
= rdbLoadLen(rdb
,NULL
)) == REDIS_RDB_LENERR
) return NULL
;
731 /* Use a real list when there are too many entries */
732 if (len
> server
.list_max_ziplist_entries
) {
733 o
= createListObject();
735 o
= createZiplistObject();
738 /* Load every single element of the list */
740 if ((ele
= rdbLoadEncodedStringObject(rdb
)) == NULL
) return NULL
;
742 /* If we are using a ziplist and the value is too big, convert
743 * the object to a real list. */
744 if (o
->encoding
== REDIS_ENCODING_ZIPLIST
&&
745 ele
->encoding
== REDIS_ENCODING_RAW
&&
746 sdslen(ele
->ptr
) > server
.list_max_ziplist_value
)
747 listTypeConvert(o
,REDIS_ENCODING_LINKEDLIST
);
749 if (o
->encoding
== REDIS_ENCODING_ZIPLIST
) {
750 dec
= getDecodedObject(ele
);
751 o
->ptr
= ziplistPush(o
->ptr
,dec
->ptr
,sdslen(dec
->ptr
),REDIS_TAIL
);
755 ele
= tryObjectEncoding(ele
);
756 listAddNodeTail(o
->ptr
,ele
);
759 } else if (rdbtype
== REDIS_RDB_TYPE_SET
) {
760 /* Read list/set value */
761 if ((len
= rdbLoadLen(rdb
,NULL
)) == REDIS_RDB_LENERR
) return NULL
;
763 /* Use a regular set when there are too many entries. */
764 if (len
> server
.set_max_intset_entries
) {
765 o
= createSetObject();
766 /* It's faster to expand the dict to the right size asap in order
767 * to avoid rehashing */
768 if (len
> DICT_HT_INITIAL_SIZE
)
769 dictExpand(o
->ptr
,len
);
771 o
= createIntsetObject();
774 /* Load every single element of the list/set */
775 for (i
= 0; i
< len
; i
++) {
777 if ((ele
= rdbLoadEncodedStringObject(rdb
)) == NULL
) return NULL
;
778 ele
= tryObjectEncoding(ele
);
780 if (o
->encoding
== REDIS_ENCODING_INTSET
) {
781 /* Fetch integer value from element */
782 if (isObjectRepresentableAsLongLong(ele
,&llval
) == REDIS_OK
) {
783 o
->ptr
= intsetAdd(o
->ptr
,llval
,NULL
);
785 setTypeConvert(o
,REDIS_ENCODING_HT
);
786 dictExpand(o
->ptr
,len
);
790 /* This will also be called when the set was just converted
791 * to regular hashtable encoded set */
792 if (o
->encoding
== REDIS_ENCODING_HT
) {
793 dictAdd((dict
*)o
->ptr
,ele
,NULL
);
798 } else if (rdbtype
== REDIS_RDB_TYPE_ZSET
) {
799 /* Read list/set value */
801 size_t maxelelen
= 0;
804 if ((zsetlen
= rdbLoadLen(rdb
,NULL
)) == REDIS_RDB_LENERR
) return NULL
;
805 o
= createZsetObject();
808 /* Load every single element of the list/set */
812 zskiplistNode
*znode
;
814 if ((ele
= rdbLoadEncodedStringObject(rdb
)) == NULL
) return NULL
;
815 ele
= tryObjectEncoding(ele
);
816 if (rdbLoadDoubleValue(rdb
,&score
) == -1) return NULL
;
818 /* Don't care about integer-encoded strings. */
819 if (ele
->encoding
== REDIS_ENCODING_RAW
&&
820 sdslen(ele
->ptr
) > maxelelen
)
821 maxelelen
= sdslen(ele
->ptr
);
823 znode
= zslInsert(zs
->zsl
,score
,ele
);
824 dictAdd(zs
->dict
,ele
,&znode
->score
);
825 incrRefCount(ele
); /* added to skiplist */
828 /* Convert *after* loading, since sorted sets are not stored ordered. */
829 if (zsetLength(o
) <= server
.zset_max_ziplist_entries
&&
830 maxelelen
<= server
.zset_max_ziplist_value
)
831 zsetConvert(o
,REDIS_ENCODING_ZIPLIST
);
832 } else if (rdbtype
== REDIS_RDB_TYPE_HASH
) {
836 len
= rdbLoadLen(rdb
, NULL
);
837 if (len
== REDIS_RDB_LENERR
) return NULL
;
839 o
= createHashObject();
841 /* Too many entries? Use an hash table. */
842 if (len
> server
.hash_max_ziplist_entries
)
843 hashTypeConvert(o
, REDIS_ENCODING_HT
);
845 /* Load every field and value into the ziplist */
846 while (o
->encoding
== REDIS_ENCODING_ZIPLIST
&& len
-- > 0) {
849 /* Load raw strings */
850 field
= rdbLoadStringObject(rdb
);
851 if (field
== NULL
) return NULL
;
852 redisAssert(field
->encoding
== REDIS_ENCODING_RAW
);
853 value
= rdbLoadStringObject(rdb
);
854 if (value
== NULL
) return NULL
;
855 redisAssert(field
->encoding
== REDIS_ENCODING_RAW
);
857 /* Convert to hash table if size threshold is exceeded */
858 if (sdslen(field
->ptr
) > server
.hash_max_ziplist_value
||
859 sdslen(value
->ptr
) > server
.hash_max_ziplist_value
)
861 hashTypeConvert(o
, REDIS_ENCODING_HT
);
865 /* Add pair to ziplist */
866 o
->ptr
= ziplistPush(o
->ptr
, field
->ptr
, sdslen(field
->ptr
), ZIPLIST_TAIL
);
867 o
->ptr
= ziplistPush(o
->ptr
, value
->ptr
, sdslen(value
->ptr
), ZIPLIST_TAIL
);
870 /* Load remaining fields and values into the hash table */
871 while (o
->encoding
== REDIS_ENCODING_HT
&& len
-- > 0) {
874 /* Load encoded strings */
875 field
= rdbLoadEncodedStringObject(rdb
);
876 if (field
== NULL
) return NULL
;
877 value
= rdbLoadEncodedStringObject(rdb
);
878 if (value
== NULL
) return NULL
;
880 field
= tryObjectEncoding(field
);
881 value
= tryObjectEncoding(value
);
883 /* Add pair to hash table */
884 ret
= dictAdd((dict
*)o
->ptr
, field
, value
);
885 redisAssert(ret
== REDIS_OK
);
888 /* All pairs should be read by now */
889 redisAssert(len
== 0);
891 } else if (rdbtype
== REDIS_RDB_TYPE_HASH_ZIPMAP
||
892 rdbtype
== REDIS_RDB_TYPE_LIST_ZIPLIST
||
893 rdbtype
== REDIS_RDB_TYPE_SET_INTSET
||
894 rdbtype
== REDIS_RDB_TYPE_ZSET_ZIPLIST
||
895 rdbtype
== REDIS_RDB_TYPE_HASH_ZIPLIST
)
897 robj
*aux
= rdbLoadStringObject(rdb
);
899 if (aux
== NULL
) return NULL
;
900 o
= createObject(REDIS_STRING
,NULL
); /* string is just placeholder */
901 o
->ptr
= zmalloc(sdslen(aux
->ptr
));
902 memcpy(o
->ptr
,aux
->ptr
,sdslen(aux
->ptr
));
905 /* Fix the object encoding, and make sure to convert the encoded
906 * data type into the base type if accordingly to the current
907 * configuration there are too many elements in the encoded data
908 * type. Note that we only check the length and not max element
909 * size as this is an O(N) scan. Eventually everything will get
912 case REDIS_RDB_TYPE_HASH_ZIPMAP
:
913 /* Convert to ziplist encoded hash. This must be deprecated
914 * when loading dumps created by Redis 2.4 gets deprecated. */
916 unsigned char *zl
= ziplistNew();
917 unsigned char *zi
= zipmapRewind(o
->ptr
);
918 unsigned char *fstr
, *vstr
;
919 unsigned int flen
, vlen
;
920 unsigned int maxlen
= 0;
922 while ((zi
= zipmapNext(zi
, &fstr
, &flen
, &vstr
, &vlen
)) != NULL
) {
923 if (flen
> maxlen
) maxlen
= flen
;
924 if (vlen
> maxlen
) maxlen
= vlen
;
925 zl
= ziplistPush(zl
, fstr
, flen
, ZIPLIST_TAIL
);
926 zl
= ziplistPush(zl
, vstr
, vlen
, ZIPLIST_TAIL
);
931 o
->type
= REDIS_HASH
;
932 o
->encoding
= REDIS_ENCODING_ZIPLIST
;
934 if (hashTypeLength(o
) > server
.hash_max_ziplist_entries
||
935 maxlen
> server
.hash_max_ziplist_value
)
937 hashTypeConvert(o
, REDIS_ENCODING_HT
);
941 case REDIS_RDB_TYPE_LIST_ZIPLIST
:
942 o
->type
= REDIS_LIST
;
943 o
->encoding
= REDIS_ENCODING_ZIPLIST
;
944 if (ziplistLen(o
->ptr
) > server
.list_max_ziplist_entries
)
945 listTypeConvert(o
,REDIS_ENCODING_LINKEDLIST
);
947 case REDIS_RDB_TYPE_SET_INTSET
:
949 o
->encoding
= REDIS_ENCODING_INTSET
;
950 if (intsetLen(o
->ptr
) > server
.set_max_intset_entries
)
951 setTypeConvert(o
,REDIS_ENCODING_HT
);
953 case REDIS_RDB_TYPE_ZSET_ZIPLIST
:
954 o
->type
= REDIS_ZSET
;
955 o
->encoding
= REDIS_ENCODING_ZIPLIST
;
956 if (zsetLength(o
) > server
.zset_max_ziplist_entries
)
957 zsetConvert(o
,REDIS_ENCODING_SKIPLIST
);
959 case REDIS_RDB_TYPE_HASH_ZIPLIST
:
960 o
->type
= REDIS_HASH
;
961 o
->encoding
= REDIS_ENCODING_ZIPLIST
;
962 if (hashTypeLength(o
) > server
.hash_max_ziplist_entries
)
963 hashTypeConvert(o
, REDIS_ENCODING_HT
);
966 redisPanic("Unknown encoding");
970 redisPanic("Unknown object type");
975 /* Mark that we are loading in the global state and setup the fields
976 * needed to provide loading stats. */
977 void startLoading(FILE *fp
) {
982 server
.loading_start_time
= time(NULL
);
983 if (fstat(fileno(fp
), &sb
) == -1) {
984 server
.loading_total_bytes
= 1; /* just to avoid division by zero */
986 server
.loading_total_bytes
= sb
.st_size
;
990 /* Refresh the loading progress info */
991 void loadingProgress(off_t pos
) {
992 server
.loading_loaded_bytes
= pos
;
995 /* Loading finished */
996 void stopLoading(void) {
1000 int rdbLoad(char *filename
) {
1003 redisDb
*db
= server
.db
+0;
1005 long long expiretime
, now
= mstime();
1010 fp
= fopen(filename
,"r");
1015 rioInitWithFile(&rdb
,fp
);
1016 if (rioRead(&rdb
,buf
,9) == 0) goto eoferr
;
1018 if (memcmp(buf
,"REDIS",5) != 0) {
1020 redisLog(REDIS_WARNING
,"Wrong signature trying to load DB from file");
1024 rdbver
= atoi(buf
+5);
1025 if (rdbver
< 1 || rdbver
> 3) {
1027 redisLog(REDIS_WARNING
,"Can't handle RDB format version %d",rdbver
);
1037 /* Serve the clients from time to time */
1038 if (!(loops
++ % 1000)) {
1039 loadingProgress(rdb
.tell(&rdb
));
1040 aeProcessEvents(server
.el
, AE_FILE_EVENTS
|AE_DONT_WAIT
);
1044 if ((type
= rdbLoadType(&rdb
)) == -1) goto eoferr
;
1045 if (type
== REDIS_RDB_OPCODE_EXPIRETIME
) {
1046 if ((expiretime
= rdbLoadTime(&rdb
)) == -1) goto eoferr
;
1047 /* We read the time so we need to read the object type again. */
1048 if ((type
= rdbLoadType(&rdb
)) == -1) goto eoferr
;
1049 /* the EXPIRETIME opcode specifies time in seconds, so convert
1050 * into milliesconds. */
1052 } else if (type
== REDIS_RDB_OPCODE_EXPIRETIME_MS
) {
1053 /* Milliseconds precision expire times introduced with RDB
1055 if ((expiretime
= rdbLoadMillisecondTime(&rdb
)) == -1) goto eoferr
;
1056 /* We read the time so we need to read the object type again. */
1057 if ((type
= rdbLoadType(&rdb
)) == -1) goto eoferr
;
1060 if (type
== REDIS_RDB_OPCODE_EOF
)
1063 /* Handle SELECT DB opcode as a special case */
1064 if (type
== REDIS_RDB_OPCODE_SELECTDB
) {
1065 if ((dbid
= rdbLoadLen(&rdb
,NULL
)) == REDIS_RDB_LENERR
)
1067 if (dbid
>= (unsigned)server
.dbnum
) {
1068 redisLog(REDIS_WARNING
,"FATAL: Data file was created with a Redis server configured to handle more than %d databases. Exiting\n", server
.dbnum
);
1071 db
= server
.db
+dbid
;
1075 if ((key
= rdbLoadStringObject(&rdb
)) == NULL
) goto eoferr
;
1077 if ((val
= rdbLoadObject(type
,&rdb
)) == NULL
) goto eoferr
;
1078 /* Check if the key already expired */
1079 if (expiretime
!= -1 && expiretime
< now
) {
1084 /* Add the new object in the hash table */
1087 /* Set the expire time if needed */
1088 if (expiretime
!= -1) setExpire(db
,key
,expiretime
);
1096 eoferr
: /* unexpected end of file is handled here with a fatal exit */
1097 redisLog(REDIS_WARNING
,"Short read or OOM loading DB. Unrecoverable error, aborting now.");
1099 return REDIS_ERR
; /* Just to avoid warning */
1102 /* A background saving child (BGSAVE) terminated its work. Handle this. */
1103 void backgroundSaveDoneHandler(int exitcode
, int bysignal
) {
1104 if (!bysignal
&& exitcode
== 0) {
1105 redisLog(REDIS_NOTICE
,
1106 "Background saving terminated with success");
1107 server
.dirty
= server
.dirty
- server
.dirty_before_bgsave
;
1108 server
.lastsave
= time(NULL
);
1109 } else if (!bysignal
&& exitcode
!= 0) {
1110 redisLog(REDIS_WARNING
, "Background saving error");
1112 redisLog(REDIS_WARNING
,
1113 "Background saving terminated by signal %d", bysignal
);
1114 rdbRemoveTempFile(server
.rdb_child_pid
);
1116 server
.rdb_child_pid
= -1;
1117 /* Possibly there are slaves waiting for a BGSAVE in order to be served
1118 * (the first stage of SYNC is a bulk transfer of dump.rdb) */
1119 updateSlavesWaitingBgsave(exitcode
== 0 ? REDIS_OK
: REDIS_ERR
);
1122 void saveCommand(redisClient
*c
) {
1123 if (server
.rdb_child_pid
!= -1) {
1124 addReplyError(c
,"Background save already in progress");
1127 if (rdbSave(server
.rdb_filename
) == REDIS_OK
) {
1128 addReply(c
,shared
.ok
);
1130 addReply(c
,shared
.err
);
1134 void bgsaveCommand(redisClient
*c
) {
1135 if (server
.rdb_child_pid
!= -1) {
1136 addReplyError(c
,"Background save already in progress");
1137 } else if (server
.aof_child_pid
!= -1) {
1138 addReplyError(c
,"Can't BGSAVE while AOF log rewriting is in progress");
1139 } else if (rdbSaveBackground(server
.rdb_filename
) == REDIS_OK
) {
1140 addReplyStatus(c
,"Background saving started");
1142 addReply(c
,shared
.err
);