初步学习pg_control文件之六

接前文:初步学习pg_control文件之五 ,DB_IN_ARCHIVE_RECOVERY何时出现?

看代码:如果recovery.conf文件存在,则返回 InArchiveRecovery = true。

/*                                        
 * See if there is a recovery command file (recovery.conf), and if so                                      
 * read in parameters for archive recovery and XLOG streaming.  
 * The file is parsed using the main configuration parser.                                        
 */                                        
static void                                        
readRecoveryCommandFile(void)                                        
{                                        
    …                                    
    fd = AllocateFile(RECOVERY_COMMAND_FILE, "r");                                    
    if (fd == NULL)                                    
    {                                    
        if (errno == ENOENT)                                
            return;                /* not there, so no archive recovery */            
        ereport(FATAL,                                
                (errcode_for_file_access(),                        
                 errmsg("could not open recovery command file "%s": %m",                        
                        RECOVERY_COMMAND_FILE)));                
    }                                    
    …                                    
                                        
    /* Enable fetching from archive recovery area */                                    
    InArchiveRecovery = true;                                    
                                        
    …                                    
}                                        

然后,如果pg_control文件的state不是 DB_SHUTDOWNED状态,则可以认为需要recovery,

此时,如果 InArchiveRecovery 为true,则开始设置DB_IN_ARCHIVE_RECOVERY 状态。

/*                                        
 * This must be called ONCE during postmaster or standalone-backend startup                                        
 */                                        
void                                        
StartupXLOG(void)                                        
{                                        
    …                                    
                                        
    /*                                    
     * Check for recovery control file, and if so set up state for offline                                    
     * recovery                                    
     */                                    
    readRecoveryCommandFile();                                    
                                        
    …                                    
                                        
    /*                                    
     * Check whether we need to force recovery from WAL.  If it appears to                                    
     * have been a clean shutdown and we did not have a recovery.conf file,                                    
     * then assume no recovery needed.                                    
     */                                    
    if (XLByteLT(checkPoint.redo, RecPtr))                                    
    {                                    
        if (wasShutdown)                                
            ereport(PANIC,                            
                    (errmsg("invalid redo record in shutdown checkpoint")));                    
        InRecovery = true;                                
    }                                    
    else if (ControlFile->state != DB_SHUTDOWNED)                                    
        InRecovery = true;                                
    else if (InArchiveRecovery)                                    
    {                                    
        /* force recovery due to presence of recovery.conf */                                
        InRecovery = true;                                
    }                                    
                                        
    /* REDO */                                    
    if (InRecovery)                                    
    {                                    
        int            rmid;                    
                                        
        /* use volatile pointer to prevent code rearrangement */                                
        volatile XLogCtlData *xlogctl = XLogCtl;                                
                                        
        /*                                
         * 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;                            
        }                                
                                        
        …                                
        UpdateControlFile();                                
        …                                
    }                                    
    …                                    
                                        
}                                        
原文地址:https://www.cnblogs.com/gaojian/p/3228099.html