问题背景
某日收到业务反馈,数据库查询延迟增大,部分报表数据不准确。经排查发现,Data Guard 备库的归档日志目录已满,导致备库无法接收和应用新的归档日志,同步中断。
问题现象
1. 备库归档日志空间告警
登录备库,检查闪回恢复区使用情况:
SELECT
name,
space_limit / 1024 / 1024 / 1024 AS total_gb,
space_used / 1024 / 1024 / 1024 AS used_gb,
ROUND((space_used / space_limit) * 100, 2) AS pct_used
FROM v$recovery_file_dest;
结果:
| 指标 | 值 | 状态 |
|---|---|---|
| 总空间 | 20 GB | 初始配置 |
| 已使用 | 19.93 GB | 几乎占满 |
| 使用率 | 99.65% | ⚠️ 危险阈值 |
2. 备库同步状态异常
SELECT database_role, open_mode, protection_mode FROM v$database;
备库处于 MOUNTED 状态,但日志应用进程停滞。
SELECT process, status, sequence# FROM v$managed_standby;
MRP0 进程状态显示 WAIT_FOR_GAP,表示等待归档日志。
根因分析
归档日志空间满的原因通常有以下几个:
| 原因 | 说明 |
|---|---|
| 闪回恢复区过小 | 初始配置仅为 20GB,远小于归档日志生成速度 |
| 未配置自动清理策略 | 归档日志被应用后未自动删除,长期累积导致空间不足 |
| 业务高峰期日志量激增 | 特定时段产生大量归档日志,超出日常估算 |
核心问题:闪回恢复区(Fast Recovery Area,FRA)空间不足,MRP 进程无法接收新的归档日志。
解决过程
第一阶段:清理归档日志(紧急恢复)
查看闪回恢复区目录结构,定位归档日志位置:
cd /app/oracle/fast_recovery_area/PDMDB1/PDMDB1
du -sh *
使用 RMAN 清理已被应用的历史归档日志:
rman target /
sql
-- 删除已被应用且超过 7 天的归档日志
DELETE ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-7';
清理结果:
| 指标 | 清理前 | 清理后 |
|---|---|---|
| 使用率 | 99.65% | 20.36% |
| 已使用空间 | 19.93 GB | 61.07 GB * |
| 可用空间 | 0.07 GB | 238.93 GB |
*> 注:清理后闪回恢复区显示 61.07 GB,是因为归档日志从 99% 降到了正常范围,部分闪回日志仍保留。
第二阶段:恢复同步
清理空间后,重新启动备库的日志应用进程:
sql
-- 取消当前日志应用
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
-- 重新启动日志应用
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
第三阶段:确认同步恢复
执行以下检查,确认同步已正常恢复:
sql
-- 1. 确认无日志缺口
SELECT * FROM v$archive_gap;
-- 2. 确认日志已应用
SELECT thread#, MAX(sequence#) AS last_applied
FROM v$archived_log
WHERE applied='YES'
GROUP BY thread#;
-- 3. 查看 MRP 进程状态
SELECT process, status, sequence# FROM v$managed_standby;
确认结果:
| 检查项 | 结果 | 状态 |
|---|---|---|
V$ARCHIVE_GAP |
no rows selected |
✅ 无缺口 |
| 最新已应用日志 | SEQUENCE# 56809 | ✅ 持续更新 |
| 数据文件时间戳 | 更新至当前时间 | ✅ 同步正常 |
第四阶段:扩容闪回恢复区(根治措施)
4.1 确认磁盘空间
df -h /app/oracle/fast_recovery_area
确认磁盘可用空间大于目标容量。
4.2 扩容
ALTER SYSTEM SET db_recovery_file_dest_size = 300G SCOPE=BOTH;
4.3 验证扩容结果
SHOW PARAMETER db_recovery_file_dest_size;
SELECT
name,
ROUND(space_limit / 1024 / 1024 / 1024, 2) AS total_gb,
ROUND(space_used / 1024 / 1024 / 1024, 2) AS used_gb,
ROUND((space_used / space_limit) * 100, 2) AS pct_used
FROM v$recovery_file_dest;
扩容后结果:
| 指标 | 扩容前 | 扩容后 |
|---|---|---|
| 总空间 | 20 GB | 300 GB |
| 使用率 | 99.65% | 6.67% |
| 可用空间 | 0.07 GB | 约 280 GB |
第五阶段:配置自动清理策略
在 RMAN 中配置归档日志自动删除:
rman target /
-- 配置归档日志删除策略:备库应用后自动删除
CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON STANDBY;
预防措施总结
| 预防措施 | 配置方法 | 效果 |
|---|---|---|
| 扩容闪回恢复区 | ALTER SYSTEM SET db_recovery_file_dest_size = 300G |
从根本上解决空间不足问题 |
| 自动清理已应用日志 | CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON STANDBY |
日志应用后自动删除,避免累积 |
| 定期空间监控 | 监控 v$recovery_file_dest 使用率 |
提前预警,避免被动 |
| 设置闪回保留时间 | ALTER SYSTEM SET db_flashback_retention_target = 720 |
控制闪回日志保留时长 |
监控建议
建议建立自动化监控,每周执行以下 SQL:
SELECT
name,
ROUND(space_limit / 1024 / 1024 / 1024, 2) AS total_gb,
ROUND(space_used / 1024 / 1024 / 1024, 2) AS used_gb,
ROUND((space_used / space_limit) * 100, 2) AS pct_used
FROM v$recovery_file_dest;
当 pct_used > 80% 时触发告警,提前介入处理,避免再次发生归档日志空间写满导致同步中断的问题。
总结
归档日志空间满导致 Data Guard 同步中断,是 DBA 运维中常见的问题。本例中,通过清理历史日志 快速恢复业务,再通过扩容 和配置自动清理策略彻底解决问题。
核心经验:
-
及时监控:闪回恢复区使用率应纳入日常巡检
-
合理规划:初始配置应考虑业务增长,避免反复调整
-
自动运维:配置 RMAN 自动删除策略,减少手工干预
希望这篇文章能帮助遇到同样问题的 DBA 同行快速定位和解决问题。
相关命令速查:
| 操作 | 命令 |
|---|---|
| 查看 FRA 使用率 | SELECT ... FROM v$recovery_file_dest; |
| 查看 GAP | SELECT * FROM v$archive_gap; |
| 重启 MRP | ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT; |
| 扩容 FRA | ALTER SYSTEM SET db_recovery_file_dest_size = 300G SCOPE=BOTH; |
| 配置自动删除 | CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON STANDBY; |