A-A+
BBED恢复已删除的行记录
参考文档:disassembling the oracle data block,writter by graham thornton 2005
操作系统信息
[oracle@rhl6 lib]$ uname -a Linux rhl6.0x64 2.6.32-71.el6.x86_64 #1 SMP Wed Sep 1 01:33:01 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux
数据库版本
SQL> set line 400
SQL> select * from gv$version;
INST_ID BANNER
---------- --------------------------------------------------------------------------------
1 Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
1 PL/SQL Release 11.2.0.3.0 - Production
1 CORE 11.2.0.3.0 Production
1 TNS for Linux: Version 11.2.0.3.0 - Production
1 NLSRTL Version 11.2.0.3.0 - Production
测试数据
SQL> sho user USER is "YALLONKING" SQL> select rowid,t.* from yallonking t; ROWID ID NAME MY_DATE ------------------ ---------- -------------------- ------------------- AAARcnAAFAAAACEAAA 1 yallonking 2013/07/21 11:12:03 AAARcnAAFAAAACEAAB 2 oraking 2013/07/21 11:12:09 AAARcnAAFAAAACEAAC 3 xiaolong 2013/07/21 11:12:17
删除第三行记录,更新第二行记录
SQL> delete from yallonking where id=3; 1 row deleted. SQL> commit; Commit complete. SQL> update yallonking set name='YALLONKING' where id=2; 1 row updated. SQL> commit; Commit complete. SQL> select rowid,t.* from yallonking t; ROWID ID NAME MY_DATE ------------------ ---------- -------------------- ------------------- AAARcnAAFAAAACEAAA 1 yallonking 2013/07/21 11:12:03 AAARcnAAFAAAACEAAB 2 YALLONKING 2013/07/21 11:12:09
首先比对下这个表三行记录的row flag值
由于记录很少,所以表上的记录会在一个block上的不同offset
SQL> sho user
USER is "SYS"
SQL> select get_rowid('AAARcnAAFAAAACEAAA') from dual;
GET_ROWID('AAARCNAAFAAAACEAAA')
--------------------------------------------------------------------------------
Row_id type is :1
Object# is :71463
Relative_fno is :5
Block number is :132
Row number is :0
转储指定块
SQL> alter session set tracefile_identifier='wyl'; Session altered. SQL> alter system checkpoint; System altered. SQL> alter system dump datafile 5 block 132; System altered.
查看转储文件中关于bitmask的值(--H-FL--)
关于bitmask中8位的说明如下图

此处发现,更新操作,在bitmask中不会有标注。
[root@rhl6 trace]# pwd
/u01/app/oracle/diag/rdbms/ora11gr2/ora11gr2/trace
[root@rhl6 trace]# grep 'Block header dump' -A 100 ora11gr2_ora_11206_wyl.trc
Block header dump: 0x01400084
Object id on Block? Y
seg/obj: 0x11727 csc: 0x00.ba7e9 itc: 2 flg: E typ: 1 - DATA
brn: 0 bdba: 0x1400080 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0002.01d.000002b8 0x00c00715.00b7.14 --U- 1 fsc 0x0000.000bab1a
0x02 0x0005.012.000002b0 0x00c03464.0097.22 --U- 1 fsc 0x0015.000ba7eb
bdba: 0x01400084
data_block_dump,data header at 0x7f539b40ca64
===============
tsiz: 0x1f98
hsiz: 0x18
pbl: 0x7f539b40ca64
76543210
flag=--------
ntab=1
nrow=3
frre=-1
fsbo=0x18
fseo=0x1f39
avsp=0x1f37
tosp=0x1f4e
0xe:pti[0] nrow=3 offs=0
0x12:pri[0] offs=0x1f7f
0x14:pri[1] offs=0x1f39
0x16:pri[2] offs=0x1f52
block_row_dump:
tab 0, row 0, @0x1f7f
tl: 25 fb: --H-FL-- lb: 0x0 cc: 3
col 0: [ 2] c1 02
col 1: [10] 79 61 6c 6c 6f 6e 6b 69 6e 67
col 2: [ 7] 78 71 07 15 0c 0d 04
tab 0, row 1, @0x1f39
tl: 25 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 03
col 1: [10] 59 41 4c 4c 4f 4e 4b 49 4e 47
col 2: [ 7] 78 71 07 15 0c 0d 0a
tab 0, row 2, @0x1f52
tl: 2 fb: --HDFL-- lb: 0x2
end_of_block_dump
End dump data blocks tsn: 5 file#: 5 minblk 132 maxblk 132
注:此处可以看到该块中有3行该表的记录,其中第三行(tab 0, row 2)已经被标记为删除(--HDFL--)
使用bbed进行修改
SQL> col file_name for a50
SQL> set line 400
SQL> select FILE_NAME,b.TABLESPACE_NAME from dba_data_files a,dba_tables b where a.TABLESPACE_NAME=b.TABLESPACE_NAME and b.table_name='YALLONKING';
FILE_NAME TABLESPACE_NAME
-------------------------------------------------- ------------------------------
/u01/app/oracle/oradata/ora11gr2/users01.dbf USERS
BBED> show all
FILE# 5
BLOCK# 1
OFFSET 0
DBA 0x01400001 (20971521 5,1)
FILENAME /u01/app/oracle/oradata/ora11gr2/yallonking01.dbf
BIFILE bifile.bbd
LISTFILE /home/oracle/bbedfile.lst
BLOCKSIZE 8192
MODE Edit
EDIT Unrecoverable
IBASE Dec
OBASE Dec
WIDTH 80
COUNT 512
LOGFILE log.bbd
SPOOL No
BBED> set dba 5,132
DBA 0x01400084 (20971652 5,132)
BBED> find /c xiaolong
File: /u01/app/oracle/oradata/ora11gr2/yallonking01.dbf (5)
Block: 132 Offsets: 8125 to 8191 Dba:0x01400084
------------------------------------------------------------------------
7869616f 6c6f6e67 07787107 150c0d12 2c000302 c103076f 72616b69 6e670778
7107150c 0d0a2c00 0302c102 0a79616c 6c6f6e6b 696e6707 78710715 0c0d0402
061aab
<32 bytes per line>
BBED> find /c xiaolong TOP
File: /u01/app/oracle/oradata/ora11gr2/yallonking01.dbf (5)
Block: 132 Offsets: 8125 to 8191 Dba:0x01400084
------------------------------------------------------------------------
7869616f 6c6f6e67 07787107 150c0d12 2c000302 c103076f 72616b69 6e670778
7107150c 0d0a2c00 0302c102 0a79616c 6c6f6e6b 696e6707 78710715 0c0d0402
061aab
<32 bytes per line>
注:top指定从offset 0 开始,curr指定从当前位置开始
此处发现字符xiaolong的offset是8125,我们需要从该位置向前找到行首位置并查看其bitmask的值,也说明我们要找的offset肯定在8125之前
BBED> map /v dba 5,132
File: /u01/app/oracle/oradata/ora11gr2/yallonking01.dbf (5)
Block: 132 Dba:0x01400084
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0 <<块头结构
ub1 type_kcbh @0 <<块类型
ub1 frmt_kcbh @1 <<块格式(1为oracle 7,2为oracle 8+)
ub1 spare1_kcbh @2
ub1 spare2_kcbh @3
ub4 rdba_kcbh @4 <<相关的数据块地址
ub4 bas_kcbh @8 <<SCN base
ub2 wrp_kcbh @12 <<SCN Wrap
ub1 seq_kcbh @14 <<序列号
ub1 flg_kcbh @15
ub2 chkval_kcbh @16
ub2 spare3_kcbh @18
struct ktbbh, 72 bytes @20
ub1 ktbbhtyp @20
union ktbbhsid, 4 bytes @24
struct ktbbhcsc, 8 bytes @28
sb2 ktbbhict @36
ub1 ktbbhflg @38
ub1 ktbbhfsl @39
ub4 ktbbhfnx @40
struct ktbbhitl[2], 48 bytes @44
struct kdbh, 14 bytes @100
ub1 kdbhflag @100
sb1 kdbhntab @101
sb2 kdbhnrow @102
sb2 kdbhfrre @104
sb2 kdbhfsbo @106
sb2 kdbhfseo @108
sb2 kdbhavsp @110
sb2 kdbhtosp @112
struct kdbt[1], 4 bytes @114
sb2 kdbtoffs @114
sb2 kdbtnrow @116
sb2 kdbr[3] @118 <<行目录
ub1 freespace[7969] @124 <<空闲空间
ub1 rowdata[95] @8093 <<行数据
ub4 tailchk @8188
查看表中3行记录的bitmask值并记录他们的offset值
BBED> p *kdbr[0] <<第一行记录 rowdata[70] ----------- ub1 rowdata[70] @8163 0x2c BBED> p *kdbr[1] <<第二行记录 rowdata[0] ---------- ub1 rowdata[0] @8093 0x2c BBED> p *kdbr[2] <<第三行记录,此处的2可以从之前的trace中标记为'--HDFL--'处获得 rowdata[25] ----------- ub1 rowdata[25] @8118 0x3c
注意:前2行记录都是0x2c(十进制的2*16+12=44= --H-FL-- =0+0+32+0+8+4+0+0=44)
第三行记录是0x3c(十进制的3*16+12=60= --HDFL-- =0+0+32+16+8+4+0+0=60)
所以,我们在这里只需要将第三行的bitmask从0x3c改为0x2c,也就是将之前的trace中的‘--HDFL--’ 改为 ‘--H-FL--’即可,也就是把60变为44即可。
上边我们已找到了需要修改的offset位置了,下边进行修改即可。
BBED> dump /v dba 5,132 offset 8118 File: /u01/app/oracle/oradata/ora11gr2/yallonking01.dbf (5) Block: 132 Offsets: 8118 to 8191 Dba:0x01400084 ------------------------------------------------------- 3c020302 c1040878 69616f6c 6f6e6707 l <...á..xiaolong. 78710715 0c0d122c 000302c1 03076f72 l xq.....,...á..or 616b696e 67077871 07150c0d 0a2c0003 l aking.xq.....,.. 02c1020a 79616c6c 6f6e6b69 6e670778 l .á..yallonking.x 7107150c 0d040206 1aab l q........? <16 bytes per line> BBED> modify /x 2c dba 5,132 offset 8118 <</x是指修改类型为16进制 File: /u01/app/oracle/oradata/ora11gr2/yallonking01.dbf (5) Block: 132 Offsets: 8118 to 8191 Dba:0x01400084 ------------------------------------------------------------------------ 2c020302 c1040878 69616f6c 6f6e6707 78710715 0c0d122c 000302c1 03076f72 616b696e 67077871 07150c0d 0a2c0003 02c1020a 79616c6c 6f6e6b69 6e670778 7107150c 0d040206 1aab <32 bytes per line> BBED> dump /v dba 5,132 offset 8118 File: /u01/app/oracle/oradata/ora11gr2/yallonking01.dbf (5) Block: 132 Offsets: 8118 to 8191 Dba:0x01400084 ------------------------------------------------------- 2c020302 c1040878 69616f6c 6f6e6707 l ,...á..xiaolong. 78710715 0c0d122c 000302c1 03076f72 l xq.....,...á..or 616b696e 67077871 07150c0d 0a2c0003 l aking.xq.....,.. 02c1020a 79616c6c 6f6e6b69 6e670778 l .á..yallonking.x 7107150c 0d040206 1aab l q........? <16 bytes per line>
注意:上边的修改中,我们可以看出已经将3c改为了2c
下边返回到数据库查看恢复的记录。
SQL> alter system flush BUFFER_CACHE; System altered. SQL> select rowid,t.* from yallonking t; ROWID ID NAME MY_DATE ------------------ ---------- -------------------- ------------------- AAARcnAAFAAAACEAAA 1 yallonking 2013/07/21 11:12:03 AAARcnAAFAAAACEAAB 2 YALLONKING 2013/07/21 11:12:09 AAARcnAAFAAAACEAAC 3 xiaolong 2013/07/21 11:12:17
至此ok!