LLL的数据库培训—第二部分—Oracle基础知识培训—第17讲—重做日志(online redo log)文件之一概念与管理
引子:
如果数据库不会崩溃,根本就不需要重做日志文件。如果数据库崩溃了,前端业务发出的sql命令应该如何执行,又如何可以同时保持数据库的高性能写入。
日志文件的作用就是为了在数据库崩溃之后能够恢复已提交的数据,但普通的数据库都有一个日志文件(catalog)来存放变化的信息,一个数据库也只有一个日志文件。
但这样会带来很大的问题,比如日志文件过大,IO的读写会降低数据库效率。同样数据库崩溃时,数据库的还原也会相当慢。
从理论上来说, Oracle也可以使用上面所谈到的日志文件结构,但 Oracle却引入了一种相当复杂的日志文件结构, Oracle称之为重做日志。是为了改变或是为了避免上述的问题。
一、重做日志(redo log)文件的概念
1、什么是重做日志文件(redo log)
(1)它是几组文件,默认命名为redo01.log、redo02.log、redo03.log
(2)每一组(group)由1个或多个redol0g成员(member)组成
(3)用户执行sql语句后,服务器进程收到SQL语句进行解析,和sql语句有关的undo块、索引块、表数据等放入块缓冲区缓存,块缓冲区缓存,这些都会写入重做日志缓冲区(redo log buffer),进行数据保护,等重做日志的触发条件触发后,才会写入redo log文件。
2、REDO LOG 的作用
--记录 ORACLE 数据库的变化 --可以避免数据提交后直接写入数据文件 --实例恢复和介质恢复
3、快速提交技术(fast commmit)
Oracle服务器是使用了一种称为快速提交(fast commit)的技术,该技术既能保证 Oracle系统的效率,又能保证在系统崩溃的情况下所有提交的数据可以得到恢复。
为此 Oracle系统引入了系统变化数(System Change Number,SCN)。无论任何时候只要某个事务(transaction被提交, Oracle服务器都将产生一个SCN(号码)并将其赋予该事务的所有数据行。在同一个数据库中,SCN是单调递增的并且是唯一的。
为了避免在进行一致性检验时操作系统时钟可能引发的问题, Oracle服务器将SCN作为 Oracle的内部时间戳来保证数据文件中的数据的同步和数据的读一致性
当在 SQLPlus中发了 commit语句之后 Oracle的内部操作步骤如下:
(1)服务器进程将把提交的记录连同所产生的SCN(号码)一起写入重做日志缓冲区中; (2)重做日志写进程将把重做日志缓冲区中一直到所提交的记录(包括该记录)的所有记录连续地写到重做日志文件中,在此之后, Oracle服务器就可以保证即使在系统崩溃的情况下所有提交的数据也可以得到恢复; (3)Oracle通知用户(进程)提交已经完成; (4)服务器进程将修改数据库高速缓冲区中的相关数据的状态并释放资源和打开锁等。
4、引入重做日志的目的
正是由于上述的提交技术, Oracle服务器能够保证所有的已经提交的数据一定会被记录在重做日志文件上,一旦数据库崩溃, Oracle服务器就使用重做日志文件中的这些数据来进行数据库的恢复工作。
可以说引入重做日志文件的目的就是为了数据库的恢复(在 Oracle8i之前的版本中这些数据除了用作恢复之外,别无它用),为此 Oracle引入了重做日志结构,如下图
5、redo 重做日志的触发条件:
--用户提交(commit) --有 1/3 重做日志缓冲区未被写入磁盘(磁盘是指redo01.log等) --有大于1m 的重做日志缓冲区未被写入磁盘 --3 秒超时 --dbwr 需要写入的数据的 scn 大于 lgwr 记录的 scn, dbwr 触发 lgwr 写入。
二、重做日志组(group)及成员(member)
上述图中,每个重做日志文件就是一个成员(member),每个方框中的2个成员,组成一个组(group)。
1、重做日志组和成员间的关系
(1)每个组可以有多个成员 (2)每个组中的成员信息完全一致 (3)建议将每一组中的成员分布在不同磁盘上(最好是放在不同I/O的控制器控制的磁盘上)
2、重做日志的工作过程
重做日志写进程(LGWR)在任意时刻只能写一组重做日志组,LGWR后台进程正在写的重做日志组称作当前(current)重做日志组。
(1)LGWR将把完全相同的信息从重做日志缓冲区(redo log buffer)中复制到该组的每个重做日志文件中。它是以循环的方式写重做日志组的。 (2)当LGWR写满了一组重做日志时,它就开始写下一组重做日志。这称为日志切换(switch)。 (3)当写满了最后一组重做日志时,LGWR开始又写第一组重做日志。 (4)Oracle用以上这种循环的操作方式的确提高数据库系统的效率而产生的日志文件不够大的难题。
3、重做日志循环方式带来的问题
但是这种循环的操作方式本身又带来了另一个严重的问题。
那就是当LGWR循环写了一圈之后再写重做日志组中的文件时,这些重做日志文件中的信息就要被覆盖掉。
4、归档日志的引入:
通过上述描述,Oracle数据库就无法保证在数据库崩溃后能够恢复全部提交过的数据,为了解决这一难题, Oracle引入了称为归档/存档(archived)日志的结构
三、归档日志结构信息(大概讲解,后续进行细讲)
1、归档日志是如何工作的
见上图中重做日志文件结构。
(1)如果 Oracle数据库运行在归档模式下时(Oracle数据库的默认模式为非归档方式),当LGWR(日志写进程)的写操作从一个重做日志组切换到另一个重做日志组后,归档写进程(ARCH/ARCRO)就会将原来的重做日志文件中的信息复制到归档日志文件中,可以把归档日志文件看成是重做日志文件的备份。
(2)Oracle服务器保证在归档写进程没有将重做日志文件中的信息复制到归档日志文件中之前,LGWR不能再写这组重做日志文件。
(3)有了归档日志文件 Oracle服务器就能保证所谓的全恢复,因为那些在重做日志文件中被覆盖掉的信息已经存在归档日志文件中了。
2、为何不多设置一些重做日志组,而是使用了归档日志这一概念
有人会问,设置这些归档日志是否过于麻烦了?如果多设一些重做日志组(如几百组)不就不需要归档(archived)日志结构了吗?
从理论上讲是可行的,但这同样会产生效率的问题因为 Oracle服务器的效率随着所管理的文件数的增加而下降。
与重做日志文件不一样,重做日志文件为联机日志文件,即Oracle服务器在运行时需要管理它们。
而归档日志文件是脱机日志文件,即除了在归档写进程进行复制的那一瞬间, Oracle服务器在运行时是不需要管理它们的。
因此使用归档日志文件要比使用很多组重做日志系统的开销小得多。
有 Oracle的文章称为 Oracle的这种日志结构为两级日志结构。
Oracle利用把重做日志分组和引入归档日志的方式在数据库系统的效率和数据库的可恢复性之间进行了巧妙的折中。
这也是 Oracle的得意之作之一,因此在OCP或OCA的考试中几乎是必考的内容。
四、重做日志文件的管理
1、获取重做日志的信息
通过两个视图查看
SQL>select * from v$log; SQL> select * from v$logfile;
2、v$logfile 中 status 的状态值
invalid : 表明该文件不可访问
stale : 表明文件内容不完全
deleted : 表明该文件不再使用
null : 表明文件正在使用
3、v$log重做日志的四个文件状态
(1)unused:
通常指从未被使用的日志组,即新添加的日志组。
(2)current:
状态为LGWR进程正把redo log buffer的日志写进日志组(redolog)中。
(3)active:
为刚刚完成日志切换后的状态,
--如果是非归档模式,此时该日志组中提交的事务引起的数据改变还没有完全从DB buffer cache写入到数据文件中,因此该日志组还不能被覆盖,并且待完全写入后变为inactive状态。 --如果数据库为归档模式,那么是在该状态下完成归档的。
active状态只是表明, 目前log buffer的数据没有向当前这个组中写数据,并不能说明这组redo log的数据已经完成了归档,也可能在执行归档过程[但是通过alter system switch logfile使文件变为了active,文件已经归档了。]。 活动的非当前日志,该日志可能已经完成归档也可能没有归档,活动的日志文件在Crash recovery(实例恢复)时会被用到。 ACITVE状态意味着检查点尚未完成,如果日志文件循环使用再次到达该文件,数据库将处于等待的停顿状态,此时在alert文件中,可以看到类似如下记录:Checkpoint not complete。 当这种问题出现时,可以从数据库内部通过v$session_wait来观察,该视图会显示数据库当前哪些session正处于这种等待。Checkpoint not complete在数据库中体现为等待事件log file switch(checkpoint incomplete): SQL> select sid,event,state from v$session_wait;---查询结果中event的值为:log file switch 在此同时,可能DBWR进程正在进行db file parallel write,日志文件必须等待DBWR完成检查点触发的写操作之后才能被覆盖。如果设置了参数log_checkpoints_to_alert为TRUE的话,还可以在alert文件中清晰地看到检查点的增进和完成情况。
(4)inactive:
状态的日志可以被覆盖,可以允许写入日志。如果是在归档模式下,那么此阶段证明归档已经完成。
4、添加日志组
alter database add logfile group 1 ('/oracle/oradata/mesorcl/redo01.log') size 100m;
5、删除日志组及日志组成员
alter database drop logfile group 1;
注意:
(1)删除的条件是当前日志组的状态不能是current或active。如果要删除需要将文件组状态改为unactive (2)保证至少由两组redolog日志(如果只有2组,系统也不会让删除剩下的) (3)使用切换日志或提交检查点方式更改日志状态(SQL>alter system switch logfile;或SQL>alter system checkpoint;)
6、添加日志组成员
alter database add logfile member '/oracle/oradata/mesorcl/redo01.log' to group 1;
7、删除日志组成员
alter database drop logfile member '/oracle/oradata/mesorcl/redo01.log';
8、移动或重命名重做日志文件
两种思路:在线模式和停机模式
(1)停机模式:
--关闭数据库:
SQL> shutdown immediate;
--在OS提示符界面中移动文件。本例使用了mv命令:
mv /u02/oraredo/012c/redoo2b. rdo /u01/oraredo/012c/redoo2b.rdo
--将数据库启动到mount模式
SQL> startup mount;
--使用新文件位置和名称更新控制文件:
SQL> alter database rename file '/uo2/oraredo/012c/redoo2b.rdo to '/u01/oraredo//redoo2b.rdo';
--打开数据库:
SQL> alter database open;
(2)在线模式:此种模式不仅可以移动日志文件,还可以更改日志文件大小
--增加新的redolog 组(可以更换位置并且设置新的大小)
alter database add logfile group 5 ('/oracle/oradata/redo05.log') size 100m;
--删除旧的redolog组
alter database drop logfile member '/oracle/oradata/mesorcl/redo01.log';
--如此重复,既可以删除group 1,2,3,增加group 4,5,6等。同时还可以再将4,5,6用同样方法改为group 1,2,3.
9、利用OMF(Oracle Manage File)管理重组日志文件
利用Oracle管理文件(Oracle Mnnage File)来自动管理和维护重做日志文件,时Oraclle 9i引入的,改方法简化了重做日志的管理和维护。
(1)开启方法
配置参数:db_create_online_log_dest_1,设置对应的目录即可,可以最多添加5个成员。
SQL>alter system set DB_CREATE_ONLINE_LOG_DEST_1='/oracle/oradata/redolog'; SQL>alter system set DB_CREATE_ONLINE_LOG_DEST_2='/oracle2/oradata/redolog'; SQL>alter system set DB_CREATE_ONLINE_LOG_DEST_3='/oracle3/oradata/redolog';
(2)创建redolog 组
SQL>alter database add logfile;
(3)查看生成的日志文件组
SQL>select * from v$logfile;