PostgreSQL standby会不会做检查点? 以及做检查点的用处

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
简介:

标签

PostgreSQL , checkpoint , standby , CreateRestartPoint


背景

当数据库异常关闭时,数据库关闭时来不及或根本没有机会创建一个一致性的检查点,所以需要从上一个一致性检查点开始恢复。

实际上是数据库启动时检查控制文件中的数据库状态,如果状态不是shutdown的,那么说明数据库是异常关闭的(当然我们说,除了recovery状态),总之就需要从检查点开始恢复。

src/include/catalog/pg_control.h

/*  
 * System status indicator.  Note this is stored in pg_control; if you change  
 * it, you must bump PG_CONTROL_VERSION  
 */  
typedef enum DBState  
{  
        DB_STARTUP = 0,  
        DB_SHUTDOWNED,  
        DB_SHUTDOWNED_IN_RECOVERY,  
        DB_SHUTDOWNING,  
        DB_IN_CRASH_RECOVERY,  
        DB_IN_ARCHIVE_RECOVERY,  
        DB_IN_PRODUCTION  
} DBState;  

那么问题来了,对于standby,一直是出于recovery状态的,即使停库也可能是这个状态(实际上是shutdown_in_recovery),所以STANDBY停库再起来,理论上来说又需要重上一个检查点开始恢复WAL,即使这个数据库已经恢复到了最新的WAL。

为了提高性能,缩短recovery时间,pg在standby上面也支持了checkpoint,叫做CreateRestartPoint。

CreateRestartPoint@src/backend/access/transam/xlog.c

/*  
 * Establish a restartpoint if possible.  
 *  
 * This is similar to CreateCheckPoint, but is used during WAL recovery  
 * to establish a point from which recovery can roll forward without  
 * replaying the entire recovery log.  
 *  
 * Returns true if a new restartpoint was established. We can only establish  
 * a restartpoint if we have replayed a safe checkpoint record since last  
 * restartpoint.  
 */  
bool  
CreateRestartPoint(int flags)  
{  

当standby关闭,重启时,从restartpoint开始APPLY WAL,而不是上游节点(主节点)在WAL日志中写的检查点开始。

停库时,备库写检查点

/*  
 * This must be called ONCE during postmaster or standalone-backend shutdown  
 */  
void  
ShutdownXLOG(int code, Datum arg)  
{  
        /* Don't be chatty in standalone mode */  
        ereport(IsPostmasterEnvironment ? LOG : NOTICE,  
                        (errmsg("shutting down")));  
  
        /*  
         * Signal walsenders to move to stopping state.  
         */  
        WalSndInitStopping();  
  
        /*  
         * Wait for WAL senders to be in stopping state.  This prevents commands  
         * from writing new WAL.  
         */  
        WalSndWaitStopping();  
  
        if (RecoveryInProgress())   // 备库写检查点  
                CreateRestartPoint(CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_IMMEDIATE);  
        else  
        {  
                /*  
                 * If archiving is enabled, rotate the last XLOG file so that all the  
                 * remaining records are archived (postmaster wakes up the archiver  
                 * process one more time at the end of shutdown). The checkpoint  
                 * record will go to the next XLOG file and won't be archived (yet).  
                 */  
                if (XLogArchivingActive() && XLogArchiveCommandSet())  
                        RequestXLogSwitch(false);  
  
                CreateCheckPoint(CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_IMMEDIATE);  
        }  
        ShutdownCLOG();  
        ShutdownCommitTs();  
        ShutdownSUBTRANS();  
        ShutdownMultiXact();  
}  
CreateRestartPoint  
  
...  
        LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);  
        if (ControlFile->state == DB_IN_ARCHIVE_RECOVERY &&  
                ControlFile->checkPointCopy.redo < lastCheckPoint.redo)  
        {  
                ControlFile->checkPoint = lastCheckPointRecPtr;  
                ControlFile->checkPointCopy = lastCheckPoint;  
                ControlFile->time = (pg_time_t) time(NULL);  
  
                /*  
                 * Ensure minRecoveryPoint is past the checkpoint record.  Normally,  
                 * this will have happened already while writing out dirty buffers,  
                 * but not necessarily - e.g. because no buffers were dirtied.  We do  
                 * this because a non-exclusive base backup uses minRecoveryPoint to  
                 * determine which WAL files must be included in the backup, and the  
                 * file (or files) containing the checkpoint record must be included,  
                 * at a minimum. Note that for an ordinary restart of recovery there's  
                 * no value in having the minimum recovery point any earlier than this  
                 * anyway, because redo will begin just after the checkpoint record.  
                 */  
                if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)  
                {  
                        ControlFile->minRecoveryPoint = lastCheckPointEndPtr;  
                        ControlFile->minRecoveryPointTLI = lastCheckPoint.ThisTimeLineID;  
  
                        /* update local copy */  
                        minRecoveryPoint = ControlFile->minRecoveryPoint;  
                        minRecoveryPointTLI = ControlFile->minRecoveryPointTLI;  
                }  
                if (flags & CHECKPOINT_IS_SHUTDOWN)  
                        ControlFile->state = DB_SHUTDOWNED_IN_RECOVERY;  // 备库正常关闭时,状态改写为DB_SHUTDOWNED_IN_RECOVERY  
                UpdateControlFile();  
        }  

小结

PostgreSQL备库也可以写检查点,目的是避免每次重启备库都需要从上一个检查点(由主库产生,在WAL中回放出来的)APPLY后面所有的WAL。

从而forward 备库停库后重启时WAL的位点。

参考

CreateRestartPoint@src/backend/access/transam/xlog.c

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
关系型数据库 数据库 PostgreSQL
PG技术大讲堂 - 第14讲:PostgreSQL 检查点
PG技术大讲堂 - 第14讲:PostgreSQL 检查点
315 1
|
SQL 关系型数据库 数据库
Postgresql lock锁等待检查
查看锁等待sql with t_wait as ( select a.mode,a.locktype,a.database,a.relation,a.page,a.tuple,a.
1879 0
|
关系型数据库 测试技术 PostgreSQL
PostgreSQL 10.1 手册_部分 III. 服务器管理_第 32 章 回归测试_32.5. 测试覆盖检查
32.5. 测试覆盖检查 PostgreSQL 源代码可以使用覆盖测试指令编译,因此可以检查哪些部分的代码被回归测试或任何其他测试套件所覆盖。当前使用 GCC 编译时支持该特性,并且需要gcov和lcov程序。
1357 0
|
SQL 关系型数据库 PostgreSQL
PostgreSQL 10.1 手册_部分 II. SQL 语言_第 13 章 并发控制_13.4. 应用级别的数据完整性检查
13.4. 应用级别的数据完整性检查 13.4.1. 用可序列化事务来强制一致性 13.4.2. 使用显式锁定强制一致性 对于使用读已提交事务的数据完整性强制业务规则非常困难,因为对每一个语句数据视图都在变化,并且如果一个写冲突发生即使一个单一语句也不能把它自己限制到该语句的快照。
1204 0
|
SQL 关系型数据库 PostgreSQL
PostgreSQL 10.1 手册_部分 II. SQL 语言_第 11 章 索引_11.12. 检查索引使用
11.12. 检查索引使用 尽管PostgreSQL中的索引并不需要维护或调优,但是检查真实的查询负载实际使用了哪些索引仍然非常重要。检查一个独立查询的索引使用情况可以使用EXPLAIN命令,它应用于这种目的的内容在第 14.1 节中有介绍。
1295 0
|
关系型数据库 数据库 数据安全/隐私保护
|
关系型数据库 PostgreSQL Python

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版