总结一下前面,首先是段头块,它指向了L2块,L2块指向了L1块,而L1块则指向了我们真实的物理数据块。那么做了truncate操作,它到底做了什么鬼?这里需要测试一下,查看如下测试引入:
SQL> select OBJECT_NAME,OBJECT_ID,DATA_OBJECT_ID from dba_objects where OBJECT_NAME='A'; OBJECT_NAME OBJECT_ID DATA_OBJECT_ID ------------------------------ ---------- -------------- A 75722 75722
我们先来看一下对象,当我们创建对象的之后,OBJECT_ID和data_object_id都会是一样的,但是当我们发生truncate之后,我们的object_id不会变,而data_object_id则会变掉。
SQL> truncate table a; Table truncated. SQL> select OBJECT_NAME,OBJECT_ID,DATA_OBJECT_ID from dba_objects where OBJECT_NAME='A'; OBJECT_NAME OBJECT_ID DATA_OBJECT_ID ------------------------------ ---------- -------------- A 75722 75727
这里可以看到Truncate表之后,data_object_id从75722变成了75727。分别看一下段头块,L2位图块,L1位图块,数据块,这个ID是否有变化。分别从检查块130,129,224,225
BBED> set block 130 BLOCK# 130 BBED> dump /v offset 272 count 20 File: /oracle/app/oracle/oradata/ora11/a1.dbf (0) Block: 130 Offsets: 272 to 291 Dba:0x00000000 ------------------------------------------------------- cf270100 00000010 80004001 08000000 l ......@..... 00000000 l ..... BBED> set block 129 BLOCK# 129 BBED> dump /v offset 104 count 20 File: /oracle/app/oracle/oradata/ora11/a1.dbf (0) Block: 129 Offsets: 104 to 123 Dba:0x00000000 ------------------------------------------------------- cf270100 01000000 00000000 80004001 l ..........@. 05000100 l .... BBED> set block 128 BLOCK# 128 BBED> dump /v offset 192 count 10 File: /oracle/app/oracle/oradata/ora11/a1.dbf (0) Block: 128 Offsets: 192 to 201 Dba:0x00000000 ------------------------------------------------------- cf270100 e6151400 0000 l .. BBED> set block 144 BLOCK# 144 BBED> dump /v offset 192 count 10 File: /oracle/app/oracle/oradata/ora11/a1.dbf (0) Block: 144 Offsets: 192 to 201 Dba:0x00000000 ------------------------------------------------------- ca270100 de300f00 0000 l .. BBED> set block 160 BLOCK# 160 BBED> dump /v offset 192 count 10 File: /oracle/app/oracle/oradata/ora11/a1.dbf (0) Block: 160 Offsets: 192 to 201 Dba:0x00000000 ------------------------------------------------------- ca270100 de300f00 0000 l .. BBED> set block 176 BLOCK# 176 BBED> dump /v offset 192 count 10 File: /oracle/app/oracle/oradata/ora11/a1.dbf (0) Block: 176 Offsets: 192 to 201 Dba:0x00000000 ------------------------------------------------------- ca270100 de300f00 0000 l .. BBED> set block 192 BLOCK# 192 BBED> dump /v offset 192 count 10 File: /oracle/app/oracle/oradata/ora11/a1.dbf (0) Block: 192 Offsets: 192 to 201 Dba:0x00000000 ------------------------------------------------------- ca270100 de300f00 0000 l .. <16 bytes per line> BBED> set block 208 BLOCK# 208 BBED> dump /v offset 192 count 10 File: /oracle/app/oracle/oradata/ora11/a1.dbf (0) Block: 208 Offsets: 192 to 201 Dba:0x00000000 ------------------------------------------------------- ca270100 de300f00 0000 l .. <16 bytes per line> BBED> set block 224 BLOCK# 224 BBED> dump /v offset 192 count 10 File: /oracle/app/oracle/oradata/ora11/a1.dbf (0) Block: 224 Offsets: 192 to 201 Dba:0x00000000 ------------------------------------------------------- ca270100 de300f00 0000 l .. BBED> set block 225 BLOCK# 225 BBED> dump /v offset 24 count 10 File: /oracle/app/oracle/oradata/ora11/a1.dbf (0) Block: 225 Offsets: 24 to 33 Dba:0x00000000 ------------------------------------------------------- ca270100 90121400 0000 l ......
通过对各个块的dump,发现段头和L2位图块的data_obj_id已经发生了改变,从ca270100变成了cf270100,而只有第一个L1发生了变化,数据块则没有发生改变。其实到了这里,MDATA如何快速恢复truncate数据的原理非常清楚了.
那么如果从手工修复的角度来看的话,要处理的东西就比较多了,这方面可以参考第三节的内容。
也可以参考hellodba的《移花接木————利用Oracle表扫描机制恢复被Truncate的数据》