🐬

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公式ドキュメントでは段階を分けて変更するよう書いてある。)

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公式ドキュメントでは段階を分けて変更するよう書いてある。)

3.RDS側のリードレプリカを作成する。

RDS for MySQLではExecutedGTIDとデータの状態が一致したDumpを取得するために、リードレプリカの作成が必要です。
RDS側でリードレプリカを作成してください。
このリードレプリカはダンプの取得元として利用します。

4.ソース(RDS for MySQL)からのスナップショット取得

  1. 作成したリードレプリカに接続し、以下のコマンドを実行してレプリケーションを一時的に停止させる。

    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>
    
  2. リードレプリカに対して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
    
  3. リードレプリカの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)

  1. Auroraクラスターのライターインスタンスエンドポイントに接続します。
  2. 以下のストアドプロシージャを実行し、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)

  1. RDS for MySQLインスタンスに接続します。
  2. ストアドプロシージャを実行し、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セット

https://dev.mysql.com/doc/refman/8.4/en/replication-administration-status.html?utm_source=chatgpt.com

注意点・補足

参考

https://repost.aws/knowledge-center/mysqldump-error-rds-mysql-mariadb

https://server-setting.info/centos/mysql_replication_1236_error.html

https://repost.aws/knowledge-center/mysqldump-error-rds-mysql-mariadb

https://aws.amazon.com/jp/blogs/news/migrating-to-amazon-aurora-mysql-with-fallback-option-using-gtid-based-replication/

https://repost.aws/questions/QU-9uYWmURRFm7HUkb5V148g/replication-external-mysql-to-aurora-mysql-replication-filters

Discussion