特殊手段恢复被truncate的表

最近在写oracle抽取数据文件工具,在抽取数据文件恢复数据的时候发现,恢复的数据比预期的多,经过对比之后发现是有一些表被truncate了,由于被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前后用解析工具得到的数据

[[email protected] 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
[[email protected] 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>

[[email protected] jiexi]$
[[email protected] jiexi]$ ./header <=====第二次解析
kkkkkkk=130
objectid=136027 <======解析之后发现对象号从136026变成了136027
address 3c00080 8
addrend
rdba=3c00086
columns_count=1
c10c
columns_count=1
c10b
[[email protected] 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模式,这样恢复数据的概率就会更高。

原文地址:https://blog.51cto.com/14523150/2436544

时间: 2024-11-02 10:19:25

特殊手段恢复被truncate的表的相关文章

SqlServer--delete和truncate 删除表的区别

--删除表中的全部数据,自动编号不清零. --1.delete from Biao --删除表中的全部数据,自动编号清零. --2.truncate table Biao --truncate特点: --1>truncate语句不能跟where条件(无法根据条件来删除,只能全部删除数据) --2>同时自动编号恢复到初始值. --3>使用truncate删除表中所有数据要比delete效率高的多. --4>truncate删除数据,不触发delete触发器.

自定义“ORA-20010: 不能DROP/TRUNCATE该表”的错误

oracle更新数据提示自定义"ORA-20010: 不能DROP/TRUNCATE该表"的错误 java.sql.BatchUpdateException: ORA-00604: error occurred at recursive SQL level 2 ORA-20010: 不能DROP/TRUNCATE该表. ORA-06512: at line 12 org.springframework.jdbc.UncategorizedSQLException: Hibernate

用Delete与Truncate清除表数据对高水位的影响

众所周知,oracle段都有一个在段内容纳数据块的上限,我们把这个上限称为"High Water Mark"(HWM).这个HWM是一个标记,用来说明已经有多少没有使用的数据块分配给这个segment.原则上HWM只会增大,不会缩小,即使将表中的数据全部删除,HWM还是为原值.HWM就像一个水库的历史最高水位,这也是为何会称之为"高水位"的缘故.实际环境中随着我们表中数据的不断增长,表的高水位也被不断的推高.当高水位达到一定程度之后,会对该表上的SQL查询效率产生负

Oracle恢复drop误删除的表

一.表的恢复 对误删的表,只要没有使用PURGE永久删除选项,那么从flash back区恢复回来希望是挺大的.一般步骤有: 1.从flash back里查询被删除的表 select * from recyclebin 2.执行表的恢复 flashback table tbName to before drop; 这里的tbName代表你要恢复的表的名称.二.表数据恢复 对误删的表记录,只要没有truncate语句,就可以根据事务的提交时间进行选择恢复,一般步骤有: 1.先从flashback_

如何通过直接复制frm文件以实现恢复/复制innodb数据表?

如何通过直接复制frm文件以实现恢复/复制innodb数据表?在MySQL5.0的使用过程中,经常会出现一些莫名奇妙的问题,导致服务无法启动,只好重新安装MySQL,但是这样原来的数据库就会丢失了.听说MySQL的数据库文件直接复制便可以使用,但是根据查询,那是指原来的一种"MyISAM"类型的表.我通常都是使用MySQL-Front直接创建表,默认是"InnoDB"类型,这种类型的一个表在磁盘上好像只对应一个"*.frm"文件,不像MyISAM

MySql清空表的方法介绍 : truncate table 表名

清空某个mysql表中所有内容 delete from 表名; truncate table 表名; 不带where参数的delete语句可以删除mysql表中所有内容,使用truncate table也可以清空mysql表中所有内容.效率上truncate比delete快,但truncate删除后不记录mysql日志,不可以恢复数据. delete的效果有点像将mysql表中所有记录一条一条删除到删完,而truncate相当于保留mysql表的结构,重新创建了这个表,所有的状态都相当于新表.

从xtraback 备份文件中 单独恢复一张 innodb 表

从xtraback 备份文件中 单独恢复一张 innodb 表 http://blog.sina.com.cn/s/blog_445e807b0101dbgw.html 能够恢复一张表的前提是独立表空间 即开启了 innodb_per_file_table=1 恢复一张innodb 表 (innodb_per_file_table)   1>数据错误,但是表没有被删除(drop table, truncate table) a. 发出这个ALTER TABLE语句: b. ALTER TABLE

TRUNCATE 删除表,无法回退。默认选择为整个表的内容,所以不能加条件。

TRUNCATE 删除表,无法回退.默认选择为整个表的内容,所以不能加条件.DELETE 删除表,可以回退.可以带where 条件.建议使用delete.但是TRUNCATE 删除表数据比delete要快. 使用TRUNCATE TABLE语句 TRUNCATE TABLE语句提供了一种删除表中所有记录的快速方法.因为TRUNCATE TABLE语句不记录日志,只记录整个数据页的释放操作,而DELETE语句对每一行修改都记录日志,所以使用TRUNCATE TABLE语句进行删除操作总是比没有指定

RMAN恢复drop purge的表

@ORA12C>  alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'; Session altered. [email protected]> create table  t_0920 as select * from dba_objects; Table created. [email protected]> select count(*) from t_0920;   COUNT(*) ----------------