サーバの定期DBフルバックアップ

うちのサーバはPostgresとmysqlが動いていて、それぞれ夜間に定期的にフルバックアップを取ってリモートサーバに転送していて、いざという時はリモートサーバにあるダンプファイルを使ってリストア一発で元に戻せるようにしてます。

今回はPostgresとmysqlフルバックアップを行い、ダンプしたファイルをzip圧縮するスクリプトの紹介です。古いファイルがあれば、ローテーション日時でリネームして、アーカイブしていきます。30日以上の古いファイルは削除されていきます。

PostgreSQL

バックアップファイルを保管するディレクトリは/root/pgdumpallとしてます。

#!/bin/sh

DUMP_PATH="/root/pgdumpall"

if [ ! -e $DUMP_PATH ] ; then 
	exit
fi

DUMP_NAME="pg_dumpall.sql"
DUMP_NAME_ZIP=$DUMP_NAME".zip"

ZIP_PROG="/usr/bin/zip"

if [ -e $DUMP_PATH/$DUMP_NAME_ZIP ] ; then
        mv $DUMP_PATH/$DUMP_NAME_ZIP $DUMP_PATH/`date +%Y%m%d%H%M%S`_$DUMP_NAME_ZIP
fi

/usr/local/postgres/bin/pg_dumpall -c -U postgres > $DUMP_PATH/$DUMP_NAME


$ZIP_PROG $DUMP_PATH/$DUMP_NAME_ZIP $DUMP_PATH/$DUMP_NAME
rm $DUMP_PATH/$DUMP_NAME


find $DUMP_PATH/ -type f -mtime +30 -exec rm {} \;

スクリプトの中の /usr/local/postgres/bin/pg_dumpall -c -U postgres この箇所は自分のサーバ環境に合わせてパスなどを書き換えて下さい。/root/pgdumpallというディレクトリが存在しなければ強制終了するようにしています。
zipコマンドのパスなども環境によって動かない場合は変更下さい。

これを実行すると、最新のダンプファイルが、
/root/pgdumpall/pg_dumpall.sql.zip
という名前で出来ます。何かあったときはこのファイルをリストアすればOKです

古いファイルは
/root/pgdumpall/20090213235626_pg_dumpall.sql.zip
というような名前でできていきます。

最後に、
find $DUMP_PATH/ -type f -mtime +30 -exec rm {} \;
このコマンドで該当フォルダの中に30日以上前に作成したファイルがあれば削除するようにしています。10日以上古いファイルを削除したい場合は+30を+10にします。


これをcronで夜間に実行して、バックアップサーバへrsyncで同期させています。

リストアする時は、

unzip /root/pgdumpall/pg_dumpall.sql.zip
/usr/local/postgres/bin/psql -U postgres template1 < /root/pgdumpall/pg_dumpall.sql

これでリストアされます。pd_dumpallコマンドでバックアップする際に-cオプションをつけているので、リストアする際に古いテーブルやデータが残っていても全て削除して入れなおしてくれます。

参考URL
http://www.postgresql.jp/document/pg803doc/html/app-pg-dumpall.html
http://dreamer-site.net/modules/xpwiki/?Fedora%20Core%206%20PostgreSQL8.2%B7%CF
http://centossrv.com/postgresql-backup.shtml


Mysql

mysqlの場合もPostgreSQLと同じ要領で作っていきます。異なる箇所はダンプファイル名やダンプコマンドだけです。
/root/mysqldumpディレクトリを予め作っておく必要があります。

#!/bin/sh

DUMP_PATH="/root/mysqldump"

if [ ! -e $DUMP_PATH ] ; then
        echo "error mysqldump directory not found"
        exit
fi


DUMP_NAME="mysqldump.sql"
DUMP_NAME_ZIP=$DUMP_NAME".zip"

ZIP_PROG="/usr/bin/zip"

if [ -e $DUMP_PATH/$DUMP_NAME_ZIP ] ; then
        mv $DUMP_PATH/$DUMP_NAME_ZIP $DUMP_PATH/`date +%Y%m%d%H%M%S`_$DUMP_NAME_ZIP
fi


/usr/local/mysql5/bin/mysqldump -u root --socket=/var/lib/mysql/mysql.sock --all-databases --default-character-set=binary > $DUMP_PATH/$DUMP_NAME


$ZIP_PROG $DUMP_PATH/$DUMP_NAME_ZIP $DUMP_PATH/$DUMP_NAME
rm $DUMP_PATH/$DUMP_NAME


find $DUMP_PATH/ -type f -mtime +30 -exec rm {} \;

mysqldumpコマンドの引数などは環境によって変えて下さい。特に--sockオプションは普通はいらないと思います。

このシェルを定期的に実行すると、最新のダンプデータが
/root/mysqldump/mysqldump.sql.zip
というファイル名で作成されます。

リストアする際は下記のようにするだけです。

unzip /root/mysqldump/mysqldump.sql.zip
/usr/local/mysql5/bin/mysql -u root --default-character-set=binary < /root/mysqldump/mysqldump.sql

この後、mysqlコンソールにログインして、flush privilegesを実行 (flush privilegesをやらないとユーザが有効にならない)
/usr/local/mysql5/bin/mysql -u root
mysql> flush privileges;

参考URL
http://dev.mysql.com/doc/refman/5.1/ja/mysqldump.html
http://www.system-act.com/server/mysql.html