1. 程式人生 > 其它 >假期前的資料庫檢查指令碼之主備關係(r11筆記第46天)

假期前的資料庫檢查指令碼之主備關係(r11筆記第46天)

快過年了,很多系統都要進入最後的檢查和複驗階段,一方面在節假日前,提前發現問題總比過節的時候發現要好。另一方面如果出現故障的時候能及時進行處理,這個時候我們就需要有一個儘可能全面的元資料收集。而且還有一點比較重要的就是工作交接,如果你臨時有事,需要讓同事來代勞,你得提供清晰易懂的資訊給他們。

可能有的同學會覺得我們已經有了資料庫監控,基本的效能分析,這個工作是不是就可以忽略了。監控只是標記狀態,出現問題時候它沒法幫你處理,還是需要人工介入,而人工介入儘可能全面的資訊就是這些元資料了,如果你們已經有了CMDB,那可能會簡化很多工作,如果沒有,也可以生成一個精簡版的,在這個基礎上能夠故障自愈那就太好了。彆著急,一口氣吃個大胖子也不現實。

之前也寫了不少的指令碼,自己也用了一些指令碼完成了一些基本的檢查任務,但是想得到一個簡練的報告,這個工作現在還沒有做好。比如對於節假日的問題處理分析,出現服務不可用,宕機類問題可能才是呼喚我們的時候。所以對於災備的資訊就尤其需要注意。

先來看看目前的簡單效果:

name                : ACCMOB0
db_unique_name      : s2accmob0
database_role       : PRIMARY
open_mode           : READ WRITE
version             : 11.2.0.3.0
Character set       : AL32UTF8
NCHAR Character set : AL16UTF16
10.11.2.145  s3accmob0.test.com   s3accmob0   1525
10.11.128.169  saccmob03.test.com   saccmob03   1525

上面的輸出就能夠達到一個基本的效果,通過這些資訊,我們就可以得到資料庫的字符集,狀態,對應的備庫資訊和IP,連對應的埠也抓到了,這個資訊其實就比較簡練了。

實現這個指令碼複雜不復雜呢,其實也沒多少。

sqlplus -s  / as sysdba <<EOF
set pages 0
set feedback off
select rpad('name', 20, ' ') || ': ' || name || chr(10)||
       rpad('db_unique_name', 20, ' ') || ': ' || db_unique_name || chr(10)||
       rpad('database_role', 20, ' ') || ': ' || database_role || chr(10)||
       rpad('open_mode', 20, ' ') || ': ' || open_mode   
  from v$database;
select rpad('version', 20, ' ') || ': ' || version 
  from v$instance; 
select rpad(description, 20, ' ') || ': ' || property_value 
  from database_properties
 where property_name in ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');
EOF
for tmp_ins in `dgmgrl -silent / " show configuration"  |grep  -i "Physical standby database"|sed 's/Physical standby database//g'|sed 's/-//g'`
do

tmp_tns=`dgmgrl -silent / " show database verbose ${tmp_ins}"  |grep StaticConnectIdentifier|awk '{print $3}'`
echo $tmp_tns

tmp_host=`echo ${tmp_tns}|grep ADDRESS|sed 's/Attempting to contact //'|sed 's/(/n/g'|sed 's/)/n/g'|grep -i 'HOST|PORT|SERVICE_NAME|SID_NAME' |grep -i HOST| awk -F= '{print $2}'`
#tmp_host=`tnsping ${tmp_ins}|grep ADDRESS|sed 's/Attempting to contact //'|sed 's/(/n/g'|sed 's/)/n/g'|grep -i 'HOST|PORT|SERVICE_NAME|SID_NAME' |grep -i HOST| awk -F= '{print $2}'`
#echo ${tmp_host}
tmp_port=`echo ${tmp_tns}|grep ADDRESS|sed 's/Attempting to contact //'|sed 's/(/n/g'|sed 's/)/n/g'|grep -i 'HOST|PORT|SERVICE_NAME|SID_NAME' |grep -i PORT| awk -F= '{print $2}'`
#echo ${tmp_port}
tmp_con_chk=`nc -w 1 -v ${tmp_host} ${tmp_port}`
#echo ${tmp_con_chk}
if [[ ${tmp_con_chk} =~ "succ" ]]; then
    echo  `grep  -w ${tmp_host} /etc/hosts|awk '{print $1}'`" " ${tmp_host} " " ${tmp_ins} " " ${tmp_port}
else
  echo 'NEED TO CHECK HOST '${tmp_host}
fi
done

這裡有幾點需要指出:

1)得到備庫的資訊,目前是基於DG Broker來抓取的,但是有的伺服器可能配置了主機名,有的配置了IP,就需要根據情況來解析。

2)得到對應的伺服器IP和埠,目前有三種實現方式,一種就是通過dgmgrl,使用show database verbose來得到連線串的資訊,另外一種就是通過tnsping來得到,第3種是通過解析tnsnames.ora來得到。

上面的例子給出了前兩種。

3)解析IP和埠後的網路情況是通過nc來實現的,nc這個命令比較好,可以設定超時時間,這個例子裡面設定了1秒。

當然你說這個指令碼看起來蠻有意思,你說有沒有缺點呢,實在太多了,所以只是一個初版,會持續更新。

缺點有以下幾個:

1)判斷資料庫的主備角色,這樣就可以避免重複解析DG Broker中主備關係資訊。

2)使用tnsping或者DG Broker中的show database verbose方式,如果多備庫間的網路不通,會有超時的情況。不過這種概率較小,如果出現問題也需要我們及時修復

3)如果是多備庫的情況,如果得到更具體的備庫資訊,比如同機房備庫,異機房備庫,這些就需要解析資產資訊了。