初步学习pg_control文件之十

简介:

接前文 初步学习pg_control文件之九 看下面这个

XLogRecPtr    checkPoint;        /* last check point record ptr */

看看这个pointer究竟保留了什么

初始化的时候:

复制代码
/*                            
 * This func must be called ONCE on system install.  It creates pg_control                            
 * and the initial XLOG segment.                            
 */                            
void                            
BootStrapXLOG(void)                            
{                            
                            
    …                        
    /*                        
     * Set up information for the initial checkpoint record                        
     *                        
     * The initial checkpoint record is written to the beginning of the WAL                        
     * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not                        
     * used, so that we can use 0/0 to mean "before any valid WAL segment".                        
     */                        
    checkPoint.redo.xlogid = 0;                        
    checkPoint.redo.xrecoff = XLogSegSize + SizeOfXLogLongPHD;                        
                            
    ...                    
    /* Now create pg_control */                        
                            
    memset(ControlFile, 0, sizeof(ControlFileData));                        
                            
    /* Initialize pg_control status fields */                        
    ControlFile->system_identifier = sysidentifier;                        
    ControlFile->state = DB_SHUTDOWNED;                        
    ControlFile->time = checkPoint.time;                        
                            
    ControlFile->checkPoint = checkPoint.redo;                        
    ControlFile->checkPointCopy = checkPoint;                        
                            
    …                        
    WriteControlFile();                        
    …                        
}                            
复制代码

运行的时候:

复制代码
/*                                
 * ProcLastRecPtr points to the start of the last XLOG record inserted by the 
 * current backend.  It is updated for all inserts.  XactLastRecEnd points to
 * end+1 of the last record, and is reset when we end a top-level transaction, 
 * or start a new one; so it can be used to tell if the current transaction has 
 * created any XLOG records.                                
 */                                
static XLogRecPtr ProcLastRecPtr = {0, 0};                                
…                                
                                
                                
/*                                
 * Insert an XLOG record having the specified RMID and info bytes,                                
 * with the body of the record being the data chunk(s) described by                                
 * the rdata chain (see xlog.h for notes about rdata).                                
 *                                
 * Returns XLOG pointer to end of record (beginning of next record).                                
 * This can be used as LSN for data pages affected by the logged action.                                
 * (LSN is the XLOG point up to which the XLOG must be flushed to disk                                
 * before the data page can be written out.  This implements the basic                                
 * WAL rule "write the log before the data".)                                
 *                                
 * NB: this routine feels free to scribble on the XLogRecData structs,                                
 * though not on the data they reference.  This is OK since the XLogRecData                                
 * structs are always just temporaries in the calling code.                                
 */                                
XLogRecPtr                                
XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata)                                
{                                
    …                            
    /*                            
     * In bootstrap mode, we don't actually log anything but XLOG resources;                            
     * return a phony record pointer.                            
     */                            
    if (IsBootstrapProcessingMode() && rmid != RM_XLOG_ID)                            
    {                            
        RecPtr.xlogid = 0;                        
        RecPtr.xrecoff = SizeOfXLogLongPHD;        /* start of 1st chkpt record */                
        return RecPtr;                        
    }                            
                                
    …                            
    /* Record begin of record in appropriate places */                            
    ProcLastRecPtr = RecPtr;                            
    Insert->PrevRecord = RecPtr;                            
    …                            
}                                
复制代码

关闭的时候:

复制代码
/*                                
 * 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, 0, sizeof(XLogRecPtr));                            
    UpdateControlFile();                            
    LWLockRelease(ControlFileLock);                            
    …                            
}                                
复制代码

RecoveryMode或者Stand by 的时候:

复制代码
/*                                
 * 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)                                
{                                
    XLogRecPtr        lastCheckPointRecPtr;                    
    CheckPoint    lastCheckPoint;                        
    uint32        _logId;                    
    uint32        _logSeg;                    
    TimestampTz xtime;                            
                                
    /* use volatile pointer to prevent code rearrangement */                            
    volatile XLogCtlData *xlogctl = XLogCtl;                            
                                
    /*                            
     * Acquire CheckpointLock to ensure only one restartpoint or checkpoint                            
     * happens at a time.                            
     */                            
    LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);                            
                                
    /* Get a local copy of the last safe checkpoint record. */                            
    SpinLockAcquire(&xlogctl->info_lck);                            
    lastCheckPointRecPtr = xlogctl->lastCheckPointRecPtr;                            
    memcpy(&lastCheckPoint, &XLogCtl->lastCheckPoint, sizeof(CheckPoint));                            
    SpinLockRelease(&xlogctl->info_lck);                            
                                
    …                            
    /*                            
     * 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);                            
                                
    …                            
}                                
复制代码

启动的时候:

复制代码
/*                                
 * This must be called ONCE during postmaster or standalone-backend startup                                
 */                                
void                                
StartupXLOG(void)                                
{                                
    …                            
    /*                            
     * Read control file and check XLOG status looks valid.                            
     *                            
     * Note: in most control paths, *ControlFile is already valid and we need                            
     * not do ReadControlFile() here, but might as well do it to be sure.                            
     */                            
    ReadControlFile();                            
                                
    if (ControlFile->state < DB_SHUTDOWNED ||                            
        ControlFile->state > DB_IN_PRODUCTION ||                        
        !XRecOffIsValid(ControlFile->checkPoint.xrecoff))                        
        ereport(FATAL,                        
                (errmsg("control file contains invalid data")));                
                                
    …                            
    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, 1);                        
        …                        
    }                            
    …                            
                                
    /* REDO */                            
    if (InRecovery)                            
    {                            
        …                        
        ControlFile->prevCheckPoint = ControlFile->checkPoint;                        
        ControlFile->checkPoint = checkPointLoc;                        
        ControlFile->checkPointCopy = checkPoint;                        
        …                        
    }                            
                                
    …                            
}                                
复制代码
目录
相关文章
|
缓存 关系型数据库 数据库
|
关系型数据库 PostgreSQL