ASM條帶揭密----_asm_stripesize、_asm_stripewidth引數的設定和影響

vage發表於2012-08-13
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
 http://www.itpub.net/thread-1609235-1-1.html ”提到的方法,跟蹤作業系統驅動層的IO資訊。通過IO的分佈、IO大小,來了解條帶的影響。
 好,我們將兩種方式都採用,結合起來判斷。
 先來個圖,瞭解一下條帶大小、寬度,AU大小的影響吧:
ASM條帶揭密----_asm_stripesize、_asm_stripewidth引數的設定和影響
圖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。
 就像我們上面例子中所說,如果AU、條帶大小是4M,ASM雖然可以在每個磁碟上連續儲存4M資料,但發生IO操作時,每次IO的大小最大還是1M,連續的4M資料,還是需要4次IO才能操作完。
 當然大於1M的AU也有一點好處,比如4M的AU大小下,如果的確是大IO訪問,OS的上限是一次讀1M,所以磁碟上連續4M資料,要分4次IO來讀。雖然是4次IO,但卻是4次連續IO。比4次不連續的IO,還是要有點優勢的。但是,這是不考慮併發的情況下。如果有併發,程式A讀一次IO後,下一次IO開始前很可能有另一個程式進行了另外的IO操作。程式A再進行下一次IO,很可能和上一次IO在磁碟上位置相差很遠。總的來說,大於1M的IO,對全表掃描操作效能的提升,會有影響,但影響不大。
 我們剛才一直在說大IO操作。如果是小IO操作,在OLTP中,更多的是8K的小IO操作。對於Redo,則更多是1K、2K甚至512位元組的寫IO操作。如果程式要讀、寫8K資料,AU大小、條帶大小是否對8K讀、寫有影響呢?
 答案是基本上無影響。根據AU、條帶規,程式先計算出要讀、寫的8K資料在哪塊磁碟中,然後,直接到這塊磁碟上讀、寫8K就行了。
 無論條帶多大,最小的IO大小都是512位元組,程式想讀、寫多大,就讀、寫多大。不必一次讀、寫一個條帶。
 好,下面再看下一個圖:
ASM條帶揭密----_asm_stripesize、_asm_stripewidth引數的設定和影響
圖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歲:撿點我的職業生涯    http://www.itpub.net/thread-1602563-1-1.html),提到過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的問題了。
 好,再看一張圖吧:
ASM條帶揭密----_asm_stripesize、_asm_stripewidth引數的設定和影響
圖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=="/devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,raw"||
  args[2]->fi_pathname=="/devices/pci@0,0/pci15ad,1976@10/sd@4,0:a,raw"||
  args[2]->fi_pathname=="/devices/pci@0,0/pci15ad,1976@10/sd@5,0:a,raw"||
  args[2]->fi_pathname=="/devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw" /
{
        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 /devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,raw 8 W pid=1172 file_id:5,block_id:1033
 第一次IO是寫1033號塊,目的是什麼不太清楚。這個塊只是一個普通的資料塊。
 下面,從第2號IO開始,連續對/devices/pci@0,0/pci15ad,1976@10/sd@6這個裝置寫了16次。這個裝置其實是/dev/rdsk/c1t6d0s0,2號磁碟組的第4塊盤。
 
number:1 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 176 W pid=1371 file_id:5,block_id:522
number:2 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 256 W pid=1371 file_id:5,block_id:544
number:3 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 256 W pid=1371 file_id:5,block_id:576
number:4 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 256 W pid=1371 file_id:5,block_id:608
number:5 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 256 W pid=1371 file_id:5,block_id:640
number:6 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 256 W pid=1371 file_id:5,block_id:672
number:7 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 256 W pid=1371 file_id:5,block_id:704
number:8 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 256 W pid=1371 file_id:5,block_id:736
number:9 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 256 W pid=1371 file_id:5,block_id:768
number:10 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 256 W pid=1371 file_id:5,block_id:800
number:11 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 256 W pid=1371 file_id:5,block_id:832
number:12 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 256 W pid=1371 file_id:5,block_id:864
number:13 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 256 W pid=1371 file_id:5,block_id:896
number:14 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 256 W pid=1371 file_id:5,block_id:928
number:15 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 256 W pid=1371 file_id:5,block_id:960
number:16 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 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開始,開始寫另外一個裝置:/devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,也就是/dev/rdsk/c1t3d0s0,DG2的0號盤:
number:17 sd4 /devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,raw 192 W pid=1371 file_id:5,block_id:1032
number:18 sd4 /devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,raw 256 W pid=1371 file_id:5,block_id:1056
number:19 sd4 /devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,raw 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 /devices/pci@0,0/pci15ad,1976@10/sd@4,0:a,raw 176 W pid=1173 file_id:6,block_id:74
number:1 sd5 /devices/pci@0,0/pci15ad,1976@10/sd@4,0:a,raw 256 W pid=1173 file_id:6,block_id:96
number:2 sd6 /devices/pci@0,0/pci15ad,1976@10/sd@5,0:a,raw 256 W pid=1173 file_id:6,block_id:128
number:3 sd6 /devices/pci@0,0/pci15ad,1976@10/sd@5,0:a,raw 256 W pid=1173 file_id:6,block_id:160
number:4 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 256 W pid=1173 file_id:6,block_id:192
number:5 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 256 W pid=1173 file_id:6,block_id:224
number:6 sd4 /devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,raw 256 W pid=1173 file_id:6,block_id:256
number:7 sd4 /devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,raw 256 W pid=1173 file_id:6,block_id:288
number:8 sd5 /devices/pci@0,0/pci15ad,1976@10/sd@4,0:a,raw 256 W pid=1173 file_id:6,block_id:320
number:9 sd5 /devices/pci@0,0/pci15ad,1976@10/sd@4,0:a,raw 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 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 176 W pid=1194 file_id:6,block_id:42
number:1 sd5 /devices/pci@0,0/pci15ad,1976@10/sd@4,0:a,raw 256 W pid=1194 file_id:6,block_id:64
number:2 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 256 W pid=1194 file_id:6,block_id:96
number:3 sd5 /devices/pci@0,0/pci15ad,1976@10/sd@4,0:a,raw 256 W pid=1194 file_id:6,block_id:128
………………………………
………………………………
………………………………
number:29 sd5 /devices/pci@0,0/pci15ad,1976@10/sd@4,0:a,raw 256 W pid=1194 file_id:6,block_id:960
number:30 sd7 /devices/pci@0,0/pci15ad,1976@10/sd@6,0:a,raw 256 W pid=1194 file_id:6,block_id:992
………………………………
………………………………
………………………………
number:31 sd6 /devices/pci@0,0/pci15ad,1976@10/sd@5,0:a,raw 256 W pid=1194 file_id:6,block_id:1024
number:32 sd4 /devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,raw 192 W pid=1194 file_id:6,block_id:1064
number:33 sd6 /devices/pci@0,0/pci15ad,1976@10/sd@5,0:a,raw 256 W pid=1194 file_id:6,block_id:1088
number:34 sd4 /devices/pci@0,0/pci15ad,1976@10/sd@3,0:a,raw 256 W pid=1194 file_id:6,block_id:1120
………………………………
 DG2磁碟組中,共有4塊盤,因為我的條頻寬度是2,條帶大小是256K。Oracle 0至30次IO,交替寫/devices/pci@0,0/pci15ad,1976@10/sd@6/devices/pci@0,0/pci15ad,1976@10/sd@4這兩個裝置。也就是/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 /devices/pci@0,0/pci15ad,1976@10/sd@5,0:a,raw 256 W pid=1194 file_id:6,block_id:1024
 0至30次IO寫的是另外兩個裝置:/devices/pci@0,0/pci15ad,1976@10/sd@6/devices/pci@0,0/pci15ad,1976@10/sd@4。31次IO寫的是/devices/pci@0,0/pci15ad,1976@10/sd@5。檔案號是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,還沒進一步研究是否有方法提高這個值。
 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/321157/viewspace-740874/,如需轉載,請註明出處,否則將追究法律責任。

相關文章