(一)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(*)---------- 86968sql> sqltruncate table test01;table truncatedsql-------- 0
STEP2:导入FY_Recover_Data.pck包
[oracle@source-node ~]$ sqlplus / as sysdbasql*Plus: Release 11.2.0.4.0 Production on Tue Apr 21 10:50:17 2020copyright (c) 1982,2013,Oracle. All rights reserved.Connected to:Oracle Database 11g Enterprise Edition Release 0 - 64bit ProductionWith the Partitioning,olAP,Data Mining and Real Application Testing optionssql> @/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
11:20 set time on 43 sqlset serveroutput on54 sql> exec fy_recover_data.recover_truncated_table('liJIAMAN',TEST01'@H_301_323@);12:01: Use existing Directory name: FY_data_dir02: Recover : liJIAMAN.TEST01$02: Restore : liJIAMAN.TEST01$$09: copy file of Recover tablespace: FY_REC_DATA_copY.DAT109: begin to recover liJIAMAN.TEST01 existing Directory name: TMP_HF_DIR09: Recovering data in datafile/u01/app/oradata/testdb1/users01.dbf39: 1242 truncated data blocks found.86968 records recovered in backup liJIAMAN.TEST01$$39: Total: 39: Recovery completed.39: Data has been recovered liJIAMAN.TEST01$$PL/sql procedure successfully completed.STEP4:根据恢复日志,会创建临时中转表test01$和test01$$,恢复的数据保存在test01$$中
> show userUser is "liJIAMAN"sql test01$$; 86968将数据还原到test01表中sqlinsert into test01 test01$$;确认数据已经还原回来86968经过测试,如果表被truncate后,未执行其它 *** 作,数据可以使用fy_recover_data恢复回来。
#######################################################################################
(3.2)使用fy_recover_data包执行truncate恢复,truncate后有新数据进入表(新插入的数据比truncate之前多)
STEP1:创建测试表、序列、存储过程
test01 2 ( 3 col1 number,4 col2 5 col3 date,1); Font-weight: bold">6 col4 varchar2(30),1); Font-weight: bold">7 col5 100) 8 ); createdsql创建自增序列sqlCREATE SEQUENCE seq01 2 START WITH 1 3 MAXVALUE 99999999 4 MINVALUE 0 CYCLE 6 CACHE 10 7 ORDER;Sequence created sql创建随机数据插入存储过程,其中col1列单调递增create or replace procedure p_insert_test01 ISv_col1 NUMBER;BEGINFOR i IN 1..10000 LOOPselect seq01.nextval INTO v_col1 dual;into test01(col1,col2,col3,col4,col5)values(v_col1,(round(dbms_random.value(10000,1); Font-weight: bold">100000000)) dual),sysdate,1)">select dbms_random.string(a25) 85) dual));END LOOP;commitend p_insert_test01;STEP2:测试表插入10000条数据,col1列的值从1到10000
exec p_insert_test01;PLprocedure successfully completedsqlSELECT MIN(col1),1)">MAX(col1) FROM test01;MIN(Col1) MAX(Col1)-------- ---------- 1 10000STEP3: 执行truncate *** 作
table truncatedSTEP4: 接着往表里插入20000条数据
20000-------- ---------- 10001 30000STEP5:执行恢复 *** 作
14:00:57 on01:06 sql> 09 sql13: 13: Recover 14: 18: copy 18: 18: Recovering data 32: 40220000 records recovered 32: Total: 3232: Data has been recovered STEP6: 通过对test01$$表进行确认,发现返回的数据是truncate之后插入的数据,不符合要求30000 test01$$;30000
#######################################################################################
(3.3)使用fy_recover_data包执行truncate恢复,truncate后有新数据进入表(新插入的数据比truncate之前少)
Connected to Oracle 0 Connected as lijiaman@192.168.10.11testdb1sqlDROP table test01 PURGE; droppedsql3 col1 4 col2 col3 date,1); Font-weight: bold">6 col4 7 col5 DROP SEQUENCE seq01;Sequence droppedsql2 START 3 MAXVALUE 4 MINVALUE CYCLE 6 CACHE 7 ;Sequence createdsqlIS 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 *** 作
table truncated
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:创建测试表
testdb1sql ) tableSPACE USERS;table createdSTEP2: 初始时候,表空间总共20MB,剩余15.94MB
STEP3:test01表插入大量数据
> PL/begin p_insert_test01; ;ORA-01653: unable to extend table liJIAMAN.TEST01 by 128 tablespace USERSORA06512: at "liJIAMAN.P_INSERT_TEST01",line 6ORA06512: at line 1STEP4:此时,表空间总共20MB,剩余0.94MB
STEP5:此时test01表有90000行数据
90000-------- ---------- 109751 199750STEP6:对test01执行truncate
STEP7:执行truncate后,空间已经释放15.88 4.12 20.63 20.63
STEP8:创建表test02,用来覆盖test01释放的空间
table test02 dba_objects;STEP9:test02表创建之后,剩余空间为5.88MB,可以说明:test02表的数据占用了test01表释放出来的空间,即test01表的部分数据已经被覆盖5.88 14.12 70.63 70.63
STEP10:执行恢复 *** 作
15:09:58 05 sql10 sql17: 17: Recover 22: copy 22: 22: Recovering data 31: 64524439 records recovered 31: Total: 3131: Data has been recovered STEP11: 发现只恢复了部分数据,不符合要求 truncate之前test01表有90000行数据,恢复了24339行数据24439-------- ----------199750(四)总结
对于使用工具fy_recover_data进行数据恢复,需要确保:
①truncate之后,需要保证没有新的数据进入表中,否则无法还原;
②存放该表的数据文件块不能被覆盖,否则无法完整还原数据。
在发生故障后,可以迅速使用:
alter tablespace users read only;sqlread write;来关闭/开启表空间的写功能,这样可以保证数据文件不会被覆写。
【完】
copyright © 2020 ruiliair. All Rights Reserved.
总结以上是内存溢出为你收集整理的Oracle使用fy_recover_data恢复truncate删除的数据全部内容,希望文章能够帮你解决Oracle使用fy_recover_data恢复truncate删除的数据所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)