故障概述
今天项目上其他公司的运维人员找我说某数据库好像归档满了,并且他直接rman删了3天前的所有归档,然后发现二节点是宕机的,启动二节点数据库后发现2节点undo数据文件需要recover,这个数据库没有备份。(万幸的是,需要recover的只是2节点undo数据文件)。
切记:!!!!归档日志没有备份的情况下,在删除归档日志之前一定要确认是否存在需要使用归档日志recover的数据文件!!!!!否则如果是数据文件状态异常那只有悲剧了!!!
故障原因:
UNDOTBS2表空间上还有active状态的事务(未提交),二节点由于归档目录满了导致数据库宕机,然后Oracle会将undo表空间下的记录着active未提交的段都标志为NEEDS RECOVERY。
处理思路:
- 有完整备份的情况下,直接备份恢复就可以了,或者直接恢复归档recover就行。
- 如果没有备份,可以用新建的UNDO替代损坏的UNDO,那么损坏UNDO上的未提交事务也将不得不丢弃。当然NEEDS RECOVERY的回滚段需要先进行处理。
注:归档配置的是本地归档,根目录满了;归档满了只会导致数据库夯住,根目录满了会导致oracle无法往日志中写东西从而导致宕机。
故障处理
1. 先将datafile 5 offline
检查确认一下recover的数据文件:
SQL> select file#,status,name from v$datafile where status ='RECOVER';
FILE# STATUS NAME
---------- ------------- ---------------------------------------------------
5 RECOVER +XXXX/XXXX/datafile/undotbs2.267.795022137
1 rows selected
SQL> alter database datafile 5 offline;
Database altered.
2. 替换undo表空间
先创建一个新的undo表空间
SQL> create undo tablespace UNDOTBS02 datafile size 10g autoextend on next 2g;
Tablespace created.
查看当前节点(2节点)的表空间,还是需要recover的undotbs2。
SQL> show parameter undo
NAME TYPE VALUE
------------------- ------------ --------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS2
用新创建的undotbs02替换之前的undotbs2
SQL> alter system set undo_tablespace='UNDOTBS02' scope=both;
System altered.
尝试删除旧undo表空间,报错ora-01548
SQL> drop tablespace UNDOTBS2 including contents and datafiles;
drop tablespace UNDOTBS2 including contents and datafiles
*
ERROR at line 1:
ORA-01548: active rollback segment '_SYSSMU11_3993685818$' found, terminate dropping tablespace
ora-01548报错是因为回滚段上还有未提交活动事务的撤销信息,数据库崩溃重启实例恢复过程中,前滚需要redo(或者归档日志)回滚需要撤销信息,所以undo段需要归档日志进行recover 恢复。
检查回滚段状态:
SQL> select segment_name,status,tablespace_name from dba_rollback_segs where status not in ('ONLINE','OFFLINE') and tablespace_name='UNDOTBS2';
SEGMENT_NAME STATUS TABLESPACE_NAME
------------------------------ ------------------ -----------------------------
_SYSSMU11_3993685818$ NEEDS RECOVERY UNDOTBS2
_SYSSMU12_3786484004$ NEEDS RECOVERY UNDOTBS2
_SYSSMU13_4206247907$ NEEDS RECOVERY UNDOTBS2
_SYSSMU14_3550840220$ NEEDS RECOVERY UNDOTBS2
_SYSSMU15_1667460038$ NEEDS RECOVERY UNDOTBS2
_SYSSMU16_102810502$ NEEDS RECOVERY UNDOTBS2
_SYSSMU17_4197495598$ NEEDS RECOVERY UNDOTBS2
_SYSSMU18_2803337290$ NEEDS RECOVERY UNDOTBS2
_SYSSMU19_2100581483$ NEEDS RECOVERY UNDOTBS2
_SYSSMU20_3702784048$ NEEDS RECOVERY UNDOTBS2
10 rows selected.
3.删除NEEDS RECOVERY的回滚段
设置隐含参数_smu_debug_mode
SQL> alter system set"_smu_debug_mode" = 4;
System altered.
_smu_debug_mode:值为4时代表可以在UNDO自动管理(SMU)下能够进行一些手工的回滚段管理模式下的操作(RBU),也就是可以对回滚段操作。
设置隐含参数_offline_rollback_segments、_corrupted_rollback_segments(这两个参数必须要写进pfile,然后根据pfile启动)
vi /tmp/init.ora
...
_OFFLINE_ROLLBACK_SEGMENTS=(_SYSSMU11_3993685818$,_SYSSMU12_3786484004$,_SYSSMU13_4206247907$,_SYSSMU14_3550840220$,_SYSSMU15_1667460038$,_SYSSMU16_102810502$,_SYSSMU17_4197495598$,_SYSSMU18_2803337290$,_SYSSMU19_2100581483$,_SYSSMU20_3702784048$)
_CORRUPTED_ROLLBACK_SEGMENTS=(_SYSSMU11_3993685818$,_SYSSMU12_3786484004$,_SYSSMU13_4206247907$,_SYSSMU14_3550840220$,_SYSSMU15_1667460038$,_SYSSMU16_102810502$,_SYSSMU17_4197495598$,_SYSSMU18_2803337290$,_SYSSMU19_2100581483$,_SYSSMU20_3702784048$)
...
_offline_rollback_segments:将指定的回滚段强制置为offline状态。
_corrupted_rollback_segments:数据库不会检查回滚段头事务表信息,oracle已经将指定的回滚段置为drop状态。
关闭数据库后以init.ora文件启动数据库。
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount pfile='/tmp/init.ora';
ORACLE instance started.
Total System Global Area 2.6991E+10 bytes
Fixed Size 2213976 bytes
Variable Size 2.5770E+10 bytes
Database Buffers 1073741824 bytes
Redo Buffers 145174528 bytes
Database mounted.
SQL> alter database open;
Database altered.
删除回滚段
SQL> drop rollback segment "_SYSSMU11_3993685818$";
Rollback segment dropped.
……. –由于篇幅限制,此处重复省略
SQL> drop rollback segment "_SYSSMU20_3702784048$";
Rollback segment dropped.
成功drop回滚段后,然后删除之前的undo表空间和数据文件:
SQL> drop tablespace UNDOTBS2 including contents and datafiles;
Tablespace dropped.
检查数据文件是否恢复正常
SQL> select file#,status,name from v$datafile status='ONLINE';
FILE# STATUS NAME
---------- --------------------- --------------------------------------------------------------------------------
1 SYSTEM ++xxx/xxxx/datafile/system.256.795021933
...
10 ONLINE +xxx/xxxx/datafile/undotbs02.289.145649813
10 rows selected.
5号datafile已经不在了,10号datafile正式我们刚刚加的undo数据文件。
去除隐含参数
SQL> alter system reset "_smu_debug_mode";
System altered.
删除pfile后,重启数据库。
$rm -rf /tmp/init.ora
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.
Total System Global Area 2.6991E+10 bytes
Fixed Size 2213976 bytes
Variable Size 2.5770E+10 bytes
Database Buffers 1073741824 bytes
Redo Buffers 145174528 bytes
Database mounted.
Database altered.
在使用完隐含参数后一定要记得去除
总结
本次故障处理是由于删除了undo数据文件recover需要的归档日志,导致数据库无法open。最后通过使用隐含参数跳过数据库检查undo段,然后通过更换undo表空间恢复了数据库。
通过本次故障处理,给广大同行一点小小的建议:
1、 备份!备份!备份!
2、 删除归档日志之前一定要检查数据文件状态,如果是recover状态,删归档必须要慎重。




