はじめまして。AWS事業部の粥川です。
データセンター常駐のサーバ、ネットワーク、運用インフラエンジニアからジョブチェンジして早2年、
日々クラウドのありがたみを感じながらお仕事させていただいております。
新たなサービスのリリースが超速、というのも魅力ですが、やはり分からなかったらとにかく試す!が気軽かつ低コストでできるのはとっても嬉しい限りです。
さて、今回お話するサービスは、 Aurora PostgreSQL-compatible edition です。
Aurora 自体は MySQL 互換として以前から東京リージョンにもローンチされているクラウドネイティブなデータベースですが、今年ついに PostgreSQL 互換の Aurora がローンチされました。
RDS for PostgreSQL をご利用されているユーザ様も非常に多くいらっしゃいますので、信頼性が高く RTOをより短くできる Aurora への移行を検討し始めているお客様も多いのではないでしょうか。
今回は今年リリースされた機能、RDS for PostgreSQL から Aurora リードレプリカを作成し、最終的に Aurora を独立したクラスターとして昇格させる(レプリケーションを止める)手順について検証してみましたので、ご紹介します。
検証内容
検証する構成は以下となります。
初めに RDS for PostgreSQL インスタンスをローンチし、当該インスタンスの Aurora リードレプリカを作成します。その後、書き込み処理が走っていないタイミングで Aurora リードレプリカを昇格させ、独立した Aurora クラスターにします。
検証準備
それでは、まず RDS for PostgreSQL インスタンスを作成します。 詳細は割愛しますが、AWS マネジメントコンソールから PostgreSQL インスタンスを作成しました。
"rdsposgre01"というインスタンスがローンチされています。
次にこのDBへ接続し、テーブルを作成してみます。
DBに接続し状態を確認すると、新規ローンチしたものなのでテーブルはまだありません。
テスト用のテーブルを作成するため。以下DDLを実行します。
CREATE TABLE USERS ( id CHAR(4) NOT NULL, name TEXT NOT NULL, age INTEGER, PRIMARY KEY (id) );
テスト用のレコードを追加します。
INSERT INTO USERS (id, name, age) VALUES ('0001', '田中 大介', 35); INSERT INTO USERS (id, name, age) VALUES ('0002', '山田 朋子', 29); INSERT INTO USERS (id, name, age) VALUES ('0003', '森 祐希', 41);
テーブルの作成、レコードの追加が完了し、以下の状態となりました。
Aurora リードレプリカの作成
準備が完了したところで、早速"rdsposgre01"インスタンスの Aurora リードレプリカを作成します。
AWS マネジメントコンソールで"rdsposgre01"インスタンスを選択し、「インスタンスの操作」-「Aurora リードレプリカの作成」をクリックします。
「Aurora リードレプリカの作成」画面に遷移しますので、インスタンスクラスやインスタンス識別子等、設定を入力し「リードレプリカの作成」をクリックします。
今回は、"aurora-rdsposgre01"という識別子を設定しましたので、新たに"aurora-rdsposgre01-cluster"というAurora クラスターが作成されます。
AWS マネジメントコンソールから、RDS のクラスターを選択すると、確かに該当の Aurora クラスターが作成されています。
通常の Aurora クラスターと違い、「DB クラスターロール」が"レプリカ"となっていますね。
実際にレプリケーションされているか、各DBに接続し確認してみました。
下記ターミナルの左が"rdsposgre01"、右が"aurora-rdsposgre01"です。途中"rdsposgre01"で INSERT を実行し、"aurora-rdsposgre01"にレプリケーションされていることが分かります。また、"aurora-rdsposgre01"側で最後にINSERTを実行しましたが、read-onlyのため失敗していることが分かります。
Aurora リードレプリカの昇格
Aurora リードレプリカの作成が完了しましたので、昇格作業を実施し、RDS for PostgreSQLとのレプリケーションを解除します。
昇格作業は数クリックで完了しますが、AWSのホワイトペーパーを見ると、実施前にソースである RDS for PostgreSQL 側を以下の状態とする必要があります。
- トランザクションの書き込みを全て停止
- Aurora リードレプリカのレプリカラグを"0"
レプリカラグは、CloudWatch メトリクスの"RDSToAuroraPostgreSQLReplicaLag"を参照するのですが、ここで注意点があります。せっかくトランザクション書き込みを全て停止しレプリカラグを"0"にしようと試みても、書き込み等が非常に少ない状況の場合"RDSToAuroraPostgreSQLReplicaLag"が大きくカウントされてしまうという仕様になっているそうです。つまり、レプリカラグ"0"の状態を作り出すことは、実質不可能です。。。
そのため、本記事執筆時は1点目の"トランザクションの書き込みを全て停止"のみ確認し、昇格作業を実施します。よくよく考えると、ようはレプリケーションが発生するような書き込み処理が発生していなければ、自ずとレプリカラグも"0"になるはずなので、1点目が確認できれば十分ということですね。
書き込みが発生していない状態→ユーザセッションがない状態を作るため、セキュリテイグループで許可しているDB接続ポート(今回は"5432/TCP")を一時的にブロックします。が、その前にCloudWatch メトリクスの"DatabaseConnections"で現在のユーザセッション数を確認します。
上記は"rdsposgre01"の直近1時間の"DatabaseConnections"です。
誰も接続していないはずなのにセッション数が"1"になっている・・・おかしい・・・と思い確認してみたところ、どうやら
対象インスタンスのリードレプリカが存在する場合、レプリケーション用のセッションもカウントされているとのことでした。なるほど、それなら納得ですね。
レプリケーション用セッション以外にユーザセッションは確立されていないことが確認できましたので、セキュリティグループでDB接続ポートを一時的にブロックし、Aurora リードレプリカの昇格を実行します。(セキュリティグループの操作はここでは割愛します。)
AWS マネジメントコンソールで"aurora-rdsposgre01"インスタンスを選択し、「インスタンスの操作」-「リードレプリカの昇格」をクリックします。確認画面が表示されますので、「リードレプリカの昇格」ボタンをクリックします。
これで Aurora クラスターは昇格したはず!なので、クラスターの状態を確認してみましょう。
AWS マネジメントコンソールから、RDS のクラスターを表示し、"aurora-rdsposgre01-cluster"を選択します。数分待つと、「DB クラスターロール」が"レプリカ"から"マスター"に変わります。ちゃんと昇格されました!
最後に、各DBに接続しレプリケーションが解除されたことを確認してみます。リードレプリカを作成した際と同様に、途中"rdsposgre01"で INSERT を実行しましたが、"aurora-rdsposgre01"にはレプリケーションされていないことが分かります。また、"aurora-rdsposgre01"で先程エラーになったINSERTを実行すると、正常に実行されています!
いかがでしたでしょうか。昇格するタイミングさえ調整できれば、RDS for PostgreSQL から Aurora PostgreSQL へ、少ない手順で移行することができます。PostgreSQL、Aurora それぞれで良さがあるので、一概に Aurora に移行することがベターというわけではありませんが、移行手順が簡潔であることは、Aurora 利用に向けた一つの検討材料になるのではないでしょうか。