16->联机重做日志文件

时间:2021-11-07 08:11:36

一。概念

联机日志文件又叫重做日志文件,记录了对数据库修改的信息,包括用户对数据修改和数据库管理员对数据库结构的修改。它主要用于在发生故障的时候和数据库备份文件配合恢复数据库,一般发生故障有2个情况:一个是介质损坏另外一个是用户误操作。每个数据库至少有两个日志文件组,每组至少包含1个或者多个日志成员,这里要多个日志成员的原因是防止日志文件组内某个日志文件损坏后及时提供备份,所以同一组的日志成员一般内容信息相同,但是存放位置不同

在Oracle数据库中,执行数据修改操作后,并不是马上写入数据文件,而是首先生成重做信息,并写入SGA中的一块叫LOG_BUFFER的固定区域,LOG_BUFFER的空间并不是无限大,事实上它非常小,一般设置在3~5MB左右。LOG_BUFFER有一定的触发条件,当满足触发条件后,会有相应进程(LGWR)将LOG_BUFFER中的内容写入一个特定类型的文件,就是传说中的联机重做日志文件。

联机重做日志文件是循环使用的(比如有三组日志文件)。当第一个日志文件达到一定数量时,就会停止写入,而转向第二个日志文件,第二个满转向第三个日志文件.第三个满就向第一个日志文件写入.而第一个日志文件有没有自动备份就涉及到归档或者不归档的问题.当数据库自动对原来的日志文件进行备份的话就叫归档模式,不需要对数据库进行自动备份就叫非归档模式. 这样循环的过程 就叫做日志组切换(Log Switch)

二。触发情况

那么什么情况触发LGWR进程写日志文件呢?以下情况将触发LGWR进程写操作:

1).当commit事务发生

2).当redo log buffer存储达到1/3

3).当重做日志缓冲区有超过一个兆字节的更改记录

4).在DBWN将buffer cache修改过的数据块的信息写入到数据文件之前

触发CHECK POINT事件的情况:

(当database buffer cache中用户commit但是还未写入数据文件的数据【简称脏数据】写入数据文件的过程就是一个checkpoint)

1).每次系统做日志切换时或者执行alter system switch logfile。

2).实例通过normal,transactional,immediate选项关闭时

3).通过设置初始化参数FAST_START_MTTR_TARGET强制发生

4) .数据库管理员手工设置ALTER SYSTEM CHECKPOINT、 ALTER TABLESPACE, DATAFILE OFFLINE时。

5).使用alter tablespace[OFFLINE NORMAL|READ ONLY|BEGIN BACKUP] 语句导致指定数据文件发生检查点

三。规划联机重做日志

   1、多路复用(Group)
 
   多路复用是避免损坏联机重做日志文件。
    多路复用时LGWR将同一重做日志信息同时写入多个同样的联机重做日志文件。
 
    建议必须要使用多路复用(至少两个组)。
 
    16->联机重做日志文件
 
    注:当某个成员不可用,则标记为INVALID,并向LGWR跟踪文件和数据报警文件中写入错误信息。不同问题会不同反映。
      * 一个操作成功一个操作失败时:按正常过程进行,忽略不可用成员
      * 日志切换时需要存档而不能访问下一个组时:暂时中断操作,直到归档完成
      * 介质失败,切换时不能访问下一组:关闭数据库,并返回错误信息
      * LGWR写入时不能访问文件:关闭数据库,并返回错误信息
 
    注:不同的组中不一定需要相同个数的成员。只含有1个组的多路复用是非法的。
 
    2、日志成员存放在不同磁盘
 
    设置多路复用时,将日志组成员放置到不同的磁盘上。这样当某磁盘失败时,可以跳过这个成员继续工作。
 
    另外将成员放置到不同磁盘上可以消除LGWR和ARCn在后台进程对联机重做日志成员的争夺。
 
    注:数据文件和联机重做日志文件也应该放在不同磁盘上,以减少写数据块和写记录之间出现的竞争。
 
    3、联机重做日志成员的大小
 
    规定联机重做日志的大小,以便将填满的组存档到脱机存档介质(磁带或磁盘)的某个单元中。
    例如磁盘上有一个填满的联机重做日志组,且磁盘还有49%的未使用存储空间,此时最好降低联机重做日志文件的大小。
 
    多路复用时,同一个组中的多有成员比用拥有同样的大小!
    不同组的成员大小不同,但是这样没有什么好处,而且会对检验点的设置带来不便。
 
    4、联机重做日志文件的数量
 
    联机日志文件数量的确定最好的方法是测试不同的配置的效果。
    最佳配置:在不妨碍LGWR向重做日志写入信息的前提下,使用尽可能少的组(至少2个组)。
 
    仔细检查LGWR跟踪文件和数据库报警文件的内容,如果消息表明:因为检验点还没有完成或者组还没有存档的缘故,LGWR不得不频繁得等待组,那么就需要添加组来解决问题。
 
    注:MAXLOGFILES-最大组数;MAXLOGMEMBERS-最大成员数;要修改这两个参数需要重建数据库或控制文件,所以创建数据库时要慎重。
 
    5、控制存档延迟
 
    在数据库中使用联机重做日志归档,然后将归档日志放到备用数据库,通过查询日志来进行和数据库中同样的操作。这两个操作之间存在一个时间间隔,就叫做存档延迟。可以通过ARCHIVE_LAG_TARGET初始化参数来严格限定延迟的时间长度。
 
    设置了ARCHIVE_LAG_TARGET之后,Oracle将定期检查实例当前的联机重做日志,在发生一下情况时切换日志:
    * n秒钟前创建了当前日志,并估计当前日志存档时间为m秒,而n+m值超过ARCHIVE_LAG_TARGET的值
    * 当前日志包含重做记录
 
    ARCHIVE_LAG_TARGET = 1800  单位是秒,默认为0,表示禁止该功能
 
    在选择数值时考虑一下因素:
    * 切换日志所消耗的系统开销
    * 作为日志完整条件的结果,通常日志切换发生的频率
    * 备用数据库可以人寿多少重做损失
 
    注:当数据库本身就经常切换时,设置这个值没有什么意义,而且当设置值很低时,对性能会产生负面影响。


四。命令操作

1 手工进行重做日志组的切换

   查询重做日志信息 

  SQL> select group#,status from v$log;


    GROUP# STATUS
---------- ----------------
         1 CURRENT
         2 INACTIVE
         3 INACTIVE

日志组切换 现在在写入第一个组 状态为当前

手工切换 日志组

SQL> alter system switch logfile;


系统已更改。

被切换到了第二组

SQL> select group#,status from v$log;


    GROUP# STATUS
---------- ----------------
         1 ACTIVE
         2 CURRENT
         3 INACTIVE

2 添加重做日志组

  查询所有的重做日志

  SQL> select group#,member from v$logfile;


    GROUP# MEMBER
  ---------- --------------------------------------------------
         3 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO03.LOG
         2 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO02.LOG
         1 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO01.LOG

  添加一个重做日志组 4

  SQL> alter database add logfile group 4 ('C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\
         REDO04.LOG') size 10M;

       数据库已更改。

   发现已经多加入了一条

SQL> select group#,member from v$logfile;


    GROUP# MEMBER
    ---------- --------------------------------------------------
         3 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO03.LOG
         2 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO02.LOG
         1 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO01.LOG
         4 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO04.LOG

3 添加重做日志组成员(添加的日志组成员默认是INVALID 当切换日志组时 自动变为空)

   SQL> alter database add logfile member 'C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\RE
   DO04_1.LOG' to group 4;


   数据库已更改。


   SQL> select group#,member from v$logfile;


      GROUP# MEMBER
       ---------- --------------------------------------------------
         3 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO03.LOG
         2 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO02.LOG
         1 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO01.LOG
         4 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO04.LOG
         4 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO04_1.LOG

4 删除重做日志组

   

取消日志组
    要注意:
    ① 至少需要保留两组联机重做日志文件
    ② 日志组状态为“非活动”时才可以取消,如果是“活动”的,则需要进行强制切换
    ③ 要确保日志组已经存档,可以查看V$LOG视图查看是否存档
 
    ALTER DATABASE DROP LOGFILE GROUP 3;
 
    在执行DROP之后要在操作系统中删除磁盘文件

取消联机重做日志成员
 
    要注意:
    ① 可以取消原先对称的组中的成员,使其暂时不对称,但最好立即调整这种状况
    ② 实例需要至少两个有效联机重做日志文件,且不能取消最后一个有效成员,使用V$LOGFILE查看状态
    ③ 和取消组一样,需要成员为非活动状态,否则需要进行一次强制切换
    ④ 确保要取消的成员已经经过存档
 
    ALTER DATABASE DROP LOGFILE MEMBER '/oracle/dbs/log3c.rdo';
清除联机重做日志文件
 
    在联机重做日志损坏时,可以使用CLEAR命令来初始化联机重做日志文件
 
    但是要注意以下情况不能使用:
    * 仅有两个日志组
    * 受到损坏的重做日志文件属于当前组
 
    ALTER DATABASE CLEAR LOGFILE GROUP 3;
    ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP 3;
5 重命名重做日志组

1 数据库必须切换到 mount状态
SQL> startup mount;
ORACLE 例程已经启动。


Total System Global Area  285212672 bytes
Fixed Size                  1248552 bytes
Variable Size              79692504 bytes
Database Buffers          197132288 bytes
Redo Buffers                7139328 bytes
数据库装载完毕。
比如 存在一个组4的日志文件 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO04.LOG
拷贝一个  REDO04.LOG到 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO04_1.LOG
现在查 看日志是否是 REDO04.LOG
SQL> col member format a50;
SQL> select group#,member from v$logfile;
    GROUP# MEMBER
---------- --------------------------------------------------
         3 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO03.LOG
         2 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO02.LOG
         1 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO01.LOG
         4 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO04.LOG
现在要把 组4 改为相同目录下的 REDO04_1.LOG
执行命令:
SQL> alter database rename file 'C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO04.LO
G' to 'C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO04_1.LOG';
数据库已更改。
修改数据库状态为open
SQL> alter database open;


数据库已更改。


SQL> select group#,member from v$logfile;


    GROUP# MEMBER
---------- --------------------------------------------------
         3 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO03.LOG
         2 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO02.LOG
         1 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO01.LOG
         4 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO04_1.LOG
修改成功

还有一种方法  比如 add成员member  在删除掉前面旧的member