从代码层判断 pg_basebackup 是否已正常结束 - 暨改进建议

标签

PostgreSQL , pg_basebackup


背景

用户通常会使用pg_basebackup来对PostgreSQL实施在线备份,对于超级大的数据库实例,可能需要备份很久。

如果将任务分解来看,假设备份是任务流中的一个步骤,如果设置了超时时间,那么在超时导致该步骤失败之后,如何判断pg_basebackup是否已执行成功?

1、从pg_basebackup的源码中分析,文件是否有备份顺序,是否可能从某些文件是否存在来判断?

2、从pg_basebackup的返回值或STDOUT中判断。

从pg_basebackup的源码中分析

pg_basebackup的源码

src/bin/pg_basebackup/pg_basebackup.c

int  
main(int argc, char **argv)  
{  
..............  
        BaseBackup();  
  
        success = true;  
        return 0;  
}  
static void  
BaseBackup(void)  
{  
        PGresult   *res;  
        char       *sysidentifier;  
        TimeLineID      latesttli;  
        TimeLineID      starttli;  
        char       *basebkp;  
        char            escaped_label[MAXPGPATH];  
        char       *maxrate_clause = NULL;  
        int                     i;  
        char            xlogstart[64];  
        char            xlogend[64];  
        int                     minServerMajor,  
                                maxServerMajor;  
        int                     serverVersion,  
                                serverMajor;  
....................  
  
        /* Free the recovery.conf contents */  
        destroyPQExpBuffer(recoveryconfcontents);  
  
        /*  
         * End of copy data. Final result is already checked inside the loop.  
         */  
        PQclear(res);  
        PQfinish(conn);  
  
        /*  
         * Make data persistent on disk once backup is completed. For tar format  
         * once syncing the parent directory is fine, each tar file created per  
         * tablespace has been already synced. In plain format, all the data of  
         * the base directory is synced, taking into account all the tablespaces.  
         * Errors are not considered fatal.  
         */  
        if (do_sync)  
        {  
                if (format == 't')  
                {  
                        if (strcmp(basedir, "-") != 0)  
                                (void) fsync_fname(basedir, true, progname);  
                }  
                else  
                {  
                        (void) fsync_pgdata(basedir, progname, serverVersion);  
                }  
        }  
  
        // 改进可以写到这个位置,用户识别后,可以删除这个文件。  
  
        if (verbose)  
                fprintf(stderr, _("%s: base backup completed\n"), progname);  
}  

在结束时,并没有特别的输出,同时对源端文件的扫描也没有特定的顺序,或者结束时,并没有写特殊的标记文件。

如果需要通过备份内容来识别pg_basebackup是否结束,需要改进pg_basebackup,建议:

1、备份开始时,在本地(目标端),写一个标签文件,记录本次备份的开始时间

2、结束时,修改这个标签文件,记录结束时间。

那么可以查看这个文件来判断pg_basebackup是否结束。

从pg_basebackup的返回值或STDOUT中判断

实际上,从pg_basebackup源码可以看到,如果备份开启了 -v 参数,那么在备份结束后,会输出日志

fprintf(stderr, _("%s: base backup completed\n"), progname);

参数

       -v  
       --verbose  
           Enables verbose mode. Will output some extra steps during startup and shutdown, as well as show the exact file name that is currently being processed if progress reporting is also enabled.  

因此我们如果记录了备份命令的标准输出,那么可以从标准输出来判断pg_basebackup是否正常结束。

pg_basebackup xxxx >log 2>&1  
  
或

pg_basebackup xxxx && echo "success" > log

备份日志输出到日志文件,如果日志文件中包含base backup completed的输出,则表示备份成功。

小结

通过本文提到的方法,可以在异步调用pg_basebackup时,判定pg_basebackup是否正常结束。

否则,用户在调用pg_basebackup超时后,无法得知其任务状态,只能删除备份的目标目录(否则会报dir already exists ERROR),重新执行pg_basebackup。对于大实例,可能永远也执行不成功。

参考

man pg_basebackup

src/bin/pg_basebackup/pg_basebackup.c

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值