postgresql检查点
1 Checkpoint作用
1.1将事务提交的修改写进disk(写脏数据);保证数据库的完整性和一致性。
1.2缩短恢复时间
www.zzzyk.com
2 checkpoint所用结构体
typedef struct CheckPoint
{
XLogRecPtr redo; TimeLineID ThisTimeLineID;
uint32 nextXidEpoch;
TransactionId nextXid;
Oid nextOid;
MultiXactId nextMulti; MultiXactOffset nextMultiOffset;
TransactionId oldestXid;
Oid oldestXidDB; pg_time_t time;
TransactionId oldestActiveXid;
} CheckPoint;
XLogRecPtr
typedef struct XLogRecPtr
{
uint32 xlogid; /* log file #, 0 based */
uint32 xrecoff; /* byte offset of location in log file */
} XLogRecPtr;
3 checkpoint's position
the checkpoint's position is saved in the file pg_control and log
when pg_control corrupt
To deal with the case where pg_control is corrupt, we should support the possibility of scanning existing log segments in reverse order — newest to oldest — in order to find the latest checkpoint
4checkpoint执行控制
4.1,数据量达到checkpoint_segments(=3)*16M时,系统自动触发;
4.2,时间间隔达到checkpoint_timeout参数值时;
4.3,用户发出checkpoint命令时。
5 创建一个检查点
5.1是recptr是pg_contrl中checkpoint中的recptr进行赋值(如果pg_control中关于checkpoint的记录是正确的话)。
5.2如果pg_control中recptr的记录是不正确的,则checkpoint.recptr = {0}。
// redo保存了xlog的当前插入transaction log位置。
5.2.1INSERT_RECPTR(checkPoint.redo, Insert, Insert->curridx);
其中Insert为:XLogCtlInsert *Insert = &XLogCtl->Insert;
5.2.2checkPoint.nextXid = ShmemVariableCache->nextXid;
5.2.3checkPoint.oldestXid = ShmemVariableCache->oldestXid;
5.2.4checkPoint.oldestXidDB = ShmemVariableCache->oldestXidDB;
6 Flush all data in shared memory to disk, and fsync
实现函数static void
CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
{
CheckPointCLOG();
CheckPointSUBTRANS();
CheckPointMultiXact();
CheckPointPredicate();
// CheckPointRelationMap();
CheckPointBuffers(flags); /* performs all required fsyncs */
/* We deliberately delay 2PC checkpointing as long as possible */
CheckPointTwoPhase(checkPointRedo);
}
保证redo之前的日志记录的数据修改都刷新到数据库磁盘文件中。
Xlog文件随时间的变化 current insertion point
----------------------------------------------------------------->
数据是一致性 | 数据一致性未知
CheckPoint中的redo
创建checkPoint时,首先获取redo位置,然后保证redo之前的xlog记录的修改都刷新到数据磁盘文件中。这样保证的checkPoint左的数据库文件一致性。如果在checkPoint后需要recovery,只需要redo位置向右replay xlog。
4 Now insert the checkpoint record into XLOG.
4.1 rdata.data = (char *) (&checkPoint);
rdata.len = sizeof(checkPoint);
rdata.buffer = InvalidBuffer;
rdata.next = NULL;
4.2 insert
recptr = XLogInsert(RM_XLOG_ID,
shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
XLOG_CHECKPOINT_ONLINE,
&rdata);
4.3 flush to disk
Ensure that all XLOG data through the given position is flushed to disk.
XLogFlush(recptr);
结束一个检查点
把一些统计信息写到LOG(= 15)中。