cronを使って直近7日分のmysqldumpをAmazon S3に自動バックアップする方法
こんにちは、たつきちです。
この記事では、Linuxサーバー上で
- cronを使ってmysqldumpを毎日定期実行しつつ
- Amazon S3に直近7日分だけが残る形でバックアップ
をする方法について説明します。
mysqldumpの結果を物理サーバー上でlogrotateして直近n日分だけ残すといった運用も多いと思いますが、やっぱり命より大事なデータベースバックアップなので外部のストレージにしっかり保存しておきたいですよね。
1. 準備
S3への保存のために、サーバーにawscliをインストールしておく必要があります。
例えばUbuntu(18.04)であれば、aptで簡単にインストールできます。
$ sudo apt update
$ sudo apt install awscli -y
2. タイムゾーンをJSTに設定
多くのLinuxディストリビューションではデフォルトのタイムゾーンがUTCになっています。
意図したタイミングでcronタスクを実行するために、あらかじめタイムゾーンをJSTに変更しておきましょう。
こちらもUbuntu(18.04)であれば timedatectl コマンドを使えば簡単に変更できます。
$ sudo timedatectl set-timezone Asia/Tokyo
$ timedatectl
Local time: Tue 2020-02-04 08:38:12 JST
Universal time: Mon 2020-02-03 23:38:12 UTC
RTC time: Mon 2020-02-03 23:38:13
Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
systemd-timesyncd.service active: yes
RTC in local TZ: no
Ubuntu以外のディストリビューションであればこちらの記事が参考になると思います。
3. cronを設定
準備が整ったら、cronタスクを定義しましょう。
crontab -e を使ってもいいですが、ヒューマンエラーのリスクもあるので /etc/cron.d/ 配下にファイルを作るのがおすすめです。
実行時刻を細かく指定しないなら、
/etc/cron.daily/配下にシェルスクリプト形式で設置するでもよいですね。
# /etc/cron.d/mysqldump-s3
0 0 * * * {実行ユーザー} mysqldump -u{DBユーザー} -p{DBパスワード} {データベース名} > mysqldump.sql && tar zcf mysqldump.tar.gz mysqldump.sql && aws s3 cp mysqldump.tar.gz s3://{バケット名}/mysqldump.`date +\%u`.tar.gz && rm mysqldump.sql mysqldump.tar.gz
- 毎日00:00に
- mysqldumpを実行し
- gzipでtarball化し
-
date +%uコマンドで 曜日名をファイル名に含めた形でS3にアップロード し - 要らなくなった出力ファイルを削除
という内容になっています。
4つ目がポイントですね。 date +%u コマンドは、現在時刻を月曜=1〜日曜=7として出力してくれます。(参考)
+%u の部分を +\%u と書いて、 % をエスケープしている点に注意してください。エスケープしないと、crontab内では % はコマンドの終端扱いされてしまうため、正常に動作しません。
ちなみに
crondサービスの再起動は不要です✋
「直近3日分」とか「直近2週間分」とかやりたい場合は?
工夫すればもちろんできます。
例えば「直近14日分」をバックアップしたければ、出力結果が1〜14になるようなコマンドを組み立ててあげればよいわけです。
具体的には以下のようにすればよいです。
aws s3 cp mysqldump.tar.gz s3://{バケット名}/$((`date +\%-d` \% 14)).tar.gz
$(()) を使って、日付に対して14の剰余を計算しています👍
$(()) の代わりにexprコマンドを使っても同じ結果が得られます。
aws s3 cp mysqldump.tar.gz s3://{バケット名}/$(expr `date +\%-d` \% 14).tar.gz
なお、ここでもcrontab向けに剰余演算子の % を \% とエスケープしている点に注意してください。
動作確認などのためにターミナルから直接実行する場合などは、この \ は不要です。(逆に、あるとエラーになります)
4. 結果
実際にこの運用をしているS3の画面キャプチャです。直近7日分のデータベースバックアップが毎日更新されています👍

まとめ
- データベースのバックアップはS3など外部ストレージに保存しておくと安心
-
dateコマンドで曜日や日付の剰余などを計算してファイル名に埋め込むことで、直近n日分のバックアップファイルをローテートして残すことができる - cronタスク内のコマンドに
%という文字を使うときは\%とエスケープが必要
Discussion