一次RAC VIP漂移的結果診斷及修複
背景概述
客戶的10G資料庫VIP出現宕,引起VIP負載到另一個節點
事件支援細節
04:29:56.378 一號機器VIP 出現 went OFFLINE unexpectedly,當天出現這個VIP漂移的故障後為檢查VIP宕掉的原因,
對VIP資源啟動DEBUG 5模式:./crsctl debug log res "orahostname1.vip:5"
04:38:36.047 一號節點VIP 出現 went OFFLINE unexpectedly。
根據ora.hostname.vip.log日誌顯示,出現VIP宕原因基本可以確定為公網IP與預設網管通訊不暢引起。
根據Oracle管方建議,調整racgvip程式中的參數從 FAIL_WHEN_DEFAULTGW_NO_FOUND=1 修改成
FAIL_WHEN_DEFAULTGW_NO_FOUND=0
但是調整完後故障依舊
04:17:37.822: [ CRSRES][11025]32ora.hostname1.vip on hostname1 went OFFLINE unexpectedly
為明確原因,再次收集ora.hostname1.vip.log及racgvip 資訊進行分析
分析結果如下:
在racgvip程式中,有如下代碼
# Check the status of the interface thro' pinging gateway
if [ -n "$DEFAULTGW" ]
then
_RET=1
# get base IP address of the interface
tmpIP=`$LSATTR -El ${_IF} -a netaddr | $AWK '{print $2}'`
# get RX packets numbers (bug8341569,9157855->bug9743421)
_O1=`$NETSTAT -n -I $_IF | $AWK "{ if (/^$_IF/) {print \\$(NF-4); exit}}"`
x=$CHECK_TIMES
while [ $x -gt 0 ]
do
if [ -n "$tmpIP" ]
then
logx "About to execute command: $PING -S $tmpIP $PING_TIMEOUT $DEFAULTGW"
$PING -S $tmpIP $PING_TIMEOUT $DEFAULTGW > /dev/null 2>&1
else
logx "About to execute command: $PING $PING_TIMEOUT $DEFAULTGW"
$PING $PING_TIMEOUT $DEFAULTGW > /dev/null 2>&1
fi
_O2=`$NETSTAT -n -I $_IF | $AWK "{ if (/^$_IF/) {print \\$(NF-4); exit}}"`
if [ "$_O1" != "$_O2" ]
then
# RX packets numbers changed
_RET=0
break
fi
$SLEEP 1
x=`$EXPR $x - 1`
done
if [ $_RET -ne 0 ]
then
logx "IsIfAlive: RX packets checked if=$_IF failed"
else
logx "IsIfAlive: RX packets checked if=$_IF OK"
fi
else
logx "IsIfAlive: Default gateway is not defined (host=$HOSTNAME)"
if [ $FAIL_WHEN_DEFAULTGW_NO_FOUND -eq 1 ]
then
_RET=1
else
_RET=0
fi
fi
從源碼我們可以看到檢查預設網關的處理邏輯
1、如果檢測到預設網關存在執行網管檢查邏輯
2、_01收集網卡網路包量
3、$PING -S $tmpIP $PING_TIMEOUT $DEFAULTGW ping網管
4、_02再次收集網卡網路包量
5、如果_01網卡網路包量 與 _02網卡網路包量不相同,表明網卡與預設網卡之間通訊正常 _RET 返回編碼為0
6、如果_01網卡網路包量 與 _02網卡網路包量相同,_RET 返回編碼沒指定,預設返回1,同時列印日誌logx "IsIfAlive: RX packets checked if=$_IF failed",即判斷網卡失敗。
FAIL_WHEN_DEFAULTGW_NO_FOUND參數從1修改成0,是為了跳過網關ping檢測,而從源碼中我們可以看到,FAIL_WHEN_DEFAULTGW_NO_FOUND參數只有在網卡參數$DEFAULTGW為空白才生效,即主機上沒有配置網關並且參數FAIL_WHEN_DEFAULTGW_NO_FOUND配置為非1時返回碼RET為0。
由於我們的環境中DEFAULTGW能擷取成功及DEFAULTGW非空,導致程式沒有進入FAIL_WHEN_DEFAULTGW_NO_FOUND判斷是否為1的處理流程。
故障期間DEBUG錯誤資訊如下:
2013-11-06 04:17:37.776: [ RACG][1] [18219068][1][ora.s9lp1.vip]: Wed Nov 6 04:17:33 CST 2013 [ 6422696 ] checkIf: start for if=en5
Wed Nov 6 04:17:33 CST 2013 [ 6422696 ] IsIfAlive: start for if=en5
Wed Nov 6 04:17:33 CST 2013 [ 6422696 ] defaultgw: started
2013-11-06 04:17:37.776: [ RACG][1] [18219068][1][ora.s9lp1.vip]: Wed Nov 6 04:17:33 CST 2013 [ 6422696 ] defaultgw: completed with 10.0.241.254 (網關擷取成功,網關為10.0.241.254)
Wed Nov 6 04:17:33 CST 2013 [ 6422696 ] About to execute command: /usr/sbin/ping -S 10.0.241.150 -c 1 -w 1 10.0.241.254
2013-11-06 04:17:37.777: [ RACG][1] [18219068][1][ora.s9lp1.vip]: Wed Nov 6 04:17:35 CST 2013 [ 6422696 ] About to execute command: /usr/sbin/ping -S 10.0.241.150 -c 1 -w 1 10.0.241.254 (PING 網關)
Wed Nov 6 04:17:37 CST 2013 [ 6422696 ] IsIfAlive: RX packets checked if=en5 failed(由於檢查到網卡en5在2秒中內網卡流量包未方式變化,判斷為en5失敗)
1、故障每次發生都在淩晨04左右,時間如下:
2013-10-28 04:29:56
2013-11-01 04:38:36
2013-11-06 04:17:37
2、從源碼上分析,發生故障期間網卡en5連續1秒的網路包未變化
可能的原因:
ping -S 10.0.241.150 -c 1 -w 1 10.0.241.254
Oracle檢測網管時,由於當時網路品質不好導致ping不能在1秒鐘內返回結果。
引起網卡en5 ping前 ping後沒有 網路包發生變化。
根據以上分析我們建議:
1、修改racgvip源碼跳過網管檢測
修改前:
# Check the status of the interface thro' pinging gateway
if [ -n "$DEFAULTGW" ]
修改後:
# Check the status of the interface thro' pinging gateway
if [ -n "$DEFAULTGW" -a $FAIL_WHEN_DEFAULTGW_NO_FOUND -eq 1 ]
查閱oracle11.2.0.3版本的 RACGVIP代碼,同樣以次修改
以下為Oracle11G的racgvip代碼
if [ -n "$DEFAULTGW" -a $FAIL_WHEN_DEFAULTGW_NOT_FOUND -eq 1 ]
then
_RET=1
# get RX packets numbers
_O1=`$IFCONFIG $_IF | $AWK '{ if (/RX packets:/) { sub("packets:", "", $2); print $2}}'`
x=$CHECK_TIMES
while [ $x -gt 0 ]
do
logx "About to execute $PING -r -I $_IF $DEFAULTGW $PING_TIMEOUT"
$PING -r -I $_IF $DEFAULTGW $PING_TIMEOUT > /dev/null 2>&1
rc=$?
if [ $rc -eq 0 ]
then
_RET=0
break
else
echo "ping to $DEFAULTGW via $_IF failed, rc = $rc (host=$HOSTNAME)"
fi
x=$(($x-1))
done
結論及解決方案
修改racgvip代碼
修改完成後,需要觀察ora.s9lp1.vip.log裡出現如下資訊:
IsIfAlive: Default gateway is not defined (host=$HOSTNAME)
表明修改失效