Oracle delete和truncate实践操作之一
实践说明
本文章主要记录在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实践操作之一的更多相关文章
- 详解Oracle DELETE和TRUNCATE 的区别(摘)
语法delete from aa truncate table aa 区别 1.delete from后面可以写条件,truncate不可以. 2.delete from记录是一条条删的,所删除的每行 ...
- 详解Oracle DELETE和TRUNCATE 的区别
原文地址:http://www.cnblogs.com/simplefrog/archive/2012/07/30/2615169.html 语法delete from aa truncate tab ...
- Oracle DELETE和TRUNCATE 的区别
语法delete from aa truncate table aa 区别 1.delete from后面可以写条件,truncate不可以. 2.delete from记录是一条条删的,所删除的每行 ...
- 3.数据库操作相关术语,Oracle认证,insert into,批量插入,update tablename set,delete和truncate的差别,sql文件导入
1相关术语 语句 含义 操作 DML语句 (Data Manipulation Language) 数据库操作语言 insert update delete select DDL语言 (Date ...
- Oracle中的Truncate和Delete语句
Oracle中的Truncate和Delete语句 首先讲一下,truncate命令: 语法:TRUNCATE TABLE table; 表格里的数据被清空,存储空间被释放. 运行后会自动 ...
- oracle中delete、truncate、drop的区别
oracle中delete.truncate.drop的区别 标签: deleteoracletable存储 2012-05-23 15:12 7674人阅读 评论(0) 收藏 举报 分类: ora ...
- oracle中drop、delete和truncate的区别
oracle中drop.delete和truncate的区别 oracle中可以使用drop.delete和truncate三个命令来删除数据库中的表,网上有许多文章和教程专门讲解了它们之间的异同,我 ...
- Oracle user,role,profile常规操作--用户,权限,角色,配置文件
Oracle user,role,profile常规操作--用户,权限,角色,配置文件 1 权限查询 1查看所有用户 SQL> select username,account_status,lo ...
- Oracle手边常用命令及操作语句
Oracle手边常用命令及操作语句 作者:白宁超 时间:2016年3月4日11:24:08 摘要:日常使用oracle数据库过程中,常用脚本命令莫不是用户和密码.表空间.多表联合.执行语句等常规操作. ...
随机推荐
- Bzoj 2839 集合计数 题解
2839: 集合计数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 495 Solved: 271[Submit][Status][Discuss] ...
- ~~Python解释器安装教程及环境变量配置~~
进击のpython Python解释器安装教程以及环境变量配置 对于一个程序员来说,能够自己配置python解释器是最基础的技能 那么问题来了,现在市面上有两种Python版本 Python 2.x ...
- 异常:带有 CLSID {} 的 COM 对象无效或未注册
今天处理调试打印程序的时候,看到这个异常: 代码: try { string strApplyEmpno=""; string strApplyDeptCode="&qu ...
- select模块(I/O多路复用)
0709自我总结 select模块 一.介绍 Python中的select模块专注于I/O多路复用,提供了select poll epoll三个方法(其中后两个在Linux中可用,windows仅支持 ...
- 基于TCP协议的套接字编程
06.26自我总结 1.关于Socket Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在 ...
- JS浅学
(变量的名字.focus(); )让打开的新的页面获取焦点 (变量的名字.close();)关闭打开的页面 可以用(!变量名)直接判断是否打开过新的页面 用(变量名.closed)判断是不是被关闭了 ...
- Hive之函数与自定义函数
系统自带的函数 1)查看系统自带的函数 hive> show functions; 2)显示自带的函数的用法 hive> desc function upper; 3)详细显示自带的函数的 ...
- javaee+tomcat新特性,乱码问题
Tomcat版本问题,servlet乱码问题 我在学习的时候,老师用的是Tomcat1.7版本,在jsp发送get请求的时候,Servlet中还要对get请求传递过来的参数进行解码编码,因为tomca ...
- 使用Mxnet基于skip-gram模型实现word2vect
1. 需求 使用skip-gram模式实现word2vect,然后在jaychou_lyrics.txt数据集上应用 jaychou_lyrics.txt数据集收录了周杰伦从第一张专辑到第十张专辑中的 ...
- linux初学者-网络桥接篇
linux初学者-网络桥接篇 在网络的使用中,有时需要搭建网络桥来实现网络桥接.例如在一台主机上制作一台虚拟机,虚拟机是没有物理网卡的,这时虚拟机数据的发送和接收就需要通过主机上的物理网卡,需要主机的 ...