记一次空间告警与pg_rman keep-data-days参数研究

67 篇文章 52 订阅
31 篇文章 4 订阅
文章讲述了在使用pg_rman进行备份时遇到的困惑,即设置keep-data-days=1为何仍保留3天备份。作者通过源码分析发现,pg_rman在备份完成后才会清理过期文件,导致在备份期间会有额外一天的备份。最后提供了解决方案,即设置keep-data-days=0以确保仅保留当天备份。
摘要由CSDN通过智能技术生成

一、 背景

       收到一个磁盘空间告警,检查发现是本地备份保留比较多导致的,处理过程倒很简单,手动清理掉旧的备份(已自动备到远端服务器),告警就恢复了。

       但是检查备份脚本的时候,发现keep-data-days参数明明只设置了1,为什么本地会出现3份备份(保留了3天的备份)?

pg_rman backup -b ${BACKUP_TYPE}  -s -C -Z -P --keep-data-days=1 --keep-arclog-files=…(非完整命令)

查了下官方文档的解释…说了好像没说一样

pg_rman

二、 源码学习

1. 奇怪的第3份备份文件

       检查了下其他设置keep-data-days=1的服务器,发现都只有最近2天的备份文件,而之前在处理告警时,备份正在执行中。因此可以推测,pg_rman是在备份完成后才清理掉过期的备份文件。因此在备份期间会有3天的文件,而备完后就只有2

       要验证这个猜测,可以简单地再执行下备份,也可以从pg_rman备份源码分析。

       以下在backup.c文件的do_backup函数,可以看到pgBackupDelete函数调用是在各种备份完成之后,符合前面的结论。

int
do_backup(pgBackupOption bkupopt)
{
    parray *backup_list;
    parray *files_database;
    parray *files_arclog;
    parray *files_srvlog;
    int    ret;
    char   path[MAXPGPATH];

    /* repack the necesary options */
    int keep_arclog_files = bkupopt.keep_arclog_files;
    int keep_arclog_days  = bkupopt.keep_arclog_days;
    int keep_srvlog_files = bkupopt.keep_srvlog_files;
    int keep_srvlog_days  = bkupopt.keep_srvlog_days;
    int keep_data_generations = bkupopt.keep_data_generations;
    int keep_data_days        = bkupopt.keep_data_days;

…
    /*
     * Signal for backup_cleanup() that there may actually be some cleanup
     * for it to do from this point on.
     */
    in_backup = true;

    /* backup data */
    files_database = do_backup_database(backup_list, bkupopt);

    /* backup archived WAL */
    files_arclog = do_backup_arclog(backup_list);

    /* backup serverlog */
    files_srvlog = do_backup_srvlog(backup_list);

    pgut_atexit_pop(backup_cleanup, NULL);

    /* update backup status to DONE */
    current.end_time = time(NULL);
    current.status = BACKUP_STATUS_DONE;
   …

    /* Delete old backup files after all backup operation. */
    pgBackupDelete(keep_data_generations, keep_data_days);
    …
    return 0;
}

2. keep-data-days的含义

       3份备份的问题解决了,还剩下一个,为什么设置keep-data-days=1会保留2天的备份文件而不是1天?以下在delete.c文件的pgBackupDelete函数

/*
 * Delete backups that are older than KEEP_xxx_DAYS, or have more generations
 * than KEEP_xxx_GENERATIONS.
 */
void
pgBackupDelete(int keep_generations, int keep_days)
{
    int     i;
    parray *backup_list;
    int     existed_generations;
    bool    check_generations;
 …
    /* determine whether to check based on the given days */
    if (keep_days == KEEP_INFINITE)
    {
        check_days = false;
        strncpy(days_str, "INFINITE", lengthof(days_str));
    }
    else
    {
        check_days = true;
        snprintf(days_str, lengthof(days_str),
                "%d", keep_days);
        /*
         * Calculate the threshold day from given keep_days.
         * Any backup taken before this threshold day to be
         * a candidate for deletion.
         */
        tim = current.start_time - (keep_days * 60 * 60 * 24);
        ltm = localtime(&tim);
        ltm->tm_hour = 0;
        ltm->tm_min  = 0;
        ltm->tm_sec  = 0;
        keep_after = mktime(ltm);
        time2iso(keep_after_timestamp, lengthof(keep_after_timestamp),
                    keep_after);
    }
…
}

       可以看到最重要的一行注释:Calculate the threshold day from given keep_days. Any backup taken before this threshold day to be a candidate for deletion.

       而所谓的threshold day是怎么算的 —— tim = current.start_time - (keep_days * 60 * 60 * 24);

       以20230809为例,当keep-data-days=1,则threshold day为当前时间减1,即20230808。而在阈值日期之前的备份才是过期的,因此20230808不属于,自然也就不会被删除。而20230807就属于过期的文件,因此在备份完成后,它会被删除。

3. 如何只保留当天的备份

      有了上面的分析,其实就很简单了,就是设置keep-data-days=0。threshold day为当前时间减0,即20230809,因此当天之前的备份都是过期的,备份完成后也就会删除20230808的文件。简单测试一把:

pg_rman backup -b ${BACKUP_TYPE}  -s -C -Z -P --keep-data-days=0 --keep-arclog-files=…(非完整命令)

​​​​​​​

符合预期~

今天将由于需要就将我的SQL 2008升级到SQL 2008 R2. 说到为什么要升级是因为,从另一台机器上备份了一个数据库,到我的机器上还原的时候提示“System.Data.SqlClient.Sqlerror:该数据库是在运行版本10.50.2500的服务器上备份的,该版本与此服务器(运行版本10.00.1600)不兼容。请在支持该备份的服务器上还原数据库,或者使用与此服务器兼容的备份。” 经过一番查证得知: 所谓的10.00.1600其实就是SQL 2008 10.50.1600其实就是SQL 2008 R2 10.50.2500其实就是SQL 2008 R2 SP1 这样一来基本就明了了。 我得升级自己的数据库到SQL 2008 R2 SP1。 这篇文章就把我先升级到SQL 2008 R2的过程详细录下来,下一篇文章会介绍升级R2到R2 SP1. 第一步:准备安装程序。 首先SQL 2008是安装好的 因此只需要下载SQL 2008 R2安装程序,下载地址如下:http://care.dlservice.microsoft.com/dl/download/1/E/6/1E626796-588A-495C-917B-321093FB98EB/2052/SQLFULL_x86_CHS.exe?lcid=2052&ptype=pcare 第二步:升级开始。SHOW TIME!!! 1、如果是从SQL2008升级到SQL2008R2那么只能选择左侧“安装”对应右侧“从SQL SERVER 2000,SQL 2005或SQL 2008升级”这个选项来升级。 大家也注意到有一个“维护”但是这个选项是“从SQL 2008其他例如EXPRESS版本升级” 在此,要区分清楚。 2、安装程序支持规则检查。通过之后就继续下一步。 3、输入产品密钥,这个地方,你的密钥是什么版本的,装完之后你的数据库就是什么版本:像企业版,开发版等等等。 4、许可条款必须接受,不然人家不让用啊~~~ 5、安装程序支持文件。 6、程序支持规则安装完成后程序会自动检测安装的文件是否满足需求。 7、当你的服务器中只有一个实例的时候,你很难听到实例这个词,人们都直接叫他“数据库”了。只有在服务器上安装的实例数目超过两个的时候你才会听到“实例”二字比较多。 但是“实例”肯定是学习数据库过程中必须熟知的东东!!! 此处,选择你想要升级的实例。下一步就行了。 8、以前安装过的组件(component)都会出现在这里,不用管,以前有的,现在当然也要有,闭着眼睛点击“下一步”吧! 9、因为是升级安装,所以你以前的实例名字是什么,这里还是什么。继续“下一步”。 10、不废话,“下一步”。 11、是否发送错误报告,随便,下一步。 12、“下一步”。 13、点击“升级”按钮进行升级,中途等待大约20-30分钟就完成了。 升级过程中如图: 14、安装成功要求重新启动。重启吧没的说!! 15、重启完毕,启动SSMS(SQL SERVER MANAGEMENT STUDIO)在登陆界面上就会立马察觉到不同,SQL 2008变成了SQL 2008 R2. 16、连接上数据库引擎,在左侧导航栏就可以看到你数据库的版本了。这次变成了10.50.1600。如果还要升级到10.50.2500。那就继续安装一个升级补丁吧! 至此,10.00.1600升级10.50.1600已经成功完成。 总结一下: 10.00.1600就是SQL SERVER 2008 10.50.1600就是SQL SERVER 2008 R2 这篇博文里讲的是升级安装,如果你要进行全新安装,请按照如下操作: 一、卸载SQL SERVER 2008,一定要卸载,数据库不像其他常用的应用程序(那些程序会自动检测是否有旧版本,然后给你卸载并升级)。 另:对SQL来说,如果你安装好之后,再进行一次安装的话,实际上安装的是另外一个实例。 二、卸载完之后就安装就行了。执行的是安装---全新安装。 其他细节参考我的博文:SQL SERVER 2008安装(在实例、权限等方面,SQL 2008和SQL 2008 R2是一样的)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hehuyi_In

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值