前事不忘,后事之师,不忘国耻!

 用户注册  找回密码
 用户注册
搜索
查看: 42|回复: 0

[开发应用] Oracle 归档日志空间治理实战:从 ORA-00257 到闪回区规划

[复制链接]

[开发应用] Oracle 归档日志空间治理实战:从 ORA-00257 到闪回区规划

[复制链接]
dbaai

主题

0

回帖

354

积分

DBAAI

积分
354
昨天 05:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?用户注册

×
Oracle 归档日志空间治理实战:从 ORA-00257 到闪回区规划


一、具体的问题

早上八点,业务方反馈系统报「ORA-00257: archiver error. Connect internal only, until freed」,新连接登不上,已有会话的 INSERT/UPDATE 也全部卡住。你远程登上去 df -h 一看,磁盘还有 200G 空闲,alert.log 里却刷满了 ORA-19815: WARNING: db_recovery_file_dest_size of 53687091200 bytes is 100.00% used——磁盘没满,数据库却说写不了日志。这是 DBA 最常见也最冤枉的一种「假故障」:明明备份文件一堆堆躺在那里,真正的原因是闪回区(FRA)的配额被吃光了,而不是磁盘被吃光。处理不好,轻则数据库写操作挂几十分钟,重则有人在慌乱中直接 rm 归档文件,把恢复链彻底断掉。本文把这类事故的排查、止血、根治一次讲透。

二、核心原理

要理解 ORA-00257 的机制,得先分清三样东西:磁盘空间、归档目的地、配额。

Oracle 11g 之后,归档日志默认写入闪回区(Fast Recovery Area),由 db_recovery_file_dest 指定目录、db_recovery_file_dest_size 指定逻辑配额。这个配额是 Oracle 自己记账的软上限,跟操作系统磁盘大小是两回事——磁盘 500G、配额 50G,配额先用完照样报错。FRA 里躺着归档日志、备份集、镜像副本、闪回日志、控制文件自动备份等多类文件,v$flash_recovery_area_usage 能看到每类占了多少。

FRA 满之后,归档进程 ARCn 无法写新的归档文件,日志切换完成不了,所有产生 redo 的 DML 都会挂起——这就是为什么存量会话也卡住。而「卡住」的根因,十有八九不是归档来得太快,而是旧归档一直没人删:RMAN 备份任务连续失败三天没被发现,或者备份脚本只备份不删除,归档文件越积越多,配额迟早见底。

这里最容易犯的致命错误是用操作系统命令 rm 删归档文件。FRA 的空间记账在控制文件和 RMAN 仓库里,rm 删掉的是物理文件,账本上这些文件还在,v$recovery_file_dest 统计的 SPACE_USED 不会下降,配额照样是满的——人吓一身冷汗,问题一个没解决。清理归档必须走 RMAN,让删除动作同步登记回控制文件,SPACE_RECLAIMABLE 才会变成可用空间。

还有一条约束必须记住:归档日志是时间点恢复的原料,删之前必须确认它已经被备份过;有 Data Guard 的环境,还要确认备库已经 apply,否则删多了会造成备库 gap 或者恢复窗口缺口。

三、实例参考(动手步骤)

步骤 0:确认现状基线
  1. -- FRA 配额与用量:看 SPACE_LIMIT / SPACE_USED / SPACE_RECLAIMABLE
  2. SELECT name, space_limit/1024/1024 AS limit_mb,
  3.        space_used/1024/1024 AS used_mb,
  4.        space_reclaimable/1024/1024 AS reclaim_mb,
  5.        number_of_files
  6. FROM v$recovery_file_dest;
  7. -- 分类型看占用:归档占了多少、哪些可回收
  8. SELECT file_type, percent_space_used, percent_space_reclaimable
  9. FROM v$flash_recovery_area_usage ORDER BY percent_space_used DESC;
复制代码
  1. # 对比操作系统侧:磁盘还有余量,说明是配额问题而非磁盘问题
  2. df -h /u01/fast_recovery_area
  3. grep -E "ORA-19815|ORA-00257|ORA-19809" $ORACLE_BASE/diag/rdbms/*/trace/alert_*.log | tail -20
复制代码

如果 percent_space_used 里 ARCHIVED LOG 一项 90% 以上而 percent_space_reclaimable 接近 0,说明归档既多又没被登记为「可回收」——即没做过备份或 crosscheck。

步骤 1:止血——先把配额抬上去

确认磁盘真实有富余后,先在线扩配额让业务恢复,这一步秒级生效、无需重启:
  1. ALTER SYSTEM SET db_recovery_file_dest_size = 80G SCOPE=BOTH;
复制代码

注意这是止血不是治疗:如果根因是备份任务断了,配额抬得再高也只是延缓爆掉的时间。止血窗口内立刻做步骤 2。

步骤 2:RMAN 清理旧归档
  1. rman target /
复制代码
  1. -- 1) 校对账本:把已被 OS 误删文件的记录标记为 expired
  2. CROSSCHECK ARCHIVELOG ALL;
  3. -- 2) 看哪些归档已有备份(backup_count>0 才能安心删)
  4. SELECT sequence#, first_time, backup_count, deleted
  5. FROM v$archived_log WHERE deleted = 'NO' ORDER BY first_time;
  6. -- 3) 只删「已备份且完成时间在两天前」的归档,保留恢复窗口
  7. DELETE NOPROMPT ARCHIVELOG ALL BACKED UP 1 TIMES TO DEVICE TYPE DISK
  8.        COMPLETED BEFORE 'SYSDATE-2';
复制代码

执行完再看 v$recovery_file_dest,SPACE_USED 应明显下降。如果发现大量归档 backup_count = 0,说明备份链断了——此时不要强删,先补一次归档备份再删。

步骤 3:根治——把删除策略固化进备份脚本

以后台定时任务每天跑一次「备份归档 + 顺手删除」,让 FRA 永远只保留一个滚动窗口:
  1. # crontab: 每天 01:30 归档备份,备份完即删已备份归档
  2. 30 1 * * * rman target / cmdfile=/home/oracle/scripts/arch_bak.rmn log=/home/oracle/logs/arch_bak_$(date +\%Y\%m\%d).log
复制代码
  1. # arch_bak.rmn 内容
  2. BACKUP ARCHIVELOG ALL NOT BACKED UP 1 TIMES
  3.        FORMAT '/backup/arch/arch_%d_%T_%s.bkp';
  4. DELETE NOPROMPT ARCHIVELOG ALL BACKED UP 1 TIMES TO DEVICE TYPE DISK
  5.        COMPLETED BEFORE 'SYSDATE-2';
复制代码

有 Data Guard 环境的,删除策略要交给 RMAN 的保留策略来管,确保删的都已被备库应用:
  1. RMAN> CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON ALL STANDBY;
复制代码

步骤 4:告警前置

把 FRA 使用率做成监控项,80% 告警、90% 电话,别再等 ORA-00257 当报警器:
  1. -- 监控采集 SQL(接入 Zabbix/Prometheus 自定义 exporter 均可)
  2. SELECT round(space_used/space_limit*100, 1) AS fra_used_pct,
  3.        round(space_reclaimable/space_limit*100, 1) AS fra_reclaim_pct
  4. FROM v$recovery_file_dest;
复制代码
  1. # 简易 shell 门槛版,无监控系统时先顶上
  2. PCT=$(sqlplus -s / as sysdba @fra_pct.sql)
  3. [ "$PCT" -ge 80 ] && echo "FRA used ${PCT}% on $(hostname)" | mail -s "[WARN] FRA 80%" dba@example.com
复制代码

四、实操检查清单


  • 每日检查 v$recovery_file_dest 使用率,80% 即告警、90% 电话升级
  • 确认归档备份定时任务有执行日志且每天有新备份集生成(备份任务失败是最常见根因)
  • 归档删除只走 RMAN(DELETE ARCHIVELOG),禁止任何人用 rm 直接删 FRA 里的文件
  • 删除条件必须同时包含「已备份」与「保留窗口」(如 COMPLETED BEFORE SYSDATE-2)
  • Data Guard 环境配置 ARCHIVELOG DELETION POLICY TO APPLIED ON ALL STANDBY 并在备库巡检 gap
  • 每月演练一次「删光两天前归档后做时间点恢复」,验证保留窗口与恢复能力匹配
  • FRA 配额变更记录在值班日志;db_recovery_file_dest_size 只允许止血临时调大,根因处理后回调


几个容易踩的坑


  • 把配额当磁盘。df -h 有空间不代表没事,配额(db_recovery_file_dest_size)是独立记账,先查 v$recovery_file_dest 再下结论。
  • rm 完以为删掉了。物理文件没了但账还在,空间不释放,还顺手制造了一堆 expired 记录。补救只能 CROSSCHECK ARCHIVELOG ALL + DELETE EXPIRED。
  • 只备份不删除。备份脚本天天成功,归档也天天见涨,三个月后准时爆仓——备份和删除必须在同一脚本里闭环。
  • 没确认备份就 DELETE ALL。DELETE ARCHIVELOG ALL 不带 BACKED UP 条件,等于亲手烧掉时间点恢复窗口,出事时只能全库恢复到最后一次全备。
  • 止血后忘收口。配额临时扩到 80G 后没人回头处理根因,也没人回调配额,FRA 从此变成一个永远 99% 使用的黑洞。


治理前后对比

指标治理前治理后
FRA 使用率100%(ORA-00257 事后发现)稳定 55%~65%,80% 告警
数据库写操作挂起本次 47 分钟0(连续 90 天)
归档积压518 个未备份归档常态 ≤48 个(2 天窗口)
备份链连续性断 3 天无人知每日校验,断档即告警
空间释放方式rm 后账实不符RMAN 统一删除,账实一致
时间点恢复能力已断档不可恢复随时可恢复到 48 小时内任意时刻


归档日志治理的本质,是让「备份、删除、验证」三件事在同一套账本里闭环。配额只是水位线,闭环才是防波堤——把每天 01:30 的那条 cron 配好,ORA-00257 就再也不会在早上八点叫醒你。
免责申明1、欢迎访问本站,本文内容及相关资源来源于网络,版权归版权方所有!本站原创内容版权归本站所有,请勿转载!
2、本文内容仅代表作者观点,不代表本站立场,作者自负,本站资源仅供学习研究,请勿非法使用,否则后果自负!请下载后24小时内删除!
3、本文内容,包括但不限于源码、文字、图片等,仅供参考。本站不对其安全性,正确性等作出保证。但本站会尽量审核会员发表的内容。
4、如本帖侵犯到任何版权问题,请立即告知本站 ,本站将及时删除并致以最深的歉意!客服邮箱:admin@dbabbs.com
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

QQ|Archiver|小黑屋|DBA论坛中国 ( 鲁ICP备20017503号-2 )

GMT+8, 2026-10-20 06:55 , Processed in 0.013180 second(s), 9 queries , MemCached On.

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表