暂无图片
暂无图片
7
暂无图片
暂无图片
暂无图片

undo表空间recover状态 故障处理

原创 张洋华 2020-06-22
4025

故障概述

今天项目上其他公司的运维人员找我说某数据库好像归档满了,并且他直接rman删了3天前的所有归档,然后发现二节点是宕机的,启动二节点数据库后发现2节点undo数据文件需要recover,这个数据库没有备份。(万幸的是,需要recover的只是2节点undo数据文件)。
切记:!!!!归档日志没有备份的情况下,在删除归档日志之前一定要确认是否存在需要使用归档日志recover的数据文件!!!!!否则如果是数据文件状态异常那只有悲剧了!!!

故障原因:

UNDOTBS2表空间上还有active状态的事务(未提交),二节点由于归档目录满了导致数据库宕机,然后Oracle会将undo表空间下的记录着active未提交的段都标志为NEEDS RECOVERY。
处理思路

  1. 有完整备份的情况下,直接备份恢复就可以了,或者直接恢复归档recover就行。
  2. 如果没有备份,可以用新建的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状态,删归档必须要慎重。

最后修改时间:2020-07-01 11:51:01
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论