Amazon RDS for MySQL のレプリカの高遅延の場合はどのように解決できますか?

最終更新日: 2020 年 8 月 21 日

Amazon Relational Database Service (Amazon RDS) for MySQL を使用時に、レプリカの遅延の原因を特定するにはどうすればよいですか ?

簡単な説明

Amazon RDS for MySQL は非同期レプリケーションを使用するため、レプリカがプライマリ DB インスタンスに追いつかない場合があります。これにより、レプリケーションの遅延が発生する可能性があります。

バイナリログファイルの位置ベースのレプリケーションで Amazon RDS for MySQL リードレプリカを使用する場合、Amazon RDS ReplicaLag メトリクスを参照することで、Amazon CloudWatch でレプリケーションの遅延をモニタリングできます。ReplicaLag メトリックは、SHOW SLAVE STATUS コマンドの Seconds_Behind_Master フィールドの値を報告します。

Seconds_Behind_Master では、レプリカ DB インスタンスの現在のタイムスタンプと、レプリカ DB インスタンスで処理されているイベントについてプライマリ DB インスタンスに記録された元のタイムスタンプとの差を示します。

MySQL レプリケーションは、3 つのスレッド (Binlog Dump スレッド、IO_THREAD、およびSQL_THREAD) で動作します。これらのスレッドの機能に関する詳細は、MySQL ドキュメントの「レプリケーション実装ガイド」をご参照ください。レプリケーションに遅延がある場合は、まずレプリカ IO_THREAD とレプリカ SQL_THREAD のどちらによる遅延なのかを特定します。その結果、遅延の根本原因を特定することができます。

解決方法

どのレプリケーションスレッドの遅延によるものかを特定するには、次の例を参照してください :

1.    まず、プライマリ DB インスタンスで MASTER STATUS コマンドを実行し、出力を確認します :

mysql> SHOW MASTER STATUS;
+----------------------------+----------+--------------+------------------+-------------------+
| File                       | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------------+----------+--------------+------------------+-------------------+
| mysql-bin-changelog.066552|      521 |              |                  |                   |
+----------------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

注 : 出力例では、マスター DB インスタンスが mysql-bin.066552 ファイルにバイナリログを書き込んでいます。

2.    レプリカ DB インスタンスで SHOW SLAVE STATUS コマンドを実行し、出力を確認します :

出力例 A:

mysql> SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
Master_Log_File: mysql-bin.066548
Read_Master_Log_Pos: 10050480
Relay_Master_Log_File: mysql-bin.066548
Exec_Master_Log_Pos: 10050300
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

出力例 A では、Master_Log_File:mysql-bin.066548 で、レプリカ IO_THREAD がバイナリログファイル mysql-bin.066548 からの読み込みを示しています。これは、プライマリ DB インスタンスがバイナリログをファイル mysql-bin.066552 に書き込むためです。この出力は、レプリカ IO_THREAD4 バイナリログ (binlog) だけ遅れていることを示しています。ただし、Relay_Master_Log_Filemysql-bin.066548 であり、 これはレプリカ SQL_THREADIO_THREAD と同様のファイルから読み取っていることを示しています。これは、レプリカ SQL_THREAD は追いついているが、レプリカ IO_THREAD が遅れていることを意味します。

出力例 B:

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

出力例 B では、マスターログファイルが mysql-bin-changelog.066552です。これは、マスターステータスからのファイルパラメータでもあり、IO_THREAD がプライマリ DB インスタンスに追いつくことを意味します。レプリカ出力では、SQL スレッドはRelay_Master_Log_File:mysql-bin-changelog.066530 を実行しています。これは、SQL_THREAD12 のバイナリログだけ遅れることを意味します。

通常、IO_THREAD はマスターからのみバイナリログを読み取るため、IO_THREAD はラージレプリケーション遅延を引き起こしません。ただし、ネットワーク接続性とネットワークレイテンシは、サーバー間の読み取り速度に影響を与える可能性があります。高帯域幅使用が原因で、レプリカ IO_THREAD が遅くなる可能性があります。

レプリカ SQL_THREAD がレプリケーション遅延の原因となっている場合、これらの遅延には次のような原因が考えられます :

  • プライマリ DB インスタンスで長時間実行されるクエリ
  • DB インスタンスクラスのサイズまたはストレージの不足
  • プライマリ DB インスタンスで実行される並列クエリ
  • レプリカ DB インスタンス上のディスクに同期されたバイナリログ
  • レプリカの Binlog_format が [ROW] に設定されています
  • レプリカ作成の遅延

プライマリインスタンスで長時間実行されるクエリ

レプリカ DB インスタンスでの実行と同程度の時間を要するプライマリ DB インスタンスで長時間実行されるクエリは、seconds_behind_master を増やすことが可能です。例えば、プライマリ DB インスタンスで開始した変更が実行までに 1 時間かかる場合、その変更がレプリカで実行されるまでにも 1 時間かかります。変更がレプリカで完了するのに 1 時間かかる可能性があるため、その変更が完了するまでに全体の遅延はおよそ 2 時間です。これは見込まれた遅延ですが、マスター上のスロークエリログを監視することによって、この遅延を最小とすることができます。遅延を減らすために、長期実行されるステートメントを識別することもできます。そして、長時間実行されるステートメントを小さなステートメントまたはトランザクションに分割します。詳細については、「 MySQL のスロークエリと一般ログにアクセスする」をご参照ください。

DB インスタンスクラスのサイズまたはストレージの不足

レプリカ DB インスタンスのクラスまたはストレージ設定がプライマリよりも小さい場合、レプリカは調整されプライマリで行われた変更に追いつくことができません。レプリカの DB インスタンスタイプがプライマリ DB インスタンス以上であることを確認してください。レプリケーションが効率的に機能するには、各リードレプリカにソース DB インスタンスと同量の計算リソースおよびストレージリソースが必要です。詳細については、「DB インスタンスのクラス」をご参照ください。

プライマリ DB インスタンスで実行される並列クエリ

プライマリで並列にクエリを実行すると、レプリカでシリアル順序でコミットされます。これは、MySQL レプリケーションがデフォルトでシングルスレッド (SQL_THREAD) であるためです。ソース DB インスタンスへの大量の書き込みが並列して発生する可能性がある場合、リードレプリカへの書き込みは単一の SQL_THREAD を使用してシリアル化されます。これにより、ソース DB インスタンスおよびリードレプリカ間に遅延が生じる可能性があります。

マルチスレッド (パラレル) レプリケーションは MySQL 5.6 、MySQL 5.7 、およびそれ以降のバージョンで利用可能です。マルチスレッドレプリケーションに関する詳細については、MySQL ドキュメントの「バイナリログオプションと変数」をご参照ください。

マルチスレッドレプリケーションはレプリケーションのズレが生じる可能性があります。例えば、レプリケーションエラーをスキップする場合、スキップするトランザクションの特定が困難なため、マルチスレッドレプリケーションは推奨されません。これにより、プライマリインスタンスとレプリカ DB インスタンス間でデータの整合性にズレが生じる可能性があります。

レプリカ DB インスタンス上のディスクに同期されたバイナリログ

自動バックアップがレプリカ上で有効となっている場合、バイナリログをレプリカ上のディスクに同期する追加作業が必要になることがあります。パラメータ sync_binlog のデフォルト値は 1 に設定されます。この値を 0 に変更すると、MySQL サーバーによるバイナリログのディスクへの同期も無効になります。オペレーティングシステム (OS) は、ディスクにログを記録する代わりに、バイナリログをディスクにフラッシュすることがあります。

バイナリログの同期を無効にすると、コミットごとにバイナリログをディスクに同期するために発生するパフォーマンスオーバーヘッドを減らすことができます。しかし、停電の発生や OS のクラッシュにより、コミットの一部がバイナリログと同期されないことがあります。このことがポイントインタイムリストア (PITR) に影響を与える可能性があります。詳細については、MySQL ドキュメントの「sync_binlog」をご参照ください。

レプリカの Binlog_format が [ROW] に設定されている

レプリカの binlog_format が [ ROW] に設定され、更新されるテーブルに主キーがない場合は、デフォルトで slave-rows-search-algorithms=TABLE_SCAN,INDEX_SCAN がプライマリで変更されたすべての行に対して実行されます。また、このパラメータはレプリカに対してフルテーブルスキャンも実行します。この場合、短期的な解決策は、検索アルゴリズムを INDEX_SCAN,HASH_SCAN に変更して、テーブル全体のスキャンのオーバーヘッドを減らすことです。永続的なソリューションの場合、各テーブルに明示的なプライマリキーを追加します。

slave-rows-search-algorithm パラメーターについての詳細は、MySQL ドキュメントの「slave-rows-search-algorithms」をご参照ください。

レプリカ作成の遅延

Amazon RDS は、マスターの DB スナップショットを作成して、MySQL マスターのリードレプリカを作成します。そして、Amazon RDS はスナップショットを復元して新しい DB インスタンス (レプリカ) を作成し、2 つの間でレプリケーションを確立します。

Amazon RDS では、新しいリードレプリカの作成に時間がかかります。レプリケーションが確立されると、プライマリのバックアップを作成するのにかかる時間に遅延があります。この遅延を最小限とするために、レプリカの作成要求の前に手動でバックアップを作成してください。そして、レプリカの作成プロセスで作成されたスナップショットはより高速な増分バックアップです。

リードレプリカをスナップショットから復元すると、レプリカはすべてのデータが Amazon Simple Storage Service (Amazon S3) からレプリカ DB インスタンスに関連付けられている Amazon Elastic Block Store (Amazon EBS) ボリュームに転送されるのを待つ必要はありません。レプリカ DB インスタンスは DB 操作の実行に使用でき、既存の EBS スナップショットから作成された新しいボリュームはバックグラウンドでロードされます (遅延ロード)。

Amazon RDS for MySQL レプリカ (EBS ベースのボリューム) の場合、負荷の影響によりレプリケーションのパフォーマンスが低下する可能性があるため、レプリカの遅延が最初に増加する可能性があります。詳細については、「Amazon EBS ボリュームの初期化」をご参照ください。

InnoDB キャッシュウォームアップ機能を有効にすることを検討してください。マスター DB インスタンスのバッファプールの現在の状態を保存し、復元されたリードレプリカでバッファプールを再ロードすることで、パフォーマンスが向上します。InnoDB キャッシュウォームアップの詳細については、 「Amazon RDS での MySQL」をご参照ください。


この記事はお役に立ちましたか?


請求または技術面でのサポートが必要ですか?