接前文  初步学习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文件之十一的更多相关文章

  1. 初步学习pg_control文件之十二

    接前问,初步学习pg_control文件之十一,再来看下面这个 XLogRecPtr minRecoveryPoint; 看其注释: * minRecoveryPoint is updated to ...

  2. 初步学习pg_control文件之十五

    接前文  初步学习pg_control文件之十四 再看如下这个: int MaxConnections; 应该说,它是一个参考值,在global.c中有如下定义 /* * Primary determ ...

  3. 初步学习pg_control文件之十四

    接前文 初步学习pg_control文件之十三 看如下几个: /* * Parameter settings that determine if the WAL can be used for arc ...

  4. 初步学习pg_control文件之十三

    接前文,初步学习pg_control文件之十二 看这个: * backupStartPoint is the redo pointer of the backup start checkpoint, ...

  5. 初步学习pg_control文件之十

    接前文 初步学习pg_control文件之九 看下面这个 XLogRecPtr checkPoint; /* last check point record ptr */ 看看这个pointer究竟保 ...

  6. 初步学习pg_control文件之九

    接前文,初步学习pg_control文件之八 来看这个: pg_time_t time; /* time stamp of last pg_control update */ 当初初始化的时候,是这样 ...

  7. 初步学习pg_control文件之八

    接前文  初步学习pg_control文件之七  继续 看:catalog_version_no 代码如下: static void WriteControlFile(void) { ... /* * ...

  8. 初步学习pg_control文件之七

    接前文 初步学习pg_control文件之六  看   pg_control_version 以PostgreSQL9.1.1为了,其HISTORY文件中有如下的内容: Release Release ...

  9. 初步学习pg_control文件之六

    接前文:初步学习pg_control文件之五 ,DB_IN_ARCHIVE_RECOVERY何时出现? 看代码:如果recovery.conf文件存在,则返回 InArchiveRecovery = ...

随机推荐

  1. Jmeter入门18 Jmeter添加cookie的两种方式

    jmeter中添加cookie可以通过配置HTTP Cookie Manager,也可以通过HTTP Header Manager,因为cookie是放在头文件里发送的. 实例:博客园点击添加新随笔  ...

  2. WPF产生不重复的随机数

    WPF产生不重复的随机数 在给定的区间范围(比如[50,99]),产生给定数量的随机数(不如10个),要求产生的随机数不重复首先给定变量min=50;max=99+1;//习惯与程序规定的编码不同所致 ...

  3. ACM-ICPC(10/21)

    写一发后缀数组套路题,看起来简单,写起来要人命哦~~~ 总共13题. 分两天debug吧,有点累了~~~ suffix(后缀数组的应用) sa[i] :排名第 i 的后缀在哪(i 从 1 开始) ra ...

  4. Linux使用sz、rz命令下载、上传文件

    1.安装服务 yum -y install lrzsz 2.上传命令:rz 使用rz命令,会调用系统的资源管理器,选择文件进行上传即可.上传的文件默认保存linux当前所在目录 3.下载命令:sz 根 ...

  5. html上传图片(进度条变化)、音乐

    <html> <head> <title>$Title$</title> </head> <link href="css/b ...

  6. SQL中char、varchar、nvarchar、text 的区别

    char char是定长的,也就是当你输入的字符小于你指定的数目时,char(8),你输入的字符小于8时,它会再后面补空值.当你输入的字符大于指定的数时,它会截取超出的字符. nvarchar(n) ...

  7. shell命令查看某文件夹下的文件个数

    shell命令查看某文件夹下的文件个数 2010-06-25 17:05:15|  分类: shell |字号 订阅   1.查看某文件夹下文件的个数: ls -l |grep "^-&qu ...

  8. Javascript 基础汇总

    1 javascript字符串 属性:.length  计算字符串长度 转义字符 \     \n 换行 \r 回车 字符串断行 需要使用反斜杠  \ 2 字符串方法 charAt(n)  返回指定索 ...

  9. MVC5 模型 生成EF

    在看本篇之前请先去了解一下EF以及如何利用模型生成数据库  https://i.cnblogs.com/posts?categoryid=1107227 看Code First就可以了. 等你了解了E ...

  10. CONVERT函数----SQL

    CONVERT函数是把时间转换成新类型的通用格式,这样方便查询 CONVERT(type,expression,style) type: 例如:varchar(10)  数据库字符串的类型,大小可以自 ...