PostgreSQL备机checkpoint

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介: PostgreSQL备机checkpoint

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

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

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

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


调用流程:

StartupXLOG
  do{
    ...
    RmgrTable[record->xl_rmid].rm_redo(xlogreader);
    |--  RecoveryRestartPoint(&checkPoint);
      |--  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
      |--  ControlFile->checkPoint = lastCheckPointRecPtr;
    ...
    record = ReadRecord(xlogreader, InvalidXLogRecPtr, LOG, false);
    |--  record = XLogReadRecord(xlogreader, RecPtr, &errormsg);
    |--  ReadRecPtr = xlogreader->ReadRecPtr;
  } while (record != NULL);
ShutdownXLOG->CreateRestartPoint:
  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
  ControlFile->checkPoint = lastCheckPointRecPtr;

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();
  Shutdown
  MultiXact();
}


7、总结

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

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
关系型数据库 调度 数据库
|
关系型数据库 PostgreSQL
PostgreSQL的Checkpoint 发生的时机
官方说明来自: http://www.postgresql.org/docs/9.2/static/runtime-config-wal.html#RUNTIME-CONFIG-WAL-CHECKPOINTS 何时发生Checkpoint呢?   下列条件任意之一会导致Checkpoint发生:  shared_buffers中,产生了 checkpoint_segments*16MB 以上的数据。
1162 0
|
Web App开发 关系型数据库 测试技术
|
关系型数据库 PostgreSQL
|
SQL Cloud Native 关系型数据库
ADBPG(AnalyticDB for PostgreSQL)是阿里云提供的一种云原生的大数据分析型数据库
ADBPG(AnalyticDB for PostgreSQL)是阿里云提供的一种云原生的大数据分析型数据库
1234 1
|
数据可视化 关系型数据库 MySQL
将 PostgreSQL 迁移到 MySQL 数据库
将 PostgreSQL 迁移到 MySQL 数据库
1701 2
|
SQL 关系型数据库 Linux
【PostgreSQL】基于CentOS系统安装PostgreSQL数据库
【PostgreSQL】基于CentOS系统安装PostgreSQL数据库
890 0
|
SQL 存储 自然语言处理
玩转阿里云RDS PostgreSQL数据库通过pg_jieba插件进行分词
在当今社交媒体的时代,人们通过各种平台分享自己的生活、观点和情感。然而,对于平台管理员和品牌经营者来说,了解用户的情感和意见变得至关重要。为了帮助他们更好地了解用户的情感倾向,我们可以使用PostgreSQL中的pg_jieba插件对这些发帖进行分词和情感分析,来构建一个社交媒体情感分析系统,系统将根据用户的发帖内容,自动判断其情感倾向是积极、消极还是中性,并将结果存储在数据库中。
玩转阿里云RDS PostgreSQL数据库通过pg_jieba插件进行分词
|
关系型数据库 测试技术 分布式数据库
PolarDB | PostgreSQL 高并发队列处理业务的数据库性能优化实践
在电商业务中可能涉及这样的场景, 由于有上下游关系的存在, 1、用户下单后, 上下游厂商会在自己系统中生成一笔订单记录并反馈给对方, 2、在收到反馈订单后, 本地会先缓存反馈的订单记录队列, 3、然后后台再从缓存取出订单并进行处理. 如果是高并发的处理, 因为大家都按一个顺序获取, 容易产生热点, 可能遇到取出队列遇到锁冲突瓶颈、IO扫描浪费、CPU计算浪费的瓶颈. 以及在清除已处理订单后, 索引版本未及时清理导致的回表版本判断带来的IO浪费和CPU运算浪费瓶颈等. 本文将给出“队列处理业务的数据库性能优化”优化方法和demo演示. 性能提升10到20倍.
825 4