墨墨导读:本文来自墨天轮用户 肖杰 的投稿,介绍用BBED恢复删除数据的全过程。
墨天轮主页:https://www.modb.pro/u/6722
Oracle中delete行时,数据实际上并没有被删除。而是将行标记为已删除,并相应地调整空闲空间计数器和指针。行状态存储在每行的行标头中,该行标头占用每行的前几个字节。
行标头由行标记、锁字节(ITL条目)和列计数组成。第一个Row标志是一个单字节,它保存一个显示行状态的位掩码。位掩码解码如下
因此行标头=head of row picec + first data picec + last data picec = 44 => 0x2c
当数据被删除后,行标头+16即60=>0x3c
因此,当数据未被覆盖时,修改行标头0x3c为0x2c即可恢复。
测试:
1,创建测试数据
SQL> create table devin.test_delete(id number,name nvarchar2(10)) tablespace devin;
Table created.
SQL> insert into devin.test_delete values(1,'devin1');
1 row created.
SQL> insert into devin.test_delete values(2,'devin2');
1 row created.
SQL> insert into devin.test_delete values(3,'devin3');
1 row created.
SQL> commit;
Commit complete.
SQL> select * from devin.test_delete;
ID NAME
---------- ----------------------------------------------------------------------
1 devin1
2 devin2
3 devin3
SQL> delete from devin.test_delete where id=3;
1 row deleted.
SQL> commit;
Commit complete.
SQL> select * from devin.test_delete;
ID NAME
---------- ----------------------------------------------------------------------
1 devin1
2 devin2
SQL> col segment_Name for a15
SQL> select segment_name,tablespace_name,header_file,header_block from dba_segments where segment_name='TEST_DELETE';
SEGMENT_NAME TABLESPACE_NAME HEADER_FILE HEADER_BLOCK
--------------- ------------------------------ ----------- ------------
TEST_DELETE DEVIN 9 138
可以看到表位于9号文件,段头块是138,先dump 138快,根据段头找到具体的数据存放的block。
2,dump header block
SQL> alter system dump datafile 9 block 138;
System altered.
*** 2021-02-05T11:00:07.663087+08:00
Start dump data blocks tsn: 9 file#:9 minblk 138 maxblk 138
Block dump from cache:
Dump of buffer cache at level 4 for pdb=0 tsn=9 rdba=37748874
BH (0x6ebdb498) file#: 9 rdba: 0x0240008a (9/138) class: 4 ba: 0x6e8da000
set: 6 pool: 3 bsz: 8192 bsi: 0 sflg: 0 pwc: 0,0
dbwrid: 0 obj: 75550 objn: 7