总结一下前面,首先是段头块,它指向了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的数据》
