🐬
RDS MySQLとAurora MySQLの間でGTIDベースのマルチマスターレプリケーションを構成する
RDS MySQLからAurora MySQLへ移行をする、などでレプリケーションを行う際に、RDS特有の制約などでハマったポイントなどがあったため備忘録としてまとめました。
前提条件
- ソースとターゲットそれぞれのMySQLバージョン
- ソース:RDS MySQL 8.0.35
- ターゲット:Auroa MySQL 3.10
- 上記以外のバージョンの場合、実行できないストアドプロシージャが出てくる可能性があります。
- ソースとターゲットのデーターベース名が同一。(後述)
手順イメージ
手順
1.MySQL RDS側での事前設定(+Terraformコード例)
-
自動バックアップの設定
-
レプリケーションに必要なバイナリログを有効化するために必要
resource "aws_db_instance" "hoge" { ・・・ (その他必要な属性) ・・・ backup_retention_period = 7 # 自動バックアップ設定 apply_immediately = true # メンテナンスウィンドウを待たずに即時反映する }
-
-
パラメータグループのパラメータ設定
-
レプリケーションに必要なGTIDモードの変更のため必要
resource "aws_db_parameter_group" "hoge" { name = "hogehoge" family = "mysql8.0" ・・・ (その他必要な属性) ・・・ parameter { name = "binlog_format" value = "ROW" apply_method = "pending-reboot" } parameter { name = "enforce_gtid_consistency" value = "ON" apply_method = "pending-reboot" } parameter { name = "gtid-mode" value = "ON" apply_method = "pending-reboot" } parameter { name = "binlog_row_image" value = "FULL" apply_method = "pending-reboot" } }
-
変更後にDBインスタンスの再起動が必要。
- 再起動を行うため、GTIDモードは直接
ON
に変更して問題ない。(MySQL公式ドキュメントでは段階を分けて変更するよう書いてある。)
- 再起動を行うため、GTIDモードは直接
-
2.Aurora for MySQL側での事前設定
-
自動バックアップの設定
-
レプリケーションに必要なバイナリログを有効化するために必要
resource "aws_db_instance" "this" { ・・・ (その他必要な属性) ・・・ backup_retention_period = 7 # 自動バックアップ設定 }
-
-
パラメータグループのパラメータ設定
-
レプリケーションに必要なGTIDモードの変更のため必要
resource "aws_db_parameter_group" "this" { name = "hogehoge" family = "mysql8.0" ・・・ (その他必要な属性) ・・・ parameter { name = "binlog_format" value = "ROW" apply_method = "pending-reboot" } parameter { name = "enforce_gtid_consistency" value = "ON" apply_method = "pending-reboot" } parameter { name = "gtid-mode" value = "ON" apply_method = "pending-reboot" } parameter { name = "binlog_row_image" value = "FULL" apply_method = "pending-reboot" } }
-
変更後にDBインスタンスの再起動が必要。
- 再起動を行うため、GTIDモードは直接
ON
に変更して問題ない。(MySQL公式ドキュメントでは段階を分けて変更するよう書いてある。)
- 再起動を行うため、GTIDモードは直接
-
3.RDS側のリードレプリカを作成する。
RDS for MySQLではExecutedGTIDとデータの状態が一致したDumpを取得するために、リードレプリカの作成が必要です。
RDS側でリードレプリカを作成してください。
このリードレプリカはダンプの取得元として利用します。
4.ソース(RDS for MySQL)からのスナップショット取得
-
作成したリードレプリカに接続し、以下のコマンドを実行してレプリケーションを一時的に停止させる。
CALL mysql.rds_stop_replication;
実行例
mysql> CALL mysql.rds_stop_replication; +-------------------------------+ | Message | +-------------------------------+ | Slave is now down or disabled | +-------------------------------+ 1 row in set (3.05 sec) Query OK, 0 rows affected (3.05 sec) mysql>
-
リードレプリカに対して
mysqldump
を実行します。set +o history export MYSQL_HOST='<リードレプリカのホスト名>' export MYSQL_PORT=3306 export MYSQL_DATABASE='<対象のデータベース名>' export MYSQL_USER='<RDS側のMySQLユーザー名>' export MYSQL_PWD='<RDS側のMySQLパスワード>' set -o history mysqldump -h "$MYSQL_HOST" -u "$MYSQL_USER" "$MYSQL_DATABASE" \ --single-transaction \ --skip-lock-tables \ --set-gtid-purged=OFF > dump.sql
-
リードレプリカのExecutedGTIDセットを手動で取得して控える。
mysql -h "$MYSQL_HOST" \ -u "$MYSQL_USER" \ -s -N \ -e "SELECT @@GLOBAL.gtid_executed;" \ | tr -d '\\n'
取得されるExecutedGTIDセットの例
846b322b-eae7-37e9-a545-be3603e2c70f:1-747,a4ac629a-31db-11ec-9b52-0a7d87c0f0ab:1-2476,f2fe7974-318a-3034-82f3-971e7a002eb9:1
5.ターゲット(Aurora for MySQL)へのスナップショットのリストア
set +o history
export MYSQL_HOST='<Aurora側のクラスタエンドポイント>'
export MYSQL_PORT=3306
export MYSQL_DATABASE='<対象のデータベース名>'
export MYSQL_USER='<対象のデータベース名>_admin'
export MYSQL_PWD='<RDS側のMySQLパスワード>'
set -o history
mysql -h "$MYSQL_HOST" -u "$MYSQL_USER" "$MYSQL_DATABASE" < dump.sql
先ほど控えたGTIDを以下ストアドプロシジャでセットする
CALL mysql.rds_gtid_purged('a4ac629a-31db-11ec-9b52-0a7d87c0f0ab:1-2404');
6.レプリケーションフローの確立(RDS → Aurora)
- Auroraクラスターのライターインスタンスエンドポイントに接続します。
- 以下のストアドプロシージャを実行し、RDSをソースとして設定します。このプロシージャはGTID自動ポジショニングを利用します。
CALL mysql.rds_set_external_source_with_auto_position (
'<RDS側のホスト名>',
3306,
'<RDS側のMySQLユーザー名>',
'<RDS側のMySQLパスワード>',
0
);
以下のストアドプロシージャを実行すると、レプリケーションが開始します。
CALL mysql.rds_start_replication;
成功した場合の出力例
mysql> CALL mysql.rds_start_replication;
+---------------------------+
| Message |
+---------------------------+
| Replica running normally. |
+---------------------------+
1 row in set (2.31 sec)
Query OK, 0 rows affected (2.31 sec)
mysql>
7.レプリケーションフローの確立(Aurora → RDS)
- RDS for MySQLインスタンスに接続します。
- ストアドプロシージャを実行し、Auroraをソースとして設定し、GTID自動ポジショニングを有効にします。SQL
CALL mysql.rds_set_external_master_with_auto_position (
'<Aurora側のクラスタエンドポイント>'
, 3306
, '<対象のデータベース名>_admin'
, '<Aurora側のMySQLユーザーパスワード>'
, 0
, 0
);
以下のAWSマネージドプロシージャを使用して、レプリケーションを開始します。
CALL mysql.rds_start_replication;
成功した場合の出力例
mysql> CALL mysql.rds_start_replication;
+-----------------------------------------------------+
| Message |
+-----------------------------------------------------+
| Replication started. Slave is now running normally. |
+-----------------------------------------------------+
1 row in set (3.06 sec)
Query OK, 0 rows affected (3.06 sec)
mysql>
8.それぞれのDBでレプリケーションの状態を確認する
SHOW REPLICA STATUS\G
SHOW REPLICA STATUS
の主要なフィールド
フィールド | 正常な状態 | 意味 |
---|---|---|
Replica_IO_Running |
Yes |
ソース接続とバイナリログ受信状態 |
Replica_SQL_Running |
Yes |
イベント適用状態 |
Seconds_Behind_Source |
0 |
レプリカ遅延秒数 |
Last_SQL_Error / Last_IO_Error
|
(空) | レプリケーションエラー内容 |
Executed_Gtid_Set |
(継続的に更新) | 適用済みGTIDセット |
注意点・補足
- Dump取得時にall-databasesは使用不可。必ず目的のデータベースを指定する。
- RDS、AuroraのMySQLでmysqlデータベースのCREATE文の実行が不可であるため。
- RDS for MySQLはテーブルのロックができないため、GTID込みのDump取得は不可。
- Aurora for MySQLでは、レプリケーションスレーブとしての動作時にデータベース名の変換は不可。
- 事前にAurora側のデータベース名をRDS側と完全一致になるように運用回避が必要。
- https://repost.aws/questions/QU-9uYWmURRFm7HUkb5V148g/replication-external-mysql-to-aurora-mysql-replication-filters
参考
Discussion