MySQLのデータとバイナリログをS3にバックアップする簡易スクリプト
作ってみました。
S3用のコマンドラインツール「s3cmd」を使っています。
これを含めて小さなシェルスクリプトは幾つかここ(tyn-iMarket / shellscripts)に置いてあります。
毎週日曜日にデータをダンプしてS3に保存し、それまでS3に保存してあったバイナリログは削除します。
日曜日以外はバイナリログをフラッシュして、最終更新日が1日以内のバイナリログをS3に保存し、最終更新日が1日以降のバイナリログを削除します。
世代管理などは特に行なっていません。
#!/bin/sh # バックアップ先ディレクトリ BACKUP_DIR=/usr/local/imarket/backup # ダンプファイル名 DUMP_FILE=mysql-dump.sql # S3のバケット名 S3_BUCKET=hoge-hoge # ログファイル LOG=/var/log/imarket/mysql-backup.log # S3にファイルを保存する put_s3() { s3cmd put --acl-private $1 s3://$2/ >> $LOG 2>&1 } # S3からファイルを削除する del_s3() { s3cmd del $1 >> $LOG 2>&1 } # ファイルを削除する del_file() { rm -f $1 echo "Delete $1" `date +"%Y/%m/%d %H:%M:%S"` >> $LOG } backup_dump_file() { mysqldump -u root --single-transaction --master-data=2 --flush-logs --all-databases > ${BACKUP_DIR}/${DUMP_FILE} put_s3 ${BACKUP_DIR}/${DUMP_FILE} $S3_BUCKET for S3_BINLOG in `s3cmd ls s3://${S3_BUCKET_BINLOG}/ | grep ${S3_BUCKET_BINLOG}/${BINLOG} | awk '{print $4}'` do del_s3 $S3_BINLOG done } # MySQLディレクトリ MYSQL_DIR=/var/lib/mysql # バイナリログ名 BINLOG="mysql-bin.[0-9]*" # 何日以内のバイナリログを保存するか PUT_MTIME=1 # 何日以降のバイナリログを削除するか DELETE_MTIME=0 # S3のバケット名 S3_BUCKET_BINLOG=imarket-backup/mysql-bin backup_binlog_file() { mysqladmin flush-logs -u root sleep 5 for file in `find $MYSQL_DIR -maxdepth 1 -name $BINLOG -mtime -$PUT_MTIME` do put_s3 $file $S3_BUCKET_BINLOG done for file in `find $MYSQL_DIR -maxdepth 1 -name $BINLOG -mtime +$DELETE_MTIME` do del_file $file $S3_BUCKET_BINLOG done } echo "Start backup -" `date +"%Y/%m/%d %H:%M:%S"` >> $LOG if [ `date +"%w"` = 0 ]; then backup_dump_file else backup_binlog_file fi echo "End backup -" `date +"%Y/%m/%d %H:%M:%S"` >> $LOG
最終更新日が1日以内・1日以降の判定がタイミング次第でブレるのを防ぐため、バイナリログをフラッシュした後5秒スリープしています。
まあそんなことせずに、2日以上経過したログを削除すればよいのですが。