Redis AOF源码解析
2023-12-13 04:17:30
本文取3.0版本分析(各个版本差异很大,4.0以上才有aof和rdb混合模式)
触发时机
? ? ? ? 1、bgrewriteaofCommand函数触发,即在Redis server服务上运行bgrewriteaof命令。
????????1-1、当前已经有 AOF 重写的子进程正在执行,重复执行bgrewriteaof命令,是不会执行bgrewriteaof命令。
? ? ? ? 1-2、执行rewriteAppendOnlyFileBackground函数。
? ? ? ? 2、rewriteAppendOnlyFileBackground函数触发:
????????2-1、当前没有aof子进程和rdb子进程,但是存在着等待执行任务调度的aof命令,只有到了执行任务调度aof命令的情况下,才会触发aof重写。
? ? ? ? 2-2、当前没有aof子进程和rdb子进程,但是设置了aof阈值的情况,如果当前aof文件超过了预留的阈值,则会触发aof重写。
? ? ? ? 3、开启Redis server aof配置功能
????????3-1、当用户在运行时使用config命令,从 appendonly no 切换到 appendonly yes 时执行。
? ? ? ? 3-2、执行rewriteAppendOnlyFileBackground函数。
? ? ? ? 4、主从复制函数readSyncBulkPayload,startAppendOnly函数
? ? ? ? 4-1、主从复制开启aof配置功能下,如果有rdb子进程,那么等待rdb子进程处理完后,再通过任务调度执行aof持久化,如果有aof进程,强制kill掉正在执行的aof子进程,重新生成aof持久化文件。
生成aof文件过程
挺复杂的,后面继续研究
/* This is how rewriting of the append only file in background works:
*
* 以下是后台重写 AOF 文件(BGREWRITEAOF)的工作步骤:
*
* 1) The user calls BGREWRITEAOF
* 用户调用 BGREWRITEAOF
*
* 2) Redis calls this function, that forks():
* Redis 调用这个函数,它执行 fork() :
*
* 2a) the child rewrite the append only file in a temp file.
* 子进程在临时文件中对 AOF 文件进行重写
*
* 2b) the parent accumulates differences in server.aof_rewrite_buf.
* 父进程将新输入的写命令追加到 server.aof_rewrite_buf 中
*
* 3) When the child finished '2a' exists.
* 当步骤 2a 执行完之后,子进程结束
*
* 4) The parent will trap the exit code, if it's OK, will append the
* data accumulated into server.aof_rewrite_buf into the temp file, and
* finally will rename(2) the temp file in the actual file name.
* The the new file is reopened as the new append only file. Profit!
*
* 父进程会捕捉子进程的退出信号,
* 如果子进程的退出状态是 OK 的话,
* 那么父进程将新输入命令的缓存追加到临时文件,
* 然后使用 rename(2) 对临时文件改名,用它代替旧的 AOF 文件,
* 至此,后台 AOF 重写完成。
*/
int rewriteAppendOnlyFileBackground(void) {
pid_t childpid;
long long start;
// 已经有进程在进行 AOF 重写了
if (server.aof_child_pid != -1) return REDIS_ERR;
// 记录 fork 开始前的时间,计算 fork 耗时用
start = ustime();
if ((childpid = fork()) == 0) {
char tmpfile[256];
/* Child */
// 关闭网络连接 fd
closeListeningSockets(0);
// 为进程设置名字,方便记认
redisSetProcTitle("redis-aof-rewrite");
// 创建临时文件,并进行 AOF 重写
snprintf(tmpfile,256,"temp-rewriteaof-bg-%d.aof", (int) getpid());
if (rewriteAppendOnlyFile(tmpfile) == REDIS_OK) {
size_t private_dirty = zmalloc_get_private_dirty();
if (private_dirty) {
redisLog(REDIS_NOTICE,
"AOF rewrite: %zu MB of memory used by copy-on-write",
private_dirty/(1024*1024));
}
// 发送重写成功信号
exitFromChild(0);
} else {
// 发送重写失败信号
exitFromChild(1);
}
} else {
/* Parent */
// 记录执行 fork 所消耗的时间
server.stat_fork_time = ustime()-start;
if (childpid == -1) {
redisLog(REDIS_WARNING,
"Can't rewrite append only file in background: fork: %s",
strerror(errno));
return REDIS_ERR;
}
redisLog(REDIS_NOTICE,
"Background append only file rewriting started by pid %d",childpid);
// 记录 AOF 重写的信息
server.aof_rewrite_scheduled = 0;
server.aof_rewrite_time_start = time(NULL);
server.aof_child_pid = childpid;
// 关闭字典自动 rehash
updateDictResizePolicy();
/* We set appendseldb to -1 in order to force the next call to the
* feedAppendOnlyFile() to issue a SELECT command, so the differences
* accumulated by the parent into server.aof_rewrite_buf will start
* with a SELECT statement and it will be safe to merge.
*
* 将 aof_selected_db 设为 -1 ,
* 强制让 feedAppendOnlyFile() 下次执行时引发一个 SELECT 命令,
* 从而确保之后新添加的命令会设置到正确的数据库中
*/
server.aof_selected_db = -1;
replicationScriptCacheFlush();
return REDIS_OK;
}
return REDIS_OK; /* unreached */
}
文章来源:https://blog.csdn.net/lyyCSDNBLOG/article/details/134812128
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!