现在的位置: 首页 > 综合 > 正文

undo表空间故障特殊恢复(一)

2013年10月11日 ⁄ 综合 ⁄ 共 10490字 ⁄ 字号 评论关闭

author:skate

time:2010-09-09


 undo表空间故障特殊恢复(一)

 

这个测试的是instance recover(单实例里就是crash recovery)的恢复不需要故障undo里的数据,一般的情况instance recover使用联机日志文件的,当发生多版本更新的故障,也可需要回滚段数据的。

 

 

测试环境概要信息:

SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod
PL/SQL Release 10.2.0.4.0 - Production
CORE    10.2.0.4.0      Production
TNS for 32-bit Windows: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production

 

SQL> show parameter undo

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS4
SQL>

 

表tabtest是测试表

 

SQL> select count(1) from tabtest;

  COUNT(1)
----------
     14712

 

模拟回滚段存储一些数据

SQL> insert into tabtest select * from tabtest where rownum <11;

已创建10行。

 

SQL> insert into tabtest select * from tabtest where rownum <11;

已创建10行。

 

SQL> select count(1) from tabtest;

  COUNT(1)
----------
     14732

 

SQL> insert into tabtest select * from tabtest where rownum <3001;

已创建3000行。

 

 

模拟故障,让回滚段的数据没来得回滚,使回滚段在数据库关闭时,保留未commit的事务

 

 

SQL> shutdown abort;
ORACLE 例程已经关闭。
SQL>

 

SQL> quit
从 Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options 断

只有退出sqlplus环境,才能更改回滚段数据文件,删除回滚数据文件,模拟回滚段丢失

 

C:/Documents and Settings/Administrator>sqlplus "/as sysdba"

SQL*Plus: Release 10.2.0.4.0 - Production on 星期四 9月 9 21:55:27 2010

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

已连接到空闲例程。

 

SQL> startup
ORACLE 例程已经启动。

Total System Global Area  574619648 bytes
Fixed Size                  1297944 bytes
Variable Size             234881512 bytes
Database Buffers          331350016 bytes
Redo Buffers                7090176 bytes
数据库装载完毕。
ORA-01157: 无法标识/锁定数据文件 10 - 请参阅 DBWR 跟踪文件
ORA-01110: 数据文件 10: 'E:/ORACLE/PRODUCT/10.2.0/ORADATA/TEST/UNDOTBS31.DBF'

错误出现了,因为我已经删除文件“E:/ORACLE/PRODUCT/10.2.0/ORADATA/TEST/UNDOTBS31.DBF”

 

尝试恢复

 

 

SQL> recover datafile 10;
ORA-00283: 恢复会话因错误而取消
ORA-01110: 数据文件 10: 'E:/ORACLE/PRODUCT/10.2.0/ORADATA/TEST/UNDOTBS31.DBF'
ORA-01157: 无法标识/锁定数据文件 10 - 请参阅 DBWR 跟踪文件
ORA-01110: 数据文件 10: 'E:/ORACLE/PRODUCT/10.2.0/ORADATA/TEST/UNDOTBS31.DBF'

SQL>

 

根据这个错误知道回滚段数据故障会丢失,如果有备份的话,直接recover datafile 很简单就可以恢复,这里假设没有备份,
那该如何处理呢?现在因为回滚段数据文件的故障,导致数据库无法打开,那我们想办法让数据库的检查绕过或修复回滚段数
据文件,数据库open时,所有的数据文件都要online,如果不能online,那就要恢复或者直接把数据文件drop掉。我们这里没有
备份不能恢复,那就drop掉故障的数据文件,然后让数据可以打开,然后在重新创建新的回滚段表空间,让数据库使用新的回滚段
表空间,最后在把有故障的回滚段表空间删除。这是解决问题的基本思路。操作步骤如下:

 

 

SQL> alter database datafile 10 offline drop;

数据库已更改。

 

SQL> select name,status from v$datafile where file#=10;

NAME
--------------------------------------------------------------------------------

STATUS
-------
E:/ORACLE/PRODUCT/10.2.0/ORADATA/TEST/UNDOTBS31.DBF
RECOVER

SQL> alter database open;

数据库已更改。

 

正常情况,数据库时可以被打开的,但有时也会由于其他的一些异常,使数据还是无法打开

 

SQL> select name,status from v$datafile where file#=10;

NAME
--------------------------------------------------------------------------------

STATUS
-------
E:/ORACLE/PRODUCT/10.2.0/ORADATA/TEST/UNDOTBS31.DBF
RECOVER

SQL> show parameter undo

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS3

 

创建新的回滚段表空间

 

SQL> create undo tablespace undotbs1 datafile 'E:/ORACLE/PRODUCT/10.2.0/ORADATA/
TEST/UNDOTBS13.DBF' size 50m;

 

表空间已创建。

 

SQL> alter system set undo tablespace='undotbs1' scope=spfile;
alter system set undo tablespace='undotbs1' scope=spfile
                 *
第 1 行出现错误:
ORA-02065: 非法的 ALTER SYSTEM 选项

 

更改系统的默认回滚段表空间

 

SQL> alter system set undo_tablespace='undotbs1' scope=spfile;

系统已更改。

 

现在查看还是原来的回滚段表空间,说明更改还没生效,需要重新启动数据库,参数的更改才会生效

SQL> show parameter undo

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS3

 

SQL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。

SQL> startup
ORACLE 例程已经启动。

Total System Global Area  574619648 bytes
Fixed Size                  1297944 bytes
Variable Size             234881512 bytes
Database Buffers          331350016 bytes
Redo Buffers                7090176 bytes
数据库装载完毕。
数据库已经打开。

 

这回再查看,就已经是我刚刚新创建的回滚段表空间了!!!

 

SQL> show parameter undo

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      undotbs1

查看下当前系统的使用的回滚段情况

 

 

SQL> select segment_name,status,tablespace_name from dba_rollback_segs;

SEGMENT_NAME                   STATUS           TABLESPACE_NAME
------------------------------ ---------------- ------------------------------
SYSTEM                         ONLINE           SYSTEM
_SYSSMU1$                      ONLINE           UNDOTBS1
_SYSSMU2$                      ONLINE           UNDOTBS1
_SYSSMU3$                      ONLINE           UNDOTBS1
_SYSSMU4$                      ONLINE           UNDOTBS1
_SYSSMU5$                      ONLINE           UNDOTBS1
_SYSSMU6$                      ONLINE           UNDOTBS1
_SYSSMU7$                      ONLINE           UNDOTBS1
_SYSSMU8$                      ONLINE           UNDOTBS1
_SYSSMU9$                      ONLINE           UNDOTBS1
_SYSSMU10$                     ONLINE           UNDOTBS1

SEGMENT_NAME                   STATUS           TABLESPACE_NAME
------------------------------ ---------------- ------------------------------
_SYSSMU11$                     NEEDS RECOVERY   UNDOTBS3
_SYSSMU12$                     NEEDS RECOVERY   UNDOTBS3
_SYSSMU13$                     NEEDS RECOVERY   UNDOTBS3
_SYSSMU14$                     NEEDS RECOVERY   UNDOTBS3
_SYSSMU15$                     NEEDS RECOVERY   UNDOTBS3
_SYSSMU16$                     NEEDS RECOVERY   UNDOTBS3
_SYSSMU17$                     NEEDS RECOVERY   UNDOTBS3
_SYSSMU18$                     NEEDS RECOVERY   UNDOTBS3
_SYSSMU19$                     NEEDS RECOVERY   UNDOTBS3
_SYSSMU20$                     NEEDS RECOVERY   UNDOTBS3

已选择21行。

 

我们已经使用了新的回滚段了, 我们还要把有故障的回滚段表空间删除,你也可以不删除哦

 

SQL> drop tablespace undotbs3 including contents and datafiles;
drop tablespace undotbs3 including contents and datafiles
*
第 1 行出现错误:
ORA-01548: 已找到活动回退段 '_SYSSMU11$', 终止删除表空间

 

这里错误说明回退段 '_SYSSMU11$'还有事务需要恢复,这里的事务我们打开数据库时已经忽略了,默认这里的数据已经提交到系统,
那里面的数据对我们来说就是无用的数据了,那就直接删了它吧,我们这里要用隐含参数“_corrupted_rollback_segments”帮助我们完成。根据具体情况,可能还会要用到如下隐含参数

_allow_resetlogs_corruption
_offline_rollback_segments

 

 

SQL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。

我这里只用了“_corrupted_rollback_segments”

在文本参数文件inittest.ora的最后追加如下一条记录

*._corrupted_rollback_segments=( _SYSSMU12$,_SYSSMU13$,_SYSSMU14$,_SYSSMU15$,_SYSSMU16$,_SYSSMU17$,_SYSSMU18$,_SYSSMU19$,_SYSSMU20$,_SYSSMU11$)

 

然后用inittest.ora启动数据库

 

SQL> startup  pfile='E:/oracle/product/10.2.0/db_1/database/inittest.ora'
ORACLE 例程已经启动。

Total System Global Area  574619648 bytes
Fixed Size                  1297944 bytes
Variable Size             234881512 bytes
Database Buffers          331350016 bytes
Redo Buffers                7090176 bytes
数据库装载完毕。
数据库已经打开。

 

SQL> select segment_name,status,tablespace_name from dba_rollback_segs;

SEGMENT_NAME                   STATUS           TABLESPACE_NAME
------------------------------ ---------------- ------------------------------
SYSTEM                         ONLINE           SYSTEM
_SYSSMU1$                      ONLINE           UNDOTBS1
_SYSSMU2$                      ONLINE           UNDOTBS1
_SYSSMU3$                      ONLINE           UNDOTBS1
_SYSSMU4$                      ONLINE           UNDOTBS1
_SYSSMU5$                      ONLINE           UNDOTBS1
_SYSSMU6$                      ONLINE           UNDOTBS1
_SYSSMU7$                      ONLINE           UNDOTBS1
_SYSSMU8$                      ONLINE           UNDOTBS1
_SYSSMU9$                      ONLINE           UNDOTBS1
_SYSSMU10$                     OFFLINE          UNDOTBS1

SEGMENT_NAME                   STATUS           TABLESPACE_NAME
------------------------------ ---------------- ------------------------------
_SYSSMU11$                     NEEDS RECOVERY   UNDOTBS3
_SYSSMU12$                     NEEDS RECOVERY   UNDOTBS3
_SYSSMU13$                     NEEDS RECOVERY   UNDOTBS3
_SYSSMU14$                     NEEDS RECOVERY   UNDOTBS3
_SYSSMU15$                     NEEDS RECOVERY   UNDOTBS3
_SYSSMU16$                     NEEDS RECOVERY   UNDOTBS3
_SYSSMU17$                     NEEDS RECOVERY   UNDOTBS3
_SYSSMU18$                     NEEDS RECOVERY   UNDOTBS3
_SYSSMU19$                     NEEDS RECOVERY   UNDOTBS3
_SYSSMU20$                     NEEDS RECOVERY   UNDOTBS3

已选择21行。

SQL> drop tablespace undotbs3 including contents and datafiles;

表空间已删除。

 

故障的回滚段表空间已经删除,如下就可以看到

 

 

SQL> select segment_name,status,tablespace_name from dba_rollback_segs;

SEGMENT_NAME                   STATUS           TABLESPACE_NAME
------------------------------ ---------------- ------------------------------
SYSTEM                         ONLINE           SYSTEM
_SYSSMU1$                      ONLINE           UNDOTBS1
_SYSSMU2$                      ONLINE           UNDOTBS1
_SYSSMU3$                      ONLINE           UNDOTBS1
_SYSSMU4$                      ONLINE           UNDOTBS1
_SYSSMU5$                      ONLINE           UNDOTBS1
_SYSSMU6$                      ONLINE           UNDOTBS1
_SYSSMU7$                      ONLINE           UNDOTBS1
_SYSSMU8$                      ONLINE           UNDOTBS1
_SYSSMU9$                      ONLINE           UNDOTBS1
_SYSSMU10$                     ONLINE           UNDOTBS1

已选择11行。

SQL>

 

现在还以文本文件inittest.ora启动数据库,我们要去掉隐含参数

 

SQL> shutdown immediate;
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。

SQL> startup  pfile='E:/oracle/product/10.2.0/db_1/database/inittest.ora'
ORACLE 例程已经启动。

Total System Global Area  574619648 bytes
Fixed Size                  1297944 bytes
Variable Size             234881512 bytes
Database Buffers          331350016 bytes
Redo Buffers                7090176 bytes
数据库装载完毕。
数据库已经打开。

 

创建最新的服务器参数文件

 

SQL> create spfile from pfile;

文件已创建。

 

SQL> shutdown immediate;
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。

SQL> startup
ORACLE 例程已经启动。

Total System Global Area  574619648 bytes
Fixed Size                  1297944 bytes
Variable Size             234881512 bytes
Database Buffers          331350016 bytes
Redo Buffers                7090176 bytes
数据库装载完毕。
数据库已经打开。

 

数据库可以正常打开了,那就检查下数据吧

SQL> select count(1) from tabtest;

  COUNT(1)
----------
     17732

SQL>

 

从这个结果可以看到,那两个10记录的insert已经提交的数据库,而3000条记录的insert未提交的数据库

 

说明:

 

这里用隐含参数强制打开数据库,破坏了数据库的完整性,为了保证数据的安全,最好exp/imp.但如果数据和那庞大,又不允许停机,那就
用analyze table tablename validate structure cascade验证,其实即使是imp/exp也不能保证数据的一致性,因为我们已经把故障回滚段里的数据忽略了,imp/exp也只能尽量保证各种检查点scn一致。

 

 

------end---

 

 

 

 

 

 

 

 

抱歉!评论已关闭.