はじめにの要件
「同一のAWSリージョン内で2つのAurora MySQLクラスター間でレプリケーションを貼る」
この要件に対応するためには現時点(2024年12月時点)では、"MySQL binary log (binlog) replication"を利用する必要があります。
Two Aurora MySQL DB clusters in the same AWS Region, by using MySQL binary log (binlog) replication.
本記事では、Amazon Aurora MySQLクラスター間でbinlogレプリケーションを構築する方法と、レプリケーション実行中の障害時の検証をします。
binlogレプリケーションはMySQLの機能です。そもそもの構成や仕組みについてはこの記事では触れないので公式ドキュメントや別記事を参照ください。
前提
本記事では以下の前提があります。
- Aurora MySQLのバージョンは
8.0.mysql_aurora.3.04.2
(MySQL8.0.28) - 本記事ではレプリケーションにてレプリ元となるクラスターを"Source側"、レプリ先となる方(Replica)を"Target側"と呼ぶ
- レプリケーションTargetとなるMySQLクラスターはSourceのクラスターからcloneを元に作成する
- binlogレプリケーションではGTIDモードを採用する
GTIDについて
Global Transaction Identifiers (GTID) はトランザクションごとに全体ユニークなIDを付与する仕組みでbinlogレプリケーションにおいては以下のメリットがあります。
- Masterサーバがフェイルオーバーした際にbinlogファイルとそのポジションを指定することなくReplicaサーバは新規Masterからのレプリケーションを継続できる
- 新規Replicaサーバの構築時にもbinlogファイルとそのポジションを指定する必要がない
GTIDの詳細は以下の公式ドキュメントを参照ください。
本記事ではAurora MySQLクラスター間のbinlogレプリケーションを扱いますが、Source側AuroraクラスターでのMaster(Writer)インスタンスのフェイルオーバーが発生しても基本的にAuroraクラスターにて新規インスタンスは同じbinlog情報を持つと考えられるため、GTIDの恩恵が大きいと言えない部分がありそうです。1
以下のAWS側のドキュメントでも、
You typically use GTID-based replication with Aurora when replicating from an external MySQL-compatible database into an Aurora cluster.
とあり、Source側がオンプレミスのMySQLのDBにてGTIDのレプリケーションにしておけばオンプレミスでのフェイルオーバー発生時の運用が改善されると述べられています。
また、GTIDでのレプリケーションの場合のデメリットとして、一部のレプリケーションをスキップさせたい等のbinlogポジションを指定する細かな設定ができなくなる、というものがありますがそういった要件は無い前提とします。
これらのことを考慮しつつ本記事ではGTIDを採用したレプリケーション構築を行います。
構築 of Aurora MySQLクラスター間のbinlogレプリケーション
Step1: レプリケーションSourceとなるMySQLクラスターに設定されているパラメータグループの値を変更
新規作成したパラメータグループにて以下のパラメーターで設定する。
Parameter | Value |
---|---|
gtid-mode | ON |
enforce_gtid_consistency | ON |
binlog_format | MIXED |
上記のパラメータはすべて "Apply Type" が "Static" であり、パラメータ値の変更を適用させるにはRDSインスタンスを再起動する必要があります。
Step2: SourceとなるMySQLクラスターからTargetとなるクラスターをClone
AWSコンソール上から作成する場合は以下の画像のようにクラスター設定の"Actions"から"Create clone"を選択し、各種設定をする。
IaCでリソースを管理している場合はCloneの作成は各種IaCツールから作成してください。
Step3: CloneされたTargetのクラスターのWriterインスタンスのLogからBinlogポジションを確認する
前Stepにて、CloneされたTargetクラスターのRDSのWriterインスタンスのLogにてBinlogポジションが以下画像のように出力されているので、これをメモしておきます。
このBinlogポジションは後述のStepでの初回レプリケーション作成にて必要になります。
Step4: AWS側にてTarget側クラスターからSource側クラスターへMySQL接続できるようにサブネット/セキュリティグループを設定する
binlogレプリケーションではTarget側からSource側へ接続するので、そのためのクラウド側の設定をする必要があります。
各クラスターが持つサブネット間のルート設定とセキュリティグループ設定を確認してください。
設定の詳細はこの記事では割愛します。
Step5 (Optional) Source側にてbinlogレプリケーションの保持期間を設定する
レプリ対象データのサイズに応じて初回レプリケーションの時間がかかります。
Aurora MySQLではbinlogファイルに直接アクセスができないので、初回レプリケーション時のレプリケーションにてbinlogファイルが消える前に設定できるように、必要に応じて保持期間を延ばす設定をしておきましょう。
Source側のMySQLにログインし以下コマンドにてレプリケーションの保持期間を延ばしておきます。
mysql> CALL mysql.rds_set_configuration('binlog retention hours', 144);
Aurora MySQLはデフォルトで24
(1day)に設定されています。
Step6: Source側にレプリケーション用ユーザーの作成および権限付与
Source側にて レプリカターゲットからレプリカソースに接続してレプリケーションを実行するためのユーザーを作成します。
Source側のMySQLにログインし以下コマンドを実行します。
- ユーザー名とパスワードは任意で設定可能です
- SSL設定は要件に応じて設定してください
mysql> CREATE USER 'rpl'@'%' IDENTIFIED BY 'Passw0rd';
mysql> GRANT REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO 'rpl'@'%';
Step7: Target側にてレプリケーション設定をする
Target側MySQLにログインし、以下の内容をrds_set_external_sourceのプロシージャに設定し実行する
- 以前のStepで確認したBinlogファイル名とポジション
- レプリケーション用ユーザーとパスワード
- ソース側ホスト名
mysql> CALL mysql.rds_set_external_source (
'source_host',
3306,
'rpl',
'Passw0rd',
'mysql-bin-changelog.000002',
772,
0
);
Step8: (Optional) Target側にて必要に応じてレプリケーションのフィルタリング設定をする
レプリケーションの対象のテーブルを指定する要件がある場合はTarget側パラメータグループの値を設定します。
パラメータ値は以下のAWS公式ドキュメントに記載されているので、こちらを参照ください。
これらのパラメータ値は"Dynamic"設定なのでレプリケーションを停止させている状態で設定し、レプリケーションを再開させることで適用されるようになります。
Step9: Target側にてレプリケーションを開始する
Target側MySQLにログインし、rds_start_replicationのプロシージャでレプリケーションを開始します。
mysql> CALL mysql.rds_start_replication;
レプリケーションが成功しているかSHOW REPLICA STATUS
にてLast_Errno: 0
になっているか確認します。
mysql> SHOW REPLICA STATUS\G
*************************** 1. row ***************************
Replica_IO_State: Waiting for source to send event
Source_Host: source_host
Source_User: rpl
Source_Port: 3306
Connect_Retry: 60
Source_Log_File: mysql-bin-changelog.000023
Read_Source_Log_Pos: 94329298
Relay_Log_File: relaylog.000002
Relay_Log_Pos: 336
Relay_Source_Log_File: mysql-bin-changelog.000023
Replica_IO_Running: Yes
Replica_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table: mysql.%
Last_Errno: 0
Step10: GTIDのレプリケーションで開始しなおす
SHOW REPLICA STATUS
にてExecuted_Gtid_Set
に値があることを確認しましょう。
Executed_Gtid_Set: xxxx-xxxx-xxxx-xxxx-xxxx:1-1690
GTIDのレプリケーションを開始前に既存のレプリケーションをrds_stop_replicationのストアドで停止します。
mysql> CALL mysql.rds_stop_replication;
GTIDを使ったレプリケーション設定をrds_set_external_source_with_auto_positionストアドで設定します。
CALL mysql.rds_set_external_source_with_auto_position (
'source_host'
, 3306
, 'rpl'
, 'Passw0rd'
, 0
);
レプリケーションを再開します。
mysql> CALL mysql.rds_start_replication;
SHOW REPLICA STATUS
にてAuto_Position: 1
が設定されていれば、GTIDでのレプリケーションが実施できています。
Auto_Position: 1
Source側でのフェイルオーバー検証
上述の"GTIDについて"の章にて、Auroraクラスター間のレプリケーションではGTIDの恩恵は直接無い前提ですが、運用検証としてSource側のAuroraクラスターにてフェイルオーバーを発生させてレプリケーションに問題が生じないかを確認します。
フェイルオーバー実行前のレプリケーション状況を確認
mysql> SHOW REPLICA STATUS\G
*************************** 1. row ***************************
Replica_IO_State: Waiting for source to send event
.....
Source_Log_File: mysql-bin-changelog.000023
Read_Source_Log_Pos: 94330102
.....
Last_Errno: 0
Last_Error:
.....
AWSコンソール上からSource側のフェイルオーバーを実行
フェイルオーバーが完了したことを確認
binlogポジションが前進しているが、エラー無し。
mysql> SHOW REPLICA STATUS\G
*************************** 1. row ***************************
Replica_IO_State: Waiting for source to send event
.....
Source_Log_File: mysql-bin-changelog.000024
Read_Source_Log_Pos: 197
.....
Last_Errno: 0
Last_Error:
.....
Source側でデータをインサートする
→ 問題なくTarget側にレプリケーションされることを確認
binlogポジションが前進していることを確認
mysql> SHOW REPLICA STATUS\G
*************************** 1. row ***************************
Replica_IO_State: Waiting for source to send event
.....
Source_Log_File: mysql-bin-changelog.000024
Read_Source_Log_Pos: 599
.....
Last_Errno: 0
Last_Error:
.....
参考
-
Aurora(RDS)クラスターでのWriter/Readerインスタンスのbinlogファイルの一貫性について筆者は確認できていません ↩