Aurora インスタンスクラス変更のダウンタイム最小化手順

目次
  1. 🎯 結論:CCM 対象リーダーを先に変更し、手動フェイルオーバーで切り替える
  2. 🤔 なぜライターを直接変更すると書き込みが止まるのか
  3. 🛠️ 作業前の確認とダウンタイムを最小化する変更手順
  4. 🙅 よくある誤解:「ライターを先に変更すれば速い」は本当か
  5. 📊 検証環境で書き込み中断時間を実測する方法
  6. ❓ よくある質問
  7. 🔁 繰り返すスケール変更に備えた再発防止と運用設計
このテーマのまとめPostgreSQL 運用・トラブル解決ガイド|「遅い・詰まる・肥大化」を仕組みから切り分けるこのテーマのまとめRDS・Aurora 運用・トラブル解決ガイド|仕組み・障害切り分け・性能監視の全体像
本記事にはプロモーション(広告)が含まれています。

Aurora のインスタンスクラス変更は「数クリックで終わる作業」に見えますが、ライターをそのまま変更すると書き込みが止まります。さらに Cluster Cache Management(CCM)を有効にしている Aurora PostgreSQL では、ライターと Tier 0 リーダーのインスタンスクラスをそろえるという前提があるため、どちらを先に変更するかで作業後の性能回復まで変わってきます。

CCM 有効の Aurora PostgreSQL クラスターでインスタンスクラスをスケールアップ/スケールダウンするときに、書き込み停止時間を最短にする順序、作業前の確認項目、よくある誤解、検証環境での実測方法を順に扱います。メンテナンス手順書を書く直前に上から読んで確認できる構成にしています。

🎯 結論:CCM 対象リーダーを先に変更し、手動フェイルオーバーで切り替える

ライター1台+CCM 対象リーダー(Promotion Tier 0)1台+その他リーダー N 台という、よくある構成でインスタンスクラスを変更するなら、次の順序が基本です。

  1. CCM 対象リーダー(Tier 0)を新しいインスタンスクラスへ変更する。この変更は当該リーダーの再起動のみで済み、フェイルオーバーは発生しないため、書き込みは止まりません。
  2. aws rds failover-db-cluster で、そのリーダーへ手動フェイルオーバーする。フェイルオーバー先は既に新しいインスタンスクラスになっており、CCM によってバッファキャッシュもライターと同期されている状態なので、書き込みの中断とその後の性能の落ち込みを短く抑えられます。
  3. 旧ライター(フェイルオーバー後はリーダー)を新しいクラスへ変更する。これでクラスター全体が新クラスにそろい、「ライターと Tier 0 リーダーが同じインスタンスクラス」という CCM の前提も満たされます。

逆に、ライターのインスタンスクラスを直接変更する手順を取ると、変更に伴う再起動が終わるまでライターが利用できず、その間ずっと書き込みが止まります。Aurora は「ライターをいま変更中だから、代わりにリーダーへ切り替えておく」という親切なことはしてくれません😇

🤔 なぜライターを直接変更すると書き込みが止まるのか

インスタンスクラスの変更は対象インスタンスの再起動を伴う

Aurora はストレージ層をクラスターで共有し、その上にコンピュートノード(DB インスタンス)が乗る構造になっています。インスタンスクラスの変更はこのコンピュートノード側の話で、別のスペックのホストへ載せ替える操作です。したがって、対象インスタンスの機能停止(再起動)が必ず発生します。ストレージ上のデータが作り直されるわけではないので、データサイズに比例して長くなる類の作業ではありませんが、「再起動を伴わない無停止の変更」でもありません。

変更対象がリーダーであれば、停止するのはそのリーダーだけです。リーダーエンドポイント経由の参照クエリは他のリーダーへ振り分けられますし、ライターは動き続けるので書き込みは継続します。ところが変更対象がライターの場合、停止するのは唯一の書き込み窓口です。再起動が完了してインスタンスが available に戻るまで、トランザクションのコミットはできません。

ライターを変更しても自動フェイルオーバーは起きない

ここが最も誤解されやすい点です。ライターのインスタンスクラスを変更しても、Aurora は自動でフェイルオーバーしません。計画的なインスタンス変更は「障害」ではないため、クラスターは「ライターが一時的に停止している」状態をそのまま維持し、変更が完了したら同じインスタンスがライターとして戻ってきます。

つまりライター直接変更の書き込み停止時間は、「ライターの再起動+新しいホストでの起動完了まで」の全部です。一方、フェイルオーバー方式であれば、停止するのは「クラスターエンドポイントの指す先が旧ライターから新ライターへ切り替わるまで」の区間だけになります。両者は原理的に別の長さの処理で、後者のほうが短く収まるのが期待値だからこそ、「リーダーを先に上げてから、そこへ寄せる」という順序が推奨になります。

なお、障害起因のフェイルオーバーと計画的なフェイルオーバーでは、イベント履歴に残るメッセージも異なります。想定外のフェイルオーバーが起きたときの切り分けについては、RDS Multi-AZ フェイルオーバー原因の確認手順 のアプローチが Aurora でもそのまま参考になります。

CCM がライターと Tier 0 リーダーのバッファキャッシュを同期する仕組み

Aurora のストレージは共有ですが、バッファキャッシュ(共有バッファ)はインスタンスごとに独立しています。ライターが長時間稼働してホットなページをキャッシュに抱えている一方、リーダーは参照クエリの傾向に応じた別の内容をキャッシュしている、という状態が普通です。

この状態でフェイルオーバーすると何が起きるか。新ライターは、それまでライターが持っていたワーキングセットをキャッシュに持っていません。結果として、フェイルオーバー直後はストレージ層への読み取りが急増し、クエリのレイテンシが一時的に悪化します。「フェイルオーバー自体は短時間で終わったのに、その後しばらくアプリが重かった」という現象の多くはこれが原因です😇

Cluster Cache Management は、この「キャッシュが冷えた状態からの立ち上がり」を短くするための Aurora PostgreSQL の機能です。ライターがどのページをキャッシュに保持しているかという情報を、指定されたリーダー(Promotion Tier 0)側が追跡し、同じページを自分のバッファキャッシュに読み込んでウォームな状態を保ちます。フェイルオーバー後、新ライターは最初からホットなページを手元に持っている状態で書き込みを引き受けられるため、ウォームアップにかかる時間を短縮できます✨

CCM はクラスターパラメータ apg_ccm_enabled で制御します。リーダー側の挙動やラグとの関係については、Auroraレプリカラグ監視|AuroraReplicaLag でも触れている観点が役立ちます。

CCM はライターと Tier 0 リーダーが同じインスタンスクラスであることが前提

CCM を使うときの制約がこれです。CCM は、ライターと Tier 0 のリーダーが同じインスタンスクラス(インスタンスタイプとサイズ)であることを前提としています。

理由はバッファキャッシュのサイズにあります。キャッシュサイズはインスタンスのメモリ量に依存するので、ライターが大きいクラスで Tier 0 リーダーが小さいクラスだと、リーダーはライターのワーキングセットを全部キャッシュに載せられません。逆にリーダーが大きければ無駄が出ます。「ライターのキャッシュ内容を鏡のように保つ」という設計上、両者のキャッシュ容量がそろっていることが条件になるわけです。

この前提があるため、インスタンスクラスの変更は「ライターだけ」「Tier 0 リーダーだけ」で終わらせてはいけません。最終的に両方を新クラスにそろえるところまでが作業のゴールで、そろえる途中の順序としてリーダー先行が有利になります。

この記事のテーマをさらに学べる本

PostgreSQLの内部構造と照らし合わせて設計・運用計画を解説しており、挙動の理解を深められます。

[改訂3版]内部構造から学ぶPostgreSQL-設計・運用計画の鉄則
[改訂3版]内部構造から学ぶPostgreSQL-設計・運用計画の鉄則上原 一樹/勝俣 智成/佐伯 昌樹/原田 登志
楽天ブックスで詳しく見る Yahoo!ショッピングで見る

🛠️ 作業前の確認とダウンタイムを最小化する変更手順

作業前に見る 3 点:Promotion Tier、apg_ccm_enabled、現在のインスタンスクラス

手を動かす前に次の 3 点を確認します。手順書にもそのまま確認項目として書いておくと、作業者が変わっても抜けません。

1 つ目は、クラスターのメンバー構成と Promotion Tier です。どのインスタンスがライターで、どのリーダーが Tier 0 なのかを見ます。

aws rds describe-db-clusters \
  --db-cluster-identifier <クラスター識別子> \
  --query 'DBClusters[0].DBClusterMembers[].{Instance:DBInstanceIdentifier,Writer:IsClusterWriter,Tier:PromotionTier}' \
  --output table

IsClusterWriter が true のものが現ライター、PromotionTier が 0 のリーダーが CCM 対象候補です。Tier 0 が複数いる、あるいは Tier 0 のリーダーが存在しない構成になっていないかもここで見ます。

2 つ目は apg_ccm_enabled の設定値です。CCM はクラスターパラメータグループで有効化するので、実際に適用されている値を確認します。

aws rds describe-db-cluster-parameters \
  --db-cluster-parameter-group-name <クラスターパラメータグループ名> \
  --query "Parameters[?ParameterName=='apg_ccm_enabled']" \
  --output table

インスタンス上で実際に効いている値を見るなら、psql から確認するのが確実です。

SHOW apg_ccm_enabled;

パラメータグループ側が変更済みでも、インスタンスへの反映が pending-reboot のままになっているケースがあります。グループの値とインスタンスの値を両方見て、食い違いがないかを確認します。

3 つ目は、各インスタンスの現在のインスタンスクラスとステータスです。

aws rds describe-db-instances \
  --query 'DBInstances[?DBClusterIdentifier==`<クラスター識別子>`].{Instance:DBInstanceIdentifier,Class:DBInstanceClass,Status:DBInstanceStatus,AZ:AvailabilityZone}' \
  --output table

💡 ここで AZ も一緒に取っておくのがポイントです。後述するように、手動フェイルオーバーでライターの AZ が入れ替わるため、作業前後の AZ 配置を記録しておく必要があります。また、DBInstanceStatus が available 以外のインスタンスがある状態で作業を始めないようにします。

手順 1:CCM 対象リーダー(Tier 0)を新しいインスタンスクラスへ変更する

最初に変更するのは Tier 0 のリーダーです。

aws rds modify-db-instance \
  --db-instance-identifier <CCM対象リーダー> \
  --db-instance-class <新しいインスタンスクラス> \
  --apply-immediately

✅ この変更で停止するのは当該リーダーだけで、ライターは稼働し続けるため書き込みは止まりません。リーダーのインスタンスクラス変更をきっかけにフェイルオーバーが起きることもありません。

⚠️ ただし注意点が 2 つあります。

ひとつは、この時点でライターと Tier 0 リーダーのインスタンスクラスが一時的に不一致になることです。CCM の前提から外れた状態なので、この区間でキャッシュ同期が期待どおりに働かない可能性を想定しておき、不一致の時間を短くするために手順 1 と手順 2 を続けて実施する計画にします。

もうひとつは、リーダーが 1 台しかいない構成では、この間の参照クエリの受け皿がなくなることです。リーダーエンドポイントに参照を振っているアプリケーションは、この区間で接続エラーやライターへのフォールバックが発生します。参照系の一時的な縮退を許容できるか、事前に確認してください。

変更が完了したら、DBInstanceStatus が available に戻り、DBInstanceClass が新しい値になっていることを describe-db-instances で確認します。ここを確認せずに次へ進むのが典型的な事故パターンです😇

手順 2:aws rds failover-db-cluster でそのリーダーへ手動フェイルオーバーする

リーダーが新クラスで available になったら、そのリーダーをターゲットに指定して手動フェイルオーバーします。

aws rds failover-db-cluster \
  --db-cluster-identifier <クラスター識別子> \
  --target-db-instance-identifier <CCM対象リーダー>

⚠️ --target-db-instance-identifier は必ず明示します。指定しない場合、昇格先は Promotion Tier の設定にもとづいてクラスター側が選ぶため、意図しないインスタンスが昇格して「CCM でウォームにしていたリーダーではないほうがライターになった」という結果になりかねません。

このフェイルオーバーが、今回の作業で書き込みが止まる唯一の区間です。この区間を短く、かつフェイルオーバー後の性能低下も小さくするために、ここまでで昇格先を新クラスにし、CCM でキャッシュをウォームに保ってきたわけです。

フェイルオーバー完了後は、ロールが入れ替わったことを確認します。

aws rds describe-db-clusters \
  --db-cluster-identifier <クラスター識別子> \
  --query 'DBClusters[0].DBClusterMembers[].{Instance:DBInstanceIdentifier,Writer:IsClusterWriter,Tier:PromotionTier}' \
  --output table

アプリケーション側では、クラスターエンドポイントの名前解決が新ライターへ切り替わっているか、コネクションプールが古い接続を掴んだままになっていないかを確認します。DNS の TTL やドライバのプール設定次第で、インフラ側のフェイルオーバーが終わってもアプリの復旧が遅れることがあります。

手順 3:旧ライターを新クラスへ変更し、Tier 0 と同一クラスの条件をそろえる

フェイルオーバーで旧ライターはリーダーになっています。これを新クラスへ変更します。

aws rds modify-db-instance \
  --db-instance-identifier <旧ライター> \
  --db-instance-class <新しいインスタンスクラス> \
  --apply-immediately

この時点では書き込みは新ライターが受けているので、この変更で書き込みは止まりません。完了後は、クラスター内の全インスタンス(少なくともライターと Tier 0 リーダー)のインスタンスクラスが一致していること、そして Promotion Tier の設定が意図どおりであることを確認して作業を締めます。後者は、ロールが入れ替わったことで「新しくリーダーになった旧ライター」の Tier が 0 になっているか、Tier 0 が重複していないかという観点です。

CCM の前提を満たすのは「ライターと Tier 0 リーダーが同じクラス」です。ロールが入れ替わった後もこの条件が成立しているか、構成図と照らして確認してください。必要なら modify-db-instance --promotion-tier で Tier を再設定します。

手順を逆にするとキャッシュ同期の効果が活きない理由

ここまでの手順の意味は、逆順を考えると明確になります。

ライターを先に変更した場合、変更に伴う再起動の間ずっと書き込みが止まります。自動フェイルオーバーは起きないので、停止時間はインスタンス変更の所要時間そのものです。しかも、その後にリーダーを変更する作業も残っています。

ライターを変更した後にフェイルオーバーする場合は、ライター側の停止時間に加えてフェイルオーバーの中断も発生し、二度止まります。

リーダーを変更せずにフェイルオーバーだけ先にする場合は、昇格先がまだ旧クラスのままなので、スケールアップが目的だったのに一時的に小さいインスタンスが書き込みを担うことになります。ピーク時間帯なら性能面のリスクがあります。

💡 「リーダー変更、手動フェイルオーバー、旧ライター変更」の順序は、書き込みが止まる区間をフェイルオーバーの一回だけに限定し、かつその昇格先が新クラスかつキャッシュウォームである状態を作るためのものです。CCM の効果は「フェイルオーバー先のリーダーがウォームであること」に依存するので、昇格先を先に整える点が要になります。

この記事のテーマをさらに学べる本

EC2やRDSの運用、バックアップ/リストアなどAWS運用の基本を体系立てて解説しています。

AWS運用入門
AWS運用入門佐竹 陽一/山崎 翔平/小倉 大/峯 侑資
楽天ブックスで詳しく見る Yahoo!ショッピングで見る

🙅 よくある誤解:「ライターを先に変更すれば速い」は本当か

「変更中は自動でフェイルオーバーしてくれる」は誤り

「ライターを変更すれば、Aurora が勝手にリーダーへ切り替えてくれて、終わったら戻ってくるのだろう」という理解は誤りです。計画的なインスタンスクラス変更は障害検知の対象ではなく、ライターのインスタンスクラス変更によって自動フェイルオーバーは発生しません。変更が完了するまでライターは利用できず、その間の書き込みはエラーになります。

「ライターを先にやったほうが一発で済んで速い」という直感は、作業ステップの数だけを見ると正しく聞こえますが、書き込み停止時間という指標では不利です。メンテナンス時間枠そのものを短くしたいのか、アプリの書き込み停止を短くしたいのか、目的を決めてから手順を選んでください。多くの業務システムでは後者が優先されます。

「ダウンタイムは数秒」と断定できない理由

フェイルオーバーの所要時間を「数秒」と書いた手順書を見かけますが、断定はできません。所要時間は次のような要素に左右されます。

  • アプリケーションの接続数、コネクションプールの構成とヘルスチェック間隔
  • 実行中のトランザクションの状態(長時間トランザクションや大量の未コミット変更があるか)
  • クライアント側の DNS キャッシュの TTL と、ドライバがエンドポイントを再解決するタイミング
  • リトライ設計の有無(リトライがなければ、インフラ側の切り替えが終わってもアプリはエラーを出し続ける)

とくに最後の 2 点はインフラ側の施策では縮まりません。Aurora 側の切り替えが完了していても、アプリが古い接続を掴み続けていれば、ユーザーから見た断時間はもっと長くなります。「ダウンタイム見積もり」を手順書に書くなら、自分の環境で実測した値を根拠にしてください。見積もりの根拠が「ネット記事に数秒と書いてあった」では、承認を取る場で説明できません😇

リーダーのクラスだけ上げて放置するとどうなるか

スケールアップの途中で「とりあえずリーダーだけ大きくして、ライターは次のメンテナンスで」という判断をすると、ライターと Tier 0 リーダーのインスタンスクラスが不一致のまま運用されることになります。これは CCM の前提から外れた状態であり、障害時のフェイルオーバーでキャッシュウォームアップ短縮の効果が期待どおりに得られない可能性があります。

さらに実務的な問題として、不一致状態は気づかれないまま放置されがちです。作業を途中で止めるなら、その状態を課題管理に残し、ライターと Tier 0 のクラス一致を定期チェックの項目に入れてください。RDS / Aurora 運用で押さえるべき内部の仕組みと監視の全体像は RDS・Aurora 運用・トラブル解決ガイド|仕組み・障害切り分け・性能監視の全体像 にまとめているので、チェックリストを作るときの土台として使えます。

📊 検証環境で書き込み中断時間を実測する方法

本番適用の前に、検証環境で同じ流れを一度通しておくことをおすすめします。所要時間を見積もる手段としても、手順書の抜けを見つける手段としても有効です。

CCM 有効の最小構成クラスターで同じ流れを再現する

検証に必要なのは、本番と同じ台数のクラスターではなく、同じ構造のクラスターです。

  • ライター 1 台+リーダー 1 台の最小構成で Aurora PostgreSQL クラスターを作成する
  • クラスターパラメータグループで apg_ccm_enabled を有効にし、インスタンスへ反映されていることを SHOW apg_ccm_enabled; で確認する
  • リーダーの Promotion Tier を 0 に設定する
  • ライターとリーダーのインスタンスクラスを一致させ、CCM の前提を満たした状態を作る

この状態から、「リーダーのインスタンスクラス変更、手動フェイルオーバー、旧ライターのインスタンスクラス変更」を本番と同じコマンドで実施します。本番で使う予定のコマンドをそのままコピーして使えば、手順書との差分が出ません。

ただし、検証環境のインスタンスサイズやデータ量が本番と大きく違う場合、所要時間の絶対値はそのまま本番の見積もりにはなりません。手順の妥当性の検証と時間の見積もりは分けて考え、後者は本番に近い構成で測ってください。

各段階の書き込み中断時間とフェイルオーバー後のロールを記録する

書き込み中断時間は、クラスターエンドポイントに対して一定間隔で書き込みを続け、途切れた区間を見ることで測ります。たとえば次のような計測用テーブルと投入ループを使います。

CREATE TABLE IF NOT EXISTS failover_probe (
  id    bigserial PRIMARY KEY,
  ts    timestamptz NOT NULL DEFAULT clock_timestamp(),
  node  text        NOT NULL DEFAULT inet_server_addr()::text
);
while true; do
  psql "host=<クラスターエンドポイント> port=5432 dbname=<DB名> user=<ユーザー> \
        connect_timeout=2" \
    -c "INSERT INTO failover_probe DEFAULT VALUES;" \
    >/dev/null 2>>probe_error.log \
    || echo "$(date -u +%FT%T.%3NZ) insert failed" >> probe_error.log
  sleep 0.2
done

計測後、投入レコードの時刻の差分から最大のギャップを求めれば、書き込みが途切れていた区間が分かります。

SELECT ts,
       ts - lag(ts) OVER (ORDER BY ts) AS gap
FROM failover_probe
ORDER BY gap DESC NULLS LAST
LIMIT 10;

記録しておくべき項目は次のとおりです。

  • 手順 1(リーダー変更)の間に書き込みギャップが発生していないこと。ここでギャップが出るなら、リーダーエンドポイントとクラスターエンドポイントの使い分けやアプリの接続設定を見直す必要があります
  • 手順 2(手動フェイルオーバー)での最大ギャップ。これが本番で見積もるべきダウンタイムに相当します
  • 手順 3(旧ライター変更)の間に書き込みギャップが発生していないこと
  • 各段階の前後でのロール割り当て(IsClusterWriter)と Promotion Tier、インスタンスクラス、AZ
  • フェイルオーバー時のクライアント側エラーメッセージ。アプリのリトライ設計を決めるうえで、どのエラーが返るかを実際に見ておく価値があります

あわせて、RDS のイベント履歴(aws rds describe-events)を取得し、インフラ側が各処理をいつ開始・完了したかと、アプリ側で観測したギャップの時刻を突き合わせます。「インフラ側は終わっていたのにアプリの断が続いた」区間が見えれば、それはアプリ側のチューニング対象です。

キャッシュウォームアップの効果を見るために確認する指標

CCM の効果は「フェイルオーバー直後の性能の落ち込みが小さいこと」として現れます。所要時間だけでなく、次の指標をフェイルオーバー前後で比較してください。

CloudWatch 側では、新ライターのバッファキャッシュのヒット状況と読み取り系のメトリクスを見ます。キャッシュが冷えていれば、フェイルオーバー直後にストレージからの読み取りが増え、読み取りレイテンシやコミットのレイテンシが一時的に悪化します。CCM が効いていれば、この悪化の幅と継続時間が小さくなるはずです。

PostgreSQL 内部からは、pg_stat_database のブロック読み取り状況を一定間隔でスナップショットし、差分を見るのが分かりやすい方法です。

SELECT datname, blks_read, blks_hit,
       round(100.0 * blks_hit / nullif(blks_hit + blks_read, 0), 2) AS hit_pct
FROM pg_stat_database
WHERE datname = current_database();

フェイルオーバー直前に値を取り、直後から数分おきに取って差分のヒット率を比較します。あわせて、アプリの代表的なクエリについて pg_stat_statements の平均実行時間や、待機イベント(Performance Insights の上位待機)を見ると、どこで待っていたのかが具体的に分かります。読み取り待ちが支配的ならキャッシュの冷えが原因、ロック待ちが支配的なら別の要因、という切り分けができます。

比較のためには、CCM を無効にした場合との対比を取るのが最も説得力があります。検証環境で apg_ccm_enabled を無効にして同じフェイルオーバーを実施し、同じ指標を取って並べれば、自分の環境における CCM の効果を数字で示せます✨

OSS-DB Silver 対策テキスト(OSS教科書)

PostgreSQLの仕組みを体系的に学ぶなら、OSS-DB Silverの公式対応テキストが近道です。資格を取らなくても基礎固めに役立ちます。

OSS教科書 OSS-DB Silver Ver.3.0対応 (EXAMPRESS) [ 福岡 博 ]

OSS教科書 OSS-DB Silver Ver.3.0対応 (EXAMPRESS) [ 福岡 博 ]

❓ よくある質問

CCM が有効でもインスタンスクラスは変更できる?

変更できます。CCM はインスタンスクラス変更をブロックする機能ではありません。ただし CCM は「ライターと Tier 0 リーダーが同じインスタンスクラスであること」を前提にした機能なので、変更の最終状態で両者のクラスが一致するように作業を設計します。

変更の途中で一時的に不一致になるのは避けられません。だからこそ、不一致の時間を短くするために「リーダー変更、すぐフェイルオーバー、旧ライター変更」を連続して実施する計画にします。作業を日をまたいで分割すると、不一致状態が長く続くことになります。

ライターとリーダーでインスタンスクラスが違うままだとどうなる?

CCM の前提を満たしていない状態になります。ライターより小さいクラスのリーダーが Tier 0 になっていると、ライターのワーキングセットを同じようにキャッシュへ載せられず、フェイルオーバー時のキャッシュウォームアップ短縮という CCM の効果が期待どおりに得られない可能性があります。

加えて、障害起因のフェイルオーバーでそのリーダーが昇格した場合、書き込みを小さいインスタンスで受けることになるという容量面のリスクもあります。スケールアップしたのは負荷が増えたからであり、昇格先が旧クラスのままなら、障害時にその負荷を受け切れない可能性を考える必要があります。クラス一致は CCM のためだけでなく、可用性設計の一部として扱う項目です。

手動フェイルオーバーなしでスケールアップできる?

ライターのインスタンスクラスを直接変更すれば、手動フェイルオーバーなしでスケールアップは可能です。ただしその場合、変更に伴う再起動が完了するまで書き込みが止まります。自動フェイルオーバーは発生しないので、代替の書き込み先はありません。

したがって選択は次のようになります。書き込み停止を最短にしたいなら、リーダー先行+手動フェイルオーバーを選び、ライターの AZ が入れ替わる副作用を受け入れます。ロール配置や AZ を変えたくなく、停止時間を長めに確保できるなら、ライター直接変更でも構いません。ただし停止時間は長くなる前提で計画します。

夜間の十分なメンテナンス枠が確保できて、ライターの AZ を固定したい要件があるなら後者も選択肢です。日中のサービス稼働中に実施するなら、前者を選ぶことになります。

スケールダウンのときも同じ順序でいい?

基本的な順序は同じです。「Tier 0 リーダーを小さいクラスへ変更、そのリーダーへ手動フェイルオーバー、旧ライターを小さいクラスへ変更」で、書き込み停止はフェイルオーバーの一回に限定できます。

⚠️ ただしスケールダウンには固有の注意点があります。昇格先が小さいインスタンスになるため、フェイルオーバー直後に現在の負荷を受け切れるかどうかを事前に見積もってください。バッファキャッシュのサイズも小さくなるので、CCM でウォームにしていても、載せられるページ数自体が減ります。CPU、メモリ、コネクション数、キャッシュヒット率の現状を確認し、縮小後のクラスで足りることを確かめてから実施します。負荷が低い時間帯を選ぶのも有効です。

スケールダウン後も Tier 0 とクラス一致の条件が維持されているかは、スケールアップと同じように確認します。

🔁 繰り返すスケール変更に備えた再発防止と運用設計

ライターの AZ が入れ替わる前提でアプリ側の接続を設計する

この手順は手動フェイルオーバーを含むため、スケールアップとスケールダウンを繰り返すたびに、書き込みを担うインスタンスが入れ替わります。ライターとリーダーを別々の AZ に配置している構成では、ライターの AZ も入れ替わります。

ここから導かれる設計上の要件は次のとおりです。

  • アプリケーションは特定のインスタンスエンドポイントや AZ に依存しない。接続先はクラスターエンドポイント(書き込み)とリーダーエンドポイント(参照)を使い、インスタンスエンドポイントを設定ファイルに直書きしない
  • DNS を再解決する構成にする。JVM の DNS キャッシュ設定やコネクションプールの接続寿命(最大生存時間)を、エンドポイントの切り替えに追従できる値にしておく
  • リトライを実装する。フェイルオーバー中の書き込みエラーは一時的なものなので、バックオフを入れたリトライで吸収できる範囲が広がります
  • AZ 間通信のレイテンシとデータ転送を考慮する。アプリの稼働 AZ とライターの AZ が離れると、クロス AZ の通信が増えます。レイテンシ要件が厳しいシステムでは、この影響を事前に評価します

これらが整っていない環境では、インフラ側の手順をどれだけ最適化しても、アプリから見たダウンタイムは縮まりません😇

スケール変更を手順書化し、Tier 0 とクラス一致を定期チェックする

同じ作業を複数人で、あるいは数か月おきに実施するなら、手順書に落とすのが前提です。少なくとも次の内容を含めてください。

  • 作業前チェック:各インスタンスのクラス・ステータス・AZ・Promotion Tier、apg_ccm_enabled の値、実行中の長時間トランザクションの有無
  • 実行コマンド:modify-db-instance と failover-db-cluster を、--target-db-instance-identifier を明示した形で記載する
  • 各ステップの完了条件:次のステップに進む判断基準(DBInstanceStatus が available、DBInstanceClass が期待値、IsClusterWriter が期待値)を明文化する
  • 作業後チェック:ライターと Tier 0 のクラス一致、Tier 設定の妥当性、AZ 配置の記録、アプリからの書き込み・参照の疎通
  • 切り戻し手順:想定外のロール配置になった場合に、どのインスタンスへ再フェイルオーバーするか

さらに、日常の運用チェックに「ライターと Tier 0 リーダーのインスタンスクラスが一致しているか」「Tier 0 のリーダーが 1 台存在するか」を加えておくと、作業の途中で止まった構成や、インスタンス追加時の設定漏れを早期に検知できます。前述の describe-db-clusters と describe-db-instances を組み合わせたスクリプトを定期実行し、期待値と差分があれば通知する作りにしておけば十分です。

Aurora のバージョンやエンジン(PostgreSQL / MySQL)によって利用できる機能や挙動は異なります。CCM は Aurora PostgreSQL の機能であり、Aurora MySQL では同じパラメータ名の設定はありません。マルチクラスター構成や Global Database を併用している場合は、フェイルオーバーの影響範囲がさらに広がるため、個別に確認が必要です。

定期的なスケール変更が必要なら Aurora Serverless v2 も検討する

プロビジョンドインスタンスのクラス変更は、どう工夫しても「再起動またはフェイルオーバーのどちらかを通る」作業です。これを月次・週次で繰り返すのは、作業負荷の面でもリスクの面でも割に合わなくなってきます。

負荷の変動が大きく、定期的なスケール変更が前提になるワークロードであれば、Aurora Serverless v2 を代替として検討する価値があります。Serverless v2 は処理を中断することなく自動的にキャパシティをスケーリングするため、インスタンスクラス変更のたびにフェイルオーバーを計画する必要がなくなります✨

ただし移行判断にあたっては、次の点を自分のワークロードで評価してください。

  • 最小 ACU / 最大 ACU の設定レンジと、ワークロードのピーク・ボトムが収まるか
  • コスト構造がプロビジョンドと変わるため、実際の稼働パターンでの試算が必要になること
  • 利用しているエンジンバージョンや機能が Serverless v2 でサポートされているか
  • 既存のプロビジョンドクラスターから移行する際の手順と停止時間

「スケール変更の手間をなくしたいから Serverless v2」という単純な話にはならないので、現在の負荷パターンを CloudWatch と Performance Insights で把握した上で比較します。負荷が安定していてスケール変更が年に数回程度なら、プロビジョンドのまま今回の手順を手順書化しておくほうが合理的なケースも多くあります。


Aurora の仕様や各サービスの制限値、対応バージョンは変更されることがあります。実際の作業計画を確定する前に、Cluster Cache Management、インスタンスクラス変更、フェイルオーバーに関する AWS の公式ドキュメントで最新の仕様を確認し、本番適用前に検証環境で一度通してから実施してください。