实践说明

  本文章主要记录在Oracle中,delete和truncate进行数据删除之后,如何进行数据恢复。由于网上对delete和truncate的区别说明较多,此处不过多介绍两者区别。

  注:由于环境和版本以及其他因素,本文章中并非最佳解决方法,仅供参考。

实践过程

  环境准备

    1、在本机准备Oracle bbed执行程序(需要通过指定包编译获取)  delete主要还原工具

    2、FY_Recover_Data工具下载(HelloDBA大神作品)truncate主要还原工具

  Delete删除恢复过程

    1、准备测试数据

    

 SQL> create tablespace test1 datafile '+DATA' size 5M autoextend on next 1M maxsize 15M;
Tablespace created. SQL> select TABLESPACE_NAME,FILE_ID,STATUS,FILE_NAME,BYTES/1024/1024 from dba_data_files; TABLESPACE_NAME FILE_ID STATUS FILE_NAME BYTES/1024/1024
-------------------- ---------- --------- ------------------------------------------------------------ ---------------
USERS 4 AVAILABLE +DATA/orcl/users01.dbf 52.5
UNDOTBS1 3 AVAILABLE +DATA/orcl/undotbs01.dbf 255
SYSAUX 2 AVAILABLE +DATA/orcl/sysaux01.dbf 1060
SYSTEM 1 AVAILABLE +DATA/orcl/system01.dbf 770
UNDOTBS2 5 AVAILABLE +DATA/orcl/undotbs02.dbf 82.25
TEST1 6 AVAILABLE +DATA/orcl/datafile/test1.268.1016378251 5 6 rows selected. SQL> create user test identified by test default tablespace test1;
User created. SQL> grant dba to test;
Grant succeeded. SQL> conn test/test
Connected.
SQL> create table t1 as select * from dba_objects where object_id<10;
Table created.
SQL> commit; Commit complete.

    2、delete操作本质

    在执行delete后,数据并没有在物理上删除,只是把对应记录标记为删除,而且delete后,对表的HWM没有改造,表的大小依然那么大,delete数据后,占用的空间一直都在,别的表记录不能在此写入。

    

 SQL> select dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block#,t.object_id from TEST.T1 t;
FILE# BLOCK# OBJECT_ID
---------- ---------- ----------
6 131 2
6 131 3
6 131 4
6 131 5
6 131 6
6 131 7
6 131 8
6 131 9 8 rows selected.

    上述记录为T1表所在的数据文件6,以及对应的BLOCK#131。通过以下两种方法可以查看其block中对应行的标识。

    方法一、dump出对应的数据块

 SQL> alter system dump datafile 6 block 131;
System altered. SQL> select spid from v$process where addr=(select paddr from v$session where sid=(select sid from v$mystat where rownum=1));
SPID
------------------------
26716 [oracle@dbrac1 trace]$ pwd
/u01/app/oracle/diag/rdbms/orcl/orcl1/trace
[oracle@dbrac1 trace]$ ls -lrt *26716*
-rw-r----- 1 oracle asmadmin 614 8月 15 15:34 orcl1_ora_26716.trm
-rw-r----- 1 oracle asmadmin 12708 8月 15 15:34 orcl1_ora_26716.trc 。。。。。。。。
block_row_dump:
tab 0, row 0, @0x1f30
tl: 80 fb: --H-FL-- lb: 0x0 cc: 14 <==============fb : HFL即代表为正常记录
col 0: [] 53 59 53
col 1: [] 43 5f 4f 42 4a 23
col 2: *NULL*
col 3: [] c1 03
col 4: [] c1 03
col 5: [] 43 4c 55 53 54 45 52
col 6: [] 78 71 08 18 0c 26 24
col 7: [] 78 71 08 18 0c 26 24
col 8: [] 32 30 31 33 2d 30 38 2d 32 34 3a 31 31 3a 33 37 3a 33 35
col 9: [] 56 41 4c 49 44
col 10: [] 4e
col 11: [] 4e
col 12: [] 4e
col 13: [] c1 06
tab 0, row 1, @0x1ee2
tl: 78 fb: --H-FL-- lb: 0x0 cc: 14 <==============fb: HFL即代表为正常记录 HDFL代表删除记录
col 0: [] 53 59 53
col 1: [] 49 5f 4f 42 4a 23
col 2: *NULL*
col 3: [] c1 04
col 4: [] c1 04

    方法二、通过bbed查看相应块行记录

 ASMCMD> cp TEST1.268.1016378251 /home/grid/test1.dbf                <===============bbed不能直接读取ASM中数据文件,需要CP出来
copying +DATA/ORCL/DATAFILE/TEST1.268.1016378251 -> /home/grid/test1.dbf BBED> info all
File# Name Size(blks)
----- ---- ----------
1 /home/oracle/bbed/asm_disk_header 0
2 /home/oracle/bbed/asm_disk_header2 0
6 /home/oracle/bbed/test1.dbf 1920 BBED> set dba 6,131 <================设置数据文件6,Block 131
DBA 0x01800083 (25165955 6,131)
BBED> p *kdbr[]
rowdata[]
------------
ub1 rowdata[] @8108 0x2c <=================此处2c代表正常记录 3c代表删除记录 BBED> x /rcccccccc
rowdata[] @8108
------------
flag@8108: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8109: 0x00
cols@8110: 14 col 0[] @8111: SYS
col 1[] @8115: C_OBJ#
col 2[] @8122: *NULL*
col 3[] @8123: col 4[] @8126: col 5[] @8129: CLUSTER
col 6[] @8137: xq...&$
col 7[] @8145: xq...&$
col 8[] @8153: 2013-08-24:11:37:35
col 9[] @8173: VALID
col 10[] @8179: N
col 11[] @8181: N
col 12[] @8183: N
col 13[] @8185:

    注:以上关于Block的内容可参考 来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26715884/viewspace-2114424/

    3、删除记录

 SQL> delete from test.t1;
8 rows deleted. SQL> commit;
Commit complete. SQL> alter system flush buffer_cache; <============需要将脏块刷进数据文件
System altered. SQL> alter system dump datafile 6 block 131;
System altered. SQL> select spid from v$process where addr=(select paddr from v$session where sid=(select sid from v$mystat where rownum=1));
SPID
------------------------
19634 [oracle@dbrac1 trace]$ pwd
/u01/app/oracle/diag/rdbms/orcl/orcl1/trace
[oracle@dbrac1 trace]$ ls -lrt *19634*
-rw-r----- 1 oracle asmadmin 322 8月 15 15:50 orcl1_ora_19634.trm
-rw-r----- 1 oracle asmadmin 8370 8月 15 15:50 orcl1_ora_19634.trc
[oracle@dbrac1 trace]$ vi orcl1_ora_19634.trc
。。。。。
block_row_dump:
tab 0, row 0, @0x1f30
tl: 2 fb: --HDFL-- lb: 0x2 <=================== fb:标识已经变成HDFL,为已删除状态。
tab 0, row 1, @0x1ee2
tl: 2 fb: --HDFL-- lb: 0x2
tab 0, row 2, @0x1e96
tl: 2 fb: --HDFL-- lb: 0x2
tab 0, row 3, @0x1e4a
tl: 2 fb: --HDFL-- lb: 0x2
tab 0, row 4, @0x1dfb
tl: 2 fb: --HDFL-- lb: 0x2

    4、通过bbed还原数据

 ASMCMD> cp TEST1.268.1016378251 /home/grid/test2.dbf
copying +DATA/ORCL/DATAFILE/TEST1.268.1016378251 -> /home/grid/test2.dbf <=======为了减少麻烦,将数据库关闭后,将文件重新拿出来,命名test2.dbf
BBED> info all
File# Name Size(blks)
----- ---- ----------
1 /home/oracle/bbed/asm_disk_header 0
2 /home/oracle/bbed/asm_disk_header2 0
6 /home/oracle/bbed/test1.dbf 1920
7 /home/oracle/bbed/test2.dbf 1920 <========删除数据后的数据文件 BBED> set dba 7,131
DBA 0x01c00083 (29360259 7,131)
BBED> p *kdbr[]
rowdata[]
------------
ub1 rowdata[] @8108 0x3c <======标记已调整为3c证明数据处于删除状态
BBED> dump
File: /home/oracle/bbed/test2.dbf (7)
Block: 131 Offsets: 8108 to 8191 Dba:0x01c00083
------------------------------------------------------------------------
3c020e03 53595306 435f4f42 4a23ff02 c10302c1 0307434c 55535445 52077871
08180c26 24077871 08180c26 24133230 31332d30 382d3234 3a31313a 33373a33
35055641 4c494401 4e014e01 4e02c106 010641c7 <32 bytes per line> BBED> m /x 2c <============通过修改数据块标识,调整行记录状态
File: /home/oracle/bbed/test2.dbf (7)
Block: 131 Offsets: 8108 to 8191 Dba:0x01c00083
------------------------------------------------------------------------
2c020e03 53595306 435f4f42 4a23ff02 c10302c1 0307434c 55535445 52077871
08180c26 24077871 08180c26 24133230 31332d30 382d3234 3a31313a 33373a33
35055641 4c494401 4e014e01 4e02c106 010641c7 <32 bytes per line> BBED> sum apply
Check value for File 7, Block 131:
current = 0x0000, required = 0x0000 BBED> x /rcccccccccc

rowdata[560] @8108
  ------------
  flag@8108: 0x2c (KDRHFL, KDRHFF, KDRHFH)
  lock@8109: 0x02
  cols@8110: 14

col    0[3] @8111: SYS
col 1[6] @8115: C_OBJ# <===============在还原之后,数据可以查看

    5、验证数据

ASMCMD> rm -rf TEST1.268.1016378251
ASMCMD> cp /home/grid/test2.dbf +DATA/orcl/DATAFILE/test2.dbf
copying /home/grid/test2.dbf -> +DATA/orcl/DATAFILE/test2.dbf SQL> startup mount
ORACLE instance started.
Total System Global Area 1043886080 bytes
Fixed Size 2259840 bytes
Variable Size 645923968 bytes
Database Buffers 390070272 bytes
Redo Buffers 5632000 bytes
Database mounted.
SQL> alter database rename file '+DATA/orcl/DATAFILE/TEST1.268.1016378251' to '+DATA/orcl/DATAFILE/test2.dbf';
Database altered. SQL> alter database open;
Database altered. SQL> select OWNER,OBJECT_NAME from test.t1; <=============此处查出结果,与第4步结果一致,证明恢复成功
OWNER OBJECT_NAME
------------------------------ ----------------------------------------
SYS C_OBJ#

    6、总结

    以上过程看似步骤简单,实际上蕴含很多知识点。

    1) Block块删除行后,标识位改变算法(本次实践的重点)

    2)使用bbed读取ASM中数据文件方法

    3)查看Block块内容方法

    4)从本地传文件至ASM磁盘组方法

    5)bbed中一些常用的命令

 关于Truncate表的恢复方法,详见下一章节Oracle delete和truncate实践操作之二。 

Oracle delete和truncate实践操作之一的更多相关文章

  1. 详解Oracle DELETE和TRUNCATE 的区别(摘)

    语法delete from aa truncate table aa 区别 1.delete from后面可以写条件,truncate不可以. 2.delete from记录是一条条删的,所删除的每行 ...

  2. 详解Oracle DELETE和TRUNCATE 的区别

    原文地址:http://www.cnblogs.com/simplefrog/archive/2012/07/30/2615169.html 语法delete from aa truncate tab ...

  3. Oracle DELETE和TRUNCATE 的区别

    语法delete from aa truncate table aa 区别 1.delete from后面可以写条件,truncate不可以. 2.delete from记录是一条条删的,所删除的每行 ...

  4. 3.数据库操作相关术语,Oracle认证,insert into,批量插入,update tablename set,delete和truncate的差别,sql文件导入

     1相关术语 语句 含义 操作 DML语句 (Data Manipulation Language) 数据库操作语言 insert update delete select DDL语言 (Date ...

  5. Oracle中的Truncate和Delete语句

    Oracle中的Truncate和Delete语句   首先讲一下,truncate命令:   语法:TRUNCATE  TABLE  table; 表格里的数据被清空,存储空间被释放. 运行后会自动 ...

  6. oracle中delete、truncate、drop的区别

    oracle中delete.truncate.drop的区别 标签: deleteoracletable存储 2012-05-23 15:12 7674人阅读 评论(0) 收藏 举报  分类: ora ...

  7. oracle中drop、delete和truncate的区别

    oracle中drop.delete和truncate的区别 oracle中可以使用drop.delete和truncate三个命令来删除数据库中的表,网上有许多文章和教程专门讲解了它们之间的异同,我 ...

  8. Oracle user,role,profile常规操作--用户,权限,角色,配置文件

    Oracle user,role,profile常规操作--用户,权限,角色,配置文件 1 权限查询 1查看所有用户 SQL> select username,account_status,lo ...

  9. Oracle手边常用命令及操作语句

    Oracle手边常用命令及操作语句 作者:白宁超 时间:2016年3月4日11:24:08 摘要:日常使用oracle数据库过程中,常用脚本命令莫不是用户和密码.表空间.多表联合.执行语句等常规操作. ...

随机推荐

  1. C# 使用XDocument实现读取、添加,修改XML文件

    新建xml文件编写如下内容做测试使用 需要引用:System.Xml.Linq 命名空间 一.读取XML 读取所有文档  筛选子元素为attribute1的元素,结果是IEumerable 通过Lin ...

  2. 使用Task实现非阻塞式的I/O操作

    在前面的<基于任务的异步编程模式(TAP)>文章中讲述了.net 4.5框架下的异步操作自我实现方式,实际上,在.net 4.5中部分类已实现了异步封装.如在.net 4.5中,Strea ...

  3. Java编程思想:文件加锁

    import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; i ...

  4. pgsql查询优化之模糊查询

    前言 一直以来,对于搜索时模糊匹配的优化一直是个让人头疼的问题,好在强大pgsql提供了优化方案,下面就来简单谈一谈如何通过索引来优化模糊匹配 案例 我们有一张千万级数据的检查报告表,需要通过检查报告 ...

  5. 宽字符转窄字符CW2AEX<>(szAreaInfo,CP_UTF8)

    CString szAreaInfo; CW2AEX<>(szAreaInfo,CP_UTF8); 最好能像上面这样转换,否则汉字就会转成乱码.

  6. 实验吧--web--天下武功唯快不破

    ---恢复内容开始--- 英文翻译过来嘛,就是:天下武功无快不破嘛.(出题者还是挺切题的) 看看前端源码: 注意这里 please post what you find with parameter: ...

  7. C#3.0新增功能09 LINQ 标准查询运算符 04 运算

    连载目录    [已更新最新开发文章,点击查看详细] 本篇主要介绍标准查询运算符的常用运算功能. 01 对数据排序 排序操作基于一个或多个属性对序列的元素进行排序. 第一个排序条件对元素执行主要排序. ...

  8. [剑指offer] 53. 表达数值的字符串

    题目描述 请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100","5e2","-123","3.1 ...

  9. [剑指offer] 3. 从头到尾打印链表

    题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 思路: 利用容器,遍历一遍加入到一个新容器里,然后反置输出. vector 用 reverse stack 则直接一个个出栈 ...

  10. 《C#从入门到精通(第3版)》目录

    C#从入门到精通(第3版)pdf+源码 一.基础知识 1.初识C#及其开发环境 2.开始C#之旅 3.变量与常量 4.表达式与运算符 5.字符与字符串 6.流程控制语句 7.数组与集合 8.属性和方法 ...