浅谈Oracle的高水位线--HWM(二)

2014-11-24 12:34:56 · 作者: · 浏览: 1
recursive calls
0 db block gets
7 consistent gets --全表扫读了6个块
0 physical reads
0 redo size
469 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
这6个块是如何算出来的呢?
[sql]
hr@ORCL> select file_id,block_id,blocks from dba_extents where segment_name='T';
FILE_ID BLOCK_ID BLOCKS
---------- ---------- ----------
4 385 8
这t段一共用了8个块,分别是385 386 387 388 389 390 391 392 393
Highwater:: 0x01000189 即:4号文件的393号块
这个可由下面dbms_utility包算出
[sql]
sys@ORCL> select to_number('01000189','xxxxxxxx') from dual;
TO_NUMBER('01000189','XXXXXXXX')
--------------------------------
16777609
sys@ORCL> select dbms_utility.data_block_address_file(16777609) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(16777609)
----------------------------------------------
4
sys@ORCL> select dbms_utility.data_block_address_block(16777609) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(16777609)
-----------------------------------------------
393
读了一次段头块:4号文件387号块
读了高水位之下的388 389 390 391 392 等5个块
这样一共就读了6个块
注:
385是FIRST LEVEL BITMAP BLOCK
386是SECOND LEVEL BITMAP BLOCK
接着分析我们所dump的内容: www.2cto.com
[sql]
Low HighWater Mark :
Highwater:: 0x01000189 ext#: 0 blk#: 8 ext size: 8
接下来谈谈highwater mark 和 low highwater mark
low high water mark与high water mark 之间可能存在formated block也可以可能存在
unformatted block


先来理清dba_tables里面的字段blocks的含义
dba_tables.blocks记录的是分析得到的 formatted block 的总数
而 low hwm 和 high hwm之间可能同时存在 formatted block 和 unfomatted block
所以准确地说 blocks 不能代表 low hwm 或high hwm
如果 low hwm 和 high hwm之间正好没有formatted block时,dba_tables.blocks和
low hwm下的blocks一致
那么什么是Oracle中未格式化的块呢?
未格式化,意思就是这个块,已经是属于这个段了,但是还保留着原来的样子没动
格式化就是把块中的数据清除掉,并把块头改为这个对象的
MSSM表空间中的段,只有一个高水位,高水位下的块都是格式化了的
但是ASSM表空间中的段,有两个高水位:低高水位和高高水位
即上文trc里的:Highwater:: 0x01000189和Low HighWater Mark Highwater:: 0x01000189
低高水位下的块全部是格式化了的
但是低高水位和高高水位之间的块,则可能是格式化了的,也可能是没有
现在的t的高高水位是file 4,block 393;其低高水位是file 4,block 393
我们现在再来看一下t现在data_object_id是多少:
[sql]
hr@ORCL> select object_id,data_object_id from dba_objects where object_name='T';
OBJECT_ID DATA_OBJECT_ID
---------- --------------
52713 52714
这里很明显t的data_object_id大于object_id
也就是说,在t上曾经发生过move或truncate操作
注意,对于truncate操作而言,truncate后其data_object_id不一定就是在原先的data_
object_id上加1
[sql]
sys@ORCL> select to_char('52714','XXXXXXXX') from dual;
TO_CHAR('
---------
CDEA
换句话说,t中现在在其低高水位和其高高水位之间的block,只要这个block上记录的data
_object_id不等于CDEA
我们可以通过dump里面的Block header dump部分中的seg/obj来判断其data_object_id
是否与段编号相等
那么这个block 就是一个未格式化的块
也就是说,可以通