前面讲了如何从外部来观察checkpoint,但是,实际上checkpoint内部是如何运行的呢?这里就有必要讲讲来龙去脉了。
目前,PG中有一个单独的checkpoint的进程。一般来说,在正常的启动过程中,这个进程是postmaster进程生成的,实际上是一个信号的处理函数heaper()生成的,具体的调用关系如下:
main()->postmastermain()->reaper()->StartCheckpointer()->StartChildProcess()->AuxiliaryProcessMain()->CheckpointerMain()
postmaster中触发heaper()的是一个子进程退出的信号,这个子进程的名字是startup process,具体这个进程干啥了大家可以去看看代码。
CheckpointerMain()就是checkpoint进程的主体了。CheckpointerMain()主要分两部分:完成一些必要的初始化工作,之后就进入一个不断做checkpoint的死循环中。
初始化包括三部分的内容:一,在CheckpointerShmem这个所有进程都可以访问的变量中设置checkpoint进程的PID,这个PID回头是其他进程通过kill函数来通知做checkpoint的必要参数;设置信号处理函数,其中一个信号处理函数是负责接收SIGINT信号来表示需要做checkpoint了;三,设置long jump的异常堆栈,使得出现ERROR时能跳转回来进行一场处理(也就是用C来简单实现了C++中异常捕获和处理)。
在这个进程的死循环中,这个死循环的伪码如下:
for(;;){ AbsorbFsyncRequests() // 整理fsync的请求 if (got_SIGHUP) { //用户执行了realod命令,重新加载配置问题 ProcessConfigFile(PGC_SIGHUP); UpdateSharedMemoryConfig(); } if (checkpoint_requested) { //接到信号,需要执行检查点 checkpoint_requested = false; BgWriterStats.m_requested_checkpoints++; do_checkpoint = true; } if (shutdown_requested) { // 进程接到数据库退出的信号,退出 ShutdownXLOG(0, 0); proc_exit(0); } if (elapsed_secs >= CheckPointTimeout) { // 如果距离上次检查点发生的时间间隔大于checkpoint_timeout,则需要执行周期的checkpoint if (!do_checkpoint) BgWriterStats.m_timed_checkpoints++; do_checkpoint = true; flags |= CHECKPOINT_CAUSE_TIME; } if(do_checkpoint) { CreateCheckPoint(flags);//做检查点 smgrcloseall() ;// 关闭所有的segments } CheckArchiveTimeout() //检查归档的timeout,切换WAL文件 pgstat_send_bgwriter();//向pg_stat进程发生本次checkpoint的统计信息 elapsed_secs = now - last_checkpoint_time; if (elapsed_secs >= CheckPointTimeout)//如果做检查点花费时间大于周期 continue; elapsed_secs = now - last_xlog_switch_time; if (elapsed_secs >= XLogArchiveTimeout) // 如果大于归档的timeout continue; WaitLatch()//睡眠,直至超时或是信号发生 }
可以看到,能够影响发生做checkpoint基本上就两个原因:被其他进程要求执行(上一篇博客提到过),在一个就是超时了。
而在这个循环中,有三个比较重要的函数:AbsorbFsyncRequests(),pgstat_send_bgwriter();和CreateCheckPoint(flags)。
AbsorbFsyncRequests()主要将CheckpointerShmem这个全局变量中fsync请求都拷贝过来,这些请求主要存在于CheckpointerShmem的requests字段中,这个字段是一个变长数组,长度就是block的块数。当bgwriter或是backend将一个block写回(write)物理文件后,会将对该文件的sync请求放入CheckpointerShmem的requests中。拷贝fsync请求之后,然后根据将每个请求塞入哈希表pendingOpsTable中,key就是由物理文件的rnode,将segno加入每个fork对应的位图中。简单来说,就是如果同一个segment上多个block需要fsync那么这些fsync会合并成对一个segment的fsync请求。所以这样就大大消除了fysnc的请求。这样的好处是,不到做检查点,pg是不会去主动fsync被写脏的segment的,只有到了检查点,才会主动去fsync。而在未发生checkpoint的这段时间内,操作系统会根据参数在后台fsync文件,这个需要配置dirty_ratio和dirty_background_ratio来控制OS后台fsync文件。
而并不是只有checkpoint进程才会将写回的segment调用fsync的,backend进程也会调用,只不过是在系统压力很大的情况下才会发生:如果CheckpointerShmem的requests这个数组被塞满了,并且在将同一个segment的fysnc请求合并成一个之后,发现CheckpointerShmem的requests这个数组依然还是塞满了,那就说明系统需要fsync的segment的数量和share buffer中block的数量是一样的,这意味着什么呢?假设一个服务器给PG的share buffer是20G,那么出现这种情形,需要fsync回磁盘的数据超过 (20G/8K) *32M = 80T,如果真的发生了,说明系统的压力已经超出了硬件的承受能力了。
当然 bgwriter也存在调用fsync数据块的可能,只不过这种可能性比前面说的这种可能性还要低好多,所以可以忽略。
而pgstat_send_bgwriter()函数则是将每个checkpoint的统计信息发给pg_stat进程,统计信息存在如下的一个结构中:
typedef struct PgStat_MsgBgWriter { PgStat_MsgHdr m_hdr; PgStat_Counter m_timed_checkpoints; //定期检查点次数 PgStat_Counter m_requested_checkpoints; //请求执行的检查点次数 PgStat_Counter m_buf_written_checkpoints; //检查点刷了多少脏block PgStat_Counter m_buf_written_clean; //bgwriter刷了多少脏block PgStat_Counter m_maxwritten_clean; //bgwriter刷脏块超过bgwriter_lru_maxpages的次数 PgStat_Counter m_buf_written_backend; //backend刷回的脏块 PgStat_Counter m_buf_fsync_backend; //backend fsync的次数 PgStat_Counter m_buf_alloc; // 重新分配的块数 PgStat_Counter m_checkpoint_write_time;//检查点写文件花的时间 PgStat_Counter m_checkpoint_sync_time; //检查点fsync文件花的时间 } PgStat_MsgBgWriter;
这个数据结构基本上就对应我们前面说的pg_stat_bgwriter这个系统视图。checkpoint进程每次发生的统计信息只包括于本进程以及backend进程相关的信息:m_timed_checkpoints,m_requested_checkpoints,m_buf_written_checkpoints,m_buf_written_backend,m_buf_fsync_backend m_checkpoint_write_time,m_checkpoint_sync_time。
而m_buf_fsync_backend这个字段的值大于0,就说明前面说backend调用fsync的极端情况出现了,您该跟boss打报告研究下对策了。
对于CreateCheckPoint(flags)这个函数,无疑是checkpoint进程的核心,下一篇将为您讲述。
相关推荐
Linux 中检查点 (Checkpoint) 的核心支持 ——ckpt 文件系统的设计 Linux 操作系统中,检查点 (Checkpoint) 机制是提高系统可靠性、减少运算损失的重要技术。检查点机制的核心支持是实现高效的进程迁移和负载平衡的...
对于oracle 检查点的分析,有助于了解oracle checkpoint的基础理论。
在 QTP 中,可以通过 insert→checkpoint→standard checkpoint 等方法添加检查点。在添加检查点时,QTP 会基于检查点内的信息分配名称。即使您随后修改了其所基于的信息,检查点名称也不会改变。 在关键字视图中...
ORACLE中的checkpoint
检查点属性窗中有两个选项:Checkpoint timeout 和 Insert statement。 * Checkpoint timeout:指定检查点运行的最长时限,QTP 在检查点通过(在本时间范围内)或超时后,才进行下一步操作。 * Insert statement:...
CheckPoint防火墙Nat配置讲解
Checkpoint 防火墙命令行维护手册是关于Checkpoint 防火墙的命令行维护指南,旨在帮助管理员快速掌握Checkpoint 防火墙的基本配置、系统状态查看、路由管理等知识点。 基本配置命令 Checkpoint 防火墙命令行维护...
知识点二:Checkpoint 防火墙的管理服务器配置 * 设置一次性密码用于与管理服务器通信 * 添加许可证 * 添加系统管理员帐户 * 配置管理服务器的其他设置 知识点三:Checkpoint 防火墙的策略编辑器 * 策略编辑器的...
CHECKPOINT防火墙 中文版安装配置指南
QTP入门-检查点输出值参数化 录像 检查点 输出值 参数化 同步点 1.检查点 目的: 检查点比较指定属性的当前值与期望值,以判断当前的程序(或站点)功能是否正常。 在密码正确的情况下预期结果是进入主界面,检查...
tensorflow将训练好的网络模型保存到了checkpoint中,如果要利用训练好的网络模型去fintune另一个网络,需要为前置层的参数赋值,因此把checkpoint中的参数保存到npy文件中方便赋值。
CheckPoint\Checkpoint防火墙命令行维护手册
checkpoint-DOM:检查点DOM
checkpoint ccse
CheckPoint 4800 CPU 资源分配 CheckPoint 4800 CPU 资源分配 CheckPoint 4800 CPU 资源分配
checkpoint UTM实施指南
checkpoint的目的是解决R中程序包可重复性的问题。具体地说, checkpoint解决了当您没有正确版本的R程序包时发生的问题。 由于软件包一直都在CRAN上进行更新,因此很难重新创建一个环境,使您的所有软件包都与某个较...
这种在训练中保存模型,习惯上称之为保存检查点。 2.添加保存点 通过添加检查点,可以生成载入检查点文件,并能够指定生成检查文件的个数,例如使用saver的另一个参数——max_to_keep=1,表明最多只保存一个检查点...
Checkpoint 简单配置手册.pdf
oracle的checkpoint工作原理