(一)truncate操作概述
在生产中,truncate是使用较多的命令,在使用不当的情况下,往往会造成表的数据全部丢失,恢复较为困难。对于truncate恢复,常见的有以下几种方法可以进行恢复:
- 使用数据泵导入。该方法操作简单,前提是必须要有备份可用,并且会有数据的丢失;
- 使用RMAN进行不完全恢复。可将数据库恢复到truncate之前的时刻,但是恢复时间较长;
- 使用odu、prm-dul、GDUL等收费软件进行恢复;
- 使用fy_recover_data包;
使用RMAN进行异机恢复已在之前测试过,详见:https://www.cnblogs.com/lijiaman/p/11577001.html 。
(二)FY_Recover_Data介绍
FY_Recover_Data是国内Oracle ACE大佬黄玮(个人网站:http://www.hellodba.com)开发的一个package,该脚本专门用于对truncate的表进行恢复。
根据作者所述,其原理:如果我们已经有一套元数据及数据块,然后将被TRUNCATE的用户数据块的内容取代其用户数据块的内容,是否可以“骗”过Oracle,让它读出这些数据呢?
回顾一下表扫描的过程,这个方法应该是可行的。我们只要想办法构造出一个结构相同、且具有完整元数据信息和格式化了的用户数据块的傀儡表对象,然后将被TRUNCATE的用户数据块找出,再将其数据内容部分嫁接到傀儡对象的用户数据块,使Oracle以外这是傀儡对象的数据,就能让Oracle扫描并读出数据内容。其原理用图示描述如下:
+-------------------------+
| Copy Of Dummy Data File |
| (With Formmated Blocks)|
+-------------------------+
||
\/
(Blcok Header,Block Tail)
||
\/
+-------------------+ +----------------+ Table Scan +---------------+
| Source Data File | => (Data Block Content) => | Dummy Table | ============> | Restore Table |
|(Without Meta Data)| |(With Meta Data)| +---------------+
+-------------------+ +----------------+
FY_Recover_Data对于表恢复的支持性如下:
压缩表 | 支持 |
索引组织表 | 支持 |
分区表 | 支持 |
行链接/行迁移 | 不支持 |
标准sql类型 | 支持 |
BLOB/CLOB | 支持Store in Row |
离线恢复 | 支持 |
操作系统平台 | 全部 |
数据库版本 | 9i以上 |
本文使用FY_Recover_Data对truncate的几种情况进行恢复测试,以验证fy_recover_data的恢复能力。
(三)操作过程记录
(3.1)使用fy_recover_data包执行truncate恢复,truncate后未有新数据进入表
STEP1:创建测试表,并执行truncate
sql> create table test01 as select * from dba_objects; sqlselect count(*) test01; COUNT(*) ---------- 86968 sql> sqltruncate table test01; Table truncated sql-------- 0
STEP2:导入FY_Recover_Data.pck包
[oracle@source-node ~]$ sqlplus / as sysdba sql*Plus: Release 11.2.0.4.0 Production on Tue Apr 21 10:50:17 2020 Copyright (c) 1982,2013,Oracle. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 0 - 64bit Production With the Partitioning,OLAP,Data Mining and Real Application Testing options sql> @/home/oracle/FY_Recover_Data.pck 第一次执行发现第30行存在“&”符号,删除该符号 Enter value for files: old 30: 1. Temp Restore and Recover tablespace & files --- new 1. Temp Restore and Recover tablespace --- Package created. Warning: Package Body created with compilation errors. sql/FY_Recover_Data.pck 删除“&”符号后导入成功 Package created. Package body created.
STEP3:开始执行恢复,只需要两个参数:schema和table_name
STEP4:根据恢复日志,会创建临时中转表test01$和test01$$,恢复的数据保存在test01$$中
经过测试,如果表被truncate后,未执行其它操作,数据可以使用fy_recover_data恢复回来。
#######################################################################################
(3.2)使用fy_recover_data包执行truncate恢复,truncate后有新数据进入表(新插入的数据比truncate之前多)
STEP1:创建测试表、序列、存储过程
STEP2:测试表插入10000条数据,col1列的值从1到10000
STEP3: 执行truncate操作
STEP4: 接着往表里插入20000条数据
STEP5:执行恢复操作
#######################################################################################
(3.3)使用fy_recover_data包执行truncate恢复,truncate后有新数据进入表(新插入的数据比truncate之前少)
Connected to Oracle 0
Connected as lijiaman@192.168.10.11testdb1
sqlDROP TABLE test01 PURGE;
dropped
sql3 col1 4 col2 col3 date,1); font-weight: bold">6 col4 7 col5 DROP SEQUENCE seq01;
Sequence dropped
sql2 START 3 MAXVALUE 4 MINVALUE CYCLE
6 CACHE 7 ;
Sequence created
sqlsqlIS
2 v_col1 ;
3 BEGIN
4 LOOP
5 dual;
6 values
(v_col1,1); font-weight: bold">9 (10 sysdate,1); font-weight: bold">11 (12 ( dual));
13 LOOP;
14 ;
15 end p_insert_test01;
16 /
Procedure created
STEP3:执行truncate操作
STEP4:修改存储过程,酶促插入100条数据
22:34 39 sql44 sql52: 52: Recover 57: Copy 57: 57: Recovering data 23:06: 100 records recovered 06: Total: 0606: Data has been recovered STEP6: 通过对test01$$表进行确认,发现返回的数据是truncate之后插入的数据,不符合要求
sql-------- 1010010100
#######################################################################################
(3.4)测试数据文件被覆盖是否影响恢复
STEP1:创建测试表
STEP2: 初始时候,表空间总共20MB,剩余15.94MB
STEP3:test01表插入大量数据
STEP4:此时,表空间总共20MB,剩余0.94MB
STEP5:此时test01表有90000行数据
STEP6:对test01执行truncate
STEP8:创建表test02,用来覆盖test01释放的空间
STEP10:执行恢复操作
(四)总结
对于使用工具fy_recover_data进行数据恢复,需要确保:
①truncate之后,需要保证没有新的数据进入表中,否则无法还原;
②存放该表的数据文件块不能被覆盖,否则无法完整还原数据。
在发生故障后,可以迅速使用:
来关闭/开启表空间的写功能,这样可以保证数据文件不会被覆写。
【完】
Copyright © 2020 ruiliair. All Rights Reserved.