欢迎光临
我们一直在努力

Oracle宕机案例汇总(一)




Oracle宕机案例汇总(一)



案例一:UNDO坏块导致
Oracle无法
Open



场景:


周五马上下班了,研发反馈数据库连不上了,由于是公司内部的数据库,所有数据来源于其他库通过expdp/impdp
导入得到的,主要用于问题重现处理产品
BUG
,数据库的特点是数据量大,用户多,几乎每时每刻数据库都在进行
impdp

drop user
操作,数据允许有部分丢失
….
,好吧,说了这么多,我只想说数据库没有任何备份,当然也没有启动归档模式;




通过告警日志可以马上定位到UNDO
坏块导致的数据库宕机;


ORA-01578


: ORACLE data block corrupted (file #


3


, block #


280


)


ORA-01110: data file 3: '/u02/app/oracle/oradata/orcl11/


undotbs01.dbf


'



最保险的方式,



通过
rman
备份
+
归档进行恢复,可以保证数据的一致性





但是既然没有rman
,也是有方法启动数据库的。



数据库在open
状态下出现
UNDO
损坏比较容易解决,只要创建新的
UNDO
,当前
UNDO
切换到新创建的
UNDO
,删除旧的
UNDO

就可以解决;





但是当前情况是数据库无法OPEN
,只能启动到
mount
状态


SQL>


 startup


ORACLE instance started.


Total System Global Area  784998400 bytes


Fixed Size                  2257352 bytes


Variable Size             515903032 bytes


Database Buffers          264241152 bytes


Redo Buffers                2596864 bytes


Database mounted.


ORA-01092: ORACLE instance terminated. Disconnection forced


ORA-01578


: ORACLE data block corrupted (file #


3


, block #


280


)


ORA-01110: data file 3: '/u02/app/oracle/oradata/orcl11/


undotbs01.dbf


'


Process ID: 8265


Session ID: 1 Serial number: 5


 



显然在mount
状态下是不允许创建和删除
undo
表空间操作


SQL> create undo tablespace UNDOTBS2 datafile '/u02/app/oracle/oradata/orcl11/undotbs02.dbf' size 1M autoextend on;


create undo tablespace UNDOTBS2 datafile '/u02/app/oracle/oradata/orcl11/undotbs02.dbf' size 1M autoextend on


*


ERROR at line 1:


ORA-01109:


 database not open



SQL> drop tablespace UNDOTBS1 including contents and datafiles;


drop tablespace UNDOTBS1 including contents and datafiles


*


ERROR at line 1:


ORA-01109:


database not open


 



那么在数据库不能
open
情况下,如何跳过
undo
坏块,启动数据库呢?



这时可以使用两个隐含参数


”_CORRUPTED_ROLLBACK_SEGMENTS”






 

_offline_rollback_segments




,
两个参数效果很相似。


(1)_CORRUPTED_ROLLBACK_SEGMENTS



表示数据库启动时跳过损坏的回滚段,如果无法确认具体哪个回滚段损坏,会选择跳过所有回滚段,具体用法是在参数文件中增加参数,


_CORRUPTED_ROLLBACK_SEGMENTS=(SYSSMU1$, _SYSSMU2$, _SYSSMU3$, …etc)


 
具体回滚段名称需要查询得到,


(2)_offline_rollback_segments

表示在数据库启动时,可以指定部分回滚段

offline;



现在万事具备了,只需要查询出损坏的回滚段名,或查询出所有回滚段名加入到


_CORRUPTED_ROLLBACK_SEGMENTS



参数中,即可open
数据库了。



某些情况下,在undo
损坏时,会在告警日志中显示几号回滚段损坏,但是本次没有显示具体回滚段名称;




那么问题来了,如何在mount
状态下,查看
UNDO
回滚段名称?



显然mount状态下
是无法直接查询的;


SQL> select * from v$rollname;


select * from v$rollname


              *


ERROR at line 1:


ORA-01219:


database not open: queries allowed on fixed tables/views only


 




那么在数据库mount
或关闭状态下,如何查询数据库
UNDO
段名呢?



一般情况下有两种方法:




方法一:使用操作系统命令strings



,本次案例数据库操作系统为
Redhat6.5;


1.Get SMU information as following command:


[root@chenjch ~]# $strings system01.dbf | grep _SYSSMU | cut -d $ -f 1 | sort -u > listSMU


<=======
请替换
system01.dbf

文件为您的数据库的
system
表空间的数据文件。





得到回滚段名后,在执行如下操作即可


2.Add the following parameter in init.ora:


UNDO_MANAGEMENT=MANUAL


_ALLOW_RESETLOGS_CORRUPTION = TRUE


_CORRUPTED_ROLLBACK_SEGMENTS=(SYSSMU1$, _SYSSMU2$, _SYSSMU3$, …etc)


<=========
请替换
SYSSMU*$

为您的数据库中,步骤
1
查询出来的具体
SYSSMU*$

名称。


3. Startup the database using pfile:


SQL>startup pfile='init.ora'


SQL>show parameter corrupt;


4. Recover and open the database:


SQL>RECOVER DATABASE UNTIL CANCEL;


Cancel


SQL>ALTER DATABASE OPEN RESETLOGS;


 




方法二:bbed
工具



,可以在数据库不启动情况下,直接查询或修改数据块部分信息,当然也可以查询
UNDO
段名称;


11g
开始已经没有这个工具了,需要单独下载;


 


—–Oracle 11g
版本,
undo$
表信息一般位于
1
号文件第
225
个数据块中


BBED> set file 1 block


225


 


       


        FILE#           1


        BLOCK#         225


BBED> map


 File: /u02/app/oracle/oradata/orcl11/system01.dbf (1)


 Block: 225                                   Dba:0x004000e1


————————————————————


 KTB Data Block (Table/Cluster)


……


     


 


sb2 kdbr[25]                               @86     


 


——-
含有
25

UNDO


……


BBED> p


kdbr


sb2 kdbr[0]                                 @86       8078


sb2 kdbr[1]                                 @88       8011


……


sb2 kdbr[23]                                @132      6537


sb2 kdbr[24]                                @134      6470


 


BBED>


 x /rnc *kdbr[0]


        


—-
查看


UNDO
段名称


col    1[6] @8151:


 SYSTEM


 


BBED>


 x /rnc *kdbr[1]


        


—-
查看
1

UNDO
段名称


col   1[20] @8085:


_SYSSMU1_4115952380$


……



依次可以查询出所有UNDO
段名


 



参数文件:


#*.undo_tablespace='UNDOTBS1'


#*.undo_management=AUTO


*.undo_tablespace='SYSTEM'


*.undo_management='MANUAL'


*._corrupted_rollback_segments='_SYSSMU1_4115952380$','_SYSSMU2_3882698531$','_SYSSMU3_1780844141$'


……


'   


SQL> shutdown immediate


 


SQL> startup


ORACLE instance started.


Total System Global Area  784998400 bytes


Fixed Size                  2257352 bytes


Variable Size             515903032 bytes


Database Buffers          264241152 bytes


Redo Buffers                2596864 bytes


Database mounted.


Database


opened


.


 



总结:


通过bbed
工具进行测试,并不是
UNDO
任何块损坏都会造成数据库宕机,只有段头块损坏会出现这个问题,可以通过下面
SQL
查看段头块;

select
 header_file
,
 header_block

  
from
 dba_segments

 
where
 segment_name

like
 
'_SYSSMU%'

 
order
 
by
 
2
;

UNDO
损坏可以分为几种情况:


一:open
状态下损坏,直接新建,切换,删除即可,或通过备份进行恢复;


二:
无法
OPEN
,使用隐含参数跳过损坏的段,启动数据库,或通过备份进行恢复;


有时UNDO
损坏在告警日志中并不会马上报错,之前遇到过数据库服务器断电,来电后启动数据库时
open
阶段一直卡住并没有任何返回结果,后台告警日志也没有输出日志,在打开另一个
sqlplus
窗口,检查数据库状态时,发现数据库已经是
open
状态了,但是所有
dml
语句都会卡住,无法正常执行,这种情况可以考虑到数据块在异常断电启动恢复实例时,要经过前滚和回滚,前滚结束后就可以
open
数据库了,然后在进行回滚,而这

次情况看上去是前滚已经结束,回滚出现异常,可以猜测是UNDO出现问题,在没有备份的情况下,尝试用

_corrupted_rollback_segments


也可以解决问题;




第二种方法更详细解释可以看我另一篇博客


http://blog.itpub.net/29785807/viewspace-2128326/


Oracle_UNDO坏块测试和修复(BBED)


欢迎关注我的微信公众号"IT小Chen",共同学习,共同成长!!!




赞(0)
【声明】:本博客不参与任何交易,也非中介,仅记录个人感兴趣的主机测评结果和优惠活动,内容均不作直接、间接、法定、约定的保证。访问本博客请务必遵守有关互联网的相关法律、规定与规则。一旦您访问本博客,即表示您已经知晓并接受了此声明通告。