mysql有高水位线吗_浅谈Oracle的高水位线--HWM

本文深入探讨了Oracle数据库的高水位线(HWM),通过实验解析了HWM的概念及其在段头块中的位置。文章指出,HWM记录了数据段能容纳数据的上限,并详细介绍了如何通过dump数据块来理解HWM。全表扫描时,系统通常读取到低高水位线,然后根据位图读取已格式化的块,避免未格式化的块。文章还讨论了HWM的重要性,以及如何通过不同方法降低HWM,如expdp/impdp、shrink、move、CTAS等。
摘要由CSDN通过智能技术生成

高水位是记录段里能容纳数据的上限,高水位存在段里

全表扫先读段头块,而后在段头块里面找到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.

dump的部分trc内容摘入

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

这6个块是如何算出来的呢?

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包算出

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的内容: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

1360081779_4440.png

先来理清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

这里很明显t的data_object_id大于object_id

也就是说,在t上曾经发生过move或truncate操作

注意,对于truncate操作而言,truncate后其data_object_id不一定就是在原先的data_object_id上加1

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 就是一个未格式化的块

也就是说,可以通过data_object_id来确定块是在HWM和LHWM的位置

那么Oracle为什么要增加低高水位设置?出于什么目的?全表扫描时,是到低高水位,还是到高高水位?

Oracle设计有一个原则,就是把一个大操作分散到很多小操作中,以保证某个大操作不会花费太长时间

无论是延迟提交,还是什么,都体现了这种思想,这和Linux的理念有异曲同工之妙哦

而低高水位线与高高水位线结合,正是这种思想的体现

可以不用一次性格式化所有新分配的块,留一部分给下次操作来完成

全表扫描时,通常都是读至低高水位线,然后根据位图去读低高与高高之间格式化过的块,避开未格式化的块

如何查看HWM?如何知道HWM下有多少空闲的空间?

最实用的方法就是dump segment_header,速度快,而且对应用没有影响

而且,trc里面的"#blocks in seg. hdr's freelists:"可以告诉我们HWM下有多少空闲块

这里需要注意,如果dba_segments.freelist_groups > 1,那么freelist不再segment header中

比如,freelist_group = 3 ,则你便要分别dump header后面的3个块,来看每个group的freelist的个数

那么如何降低HWM呢?

① expdp/impdp

② 10G及以后的版本可以采用shrink,需要注意的是,表所在表空间须为自动段空间管理

alter table tab_name enable row movement;

alter table tab_name shrink space;

③ 使用move,不过在Move期间,会影响到DML语句,如UPDATE,也需要考虑空间问题

总之move会锁表 而且是TM 另外还会影响index,所以,之后记得rebuild index

alter table move tab_name; 在当前表空间中move

alter table move tab_name tablespace tbs_name; 将其move到其他表空间

④ CTAS 然后rename,rebuild index

⑤ 在线重定义

等等.......

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2013-02-06 00:32

浏览 539

评论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值