最近墨天轮推送了文章《记一次control file sequential read延迟增加分析过程》,链接https://www.modb.pro/db/45742,对其中内容非常感兴趣,但是一些细节不是很明白,坐言起行,根据大佬们提供的资料进行了一些浅显研究,对ASM条带有了进一步认识,特此记录下来。
下面测试用例在11.2.0.4版本中进行测试,限于作者水平以及测试环境,有不足之处欢迎指正。
1. 基础知识ASM条带化与AU
下面内容摘自Oracle Automatic Storage Management Administrator’s Guide,感兴趣可以阅读对应版本原文。
1.1 条带类型
- fine-grained stripping
细粒度条带的条带stripes的大小始终为128K,我们将ASM文件分成很多128 K 的chunks,每个AU也划分为每个128K的chunks,首先放入第一个磁盘的第一个extent,然后第二个磁盘的第一个extent,然后循环起来直至ASM 文件全部放置完成
可以看出这种方式将文件细分成很小的大小分散在各个磁盘中,提高了I/O的响应速度,对并发高,要求延迟小的OLTP系统有利。 - Coarse-Grained Striping
粗粒度条带的stripes 的大小为AU的大小,我们将ASM文件分解成很多块,每个大小为AU的大小,首先放入第一个磁盘的第一个extent,然后第二个磁盘的第一个extent,以此类推直至所有ASM文件放置完成
可以看出这种方式每次I/O可访问更多的数据,对对吞吐量要求较高的OLAP系统有利
1.2 默认ASM各类文件条带属性
- Automatic Storage Management Administrators Guide官方文档中有详细介绍各个文件默认属性,11gR2默认只有controlfile为Fine-Grained Striping,条带属性可以在创建文件时设置。
1.3 条带extent分配
The Oracle ASM instance is release 11.2 and the disk group compatibility attributes for ASM and RDBMS have been set to 11.2,
so variable extents are shown in the graphic after the first 20,000 extents. For the first 20,000 extents,
the extent size is 1 M and equals one allocation unit (AU). For the next 20,000 extents, the extent size is 4 M and equals 4 AU
2. 以控制文件为例确定数据块在哪个磁盘
2.1 查询文件AU分布信息
可以通过查询v a s m a l i a s 与 X asm_alias与X asmalias与XKFFXP关联获取文件AU分布信息。
X K F F X P 是 A S M ( A u t o m a t i c S t o r a g e M a n a g e m e n t ) 自 动 存 储 管 理 特 性 的 重 要 内 部 视 图 , 该 视 图 反 应 了 F i l e E x t e n t M a p 映 射 关 系 , A S M 会 将 文 件 s p l i t 成 多 个 多 个 p i e c e 分 片 , 这 些 分 片 被 称 为 E x t e n t s 。 在 D i s k 上 存 放 这 些 E x t e n t 的 位 置 , 就 是 我 们 常 说 的 ” A l l o c a t i o n U n i t ” 。 详 细 可 参 考 : [ X KFFXP是ASM(Automatic Storage Management)自动存储管理特性的重要内部视图,该视图反应了File Extent Map映射关系,ASM会将文件split成多个多个piece分片,这些分片被称为Extents。 在Disk上存放这些Extent的位置,就是我们常说的”Allocation Unit”。 详细可参考:[X KFFXP是ASM(AutomaticStorageManagement)自动存储管理特性的重要内部视图,该视图反应了FileExtentMap映射关系,ASM会将文件split成多个多个piece分片,这些分片被称为Extents。在Disk上存放这些Extent的位置,就是我们常说的”AllocationUnit”。详细可参考:[XKFFXP介绍](http://www.askmaclean.com/archives/oracle%E5%86%85%E9%83%A8%E8%A7%86%E5%9B%BExkffxp.html)
$ su - grid
$ sqlplus / as sysasm
set linesize 200 pagesize 1400
col "FILE NAME" format a35
col "ASM DISK" format a25
set head on
select b.NAME "FILE NAME",
c.PATH "ASM DISK",
a.NUMBER_KFFXP "FILE NUMBER",
a.XNUM_KFFXP "EXTENT NUMBER",
a.DISK_KFFXP "DISK NUMBER",
a.GROUP_KFFXP "GROUP NUMBER",
a.AU_KFFXP "AU NUMBER",
a.SIZE_KFFXP "NUMBER of AUs"
from x$kffxp a, v$asm_alias b,v$asm_disk c
where a.GROUP_KFFXP = b.GROUP_NUMBER
and b.group_number = c.group_number
and a.DISK_KFFXP = c.disk_number
and a.NUMBER_KFFXP = FILE_NUMBER
and b.system_created = 'Y'
and a.lxn_kffxp = 0 --logical extent number 0代表primary extent,我们只看primary extent
and b.name like 'Current%' --以RAC控制文件为例
order by 7;
FILE NAME ASM DISK FILE NUMBER EXTENT NUMBER DISK NUMBER GROUP NUMBER AU NUMBER NUMBER of AUs
----------------------------------- ------------------------- ----------- ------------- ----------- ------------ ---------- -------------
Current.260.984508003 /dev/sdd 260 0 0 1 1348 1
Current.260.984508003 /dev/sdg 260 1 1 1 5228 1
Current.260.984508003 /dev/sdd 260 2 0 1 1350 1
Current.260.984508003 /dev/sdg 260 3 1 1 5229 1
Current.260.984508003 /dev/sdd 260 4 0 1 1352 1
Current.260.984508003 /dev/sdg 260 5 1 1 5230 1
Current.260.984508003 /dev/sdd 260 6 0 1 1354 1
Current.260.984508003 /dev/sdg 260 7 1 1 5231 1
Current.260.984508003 /dev/sdd 260 8 0 1 1356 1
Current.260.984508003 /dev/sdg 260 9 1 1 5232 1
Current.260.984508003 /dev/sdd 260 10 0 1 1358 1
Current.260.984508003 /dev/sdg 260 11 1 1 5233 1
Current.260.984508003 /dev/sdd 260 12 0 1 1360 1
Current.260.984508003 /dev/sdg 260 13 1 1 5234 1
Current.260.984508003 /dev/sdd 260 14 0 1 1362 1
Current.260.984508003 /dev/sdg 260 15 1 1 5235 1
Current.260.984508003 /dev/sdd 260 16 0 1 1364 1
Current.260.984508003 /dev/sdg 260 17 1 1 5236 1
Current.260.984508003 /dev/sdd 260 18 0 1 1366 1
Current.260.984508003 /dev/sdg 260 19 1 1 5237 1
Current.260.984508003 /dev/sdd 260 20 0 1 1368 1
Current.260.984508003 /dev/sdg 260 21 1 1 5238 1
Current.260.984508003 /dev/sdd 260 22 0 1 1370 1
Current.260.984508003 /dev/sdg 260 23 1 1 5239 1
2.2 查看条带隐含参数
_asm_stripesize
_asm_stripewidth
col name for a40;
col value for a15;
col describe for a50
select
x.ksppinm name,
y.ksppstvl value,
y.ksppstdf isdefault,
x.ksppdesc describe,
decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod,
decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj
from
sys.x$ksppi x,
sys.x$ksppcv y
where
x.inst_id = userenv('Instance') and
y.inst_id = userenv('Instance') and
x.indx = y.indx and x.ksppinm like '%¶meter%'
order by
translate(x.ksppinm, ' _', ' ')
/
Enter value for parameter: strip
old 14: x.indx = y.indx and x.ksppinm like '%¶meter%'
new 14: x.indx = y.indx and x.ksppinm like '%strip%'
NAME VALUE ISDEFAULT DESCRIBE ISMOD ISADJ
---------------------------------------- --------------- --------- -------------------------------------------------- ---------- -----
_asm_stripesize 131072 TRUE ASM file stripe size FALSE FALSE
_asm_stripewidth 8 TRUE ASM file stripe width FALSE FALSE
11g默认参数值如下:
_asm_stripesize 131072即128KB,
_asm_stripewidth 8为例,
数据存放不止与条带宽度有关,还与ASM DISKGROUP中磁盘数有关,下面均以磁盘组external冗余为例
经过不同磁盘数测试得出情况如下:
- 如果磁盘数为1,则细粒度条带也是按照放满第一个AU再放第二个AU顺序存放,可以通过dd验证这种情况。
- 如果磁盘数大于1小于条带宽度,则会按照磁盘数进行交叉循环存放,第一个条带尺寸128k存放于第一个磁盘的AU1,第二个条带尺寸存放于第二块磁盘的AU2,当AU放满,会再次分配新的extent以及对应AU。
- 如果磁盘数大于条带宽度,则会根据条带宽度进行在不同磁盘间存放,当第一组AU存放满之后,由于ASM磁盘要均匀存放数据在磁盘组所有磁盘,所以会根据算法再使用其他未放置数据磁盘,循环往复,直到所有数据都均匀分布在磁盘组所有磁盘。
2.3 查看需要查询asm文件block_size
下面例子中ASM磁盘组有两块磁盘,虽然会在不同磁盘间循环存放,但是对于extent来说是逻辑连续的,2.1小节中查询数据分布只需按照extent,au number号排序,然后根据计算要查找的数据块号顺延计算第几个au,然后按照extent,au number排序后结果对应行号,是哪一个au number,则对应block即存放于哪个对应au以及对应磁盘。
$ sqlplus / as sysasm
SQL> select group_number,file_number,block_size,blocks,bytes from v$asm_file where FILE_NUMBER=260 and GROUP_NUMBER=1;
GROUP_NUMBER FILE_NUMBER BLOCK_SIZE BLOCKS BYTES
------------ ----------- ---------- ---------- ----------
1 260 16384 1297 21250048
2.4 查看磁盘组au size
GROUP_NUMBER NAME ALLOCATION_UNIT_SIZE
------------ ------------------------------ --------------------
1 DATADG 1048576
2.5 查询controlfile sequential read的p1 p2
根据p1查询读取哪个控制文件
SYS> SELECT cfnam,indx,cfbsz FROM X$KCCCF WHERE INDX = &p1
CFNAM INDX CFBSZ
------------------------------------------------------------ ---- --------
+DATADG/honor/controlfile/current.260.984508003 0 16384
2.6 根据p2换算位于哪个AU
假设查询如下:
--查询control file sequential read等待事件
EVENT P1 P2 P3
---------------------------------------------------------------- ------------------------- ---------------- ---------------
control file sequential read 0 35 1
control file sequential read 0 42 1
control file sequential read 0 39 1
control file sequential read 0 35 1
control file sequential read 0 30
1
以P2=30为例,单个AU=1048576,control file block size=16384,
则第30个block位于:
block_numberblock_size/strip_size=3016384/131072=3.75,
即处于第四个AU,每个AU 8个128k的条带块,每个控制文件块为16384/1024=16k
第30个block处于第四个AU的mod(30*16384/131072,1)*131072/16384=6,处于第四个AU的第6个块。
对应2.1小节结果,即控制文件current.260.984508003第30个块位于第四行即/dev/sdg的5229 au上,下面我们来验证结果是否符合。
2.7 根据AU number进行dd
根据2.1小节中查询AU number信息进行dump
本例中3.75即位于第四个AU,即AU number为1351,根据上面计算,位于1351的第6个块,我们来dd一下/dev/sdd磁盘
$ dd if=/dev/sdg of=/tmp/au_5229.data bs=1048576 skip=5229 count=1
--AU number从0开始计算,所以AU number 5229即物理磁盘上第5230个1M单位,所以需要skip 5229
$ dd if=/tmp/au_5229.data of=/tmp/au5229block6.data bs=16384 skip=5 count=1
--从AU上dump出来第6个块,稍后与控制文件dump出来对比
验证控制文件第30个块
ASMCMD> cp Current.260.984508003 /tmp/Current.260.ctl
$ dd if=/tmp/Current.260.ctl of=/tmp/ctl_block30.data bs=16384 skip=29 count=1
$ hexdump -C /tmp/ctl_block30.data
00000000 15 c2 00 00 1d 00 00 00 00 00 00 00 00 00 01 04 |................|
00000010 f7 2c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |.,..............|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000000a0 00 00 00 00 00 00 ff ff 00 00 00 00 00 00 00 00 |................|
000000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00003ff0 00 00 00 00 00 00 00 00 00 00 00 00 01 15 00 00 |................|
00004000
查看dd出来AU 30个块内容:
$ hexdump -C /tmp/au5229block6.data
00000000 15 c2 00 00 1d 00 00 00 00 00 00 00 00 00 01 04 |................|
00000010 f7 2c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |.,..............|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000000a0 00 00 00 00 00 00 ff ff 00 00 00 00 00 00 00 00 |................|
000000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00003ff0 00 00 00 00 00 00 00 00 00 00 00 00 01 15 00 00 |................|
00004000
--可以看到内容完全一致,那么我们对ASM物理结构理解与实际相符。
END
感谢各位大佬的深入研究,才能让有进一步研究的资料。
参考:
https://www.modb.pro/db/45742?XZS=
http://www.askmaclean.com/archives/oracle%E5%86%85%E9%83%A8%E8%A7%86%E5%9B%BExkffxp.html
Oracle® Automatic Storage Management Administrator’s Guide