🐚

CronでDBのバックアップをとる

2024/07/23に公開

接続イメージ

状況と流れ

  • 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