学无止境
分类: Oracle
2010-08-31 16:38:37
实验环境:
SQL> show parameter undo_tablespace
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_tablespace string UNDOTBS1
SQL> select file_name from dba_data_files where tablespace_name='UNDOTBS1';
FILE_NAME
--------------------------------------------------------------------------------
/u01/rc/oradata/UNDOTBS01.DBF
模拟故障:
运行dml语句,在未commit之前,从os上删除undo表空间。然后用另外一个session将数据库shutdown abort。模拟undo故障。
SQL> conn ldy/ldy
Connected.
SQL> select * from cat;
TABLE_NAME TABLE_TYPE
------------------------------ -----------
T001 TABLE
T004 TABLE
GIGA2 TABLE
SQL> desc t001
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NUMBER(20)
NAME VARCHAR2(40)
SQL> update t001 set name='Liaody' where id<101;
99 rows updated.
故障现象:
重新启动数据库,会由于无法找到undo表空间文件而报错,数据库处于mount状态
ORA-01157: cannot identify/lock data file 2 - see DBWR trace file
ORA-01110: data file 2: '/u01/rc/oradata/UNDOTBS01.DBF'
将undo表空间文件置为offline。
alter database datafile '/u01/rc/oradata/UNDOTBS01.DBF' offline;
尝试open数据库,报错,且实例被终结。
SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-01092: ORACLE instance terminated. Disconnection forced
检查alert log有如下信息:
Errors in file /u01/rc/admin/ora10g/udump/ora10g_ora_7330.trc:
ORA-00604: error occurred at recursive SQL level 1
ORA-00376: file 2 cannot be read at this time
ORA-01110: data file 2: '/u01/rc/oradata/UNDOTBS01.DBF'
Error 604 happened during db open, shutting down database
USER: terminating instance due to error 604
Instance terminated by USER, pid = 7330
ORA-1092 signalled during: alter database open...
这是由于从一个crash中恢复,需要读取undo信息。
解决方案:
修改pfile,如果是spfile,从spfile建立pfile,之后用pfile打开。
首先修改参数undo_management='MANUAL',删除UNDO_TABLESPACE和UNDO_RETENTION参数内容。
准备强行open的方法将其打开:
设置隐含参数_ALLOW_RESETLOGS_CORRUPTION = TRUE
仅设置该参数还是不能open数据库。
还需要设置_CORRUPTED_ROLLBACK_SEGMENTS =(comma separated list of Automatic Undo segments)
该隐含参数将有问题的回滚段置为corrupted。
在UNIX下可以通过检查system表空间文件来查找回滚段,注意查找出的内容最后要加上$符号
$ strings SYSTEM01.DBF | grep _SYSSMU | cut -d $ -f 1 | sort -u
[oracle@uprac1 oradata]$ strings SYSTEM01.DBF | grep _SYSSMU | cut -d $ -f 1 | sort -u
and substr(drs.segment_name,1,7) != '_SYSSMU'
^D' and substr(drs.segment_name,1,7) != ''_SYSSMU'' ' );
_SYSSMU1
_SYSSMU1
_SYSSMU10
_SYSSMU2
_SYSSMU2
_SYSSMU3
_SYSSMU3
_SYSSMU4
_SYSSMU4
_SYSSMU5
_SYSSMU5
_SYSSMU6
_SYSSMU6
_SYSSMU7
_SYSSMU7
_SYSSMU8
_SYSSMU8
_SYSSMU8
_SYSSMU9
_SYSSMU9
SYSTEM _SYSSMU9
可以看到回滚段是从_SYSSMU1$到_SYSSMU10$,所以修改该参数为:
_CORRUPTED_ROLLBACK_SEGMENTS = (_SYSSMU1$, _SYSSMU2$, _SYSSMU3$, _SYSSMU4$,
_SYSSMU5$, _SYSSMU6$, _SYSSMU7$, _SYSSMU8$, _SYSSMU9$, _SYSSMU10$)
修改之后,用该pfile启动数据库。
SQL> startup mount pfile='/u01/rc/initORA10G.ora';
ORACLE instance started.
Total System Global Area 314572800 bytes
Fixed Size 1267236 bytes
Variable Size 96471516 bytes
Database Buffers 213909504 bytes
Redo Buffers 2924544 bytes
Database mounted.
SQL> alter database open;
Database altered.
启动成功之后,重建undo表空间,再修改初始化参数文件重启即可。
SQL> drop tablespace undotbs1;
Tablespace dropped.
SQL> create undo tablespace undotbs1 datafile '/u01/rc/oradata/UNDOTBS01.DBF' size 100m;
Tablespace created.