Yappli Tech Blog

株式会社ヤプリの開発メンバーによるブログです。最新の技術情報からチーム・働き方に関するテーマまで、日々の熱い想いを持って発信していきます。

Aurora MySQL 2.x で運用している本番DBから Aurora Serverless v2 な調査用DBを作成してみる

SREチームの中原です。
Aurora MySQL 2.x で運用している本番DBから Aurora Serverless v2 な調査用DBを作成する方法について書いてみます。

TL;DR

  • Aurora MySQL 2.x で運用しているDBでも Serverless v2 な調査用DB立てられるよ
  • ただし毎回メジャーバージョンアップの処理が必要なので時間かかるよ (弊社の環境で1.5〜3時間)
  • Aurora Serverless v2 だとクエリーの途中でもスケールアップしてくれるのでハッピーだよ
  • AWS さん Aurora Serverless v2 の Aurora MySQL 2.x 対応はよ! Aurora MySQL 3.x の LTS 版提供はよ!

経緯

弊社の本番DBは Aurora MySQL 2.x の LTS バージョンで運用しています。 これまで本番影響なく調査用のクエリーを投げるために以下の手法をつかっていました。

  • クローンでプロビジョンドDBインスタンス立てる
  • スナップショットからのレストアで Aurora Serverless v1 立てる

ただ、どちらも単一の重いクエリーで詰まってしまった場合、そのクエリーを止めて、手動でスペックやキャパシティを上げるとかいった作業がいります。
めんどくさいです。
そこで、そのへんよろしくやってくれる Aurora Serverless v2 の出番です。

準備

しかし、この記事を書いている 2022/10 時点では Aurora Serverless v2 は Aurora MySQL 2.x には対応してくれていません。 なので、メジャーバージョンアップの処理が必要になります。

現在使用している本番DBのアップグレード可能なバージョンを調べておきます。 3.x に直接アップグレードできないバージョンだと先に 2.x 内でのマイナーバージョンアップが必要かもしれません。

$ aws rds describe-db-engine-versions --engine aurora-mysql   --engine-version 5.7.mysql_aurora.2.07.8  --out json | jq -cr '.DBEngineVersions[].ValidUpgradeTarget[].EngineVersion'
5.7.mysql_aurora.2.09.2
5.7.mysql_aurora.2.09.3
5.7.mysql_aurora.2.10.0
5.7.mysql_aurora.2.10.1
5.7.mysql_aurora.2.10.2
5.7.mysql_aurora.2.11.0
8.0.mysql_aurora.3.01.1
8.0.mysql_aurora.3.02.0

メジャーバージョンアップのちゃんとした手順については公式ドキュメントを参照ください。
Aurora MySQL DB クラスターのメジャーバージョンのアップグレード - Amazon Aurora

Aurora Serverless v2 が対応しているバージョンも確認しておきます。

$ aws rds describe-orderable-db-instance-options --engine aurora-mysql --db-instance-class db.serverless  --region ap-northeast-1 --query 'OrderableDBInstanceOptions[].[EngineVersion]' --output text
8.0.mysql_aurora.3.02.0
8.0.mysql_aurora.3.02.1

このへんも詳しくは公式ドキュメントを参照ください。
Aurora Serverless v2 の要件 - Amazon Aurora

調査用DBでつかうクラスターパラメータグループを作成しときます。ここではでかい結果を返すクエリーとパラレルクエリーを実行できるようにしてますが、適宜状況に合わせてお好みで。

PARAM_CLUSTER=research-db-v2
aws rds create-db-cluster-parameter-group \
  --db-cluster-parameter-group-name ${PARAM_CLUSTER} \
  --db-parameter-group-family aurora-mysql8.0

aws rds modify-db-cluster-parameter-group \
    --db-cluster-parameter-group-name ${PARAM_CLUSTER} \
    --parameters "ParameterName=max_allowed_packet,ParameterValue=1073741824,ApplyMethod=immediate" \
                 "ParameterName=aurora_parallel_query,ParameterValue=ON,ApplyMethod=immediate"

作成

では実際に調査用DBを作成していきます。 実際には以下の手順をシェルスクリプト化して定期実行しています。

  1. 本番DBのスナップショットを作成します。
    TIMESTAMP=$(/bin/date +"%Y%m%d%H%M")
    CLUSTER_PROD="prod-aurora-db"
    SNAPSHOT_PROD="prod-aurora-db-${TIMESTAMP}"
    
    aws rds create-db-cluster-snapshot \
        --db-cluster-snapshot-identifier ${SNAPSHOT_PROD} \
        --db-cluster-identifier ${CLUSTER_PROD} \
        --out text
    
    aws rds wait db-cluster-snapshot-available \
        --db-cluster-snapshot-identifier ${SNAPSHOT_PROD} \
        --out text
  2. スナップショットから Aurora MySQL 3.x なクラスターを作成します。
    ネットワークの設定や Serverless v2 のキャパシティなどは環境に合わせて適当に。 ストレージサイズに比例してそれなりに時間かかりますがaws rds wait db-cluster-availableだと30分しか待ってくれないようなので適当にループまわしてます。 時間とかは適宜状況に合わせて適当に。
    CLUSTER_RESEARCH="research-aurora-db-${TIMESTAMP}"
    SUBNET="db_subnet_group_name"
    SG="sercurity_group_id"
    VERSION="8.0.mysql_aurora.3.02.0"
    SLV2_CAP_MIN=0.5
    SLV2_CAP_MAX=32
    
    aws rds restore-db-cluster-from-snapshot \
        --db-cluster-identifier $CLUSTER_RESEARCH \
        --snapshot-identifier $SNAPSHOT_PROD \
        --engine aurora-mysql \
        --engine-version ${VERSION} \
        --db-cluster-parameter-group-name $PARAM_CLUSTER \
        --db-subnet-group-name $SUBNET \
        --vpc-security-group-ids $SG \
        --serverless-v2-scaling-configuration MinCapacity=${SLV2_CAP_MIN},MaxCapacity=${SLV2_CAP_MAX} \
        --out text
    
    sleep 1800
    
    RETRY=90
    WAIT=60
    
    for i in $(seq 1 ${RETRY}); do
      RESULT=$(aws rds describe-db-clusters --db-cluster-identifier ${CLUSTER_RESEARCH} --out json | jq -cr '.DBClusters[].Status')
      sleep $WAIT
      if [ "${RESULT}" = "available" ]; then
        break
      fi
    done
  3. バージョンアップ用DBインスタンスを起動します。
    バージョンアップ処理はサーバーレスDBインスタンスではやってくれないようなので、一度プロビジョンドDBインスタンスを起動して、バージョンアップがおわるまで待ちます。これも時間かかります。
    INSTANCE_INIT="${CLUSTER_RESEARCH}-init"
    aws rds create-db-instance \
      --db-cluster-identifier ${CLUSTER_RESEARCH} \
      --db-instance-identifier ${INSTANCE_INIT} \
      --db-instance-class db.r5.large \
      --engine aurora-mysql \
      --out text
    
    sleep 2700
    
    RETRY=240
    WAIT=120
    
    for i in $(seq 1 ${RETRY}); do
      RESULT=$(aws rds describe-db-instances --db-instance-identifier ${INSTANCE_INIT} --out json | jq -cr '.DBInstances[].DBInstanceStatus')
      sleep $WAIT
      if [ "${RESULT}" = "available" ]; then
        break
      fi
    done
  4. サーバーレスDBインスタンスを起動します。
    INSTANCE_SLV2="${CLUSTER_RESEARCH}-slv2"
    aws rds create-db-instance \
      --db-cluster-identifier ${CLUSTER_RESEARCH} \
      --db-instance-identifier ${INSTANCE_SLV2} \
      --db-instance-class db.serverless \
      --engine aurora-mysql \
      --out text
    
    aws rds wait db-instance-available \
      --db-instance-identifier "${INSTANCE_SLV2}"
  5. いらなくなったアップグレード用インスタンスを削除します。
    他に必要であれば接続用のCNAME書き換えたりとか、ロググループ等のリソース削除したりとか、適宜後処理をやってください。
    aws rds delete-db-instance \
      --db-instance-identifier ${INSTANCE_INIT} \
      --skip-final-snapshot \
      --out text

後書き

将来的に、弊社が本番DBを Aurora MySQL 3.x にアップグレードするか、AWS さんが Aurora Serverless v2 の Aurora MySQL 2.x 対応してくれるといらなくなる処理ですが、現状はこんなかんじでデイリーで権限のある人が自由に使える調査用DBを立てています。
弊社の環境ではできあがるまでに1.5〜3時間ぐらいかかってます。
はやくクローンするだけで Aurora Serverless v2 が使える日が来て欲しいところです。