Redo Log是什么?
恢复操作最重要的结构就是重做日志,它由两个或更多预分配的文件组成,这些文件存储对数据库所做的所有变更。每个数据库实例都有一个相关的 重做日志用以在实例故障时保护数据库。
重做线程-Redo Threads
当谈到多个数据库实例的上下文,每个数据库实例的重做日志也被称为重做线程。在典型配置中,只有一个数据库实例访问Oracle数据库,因此只有一个线程存在。然而,在RAC环境中,两个或更多实例并发访问单个数据库,每个实例都有自己的重做线程。每个实例的一个单独的重做线程避免了一组重做日志文件的争用,从而消除了潜在的性能瓶颈。
重做日志内容-Redo Log Contents
重做日志文件中充满了重做记录。重做记录(也称为重做条目)由一组更改向量做成,每一个更改向量都是对数据库中单个数据块更改的描述。例如:如果你在employee表中更改了一个工资值,那么你将生成一个重做记录,该记录包含用来描述对表的数据段块更改的更改向量、撤销段数据块和撤销段的事务表。
重做条目记录着你能用来重建对数据库所做的所有更改的数据,包括撤销段。因此,重做日志也保护回滚数据。当你使用重做数据恢复数据库时,数据库读取重做记录中的更改向量,并应用这些更改到相关的数据块。
重做记录以循环的方式缓存在SGA的重做日志缓冲区中,并被数据库后台进程LGWR写到重做日志文件。不管何时,当事务提交的时候,LGWR把事务重做记录从SGA的重做日志缓冲区写入到重做日志文件中,并为每一个提交的事务分配一个SCN来识别重做记录。只有当与给定的事务相关的所有重做记录安全的写到磁盘上的重做日志中,用户进程才会被通知该事务已提交。
相关的事务被提交之前,重做记录也能够被写到重做日志文件中。如果重做日志缓冲区填满,或者另一个事务提交,LGWR会把重做日志缓冲区的所有重做日志条目刷新到重做日志文件中,即使有些重做记录可能没有被提交。如果需要,数据库可以回滚这些更改。
REDO RECORDS保存所有相关的元数据的改变,包括:
- SCN和时间戳的改变
- 产生改变的事务的事务ID
- 事务提交的SCN和时间戳
- 做出改变的操作的类型
- 修改的数据段的名称和类型
Oracle数据库如何写到重做日志
一个数据库的重做日志由两个或者更多的重做日志文件组成。数据库需要至少两个文件来保证一个文件总是可以写的,而另一个被用来归档(如歌数据库在ARCHIVELOG模式)。
LGWR以循环的方式把重做日志缓冲区的重做记录写入到重做日志文件,当当前的重做日志文件被填满,LGWR开始写到下一个可用的重做日志文件,当最后一个可用的重做日志文件被填满后,LGWR返回到第一个重做日志文件并写入它,重新启动这个循环。如下图所示:
活动(当前)和不活动的重做日志文件
Oracle数据库每次只使用一个重做日志文件来存储写入到重做日志缓冲区的重做记录,LGWR当前正在写入的重做日志文件称为当前(CURRENT)重做日志文件;数据库实例恢复所需要的重做日志文件称为活动(ACTIVE)的重做日志文件;实例恢复不需要的重做日志文件称为不活动(INACTIVE)的重做日志文件。
如果数据库运行在归档模式(ARCHIVELOG MODE),那么数据库不能重用或者覆盖活动的联机重做日志文件,直到归档进程(ARCn)归档了它的内容。如果数据库运行在非归档模式(NOARCHIVELOG),那么当最后一个重做日志文件被填满后,LGWR继续重写下一个日志文件。
日志切换和日志序列号
日志切换是一个时间点,在该时点,数据库不再写入一个重做日志文件,而是开始写入下一个。通常情况下,当当前重做日志文件被完全填满,并且写入必须继续到下一个重做日志文件时,就发生日志切换。然而,你也能够配置日志切换定期进行,而不用管当前重做日志文件是否被完全填满;当然,你也能够手动强制进行日志切换。
每次日志切换发生时,Oracle数据库会为每一个重做日志文件分配一个新的日志序列号,然后LGWR开始写入它,当数据库归档重做日志文件时,归档日志会保留它的日志序列号,重做日志文件会被循环使用,并被分配下一个可用的日志序列号。
每个在线或者归档的重做日志文件通过日志序列号被唯一识别。当数据库崩溃、实例或者介质恢复的时候,数据库会通过必要的归档和重做日志文件的日志序列号按顺序的应用重做日志文件。
检查点事件
检查点事件是Oracle为了减少数据库实例恢复时间而设置的一个事件,当该事件发生时,LGWR将重做日志缓冲区中的数据写入重做日志文件中,而同时通知DBWR进程将数据库高速缓存中的已经提交的数据写入数据文件,所以检查点事件越频繁,则用于数据库恢复的重做数据就越少。此时,检查点事件也会修改数据文件头信息和控制文件信息,以记录检查点的SCN。可以使用alter database checkpoint指令强制启动检查点事件。检查点事件不是检查点进程触发的,如果不是强制产生的检查点事件,则检查点事件由DBWR进程触发。
多路复用重做日志文件
为了防止重做日志自身的故障, Oracle数据库允许多路复用日志,这意味着重做日志的两个或者多个相同副本可以在不同的位置自动维护。为获得最大收益,这些位置应该放在不同的磁盘上,即使重做日志的所有副本位于同一磁盘,但是,冗余可以帮助防止I/O错误、文件损坏等。当重做日志文件多路复用的时候,LGWR同时将相同的重做日志信息写入多个相同的重做日志文件,从而消除重做日志单点故障。
多路复用是通过创建重做日志文件组来实现的,一个组包含重做日志文件和它的多路复用副本,每个副本称为组中的成员(MEMBER),每一个日志组用一个数字来定义,比如第一组,第二组等等。如下演示:
管理重做日志
1、验证数据库是否归档
SQL> archive log list;
Database log mode Archive Mode -->表示数据库处于归档模式
Automatic archival Enabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 24
Next log sequence to archive 26
Current log sequence 26
SQL>
2、添加一个重做日志组SQL> alter database add logfile group 4
2 ('/u01/app/oracle/oradata/orcl/redo04.log')
3 size 100M;
Database altered.
SQL> select group#,status,type,member from v$logfile;
GROUP# STATUS TYPE MEMBER
---------- ------- ------- --------------------------------------------------
3 ONLINE /u01/app/oracle/oradata/orcl/redo03.log
2 ONLINE /u01/app/oracle/oradata/orcl/redo02.log
1 ONLINE /u01/app/oracle/oradata/orcl/redo01.log
4 ONLINE /u01/app/oracle/oradata/orcl/redo04.log
SQL>
SQL> alter database add logfile
2 ('/home/oracle/redo/redo05.log','/home/oracle/redo/redo06.log','/home/oracle/redo/redo07.log')
3 size 10M;
Database altered.
SQL> select group#,status,type,member from v$logfile;
GROUP# STATUS TYPE MEMBER
---------- ------- ------- --------------------------------------------------
3 ONLINE /u01/app/oracle/oradata/orcl/redo03.log
2 ONLINE /u01/app/oracle/oradata/orcl/redo02.log
1 ONLINE /u01/app/oracle/oradata/orcl/redo01.log
4 ONLINE /u01/app/oracle/oradata/orcl/redo04.log
5 ONLINE /home/oracle/redo/redo05.log
5 ONLINE /home/oracle/redo/redo06.log
5 ONLINE /home/oracle/redo/redo07.log
7 rows selected.
注:如果不加GROUP参数的话,则默认在原来日志组的基础上自动增长。SQL> SELECT group#, sequence#, bytes, blocksize, members, archived, status
2 FROM v$log;
GROUP# SEQUENCE# BYTES BLOCKSIZE MEMBERS ARC STATUS
---------- ---------- ---------- ---------- ---------- --- ----------------
1 25 52428800 512 1 YES INACTIVE
2 26 52428800 512 1 NO CURRENT
3 24 52428800 512 1 YES INACTIVE
4 0 104857600 512 1 YES UNUSED
5 0 10485760 512 3 YES UNUSED
SQL>
注:刚创建的日志组还没使用,故状态为UNUSED,Oracle没有分配日志序列号。3、删除联机重做日志组
SQL> alter database
2 drop logfile group 5;
Database altered.
SQL> select group#,status,type,member,is_recovery_dest_file from v$logfile;
GROUP# STATUS TYPE MEMBER IS_
---------- ------- ------- -------------------------------------------------- ---
3 ONLINE /u01/app/oracle/oradata/orcl/redo03.log NO
2 ONLINE /u01/app/oracle/oradata/orcl/redo02.log NO
1 ONLINE /u01/app/oracle/oradata/orcl/redo01.log NO
4 ONLINE /u01/app/oracle/oradata/orcl/redo04.log NO
SQL> host ls /home/oracle/redo/
redo05.log redo06.log redo07.log
注:使用指令删除日志组后,日志组成员还在,必须手动删除。4、向日志组添加日志成员
SQL> alter database
2 add logfile
3 member '/u01/app/oracle/oradata/orcl/redo0401.log'
4 to group 4;
Database altered.
SQL> select group#,status,type,member,is_recovery_dest_file from v$logfile;
GROUP# STATUS TYPE MEMBER IS_
---------- ------- ------- -------------------------------------------------- ---
3 ONLINE /u01/app/oracle/oradata/orcl/redo03.log NO
2 ONLINE /u01/app/oracle/oradata/orcl/redo02.log NO
1 ONLINE /u01/app/oracle/oradata/orcl/redo01.log NO
4 ONLINE /u01/app/oracle/oradata/orcl/redo04.log NO
4 INVALID ONLINE /u01/app/oracle/oradata/orcl/redo0401.log NO
SQL> SELECT group#, sequence#, bytes, blocksize, members, archived, status from v$log;
GROUP# SEQUENCE# BYTES BLOCKSIZE MEMBERS ARC STATUS
---------- ---------- ---------- ---------- ---------- --- ----------------
1 25 52428800 512 1 YES INACTIVE
2 26 52428800 512 1 NO CURRENT
3 24 52428800 512 1 YES INACTIVE
4 0 104857600 512 2 YES UNUSED--->添加后,member成员变为2
5、重命名重做日志文件
SQL> alter database
2 rename file '/u01/app/oracle/oradata/orcl/redo0401.log'
3 to '/home/oracle/redo/redo04001.log';
Database altered.
6、删除重做日志成员SQL> alter database
2 drop logfile member '/home/oracle/redo/redo04001.log';
Database altered.
注:如果删除的日志成员是重做日志组的最后一个有效的成员,则不能删除;如果该日志组当前正在使用,在日志切换前则不能删除该组的成员;如果数据库运行在归档模式,而且要删除的日志成员所在的日志组没有被归档,则该组的日志成员不能被删除。
7、重设重做日志文件的大小
Oracle数据库没有提供直接修改重做日志文件大小的方法,如果重设其大小,需要先删除该日志文件所在的日志组,然后重建日志文件,通过此种方法间接设置重做日志的大小。
8、手工切换日志
SQL> alter system switch logfile;
System altered.
9、清除重做日志文件
SQL> alter database
2 clear logfile
3 group 4;
Database altered.
重做日志数据字典视图
1、显示控制文件里的重做日志文件信息;
SQL> SELECT group#,sequence#,blocksize,archived,status FROM v$log;
GROUP# SEQUENCE# BLOCKSIZE ARC STATUS
---------- ---------- ---------- --- ----------------
1 25 512 NO CURRENT
2 23 512 YES INACTIVE
3 24 512 YES INACTIVE
SQL>
2、标识重做日志组、成员及其状态信息;
SQL> select group#,status,type,member,is_recovery_dest_file from v$logfile;
GROUP# STATUS TYPE MEMBER IS_
---------- ------- ------- -------------------------------------------------- ---
3 ONLINE /u01/app/oracle/oradata/orcl/redo03.log NO
2 ONLINE /u01/app/oracle/oradata/orcl/redo02.log NO
1 ONLINE /u01/app/oracle/oradata/orcl/redo01.log NO
SQL>
下面解释下STATUS的含义:
STALE:说明该文件内容为不完整的;
空白:表示该日志组正在使用;
INVALID:表示该文件不能被访问;
DELETED:表示该文件已经不再使用。
3、包含日志历史信息;
SQL> SELECT * FROM v$log_history;
RECID STAMP THREAD# SEQUENCE# FIRST_CHANGE# FIRST_TIM NEXT_CHANGE# RESETLOGS_CHANGE# RESETLOGS
---------- ---------- ---------- ---------- ------------- --------- ------------ ----------------- ---------
1 951176301 1 1 925702 04-AUG-17 956971 925702 04-AUG-17
2 951176317 1 2 956971 04-AUG-17 957159 925702 04-AUG-17
3 951176387 1 3 957159 04-AUG-17 967038 925702 04-AUG-17
4 951176453 1 4 967038 04-AUG-17 990482 925702 04-AUG-17
5 951177268 1 5 990482 04-AUG-17 998445 925702 04-AUG-17
6 951179324 1 6 998445 04-AUG-17 1025603 925702 04-AUG-17
7 951205593 1 7 1025603 05-AUG-17 1038836 925702 04-AUG-17
8 951254394 1 8 1038836 05-AUG-17 1062330 925702 04-AUG-17
9 951264050 1 9 1062330 05-AUG-17 1082529 925702 04-AUG-17
10 951271871 1 10 1082529 06-AUG-17 1103553 925702 04-AUG-17
11 951285670 1 11 1103553 06-AUG-17 1137225 925702 04-AUG-17
参考:官方文档