特殊手段恢复被truncate的表

       最近在写oracle抽取数据文件工具,在抽取数据文件恢复数据的时候发现,恢复的数据比预期的多,经过对比之后发现是有一些表被truncate了,由于被truncate之后部分块还没有被覆盖。所以这样的数据也就抽取出来了。其实抽取工具的原理就是根据段头、三级块位图、二级块位图、一级块位图等,再加上系统表空间对应的数据文件。最后整合之后就可以转换成表数据。简单的抽取过程可以参考之前写的文章https://blog.csdn.net/m15217321304/article/details/88687988。这里注重是通过bbed修改元数据来实现恢复truncate表的操作。

1、创建测试数据

SQL> create tablespace py datafile '/u01/app/oradata/QXY/py.dbf' size 5M autoextend off;

Tablespace created.

SQL> create table pygc(id int) tablespace py;

Table created.

SQL> insert into pygc values (10);

1 row created.

SQL> insert into pygc values (11);

1 row created.

SQL> commit;

Commit complete.

SQL> select object_id, data_object_id, object_name from dba_objects where object_name='PYGC';

 OBJECT_ID DATA_OBJECT_ID OBJECT_NAME
---------- -------------- ---------------------------------------------------------------------
    136026         136026 PYGC

SQL> 

创建一个表空间PY,并在该表空间创建一张表PYGC插入两行数据。表PYGC的对象号为136026。

2、dump表PYGC数据块的信息

SQL> select distinct dbms_rowid.ROWID_RELATIVE_FNO(rowid), dbms_rowid.ROWID_BLOCK_NUMBER(rowid) from PYGC;

DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------------------------ ------------------------------------
                                  15                                  134

SQL> 

SQL>       
SQL> alter system dump datafile 15 block 134;

System altered.

SQL> 


SQL> select value from v$diag_info where name = 'Default Trace File';

VALUE
-------------------------------------------------------------------------
/u01/app/diag/rdbms/qxy/QXY/trace/QXY_ora_4123.trc

SQL> 

Block dump from disk:
buffer tsn: 17 rdba: 0x03c00086 (15/134)
scn: 0x0000.0225a6ce seq: 0x01 flg: 0x06 tail: 0xa6ce0601
frmt: 0x02 chkval: 0x8361 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x00007F43CF4AF000 to 0x00007F43CF4B1000
7F43CF4AF000 0000A206 03C00086 0225A6CE 06010000  [..........%.....]
7F43CF4AF010 00008361 00000001 0002135A 0225A6CB  [a.......Z.....%.]
7F43CF4AF020 00000000 0032F802 03C00080 00010017  [......2.........]
7F43CF4AF030 00002CD0 04C023C2 00060593 00002002  [.,...#....... ..]
7F43CF4AF040 0225A6CE 00000000 00000000 00000000  [..%.............]
7F43CF4AF050 00000000 00000000 00000000 00000000  [................]
7F43CF4AF060 00000000 00020100 0016FFFF 1F701F8C  [..............p.]
7F43CF4AF070 00001F70 1F920002 00001F8C 00000000  [p...............]
7F43CF4AF080 00000000 00000000 00000000 00000000  [................]
        Repeat 502 times
7F43CF4B0FF0 0201012C 012C0CC1 0BC10201 A6CE0601  [,.....,.........]
Block header dump:  0x03c00086
 Object id on Block? Y
 seg/obj: 0x2135a  csc: 0x00.225a6cb  itc: 2  flg: E  typ: 1 - DATA 
     brn: 0  bdba: 0x3c00080 ver: 0x01 opc: 0 
     inc: 0  exflg: 0
 
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0017.001.00002cd0  0x04c023c2.0593.06  --U-    2  fsc 0x0000.0225a6ce
0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
bdba: 0x03c00086
data_block_dump,data header at 0x7f43cf4af064
===============
tsiz: 0x1f98
hsiz: 0x16
pbl: 0x7f43cf4af064
     76543210
flag=--------
ntab=1
nrow=2
frre=-1
fsbo=0x16
fseo=0x1f8c
avsp=0x1f70
tosp=0x1f70
0xe:pti[0]      nrow=2  offs=0
0x12:pri[0]     offs=0x1f92
0x14:pri[1]     offs=0x1f8c
block_row_dump:
tab 0, row 0, @0x1f92
tl: 6 fb: --H-FL-- lb: 0x1  cc: 1
col  0: [ 2]  c1 0b
tab 0, row 1, @0x1f8c
tl: 6 fb: --H-FL-- lb: 0x1  cc: 1
col  0: [ 2]  c1 0c
end_of_block_dump
End dump data blocks tsn: 17 file#: 15 minblk 134 maxblk 134

可以看到15号文件的134块包含了2行数据c10b、c10c。该格式是raw格式,转换成number就是10、11。可以通过oracle有自带转换工具dbms_stats.convert_raw_value,我这里进行了封装,转换之后如下:

SQL> select displayraw('c10b','NUMBER') from dual;  

DISPLAYRAW('C10B','NUMBER')
--------------------------------------------------------------------------------
10

SQL> select displayraw('c10c','NUMBER') from dual; 

DISPLAYRAW('C10C','NUMBER')
--------------------------------------------------------------------------------
11

SQL> 

3、查看表PYGC段头信息


SQL> col segment_name for a20
SQL> select SEGMENT_NAME,HEADER_FILE,HEADER_BLOCK from dba_segments where segment_name = 'PYGC';

SEGMENT_NAME         HEADER_FILE HEADER_BLOCK
-------------------- ----------- ------------
PYGC                          15          130

SQL> 

SQL> alter system dump datafile 15 block 130;

System altered.

SQL> select value from v$diag_info where name = 'Default Trace File';

VALUE
--------------------------------------------------------------------------------
/u01/app/diag/rdbms/qxy/QXY/trace/QXY_ora_4893.trc

SQL> 



buffer tsn: 17 rdba: 0x03c00082 (15/130)
scn: 0x0000.0225a6cb seq: 0x01 flg: 0x04 tail: 0xa6cb2301
frmt: 0x02 chkval: 0xbaf6 type: 0x23=PAGETABLE SEGMENT HEADER
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x00007F193760EA00 to 0x00007F1937610A00
7F193760EA00 0000A223 03C00082 0225A6CB 04010000  [#.........%.....]
7F193760EA10 0000BAF6 00000000 00000000 00000000  [................]
7F193760EA20 00000000 00000001 00000008 00000A9C  [................]
7F193760EA30 00000000 00000008 00000008 03C00088  [................]
7F193760EA40 00000000 00000000 00000000 00000005  [................]
7F193760EA50 00000000 00000000 00000000 00000000  [................]
7F193760EA60 00000008 00000008 03C00088 00000000  [................]
7F193760EA70 00000000 00000000 00000005 03C00080  [................]
7F193760EA80 03C00080 00000000 00000000 00000000  [................]
7F193760EA90 00000000 00000000 00000000 00000000  [................]
        Repeat 3 times
7F193760EAD0 00000001 00002000 00000000 00001434  [..... ......4...]
7F193760EAE0 00000000 03C00081 00000001 03C00080  [................]
7F193760EAF0 03C00081 00000000 00000000 00000000  [................]
7F193760EB00 00000000 00000000 00000001 00000000  [................]
7F193760EB10 0002135A 10000000 03C00080 00000008  [Z...............]
7F193760EB20 00000000 00000000 00000000 00000000  [................]
        Repeat 152 times
7F193760F4B0 03C00080 03C00083 00000000 00000000  [................]
7F193760F4C0 00000000 00000000 00000000 00000000  [................]
        Repeat 151 times
7F193760FE40 00000000 00000000 03C00081 00000000  [................]
7F193760FE50 00000000 00000000 00000000 00000000  [................]
        Repeat 185 times
7F19376109F0 00000000 00000000 00000000 A6CB2301  [.............#..]
  Extent Control Header
  -----------------------------------------------------------------
  Extent Header:: spare1: 0      spare2: 0      #extents: 1      #blocks: 8
                  last map  0x00000000  #maps: 0      offset: 2716
      Highwater::  0x03c00088  ext#: 0      blk#: 8      ext size: 8
  #blocks in seg. hdr's freelists: 0
  #blocks below: 5
  mapblk  0x00000000  offset: 0
                   Unlocked
  --------------------------------------------------------
  Low HighWater Mark :
      Highwater::  0x03c00088  ext#: 0      blk#: 8      ext size: 8
  #blocks in seg. hdr's freelists: 0
  #blocks below: 5
  mapblk  0x00000000  offset: 0
  Level 1 BMB for High HWM block: 0x03c00080
  Level 1 BMB for Low HWM block: 0x03c00080
  --------------------------------------------------------
  Segment Type: 1 nl2: 1      blksz: 8192   fbsz: 0
  L2 Array start offset:  0x00001434
  First Level 3 BMB:  0x00000000
  L2 Hint for inserts:  0x03c00081
  Last Level 1 BMB:  0x03c00080
  Last Level II BMB:  0x03c00081
  Last Level III BMB:  0x00000000
     Map Header:: next  0x00000000  #extents: 1    obj#: 136026 flag: 0x10000000
  Inc # 0
  Extent Map
  -----------------------------------------------------------------
   0x03c00080  length: 8

  Auxillary Map
  --------------------------------------------------------
   Extent 0     :  L1 dba:  0x03c00080 Data dba:  0x03c00083
  --------------------------------------------------------

   Second Level Bitmap block DBAs
   --------------------------------------------------------
   DBA 1:   0x03c00081

End dump data blocks tsn: 17 file#: 15 minblk 130 maxblk 130

该dump数据包含了高水位信息、块位图信息等。

4、truncate前后用解析工具得到的数据

[oracle@QXY1 jiexi]$ ./header 
kkkkkkk=130       <====代表段头数据在130块
objectid=136026   <====对象号是136026
address 3c00080 8 <====该对象包含的extent和对应的区长度
addrend
rdba=3c00086   <====真正的数据块地址,包含在了 address 3c00080 和3c00080+8之间,说明下面的内容属于对象136026
columns_count=1  <====真正的数据内容,该对象只有1列
c10c
columns_count=1
c10b
[oracle@QXY1 jiexi]$ 



SQL> alter system switch logfile;

System altered.

SQL> col member for a50
SQL> select l.member from v$logfile l, v$log g where l.group#=g.group# and g.status='CURRENT';

MEMBER
--------------------------------------------------
/u01/app/oradata/QXY/redo02.log

SQL> 




<======做truncate操作
SQL> select * from pygc;

        ID
----------
        10
        11

SQL> truncate table pygc;

Table truncated.

SQL>  select * from pygc;

no rows selected

SQL> 


[oracle@QXY1 jiexi]$ 
[oracle@QXY1 jiexi]$ ./header   <=====第二次解析
kkkkkkk=130
objectid=136027      <======解析之后发现对象号从136026变成了136027
address 3c00080 8
addrend
rdba=3c00086
columns_count=1
c10c
columns_count=1
c10b
[oracle@QXY1 jiexi]$ 

这里不介绍把raw数据怎么结合解析system表空间数据文件得到数据转换成对应的表。可以参考之前写的文章。

truncate之后,object_id和data_object_id的值就不一样了,如下:

SQL> select object_id, data_object_id, object_name from dba_objects where object_name='PYGC';

 OBJECT_ID DATA_OBJECT_ID OBJECT_NAME
---------- -------------- --------------------------------------------------------
    136026         136027 PYGC

SQL> 

5、再做一次段头块dump

SQL> alter system dump datafile 15 block 130;

System altered.

SQL> select value from v$diag_info where name = 'Default Trace File';

VALUE
--------------------------------------------------------------------------------
/u01/app/diag/rdbms/qxy/QXY/trace/QXY_ora_4925.trc

SQL> 


buffer tsn: 17 rdba: 0x03c00082 (15/130)
scn: 0x0000.0225a8a2 seq: 0x01 flg: 0x04 tail: 0xa8a22301
frmt: 0x02 chkval: 0x8c34 type: 0x23=PAGETABLE SEGMENT HEADER
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x00007FC77D732A00 to 0x00007FC77D734A00
7FC77D732A00 0000A223 03C00082 0225A8A2 04010000  [#.........%.....]
7FC77D732A10 00008C34 00000000 00000000 00000000  [4...............]
7FC77D732A20 00000000 00000001 00000008 00000A9C  [................]
7FC77D732A30 00000000 00000003 00000008 03C00083  [................]
7FC77D732A40 00000000 00000000 00000000 00000000  [................]
7FC77D732A50 0014001B 000036CD 00000001 00000000  [.....6..........]
7FC77D732A60 00000003 00000008 03C00083 00000000  [................]
7FC77D732A70 00000000 00000000 00000000 03C00080  [................]
7FC77D732A80 03C00080 00000000 00000000 00000000  [................]
7FC77D732A90 00000000 00000000 00000000 00000000  [................]
        Repeat 3 times
7FC77D732AD0 00000001 00002000 00000000 00001434  [..... ......4...]
7FC77D732AE0 00000000 03C00081 00000001 03C00080  [................]
7FC77D732AF0 03C00081 00000000 00000000 00000000  [................]
7FC77D732B00 00000000 00000000 00000001 00000000  [................]
7FC77D732B10 0002135B 10000000 03C00080 00000008  [[...............]
7FC77D732B20 00000000 00000000 00000000 00000000  [................]
        Repeat 152 times
7FC77D7334B0 03C00080 03C00083 00000000 00000000  [................]
7FC77D7334C0 00000000 00000000 00000000 00000000  [................]
        Repeat 151 times
7FC77D733E40 00000000 00000000 03C00081 00000000  [................]
7FC77D733E50 00000000 00000000 00000000 00000000  [................]
        Repeat 185 times
7FC77D7349F0 00000000 00000000 00000000 A8A22301  [.............#..]
  Extent Control Header
  -----------------------------------------------------------------
  Extent Header:: spare1: 0      spare2: 0      #extents: 1      #blocks: 8
                  last map  0x00000000  #maps: 0      offset: 2716
      Highwater::  0x03c00083  ext#: 0      blk#: 3      ext size: 8 <===和truncate之前对比发现,高水位发生了变化
  #blocks in seg. hdr's freelists: 0
  #blocks below: 0
  mapblk  0x00000000  offset: 0
      Disk Lock:: Locked by xid:  0x001b.014.000036cd
  --------------------------------------------------------
  Low HighWater Mark :
      Highwater::  0x03c00083  ext#: 0      blk#: 3      ext size: 8  
  #blocks in seg. hdr's freelists: 0
  #blocks below: 0
  mapblk  0x00000000  offset: 0
  Level 1 BMB for High HWM block: 0x03c00080
  Level 1 BMB for Low HWM block: 0x03c00080
  --------------------------------------------------------
  Segment Type: 1 nl2: 1      blksz: 8192   fbsz: 0
  L2 Array start offset:  0x00001434
  First Level 3 BMB:  0x00000000
  L2 Hint for inserts:  0x03c00081
  Last Level 1 BMB:  0x03c00080
  Last Level II BMB:  0x03c00081
  Last Level III BMB:  0x00000000
     Map Header:: next  0x00000000  #extents: 1    obj#: 136027 flag: 0x10000000
  Inc # 0
  Extent Map
  -----------------------------------------------------------------
   0x03c00080  length: 8

  Auxillary Map
  --------------------------------------------------------
   Extent 0     :  L1 dba:  0x03c00080 Data dba:  0x03c00083
  --------------------------------------------------------

   Second Level Bitmap block DBAs
   --------------------------------------------------------
   DBA 1:   0x03c00081

End dump data blocks tsn: 17 file#: 15 minblk 130 maxblk 130

可以发现truncate前后,高位数的数据发生了变化,offset 272位置标记object_id的值从原来的136026(0002135A)变成了136027(0002135B ), truncate之前的高水位的地址为0x03c00088,并且高水位在0号区的第8个块的位置。
  truncate之后高水位的地址为0x03c00083,并且高水位在0号区的第3个块上面。

6、truncate之后做数据块的dump

SQL> alter system dump datafile 15 block 134;

System altered.

SQL> select value from v$diag_info where name = 'Default Trace File';

VALUE
--------------------------------------------------------------------------------
/u01/app/diag/rdbms/qxy/QXY/trace/QXY_ora_4951.trc

SQL> 

buffer tsn: 17 rdba: 0x03c00086 (15/134)
scn: 0x0000.0225a6ce seq: 0x01 flg: 0x06 tail: 0xa6ce0601
frmt: 0x02 chkval: 0x8361 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x00007FCD7A101A00 to 0x00007FCD7A103A00
7FCD7A101A00 0000A206 03C00086 0225A6CE 06010000  [..........%.....]
7FCD7A101A10 00008361 00000001 0002135A 0225A6CB  [a.......Z.....%.]
7FCD7A101A20 00000000 0032F802 03C00080 00010017  [......2.........]
7FCD7A101A30 00002CD0 04C023C2 00060593 00002002  [.,...#....... ..]
7FCD7A101A40 0225A6CE 00000000 00000000 00000000  [..%.............]
7FCD7A101A50 00000000 00000000 00000000 00000000  [................]
7FCD7A101A60 00000000 00020100 0016FFFF 1F701F8C  [..............p.]
7FCD7A101A70 00001F70 1F920002 00001F8C 00000000  [p...............]
7FCD7A101A80 00000000 00000000 00000000 00000000  [................]
        Repeat 502 times
7FCD7A1039F0 0201012C 012C0CC1 0BC10201 A6CE0601  [,.....,.........]
Block header dump:  0x03c00086
 Object id on Block? Y
 seg/obj: 0x2135a  csc: 0x00.225a6cb  itc: 2  flg: E  typ: 1 - DATA
     brn: 0  bdba: 0x3c00080 ver: 0x01 opc: 0
     inc: 0  exflg: 0

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0017.001.00002cd0  0x04c023c2.0593.06  --U-    2  fsc 0x0000.0225a6ce
0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
bdba: 0x03c00086
data_block_dump,data header at 0x7fcd7a101a64
===============
tsiz: 0x1f98
hsiz: 0x16
pbl: 0x7fcd7a101a64
     76543210
flag=--------
ntab=1
nrow=2
frre=-1
fsbo=0x16
fseo=0x1f8c
avsp=0x1f70
tosp=0x1f70
0xe:pti[0]      nrow=2  offs=0
0x12:pri[0]     offs=0x1f92
0x14:pri[1]     offs=0x1f8c
block_row_dump:
tab 0, row 0, @0x1f92
tl: 6 fb: --H-FL-- lb: 0x1  cc: 1
col  0: [ 2]  c1 0b
tab 0, row 1, @0x1f8c
tl: 6 fb: --H-FL-- lb: 0x1  cc: 1
col  0: [ 2]  c1 0c
end_of_block_dump
End dump data blocks tsn: 17 file#: 15 minblk 134 maxblk 134

truncate前后,数据块中的数据还是两行,可以理解为数据并没有被删除。(这个时候这个数据块是可以被覆盖的,因为当前块已经不属于任意段头块中的区范围)

7、修改obj$

SQL> desc obj$
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 OBJ#                                      NOT NULL NUMBER
 DATAOBJ#                                           NUMBER
 OWNER#                                    NOT NULL NUMBER
 NAME                                      NOT NULL VARCHAR2(30)
 NAMESPACE                                 NOT NULL NUMBER
 SUBNAME                                            VARCHAR2(30)
 TYPE#                                     NOT NULL NUMBER
 CTIME                                     NOT NULL DATE
 MTIME                                     NOT NULL DATE
 STIME                                     NOT NULL DATE
 STATUS                                    NOT NULL NUMBER
 REMOTEOWNER                                        VARCHAR2(30)
 LINKNAME                                           VARCHAR2(128)
 FLAGS                                              NUMBER
 OID$                                               RAW(16)
 SPARE1                                             NUMBER
 SPARE2                                             NUMBER
 SPARE3                                             NUMBER
 SPARE4                                             VARCHAR2(1000)
 SPARE5                                             VARCHAR2(1000)
 SPARE6                                             DATE


SQL> select obj#,DATAOBJ#,NAME from obj$ where obj#=136026;

      OBJ#   DATAOBJ# NAME
---------- ---------- ------------------------------
    136026     136027 PYGC

SQL> 

和dba_objects视图查到的结果一致
SQL> select object_id, data_object_id, object_name from dba_objects where object_name='PYGC';

 OBJECT_ID DATA_OBJECT_ID OBJECT_NAME
---------- -------------- -----------------------------------------------------------------
    136026         136027 PYGC

SQL> 

SQL> select dbms_rowid.ROWID_RELATIVE_FNO(rowid), dbms_rowid.ROWID_BLOCK_NUMBER(rowid) from obj$ where obj#=136026;

DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------------------------ ------------------------------------
                                   1                                82466
                                   
SQL> alter system dump datafile 1 block 82466;

System altered.

SQL> select value from v$diag_info where name = 'Default Trace File';

VALUE
--------------------------------------------------------------------------------
/u01/app/diag/rdbms/qxy/QXY/trace/QXY_ora_4996.trc

SQL> 

把OBJECT_ID=136026转换成raw格式,然后在82466块的trace中查询位置

SQL> select utl_raw.CAST_FROM_NUMBER(136026) from dual;

UTL_RAW.CAST_FROM_NUMBER(136026)
--------------------------------------------------------------------------------
C30E3D1B

SQL> 

SQL> select utl_raw.CAST_FROM_NUMBER(136027) from dual;

UTL_RAW.CAST_FROM_NUMBER(136027)
--------------------------------------------------------------------------------
C30E3D1C

SQL> 

即136026 = c3 0e 3d 1b
  136027 = c3 0e 3d 1c

在文件/u01/app/diag/rdbms/qxy/QXY/trace/QXY_ora_4996.trc中查询对应的数据在row=69(这个数据和obj$对应)
tab 0, row 69, @0x424
tl: 67 fb: --H-FL-- lb: 0x1  cc: 18
col  0: [ 4]  c3 0e 3d 1b           <===obj#
col  1: [ 4]  c3 0e 3d 1c           <===dataobj#
col  2: [ 1]  80
col  3: [ 4]  50 59 47 43           <===name
col  4: [ 2]  c1 02
col  5: *NULL*
col  6: [ 2]  c1 03
col  7: [ 7]  78 77 06 0a 10 12 26
col  8: [ 7]  78 77 06 0a 10 24 25
col  9: [ 7]  78 77 06 0a 10 12 26
col 10: [ 2]  c1 02
col 11: *NULL*
col 12: *NULL*
col 13: [ 1]  80
col 14: *NULL*
col 15: [ 2]  c1 07
col 16: [ 2]  c1 02
col 17: [ 1]  80

把name=50 59 47 43 转换成varchar2

SQL> select displayraw('50594743','VARCHAR2') from dual;

DISPLAY_RAW('50594743','VARCHAR2')
--------------------------------------------------------------------------------
PYGC

SQL> 

现在就用bbed,把dataobj#=136027 改成 136026

BBED> info all
 File#  Name                                                        Size(blks)
 -----  ----                                                        ----------
     1  /u01/app/oradata/QXY/system01.dbf                                    0
     2  /u01/app/oradata/QXY/sysaux01.dbf                                    0
     3  /u01/app/oradata/QXY/untbs1.dbf                                      0
     4  /u01/app/oradata/QXY/users01.dbf                                     0
     5  /u01/app/oradata/QXY/example01.dbf                                   0
     6  /u01/app/oradata/QXY/OGG.dbf                                         0
     7  /u01/app/oradata/test.dbf                                            0
     8  /u01/app/oradata/QXY/corrupt.dbf                                     0
     9  /u01/app/oradata/QXY/utb1.dbf                                        0
    10  /u01/app/oradata/QXY/undotbs03.dbf                                   0
    11  /u01/app/oradata/QXY/streams_tbs01.dbf                               0
    12  /u01/app/oradata/QXY/chenhao01.dbf                                   0
    13  /u01/app/oradata/QXY/t.dbf                                           0
    14  /u01/app/oradata/QXY/xxx.dbf                                         0
    15  /u01/app/oradata/QXY/py.dbf                                          0

BBED> 
BBED> set dba 1,82466
        DBA             0x00414222 (4276770 1,82466)

BBED> map 
 File: /u01/app/oradata/QXY/system01.dbf (1)
 Block: 82466                                 Dba:0x00414222
------------------------------------------------------------
 KTB Data Block (Table/Cluster)

 struct kcbh, 20 bytes                      @0       

 struct ktbbh, 72 bytes                     @20      

 struct kdbh, 14 bytes                      @92      

 struct kdbt[1], 4 bytes                    @106     

 sb2 kdbr[72]                               @110     

 ub1 freespace[898]                         @254     

 ub1 rowdata[7036]                          @1152    

 ub4 tailchk                                @8188    


BBED> p *kdbr[69]   <======从dump中可以知道在row=69
rowdata[0]
----------
ub1 rowdata[0]                              @1152     0x2c

BBED> 


BBED> d
 File: /u01/app/oradata/QXY/system01.dbf (1)
 Block: 82466            Offsets: 1152 to 1663           Dba:0x00414222
------------------------------------------------------------------------
 2c011204 c30e3d1b 04c30e3d 1c018004 50594743 02c102ff 02c10307 7877060a 
 10122607 7877060a 10242507 7877060a 10122602 c102ffff 0180ff02 c10702c1 
 0201802c 001204c3 0e3d1804 c30e3d18 01800358 414202c1 02ff02c1 03077877 
 060a0c20 25077877 060a0c20 25077877 060a0c20 2502c102 ffff0180 ff02c107 
 02c10201 803c0112 04c30e3d 1604c30e 3d170180 014302c1 02ff02c1 03077877 
 060a0b1c 3b077877 060a0b1f 2e077877 060a0b1c 3b02c102 ffff0180 ff02c107 
 02c10201 803c0112 04c30e3d 1404c30e 3d150180 014302c1 02ff02c1 03077877 
 060a0b17 01077877 060a0b1a 26077877 060a0b17 0102c102 ffff0180 ff02c107 
 02c10201 803c0212 04c30e3d 1304c30e 3d130180 014302c1 02ff02c1 03077877 
 060a0b16 2b077877 060a0b16 2b077877 060a0b16 2b02c102 ffff0180 ff02c107 
 02c10201 803c0212 04c30e3d 0f04c30e 3d120180 04414243 4402c102 ff02c103 
 07787706 0a071c08 07787706 0a0b102b 07787706 0a071c08 02c102ff ff0180ff 
 02c10702 c1020180 3c021204 c30e3d0e 04c30e3d 0e018004 41424344 02c102ff 
 02c10307 7877060a 05051507 7877060a 05051507 7877060a 05051502 c102ffff 
 0180ff02 c10702c1 0201803c 011204c3 0e3d0804 c30e3d09 01800642 4c4f434b 
 3302c102 ff02c103 07787706 060a3927 07787706 060a3a37 07787706 060a3927 

 <32 bytes per line>

BBED> 
现在把c30e3d1c改成c30e3d1b

BBED> set offset +12
        OFFSET          1164

BBED> d
 File: /u01/app/oradata/QXY/system01.dbf (1)
 Block: 82466            Offsets: 1164 to 1675           Dba:0x00414222
------------------------------------------------------------------------
 1c018004 50594743 02c102ff 02c10307 7877060a 10122607 7877060a 10242507 
 7877060a 10122602 c102ffff 0180ff02 c10702c1 0201802c 001204c3 0e3d1804 
 c30e3d18 01800358 414202c1 02ff02c1 03077877 060a0c20 25077877 060a0c20 
 25077877 060a0c20 2502c102 ffff0180 ff02c107 02c10201 803c0112 04c30e3d 
 1604c30e 3d170180 014302c1 02ff02c1 03077877 060a0b1c 3b077877 060a0b1f 
 2e077877 060a0b1c 3b02c102 ffff0180 ff02c107 02c10201 803c0112 04c30e3d 
 1404c30e 3d150180 014302c1 02ff02c1 03077877 060a0b17 01077877 060a0b1a 
 26077877 060a0b17 0102c102 ffff0180 ff02c107 02c10201 803c0212 04c30e3d 
 1304c30e 3d130180 014302c1 02ff02c1 03077877 060a0b16 2b077877 060a0b16 
 2b077877 060a0b16 2b02c102 ffff0180 ff02c107 02c10201 803c0212 04c30e3d 
 0f04c30e 3d120180 04414243 4402c102 ff02c103 07787706 0a071c08 07787706 
 0a0b102b 07787706 0a071c08 02c102ff ff0180ff 02c10702 c1020180 3c021204 
 c30e3d0e 04c30e3d 0e018004 41424344 02c102ff 02c10307 7877060a 05051507 
 7877060a 05051507 7877060a 05051502 c102ffff 0180ff02 c10702c1 0201803c 
 011204c3 0e3d0804 c30e3d09 01800642 4c4f434b 3302c102 ff02c103 07787706 
 060a3927 07787706 060a3a37 07787706 060a3927 02c102ff ff0180ff 02c10702 

 <32 bytes per line>

BBED> m /x 1b
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
 File: /u01/app/oradata/QXY/system01.dbf (1)
 Block: 82466            Offsets: 1164 to 1675           Dba:0x00414222
------------------------------------------------------------------------
 1b018004 50594743 02c102ff 02c10307 7877060a 10122607 7877060a 10242507 
 7877060a 10122602 c102ffff 0180ff02 c10702c1 0201802c 001204c3 0e3d1804 
 c30e3d18 01800358 414202c1 02ff02c1 03077877 060a0c20 25077877 060a0c20 
 25077877 060a0c20 2502c102 ffff0180 ff02c107 02c10201 803c0112 04c30e3d 
 1604c30e 3d170180 014302c1 02ff02c1 03077877 060a0b1c 3b077877 060a0b1f 
 2e077877 060a0b1c 3b02c102 ffff0180 ff02c107 02c10201 803c0112 04c30e3d 
 1404c30e 3d150180 014302c1 02ff02c1 03077877 060a0b17 01077877 060a0b1a 
 26077877 060a0b17 0102c102 ffff0180 ff02c107 02c10201 803c0212 04c30e3d 
 1304c30e 3d130180 014302c1 02ff02c1 03077877 060a0b16 2b077877 060a0b16 
 2b077877 060a0b16 2b02c102 ffff0180 ff02c107 02c10201 803c0212 04c30e3d 
 0f04c30e 3d120180 04414243 4402c102 ff02c103 07787706 0a071c08 07787706 
 0a0b102b 07787706 0a071c08 02c102ff ff0180ff 02c10702 c1020180 3c021204 
 c30e3d0e 04c30e3d 0e018004 41424344 02c102ff 02c10307 7877060a 05051507 
 7877060a 05051507 7877060a 05051502 c102ffff 0180ff02 c10702c1 0201803c 
 011204c3 0e3d0804 c30e3d09 01800642 4c4f434b 3302c102 ff02c103 07787706 
 060a3927 07787706 060a3a37 07787706 060a3927 02c102ff ff0180ff 02c10702 

 <32 bytes per line>

BBED> sum apply
Check value for File 1, Block 82466:
current = 0xa9ac, required = 0xa9ac

BBED> verify
DBVERIFY - Verification starting
FILE = /u01/app/oradata/QXY/system01.dbf
BLOCK = 82466


DBVERIFY - Verification complete

Total Blocks Examined         : 1
Total Blocks Processed (Data) : 1
Total Blocks Failing   (Data) : 0
Total Blocks Processed (Index): 0
Total Blocks Failing   (Index): 0
Total Blocks Empty            : 0
Total Blocks Marked Corrupt   : 0
Total Blocks Influx           : 0
Message 531 not found;  product=RDBMS; facility=BBED


BBED> 



SQL> alter system flush buffer_cache;

System altered.

SQL> alter system flush shared_pool;

System altered.

SQL> select obj#,DATAOBJ#,NAME from obj$ where obj#=136026;

      OBJ#   DATAOBJ# NAME
---------- ---------- ------------------------------
    136026     136026 PYGC

SQL> select object_id, data_object_id, object_name from dba_objects where object_name='PYGC';

 OBJECT_ID    DATA_OBJECT_ID     OBJECT_NAME
-----------  ---------------- ----------------------
    136026         136026      PYGC


SQL> select count(*) from pygc;  <====但是这个时候查询会报ORA-08103的错误,如下:
select count(*) from pygc
                     *
ERROR at line 1:
ORA-08103: object no longer exists


SQL> 
SQL> 

8、修改tab$

表结构如下:

SQL> 
SQL> desc tab$
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 OBJ#                                      NOT NULL NUMBER
 DATAOBJ#                                           NUMBER
 TS#                                       NOT NULL NUMBER
 FILE#                                     NOT NULL NUMBER
 BLOCK#                                    NOT NULL NUMBER
 BOBJ#                                              NUMBER
 TAB#                                               NUMBER
 COLS                                      NOT NULL NUMBER
 CLUCOLS                                            NUMBER
 PCTFREE$                                  NOT NULL NUMBER
 PCTUSED$                                  NOT NULL NUMBER
 INITRANS                                  NOT NULL NUMBER
 MAXTRANS                                  NOT NULL NUMBER
 FLAGS                                     NOT NULL NUMBER
 AUDIT$                                    NOT NULL VARCHAR2(38)
 ROWCNT                                             NUMBER
 BLKCNT                                             NUMBER
 EMPCNT                                             NUMBER
 AVGSPC                                             NUMBER
 CHNCNT                                             NUMBER
 AVGRLN                                             NUMBER
 AVGSPC_FLB                                         NUMBER
 FLBCNT                                             NUMBER
 ANALYZETIME                                        DATE
 SAMPLESIZE                                         NUMBER
 DEGREE                                             NUMBER
 INSTANCES                                          NUMBER
 INTCOLS                                   NOT NULL NUMBER
 KERNELCOLS                                NOT NULL NUMBER
 PROPERTY                                  NOT NULL NUMBER
 TRIGFLAG                                           NUMBER
 SPARE1                                             NUMBER
 SPARE2                                             NUMBER
 SPARE3                                             NUMBER
 SPARE4                                             VARCHAR2(1000)
 SPARE5                                             VARCHAR2(1000)
 SPARE6                                             DATE

SQL> 

查询对象dataobj#=136027在tab$表中的位置

SQL> 
SQL> select dbms_rowid.ROWID_RELATIVE_FNO(rowid), dbms_rowid.ROWID_BLOCK_NUMBER(rowid) from tab$ where obj#=136026;

DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------------------------ ------------------------------------
                                   1                                90285

SQL> 
SQL> alter system dump datafile 1 block 90285;

System altered.

SQL> select value from v$diag_info where name = 'Default Trace File';

VALUE
--------------------------------------------------------------------------------
/u01/app/diag/rdbms/qxy/QXY/trace/QXY_ora_5076.trc

SQL> 

tab 1, row 1, @0x1a25
tl: 123 fb: -CH-FL-- lb: 0x2  cc: 36 cki: 1
col  0: [ 4]  c3 0e 3d 1c                   <======DATAOBJ# 转换成数字 136027
col  1: [ 2]  c1 12
col  2: [ 2]  c1 10
col  3: [ 3]  c2 02 1f
col  4: *NULL*
col  5: *NULL*
col  6: [ 2]  c1 02
col  7: *NULL*
col  8: [ 2]  c1 0b
col  9: [ 2]  c1 29
col 10: [ 2]  c1 02
col 11: [ 3]  c2 03 38
col 12: [ 2]  c1 02
col 13: [38]
 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d
 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d
col 14: *NULL*
col 15: *NULL*
col 16: *NULL*
col 17: *NULL*
col 18: *NULL*
col 19: *NULL*
col 20: *NULL*
col 21: *NULL*
col 22: *NULL*
col 23: *NULL*
col 24: *NULL*
col 25: *NULL*
col 26: [ 2]  c1 02
col 27: [ 2]  c1 02
col 28: [ 6]  c5 06 25 58 0a 0d
col 29: [ 1]  80
col 30: [ 3]  c2 08 25
col 31: *NULL*
col 32: *NULL*
col 33: *NULL*
col 34: *NULL*
col 35: [ 7]  78 77 06 0a 08 24 24

8、使用bbed把136027 修改成136026, 也就是把c3 0e 3d 1c 修改成c3 0e 3d 1b

BBED> d
 File: /u01/app/oradata/QXY/system01.dbf (1)
 Block: 90285            Offsets: 6790 to 7301           Dba:0x004160ad
------------------------------------------------------------------------
 c30e3d1c 02c11202 c11003c2 021fffff 02c102ff 02c10b02 c12902c1 0203c203 
 3802c102 262d2d2d 2d2d2d2d 2d2d2d2d 2d2d2d2d 2d2d2d2d 2d2d2d2d 2d2d2d2d 
 2d2d2d2d 2d2d2d2d 2d2d2dff ffffffff ffffffff ffffff02 c10202c1 0206c506 
 25580a0d 018003c2 0825ffff ffff0778 77060a08 2424ac00 01020002 00004160 
 ad000100 4160ad00 0104c30e 3d1b6c00 140002c1 1602c116 02c10801 80065350 
 41524536 02c10d02 c1080180 ffff0180 ffff02c1 16018001 80018001 80018001 
 806c0014 0002c115 02c11502 c20b0180 06535041 52453502 c10202c2 0b0180ff 
 ff0180ff ff02c115 018003c2 093502c1 02018001 8002c20b 6c001400 02c11402 
 c11402c2 0b018006 53504152 453402c1 0202c20b 0180ffff 0180ffff 02c11401 
 8003c209 3502c102 01800180 02c20b6c 00140002 c11302c1 1302c117 01800653 
 50415245 3302c103 02c11701 80ffff01 80ffff02 c1130180 01800180 01800180 
 01806c00 140002c1 1202c112 02c11701 80065350 41524532 02c10302 c1170180 
 ffff0180 ffff02c1 12018001 80018001 80018001 806c0014 0002c111 02c11102 
 c1170180 06535041 52453102 c10302c1 170180ff ff0180ff ff02c111 01800180 
 01800180 01800180 6c001400 02c11002 c11002c1 11018004 4f494424 02c11802 
 c1110180 ffff0180 ffff02c1 10018001 80018001 80018001 806c0014 0002c10f 

 <32 bytes per line>

BBED> set offset +3
        OFFSET          6793

BBED> m /x 1b
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
 File: /u01/app/oradata/QXY/system01.dbf (1)
 Block: 90285            Offsets: 6793 to 7304           Dba:0x004160ad
------------------------------------------------------------------------
 1b02c112 02c11003 c2021fff ff02c102 ff02c10b 02c12902 c10203c2 033802c1 
 02262d2d 2d2d2d2d 2d2d2d2d 2d2d2d2d 2d2d2d2d 2d2d2d2d 2d2d2d2d 2d2d2d2d 
 2d2d2d2d 2d2d2d2d ffffffff ffffffff ffffffff 02c10202 c10206c5 0625580a 
 0d018003 c20825ff ffffff07 7877060a 082424ac 00010200 02000041 60ad0001 
 004160ad 000104c3 0e3d1b6c 00140002 c11602c1 1602c108 01800653 50415245 
 3602c10d 02c10801 80ffff01 80ffff02 c1160180 01800180 01800180 01806c00 
 140002c1 1502c115 02c20b01 80065350 41524535 02c10202 c20b0180 ffff0180 
 ffff02c1 15018003 c2093502 c1020180 018002c2 0b6c0014 0002c114 02c11402 
 c20b0180 06535041 52453402 c10202c2 0b0180ff ff0180ff ff02c114 018003c2 
 093502c1 02018001 8002c20b 6c001400 02c11302 c11302c1 17018006 53504152 
 453302c1 0302c117 0180ffff 0180ffff 02c11301 80018001 80018001 8001806c 
 00140002 c11202c1 1202c117 01800653 50415245 3202c103 02c11701 80ffff01 
 80ffff02 c1120180 01800180 01800180 01806c00 140002c1 1102c111 02c11701 
 80065350 41524531 02c10302 c1170180 ffff0180 ffff02c1 11018001 80018001 
 80018001 806c0014 0002c110 02c11002 c1110180 044f4944 2402c118 02c11101 
 80ffff01 80ffff02 c1100180 01800180 01800180 01806c00 140002c1 0f02c10f 

 <32 bytes per line>

BBED> 
BBED> 
BBED> sum apply;
Check value for File 1, Block 90285:
current = 0xb3b5, required = 0xb3b5

BBED> 

再次查询dba_object视图

SQL> select obj#, dataobj# from tab$ where obj#=136026;

      OBJ#   DATAOBJ#
---------- ----------
    136026     136027

SQL> alter system flush buffer_cache;

System altered.

SQL> alter system flush shared_pool;

System altered.

SQL> select obj#, dataobj# from tab$ where obj#=136026;

      OBJ#   DATAOBJ#
---------- ----------
    136026     136026

SQL> 

可以看到dataobj#的值已经从原来的136027变成了136026。但是查询PYGC还是会报ORA-08103的错误。

SQL> alter system flush buffer_cache;

System altered.

SQL> alter system flush shared_pool;

System altered.

SQL> select obj#, dataobj# from tab$ where obj#=136026;

      OBJ#   DATAOBJ#
---------- ----------
    136026     136026

SQL> 



SQL> select * from pygc;
select * from pygc
              *
ERROR at line 1:
ORA-08103: object no longer exists

9、修改段头块中的object_id的值,把136027改为136026

修改pygc表的段头信息,在偏移量272的位置是objectid
SQL> col segment_name for a20
SQL> select SEGMENT_NAME,HEADER_FILE,HEADER_BLOCK from dba_segments where segment_name = 'PYGC';

SEGMENT_NAME         HEADER_FILE HEADER_BLOCK
-------------------- ----------- ------------
PYGC                          15          130

BBED> set dba 15,130
        DBA             0x03c00082 (62914690 15,130)

BBED> set offset 272
        OFFSET          272

BBED> d
 File: /u01/app/oradata/QXY/py.dbf (15)
 Block: 130              Offsets:  272 to  783           Dba:0x03c00082
------------------------------------------------------------------------
 5b130200 00000010 8000c003 08000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 
 
 136026转换成10进制是2135A
 
 SQL> select to_char(136026,'xxxxxxxx') from dual;

TO_CHAR(1
---------
    2135a

SQL>

现在只需把5b改成5a,也就是把136027改成136026

BBED> m /x 5a
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
 File: /u01/app/oradata/QXY/py.dbf (15)
 Block: 130              Offsets:  272 to  783           Dba:0x03c00082
------------------------------------------------------------------------
 5a130200 00000010 8000c003 08000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 

 <32 bytes per line>

BBED> sum apply;
Check value for File 15, Block 130:
current = 0xbaf6, required = 0xbaf6

BBED> 



SQL> alter system flush shared_pool;

System altered.

SQL> select * from pygc;   <=======查询已经没有报错,但是查询结果没有值。

no rows selected

SQL> 

可以看到,这个时候查询PYGC已经不报错了,但是没有值,没有值的原因是段头块中的高水位被修改了。表的数据被屏蔽在了高水位之上,所以查询表得不到任何数据,就把高水位改成truncate之前的。

truncate前后高水位的信息

truncate之前的高水位
  Extent Header:: spare1: 0      spare2: 0      #extents: 1      #blocks: 8
                  last map  0x00000000  #maps: 0      offset: 2716
      Highwater::  0x03c00088  ext#: 0      blk#: 8      ext size: 8
  #blocks in seg. hdr's freelists: 0
  #blocks below: 5
  mapblk  0x00000000  offset: 0
                     Unlocked
    --------------------------------------------------------
  Low HighWater Mark :
      Highwater::  0x03c00088  ext#: 0      blk#: 8      ext size: 8
  #blocks in seg. hdr's freelists: 0
  #blocks below: 5
  mapblk  0x00000000  offset: 0
  Level 1 BMB for High HWM block: 0x03c00080
  Level 1 BMB for Low HWM block: 0x03c00080
  
truncate之后的高水位信息
 Extent Header:: spare1: 0      spare2: 0      #extents: 1      #blocks: 8
                  last map  0x00000000  #maps: 0      offset: 2716
      Highwater::  0x03c00083  ext#: 0      blk#: 3      ext size: 8
  #blocks in seg. hdr's freelists: 0
  #blocks below: 0
  mapblk  0x00000000  offset: 0
      Disk Lock:: Locked by xid:  0x001b.014.000036cd
  --------------------------------------------------------
  Low HighWater Mark :
      Highwater::  0x03c00083  ext#: 0      blk#: 3      ext size: 8
  #blocks in seg. hdr's freelists: 0
  #blocks below: 0
  mapblk  0x00000000  offset: 0
  Level 1 BMB for High HWM block: 0x03c00080
  Level 1 BMB for Low HWM block: 0x03c00080
  
  可以看到truncate之前的高水位的地址为0x03c00088,并且高水位在0号区的第8个块的位置。
  truncate之后高水位的地址为0x03c00083,并且高水位在0号区的第3个块上面。

    这里是因为truncate前后都dump了段头块的信息,现实中根本不会有这样的机会的。 但是可以通过redo来查看truncate前后的信息,方法如下:

SQL> alter system dump logfile '/u01/app/oradata/QXY/redo02.log';

System altered.

SQL>  select value from v$diag_info where name = 'Default Trace File';

VALUE
--------------------------------------------------------------------------------
/u01/app/diag/rdbms/qxy/QXY/trace/QXY_ora_5936.trc

SQL> 


REDO RECORD - Thread:1 RBA: 0x00015d.0000000f.0110 LEN: 0x01b8 VLD: 0x01
SCN: 0x0000.0225a89c SUBSCN:  6 06/10/2019 15:35:36
CHANGE #1 TYP:0 CLS:70 AFN:19 DBA:0x04c01287 OBJ:4294967295 SCN:0x0000.0225a89c SEQ:2 OP:5.1 ENC:0 RBL:0
ktudb redo: siz: 164 spc: 7536 flg: 0x0022 seq: 0x0611 rec: 0x06
            xid:  0x001b.014.000036cd
ktubu redo: slt: 20 rci: 5 opc: 13.29 objn: 136026 objd: 136026 tsn: 17   
Undo type:  Regular undo       Undo type:  Last buffer split:  No
Tablespace Undo:  No
             0x00000000
Segment Header Undo
Seghdr dba:  0x03c00082 Mapblock dba:  0x00000000 Mapredo Offset: 4 scls: 4 mcls: 140668768878599
Both the HWMs
Low HWM
      Highwater::  0x03c00088  ext#: 0      blk#: 8      ext size: 8   <=====高水位信息,包含地址、高水位所在的区、块、区包含的块
  #blocks in seg. hdr's freelists: 0
  #blocks below: 5                                                     <=====高水位下面包含5个块
  mapblk  0x00000000  offset: 0
lfdba:  0x03c00080
High HWM
      Highwater::  0x03c00088  ext#: 0      blk#: 8      ext size: 8
  #blocks in seg. hdr's freelists: 0
  #blocks below: 5
  mapblk  0x00000000  offset: 0
lfdba:  0x03c00080 hint dba:  0x03c00081
Lasts in Header
LF: 62914688 LS: 62914689 LT: 0 FT: 0
CHANGE #2 TYP:0 CLS:4 AFN:15 DBA:0x03c00082 OBJ:136026 SCN:0x0000.0225a89c SEQ:1 OP:13.28 ENC:0 RBL:0  <====truncate操作
Both the HWMs
Low HWM
      Highwater::  0x03c00083  ext#: 0      blk#: 3      ext size: 8  <====truncate之后的高水位信息
  #blocks in seg. hdr's freelists: 0
  #blocks below: 0
  mapblk  0x00000000  offset: 0
lfdba:  0x03c00080
High HWM
      Highwater::  0x03c00083  ext#: 0      blk#: 3      ext size: 8
  #blocks in seg. hdr's freelists: 0
  #blocks below: 0
  mapblk  0x00000000  offset: 0
lfdba:  0x03c00080 hint dba:  0x03c00081
Lasts in Header
LF: 62914688 LS: 62914689 LT: 0 FT: 0
CHANGE #3 TYP:0 CLS:8 AFN:15 DBA:0x03c00080 OBJ:136026 SCN:0x0000.0225a89c SEQ:2 OP:13.22 ENC:0 RBL:0
Redo on Level1 Bitmap Block
Redo to set hwm
Opcode: 32      Highwater::  0x03c00083  ext#: 0      blk#: 3      ext size: 8
  #blocks in seg. hdr's freelists: 0
  #blocks below: 0
  mapblk  0x00000000  offset: 0

dump logfile得到的数据和dump 段头块的高水位数据一致。

10、使用bbed修改段头块中的高水位信息

BBED> set dba 15,130 
        DBA             0x03c00082 (62914690 15,130)

BBED> set offset 52 
        OFFSET          52

BBED> d /v count 16
 File: /u01/app/oradata/QXY/py.dbf (15)
 Block: 130     Offsets:   52 to   67  Dba:0x03c00082
-------------------------------------------------------
 03000000 08000000 8300c003 00000000 l ................

 <16 bytes per line>

BBED> m /x 08       <======把高水所在0号区的块从3改成8
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
 File: /u01/app/oradata/QXY/py.dbf (15)
 Block: 130              Offsets:   52 to   67           Dba:0x03c00082
------------------------------------------------------------------------
 08000000 08000000 8300c003 00000000 

 <32 bytes per line>

BBED> 
  
  
BBED> d /v count 16
 File: /u01/app/oradata/QXY/py.dbf (15)
 Block: 130     Offsets:   60 to   75  Dba:0x03c00082
-------------------------------------------------------
 8300c003 00000000 00000000 00000000 l ................

 <16 bytes per line>

BBED> m /x 88      <======0x03c00083改成0x03c00088
 File: /u01/app/oradata/QXY/py.dbf (15)
 Block: 130              Offsets:   60 to   75           Dba:0x03c00082
------------------------------------------------------------------------
 8800c003 00000000 00000000 00000000 

 <32 bytes per line>

BBED> 



<====同样的道理,修改Low HighWater Mark的值

BBED> set offset 96
        OFFSET          96

BBED> d 
 File: /u01/app/oradata/QXY/py.dbf (15)
 Block: 130              Offsets:   96 to  111           Dba:0x03c00082
------------------------------------------------------------------------
 03000000 08000000 8300c003 00000000 

 <32 bytes per line>

BBED> m /x 08
 File: /u01/app/oradata/QXY/py.dbf (15)
 Block: 130              Offsets:   96 to  111           Dba:0x03c00082
------------------------------------------------------------------------
 08000000 08000000 8300c003 00000000 

 <32 bytes per line>

BBED> set offset +8
        OFFSET          104

BBED> d
 File: /u01/app/oradata/QXY/py.dbf (15)
 Block: 130              Offsets:  104 to  119           Dba:0x03c00082
------------------------------------------------------------------------
 8300c003 00000000 00000000 00000000 

 <32 bytes per line>

BBED> m /x 88
 File: /u01/app/oradata/QXY/py.dbf (15)
 Block: 130              Offsets:  104 to  119           Dba:0x03c00082
------------------------------------------------------------------------
 8800c003 00000000 00000000 00000000 

 <32 bytes per line>

BBED> sum apply;
Check value for File 15, Block 130:
current = 0xbaf6, required = 0xbaf6

BBED> 

再次查询表pygc的数据就可以看到被truncate之前的数据了

SQL> alter system flush buffer_cache;

System altered.

SQL> alter system flush shared_pool;

System altered.

SQL> select * from pygc;

        ID
----------
        10
        11

SQL> 

但是现在有一个问题,就是pygc这个表无法drop和insert。如果该表需要继续使用,需要使用CTAS的方式创建一个新表。具体报错如下:


SQL> drop table pygc;
drop table pygc
           *
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 2
ORA-08102: index key not found, obj# 39, file 1, block 62284 (2)


SQL> 
SQL> insert into pygc select * from pygc;
insert into pygc select * from pygc
            *
ERROR at line 1:
ORA-00600: internal error code, arguments: [ktspgfblk3:kcbz_objdchk], [0], [0],
[1], [], [], [], [], [], [], [], []


SQL> 

如果需要drop该表,需要把修改obj$、tab$中修改的数据改回去。然后就可以drop掉,这里就不在演示,已经测试可以drop。

所以,表被truncate之后,表就会回收高水位,这样之前的数据就会被放到高水位之上,再次查询该表的时候就无记录返回。同时高水位之前的数据可以被其他需要分配块的操作占用。如果数据块被占用,则占用的数据是无法恢复的。上面的整个过程就是演示了truncate操作的原理。真正恢复数据的时候还是用DRT恢复工具恢复会方便很多,如果数据量很大,并且数据没有被覆盖,修改元数据会更快的恢复数据,但是这种方式存在风险,因为无法全部知道oracle更新了什么操作。 如果发现表被误操作,尽可能不要在操作DML,或者把表对应的表空间设置为read only模式,这样恢复数据的概率就会更高。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值