Oracle异常恢复BBED系列

0    651    1

Tags:

👉 本文共约64998个字,系统预计阅读时间或需245分钟。

BBED模拟并修复ORA-08102错误

前言部分

导读和注意事项

各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~:

① 使用BBED修复ORA-08102错误(重点)

② BBED的使用

③ 数据块格式的dump文件解释

④ ORA-08102错误的trace文件解释

⑤ 从rdba获取ROWID信息

⑥ 其它实用技能

本文简介

这几天一个朋友问我有关ORA-08102的错误,而且是关于OBJ$表上的I_OBJ4索引。这些系统对象的索引,不能采用重建或设置事件的方式来修复该错误。模模糊糊的记得很早以前看过使用BBED的方式来修复该错误,只是已经记不清了。正好,趁此机会把该错误再模拟的复现一下,也把bbed再熟悉一下吧。

朋友发给我的参考文章也是大师惜分飞的博客地址,大致看了一下过程,主要是找到索引块的相关地址,然后利用bbed把键值修改的和表中存储的一致即可。还是那句话,“纸上得来终觉浅,绝知此事要躬行。”,自己模拟实验,这个过程是必须的。

废话不多说,开始实验吧。

相关文章链接

阅读本篇文章,请先阅读以下内容:

  1. Oracle 中 Object_iD 和 Data_Object_ID 的区别:http://blog.itpub.net/26736162/viewspace-2145230/
  2. Oracle的dump函数:http://blog.itpub.net/26736162/viewspace-2145228/

注意事项

  1. bbed毕竟是未公开的恢复方式,所以不熟悉的朋友要慎用。
  2. startup force慎用
  3. 操作bbed之前最好先把数据库关闭

相关知识点扫盲

An ORA-08102 indicates that there is a mismatch between the key(s) stored in the index and the values stored in the table.What typically happens in the index is built and at some future time,some type of corruption occurs,either in the table or index,to cause the mismatch.

ORA-08102常见于索引键值与表上存的值不一致。

ora-08102这种错误说明索引或表出现了数据不一致,索引上记录的键值和表里的数据不一致,引起访问失败,一般重建下索引就可以解决。两边不一致改表和索引都能达到目的,只要一致即可,但有一个原则就是索引键值始终要保证按顺序递增。通常有三种情况:

1.如果损坏为索引,则删除索引并重建索引,但对于index的obj#小于56的情况,由于是核心的bootstrap$对象,index是在DB启动时由DB自动创建,此种情况下通过设置event 38003或startup migrate模式都不能解决,但obj#>56的则可以。

2.如果损坏为块级别,则采用坏块的处理方法

3.如果损坏的为表的记录级别的则采用bbed或其它工具

I_OBJ1、I_OBJ2、I_OBJ3、I_OBJ4、I_OBJ5这几个都是OBJ$基表的索引,如果损坏会非常麻烦,因为ORACLE 对这些对象的DDL做了严格限制,没有办法简单修复它们。

实验环境介绍

项目source db
db 类型单机
db version11.2.0.3.0
db 存储FS
OS版本及kernel版本RHEL 6.5

实验目标

实验目标:使用BBED模拟并修复ORA-08102错误。

模拟错误过程:通过bbed修改OBJ$表中DATAOBJ#列最大的行所在的块,让DATAOBJ#的值增大,从而和索引中记录的值不一致。重启数据库并创建表让数据库报出ORA-08102错误。

修复错误过程:通过bbed把表中或索引中的不一致的数据修改成一致的,从而修复ORA-08102错误。

实验过程

做全备

模拟一:BBED模拟ORA-08102错误

通过BBED修改OBJ$中DATAOBJ$重现I_OBJ4索引报ORA-08102错误。定位需要破坏的OBJ$上DATAOBJ$列最大的记录,使之和索引I_OBJ4中记录不一致,从而实现ORA-8102错误。

根据以上的SQL可以得到下表的内容:

项目
OBJ$上DATAOBJ#列的最大值94098
OBJ$上DATAOBJ#列的最大值dump值Typ=2 Len=4: c3,a,29,63 即:04c30a2963
该行所在数据块的地址FILE# BLOCK# ROW# ---------- ---------- ---------- 1 241 27
该行的存储情况COUNTS MAX_ROWNUM MIN_ROWNUM ---------- ---------- ---------- 105 104 0

即:OBJ$表上DATAOBJ#列的最大值为94098,该值在Oracle数据库中的存储格式为04c30a2963,该行数据所在的块为1号文件,241号块,第27行,该块上共有105行数据,最大值的行号为104,最小值的行号为0

dump文件解析

先对1号文件,241号块做dump:

关于块格式的详细介绍请参考:<http://blog.itpub.net/26736162/viewspace-2141499/

由于SYS.OBJ$表共21列,但是最后3列都为空,所以,dump文件里就没有显示出来。将该行数据以16进制dump出来看看:

结果和dump文件中的内容一致。

列名10进制值16进制值dump文件的存储
OBJ#1Typ=2 Len=2: c1,2col 0: [ 2] c1 02
DATAOBJ#94098Typ=2 Len=4: c3,a,29,63col 1: [ 4] c3 0a 29 63
OWNER#0Typ=2 Len=1: 80col 2: [ 1] 80
NAME_NEXT_OBJECTTyp=1 Len=12: 5f,4e,45,58,54,5f,4f,42,4a,45,43,54col 3: [12] 5f 4e 45 58 54 5f 4f 42 4a 45 43 54
NAMESPACE1Typ=2 Len=2: c1,2col 4: [ 2] c1 02
SUBNAMENULLcol 5: *NULL*
TYPE#0Typ=2 Len=1: 80col 6: [ 1] 80
CTIME2011-09-17 09:46:13Typ=12 Len=7: 78,6f,9,11,a,2f,ecol 7: [ 7] 78 6f 09 11 0a 2f 0e
MTIME2017-09-20 18:28:36Typ=12 Len=7: 78,75,9,14,13,1d,25col 8: [ 7] 78 75 09 14 13 1d 25
STIME2011-09-17 09:46:13Typ=12 Len=7: 78,6f,9,11,a,2f,ecol 9: [ 7] 78 6f 09 11 0a 2f 0e
STATUS0Typ=2 Len=1: 80col 10: [ 1] 80
REMOTEOWNERNULLcol 11: *NULL*
LINKNAMENULLcol 12: *NULL*
FLAGS0Typ=2 Len=1: 80col 13: [ 1] 80
OID$NULLcol 14: *NULL*
SPARE10Typ=2 Len=1: 80col 15: [ 1] 80
SPARE265535Typ=2 Len=4: c3,7,38,24col 16: [ 4] c3 07 38 24
SPARE30Typ=2 Len=1: 80col 17: [ 1] 80

所以,从dump文件中还可以得到第27行数据的指针偏移位置是13b,转换为10进制是315。

使用bbed破坏该块中的第27行数据

使用bbed破坏记录,修改dataobj#中的值,使得obj$.dataobj#和i_obj4中的dataobj#不匹配。

当然,也可以使用find来直接查询:

94098和94099对应的存储格式:

使用bbed 修改04c30a2963为04c30a2964,即把94098修改为94099,如下所示:

修改后查看该行记录的内容:

可以看到成功的将94098修改为94099。

本人提供Oracle(OCP、OCM)、MySQL(OCP)、PostgreSQL(PGCA、PGCE、PGCM)等数据库的培训和考证业务,私聊QQ646634621或微信dbaup66,谢谢!
AiDBA后续精彩内容已被站长无情隐藏,请输入验证码解锁本文!
验证码:
获取验证码: 请先关注本站微信公众号,然后回复“验证码”,获取验证码。在微信里搜索“AiDBA”或者“dbaup6”或者微信扫描右侧二维码都可以关注本站微信公众号。

标签:

Avatar photo

小麦苗

学习或考证,均可联系麦老师,请加微信db_bao或QQ646634621

您可能还喜欢...

发表回复