Veeam 备份 Oracle RAC 失败,是归档删除脚本的锅!

Veeam 备份 Oracle RAC 失败,是归档删除脚本的锅!

前言

在 Oracle 数据库运维过程中,RMAN-06059 可以说是一个让 DBA 十分头疼的错误。很多人第一次看到这条报错时,都会下意识认为是 ASM 磁盘故障、归档日志被误删,或者 Veeam 本身存在 Bug。然而,当真正深入排查之后才会发现,导致这类问题的往往并不是单一组件,而是 RMAN Repository、归档删除策略以及第三方备份软件之间的协同机制出现了问题

最近在一套 Oracle 11.2.0.4 RAC 环境中,就遇到了这样一个典型案例。数据库使用 ASM 存储归档日志,通过 Veeam Plugin for Oracle RMAN 每天进行数据库备份。奇怪的是,备份任务连续数月每天失败,错误信息几乎完全一致,只是每天提示的归档日志 Sequence 略有不同。起初大家都认为是某几份归档日志缺失导致的普通故障,但随着排查不断深入,最终发现真正的问题远比想象中复杂,而整个分析过程也非常具有代表性。

故障现象

Veeam 每天执行数据库备份时都会返回类似下面的错误:

text 复制代码
RMAN-03002: failure of backup plus archivelog command

RMAN-06059: expected archived log not found,
loss of archived log compromises recoverability

ORA-19625: error identifying file
+ARCH/orcl/archivelog/2026_05_16/thread_1_seq_90376...

ORA-17503: ksfdopn:2 Failed to open file

ORA-15012: ASM file does not exist

有意思的是,第二天再次执行备份,报错中的 Sequence 又发生了变化。例如第一天提示的是 thread_1_seq_90370,第二天则变成了 thread_1_seq_90376。乍一看像是每天都有新的归档文件损坏,但仔细观察后发现,这些归档全部来自 2026 年 5 月中旬,说明 RMAN 一直在尝试访问一批历史归档,而不是当天新生成的归档日志。

很多 DBA 到这里都会认为是 ASM 中文件被误删,因此第一步通常都会进入 RMAN 检查 Repository 是否仍然保存着对应记录。然而执行 LIST ARCHIVELOG 后却发现,RMAN Repository 中已经查询不到这些 Sequence;继续执行 CROSSCHECK ARCHIVELOG,同样没有任何匹配结果。这意味着当前 Repository 已经不存在这些归档记录,那么 Veeam 为什么还能不断尝试读取它们?整个问题开始变得扑朔迷离。

排查过程

继续检查数据库服务器,很快发现 Oracle 用户下存在两套独立的归档清理脚本。其中一套脚本非常简单,核心逻辑只有一条命令:

rman 复制代码
DELETE FORCE ARCHIVELOG UNTIL TIME 'SYSDATE-3';

另一套脚本则更加复杂,它会先执行 CROSSCHECK ARCHIVELOG ALL,然后删除失效记录,再按照时间删除归档,最后还执行了一条 DELETE FORCE ARCHIVELOG UNTIL TIME 'SYSDATE-10'。看到这里,问题已经开始浮出水面。

DELETE FORCE ARCHIVELOG 与普通 DELETE ARCHIVELOG 最大的区别在于,它会绕过部分删除保护机制。也就是说,即使某些归档还没有完成第三方备份、还受到归档删除策略保护,或者正在被其他 RMAN 任务访问,FORCE 依然可能将这些归档直接删除。如果这种脚本与 Veeam 的 RMAN 备份任务在时间上发生重叠,就完全有可能出现这样一种场景:Veeam 刚刚扫描到需要备份的归档列表,另一边归档清理脚本已经将这些归档从 ASM 中删除,当 Veeam 真正开始读取归档时,ASM 返回文件不存在,于是最终抛出 RMAN-06059

不过,事情并没有这么简单。如果只是删除脚本导致归档缺失,那么 Repository 为什么又查询不到这些 Sequence?继续查看 V$ARCHIVED_LOG 后,真正的原因终于暴露出来。

真正的问题

查询 V$ARCHIVED_LOG 可以看到,大量 Thread 1 的历史归档仍然保留在控制文件中,而且这些归档具有几个共同特点:BACKUP_COUNT=1,说明它们曾经完成过一次 RMAN 备份;STATUS=X,表示这些归档已经被 CROSSCHECK 标记为失效;但是对应的 ASM 文件已经不存在。

这意味着 RMAN Repository 中长期积累了大量 Expired ArchiveLog ,只是其中一部分已经被清理,而另一部分仍然残留在控制文件中。随着 Veeam 每天重新执行 BACKUP DATABASE PLUS ARCHIVELOG,RMAN 都会继续扫描这些失效归档,因此每天都会停留在不同的 Sequence 上,看起来像是每天都有新的归档损坏,实际上只是每天碰到了下一条尚未清理的失效记录。

为了验证这一判断,我们执行了:

rman 复制代码
CROSSCHECK ARCHIVELOG ALL;

LIST EXPIRED ARCHIVELOG ALL;

结果令人吃惊,RMAN 一次性发现了一千多条失效归档记录。随后执行:

rman 复制代码
DELETE NOPROMPT EXPIRED ARCHIVELOG ALL;

RMAN 最终输出:

text 复制代码
Deleted 1030 EXPIRED objects

再次执行 LIST EXPIRED ARCHIVELOG ALL 后,Repository 已经不存在任何失效归档记录,这也说明控制文件中长期积累的无效元数据已经全部清理完成。

为什么会出现这种情况

整个案例真正的问题,并不是 Veeam 本身,也不是 Oracle 的 Bug,而是归档管理策略没有统一。数据库同时存在第三方备份软件和自定义 RMAN 删除脚本,两者都在管理归档日志,却互相不知道对方做了什么。归档清理脚本按照时间甚至使用 DELETE FORCE 强制删除归档,而 Veeam 又通过 BACKUP DATABASE PLUS ARCHIVELOG 去扫描 Repository。当 Repository 与 ASM 中的真实文件逐渐失去一致性之后,RMAN 就会不断尝试读取那些理论上存在、实际上已经消失的归档文件,最终导致备份持续失败。

更值得注意的是,本次环境中累计清理了 1030 条 Expired ArchiveLog。这意味着问题并不是某一天突然发生,而是长期存在,只是一直没有人去同步 RMAN Repository 与实际归档文件,最终导致失效记录越来越多,直到彻底影响第三方备份。

总结

这个案例给我们的启发其实非常明确。Oracle 的归档日志最好始终由同一套策略统一管理,如果已经使用 Veeam Plugin for Oracle RMAN、NetBackup 或其他第三方 RMAN 备份工具,就不建议再额外编写 DELETE FORCE ARCHIVELOG 一类的定时脚本。即使确实需要保留 RMAN 清理脚本,也应该严格依赖归档删除策略,只删除已经完成备份且满足恢复要求的归档,而不是简单按照时间甚至使用 FORCE 强制删除。

另外,CROSSCHECK ARCHIVELOG ALLDELETE NOPROMPT EXPIRED ARCHIVELOG ALL 并不是只在出现故障时才需要执行,它们更应该作为日常巡检的一部分,定期同步 RMAN Repository 与真实归档文件,避免无效记录不断积累。很多时候,RMAN-06059 并不是因为归档真的丢失,而是 RMAN Repository 已经无法准确反映真实的归档状态。只有理解这一点,才能真正解决这类问题,而不是一次次重试失败的备份任务。

相关推荐
互联网中的一颗神经元6 小时前
小白python入门 - 25. SQL 与表设计入门
数据库·python·sql
桐薇全肯定11 小时前
MySQL学生成绩管理系统实战操作
java·数据库·sql
这个DBA有点耶12 小时前
热点行更新:秒杀场景下一条UPDATE语句的锁等待与性能优化
数据库·sql·mysql·性能优化·database·dba
C语言Plus13 小时前
C++ SqlBuilder一个简单、灵活且类型安全的 C++ SQL 构建器库
数据库·sql·安全·c++20
白猫不黑15 小时前
SQL注入实战:手工注入全流程详解
网络·数据库·sql·web安全·网络安全·信息安全
想你依然心痛1 天前
用MySQL玩转数据可视化:从SQL查询到动态图表的完整实战
sql·mysql·信息可视化
向夏威夷 梦断明暄1 天前
基于Tez引擎的 Hive SQL 性能优化
hive·sql·性能优化
跟着珅聪学java2 天前
MERGE INTO开发教程
sql
这个DBA有点耶2 天前
交易型数据库是什么?OLTP核心能力与2026选型指南
数据库·数据仓库·sql·database·数据库架构·olap·dba