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日以上経過したログを削除すればよいのですが。