导出误删除(drop)的表

当表被DROP后,数据仍然存在于表空间中,可以通过GDUL恢复。具体步骤如下:

1

创建一张临时的表,表结构和drop掉的表相同

SQL> create table t_test2 ... ... tablespace system;
2

初始化数据字典,以识别新创建的表

GDUL> bootstrap
3

扫描drop掉的表所在表空间

得到表空间内所有data_object_id及对应的数据块。

GDUL> scan tablespace 7

说明:该步骤建立指定表空间下所有data_object_id和数据块的对应关系,在接下来的步骤4、步骤5都需要用到。

4

查找drop表当时的data_object_id

方法1:使用闪回查询

如果SYS UNDO段未被覆盖的话,可以闪回查找旧的信息。

select obj#, dataobj# from sys.obj$
  as of timestamp to_timestamp('2017-02-08 19:00:00','YYYY-MM-DD HH24:MI:SS')
  where owner# = (select user_id from dba_users where username='ANDY')
  and name='T_TEST';

此外,还可以获取drop掉的表结构:

select column_name, data_type, data_length
  from dba_tab_columns as of timestamp to_timestamp('2017-02-08 19:00:00','YYYY-MM-DD HH24:MI:SS')
 where owner = 'ANDY'
  and table_name='T_TEST';

方法2:AWR表中可能会记录有旧的data_object_id

select s.snap_id, s.begin_interval_time, o.objno, o.tsno, o.dataobjno
  from wrh$_seg_stat_obj o
  inner join wrm$_snapshot s
    on o.snap_id = s.snap_id
 where owner='ANDY' and object_name = 'T_TEST'
 order by s.snap_id;

方法3:手工sample表空间,查找

GDUL> sample segment all

进入sample目录,手工分辨所有的采样数据,最后确认data_object_id。

方法4:使用logminer

先找到truncate时的归档或在线日志,然后从logminer输出中查找truncate的DDL语句,truncate后几行记录update "SYS"."TAB$"和update "SYS"."OBJ$"中会记录有旧的data_object_id。

5

借助步骤1创建的表结构,用步骤4找到的data_object_id导出表数据

GDUL> unload table andy.t_test2 object_id 79435;
终端输出
2017-05-05 17:02:47 unloading table "ANDY"."T_TEST2" with data_object_id 79435...
2017-05-05 17:02:47 unloaded 1480 rows.