PostgreSQL的backuplabel file 初步学习

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介:

看代码:

/* 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中恢复的过程中。







本文转自健哥的数据花园博客园博客,原文链接:http://www.cnblogs.com/gaojian/p/3238048.html,如需转载请自行联系原作者


相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
关系型数据库 数据库 C语言
PostgreSQL服务端开发学习 -- Datum
在使用C语言开发PostgreSQL后端、客户端应用时,Datum无处不在,所以必须要对Datum有很清楚的了解。
|
关系型数据库 分布式数据库 数据库
沉浸式学习PostgreSQL|PolarDB 19: 体验最流行的开源企业ERP软件 odoo
本文主要教大家怎么用好数据库, 而不是怎么运维管理数据库、怎么开发数据库内核.
1129 2
|
SQL 关系型数据库 测试技术
沉浸式学习PostgreSQL|PolarDB 20: 学习成为数据库大师级别的优化技能
在上一个实验《沉浸式学习PostgreSQL|PolarDB 19: 体验最流行的开源企业ERP软件 odoo》 中, 学习了如何部署odoo和polardb|pg. 由于ODOO是非常复杂的ERP软件, 对于关系数据库的挑战也非常大, 所以通过odoo业务可以更快速提升同学的数据库优化能力, 发现业务对数据库的使用问题(如索引、事务对锁的运用逻辑问题), 数据库的代码缺陷, 参数或环境配置问题, 系统瓶颈等.
950 1
|
人工智能 关系型数据库 分布式数据库
沉浸式学习PostgreSQL|PolarDB 16: 植入通义千问大模型+文本向量化模型, 让数据库具备AI能力
本文将带领大家来体验一下如何将“千问大模型+文本向量化模型”植入到PG|PolarDB中, 让数据库具备AI能力.
25171 19
沉浸式学习PostgreSQL|PolarDB 16: 植入通义千问大模型+文本向量化模型, 让数据库具备AI能力
|
关系型数据库 C语言 PostgreSQL
PostgreSQL服务端开发学习 --- 常用结构及宏定义1
本篇主要讲解使用C语言开发PostgreSQL服务端应用(libpq、自定义函数、扩展)常用到的结构及宏定义。
|
4月前
|
SQL 存储 关系型数据库
新手如何入门学习PostgreSQL?
新手如何入门学习PostgreSQL?
|
4月前
|
SQL 存储 关系型数据库
PostgreSQL核心之SQL基础学习
PostgreSQL核心之SQL基础学习
50 3
|
5月前
|
SQL 存储 关系型数据库
关系型数据库PostgreSQL学习
【7月更文挑战第4天】
458 2
|
6月前
|
存储 关系型数据库 数据库
经验大分享:PostgreSQL学习之【用户权限管理】说明
经验大分享:PostgreSQL学习之【用户权限管理】说明
103 0
|
关系型数据库 定位技术 分布式数据库
沉浸式学习PostgreSQL|PolarDB 18: 通过GIS轨迹相似伴随|时态分析|轨迹驻点识别等技术对拐卖、诱骗场景进行侦查
本文主要教大家怎么用好数据库, 而不是怎么运维管理数据库、怎么开发数据库内核.
1319 1