我是靠谱客的博主 真实龙猫,最近开发中收集的这篇文章主要介绍aix stripe size for oracle,ASM条带揭密----_asm_stripesize、_asm_stripewidth参数的设置和影响...,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

本帖最后由 vage 于 2012-12-25 07:40 编辑

ASM条带揭密----_asm_stripesize、_asm_stripewidth参数的设置和影响

第一部分ASM条带概述

11GR2的ASM中,有两个很诱人的参数:_asm_stripesize、_asm_stripewidth,条带大小和条带宽度。貌似通过这两个参数,我们可以对条带进行更多的控制。但这两个参数并不是设置了就可以使用的,实际情况如何呢、这两个参数到底对我们的IO有什么影响呢,还要通过实验来确定。我们可以通过两种方式来观察ASM的条带,一是直接用KFED工具,读取ASM中文件的kfffdb结构,此结构中有kfffdb.strpwdth、kfffdb.strpsz两个域,看名字就知道,这两个域分别刻录了文件的条带宽度和条带大小。

另一种观察ASM条带的方式,就是通过“揭密Oracle之七种武器二:DTrace语法:跟踪物理IO

”提到的方法,跟踪操作系统驱动层的IO信息。通过IO的分布、IO大小,来了解条带的影响。

好,我们将两种方式都采用,结合起来判断。

先来个图,了解一下条带大小、宽度,AU大小的影响吧:

dd06a1abc3fb84da465ff4eff32374f6.gif

pci1.jpg (38.75 KB, 下载次数: 40)

2012-8-13 07:04 上传

图1

上图例子,磁盘组中共有4块盘,编号分别是1至4。

另外,AU大小和条带大小相同,条带宽度为1。比如,假设上图AU大小为4M。条带大小也是4M,条带宽度为1。一个条带正好占一个AU,每个AU中只有一个条带。段数据的第一个4M在1号盘1号AU 1号条带,第二个4M在2号磁盘2号AU 1号条带,等等,以次类推。

11GR2的ASM,可以说一共有两种条带类型:不可调粗粒度,可调细粒度。

粗粒度条带下,条带大小、宽度不可调。条带大小将一直等同于AU大小,条带宽度一直是1。也就是一个条带只在一个磁盘中,不会跨越磁盘。

10G、11G默认的AU大小都是1M,这点不用我强调了吧。而且,默认情况下,ASM的条带是“不可调粗粒度”。也就是AU大小1M,条带大小也是1M,条带宽度为1。这意味着数据会以1M为单位,平均分布到磁盘组所有磁盘中。也就是ASM保证1M数据逻辑上是连续的。如果段的区大小也是1M,哪么,全表扫描时,一次IO可以在一块磁盘上一次读1M数据。

高于1M的AU,个人认为,意义不大。因为大多数OS中,最大的IO大小就是1M。

(---------最新修改: 这是以前的看法,在之后我又做了很多测试,高于操作系统IO大小限制的IO,对于提高全表扫描的性能,还是很有帮助的。

可以参考30楼、33楼我的回复。)

就像我们上面例子中所说,如果AU、条带大小是4M,ASM虽然可以在每个磁盘上连续存储4M数据,但发生IO操作时,每次IO的大小最大还是1M,连续的4M数据,还是需要4次IO才能操作完。

(--------最新修改: 这段也是以前的看法,经过测试,如果AU、条带大小是4M,4次IO有可能是连续的。4次连续的IO,比4次不连续的IO性能要好很多)

我们刚才一直在说大IO操作。如果是小IO操作,在OLTP中,更多的是8K的小IO操作。对于Redo,则更多是1K、2K甚至512字节的写IO操作。如果进程要读、写8K数据,AU大小、条带大小是否对8K读、写有影响呢?

答案是基本上无影响。根据AU、条带规,进程先计算出要读、写的8K数据在哪块磁盘中,然后,直接到这块磁盘上读、写8K就行了。

无论条带多大,最小的IO大小都是512字节,进程想读、写多大,就读、写多大。不必一次读、写一个条带。

好,下面再看下一个图:

dd06a1abc3fb84da465ff4eff32374f6.gif

pci2.jpg (56.14 KB, 下载次数: 40)

2012-8-13 07:04 上传

图2

上图仍以四块盘的DG为例。假设AU大小为4M,条带大小为512K,条带宽度为4。千万不要认为这样的假设在ASM中不成立。有人说条带大小乘以条带宽度必须等于AU大小。Oracle中没有这样的限制,后面我们有这方面的测试。

图中已经画的很明白,表的第一个512K,在AU1中,第二个512K,在AU2中,等等。

其实,AU、条带这些东西,就是决定了空间是如何被使用的,数据是如何被存放的。

在上图中,如果要读取1M连续数据,要从两个盘读。也就是如果表的区大小是1M,这一M会被分隔到两个盘中。1M的区,在上图中,将占半个条带。

下面,讨论一个常见问题,这种小条带方式,和前面的大条带方式,哪个更好?

这个问题真的不能一概而论了,流行的说法:大条带、大AU适合数据仓库,小条带小AU适合OLTP。这种说法太笼统。我们还是要理解ASM的IO方式,根据应用访问数据的特点,做合适的选择。好,正确的废话我不多说,接前前面的例子,以图1、图2的ASM DG为例,图1是4M AU,4M条带,条带宽度为1。图2是4M AU,512K条带,条带宽度为4。假设表的区大小是1M,全表扫描时读取一个区,谁更快?

答案是图1中的DG会略快一点点。

只是快一点点,原因是这样的,1M的区,在图2的DG中,会被存放在两个盘中。读取1M数据时,进程要到两个盘中各读512K。这两个读操作,不是同时的,而是先后的。

如果是同时读两个磁盘,哪么图1与图2的方式,读取1M数据的速度将是一样的。我在“35岁总结”哪篇文章中(突然35岁:捡点我的职业生涯),提到过Redo同一组中两个成员的写一样。一个进程,怎么能同时向两个磁盘发送命令呢,这不符合现代CPU的运行方式。

进程一定是先向一块盘中发送读512K的命令,再向另一块盘发送读命令。正是这一前一后发送两条命令,可能会让图2的方式,比图1稍慢一点点。慢这一点点是多久,也就是进程多发送了一条从磁盘读数据的命令。

一条命令,最多几百个CPU周期,实在是很短的时间。

在CPU不是问题的情况下,这“一点点”基本是可以忽略的。

但要注意,图2的方式,对于读1M连续数据这样的操作,比图1要多浪费点CPU。

刚才说的是读,还有写呢?如果表的区大小是1M,如果是使用append操作,连续写1M数据呢?

如果是写,图1、图2中的DG,性能相同。

因为使用DTrace脚本,打开IO的驱动层探针,最大的写IO就是256K。即使区大小是1M,进程也是以256K为单位写。这个写,在图1、图2的方式中,都不会跨越磁盘,因此不会有性能差异。

再来说一种情况,如果不是大批量连续写呢。如果是哪种大量的插入,比如日志型应用,这个情况,今天暂不展开讨论。大概说一下,ASSM的插入,通常只会向一个区中插入。对于图1这种大条带,一个区只在一块盘上。所以脏块集中一块盘上。对于图2的小条带,一个区要跨两个盘,脏块在两块盘上,写也更分散,磁盘的热点也更均匀。但实际上这种情况不便涉及ASSM原理,还要考虑buffer_cache的影响,不单只是IO的问题了。

好,再看一张图吧:

dd06a1abc3fb84da465ff4eff32374f6.gif

pci3.jpg (56.44 KB, 下载次数: 37)

2012-8-13 07:04 上传

图3

图3中的例子,主要说明一点,条带宽度可以不等于DG中的磁盘数吗?当然可以。假设为AU大小为4M,条带大小为512K,条带宽度为2。表数据的第一个512K,在AU1中,第二个在AU2中,第三个又回到AU1中,因为条带宽度为2吗。直到第15、16个512K,分别在AU1中,AU2中,AU1、AU2被占满了。第17个512K,在AU3中,第18个512K,在AU4中,等等,以此类推。

我们后面,会有一个类似的例子。

好了,不同的条带大小、宽度和AU大小,对性能还是多多少少会有些影响的,11GR2的ASM,可以允许我们对这些东西进行控制,是不是动心了,但如何控制,方法还是有点奇怪的。并不是改了隐藏参数就能发挥作用。

还有一点注意事项,在ASM中,AU,是属于磁盘组层面的概念,一个磁盘组,只能有一个统一的AU大小。在创建磁盘组时,要指定AU的大小,一旦指定,在磁盘组创建后无法变更。

而条带,是属于文件层面的概念。同一磁盘组中,各个文件可以有不同的条带大小。在创建表空间时,要同时确定条带信息。也是一旦确定,无法更改。

好了,下面,让我们开始吧。

第 二 部分  不可调粗粒度条带

我们前面说过,我把ASM条带总体上分两种:不可调粗粒度、可调细粒度。

不可调粗粒度其实是我们使用最多的一个方式,因为ASM默认的方式就是它。

在这种方式下,条带大小、宽度是不可调的,而且条带大小,就是AU的大小。宽度一直为1。

为了验证我的说法,可以如下测试:

一、环境准备:

10G中,数据文件默认的条带大小是1M,11G中_asm_stripesize参数默认值并不是1M,我们先修改一下这个值,将它设为1M:

SQL> alter system set "_asm_stripesize"=1048576;

System altered.

_asm_stripewidth的值,保留默认值为8。

为了和条带大小有所区别,创建个AU大小为4M的DG:

create diskgroup dg2 external redundancy disk

'/dev/rdsk/c1t3d0s0',

'/dev/rdsk/c1t4d0s0',

'/dev/rdsk/c1t5d0s0',

'/dev/rdsk/c1t6d0s0'

attribute 'compatible.asm' = '11.2','AU_SIZE'='4M';

注意事项,AU_SIZE是4M,不写4m,小写会报错。

创建区大小为4M的表空间:

create tablespace tbs_e4m datafile '+dg2/tbs_e4m_01.dbf' size 100m uniform size 4m;

二、观察kfffdb结构中的条带数据。

注意,前面已经提到过,在ASM中,AU,是属于磁盘组层面的概念,一个磁盘组,只能有一个统一的AU大小。条带,是属于文件层面的概念。

下面,我们可以观察一下刚刚+dg2/tbs_e4m_01.dbf

步1:首先确认ASM中的文件号

col NAME for a40

SQL> select NAME,FILE_NUMBER from V$ASM_ALIAS where name like '%tbs_e4m_01.dbf%';

NAME                                     FILE_NUMBER

---------------------------------------- -----------

tbs_e4m_01.dbf                                   256

在ASM中,此文件的编号是256。

再次查询X$KFFXP,确认1号文件位置:

SQL> select GROUP_KFFXP, DISK_KFFXP ,AU_KFFXP from X$KFFXP where NUMBER_KFFXP=1 and GROUP_KFFXP=2;

GROUP_KFFXP DISK_KFFXP   AU_KFFXP

----------- ---------- ----------

2          0         48

为什么要查1号文件,还有X$KFFXP视图的详细说明,参见ASM的文件管理深入解析(内含开源的ASM文件挖掘研究版程序)

http://www.itpub.net/thread-1597605-1-1.html

1号文件在0号盘48号AU上。下面,确定0号盘是谁:

SQL> select DISK_NUMBER,path from v$asm_disk where GROUP_NUMBER=2;

DISK_NUMBER PATH

----------- ------------------------------

0 /dev/rdsk/c1t3d0s0

1 /dev/rdsk/c1t4d0s0

2 /dev/rdsk/c1t5d0s0

3 /dev/rdsk/c1t6d0s0

0号盘是/dev/rdsk/c1t3d0s0,使用kfed读取它的48号AU的256号块:

-bash-3.2$ kfed read /dev/rdsk/c1t3d0s0 AUSZ=4194304 BLKSZ=4096 aun=48 blkn=256|more

………………

kfffdb.strpwdth:                      1 ; 0x04c: 0x01

kfffdb.strpsz:                       22 ; 0x04d: 0x16

………………

上面这两个,就是256号ASM文件的条带宽度和条带大小。但是很遗憾,我们无法获知这两个值的意义。

但是,虽然无法知道这里的条带宽度为1、大小为22具体的意义。但在后面,我们可以通过改变_asm_stripesize、_asm_stripewidth,比较这两个值的变化,来分析_asm_stripesize、_asm_stripewidth这两个参数的意义。

暂时记着这两个值,后面会有点用。

三、观察IO的脚本

真正要搞清楚ASM的IO,还是要靠DTrace,可以使用如下脚本:

# cat dfio.d

#!/usr/sbin/dtrace -s

char *rd;

char bn[4];

int  file_id;

int  block_id;

BEGIN

{

i=0;

}

io:::start

/ args[2]->fi_pathname=="[url=]/devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,raw[/url]"||

args[2]->fi_pathname=="[url=]/devices/pci@0,0/pci15ad,1976@10/sd@4,0:a,raw[/url]"||

args[2]->fi_pathname=="[url=]/devices/pci@0,0/pci15ad,1976@10/sd@5,0:a,raw[/url]"||

args[2]->fi_pathname=="[url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url]" /

{

rd=copyin((uintptr_t )(args[0]->b_addr),16);

bn[0]=rd[4];

bn[1]=rd[5];

bn[2]=rd[6];

bn[3]=rd[7];

file_id=(*((int *)&bn[0])) >> 22;

block_id=(*((int *)&bn[0])) & 0x003fffff;

printf("IO number:%d %s %s %d %s pid=%d file_id:%d,block_id:%d",i,args[1]->dev_statname,args[2]->fi_pathname,args[0]->b_bcount/1024,args[0]->b_flags&B_READ?"R"

:"W",pid,file_id,block_id);

i++;

}

这块脚本意义说来话长,还是要参看“揭密Oracle之七种武器二:DTrace语法:跟踪物理IO

http://www.itpub.net/thread-1609235-1-1.html ”。

和“揭密Oracle之七种武器二”之中的区别是,这个脚本是针对数据文件,不是针对日志。为了多输出信息,我读取了每次IO的4至7字节。Oracle的数据块,4-7字节是RDBA,然后我从RDBA中解析出文件号和块号。这样,我们可以知道每次IO是访问的哪个文件几号块。

四、观察IO

先创建个测试表:

drop table iotest1;

create table iotest1 (id int,name varchar2(30)) tablespace tbs_e4m;

运行下面的命令,观察IO:

./dfio.d

向测试表中以直接路径方式写入数据:

insert /*+append*/ into iotest1 select rownum,'AAAAAA' from lhb.a2_70m;

commit;

然后,./dfio.d脚本会跟踪到很多IO信息,下面是跟踪结果:

number:0 sd4 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,raw[/url] 8 W pid=1172 file_id:5,block_id:1033

第一次IO是写1033号块,目的是什么不太清楚。这个块只是一个普通的数据块。

下面,从第2号IO开始,连续对[url=]/devices/pci@0,0/pci15ad,1976@10/sd@6[/url]这个设备写了16次。这个设备其实是/dev/rdsk/c1t6d0s0,2号磁盘组的第4块盘。

number:1 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 176 W pid=1371 file_id:5,block_id:522

number:2 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1371 file_id:5,block_id:544

number:3 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1371 file_id:5,block_id:576

number:4 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1371 file_id:5,block_id:608

number:5 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1371 file_id:5,block_id:640

number:6 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1371 file_id:5,block_id:672

number:7 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1371 file_id:5,block_id:704

number:8 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1371 file_id:5,block_id:736

number:9 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1371 file_id:5,block_id:768

number:10 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1371 file_id:5,block_id:800

number:11 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1371 file_id:5,block_id:832

number:12 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1371 file_id:5,block_id:864

number:13 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1371 file_id:5,block_id:896

number:14 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1371 file_id:5,block_id:928

number:15 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1371 file_id:5,block_id:960

number:16 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1371 file_id:5,block_id:992

第17次IO从992号块开始读,读了256K,也就是32个块。也就是992号块到1023号块。到此为止,IOTEST表的第一个区正好被读完。下面是IOTEST1的区信息:

SQL> select extent_id, file_id, block_id ,blocks from dba_extents where segment_name='IOTEST1';

EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS

---------- ---------- ---------- ----------

0          5        512        512

1          5       1024        512

2          5       1536        512

3          5       2048        512

4          5       2560        512

5          5       3072        512

6          5       3584        512

7          5       4096        512

8          5       4608        512

9          5       5120        512

10          5       5632        512

11          5       6144        512

12          5       6656        512

13          5       7168        512

14          5       7680        512

编号为0的区,从512号块开始,到1023号块止,共4M。AU大小也是4M,这应该也是256号文件的第一个AU。

下面,从第18次IO开始,开始写另外一个设备:[url=]/devices/pci@0,0/pci15ad,1976@10/sd@3,0:a[/url],也就是/dev/rdsk/c1t3d0s0,DG2的0号盘:

number:17 sd4 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,raw[/url] 192 W pid=1371 file_id:5,block_id:1032

number:18 sd4 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,raw[/url] 256 W pid=1371 file_id:5,block_id:1056

number:19 sd4 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,raw[/url] 256 W pid=1371 file_id:5,block_id:1088

从上面的结果来看,Oracle要写满一个4M的AU,才会再写另一个设备中的下一个AU。

我的条带大小是1M,看到没,1M的条带大小,并没有启到什么限制作用。在“揭密Oracle之七种武器二”中,我对10G的ASM观察,如果AU是1M,条带是128K,Oracle在第一个AU中写128K,然后换到下一个AU中再写下一个128K。

下面,继续探索,有没有可能,这4M的AU中,数据是不连贯的。比如,以1M为单位。或者,以256K为单位。因为DTrace跟踪结果,每次写IO,大小基本都是256K。我是如下验证的:

步1:获得256号ASM文件的AU分布:

SQL> select GROUP_KFFXP, DISK_KFFXP ,AU_KFFXP from X$KFFXP where NUMBER_KFFXP=256 and GROUP_KFFXP=2;

GROUP_KFFXP DISK_KFFXP   AU_KFFXP

----------- ---------- ----------

2          1          5

2          3          7

2          0          7

…………………………

第一个AU是1号盘5号AU,第二个AU是3号盘7号AU,等等。这里,第一个AU中是文件头,位图块和一些空块。从第二个AU开始,才是段数据。这一点,从上面我们显示的IOTEST1的区信息就可以确定:

EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS

---------- ---------- ---------- ----------

0          5        512        512

1          5       1024        512

2          5       1536        512

……………………

IOTEST1的第一个区,从512号块开始。也就是文件的第一个AU被跳过去了。

下面,已经确定表段数据从第二个AU开始,继续确认一下第二个AU中,表数据是以什么单位存放的,是条带大小的1M,还是IO大小的256K。

步2:确定第二个AU中数据是否连续:

确认这个有点困难,但一定要去确认一下。如果1M的条带大小发挥了作用,哪么,AU中第一个1M和第二个1M中的数据,是不连贯的。

文件的第二个AU是3号盘7号AU,这个盘是/dev/rdsk/c1t6d0s0,也就是我们的脚本跟踪出的2至17次IO的目标设备。

我用如下命令观察表数据:

dd if=/dev/rdsk/c1t6d0s0 bs=8192 skip=3584 count=1|od -x|more

我们要跳过前7个AU,每个AU是4M,所以,7*1024*4/8,等于3584。结果如下:

-bash-3.2$ dd if=/dev/rdsk/c1t6d0s0 bs=8192 skip=3584 count=1|od -x|more

0000000 a220 0000 0200 0140 47eb 0006 0000 0404

0000020 f71c 0000 0000 0000 0000 0000 0000 0000

……………………

注意,“0200 0140”,这是块的RDBA。因为大小端的原帮,要前后颠倒一下,01400200。根据前十个二进制位是文件号,后面是块号的算法,这是5号文件512号块。正是我们要找到iotest1表的第一个块。

将skip=3584改成skip=3585,就是读取IOTEST1的下一个块了。

我用这种方式,比了一下,结果/dev/rdsk/c1t6d0s0中这个AU是完整连续的4M数据。可以这样说,1M的条带没发挥作用。

实际上我不单查看RDBA,还对比了表中数据,可以百分之百确定,数据不是以1M为单位,而是以4M为单位存放。

五、换个条带大小再测:

删除原来的表空间和数据文件,修改隐藏参数,改变条带大小再测:

SQL> alter system set "_asm_stripesize"=524288;

System altered.

SQL> alter system set "_asm_stripewidth"=4;

System altered.

这次分别在ASM实例和数据库实例中做修改,将条带宽度定为4,条带大小改为512K。再重建表空间和表:

drop tablespace tbs_e4m INCLUDING CONTENTS AND DATAFILES;

create tablespace tbs_e4m datafile '+dg2/tbs_e4m_01.dbf' size 100m uniform size 4m;

drop table iotest1;

create table iotest1 (id int,name varchar2(30)) tablespace tbs_e4m;

然后启动跟踪脚本,再执行如下的命令:

insert /*+append*/ into iotest1 select rownum,'AAAAAA' from lhb.a2_70m;

commit;

我就不再粘跟踪结果了,无论是最终的跟踪结果、还是dd命令查看的结果,都和前面一样。kfffdb.strpwdth和kfffdb.strpsz也和以前一样。

_asm_stripesize和_asm_stripewidth根本就没发挥作用。搞这样两个参数,不过是个摆设而已。

所以,我把这种条带称为“不可调粗粒度条带”。

第 二 部分   可调细粒度条带一、传统的细粒度条带测试结果:

10G开始,有两种条带,细粒度128K,粗粒度1M。下面,用10G中传统的方式再设置一次,比较一下。

创建一个细粒度条带的模版(在ASM实例中运行):

SQL> alter diskgroup dg2 ADD TEMPLATE stp_fine ATTRIBUTES (UNPROTECTED fine);

Diskgroup altered.

创建使用此模版的表空间:

SQL> create tablespace tbs_e4m4 datafile '+dg2(stp_fine)/tbs_e4m4_01.dbf' size 100m reuse uniform size 4m;

Tablespace created.

创建测试表:

SQL> create table iotest2 (id int,name varchar2(30)) tablespace tbs_e4m4;

Table created.

开启跟踪脚本,插入:

SQL> insert /*+append*/ into iotest2 select rownum,'AAAAAA' from lhb.a2_70m;

3087162 rows created.

SQL> commit;

Commit complete.

查看跟踪结果:

number:0 sd5 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@4,0:a,raw[/url] 176 W pid=1173 file_id:6,block_id:74

number:1 sd5 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@4,0:a,raw[/url] 256 W pid=1173 file_id:6,block_id:96

number:2 sd6 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@5,0:a,raw[/url] 256 W pid=1173 file_id:6,block_id:128

number:3 sd6 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@5,0:a,raw[/url] 256 W pid=1173 file_id:6,block_id:160

number:4 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1173 file_id:6,block_id:192

number:5 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1173 file_id:6,block_id:224

number:6 sd4 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,raw[/url] 256 W pid=1173 file_id:6,block_id:256

number:7 sd4 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,raw[/url] 256 W pid=1173 file_id:6,block_id:288

number:8 sd5 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@4,0:a,raw[/url] 256 W pid=1173 file_id:6,block_id:320

number:9 sd5 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@4,0:a,raw[/url] 256 W pid=1173 file_id:6,block_id:352

根据结果很容易发现,每个盘Oracle写512K。

下面,看一下每个盘中连续的数据,根据这个,确认一下条带的大小。

我不再详细描述此过程了,查询select GROUP_KFFXP, DISK_KFFXP ,AU_KFFXP from X$KFFXP where NUMBER_KFFXP=257 and GROUP_KFFXP=2; ,找到257号文件的第2个AU所在磁盘。使用dd if=/dev/rdsk/c1t4d0s0 bs=8192 skip=5184|od -tx|more,观察结果,每个AU Oracle的确使用了512K,就开始使用下一AU。

也就是说,细粒度条带下,条带大小不再是等同AU大小,而是512K。

查看257号文件kfffdb结构:

bash-3.2$ kfed read /dev/rdsk/c1t3d0s0 AUSZ=4194304 BLKSZ=4096 aun=48 blkn=257|more

…………………………

kfffdb.strpwdth:                      4 ; 0x04c: 0x04

kfffdb.strpsz:                       19 ; 0x04d: 0x13

…………………………

kfffdb.strpwdth、kfffdb.strpsz和以前果然不一样了。kfffdb.strpwdth不再是以前的1,而是4。kfffdb.strpsz变为了19。

但有一点很不巧,我之前曾把_asm_stripesize调为512K,是否这个参数终于发获了作用?

我不再详细列出测试步骤,在ASM实例和数据库实例分别修改参数,我是将宽度修改为2,将大小改为256K。删除表空间再重建,条带大小、IO大小依旧。

正在我将要宣判这两个参数是无意义的参数时。转机出现了。但只要不放弃,转机一定会出现。

二、如何让_asm_stripesize、_asm_stripewidth发挥作用:

这两个参数还是有很大作用的,并不只是个摆设。要不然,全球哪么多尖子DBA,又是和IO相关这么重要的问题,总会有人发现这两个摆设。到哪时,Oracle的脸往哪儿搁。

如下步骤调整参数,才会有意义:

步1:删除表空间,调整参数,再建表空间:

SQL>    drop tablespace tbs_e4m4 INCLUDING CONTENTS AND DATAFILES;

Tablespace dropped.

SQL> alter system set "_asm_stripewidth"=2;

System altered.

SQL> alter system set "_asm_stripesize"=262144;

System altered.

注意,调整参数,在ASM实例和数据库实例都做。条带宽度调为2,条带大小为256K。

步2:在调整参数后,在ASM实例中再添加一个模版:

SQL> alter diskgroup dg2 ADD TEMPLATE stp_fine2 ATTRIBUTES (UNPROTECTED fine);

Diskgroup altered.

这一步是关键,在修改参数后,我们要明确创建新的模版。这样,我们修改的参数,才会有意义。

步3:在数据库实例中创建使用这个模版的表空间:

SQL> create tablespace tbs_e4m4 datafile '+dg2(stp_fine2)/tbs_e4m4_01.dbf' size 100m reuse uniform size 4m;

Tablespace created.

在ASM中,删除文件马上再建,文件号不变,tbs_e4m4_01.dbf还是257号文件,可以马上确认一下kfffdb结构中的条带信息:

bash-3.2$ kfed read /dev/rdsk/c1t3d0s0 AUSZ=4194304 BLKSZ=4096 aun=48 blkn=257|more

…………………………

kfffdb.strpwdth:                      2 ; 0x04c: 0x02

kfffdb.strpsz:                       18 ; 0x04d: 0x12

…………………………

的确已经变了。宽度已经变为了2。大小变为了18。目前还不知道18和我们的条带大小256K之间具体的联系。

下面,进一步用dfio.d脚本观察IO:

在数据库实例中完成一个插入:

SQL> create table iotest2 (id int,name varchar2(30)) tablespace tbs_e4m4;

Table created.

SQL> insert /*+append*/ into iotest2 select rownum,'AAAAAA' from lhb.a2_70m;

3087162 rows created.

SQL> commit;

Commit complete.

用dfio.d观察:

bash-3.2# ./dfio.d

dtrace: script './dfio.d' matched 7 probes

下面是观察结果:

number:0 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 176 W pid=1194 file_id:6,block_id:42

number:1 sd5 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@4,0:a,raw[/url] 256 W pid=1194 file_id:6,block_id:64

number:2 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1194 file_id:6,block_id:96

number:3 sd5 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@4,0:a,raw[/url] 256 W pid=1194 file_id:6,block_id:128

………………………………

………………………………

………………………………

number:29 sd5 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@4,0:a,raw[/url] 256 W pid=1194 file_id:6,block_id:960

number:30 sd7 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw[/url] 256 W pid=1194 file_id:6,block_id:992

………………………………

………………………………

………………………………

number:31 sd6 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@5,0:a,raw[/url] 256 W pid=1194 file_id:6,block_id:1024

number:32 sd4 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,raw[/url] 192 W pid=1194 file_id:6,block_id:1064

number:33 sd6 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@5,0:a,raw[/url] 256 W pid=1194 file_id:6,block_id:1088

number:34 sd4 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,raw[/url] 256 W pid=1194 file_id:6,block_id:1120

………………………………

DG2磁盘组中,共有4块盘,因为我的条带宽度是2,条带大小是256K。Oracle 0至30次IO,交替写[url=]/devices/pci@0,0/pci15ad,1976@10/sd@6[/url]、[url=]/devices/pci@0,0/pci15ad,1976@10/sd@4[/url]这两个设备。也就是/dev/rdsk/c1t6d0s0、/dev/rdsk/c1t4d0s0这两个盘,每次写256K。写了31次,也就是8M了。

接下来的32次IO,是交替写另外两块磁盘:/dev/rdsk/c1t5d0s0、/dev/rdsk/c1t3d0s0,每个盘各写16次。也就是每个盘各写满一个AU。

注意,我们不能放过每一个细节。/dev/rdsk/c1t6d0s0、/dev/rdsk/c1t4d0s0这两个盘,交替写了31次,8M差256K。

对比IOTEST2的区信息:

SQL> select extent_id, file_id, block_id ,blocks from dba_extents where segment_name='IOTEST2';

EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS

---------- ---------- ---------- ----------

0          6         32        512

1          6        544        512

2          6       1056        512

3          6       1568        512

4          6       2080        512

5          6       2592        512

6          6       3104        512

7          6       3616        512

8          6       4128        512

9          6       4640        512

10          6       5152        512

11          6       5664        512

12          6       6176        512

13          6       6688        512

14          6       7200        512

15 rows selected.

前两个区是32号块到543号块,544号块到1055号块。再对比我们观察到的IO情况:

number:31 sd6 [url=]/devices/pci@0,0/pci15ad,1976@10/sd@5,0:a,raw[/url] 256 W pid=1194 file_id:6,block_id:1024

0至30次IO写的是另外两个设备:[url=]/devices/pci@0,0/pci15ad,1976@10/sd@6[/url]、[url=]/devices/pci@0,0/pci15ad,1976@10/sd@4[/url]。31次IO写的是[url=]/devices/pci@0,0/pci15ad,1976@10/sd@5[/url]。文件号是6,块号是1024,到1056号块开始,才是第三个区。这意味着什么,第二个区横跨了4块盘中的三个盘。原因是区大小为4M,但257号文件的第一个AU最前面的块,是文件头。在原来条带宽度为1、大小为4M的情况下,第一个AU中第一块条带(其实就是整个第一个AU)被做为文件头。当然,文件头用不了4M,其他空间由于不满4M,被废弃不用。现在条带大小是256K,第一个AU中第一块条带同样被占用做文件头。由于有4M的AU中被占了256K,4M的区无法完全放的下,到另一个盘中再占256K的情况也就出现了。所以,偶而有一个区会横跨3个盘(两块盘是条带,一块盘是放多出的256K)。

三、总结

我做过测试,修改条带参数,以这样的方式创建模版:

alter diskgroup dg2 ADD TEMPLATE stp_c1 ATTRIBUTES (UNPROTECTED coarse);

哪么,参数是不会发挥作用的。

总结一下ASM的条带设置:

1、UNPROTECTED coarse 粗粒度条带下,条带宽度、条带大小不可改变。条带宽度将一直是1,条带大不等同于AU大小。这就是我所说的“不可调粗粒度条带”。

2、UNPROTECTED fine 细粒度条带下,条带宽度、条带大小可使用_asm_stripesize、_asm_stripewidth两个隐藏参数调节。这就是“可调细粒度条带”。

Oracle对_asm_stripesize参数的最大值有要求,最大不能超过1M。因此,使用UNPROTECTED fine方式,条带最大只能是1M。

而UNPROTECTED coarse下,条带大小随AU而定,条带大小可以很大。

还有两个疑问,一是我的DTrace脚本,都是观察的写IO,观察到的读IO,最大的IO大小,根据条带大小而定。

对于不可调粗粒度条带,AU大小为4M,将表的区也定为4M,最大的IO,不会超过1M。

对于可调细粒度条带,条带大小为512K时,最大IO是512K。条带大小是256K,最大的IO是256K。

这些也都是可以观察到的。但是读IO会同时观察到很多很小的64K为单位的IO,且RDBA并非正常的数据块。这些IO是干码的,还没有进一步研究。

另外一个疑问,全表扫描的读IO,最大会是1M,但写IO,最大只是256K,还没进一步研究是否有方法提高这个值。

最后

以上就是真实龙猫为你收集整理的aix stripe size for oracle,ASM条带揭密----_asm_stripesize、_asm_stripewidth参数的设置和影响...的全部内容,希望文章能够帮你解决aix stripe size for oracle,ASM条带揭密----_asm_stripesize、_asm_stripewidth参数的设置和影响...所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(34)

评论列表共有 0 条评论

立即
投稿
返回
顶部