特殊恢复:ORA-00704、ORA-00604、ORA-01555故障时快速定位触发报错的数据块

特殊恢复:ORA-00704、ORA-00604、ORA-01555故障时快速定位触发报错的数据块

我们的文章会在微信公众号IT民工的龙马人生博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢!
由于博客中有大量代码,通过页面浏览效果更佳。

一、故障背景

在一次数据库启动过程中,遇到了严重的启动失败,alert日志和trace文件中多次出现 ORA-01555: snapshot too old 相关报错,导致数据库无法正常open。本文记录了本次故障的详细遇到此类问题时,如何跟踪问题、分析trace文件,快速定位触发报错的数据库,供遇到类似问题的同仁参考。

二、故障现象

数据库启动时,alert 日志和 trace 文件中出现如下报错:

Errors in file /oracle/app/oracle/admin/asm10g/udump/asm10g_ora_4251.trc:
ORA-00704: bootstrap process failure
ORA-00604: error occurred at recursive SQL level 1
ORA-01555: snapshot too old: rollback segment number 8 with name "_SYSSMU8$" too small

这里看到已经出现了ORA-01555的报错,默认trace文件不包括详细的trace信息

三、开启详细 trace

为了进一步定位问题,需要开启 10046 事件和 errorstack,获取更详细的 trace 信息:

www.htz.pw > oradebug setmypid
Statement processed.
www.htz.pw > oradebug event 10046 trace name context forever,level 12;
Statement processed.
www.htz.pw > oradebug event 1555 trace name errorstack forever,level 12;
Statement processed.
www.htz.pw > alter database open resetlogs;

在alert文件中可以发现下面的详细信息

ORA-01555 caused by SQL statement below (SQL ID: 2ajy4zgqrakrx, SCN: 0x0001.4000007b):
Sun Jul 20 22:16:45 CST 2014
select ts#,file#,block#,nvl(bobj#,0),nvl(tab#,0),intcols,nvl(clucols,0),audit$,flags,pctfree$,pctused$,initrans,maxtrans,rowcnt,blkcnt,empcnt,avgspc,chncnt,avgrln,analyzetime, samplesize,cols,property,nvl(degree,1),nvl(instances,1),avgspc_flb,flbcnt,kernelcols,nvl(trigflag, 0),nvl(spare1,0),nvl(spare2,0),spare4,spare6 from tab$ where obj#=:1
Sun Jul 20 22:16:45 CST 2014
Errors in file /oracle/app/oracle/admin/asm10g/udump/asm10g_ora_4251.trc:
ORA-01555: snapshot too old: rollback segment number 8 with name "???" too small
Sun Jul 20 22:16:47 CST 2014
Errors in file /oracle/app/oracle/admin/asm10g/udump/asm10g_ora_4251.trc:
ORA-01555: snapshot too old: rollback segment number 8 with name "_SYSSMU8$" too small
Sun Jul 20 22:16:48 CST 2014
Errors in file /oracle/app/oracle/admin/asm10g/udump/asm10g_ora_4251.trc:
ORA-00604: error occurred at recursive SQL level 1
ORA-01555: snapshot too old: rollback segment number 8 with name "_SYSSMU8$" too small
Sun Jul 20 22:16:48 CST 2014
Errors in file /oracle/app/oracle/admin/asm10g/udump/asm10g_ora_4251.trc:
ORA-00704: bootstrap process failure
ORA-00604: error occurred at recursive SQL level 1
ORA-01555: snapshot too old: rollback segment number 8 with name "_SYSSMU8$" too small

这里看到了报错的trace文件。

四、trace 文件分析

4.1 查找块与 ITL 信息

通过 grep 命令快速定位 trace 文件中的块头信息:

grep -E "^Block he|^0x0" /oracle/app/oracle/admin/asm10g/udump/asm10g_ora_4251.trc

输出内容类似如下:

Block header dump:  0x00400026
0x01   0x0000.007.00000011  0x00400017.0019.43  C---    0  scn 0x0000.000008f6
0x02   0x0008.012.000000fe  0x008009f2.00dd.02  ----    2  fsc 0x0000.00000000
...

可以看到,涉及的块号、SCN、ITL 等信息都被详细记录。

4.2 查看报错 SQL 的等待事件

在 trace 文件中查找 SQL 语句的等待事件:

=====================
PARSING IN CURSOR #2 len=343 dep=1 uid=0 oct=3 lid=0 tim=1372915825389474 hv=3983887101 ad='83688078'
select ts#,file#,block#,nvl(bobj#,0),nvl(tab#,0),intcols,nvl(clucols,0),audit$,flags,pctfree$,pctused$,initrans,maxtrans,rowcnt,blkcnt,empcnt,avgspc,chncnt,avgrln,analyzetime, samplesize,cols,property,nvl(degree,1),nvl(instances,1),avgspc_flb,flbcnt,kernelcols,nvl(trigflag, 0),nvl(spare1,0),nvl(spare2,0),spare4,spare6 from tab$ where obj#=:1
END OF STMT
EXEC #2:c=0,e=37,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=1372915825389473
WAIT #2: nam='db file sequential read' ela= 254 file#=1 block#=38 blocks=1 obj#=4 tim=1372915825389837

这里可能会存在多条此SQL语句

4.3 查看 SQL 的绑定变量信息

继续查找 SQL 的绑定变量:

Cursor#2(0x2ba396ac1a88) state=FETCH curiob=0x2ba396adafc8
 curflg=8007 fl2=200000 par=0x2ba396ac1a20 ses=0x83b8f158
 sqltxt(0x83688078)=
select ts#,file#,block#,nvl(bobj#,0),nvl(tab#,0),intcols,nvl(clucols,0),audit$,flags,pctfree$,pctused$,initrans,maxtrans,rowcnt,blkcnt,empcnt,avgspc,chncnt,avgrln,analyzetime, samplesize,cols,property,nvl(degree,1),nvl(instances,1),avgspc_flb,flbcnt,kernelcols,nvl(trigflag, 0),nvl(spare1,0),nvl(spare2,0),spare4,spare6 from tab$ where obj#=:1
  hash=3a1c00e80fafeffb2547c4fbed754afd
  parent=0x8038f1d0 maxchild=01 plk=0x80b3f668 ppn=n
cursor instantiation=0x2ba396adafc8 used=1405865804
 child#0(0x83687e48) pcs=0x8038e7f0
  clk=0x80b259b0 ci=0x8038e4c8 pn=0x836ead50 ctx=0x7ff93148
 kgsccflg=1 llk[0x2ba396adafd0,0x2ba396adafd0] idx=fe
 xscflg=e01414f6 fl2=45000401 fl3=4022210c fl4=100
 Bind bytecodes
  Opcode = 1   Unoptimized
  Offsi = 48, Offsi = 0
kkscoacd
 Bind#0
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0
  kxsbbbfp=2ba3971a9ba0  bln=22  avl=03  flg=05
  value=255

4.4 查看 SQL 访问的块

这里是查看报错时的正在访问的块,在上2步中,我们看到了Cursor#2,在10046中可以找到PARSING IN CURSOR #2,可以看到SQL的WAIT中WAIT #2: nam=‘db file sequential read’ ela= 254 file#=1 block#=38 blocks=1 obj#=4 tim=1372915825389837,这就代表最后访问的一个块是1,38
另外我们也可以在相同的版本的数据库中去查询
在trace中以1/38去查看,能找到下面的信息

BH (0x79ff8f58) file#: 1 rdba: 0x00400026 (1/38) class: 1 ba: 0x79f68000
  set: 3 blksize: 8192 bsi: 0 set-flg: 2 pwbcnt: 0
  dbwrid: 0 obj: 2 objn: 4 tsn: 0 afn: 1
  hash: [833bebb8,833bebb8] lru: [79ff90e8,79ff8ec8]
  obj-flags: object_ckpt_list
  ckptq: [829a5d30,829a5d30] fileq: [829a5d50,829a5d50] objq: [80b4d860,80b4d860]
  use: [829956a0,829956a0] wait: [NULL]
  st: XCURRENT md: SHR tch: 0
  flags: buffer_dirty redo_since_read
  LRBA: [0x1.3.0] HSCN: [0x1.4000007b] HSUB: [1]
  buffer tsn: 0 rdba: 0x00400026 (1/38)
  scn: 0x0001.4000007b seq: 0x01 flg: 0x00 tail: 0x007b0601
  frmt: 0x02 chkval: 0x0000 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
在以0x00400026能查找到下面信息
Block header dump:  0x00400026
 Object id on Block? Y
 seg/obj: 0x2  csc: 0x01.4000007b  itc: 2  flg: -  typ: 1 - DATA
     fsl: 0  fnx: 0x0 ver: 0x01

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0000.007.00000011  0x00400017.0019.43  C---    0  scn 0x0000.000008f6
0x02   0x0008.012.000000fe  0x008009f2.00dd.02  ----    2  fsc 0x0000.00000000

五、问题分析

通过上述 trace 分析,可以确认:

  • 报错 SQL 为系统内部的递归 SQL,访问 tab$ 表。
  • 访问的块 file#=1 block#=38,ITL 信息显示有事务未能及时回滚,导致快照过旧。
  • 报错的回滚段为 “_SYSSMU8$”,说明是自动管理的 UNDO 段空间不足。

故障解决

故障解决可以参考之前发过的一篇文章:特殊恢复:ORA-00704、ORA-00604、ORA-01555的分析与处理

------------------作者介绍-----------------------
姓名:黄廷忠
现就职:Oracle中国高级服务团队
曾就职:OceanBase、云和恩墨、东方龙马等
个人博客: (http://www.htz.pw)
CSDN地址: (https://blog.csdn.net/wwwhtzpw)
博客园地址: (https://www.cnblogs.com/www-htz-pw)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值