龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 数据库类 > Oracle 技术 >

Oracle Freelist和HWM的性能优化(1)(3)

时间:2011-04-12 23:18来源:未知 作者:admin 点击:
分享到:
segment header block中与HWM相关信息说明如下: EXTENT CONTROL: Extent Header:: spare1: 0 space2: 0 #extents: 13 #blocks: 1429 last map 0x00000000 #maps: 0 offset: 4128 Highwater:: 0x020004d0 e

segment header block中与HWM相关信息说明如下:

EXTENT CONTROL:

Extent Header:: spare1: 0 space2: 0 #extents: 13 #blocks: 1429

last map 0x00000000 #maps: 0 offset: 4128

Highwater:: 0x020004d0 ext#: 12 blk#: 275 ext size: 475

#blocks in seg. hdr’s freelists: 5

#blocks below: 1229

mapblk 0x00000000 offset: 12

Unlocked

==> spare1: this field is no longer used (old inc#, now always 0)

==> space2: this field is no longer used (old ts#, now always 0)

==> #extents: number of extents allocated to segment

==> #blocks: number of blocks allocated to segment

 

==> last map: address of last extent map block

0 if extent map is entirely in the segment header

==> #maps: number of extent map block

==> offset: offset to end of extent map

 

==> HWM dba: address of block at highwater mark

==> ext#: HWM extent number relative to segment

==> blk#: HWM block number within extent

==> ext size: HWM extent size (in blocks)

==> #blocks in seg. hdr’s freelists: number of blocks in seg. hdr’s free list

==> #blocks below: number of blocks below HWM

==> mapblk dba: dba of extent map block containing HWM extent

is 0 if HWM is in the segment header

==> offset: offset within extent map block

is the ext# if HWM is in segment header

==> Locked by: if locked by a transaction, the xid is displayed

HWM可以说是已经使用过的存储空间和未使用过的存储空间之间的分界线。在表使用过程中,HWM一直向一个方向移动,插入记录时HWM可能会向增加的方向移动,但是删除记录时HWM并不会向相反的方向移动。

HIGH WATER MARK之所以重要是因为它对全表扫描性能的影响。当实施一个全表扫描时,Oracle会读取所有HIGH WATER MARK下的块即使它们是空块。当HIGH WATER MARK 下有很多unused block时实施全表扫描会增加额外的不必要的I/O。它也会在全局共享区中填充很多很多空块。

3、分析方法

存储参数基本上属于oracle internal的东西,因此oralce并没有提供很好的手段来分析。但是对于DBA来说,还是可以通过block dump和DBMS_SPACE等手段来获取部分信息。
 
3.1 提取block和free list信息

创建dbms_space使用的存储过程show_space

SQL>
create or replace procedure show_space

( p_segname in varchar2,
p_owner in varchar2 default user,
p_type in varchar2 default 'TABLE',
p_partition in varchar2 default NULL )
as
l_free_blks number;
l_total_blocks number;
l_total_bytes number;
l_unused_blocks number;
l_unused_bytes number;
l_LastUsedExtFileId number;
l_LastUsedExtBlockId number;
l_last_used_block number;
procedure p( p_label in varchar2, p_num in number )
is
begin
dbms_output.put_line( rpad(p_label,40,'.') || p_num );
end;
begin
dbms_space.free_blocks
( segment_owner => p_owner,
segment_name => p_segname,
segment_type => p_type,
partition_name => p_partition,
freelist_group_id => 0,
free_blks => l_free_blks );
dbms_space.unused_space
( segment_owner => p_owner,
segment_name => p_segname,
segment_type => p_type,
partition_name => p_partition,
total_blocks => l_total_blocks,
total_bytes => l_total_bytes,
unused_blocks => l_unused_blocks,
unused_bytes => l_unused_bytes,
last_used_extent_file_id => l_LastUsedExtFileId,
last_used_extent_block_id => l_LastUsedExtBlockId,
last_used_block => l_last_used_block );
p( 'Free Blocks', l_free_blks );
p( 'Total Blocks', l_total_blocks );
p( 'Total Bytes', l_total_bytes );
p( 'Unused Blocks', l_unused_blocks );
p( 'Unused Bytes', l_unused_bytes );
p( 'Last Used Ext FileId', l_LastUsedExtFileId );
p( 'Last Used Ext BlockId', l_LastUsedExtBlockId );
p( 'Last Used Block', l_last_used_block );
end;

过程已创建。

SQL> create table t1(a char(1000)) storage( freelists 3);

表已创建。
SQL> set serveroutput on;
SQL> exec show_space('T1');
Free Blocks.............................0 <==Number of blocks on freelist
Total Blocks............................5 <==Total data blocks in segment
Total Bytes.............................20480 <==Total bytes in segment
Unused Blocks...........................4 <==Total unused blocks in segment
Unused Bytes............................16384 <==Total unused bytes in segment
Last Used Ext FileId....................15 <==File id of last used extent
Last Used Ext BlockId...................562 <==Block id of last used extent
Last Used Block.........................1 <==Last used block in extent
PL/SQL 过程已成功完成。

有关show_space的进一步使用技巧可参考文献5。以下利用上面得到的数据对segment header block进行dump。

SQL>alter system dump datafile 15 block 562;

在udump/ora10792.trc中
*** 2004-09-08 15:29:57.343
Start dump data blocks tsn: 27 file#: 15 minblk 562 maxblk 562

buffer tsn: 27 rdba: 0x03c00232 (15/562)
scn: 0x0000.064560e4 seq: 0x02 flg: 0x00 tail: 0x60e41002
frmt: 0x02 chkval: 0x0000 type: 0x10=DATA SEGMENT HEADER - UNLIMITED
Extent Control Header
-----------------------------------------------------------------

Extent Header:: spare1: 0 space2: 0 #extents: 1 #blocks: 4
last map 0x00000000 #maps: 0 offset: 2080
Highwater:: 0x03c00233 ext#: 0 blk#: 0 ext size: 4
#blocks in seg. hdr's freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 0
Unlocked

Map Header:: next 0x00000000 #extents: 1 obj#: 60033 flag: 0x40000000
Extent Map
-----------------------------------------------------------------

0x03c00233 length: 4
nfl = 3, nfb = 1 typ = 1 nxf = 0
SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
End dump data blocks tsn: 27 file#: 15 minblk 562 maxblk 562

对于上述块中字段的说明,以及相关试验。由于篇幅所限,本文不再列举。 对非segment header的data block的dump方法和上述类似。data block的结构和segment header block不一样,如果需要了解,可查阅参考文献和资料。

 

精彩图集

赞助商链接