Amazon RDS for MySQLのレプリケーションで遅延が発生しているかどうかを確認する方法

Amazon RDS for MySQLバージョン5.x系において、レプリケーションを利用している場合に発生する同期のラグや遅延の状況を確認する方法を記載しました。大まかな情報はAWSマネジメントコンソールやAmazon CloudWatchからメトリクスを確認することも可能ですが、実は正確ではない可能性があります。詳細な情報を調査するための方法をまとめました。
2021.03.29

コンサル部のtobachi(@toda_kk)です。

Amazon RDS for MySQLでは起動中のインスタンスからリードレプリカを作成することで、簡単にレプリケーションを設定することができます。

プライマリのインスタンスへの書き込み処理が頻繁に実行される場合、どうしてもレプリケーションにラグや遅延が発生してしまいます。パフォーマンスチューニングやトラブルシューティングの際には、レプリケーションがどれくらい遅れているのかを調べたいケースもあるかと思います。

そこで、レプリケーションのラグ・遅延時間がどの程度発生しているのか調べる方法をまとめました。

注意

本記事は、RDS for MySQLのバージョン5.x系に関するものです。実際に検証したメジャーバージョンは 5.5、5.6、5.7 です。

MySQL 8系など他のバージョンに関しては本記事の内容が当てはまらない可能性がありますので、ご注意ください。

大まかな遅延状況を簡単に調べたい場合

MySQLに限りませんが、RDSでリードレプリカインスタンスを作成している場合、Amazon CloudWatchからReplicaLagのメトリクスを参照することで、レプリケーションの遅延時間を確認することができます。

ただし、MySQLの場合は注意が必要です。AWSの公式ドキュメントを参照すると、下記の記述があります。

You can monitor replication lag in Amazon CloudWatch by viewing the Amazon RDS ReplicaLag metric.

For MySQL and MariaDB, the ReplicaLag metric reports the value of the Seconds_Behind_Master field of the SHOW SLAVE STATUS command.

MySQLの場合、このReplicaLagメトリクスはMySQLの場合Seconds_Behind_Masterという値を参照しています。しかしMySQLの公式ドキュメントによれば、この値は必ずしも正確ではない可能性があるようです。

A value of 0 for Seconds_Behind_Master can usually be interpreted as meaning that the replica has caught up with the source, but there are some cases where this is not strictly true. For example, this can occur if the network connection between source and replica is broken but the replication I/O thread has not yet noticed this—that is, slave_net_timeout has not yet elapsed.

大まかな遅延時間を調べたい場合は、CloudWarchで上記メトリクスを確認すれば問題なさそうです。ただし、より正確な情報を確認したい場合は別の方法をとる必要があります。

詳細な遅延情報を調べたい場合

レプリケーションの遅延に関する調査方法は、AWSの公式ドキュメントでもまとめられています。ただ、MySQLのレプリケーションの仕組みを把握していないと、ドキュメントを読んでもわかりづらいところがありました。

そこで、MySQLにおけるレプリケーションの仕組みを少しだけ紐解いてみます。

MySQLにおけるレプリケーションの仕組み

MySQLでは、プライマリインスタンスが出力するバイナリログを利用することでレプリケーションを実現しています。

レプリカインスタンスではこのバイナリログを読み込み、バイナリログの内容に基づいて同期を実行します。これはそれぞれ独立したスレッドとして実行されます。

  • Binlogダンプスレッド: バイナリログを出力するスレッド(プライマリインスタンスで実行)
  • スレーブI/Oスレッド: バイナリログを読み込むスレッド(レプリカインスタンスで実行)
  • スレーブSQLスレッド: 同期を実行するスレッド(レプリカインスタンスで実行)

レプリケーションの状況を確認する

上記ドキュメントの通り、プライマリインスタンスでSHOW MASTER STATUSコマンドを実行すると下記のように出力されます。

mysql> SHOW MASTER STATUS;
+----------------------------+----------+--------------+------------------+-------------------+
| File                       | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------------+----------+--------------+------------------+-------------------+
| mysql-bin-changelog.066552|      521 |              |                  |                   |
+----------------------------+----------+--------------+------------------+-------------------+

Fileとして出力された値が、バイナリログのファイルを示しています。

また、レプリカインスタンスでSHOW SLAVE STATUSコマンドを実行すると下記のように出力されます。

mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Master_Log_File: mysql-bin.066552
Read_Master_Log_Pos: 430
Relay_Master_Log_File: mysql-bin.066530
Exec_Master_Log_Pos: 50360
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

Master_Log_Fileの値はレプリカが読み込み中のバイナリログであり、同期を実行中のバイナリログがRelay_Master_Log_Fileの値となります。

そのため、ここであげた3つの値 File Master_Log_File Relay_Master_Log_File を比較することでより詳細なレプリケーションの遅延状況を確認することができます。

3つの値が一致している場合は、レプリケーションに遅延が発生していないということになります。

RDS for MySQLのレプリケーションに関する参考ドキュメント

以上、コンサル部のtobachi(@toda_kk)でした。