如何避免定时删除备份作业执行后,无备份文件存在

【问题描述】

达梦数据库可设置定时删除备份作业,但若运维人员长期未进行备份检查,且因某故障导致数据库近期无备份文件产生,此时执行定时删除备份作业,会导致数据库中无备份文件。

例如:定时删除备份作业为删除 7 天前的备份集,如果在 7 天内没有产生新的备份,或者说备份作业因为种种原因失效,此时删除 7 天前的备份集将会导致数据库失去备份冗余,如果此时发生数据库误操作或者其他需求,若没有数据库备份,将很难实现回退数据库至某一时间点。

【问题原因】

该问题的根本原因是定时删除备份作业仅按时间策略删除旧备份,而不会检查是否存在有效的新备份,一旦新备份因故障未能生成,旧备份被删除后数据库将彻底失去备份冗余。

【问题解决】

以下提供三种方式来解决该问题,采用存储过程和作业策略的方式,保证在存在一定数量的备份集时再删除部分备份集。

方式一:创建存储过程进行判断,在符合判断条件下(存在一定数量的备份集)再删除备份集,替换原有的定时删除作业,每天定时执行。存储过程举例如下:

DECLARE                            --此过程避免在定时备份执行失败时删除全部备份集,此过程建议每天定时执行,替代原有的单一删除一定时间前备份集的删除策略
        CON           INTEGER;     --备份集数量
        BACKUPSETNAME VARCHAR(100);--最近一个备份集名字
        CHECK_FLAG    INTEGER;     --备份校验标记
BEGIN
        --添加备份路径   /opt/dmdbms/data根据现场实际需求进行配置
        CALL SF_BAKSET_BACKUP_DIR_ADD('disk', '/opt/dmdbms/data');
        --赋值CON为本库全量备份集数量
        select
                count(*)
        INTO
                CON
        from
                V$BACKUPSET
        where
                true
            and "TYPE"       =0
            AND "RANGE#"     =1
            AND "OBJECT_NAME"=
                (
                        select sys_context('USERENV', 'DB_NAME') from dual
                );
        --判断是否存在可用全库备份集,具体配置请合理评估后决定  CON值至少大于1,至少保留一次备份
        IF CON > 2 THEN
                --赋值BACKUPSETNAME为本库最近一次全量备份集名称
                select
                        BACKUP_PATH
                INTO
                        BACKUPSETNAME
                from
                        V$BACKUPSET
                where
                        true
                    and "TYPE"       =0
                    AND "RANGE#"     =1
                    AND "OBJECT_NAME"=
                        (
                                select sys_context('USERENV', 'DB_NAME') from dual
                        )
                order by
                        BACKUP_TIME desc LIMIT 1;
                --对本库最近一次全量备份集进行备份有效性校验
                SELECT
                        SF_BAKSET_CHECK('DISK', BACKUPSETNAME)
                INTO
                        CHECK_FLAG
                FROM
                        DUAL;
                IF CHECK_FLAG = 1 THEN
                        --删除一定时间以前的备份
                        call SP_DB_BAKSET_REMOVE_BATCH('DISK', SYSDATE-180);
                END IF;
        END IF;
END;

方式二:配置定时作业,将方式一中的存储过程配置到定时作业中。

第一步:右键作业 -> 新建作业 -> 常规配置。

第二步:配置作业步骤 -> 添加,其中步骤类型选择"SQL 脚本",脚本语句就是创建的存储过程语句。

创建代理作业需要注意的是 sql 脚本的长度有精度限制,如果报错字符串截断,创建时删除一部分注释即可。

第三步:配置作业调度 -> 新建,这里配置为每天凌晨 1 点执行,点击确定完成作业配置。

注意

建议配置该作业调度为每天一次,如长时间没有执行该作业,可手动执行。但手动执行前此存储过程前,请提前进行数据备份,避免备份文件全部被删除。

方式三:配置作业在全量备份执行成功后进行删除备份操作,若全量备份执行失败,则结束作业。

第一步:新建全量备份作业。

第二步:设置作业步骤为完全备份。

第三步:点击"高级"设置成功时"报告执行成功并继续执行下一步",以及失败时"报告执行失败并结束作业"。

第四步:在作业步骤中添加删除备份作业,并设置作业步骤。

也可在高级中设置成功时"报告执行成功并结束作业",以及失败时"报告执行失败并结束作业"。方便我们在历史作业信息中查看备份情况。

第五步:设置作业调度,进行测试,设置作业每隔 2 分钟执行一次。(具体调度时间以实际需求为准,此设置只为进行测试)。

测试结果:全量备份失败时,不执行删除备份操作;全量备份成功时,进行下一步的删除备份操作。

以上三种方式均可避免定时任务清空备份集,其中前两种方式本质都是利用了存储过程来检查,当存在一定数量的备份集时再删除部分备份集;第三种方式则是使用了作业策略,每次删除操作都是在最新的备份成功后再执行,即可避免清空备份集。