LinuxネタではなくOracleネタではあるのですが。
運用開始後にDBが正常に動作しているか監視したいという要件はよくあったりしますので、サービス監視ネタとしてまとめてみたいと思います。
環境は、Oracle11.2.0(2ノードRAC構成)、RedHat6.2環境をベースに書いています。
Oracleのサービス監視をする
サービス監視の一環として、正常にDBが稼動しているかどうかを動作しているプロセスの個数で監視(いわゆるプロセス監視)するケースはよくありますが、Oracleは動作するプロセスが非常に多かったりしますし、サービスの動作確認用コマンドが用意されていたりするので、それを応用してシェルで自動チェックする仕組みを作ってみます。
利用するコマンドは、下記のcrsctlコマンドでリソースの状況を表示するオプションをつけて実行します。
$ crsctl stat res -t
--------------------------------------------------------------------------------
NAME TARGET STATE SERVER STATE_DETAILS
--------------------------------------------------------------------------------
Local Resources
--------------------------------------------------------------------------------
ora.DG1_CTRL.dg
ONLINE ONLINE oradb1
ONLINE ONLINE oradb2
ora.DG2_DATA.dg
ONLINE ONLINE oradb1
ONLINE ONLINE oradb2
ora.DG3_ARCH.dg
ONLINE ONLINE oradb1
ONLINE ONLINE oradb2
ora.LISTENER.lsnr
ONLINE ONLINE oradb1
ONLINE ONLINE oradb2
ora.asm
ONLINE ONLINE oradb1 Started
ONLINE ONLINE oradb2 Started
--- snip ---
--------------------------------------------------------------------------------
Cluster Resources
--------------------------------------------------------------------------------
ora.LISTENER_SCAN1.lsnr
1 ONLINE ONLINE oradb1
ora.LISTENER_SCAN2.lsnr
1 ONLINE ONLINE oradb2
ora.LISTENER_SCAN3.lsnr
1 ONLINE ONLINE oradb2
ora.cvu
1 ONLINE ONLINE oradb2
ora.oradb1.vip
1 ONLINE ONLINE oradb1
ora.oradb2.vip
1 ONLINE ONLINE oradb2
ora.oradb.db
1 ONLINE ONLINE oradb1 Open
2 ONLINE ONLINE oradb2 Open
--- snip ---
上記のように、このコマンドでリソースの状況が確認できるうえに、TARGET(しかるべき状態)とSTATE(現在の状態)が表示できるので、これを比較することでリソースの状況がチェックできそうです。
ただ、これは視覚的にすごく見やすいのですが、プログラムから見れば処理しにくい部分があるため、「-t」オプションを除いたコマンド実行結果を利用します。
$ crsctl stat res NAME=ora.DG1_CTRL.dg TYPE=ora.diskgroup.type TARGET=ONLINE , ONLINE STATE=ONLINE on oradb1, ONLINE on oradb2 NAME=ora.DG2_DATA.dg TYPE=ora.diskgroup.type TARGET=ONLINE , ONLINE STATE=ONLINE on oradb1, ONLINE on oradb2 NAME=ora.DG3_ARCH.dg TYPE=ora.diskgroup.type TARGET=ONLINE , ONLINE STATE=ONLINE on oradb1, ONLINE on oradb2 NAME=ora.LISTENER.lsnr TYPE=ora.listener.type TARGET=ONLINE , ONLINE STATE=ONLINE on oradb1, ONLINE on oradb2 NAME=ora.LISTENER_SCAN1.lsnr TYPE=ora.scan_listener.type TARGET=ONLINE STATE=ONLINE on oradb1 --- snip ---
この結果だと、TARGETとSTATEの部分がカンマ区切りで取得できるのでスクリプト的に処理しやすかったりします。
Oracleのリソース状況をチェックするスクリプト
ということで、以下のようなcrsctlコマンド実行結果を解析するシェルスクリプトを書いてみました。
#!/bin/bash
# チェック対象のリソース一覧。SCAN系やVIP、CVUなどのリソースはどちらのノードが持っているか不明なため対象外
RESOURCES=("ora.DG1_CTRL.dg" "ora.DG2_DATA.dg" "ora.DG3_ARCH.dg" "ora.LISTENER.lsnr" "ora.asm" "ora.net1.network" "ora.ons" "ora.oradb.db")
# RAC対象ノード
RACNODES=("oradb1" "oradb2")
# CRSコマンド
CRSCHECK="/opt/app/11.2.0/grid/bin/crsctl check cluster"
# 実行ファイル名
FILENAME="${0##*/}"
# CRSが生きているかチェック
crsstat=`$CRSCHECK | grep "online" | wc -l`
if [ $crsstat -ne 3 ]
then
logger -p err -t "${FILENAME}" "error: Cannot communicate with Cluster Ready Services"
exit
fi
# リソースをチェックするコマンド
CRSCMD="/opt/app/11.2.0/grid/bin/crsctl stat res "
# 各リソースをチェック
for res in "${RESOURCES[@]}"
do
# crsctlコマンドを実行しSTATE行を抽出し=で分割して結果を受取る
result=`$CRSCMD $res | grep "STATE=" | cut -d "=" -f2`
for node in "${RACNODES[@]}"
do
# HOST名が存在しないかONLINEでなければそのリソースは停止している可能性がある
status=`echo $result | grep "$node"`
if [ -z "$status" ]
then
logger -p err -t "${FILENAME}" "error:" $res "on" $node "is missing."
fi
done
done
やっていることは、crsctlコマンドの実行結果から監視対象のリソース(RESOURCES配列の中身)のTARGETとSTATEの中身を比較しており、異常があったときにsyslog経由でエラーメッセージを吐き出すというものです。
あとは、Cronとかで数分おきにシェルを実行してチェックするように動作させておけばよいかと思います。
シェルのコメントにも書いていますが、SCAN系やVIPのリソースはどっちのノードが持っているか起動の状況によりばらけたり、1ノードを意図的に落としたときにフェイルオーバーして片ノードによってしまうということがあって監視が難しいので対象外にしています。
Oracle自身もリソースやプロセスに異常があったら自己修復するような機能を備えているので、この辺が完全にアウトになることがあるのか不明ではありますが。
あと、RAC用と書きましたが、対象リソース(RESOURCES変数)や対象ノード(RACNODES変数)を書き換えればSingle環境のOracleでもチェックは可能だと思います。
同様にcrsctlコマンドは利用できるので。
監視としては、syslogにメッセージが吐き出されるので、最終的にはログ監視の中で異常を拾う仕組みにはなっていますが、監視ツールのPandoraとかではスクリプトの実行結果を元に判別できたりもするので、ログに書き出す部分に戻り値を書いてあげてもよいかもしれません。
[PR]
[PR]