64-Oracle Redo Log

小伙伴们,关于数据库的redo log相信大家都操作很多次了,且这是OCM考试必考内容。Oracle Redo Log是一种特殊的日志文件,用于完整地记录数据库中所有数据变更的详细信息。当数据库执行插如、更新或删除等更新操作,这些操作并不会立刻写入数据库的实际数据文件。依赖WAL这个规则(所有关系型数据库几乎都是)变更会首先被记录到Redo Log文件中而后后台进程刷盘落库。

一、 Redo Log 核心功能与原理

1.1 核心功能 ​​
  • 数据持久性:记录所有数据变更(INSERT/UPDATE/DELETE/DDL),确保已提交事务不丢失。
  • 崩溃恢复:实例崩溃时,通过Redo Log前滚(Roll Forward)重做已提交事务,回滚(Roll Back)未提交事务。
  • 介质恢复:结合归档日志恢复损坏的数据文件。
  • 日志写先行(WAL)​:先写Redo Log到磁盘,再写数据文件,保证事务持久性。
1.2 技术原理

写入流程

  1. 事务执行生成 Redo 记录
  2. 写入 Log Buffer(SGA 中的循环缓冲区)
  3. LGWR 进程触发条件满足(事务提交/Buffer 满 1/3/3 秒超时)
  4. Redo 记录写入 Online Redo Log 文件
  5. 磁盘持久化(调用 fsync 强制刷盘)
  6. 通知事务完成
  7. DBWR 进程写入数据文件
1.3 日志结构​:
1.4 核心组件

|-------------------|------------------------------------|
| ​组件 | ​作用 |
| ​Redo Log Buffer​ | SGA中的循环缓冲区,临时存储redo条目(约10MB-15MB)。 |
| ​LGWR进程​ | 将Redo Log Buffer写入Redo Log文件。 |
| ​Redo Log文件​ | 物理文件组(通常3组),每组包含多个成员(镜像)。 |

1.5. 版本演进

|-------|-----------------------------------------------------------------|
| ​版本​ | ​演进特性​ |
| 9i​ | 引入LogMiner,支持Redo Log分析。 |
| ​10g | LOG_BUFFER自动计算(Granule机制), 默认值 ≈ max(512KB, 128KB * CPU_COUNT) |
| ​11g​ | 引入In-Memory Undo,减少恢复时间。 |
| ​12c | 多租户下每个PDB有独立Redo线程,支持Far Sync异步redo传输。 |
| ​19c​ | 优化Active Data Guard实时redo应用。 |

二. 实操脚本与验证​

​2.1 查看Redo配置
bash 复制代码
-- 查看Redo Log Buffer大小
SELECT * FROM v$sgainfo WHERE name IN ('Fixed SGA Size', 'Redo Buffers');
--
NAME                   BYTES RESIZEABLE       CON_ID
_________________ __________ _____________ _________
Fixed SGA Size       4922232 No                    0
Redo Buffers         4530176 No                    0

-- 查看Redo Log文件组
SELECT group#, bytes/1024/1024 size_mb, members, status 
FROM v$log;
--
SYS@CDB$ROOT> alter system switch logfile;
System altered.
SYS@CDB$ROOT> SELECT group#, bytes/1024/1024 size_mb, members, status
   FROM v$log;

   GROUP#    SIZE_MB    MEMBERS STATUS
_________ __________ __________ ___________
        1        200          1 CURRENT
        2        200          1 INACTIVE
        3        200          1 ACTIVE
2.2 Redo Log管理脚本(11g+)

2.2.1 创建与维护

bash 复制代码
-- 添加ASM存储的日志组(示例)
ALTER DATABASE ADD LOGFILE THREAD 1 GROUP 4 (
    '+DATA/redo04a.log',
    '+FRA/redo04b.log'
) SIZE 2G;

-- 验证日志组,所有日志组状态
SELECT group#, member, status FROM v$logfile;
   GROUP# MEMBER                                 STATUS
_________ ______________________________________ _________
        3 /opt/oracle/oradata/FREE/redo03.log
        2 /opt/oracle/oradata/FREE/redo02.log
        1 /opt/oracle/oradata/FREE/redo01.log
--
SELECT * 
FROM (
    SELECT
        l.GROUP# AS "Group ID",
        l.STATUS AS "Group Status",
        COUNT(f.MEMBER) AS "Members",
        ROUND(l.BYTES / POWER(1024, 2), 2) AS "Size (MB)",
        l.SEQUENCE# AS "Sequence"
    FROM v$log l
    JOIN v$logfile f ON l.GROUP# = f.GROUP#
    GROUP BY l.GROUP#, l.STATUS, l.BYTES, l.SEQUENCE#
)
ORDER BY "Group ID";
--
  Group ID Group Status       Members    Size (MB)    Sequence
___________ _______________ __________ ____________ ___________
          1 CURRENT                  1          200          79
          2 INACTIVE                 1          200          77
          3 INACTIVE                 1          200          78

-- 在线重定位日志文件-ASM自动处理重平衡
ALTER DATABASE RENAME FILE '+DATA/redo04b.log' 
    TO '+N_DG/redo04b.log';
2.2.2 大小调整
bash 复制代码
-- 通过替换组调整大小(官方手册)
ALTER DATABASE ADD LOGFILE GROUP 5 ('+DATA/redo05.log') SIZE 4G;
ALTER SYSTEM SWITCH LOGFILE; -- 执行直到旧组状态为INACTIVE
ALTER DATABASE DROP LOGFILE GROUP 4;
2.3. 观察redo(11g+)
bash 复制代码
-- 查找所有非正常状态的日志成员
SELECT *
FROM (
    SELECT
        l.GROUP# AS group_id,
        f.MEMBER AS file_path,
        f.STATUS AS member_status,
        l.STATUS AS group_status
    FROM v$log l
    JOIN v$logfile f ON l.GROUP# = f.GROUP#
)
WHERE member_status IS NOT NULL 
   OR group_status NOT IN ('INACTIVE', 'CURRENT');
--no rows selected

-- 日志文件状态验证
SELECT group#, status, archived, sequence#, 
bytes/1024/1024 size_mb
FROM v$log ORDER BY group#;
--
   GROUP# STATUS      ARCHIVED       SEQUENCE#    SIZE_MB
_________ ___________ ___________ ____________ __________
        1 CURRENT     NO                    79        200
        2 INACTIVE    YES                   77        200
        3 INACTIVE    YES                   78        200
2.4. 分析 Redo 性能的推荐方法(不使用事件跟踪)
bash 复制代码
-- LGWR瓶颈检测
SELECT event, total_waits, wait_class
FROM v$system_event 
WHERE event IN ('log file parallel write', 'log file sync');
--
EVENT                         TOTAL_WAITS WAIT_CLASS
__________________________ ______________ _____________
log file parallel write              9192 System I/O
log file sync                          62 Commit

-- 查看 Redo 生成统计
SELECT 
    stat.name AS metric,
    sess.value
FROM v$sesstat sess
JOIN v$statname stat ON sess.statistic# = stat.statistic#
WHERE sess.sid = (SELECT sid FROM v$mystat WHERE rownum = 1)
AND stat.name IN (
    'redo size', 
    'redo entries', 
    'redo writes',
    'redo synch time',
    'redo wastage'
);
--
METRIC                VALUE
__________________ ________
redo entries             20
redo size              7448
redo wastage              0
redo writes               0
redo synch time           0

-- 查看日志切换频率
SELECT 
    thread#,
    sequence#,
    (next_time - first_time) * 86400 AS duration_sec,
    blocks * block_size / 1024 / 1024 AS size_mb
FROM v$archived_log 
ORDER BY sequence# DESC 
FETCH FIRST 10 ROWS ONLY;
--
   THREAD#    SEQUENCE#                                  DURATION_SEC           SIZE_MB
__________ ____________ _____________________________________________ _________________
         1           78     4302.000000000000000000000000000000000003    29.21728515625
         1           77                                             0     0.00341796875
         1           76                                             5       42.83984375
         1           75                                             0     0.00439453125
         1           74     1699.000000000000000000000000000000000004          18.03125
         1           73                                             0      0.0029296875
         1           72                                             3    42.75048828125
         1           71    0.9999999999999999999999999999999999999996     0.00732421875
         1           70                                           176     0.13134765625
         1           69                                             7     0.01025390625

10 rows selected.
2.5. 监控 LGWR 行为的标准方法
bash 复制代码
-- 查看 LGWR 活动
SELECT 
    event,
    total_waits,
    time_waited_micro,
    average_wait
FROM v$system_event
WHERE event LIKE 'log file%';
--
EVENT                          TOTAL_WAITS    TIME_WAITED_MICRO    AVERAGE_WAIT
___________________________ ______________ ____________________ _______________
log file sequential read               140                54353            0.04
log file single write                   14                 8084            0.06
log file parallel write              10035              9100663            0.09
log file sync                           65                42242            0.06

-- 查看日志缓冲区使用率
SELECT 
    (SELECT value FROM v$sysstat WHERE name = 'redo buffer allocation retries') / 
    (SELECT value FROM v$sysstat WHERE name = 'redo entries') * 100 AS retry_pct
FROM dual;
--
  RETRY_PCT
____________
           0

四. 最佳实践(源于MOS文档)

4.1 配置规范

|------------|--------|-------|------------|--------------|
| ​环境​ | ​日志大小​ | ​组数 | ​存储​ | ​冗余策略​ |
| OLTP生产 | 2-4GB | 4+ | NVMe SSD | MULTIPLEX 3路 |
| RAC集群 | 2GB | 每实例3组 | ASM HIGH冗余 | FAILGROUP隔离 |
| 云环境(ExaCC) | 2GB | 4 | 持久内存+ASM | 跨可用域部署 |

4.2 优化设计
  1. 成员分离:日志组成员放置在不同物理磁盘,Redo Log文件放在高速低延迟存储(NVMe/RAID 10)
  2. 大小计算:日志大小(MB) = (每小时Redo量GB × 1024) / 目标切换次数
  3. 监控指标
  • 日志切换频率:<20次/小时,建议切换间隔15-30分钟(避免频繁切换)
  • Log File Sync等待:<5ms
  • 压缩比:>2:1(Data Guard环境)

五、使用体验

Oracle在保障ACID的前提下,Redo Log使Oracle数据库实现:

  • RPO=0(零数据丢失),RTO<60秒(自动化恢复),支持>1百万TPS的交易负载

Oracle Redo Log机制通过持续创新实现:

  • 性能优化:从磁盘I/O到持久内存(19c+),延迟从ms级降至μs级
  • 高可用增强:实时压缩(11g)、Far Sync(12c)、跨域冗余(23ai)
  • 智能运维:自适应压缩、区块链集成、AI预测(23ai)
相关推荐
数厘17 小时前
2.4MySQL安装配置指南(电商数据分析专用)
数据库·mysql·数据分析
一只小白00017 小时前
数据库对象实例化流程模板 + 常见错误
数据库
一江寒逸18 小时前
零基础从入门到精通MySQL(下篇):精通篇——吃透索引底层、锁机制与性能优化,成为MySQL实战高手
数据库·mysql·性能优化
DevOpenClub18 小时前
全国三甲医院主体信息 API 接口
java·大数据·数据库
jnrjian18 小时前
Oracle text index 更新机制
oracle
一勺菠萝丶18 小时前
管理后台使用手册在线预览与首次登录引导弹窗实现
java·前端·数据库
无忧智库18 小时前
某大型银行“十五五”金融大模型风控与智能投顾平台建设方案深度解读(WORD)
数据库·金融
爱码小白18 小时前
数据库多表命名的通用规范
数据库·python·mysql
jnrjian18 小时前
Json text index 未读
oracle
huohuopro18 小时前
Hbase伪分布式远程访问配置
数据库·分布式·hbase