应解析RMAN日志中三类关键行:含ORA-/RMAN-错误码的行、Finished backup at/Finished recover at、Recovery Manager complete.;三者需同时满足且无报错才判定成功。
怎么从RMAN日志里准确判断备份是否成功
rman本身不返回标准的0/1退出码,rman进程只要没崩溃就常返回0,哪怕备份实际失败(比如归档丢失、磁盘满、控制文件不一致)。不能只看$?,必须解析日志内容。
关键不是找“completed”这种模糊词,而是盯住三类行:
- 含
ORA-或RMAN-的错误行(如RMAN-03009、ORA-19566) - 最后几行中是否出现
Finished backup at(全库/表空间级)或Finished recover at(恢复场景) - 是否有
Recovery Manager complete.且前面无报错——这个才是真正的收尾信号
示例日志片段:
channel ORA_DISK_1: backup set complete, elapsed time: 00:02:17 Finished backup at 18-APR-2024 03:15:22 Starting Control File and SPFILE Autobackup at 18-APR-2024 03:15:22 piece handle=/u01/backup/c-123456789-20240418-01 comment=NONE Finished Control File and SPFILE Autobackup at 18-APR-2024 03:15:23 Recovery Manager complete.
如果中间夹着 RMAN-03009: failure of backup command on ORA_DISK_1 channel,哪怕最后有 Recovery Manager complete.,也得判为失败。
Shell脚本里怎么安全截取并分析RMAN日志
别用 tail -n 20 这种固定行数方式——日志长度波动大,容易漏掉关键错误。稳妥做法是:先定位最后一段执行块,再从中提取状态。
实操建议:
- 运行
rman时强制重定向到独立日志文件,加时间戳避免覆盖:rman target / @backup.rman > /u01/log/rman_$(date +\%Y\%m\%d_\%H\%M).log 2>&1 - 用
awk '/^RMAN>/ {in_rman=1; next} /^$/ && in_rman {in_rman=0; next} in_rman' $log提取最后一次RMAN交互块(跳过SQL*Plus输出等干扰) - 检查是否存在
ORA-或RMAN-错误:用grep -q 'ORA-\|RMAN-' $log,但注意要限定在有效块内,否则可能匹配到旧日志残留 - 确认成功标志:用
awk '/Finished backup at/ || /Finished recover at/ {ok=1} /Recovery Manager complete./ && ok {print "SUCCESS"; exit 0} END {if (!ok) print "NO_FINISH_LINE"}' $log
发邮件时怎么避免告警噪音和漏报
单纯“失败就发邮件”会导致两种问题:一是磁盘满导致连续失败,每小时一封;二是静默失败(比如备份脚本被kill但日志没写完),邮件根本没触发。
关键控制点:
- 用临时锁文件防重复发送:
if [ ! -f /tmp/rman_alert_sent_$(date +\%Y\%m\%d) ]; then touch /tmp/rman_alert_sent_$(date +\%Y\%m\%d); echo "fail" | mail -s "RMAN FAIL $(date)" admin@company.com; fi - 对“部分成功”做分级:归档备份失败但数据文件备份OK,可降级为警告邮件,不进P1告警通道
- 必须校验日志文件是否非空且最后修改时间在预期窗口内(比如10分钟内),防止脚本异常退出没生成日志却误判为成功
- 邮件正文必须带日志路径和最近3行错误(用
tail -n 3 $log | grep -E '(ORA-|RMAN-|ERROR)'),不然运维没法快速定位
Oracle版本和RMAN配置对日志格式的影响
11g 和 19c 的 rman 日志结构差异不小:11g 默认不打印通道详细耗时,19c 加了 input bytes read 等字段;而且12c+引入了CONFIGURE RETENTION POLICY自动清理,可能让旧日志被delete obsolete命令覆盖。
所以脚本里要留兼容余地:
- 别硬编码匹配
input bytes read—— 11g日志里根本没有这行 - 检查
show all;输出中的RETENTION POLICY设置,若为TO RECOVERY WINDOW OF 7 DAYS,则日志保留期受此影响,不能假设所有日志都在同一目录存满7天 - 使用
set echo on在RMAN脚本开头,确保命令本身写入日志,方便回溯执行了哪条语句 - Oracle 18c+ 支持
SET COMMAND ID,可在日志里打标记,比如SET COMMAND ID TO 'FULL_BACKUP_20240418';,后续用grep 'FULL_BACKUP_20240418'定位更准
最麻烦的是RMAN在NOARCHIVELOG模式下不报错直接跳过归档备份,日志里连“skipped”都不写——这种必须提前用 select log_mode from v$database; 校验模式,不能依赖日志分析兜底。

















