zoukankan      html  css  js  c++  java
  • 初步学习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, 0, 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, 1);                                
            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, 2);                            
                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);                            
        …                            
    }                                

         

  • 相关阅读:
    spark 系列之六 SparkStreaming数据源之socket流
    spark 系列之五 SparkStreaming数据源之文件流
    spark 系列之四 Spark数据源之关系型数据库
    spark 系列之三 RDD,DataFrame与DataSet之间的转化
    spark 系列之二 Dataframe的使用
    spark 系列之一 RDD的使用
    Java Int类型与字符,汉字之间的转换
    Java实现栈
    名字的漂亮度
    在字符串中找出连续最长的数字串
  • 原文地址:https://www.cnblogs.com/gaojian/p/3230085.html
Copyright © 2011-2022 走看看