浅谈关于redo log file的故障处理

 

2        如果LGWR 至少能够访问一个组内成员,对组内可访问成员的写入将照常进行,LGWR 忽略组内的不可用成员。如果该组不活动,即检查点已完成,那么丢弃和添加一个新的联机日志成员就可以解决问题,否则如果该组是当前活动的日志组,则必须首先强制日志切换。

 

SQL> SELECT group#, sequence#, bytes, members, status

  2  FROM V$LOG;

    GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS

---------- ---------- ---------- ---------- ----------------

         1        411    1048576          2 INACTIVE

         2        412    1048576          2 INACTIVE

         3        413    1048576          2 INACTIVE

         5        414    1048576          2 CURRENT

SQL> select * from  v$logfile

  2  ORDER BY GROUP#;

 

    GROUP# STATUS  MEMBER

---------- ------- ----------------------------------------------------------

         1         D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG

         1         E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG

         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG

         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG

         3         D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG

         3         E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG

         5         E:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG

         5         E:/ORACLE1/ORA81/ORADATA/TEST/REDO08.LOG

8 rows selected

SQL>

 

为了模拟日志组中有一个成员损坏的情况,我们打开文本编辑器,并且破坏E:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG文件,然后,我们看到:

 

SQL> select * from  v$logfile;

    GROUP# STATUS  MEMBER

---------- ------- -------------------------------------------------------

         1         D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG

         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG

         3         D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG

         1         E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG

         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG

         3         E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG

         5 INVALID E:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG

         5         E:/ORACLE1/ORA81/ORADATA/TEST/REDO08.LOG

8 rows selected

SQL>

 

但是这时候数据还可以忽略这个损坏的文件而正常使用。要修复这个文件,我们需要做:

SQL> shutdown

数据库已经关闭。

已经卸载数据库。

ORACLE 例程已经关闭。

SQL> host

Microsoft Windows 2000 [Version 5.00.2195]

(C) 版权所有 1985-2000 Microsoft Corp.

E:/>COPY E:/ORACLE1/ORA81/ORADATA/TEST/REDO08.LOG E:/ORACLE1/ORA81/ORADATA/TEST/

REDO07.LOG

改写 E:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG ? (Yes/No/All): YES

已复制         1 个文件。

 

上面这一步需要注意的是,如果新的日志文件的位置或文件名称需要改变(如,介质失效),则在数据库加载(Startup Mount)后需要对这个改变位置或名称的日志文件重命名,然后再打开数据,具体过程参见重新定位或者重命名联机重做日志文件

 

E:/>exit

SQL> startup

ORACLE 例程已经启动。

Total System Global Area   36214812 bytes

Fixed Size                    75804 bytes

Variable Size              19283968 bytes

Database Buffers           16777216 bytes

Redo Buffers                  77824 bytes

数据库装载完毕。

数据库已经打开。

SQL> select * from  v$logfile;

    GROUP# STATUS  MEMBER

---------- ------- ------------------------------------------------------------

         1         D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG

         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG

         3         D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG

         1         E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG

         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG

         3         E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG

         5 UNKNOWN E:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG

         5 STALE   E:/ORACLE1/ORA81/ORADATA/TEST/REDO08.LOG

8 rows selected

SQL> alter system switch logfile;

System altered

SQL>  select * from  v$logfile;

    GROUP# STATUS  MEMBER

---------- ------- -------------------------------------------------------

         1         D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG

         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG

         3         D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG

         1         E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG

         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG

         3         E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG

         5         E:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG

         5         E:/ORACLE1/ORA81/ORADATA/TEST/REDO08.LOG

8 rows selected

SQL>

然后,看到一切正常了,则完全关闭数据(Normal),进行一个冷备份。

上面关于日志文件损坏和修复的相关部分会被记录在Alert.log文件中。

 

2        如果在日志切换时LGWR 无法访问下一个组的所有成员或者损坏的日志文件时改组中日志成员,则该实例关闭。如果组不活动,那么丢弃和添加一个新的日志组就可解决问题;如果活动,数据库可能需要从联机重做日志文件残留物进行介质恢复。

 

SQL> ALTER DATABASE DROP LOGFILE MEMBER 'E:/ORACLE1/ORA81/ORADATA/TEST/REDO08.LOG';

Database altered

SQL>  select * from  v$logfile;

    GROUP# STATUS  MEMBER

---------- ------- -----------------------------------------------------------

         1         D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG

         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG

         3         D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG

         1         E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG

         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG

         3         E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG

         5         E:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG

7 rows selected

SQL>

 

为了模拟日志组中有一个成员损坏的情况,我们打开文本编辑器,并且破坏E:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG文件,然后,我们看到:

SQL> ALTER SYSTEM SWITCH LOGFILE;

ALTER SYSTEM SWITCH LOGFILE

ORA-00313: 无法打开日志组  (线程 ) 的成员

SQL> STARTUP MOUNT

ORACLE 例程已经启动。

Total System Global Area   36214812 bytes

Fixed Size                    75804 bytes

Variable Size              19283968 bytes

Database Buffers           16777216 bytes

Redo Buffers                  77824 bytes

数据库装载完毕。

SQL> ALTER DATABASE

  2  DROP LOGFILE GROUP 5;

数据库已更改。

SQL> ALTER DATABASE OPEN;

数据库已更改。

SQL> select * from  v$logfile;

    GROUP# STATUS  MEMBER

---------- ------- -------------------------------------------------

         1         D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG

         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG

         3 STALE   D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG

         1         E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG

         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG

         3 STALE   E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG

6 rows selected

SQL>

然后,看到一切正常了,则完全关闭数据(Normal),进行一个冷备份。

上面关于日志文件损坏和修复的相关部分会被记录在Alert.log文件中。

 

在归档模式下,我们需要用alter database clear logfile group来恢复数据库:

SQL> select * from  v$logfile;

    GROUP# STATUS  MEMBER

---------- ------- --------------------------------------------------------

         1         D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG

         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG

         3         D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG

         1         E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG

         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG

         3         E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG

         4         F:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG

         4         F:/ORACLE1/ORA81/ORADATA/TEST/REDO08.LOG

8 rows selected

 

 

我们用GROUP4作试验,首先确定它不是CURRENT GROUP

SQL> SELECT group#, sequence#, bytes, members, status from v$log;

 

    GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS

---------- ---------- ---------- ---------- ----------------

         1        440    1048576          2 INACTIVE

         2        442    1048576          2 CURRENT

         3        439    1048576          2 INACTIVE

         4        441    1048576          2 INACTIVE

 

 

然后让GRUP4只有一个MEMBERDROPGROUP4中其余的MEMBER):

SQL> alter database drop logfile member 'F:/ORACLE1/ORA81/ORADATA/TEST/REDO08.LOG';

Database altered

SQL> select * from  v$logfile;

    GROUP# STATUS  MEMBER

---------- ------- ------------------------------------------------------------

         1         D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG

         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG

         3         D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG

         1         E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG

         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG

         3         E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG

         4         F:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG

7 rows selected

SQL>

 

现在GROUP 4中只有一个MEMBER,并且不是CURRENT,我们损坏这个GROUPF:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG),然后,当SWITCH到这个损坏的组以后,数据库会HANG或者严重的话会CRASH,这时候我们可能收到下面的错误:

SQL> ALTER DATABASE CLEAR LOGFILE

  2  'F:/oracle1/ora81/oradata/test/REDO07.LOG';

ALTER DATABASE CLEAR LOGFILE

*

ERROR 位于第 1 :

ORA-12571: TNS:packet writer failure

 

SQL> conn intenral@test

请输入口令:

ERROR

ORA-01092: ORACLE instance terminated. Disconnection forced

SQL>

 

这时候,我们可以退出SQLPLUS,然后重新进来:

SQL> exit

E:/>sqlplus internal

SQL*Plus: Release 8.1.7.0.0 - Production on 星期一 10 7 23:46:17 2002

(c) Copyright 2000 Oracle Corporation.  All rights reserved.

连接到:

Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production

With the Partitioning option

JServer Release 8.1.7.0.0 - Production

 

进来后,shutdown abort数据库,然后,再startup mount

SQL> shutdown abort

ORACLE 例程已经关闭。

SQL> startup mount

ORACLE 例程已经启动。

Total System Global Area   36214812 bytes

Fixed Size                    75804 bytes

Variable Size              19283968 bytes

Database Buffers           16777216 bytes

Redo Buffers                  77824 bytes

数据库装载完毕。

 

可以看到,数据库没有CRASH。现在我们CLEAR GROUP4,先用alter database clear logfile group 4;(如果不行就用alter database clear unarchived logfile group 4;):

SQL> alter database clear logfile group 4;

数据库已更改。

SQL> alter database open;

数据库已更改。

SQL>

 

好了,数据库已经恢复了:

SQL> select * from  v$logfile;

    GROUP# STATUS  MEMBER

---------- ------- ---------------------------------------------------------

         1 STALE   D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG

         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG

         3         D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG

         1 STALE   E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG

         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG

         3         E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG

         4         F:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG

7 rows selected

SQL> SELECT group#, sequence#, bytes, members, status from v$log;

    GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS

---------- ---------- ---------- ---------- ----------------

         1        448    1048576          2 INACTIVE

         2        446    1048576          2 INACTIVE

         3        447    1048576          2 INACTIVE

         4        449    1048576          1 CURRENT

SQL> alter system switch logfile;

System altered

SQL> SELECT group#, sequence#, bytes, members, status from v$log;

    GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS

---------- ---------- ---------- ---------- ----------------

         1        448    1048576          2 INACTIVE

         2        450    1048576          2 CURRENT

         3        447    1048576          2 INACTIVE

         4        449    1048576          1 ACTIVE

SQL>

 

相关讨论:

如果一个TRANSACTION开始运行,这是开始写GROUP 1,没有COMMITROLLBACK,一直到CURRENT=5,然而,这是正在归档2,可是4坏了,那么这样恢复后,数据会丢失么么?

答:不会。    因为,首先GROUP 4 不是CURRENT,那么当SWITCH GROUP 4 SWITCH GROUP 5的时候,已经发生了CHECKPOINT,也就是说,DBWR已经把数据存储在了DATAFILE,所以,在实例恢复的时候,系统检查到GROUP5CURRENT),发现需要做回滚,于是到回滚段中读取所要的数据进行回滚。

    那么如果在从GROUP 4 SWITCHGROUP 5时要发生CHECKPOINT,并且因为如果系统慢或要写的数据块多,或什么其它原因,CHECKPOINT还没结束4也坏了,INSTANCECRASH了,这时重起时INSTANCE RECOVER是需要GROUP 4的,这是会丢失数据么?

答:显然会。因为在实例恢复的时候,因为没有CHECKPOINT,所以数据还没有记录到DATAFILE,所以数据库不知道如何的做前滚,所以,数据库就不能OPEN

 

 

 

2        如果正在写入当前组的所有成员时,LGWR 突然无法访问这些成员,则该数据库例程关闭,在这种情况下,数据库可能需要从联机日志文件残留物进行介质恢复。

确定GROUP4CURRENT,如果不是,则做alter system switch logfile;直到GROUP4CURRENT

SQL> SELECT group#, sequence#, bytes, members, status from v$log;

    GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS

---------- ---------- ---------- ---------- ----------------

         1        452    1048576          2 INACTIVE

         2        450    1048576          2 INACTIVE

         3        451    1048576          2 INACTIVE

         4        453    1048576          1 CURRENT

SQL>  select * from  v$logfile;

    GROUP# STATUS  MEMBER

---------- ------- ---------------------------------------------------------

         1         D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG

         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG

         3         D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG

         1         E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG

         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG

         3         E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG

         4         F:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG

7 rows selected

SQL>

 

 

现在毁坏GROUP4。当你发现这个错误:

SQL> alter database open;

alter database open

*

ERROR 位于第 1 :

ORA-00313: ??????? 4 (?? 1) ???

ORA-00312: ???? 4 ?? 1: 'F:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG'

SQL>

 

那么,然后SHUTDOWN,并且MOUNT数据库:

SQL> shutdown

ORA-01109: ??????

已经卸载数据库。

ORACLE 例程已经关闭。

SQL> startup mount

ORACLE 例程已经启动。

Total System Global Area   36214812 bytes

Fixed Size                    75804 bytes

Variable Size              19283968 bytes

Database Buffers           16777216 bytes

Redo Buffers                  77824 bytes

数据库装载完毕。

 

恢复数据库:

SQL>  recover database until cancel;

完成介质恢复。

SQL> alter database open resetlogs;

数据库已更改。

SQL>

SQL> archive log list

数据库日志模式            存档模式

自动存档             启用

存档终点            d:/oracle1/ora81/oradata/test/archive

最早的概要信息日志序列     1

下一个存档日志序列   1

当前日志序列           1

SQL>

 

以前的ARCHIVE 已经不可用了,需要SHUTDOW,然后作一个FULL BACKUP,之后,再重新STARTUP数据库,就可以了。

 

 

 

 

 

 

 

 

 

 

阅读更多
个人分类: oracle
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭