Amazon RDS Blue/Green Deployments で Amazon Aurora PostgreSQL のメジャーバージョンアップをしてみた
短いダウンタイムでメジャーバージョンアップを行いたい
こんにちは、のんピ(@non____97)です。
皆さんはAmazon Aurora PostgreSQLを短いダウンタイムでメジャーバージョンアップしたいなと思ったことはありますか? 私はあります。
インプレースアップグレードで行うと、数十分ほどダウンタイムが発生します。よりダウンタイムを短くしようとするとDMSやPostgreSQLの機能で論理レプリケーションをして、DNSレコードを切り替えるといった方法があります。しかし、それは中々準備が大変です。
そんな時に役立つのがRDS Blue/Green Deploymentsです。ワークロードにもよりますが、RDS Blue/Green Deploymentsを活用することでダウンタイムを1分ほどに抑えることが可能です。
RDS Blue/Green Deploymentsの詳細は以下記事やAWS公式ドキュメントをご覧ください。
RDS Blue/Green DeploymentsがGAしたタイミングではRDS for MySQLとAurora MySQLのみでしたが、去年、RDS for PostgreSQLとAurora PostgreSQLでもサポートされました。
実際にRDS Blue/Green Deploymentsを使ってメジャーバージョンアップを試してみます。
いきなりまとめ
- RDS Blue/Green Deploymentsを使うことで、ダウンタイムが1分ほどで切り替えができる
- 論理レプリケーションのラグや書き込み量によって実際のダウンタイムは変動する
- RDS Blue/Green DeploymentsはSecrets Managerの統合を未サポート
- バージョンアップをする際は、Green側でのレプリカが作成完了した後にDBエンジンのバージョンアップを行う
- 検証ではGreen環境のAurora DBクラスターの作成が完了するまで40分かかった
- DDLの変更を行うと、BlueからGreenへのレプリケーションが停止する
- Blue/Green Deploymentsを再作成する必要がある
- Aurora PostgreSQL 16もRDS Blue/Green Deploymentsに対応している
- RDS Blue/Green Deployments切り替え後、新Blueに対してAWS CDKで更新することは可能
やってみた
検証環境
検証環境は以下のとおりです。
検証環境はAWS CDKでデプロイしました。使用したコードは以下リポジトにあります。
Aurora PostgreSQL 14.10から15.5にアップデートします。2024/2/6時点での14.10からのアップグレードターゲットは以下のとおりです。
$ aws rds describe-db-engine-versions \ --engine aurora-postgresql \ --engine-version 14.10 \ --query 'DBEngineVersions[*].ValidUpgradeTarget[*].{EngineVersion:EngineVersion}' \ --output text 15.5 16.1
最新の情報は以下AWS公式ドキュメントをご覧ください。
ちなみに、Aurora DBクラスターでSecrets Managerの統合を設定しているとSecrets Manager はブルー/グリーンデプロイの作成機能をサポートしていません。この DB クラスターにブルー/グリーンデプロイを作成するには、まず、この DB クラスターを変更して Secrets Manager の統合をオフにする必要があります。
とエラーになります。注意しましょう。
EC2インスタンスにpsqlをインストール
EC2インスタンスにpsqlをインストールします。GreenのAurora DBクラスターはPostgreSQL 15にするので、PostgreSQL 15のクライアントをインストールします。
$ sudo dnf install postgresql15 Last metadata expiration check: 0:35:35 ago on Mon Feb 5 04:31:27 2024. Dependencies resolved. ================================================================================================ Package Architecture Version Repository Size ================================================================================================ Installing: postgresql15 x86_64 15.5-1.amzn2023.0.1 amazonlinux 1.6 M Installing dependencies: postgresql15-private-libs x86_64 15.5-1.amzn2023.0.1 amazonlinux 142 k Transaction Summary ================================================================================================ Install 2 Packages Total download size: 1.8 M Installed size: 6.9 M Is this ok [y/N]: y Downloading Packages: (1/2): postgresql15-private-libs-15.5-1.amzn2023.0.1.x86_64.rpm 1.1 MB/s | 142 kB 00:00 (2/2): postgresql15-15.5-1.amzn2023.0.1.x86_64.rpm 11 MB/s | 1.6 MB 00:00 ------------------------------------------------------------------------------------------------ Total 7.7 MB/s | 1.8 MB 00:00 Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : postgresql15-private-libs-15.5-1.amzn2023.0.1.x86_64 1/2 Installing : postgresql15-15.5-1.amzn2023.0.1.x86_64 2/2 Running scriptlet: postgresql15-15.5-1.amzn2023.0.1.x86_64 2/2 Verifying : postgresql15-private-libs-15.5-1.amzn2023.0.1.x86_64 1/2 Verifying : postgresql15-15.5-1.amzn2023.0.1.x86_64 2/2 Installed: postgresql15-15.5-1.amzn2023.0.1.x86_64 postgresql15-private-libs-15.5-1.amzn2023.0.1.x86_64 Complete!
Aurora DBクラスターへの接続確認
Aurora DBクラスターへ接続します。認証情報はSecrets Managerに保存されています。
$ get_secrets_value=$(aws secretsmanager get-secret-value \ --secret-id AuroraSecret7ACECA7F-IzECtgHudC8Q \ --region us-east-1 \ | jq -r .SecretString) $ export PGHOST=$(echo "${get_secrets_value}" | jq -r .host) $ export PGPORT=$(echo "${get_secrets_value}" | jq -r .port) $ export PGDATABASE=$(echo "${get_secrets_value}" | jq -r .dbname) $ export PGUSER=$(echo "${get_secrets_value}" | jq -r .username) $ export PGPASSWORD=$(echo "${get_secrets_value}" | jq -r .password) $ psql psql (15.5, server 14.10) SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off) Type "help" for help. testDB=> \dt Did not find any relations. testDB=> \l List of databases Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges -----------+----------+----------+-------------+-------------+------------+-----------------+----------------------- postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | rdsadmin | rdsadmin | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | rdsadmin=CTc/rdsadmin template0 | rdsadmin | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/rdsadmin + | | | | | | | rdsadmin=CTc/rdsadmin template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres + | | | | | | | postgres=CTc/postgres testDB | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | (5 rows)
DBにサンプルデータを投入
DBにサンプルデータを投入します。投入するデータはISOが割り振っている地理情報です。
$ curl https://ftp.postgresql.org/pub/projects/pgFoundry/dbsamples/iso-3166/iso-3166-1.0/iso-3166-1.0.tar.gz \ -s \ -o iso-3166-1.0.tar.gz $ ls -l total 40 -rw-rw-r--. 1 ssm-user ssm-user 39677 Feb 5 05:12 iso-3166-1.0.tar.gz $ tar zxvf iso-3166-1.0.tar.gz iso-3166/ iso-3166/iso-3166.sql $ createdb -U postgres iso $ psql -U postgres -f iso-3166/iso-3166.sql iso BEGIN SET CREATE TABLE COPY 242 CREATE TABLE COPY 3995 COMMIT ANALYZE ANALYZE
投入後、DBやテーブルを確認します。
$ psql iso psql (15.5, server 14.10) SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off) Type "help" for help. iso=> \dt List of relations Schema | Name | Type | Owner --------+------------+-------+---------- public | country | table | postgres public | subcountry | table | postgres (2 rows) iso=> \d country Table "public.country" Column | Type | Collation | Nullable | Default ------------+---------+-----------+----------+--------- name | text | | not null | two_letter | text | | not null | country_id | integer | | not null | Indexes: "country_pkey" PRIMARY KEY, btree (two_letter) Referenced by: TABLE "subcountry" CONSTRAINT "subcountry_country_fkey" FOREIGN KEY (country) REFERENCES country(two_letter) iso=> \d subcountry Table "public.subcountry" Column | Type | Collation | Nullable | Default ------------------+------+-----------+----------+--------- country | text | | not null | subcountry_name | text | | not null | subdivision | text | | | subcountry_level | text | | | Indexes: "subcountry_country_subcountry_name_key" UNIQUE CONSTRAINT, btree (country, subcountry_name) Foreign-key constraints: "subcountry_country_fkey" FOREIGN KEY (country) REFERENCES country(two_letter) iso=> SELECT constraint_type, * FROM information_schema.table_constraints; constraint_type | constraint_catalog | constraint_schema | constraint_name | table_catalog | table_schema | table_name | constraint_type | is_deferrable | initially_deferred | enforced -----------------+--------------------+-------------------+----------------------------------------+---------------+--------------+------------+-----------------+---------------+--------------------+---------- PRIMARY KEY | iso | public | country_pkey | iso | public | country | PRIMARY KEY | NO | NO | YES UNIQUE | iso | public | subcountry_country_subcountry_name_key | iso | public | subcountry | UNIQUE | NO | NO | YES FOREIGN KEY | iso | public | subcountry_country_fkey | iso | public | subcountry | FOREIGN KEY | NO | NO | YES CHECK | iso | public | 2200_20491_1_not_null | iso | public | country | CHECK | NO | NO | YES CHECK | iso | public | 2200_20491_2_not_null | iso | public | country | CHECK | NO | NO | YES CHECK | iso | public | 2200_20491_3_not_null | iso | public | country | CHECK | NO | NO | YES CHECK | iso | public | 2200_20498_1_not_null | iso | public | subcountry | CHECK | NO | NO | YES CHECK | iso | public | 2200_20498_2_not_null | iso | public | subcountry | CHECK | NO | NO | YES (8 rows)
country
とsubcountry
というテーブルが作成されています。
それぞれの中身は以下のようなレコードが入っています。
iso=> SELECT * FROM country LIMIT 10; name | two_letter | country_id ---------------------+------------+------------ Afghanistan | AF | 4 Albania | AL | 8 Algeria | DZ | 12 American Samoa | AS | 16 Andorra | AD | 20 Angola | AO | 24 Anguilla | AI | 660 Antarctica | AQ | 10 Antigua and Barbuda | AG | 28 Argentina | AR | 32 (10 rows) iso=> SELECT count(*) FROM country; count ------- 242 (1 row)
iso=> SELECT * FROM subcountry LIMIT 10; country | subcountry_name | subdivision | subcountry_level ---------+-----------------+-----------------------+------------------ AD | AN | Andorra la Vella | AD | CA | Canillo | AD | EE | Escaldes-Engordany | AD | EN | Encamp | AD | JL | Sant Julià de Lòria | AD | MA | La Massana | AD | OR | Ordino | AE | AJ | Ajman | AE | AZ | Abu Z¸aby [Abu Dhabi] | AE | DU | Dubayy [Dubai] | (10 rows) iso=> SELECT count(*) FROM subcountry; count ------- 3995 (1 row)
作成されたテーブルにレコードを追加します。まず、country
テーブルに私の王国non-97 kingdom
を追加します。
iso=> SELECT MAX(country_id) FROM country; max ----- 894 (1 row) iso=> INSERT INTO public.country values ('non-97 kingdom', 'NK', 10000); INSERT 0 1 iso=> SELECT * FROM country WHERE two_letter='NK'; name | two_letter | country_id ----------------+------------+------------ non-97 kingdom | NK | 10000 (1 row)
subcountry
にもレコードを追加します。country
はcountry
テーブルのtwo_letter
の外部キーです。
iso=> INSERT INTO public.subcountry values ('NK', current_timestamp, current_timestamp); INSERT 0 1 iso=> INSERT INTO public.subcountry values ('NK', current_timestamp, current_timestamp); INSERT 0 1 iso=> SELECT * FROM public.subcountry WHERE country='NK'; country | subcountry_name | subdivision | subcountry_level ---------+-------------------------------+-------------------------------+------------------ NK | 2024-02-05 05:40:47.217177+00 | 2024-02-05 05:40:47.217177+00 | NK | 2024-02-05 05:40:52.079011+00 | 2024-02-05 05:40:52.079011+00 | (2 rows)
マテビューも作成しておきます。
iso=> CREATE MATERIALIZED VIEW nk_view AS SELECT country, subcountry_name, subdivision, subcountry_level FROM public.subcountry WHERE country='NK'; SELECT 2 iso=> SELECT * FROM nk_view; country | subcountry_name | subdivision | subcountry_level ---------+-------------------------------+-------------------------------+------------------ NK | 2024-02-05 05:40:47.217177+00 | 2024-02-05 05:40:47.217177+00 | NK | 2024-02-05 05:40:52.079011+00 | 2024-02-05 05:40:52.079011+00 | (2 rows)
Blue/Green Deploymentsの作成
Blue/Green Deploymentsの作成をします。
作成手順や注意点、準備事項は以下AWS公式ドキュメントにまとまっています。
Blue/Green Deploymentsの作成をするにあたって、事前に論理レプリケーションを有効にする必要があります。
ブルー/グリーンデプロイ用 Aurora PostgreSQL クラスターの準備
Aurora PostgreSQL DB クラスターのブルー/グリーンデプロイを作成する前に、以下を実行するようにしてください。
- クラスターを、論理レプリケーション (rds.logical_replication) が有効になっているカスタム DB クラスターパラメータグループに関連付けます。ブルー環境からグリーン環境へのレプリケーションには、論理レプリケーションが必要です。論理レプリケーションを有効にする手順については、「Aurora PostgreSQL DB クラスターの論理レプリケーションの設定」を参照してください。
- 論理レプリケーションを有効にした後は、必ず DB クラスターを再起動して変更を有効にしてください。ブルー/グリーンデプロイでは、ライターインスタンスが DB クラスターパラメータグループと同期している必要があり、同期していない場合は作成に失敗します。詳細については、「Aurora クラスター内の DB インスタンスの再起動」を参照してください。
- DB クラスターがブルー/グリーンデプロイと互換性のあるバージョンの Aurora PostgreSQL を実行していることを確認してください。互換性のあるバージョンの一覧については、「Aurora PostgreSQL によるブルー/グリーンデプロイ」を参照してください。
- DB クラスターが外部レプリケーションのソースでもターゲットでもないことを確認します。詳細については、「ブルー/グリーンデプロイの一般的な制約事項」を参照してください。
- DB クラスターのすべてのテーブルにプライマリキーがあることを確認します。PostgreSQL の論理レプリケーションでは、プライマリキーのないテーブルに対する UPDATE または DELETE オペレーションは許可されません。
論理レプリケーションが有効(rds.logical_replication
がon
)であることを確認します。
iso=> SELECT * FROM pg_settings WHERE name IN ('wal_level','rds.logical_replication','max_replication_slots','max_wal_sender','max_logical_replication_worker','max_worker_processes'); name | setting | unit | category | short_desc | extra_desc | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | sourcefile | sourceline | pending_restart -------------------------+---------+------+----------------------------------------+----------------------------------------------------------------------+------------+------------+---------+--------------------+---------+---------+---------------------------+----------+-----------+-----------------------------------+------------+----------------- max_replication_slots | 20 | | Replication / Sending Servers | Sets the maximum number of simultaneously defined replication slots. | | postmaster | integer | configuration file | 0 | 262143 | | 10 | 20 | /rdsdbdata/config/postgresql.conf | 182 | f max_worker_processes | 8 | | Resource Usage / Asynchronous Behavior | Maximum number of concurrent worker processes. | | postmaster | integer | configuration file | 0 | 262143 | | 8 | 8 | /rdsdbdata/config/postgresql.conf | 22 | f rds.logical_replication | on | | Customized Options | Enables logical decoding. | | postmaster | bool | configuration file | | | | off | on | /rdsdbdata/config/postgresql.conf | 168 | f wal_level | logical | | Write-Ahead Log / Settings | Sets the level of information written to the WAL. | | postmaster | enum | configuration file | | | {minimal,replica,logical} | replica | logical | /rdsdbdata/config/postgresql.conf | 175 | f (4 rows)
有効でない場合はパラメーターグループを変更します。なお、こちらのパラメーターを変更内容を反映させるためにはDBインスタンスを再起動させる必要があります。レプリカが存在していていたとしてもフェイルオーバーによるダウンタイムが発生するので注意しましょう。
Aurora DBクラスターを選択してブルー/グリーンデプロイの作成
をクリックします。
注意事項を確認して確認
をクリックします。
Blue/Green Deployments識別子やGreenのDBエンジンバージョン、DBクラスターパラメーターグループ、DBパラメーターグループを選択します。
選択できるDBエンジンの一覧は以下のとおりです。
2024/2/5時点のAWS公式ドキュメントではAurora PostgreSQL 16についての記述はありませんが、16.1からサポートしていそうですね。
抜粋 : Blue/Green Deployments - Amazon Aurora
ステージング環境の作成
をクリックすると、Blue/Green Deploymentsが作成が開始されました。
作成開始直後だからかGreenの情報はまだ確認できていません。
ステータスを確認すると、「リードレプリカの作成」と「DBエンジンのバージョンアップ」の処理があることが分かります。現在はリードレプリカの作成中のようです。
15分ほど待つと、GreenのAurora DBクラスターが作成ステータスが進んでいました。
現時点ではGreenのDBエンジンバージョンもBlueのDBエンジンバージョンも同じ14.10です。
さらに10分ほど待つと、GreenのAurora DBクラスターのバージョンアップが開始していました。
ふと、バージョンアップ中の更新もレプリケーションされるのか気になりました。BlueのAurora DBクラスターで以下のようにレコードを追加します。
iso=> INSERT INTO public.subcountry values ('NK', current_timestamp, current_timestamp); INSERT 0 1 iso=> SELECT * FROM public.subcountry WHERE country='NK'; country | subcountry_name | subdivision | subcountry_level ---------+-------------------------------+-------------------------------+------------------ NK | 2024-02-05 05:40:47.217177+00 | 2024-02-05 05:40:47.217177+00 | NK | 2024-02-05 05:40:52.079011+00 | 2024-02-05 05:40:52.079011+00 | NK | 2024-02-05 06:28:00.036196+00 | 2024-02-05 06:28:00.036196+00 | (3 rows)
15分ほど待つと、GreenのAurora DBクラスターのバージョンが指定した15.5にバージョンアップしていました。
Green環境のステータスでも「DBエンジンのバージョンアップ」が完了
となっていますね。
最近のイベントは以下のとおりです。Blueについてのイベントか、Greenについてのイベントか分かりやすいです。
詳細は以下のとおりです。トータルで40分ほどかかりました。
DB 識別子 | ロール | 時間 | システムノート |
---|---|---|---|
db-cluster (Blue) | プライマリ | February 05, 2024, 13:30 (UTC+09:00) | DB cluster created |
db-instance-writer (Blue) | プライマリ | February 05, 2024, 13:33 (UTC+09:00) | The parameter max_wal_senders was set to a value incompatible with replication. It has been adjusted from 10 to 20. |
db-instance-writer (Blue) | プライマリ | February 05, 2024, 13:34 (UTC+09:00) | The parameter max_wal_senders was set to a value incompatible with replication. It has been adjusted from 10 to 20. |
db-instance-writer (Blue) | プライマリ | February 05, 2024, 13:35 (UTC+09:00) | DB instance created |
db-instance-writer (Blue) | プライマリ | February 05, 2024, 13:36 (UTC+09:00) | CloudWatch Logs Export enabled for logs [postgresql] |
db-instance-writer (Blue) | プライマリ | February 05, 2024, 13:38 (UTC+09:00) | Monitoring Interval changed to 60 |
db-instance-writer (Blue) | プライマリ | February 05, 2024, 13:38 (UTC+09:00) | Performance Insights has been enabled |
db-instance-writer (Blue) | プライマリ | February 05, 2024, 13:54 (UTC+09:00) | The parameter max_wal_senders was set to a value incompatible with replication. It has been adjusted from 10 to 20. |
db-cluster (Blue) | プライマリ | February 05, 2024, 13:55 (UTC+09:00) | Reset master credentials |
db-instance-writer (Blue) | プライマリ | February 05, 2024, 13:55 (UTC+09:00) | DB instance shutdown |
db-instance-writer (Blue) | プライマリ | February 05, 2024, 13:55 (UTC+09:00) | The parameter max_wal_senders was set to a value incompatible with replication. It has been adjusted from 10 to 20. |
db-instance-writer (Blue) | プライマリ | February 05, 2024, 13:56 (UTC+09:00) | DB instance restarted |
db-cluster-green-ak5mgh (Green) | プライマリ | February 05, 2024, 15:12 (UTC+09:00) | DB cluster created |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:16 (UTC+09:00) | The parameter max_wal_senders was set to a value incompatible with replication. It has been adjusted from 10 to 20. |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:17 (UTC+09:00) | The parameter max_wal_senders was set to a value incompatible with replication. It has been adjusted from 10 to 20. |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:17 (UTC+09:00) | The parameter rds.logical_replication was set to a value incompatible with logical replication. It has been adjusted from 0 to 1. Please drop all logical replication slots before disabling logical decoding. |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:17 (UTC+09:00) | The parameter max_wal_senders was set to a value incompatible with replication. It has been adjusted from 10 to 20. |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:19 (UTC+09:00) | DB instance created |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:20 (UTC+09:00) | Replication has stopped. |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:20 (UTC+09:00) | CloudWatch Logs Export enabled for logs [postgresql] |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:22 (UTC+09:00) | Replication for the Read Replica resumed |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:23 (UTC+09:00) | Performance Insights has been enabled |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:23 (UTC+09:00) | Monitoring Interval changed to 60 |
db-cluster-green-ak5mgh (Green) | プライマリ | February 05, 2024, 15:24 (UTC+09:00) | Database cluster engine version upgrade started. |
db-cluster-green-ak5mgh (Green) | プライマリ | February 05, 2024, 15:24 (UTC+09:00) | Upgrade in progress: Performing online pre-upgrade checks. |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:25 (UTC+09:00) | DB instance shutdown |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:25 (UTC+09:00) | The parameter max_wal_senders was set to a value incompatible with replication. It has been adjusted from 10 to 20. |
db-cluster-green-ak5mgh (Green) | プライマリ | February 05, 2024, 15:26 (UTC+09:00) | Upgrade in progress: Creating pre-upgrade snapshot [preupgrade-db-cluster-green-ak5mgh-14-10-to-15-5-2024-02-05-06-24]. |
db-cluster-green-ak5mgh (Green) | プライマリ | February 05, 2024, 15:28 (UTC+09:00) | Upgrade in progress: Cloning volume. |
db-cluster-green-ak5mgh (Green) | プライマリ | February 05, 2024, 15:30 (UTC+09:00) | Upgrade in progress: Upgrading writer. |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:35 (UTC+09:00) | The parameter max_wal_senders was set to a value incompatible with replication. It has been adjusted from 10 to 20. |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:35 (UTC+09:00) | DB instance shutdown |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:35 (UTC+09:00) | The parameter max_wal_senders was set to a value incompatible with replication. It has been adjusted from 10 to 20. |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:36 (UTC+09:00) | DB instance shutdown |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:36 (UTC+09:00) | The parameter max_wal_senders was set to a value incompatible with replication. It has been adjusted from 10 to 20. |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:36 (UTC+09:00) | DB instance restarted |
db-cluster-green-ak5mgh (Green) | プライマリ | February 05, 2024, 15:37 (UTC+09:00) | Updated to use DBParameterGroup aurorastack-auroradbclusterparametergroup150c75b72f-olcenkiixqad |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:37 (UTC+09:00) | Replication has stopped. |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:37 (UTC+09:00) | The parameter max_wal_senders was set to a value incompatible with replication. It has been adjusted from 10 to 20. |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:38 (UTC+09:00) | The parameter max_wal_senders was set to a value incompatible with replication. It has been adjusted from 10 to 20. |
db-cluster-green-ak5mgh (Green) | プライマリ | February 05, 2024, 15:39 (UTC+09:00) | Database cluster engine major version has been upgraded. |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:39 (UTC+09:00) | The parameter max_wal_senders was set to a value incompatible with replication. It has been adjusted from 10 to 20. |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:40 (UTC+09:00) | Replication for the Read Replica resumed |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 15:40 (UTC+09:00) | Updated to use DBParameterGroup aurorastack-auroradbparametergroup158895769d-slpjow9ruia7 |
bgd-hy5ntvomddiv89r8 | ブルー/グリーンデプロイ | February 05, 2024, 15:40 (UTC+09:00) | Blue/green deployment tasks completed. You can make more modifications to the green environment databases or switch over the deployment. |
ちなみに、GreenのAurora DBクラスター作成中、BlueのAurora DBクラスターへの接続が途切れるということはありませんでした。
レプリケーションされているか確認
レプリケーションされているか確認します。
GreenのAurora DBクラスターに接続します。
$ get_secrets_value=$(aws secretsmanager get-secret-value \ --secret-id AuroraSecret7ACECA7F-IzECtgHudC8Q \ --region us-east-1 \ | jq -r .SecretString) $ export PGHOST=db-cluster-green-ak5mgh.cluster-cicjym7lykmq.us-east-1.rds.amazonaws.com $ export PGPORT=$(echo "${get_secrets_value}" | jq -r .port) $ export PGDATABASE=$(echo "${get_secrets_value}" | jq -r .dbname) $ export PGUSER=$(echo "${get_secrets_value}" | jq -r .username) $ export PGPASSWORD=$(echo "${get_secrets_value}" | jq -r .password) $ psql iso psql (15.5) SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off) Type "help" for help. iso=> SELECT * FROM public.subcountry WHERE country='NK'; country | subcountry_name | subdivision | subcountry_level ---------+-------------------------------+-------------------------------+------------------ NK | 2024-02-05 05:40:47.217177+00 | 2024-02-05 05:40:47.217177+00 | NK | 2024-02-05 05:40:52.079011+00 | 2024-02-05 05:40:52.079011+00 | NK | 2024-02-05 06:28:00.036196+00 | 2024-02-05 06:28:00.036196+00 | (3 rows) iso=> SELECT * FROM nk_view; country | subcountry_name | subdivision | subcountry_level ---------+-------------------------------+-------------------------------+------------------ NK | 2024-02-05 05:40:47.217177+00 | 2024-02-05 05:40:47.217177+00 | NK | 2024-02-05 05:40:52.079011+00 | 2024-02-05 05:40:52.079011+00 | (2 rows)
バージョンアップ中に追加したレコードも反映されていますね。マテビューはBlue側でリフレッシュしていないので、2件のままで問題ありません。
論理レプリケーションのサブスクリプションを確認します。4つのスロットがあることが分かります。
iso=> SELECT oid, subdbid, subname, subowner, subenabled, subbinary, substream, subslotname, subsynccommit, subpublications FROM pg_subscription; oid | subdbid | subname | subowner | subenabled | subbinary | substream | subslotname | subsynccommit | subpublications -------+---------+-------------------------------------------------------+----------+------------+-----------+-----------+--------------------------------------------------------+---------------+--------------------------------------------------------- 36879 | 14717 | rds_us_east_1_4udpsqnc36ykdcc2xrkm3rimy4_bg_sub_14717 | 24586 | t | f | f | rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_14717 | off | {rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_pub_14717} 36880 | 16384 | rds_us_east_1_4udpsqnc36ykdcc2xrkm3rimy4_bg_sub_16384 | 10 | t | f | f | rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_16384 | off | {rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_pub_16384} 36881 | 16401 | rds_us_east_1_4udpsqnc36ykdcc2xrkm3rimy4_bg_sub_16401 | 24586 | t | f | f | rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_16401 | off | {rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_pub_16401} 36882 | 20512 | rds_us_east_1_4udpsqnc36ykdcc2xrkm3rimy4_bg_sub_20512 | 24586 | t | f | f | rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_20512 | off | {rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_pub_20512} (4 rows)
Blue側から論理レプリケーションのパブリケーションを確認します。スロットと対応しているDBや、レプリケーションしているテーブルを確認できます。
iso=> SELECT * FROM pg_publication; oid | pubname | pubowner | puballtables | pubinsert | pubupdate | pubdelete | pubtruncate | pubviaroot -------+-------------------------------------------------------+----------+--------------+-----------+-----------+-----------+-------------+------------ 20550 | rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_pub_20512 | 20540 | t | t | t | t | t | f (1 row) iso=> SELECT * FROM aurora_stat_logical_wal_cache(); name | active_pid | cache_hit | cache_miss | blks_read | hit_rate | last_reset_timestamp --------------------------------------------------------+------------+-----------+------------+-----------+----------+------------------------------- rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_14717 | | 848 | 0 | 848 | 100.00% | 2024-02-05 06:04:41.934204+00 rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_16384 | | 840 | 0 | 840 | 100.00% | 2024-02-05 06:04:41.998953+00 rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_16401 | | 840 | 0 | 840 | 100.00% | 2024-02-05 06:04:42.150032+00 rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_20512 | | 840 | 0 | 840 | 100.00% | 2024-02-05 06:04:42.262146+00 (4 rows) iso=> SELECT * FROM pg_show_replication_origin_status(); local_id | external_id | remote_lsn | local_lsn ----------+-------------+------------+----------- (0 rows) iso=> SELECT * FROM pg_replication_slots; slot_name | plugin | slot_type | datoid | database | temporary | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn | wal_status | safe_wal_size | two_phase --------------------------------------------------------+----------+-----------+--------+----------+-----------+--------+------------+------+--------------+-------------+---------------------+------------+---------------+----------- rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_14717 | pgoutput | logical | 14717 | postgres | f | f | | | 20997 | 0/417D0F0 | 0/4180270 | reserved | | f rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_16384 | pgoutput | logical | 16384 | rdsadmin | f | f | | | 20997 | 0/417D0F0 | 0/41801E8 | reserved | | f rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_16401 | pgoutput | logical | 16401 | testDB | f | f | | | 20997 | 0/417D0F0 | 0/4180270 | reserved | | f rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_20512 | pgoutput | logical | 20512 | iso | f | f | | | 20997 | 0/417D0F0 | 0/4180270 | reserved | | f (4 rows) iso=> SELECT * FROM pg_publication_tables; pubname | schemaname | tablename -------------------------------------------------------+------------+------------ rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_pub_20512 | public | country rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_pub_20512 | public | subcountry (2 rows)
Blue側でレコードを追加すると、Greenに反映されることを確認します。
iso=> INSERT INTO public.subcountry values ('NK', current_timestamp, current_timestamp); INSERT 0 1 iso=> INSERT INTO public.subcountry values ('NK', current_timestamp, current_timestamp); INSERT 0 1
iso=> SELECT * FROM public.subcountry WHERE country='NK'; country | subcountry_name | subdivision | subcountry_level ---------+-------------------------------+-------------------------------+------------------ NK | 2024-02-05 05:40:47.217177+00 | 2024-02-05 05:40:47.217177+00 | NK | 2024-02-05 05:40:52.079011+00 | 2024-02-05 05:40:52.079011+00 | NK | 2024-02-05 06:28:00.036196+00 | 2024-02-05 06:28:00.036196+00 | NK | 2024-02-05 08:04:24.233622+00 | 2024-02-05 08:04:24.233622+00 | NK | 2024-02-05 08:04:27.876364+00 | 2024-02-05 08:04:27.876364+00 | (5 rows)
即座に反映されました。
論理レプリケーションされない処理をしてみる
論理レプリケーションされない処理を試しにやってみます。
まず、Blue側でマテビューの更新をしてもGreenに反映されないことを確認します。
マテリアライズドビューはグリーン環境では自動的に更新されません。
ブルー環境でマテリアライズドビューを更新しても、グリーン環境では更新されません。スイッチオーバー後、マテリアライズドビューの更新をスケジュールできます。
Blue側でマテビューのリフレッシュをします。リフレッシュするとGreenに反映されないとメッセージが表示されました。親切です。
iso=> SELECT * FROM nk_view; country | subcountry_name | subdivision | subcountry_level ---------+-------------------------------+-------------------------------+------------------ NK | 2024-02-05 05:40:47.217177+00 | 2024-02-05 05:40:47.217177+00 | NK | 2024-02-05 05:40:52.079011+00 | 2024-02-05 05:40:52.079011+00 | (2 rows) iso=> REFRESH MATERIALIZED VIEW nk_view; WARNING: command will not be replicated to the green instance: "REFRESH MATERIALIZED VIEW" REFRESH MATERIALIZED VIEW iso=> SELECT * FROM nk_view; country | subcountry_name | subdivision | subcountry_level ---------+-------------------------------+-------------------------------+------------------ NK | 2024-02-05 05:40:47.217177+00 | 2024-02-05 05:40:47.217177+00 | NK | 2024-02-05 05:40:52.079011+00 | 2024-02-05 05:40:52.079011+00 | NK | 2024-02-05 06:28:00.036196+00 | 2024-02-05 06:28:00.036196+00 | NK | 2024-02-05 08:04:24.233622+00 | 2024-02-05 08:04:24.233622+00 | NK | 2024-02-05 08:04:27.876364+00 | 2024-02-05 08:04:27.876364+00 | (5 rows)
Green側でマテビューを確認します。リフレッシュの結果が反映されていないことが分かります。
iso=> SELECT * FROM nk_view; country | subcountry_name | subdivision | subcountry_level ---------+-------------------------------+-------------------------------+------------------ NK | 2024-02-05 05:40:47.217177+00 | 2024-02-05 05:40:47.217177+00 | NK | 2024-02-05 05:40:52.079011+00 | 2024-02-05 05:40:52.079011+00 | (2 rows)
なお、Green側でマテビューのリフレッシュはできませんでした。
iso=> REFRESH MATERIALIZED VIEW nk_view; ERROR: cannot execute REFRESH MATERIALIZED VIEW in a read-only transaction iso=> SELECT * FROM nk_view; country | subcountry_name | subdivision | subcountry_level ---------+-------------------------------+-------------------------------+------------------ NK | 2024-02-05 05:40:47.217177+00 | 2024-02-05 05:40:47.217177+00 | NK | 2024-02-05 05:40:52.079011+00 | 2024-02-05 05:40:52.079011+00 | (2 rows)
次にテーブル定義を変更します。
CREATE TABLE や CREATE SCHEMA などのデータ定義言語 (DDL) ステートメントは、ブルー環境からグリーン環境にはレプリケートされません。
Aurora がブルーの環境で DDL の変更を検出すると、グリーンデータベースはレプリケーションが低下した状態になります。
ブルー環境での DDL の変更を緑の環境にレプリケートできないことを通知するイベントを受け取ります。ブルー/グリーンデプロイとすべてのグリーンデータベースを削除してから再作成する必要があります。そうしないと、ブルー/グリーンデプロイに切り替えることができません。
今回はsubcountry
テーブルにregion
というカラムを追加します。ALTER TABLE
はGreenにレプリケーションされないとメッセージが表示されました。
iso=> ALTER TABLE public.subcountry ADD COLUMN region text; WARNING: command will not be replicated to the green instance: "ALTER TABLE" ALTER TABLE iso=> \d subcountry Table "public.subcountry" Column | Type | Collation | Nullable | Default ------------------+------+-----------+----------+--------- country | text | | not null | subcountry_name | text | | not null | subdivision | text | | | subcountry_level | text | | | region | text | | | Indexes: "subcountry_country_subcountry_name_key" UNIQUE CONSTRAINT, btree (country, subcountry_name) Foreign-key constraints: "subcountry_country_fkey" FOREIGN KEY (country) REFERENCES country(two_letter) Publications: "rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_pub_20512"
Greenを確認します。確かに追加したregion
というカラムが反映されていません。
iso=> \d subcountry Table "public.subcountry" Column | Type | Collation | Nullable | Default ------------------+------+-----------+----------+--------- country | text | | not null | subcountry_name | text | | not null | subdivision | text | | | subcountry_level | text | | | Indexes: "subcountry_country_subcountry_name_key" UNIQUE CONSTRAINT, btree (country, subcountry_name) Foreign-key constraints: "subcountry_country_fkey" FOREIGN KEY (country) REFERENCES country(two_letter)
AWS CDKによる更新ができるか
Blue/Green Deploymentsが存在する状態でAWS CDKによる更新ができるか確認します。試しにDBクラスターとDBインスタンスのメンテナンスウィンドウを変更します。
$ npx cdk diff Stack AuroraStack Hold on while we create a read-only change set to get a diff with accurate replacement information (use --no-change-set to use a less accurate but faster template-only diff) Resources [~] AWS::RDS::DBCluster Aurora/Default Aurora2CBAB212 └─ [~] PreferredMaintenanceWindow ├─ [-] Sat:17:00-Sat:17:30 └─ [+] Sun:17:00-Sun:17:30 [~] AWS::RDS::DBInstance Aurora/Default/Writer AuroraWriter14FF9353 may be replaced └─ [~] PreferredMaintenanceWindow (may cause replacement) ├─ [-] Sat:17:30-Sat:18:00 └─ [+] Sun:17:30-Sun:18:00 ✨ Number of stacks with differences: 1 $ npx cdk deploy ✨ Synthesis time: 17.99s AuroraStack: start: Building 62022da364f861e7b04c71879f6ba59f5bf5a0469b50a1e33c90b79d85ce8e07:<AWSアカウントID>-us-east-1 AuroraStack: success: Built 62022da364f861e7b04c71879f6ba59f5bf5a0469b50a1e33c90b79d85ce8e07:<AWSアカウントID>-us-east-1 AuroraStack: start: Publishing 62022da364f861e7b04c71879f6ba59f5bf5a0469b50a1e33c90b79d85ce8e07:<AWSアカウントID>-us-east-1 AuroraStack: success: Published 62022da364f861e7b04c71879f6ba59f5bf5a0469b50a1e33c90b79d85ce8e07:<AWSアカウントID>-us-east-1 AuroraStack: deploying... [1/1] AuroraStack: creating CloudFormation changeset... ✅ AuroraStack ✨ Deployment time: 47.54s Stack ARN: arn:aws:cloudformation:us-east-1:<AWSアカウントID>:stack/AuroraStack/e6e64230-c3de-11ee-84dd-12d3827feafb ✨ Total time: 65.53s
変更後のDBクラスターとDBインスタンスのメンテナンスウィンドウは以下のとおりです。Blueのもののみ変更されていますね。
$ aws rds describe-db-clusters \ --query 'DBClusters[].{DBClusterIdentifier : DBClusterIdentifier, PreferredMaintenanceWindow : PreferredMaintenanceWindow}' [ { "DBClusterIdentifier": "db-cluster", "PreferredMaintenanceWindow": "sun:17:00-sun:17:30" }, { "DBClusterIdentifier": "db-cluster-green-ak5mgh", "PreferredMaintenanceWindow": "sat:17:00-sat:17:30" } ] $ aws rds describe-db-instances \ --query 'DBInstances[].{DBInstanceIdentifier : DBInstanceIdentifier, PreferredMaintenanceWindow : PreferredMaintenanceWindow}' [ { "DBInstanceIdentifier": "db-instance-writer", "PreferredMaintenanceWindow": "sun:17:30-sun:18:00" }, { "DBInstanceIdentifier": "db-instance-writer-green-8n9hio", "PreferredMaintenanceWindow": "sat:17:30-sat:18:00" } ]
Blue/Green Deploymentsの切り替え
それでは、Blue/Green Deploymentsの切り替えを行います。
切り替え手順や切り替え時に内部で行われている処理、注意点、ベストプラクティスは以下AWS公式ドキュメントにまとまっています。
切り替え中のダウンタイムと継続してレプリケーションされているのか確認をしたいので、Blue側でレコードの追加を行い、Green側でレコード件数を表示します。
$ get_secrets_value=$(aws secretsmanager get-secret-value \ --secret-id AuroraSecret7ACECA7F-IzECtgHudC8Q \ --region us-east-1 \ | jq -r .SecretString) $ export PGHOST=$(echo "${get_secrets_value}" | jq -r .host) $ export PGPORT=$(echo "${get_secrets_value}" | jq -r .port) $ export PGDATABASE=iso $ export PGUSER=$(echo "${get_secrets_value}" | jq -r .username) $ export PGPASSWORD=$(echo "${get_secrets_value}" | jq -r .password) $ while true; do date +"%H:%M:%S.%3N " | tr -d "\n" echo "INSERT INTO public.subcountry values ('NK', current_timestamp, current_timestamp);" | psql -t sleep 1 done 08:44:55.216 INSERT 0 1 08:44:56.266 INSERT 0 1 08:44:57.323 INSERT 0 1 08:44:58.382 INSERT 0 1 08:44:59.435 INSERT 0 1 08:45:00.482 INSERT 0 1 08:45:01.546 INSERT 0 1 08:45:02.638 INSERT 0 1
$ get_secrets_value=$(aws secretsmanager get-secret-value \ --secret-id AuroraSecret7ACECA7F-IzECtgHudC8Q \ --region us-east-1 \ | jq -r .SecretString) $ export PGHOST=db-cluster-green-ak5mgh.cluster-cicjym7lykmq.us-east-1.rds.amazonaws.com $ export PGPORT=$(echo "${get_secrets_value}" | jq -r .port) $ export PGDATABASE=iso $ export PGUSER=$(echo "${get_secrets_value}" | jq -r .username) $ export PGPASSWORD=$(echo "${get_secrets_value}" | jq -r .password) $ while true; do date +"%H:%M:%S.%3N " | tr -d "\n" echo "SELECT COUNT(*) FROM public.subcountry WHERE country='NK';" | psql -t sleep 1 done 08:44:58.694 5 08:44:59.747 5 08:45:00.803 5 08:45:01.879 5 08:45:02.947 5 08:45:04.024 5
はい、いくら待てどもBlueで追加したレコードがGreen側に反映されません。
論理レプリケーションの状態を確認します。
iso=> SELECT * FROM pg_publication; oid | pubname | pubowner | puballtables | pubinsert | pubupdate | pubdelete | pubtruncate | pubviaroot -------+-------------------------------------------------------+----------+--------------+-----------+-----------+-----------+-------------+------------ 20550 | rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_pub_20512 | 20540 | t | t | t | t | t | f (1 row) iso=> SELECT * FROM pg_replication_slots; slot_name | plugin | slot_type | datoid | database | temporary | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn | wal_status | safe_wal_size | two_phase --------------------------------------------------------+----------+-----------+--------+----------+-----------+--------+------------+------+--------------+-------------+---------------------+------------+---------------+----------- rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_14717 | pgoutput | logical | 14717 | postgres | f | t | 7472 | | 33902 | 0/4344CD8 | 0/4347188 | reserved | | f rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_16384 | pgoutput | logical | 16384 | rdsadmin | f | t | 7488 | | 33902 | 0/4344CD8 | 0/4347188 | reserved | | f rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_16401 | pgoutput | logical | 16401 | testDB | f | t | 7489 | | 33902 | 0/4344CD8 | 0/4347188 | reserved | | f rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_20512 | pgoutput | logical | 20512 | iso | f | f | | | 33448 | 0/4334808 | 0/4337A88 | reserved | | f (4 rows) iso=> SELECT * FROM pg_publication_tables; pubname | schemaname | tablename -------------------------------------------------------+------------+------------ rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_pub_20512 | public | country rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_pub_20512 | public | subcountry (2 rows)
iso=> SELECT oid, subdbid, subname, subowner, subenabled, subbinary, substream, subslotname, subsynccommit, subpublications FROM pg_subscription; oid | subdbid | subname | subowner | subenabled | subbinary | substream | subslotname | subsynccommit | subpublications -------+---------+-------------------------------------------------------+----------+------------+-----------+-----------+--------------------------------------------------------+---------------+--------------------------------------------------------- 36879 | 14717 | rds_us_east_1_4udpsqnc36ykdcc2xrkm3rimy4_bg_sub_14717 | 24586 | t | f | f | rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_14717 | off | {rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_pub_14717} 36880 | 16384 | rds_us_east_1_4udpsqnc36ykdcc2xrkm3rimy4_bg_sub_16384 | 10 | t | f | f | rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_16384 | off | {rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_pub_16384} 36881 | 16401 | rds_us_east_1_4udpsqnc36ykdcc2xrkm3rimy4_bg_sub_16401 | 24586 | t | f | f | rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_16401 | off | {rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_pub_16401} 36882 | 20512 | rds_us_east_1_4udpsqnc36ykdcc2xrkm3rimy4_bg_sub_20512 | 24586 | t | f | f | rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_20512 | off | {rds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_pub_20512} (4 rows)
iso
DBをレプリケーションしているrds_us_east_1_nkicdmh5hx7lonqhyyks76nd3q_bg_slot_20512
のactive_pid
が空になっていますね。
また、Blue/Green Deploymentsのイベントを確認すると、以下のイベントが記録されていました。
DB 識別子 | ロール | 時間 | システムノート |
---|---|---|---|
db-instance-writer (Blue) | プライマリ | February 05, 2024, 17:07 (UTC+09:00) | Data definition language (DDL) changes aren't supported for blue/green deployments. These changes aren't replicated from the blue environment to the green environment, and switchover will be blocked. Your green databases now have a status of REPLICATION_DEGRADED. Delete and recreate your blue/green deployment and avoid future DDL changes. See the engine logs for the timestamp 2024-02-05-08 for more information. The log_min_messages DB parameter must be set to WARNING (the default) or lower for DDL warning messages to be saved in the engine log files. |
db-instance-writer-green-8n9hio (Green) | プライマリ | February 05, 2024, 17:07 (UTC+09:00) | Replication has been degraded. |
Blue側でテーブルにカラムを追加したことが原因でレプリケーションが停止してしまったようです。
イベントメッセージに従いBlue/Green Deploymentsを一度削除して作り直します。
削除を実行すると、GreenのAurora DBクラスターの削除も開始されました。
GreenのAurora DBクラスターの削除完了後、再度Blue/Green Deploymentsを作成します。
再作成後のBlueとGreenの論理レプリケーションの状態は以下のとおりです。
iso=> SELECT * FROM pg_publication; oid | pubname | pubowner | puballtables | pubinsert | pubupdate | pubdelete | pubtruncate | pubviaroot -------+-------------------------------------------------------+----------+--------------+-----------+-----------+-----------+-------------+------------ 20572 | rds_us_east_1_5rohy2hsgaxinidn3ody3p7rve_bg_pub_20512 | 20562 | t | t | t | t | t | f (1 row) iso=> SELECT * FROM pg_replication_slots; slot_name | plugin | slot_type | datoid | database | temporary | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn | wal_status | safe_wal_size | two_phase --------------------------------------------------------+----------+-----------+--------+----------+-----------+--------+------------+------+--------------+-------------+---------------------+------------+---------------+----------- rds_us_east_1_5rohy2hsgaxinidn3ody3p7rve_bg_slot_14717 | pgoutput | logical | 14717 | postgres | f | t | 21175 | | 49632 | 0/456FAC0 | 0/4571660 | reserved | | f rds_us_east_1_5rohy2hsgaxinidn3ody3p7rve_bg_slot_16384 | pgoutput | logical | 16384 | rdsadmin | f | t | 21185 | | 49632 | 0/456FAC0 | 0/4571660 | reserved | | f rds_us_east_1_5rohy2hsgaxinidn3ody3p7rve_bg_slot_16401 | pgoutput | logical | 16401 | testDB | f | t | 21186 | | 49632 | 0/456FAC0 | 0/4571660 | reserved | | f rds_us_east_1_5rohy2hsgaxinidn3ody3p7rve_bg_slot_20512 | pgoutput | logical | 20512 | iso | f | t | 21187 | | 49632 | 0/456FAC0 | 0/4571660 | reserved | | f (4 rows) iso=> SELECT * FROM pg_publication_tables; pubname | schemaname | tablename -------------------------------------------------------+------------+------------ rds_us_east_1_5rohy2hsgaxinidn3ody3p7rve_bg_pub_20512 | public | country rds_us_east_1_5rohy2hsgaxinidn3ody3p7rve_bg_pub_20512 | public | subcountry (2 rows)
iso=> SELECT * FROM pg_stat_subscription;; subid | subname | pid | relid | received_lsn | last_msg_send_time | last_msg_receipt_time | latest_end_lsn | latest_end_time -------+-------------------------------------------------------+-----+-------+--------------+-------------------------------+-------------------------------+----------------+------------------------------- 36879 | rds_us_east_1_4udpsqnc36ykdcc2xrkm3rimy4_bg_sub_14717 | 680 | | 0/44590E0 | 2024-02-05 10:09:48.742687+00 | 2024-02-05 10:09:48.743167+00 | 0/44590E0 | 2024-02-05 10:09:48.742687+00 36880 | rds_us_east_1_4udpsqnc36ykdcc2xrkm3rimy4_bg_sub_16384 | 702 | | 0/44590E0 | 2024-02-05 10:09:48.743101+00 | 2024-02-05 10:09:48.743222+00 | 0/44590E0 | 2024-02-05 10:09:48.743101+00 36881 | rds_us_east_1_4udpsqnc36ykdcc2xrkm3rimy4_bg_sub_16401 | 703 | | 0/44590E0 | 2024-02-05 10:09:48.74285+00 | 2024-02-05 10:09:48.743245+00 | 0/44590E0 | 2024-02-05 10:09:48.74285+00 36882 | rds_us_east_1_4udpsqnc36ykdcc2xrkm3rimy4_bg_sub_20512 | 704 | | 0/44590E0 | 2024-02-05 10:09:48.743162+00 | 2024-02-05 10:09:48.743296+00 | 0/44590E0 | 2024-02-05 10:09:48.743162+00 (4 rows) iso=> SELECT oid, subdbid, subname, subowner, subenabled, subbinary, substream, subslotname, subsynccommit, subpublications FROM pg_subscription; oid | subdbid | subname | subowner | subenabled | subbinary | substream | subslotname | subsynccommit | subpublications -------+---------+-------------------------------------------------------+----------+------------+-----------+-----------+--------------------------------------------------------+---------------+--------------------------------------------------------- 36879 | 14717 | rds_us_east_1_4udpsqnc36ykdcc2xrkm3rimy4_bg_sub_14717 | 24586 | t | f | f | rds_us_east_1_5rohy2hsgaxinidn3ody3p7rve_bg_slot_14717 | off | {rds_us_east_1_5rohy2hsgaxinidn3ody3p7rve_bg_pub_14717} 36880 | 16384 | rds_us_east_1_4udpsqnc36ykdcc2xrkm3rimy4_bg_sub_16384 | 10 | t | f | f | rds_us_east_1_5rohy2hsgaxinidn3ody3p7rve_bg_slot_16384 | off | {rds_us_east_1_5rohy2hsgaxinidn3ody3p7rve_bg_pub_16384} 36881 | 16401 | rds_us_east_1_4udpsqnc36ykdcc2xrkm3rimy4_bg_sub_16401 | 24586 | t | f | f | rds_us_east_1_5rohy2hsgaxinidn3ody3p7rve_bg_slot_16401 | off | {rds_us_east_1_5rohy2hsgaxinidn3ody3p7rve_bg_pub_16401} 36882 | 20512 | rds_us_east_1_4udpsqnc36ykdcc2xrkm3rimy4_bg_sub_20512 | 24586 | t | f | f | rds_us_east_1_5rohy2hsgaxinidn3ody3p7rve_bg_slot_20512 | off | {rds_us_east_1_5rohy2hsgaxinidn3ody3p7rve_bg_pub_20512} (4 rows)
Blue側でレコードの追加を行い、Green側でレコード件数を表示します。
$ get_secrets_value=$(aws secretsmanager get-secret-value \ --secret-id AuroraSecret7ACECA7F-IzECtgHudC8Q \ --region us-east-1 \ | jq -r .SecretString) $ export PGHOST=$(echo "${get_secrets_value}" | jq -r .host) $ export PGPORT=$(echo "${get_secrets_value}" | jq -r .port) $ export PGDATABASE=iso $ export PGUSER=$(echo "${get_secrets_value}" | jq -r .username) $ export PGPASSWORD=$(echo "${get_secrets_value}" | jq -r .password) $ while true; do date +"%H:%M:%S.%3N " | tr -d "\n" echo "INSERT INTO public.subcountry values ('NK', current_timestamp, current_timestamp);" | psql -t sleep 1 done 11:39:31.878 INSERT 0 1 11:39:32.930 INSERT 0 1 11:39:33.984 INSERT 0 1 11:39:35.042 INSERT 0 1 11:39:36.096 INSERT 0 1 11:39:37.160 INSERT 0 1 . . (以下略) . .
$ get_secrets_value=$(aws secretsmanager get-secret-value \ --secret-id AuroraSecret7ACECA7F-IzECtgHudC8Q \ --region us-east-1 \ | jq -r .SecretString) $ export PGHOST=db-cluster-green-ak5mgh.cluster-cicjym7lykmq.us-east-1.rds.amazonaws.com $ export PGPORT=$(echo "${get_secrets_value}" | jq -r .port) $ export PGDATABASE=iso $ export PGUSER=$(echo "${get_secrets_value}" | jq -r .username) $ export PGPASSWORD=$(echo "${get_secrets_value}" | jq -r .password) $ while true; do date +"%H:%M:%S.%3N " | tr -d "\n" echo "SELECT COUNT(*) FROM public.subcountry WHERE country='NK';" | psql -t sleep 1 done 11:39:29.780 86 11:39:30.834 86 11:39:31.933 87 11:39:32.987 88 11:39:34.051 89 11:39:35.100 90 11:39:36.165 91 . . (以下略) . .
レプリケーションができていそうです。
この状態で切り替えを行います。
切り替え対象の確認とタイムアウトを設定して切り替え
をクリックします。
切り替え中は以下のように全てのAurora DBクラスターとDBインスタンスのステータスが切り替え
となります。
切り替え後の状態確認
2分ほどで切り替えが完了しました。新Blueのエンドポイントが旧Blueのエンドポイントに変わっています。また、旧Blueのエンドポイントには-old1
という文字列が付与されています。
切り替え完了後の設定は以下のとおりです。リソースIDの入れ替わりは発生していません。また、新Blueのパラメーターグループの同期ステータスが再起動を保留中
のままになっています。切り替え前からこのステータスだったので、切り替え時に再起動は行われないようです。
発生したイベントは以下のとおりです。
DB 識別子 | ロール | 時間 | システムノート |
---|---|---|---|
bgd-cavqrityavom8edj | ブルー/グリーンデプロイ | February 05, 2024, 18:50 (UTC+09:00) | Blue/green deployment tasks completed. You can make more modifications to the green environment databases or switch over the deployment. |
db-cluster新しいブルー | プライマリ | February 05, 2024, 20:41 (UTC+09:00) | Switchover from DB cluster db-cluster to db-cluster-green-cvrzdo started. |
db-cluster新しいブルー | プライマリ | February 05, 2024, 20:41 (UTC+09:00) | Sequence sync for switchover of DB cluster db-cluster to db-cluster-green-cvrzdo has initiated. Switchover when using sequences may lead to extended downtime. |
db-cluster新しいブルー | プライマリ | February 05, 2024, 20:41 (UTC+09:00) | Sequence sync for switchover of DB cluster db-cluster to db-cluster-green-cvrzdo has completed. |
bgd-cavqrityavom8edj | ブルー/グリーンデプロイ | February 05, 2024, 20:41 (UTC+09:00) | Switchover started on blue/green deployment blue-green. |
db-cluster-old1古いブルー | プライマリ | February 05, 2024, 20:42 (UTC+09:00) | Switchover from DB cluster db-cluster to db-cluster-green-cvrzdo completed. Renamed db-cluster to db-cluster-old1 and db-cluster-green-cvrzdo to db-cluster. |
db-cluster新しいブルー | プライマリ | February 05, 2024, 20:42 (UTC+09:00) | Switchover from DB cluster db-cluster to db-cluster-green-cvrzdo completed. Renamed db-cluster to db-cluster-old1 and db-cluster-green-cvrzdo to db-cluster. |
bgd-cavqrityavom8edj | ブルー/グリーンデプロイ | February 05, 2024, 20:42 (UTC+09:00) | Switchover completed on blue/green deployment blue-green. |
切り替え中に実行していたレコード追加とレコード件数表示のログを確認します。
. . (中略) . . 11:41:29.582 INSERT 0 1 11:41:30.629 INSERT 0 1 11:41:31.712 INSERT 0 1 11:41:32.762 INSERT 0 1 11:41:33.823 INSERT 0 1 11:41:34.884 ERROR: cannot execute INSERT in a read-only transaction 11:42:41.028 INSERT 0 1 11:42:42.089 INSERT 0 1 11:42:43.165 INSERT 0 1 11:42:44.216 INSERT 0 1 11:42:45.274 INSERT 0 1 . . (以下略) . .
. . (中略) . . 11:41:30.335 198 11:41:31.398 199 11:41:32.476 200 11:41:33.530 201 11:41:34.593 202 11:41:35.646 202 11:41:36.706 202 . . (中略) . . 11:42:38.110 202 11:42:39.160 202 11:42:40.209 202 11:42:41.280 203 11:42:42.362 204 11:42:43.413 205 11:42:44.461 206 11:42:45.511 207 11:42:46.563 208 11:42:47.622 psql: error: could not translate host name "db-cluster-green-cvrzdo.cluster-cicjym7lykmq.us-east-1.rds.amazonaws.com" to address: Name or service not known 11:42:48.638 psql: error: could not translate host name "db-cluster-green-cvrzdo.cluster-cicjym7lykmq.us-east-1.rds.amazonaws.com" to address: Name or service not known 11:42:49.652 psql: error: could not translate host name "db-cluster-green-cvrzdo.cluster-cicjym7lykmq.us-east-1.rds.amazonaws.com" to address: Name or service not known 11:42:50.670 psql: error: could not translate host name "db-cluster-green-cvrzdo.cluster-cicjym7lykmq.us-east-1.rds.amazonaws.com" to address: Name or service not known . . (以下略) . .
1分ほど書き込みが停止し、その後再開しています。1分というのはAWS公式ドキュメントのとおりですね。
準備ができたら、環境を切り替えてグリーン環境を新しい本稼働環境にプロモートできます。切り替えには通常 1 分もかからず、データが失われることはなく、アプリケーションを変更する必要もありません。
切り替え時に内部的には以下のような処理がされています。
- ガードレールチェックを実行して、ブルー環境とグリーン環境を切り替える準備ができているかどうかを確認します。
- 両方の環境で DB クラスターでの新しい書き込みオペレーションを停止します。
- 両方の環境で DB インスタンスへの接続を切断し、新しい接続を許可しません。
- グリーン環境がブルー環境と同期するように、レプリケーションがグリーン環境で追いつくのを待ちます。
- 両方の環境の DB クラスターと DB インスタンスの名前を変更します。
RDS は、グリーン環境の DB クラスターと DB インスタンスが、ブルー環境の対応する DB クラスターと DB インスタンスに一致するように名前を変更します。例えば、ブルー環境の DB インスタンスの名前が mydb であるとします。また、グリーン環境の対応する DB インスタンスの名前が mydb-green-abc123 であると仮定します。切り替え時、グリーン環境の DB インスタンスの名前は mydb に変更されます。
RDS は、現在の名前に -oldn を追加して、ブルー環境の DB クラスターと DB インスタンスの名前を変更します。ここで、n は数字です。例えば、ブルー環境の DB インスタンスの名前が mydb であるとします。切り替え後、DB インスタンス名は mydb-old1 になります。
また、RDS はグリーン環境のエンドポイントの名前を、ブルー環境の対応するエンドポイントと一致するように変更するため、アプリケーションを変更する必要はありません。- 両方の環境でデータベースへの接続を許可します。
- 新しい本稼働環境の DB クラスターへの書き込みオペレーションを許可します。
切り替え後、以前の本稼働 DB クラスターは、ライターインスタンスが再起動されるまで読み取りオペレーションのみを許可します。ブルー/グリーンデプロイの切り替え - 切り替えアクション 新Blueに接続してマテビューのリフレッシュができることを確認します。
3のタイミングでGreenでも接続は拒否されるようですが、特にその間接続できないという事象は遭遇しませんでした。
また、Greenのエンドポイントは新エンドポイントに切り替わり、新Blueで書き込みできるようになっても数秒間は接続できています。切り替え後も接続できていたのはTTLの影響かと予想します。
Aurora DNS ゾーンは 5 秒という短い TTL を使用します。しかし、多くのシステムでは、さまざまな設定でクライアントキャッシュを実装しているため、TTL が長くなる可能性があります。
Amazon Aurora ライターエンドポイントに接続する際、接続がリーダーインスタンスにリダイレクトされる理由のトラブルシューティング | AWS re:Post
新Blueに対して接続して、マテビューのリフレッシュを行います。
iso=> SELECT COUNT(*) FROM public.subcountry WHERE country='NK'; count ------- 254 (1 row) iso=> SELECT * FROM nk_view; country | subcountry_name | subdivision | subcountry_level ---------+-------------------------------+-------------------------------+------------------ NK | 2024-02-05 05:40:47.217177+00 | 2024-02-05 05:40:47.217177+00 | NK | 2024-02-05 05:40:52.079011+00 | 2024-02-05 05:40:52.079011+00 | NK | 2024-02-05 06:28:00.036196+00 | 2024-02-05 06:28:00.036196+00 | NK | 2024-02-05 08:04:24.233622+00 | 2024-02-05 08:04:24.233622+00 | NK | 2024-02-05 08:04:27.876364+00 | 2024-02-05 08:04:27.876364+00 | (5 rows) iso=> REFRESH MATERIALIZED VIEW nk_view; REFRESH MATERIALIZED VIEW iso=> SELECT count(*) FROM nk_view; count ------- 254 (1 row)
問題なくリフレッシュできました。
Blue/Green Deploymentsによる切り戻しが行えるか
Blue/Green Deploymentsによる切り戻しが行えるか確認します。
Blue/Green Deploymentsを選択した状態でアクション
をクリックしても、切り替え
はグレーアウトしていました。
新Blueで論理レプリケーションのステータスを確認します。
iso=> SELECT * FROM pg_publication; oid | pubname | pubowner | puballtables | pubinsert | pubupdate | pubdelete | pubtruncate | pubviaroot -----+---------+----------+--------------+-----------+-----------+-----------+-------------+------------ (0 rows) iso=> SELECT * FROM pg_replication_slots; slot_name | plugin | slot_type | datoid | database | temporary | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn | wal_status | safe_wal_size | two_phase -----------+--------+-----------+--------+----------+-----------+--------+------------+------+--------------+-------------+---------------------+------------+---------------+----------- (0 rows) iso=> SELECT * FROM pg_publication_tables; pubname | schemaname | tablename | attnames | rowfilter ---------+------------+-----------+----------+----------- (0 rows)
切り替えたタイミングで論理レプリケーションは切れているようですね。
切り替え後に、切り戻しを行う場合は以下のような対応が必要になります。
- 旧Blueの再起動を行う
- 新BlueのAurora DBクラスター名を変更する
- 旧BlueのAurora DBクラスター名を元に戻す
それなりのダウンタイムは発生しそうです。
なお、1で再起動を行うのは切り替え後の旧BlueはReadOnlyになっているためです。
RDS は、現在のリソース名に -oldn を付加することによって、ブルー環境の DB クラスターと DB インスタンスの名前を変更します。ここで、n は数字です。DB クラスターは、ライターインスタンスが再起動されるまで読み取り専用です。
新Blueに対してAWS CDKによる更新ができるか
新Blueに対してAWS CDKによる更新ができるか確認します。
DBクラスターとDBインスタンスのメンテナンスウィンドウを変更します。
$ npx cdk diff Stack AuroraStack Hold on while we create a read-only change set to get a diff with accurate replacement information (use --no-change-set to use a less accurate but faster template-only diff) Could not create a change set, will base the diff on template differences (run again with -v to see the reason) Resources [-] AWS::RDS::DBClusterParameterGroup Aurora/DbClusterParameterGroup14 AuroraDbClusterParameterGroup145F7E6F5D destroy [-] AWS::RDS::DBParameterGroup Aurora/DbParameterGroup14 AuroraDbParameterGroup146D0E289A destroy [~] AWS::RDS::DBCluster Aurora/Default Aurora2CBAB212 ├─ [~] DBClusterParameterGroupName │ └─ [~] .Ref: │ ├─ [-] AuroraDbClusterParameterGroup145F7E6F5D │ └─ [+] AuroraDbClusterParameterGroup150C75B72F └─ [~] PreferredMaintenanceWindow ├─ [-] Sun:17:00-Sun:17:30 └─ [+] Mon:17:00-Mon:17:30 [~] AWS::RDS::DBInstance Aurora/Default/Writer AuroraWriter14FF9353 may be replaced ├─ [~] DBParameterGroupName (may cause replacement) │ └─ [~] .Ref: │ ├─ [-] AuroraDbParameterGroup146D0E289A │ └─ [+] AuroraDbParameterGroup158895769D └─ [~] PreferredMaintenanceWindow (may cause replacement) ├─ [-] Sun:17:30-Sun:18:00 └─ [+] Mon:17:30-Mon:18:00 ✨ Number of stacks with differences: 1
npx cdk deploy
中に旧Blueにアタッチしているパラメーターグループが削除できないと表示されました。
$ npx cdk deploy ✨ Synthesis time: 7.64s AuroraStack: deploying... [1/1] AuroraStack: creating CloudFormation changeset... 21:16:50 | DELETE_FAILED | AWS::RDS::DBParameterGroup | AuroraDbParameterGroup146D0E289A One or more database instances are still members of this parameter group aurorastack-auroradbparametergroup146d0e 289a-9rn8loibaljt, so the group cannot be deleted (Service: Rds, Status Code: 400, Request ID: 58a6ed9b-f7bd-45d9 -8adb-e5af9dd586e5) 21:16:50 | DELETE_FAILED | AWS::RDS::DBClusterParameterGroup | AuroraDbClusterParameterGroup145F 7E6F5D One or more database instances are still members of this parameter group aurorastack-auroradbclusterparametergrou p145f7e6f5d-qe4nrfvnokxj, so the group cannot be deleted (Service: Rds, Status Code: 400, Request ID: 9cd4f56c-5f 89-4a3a-87df-55ca002a88f8)
旧Blueは不要なので削除します。
Blue/Green Deploymentsを削除します。
削除しても、連動して旧Blueが削除されるということは発生しませんでした。
手動で旧Blueを削除します。
旧Blueの削除が完了してしばらく待つと、npx cdk deploy
が完了していました。
$ npx cdk deploy ✨ Synthesis time: 7.64s AuroraStack: deploying... [1/1] AuroraStack: creating CloudFormation changeset... . . (中略) . . ✅ AuroraStack ✨ Deployment time: 924.42s Stack ARN: arn:aws:cloudformation:us-east-1:<AWSアカウントID>:stack/AuroraStack/e6e64230-c3de-11ee-84dd-12d3827feafb ✨ Total time: 932.06s
スタックのイベントは以下のとおりです。
DBクラスターとDBインスタンスのメンテナンスウィンドウを確認すると、新Blueの値が変わっていました。
$ aws rds describe-db-clusters \ --query 'DBClusters[].{DBClusterIdentifier : DBClusterIdentifier, PreferredMaintenanceWindow : PreferredMaintenanceWindow}' [ { "DBClusterIdentifier": "db-cluster", "PreferredMaintenanceWindow": "mon:17:00-mon:17:30" }, { "DBClusterIdentifier": "db-cluster-old1", "PreferredMaintenanceWindow": "sun:17:00-sun:17:30" } ] $ aws rds describe-db-instances \ --query 'DBInstances[].{DBInstanceIdentifier : DBInstanceIdentifier, PreferredMaintenanceWindow : PreferredMaintenanceWindow}' [ { "DBInstanceIdentifier": "db-instance-writer", "PreferredMaintenanceWindow": "mon:17:30-mon:18:00" }, { "DBInstanceIdentifier": "db-instance-writer-old1", "PreferredMaintenanceWindow": "sun:17:30-sun:18:00" } ]
バックアップの保持期間でも試します。7日から9日に変更します。
$ npx cdk diff Stack AuroraStack Hold on while we create a read-only change set to get a diff with accurate replacement information (use --no-change-set to use a less accurate but faster template-only diff) Resources [~] AWS::RDS::DBCluster Aurora/Default Aurora2CBAB212 └─ [~] BackupRetentionPeriod ├─ [-] 7 └─ [+] 9 ✨ Number of stacks with differences: 1 $ npx cdk deploy ✨ Synthesis time: 6.58s AuroraStack: start: Building 2d6c48c5f8ad4552b8eb63a9aa7ebc52b62d829b31da938ed94501bebf191e01:<AWSアカウントID>-us-east-1 AuroraStack: success: Built 2d6c48c5f8ad4552b8eb63a9aa7ebc52b62d829b31da938ed94501bebf191e01:<AWSアカウントID>-us-east-1 AuroraStack: start: Publishing 2d6c48c5f8ad4552b8eb63a9aa7ebc52b62d829b31da938ed94501bebf191e01:<AWSアカウントID>-us-east-1 AuroraStack: success: Published 2d6c48c5f8ad4552b8eb63a9aa7ebc52b62d829b31da938ed94501bebf191e01:<AWSアカウントID>-us-east-1 AuroraStack: deploying... [1/1] AuroraStack: creating CloudFormation changeset... ✅ AuroraStack ✨ Deployment time: 43.49s Stack ARN: arn:aws:cloudformation:us-east-1:<AWSアカウントID>:stack/AuroraStack/e6e64230-c3de-11ee-84dd-12d3827feafb ✨ Total time: 50.06s
npx cdk deploy
完了後に確認すると、確かにバックアップの保持期間が9日になっていました。
Aurora DBクラスターやDBインスタンスにおけるCloudFormationの物理IDはDBクラスター識別子、DBインスタンス識別子です。Blue/Green Deploymentsで切り替えをしてもDBクラスター識別子とDBインスタンス識別子は変わらない = 物理IDは変わらないため、AWS CDKでも操作できたのだと考えます。
ただし、AWS公式ドキュメントにはBlue/Green Deploymentsの制約事項としてCloudFormationはサポートされていないと記載がありました。
- ブルー/グリーンデプロイは、以下の機能ではサポートされていません。
- Amazon RDS Proxy
- クロスリージョンリードレプリカ
- Aurora Serverless v1 DB クラスター
- Aurora Global Database の一部である DB クラスター。
- Babelfish for Aurora PostgreSQL
- AWS CloudFormation
切り替え後にAurora DBクラスターの操作ができることから、これはCloudFormationの機能でBlue/Green DeploymentsでAurora DBクラスターを切り替えることができないことを指しているのではないかと推測します。
PostgreSQL固有の制約事項があるので注意しよう
Amazon RDS Blue/Green Deployments で Amazon Aurora PostgreSQL のメジャーバージョンアップをしてみました。
インプレースアップグレードよりも短いダウンタイムで、手動で論理レプリケーションを組むより簡単にメジャーバージョンアップを行うことができました。
RDS Blue/Green Deploymentsにはいくつか制約事項があります。確保できるダウンタイムが短く、制約事項をクリアできるのであればRDS Blue/Green Deploymentsを検討しましょう。なお、PostgreSQL固有の制約事項もあるので注意しましょう。
一般的な制約事項
- Aurora MySQL バージョン 2.08 と 2.09 はアップグレードのソースバージョンまたはターゲットバージョンとしてはサポートされていない
- Aurora MySQL の場合、ソース DB クラスターには tmp という名前のデータベースを含めることはできない
- この名前のデータベースはGreen環境にコピーされない
- Aurora PostgreSQL ではBlue DB クラスターで
rds.logically_replicate_unlogged_tables
パラメータが 1 に設定されていない限り、ログに記録されていないテーブルはGreen環境にレプリケートされない - 切り替え中、Blue環境とGreen環境では Amazon Redshift とのzero-ETLはできない
- Blue/Green Deploymentsを作成するときには、Green環境でイベントスケジューラー (
event_scheduler
パラメーター) を無効にする必要がある - Blue/Green Deploymentsは、以下の機能ではサポートされていない
- Amazon RDS Proxy
- クロスリージョンリードレプリカ
- Aurora Serverless v1 DB クラスター
- Aurora Global Database 内の DB クラスター
- Babelfish for Aurora PostgreSQL
- AWS CloudFormation
変更の制約事項
- 暗号化されていない DB クラスターを暗号化された DB クラスターに変更することはできない
- 暗号化された DB クラスターを暗号化されていない DB クラスターに変更することはできない
- Blue環境の DB クラスターをGreen環境の DB クラスターよりも上位のエンジンバージョンに変更することはできまない
- Blue環境とGreen環境のリソースは同じ AWS アカウント にある必要がある
- スイッチオーバー時、Blue DB クラスターを外部レプリケーションのソースまたはターゲットにすることはできない
- Blueの環境に Aurora Auto Scaling ポリシーが含まれている場合、これらのポリシーはGreenの環境にコピーされない
- Greenの環境にはポリシーを手動で再追加する必要がある
PostgreSQLの拡張機能についての制約事項
- Blue/Green Deploymentsを作成するときにはBlue環境で
pg_partman
拡張機能を無効にする必要がある- 有効にしていると CREATE TABLE などの DDL オペレーションを実行され、Blue環境からGreen環境への論理レプリケーションが中断されてしまう可能性がある
- Blue/Green Deploymentsを作成した後は、すべてのGreenデータベースで
pg_cron
拡張機能を無効のままにしておく必要がある - Blue環境で同じクエリプランが取り込まれた場合にプライマリキーの競合が発生しないように、
apg_plan_mgmt
拡張機能のapg_plan_mgmt.capture_plan_baselines
パラメータをすべてのGreenデータベースで off に設定する必要がある - Aurora Replicas で実行計画をキャプチャする場合は、
apg_plan_mgmt.create_replica_plan_capture
関数を呼び出すときにBlue DB クラスターエンドポイントを指定する必要がある。 - Blue DB クラスターが外部データラッパー (FDW) 拡張機能の外部サーバーとして設定されている場合はIP アドレスの代わりにクラスターエンドポイント名を使用する必要がある
- Blue/Green Deploymentsを作成するときには、Blue環境で
pglogical
およびpg_active
拡張機能を無効にする必要がある- Blueデータベースは外部インスタンスの論理レプリケーションのサブスクライバーにはなれない
PostgreSQL 論理レプリケーションの制約事項
- CREATE TABLE や CREATE SCHEMA などのデータ定義言語 (DDL) ステートメントは、Blue環境からGreen環境にはレプリケートされない
- シーケンスオブジェクトに対する NEXTVAL オペレーションは、Blue環境とGreen環境では同期されない
- Blue環境での大きなオブジェクトの作成や変更は、Green環境にはレプリケートされない
- マテリアライズドビューはGreen環境では自動的に更新されない
- UPDATE および DELETE オペレーションは、プライマリキーのないテーブルでは許可されない
論理レプリケーションを手組みする場合の操作方法も理解しておくと、理解が進みそうです。
Aurora PostgreSQLのメジャーバージョンアップを行う際は以下AWS公式ドキュメントも併せてチェックしておきましょう。アップグレード時のお作法がまとまっています。
トラブルシューティングをする際には以下re:Postが役立ちそうです。
また、Aurora MySQLへのメジャーアップグレードパスの紹介は以下記事がまとまっています。
この記事が誰かの助けになれば幸いです。
以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!