暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

BBED的使用方法

白鳝的洞穴 2020-05-27
7793
昨天的文章中客户在老白指导下用BBED解决了ORA-8102的问题。实际上在这二十多年的工作中,使用bbed解决问题的场景十分少,除了这一次外,还有一次大约是2012年左右,帮助一个快递公司在数据库DG损坏,备份磁带损坏的情况下,用bbed将生产库r01回滚段中不一致的数据修复,强行拉起数据库。除此之外,好像回忆不起来使用BBED解决问题的案例了。BBED修复是一种十分非常规的手段,只有在没办法的时候作为最后的解决方案拿出来的。只要有其他的方法能解决问题,那么一般来说这个方法都比bbed要好。作为一个DBA,掌握一些BBED工具的使用方法还是有用的,用来分析ORACLE数据块的结构,以及遇到类似老白遇到的问题,还是可以派上用场的。作为数据库服务提供人员,用到BBED来修复数据库的场景,往往也是客户很舍得给费用的时候。

获取BBED工具

UNIX/LINUX平台上:

cd $ORACLE_HOME/rdbms/lib

make -f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed

 

 

BBED的密码保护

启动BBED的时候会提示输入密码,BBED的任何版本,任何平台的密码都是blockedit

 

配置LISTFILE

为了方便BBED的使用,建议建立一个LISTFILE,里面包含你需要查看或者修复的数据文件。

SQL>COL NAME FORMAT A60 TRUNCATE

SQL>SET LINE 132

SQL>SET HEAD OFF

SQL> SET PAGES 3000

SQL>SPOOL LISTFILE.TXT

SQL>SELECT FILE#,NAME FROM V$DATAFILE;

SQL>SPOOL OFF

然后编辑LISTFILE.TXT,去掉不用的行就可以了,只保留文件信息就可以了。

 

启动BBED

bbed listfile=listfile.txt mode=edit blocksize=4096

 mode=edit是可以修改数据文件。

操作BBED

设置要查看/修改的文件号

BBED>SET FILE <FN>;

设置要查看修改的BLOCK

BBED>SET BLOCK <BLOCK>;

显示某个地址的值:

BBED>PRINT <ADDR>;

修改某个地址的值:

BBED>MODIFY X 0X....     <ADDR>;

修改CHECKSUM

BBED> SUM APPLY;

 每次修改完,必须做一个SUM APPLY,否则数据块的CHECKSUM就会出现错误。

显示帮助:

BBED>HELP ALL;

BBED>HELP PRINT;

BBED>HELP SET;

 

如何DATA BLOCK计算地址

对于DATA BLOCK来说,每一行的地址数据可以如此获得:

buffer tsn: 0 rdba:0x00400152 (1/338)

scn:0x0000.0150bef5 seq: 0x01 flg: 0x06 tail: 0xbef50601

frmt: 0x02 chkval:0xad32 type: 0x06=trans data

Block headerdump:  0x00400152

 Object id on Block? Y

 seg/obj: 0x1c csc: 0x00.150bef4  itc: 1  flg: - typ: 1 - DATA

     fsl: 0 fnx: 0x0 ver: 0x01

 

 Itl          Xid                  Uba         Flag Lck        Scn/Fsc

0x01   0x0004.004.00006a8b  0x008001b1.070e.03  --U-   1  fsc 0x0000.0150bef5

 

data_block_dump,dataheader at 0x3513044

===============

tsiz: 0xfb8

hsiz: 0x16c

pbl: 0x03513044

bdba: 0x00400152

     76543210

flag=--------

ntab=1

nrow=173

frre=-1

fsbo=0x16c

fseo=0x232

avsp=0x192

tosp=0x192

0xe:pti[0]  nrow=173    offs=0

0x12:pri[0]offs=0xfa7

0x14:pri[1]offs=0xf95

0x16:pri[2]offs=0xf84

0x18:pri[3]offs=0xf70

0x1a:pri[4]offs=0xf5c

0x1c:pri[5]offs=0xf48

0x1e:pri[6]offs=0xf36

0x20:pri[7]offs=0xf24

0x22:pri[8]offs=0xf10

0x24:pri[9]offs=0xefc

0x26:pri[10]    offs=0xeea

0x28:pri[11]    offs=0xed8

0x2a:pri[12]    offs=0x232

 

tab 0, row 12, @0x232

tl: 26 fb: --H-FL-- lb: 0x1  cc: 3

col  0:[ 1]  80

col  1:[16]  5f 4e 45 58 54 5f 43 4f 4e 53 54 5241 49 4e 54

col  2:[ 3]  c2 3d 02

 

 

 

从上面可以看到,第十二行的位置是0x232,这是一个相对地址,需要加上一个BASEBASE的计算:

l 对于字典管理表空间:44+ITC*24

l 对于本地管理表空间:52+ITC*24

因此本案例中是0X232+44+1*24=630

630指的是这一行行头的位置,行头应该以0x2c开始

BBED> set file 1

        FILE#           1

 

BBED> set block338

        BLOCK#          338

 

BBED> print 630

rowdata[0]

----------

ub1 rowdata[0] 

                            @630      0x2c

 

BBED> dump /v

 File: D:\ORACLE\ORADATA\ORA92\SYSTEM01.DBF (1)

 Block: 338    Offsets:  630 to 1141  Dba:0x00400152

-------------------------------------------------------

 2c010301 80105f4e 4558545f 434f4e53 l,....._NEXT_CONS

 54524149 4e5403c2 3d062c00 03018010 lTRAINT..=.,.....

 5f4e4558 545f434f 4e535452 41494e54 l_NEXT_CONSTRAINT

 02c23d2c 00030180 105f4e45 58545f43 l..=,....._NEXT_C

 4f4e5354 5241494e 5403c22c 3a2c0003 lONSTRAINT..,:,..

 0180105f 4e455854 5f434f4e 53545241 l..._NEXT_CONSTRA

 494e5402 c23d2c00 03018010 5f4e4558 lINT..=,....._NEX

 545f434f 4e535452 41494e54 03c22c39 lT_CONSTRAINT..,9

 2c000301 80105f4e 4558545f 434f4e53 l,....._NEXT_CONS

 54524149 4e5402c2 2c2c0003 0180105f lTRAINT..,,....._

 4e455854 5f434f4e 53545241 494e5403 lNEXT_CONSTRAINT.

 c22b642c 00030180 105f4e45 58545f43 l.+d,....._NEXT_C

 4f4e5354 5241494e 5402c22b 2c000301 lONSTRAINT..+,...

 80105f4e 4558545f 434f4e53 54524149 l.._NEXT_CONSTRAI

 4e5403c2 2a642c00 0301800a 5359535f lNT..*d,.....SYS_

 43303031 373303c2 024a2c00 0301800a l C00173...J,.....

 5359535f 43303031 373103c2 02482c00 lSYS_C00171...H,.

 0301800a 5359535f 43303031 363503c2 l....SYS_C00165..

 02422c00 0301800a 5359535f 43303031 l.B,.....SYS_C001

 363603c2 02432c00 0301800a 5359535f l66...C,.....SYS_

 43303031 363703c2 02442c00 0301800a lC00167...D,.....

 5359535f 43303031 363803c2 02452c00 lSYS_C00168...E,.

 0301800a 5359535f 43303031 363903c2 l....SYS_C00169..

 02462c00 0301800a 5359535f 43303031 l.F,.....SYS_C001

 373003c2 02472c00 0301800a 5359535f l70...G,.....SYS_

 43303031 363303c2 02402c00 0301800a lC00163...@,.....

 5359535f 43303031 363403c2 02412c00 lSYS_C00164...A,.

 0301800a 5359535f 43303031 353603c2 l....SYS_C00156..

 02392c00 0301800a 5359535f 43303031 l.9,.....SYS_C001

 353703c2 023a2c00 0301800a 5359535f l57...:,.....SYS_

 43303031 353803c2 023b2c00 0301800a lC00158...;,.....

 5359535f 43303031 353903c2 023c2c00 lSYS_C00159...<,.

 

2c01 03 3个字节是行头,01表示所定1ITL03表示这行有3个字段的值

0180表示0OWNER,0:SYS)

105f4e 4558545f434f4e53 l ,....._NEXT_CONS

 54524149 4e54

以上16+1个字节就是_NEXT_CONSTRAINT

后面就是CON#的值

03 c2 3d 06

03是字段长度,C2 3D 06表示一个数值

C2表示小数点后面有4位,3D=61  61-1=60

  06-1=05

因此这个数值是6005

 

如何计算索引叶节点地址

通过TRACE中的索引叶节点信息:

Block headerdump:  0x0200557a

 Object id on Block? Y

 seg/obj: 0x31 csc: 0x00.23049f4  itc: 5  flg: O typ: 2 - INDEX

     fsl: 0 fnx: 0x200557b ver: 0x01

 

 Itl          Xid                  Uba         Flag Lck        Scn/Fsc

0x01   0x0002.003.00005edb  0x0080bcdc.0b96.01  CB--   0  scn 0x0000.021b9dd5

0x02   0x000a.012.000061e0  0x0080c84c.0b9d.15  --U-   4  fsc 0x003c.02304a14

0x03   0x0006.02f.000061f7  0x0080c767.0c47.20  --U-   5  fsc 0x004b.02304de1

0x04   0x0003.02a.00006239  0x0080c9b1.0bff.1c  C---   0  scn 0x0000.023049de

0x05   0x0007.000.000061ec  0x0080c8c4.0c59.0c  --U-   4  fsc 0x003c.023049f5

 

Leaf block dump

===============

header address13835058056894570660=0xc0000000601b60a4

kdxcolev 0

KDXCOLEV Flags = -- -

kdxcolok 0

kdxcoopc 0x80:opcode=0: iot flags=--- is converted=Y

kdxconco 1

kdxcosdc 1

kdxconro 193   ----行数

kdxcofbo 422=0x1a6

kdxcofeo5114=0x13fa

kdxcoavs 5017

kdxlespl 0

kdxlende 13

kdxlenxt 0=0x0

kdxleprv33576313=0x2005579

kdxledsz 6

kdxlebksz 7944

 

 

row#192[5166] flag:------, lock: 0, len=13, data:(6):  00 4000 aa 00 11

col 0; len 4;(4):  c3 45 42 0e

 

 

索引的位置计算也是BASE+5166(44+24*5+5166)

索引记录的格式:

<LCK> 00+ROWID+索引字段,比如本例的索引

00 00 00 40 00 aa00 11 04 c3 45 42 0e

更详细的关于数据块的结构的信息,可以参考老白的书《DBA的思想天空》中的相关章节。老白梳理了这些数据结构的C代码头文件,如果有需要研究的,也可以找老白索取。
最后修改时间:2020-05-27 09:34:18
文章转载自白鳝的洞穴,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论