“磁盤組的rebalance什麼時候能完成?”,這個問題我經常被問到,但是如果你期望我給出一個具體的數值,那麼你會失望,畢竟asm本身已經給你提供了一個估算值(gv$asm_operation.est_minutes),其實你想知道的是rebalance完成的精确的時間。雖然我不能給你一個精确的時間,但是我可以給你一些rebalance的操作細節,讓你知道目前rebalance是否正在進行中,進行到哪個階段,以及這個階段是否需要引起你的關注。
就像在本asm系列文章的“rebalancing act”章介紹過的,rebalance操作本身包含了3個階段-planning, extents relocation 和 compacting,就rebalance需要的總時間而言,planning階段需要的時間是非常少的,你通常都不用去關注這一個階段,第二個階段extent relocation一般會占取rebalance階段的大部分時間,也是我們最為需要關注的階段,最後我們也會講述第三階段compacting階段在做些什麼。
首先需要明白為什麼會需要做rebalance,如果你為了增加磁盤組的可用空間,增加了一塊新磁盤,你可能并不太會關注rebalance什麼時候完成,好吧,也可能确實你需要關注,比如你的歸檔空間所在的dg滿了,導緻資料庫hang了。相似的,如果你為了調整磁盤的空間,例如resizing或者删除磁盤,你可能也不會太去關注rebalance啥時候完成。
但是,如果磁盤組中的一塊磁盤損壞了,這個時候你就有足夠的理由關注rebalance的進度了,假如,你的磁盤組是normal備援的,這個時候萬一你損壞磁盤的partner磁盤也損壞,那麼你的整個磁盤組會被dismount,所有跑在這個磁盤組上的資料庫都會crash,你可能還會丢失資料。在這種情況下,你非常需要知道rebalance什麼時候完成,實際上,你需要知道第二個階段extent relocation什麼時候完成,一旦它完成了,整個磁盤組的備援就已經完成了(第三個階段對于備援度來說并不重要,後面會介紹)。
為了進一步觀察extents relocation階段,我删除了具有預設并行度的磁盤組上的一塊磁盤:
sql> show parameter power
name type value
------------------------------------ ----------- ----------------
asm_power_limit integer 1
sql> set time on
16:40:57 sql> alter diskgroup data1 drop disk data1_cd_06_cell06;
diskgroup altered.
asm的視圖gv$asmoperation的estminutes字段給出了估算值的時間,機關為分鐘,這裡給出的估算時間為26分鐘。
16:41:21 sql> select inst_id, operation, state, power, sofar, est_work, est_rate, est_minutes from gv$asm_operation where group_number=1;
inst_id opera stat power sofar est_work est_rate est_minutes
---------- ----- ---- ---------- ---------- ---------- ---------- -----------
3 rebal wait 1
2 rebal run 1 516 53736 2012 26
4 rebal wait 1
大約過了10分鐘後,est_minutes的值變為了24分鐘:
16:50:25 sql> /
2 rebal run 1 19235 72210 2124 24
有些時候est_minutes的值可能并不能給你太多的證據,我們還可以看到sofar(截止目前移動的ua數)的值一直在增加,恩,不錯,這是一個很好的一個觀察名額。
asm的alert日志中也顯示了删除磁盤的操作,以及os arb0程序的id,asm用它用來做所有的rebalance工作。更重要的,整個過程之中,沒有任何的錯誤輸出:
wed jul 11 16:41:15 2012
sql> alter diskgroup data1 drop disk data1_cd_06_cell06
note: groupblock outside rolling migration privileged region
note: requesting all-instance membership refresh for group=1
...
note: starting rebalance of group 1/0x6ecaf3e6 (data1) at power 1
starting background process arb0
wed jul 11 16:41:24 2012
arb0 started with pid=41, os id=58591
note: assigning arb0 to group 1/0x6ecaf3e6 (data1) with 1 parallel i/o
note: f1x0 copy 3 relocating from 0:2 to 55:35379 for diskgroup 1 (data1)
arb0程序的跟蹤檔案也顯示了,目前正在對哪一個asm檔案的extent的在進行重配置設定,也是通過這個跟蹤檔案,我們可以知道arb0确實是在幹着自己的本職工作,沒有偷懶。
$ tail -f /u01/app/oracle/diag/asm/+asm/+asm2/trace/+asm2_arb0_58591.trc
arb0 relocating file +data1.282.788356359 (120 entries)
*** 2012-07-11 16:48:44.808
arb0 relocating file +data1.283.788356383 (120 entries)
*** 2012-07-11 17:13:11.761
arb0 relocating file +data1.316.788357201 (120 entries)
*** 2012-07-11 17:13:16.326
注意,跟蹤目錄下的arb0的跟蹤檔案可能會有很多,是以我們需要知道arb0的os是程序号,是哪一個arb0在實際做rebalance的工作,這個資訊在asm執行個體執行rebalance操作的時候,alert檔案中會有顯示。
我們還可以通過作業系統指令pstack來跟蹤arb0程序,檢視具體它在做什麼,如下,它向我們顯示了,asm正在重配置設定extent(在堆棧中的關鍵函數 kfgbrebalexecute - kfdaexecute - kffrelocate):
# pstack 58591
#0 0x0000003957ccb6ef in poll () from /lib64/libc.so.6
#9 0x0000000003d711e0 in kfk_reap_oss_async_io ()
#10 0x0000000003d70c17 in kfk_reap_ios_from_subsys ()
#11 0x0000000000aea50e in kfk_reap_ios ()
#12 0x0000000003d702ae in kfk_io1 ()
#13 0x0000000003d6fe54 in kfkrequest ()
#14 0x0000000003d76540 in kfk_transitio ()
#15 0x0000000003cd482b in kffrelocatewait ()
#16 0x0000000003cfa190 in kffrelocate ()
#17 0x0000000003c7ba16 in kfdaexecute ()
#18 0x0000000003d4beaa in kfgbrebalexecute ()
#19 0x0000000003d39627 in kfgbdriver ()
#20 0x00000000020e8d23 in ksbabs ()
#21 0x0000000003d4faae in kfgbrun ()
#22 0x00000000020ed95d in ksbrdp ()
#23 0x0000000002322343 in opirip ()
#24 0x0000000001618571 in opidrv ()
#25 0x0000000001c13be7 in sou2o ()
#26 0x000000000083ceba in opimai_real ()
#27 0x0000000001c19b58 in ssthrdmain ()
#28 0x000000000083cda1 in main ()
大約過了35分鐘後est_minutes的值變為了0
17:16:54 sql> /
2 rebal run 1 74581 75825 2129 0
很快的,asm的alert日志中顯示:
disk emptied
disk header erased
pst update completed successfully
disk closed
rebalance completed
wed jul 11 17:17:32 2012
wed jul 11 17:17:41 2012
gmon updating for reconfiguration, group 1 at 20 for pid 38, osid 93832
note: group 1 pst updated.
success: grp 1 disk data1_cd_06_cell06 emptied
note: erasing header on grp 1 disk data1_cd_06_cell06
note: process _x000_+asm2 (93832) initiating offline of disk 0.3916039210 (data1_cd_06_cell06) with mask 0x7e in group 1
note: initiating pst update: grp = 1, dsk = 0/0xe96a042a, mask = 0x6a, op = clear
gmon updating disk modes for group 1 at 21 for pid 38, osid 93832
note: pst update grp = 1 completed successfully
note: initiating pst update: grp = 1, dsk = 0/0xe96a042a, mask = 0x7e, op = clear
gmon updating disk modes for group 1 at 22 for pid 38, osid 93832
note: cache closing disk 0 of grp 1: data1_cd_06_cell06
gmon updating for reconfiguration, group 1 at 23 for pid 38, osid 93832
note: cache closing disk 0 of grp 1: (not open) data1_cd_06_cell06
note: membership refresh pending for group 1/0x6ecaf3e6 (data1)
gmon querying group 1 at 24 for pid 19, osid 38421
gmon querying group 1 at 25 for pid 19, osid 38421
note: disk in mode 0x8 marked for de-assignment
success: refreshed membership for 1/0x6ecaf3e6 (data1)
note: stopping process arb0
success: rebalance completed for group 1/0x6ecaf3e6 (data1)
note: attempting voting file refresh on diskgroup data1
是以asm預估了26分鐘的時間來完成rebalance,但實際上卻使用了36分鐘的時候(在這個場景裡compacting階段隻花取了不到一分鐘的時候,我們忽略它好了),是以首先能知道rebalance正在做什麼非常重要,然後才能知道rebalance什麼時候能完成。
注意,估算的時間是動态變化的,可能會增加或減少,這個依賴你的系統負載變化,以及你的rebalance的power值的設定,對于一個非常大容量的磁盤組來說,可能rebalance會花費你數小時甚至是數天的時間。
在下面的例子裡,我們來看下rebalance的compacting階段,我把上面删除的磁盤加回來,同時設定rebalance的power為10:
17:26:48 sql> alter diskgroup data1 add disk '/o/*/data1_cd_06_celll06' rebalance power 10;
asm給出的rebalance的估算時間為6分鐘:
17:27:22 sql> select inst_id, operation, state, power, sofar, est_work, est_rate, est_minutes from gv$asm_operation where group_number=1;
2 rebal run 10 489 53851 7920 6
3 rebal wait 10
4 rebal wait 10
大約10分鐘後,est_minutes的值變為0.
17:39:05 sql> /
2 rebal run 10 92407 97874 8716 0
這個時候我們在asm的alert日志中觀察到:
wed jul 11 17:39:49 2012
wed jul 11 17:39:58 2012
gmon updating for reconfiguration, group 1 at 31 for pid 43, osid 115117
gmon querying group 1 at 32 for pid 19, osid 38421
上面的輸出意味着asm已經完成了rebalance的第二個階段,開始了第三個階段compacting,如果我說的沒錯,通過pstack工具可以看到kfdcompact()函數,下面的輸出顯示,确實如此;
# pstack 103326
#18 0x0000000003c4b737 in kfdcompact ()
#19 0x0000000003c4c6d0 in kfdexecute ()
#20 0x0000000003d4bf0e in kfgbrebalexecute ()
#21 0x0000000003d39627 in kfgbdriver ()
#22 0x00000000020e8d23 in ksbabs ()
#23 0x0000000003d4faae in kfgbrun ()
#24 0x00000000020ed95d in ksbrdp ()
#25 0x0000000002322343 in opirip ()
#26 0x0000000001618571 in opidrv ()
#27 0x0000000001c13be7 in sou2o ()
#28 0x000000000083ceba in opimai_real ()
#29 0x0000000001c19b58 in ssthrdmain ()
#30 0x000000000083cda1 in main ()
通過tail指令檢視arb0的跟蹤檔案,發現relocating正在進行,而且一次隻對一個條目進行relocating。(這是正進行到compacting階段的另一個重要線索):
$ tail -f /u01/app/oracle/diag/asm/+asm/+asm2/trace/+asm2_arb0_103326.trc
arb0 relocating file +data1.321.788357323 (1 entries)
compacting過程中,v$asm_operation視圖的est_minutes字段會顯示為0(也是一個重要線索):
17:42:39 sql> /
2 rebal run 10 98271 98305 7919 0
固态表x$kfgmg的rebalst_kfgmg字段會顯示為2,代表正在compacting。
17:42:50 sql> select number_kfgmg, op_kfgmg, actual_kfgmg, rebalst_kfgmg from x$kfgmg;
number_kfgmg op_kfgmg actual_kfgmg rebalst_kfgmg
------------ ---------- ------------ -------------
1 1 10 2
一旦compacting階段完成,asm的alert 日志中會顯示stopping process arb0 和rebalance completed:
wed jul 11 17:43:48 2012
在這個case中,第二階段extents relocation花費了12分鐘,第三階段compacting話費了4分鐘。
在真正的環境中,compacting階段可能會占用掉比較可觀的rebalance時間,曾經遭遇過一個案例,extents relocation 花費了60分鐘,而compacting操作花費了30分鐘。但是其實compacting的消耗時間多少并不重要,因為一旦extents relocation完成,所有的資料就已經滿足了備援度的要求,不再會擔心已經失敗磁盤的partern磁盤再次失敗而出現嚴重故障。
rebalance的power可以在磁盤組rebalance過程中動态的更改,如果你認為磁盤組的預設級别太低了,可以去很容易的增加它。但是增加到多少呢?這個需要你根據你系統的io負載,io吞吐量來定。一般情況下,你可以先嘗試增加到一個保守的值,例如5,過上十分鐘看是否有所提升,以及是否影響到了其他業務對io的使用,如果你的io性能非常強,那麼可以繼續增加power的值,但是就我的經驗來看,很少能看到power 的設定超過30後還能有較大提升的。
測試的關鍵點在于,你需要在你生産系統的正常負載下去測試,不同的業務壓力,不同的存儲系統,都可能會讓rebalance時間産生較大的差異。
<b>本文來自雲栖社群合作夥伴“dbgeek”</b>