PostgreSQL的backuplabel file 初步学习

 

磨砺技术珠矶,践行数据之道,追求卓越价值

 

回到上一级页面:PostgreSQL内部结构与源代码研究索引页    回到顶级页面:PostgreSQL索引页

 

 

看代码:

/* File path names (all relative to $PGDATA) */                    
#define BACKUP_LABEL_FILE        backup_label            
#define BACKUP_LABEL_OLD        backup_label.old            

在特定条件下,会有一个文件,名为 backup_label

在StartupXLOG执行时,通过 read_backup_label 函数来进行读取:

/*                                    
 * read_backup_label: check to see if a backup_label file is present 
 * If we see a backup_label during recovery, we assume that we are recovering 
 * from a backup dump file, and we therefore roll forward from the checkpoint 
 * identified by the label file, NOT what pg_control says.    This avoids the 
 * problem that pg_control might have been archived one or more checkpoints 
 * later than the start of the dump, and so if we rely on it as the start 
 * point, we will fail to restore a consistent database state.                                    
 *                                    
 * Returns TRUE if a backup_label was found (and fills the checkpoint                                    
 * location and its REDO location into *checkPointLoc and RedoStartLSN,                                    
 * respectively); returns FALSE if not. If this backup_label came from a 
 * streamed backup, *backupEndRequired is set to TRUE.                                    
 */                                    
static bool                                    
read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired)                                    
{                                    
    char        startxlogfilename[MAXFNAMELEN];                        
    TimeLineID    tli;                            
    FILE       *lfp;                            
    char        ch;                        
    char        backuptype[20];                        
                                    
    *backupEndRequired = false;                                
                                    
    /*                                
     * See if label file is present                                
     */                                
    lfp = AllocateFile(BACKUP_LABEL_FILE, "r");                                
    if (!lfp)                                
    {                                
        if (errno != ENOENT)                            
            ereport(FATAL,                        
                    (errcode_for_file_access(),                
                     errmsg("could not read file \"%s\": %m",                
                            BACKUP_LABEL_FILE)));        
        return false;            /* it's not there, all is fine */                
    }                                
                                    
    /*                                
     * Read and parse the START WAL LOCATION and CHECKPOINT lines (this code                                
     * is pretty crude, but we are not expecting any variability in the file                                
     * format).                                
     */                                
    if (fscanf(lfp, "START WAL LOCATION: %X/%X (file %08X%16s)%c",                                
               &RedoStartLSN.xlogid, &RedoStartLSN.xrecoff, &tli,                        
               startxlogfilename, &ch) != 5 || ch != '\n')                        
        ereport(FATAL,                            
                (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),                    
                 errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));                    
                                    
    if (fscanf(lfp, "CHECKPOINT LOCATION: %X/%X%c",                                
               &checkPointLoc->xlogid, &checkPointLoc->xrecoff,                        
               &ch) != 3 || ch != '\n')                        
        ereport(FATAL,                            
                (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),                    
                 errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));                    
                                    
    /*                                
     * BACKUP METHOD line didn't exist in 9.1beta3 and earlier, so don't                                
     * error out if it doesn't exist.                                
     */                                
    if (fscanf(lfp, "BACKUP METHOD: %19s", backuptype) == 1)                                
    {                                
        if (strcmp(backuptype, "streamed") == 0)                            
            *backupEndRequired = true;                        
    }                                
                                    
    if (ferror(lfp) || FreeFile(lfp))                                
        ereport(FATAL,                            
                (errcode_for_file_access(),                    
                 errmsg("could not read file \"%s\": %m",                    
                        BACKUP_LABEL_FILE)));            
                                    
    return true;                                
}                                    

看StarupXLOG函数:

/*                                            
 * This must be called ONCE during postmaster or standalone-backend startup                                            
 */                                            
void                                            
StartupXLOG(void)                                            
{                                            
                                            
    …                                        
    if (read_backup_label(&checkPointLoc, &backupEndRequired))                                        
    {                                        
                                            
        /*                                    
         * When a backup_label file is present, we want to roll forward from                                    
         * the checkpoint it identifies, rather than using pg_control.                                    
         */                                    
        record = ReadCheckpointRecord(checkPointLoc, 0);                                    
                                            
        if (record != NULL)                                    
        {                                    
            memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));                                
                                            
            wasShutdown = (record->xl_info == XLOG_CHECKPOINT_SHUTDOWN);                                
                                            
            ereport(DEBUG1,                                
                    (errmsg("checkpoint record is at %X/%X",                        
                            checkPointLoc.xlogid, checkPointLoc.xrecoff)));                
                                            
            InRecovery = true;                /* force recovery even if SHUTDOWNED */                
                                            
            /*                                
             * Make sure that REDO location exists. This may not be the case                                
             * if there was a crash during an online backup, which left a                                
             * backup_label around that references a WAL segment that's                                
             * already been archived.                                
             */                                
            if (XLByteLT(checkPoint.redo, checkPointLoc))                                
            {                                
                if (!ReadRecord(&(checkPoint.redo), LOG, false))                            
                    ereport(FATAL,                        
                            (errmsg("could not find redo location referenced by checkpoint record"),
                             errhint("If you are not restoring from a backup, 
try removing the file \"%s/backup_label\".
", DataDir))); } } else { ereport(FATAL, (errmsg("could not locate required checkpoint record"), errhint("If you are not restoring from a backup,
try removing the file \"%s/backup_label\".
", DataDir))); wasShutdown = false; /* keep compiler quiet */ } /* set flag to delete it later */ haveBackupLabel = true; } 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"))); } memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint)); wasShutdown = (record->xl_info == XLOG_CHECKPOINT_SHUTDOWN); } … }

通过运行发现,上一次正常关闭或者崩溃,都不会产生  backup_label 文件。

关于这个文件,大家都是这么说的:

http://jsoc.stanford.edu/production/postgres_backup_restore.html.bk!

http://raghavt.blogspot.com/2011/05/postgresql-90-backup-recovery.html

http://www.network-theory.co.uk/docs/postgresql/vol3/MakingaBaseBackup.html

就是:pg_start_backup,会生成 backup_label文件。pg_stop_backup,会删除backup_label文件。

而如果StartupXLOG函数运行时,发现了backup_label文件,那么意味着它处正在从online backup中恢复的过程中。

 

 

回到上一级页面:PostgreSQL内部结构与源代码研究索引页    回到顶级页面:PostgreSQL索引页

磨砺技术珠矶,践行数据之道,追求卓越价值

 

posted @ 2013-08-05 14:13  健哥的数据花园  阅读(2662)  评论(0编辑  收藏  举报