ちょっと話題の記事

【新機能】Amazon RDS の高可用性構成で書き込み性能向上とフェイルオーバーが高速になる!新しい高可用性オプションの Multi-AZ DB Cluster が一般提供になりました

Amazon RDS 新しい高可用性オプションでは書き込みパフォーマンスが高く、20〜40秒程度の高速な切り替えができます。一手間入れると 10 秒程度の切り替えも狙えそうです。現在利用できるのは MySQL と PostgreSQL です。

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ウィスキー、シガー、パイプをこよなく愛する大栗です。

先程 RDS の新しい高可用性オプションである Multi-AZ DB Cluster が一般提供となったためレポートします。Multi-AZ DB Cluster は従来の高可用性オプションの Multi-AZ DB Instance と比較して書き込み性能の向上とフェイルオーバーの高速化が期待できるオプションです。

New Amazon RDS for MySQL & PostgreSQL Multi-AZ Deployment Option: Improved Write Performance & Faster Failover

なおプレビュー時の紹介はこちらのエントリーです。

Multi-AZ DB Cluster

RDS には従来高可用性のためのオプションとして Multi-AZ Instance がありました。従来の Multi-AZ Instance オプションでは高可用性のために 2 個の AZ に各々インスタンスを配置して、片方を Active もう片方を Standby としてデータを Amazon 独自のテクノロジー1でレプリケーション(MariaDB、MySQL、Oracle、PostgreSQL の場合)していました。そのため待機系である Standby はユーザーはアクセスできず、フェイルオーバーではリカバリ処理が必要のため時間がかかるものでした。

Multi-AZ DB instance deployments

AWS Documentation > Amazon Relational Database Service (RDS) > User Guide > Multi-AZ DB instance deployments https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.MultiAZSingleStandby.html より引用

新しく登場した Multi-AZ Cluster では DB Engine のネイティブなレプリケーションを利用して、 Writer から各々別の AZ にある 2台の Reader へレプリケーションします。フェイルオーバー時は最新の変更レコードを持っている Reader を Writer へ昇格させるので高速に切り替えられます。ドキュメント2によると通常は 20 〜 40 秒で切り替えられると記述されています。つまり MySQL の高速なフェイルオーバー機能で有名な MHA3 に近い動きをする模様です。

従来の Multi-AZ Instance と比較して書き込みレイテンシーが低減されています。これは DB Engine のネイティブなレプリケーションを利用しており、WAL の書き込みの完了までしか待たない準同期レプリケーション4をしているためと思われます。

Multi-AZ DB cluster deployments

AWS Documentation > Amazon Relational Database Service (RDS) > User Guide > Multi-AZ DB cluster deployments https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts.html より引用

従来の高可用性オプションとの違い

従来の高可用性オプションとの比較は以下のようになります。

項目 Multi-AZ DB Instance
従来からの機能
Multi-AZ DB Cluster
新機能
DB エンジン Amazon RDS for MariaDB, Amazon RDS for MySQL, Amazon RDS for PostgreSQL, Amazon RDS for Oracle, Amazon RDS for SQL Server Amazon RDS for PostgreSQL, Amazon RDS for MySQL
追加の読み取り容量 なし:スタンバイインスタンスへアクセスできない。ただし別途リードレプリカを構成可能。 2台のスタンバイインスタンスへ読み取りアクセスが可能。追加のリードレプリカは構成できない。
トランザクションコミット Multi-AZ DB Instance と比較して最大2倍高速なトランザクションコミット
フェイルオーバー時間 フェイルオーバー時間は通常 60~120 秒 フェイルオーバー時間は通常 35 秒未満。未処理のトランザクション量に依存する。
AZ 停止に対する回復力 自動的に最新インスタンスへフェイルオーバーする 残り2台のスタンバイの1台が引き継ぎプライマリの書き込みワークロードを処理する
トランザクションコミットのジッタ 書き込みパスの障害に影響を受けやすい 3台中2台の書き込みクォーラムを使用。最大1個の障害のある書き込みパスに影響されない

Multi-AZ DB Cluster のエンドポイントの種類

Multi-AZ DB Cluster では従来の Multi-AZ Instance と異なりレプリケーション先のインスタンスへのアクセスが可能であり、Writer のロールがインスタンス間で移動するため複数のエンドポイントの指定方法があります。これは Aurora Cluster のエンドポイントに類似しており、以下の種類があります。なお2022年3月3日現在ではカスタムエンドポイントには対応していない模様です。

  • クラスタエンドポイント:クラスタ内の Writer を指すエンドポイント。ロールが別のインスタンスに移動してもエンドポイントが追随します。
  • リーダーエンドポイント:クラスタ内の Reader を指すエンドポイント。名前解決がラウンドロビン的に切り替わるのでアクセス先の負荷分散が可能です。
  • インスタンスエンドポイント:インスタンスごとに個別のエンドポイント。ロールが Writer と Reader で切り替わっても不変です。

各エンドポイントの詳細については、以下のエントリの最初にある概要を御覧ください。

リージョン

2022年3月3日現在で、以下のリージョンで Multi-AZ DB Cluster が利用できます。日本に来るまで少し待ちましょう。

  • 米国東部 (バージニア北部): us-east-1
  • 米国西部 (オレゴン): us-west-2
  • 欧州 (アイルランド): eu-west-1

制限

2022年3月3日現在では、Multi-AZ DB Cluster には以下の制限があります。

  • Multi-AZ DB Cluster は MySQL 8.0.28 以降の 8.0 系、PostgreSQL 13.4 以降の 13 系のみで作成できます。(RDS Console では PostgreSQL 13.5 の場合 Multi-AZ DB Cluster が無効でしたがすぐに修正されると思われます。)
  • Multi-AZ DB Cluster は Provisioned IOPS ストレージ(io1)のみサポートされます。
  • Single-AZ DB Instance と従来の Multi-AZ Instance を Multi-AZ DB Cluster へ変更することはできません。代替手段として Single-AZ DB Instance と従来の Multi-AZ Instance のスナップショットを Multi-AZ DB Cluster へリストアできます。
  • Multi-AZ DB Cluster のスナップショットを Single-AZ DB Instance と従来の Multi-AZ Instance へリストアできません。
  • Multi-AZ DB Cluster は全て DB クラスタレベルで行われるため、DB インスタンスレベルで変更できません。
  • Multi-AZ DB Cluster は以下の機能をサポートしていません。
    • Amazon RDS Proxy
    • AWS Backup
    • AWS CloudFormation
    • Multi-AZ DB Cluster のスナップショットの Amazon S3 へのエクスポート
    • IAM DB 認証
    • Kerberos 認証
    • AWS Secrets Manager との統合
    • ポートの変更(代替手段として、PITRでリストアして別のポートを指定可能)
    • オプショングループ
    • リードレプリカ
    • リザーブド DB インスタンス
    • Amazon S3 バケットから Multi-AZ DB Cluster スナップショットのリストア
    • 最大割当ストレージを指定するストレージの自動スケーリング(ストレージの手動拡張は可能)
    • DB クラスタの停止と開始
  • RDS for MySQL の Multi-AZ DB Cluster は外部ターゲットのデータベースへのレプリケーションをサポートしてません。
  • RDS for MySQL の Multi-AZ DB Cluster は次のシステムストアドプロシージャのみサポートしています。
    • mysql.rds_rotate_general_log
    • mysql.rds_rotate_slow_log
    • mysql.rds_show_configuration
  • RDS for PostgreSQL の Multi-AZ DB Cluster は次の PostgreSQL 拡張機能をサポートしていません。
    • aws_s3
    • pg_transport
    • pglogical
  • RDS for PostgreSQL の Multi-AZ DB Cluster はアウトバウンドネットワークアクセスにカスタム DNS サーバーを使用できません。
  • RDS for PostgreSQL の Multi-AZ DB Cluster は論理レプリケーションをサポートしていません。

やってみる

公式ブログでは PostgreSQL の例が載っていたので DevelopersIO では MySQL で試してみます。現時点では利用できるリージョンが限られているため、日本から近そうなオレゴンリージョンを使います。

事前準備

事前にサブネットグループやセキュリティグループなどネットワーク関連リソースを準備しておきます。

次に事前準備しておくリソースとしてパラメータグループを作成します。RDS コンソールでパラメータグループページのパラメータグループの作成をクリックします。

パラメータグループファミリーがmysql8.0の場合はDB Cluster Parameter Groupが作成できます。同様に DB Parameter Group も作成します。

データベースの作成

RDS コンソールでデータベースページのデータベースの作成をクリックします。

データベース作成方法は標準作成を選択します。エンジンのオプションはMySQLにします。バージョンは Multi-AZ DB Cluster をサポートしているMySQL 8.0.28を選択します。

テンプレートは本番稼働用、可用性と耐久性はMulti-AZ DB Clusterを選択します。

DB クラスター識別子とマスターユーザー名、パスワードを任意に入力します。DB インスタンスクラスは MySQL で選択できる最小スペックのインスタンスであるdb.m6gd.largeとしました。

Multi-AZ DB Cluster ではストレージタイプは Provisioned IOPS(io1)のみサポートしています。必要なサイズとパフォーマンスを割り当てます。io1 は汎用 SSD(gp2)と比べて高額になるため注意しましょう。

DB Cluster を配置する VPC とサブネットグループを指定します。今回インターネット経由でのアクセスは必要ないためパブリックアクセスはなしを選択します。ここでは VPC セキュリティグループは新規作成にしています。

Multi-AZ DB Cluster では IAM DB 認証と Kerberos 認証を利用できないため、データベース認証はパスワード認証のみ選択できます。

DB クラスターのパラメータグループで、先ほど作成したクラスタパラメータグループを指定します。バックアップ設定は必要に応じて設定しましょう。

暗号化は必要に応じて設定を行います。ここでは Performance Insights を有効にしています。

ここでは拡張モニタリングを有効化しています。必要に応じてモニタリングロールやログのエクスポート設定を行います。

メンテナンスや削除保護の設定を行い、データベースの作成をクリックしてクラスタを作成します。

Multi-AZ DB Cluster が起動するまでしばらく待ちます。Amazon Aurora と同様にクラスタがあって、その配下としてインスタンスが構成されます。

起動が完了するとクラスタと各インスタンスのステータスが利用可能になります。

クラスタの詳細を確認すると、接続とセキュリティにエンドポイントが表示されています。この情報を元にアクセスします。

ログイン確認

ログインしています。ここでは Amazon Linux 2 をクライアントの OS としています。

MySQL のリポジトリの設定をダウンロードします。

$ wget https://dev.mysql.com/get/mysql80-community-release-el7-5.noarch.rpm

ダウンロードしたファイルをインストールします。

$ sudo yum localinstall -y ./mysql80-community-release-el7-5.noarch.rpm

mysql-community-clientをインストールします。

$ sudo yum install -y mysql-community-client

まずはクラスタエンドポイントを確認してみます。以下のようにクラスタエンドポイントは CNAME でインスタンスエンドポイントを指しており、インスタンスエンドポイントに対して A レコードが設定されています。なおリーダーエンドポイントでは各インスタンスエンドポイントを CNAME としてラウンドロビン的に振り分けしていました。

$ dig database-cluster-1.cluster-xxxxxxxxxxxx.us-west-2.rds.amazonaws.com +answer

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> database-cluster-1.cluster-xxxxxxxxxxxx.us-west-2.rds.amazonaws.com +answer
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1858
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;database-cluster-1.cluster-xxxxxxxxxxxx.us-west-2.rds.amazonaws.com. IN        A

;; ANSWER SECTION:
database-cluster-1.cluster-xxxxxxxxxxxx.us-west-2.rds.amazonaws.com. 5 IN CNAME database-cluster-1-instance-1.xxxxxxxxxxxx.us-west-2.rds.amazonaws.com.
database-cluster-1-instance-1.xxxxxxxxxxxx.us-west-2.rds.amazonaws.com. 5 IN A 172.31.44.12

;; Query time: 3 msec
;; SERVER: 172.31.0.2#53(172.31.0.2)
;; WHEN: Thu Mar 03 05:29:17 UTC 2022
;; MSG SIZE  rcvd: 169

クラスタエンドポイントに対してアクセスします。

$ mysql -h database-cluster-1.cluster-xxxxxxxxxxxx.us-west-2.rds.amazonaws.com -u admin -p
Enter password: # パスワードを入力
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 206
Server version: 8.0.28 Source distribution

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

プラグインの情報を確認してみます。レプリケーションに関するものはrpl_semi_sync_masterrpl_semi_sync_slaveだけなのでグループレプリケーションは使用せずに準同期レプリケーションを設定しているようです。

mysql> SELECT * FROM INFORMATION_SCHEMA.PLUGINS;
+----------------------------------+----------------+---------------+--------------------+---------------------+-----------------------------+------------------------+--------------------+------------------------------------------------------------------------------------+----------------+----------------------+
| PLUGIN_NAME                      | PLUGIN_VERSION | PLUGIN_STATUS | PLUGIN_TYPE        | PLUGIN_TYPE_VERSION | PLUGIN_LIBRARY              | PLUGIN_LIBRARY_VERSION | PLUGIN_AUTHOR      | PLUGIN_DESCRIPTION                                                                 | PLUGIN_LICENSE | LOAD_OPTION          |
+----------------------------------+----------------+---------------+--------------------+---------------------+-----------------------------+------------------------+--------------------+------------------------------------------------------------------------------------+----------------+----------------------+
| binlog                           | 1.0            | ACTIVE        | STORAGE ENGINE     | 80028.0             | NULL                        | NULL                   | Oracle Corporation | This isa pseudo storage engine to represent the binlog in a transaction           | GPL            | FORCE                |
| mysql_native_password            | 1.1            | ACTIVE        | AUTHENTICATION     | 2.0                 | NULL                        | NULL                   | Oracle Corporation | Native MySQL authentication                                                        | GPL            | FORCE                |
| sha256_password                  | 1.1            | ACTIVE        | AUTHENTICATION     | 2.0                 | NULL                        | NULL                   | Oracle Corporation | SHA256 password authentication                                                     | GPL            | FORCE                |
| caching_sha2_password            | 1.0            | ACTIVE        | AUTHENTICATION     | 2.0                 | NULL                        | NULL                   | Oracle Corporation | Cachingsha2 authentication                                                        | GPL            | FORCE                |
| sha2_cache_cleaner               | 1.0            | ACTIVE        | AUDIT              | 4.1                 | NULL                        | NULL                   | Oracle Corporation | Cache cleaner for Caching sha2 authentication                                      | GPL            | FORCE                |
| daemon_keyring_proxy_plugin      | 1.0            | ACTIVE        | DAEMON             | 80028.0             | NULL                        | NULL                   | Oracle             | A plugin that implements the keyring component services atop of the keyring plugin | GPL            | FORCE                |
| CSV                              | 1.0            | ACTIVE        | STORAGE ENGINE     | 80028.0             | NULL                        | NULL                   | Oracle Corporation | CSV storage engine                                                                 | GPL            | FORCE                |
| MEMORY                           | 1.0            | ACTIVE        | STORAGE ENGINE     | 80028.0             | NULL                        | NULL                   | Oracle Corporation | Hash based, stored in memory, useful for temporary tables                          | GPL            | FORCE                |
| InnoDB                           | 8.0            | ACTIVE        | STORAGE ENGINE     | 80028.0             | NULL                        | NULL                   | Oracle Corporation | Supports transactions, row-level locking, and foreign keys                         | GPL            | FORCE                |
| INNODB_TRX                       | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | InnoDB transactions                                                                | GPL            | FORCE                |
| INNODB_CMP                       | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | Statistics for the InnoDB compression                                              | GPL            | FORCE                |
| INNODB_CMP_RESET                 | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | Statistics for the InnoDB compression; reset cumulated counts                      | GPL            | FORCE                |
| INNODB_CMPMEM                    | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | Statistics for the InnoDB compressed buffer pool                                   | GPL            | FORCE                |
| INNODB_CMPMEM_RESET              | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | Statistics for the InnoDB compressed buffer pool; reset cumulated counts           | GPL            | FORCE                |
| INNODB_CMP_PER_INDEX             | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | Statistics for the InnoDB compression (per index)                                  | GPL            | FORCE                |
| INNODB_CMP_PER_INDEX_RESET       | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | Statistics for the InnoDB compression (per index); reset cumulated counts          | GPL            | FORCE                |
| INNODB_BUFFER_PAGE               | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | InnoDB Buffer Page Information                                                     | GPL            | FORCE                |
| INNODB_BUFFER_PAGE_LRU           | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | InnoDB Buffer Page in LRU                                                          | GPL            | FORCE                |
| INNODB_BUFFER_POOL_STATS         | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | InnoDB Buffer Pool Statistics Information                                          | GPL            | FORCE                |
| INNODB_TEMP_TABLE_INFO           | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | InnoDB Temp Table Stats                                                            | GPL            | FORCE                |
| INNODB_METRICS                   | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | InnoDB Metrics Info                                                                | GPL            | FORCE                |
| INNODB_FT_DEFAULT_STOPWORD       | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | Defaultstopword list for InnDB Full Text Search                                   | GPL            | FORCE                |
| INNODB_FT_DELETED                | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | INNODB AUXILIARY FTS DELETED TABLE                                                 | GPL            | FORCE                |
| INNODB_FT_BEING_DELETED          | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | INNODB AUXILIARY FTS BEING DELETED TABLE                                           | GPL            | FORCE                |
| INNODB_FT_CONFIG                 | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | INNODB AUXILIARY FTS CONFIG TABLE                                                  | GPL            | FORCE                |
| INNODB_FT_INDEX_CACHE            | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | INNODB AUXILIARY FTS INDEX CACHED                                                  | GPL            | FORCE                |
| INNODB_FT_INDEX_TABLE            | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | INNODB AUXILIARY FTS INDEX TABLE                                                   | GPL            | FORCE                |
| INNODB_TABLES                    | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | InnoDB INNODB_TABLES                                                               | GPL            | FORCE                |
| INNODB_TABLESTATS                | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | InnoDB INNODB_TABLESTATS                                                           | GPL            | FORCE                |
| INNODB_INDEXES                   | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | InnoDB INNODB_INDEXES                                                              | GPL            | FORCE                |
| INNODB_TABLESPACES               | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | InnoDB INNODB_TABLESPACES                                                          | GPL            | FORCE                |
| INNODB_COLUMNS                   | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | InnoDB INNODB_COLUMNS                                                              | GPL            | FORCE                |
| INNODB_VIRTUAL                   | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | InnoDB INNODB_VIRTUAL                                                              | GPL            | FORCE                |
| INNODB_CACHED_INDEXES            | 8.2            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | InnoDB cached indexes                                                              | GPL            | FORCE                |
| INNODB_SESSION_TEMP_TABLESPACES  | 8.0            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | NULL                        | NULL                   | Oracle Corporation | InnoDB Session Temporary tablespaces                                               | GPL            | FORCE                |
| MyISAM                           | 1.0            | ACTIVE        | STORAGE ENGINE     | 80028.0             | NULL                        | NULL                   | Oracle Corporation | MyISAM storage engine                                                              | GPL            | FORCE                |
| MRG_MYISAM                       | 1.0            | ACTIVE        | STORAGE ENGINE     | 80028.0             | NULL                        | NULL                   | Oracle Corporation | Collection of identical MyISAM tables                                              | GPL            | FORCE                |
| PERFORMANCE_SCHEMA               | 0.1            | ACTIVE        | STORAGE ENGINE     | 80028.0             | NULL                        | NULL                   | Oracle Corporation | Performance Schema                                                                 | GPL            | FORCE                |
| TempTable                        | 1.0            | ACTIVE        | STORAGE ENGINE     | 80028.0             | NULL                        | NULL                   | Oracle Corporation | InnoDB temporary storage engine                                                    | GPL            | FORCE                |
| ARCHIVE                          | 3.0            | ACTIVE        | STORAGE ENGINE     | 80028.0             | NULL                        | NULL                   | Oracle Corporation | Archivestorage engine                                                             | GPL            | ON                   |
| BLACKHOLE                        | 1.0            | ACTIVE        | STORAGE ENGINE     | 80028.0             | NULL                        | NULL                   | Oracle Corporation | /dev/null storage engine (anything you write to it disappears)                     | GPL            | ON                   |
| FEDERATED                        | 1.0            | DISABLED      | STORAGE ENGINE     | 80028.0             | NULL                        | NULL                   | Oracle Corporation | Federated MySQL storage engine                                                     | GPL            | OFF                  |
| ngram                            | 0.1            | ACTIVE        | FTPARSER           | 1.1                 | NULL                        | NULL                   | Oracle Corporation | Ngram Full-Text Parser                                                             | GPL            | ON                   |
| mysqlx_cache_cleaner             | 1.0            | ACTIVE        | AUDIT              | 4.1                 | NULL                        | NULL                   | Oracle Corporation | Cache cleaner for sha2 authentication in X plugin                                  | GPL            | ON                   |
| mysqlx                           | 1.0            | DISABLED      | DAEMON             | 80028.0             | NULL                        | NULL                   | Oracle Corporation | X Plugin for MySQL                                                                 | GPL            | OFF                  |
| rpl_semi_sync_master             | 1.0            | ACTIVE        | REPLICATION        | 4.0                 | semisync_master.so          | 1.10                   | Oracle Corporation | Source-side semi-synchronous replication.                                          | GPL            | ON                   |
| rpl_semi_sync_slave              | 1.0            | ACTIVE        | REPLICATION        | 4.0                 | semisync_slave.so           | 1.10                   | Oracle Corporation | Replica-side semi-synchronous replication.                                         | GPL            | ON                   |
| RDS_PROCESSLIST                  | 1.0            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | rds_performance_insights.so | 1.10                   | Author Name        | EXTENDED PROCESSLIST                                                               | GPL            | FORCE_PLUS_PERMANENT |
| RDS_EVENTS_THREADS_WAITS_CURRENT | 1.0            | ACTIVE        | INFORMATION SCHEMA | 80028.0             | rds_performance_insights.so | 1.10                   | Author Name        | ACTIVE SESSIONS TABLE WITH THE WAIT EVENT                                          | GPL            | FORCE_PLUS_PERMANENT |
+----------------------------------+----------------+---------------+--------------------+---------------------+-----------------------------+------------------------+--------------------+------------------------------------------------------------------------------------+----------------+----------------------+
49 rows in set (0.00 sec)

準同期レプリケーションの設定を確認してみます。rpl_semi_sync_master_enabledが ON になっており、rpl_semi_sync_master_timeoutが設定されいるので、たしかに準同期レプリケーションでデータの冗長化を行っているようです。またrpl_semi_sync_master_wait_for_slave_countが 1 になっているため、1台のレプリカの応答確認の受信後に処理が続行されます。

mysql> SHOW VARIABLES LIKE 'rpl_semi_sync_%';
+---------------------------------------------+---------------------+
| Variable_name                               | Value               |
+---------------------------------------------+---------------------+
| rpl_semi_sync_master_compute_delay_interval | 1                   |
| rpl_semi_sync_master_enabled                | ON                  |
| rpl_semi_sync_master_max_write_delay        | 50000               |
| rpl_semi_sync_master_target_apply_lag       | 120                 |
| rpl_semi_sync_master_timeout                | 9223372036854775807 |
| rpl_semi_sync_master_trace_level            | 32                  |
| rpl_semi_sync_master_wait_for_slave_count   | 1                   |
| rpl_semi_sync_master_wait_no_slave          | ON                  |
| rpl_semi_sync_master_wait_point             | AFTER_SYNC          |
| rpl_semi_sync_master_write_delay_increment  | 10                  |
| rpl_semi_sync_slave_enabled                 | OFF                 |
| rpl_semi_sync_slave_trace_level             | 32                  |
+---------------------------------------------+---------------------+
12 rows in set (0.01 sec)

読み取り専用のフラグを確認しましたが、Writer のため全て OFF になっています。

mysql> SHOW VARIABLES LIKE '%read_only';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_read_only      | OFF   |
| read_only             | OFF   |
| super_read_only       | OFF   |
| transaction_read_only | OFF   |
+-----------------------+-------+
4 rows in set (0.01 sec)

次に Reader へアクセスしてみます。ここではインスタンスエンドポイントを使ってアクセスしてみます。

$ mysql -h database-cluster-1.cluster-ro-xxxxxxxxxxxx.us-west-2.rds.amazonaws.com -u admin -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 209
Server version: 8.0.28 Source distribution

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

準同期レプリケーションの設定を確認してみます。rpl_semi_sync_slave_enabledが ON になっており、準同期レプリケーションを受けているようです。

mysql> SHOW VARIABLES LIKE 'rpl_semi_sync_%';
+---------------------------------------------+---------------------+
| Variable_name                               | Value               |
+---------------------------------------------+---------------------+
| rpl_semi_sync_master_compute_delay_interval | 1                   |
| rpl_semi_sync_master_enabled                | OFF                 |
| rpl_semi_sync_master_max_write_delay        | 50000               |
| rpl_semi_sync_master_target_apply_lag       | 120                 |
| rpl_semi_sync_master_timeout                | 9223372036854775807 |
| rpl_semi_sync_master_trace_level            | 32                  |
| rpl_semi_sync_master_wait_for_slave_count   | 1                   |
| rpl_semi_sync_master_wait_no_slave          | ON                  |
| rpl_semi_sync_master_wait_point             | AFTER_SYNC          |
| rpl_semi_sync_master_write_delay_increment  | 10                  |
| rpl_semi_sync_slave_enabled                 | ON                  |
| rpl_semi_sync_slave_trace_level             | 32                  |
+---------------------------------------------+---------------------+
12 rows in set (0.00 sec)

読み取り専用のフラグを確認すると、read_onlyが ON になっています。5

mysql> SHOW VARIABLES LIKE '%read_only';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_read_only      | OFF   |
| read_only             | ON    |
| super_read_only       | OFF   |
| transaction_read_only | OFF   |
+-----------------------+-------+
4 rows in set (0.01 sec)

フェイルオーバー確認

実際にフェイルオーバーをさせてみて、動作を確認してみます。

以下のようなスクリプトを各インスタンスエンドポイントとクラスタエンドポイントを対象に作成します。0.5秒毎にアクセスしてread_onlyの状況を確認するスクリプトです。

#! /bin/bash

RDSINSTANCE=database-cluster-1-instance-1.xxxxxxxxxxxx.us-west-2.rds.amazonaws.com
while true
do
  DATETIME=$(date "+%Y-%m-%d %T.%N")
  (echo "select '${DATETIME}', now(3), @@hostname, @@read_only;" | mysql -uadmin -ppassword -h $RDSINSTANCE -s) &
  sleep 0.5
done

作成した各々のスクリプトを動作させます。動作せながら Multi-AZ DB Cluster をフェイルオーバーさせてみます。

クラスタを選択した状態で右上のアクションを選択してメニューを表示させ、フェイルオーバーをクリックします。

フェイルオーバーをクリックするとフェイルオーバーが始まります。

ステータスもフェイルオーバーになります。

実行したスクリプトは以下のように結果が出力されてきます。末尾の数字はread_onlyのステータスです。

・
・
・
2022-03-03 06:11:00.609159195	2022-03-03 06:11:00.629	ip-10-3-2-113	0
2022-03-03 06:11:01.111533103	2022-03-03 06:11:01.134	ip-10-3-2-113	0
2022-03-03 06:11:01.613920997	2022-03-03 06:11:01.656	ip-10-3-2-113	0
2022-03-03 06:11:02.116430901	2022-03-03 06:11:02.169	ip-10-3-2-113	0
2022-03-03 06:11:02.618524153	2022-03-03 06:11:02.652	ip-10-3-2-113	0
・
・
・

クラスタエンドポイントを対象にしたスクリプトの結果は以下のようになりました。Reader から Writer への昇格と DNS の変更など含めて 21秒程度で切り替えが実施されました。ドキュメントにも通常は 20〜40 秒で切り替えられると記述があるのでその通りの結果となっています。

2022-03-03 06:27:18.440485098	2022-03-03 06:27:18.464	ip-10-3-1-169	0
2022-03-03 06:27:18.942682338	2022-03-03 06:27:18.967	ip-10-3-1-169	0
2022-03-03 06:27:19.445148025	2022-03-03 06:27:19.466	ip-10-3-1-169	0
2022-03-03 06:27:19.947500024	2022-03-03 06:27:19.968	ip-10-3-1-169	0
2022-03-03 06:27:20.449784102	2022-03-03 06:27:20.471	ip-10-3-1-169	0
2022-03-03 06:27:42.062079530	2022-03-03 06:27:42.082	ip-10-3-3-99	0
2022-03-03 06:27:42.564400791	2022-03-03 06:27:42.587	ip-10-3-3-99	0
2022-03-03 06:27:43.066604908	2022-03-03 06:27:43.088	ip-10-3-3-99	0
2022-03-03 06:27:43.568878118	2022-03-03 06:27:43.601	ip-10-3-3-99	0
2022-03-03 06:27:44.071074157	2022-03-03 06:27:44.091	ip-10-3-3-99	0

同時に各インスタンスエンドポイントの結果も確認します。

まずは旧 Witer へのアクセスです。アクセスが不要になってから Reader として起動するまで数分掛かっています。これはクラスタから切り離した後に、レプリケーションの再設定やデータのリカバリなどを行い Reader としての機能を取り戻すまで設定を行っているためと思われます。全体で3台構成であるため、このインスタンスが Reader になるまでは 別のインスタンスが Reader のロールを継続しているため Reader のアクセスは不通になりません。

2022-03-03 06:27:18.042339787	2022-03-03 06:27:18.062	ip-10-3-1-169	0
2022-03-03 06:27:18.544383743	2022-03-03 06:27:18.564	ip-10-3-1-169	0
2022-03-03 06:27:19.046471907	2022-03-03 06:27:19.066	ip-10-3-1-169	0
2022-03-03 06:27:19.548570310	2022-03-03 06:27:19.568	ip-10-3-1-169	0
2022-03-03 06:27:20.050597504	2022-03-03 06:27:20.076	ip-10-3-1-169	0
2022-03-03 06:33:26.476519567	2022-03-03 06:33:26.466	ip-10-3-1-6	1
2022-03-03 06:33:26.978677806	2022-03-03 06:33:26.965	ip-10-3-1-6	1
2022-03-03 06:33:27.481072909	2022-03-03 06:33:27.489	ip-10-3-1-6	1
2022-03-03 06:33:27.983574410	2022-03-03 06:33:27.967	ip-10-3-1-6	1
2022-03-03 06:33:28.485852053	2022-03-03 06:33:28.465	ip-10-3-1-6	1

次は Reader から Writer へ昇格したインスタンスを確認すると、昇格時にも継続してアクセスが行えています。また、旧 Writer がアクセスできなくなってから、新 Writer でread_onlyが 0 になって更新が可能になるまで 10 秒程度となっています。

2022-03-03 06:27:28.365129765	2022-03-03 06:27:28.395	ip-10-3-3-99	1
2022-03-03 06:27:28.867197590	2022-03-03 06:27:28.887	ip-10-3-3-99	1
2022-03-03 06:27:29.369248065	2022-03-03 06:27:29.401	ip-10-3-3-99	1
2022-03-03 06:27:29.871448661	2022-03-03 06:27:29.898	ip-10-3-3-99	1
2022-03-03 06:27:30.373557114	2022-03-03 06:27:30.395	ip-10-3-3-99	1
2022-03-03 06:27:30.875868334	2022-03-03 06:27:30.896	ip-10-3-3-99	0
2022-03-03 06:27:31.377930279	2022-03-03 06:27:31.398	ip-10-3-3-99	0
2022-03-03 06:27:31.880007643	2022-03-03 06:27:31.908	ip-10-3-3-99	0
2022-03-03 06:27:32.382127689	2022-03-03 06:27:32.402	ip-10-3-3-99	0
2022-03-03 06:27:32.884347231	2022-03-03 06:27:32.916	ip-10-3-3-99	0

このように今までの Multi-AZ Instance 構成のフェイルオーバーと比べてかなり高速に切り替えが可能になっていることが分かりました。

補足(2022年3月4日 11:25 追記)

PostgreSQL の場合のパラメータ関連について、結果を記載しておきます。

拡張機能は既存の RDS と同様にplpgsqlのみでした。

postgres=> SELECT * FROM pg_extension;
  oid  | extname | extowner | extnamespace | extrelocatable | extversion | extconfig | extcondition
-------+---------+----------+--------------+----------------+------------+-----------+--------------
 14287 | plpgsql |       10 |           11 | f              | 1.0        |           |
(1 row)

レプリケーション関連の設定を見てみます。

Writer 側でレプリケーションの設定であるsynchronous_standby_namesを確認します。先頭がANY 1なので、クォーラムに基づく同期レプリケーションで少なくとも1台の応答を待つ設定となっています。

postgres=> show synchronous_standby_names;
                                                             synchronous_standby_names
---------------------------------------------------------------------------------------------------------------------------------------------------
 ANY 1 ("rds_us_west_2_db_ed7t6qfjz32p7tmk6heijmmmhq","rds_us_west_2_db_l2ygwyavtnu7swndtkru2xz6me","rds_us_west_2_db_x4cujt43g35aecpaqr6stvjkiq")
(1 row)

さいごに

通常の RDS は Amazon Aurora と比べると、どうしてもフェイルオーバーが遅いのが悩みのタネの一つでした。今回の Multi-AZ Cluster によってフェイルオーバーが高速になるので、かなり使いやすくなると思います。

DNS ベースでの切り替えでは 20 秒程度かかっていましたが、各インスタンス上での切り替え自体は 10 秒程度で行えています。そのため MySQL の場合であれば、ProxySQL などを活用すれば 10 秒でフェイルオーバーが出来るかと思います。実際に障害が発生したときのフェイルオーバーでは障害検知の時間が追加でかかりますが、かなり高速になると思います。

ProxySQL を使用して更に高速なフェイルオーバーを行う場合は、以下のエントリーを参考にして頂ければ実装できると思います。ポイントは mysql_replication_hostgroupscheck_typeinnodb_read_onlyからread_onlyに変更すればうまくいくと思います。


  1. 著者はストレージレベルでの同期レプリケーションと推察しています。 
  2. Failover process for Multi-AZ DB clusters 
  3. yoshinorim/mha4mysql-manager 
  4. MySQL では準同期レプリケーションですが、PostgreSQLでは同期レプリケーションと呼びます。 
  5. Aurora MySQL の場合は Writer と Reader でinnodb_read_onlyが変わります。