Amazon Aurora MySQL 互換エディション DB クラスターがフェイルオーバーしたときに、read-only エラーが発生する理由を把握したいです。
簡単な説明
Aurora MySQL 互換 DB クラスターでマルチ AZ のフェイルオーバーが発生すると、クラスターエンドポイントは自動的に更新されます。古いライターは、再起動して読み取り専用モードに設定されます。その後、Aurora は既存のレプリカをライターに昇格させます。エンドポイントにはこの変更が反映され、ライターとリーダーの新しいロールを指すようになります。
リーダーロールを使用して既存のノードで次のいずれかの操作を行うと、read-only というエラーメッセージが表示される場合があります。
- データ定義言語 (DDL) 操作
- データ操作言語 (DML) 操作
- データ制御言語 (DCL) 操作
解決策
ロールが読み取り専用かどうかを判断する
ロールが読み取り専用かどうかを確認するには、innodb_read_only を参照します。
出力例:
mysql> show variables where variable_name='innodb_read_only';+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| innodb_read_only | ON |
+------------------+-------+
1 row in set (0.01 sec)
クラスターのライターエンドポイントを使用する
Aurora MySQL クラスターでの DB インスタンスの役割は変更される可能性があります。クラスターのライターエンドポイントを使用して、常に最新のライターを指すようにすることをおすすめします。DB インスタンスエンドポイントまたはダイレクト IP アドレスを使用する場合、フェイルオーバーが発生していることに気付かない場合があります。同じホストに再接続すると、read-only エラーが発生し、DDL または DML の変更を実行できなくなります。
DNS の過剰なキャッシュを避ける
スマートドライバーを使用していない場合は、フェイルオーバーイベントが発生した後は、DNS レコードの更新と伝播に依存することになります。Aurora MySQL DNS ゾーンでは、有効期間 (TTL) は 5 秒の短期間です。ネットワークとクライアントの設定では TTL を増やすことはできません。DNS キャッシュは、オペレーティングシステム (OS)、ネットワーク層、アプリケーションコンテナなど、アーキテクチャの複数の層で発生します。意図しない DNS キャッシュが 5 秒を超えて続く場合は、フェイルオーバー後に古いライターに再接続する可能性があります。
Java 仮想マシン (JVM) は DNS を過剰にキャッシュする可能性があります。JVM がホスト名を IP アドレスに解決する際、IP アドレスを指定した期間キャッシュします。一部の構成では、JVM のデフォルト TTL は JVM の再起動時にのみ DNS エントリを更新するため、フェイルオーバー後に read-only エラーが発生する場合があります。この問題を解決するには、短期間の TTL を手動で設定し、DNS エントリが定期的に更新されるようにします。
AWS Advanced JDBC ドライバーを使用する
Aurora MySQL DB クラスターエンドポイントは DNS レコードの更新を自動的に伝達します。データベースでイベントが発生すると、DNS レコードの更新が遅れる場合があります。この場合、アプリケーションがイベントを処理します。
AWS Advanced JDBC (Java Database Connectivity) Wrapper ドライバーは、INFORMATION_SCHEMA.REPLICA_HOST_STATUS メタデータテーブル経由で DB クラスターのトポグラフィを使用します。テーブルはほぼリアルタイムであるため、AWS Advanced JDBC Wrapper ドライバーは接続を適切なロールにルーティングします。このドライバーは、既存のレプリカ間の負荷分散も行います。Java のプロキシパターンを使用して AWS Advanced JDBC Wrapper を実装します。ネイティブ Aurora MySQL ドライバーを依存関係として追加する必要があります。詳細については、Baeldung のウェブサイトで「Java のプロキシパターン」を参照してください。AWS Advanced JDBC Wrapper は GitHub のウェブサイトからダウンロードできます。
詳細については、「Amazon RDS マルチ AZ DB クラスターをアップグレードする際に、Advanced JDBC Wrapper ドライバーを使用してダウンタイムを 1 秒以内に抑える」を参照してください。
注: DNS キャッシュが過剰に発生すると、AWS Advanced JDBC Wrapper ドライバーに影響する可能性があります。詳細については、「Amazon Aurora でのアプリケーションの可用性を改善する」を参照してください。
接続先インスタンスをテストする
スマートドライバーを使用していない場合は、新しい接続を確立した後にインスタンスをテストしてください。ライターインスタンスに接続しているかどうかをテストするには、@@innodb_read_only 変数を参照します。値が 0 の場合、ライターに接続されています。
出力例:
mysql> select @@innodb_read_only;+--------------------+
| @@innodb_read_only |
+--------------------+
| 0 |
+--------------------+
1 row in set (0.00 sec)
関連情報
Amazon Aurora MySQL データベース管理者用ハンドブック
Amazon Aurora エンドポイント接続