Amazon Web Services ブログ

Amazon RDS for MySQL、Amazon RDS for MariaDB、Aurora MySQL におけるマルチスレッドレプリケーションのモニタリング

本記事は 2025 年 10 月 21 日 に公開された「Monitoring multithreaded replication in Amazon RDS for MySQL, Amazon RDS for MariaDB, and Aurora MySQL」を翻訳したものです。

前回の記事では、MySQL のレプリケーションとマルチスレッドレプリケーション (MTR) の仕組み、主要な設定オプション、ベストプラクティスについて解説しました。本記事では、Amazon Aurora MySQL、Amazon Relational Database Service (Amazon RDS) for MySQL、Amazon RDS for MariaDB における並列レプリケーションのパフォーマンスを効果的にモニタリングし、関連パラメータをチューニングする方法を説明します。

MySQL が提供する MTR のモニタリング手法をいくつか紹介します。

SHOW REPLICA STATUS

SHOW REPLICA STATUS は MTR のモニタリングやトラブルシューティングの最初のステップとして有用です。特にレプリケーションが失敗して停止した場合に有用です。レプリカインスタンスで実行します。各フィールドの意味と解釈については、AWS Knowledge Center の How do I troubleshoot high replica lag with Amazon RDS for MySQL? と MySQL ドキュメントの SHOW REPLICA STATUS Statement を参照してください。

mysql> SHOW REPLICA STATUS\G
*************************** 1. row ***************************
             Replica_IO_State: Waiting for source to send event
              Source_Log_File: mysql-bin-changelog.002961
          Read_Source_Log_Pos: 10799580
               Relay_Log_File: relaylog.008193
                Relay_Log_Pos: 26644679
        Relay_Source_Log_File: mysql-bin-changelog.002737
           Replica_IO_Running: Yes
          Replica_SQL_Running: Yes
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Source_Log_Pos: 26644443
              Relay_Log_Space: 29257792087
        Seconds_Behind_Source: 5203
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
    Replica_SQL_Running_State: Waiting for replica workers to process their queues
           Source_Retry_Count: 86400

MTR ではシングルスレッドレプリケーションと比べ、一部のフィールドの意味が若干異なります。

  • Seconds_Behind_Source はマルチスレッドレプリケーションでも有効かつ正確ですが、Exec_Source_Log_Pos に基づいているため、最後にコミットされたトランザクションの位置を反映していない場合がある点に注意してください。
    • ターゲットデータベースへの切り替えを伴う操作を行う場合、Seconds_Behind_Source や、RDS for MySQL / RDS for MariaDB の Amazon CloudWatch メトリクス ReplicaLag、Aurora MySQL の AuroraBinlogReplicaLag に依存すべきではありません。Amazon RDS Blue/Green Deployments の使用を推奨します。Blue/Green Deployments は最小限のダウンタイムで切り替えプロセスを自動化するだけでなく、組み込みのセーフガードにより、切り替え前にレプリカ (Green) 環境がソース (Blue) と完全に同期済みであることを確認します。
  • Last_SQL_Errno と Last_SQL_Error はコーディネータスレッドのエラーのみを表示し、ワーカースレッドのエラーは含みません。ワーカースレッドのエラーは、各ワーカースレッドのステータスを表示する replication_applier_status_by_worker テーブルで確認できます。利用できない場合は、レプリカのエラーログを使用してください。SHOW REPLICA STATUS やコーディネータテーブルに表示されるエラーの詳細を調べる際にも、エラーログまたは replication_applier_status_by_worker テーブルを活用してください。
  • MTR における Replica_SQL_Running_State フィールドの一般的な状態には、'Waiting for dependent transaction to commit' や 'Waiting for preceding transaction to be committed' があります。どちらもワーカースレッドが依存するトランザクションの完了を待っていることを示す正常な状態です。ただし、頻繁に表示される場合は、レプリケーションの並列性やパフォーマンスを向上させるため、ソース側のワークロードのチューニング(大きなトランザクションの分割など)を検討してください。binlog_transaction_dependency_tracking を WRITESET に設定すると、依存関係を大幅に削減できます。ベストプラクティスについては Overview and best practices of multithreaded replication in Amazon RDS for MySQL, Amazon RDS for MariaDB, and Amazon Aurora MySQL を参照してください。

Performance Schema テーブル

MySQL は SHOW REPLICA STATUS よりも詳細なレベルでレプリケーションをモニタリングするために、Performance Schema テーブル群を提供しており、使用を推奨します。MTR モニタリングに有用なテーブルは次の 3 つです。

  • replication_connection_status
  • replication_applier_status_by_coordinator
  • replication_applier_status_by_worker

各テーブルにデータが正しく格納されるよう、Performance Schema を有効化しておくことを推奨します。

replication_connection_status テーブルには、レプリカからソースへの接続を処理する I/O スレッドの現在のステータス、リレーログにキューイングされた最後のトランザクション、および現在キューイング中のトランザクションの情報が格納されます。

replication_applier_status_by_coordinator テーブルには、コーディネータスレッドのステータスが格納されます。具体的には、コーディネータスレッドがワーカーのキューにバッファリングした最後のトランザクションと、現在バッファリング中のトランザクションの情報です。開始タイムスタンプは、コーディネータスレッドがリレーログからトランザクションの最初のイベントを読み取ってワーカーのキューにバッファリングを開始した時刻を、終了タイムスタンプは最後のイベントのバッファリングが完了した時刻を示します。

replication_applier_status_by_worker テーブルは最も重要なテーブルです。ワーカースレッドのステータスを表示します。レプリケーションが失敗して停止した場合、LAST_ERROR_NUMBER と LAST_ERROR_MESSAGE カラムが原因の特定に役立ちます。エラー番号 0 とメッセージが空文字の場合は「エラーなし」を意味します。LAST_ERROR_MESSAGE の値が空でない場合、エラーの値はレプリカのエラーログにも出力されます。以下に例を示します。

LAST_ERROR_NUMBER: 1062
LAST_ERROR_MESSAGE: "Error 'Duplicate entry '123' for key 'PRIMARY''
on query 'INSERT INTO customers(id, name) VALUES (123, 'John')'

カスタムビュー

Performance Schema テーブルには生データが格納されており、実用的な知見を得るのは容易ではありません。現状、MTR ラグの測定や MTR の利用率・有効性を評価するためにこのテーブルをクエリする業界標準やベストプラクティスは確立されていません。データをより活用しやすくするため、カスタムビューの作成を推奨します。以下のビューは、MySQL レプリケーションのワーカースレッドに関する詳細な統計情報(現在のアクティビティ、タイミング情報、エラーステータスなど)を表示する例です。長時間実行中のレプリカトランザクション、未使用のワーカー、レプリケーションエラーの特定に役立ちます。本番環境に導入する前に十分にテストしてください。

CREATE OR REPLACE
  ALGORITHM = MERGE
  SQL SECURITY INVOKER 
VIEW binlog_replication_worker_stats AS
SELECT 
  COALESCE(NULLIF(CHANNEL_NAME, ''), 'default') as channel,
  WORKER_ID as worker_num,
  THREAD_ID as thread_id,
  APPLYING_TRANSACTION_START_APPLY_TIMESTAMP != '0000-00-00 00:00:00.000000' as active,
  CASE 
    WHEN APPLYING_TRANSACTION_START_APPLY_TIMESTAMP != '0000-00-00 00:00:00.000000'
    THEN sys.format_time(GREATEST(0, TIMESTAMPDIFF(MICROSECOND, 
         APPLYING_TRANSACTION_START_APPLY_TIMESTAMP, NOW(6))) * 1000000)
    ELSE NULL
  END as time_applying_current_trx,
  CASE 
    WHEN LAST_APPLIED_TRANSACTION_START_APPLY_TIMESTAMP != '0000-00-00 00:00:00.000000'
    THEN sys.format_time(GREATEST(0, TIMESTAMPDIFF(MICROSECOND, 
         LAST_APPLIED_TRANSACTION_START_APPLY_TIMESTAMP,
         LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP)) * 1000000)
    ELSE NULL
  END as time_applying_last_trx,
  CASE 
    WHEN LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP != '0000-00-00 00:00:00.000000'
    THEN LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP
    ELSE NULL
  END as last_active,
  SERVICE_STATE as worker_state,
  LAST_ERROR_NUMBER as last_error_code,
  LAST_ERROR_MESSAGE as last_error_message
FROM 
  performance_schema.replication_applier_status_by_worker
ORDER BY 
  channel,
  worker_num;

ビューの各カラムの意味は次のとおりです。

カラム名 説明
channel レプリケーションチャネル名(名前のないチャネルは default)。
worker_num ワーカースレッド番号(performance_schema の worker_id)。
thread_id ワーカーの MySQL スレッド ID。
active ワーカーが現在トランザクションを適用中かどうか(1=はい、0=いいえ)。
time_applying_current_trx 現在のトランザクションの適用にかかっている時間(アクティブな場合)。
time_applying_last_trx 最後のトランザクションの適用にかかった時間。
last_active 最後のトランザクションが終了したタイムスタンプ。
worker_state ワーカースレッドの現在の状態(ON/OFF)。
last_error_code 最後のエラー番号(エラーがなければ 0)。
last_error_message 最後のエラーメッセージ(エラーがなければ空)。

以下はビューをクエリした場合のサンプル出力です。

mysql> select * from binlog_replication_worker_stats;
+---------+------------+-----------+--------+---------------------------+------------------------+----------------------------+--------------+-----------------+--------------------+
| channel | worker_num | thread_id | active | time_applying_current_trx | time_applying_last_trx | last_active                | worker_state | last_error_code | last_error_message |
+---------+------------+-----------+--------+---------------------------+------------------------+----------------------------+--------------+-----------------+--------------------+
| default |          1 |        46 |      1 | 930 us                    | 1.62 ms                | 2025-04-09 18:24:21.130941 | ON           |               0 |                    |
| default |          2 |        47 |      1 | 1.78 ms                   | 3.6 ms                 | 2025-04-09 18:24:21.130124 | ON           |               0 |                    |
| default |          3 |        48 |      1 | 1.7 ms                    | 2.47 ms                | 2025-04-09 18:24:21.130132 | ON           |               0 |                    |
| default |          4 |        49 |      1 | 7 us                      | 2.18 ms                | 2025-04-09 18:24:21.131854 | ON           |               0 |                    |
+---------+------------+-----------+--------+---------------------------+------------------------+----------------------------+--------------+-----------------+--------------------+
4 rows in set (0.01 sec

Active カラムについて:理想的には、すべてのスレッドがアクティブであることを確認します。全スレッドがアクティブであれば、並列処理がうまく機能している証拠です。ワーカーのアクティビティに大きな差がある場合、次のような問題を示している可能性があります。

  • 依存関係の競合により、イベントが順次処理されている
  • インデックスの欠如によりトランザクションの処理に時間がかかっている
  • 複数のプロセスが同じロックを待機しているためトランザクションが遅延している
  • DDL 操作が適用されている

time_applying_current_trx(および time_applying_last_trx)は、長時間実行されているトランザクションの特定に役立ちます。長時間実行トランザクションは、replica_pending_jobs_size_max の説明にあるように、レプリカでレプリケーションの直列化を引き起こす可能性があります(詳細は Overview and best practices of multithreaded replication in Amazon RDS for MySQL, Amazon RDS for MariaDB, and Amazon Aurora MySQL を参照)。直列化が起きると、time_applying_current_trx の値が高いアクティブなスレッドが 1 つだけになっていることがあります。

すべての問題を解決した後も、last_active カラムに示されるように多くのワーカースレッドが長時間非アクティブな状態が頻繁に発生する場合は、replica_parallel_workers パラメータの値を下げることを検討してください。逆に、すべてのワーカースレッドが常にビジーまたはアクティブな状態であれば、replica_parallel_workers を増やすと改善する可能性があります。

エンジンエラーログ

log_error_verbosity を 3 に設定すると、MTR のログメッセージが利用できるようになります。Aurora MySQL ではこの設定がデフォルトで有効ですが、RDS for MySQL と RDS for MariaDB ではパラメータグループの値を変更する必要があります。有効にすると、レプリカのコーディネータスレッドが統計情報を定期的にエラーログに書き出し、イベントがワーカースレッド間でどのように分配されているかを確認できます。ログエントリの出力頻度は処理されるイベントの量に依存しますが、最短でも 120 秒に 1 回までです。以下はエラーログの出力例です。

2025-07-09T12:26:21.017757Z 2892166 [Note] [MY-010559] [Repl] Multi-threaded slave statistics for channel '': seconds elapsed = 120; events assigned = 2276626433; worker queues filled over overrun level = 0; waited due a Worker queue full = 0; waited due the total size = 0; waited at clock conflicts = 171233788281300 waited (count) when Workers occupied = 6460064 waited when Workers occupied = 151556259200 (rpl_replica.cc:4978), 

2025-07-09T12:28:33.805410Z 2892166 [Note] [MY-010559] [Repl] Multi-threaded slave statistics for channel '': seconds elapsed = 132; events assigned = 2276672513; worker queues filled over overrun level = 0; waited due a Worker queue full = 0; waited due the total size = 0; waited at clock conflicts = 171234310046600 waited (count) when Workers occupied = 6460064 waited when Workers occupied = 151556259200 (rpl_replica.cc:4978)

各フィールドの説明は、MySQL ドキュメントの Monitoring Replication Applier Worker Threads を参照してください。長期保存のためにログを CloudWatch Logs に発行し、CloudWatch Logs Insights でログの解釈や経時変化の比較を行うことを推奨します。詳細は CloudWatch Logs Insights のクエリ構文を参照してください。

waited due the total size は理想的にはゼロであるべきです。ゼロ以外で、特にレプリカラグが発生しているサンプル間で増加している場合は、大きなトランザクションがないか確認してください。大きなトランザクションがない場合は、replica_pending_jobs_size_max パラメータの値を増やすことを検討してください。Waited (count) when workers occupied はできるだけ低い値であるべきです。サンプル間で大きな変化がある場合は、replica_parallel_workers の増加を検討してください。

Waited at clock conflicts は、トランザクション/イベントの依存関係を示しており、あるトランザクション/イベントが適用前に別のトランザクションの完了を待つ必要があったことを意味します。ほとんどの場合、この値が高く増加し続けるのは正常です。トランザクションの依存関係を減らしてレプリケーションの並列性を高めるには、本ブログ記事シリーズのパート 1 で紹介したベストプラクティスに従ってください。具体的には、binlog_transaction_dependency_tracking を WRITESET に、replica_parallel_type を LOGICAL_CLOCK に設定します。データの整合性の観点から、特にコミット順序に依存するアプリケーションでは、replica_preserve_commit_order を無効にすることは推奨しません。

まとめ

本記事では、SHOW REPLICA STATUS、Performance Schema テーブル、エラーログ、Amazon が提供するカスタムビューなどのツールを使用した MySQL マルチスレッドレプリケーションのモニタリングとチューニングについて解説しました。マルチスレッドレプリケーションの効果的なモニタリングは、レプリケーションパフォーマンスの最適化に重要です。チューニングは反復的なプロセスです。まず控えめなパラメータ調整から始め、効果を注意深くモニタリングしましょう。定期的なパフォーマンス監査と予防的な最適化により、データの整合性が向上しレイテンシを最小化できます。Aurora MySQL、RDS for MySQL、RDS for MariaDB のレプリケーションの詳細については、次のリソースを参照してください。

ご意見やご感想がありましたら、コメント欄にお寄せください。

著者について

Huy Nguyen

Huy Nguyen

Huy は、AWS サポートのシニアエンジニア。Amazon RDS と Amazon Aurora を専門とし、お客様が AWS クラウドでスケーラブルで高可用性かつセキュアなソリューションを構築できるよう、ガイダンスと技術支援を提供しています。

Arun Gadila

Arun Gadila

Arun は、AWS の Cloud Support Database Engineer II。3.5 年以上の経験を持ち、RDS for MySQL、Aurora MySQL、RDS for SQL Server を専門としています。RDS MySQL と Aurora MySQL の両方で Subject Matter Expert (SME) として認められ、深い技術知識を活かしてお客様のデータベース環境の最適化と複雑な課題の解決を支援しています。

Marc Reilly

Marc Reilly

Marc は、Amazon Aurora MySQL チームのシニアデータベースエンジニア。


この記事は、Solutions Architect の Shinya Sugiyama が翻訳を担当しました。