初步学习pg_control文件之十一
接前文 初步学习pg_control文件之十,再看这个
XLogRecPtr prevCheckPoint; /* previous check point record ptr */
发生了checkpoint的时候,肯定要处理的:
/*
* Perform a checkpoint --- either during shutdown, or on-the-fly
*
* flags is a bitwise OR of the following:
* CHECKPOINT_IS_SHUTDOWN: checkpoint is for database shutdown.
* CHECKPOINT_END_OF_RECOVERY: checkpoint is for end of WAL recovery.
* CHECKPOINT_IMMEDIATE: finish the checkpoint ASAP,
* ignoring checkpoint_completion_target parameter.
* CHECKPOINT_FORCE: force a checkpoint even if no XLOG activity has occured
* since the last one (implied by CHECKPOINT_IS_SHUTDOWN or
* CHECKPOINT_END_OF_RECOVERY).
*
* Note: flags contains other bits, of interest here only for logging purposes.
* In particular note that this routine is synchronous and does not pay
* attention to CHECKPOINT_WAIT.
*/
void
CreateCheckPoint(int flags)
{
… /*
* Update the control file.
*/
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
if (shutdown)
ControlFile->state = DB_SHUTDOWNED;
ControlFile->prevCheckPoint = ControlFile->checkPoint;
ControlFile->checkPoint = ProcLastRecPtr;
ControlFile->checkPointCopy = checkPoint;
ControlFile->time = (pg_time_t) time(NULL);
/* crash recovery should always recover to the end of WAL */
MemSet(&ControlFile->minRecoveryPoint, , sizeof(XLogRecPtr));
UpdateControlFile();
LWLockRelease(ControlFileLock);
…
}
可是为何要保留这个东西呢,看下面这段代码就知道了:
/*
* This must be called ONCE during postmaster or standalone-backend startup
*/
void
StartupXLOG(void)
{
…
if (read_backup_label(&checkPointLoc, &backupEndRequired))
{
…
}
else
{
/*
* Get the last valid checkpoint record. If the latest one according
* to pg_control is broken, try the next-to-last one.
*/
checkPointLoc = ControlFile->checkPoint;
RedoStartLSN = ControlFile->checkPointCopy.redo;
record = ReadCheckpointRecord(checkPointLoc, );
if (record != NULL)
{
ereport(DEBUG1,
(errmsg("checkpoint record is at %X/%X",
checkPointLoc.xlogid, checkPointLoc.xrecoff)));
}
else if (StandbyMode)
{
/*
* The last valid checkpoint record required for a streaming
* recovery exists in neither standby nor the primary.
*/
ereport(PANIC,
(errmsg("could not locate a valid checkpoint record")));
}
else
{
checkPointLoc = ControlFile->prevCheckPoint;
record = ReadCheckpointRecord(checkPointLoc, );
if (record != NULL)
{
ereport(LOG,
(errmsg("using previous checkpoint record at %X/%X",
checkPointLoc.xlogid, checkPointLoc.xrecoff)));
InRecovery = true; /* force recovery even if SHUTDOWNED */
}
else
ereport(PANIC,
(errmsg("could not locate a valid checkpoint record")));
}
…
}
…
/* REDO */
if (InRecovery)
{
…
/*
* Update pg_control to show that we are recovering and to show the
* selected checkpoint as the place we are starting from. We also mark
* pg_control with any minimum recovery stop point obtained from a
* backup history file.
*/
if (InArchiveRecovery)
ControlFile->state = DB_IN_ARCHIVE_RECOVERY;
else
{
ereport(LOG,
(errmsg("database system was not properly shut down; "
automatic recovery in progress)));
ControlFile->state = DB_IN_CRASH_RECOVERY;
}
ControlFile->prevCheckPoint = ControlFile->checkPoint;
ControlFile->checkPoint = checkPointLoc;
ControlFile->checkPointCopy = checkPoint;
…
}
…
}
就是说,如果拿不到最好的,就拿到上次的那个checkpoint1点:Get the last valid checkpoint record. If the latest one according to pg_control is broken, try the next-to-last one.
此外,我们可以看restartPoint时,也有此处理:
/*
* 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)
{
…
/*
* Update pg_control, using current time. Check that it still shows
* IN_ARCHIVE_RECOVERY state and an older checkpoint, else do nothing;
* this is a quick hack to make sure nothing really bad happens if somehow
* we get here after the end-of-recovery checkpoint.
*/
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
if (ControlFile->state == DB_IN_ARCHIVE_RECOVERY &&
XLByteLT(ControlFile->checkPointCopy.redo, lastCheckPoint.redo))
{
ControlFile->prevCheckPoint = ControlFile->checkPoint;
ControlFile->checkPoint = lastCheckPointRecPtr;
ControlFile->checkPointCopy = lastCheckPoint;
ControlFile->time = (pg_time_t) time(NULL);
if (flags & CHECKPOINT_IS_SHUTDOWN)
ControlFile->state = DB_SHUTDOWNED_IN_RECOVERY;
UpdateControlFile();
}
LWLockRelease(ControlFileLock);
…
}
初步学习pg_control文件之十一的更多相关文章
- 初步学习pg_control文件之十二
接前问,初步学习pg_control文件之十一,再来看下面这个 XLogRecPtr minRecoveryPoint; 看其注释: * minRecoveryPoint is updated to ...
- 初步学习pg_control文件之十五
接前文 初步学习pg_control文件之十四 再看如下这个: int MaxConnections; 应该说,它是一个参考值,在global.c中有如下定义 /* * Primary determ ...
- 初步学习pg_control文件之十四
接前文 初步学习pg_control文件之十三 看如下几个: /* * Parameter settings that determine if the WAL can be used for arc ...
- 初步学习pg_control文件之十三
接前文,初步学习pg_control文件之十二 看这个: * backupStartPoint is the redo pointer of the backup start checkpoint, ...
- 初步学习pg_control文件之十
接前文 初步学习pg_control文件之九 看下面这个 XLogRecPtr checkPoint; /* last check point record ptr */ 看看这个pointer究竟保 ...
- 初步学习pg_control文件之九
接前文,初步学习pg_control文件之八 来看这个: pg_time_t time; /* time stamp of last pg_control update */ 当初初始化的时候,是这样 ...
- 初步学习pg_control文件之八
接前文 初步学习pg_control文件之七 继续 看:catalog_version_no 代码如下: static void WriteControlFile(void) { ... /* * ...
- 初步学习pg_control文件之七
接前文 初步学习pg_control文件之六 看 pg_control_version 以PostgreSQL9.1.1为了,其HISTORY文件中有如下的内容: Release Release ...
- 初步学习pg_control文件之六
接前文:初步学习pg_control文件之五 ,DB_IN_ARCHIVE_RECOVERY何时出现? 看代码:如果recovery.conf文件存在,则返回 InArchiveRecovery = ...
随机推荐
- 716. Max Stack (follow up questions for min stack)
Design a max stack that supports push, pop, top, peekMax and popMax. push(x) -- Push element x onto ...
- Android——HelloWorld
今天正式加入实验室做安卓,看上去无从下手,让我想到当年学ACM一样,但是也一直搞过来了,现在又是一个新的起点. 废话不多说~~~ Hello World 安装: JDK SDK Eclipse 参考: ...
- 课堂笔记:HTML----------图片热点
HTML----------图片热点: 规划出图片上的一个区域,可以做出超链接,直接点击图片区域就可完成跳转的效果. 代码: <!DOCTYPE html PUBLIC "-//W3C ...
- PHP设计模式——桥接模式
<?php /* * 桥接模式 * 使用发送器,将一个类对象传入另一个类作为属性,耦合M+N个类 * */ abstract class Info { protected $_send = NU ...
- mybatis学习记录二——mybatis开发dao的方法
4.1 SqlSession使用范围 4.1.1 SqlSessionFactoryBuilder 通过SqlSessionFactoryBuilder创建会话工厂SqlSession ...
- google为什么将爬虫从python移植到C++
这是好几年前Quora上的一个问题,有点过时,但看了之后感觉不错,就总结了一下 原文链接:http://www.quora.com/Why-did-Google-move-from-Python-to ...
- HDU 1399 Starship Hakodate-maru(暴力搜索)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1399 Starship Hakodate-maru Time Limit: 2000/1000 MS ...
- pv与单广告位曝光统计优化
上一篇文章<巧用域名发散,缓解单广告位并发请求限制>中提到了我已经将广告的数据请求写成了单广告位请求.既然数据请求都已经是单广告位的了,那么曝光统计也理所应当是单广告位的. pv是什么? ...
- IP地址获取当前地理位置(省份)的接口
腾讯的接口是 ,返回数组 http://fw.qq.com/ipaddress 返回值 var IPData = new Array("61.135.152.194"," ...
- c#中关于结构体和字节数组转化
最近在使用结构体与字节数组转化来实现socket间数据传输.现在开始整理一下.对于Marshal可以查阅msdn,关于字节数组与结构体转代码如下: using System; using System ...