• Oracle delete和truncate实践操作之一


    实践说明

      本文章主要记录在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实践操作之二。 

  • 相关阅读:
    Ansible 的初步使用
    HBase 和 Hive 的差别是什么,各自适用在什么场景中?Spark SQL能做什么?
    spark安装配置
    scala安装配置
    Apache Spark 3.0.0重磅发布 —— 重要特性全面解析
    hbase的安装与配置(三台集群分布式)
    Flv的结构分析
    几种直播流媒体协议
    rtmp推送aac没有声音的问题记录
    c++中SetEvent和ResetEvent的使用
  • 原文地址:https://www.cnblogs.com/bicewow/p/11358474.html
Copyright © 2020-2023  润新知