千家信息网

PostgreSQL备机checkpoint

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,数据库异常关闭时,数据库关闭时来不及或者没机会做checkpoint,则需要从上一个一致性检查的开始恢复。PostgreSQL备机checkpoint是不能产生checkpoint WAL的,因为如果
千家信息网最后更新 2026年10月31日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、回放函数

voidxlog_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 voidRecoveryRestartPoint(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

boolCreateRestartPoint(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

voidShutdownXLOG(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开始重复恢复。

位置 问题 检查 主机 位点 数据 数据库 检查点 长时 支持 一致 混乱 这样的话 一致性 再次 函数 命令 手动 文件 日志 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 百单网互联网科技有限公司 互联网佳科技有限公司 苏州找大状互联网科技有限公司 互联网科技公司税收优惠 金融科技还是互联网 互联网中国科技 嘟嘟瓜互联网科技 上海喔噻互联网科技 丰台科技园 互联网 开启互联网科技时代小说 佳云科技和互联网广告 速维有品互联网信息科技(苏州)有限公司 996高科技互联网公司 畅思互联网科技 互联网科技的全部知识 锡山区互联网智能科技产品供应 广东工业互联网大赛深圳学泰科技 皮皮虾互联网科技有限公司 版纳互联网科技选哪家 互联网科技手抄报图片 互联网新科技 河南云网互联网络科技有限公司 喔噻互联网科技 西安互联网科技公司 有木互联网科技 黑科技闪耀互联网之光 健康食品互联网创新科技园项目 广东猫王互联网科技有限公司电话 银川新华互联网科技学校招聘 广州全民伙伴互联网科技有限公司
0