🎉 1.5 Oracle数据库重做日志检查
Oracle 重做日志(Redo Log)是数据库恢复的核心组件,记录所有数据变更操作。在日常巡检中,检查重做日志的状态、配置和切换频率是保障数据库高可用性的关键环节。以下从多个维度给出检查方法和优化建议。
一、重做日志的作用
- 实例恢复:当数据库意外宕机时,通过重做日志将已提交但未写入数据文件的事务前滚。
- 介质恢复:配合归档日志,可将数据库恢复到任意时间点。
- LogMiner 分析:基于重做日志进行数据变更审计。
二、检查重做日志组状态
1. 查看日志组基本信息
SELECT group#, sequence#, bytes/1024/1024 AS size_mb, members, status, archived, first_time
FROM v$log
ORDER BY group#;
字段说明:
group#:日志组编号sequence#:当前日志序列号(递增)size_mb:日志文件大小(MB)members:该组包含的日志成员数-
status:CURRENT:当前正在写入的日志组ACTIVE:日志组包含的事务尚未完成检查点,实例恢复需要INACTIVE:日志组已归档且检查点已完成,可被复用UNUSED:新创建的日志组尚未使用
archived:YES 表示已归档,NO表示未归档first_time:日志组首次被写入的时间
2. 查看日志成员详细信息
SELECT group#, member, status, type
FROM v$logfile
ORDER BY group#;
status:INVALID 表示文件不可用,STALE 表示内容不一致,正常应为空或ACTIVE。type:ONLINE 表示在线日志,STANDBY表示备用库日志。
三、检查日志切换频率
频繁的日志切换会增加 I/O 开销和归档压力,通常建议切换间隔 15~30 分钟 为宜。
1. 查看最近一天的切换次数
SELECT TO_CHAR(first_time, 'YYYY-MM-DD') day,
COUNT(*) switches
FROM v$log_history
WHERE first_time >= SYSDATE - 1
GROUP BY TO_CHAR(first_time, 'YYYY-MM-DD')
ORDER BY day;
2. 计算平均切换间隔(秒)
WITH times AS (
SELECT first_time, LAG(first_time) OVER (ORDER BY first_time) prev_time
FROM v$log_history
WHERE first_time >= SYSDATE - 1
)
SELECT ROUND(AVG((first_time - prev_time) * 86400)) avg_interval_sec
FROM times
WHERE prev_time IS NOT NULL;
3. 查看当前日志已使用时间
SELECT group#, sequence#,
ROUND((SYSDATE - first_time) * 86400) seconds_active
FROM v$log
WHERE status = 'CURRENT';
四、归档模式检查
对于生产库,通常需要开启归档模式以保证恢复能力。
1. 检查归档状态
ARCHIVE LOG LIST;
或
SELECT log_mode FROM v$database;
2. 查看归档日志生成量
SELECT TRUNC(completion_time) day,
ROUND(SUM(blocks * block_size) / 1024 / 1024 / 1024, 2) size_gb,
COUNT(*) count
FROM v$archived_log
WHERE completion_time >= SYSDATE - 7
GROUP BY TRUNC(completion_time)
ORDER BY day;
五、重做日志配置优化建议
1. 组数与大小
-
组数:至少 3 组(LGWR 建议 3~6 组)。可用以下 SQL 查看当前组数:
SELECT COUNT(*) groups FROM v$log; - 大小:根据切换频率调整,目标每 15~30 分钟切换一次。若切换过于频繁(如 <5 分钟),需增加日志文件大小或组数。
2. 冗余配置
- 每个日志组至少 2 个成员,并分别存放于不同物理磁盘,避免单点故障。
-
检查成员分布:
SELECT group#, member, status FROM v$logfile ORDER BY group#;
3. 新增或调整日志组
-- 添加一个日志组(两个成员)
ALTER DATABASE ADD LOGFILE GROUP 4
('/u01/oradata/ORCL/redo04a.log', '/u02/oradata/ORCL/redo04b.log') SIZE 2G;
-- 删除一个日志组(不能删除 CURRENT/ACTIVE 组)
ALTER DATABASE DROP LOGFILE GROUP 3;
4. 调整日志成员(增加冗余)
-- 为现有组增加成员
ALTER DATABASE ADD LOGFILE MEMBER '/u02/oradata/ORCL/redo01b.log' TO GROUP 1;
六、常见问题与排查
| 问题 | 检查方法 | 解决方向 |
|---|---|---|
| 日志组频繁切换 | v$log_history 切换间隔 <5 分钟 |
增大日志文件大小或增加组数 |
| 日志组状态为 ACTIVE 且长期不切换 | 可能因检查点未完成 | 增大 fast_start_mttr_target 或调整 log_checkpoint_timeout |
| 归档日志空间满导致数据库挂起 | v$recovery_file_dest 使用率 >90% |
清理过期归档或增加 FRA 空间 |
| 日志成员状态 INVALID | v$logfile 中状态异常 |
检查磁盘 I/O,重建丢失成员 |
| 归档进程异常 | ARCHIVE LOG LIST 显示 Automatic archival 为 Disabled |
ALTER DATABASE ARCHIVELOG AUTO ON; |
七、一键巡检脚本(SQL*Plus)
sql
-- 重做日志配置概览
set pages 100 lines 200
col member for a50
prompt == 日志组状态 ==
select group#, sequence#, bytes/1024/1024 size_mb, members, status, archived, first_time
from v$log order by group#;
prompt == 日志成员状态 ==
select group#, member, status from v$logfile order by group#;
prompt == 当日切换次数 ==
select count(*) switch_today from v$log_history where first_time >= trunc(sysdate);
prompt == 最近切换间隔(秒)==
with t as (
select first_time, lag(first_time) over(order by first_time) prev_time
from v$log_history where first_time >= sysdate-1
)
select round(avg((first_time - prev_time)*86400)) avg_interval_sec
from t where prev_time is not null;
prompt == 归档状态 ==
archive log list;
将以上内容保存为 check_redo.sql,使用 @check_redo 执行即可快速获取重做日志的关键信息。
通过定期检查重做日志,可以提前发现潜在的 I/O 瓶颈、归档空间不足或冗余缺失问题,确保数据库的恢复能力和性能稳定。
阅读:144
发布时间: