WordPressバックアップスクリプト

(スクリプトの改良版があります!)

昨晩、WordPressのバックアップスクリプトの問題のせいで、
約1時間分の喪失で済むところを、
約1日分ものデータを吹っ飛ばしてしまったので、
真夜中に急遽スクリプトを見直したー

おかげで今日1日、眠たくて眠たくて・・・(苦笑)
早く3連休よ、来いっ・・・!

で、自作してるバックアップのスクリプトなんだけど、
以前に増して汎用的に作り直したし、
かなり使えそうな感じに仕上がったから、
折角なので、とりあえず上げておく!

wp-backup1

長々と書いてあるけど、やってることは、
rsyncでディレクトリの同期を取って、
mysqldumpでDBのバックアップを取ってるだけ(笑)

ただ汎用性を求めて、パラメータ部分と処理部分を分けたり、
パラメータに合わせて動的に引数を生成したりしているから、
かなり長くなってる^^;

そしてシェルスクリプトを書き慣れてないから、
書き方とか問題ないかは不明・・・(汗)

パラメータの説明と処理の捕捉なんかを。

# rsync パス
RSYNC_PATH=/usr/bin/rsync
# mysqldump パス
MYSQLDUMP_PATH=/usr/local/mysql/bin/mysqldump
# gzip パス
GZIP_PATH=/bin/gzip

使用する各コマンドのパス。
別にコマンドだけ書いておけば良いような気も?

# バックアップ元ディレクトリ
SRC_DIR=/home/www/wordpress
# バックアップ先ディレクトリ
DST_DIR=/mnt/backup/wordpress
# データベースのバックアップ先
DB_DUMP_FILE=/mnt/backup/wp-db
DB_DUMP_FILE_EXT=.sql.gz

SRC_DIRとDST_DIRは、WordPressのディレクトリの
コピー元とコピー先を指定。
DB_DUMP_FILEには、DBのダンプ出力先。
拡張子が別になってるのは、動的にファイル名を変えるため^^;
バックアップ先がリモートの場合、コピー先、ダンプ出力先を、
リモート側のパスにするべし。

# rsync の除外リスト
RSYNC_EXCLUDE_LIST=/root/wp-rsync-exclude

rsyncを実行するときに使用する
除外リストを記述したファイルのパス。(詳細は後述)
使用しない場合は、コメントアウト。

# MySQLのSOCKファイル
DB_SOCK=/tmp/mysql.sock
# MySQLのホスト名
#DB_HOST=localhost
# MySQLのポート番号
#DB_PORT=3306
# MySQLのユーザ
DB_USER=backup
# MySQLのパスワード
DB_PASS="********"
# 対象のデータベース
DB_NAME=wordpress

データベースの情報。
不要なパラメータは、コメントアウトすれば、
コマンド実行時の引数から除外される。

# ssh-agent パス
SSH_AGENT_PATH=/usr/bin/ssh-agent
# ssh-add パス
SSH_ADD_PATH=/usr/bin/ssh-add
# ssh パス
SSH_PATH=/usr/bin/ssh
# バックアップ先のSSH接続情報
SSH_HOST=hoge@example.com
SSH_KEY=/root/.ssh/hoge

SSHの接続に使用する情報。
SSHを使わずにローカル間で実行する場合は、全てコメントアウトで。
○○_PATHは、それぞれコマンドのパスを。
DST_SSH_HOSTは、「ユーザ名@ホスト名」って感じで、
DST_SSH_KEYは、秘密鍵ファイルのパス。
因みに自動で動かないとダメだから、公開鍵認証が必須。

if [ "$1" = "--day" -o "$2" = "--day" ]; then
    export LC_ALL="en" > /dev/null 2>&1
    DST_DIR=${DST_DIR}-`date '+%a'`
    DB_DUMP_FILE=${DB_DUMP_FILE}-`date '+%a'`${DB_DUMP_FILE_EXT}
    export LC_ALL="" > /dev/null 2>&1
elif [ "$1" = "--hour" -o "$2" = "--hour" ]; then
    DST_DIR=${DST_DIR}`expr \`date +%H\` \% 2`
    DB_DUMP_FILE=${DB_DUMP_FILE}`expr \`date +%H\` \% 2`${DB_DUMP_FILE_EXT}
else
    DB_DUMP_FILE=${DB_DUMP_FILE}${DB_DUMP_FILE_EXT}
fi

引数に “--day” を指定して起動した時は、
1日1回のバックアップを想定して “-The” とか曜日を付加。
“--hour” を指定して起動した時は、1時間おきのバックアップを想定して、
時間が偶数の時は”0″、奇数の時は”1″を付加するようにしてみた。
引数がなければ、そのままの名前で。
ここを変えれば、好きに名前を制御できるー

因みに引数に “--test” を指定すると、
バックアップを実行せずに使用するコマンドを出力するモードに。
これで実行するコマンドが正しいかどうか確認できる。

以降は、実行するコマンドの文字列を構築して実行してる感じ。

問題になってたmysqldumpでエラーが発生時の対処は、
まず直接出力先に送るんじゃなくて、名前に”.tmp”を付けて実行。
そして終了コードを確認して、正常ならリネーム、異常なら削除するように。

eval "${CMD}; typeset -a ret=(\${PIPESTATUS[0]})"
# mysqldumpのエラーチェック
if [ ${ret} -ne 0 ]; then
	eval ${F_CMD}
	echo "Error mysqldump..." 1>&2
else
	eval ${S_CMD}
fi

evalとかパイプを使ってるせいで、
この終了コードを取得するのに、地味に苦労した・・・(笑)
これで何か起こっても最後に正常だったデータは残るはず!

CMD="${CMD} --add-drop-database --lock-all-tables 2>/dev/null | ${GZIP_PATH}"

mysqldump実行時のエラー出力をnullに出してるのは、
バージョンを5.6に上げてから引数でパスワードを指定したら、
Warning: Using a password on the command line interface can be insecure.こんな警告が常に出力されて、
このままcronに登録したら毎回メールが飛んできちゃうけど、
解決方法もすぐに分からなかったので仕方なく・・・
本来ならエラーが発生したときに、
そのままエラー内容を飛ばして欲しいんだけど。。。

あと、このスクリプト、別にWordPressだけじゃなくて、
何らかのディレクトリと何らかのデータベースを
バックアップするのに使えるし、
少し改造すればディレクトリのみ、データベースのみの
バックアップも出来るから、かなり汎用性が高い気がする!

あ、そうだ、あとrsyncの除外リストの中身を。

# WordPress
# (cache)
- /wordpress/wp-content/cache/*

とりあえずキャッシュフォルダを除外するようにしてる。

で、このスクリプトをcronの、バックアップを取りたい時間に
仕込んでおけば、良い感じにバックアップが取れる!

一応ウチのサーバでは正常に動いてるけど、利用は自己責任でー

因みにこのスクリプト、まだまだ改良中。
とりあえずリストア処理の対応を考えてたり、
コードの整理をしたりしてる。
また出来次第、上げていこうかなー

じゃ、ゲームして寝るー
バイニー☆

test?

WordPressバックアップスクリプト」への1件のフィードバック

  1. ピンバック: スクリプト改良 | みつ(@@@)の雑記

コメントを残す