🐚
CronでDBのバックアップをとる
接続イメージ
状況と流れ
- private subnetにpostgresqlがインストールされたEC2(DBとして使っているEC2)があります。
- EC2にセッションマネージャーで接続し、
pg_dump
コマンドでDBのバックアップを取ります。 - 取得したSQLファイルをS3にアップロードします。
- 同時に各コマンドの実行状況をCloudWatchに流します。
Shell Script
- EC2内に設置した諸々上記↑を実行するスクリプトです。
#!/bin/bash # PATHを設定 PATH=<your aws cli command path> # 環境変数を設定 DB_NAME="<your database name>" DB_USER="<your database user name>" BACKUP_DIR="/path/to/your/directory" BACKUP_NAME="$(date +\%Y\%m\%d\%H\%M\%S).sql" # 任意のファイル名 BACKUP_PATH="$BACKUP_DIR/$BACKUP_NAME" S3_BUCKET="<your bucket name>" S3_PATH="s3://$S3_BUCKET/" LOG_GROUP_NAME="<your log group name>" LOG_STREAM_NAME="$(date +\%Y\%m\%d\%H\%M\%S)" # 任意のログストリーム名 # AWS CLI のインストールチェック if ! <result of which aws> --version &> /dev/null then echo "AWS CLI could not be found. Please install it to proceed." exit 1 fi <result of which aws> logs create-log-stream --log-group-name "$LOG_GROUP_NAME" --log-stream-name "$LOG_STREAM_NAME" # CloudWatchにログを送信する関数 log_to_cloudwatch() { TIMESTAMP=$(date +%s%3N) MESSAGE=$1 <result of which aws> logs put-log-events \ --log-group-name "$LOG_GROUP_NAME" \ --log-stream-name "$LOG_STREAM_NAME" \ --log-events timestamp=$TIMESTAMP,message="$MESSAGE" \ --region "<your region name>" } # バックアップを作成 pg_dump -U $DB_USER $DB_NAME > $BACKUP_PATH # バックアップのステータスを確認 if [ $? -eq 0 ]; then log_to_cloudwatch "Backup created successfully: $BACKUP_PATH" else log_to_cloudwatch "Backup failed" exit 1 fi # S3にアップロード <result of which aws> s3 cp $BACKUP_PATH $S3_PATH # アップロードのステータスを確認 if [ $? -eq 0 ]; then log_to_cloudwatch "Backup uploaded to S3 successfully: $S3_PATH" rm $BACKUP_PATH else log_to_cloudwatch "Backup upload to S3 failed" exit 1 fi
cronの設定
※ 時間設定などは一例です。
crontab
0 2 * * 3 /path/to/your/shell.sh
困ったこと
- スクリプト単体で実行すると適切に動作するのに、cronで動かすとうまくいかない、と言う状況が発生しました。
- (
sh /path/to/your/shell.sh
は動く)
- (
解消までに
- cronのログを確認しました。→cron自体は起動しているようです。
# ログファイル sudo tail -f /var/log/cron # その中身(抜粋) Jul 23 03:38:01 ip-<hogehoge> CROND[23330]: (ec2-user) CMD (sh /path/to/your/shell.sh)
- スクリプトのログを出力しました。→スクリプトの実行でコケていることがわかりました。crontab
# 時間設定は適宜変更してください 0 8 * * 2 /path/to/your/shell.sh >> /path/to/your/logfile.log 2>&1
- ログファイルに出ているエラー文に対応していきました。結果として上記スクリプトが出来上がっています。
まとめ
- aws cliコマンドがcronになると動かないと言うのは想定外でした。
- 他にもっと良いスクリプトの書き方があるかもしれませんが、何かの参考になれば幸いです。
Discussion