oracle truncate恢复方法

truncate表后恢复方法总结


 
百度云有fy_recover_data包 https://pan.baidu.com/s/1c2tlfUS
1.1  BLOG文档结构图
image
 
1.2  前言部分
 
1.2.1  导读和注意事项
各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~:
① truncate操作后的恢复方法(重点)
 
  Tips:
       ① 若文章代码格式有错乱,推荐使用QQ、搜狗或360浏览器,也可以下载pdf格式的文档来查看,pdf文档下载地址:http://yunpan.cn/cdEQedhCs2kFz (提取码:ed9b) 
       ② 本篇BLOG中命令的输出部分需要特别关注的地方我都用灰色背景和粉红色字体来表示,比如下边的例子中,thread 1的最大归档日志号为33,thread 2的最大归档日志号为43是需要特别关注的地方;而命令一般使用黄色背景和红色字体标注;对代码或代码输出部分的注释一般采用蓝色字体表示。
 
  List of Archived Logs in backup set 11
  Thrd Seq     Low SCN    Low Time            Next SCN   Next Time
  ---- ------- ---------- ------------------- ---------- ---------
  1    32      1621589    2015-05-29 11:09:52 1625242    2015-05-29 11:15:48
  1    33      1625242    2015-05-29 11:15:48 1625293    2015-05-29 11:15:58
  2    42      1613951    2015-05-29 10:41:18 1625245    2015-05-29 11:15:49
  2    43      1625245    2015-05-29 11:15:49 1625253    2015-05-29 11:15:53
 
 
 
 
[ZFXXDB1:root]:/>lsvg -o
T_XDESK_APP1_vg
rootvg
[ZFXXDB1:root]:/>
00:27:22 SQL> alter tablespace idxtbs read write;
 
 
====》2097152*512/1024/1024/1024=1G 
 
 
 
本文如有错误或不完善的地方请大家多多指正,ITPUB留言或QQ皆可,您的批评指正是我写作的最大动力。
 
 
1.2.2  相关参考文章链接
 
 
1.2.3  本文简介
truncate操作是比较危险的操作,不记录redo,不能通过闪回查询来找回数据,但是只要段所占用的块没有全部被重新占用的情况下,我们还是可以通过一些特殊的办法来找回truncate掉的数据,因为当Truncate命令发起之后,Oracle实际上并没有在删除底层数据块上的数据,而是要等到重用的时候才会把这一部分数据回收,于是这给了我们一个能够恢复数据库的机会。
总体而言,恢复的办法是通过一些大牛写的工具来恢复,分为收费和免费的,我们下边分别说明。实验部分我们只实验fy_recover_data包和gdul工具。
有的实验是很久之前做的,这篇文章发布太晚,因为中间学习了DUL和BBED的相关知识。
1.3  收费软件
 
这里简单列举一下,具体内容请到相关网站了解:
工具名称 下载地址 作者 软件
ODU http://www.oracleodu.com/cn/ 老熊 命令行操作
PRM-DUL http://www.parnassusdata.com/ Maclean Liu 图形界面操作
AUL/mydul http://www.dbatools.net/mydul/ d.c.b.a/楼方鑫 命令行
 
 
 
1.4  免费软件
1.4.1  fy_recover_data包
作者个人信息:
WWW.HelloDBA.COM                                                   
Created By: Fuyuncat                                               
Created Date: 08/08/2012                                           
Email: Fuyuncat@gmail.com                                          
Copyright (c), 2014, WWW.HelloDBA.COM All rights reserved.         
Latest Version: http://www.HelloDBA.com/download/FY_Recover_Data.zip
该包采用纯plsql语句恢复被truncate掉的表,操作比较简单,下载可以去官网下载,或者小麦苗的云盘共享目录。
 
Fy_Recover_Data是利用Oracle表扫描机制、数据嫁接机制恢复TRUNCATE或者损坏数据的工具包。由纯PLSQL编写,原理图如下:
wps33F2.tmp
 
 
 
包内容:
wps3403.tmp
 
1.4.2  gdul工具
GDUL是老耿开发的一款类dul工具,当数据库由于某种原因无法打开时,可以利用GDUL把表数据直接读取出来,工具下载地址参考小麦苗的blog,老耿的信息如下:
*********************************************************************
  GDUL for ORACLE DB.
  Version 4.0.0.1, build date: 2016.04.12.
  Copyright (c) 2007, 2016. Andy Geng.  ALL RIGHTS RESERVED.
  Email: dbtool@aliyun.com
  WeChat official account: dbtool
  QQ group: 235019291
*********************************************************************
 
1.4.2.1  gDUL功能特点
v 完整支持多种格式导出,包括expdp,exp,text格式。目前市面上的类dul工具只有gDUL支持expdp格式。
v 支持ASM文件系统,并内置asmcmd命令。
v 支持绝大多数列类型,支持常见的NUMBER,CHAR, VARCHAR2, DATE,LOB, LONG等类型。。其中 SecureFile LOB 支持压缩,尚不支持去重和加密。
v 支持导出常规表、IOT、Cluster 表、分区表、压缩表。
v 支持 truncated 表、删除行恢复。
v 支持常规表空间和 bigfile 表空间。
v 支持主流硬件平台(HP-UX,AIX, Solaris, Linux, Windows),各个平台仅需单一的可执行文件,方便分发。
v 重点是——永久免费使用,无需额外费用,不开源。
 
 
 
1.4.3  dul
DUL 是 Data Unloader 的缩写,是一个荷兰的 Oracle 工程师开发的,他的名字为 Bernard Van Duijnen。 DUL 是一个 C 开发的小程序,编译后整个程序只有一个文件,大小也不过几百 KB,它工作时不需 Oracle RDBMS 以及任何的 Oracle 的程序、组件,它可以直接从一个坏了数据库的数据文件中读取数据,生成 IMP 或 SQL*Loader 可以识别的文件。
DUL 不是一个商用化的产品,Oracle 不卖、不提供也不支持它的使用。DUL 只有在 Oracle 的内部网站才可以下载到,因此也只有 Oracle 的 Supporter 才能下载到有这个工具,如果与 Oracle 的 Supporter 熟悉,没准他私底下会给你一个,这个工具也因此有一些流落到民间,被一些人收入囊中,奉为珍宝。 
不同的平台、不同版本的数据库都有相应的 DUL 软件,9.x 及之前 DUL 是没有 License 限制的,也就是有这个工具可以无限制的使用,不过最新的 DUL 在这方面已经改进了,kamus 说最新 DUL 拿到手只能用一个月。 
关于这一小点稍总结一下,获得 DUL 有以下几种途径: 
wps3404.tmp
 如果你是 Oracle 的 Supporter ,可以在内部网站下载,地址为: http://www.nl.oracle.com/support/dul/ 
wps3405.tmp
 如果你有 Oracle 的 Supporter 的朋友可以向他们要一个,itpub 也几位斑竹都到 Oracle 了,如 coolyl,kamus,lunar。 
wps3406.tmp
 一些 dul 流落到民间,可以向有这软件的朋友要一个,不过他们不一定有你需要的那个。 
 
所以关于DUL我们不做过多的解释。
 
1.4.4  bbed来恢复
这个比较复杂,若对oracle不熟悉或者bbed不熟悉都不推荐使用这个,具体案例参考:http://blog.itpub.net/26736162/viewspace-2080727/
 
 
第二章 实验部分
2.1  实验环境介绍
项目 db
db 类型 单实例
db version 11.2.0.4.0
db 存储 FS
主机IP地址/hosts配置 192.168.59.129
OS版本及kernel版本 AIX 7.1 64位
归档模式 Archive Mode
ORACLE_SID oralhr
 
 
2.2  实验目标
将truncate掉的表数据成功找回。
 
2.3  实验过程
 
2.3.1  fy_recover_data包恢复truncate的表
[ZFXDESKDB1:oracle]:/oracle>ORACLE_SID=oraESKDB1
[ZFXDESKDB1:oracle]:/oracle>sqlplus / as sysdba
 
SQL*Plus: Release 11.2.0.4.0 Production on Mon Mar 21 15:51:55 2016
 
Copyright (c) 1982, 2013, Oracle.  All rights reserved.
 
 
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options
 
SYS@oraESKDB1> set time on;
15:52:10 SYS@oraESKDB1> set timing on;
15:52:10 SYS@oraESKDB1> set serveroutput on;
15:52:10 SYS@oraESKDB1> create table scott.TB_0321    as SELECT * FROM dba_objects;
 
Table created.
 
Elapsed: 00:00:00.59
15:52:18 SYS@oraESKDB1> SELECT COUNT(1) FROM   scott.TB_0321;
 
  COUNT(1)
----------
     86651
 
Elapsed: 00:00:00.19
15:52:24 SYS@oraESKDB1> INSERT INTO scott.TB_0321 SELECT * FROM scott.TB_0321;
 
 
86651 rows created.
 
Elapsed: 00:00:00.26
15:52:30 SYS@oraESKDB1> COMMIT;
Commit complete.
 
Elapsed: 00:00:00.01
15:52:30 SYS@oraESKDB1> INSERT INTO scott.TB_0321 SELECT * FROM scott.TB_0321;
COMMIT;
 
173302 rows created.
 
Elapsed: 00:00:00.43
15:53:02 SYS@oraESKDB1> SELECT COUNT(1) FROM   scott.TB_0321;
 
  COUNT(1)
----------
  346604
 
Elapsed: 00:00:00.27
16:15:18 SYS@oraESKDB1> SELECT d.BYTES/1024/1024 FROM dba_segments d WHERE d.segment_name ='TB_0321';
 
D.BYTES/1024/1024
-----------------
               40
 
Elapsed: 00:00:00.44
16:15:25 SYS@oraESKDB1> truncate table scott.TB_0321;
 
Table truncated.
 
Elapsed: 00:00:00.20
16:15:46 SYS@oraESKDB1> SELECT COUNT(1) FROM   scott.TB_0321;
 
  COUNT(1)
----------
         0
 
Elapsed: 00:00:00.01
 
====》数据已经被truncate掉了,下边我们来恢复
 
 
16:15:52 SYS@oraESKDB1> @/oracle/FY_Recover_Data.pck
 
Package created.
 
Elapsed: 00:00:00.06
 
Package body created.
 
Elapsed: 00:00:00.03
16:15:59 SYS@oraESKDB1> exec fy_recover_data.recover_truncated_table('scott','TB_0321');
16:16:06: Use existing Directory Name: FY_DATA_DIR
16:16:07: Recover Table: SCOTT.TB_0321$
16:16:09: Restore Table: SCOTT.TB_0321$$
16:16:24: Copy file of Recover Tablespace: FY_REC_DATA_COPY.DAT1
16:16:24: begin to recover table SCOTT.TB_0321
16:16:24: Use existing Directory Name: TMP_HF_DIR
16:17:09: Recovering data in datafile +DATA/oraeskdb/datafile/users.351.902678817
16:17:09: Use existing Directory Name: TMP_HF_DIR
16:39:16: 4984 truncated data blocks found.
16:39:16: 346604 records recovered in backup table SCOTT.TB_0321$$
16:39:17: Total: 4984 truncated data blocks found.
16:39:17: Total: 346604 records recovered in backup table SCOTT.TB_0321$$
16:39:17: Recovery completed.
16:39:17: Data has been recovered to SCOTT.TB_0321$$
 
PL/SQL procedure successfully completed.
 
Elapsed: 00:23:11.59
 
16:39:17 SYS@oraESKDB1> SELECT COUNT(1) FROM   scott.TB_0321$$;
 
  COUNT(1)
----------
   346604
 
Elapsed: 00:00:01.55
16:40:51 SYS@oraESKDB1>
16:40:51 SYS@oraESKDB1> alter table scott.TB_0321 nologging;
 
Table altered.
 
Elapsed: 00:00:00.03
16:41:43 SYS@oraESKDB1> insert /*+append*/ into scott.TB_0321 select * from scott.TB_0321$$;
 
346604 rows created.
 
Elapsed: 00:00:00.86
16:41:52 SYS@oraESKDB1> commit;
 
Commit complete.
 
Elapsed: 00:00:00.01
16:41:55 SYS@oraESKDB1> alter table scott.TB_0321 logging;
 
Table altered.
 
Elapsed: 00:00:00.02
16:42:06 SYS@oraESKDB1>
16:42:06 SYS@oraESKDB1> drop tablespace   FY_REC_DATA  including contents and datafiles;
 
Tablespace dropped.
 
Elapsed: 00:00:08.00
16:42:35 SYS@oraESKDB1> drop tablespace   FY_RST_DATA  including contents and datafiles;
 
Tablespace dropped.
 
Elapsed: 00:00:07.59
16:42:44 SYS@oraESKDB1>
 
 
数据成功恢复。
 
 
2.3.2  gdul恢复truncate的表
set time on;
set timing on;
set serveroutput on;
drop table scott.TB_0322_05;
create table scott.TB_0322_05    as SELECT * FROM dba_objects;
 
SELECT COUNT(1) FROM   scott.TB_0322_05;
INSERT INTO scott.TB_0322_05 SELECT * FROM scott.TB_0322_05;
COMMIT;
INSERT INTO scott.TB_0322_05 SELECT * FROM scott.TB_0322_05;
COMMIT;
INSERT INTO scott.TB_0322_05 SELECT * FROM scott.TB_0322_05;
COMMIT;
INSERT INTO scott.TB_0322_05 SELECT * FROM scott.TB_0322_05;
COMMIT;
SELECT COUNT(1) FROM   scott.TB_0322_05;
 
SELECT d.BYTES/1024/1024 FROM dba_segments d WHERE d.segment_name ='TB_0322_05';
 
 
truncate table scott.TB_0322_05;
 
alter system checkpoint;
 
col ownere format a10
col DIRECTORY_NAME format a30
col DIRECTORY_PATH format a50
select OWNER,DIRECTORY_NAME,DIRECTORY_PATH from  dba_directories;
 
 
bootstrap
desc scott.TB_0322_05
unload table  scott.TB_0322_05
scan tablespace 4
untrunc table  scott.TB_0322_05
 
cp SCOTT_TB_0322_05.dmp /oracle/app/oracle/admin/oralhr/dpdump/
impdp  scott/tiger directory=DATA_PUMP_DIR dumpfile=SCOTT_TB_0322_05.dmp LOGFILE=SCOTT_TB_0322_05.log TABLES=TB_0322_05
 
15:41:04 SQL> set time on;
15:59:49 SQL> set timing on;
15:59:49 SQL> set serveroutput on;
15:59:49 SQL> drop table scott.TB_0322_05;
create table scott.TB_0322_05    as SELECT * FROM dba_objects;
 
SELECT COUNT(1) FROM   scott.TB_0322_05;
INSERT INTO scott.TB_0322_05 SELECT * FROM scott.TB_0322_05;
 
Table dropped.
 
Elapsed: 00:00:00.07
15:59:49 SQL> COMMIT;
INSERT INTO scott.TB_0322_05 SELECT * FROM scott.TB_0322_05;
COMMIT;
INSERT INTO scott.TB_0322_05 SELECT * FROM scott.TB_0322_05;
COMMIT;
INSERT INTO scott.TB_0322_05 SELECT * FROM scott.TB_0322_05;
COMMIT;
SELECT COUNT(1) FROM   scott.TB_0322_05;
 
SELECT d.BYTES/1024/1024 FROM dba_segments d WHERE d.segment_name ='TB_0322_05';
 
 
truncate table scott.TB_0322_05;
 
alter system checkpoint;
 
Table created.
 
Elapsed: 00:00:00.97
15:59:50 SQL> 15:59:50 SQL>
  COUNT(1)
----------
     75707
 
Elapsed: 00:00:00.86
15:59:51 SQL>
75707 rows created.
 
Elapsed: 00:00:00.23
15:59:52 SQL>
Commit complete.
 
Elapsed: 00:00:00.17
15:59:52 SQL>
151414 rows created.
 
Elapsed: 00:00:00.50
15:59:52 SQL>
Commit complete.
 
Elapsed: 00:00:00.23
15:59:52 SQL>
302828 rows created.
 
Elapsed: 00:00:01.63
15:59:54 SQL>
Commit complete.
 
Elapsed: 00:00:00.22
15:59:54 SQL>
605656 rows created.
 
Elapsed: 00:00:06.19
16:00:00 SQL>
Commit complete.
 
Elapsed: 00:00:00.02
16:00:01 SQL>
  COUNT(1)
----------
   1211312
 
Elapsed: 00:00:00.07
16:00:01 SQL> 16:00:01 SQL>
D.BYTES/1024/1024
-----------------
              136
 
Elapsed: 00:00:00.17
16:00:01 SQL> 16:00:01 SQL> 16:00:01 SQL>
Table truncated.
 
Elapsed: 00:00:01.26
16:00:02 SQL> 16:00:02 SQL>
System altered.
 
Elapsed: 00:00:00.15
16:00:02 SQL>
16:00:02 SQL> SELECT COUNT(1) FROM   scott.TB_0322_05;
 
  COUNT(1)
----------
         0
 
Elapsed: 00:00:00.00
16:02:35 SQL>
 
[oracle@ZFFR4CB1101:/home/oracle/gdul]$ ./gdul
 
*********************************************************************
  GDUL for ORACLE DB.
  Version 3.5.0.1, build date: 2016.03.07.
  Copyright (c) 2007, 2016. Andy Geng.  ALL RIGHTS RESERVED.
  Email: gengyonghui@aliyun.com
  QQ group: 235019291, WeChat Official Account: dbtool
*********************************************************************
 
GDUL> bootstrap
Bootstrap finish.
GDUL> desc scott.TB_0322_05
 
object_id: 78302, dataobj#: 78303, cluster tab#: 0
segment header: (ts#: 4, rfile#: 4, block#: 682))
 
Seg Column#  Column#    Name                 Null?           Type     
------------ ---------- -------------------- --------------- --------------
1            1          OWNER                                VARCHAR2(30)
2            2          OBJECT_NAME                          VARCHAR2(128)
3            3          SUBOBJECT_NAME                       VARCHAR2(30)
4            4          OBJECT_ID                            NUMBER   
5            5          DATA_OBJECT_ID                       NUMBER   
6            6          OBJECT_TYPE                          VARCHAR2(19)
7            7          CREATED                              DATE     
8            8          LAST_DDL_TIME                        DATE     
9            9          TIMESTAMP                            VARCHAR2(19)
10           10         STATUS                               VARCHAR2(7)
11           11         TEMPORARY                            VARCHAR2(1)
12           12         GENERATED                            VARCHAR2(1)
13           13         SECONDARY                            VARCHAR2(1)
14           14         NAMESPACE                            NUMBER   
15           15         EDITION_NAME                         VARCHAR2(30)
 
GDUL> unload table  scott.TB_0322_05
2016-03-22 16:01:54...unloaded "SCOTT"."TB_0322_05"   0 rows
GDUL> scan tablespace 4
start scan tablespace 4...
scan tablespace completed.
GDUL> untrunc table  scott.TB_0322_05
2016-03-22 16:04:29...untruncating table TB_0322_05 1211312 rows unloaded.
GDUL>
 
16:02:35 SQL> select * from dba_directories;
 
OWNER                          DIRECTORY_NAME                 DIRECTORY_PATH
------------------------------ ------------------------------ -----------------------------------------------------------------------
SYS                            SUBDIR                         /u01/app/oracle/product/11.2.0/dbhome_1/demo/schema/order_entry//2002/Sep
SYS                            SS_OE_XMLDIR                   /u01/app/oracle/product/11.2.0/dbhome_1/demo/schema/order_entry/
SYS                            LOG_FILE_DIR                   /u01/app/oracle/product/11.2.0/dbhome_1/demo/schema/log/
SYS                            MEDIA_DIR                      /u01/app/oracle/product/11.2.0/dbhome_1/demo/schema/product_media/
SYS                            XMLDIR                         /u01/app/oracle/product/11.2.0/dbhome_1/rdbms/xml
SYS                            DATA_FILE_DIR                  /u01/app/oracle/product/11.2.0/dbhome_1/demo/schema/sales_history/
SYS                            DATA_PUMP_DIR                  /u01/app/oracle/product/11.2.0/dbhome_1/rdbms/log/
SYS                            ORACLE_OCM_CONFIG_DIR          /u01/app/oracle/product/11.2.0/dbhome_1/ccr/state
 
8 rows selected.
 
Elapsed: 00:00:00.00
16:05:29 SQL>
 
[oracle@ZFFR4CB1101:/home/oracle/gdul/dump]$ impdp  scott/tiger directory=DATA_PUMP_DIR dumpfile=SCOTT_TB_0322_05.dmp LOGFILE=SCOTT_TB_0322_05.log TABLES=TB_0322_05
 
Import: Release 11.2.0.3.0 - Production on Tue Mar 22 16:16:48 2016
 
Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.
 
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options
Master table "SCOTT"."SYS_IMPORT_TABLE_01" successfully loaded/unloaded
Starting "SCOTT"."SYS_IMPORT_TABLE_01":  scott/******** directory=DATA_PUMP_DIR dumpfile=SCOTT_TB_0322_05.dmp LOGFILE=SCOTT_TB_0322_05.log TABLES=TB_0322_05
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
. . imported "SCOTT"."TB_0322_05"                        117.1 MB 1211312 rows
Job "SCOTT"."SYS_IMPORT_TABLE_01" successfully completed at 16:16:59
 
[oracle@ZFFR4CB1101:/home/oracle/gdul/dump]$
[oracle@ZFFR4CB2101:/home/oracle]$ sqlplus / as sysdba
 
SQL*Plus: Release 11.2.0.3.0 Production on Tue Mar 22 16:17:39 2016
 
Copyright (c) 1982, 2011, Oracle.  All rights reserved.
 
 
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options
 
SQL> SELECT COUNT(1) FROM   scott.TB_0322_05;
 
  COUNT(1)
----------
   1211312
 
SQL>
 
数据成功恢复。
 
 
 
2.4  实验总结
 
总体而言用fy_recover_data包或GDUL工具都是非常好的,fy_recover_data可以恢复truncate的数据,但不能恢复drop的数据,而GDUL工具就比较全面了,具体可以参考前边的简介或下载文档来看,小麦苗的共享云盘里也有比较全的文档。
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
PRM DUL for oracle恢复truncate截断掉的表 Oracle DBA神器:PRM灾难恢复工具,Schema级别数据恢复。PRM For Oracle Database – schema级别oracle数据库数据恢复特性 ,PRM即ParnassusData Recovery Manager是企业级别Oracle数据库灾难恢复工具。PRM可以在无备份的情况下恢复truncated/drop掉的表,也可以恢复无法打开的Oracle数据库(Alter Database Open失败)中的数据。 PRM是图形化增强版的Oracle DUL工具,同时具备很多Oracle DUL不具备的特性 情况 当某张表被意外truncated掉了,需要恢复其上的所有数据时。表空间的多个数据文件均存放在ASM上,且没有任何形式的备份。 注意这边文章针对的是PRM在 数据字典模式下的Truncate恢复选项不可用时使用,数据字典模式下的Truncate恢复选项是最简单、易用的一种模式,具体使用见《使用PRM恢复Oracle数据库中误truncate截断的表数据》http://www.parnassusdata.com/zh-hans/node/52 PRM 3.0的下载地址: http://parnassusdata.com/sites/default/files/ParnassusData_PRMForOracle_3002.zip PRM 的官方网站: http://www.parnassusdata.com/ PRM背景 PRM恢复表数据时存在多种模式, PRM需要知道哪些表上的数据块是需要被读取并取出数据的。默认的表现形式是直接从segment header数据段头里获取EXTENT MAP即盘区图,另一种方案就是由PRM自己去构建一个盘区图。 这些盘区图可以通过,PRM的SCAN DATABASE选项来获得: Recovery Wizard => Non-Dictionary Mode,如果是ASM则选择Non-Dictionary Mode(ASM) 执行SCAN Database后会生成SEG$和EXT$的数据到PRM内嵌的数据库中,之后可以选择SCAN TABLES FROM SEGMENTS 或者 SCAN TABLES FROM EXTENTS。 FROM Segments 意味着使用Segment Header中获得的Extent MAP信息,而FROM Extents意味着使用PRM自己扫描获得的EXTENT信息。 请注意当TRUNCATE发生后, 数据表Table的Segment Header中的Extent MAP信息就会被清空了, 但实际存放数据的数据块中的行数据还是在哪里的,除非被其他数据表/索引的增长而覆盖了。 所以当Truncate发生后选择SCAN TABLES FROM SEGMENT 是找不回数据的,必须使用SCAN TABLES FROM EXTENTS, EXTENT的信息是PRM自己去数据文件中扫描获得的,所以只要有数据的地方PRM就会自己去找到。 除了Truncate需要使用到 SCAN TABLES FROM EXTENTS之外对于DROP TABLE的恢复也可以用到SCAN TABLES FROM EXTENTS , 总之当Segment Header找不到(可能存放Segment Header的数据文件丢失了)、或者已损坏(可能Segment Header的数据块被损坏了)、或者其中的Extent Map数据无效(Truncate、DROP或逻辑损坏)时都可以使用SCAN TABLES FROM EXTENTS 。 但是如果不存在上述的问题时,建议用SCAN TABLES FROM SEGMENTS ,因为从Segment Header获取信息更方便也更高效一些。 在PRM中同一个程序实例 同时只能使用SCAN TABLES FROM SEGMENTS 或者 SCAN TABLES FROM EXTENTS 中的一个。 使用SCAN TABLES FROM EXTENTS 后需要找到对应被TRUNCATE掉的表的原始DATA_OBJECT_ID,即左侧属性图中的一个对象,并将其DataBridge 数据搭桥传输到目标数据库中即可。 用户truncate误删 schema下的若干数据表,无法使用flashback query等技术恢复数据,尝试从之前的全备份中恢复,数据库restore速度较快,但是archivelog恢复时由于HP data Protecter的不明原因导致归档恢复十分缓慢,缓慢一个归档往往要几分钟,而需要restore数百个归档,时间上无法接受。 该案例通过PRM-DUL直接在字典模式下恢复truncate数据的功能,在不到一个小时内就恢复了数十万条数据,虽然我们无法保证不丢失一条数据,但至少帮助用户在最短时间内恢复了主要业务。
使用ODU恢复Truncate表ODUmanual ODU3月 15th, 2009 意外Truncate表的事情时有发生,ODU提供了方便的恢复Truncate表的功能。被Truncate的表,只要原来的空间没有被重用(即数据被覆盖),则数据都是可以恢复的。 如果发现一个表被意外地Truncate,而需要马上恢复。首先要做的就是关闭数据库,或者OFFLINE那个表所在的表空间,或者关闭所有应用。目的只有一个,确保空间不会被重用,数据不会被覆盖。 下面举例说明如何用ODU恢复Truncate掉的表。 1. 建立测试的表DB_JJ_INFO_TEMP。 SQL> connect pdata/test 已连接。 SQL> create table DB_JJ_INFO_TEMP as select * from dba_objects; SQL> truncate table DB_JJ_INFO_TEMP; 2. 我们OFFLINE掉DB_JJ_INFO_TEMP表的表空间(实际上在实际的系统中,如果有比较多的活动,则表空间不容易被OFFLINE下来)。然后做一个Checkpoint,让ODU能够读到最新的数据字典数据。 SQL> select tablespace_name from user_tables where table_name='DB_JJ_INFO_TEMP'; TABLESPACE_NAME ------------------------------ PDATA SQL> alter tablespace PDATA offline; 表空间已更改。 SQL> alter system checkpoint; 系统已更改。 22=================================完善字典文件格式如下 control.txt文件中的数据格式为: 表空间号 文件号 相对文件号 文件名 块大小 是否大文件表空间 每列之间用空白分隔,可以只需要前四列,即块大小和是否大文件表空间可省略,块大小省略时,数据文件的默认块大小为config.txt中block_size的大小。下面是一个示例的数据: #ts #fno #rfno filename block_size bigfile 0 1 1 D:\ORACLE\ORADATA\XJ\SYSTEM01.DBF 4096 1 2 2 D:\ORACLE\ORADATA\XJ\UNDOTBS01.DBF 4096 3 3 3 D:\ORACLE\ORADATA\XJ\DRSYS01.DBF 4096 4 4 4 D:\ORACLE\ORADATA\XJ\EXAMPLE01.DBF 4096 5 5 5 D:\ORACLE\ORADATA\XJ\INDX01.DBF 4096 6 6 6 D:\ORACLE\ORADATA\XJ\ODM01.DBF 4096 7 7 7 D:\ORACLE\ORADATA\XJ\TOOLS03.DBF 4096 7 8 8 D:\ORACLE\ORADATA\XJ\TOOLS02.DBF 4096 9 9 9 D:\ORACLE\ORADATA\XJ\XDB01.DBF 4096 11 10 10 D:\ORACLE\ORADATA\XJ\TEST01.DBF 2048 14 11 11 D:\ORACLE\ORADATA\XJ\K16.DBF 16384 如果数据文件头是完好的,则ODU会自动从文件头里面获取表空间号,文件号,相对文件号,文件块大小等。表空间号,文件号和相对文件号可以写为0。 注意:ODU将检查control.txt文件中的第一个数据文件是否为SYSTEM表空间文件,所以要将SYSTEM表空间的第1个文件放在control.txt文件中的第一行。否则将不能自动获得数据字典数据。 3. 运行ODU,并unload数据字典。 ODU> unload dict get_bootstrap_dba: compat header size:12 CLUSTER C_USER# file_no: 1 block_no: 177 TABLE OBJ$ file_no: 1 block_no: 241 CLUSTER C_OBJ# file_no: 1 block_no: 49 CLUSTER C_OBJ# file_no: 1 block_no: 49 found IND$’s obj# 19 found IND$’s dataobj#:2,ts#:0,file#:1,block#:49,tab#:3 found TABPART$’s obj# 230 found TABPART$’s dataobj#:230,ts#:0,file#:1,block#:3313,tab#:0 found INDPART$’s obj# 234 found INDPART$’s dataobj#:234,ts#:0,file#:1,block#:3377,tab#:0 found TABSUBPART$’s obj# 240 found TABSUBPART$’s dataobj#:240,ts#:0,file#:1,block#:3473,tab#:0 found INDSUBPART$’s obj# 245 found INDSUBPART$’s dataobj#:245,ts#:0,file#:1,block#:3553,tab#:0 found IND$’s obj# 19 found IND$’s dataobj#:2,ts#:0,file#:1,block#:49,tab#:3 found LOB$’s obj# 156 found LOB$’s dataobj#:2,ts#:0,file#:1,block#:49,tab#:6 found LOBFRAG$’s obj# 258 found LOBFRAG$’s dataobj#:258,ts#:0,file#:1,block#:3761,tab#:0 4. 获取PDATA用户下的DB_JJ_INFO_TEMP表,也就是我们要恢复的表的信息: ODU> desc PDATA.DB_JJ_INFO_TEMP Object ID:33547 Storage(Obj#=33547 DataObj#=33549 TS#=11 File#=10 Block#=1400 Cluster=0) NO. SEG INT Column Name Null? Type --- --- --- ------------------------------ --------- ------------------------------ 1 1 1 OWNER VARCHAR2(30) 2 2 2 OBJECT_NAME VARCHAR2(128) 3 3 3 SUBOBJECT_NAME VARCHAR2(30) 4 4 4 OBJECT_ID NUMBER 5 5 5 DATA_OBJECT_ID NUMBER 6 6 6 OBJECT_TYPE VARCHAR2(18) 7 7 7 CREATED DATE 8 8 8 LAST_DDL_TIME DATE 9 9 9 TIMESTAMP VARCHAR2(19) 10 10 10 STATUS VARCHAR2(7) 11 11 11 TEMPORARY VARCHAR2(1) 12 12 12 GENERATED VARCHAR2(1) 13 13 13 SECONDARY VARCHAR2(1) 从上面的输出中,我们可以看到,PDATA.DB_JJ_INFO_TEMP表所在的表空间号为11,数据段头部为10号文件的1400号块。 5. 接下来用ODU扫描表空间的extent: ODU> scan extent tablespace 11 scanning extent… scanning extent finished. 6. 我们使用ODU来确定DB_JJ_INFO_TEMP表原来的data object id。一般来说,数据段的数据块,一般是在段头后面相邻的块中。但是我们可以从段头来确认: ODU> dump datafile 10 block 1400 Block Header: block type=0×23 (ASSM segment header block) block format=0×02 (oracle 8 or 9) block rdba=0×02800578 (file#=10, block#=1400) scn=0×0000.00286f2d, seq=4, tail=0×6f2d2304 block checksum value=0×0=0, flag=0 Data Segment Header: Extent Control Header ------------------------------------------------------------- Extent Header:: extents: 1 blocks: 5 last map: 0×00000000 #maps: 0 offset: 668 Highwater:: 0×02800579 (rfile#=10,block#=1401) ext#: 0 blk#: 3 ext size:5 #blocks in seg. hdr’s freelists: 0 #blocks below: 0 mapblk: 0×00000000 offset: 0 -------------------------------------------------------- Low HighWater Mark : Highwater:: 0×02800579 ext#: 0 blk#: 3 ext size: 5 #blocks in seg. hdr’s freelists: 0 #blocks below: 0 mapblk 0×00000000 offset: 0 Level 1 BMB for High HWM block: 0×02800576 Level 1 BMB for Low HWM block: 0×02800576 -------------------------------------------------------- Segment Type: 1 nl2: 1 blksz: 2048 fbsz: 0 L2 Array start offset: 0×00000434 First Level 3 BMB: 0×00000000 L2 Hint for inserts: 0×02800577 Last Level 1 BMB: 0×02800576 Last Level 1I BMB: 0×02800577 Last Level 1II BMB: 0×00000000 Map Header:: next 0×00000000 #extents: 1 obj#: 33549 flag: 0×220000000 Extent Map ------------------------------------------------------------- 0×02800576 length: 5 Auxillary Map ------------------------------------------------------------- Extent 0 : L1 dba: 0×02800576 Data dba: 0×02800579 ------------------------------------------------------------- Second Level Bitmap block DBAs ------------------------------------------------------------- DBA 1: 0×02800577 从上面的输出中的“Extent 0 : L1 dba: 0×02800576 Data dba: 0×02800579”可以看到,段的第1个数据块的RDBA为0×02800579,也就是10号文件的1401块。 我们dump第10号文件的1401块头,来得到表DB_JJ_INFO_TEMP原来的data object id: ODU> dump datafile 10 block 1401 header Block Header: block type=0×06 (table/index/cluster segment data block) block format=0×02 (oracle 8 or 9) block rdba=0×02800579 (file#=10, block#=1401) scn=0×0000.00285f2b, seq=2, tail=0×5f2b0602 block checksum value=0×0=0, flag=0 Data Block Header Dump: Object id on Block? Y seg/obj: 0×830b=33547 csc: 0×00.285f21 itc: 3 flg: E typ: 1 (data) brn: 0 bdba: 0×2800576 ver: 0×01 Itl Xid Uba Flag Lck Scn/Fsc 0×01 0xffff.000.00000000 0×00000000.0000.00 C--- 0 scn 0×0000.00285f21 0×02 0×0000.000.00000000 0×00000000.0000.00 ---- 0 fsc 0×0000.00000000 0×03 0×0000.000.00000000 0×00000000.0000.00 ---- 0 fsc 0×0000.00000000 Data Block Dump: ================ flag=0×0 -------- ntab=1 nrow=16 frre=-1 fsbo=0×32 ffeo=0×145 avsp=0×113 tosp=0×113 可以看到,DB_JJ_INFO_TEMP表原来的data object id就是33547。 7. 使用ODU来unload数据: ODU> unload table PDATA.DB_JJ_INFO_TEMP object 33547 Unloading table: DB_JJ_INFO_TEMP,object ID: 33547 Unloading segment,storage(Obj#=33547 DataObj#=33547 TS#=11 File#=10 Block#=1400 Cluster=0) 8. 使用sqlplus将PDATA表空间ONLINE: SQL> alter tablespace test online; 表空间已更改。 9. 使用sqlldr导入我们恢复的数据: E:\ODU\data>sqlldr test/test control=TEST_T1.ctl SQL*Loader: Release 9.2.0.8.0 - Production on 星期日 3月 15 15:13:56 2009 Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved. 达到提交点,逻辑记录计数6502 达到提交点,逻辑记录计数13004 达到提交点,逻辑记录计数19506 达到提交点,逻辑记录计数26008 达到提交点,逻辑记录计数30071 至此,恢复数据的步骤已经完成。我们来对比一下数据,看看数据是否和被Truncate前的数据完全一样: SQL> select * from t2 minus select * from DB_JJ_INFO_TEMP; 可以看到,数据已经完全恢复
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值