truncate,不记录redo,也不能通过闪回查询来找回数据,但是只要段所占用的块没有全部被重新占用的情况下,我们还是可以通过一些特殊的办法来找回truncate掉的数据,因为当truncate命令发起之后,Oracle实际上并没有在删除底层数据块上的数据,而是要等到重用的时候才会把这一部分数据回收,于是这给了我们一个能够恢复数据库的机会。

所以当truncate 表后,需要立马的进行恢复,当尤其是生产上表空间不太够的情况,或者是业务比较繁忙的情况,不一定能够完全恢复truncate表的数据,所以时间就是金钱,理论上也不太可能把业务数据的表空间设置成read only状态,所以,尽快进行恢复操作;

1.ORACLE官方上是dul能够进行数据抽取

DUL 是Data Unloader 的缩写,是一个荷兰的Oracle 工程师开发的,他的名字为Bernard Van Duijnen。DUL 是一个C 开发的小程序,编译后整个程序只有一个文件,大小也不过几百 KB,它工作时不需 Oracle RDBMS 以及任何的Oracle 的程序、组件,它可以直接从一个坏了数据库的数据文件中读取数据,生成IMP 或SQL*Loader 可以识别的文件。

DUL 不是一个商用化的产品,Oracle 不卖、不提供也不支持它的使用。DUL 只有在Oracle 的内部网站才可以下载到,因此也只有Oracle 的Supporter 才能下载到有这个工具。 

2.FY_Recover_Data.zip 存储过程恢复

  如果我们已经有一套元数据及数据块,然后将被TRUNCATE的用户数据块的内容取代其用户数据块的内容,是否可以“骗”过Oracle,让它读出这些数据呢?

回顾一下表扫描的过程,这个方法应该是可行的。我们只要想办法构造出一个结构相同、且具有完整元数据信息和格式化了的用户数据块的傀儡表对象,然后将被TRUNCATE的用户数据块找出,再将其数据内容部分嫁接到傀儡对象的用户数据块,使Oracle以外这是傀儡对象的数据,就能让Oracle扫描并读出数据内容。其原理用图示描述如下:

Oracle truncate 表恢复_truncate

FY_Recover_Data.pck恢复truncate的表

 环境:oracle 11g/19c linux 7.6

恢复要求:FY_Recover_Data.pck支持windows和linux truncate表操作,

1.oracle有完整元数据信息,系统表空间不能有问题。

2.执行的时候需要有dba权限的用户执行(最好是sys用户,如果发现包状态异常,那就是权限过小,不能访问一些视图和系统表

3.Linux测试完恢复(tmp下有表空间的数据文件,如果不用的话,建议删除fy_rec_Data,fy_rst_data)表空间,不然服务器重启,数据库起不起来(临时文件被清理了)

CREATE TABLE ENMO_OBJ AS SELECT * FROM DBA_OBJECTS;

INSERT INTO  ENMO_OBJ  SELECT * FROM DBA_OBJECTS;
INSERT INTO  ENMO_OBJ  SELECT * FROM DBA_OBJECTS;
INSERT INTO  ENMO_OBJ  SELECT * FROM ENMO_OBJ ;

COMMIT;

Oracle truncate 表恢复_恢复_02

查看这个包:

tow表示需要恢复的表的所有者(本次测试为SYS),ttb为表的名称,fbks表示恢复表中要填写的块号(可选也可不填 1),后面临时表空间,和离线文件都默认为空;

truncate table ENMO_OBJ;

进行恢复。

在执行的时候,查看登陆用户有没有权限:

select  count(*) from sys.user$; select  count(*) from sys.tab$;  --如果查看不了这些视图,说明用户权限不够,建议用sys,system或者具有dba权限用户彩操作。

 

 我是用plsql develop

 打开FY_Recover_Data包,执行里面的存储过程recover_truncated_table;

plsql 命令行执行:exec fy_recover_data.recover_truncated_table('SYS','ENMO_OBJ');

Oracle truncate 表恢复_truncate_03

 记住了,一定要是大写,表名和用户名.

17:56:46: Use existing Directory Name: FY_DATA_DIR

17:56:46: Recover Table: SYS.ENMO_OBJ$

17:56:46: Restore Table: SYS.ENMO_OBJ$$

17:56:50: Copy file of Recover Tablespace: FY_REC_DATA_COPY.DAT

17:56:50: begin to recover table SYS.ENMO_OBJ

17:56:50: Use existing Directory Name: TMP_HF_DIR

17:56:51: Recovering data in datafile /oracle/app/oradata/zydb/system01.dbf

17:56:51: Use existing Directory Name: TMP_HF_DIR

17:58:10: 4042 truncated data blocks found.  
17:58:10: 284764 records recovered in backup table SYS.ENMO_OBJ$$

17:58:10: Total: 4042 truncated data blocks found.  
17:58:10: Total: 284764 records recovered in backup table SYS.ENMO_OBJ$$

17:58:10: Recovery completed.

17:58:10: Data has been recovered to SYS.ENMO_OBJ$$

 恢复出来了,如果被truncate表数据量很大,恢复时间比较久。

INSERT INTO ENMO_OBJ SELECT * FROM SYS.TENMO_OBJ$$;
COMMIT;

Oracle truncate 表恢复_恢复_04

tmp下有表空间的数据文件,如果用完了的话,建议删除fy_rec_Data,fy_rst_data表空间。

Oracle truncate 表恢复_truncate_05

drop tablespace fy_rec_data including contents and datafiles;

drop tablespace fy_rst_data including contents and datafiles;

下次需要恢复的时候建两个表空间就好了。