什么是oracle中未格式化的块?
让我们来看一下熊哥对上述问题的精彩解释:"未格式化,意思就是这个块,已经是属于这个段了,但是还保留着原来的样子没动。格式化就是把块中的数据清除掉,并把块头改为这个对象的。MSSM表空间中的段,只有一个高水位,高水位下的块都是格式化了的。但是ASSM表空间中的段,有两个高水位,低高水位和高高水位,低高水位下的块全部是格式化了的,但是低高水位和高高水位之间的块,则可能是格式化了的,也可能没有"。
解释的再清晰不过了,我们现在来看一个未格式化的块的例子:
SQL> select HEADER_FILE,HEADER_BLOCK from dba_segments where segment_name='SYSQFI';
HEADER_FILE HEADER_BLOCK
----------- ------------
10 157324
把SYSQFI所在的段头dump出来:
Extent Control Header
-----------------------------------------------------------------
Extent Header:: spare1: 0 spare2: 0 #extents: 1 #blocks: 128
last map 0x00000000 #maps: 0 offset: 2716
Highwater:: 0x
#blocks in seg. hdr's freelists: 0
#blocks below: 60
mapblk 0x00000000 offset: 0
Unlocked
--------------------------------------------------------
Low HighWater Mark :
Highwater:: 0x0282668d ext#: 0 blk#: 4 ext size: 128
可以看到高高水位是0x028266c9,低高水位是0x0282668d。
SQL> exec sys.cdba('
.
The file is 10
The block is 157385
PL/SQL procedure successfully completed
SQL> exec sys.cdba('0282668d','H');
.
The file is 10
The block is 157325
PL/SQL procedure successfully completed
也就是说SYSQFI的高高水位是file 10,block 157385;其低高水位是file 10,block 157325。
我们现在再来看一下SYSQFI现在data object number是多少:
SQL> select object_id,data_object_id from dba_objects where object_name='SYSQFI';
OBJECT_ID DATA_OBJECT_ID
---------- --------------
65795 66347
这里明显SYSQFI的data object number大于其object number,也就是说在SYSQFI上曾经发生过truncate或者move操作。注意对于truncate操作而言,truncate后其data object number不一定就是在原先的data object number上加1。
SQL> select to_char('66347','XXXXXXXX') from dual;
TO_CHAR('66347','XXXXXXXX')
---------------------------
1032B
SQL> select to_char('65795','XXXXXXXX') from dual;
TO_CHAR('65795','XXXXXXXX')
---------------------------
10103
换句话说,SYSQFI中现在在其低高水位(file 10,block 157325)和其高高水位(file 10,block 157385)之间的block,只要这个block上记录的data object number不等于1032B,那这个block就是一个未格式化的块!
我们现在来看file 10,block 157330:
Start dump data blocks tsn: 8 file#: 10 minblk 157330 maxblk 157330
buffer tsn: 8 rdba: 0x02826692 (10/157330)
scn: 0x0002.d25fa5bd seq: 0x01 flg: 0x06 tail: 0xa5bd0601
frmt: 0x02 chkval: 0x8d34 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
......中间内容省略
Block header dump: 0x02826692
Object id on Block? Y
seg/obj: 0x10103 csc: 0x02.d25fa591 itc: 2 flg: E typ: 1 - DATA
brn: 0 bdba: 0x2826689 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x
0x02 0x
data_block_dump,data header at 0x110572064
===============
tsiz: 0x
hsiz: 0xe8
pbl: 0x110572064
bdba: 0x02826692
76543210
flag=--------
ntab=1
nrow=107
frre=36
fsbo=0xe8
fseo=0x220
avsp=0x
tosp=0x153e
0xe:pti[0] nrow=107 offs=0
0x12:pri[0] offs=0x269
0x14:pri[1] offs=0x220
......中间内容省略
0xe4:pri[105] sfll=106
0xe6:pri[106] sfll=-1
block_row_dump:
tab 0, row 0, @0x269
tl: 71 fb: --H-FL-- lb: 0x1 cc: 11
col 0: [ 4] c3 0e 34 46
col 1: [ 2] c1 56
col 2: [14] bd e8 cf ee cd a8 d6 aa b
col 3: [ 6] 53 41
col 4: [ 6] 53 42 54 44 4d 54
col 5: [ 1] 4e
col 6: *NULL*
col 7: *NULL*
col 8: [ 5] c4 15 09 06
col 9: [ 3] 46 45 57
col 10: [16] 53 41
tab 0, row 1, @0x220
tl: 71 fb: --H-FL-- lb: 0x1 cc: 11
col 0: [ 4] c3 0e 34 47
col 1: [ 2] c1 57
col 2: [14] b4 fb cf ee cd a8 d6 aa b
col 3: [ 6] 53 41
col 4: [ 6] 53 42 54 43 4d 54
col 5: [ 1] 4e
col 6: *NULL*
col 7: *NULL*
col 8: [ 5] c4 15 09 06
col 9: [ 3] 46 45 57
col 10: [16] 53 41
......中间内容省略
tab 0, row 34, @0x2b2
tl: 74 fb: --H-FL-- lb: 0x1 cc: 11
col 0: [ 4] c3 0e 35 04
col 1: [ 2] c1 21
col 2: [17] c6 e4 cb fb d2 b5 ce f1 ca d
col 3: [ 6] 53 41
col 4: [ 6] 53 42 54 49 43 32
col 5: [ 1] 43
col 6: *NULL*
col 7: *NULL*
col 8: [ 5] c4 15 09 06
col 9: [ 3] 46 45 57
col 10: [16] 53 41
tab 0, row 35, @0x1652
tl: 66 fb: --H-FL-- lb: 0x1 cc: 11
col 0: [ 4] c3 0e 35 05
col 1: [ 2] c1 22
col 2: [17] c6 e4 cb fb d2 b5 ce f1 ca d
col 3: [ 6] 53 41
col 4: [ 6] 53 42 54 49 41 32
col 5: [ 1] 4e
col 6: *NULL*
col 7: *NULL*
col 8: *NULL*
col 9: *NULL*
col 10: [16] 53 41
end_of_block_dump
End dump data blocks tsn: 8 file#: 10 minblk 157330 maxblk 157330
exec sys.cdba 我怎么执行不了
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'SYS.CDBA' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
CDBA是一段转换DBA(Database Address)的代码,具体可参见113005.1,不过那里面的代码稍微有点问题,需要改一下。其核心就是利用了dbms_utility.data_block_address_file和dbms_utility.data_block_address_block来做转换。