shuto_log.aep

自分がやったことなどを備忘録的な感じで残していこうと思います。

時々mariadbが落ちるのを力技で解決した話

CentOSWordPressのHPを運営しているのですがときどきmariadbが落ちるので、シェルスクリプトを組んで力技で解決してみました。(根本的な解決になっていない)(この記事書いている間に原因見つけたっぽくて最後におまけで書いてあります。)

やったこと

"mariadbの生存を確認して死んでいたら起動する"というシェルスクリプトを組んで、cronで毎分実行します。

シェルスクリプトの作成

まずシェルスクリプトを作成します。ここでは/var/www/HP/にdbCheck.shというシェルスクリプトを作成するとします。
※注意:僕のHPの公開ディレクトリはこれよりも深いです。実際にシェルスクリプトを置く場合は、セキュリティ上"公開ディレクトリの外に置く"ことを強く推奨します。というかこういうスクリプトを配置する適切な場所、知ってる方いたら教えて頂きたいくらいです。
以下内容。

#! /bin/bash
count=`ps -ef | grep mysqld | grep -v grep | wc -l`
if [ $count = 0 ]; then
    date=`date`
    systemctl start mariadb
    echo "$date | DB was restarted." >> /var/www/HP/dbRestart.log
    unset date
fi
unset count

mariadbを起動する際にsystemctl startを使うので、このスクリプトはroot権限で実行しなければなりません。なのでdbCheck.shの実行権限は特にいじらず644のままにしました。(root以外の権限で実行する場合は実行権限を付与してやる必要があります。)

スクリプトの詳細

スクリプトの説明をします。
やってることは、

  1. 全プロセス一覧から「mysqld」の文字列を含むものの行数を数える。
  2. 数が0ならばmariadb(mysql)が動いていいないということなので、mariadbを起動する。
  3. 起動したら/var/www/HP/dbRestart.logにログを残す。
  4. 最後に、使った変数を削除。

といった感じです。

まずここでは変数を用います。シェルスクリプトで変数って僕も今まで使い方知りませんでした。変数を使う場合は

var="hogehoge"

とか

var=1000

って打つそうですが、ここで注意しないといけないのは、「=」の前後にスペースを入れてはいけないということです。
また、作った変数の中身を参照するには$を付けてやります。なお、未宣言の変数を参照してもエラーが出ずに空白が返されます。(ちょっと不親切)

echo $var  #hogehoge

そして、何か命令の出力を代入したい時はバッククオート(`)でくくります。なのでここでは`ps -ef | grep mysqld | grep -v grep | wc -l`の結果をcountという変数に入れていることになります。

ps -e | grep mysqld | wc -l

についてですが、これは
www.mk-mode.com
このサイトのスクリプトをほぼそのままお借りしています。
パイプ(|)についての説明は省きますが、まずps -eで全ユーザの起動中の全プロセスを出力します。
実行すると分かるのですが、こんな感じで大量のプロセス一覧が表示されます。

  PID TTY          TIME CMD
    1 ?        00:00:22 systemd
    2 ?        00:00:00 kthreadd
    3 ?        00:00:03 ksoftirqd/0
    5 ?        00:00:00 kworker/0:0H
(中略)
 7612 pts/0    00:00:00 bash
24109 ?        00:00:00 crond
31303 ?        00:00:00 sshd
31307 ?        00:00:00 sshd
31308 pts/1    00:00:00 bash

次にその結果の中から「mysqld」という文字列を含む行だけを抽出します(grep mysqld)。mariadbはプロセス名はmysqldらしいです。ややこしいですね。
そして最後に抽出した文字列の行数を数えます(wc -l)。wcという命令はデフォルトでは行数以外に単語数やバイト数も表示してしまうので、行数だけを表示する-lオプションを使います。
プロセス一覧に「mysqld」という文字列を含む行が存在しなければ、mariadbが起動していないということなので、countが0になります。
これを利用してmariadbの生存確認が出来るわけです。

最後に

ここまでやっといてアレなのですが、結局原因について色々調べた結果、どうやらうちのWordPressのxmlrpc.phpに大量のDoS攻撃があったようで、それが怪しいです。
しかも僕はxmlrpc.phpを用いた機能を使っていないので、結局xmlrpc.phpへの接続を全て拒否にしました。これで解決すれば良いのになあ。