`

说说pg中的检查点(checkpoint)之二

 
阅读更多

       前面讲了如何从外部来观察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文件系统的设计.pdf

    Linux 中检查点 (Checkpoint) 的核心支持 ——ckpt 文件系统的设计 Linux 操作系统中,检查点 (Checkpoint) 机制是提高系统可靠性、减少运算损失的重要技术。检查点机制的核心支持是实现高效的进程迁移和负载平衡的...

    Oracle checkpoint 检查点详解

    Checkpoint 分为完全检查点(Normal checkpoint)和增量检查点(Incremental checkpoint)两种。完全检查点是指将所有脏块写入到硬盘,增量检查点是指将部分脏块写入到硬盘。 在了解 Checkpoint 工作原理之前,需要...

    QTP检查点使用与分析

    在 QTP 中,可以通过 insert→checkpoint→standard checkpoint 等方法添加检查点。在添加检查点时,QTP 会基于检查点内的信息分配名称。即使您随后修改了其所基于的信息,检查点名称也不会改变。 在关键字视图中...

    关于checkpoint比较经典的解释

    3. **更新控制文件**:完成第二步后,CKPT进程会在控制文件中记录检查点完成的信息。 只有这三个步骤全部完成后,检查点才算完成,确保了日志文件、数据文件和控制文件达到新的同步点。 ##### 1.3 触发检查点的...

    ORACLE中的checkpoint

    在Oracle数据库管理中,Checkpoint是一种关键机制,用于确保数据的一致性和安全性。Checkpoint的主要功能是在数据库发生故障时,能够快速恢复到一个一致的状态,而无需进行全量的重做日志回放。以下是对Checkpoint...

    LoadRunner检查点设置

    在LoadRunner中,检查点(Checkpoint)是一种重要的验证机制,用于验证在虚拟用户执行过程中,应用程序是否按照预期的方式响应。检查点可以帮助测试人员确认特定的操作是否成功完成,或者页面是否正确加载。 本文...

    oracle checkpoint工作原理

    2. **增量检查点(Incremental Checkpoint)**:这是一种优化策略,仅写入自上次完全检查点以来修改过的脏数据块,从而减少了I/O操作,提高了系统性能。 #### 四、Checkpoint 相关概念 在深入了解Checkpoint的工作...

    检查点技术介绍

    - **触发执行检查点**:当执行 `CHECKPOINT` 语句或进行某些数据库操作时,例如使用 `ALTER DATABASE` 命令,或者当 SQL Server 非正常停止运行时,都会触发检查点。 - **自动执行检查点**:当数据库的日志记录达到...

    Oracle checkpoint 原理

    Oracle检查点(Checkpoint)是数据库管理系统中的一个关键概念,它涉及到数据一致性、恢复机制和性能优化。检查点的主要目的是确保在实例失败后,数据库能够快速地恢复到一致性的状态。 检查点分为增量检查点...

    2-UFT设置检查点的操作

    3. **位图检查点(Bitmap Checkpoint)**:用于检查屏幕上的图像或控件的外观是否符合预期,例如位置、大小、颜色等。 - 在UFT中选择【Bitmap Checkpoint】。 - 点击你想要检查的对象。 - 设置检查点条件,例如比较...

    [QTP 入門] 05 建立 Checkpoint - 檢查文字

    检查点是QTP自动化测试中的基础组成部分,除了文本检查点,还有图像、数据库、对象等多种类型的检查点。熟练掌握检查点的创建和使用,对于编写高效、可靠的自动化测试脚本至关重要。同时,合理地利用检查点可以帮助...

    解释checkpoint数据库原理的资料

    物理Checkpoint是指将数据库缓冲区缓存(database buffer cache)中的脏页(dirty blocks)写入到数据文件中,并更新控制文件和重做日志文件,使其包含最新的检查点信息。这个过程通常由后台进程CKPT来触发,也可以...

    Python库 | tensorflow-checkpoint-reader-0.1.0.tar.gz

    `tensorflow-checkpoint-reader`是一个Python库,专为处理TensorFlow框架中的检查点(checkpoint)文件而设计。这些检查点文件存储了模型训练过程中的权重和参数,以便在后续的训练或者部署中恢复模型的状态。下面...

    [QTP 入門]04 建立 Checkpoint - 檢查網頁

    本教程主要关注如何在测试过程中创建检查点(Checkpoint),以确保网页内容或状态符合预期。在自动化测试中,检查点是一种重要的验证手段,用于比对实际测试结果与预期结果是否一致,从而确保应用程序的正确运行。 ...

    oracle_检查点概念及说明解读.pdf

    Oracle 检查点(Checkpoint)是数据库管理系统中一种关键的优化策略,它涉及到数据库的稳定性和恢复机制。检查点的主要目标是确保在系统崩溃或意外停机后,数据库能够快速恢复到一致的状态,减少恢复过程中的数据...

    检查点SCN深入研究

    检查点SCN(System Change Number)是Oracle数据库中用于数据一致性与恢复的关键概念。SCN是一个全局递增的序列号,记录了数据库发生的每一次变化,确保在实例故障或崩溃后,能够通过重做日志恢复到一致性的状态。 ...

Global site tag (gtag.js) - Google Analytics