实践说明

  本文章主要记录在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. F#周报2019年第28期

    新闻 FableConf门票开始贩售 Bolero的HTML模板支持热加载 Bolero从v0.4到v0.5的升级指南 完整的SAFE-Chat迁移至了Fable 2 为纯函数式3D图形生成领域专用语 ...

  2. android_onSaveInstanceState_onRestoreInstanceState研究

    当一个activity的状态是一个容易被系统宰掉时,比如pause或者stop状态,此时这个活动不一定已经被销毁了,那么这个activity的onSaveInstanceState方法会被系统调用(值 ...

  3. 启动Chrome时自动开启开发者模式

    右键点击Google Chrome浏览器图标→属性,在目标里面加上参数--auto-open-devtools-for-tabs即可

  4. Oracle 学习笔记二

    一.oracle通用函数vnl(a,b) 用于任何类型,如果a的值不为null返回a的值否则返回b的值 条件判断oracle中可以使用 case 字段 when 条件1 then 表达式1 when ...

  5. 新手小白之学习python一飞冲天日志之—基本数据类型,条件控制语句

    python的历史 04年目前最流行的WEB框架Django诞生 python2:源码不统一,有重复的功能代码 python3:源码统一,没有重复的功能代码 python是一个什么编程语言 编译型:编 ...

  6. Ubuntu安装Sublime Text 3

    终端命令行安装: Install the GPG key: wget -qO - https://download.sublimetext.com/sublimehq-pub.gpg | sudo a ...

  7. Excel催化剂图表系列之品味IBCS瀑布图观察企业利润构成

    IBCS图表,每个细节都值得反复琢磨参悟,此篇给大家送上详尽的瀑布图方式下的利润数据观察.请不要拿Excel2016版提供的瀑布图与IBCS版的瀑布图作对比,那完全不是一个级别的,可以类比为拿一辆经济 ...

  8. 个人永久性免费-Excel催化剂功能第43波-文本处理类函数增强

    Excel的函数有400多个,真正常用的50多个,而常有的文本处理类函数也不多,不是因为文本类处理简单,而是Excel真的有点挤牙膏式的每个版本更新那么几个小函数,普通用户等得急切,但实际上这些小函数 ...

  9. 利用TCP协议,实现基于Socket的小聊天程序(初级版)

    TCP TCP (Transmission Control Protocol)属于传输层协议.其中TCP提供IP环境下的数据可靠传输,它提供的服务包括数据流传送.可靠性.有效流控.全双工操作和多路复用 ...

  10. Java EE.Servlet.生成响应

    Servlet的核心职责就是根据客户端的请求生成动态响应. 1.编码类型 2.流操作(下载文件) servlet支持两种格式的输入/输出流.一种是字符输入输出流.另一种是字节输入输出流. 3.重定向