实践说明
本文章主要记录在Oracle中,delete和truncate进行数据删除之后,如何进行数据恢复。由于网上对delete和truncate的区别说明较多,此处不过多介绍两者区别。
注:由于环境和版本以及其他因素,本文章中并非最佳解决方法,仅供参考。
实践过程
环境准备
1、在本机准备Oracle bbed执行程序(需要通过指定包编译获取) delete主要还原工具
2、FY_Recover_Data工具下载(HelloDBA大神作品)truncate主要还原工具
Delete删除恢复过程
1、准备测试数据
1 SQL> create tablespace test1 datafile '+DATA' size 5M autoextend on next 1M maxsize 15M; 2 Tablespace created. 3 4 SQL> select TABLESPACE_NAME,FILE_ID,STATUS,FILE_NAME,BYTES/1024/1024 from dba_data_files; 5 6 TABLESPACE_NAME FILE_ID STATUS FILE_NAME BYTES/1024/1024 7 -------------------- ---------- --------- ------------------------------------------------------------ --------------- 8 USERS 4 AVAILABLE +DATA/orcl/users01.dbf 52.5 9 UNDOTBS1 3 AVAILABLE +DATA/orcl/undotbs01.dbf 255 10 SYSAUX 2 AVAILABLE +DATA/orcl/sysaux01.dbf 1060 11 SYSTEM 1 AVAILABLE +DATA/orcl/system01.dbf 770 12 UNDOTBS2 5 AVAILABLE +DATA/orcl/undotbs02.dbf 82.25 13 TEST1 6 AVAILABLE +DATA/orcl/datafile/test1.268.1016378251 5 14 15 6 rows selected. 16 17 SQL> create user test identified by test default tablespace test1; 18 User created. 19 20 SQL> grant dba to test; 21 Grant succeeded. 22 23 SQL> conn test/test 24 Connected. 25 SQL> create table t1 as select * from dba_objects where object_id<10; 26 Table created. 27 SQL> commit; 28 29 Commit complete.
2、delete操作本质
在执行delete后,数据并没有在物理上删除,只是把对应记录标记为删除,而且delete后,对表的HWM没有改造,表的大小依然那么大,delete数据后,占用的空间一直都在,别的表记录不能在此写入。
1 SQL> select dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block#,t.object_id from TEST.T1 t; 2 FILE# BLOCK# OBJECT_ID 3 ---------- ---------- ---------- 4 6 131 2 5 6 131 3 6 6 131 4 7 6 131 5 8 6 131 6 9 6 131 7 10 6 131 8 11 6 131 9 12 13 8 rows selected.
上述记录为T1表所在的数据文件6,以及对应的BLOCK#131。通过以下两种方法可以查看其block中对应行的标识。
方法一、dump出对应的数据块
1 SQL> alter system dump datafile 6 block 131; 2 System altered. 3 4 SQL> select spid from v$process where addr=(select paddr from v$session where sid=(select sid from v$mystat where rownum=1)); 5 SPID 6 ------------------------ 7 26716 8 9 10 [oracle@dbrac1 trace]$ pwd 11 /u01/app/oracle/diag/rdbms/orcl/orcl1/trace 12 [oracle@dbrac1 trace]$ ls -lrt *26716* 13 -rw-r----- 1 oracle asmadmin 614 8月 15 15:34 orcl1_ora_26716.trm 14 -rw-r----- 1 oracle asmadmin 12708 8月 15 15:34 orcl1_ora_26716.trc 15 16 。。。。。。。。 17 block_row_dump: 18 tab 0, row 0, @0x1f30 19 tl: 80 fb: --H-FL-- lb: 0x0 cc: 14 <==============fb : HFL即代表为正常记录 20 col 0: [ 3] 53 59 53 21 col 1: [ 6] 43 5f 4f 42 4a 23 22 col 2: *NULL* 23 col 3: [ 2] c1 03 24 col 4: [ 2] c1 03 25 col 5: [ 7] 43 4c 55 53 54 45 52 26 col 6: [ 7] 78 71 08 18 0c 26 24 27 col 7: [ 7] 78 71 08 18 0c 26 24 28 col 8: [19] 32 30 31 33 2d 30 38 2d 32 34 3a 31 31 3a 33 37 3a 33 35 29 col 9: [ 5] 56 41 4c 49 44 30 col 10: [ 1] 4e 31 col 11: [ 1] 4e 32 col 12: [ 1] 4e 33 col 13: [ 2] c1 06 34 tab 0, row 1, @0x1ee2 35 tl: 78 fb: --H-FL-- lb: 0x0 cc: 14 <==============fb: HFL即代表为正常记录 HDFL代表删除记录 36 col 0: [ 3] 53 59 53 37 col 1: [ 6] 49 5f 4f 42 4a 23 38 col 2: *NULL* 39 col 3: [ 2] c1 04 40 col 4: [ 2] c1 04
方法二、通过bbed查看相应块行记录
1 ASMCMD> cp TEST1.268.1016378251 /home/grid/test1.dbf <===============bbed不能直接读取ASM中数据文件,需要CP出来 2 copying +DATA/ORCL/DATAFILE/TEST1.268.1016378251 -> /home/grid/test1.dbf 3 4 BBED> info all 5 File# Name Size(blks) 6 ----- ---- ---------- 7 1 /home/oracle/bbed/asm_disk_header 0 8 2 /home/oracle/bbed/asm_disk_header2 0 9 6 /home/oracle/bbed/test1.dbf 1920 10 11 BBED> set dba 6,131 <================设置数据文件6,Block 131 12 DBA 0x01800083 (25165955 6,131) 13 BBED> p *kdbr[0] 14 rowdata[560] 15 ------------ 16 ub1 rowdata[560] @8108 0x2c <=================此处2c代表正常记录 3c代表删除记录 17 18 BBED> x /rcccccccc 19 rowdata[560] @8108 20 ------------ 21 flag@8108: 0x2c (KDRHFL, KDRHFF, KDRHFH) 22 lock@8109: 0x00 23 cols@8110: 14 24 25 col 0[3] @8111: SYS 26 col 1[6] @8115: C_OBJ# 27 col 2[0] @8122: *NULL* 28 col 3[2] @8123: col 4[2] @8126: col 5[7] @8129: CLUSTER 29 col 6[7] @8137: xq...&$ 30 col 7[7] @8145: xq...&$ 31 col 8[19] @8153: 2013-08-24:11:37:35 32 col 9[5] @8173: VALID 33 col 10[1] @8179: N 34 col 11[1] @8181: N 35 col 12[1] @8183: N 36 col 13[2] @8185:
注:以上关于Block的内容可参考 来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26715884/viewspace-2114424/
3、删除记录
1 SQL> delete from test.t1; 2 8 rows deleted. 3 4 SQL> commit; 5 Commit complete. 6 7 SQL> alter system flush buffer_cache; <============需要将脏块刷进数据文件 8 System altered. 9 10 11 SQL> alter system dump datafile 6 block 131; 12 System altered. 13 14 SQL> select spid from v$process where addr=(select paddr from v$session where sid=(select sid from v$mystat where rownum=1)); 15 SPID 16 ------------------------ 17 19634 18 19 [oracle@dbrac1 trace]$ pwd 20 /u01/app/oracle/diag/rdbms/orcl/orcl1/trace 21 [oracle@dbrac1 trace]$ ls -lrt *19634* 22 -rw-r----- 1 oracle asmadmin 322 8月 15 15:50 orcl1_ora_19634.trm 23 -rw-r----- 1 oracle asmadmin 8370 8月 15 15:50 orcl1_ora_19634.trc 24 [oracle@dbrac1 trace]$ vi orcl1_ora_19634.trc 25 。。。。。 26 block_row_dump: 27 tab 0, row 0, @0x1f30 28 tl: 2 fb: --HDFL-- lb: 0x2 <=================== fb:标识已经变成HDFL,为已删除状态。 29 tab 0, row 1, @0x1ee2 30 tl: 2 fb: --HDFL-- lb: 0x2 31 tab 0, row 2, @0x1e96 32 tl: 2 fb: --HDFL-- lb: 0x2 33 tab 0, row 3, @0x1e4a 34 tl: 2 fb: --HDFL-- lb: 0x2 35 tab 0, row 4, @0x1dfb 36 tl: 2 fb: --HDFL-- lb: 0x2
4、通过bbed还原数据
1 ASMCMD> cp TEST1.268.1016378251 /home/grid/test2.dbf 2 copying +DATA/ORCL/DATAFILE/TEST1.268.1016378251 -> /home/grid/test2.dbf <=======为了减少麻烦,将数据库关闭后,将文件重新拿出来,命名test2.dbf 3 BBED> info all 4 File# Name Size(blks) 5 ----- ---- ---------- 6 1 /home/oracle/bbed/asm_disk_header 0 7 2 /home/oracle/bbed/asm_disk_header2 0 8 6 /home/oracle/bbed/test1.dbf 1920 9 7 /home/oracle/bbed/test2.dbf 1920 <========删除数据后的数据文件 10 11 BBED> set dba 7,131 12 DBA 0x01c00083 (29360259 7,131) 13 BBED> p *kdbr[0] 14 rowdata[560] 15 ------------ 16 ub1 rowdata[560] @8108 0x3c <======标记已调整为3c证明数据处于删除状态 17 BBED> dump 18 File: /home/oracle/bbed/test2.dbf (7) 19 Block: 131 Offsets: 8108 to 8191 Dba:0x01c00083 20 ------------------------------------------------------------------------ 21 3c020e03 53595306 435f4f42 4a23ff02 c10302c1 0307434c 55535445 52077871 22 08180c26 24077871 08180c26 24133230 31332d30 382d3234 3a31313a 33373a33 23 35055641 4c494401 4e014e01 4e02c106 010641c7 24 25 <32 bytes per line> 26 27 BBED> m /x 2c <============通过修改数据块标识,调整行记录状态 28 File: /home/oracle/bbed/test2.dbf (7) 29 Block: 131 Offsets: 8108 to 8191 Dba:0x01c00083 30 ------------------------------------------------------------------------ 31 2c020e03 53595306 435f4f42 4a23ff02 c10302c1 0307434c 55535445 52077871 32 08180c26 24077871 08180c26 24133230 31332d30 382d3234 3a31313a 33373a33 33 35055641 4c494401 4e014e01 4e02c106 010641c7 34 35 <32 bytes per line> 36 37 BBED> sum apply 38 Check value for File 7, Block 131: 39 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实践操作之二。