LoginSignup
2
1

More than 5 years have passed since last update.

MySQLのデータの結果を監視してメールを送信するバッチ(cron設定する)

Last updated at Posted at 2017-12-11

作ろうと思ったきっかけ

データベース上でデータ不整合が発生する現象が発生した。
AというテーブルのBカラムの集計値はCというテーブルのDカラムと一致しなければならないのに、何故か一致しない。
どこかで不整合が発生する仕組みになってしまったのだろうが、原因が特定できない。
発生した日のログを見ようと思ったが、発生した日すらわからない。
このシステム稼働してもう何年だっけ?という手詰まりなので、
「今までの事はさておき、これから発生したとして、発生した日がわかればログも追いやすいだろう。チェックバッチを作って毎日チェックしよう」という悲しいモチベーションで作る事になった。

check.shをとりあえず作ってみる

ネーミングセンスの悪さは否めない。

先に言っておくと、下の記述は良くない。

check_ng.sh
#!/bin/bash

# 集計値と異なる場合にメールを送信するsh

# メール送信時に送信時刻を記載するためだけのもの
NOW_TIME=`date +"%Y-%m-%d %H:%M:%S"`
# 送信先メールアドレス
ADMIN="hoge@hogehoge.com"

# SQLファイルの指定
# 簡単ならば直接記述しても良いけれども、ボチボチ修正も入りそうなので
# 外からファイルを読み込む事にする。
SQL_FILE_NAME=diff_check.sql
# このSQLは「count (*)」とかにしておいて、差分が発生した時だけ0以外の
# 値が取得できるものとする。

# MYSQLの設定
DB_USER=hoge
DB_PASSWORD=fuga
DB_NAME=example

COUNT=`cat "$SQL_FILE_NAME" | mysql -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" -N 2>&1`
# ほとんどの場合は何かしらワーニングがついてくると思うのですが…
echo $COUNT

if [ $COUNT -ne 0 ] ; then
echo "$NOW_TIME error" |mail -s "error" $ADMIN
echo "NG"
else
echo "OK"
fi

check_ng.sh: 25 行: [: 引数が多すぎますとか言われます。
echo $COUNT の中身が「mysql: [Warning] Using a password on the command line interface can be insecure. 0」とかなってるからしょうがないです。

最初は「mysql: [Warning] Using a password on the command line interface can be insecure. 」を削れば良いかと思いました。
COUNT=${COUNT#"mysql: [Warning] Using a password on the command line interface can be insecure. "}とか。
でもこのワーニング文言、実は環境ごとに微妙に違うようで、この実装だと他の案件で流用できない。それもどうかと思うけれど、何もかもがあまりよくない。

そもそもの話なのだけれども、DB_PASSWORDという変数がもはやおかしい。
https://dev.mysql.com/doc/refman/5.6/ja/environment-variables.html
を見ると
MYSQL_PWDという環境変数がある。これを使えばいい。

※やっぱりセキュアではないんだけれども。
「mysqld に接続する際のデフォルトのパスワード。これを使用することはセキュアではありません。」と書いてある。
本番稼働しているMYSQLに対して、クリティカルな異常でも何でもない監視用バッチの為にcnfを弄って対応する事も難しい。許可が降りない。

どうせ上の例でもパスワードをハードコーディングしていてセキュアでもなんでもないので、今更セキュアを気にしてもしょうがないと割り切る。

check.sh
#!/bin/bash

# 集計値と異なる場合にメールを送信するsh

# メール送信時に送信時刻を記載するためだけのもの
NOW_TIME=`date +"%Y-%m-%d %H:%M:%S"`
# 送信先メールアドレス
ADMIN="hoge@hogehoge.com"

# SQLファイルの指定
# 簡単ならば直接記述しても良いけれども、ボチボチ修正も入りそうなので
# 外からファイルを読み込む事にする。
SQL_FILE_NAME=diff_check.sql

# MYSQLの設定
DB_USER=hoge
DB_NAME=example

# -pの部分はごっそり消していい。
COUNT=`cat "$SQL_FILE_NAME" | MYSQL_PWD=fuga mysql -u "$DB_USER" "$DB_NAME" -N 2>&1`
# これで件数だけ取得できる
echo $COUNT

if [ $COUNT -ne 0 ] ; then
echo "$NOW_TIME error" |mail -s "error" $ADMIN
echo "NG"
else
echo "OK"
fi

ちなみに、

MYSQL_PWD=fuga
COUNT=`cat "$SQL_FILE_NAME" | mysql -u "$DB_USER" "$DB_NAME" -N 2>&1`

ではダメです。

COUNT=`cat "$SQL_FILE_NAME" | MYSQL_PWD=fuga mysql -u "$DB_USER" "$DB_NAME" -N 2>&1`

こうでないと、うごかない。

cronの設定

あとは、cronで設定するだけ。

00 6 * * * sh /home/hoge/batch/check.sh > /home/hoge/batchlog/check_`date +\%Y-\%m-\%d`.log
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1