全表扫先读段头块,而后在段头块里面找到HWM
下面用实验由内而外来理解Oracle的HWM
--t表有一条数据 hr@ORCL> select * from t; ID NAME ---------- ---------- 1 AAAAA --找t段的段头块 hr@ORCL> select header_file,header_block from dba_segments where segment_name='T' and owner='HR'; HEADER_FILE HEADER_BLOCK ----------- ------------ 4 387 --另开一个session,dump段头块 sys@ORCL> alter session set tracefile_identifier='sys_dump_t_01'; Session altered. sys@ORCL> alter system dump datafile 4 block 387; System altered.
Extent Control Header ----------------------------------------------------------------- Extent Header:: spare1: 0 spare2: 0 #extents: 1 #blocks: 8 last map 0x00000000 #maps: 0 offset: 2716 Highwater:: 0x01000189 ext#: 0 blk#: 8 ext size: 8 --Highwater就是高水位,0x01000189这个是HWM的地址 #blocks in seg. hdr's freelists: 0 #blocks below: 5 mapblk 0x00000000 offset: 0 Unlocked -------------------------------------------------------- Low HighWater Mark : Highwater:: 0x01000189 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: 0x01000181 Level 1 BMB for Low HWM block: 0x01000181 -------------------------------------------------------- Segment Type: 1 nl2: 1 blksz: 8192 fbsz: 0 L2 Array start offset: 0x00001434 First Level 3 BMB: 0x00000000 L2 Hint for inserts: 0x01000182 Last Level 1 BMB: 0x01000181 Last Level II BMB: 0x01000182 Last Level III BMB: 0x00000000 Map Header:: next 0x00000000 #extents: 1 obj#: 52713 flag: 0x10000000 Inc # 0 Extent Map ----------------------------------------------------------------- 0x01000181 length: 8 Auxillary Map -------------------------------------------------------- Extent 0 : L1 dba: 0x01000181 Data dba: 0x01000184 -------------------------------------------------------- Second Level Bitmap block DBAs -------------------------------------------------------- DBA 1: 0x01000182 End dump data blocks tsn: 4 file#: 4 minblk 387 maxblk 387
--对t表做一次全表扫 hr@ORCL> set autot traceonly hr@ORCL> select * from t; Execution Plan ---------------------------------------------------------- Plan hash value: 1601196873 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 20 | 3 (0)| 00:00:01 | | 1 | TABLE ACCESS FULL| T | 1 | 20 | 3 (0)| 00:00:01 | -------------------------------------------------------------------------- Note ----- - dynamic sampling used for this statement Statistics ---------------------------------------------------------- 0 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
hr@ORCL> select file_id,block_id,blocks from dba_extents where segment_name='T'; FILE_ID BLOCK_ID BLOCKS ---------- ---------- ---------- 4 385 8
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
Low HighWater Mark : Highwater:: 0x01000189 ext#: 0 blk#: 8 ext size: 8
先来理清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是多少:
hr@ORCL> select object_id,data_object_id from dba_objects where object_name='T'; OBJECT_ID DATA_OBJECT_ID ---------- -------------- 52713 52714
sys@ORCL> select to_char('52714','XXXXXXXX') from dual; TO_CHAR(' --------- CDEA
等等.......