RDB Functions

Redis Server Course Redis Technical Support Redis Enterprise Server

RDB Functions

이 문서는 레디스 버전 5.0.4를 기준으로 작성했습니다.

RDB Loading function과 Save function 비교

rdb loading function compare
    그림 1-1   RDB loading function 비교

RDB Funtion 비교

타입 저장/로드 function: rdbSaveType(), rdbLoadType()

int이지만 1바이트 unsigned char로 저장한다. Data type와 rdb에서 구분자로 사용되는 OPcode를 저장한다.

  • int rdbSaveType(rio *rdb, unsigned char type) --- int rdbLoadType(rio *rdb)
    • rdbWriteRaw(rdb,&type,1) --- rioRead(rdb,&type,1); return unsigned char type

데이터 타입은 아래와 같다.
RDB_TYPE_STRING 0
RDB_TYPE_LIST 1
RDB_TYPE_SET 2
RDB_TYPE_ZSET 3
RDB_TYPE_HASH 4
RDB_TYPE_ZSET_2 5 /* ZSET version 2 with doubles stored in binary. */
RDB_TYPE_MODULE 6
RDB_TYPE_MODULE_2 7 /* Module value with annotations for parsing without the generating module being loaded. */

Object types for encoded objects.
RDB_TYPE_HASH_ZIPMAP 9
RDB_TYPE_LIST_ZIPLIST 10
RDB_TYPE_SET_INTSET 11
RDB_TYPE_ZSET_ZIPLIST 12
RDB_TYPE_HASH_ZIPLIST 13
RDB_TYPE_LIST_QUICKLIST 14
RDB_TYPE_STREAM_LISTPACKS 15

Special RDB opcodes (saved/loaded with rdbSaveType/rdbLoadType).
RDB_OPCODE_MODULE_AUX 247 /* Module auxiliary data. */
RDB_OPCODE_IDLE 248 /* LRU idle time. */
RDB_OPCODE_FREQ 249 /* LFU frequency. */
RDB_OPCODE_AUX 250 /* RDB aux field. */
RDB_OPCODE_RESIZEDB 251 /* Hash table resize hint. */
RDB_OPCODE_EXPIRETIME_MS 252 /* Expire time in milliseconds. */
RDB_OPCODE_EXPIRETIME 253 /* Old expire time in seconds. */
RDB_OPCODE_SELECTDB 254 /* DB number of the following keys. */
RDB_OPCODE_EOF 255 /* End of the RDB file. */

밀리초 저장/로드 function: rdbSaveMillisecondTime(), rdbLoadMillisecondTime()

밀리초를 저장/로드한다. Long long을 사용해서 8바이트를 사용한다. Expire time, Update mstime(Enterprise ver)에서 사용한다.

  • int rdbSaveMillisecondTime(rio *rdb, long long t) --- long long rdbLoadMillisecondTime(rio *rdb, int rdbver)
    • rdbWriteRaw(rdb,&t64,8) --- rdbLoadRaw(rdb,&t64,8)

길이 저장/로드 function: rdbSaveLen(), rdbLoadLen()

데이터의 길이(string), 개수(SET같은 타입의 경우)를 저장한다. 차지하는 바이트수는 값에 따라 다르다.
1byte: 구분자 2bits, 길이 6bits(0~63)
2bytes: 구분자 2bits, 길이 14bits(64~16,383)
5bytes: 구분자 1byte, 길이 4bytes(int)
9bytes: 구분자 1byte, 길이 8bytes(long)

  • int rdbSaveLen(rio *rdb, uint64_t len) --- uint64_t rdbLoadLen(rio *rdb, int *isencoded)
    • rdbWriteRaw(rdb,buf,1/2/(1/4)/(1/8)) --- rdbLoadLenByRef(rdb,isencoded,&len)
                                                                                rioRead(rdb,buf,1+(1/4/8))

값(value)의 데이터 타입 저장/로드 function: rdbSaveObjectType(), rdbLoadObjectType()

val->type 또는 encoding을 위에서 설명한 rdbSaveType(), rdbLoadType()를 사용해서 저장/로드한다.

  • int rdbSaveObjectType(rio *rdb, robj *o) --- int rdbLoadObjectType(rio *rdb)
    • rdbSaveType(rdb,RDB_TYPE_*) --- int type = rdbLoadType(rdb); return type

값(value)을 저장/로드 function: rdbSaveObject(), rdbLoadObject()

robj를 저장/로드한다.

  • ssize_t rdbSaveObject(rio *rdb, robj *o)
  • robj *rdbLoadObject(int rdbtype, rio *rdb)

문자열(string)을 압축해서 저장/로드 function: rdbSaveLzfStringObject(), rdbLoadLzfStringObject()

LZF로 압축/해제한다.

  • ssize_t rdbSaveLzfStringObject(rio *rdb, unsigned char *s, size_t len)
  • void *rdbLoadLzfStringObject(rio *rdb, int flags, size_t *lenptr)

문자열(string)을 저장/로드 function: rdbSaveStringObject(), rdbLoadStringObject()

  • ssize_t rdbSaveStringObject(rio *rdb, robj *obj)
  • robj *rdbLoadStringObject(rio *rdb)

Float/Double를 저장/로드 function

  • Save
  • Load

RDB 전체 함수 리스트(ent810, redis-7.2.7) rdb.c

업데이트 날짜: 2025년 7월 15일(화)
기준: ent810(redis-7.2.7) rdb.c
  1. ssize_t rdbWriteRaw(rio *rdb, void *p, size_t len) rioWrite(rdb,p,len)
  2. int rdbSaveType(rio *rdb, unsigned char type) rdbWriteRaw(rdb,&type,1);
  3. int rdbLoadType(rio *rdb) rioRead(rdb,&type,1) // RDB 형식의 "type", 즉 1바이트 부호 없는 정수를 로드합니다.
  4. time_t rdbLoadTime(rio *rdb) rioRead(rdb,&t32,4)
  5. int rdbSaveMillisecondTime(rio *rdb, long long t) return rdbWriteRaw(rdb,&t64,8);
  6. long long rdbLoadMillisecondTime(rio *rdb, int rdbver) rioRead(rdb,&t64,8);
  7. int rdbSaveLen(rio *rdb, uint64_t len) // 인코딩된 길이를 저장합니다.
  8. int rdbLoadLenByRef(rio *rdb, int *isencoded, uint64_t *lenptr) // 인코딩된 길이를 로드합니다.
  9. uint64_t rdbLoadLen(rio *rdb, int *isencoded) rdbLoadLenByRef()
  10. int rdbEncodeInteger(long long value, unsigned char *enc)
  11. void *rdbLoadIntegerObject(rio *rdb, int enctype, int flags, size_t *lenptr)
  12. int rdbTryIntegerEncoding(char *s, size_t len, unsigned char *enc)
  13. ssize_t rdbSaveLzfBlob(rio *rdb, void *data, size_t compress_len, size_t original_len)
  14. ssize_t rdbSaveLzfStringObject(rio *rdb, unsigned char *s, size_t len)
  15. void *rdbLoadLzfStringObject(rio *rdb, int flags, size_t *lenptr) // LZF 압축 문자열을 RDB 형식으로 로드합니다.
  16. ssize_t rdbSaveRawString(rio *rdb, unsigned char *s, size_t len) // [len][data] 형식으로 저장합니다.
  17. ssize_t rdbSaveLongLongAsStringObject(rio *rdb, long long value) // long long 숫자를 인코딩된 문자열이나 그냥 문자열로 저장합니다.
  18. ssize_t rdbSaveStringObject(rio *rdb, robj *obj) // rdbSaveRawString()과 비슷하지만, 대신 Redis 객체를 저장합니다.
  19. void *rdbGenericLoadStringObject(rio *rdb, int flags, size_t *lenptr) // 플래그에 따라 RDB 파일에서 문자열 객체를 로드합니다.
  20. robj *rdbLoadStringObject(rio *rdb) return rdbGenericLoadStringObject(rdb,RDB_LOAD_NONE,NULL);
  21. robj *rdbLoadEncodedStringObject(rio *rdb) return rdbGenericLoadStringObject(rdb,RDB_LOAD_ENC,NULL);
  22. int rdbSaveDoubleValue(rio *rdb, double val) // double 값을 저장합니다.
  23. int rdbLoadDoubleValue(rio *rdb, double *val) // double 값을 로드합니다.
  24. int rdbSaveBinaryDoubleValue(rio *rdb, double val) memrev64ifbe(&val); rdbWriteRaw(); // binary64 형식을 가정하여 double 값을 저장합니다.
  25. int rdbLoadBinaryDoubleValue(rio *rdb, double *val) rioRead(); memrev64ifbe(val); // RDB 8 이상에서 double을 로드합니다.
  26. int rdbSaveBinaryFloatValue(rio *rdb, float val) // rdbSaveBinaryDoubleValue()와 유사하지만 단일 정밀도입니다.
  27. int rdbLoadBinaryFloatValue(rio *rdb, float *val) // rdbLoadBinaryDoubleValue()와 유사하지만 단일 정밀도입니다.
  28. int rdbSaveObjectType(rio *rdb, robj *o) // 객체 "o"의 객체 유형(object type)을 저장합니다.
  29. int rdbLoadObjectType(rio *rdb) // rdbLoadType()을 사용하여 RDB 형식의 TYPE을 로드
  30. ssize_t rdbSaveStreamPEL(rio *rdb, rax *pel, int nacks) // Stream consumer group 보류 항목 목록(PEL)을 RDB 파일로 직렬화합니다.
  31. size_t rdbSaveStreamConsumers(rio *rdb, streamCG *cg) // Stream consumer group 소비자를 RDB에 직렬화합니다.
  32. ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key, int dbid) // Redis 객체를 저장합니다. <-> rdbLoadObject()
  33. size_t rdbSavedObjectLen(robj *o, robj *key, int dbid) // rdbSaveObject() 함수의 인수 '*rdb'를 'NULL'로하면 저장하지 않고 길이(len)을 리턴함.
  34. int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val, long long expiretime, int dbid) // 만료 시간, 유형, 키, 값을 포함하는 키-값 쌍을 저장. 성공:1, 실패:-1
  35. ssize_t rdbSaveAuxField(rio *rdb, void *key, size_t keylen, void *val, size_t vallen) // AUX 필드 저장
  36. ssize_t rdbSaveAuxFieldStrStr(rio *rdb, char *key, char *val) // strlen()으로 키/값 길이를 얻을 수 있는 경우 사용되는 rdbSaveAuxField()에 대한 래퍼입니다.
  37. ssize_t rdbSaveAuxFieldStrInt(rio *rdb, char *key, long long val) // strlen(키) + 정수형(long long 범위까지)에 대한 래퍼입니다.
  38. int rdbSaveInfoAuxFields(rio *rdb, int rdbflags, rdbSaveInfo *rsi) // 생성된 RDB에 대한 정보와 함께 몇 개의 기본 AUX 필드를 저장합니다.
  39. ssize_t rdbSaveSingleModuleAux(rio *rdb, int when, moduleType *mt)
  40. ssize_t rdbSaveFunctions(rio *rdb) // <-> rdbFunctionLoad()
  41. ssize_t rdbSaveDb(rio *rdb, int dbid, int rdbflags, long *key_counter) // 📍db->dict 저장, rdbSaveKeyValuePair()
    // rdbSaveRio() 함수에서만 사용한다.
  42. int rdbSaveRio(int req, rio *rdb, int *error, int rdbflags, rdbSaveInfo *rsi)
    // 사용 함수: rdbSaveModulesAux(), rdbSaveFunctions(), rdbSaveDb(), dbSaveType(rdb,RDB_OPCODE_EOF)
    // 📍rdbSaveDbType() 함수를 새로 만들어서 type_dicts[]를 저장한다.
    // rdbSaveRioWithEOFMark(), rdbSaveInternal()에서 사용한다.
  43. int rdbSaveRioWithEOFMark(int req, rio *rdb, int *error, rdbSaveInfo *rsi) // 이 함수는 생성된 RDB 덤프에 접두사와 접미사를 추가하는 rdbSaveRio()의 래퍼입니다.
    // 파일 시작과 끝에 40바이트 eofmark를 넣는다. rdbSaveToSlavesSockets() 함수: Memory to Memory 전송 시 이 eofmark로 파일 끝을 구분(확인)한다.
  44. static int rdbSaveInternal(int req, const char *filename, rdbSaveInfo *rsi, int rdbflags)
    // rdbSaveToFile(), rdbSave()에서 사용
  45. int rdbSaveToFile(const char *filename) rdbSaveInternal() // DB를 파일에 저장합니다.
  46. int rdbSave(int req, char *filename, rdbSaveInfo *rsi, int rdbflags) // DB를 디스크에 저장합니다.
    // rdbSaveBackground(), saveCommand()에서 사용
  47. int rdbSaveBackground(int req, char *filename, rdbSaveInfo *rsi, int rdbflags)
    // bgsaveCommand()에서 사용
    redisFork(CHILD_TYPE_RDB);
    child: rdbSave(req, filename,rsi,rdbflags);
  48. void rdbRemoveTempFile(pid_t childpid, int from_signal)
    // backgroundSaveDoneHandlerDisk()에서 사용
    1) open(tmpfile, O_RDONLY|O_NONBLOCK); unlink(tmpfile); or 2) bg_unlink(tmpfile);
  49. robj *rdbLoadCheckModuleValue(rio *rdb, char *modulename)
  50. static int _ziplistPairsEntryConvertAndValidate(unsigned char *p, unsigned int head_count, void *userdata)
  51. int ziplistPairsConvertAndValidateIntegrity(unsigned char *zl, size_t size, unsigned char **lp)
    // 데이터 구조를 'listpack'으로 변환하여 'lp'에 저장하는 동안 무결성을 검증합니다.
  52. static int _ziplistEntryConvertAndValidate(unsigned char *p, unsigned int head_count, void *userdata)
    // 'ziplistValidateIntegrity'에 대한 콜백입니다.
    // 'p'가 가리키는 ziplist 요소는 변환되어 listpack에 저장됩니다.
  53. static int _listZiplistEntryConvertAndValidate(unsigned char *p, unsigned int head_count, void *userdata)
    // 'ziplistValidateIntegrity'에 대한 콜백입니다.
    // 'p'가 가리키는 ziplist 요소는 변환되어 quicklist에 저장됩니다.
  54. static int _lpEntryValidation(unsigned char *p, unsigned int head_count, void *userdata)
    // 'listpack'에 중복 레코드가 없는지 확인하기 위한 콜백
  55. int lpValidateIntegrityAndDups(unsigned char *lp, size_t size, int deep, int pairs)
    // listpack 구조의 무결성을 검증합니다.
    // `deep`이 0이면 헤더의 무결성만 검증합니다.
    // `deep`이 1이면 모든 항목을 하나씩 검사합니다.
    // `pairs`가 0이면 모든 요소가 고유해야 합니다(세트입니다).
    // `pairs`가 1이면 홀수 요소가 고유해야 합니다(키-값 맵입니다).
  56. robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error, int rdbver) // <-> rdbSaveObject()
    // 지정된 파일에서 지정된 유형의 Redis 객체를 로드합니다.
    // 성공 시 새로 할당된 객체가 반환되고, 그렇지 않으면 NULL이 반환됩니다.
    // 함수가 NULL을 반환하고 'error'가 NULL이 아니면 'error'가 가리키는 정수는 발생한 오류의 유형으로 설정됩니다.
  57. void startLoading(size_t size, int rdbflags, int async) // 글로벌 상태에서 로딩 중임을 표시하고 로딩 통계를 제공하는 데 필요한 필드를 설정합니다.
  58. void startLoadingFile(size_t size, char* filename, int rdbflags)
    // 글로벌 상태로 로딩 중임을 표시하고 로딩 통계를 제공하는 데 필요한 필드를 설정합니다.
    // 'filename'은 선택 사항이며 오류 발생 시 rdb-check에 사용됩니다.
  59. void loadingAbsProgress(off_t pos) server.loading_loaded_bytes = pos;
    // absolute(절대) 로딩 진행률 정보를 새로 고침합니다.
    // rdbLoadRioWithLoadingCtx() -> rdbLoadProgressCallback()에서 사용
  60. void loadingIncrProgress(off_t size) server.loading_loaded_bytes += size;
    // incremental(증분) 로딩 진행 정보 새로 고침
    // aof.c loadSingleAppendOnlyFile()에서 사용
  61. void updateLoadingFileName(char* filename) rdbFileBeingLoaded = filename;
    // 현재 로드 중인 파일 이름을 업데이트합니다.
  62. void stopLoading(int success) // Loading finished
  63. void startSaving(int rdbflags) // rdbSaveRioWithEOFMark(), rdbSaveToFile()에서 사용
  64. void stopSaving(int success) // rdbSaveRioWithEOFMark(), rdbSaveToFile(), rdbSave()에서 사용
  65. Track loading progress in order to serve client's from time to time and if needed calculate rdb checksum.
  66. void rdbLoadProgressCallback(rio *r, const void *buf, size_t len)
    // 수시로 클라이언트에게 서비스를 제공하기 위해 로딩 진행 상황을 추적하고 필요한 경우 RDB 체크섬을 계산합니다.
  67. int rdbFunctionLoad(rio *rdb, int ver, functionsLibCtx* lib_ctx, int rdbflags, sds *err)
    // rdbLoadRioWithLoadingCtx()에서 사용
    // 주어진 functions_ctx를 rdb에 저장합니다.
    // err 출력 매개변수는 선택 사항이며, 실패 시 관련 오류 메시지와 함께 설정됩니다.
    // 실패 시 오류 메시지를 해제하는 것은 호출자의 책임입니다.
    // lib_ctx 인수도 선택 사항입니다.
    // NULL이 지정된 경우, 실제 함수 로딩을 수행하지 않고 rdb 구조만 검증합니다.
  68. int rdbLoadRio(rio *rdb, int rdbflags, rdbSaveInfo *rsi) rdbLoadRioWithLoadingCtx()
    // rio 스트림 'rdb'에서 RDB 파일을 로드합니다.
    // 성공하면 C_OK가 반환되고, 실패하면 C_ERR이 반환되고 'errno'가 그에 따라 설정됩니다.
  69. int rdbLoadRioWithLoadingCtx(rio *rdb, int rdbflags, rdbSaveInfo *rsi, rdbLoadingCtx *rdb_loading_ctx)
    // rio 스트림 'rdb'에서 RDB 파일을 로드합니다.
  70. int rdbLoad(char *filename, rdbSaveInfo *rsi, int rdbflags)
    // rdbLoad() -> rdbLoadRio() -> rdbLoadRioWithLoadingCtx()
    // rdbLoadRio()와 유사하지만 rio 스트림 대신 파일 이름을 사용합니다. rdbLoadRio()를 사용합니다.
    // 파일 이름은 읽기 전용으로 열려 있으며, 실제 로딩을 위해 rio 스트림 객체가 생성됩니다.
    // 또한 INFO 출력에 표시되는 'ETA'는 초기화되고 완료됩니다.
    // 'RDB_SAVE_INFO_INIT'으로 초기화된 'rsi' 구조체를 전달하면 로딩 코드가 구조체의 정보 필드를 채웁니다.
  71. static void backgroundSaveDoneHandlerDisk(int exitcode, int bysignal)
    // 백그라운드 저장 child(BGSAVE)이 작업을 종료했습니다. 이것을 처리(정리)합니다.
    // 이 함수는 실제 'BGSAVE'의 경우를 다룹니다.
  72. static void backgroundSaveDoneHandlerSocket(int exitcode, int bysignal)
    // 백그라운드 저장 child(BGSAVE)이 작업을 종료했습니다. 이것을 처리(정리)합니다.
    // 이 함수는 diskless replication(디스크 없는 복제)를 위한 RDB -> 슬레이브 소켓 전송의 경우를 처리합니다.
  73. void backgroundSaveDoneHandler(int exitcode, int bysignal)
    // 백그라운드 RDB 저장/전송이 종료되면 올바른 핸들러를 호출합니다.
    switch(server.rdb_child_type)
    case RDB_CHILD_TYPE_DISK: backgroundSaveDoneHandlerDisk(exitcode,bysignal); break;
    case RDB_CHILD_TYPE_SOCKET: backgroundSaveDoneHandlerSocket(exitcode,bysignal); break;
  74. void killRDBChild(void)
    // 'SIGUSR1'을 사용하여 RDB를 저장하는 자식을 종료합니다
    // (이렇게 하면 부모는 자식이 오류로 인해 종료된 것이 아니라 우리가 원해서 종료되었다는 것을 알 수 있음).
    // 그리고 필요한 정리를 수행합니다.
  75. int rdbSaveToSlavesSockets(int req, rdbSaveInfo *rsi)
    // 현재 SLAVE_STATE_WAIT_BGSAVE_START 상태인 슬레이브의 소켓에 RDB를 쓰는 RDB 자식을 생성합니다.
    redisFork(CHILD_TYPE_RDB);
    rdbSaveRioWithEOFMark(req,&rdb,NULL,rsi);
  76. int rdbSaveToClonesSockets(int req, rdbSaveInfo *rsi) // ent 함수
    // clone.c syncCloneCommand() -> startBgsaveForClone()에서 사용.
    redisFork(CHILD_TYPE_RDB);
    rdbSaveRioWithEOFMark(req,&rdb,NULL,rsi);
  77. void saveCommand(client *c) rdbSave()
  78. void bgsaveCommand(client *c) rdbSaveBackground()
  79. rdbSaveInfo *rdbPopulateSaveInfo(rdbSaveInfo *rsi)
    // RDB 파일 내에 복제 정보를 저장하는 데 사용되는 rdbSaveInfo 구조체를 채웁니다.
    // 현재 이 구조체는 마스터 스트림에서 현재 선택된 DB만 명시적으로 포함하고 있습니다.
    // 그러나 rdbSave*() 계열 함수가 NULL rsi 구조체를 수신하는 경우 복제 ID/오프셋도 저장되지 않습니다.
    // 이 함수는 일반적으로 호출자에서 스택에 할당되는 'rsi'를 채우고, 인스턴스에 유효한
    // 마스터 클라이언트가 있으면 채워진 포인터를 반환합니다.
    // 그렇지 않으면 NULL이 반환되고 RDB 저장은 복제 관련 정보를 저장하지 않습니다.

<< RDB format RDB Functions Replication Intro >>

Email 답글이 올라오면 이메일로 알려드리겠습니다.

혹시 처음이세요?
레디스게이트에는 레디스에 대한 많은 정보가 있습니다.
레디스 소개, 명령어, SQL, 클라이언트, 서버, 센티널, 클러스터 등이 있습니다.
혹시 필요한 정보를 찾기 어려우시면 redisgate@gmail.com로 메일 주세요.
제가 찾아서 알려드리겠습니다.
 
close
IP를 기반으로 보여집니다.