一、 核心原理:变更数据捕获与持久化
- 根本目的: 确保所有已提交事务 (Committed Transactions) 对数据库所做的更改不会丢失,即使在发生各种故障(如实例崩溃、断电、介质故障)的情况下也能恢复。
- 记录内容 - “重做”信息:
- 重做日志记录的是**物理更改 (Physical Changes)**,而不是逻辑 SQL 语句。
- 它记录了数据块 (Data Block) 在修改前和后的状态,或者更精确地说,是如何重建 (Redo) 这些更改所需的最小信息。具体包括:
- 对数据块的更改:插入、更新、删除行。
- 对撤销/回滚段 (Undo Segments) 数据块的更改(撤销数据本身也受重做保护)。
- 对数据字典的更改(如表、列定义的修改)。
- 创建/修改/删除段 (Segments) 和区段 (Extents) 的元数据操作。
- 某些直接路径操作 (Direct Path Loads) 的可选日志记录(使用
APPEND提示时默认不记录,但为了可恢复性可以启用)。 - **事务提交记录 (Commit Record)**:这是重做日志中极其关键的部分,标志着事务的永久性生效。
- 写入时机 - 关键过程:
- 用户进程 (User Process) 发起修改数据的 SQL 语句(INSERT, UPDATE, DELETE, DDL)。
- 服务器进程 (Server Process) 在数据库缓冲区缓存 (Database Buffer Cache) 中找到或读入需要修改的数据块。
- 服务器进程在修改缓冲区缓存中的块之前,会先为这个修改生成**重做记录 (Redo Record)**。
- 这些重做记录首先被写入服务器进程的私有内存区域(进程 PGA)。
- 当发生以下情况之一时,服务器进程会将 PGA 中的重做记录复制到共享内存中的 **重做日志缓冲区 (Redo Log Buffer)**:
- 事务提交 (
COMMIT)。 - 日志缓冲区被填充了 1/3。
- 日志缓冲区中的重做记录量达到 1MB。
- 在 DBWn (Database Writer) 进程将脏缓冲区 (Dirty Buffers) 写入数据文件之前(这是关键的先写日志 - Write-Ahead Logging, WAL 原则)。
- 每隔 3 秒。
- 事务提交 (
- 日志写入进程 (Log Writer Process - LGWR) 负责将重做日志缓冲区中的内容顺序地、连续地写入到联机重做日志文件 (Online Redo Log Files) 中。LGWR 会在以下情况触发写入:
- 用户显式提交事务 (
COMMIT)。这是最常见的触发点,提交操作会等待 LGWR 将包含该事务提交记录在内的所有相关重做记录成功写入磁盘后才向用户返回“提交成功”消息。这保证了已提交事务的持久性。 - 重做日志缓冲区满 1/3。
- 重做日志缓冲区中的重做记录量达到 1MB。
- 每隔 3 秒(超时机制)。
- 在 DBWn 进程开始将脏缓冲区写入数据文件之前(强制执行 WAL 原则,确保恢复时能先重做更改)。
- 发生日志切换 (Log Switch)。
- 用户显式提交事务 (
- 先写日志 (Write-Ahead Logging - WAL): 这是数据库恢复理论的核心原则。Oracle 严格遵守:
- 规则: 在对数据文件中的数据块进行任何修改之前,描述该修改的重做记录必须已经被写入(刷新到磁盘)联机重做日志文件中。
- 目的: 确保如果数据库发生故障(如崩溃),那些在内存(缓冲区缓存)中已修改但尚未写入数据文件(即“丢失”的更改)可以通过重做日志文件“重做”出来。没有重做日志记录,就无法恢复未写入数据文件的更改。
二、 结构与特性
- 联机重做日志组 (Online Redo Log Groups):
- Oracle 数据库要求至少 2 个重做日志组才能正常运行(强烈建议至少 3 组)。
- 每个组是一个逻辑实体。
- 组内成员 (Members): 每个组包含一个或多个完全相同的物理文件(称为重做日志成员)。这些成员是镜像关系,LGWR 进程会同时向同一组内的所有成员写入相同的内容。
- 成员镜像目的: **高可用性 (High Availability)**。如果一个成员文件损坏(如磁盘故障),只要组内还有一个有效成员可用,数据库就能继续运行,LGWR 继续向剩余的有效成员写入。防止单点故障导致数据库挂起。
- 联机重做日志文件 (Online Redo Log Files):
- 物理的操作系统文件(通常以
.log或.rdo为扩展名)。 - 文件大小在创建组时固定(可通过重建组调整大小)。
- 文件采用循环使用 (Circular Usage) 机制:
- LGWR 顺序写入当前活动的重做日志组。
- 当当前组被写满时,发生 **日志切换 (Log Switch)**。
- 日志切换触发 CKPT (Checkpoint Process) 进程执行检查点(通知 DBWn 将缓冲区缓存中与该组相关的脏块写入数据文件,并更新控制文件和数据文件头部的 SCN)。
- LGWR 切换到下一个可用的日志组继续写入。
- 当最后一个组写满后,LGWR 会回绕到第一个组开始覆盖写入。
- 物理的操作系统文件(通常以
- 日志切换 (Log Switch):
- 触发条件:
- 当前日志组被写满(最常见)。
- 手动执行
ALTER SYSTEM SWITCH LOGFILE;。 - 某些维护操作(如开始热备份
ALTER TABLESPACE ... BEGIN BACKUP;)。
- 影响:
- 触发检查点(CKPT)。
- 可能引起短暂的性能抖动(如果 DBWn 需要大量写脏块)。
- 如果下一个组尚未完成归档(在归档模式下)或尚未完成检查点(如果前一个检查点未完成),LGWR 会等待,可能导致
LOG FILE SWITCH (ARCHIVING NEEDED)或LOG FILE SWITCH (CHECKPOINT INCOMPLETE)等待事件,数据库可能挂起。这是配置不当的常见问题点。
- 触发条件:
- 归档模式 (ARCHIVELOG) vs 非归档模式 (NOARCHIVELOG):
- 非归档模式 (NOARCHIVELOG):
- 日志切换后,被覆盖的联机重做日志文件内容会被丢弃。
- 优点: 简单,无需管理归档文件。
- 缺点:
- 无法进行时间点恢复 (Point-in-Time Recovery, PITR)。只能恢复到最后一次完整备份的时刻。备份后到故障前的所有数据更改会丢失。
- 只能进行完全恢复 (Complete Recovery) 到备份点,不能进行**不完全恢复 (Incomplete Recovery)**。
- 无法进行**联机备份 (Hot Backup),只能进行脱机备份 (Cold Backup)**(需要关闭数据库)。
- 适用场景: 非关键、可丢失数据的开发/测试环境,或只读数据库。
- 归档模式 (ARCHIVELOG):
- 日志切换后,归档进程 (ARCn) 会自动将已满的联机重做日志文件复制到一个或多个指定的归档日志文件 (Archived Redo Log Files) 中,通常以
.arc为扩展名。 - 归档完成后,该联机日志组才能被 LGWR 再次覆盖使用。
- 优点:
- 支持时间点恢复 (PITR):可以将数据库恢复到任意时间点(只要存在该时间点之前的备份和归档日志)。
- 支持不完全恢复(如恢复到某个 SCN 或时间)。
- 支持**联机备份 (Hot Backup)**:在数据库运行时进行备份。
- 提供更高的数据保护级别。
- 缺点:
- 需要额外的磁盘空间存储归档日志。
- 需要管理归档日志文件(备份、删除过期文件)。
- 如果归档目标空间不足或进程失败,可能导致数据库挂起(
ARCHIVE LOG进程等待ARCn完成归档)。
- 适用场景: 所有生产环境、关键业务数据库。
- 日志切换后,归档进程 (ARCn) 会自动将已满的联机重做日志文件复制到一个或多个指定的归档日志文件 (Archived Redo Log Files) 中,通常以
- 非归档模式 (NOARCHIVELOG):
- 归档进程 (ARCH - Archiver Process):
- 在归档模式下,当发生日志切换时,ARCn 进程被唤醒。
- 负责将已满的联机重做日志文件复制到归档目标 (
LOG_ARCHIVE_DEST_n参数指定)。 - 可以配置多个 ARCn 进程 (
LOG_ARCHIVE_MAX_PROCESSES) 来处理高负载。 - 归档成功后,更新控制文件中的归档信息。
- 检查点 (Checkpoint):
- 虽然检查点本身不是重做日志的直接部分,但与之紧密相关(由日志切换触发)。
- 作用: 减少实例恢复所需的时间。
- 过程:
- CKPT 进程在检查点事件(如日志切换)发生时被触发。
- CKPT 更新控制文件和数据文件头部,记录一个系统变更号 (System Change Number, SCN)。这个 SCN 表示:在此 SCN 之前提交的事务所做的所有更改,其对应的脏数据块都已经被 DBWn 写入到了数据文件中。
- 通知 DBWn 将缓冲区缓存中所有修改时间早于或等于该 SCN 的脏块写入数据文件(DBWn 是实际执行写入的进程)。
- 对恢复的影响: 实例恢复(如数据库异常关闭后重启)时,只需要从最后一次完成检查点的 SCN 开始应用重做日志,而不是从更早的日志开始。大大缩短恢复时间。
三、 关键作用
- 保证事务持久性 (Durability): 这是最核心的作用。通过强制
COMMIT等待 LGWR 将重做记录(包括提交记录)写入磁盘,确保即使系统在COMMIT成功后立即崩溃,该事务的更改也不会丢失,在重启恢复后仍然存在。 - 支持数据库恢复:
- 实例恢复 (Instance Recovery / Crash Recovery): 当数据库实例异常终止(如断电、
shutdown abort)后重新启动时自动发生。- 前滚 (Roll Forward): 使用联机重做日志文件和归档重做日志文件(如果适用),将从最后一次完成检查点的 SCN 开始到故障发生时最后写入的重做记录为止的所有更改(包括已提交和未提交的事务)重新应用到数据文件上。这会将数据库恢复到故障发生前的物理状态。
- 回滚 (Roll Back): 前滚结束后,数据库包含所有已提交和未提交的更改。然后,Oracle 使用撤销段 (Undo Segments) 中的信息(这些信息本身也受重做日志保护)来回滚 (Undo) 所有未提交事务的更改,确保数据库只包含已提交的数据,达到一致性状态。
- 介质恢复 (Media Recovery): 当数据文件因磁盘损坏、文件丢失或人为错误而损坏或丢失时进行。
- 还原 (Restore): 使用 RMAN 或用户管理的备份将受损/丢失的数据文件恢复到某个过去的时间点(通常是备份时刻)。
- 恢复 (Recover): 应用自备份以来生成的所有归档重做日志文件和必要的联机重做日志文件(如果备份后数据库还运行过一段时间),将还原的数据文件前滚到指定的时间点(如当前时间、某个 SCN 或特定时间)。然后进行必要的回滚(在恢复完成后自动或手动打开数据库时进行)。
- 实例恢复 (Instance Recovery / Crash Recovery): 当数据库实例异常终止(如断电、
- 支持联机备份: 在归档模式下,允许在数据库打开且用户正常访问时进行物理备份(表空间或全库)。备份期间产生的更改会被记录在重做日志中。恢复时,需要应用备份期间和备份之后生成的归档日志来使备份的数据文件达到一致性状态。
- 支持高可用性解决方案:
- Data Guard: 重做日志传输是物理备库(Physical Standby)同步的基础。主库的 ARCn 或 LGWR(使用 SYNC/ASYNC)将重做数据发送到备库,备库的 RFS (Remote File Server) 进程接收并写入备库的备用重做日志 (Standby Redo Log - SRL),然后备库的 MRP (Managed Recovery Process) 应用这些重做日志来保持与主库同步。
- GoldenGate / 逻辑复制: 虽然不直接传输物理 redo,但 GoldenGate 等工具可以从重做日志或归档日志中挖掘逻辑变更信息 (LogMiner),用于逻辑复制。
- 提供数据变更审计基础: 通过工具如 LogMiner,可以读取和分析归档重做日志文件(有时也可分析联机日志),了解数据库的历史变更(谁在什么时间做了什么操作),用于审计、数据修复或数据同步。
四、 管理与配置
- 创建/添加日志组和成员:
ALTER DATABASE ADD LOGFILE GROUP <group#> ('<member1_path>', '<member2_path>', ...) SIZE <size>;(创建新组)ALTER DATABASE ADD LOGFILE MEMBER '<new_member_path>' TO GROUP <group#>;(向现有组添加成员)
- 删除日志组和成员:
ALTER DATABASE DROP LOGFILE GROUP <group#>;(删除整个组,该组不能是CURRENT或ACTIVE状态)ALTER DATABASE DROP LOGFILE MEMBER '<member_path>';(删除特定成员,不能是组内最后一个成员)
- 重命名/移动成员:
- 关闭数据库或将要移动的日志组切换到非活动状态(
ALTER SYSTEM SWITCH LOGFILE;多次直到V$LOG.STATUS为INACTIVE)。 - 使用操作系统命令移动/重命名物理文件。
ALTER DATABASE RENAME FILE '<old_path>' TO '<new_path>';(在MOUNT状态下执行)。- 打开数据库 (
ALTER DATABASE OPEN;)。
- 关闭数据库或将要移动的日志组切换到非活动状态(
- 调整大小:
- 重做日志文件的大小在创建组时固定。
- 调整大小的唯一方法是重建日志组:
- 添加一个新的、所需大小的日志组。
- 强制切换日志 (
ALTER SYSTEM SWITCH LOGFILE;) 直到旧的、需要调整大小的组状态变为INACTIVE。 - 删除旧的日志组 (
ALTER DATABASE DROP LOGFILE GROUP <old_group#>;)。
- 配置归档模式:
- 查看当前模式:
SELECT log_mode FROM v$database; - 切换到归档模式 (需在
MOUNT状态):SHUTDOWN IMMEDIATE; STARTUP MOUNT; ALTER DATABASE ARCHIVELOG; ALTER DATABASE OPEN; - 设置归档目标 (
LOG_ARCHIVE_DEST_n,LOG_ARCHIVE_DEST_STATE_n) 和格式 (LOG_ARCHIVE_FORMAT)。 - 设置归档进程数量 (
LOG_ARCHIVE_MAX_PROCESSES)。
- 查看当前模式:
- 关键视图:
V$LOG:显示日志组信息(组号、序列号、大小、成员数、状态、是否归档)。V$LOGFILE:显示日志成员文件信息(组号、成员状态、文件路径)。V$LOG_HISTORY:显示日志切换历史(序列号、切换时间、SCN)。V$ARCHIVED_LOG:显示已归档的日志文件信息(序列号、名称、归档时间、大小、SCN 范围)。V$ARCHIVE_DEST_STATUS:显示归档目标的配置和状态。V$INSTANCE_RECOVERY:显示实例恢复相关的参数和估算的恢复时间 (MTTR)。
五、 故障、性能与恢复
- 常见故障类型:
- 联机日志文件损坏/丢失:
- 非活动 (INACTIVE) 或已归档 (ARCHIVED) 成员损坏: 如果组内还有其他有效成员,数据库通常不受影响(镜像保护)。尽快删除损坏成员并添加新成员。
- 活动 (ACTIVE) 成员损坏: 数据库可能挂起或报错。需要尝试清除日志 (
ALTER DATABASE CLEAR LOGFILE GROUP <group#>;) 或进行不完全恢复。 - 当前 (CURRENT) 成员损坏: 极其严重! 通常会导致数据库实例崩溃 (
ORA-00312,ORA-00313)。需要复杂的恢复过程(如CLEAR UNARCHIVED LOGFILE+ 不完全恢复,或使用备份进行恢复),很可能导致数据丢失。
- 归档失败:
- 归档目标空间不足 (
ORA-00257)。 - 归档目标权限问题或路径无效。
- ARCn 进程失败。
- 后果: 如果
ACTIVE日志组需要归档后才能被覆盖,LGWR 将被阻塞,导致数据库挂起 (ARCHIVE LOG进程等待)。
- 归档目标空间不足 (
- 日志切换问题:
LOG FILE SWITCH (ARCHIVING NEEDED):等待归档完成。LOG FILE SWITCH (CHECKPOINT INCOMPLETE):等待检查点完成(通常因为 DBWn 写脏块太慢,可能 I/O 瓶颈或缓冲区缓存过大且脏块过多)。LOG FILE SWITCH (PRIVATE STRAND FLUSH INCOMPLETE):内部重做分配结构问题。- 后果: LGWR 等待,所有需要写日志的会话(几乎所有 DML)都会被阻塞,数据库接近或完全挂起。
- 联机日志文件损坏/丢失:
- 性能调优:
- 日志缓冲区大小 (
LOG_BUFFER): 太小会导致 LGWR 过于频繁地写入(log buffer space等待事件),太大可能浪费内存。需要根据重做量调整。 - 日志文件大小: 太小会导致频繁的日志切换和检查点,增加 I/O 开销和可能的争用(
log file switch等待事件)。太大则可能延长实例恢复时间。需要平衡。 - 日志文件组数量: 太少的组可能导致 LGWR 等待归档或检查点。建议至少 3-5 组。
- 提交频率: 过于频繁的小事务提交会增加 LGWR 的 I/O 负载(每个
COMMIT都触发 LGWR 写)。考虑批量提交。 - NOLOGGING 操作: 对于可以接受在介质恢复时丢失的操作(如
CREATE TABLE AS SELECT,INSERT /*+ APPEND */,SQL*Loader Direct Path),在对象或操作级别使用NOLOGGING可以显著减少重做日志生成量。风险: 如果发生介质故障且需要从备份恢复,这些操作无法通过重做日志恢复,对象可能处于逻辑损坏状态,需要重新执行操作。谨慎使用! - I/O 子系统性能: LGWR 是顺序写,但非常频繁且对延迟敏感(
COMMIT等待 LGWR)。将联机重做日志文件放在高速、低延迟、专用的磁盘或存储上(最好 RAID 1 或 10),避免与数据文件、归档目标共享 I/O 通道。考虑使用写缓存(有备用电池保护的 RAID 控制器缓存或 NVRAM)。 - 归档性能: 确保归档目标 I/O 性能足够,配置足够的 ARCn 进程。考虑将归档目标放在与联机日志文件不同的物理磁盘上。
- 关键等待事件监控:
log file sync:用户会话等待其提交操作相关的重做记录被 LGWR 写入磁盘。这是衡量COMMIT性能的主要指标。过高的等待通常与慢的日志磁盘 I/O 或过小的日志缓冲区有关。log file parallel write:LGWR 进程等待将日志缓冲区内容写入物理日志文件的 I/O 完成。直接反映日志文件写入延迟。log buffer space:服务器进程等待日志缓冲区中的可用空间。通常表明日志缓冲区太小或 LGWR 写入不够快。log file switch (archiving needed)/log file switch (checkpoint incomplete):如前所述。
- 日志缓冲区大小 (
- 恢复场景:
- 恢复丢失/损坏的非当前/非活动日志成员: 如前所述,利用镜像特性,删除损坏成员并添加新成员。
- 恢复丢失/损坏的活动日志组: 尝试
ALTER DATABASE CLEAR LOGFILE GROUP <group#>;。如果该组尚未归档,需要加上UNARCHIVED选项 (ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP <group#>;)。警告: 清除未归档的日志会破坏连续归档链,之后必须立即进行全库备份!如果清除失败,可能需要进行不完全恢复。 - 恢复丢失/损坏的当前日志组: 最严重情况。
- 尝试
ALTER SYSTEM CHECKPOINT;+ALTER SYSTEM SWITCH LOGFILE;(可能失败)。 - 尝试
ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP <current_group#>;(可能失败)。 - 如果上述失败,通常需要:
- 使用最近的有效备份还原所有数据文件和控制文件。
- 进行不完全恢复 (Incomplete Recovery):
RECOVER DATABASE UNTIL CANCEL;(应用归档日志直到损坏的当前日志组之前的最后一个日志组)。 - 用
RESETLOGS选项打开数据库:ALTER DATABASE OPEN RESETLOGS;。这会重置日志序列号,创建一个新的数据库化身 (Incarnation),备份之后的所有更改将丢失。
- 尝试
- 归档日志丢失: 如果丢失了恢复所需的某个归档日志文件,恢复将无法继续进行到该日志之后的时间点。只能恢复到丢失的归档日志文件之前的最近时间点(进行不完全恢复)。凸显归档日志备份和管理的重要性。
- 预防措施:
- 多路复用 (Multiplexing): 每个日志组至少配置 2 个成员,并将它们放在不同的物理磁盘或控制器上。这是防止单点故障导致数据库挂起的最重要措施。
- 合理的日志大小和组数: 避免过小(频繁切换)或过大(恢复时间长)。足够组数缓冲切换。
- 启用归档模式 (ARCHIVELOG): 生产环境必须启用。
- 监控归档: 确保归档目标空间充足、权限正确、ARCn 进程正常运行。监控
V$ARCHIVE_DEST_STATUS,V$RECOVERY_AREA_USAGE(如果使用 FRA)。 - 备份归档日志: 定期使用 RMAN 备份归档日志文件,并在备份成功后删除已备份的归档日志(
DELETE INPUT)。防止归档目标空间耗尽。 - 监控日志切换和检查点: 关注
LOG FILE SWITCH相关等待事件。优化 DBWn 性能(I/O,DB_WRITER_PROCESSES)。 - 使用 FRA (Fast Recovery Area): 简化归档日志、备份文件的管理(空间回收自动化)。但仍需监控 FRA 空间使用率 (
V$RECOVERY_AREA_USAGE)。 - 定期验证备份: 使用 RMAN
VALIDATE或RESTORE VALIDATE确保备份(包括归档日志备份)有效可恢复。 - 测试恢复流程: 定期进行恢复演练,确保在真实故障时能够有效执行。
总结:
Oracle 重做日志文件是数据库的生命线,是 ACID 特性中持久性 (Durability) 的核心保障。它通过物理记录数据块的变更,严格遵守先写日志 (WAL) 原则,为实例恢复和介质恢复提供了坚实的基础。其循环写入、组内多路复用、归档模式的设计,平衡了性能、可用性和可恢复性。深入理解其工作原理(LGWR, ARCn, 检查点)、关键特性(组、成员、归档)、核心作用(持久性、恢复、高可用性支持)以及如何进行配置、监控、调优和故障处理(特别是日志文件损坏/丢失的恢复),是每一位 Oracle DBA 必须具备的核心技能。忽视重做日志的管理和监控,往往会导致灾难性的数据丢失或长时间的服务中断。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




