ORACLE_OCP之ORACLE REDO
- The redo log records all changes made to data, including both uncommitted and committed changes.
- 重做日志记录对数据所做的所有更改,包括未提交和已提交的更改。
- Oracle通过Redo来保证数据库的事务可以被重演,从而使得在故障之后,数据可以被恢复。在数据库中,Redo的功能主要通过3个组件来实现:Redo Log Buffer、LGWR后台进程和Redo Log File(在归档模式下,Redo Log File最终会经由ARCn进程写出为归档日志文件)。
- 在数据发生commit时,将更改的SQL脚本写入在线重做日志(ONLINE REDO LOG)。主要用于数据库的增量备份和增量恢复。
一、REDO相关体系结构
- Redo Log Buffer位于SGA之中,是一块循环使用的内存区域,其保存数据库变更的相关信息。这些信息以重做条目(Redo Entries)形式存储(Redo Entries也经常称为Redo Records)。Redo Entries包含重构、重做数据库变更的重要信息,这些变更包括INSERT、UPDATE、DELETE、CREATE、ALTER或者DROP等。
- Redo Entries的内容被Oracle数据库进程从用户的内存空间(PGA)复制到SGA中的Redo Log Buffer之中。Redo Entries在内存中占用连续的顺序空间,由于Redo Log Buffer是循环使用的,Oracle通过一个后台进程LGWR不断把Redo Log Buffer的内容写出到Redo Log File中,Redo Log File同样是循环使用的。
二、Redo Log 组件
- Redo Log Buffer:如果数据需要写到在线重做日志中,则在写至磁盘之前要在Redo Buffer中临时缓存这些数据。由于内存到内存的传输比内存到磁盘的传输快得多,因此使用重做日志Buffer可以加快数据库的操作。
- 数据在重做缓冲区的停留时间不会太长。实际上LGWR会在一下某个情况发生时启动对这个区的刷新输出(flush)。
注:具体LGWR触发条件,自行了解哦
- ARCn:归档进程,ARCn的任务就是,当LGWR将在线日志文件填满时,就将其复制到另外一个位置。此后这些归档的重做日志文件可以用于完成介质恢复。
- Redo Log Files:重做日志文件,以组出现。可以查询v$logfile找到对应的日志文件。
三、Online REDO LOG(重做日志)和 ARCHIVE REDO LOG(归档重做日志)
- Online Redo log files–在线重做日志,又称联机重做日志,指Oracle以SQL脚本的形式实时记录数据库的数据更新,换句话说,实时保存已执行的SQL脚本到在线日志文件中(按特定的格式)。
- Archive Redo log files–归档重做日志,简称归档日志,指当条件满足时,Oracle将在线重做日志以文件形式保存到硬盘(持久化)。
- 每个Oracle数据库都至少有两个Online重做日志组,每个组中至少有一个重做日志文件,这些在线重做日志组以循环方式使用。(用户可以通过视图操作添加/修改/删除日志组和日志文件来自定义在线重做日志),每组内的日志文件的内容完全相同,且保存在不同的位置,用于磁盘日志镜像,以做多次备份提高安全性。默认情况这n组通常只有一组处于活动状态,不断地同步写入已操作的脚本,当日志文件写满时(达到指定的空间配额),如果当前数据库处于归档模式,则将在线日志归档到硬盘,成为归档日志;若当前数据库处于非归档模式,则不进行归档操作,而当前在线日志的内容会被下一次重新写入覆盖而无法保存。因此,通常对于生产环境的数据库在运行时,是要处于归档模式下的,以保存数据更新的日志。当前归档日志组写满后,Oracle会切换到下一日志组,继续写入,就这样循环切换;当处于归档模式下,切换至原已写满的日志组,若该日志组归档完毕则覆盖写入,若没有则只能使用日志缓冲区,等待归档完毕之后才能覆盖写入。当然,处于非归档模式下是直接覆盖写入的。
归档重做日志文件实际上就是已填满的“旧”的在线重做日志文件的副本。系统将日志文件填满时,ARCH进程会在另一个位置建立重做日志文件的一个副本,也可以在本地或者远程位置上建立多个另外的副本。如果由于磁盘损坏或者其他物理故障而导致失败,就会用这些归档重做日志文件来执行介质恢复。
默认情况下,一个数据库默认为非归档模式,如果是非归档模式的话,也就说明我们没有办法通过日志来对数据库做一个恢复。
1、LGWR重复循环的写重做日志文件,当一个日志文件被写满之后,LGWR就会写下一个Redo Log文件,当最后一个日志文件满了之后,LGWR就会返回来写第一个日志文件。
- LGWR写ONLINE REDO LOG过程
- ARCn将ONLINE REDO写入到ARCHIVE LOG
2、归档模式 vs 非归档模式
-
非归档模式
- 不适用与生产数据库
创建数据库时,缺省的日志管理模式为非归档模式
当日志切换,检查点产生后,联机重做日志文件即可被重新使用
联机日志被覆盖后,介质恢复仅仅支持到最近的完整备份
不支持联机备份表空间,一个表空间损坏将导致整个数据库不可用,需要删除掉损坏的表空间或从备份恢复
对于操作系统级别的数据库备份需要将数据库一致性关闭
应当备份所有的数据文件、控制文件(单个)、参数文件、密码文件、联机日志文件(可选)
- 不适用与生产数据库
-
归档模式
-
能够对联机日志文件进行归档,生产数据库强烈建议归档
在日志切换时,下一个即将被写入日志组必须归档完成之后,日志组才可以使用
归档日志的Log sequence number信息会记录到控制文件之中
必须有足够的磁盘空间用于存放归档日志 -
备份与恢复
支持热备份,且当某个非系统表空间损坏,数据库仍然处于可用状态,且支持在线恢复
使用归档日志能够实现联机或脱机时点恢复(即可以恢复到指定的时间点、指定的归档日志或指定的SCN)
-
四、查看REDO LOG的位置
SQL> COL MENBER FOR A40;
SQL> SET LINES 100
SQL> COL MEMBER FOR A40
SQL> SELECT GROUP# , MEMBER FROM V$LOGFILE;
GROUP# MEMBER
---------- ----------------------------------------
3 /u01/app/oracle/oradata/orcl/redo03.log
2 /u01/app/oracle/oradata/orcl/redo02.log
1 /u01/app/oracle/oradata/orcl/redo01.log
五、查看REDO LOG状态信息(V$LOG)
SQL> SET LINES 300
SQL> SELECT * FROM V$LOG;
GROUP# THREAD# SEQUENCE# BYTES BLOCKSIZE MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIME NEXT_CHANGE# NEXT_TIME CON_ID
---------- ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ------------------- ------------ ------------------- ----------
1 1 13 209715200 512 1 NO INACTIVE 2642725 2020-12-27 04:56:23 2773812 2020-12-27 11:04:17 0
2 1 14 209715200 512 1 NO INACTIVE 2773812 2020-12-27 11:04:17 2890203 2020-12-28 07:25:17 0
3 1 15 209715200 512 1 NO CURRENT 2890203 2020-12-28 07:25:17 1.8447E+19 0
- 可以看到我们这里已经有两种状态为 INACTIVE 和 CURRENT,那么我们把REDO LOG组所有的状态都列出来。并给出相应解释:
- UNUSED - 从未对联机重做日志组进行写入,这种状态的日志文件要么是刚增加的,要么是当日志不是current redo log时RESETLOGS操作后的状态
- CURRENT - 当前的联机重做日志组,这意味着该联机重做日志组是活动的。
- ACTIVE - 联机重做日志组是活动的,但是并非当前联机重做日志组,崩溃恢复需要该状态的日志,它可能用于块恢复,它可能已经归档也可能未归档。
- CLEARING - 在ALTER DATABASE CLEAR LOGFILE 命令后正在将该日志重建为一个空日志,日志清除后其状态更改为UNUSED。
- CLEARING_CURRENT - 正在清除当前日志文件中的已关闭线程,如果切换时发生某些故障,如写入新日志标题时的I/O错误,则该日志可以停留在该状态。
- INACTIVE - 实例恢复不再需要联机重做日志组,它可能已经归档也可能未归档。//看归档状态
六、查看REDO LOG状态信息(V$LOGFILE)
//新添加的成员显示不可用
SQL> SELECT GROUP#, MEMBER, STATUS FROM V$LOGFILE;
GROUP# MEMBER STATUS
---------- ---------------------------------------- -------
3 /u01/app/oracle/oradata/orcl/redo03.log
2 /u01/app/oracle/oradata/orcl/redo02.log
1 /u01/app/oracle/oradata/orcl/redo01.log
1 /u01/app/oracle/oradata/orcl/redo01_1 INVALID
- 可以看到我们这里STATUS(状态)列下并无数据,但实际上现在这个列中的值为NULL,那么我们把REDO LOG文件所有的状态都列出来。并给出相应解释:
- INVALID – 该文件不可访问
- STALE - 该文件内容不完全,例如正在添加一个日志文件成员
- DELETED - 该文件已不再使用
- NULL – 该文件正在使用中
七、REDO日志切换命令
-
REDO组可以用两种方法去切换:
-
正常切换: (推荐使用)
alter system switch logfile;
-
用发生检查点的方式去切换:
alter system checkpoint;
-
-
测试:
SQL> ALTER SYSTEM SWITCH LOGFILE;
System altered.
SQL> SELECT * FROM V$LOG;
GROUP# THREAD# SEQUENCE# BYTES BLOCKSIZE MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIME NEXT_CHANGE# NEXT_TIME CON_ID
---------- ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ------------------- ------------ ------------------- ----------
1 1 16 209715200 512 2 NO CURRENT 2912837 2020-12-29 08:04:07 1.8447E+19 0
2 1 14 209715200 512 1 NO INACTIVE 2773812 2020-12-27 11:04:17 2890203 2020-12-28 07:25:17 0
3 1 15 209715200 512 1 NO ACTIVE 2890203 2020-12-28 07:25:17 2912837 2020-12-29 08:04:07 0
SQL> ALTER SYSTEM SWITCH LOGFILE;
System altered.
SQL> SELECT * FROM V$LOG;
GROUP# THREAD# SEQUENCE# BYTES BLOCKSIZE MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIME NEXT_CHANGE# NEXT_TIME CON_ID
---------- ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ------------------- ------------ ------------------- ----------
1 1 16 209715200 512 2 NO ACTIVE 2912837 2020-12-29 08:04:07 2912868 2020-12-29 08:05:08 0
2 1 17 209715200 512 1 NO CURRENT 2912868 2020-12-29 08:05:08 1.8447E+19 0
3 1 15 209715200 512 1 NO ACTIVE 2890203 2020-12-28 07:25:17 2912837 2020-12-29 08:04:07 0
//切了一圈之后,新添加的redo日志文件成员变为可用;
SQL> SELECT GROUP#, MEMBER, STATUS FROM V$LOGFILE;
GROUP# MEMBER STATUS
---------- ---------------------------------------- -------
3 /u01/app/oracle/oradata/orcl/redo03.log
2 /u01/app/oracle/oradata/orcl/redo02.log
1 /u01/app/oracle/oradata/orcl/redo01.log
1 /u01/app/oracle/oradata/orcl/redo01_1
八、使用EM – EXPRESS进行实验!
-
原始状态:
-
创建重做日志组:
-
首先我们要了解到,重做日志组的大小是无法更改的,我们只能删除掉旧的日志组,重新创建。
-
对应SQL语句:(点显示SQL就能看的了)
ALTER DATABASE
ADD LOGFILE
GROUP 4
(
‘/u01/app/oracle/oradata/orcl/redo04.log’
)
SIZE 240M; -
创建成功:
-
-
为重做日志组添加成员
-
切换重做日志组
-
删除重做日志组
- 为INACTIVE状态的组才能被删除,当为ACTIVE状态时通过强制检查点进行所有组的ACTIVE到INACTIVE的状态切换,如果为CURRENT状态的组需要切换。
- 注意:我们在数据库中删除重做日志组的时候,对应的物理文件在操作系统中并没有被删除,所以我们需要手动删除掉操作系统中的对应文件(所以我们只在数据库中删除了的话,在重新建立同名的重做日志组会发生错误,读者可自行实验!)