2013年(350)
分类: Oracle
2013-04-10 13:31:47
===========================================================================
在Oracle数据库环境下流传着这样一句话:要想知道数据库曾经都做过什么,问问重做日志文件就知道!人们是这样说,重做日志文件也是这样做的。重做日志文件为什么能做到这一点,又是如何数十年如一日,始终保持重做日志组成员先进性的呢?这一切,要从重做日志文件的名字说起……
重做有一个好听的英文名字叫Redo,特指一项操作。在Oracle数据库中,执行数据修改操作后,并不是马上写入数据文件,而是首先生成重做信息,并写入SGA中的一块叫LOG_BUFFER(关于这部分内容将在介绍实例的体系结构时详细阐述)的固定区域,LOG_BUFFER的空间并不是无限大,事实上它非常小,一般设置在3~5MB左右。LOG_BUFFER有一定的触发条件,当满足触发条件后,会有相应进程将LOG_BUFFER中的内容写入一个特定类型的文件,就是传说中的联机重做日志文件。
在Oracle数据库环境中,如果开展“评选劳动模范”之类的活动,联机重做日志绝对是当之无愧的劳模代表(没有之一)。在某些比较极端的环境,甚至自联机重做日志文件降临到Oracle数据库环境的那刻起,它就要从早忙到晚,从这头忙到那一头,再从那头忙回到这一头,艰苦朴素、吃苦耐劳,时刻履行着作为一名重做日志组成员的光荣使命,数十年如一日,毫无怨言并且无条件地服从组织安排,全心全意完成组织交待的各项任务,忠实做好各项操作的记录工作。这一切,都是每一名重做日志组成员的真实写照。
一个好汉三个帮,重做日志文件也有多个帮手,每个数据库至少要有两个重做日志文件组(一般应该为3~5组)。
联机重做日志文件是循环使用,如图16-1所示,创建了3个重做日志文件组,Oracle以循环方式使用这些重做日志文件组。如当前在写LOG日志组1,那么LOG日志组1即为CURRENT状态,当该重做日志文件组中的日志文件被写满数据后,后台进程LGWR就开始写下一个,即LOG日志组2(此时LOG日志组1状态被切换为ACTIVE状态,LOG日志组2的状态则变为CURRENT)。以此类推,当所有的日志文件都被写满后,后台进程LGWR再次重新写入LOG日志组1……
因为联机重做日志文件非常重要,Oracle建议每组联机重做日志文件至少要有一份冗余。Oracle管这种方式叫复合(Multiplexed),即为每个重做日志文件保持多份镜像,这样一旦因为磁盘损坏,或误操作导致丢失了某个重做日志文件,只要该组至少还有一个重做日志文件状态正常,就能够保证数据不会丢失。
图16-1 联机重做日志文件组
1.联机重做日志创建联机重做日志文件时都是以组为单位,也就是说,想为数据库添加一个联机重做日志文件,就必须先为数据库创建一个联机重做日志文件组(如果使用DBCA建库,默认会创建三个联机重做日志文件组)。创建联机重做日志文件组的语法如图16-2所示。
图16-2 联机重做日志组创建语法
在创建重做日志文件组时,可以为联机重做日志文件指定复合,并设置联机重做日志文件的大小,例如:
JSSBOOK> ALTER DATABASE ADD LOGFILE GROUP 4
2 ( 'f:\oracle\oradata\jssbook\redod01.log',
3 'f:\oracle\oradata\jssbook\redod02.log') size 50m;
Database altered.删除连接联机重做日志文件组的语法就更简单了,例如,删除刚创建的GROUP 4:
JSSBOOK> ALTER DATABASE DROP LOGFILE GROUP 4;
Database altered.提示:
使用 ALTER DATABASE DROP LOGFILE 命令删除联机重做日志文件组时,不能删除当前系统正在使用(CURRENT)或活动(ACTIVE)状态的联机重做日志文件组(一般来说,刚刚创建的联机重做日志文件组的状态应该为UNUSED,表示还从未被写入过数据)。另外, ALTER DATABASE DROP LOGFILE 命令只删除该联机重做日志文件组在数据字典中的定义,不会级联删除操作系统中对应的物理文件,如果需要删除对应的物理文件,DBA必须手动通过操作系统命令进行删除。你也可以为当前的联机重做日志组添加联机重做日志文件,语法如图16-3所示。
图16-3 联机重做日志文件组添加成员语法
例如,为第3组联机重做日志添加日志文件:
JSSBOOK> ALTER DATABASE ADD LOGFILE MEMBER 'f:\oracle\oradata\jssbook\redoa02.log' TO GROUP 1;
Database altered.提示:
添加联机重做日志文件不能指定大小,因为每个联机重做日志文件组中的文件都是相互冗余,因此文件大小必须一致。实际上在Oracle数据库中,每一个联机重做日志文件组都可以拥有不同于其他联机重做日志文件组的大小,不过Oracle建议数据库中每组联机重做日志文件都拥有相同的大小。删除联机重做日志文件组中的某个日志文件也很简单,如删除GROUP1中刚刚添加的日志文件,执行命令如下:
JSSBOOK> ALTER DATABASE DROP LOGFILE MEMBER 'f:\oracle\oradata\jssbook\redoa02.log';
Database altered.提示:
删除联机重做日志文件组成员前,必须确保删除后该联机重做日志文件组中至少还拥有一个组员,不然删除操作可能会触发ORA-00361错误。有两个视图可以用来查询当前系统中的联机重做日志文件的相关信息,其中用V$LOG视图查询当前的联机重做日志文件组信息,例如:
JSSBOOK> SELECT * FROM V$LOG;
GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM
------ ------- --------- -------- ------ --- ------- ------------ ---------
1 1 13 52428800 2 YES INACTIVE 8651585360 29-JUN-09
2 1 14 52428800 1 NO CURRENT 8651626514 01-JUL-09
3 1 12 52428800 1 YES INACTIVE 8651585358 29-JUN-09注意该视图中的STATUS列,表示对应的联机重做日志文件组状态,可能有下列几个值:
V$LOGFILE 则可以查询当前的联机重做日志文件明细,例如:
JSSBOOK> SELECT * FROM V$LOGFILE;
GROUP# STATUS TYPE MEMBER IS_
---------- ------- ------- -------------------------------------------------- ---
1 ONLINE F:\ORACLE\ORADATA\JSSBOOK\REDO01.LOG NO
2 ONLINE F:\ORACLE\ORADATA\JSSBOOK\REDO02.LOG NO
3 ONLINE F:\ORACLE\ORADATA\JSSBOOK\REDO03.LOG NO
1 INVALID ONLINE F:\ORACLE\ORADATA\JSSBOOK\REDOA02.LOG NO该视图中GROUP#列关联V$LOG.GROUP#,而MEMBER列则显示日志文件存储的实际路径。另一个需要注意的是TYPE列,该列只有两个值:STANDBY表示该日志文件为Standby数据库专用,即Standby Redologs,ONLINE则表示该日志文件为普通联机重做日志文件。
3.设置联机重做日志文件大小很多朋友可能会有疑问,究竟为联机重做日志文件分配多大的空间合适呢?这确实是一个很值得讨论的话题,不过这一问题并没有准确或者说固定的答案,每个O racle 数据库设置的值可能都不相同。如果愿意深入研究的话,那么我认为在创建联机重做日志文件时,至少有下面几个因素需要考虑到:
并不是所有的操作都会被记录重做日志。在执行某些操作时,DBA可能会希望尽可能少的记录重做日志,以加快执行速度,如执行某些DDL语句时附加NOLOGGING子句或执行DML时指定HINT APPEND的方式操作数据,这种操作方式不会产生重做记录(或者是只生成了极少一部分),另外像SQL*L oader 这类的工具采用直接路径方式时由于跳过了引擎,也不会生成重做记录。
不过如果你想,可以让所有操作均记录重做日志,Oracle数据库有一个F orce L ogging 的属性,一旦将数据库改为 Force Logging ,则N ologging 和A ppend H int 方式自动失效(甚至连SQLLDR命令的直接路径导入也会自动转换为常规路径),在这种方式下可以确保数据库中所做的操作均会记录重做信息。
查询当前数据库是否启用了F orce L ogging ,可以查询V$DATABASE视图的 Force_Logging 列,例如:
JSSBOOK> SELECT FORCE_LOGGING FROM V$DATABASE;
FOR
---
NO在默认情况下数据库处于 Noforce Logging 状态,要将数据库置于 Force Logging 模式,执行下列语句即可:
JSSBOOK> ALTER DATABASE FORCE LOGGING;
Database altered.该设置即时修改即时生效。不过需要注意的是,如果执行该操作时,数据库正在执行一些类似 Nologging 的操作,那么 Force Logging 必须等待这些操作完成后,才能对数据库属性进行修改。
取消 Force Logging 模式也很简单,执行下列语句即可:
JSSBOOK> ALTER DATABASE NO FORCE LOGGING;
Database altered.该设置同样是修改后即时生效的。
=================================================