前一段时间解决了一个ORA-1122错误,正好本机的数据库环境由于Windows的自动重起,导致数据库无法打开,出现错误信息也是ORA-1122。
这次出现错误的表空间是UNDO表空间。
上一篇介绍了利用北京进行恢复的方法,这篇尝试重建UNDO表空间的方法。
UNDO表空间的ORA-1122错误解决(一):http://www.ixdba.net/article/cb/1355.html
由于数据库存在备份,因此可以轻松的对数据库进行恢复,不过难得碰到一个错误的情况,尝试一下是否可以在缺少备份的基础上进行数据库的恢复:
再看一下问题,尝试打开数据库,则会报错:
SQL> CONN /@TEST AS SYSDBA已连接到空闲例程。
SQL> STARTUP MOUNT
ORACLE 例程已经启动。
Total System Global Area 76619308 bytes
Fixed Size 454188 bytes
Variable Size 50331648 bytes
Database Buffers 25165824 bytes
Redo Buffers 667648 bytes数据库装载完毕。
SQL> ALTER DATABASE OPEN;
ALTER DATABASE OPEN
*
ERROR 位于第 1 行:
ORA-01122: 数据库文件 2 验证失败
ORA-01110: 数据文件 2: 'F:ORACLEORADATATESTUNDOTBS01.DBF'
ORA-01200: 25600的实际文件大小小于26880块的正确大小
如果没有备份,那么就只能采用其他的方式来进行恢复,如果出现问题的数据文件中的内容不是关键内容的话,也可以考虑使用ALTER DATABASE DATAFILE OFFLINE的方式。
方法可以参考一个类似的案例:一次ORA-1122错误的解决:http://www.ixdba.net/article/05/1353.html
不过这里出现问题的是UNDO表空间,如果UNDO表空间中没有要回滚的数据,那么问题比较简单,因为Oracle可以更换UNDO表空间,只需要直接将UNDO表空间的数据文件OFFLINE,启动数据库后,新建一个UNDO表空间,并切换当前的UNDO表空间即可。
www.ixdba.net
但是如果UNDO表空间中记录了要回滚的数据,那么恢复操作就会更复杂了。
尝试OFFLINE出现问题的数据文件:
SQL> ALTER DATABASE DATAFILE 'F:ORACLEORADATATESTUNDOTBS01.DBF' OFFLINE;
数据库已更改。
SQL> ALTER DATABASE OPEN;
数据库已更改。
下面可以为系统创建新的UNDO表空间,并实现切换:
SQL> CREATE UNDO TABLESPACE UNDOTBS2 DATAFILE 'F:ORACLEORADATATESTUNDOTBS02.DBF' SIZE 200M;
表空间已创建。
SQL> SHOW PARAMETER UNDO_TABLESPACE
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_tablespace string UNDOTBS1
SQL> ALTER SYSTEM SET UNDO_TABLESPACE = UNDOTBS2;
系统已更改。
虽然数据库已经启动完成,UNDO表空间也已经切换,但是问题并没有结束,如果尝试删除UNDO表空间UNDOTBS1则会报错:
SQL> DROP TABLESPACE UNDOTBS1 INCLUDING CONTENTS AND DATAFILES;
DROP TABLESPACE UNDOTBS1 INCLUDING CONTENTS AND DATAFILES
*
ERROR 位于第 1 行:
ORA-01548: 已找到活动回退段'_SYSSMU1$',终止删除表空间
SQL> SELECT COUNT(*) FROM YANGTK.T;
SELECT COUNT(*) FROM YANGTK.T
*
ERROR 位于第 1 行:
ORA-00376: 此时无法读取文件 2
ORA-01110: 数据文件 2: 'F:ORACLEORADATATESTUNDOTBS01.DBF'
在查询包括需要进行回滚操作的表时,同样会遇到错误。而对于其他没有问题的表,则可以正常访问:
SQL> SELECT COUNT(*) FROM YANGTK.T1;
COUNT(*)
----------
20
现在问题就是前面所提到的,OFFLINE的UNDO表空间中保存着需要进行回滚的记录,而这些记录会导致数据库部分内容还没有最终恢复完成,在此之前受影响的部分对象是无法正常访问的。
SQL> SELECT SEGMENT_NAME, OWNER, TABLESPACE_NAME, STATUS
2 FROM DBA_ROLLBACK_SEGS;
SEGMENT_NAME OWNER TABLESPACE_NAME STATUS
-------------------- ------ -------------------- ----------------