当前位置: 首页 > news >正文

Redis rdb源码解析

   前置学习:Redis server启动源码-CSDN博客

1、触发时机

        1、执行save命令--->rdbSave函数

        2、执行bgsave命令--->rdbSaveBackground函数或者(serverCron->prepareForShutdown)

        3,主从复制-->startBgsaveForReplication函数,落盘方式(rdbSaveBackground函数),不落盘方式(rdbSaveToSlavesSockets函数)。

        4、flushall命令--->flushallCommand函数

        5、正常关闭服务(serverCron->prepareForShutdown函数)

2、执行过程

在主进程(父进程)中fork一个子进程来生成rdb文件(二进制),父子进程通过管道来处理数据传输通信。

 生成RDB文件过程

/* Save the DB on disk. Return REDIS_ERR on error, REDIS_OK on success ** 将数据库保存到磁盘上。** 保存成功返回 REDIS_OK ,出错/失败返回 REDIS_ERR 。*/
int rdbSave(char *filename) {dictIterator *di = NULL;dictEntry *de;char tmpfile[256];char magic[10];int j;long long now = mstime();FILE *fp;rio rdb;uint64_t cksum;// 创建临时文件snprintf(tmpfile,256,"temp-%d.rdb", (int) getpid());fp = fopen(tmpfile,"w");if (!fp) {redisLog(REDIS_WARNING, "Failed opening .rdb for saving: %s",strerror(errno));return REDIS_ERR;}// 初始化 I/OrioInitWithFile(&rdb,fp);// 设置校验和函数if (server.rdb_checksum)rdb.update_cksum = rioGenericUpdateChecksum;// 写入 RDB 版本号(魔数)snprintf(magic,sizeof(magic),"REDIS%04d",REDIS_RDB_VERSION);if (rdbWriteRaw(&rdb,magic,9) == -1) goto werr;// 遍历所有数据库for (j = 0; j < server.dbnum; j++) {// 指向数据库redisDb *db = server.db+j;// 指向数据库键空间dict *d = db->dict;// 跳过空数据库if (dictSize(d) == 0) continue;// 创建键空间迭代器di = dictGetSafeIterator(d);if (!di) {fclose(fp);return REDIS_ERR;}/* Write the SELECT DB opcode ** 写入 DB 选择器*/if (rdbSaveType(&rdb,REDIS_RDB_OPCODE_SELECTDB) == -1) goto werr;if (rdbSaveLen(&rdb,j) == -1) goto werr;/* Iterate this DB writing every entry ** 遍历数据库,并写入每个键值对的数据*/while((de = dictNext(di)) != NULL) {sds keystr = dictGetKey(de);robj key, *o = dictGetVal(de);long long expire;// 根据 keystr ,在栈中创建一个 key 对象initStaticStringObject(key,keystr);// 获取键的过期时间expire = getExpire(db,&key);// 保存键值对数据if (rdbSaveKeyValuePair(&rdb,&key,o,expire,now) == -1) goto werr;}dictReleaseIterator(di);}di = NULL; /* So that we don't release it again on error. *//* EOF opcode ** 写入 EOF 代码*/if (rdbSaveType(&rdb,REDIS_RDB_OPCODE_EOF) == -1) goto werr;/* CRC64 checksum. It will be zero if checksum computation is disabled, the* loading code skips the check in this case. ** CRC64 校验和。** 如果校验和功能已关闭,那么 rdb.cksum 将为 0 ,* 在这种情况下, RDB 载入时会跳过校验和检查。*/cksum = rdb.cksum;memrev64ifbe(&cksum);rioWrite(&rdb,&cksum,8);/* Make sure data will not remain on the OS's output buffers */// 冲洗缓存,确保数据已写入磁盘if (fflush(fp) == EOF) goto werr;if (fsync(fileno(fp)) == -1) goto werr;if (fclose(fp) == EOF) goto werr;/* Use RENAME to make sure the DB file is changed atomically only* if the generate DB file is ok. ** 使用 RENAME ,原子性地对临时文件进行改名,覆盖原来的 RDB 文件。*/if (rename(tmpfile,filename) == -1) {redisLog(REDIS_WARNING,"Error moving temp DB file on the final destination: %s", strerror(errno));unlink(tmpfile);return REDIS_ERR;}// 写入完成,打印日志redisLog(REDIS_NOTICE,"DB saved on disk");// 清零数据库脏状态server.dirty = 0;// 记录最后一次完成 SAVE 的时间server.lastsave = time(NULL);// 记录最后一次执行 SAVE 的状态server.lastbgsave_status = REDIS_OK;return REDIS_OK;werr:// 关闭文件fclose(fp);// 删除文件unlink(tmpfile);redisLog(REDIS_WARNING,"Write error saving DB on disk: %s", strerror(errno));if (di) dictReleaseIterator(di);return REDIS_ERR;
}
http://www.lryc.cn/news/255946.html

相关文章:

  • 深入理解CyclicBarrier
  • 微信小程序 - 格式化操作 moment.js格式化常用使用方法总结大全
  • 学习pytorch18 pytorch完整的模型训练流程
  • 电子学会C/C++编程等级考试2021年09月(五级)真题解析
  • Halcon联合winform显示以及处理
  • 【设计模式-4.3】行为型——责任链模式
  • 单片机语言--C51语言的数据类型以及存储类型以及一些基本运算
  • 《每天一个Linux命令》 -- (5)通过sshkey密钥登录服务器
  • kubernetes的服务发现(二)
  • 【矩阵论】Chapter 4—特征值和特征向量知识点总结复习
  • Linux 进程地址空间
  • websocket vue操作
  • 腾讯云CentOS8 jenkins war安装jenkins步骤文档
  • Linux: glibc: net/if.h vs linux/if.h
  • 使用Android Studio导入Android源码:基于全志H713 AOSP,方便解决编译、编码问题
  • python random详解
  • java-两个列表进行比较,判断那些是需要新增的、删除的、和更新的
  • 【WPF.NET开发】WPF中的对话框
  • NLP项目实战01之电影评论分类
  • 一款可无限扩展的软件定时器开源框架项目代码
  • GRE与顺丰圆通快递盒子
  • 12.Mysql 多表数据横向合并和纵向合并
  • 线性回归与逻辑回归:深入解析机器学习的基石模型
  • 电脑待机怎么设置?让你的电脑更加节能
  • 数据库对象介绍与实践:视图、函数、存储过程、触发器和物化视图
  • arm平台编译so文件回顾
  • 【数据结构】顺序表的定义和运算
  • idea使用maven的package打包时提示“找不到符号”或“找不到包”
  • MetricBeat监控MySQL
  • Child Mind Institute - Detect Sleep States(2023年第一次Kaggle拿到了银牌总结)