Oracle中delete行时,数据实际上并没有被删除。而是将行标记为已删除,并相应地调整空闲空间计数器和指针。行状态存储在每行的行标头中,该行标头占用每行的前几个字节。
行标头由行标记、锁字节(ITL条目)和列计数组成。第一个Row标志是一个单字节,它保存一个显示行状态的位掩码。位掩码解码如下
因此行标头=head of row picec + first data picec + last data picec = 44 => 0x2c
当数据被删除后,行标头+16即60=>0x3c 因此,当数据未被覆盖时,修改行标头0x3c为0x2c即可恢复。
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
--------------- ------------------------------ ----------- ------------