PostgreSQL备机checkpoint

数据库异常关闭时,数据库关闭时来不及或者没机会做checkpoint,则需要从上一个一致性检查的开始恢复。

? ? PostgreSQL备机checkpoint是不能产生checkpoint WAL的,因为如果写这样类型的checkpoint的话,就会将接收的WAL打乱,那么日志将混乱,回放会出问题。

? ? 那么问题来了,备机支持checkpoint吗?他的checkpoint怎么做的?

? ? PostgreSQL为了缩短恢复时间,备机上也支持checkpoint,即CreateRestartPoint。但是其pg_control文件的checkpoint记录的位点是从主机传过来WAL里面的checkpoint记录位置。

1、备机回放

StartupXLOG
    do{
        ...
        RmgrTable[record->xl_rmid].rm_redo(xlogreader);//回放
        ...
        record = ReadRecord(xlogreader, InvalidXLogRecPtr, LOG, false);//读取一个xlog
    } while (record != NULL);

2、回放函数

void
xlog_redo(XLogReaderState *record)
{
    ...
    else if (info == XLOG_CHECKPOINT_SHUTDOWN){
        ...
        memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
        ...
        RecoveryRestartPoint(&checkPoint);
    }else if (info == XLOG_CHECKPOINT_ONLINE){
        ...
        memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
        ...
        RecoveryRestartPoint(&checkPoint);
    }
    ...
}

3、RecoveryRestartPoint

static void
RecoveryRestartPoint(const CheckPoint *checkPoint)
{
    ...
    SpinLockAcquire(&XLogCtl->info_lck);
    XLogCtl->lastCheckPointRecPtr = ReadRecPtr;//ReadRecPtr为读取checkpoint记录后的位置
    XLogCtl->lastCheckPointEndPtr = EndRecPtr;
    XLogCtl->lastCheckPoint = *checkPoint;
    SpinLockRelease(&XLogCtl->info_lck);
}

4、ReadRecPtr赋值

ReadRecord
    for (;;)
    {
        char       *errormsg;

        record = XLogReadRecord(xlogreader, RecPtr, &errormsg);
        ReadRecPtr = xlogreader->ReadRecPtr;
        EndRecPtr = xlogreader->EndRecPtr;
        ...
    }

5、备机createcheckpoint

bool
CreateRestartPoint(int flags)
{

    LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);

    /* Get a local copy of the last safe checkpoint record. */
    SpinLockAcquire(&XLogCtl->info_lck);
    lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;//checkpoint的位置来自XLogCtl->lastCheckPointRecPtr
    lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
    lastCheckPoint = XLogCtl->lastCheckPoint;
    SpinLockRelease(&XLogCtl->info_lck);

    ...

    if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) || lastCheckPoint.redo <= ControlFile->checkPointCopy.redo){
        //回放了最后一个checkpoint记录后,备机再次手动执行checkpoint命令
        UpdateMinRecoveryPoint(InvalidXLogRecPtr, true);
        if (flags & CHECKPOINT_IS_SHUTDOWN){
            LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
            ControlFile->state = DB_SHUTDOWNED_IN_RECOVERY;
            ControlFile->time = (pg_time_t) time(NULL);
            UpdateControlFile();
            LWLockRelease(ControlFileLock);
        }
        LWLockRelease(CheckpointLock);
        return false;
    }
    ...
    LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
    if (ControlFile->state == DB_IN_ARCHIVE_RECOVERY && ControlFile->checkPointCopy.redo < lastCheckPoint.redo){
        ControlFile->prevCheckPoint = ControlFile->checkPoint;
        ControlFile->checkPoint = lastCheckPointRecPtr;//checkpoint的位置
        ControlFile->checkPointCopy = lastCheckPoint;
        ControlFile->time = (pg_time_t) time(NULL);
        ...
        if (flags & CHECKPOINT_IS_SHUTDOWN)
            ControlFile->state = DB_SHUTDOWNED_IN_RECOVERY;
        UpdateControlFile();
    }
    ...

    return true;
}

6、备机shutdown

void
ShutdownXLOG(int code, Datum arg)
{
    /*
     * 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())//备机写checkpoint
        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();
}

7、总结

PostgreSQL备库也可以写检查点,目的是避免每次重启备库都需要从上一个检查点(由主库产生,在WAL中回放出来的)APPLY后面所有的WAL。但是他记录的checkpoint位点是从主库传过来的。这样的话就有问题了,如果主机很长时间都没有做checkpoint了,备机即使正常关闭,重启时,也会从上一个checkpoint开始恢复,这样也会恢复很长时间;并且多次重启也需要从上一次checkpoint开始重复恢复。

原文地址:https://blog.51cto.com/yanzongshuai/2381680

时间: 2024-10-23 14:41:45

PostgreSQL备机checkpoint的相关文章

刚查了,Z3795不支持EPT,即WP8开发必须的SLAT,看来只能作为简单的WINDOWS备机了

刚查了,Z3795不支持EPT,即WP8开发必须的SLAT,看来只能作为简单的WINDOWS备机了,也就只能做做文档编辑,脚本编写之类的. 数据来源 http://ark.intel.com/zh-CN/Products/VirtualizationTechnology 查询CPU是否支持SLAT SLAT(Second Level Address Translation),也叫“二级地址转换技术”.在 Intel和AMD处理器中均有所支持,但名称有所不同,Intel叫做EPT(Extended

在oracle11g中配置多个DataGuard物理备机

主机配置 alter system set DB_UNIQUE_NAME='starboss' scope=spfile; alter system set LOG_ARCHIVE_CONFIG='DG_CONFIG=(starboss,starbossstby01,starbossstby02)'; alter system set LOG_ARCHIVE_DEST_1='LOCATION=/opt/app/oracle/archivelog/ VALID_FOR=(ALL_LOGFILES,

Centos7系统keepalived备机启动后自动从backup切换成master

操作系统环境:CentOS Linux release 7.0.1406(Core) 64位 主机ip:192.168.1.191,备机ip:192.168.1.150,虚ip:192.168.2.10. /etc/keepalived/keepalived.conf主备配置正确的情况下 搭完后备用机一**启动keepalived就自动从BACKUP切换到MASTER(另一机并未关keepalived服务)**,正常主机没有down之前备机应该是backup状态才对啊,下面是我的日志显示: 个人

Rose资源组主备机来回切换

Q:Rose资源组主备机来回切换,反复回切:A:经过分析,发现配置的oracle监听资源,存在单机运行不稳定问题,启动后,自动停止: 删掉现有监听后,重新创建监听,问题解决. 原文地址:http://blog.51cto.com/xinghaiyuan/2070229

Jira+Confluence备机环境部署(迁移环境、双机数据同步)记录

之前在公司机房的一台服务器上部署了一套Jira+Confluence环境,由于很多资料和运维信息都在上面做的分享记录,而该环境部署在单机,所以安全起见,考虑再部署一套备机环境,实现双机实时同步环境.下面是操作记录: 原文地址:https://www.cnblogs.com/kevingrace/p/9403353.html

shell脚本应用《十》查看多个系统CPU,指定的进程CPU,主备机,内存使用情况

需求:查看多台机器看多个系统CPU,指定的进程CPU,主备机状态,内存使用情况:并在一台机器上显示: 第一:先设置ssh免密码登录 ssh-keygen -t rsa P'' -f ~/.ssh/id_rsa 不提示直接生成秘钥ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected] 第二:查询脚本,分别拷贝到各个机器上 scp /usr/local/src/cpu_men.sh [email protected]: /usr/local/src/脚本

Postgresql standby(备机只读)环境搭建

下载PostgreSQL源码包,放在任意目录 设置/etc/sysctl.conf,增加以下内容 kernel.shmmni= 4096 kernel.sem =501000 6412800000 501000 12800 fs.file-max =767246 net.ipv4.ip_local_port_range= 1024 65000 net.core.rmem_default= 1048576 net.core.rmem_max= 1048576 net.core.wmem_defau

备机大地院系项目dataguard archived_log及standby_log

主库archivelog及standbylog 仅仅是测试4天的数据,项目并未正式上线/data/dddb/DBSoftware/app/oracle/product/11.2.0/dbhome_1/dbs/archivelog/data/dddb/DBSoftware/app/oracle/standbylog 备库archivedlog及standbylog 主库spfile 主库"listener.ora" 主库tnsnames.ora 备库spfile 备库tnsnames.o

Postgresql数据库部署之:Postgresql本机启动和Postgresql注册成windows 服务

1.初始化并创建数据库(一次即可)  initdb -D C:\Soft\PostgreSQL\10\data -E UTF-8 --locale=chs -U postgres -W  You can now start the database server using(启动数据库命令): pg_ctl -D ^"C^:^\Soft^\PostgreSQL^\10^\data^" -l logfile start --家里电脑pg 启动路径 C:/Users/computer/sc