この記事は最終更新日から1年以上が経過しています。

SNMPでMYSQLサーバーをモニタリングする

SNMP(Simple Network Management Protocol)とはネットワーク上の機器を監視・制御するためのプロトコルです。これを使ってMySQLの状態を監視出来るようにします。

SHOW STATUSコマンドなどでリアルタイムな情報は確認できますが、SNMPとMRTGというツールを使って定期的なデータを保存するようにし、グラフ化して情報を見える化します。

サーバー構成

サーバー構成としては、MySQLが稼働しているサーバーにsnmpdをインストールし、もう一台のサーバーからMRTGでMySQLサーバーの状態を監視します。

server1(CentOS 6.5)
+---------------+
| 192.168.1.1   |
+---------------+
| snmpd         |<----+
| mysql         |     |
+---------------+     |
                      |
server2(CentOS 6.5)   |
+---------------+     |
| 192.168.1.2   |     |
+---------------+     |
| mrtg          |-----+
| httpd         |
+---------------+ 

server1には既にMySQL、server2にはWEBサーバーがインストールされているものとし、SNMPとMRTGの導入方法を紹介します。

サーバーが1台のみの場合はすべてserver1に設定しても問題ありません。

snmpdインストール

まず、server1にsnmpdをインストールします。

yum -y install net-snmp
yum -y install net-snmp-util

net-snmpはSNMPエージェントのsnmpdが含まれます。SNMPエージェントはMIB(Management Information Base)管理情報ベースと呼ばれるデータベースを持ち、SNMPマネージャからのリクエストに対して応答を返します。

net-snmp-utilにはSNMPマネージャのsnmpwalkコマンドが含まれています。

次に設定ファイルを編集します。

vi /etc/snmp/snmpd.conf

下記設定を追加して保存します。

#       sec.name  source          community
com2sec local     localhost       private
com2sec mynetwork 192.168.1.0/24  public

#     group.name sec.model  sec.name
group MyRWGroup  any        local
group MyROGroup  any        mynetwork

#           incl/excl subtree                          mask
view all    included  .1                               80

#                context sec.model sec.level prefix read   write  notif
access MyROGroup ""      any       noauth    exact  all    none   none
access MyRWGroup ""      any       noauth    exact  all    all    all

2・3行目の設定はネットワークとコミュニティをセキュリティ名で定義しています。
ネットワーク:localhost・コミュニティ:privateをセキュリティ名:localとして定義、ネットワーク:192.168.1.0/24・コミュニティ:publicをセキュリティ名:mynetworkとして定義しています。
SNMPではコミュニティ名が情報にアクセスするためのパスワードになります。

6・7行目の設定はセキュリティモデルとセキュリティ名をグループ名で定義しています。
セキュリティモデルには、v1・v2・usmが設定可能で、それぞれSNMPバージョン1・2・3という意味になります。
上記設定ではanyで一括指定しています。

10行目の設定はSNMPエージェントがもっている情報はすべて公開するという設定をallという名前で設定しました。

13・14行目の設定はアクセス許可のための設定です。MyROGroupはすべての情報へのread権限、MyRWGroupにはすべての情報へのread・write権限を付与しています。read・write権限には10行目で指定したallを使用しています。

この辺りはsnmpd.confにサンプルの設定が書いてありますので、そちらも参考にしてください。

続いてsnmpdを起動します。snmpデーモンを起動していないとサーバーはSNMPエージェントとして動作しません。

/etc/rc.d/init.d/snmpd start

snmpdが起動できたらsnmpwalkコマンドで管理情報が取得出来るか確認します。

snmpwalk -v 1 -c public 192.168.1.1

情報がズラーっと出てきたら成功です。 「Timeout: No Response from 192.168.1.1」とか「getaddrinfo: 192.168.1.1 Name or service not known」とか出てきたら情報の取得に失敗していますので、再度設定を見直しましょう。

MySQL情報取得シェルスクリプト作成

MySQLの情報を取得するシェルスクリプトを作成します。snmpdでこのシェルを実行し情報を取得するためのものです。
シェルスクリプトはどこに作成してもいいのですが、snmpdで実行しますよ、ってわかりやすくする為に以下の場所に作成します。

vi /etc/snmp/mysql.sh

シェルスクリプトの内容は以下の様にします。

#!/bin/sh

/usr/bin/mysql -u root -pPASSWORD -e 'SHOW STATUS' 2>/dev/null | grep "^$1" | awk '{print $2}'

exit 0

引数で受け取ったパラメータのステータスを出力するためだけのシェルスクリプトです。PASSWORDの部分はそれぞれの環境に合わせて書き換えます。
作成したシェルスクリプトに実行権限を付与し実行してみます。

chmod 755 /etc/snmp/mysql.sh
/etc/snmp/mysql.sh Threads_connected
1

結果が取得できれば成功です。

このシェルスクリプトの結果をSNMP経由で取得できるようにするために、snmpd.confに下記設定を追加します。

vi /etc/snmp/snmpd.conf
exec mysql_threads_connected /etc/snmp/mysql.sh Threads_connected
exec mysql_threads_running /etc/snmp/mysql.sh Threads_running

Threads_connectedとThreads_runningの情報を取得する設定を追加しました。
exec行に追加した情報はextTableサブツリー(1.3.6.1.4.1.2021.8)内に含まれるようなります。
snmpwalkで確認してみます。

snmpwalk -v 1 -c public 192.168.1.1 .1.3.6.1.4.1.2021.8
UCD-SNMP-MIB::extIndex.1 = INTEGER: 1
UCD-SNMP-MIB::extIndex.2 = INTEGER: 2
UCD-SNMP-MIB::extNames.1 = STRING: mysql_threads_connected
UCD-SNMP-MIB::extNames.2 = STRING: mysql_threads_running
UCD-SNMP-MIB::extCommand.1 = STRING: /etc/snmp/mysql_threads.sh Threads_connected
UCD-SNMP-MIB::extCommand.2 = STRING: /etc/snmp/mysql_threads.sh Threads_running
UCD-SNMP-MIB::extResult.1 = INTEGER: 0
UCD-SNMP-MIB::extResult.2 = INTEGER: 0
UCD-SNMP-MIB::extOutput.1 = STRING: 1
UCD-SNMP-MIB::extOutput.2 = STRING: 1
UCD-SNMP-MIB::extErrFix.1 = INTEGER: noError(0)
UCD-SNMP-MIB::extErrFix.2 = INTEGER: noError(0)
UCD-SNMP-MIB::extErrFixCmd.1 = STRING: 
UCD-SNMP-MIB::extErrFixCmd.2 = STRING:

オプション -On を使用するとOIDが数字で表示されますので、各OIDは下記の様に確認できます。

snmpwalk -v 1 -c public -On 192.168.1.1 .1.3.6.1.4.1.2021.8
.1.3.6.1.4.1.2021.8.1.1.1 = INTEGER: 1
.1.3.6.1.4.1.2021.8.1.1.2 = INTEGER: 2
.1.3.6.1.4.1.2021.8.1.2.1 = STRING: mysql_threads_connected
.1.3.6.1.4.1.2021.8.1.2.2 = STRING: mysql_threads_running
.1.3.6.1.4.1.2021.8.1.3.1 = STRING: /etc/snmp/mysql_threads.sh Threads_connected
.1.3.6.1.4.1.2021.8.1.3.2 = STRING: /etc/snmp/mysql_threads.sh Threads_running
.1.3.6.1.4.1.2021.8.1.100.1 = INTEGER: 0
.1.3.6.1.4.1.2021.8.1.100.2 = INTEGER: 0
.1.3.6.1.4.1.2021.8.1.101.1 = STRING: 1
.1.3.6.1.4.1.2021.8.1.101.2 = STRING: 1
.1.3.6.1.4.1.2021.8.1.102.1 = INTEGER: noError(0)
.1.3.6.1.4.1.2021.8.1.102.2 = INTEGER: noError(0)
.1.3.6.1.4.1.2021.8.1.103.1 = STRING: 
.1.3.6.1.4.1.2021.8.1.103.2 = STRING: 

.1.3.6.1.4.1.2021.8.1.101.n (nは連番)がexec行で指定したシェルスクリプトの実行結果です。1行目以降は無視されますので、2行以上返すシェルスクリプトでも1行目の結果しか取得できません。
exec教を増やすと末尾の数字が3、4、とそれぞれ増えていきます。

この結果を使ってMRTGでMySQLサーバーの状態を監視します。

MRTGインストール・設定

次にserver2にMRTGをインストールします。

yum -y install mrtg

そして例の如く設定ファイルを編集します。

vi /etc/mrtg/mrtg.cfg
WorkDir: /home/mrtg/public
EnableIPv6: no

Target[server1_mysql_threds]:.1.3.6.1.4.1.2021.8.1.101.1&.1.3.6.1.4.1.2021.8.1.101.2:public@192.168.1.1
Options[server1_mysql_threds]: absolute, gauge, growright, nolegend, nopercent
MaxBytes[server1_mysql_threds]: 151
YLegend[server1_mysql_threds]: Threads
ShortLegend[server1_mysql_threds]: Threads
LegendI[server1_mysql_threds]: Connected
LegendO[server1_mysql_threds]: Running
Title[server1_mysql_threds]: [sever1] MySQL Threads
PageTop[server1_mysql_threds]: <H1>[sever1] MySQL Threads</H1>

4行目の設定Targetにsnmpwalkで確認したUCD-SNMP-MIB::extOutput.n(nは連番)のOIDとコミュニティとネットワークを指定します。
MRTGは基本的に2つの値をグラフ化するので、2つのOIDを指定しています。

6行目の設定MaxBytesにはMySQLのmax_connectionsを設定しています。

1行目のWorkDirにはMRTGがデータを出力するフォルダを設定します。
デフォルトの設定だと「http://ホスト名/mrtg/」のアクセスを「/var/www/mrtg」を読み込むように設定されていますが、僕の場合はバーチャルホストで「/home/mrtg/public」を読み込む様に設定しました。

vi /etc/httpd/conf.d/mrtg.conf 
#Alias /mrtg /var/www/mrtg
#
#<Location /mrtg>
#    Order deny,allow
#    Deny from all
#    Allow from 127.0.0.1
#    Allow from ::1
#    # Allow from .example.com
#</Location>

<VirtualHost *:80>
    ServerName mrtg.sawara.me
    DocumentRoot /home/mrtg/public
    ErrorLog /var/log/httpd/mrtg_error_log
    CustomLog /var/log/httpd/mrtg_access_log combined env=!no_log
</VirtualHost>
<Directory /home/mrtg/public >
    Options Indexes FollowSymLinks Includes ExecCGI
    AllowOverride All
    Order allow,deny
    Allow from all
</Directory>

WEBサーバーの設定周りは各環境に合わせて変更してください。

MRTGインストール時に5分毎にデータを取得するcronが自動的に設定されています。5分待って自動的にデータが出力されるのを待つのもいいですが、crondに設定されているコマンドを直接入力することもできます。

cat /etc/cron.d/mrtg  
*/5 * * * * root LANG=C LC_ALL=C /usr/bin/mrtg /etc/mrtg/mrtg.cfg --lock-file /var/lock/mrtg/mrtg_l --confcache-file /var/lib/mrtg/mrtg.ok

上記コマンドを直接実行します。

LANG=C LC_ALL=C /usr/bin/mrtg /etc/mrtg/mrtg.cfg --lock-file /var/lock/mrtg/mrtg_l --confcache-file /var/lib/mrtg/mrtg.ok

MRTGは過去のデータからグラフを作成するため、1回目・2回目はwarningが出力されますが、気にしなくて大丈夫です。3回実行すればwarningは出力されなくなります。

上記コマンドを実行後にWorkDirの中にファイルができているはずです。

ls /home/mrtg/public/ 
server1_mysql_threds-day.png
server1_mysql_threds-month.png
server1_mysql_threds-week.png
server1_mysql_threds-year.png
server1_mysql_threds.html
server1_mysql_threds.log
server1_mysql_threds.old

作成されたファイルを確認後、「http://ホスト名/server1_mysql_threds.html」にアクセスします。
次のように表示されていたら成功です。

mrtg2

これでMySQLの状態が監視出来るようになりました。

最後に

snmpd.confのexec行を増やして更に監視する項目を増やすこともできます。

また下記の用にしてSNMPを介さずにMRTGから直接監視する方法もあります。

Target[server1_mysql_threds]:`/etc/snmp/mysql.sh` 
Options[server1_mysql_threds]: absolute, gauge, growright, nolegend, nopercent
MaxBytes[server1_mysql_threds]: 151
YLegend[server1_mysql_threds]: Threads
ShortLegend[server1_mysql_threds]: Threads
LegendI[server1_mysql_threds]: Connected
LegendO[server1_mysql_threds]: Running
Title[server1_mysql_threds]: [sever1] MySQL Threads
PageTop[server1_mysql_threds]: <H1>[sever1] MySQL Threads</H1>

※ シェルスクリプトの内容を書き換える必要がありますが。

一見この方がシンプルで良さそうなのですが、MRTGを動かすサーバー上にもMySQLクライアントがインストールされている必要があったり、他のSNMPマネージャから情報が取得できなかったりするので、より汎用的にするにはやはり今回のようにSNMPで取得するようにした方がいいです。

コメントを残す