使用bbed恢复delete 的rows

参考:http://blog.csdn.net/tianlesoftware/article/details/6684505

  When rows are deleted in Oracle the data is not actually removed. The row is simplymarked as deleted and the free space counters and pointers adjustedaccordingly. The status of a row is stored in the Row Header which occupies thefirst few bytes of each row.


  当row 被delete 的时候,实际上data 并没有被remove,只是将该row 标记为delete,然后其对应的空间被统计为free space。 row 的status 存在每个row的row header里。

 

  TheRow Header consists of the Row Flag, Lock Byte (ITL entry) and Column Count.The first of these - the Row Flag - is a single byte that holds a bitmask thatshows the status of the row. The bitmask is decoded as follows:

  RowHeader 包含Row Flag,Lock Byte(ITL)和column Count。其中Row Flag占用1个byte,并且以bitmask 来保存。bitmask 的解释如下:



实验如下:

1.创建环境表DVD
SQL> conn hr/hr;
Connected.
SQL>
SQL> create table dvd(job varchar2(100));

Table created.

SQL> insert into dvd values('Dave is DBA!');

1 row created.

SQL> insert into dvd values('Dave like Oracle!');

1 row created.

SQL> commit;

Commit complete.

SQL>  conn / as sysdba
Connected.
SQL>
SQL> set lines 200
SQL> select OWNER,TABLE_NAME,TABLESPACE_NAME from dba_tables where table_name='DVD';

OWNER                          TABLE_NAME                     TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------
HR                             DVD                            USERS


2.查询dvd相关file/block信息;
SQL> select rowid,dbms_rowid.rowid_relative_fno(rowid) rel_fno,dbms_rowid.rowid_block_number(rowid) blockno,dbms_rowid.rowid_row_number(rowid) rowno,a.* from dvd a;

ROWID                 REL_FNO    BLOCKNO      ROWNO JOB
------------------ ---------- ---------- ---------- ----------------------------------------------------------------------------------------------------
AAAV8YAAEAAAAIPAAA          4        527          0 Dave is DBA!
AAAV8YAAEAAAAIPAAB          4        527          1 Dave like Oracle!

SQL>


--新开一个窗口执行dump块查询信息
oracle@wang ~]$   sqlplus / as sysdba

SQL*Plus: Release 11.2.0.4.0 Production on Tue Nov 28 14:31:49 2017

Copyright (c) 1982, 2013, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> alter system dump datafile 4 block 527;

System altered.

SQL> oradebug setmypid
Statement processed.
SQL>
SQL> oradebug tracefile_name
/u01/app/oracle/diag/rdbms/dbdb/DBdb/trace/DBdb_ora_2013.trc
SQL>


--查看trace:
[oracle@wang ~]$ more /u01/app/oracle/diag/rdbms/dbdb/DBdb/trace/DBdb_ora_2013.trc
Trace file /u01/app/oracle/diag/rdbms/dbdb/DBdb/trace/DBdb_ora_2013.trc
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
ORACLE_HOME = /u01/app/oracle/product/11.2.0/db_1
System name:    Linux
Node name:      wang
Release:        3.10.0-327.el7.x86_64
Version:        #1 SMP Thu Oct 29 17:29:29 EDT 2015
Machine:        x86_64
Instance name: DBdb
Redo thread mounted by this instance: 1
Oracle process number: 27
Unix process pid: 2013, image: oracle@wang (TNS V1-V3)


*** 2017-11-28 14:31:56.277
*** SESSION ID:(40.13) 2017-11-28 14:31:56.277
*** CLIENT ID:() 2017-11-28 14:31:56.277
*** SERVICE NAME:(SYS$USERS) 2017-11-28 14:31:56.277
*** MODULE NAME:(sqlplus@wang (TNS V1-V3)) 2017-11-28 14:31:56.277
*** ACTION NAME:() 2017-11-28 14:31:56.277
 
Start dump data blocks tsn: 4 file#:4 minblk 527 maxblk 527
Block dump from cache:
Dump of buffer cache at level 4 for tsn=4 rdba=16777743
BH (0x89ff27e8) file#: 4 rdba: 0x0100020f (4/527) class: 1 ba: 0x89eee000
  set: 3 pool: 3 bsz: 8192 bsi: 0 sflg: 2 pwc: 0,0
  dbwrid: 0 obj: 89880 objn: 89880 tsn: 4 afn: 4 hint: f
  hash: [0x8fe6a618,0x87fd9a18] lru: [0x89ff2a10,0x89ff27a0]
  ckptq: [NULL] fileq: [NULL] objq: [0x89ff2a38,0x8b4e5e60] objaq: [0x89ff2a48,0x8b4e5e50]
  st: XCURRENT md: NULL fpin: 'ktspbwh2: ktspfmdb' tch: 5
  flags: block_written_once redo_since_read
  LRBA: [0x0.0.0] LSCN: [0x0.0] HSCN: [0xffff.ffffffff] HSUB: [1]
Block dump from disk:
buffer tsn: 4 rdba: 0x0100020f (4/527)
scn: 0x0000.0039530d seq: 0x01 flg: 0x06 tail: 0x530d0601
frmt: 0x02 chkval: 0x9014 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x00007F3C1C8B7A00 to 0x00007F3C1C8B9A00
7F3C1C8B7A00 0000A206 0100020F 0039530D 06010000  [.........S9.....]
7F3C1C8B7A10 00009014 00000001 00015F18 00395308  [........._...S9.]
7F3C1C8B7A20 00000000 00320002 01000208 00160002  [......2.........]
7F3C1C8B7A30 000005FA 00C3D82B 00180272 00002002  [....+...r.... ..]
7F3C1C8B7A40 0039530D 00000000 00000000 00000000  [.S9.............]
7F3C1C8B7A50 00000000 00000000 00000000 00000000  [................]
7F3C1C8B7A60 00000000 00020100 0016FFFF 1F5D1F73  [............s.].]
7F3C1C8B7A70 00001F5D 1F880002 00001F73 00000000  [].......s.......]
7F3C1C8B7A80 00000000 00000000 00000000 00000000  [................]
        Repeat 500 times
7F3C1C8B99D0 00000000 2C000000 44110101 20657661  [.......,...Dave ]
7F3C1C8B99E0 656B696C 61724F20 21656C63 0C01012C  [like Oracle!,...]
7F3C1C8B99F0 65766144 20736920 21414244 530D0601  [Dave is DBA!...S]
Block header dump:  0x0100020f
 Object id on Block? Y
 seg/obj: 0x15f18  csc: 0x00.395308  itc: 2  flg: E  typ: 1 - DATA
     brn: 0  bdba: 0x1000208 ver: 0x01 opc: 0
     inc: 0  exflg: 0
 
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0002.016.000005fa  0x00c3d82b.0272.18  --U-    2  fsc 0x0000.0039530d
0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
bdba: 0x0100020f
data_block_dump,data header at 0x7f3c1c8b7a64
===============
tsiz: 0x1f98
hsiz: 0x16
pbl: 0x7f3c1c8b7a64
     76543210
flag=--------
ntab=1
nrow=2
frre=-1
fsbo=0x16
fseo=0x1f73
avsp=0x1f5d
tosp=0x1f5d
0xe:pti[0]      nrow=2  offs=0
0x12:pri[0]     offs=0x1f88
0x14:pri[1]     offs=0x1f73
block_row_dump:
tab 0, row 0, @0x1f88
tl: 16 fb: --H-FL-- lb: 0x1  cc: 1
col  0: [12]  44 61 76 65 20 69 73 20 44 42 41 21
tab 0, row 1, @0x1f73
tl: 21 fb: --H-FL-- lb: 0x1  cc: 1
col  0: [17]  44 61 76 65 20 6c 69 6b 65 20 4f 72 61 63 6c 65 21
end_of_block_dump
End dump data blocks tsn: 4 file#: 4 minblk 527 maxblk 527

*** 2017-11-28 14:31:57.368
Processing Oradebug command 'setmypid'

*** 2017-11-28 14:31:57.368
Oradebug command 'setmypid' console output:

*** 2017-11-28 14:32:00.927
Processing Oradebug command 'tracefile_name'

*** 2017-11-28 14:32:00.927
Oradebug command 'tracefile_name' console output:
/u01/app/oracle/diag/rdbms/dbdb/DBdb/trace/DBdb_ora_2013.trc
[oracle@wang ~]$

我们的表dvd里只有2行记录,所以这里显示的row 为2.
注意这里的fb: --H-FL--。 其有8个选项,每个值分别与bitmask 对应。

Therefore,columns that fit within a single block, are not chained, migrated or part of aclustered table and are not deleted will have the following attributes:
(1)Head of Row Piece
(2)First Data Piece
(3)Last Data Piece
       
如果一个row 没有被删除,那么它就具有上面的3个属性,即Flag 表示为:--H-FL--. 这里的字母分别代表属性的首字母。其对应的值:32 + 8 + 4 =44 or 0x2c.

如果一个row 被delete了,那么row flag 就会更新,bitmask 里的deleted 被设置为16. 此时row flag 为: 32 + 16 + 8 + 4 = 60 or 0x3c.

--验证一下:
SQL> select rowid,dbms_rowid.rowid_relative_fno(rowid) rel_fno,dbms_rowid.rowid_block_number(rowid) blockno,dbms_rowid.rowid_row_number(rowid) rowno from dvd;

ROWID                 REL_FNO    BLOCKNO      ROWNO
------------------ ---------- ---------- ----------
AAAV84AAEAAAAIPAAA          4        527          0
AAAV84AAEAAAAIPAAB          4        527          1

SQL> select * from dvd;

JOB
--------------------------------------------------------------------------------
Dave is DBA!
Dave like Oracle!

SQL> delete from dvd where rownum=1;

1 row deleted.

SQL> commit;

Commit complete.

SQL> select * from dvd;

JOB
--------------------------------------------------------------------------------
Dave like Oracle!

--再次查看dump 的标记:
[oracle@wang ~]$   sqlplus / as sysdba

SQL*Plus: Release 11.2.0.4.0 Production on Tue Nov 28 14:36:29 2017

Copyright (c) 1982, 2013, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

--需先flush buffer_cache清空buffer:
SQL>  alter system flush buffer_cache;

System altered.

SQL> alter system dump datafile 4 block 527;

System altered.

SQL>
SQL> oradebug setmypid
Statement processed.
SQL>
SQL> oradebug tracefile_name
/u01/app/oracle/diag/rdbms/dbdb/DBdb/trace/DBdb_ora_2065.trc
SQL>
SQL>

--再次查看trace文件:
[oracle@wang ~]$ more /u01/app/oracle/diag/rdbms/dbdb/DBdb/trace/DBdb_ora_2065.trc
省略................................................................
省略................................................................
省略................................................................
block_row_dump:
tab 0, row 0, @0x1f88
tl: 2 fb: --HDFL-- lb: 0x2                            ---注意由-H-FL变为-HdFL
tab 0, row 1, @0x1f73
tl: 21 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [17]  44 61 76 65 20 6c 69 6b 65 20 4f 72 61 63 6c 65 21
end_of_block_dump
End dump data blocks tsn: 4 file#: 4 minblk 527 maxblk 527

*** 2017-11-28 14:36:42.754
Processing Oradebug command 'setmypid'

*** 2017-11-28 14:36:42.754
Oradebug command 'setmypid' console output:

*** 2017-11-28 14:36:48.261
Processing Oradebug command 'tracefile_name'

*** 2017-11-28 14:36:48.262
Oradebug command 'tracefile_name' console output:
/u01/app/oracle/diag/rdbms/dbdb/DBdb/trace/DBdb_ora_2065.trc
[oracle@wang ~]$  

这里的row 1flag 变成了--HDFL--


3.2 现在我们用bbed 将删除的row 1 内容找回来
--编辑BBED的PARFILE参数文件
先查看数据文件
SQL> select file#||' '||name||' '||bytes from v$datafile ;

FILE#||''||NAME||''||BYTES
--------------------------------------------------------------------------------
1 /u01/app/oracle/oradata/DBdb/system01.dbf 2936012800
2 /u01/app/oracle/oradata/DBdb/sysaux01.dbf 723517440
3 /u01/app/oracle/oradata/DBdb/undotbs01.dbf 2710568960
4 /u01/app/oracle/oradata/DBdb/users01.dbf 3207331840
5 /u01/app/oracle/oradata/DBdb/example01.dbf 355205120

--进入bbed窗口

--配置BBED参数文件parfile
--编辑listfile
[oracle@wang ~]$ vi filelist.txt
1 /u01/app/oracle/oradata/DBdb/system01.dbf 2936012800
2 /u01/app/oracle/oradata/DBdb/sysaux01.dbf 723517440
3 /u01/app/oracle/oradata/DBdb/undotbs01.dbf 2710568960
4 /u01/app/oracle/oradata/DBdb/users01.dbf 3207331840
5 /u01/app/oracle/oradata/DBdb/example01.dbf 355205120
"filelist.txt" [New] 6L, 275C written                                                                                                                
[oracle@wang ~]$

--编辑parfile:
[oracle@wang ~]$ vi bbed.par
blocksize=8192
listfile=/home/oracle/filelist.txt
mode=edit
~
"bbed.par" [New] 3L, 60C written                                                                                                                     
[oracle@wang ~]$

--进入bbed窗口
[oracle@wang ~]$ bbed parfile=/home/oracle/bbed.par
Password: blockedit

BBED: Release 2.0.0.0.0 - Limited Production on Tue Nov 28 15:02:40 2017

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

************* !!! For Oracle Internal Use only !!! ***************

BBED> show all
        FILE#           1
        BLOCK#          1
        OFFSET          0
        DBA             0x00400001 (4194305 1,1)
        FILENAME        /u01/app/oracle/oradata/DBdb/system01.dbf
        BIFILE          bifile.bbd
        LISTFILE        /home/oracle/filelist.txt
        BLOCKSIZE       8192
        MODE            Edit
        EDIT            Unrecoverable
        IBASE           Dec
        OBASE           Dec
        WIDTH           80
        COUNT           512
        LOGFILE         log.bbd
        SPOOL           No
        
--修改指定到文件4,块527:
BED> set dba 4,527 offset 0
        DBA             0x0100020f (16777743 4,527)
        OFFSET          0

BBED> show all
        FILE#           4
        BLOCK#          527
        OFFSET          0
        DBA             0x0100020f (16777743 4,527)
        FILENAME        /u01/app/oracle/oradata/DBdb/users01.dbf
        BIFILE          bifile.bbd
        LISTFILE        /home/oracle/filelist.txt
        BLOCKSIZE       8192
        MODE            Edit
        EDIT            Unrecoverable
        IBASE           Dec
        OBASE           Dec
        WIDTH           80
        COUNT           512
        LOGFILE         log.bbd
        SPOOL           No

--查找Dave所在位置
BBED> find /c Dave
 File: /u01/app/oracle/oradata/DBdb/users01.dbf (4)
 Block: 527              Offsets: 8155 to 8191           Dba:0x0100020f
------------------------------------------------------------------------
 44617665 206c696b 65204f72 61636c65 213c0201 0c446176 65206973 20444241
 210206e0 53

 <32 bytes="" per="" line="">

--翻译其数据
BBED> d /v dba 4,527 offset 8155
 File: /u01/app/oracle/oradata/DBdb/users01.dbf (4)
 Block: 527     Offsets: 8155 to 8191  Dba:0x0100020f
-------------------------------------------------------
 44617665 206c696b 65204f72 61636c65 l Dave like Oracle
 213c0201 0c446176 65206973 20444241 l !<...Dave is DBA
 210206e0 53                         l !...S

 <16 bytes="" per="" line="">

--前后迁移offset偏移量,发现在offset在8156时发现3c标志
BBED> d /v dba 4,527 offset 8156
 File: /u01/app/oracle/oradata/DBdb/users01.dbf (4)
 Block: 527     Offsets: 8156 to 8191  Dba:0x0100020f
-------------------------------------------------------
 61766520 6c696b65 204f7261 636c6521 l ave like Oracle!
 3c02010c 44617665 20697320 44424121 l <...Dave is DBA!
 0206e053                            l ...S

 <16 bytes="" per="" line="">
这里已经出现了我们3c(deleted)标志,但是注意这里的位置的根据我们的查找的字符串来分的,实际在block里的分割方式不一样按照我们的offset 来进行。 我们可以通过row directory 来进行一个确认。

--print row directory 确认一下
BBED>  p kdbr
sb2 kdbr[0]                                 @118      8072
sb2 kdbr[1]                                 @120      8051

BBED>  p *kdbr[0]
rowdata[21]
-----------
ub1 rowdata[21]                             @8172     0x3c

BBED> p *kdbr[1]
rowdata[0]
----------
ub1 rowdata[0]                              @8151     0x2c

通过row directory,我们可以确认对应row记录的row header保存在offset 8172的位置,值为3c。 我们find 字符串的目的就是为了和rowdirectory 中的offset 进行比较。 他们相近时,就可以确定。

--现在我们将@8172位置的3c 变成2c。 即从deleted 变成正常
BBED> modify /x 2c offset 8172
 File: /u01/app/oracle/oradata/DBdb/users01.dbf (4)
 Block: 527              Offsets: 8172 to 8191           Dba:0x0100020f
------------------------------------------------------------------------
 2c02010c 44617665 20697320 44424121 0206e053

 <32 bytes="" per="" line="">

--应用更改:
BBED> sum apply
Check value for File 4, Block 527:
current = 0xf25d, required = 0xf25d

BBED>  

--flush buffer cache,然后查询
SQL> conn / as sysdba
Connected.
SQL> alter system flush buffer_cache;

System altered.

SQL> conn hr/hr;
Connected.
SQL> select * from dvd;

JOB
--------------------------------------------------------------------------------
Dave is DBA!
Dave like Oracle!

之前delete 的数据已经恢复出来。。。。。。。。。
        
        

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/31397003/viewspace-2147869/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/31397003/viewspace-2147869/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值