(一)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
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.