如何确定被多次truncate后的data object id

| 1 Comment

今天上午我一个同事误truncate了一个表uplbth,她问我是否可以恢复?

我们先去看一下这个表现在的状况:

SQL> select owner,object_name,object_id,data_object_id from dba_objects where object_name='UPLBTH';

 

OWNER                        OBJECT_NAME      OBJECT_ID DATA_OBJECT_ID

------------------------------ --------------- ---------- --------------

CAIPRA                         UPLBTH               52210          95137

从结果里我们可以看到,这个表的data object id已经比其object id大了太多,极有可能是曾经被多次truncate

后来我问了一下她是否多次truncate过这个表,她说是。然后我对她说,你等我信儿吧。

 

熊哥曾经在"使用ODU恢复Truncate"这篇文章里提到了如何确定被多次truncate后的data object id,我这里用另外一种方式来精确定位我要恢复的data object id

 

利用的原理就是:oracle里有system回滚段,而oracle对数据字典的操作基本上是DML,既然是DML,那就好办了,我们有很大的概率可以成功执行flashback query

 

回到刚才的例子,我首先从dba_objects里知道了uplbthlast_ddl_time2010-2-3 10:18:57;接着,我们直接执行flashback query来确定在执行truncate操作的那个时间点之前uplbthdata object id

SQL> select  owner,object_name,object_id,data_object_id from dba_objects as of timestamp to_timestamp('2010-02-03 10:18:00','YYYY-MM-DD HH24:MI:SS') where object_name='UPLBTH';

 

OWNER                          OBJECT_NAME      OBJECT_ID DATA_OBJECT_ID

------------------------------ --------------- ---------- --------------

CAIPRA                         UPLBTH               52210          77675

 

可以看到,当时的data object id77675,精确的确定了data object id后,剩下的事情就都交给ODU好了:

ODU> unload table caipra.uplbth object 77675

 

Unloading table: UPLBTH,object ID: 52210

Unloading segment,storage(Obj#=52210 DataObj#=77675 TS#=16 File#=15 Block#=18828 Cluster=0)

1888 rows unloaded

 

可以看到,我们成功恢复出来了1880条数据。

注意,这里你用logmnr在缺省情况下是挖不出来data object id的,朋友们可以自己试一下。

1 Comment

nice

Leave a comment