Amazon RDS for MySQL のレプリカの遅延が大きい場合はどのように解決すればよいですか?

最終更新日: 2021 年 4 月 6 日

Amazon Relational Database Service (Amazon RDS) for MySQL を使用する際のレプリカの遅延の原因を特定しようとしています。その方法を教えてください。

簡単な説明

Amazon RDS for MySQL は、非同期レプリケーションを使用します。これは、レプリカがプライマリ DB インスタンスに追いつかないことがあることを意味しています。その結果、レプリケーションの遅延が発生する可能性があります。

Amazon RDS for MySQL リードレプリカをバイナリログファイルの位置ベースのレプリケーションで使用する場合、レプリケーションの遅延を監視できます。Amazon CloudWatch で、Amazon RDS の ReplicaLag メトリクスを確認します。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 インスタンスで SHOW 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 コマンドを実行し、出力を確認します:

例 1:

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

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

例 2:

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

例 2 は、プライマリインスタンスのログファイルが mysql-bin-changelog.066552 であることを示しています。出力は、IO_THREAD がプライマリ DB インスタンスに追いついていることを示しています。レプリカ出力では、SQL スレッドは Relay_Master_Log_File: mysql-bin-changelog.066530 を実行しています。その結果、SQL_THREAD は 22 バイナリログだけ遅れています。

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

レプリカ SQL_THREAD がレプリケーション遅延の原因である場合、これらの遅延は次の原因で発生している可能性があります。

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

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

レプリカ DB インスタンスでの実行と同程度の時間を要するプライマリ DB インスタンスで長時間実行されるクエリは、seconds_behind_master を増やすことができます。例えば、プライマリインスタンスで変更を開始し、実行に 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 に設定されている

プライマリ DB インスタンスで binlog_format を ROW に設定し、ソーステーブルにプライマリキーがない場合、SQL スレッドはレプリカで表のフルスキャンを実行します。これは、パラメータ slave_rows_search_algorithms のデフォルト値が TABLE_SCAN,INDEX_SCAN であるためです。この問題を短期的に解決するには、検索アルゴリズムを INDEX_SCAN,HASH_SCAN に変更して、表のフルスキャンのオーバーヘッドを減らします。長期的には、各テーブルに明示的なプライマリキーを追加するのがベストプラクティスです。

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

レプリカ作成の遅延

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

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

スナップショットからリードレプリカを復元する場合、レプリカは、ソースからすべてのデータが転送されるのを待機しません。レプリカ DB インスタンスは、DB オペレーションを実行するために利用できます。新しいボリュームは、既存の Amazon Elastic Block Store (Amazon EBS) スナップショットロードからバックグラウンドで作成されます。

注: Amazon RDS for MySQL レプリカ (EBS ベースのボリューム) の場合、遅延ロード効果がレプリケーションのパフォーマンスに影響を及ぼす可能性があるため、当初はレプリカの遅延が増加する可能性があります。

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


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


請求に関するサポートまたは技術的なサポートが必要ですか?