Amazon RDS for MySQL でレプリカラグが大きい場合のトラブルシューティング方法を教えてください。

所要時間3分
0

MySQL 用の Amazon Relational Database Service (Amazon RDS) を使用する際のレプリカラグの原因を調べたいと考えています。

短い説明

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 レプリケーションは、Binlog Dump スレッド、IO_THREADSQL_THREAD の 3 つのスレッドで動作します。これらのスレッドがどのように機能するかについての詳細は、レプリケーションスレッドに関する 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 バイナリログ遅れていることを示しています。ただし、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_ 形式が ROW に設定されています
  • レプリカ作成ラグ

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

プライマリ DB インスタンスで長時間実行されるクエリが、レプリカ DB インスタンスで実行するのと同じ時間がかかる場合、seconds_behind_master が増える可能性があります。たとえば、プライマリインスタンスで変更を開始し、実行に 1 時間かかる場合、遅延は 1 時間です。レプリカでも変更が完了するまでに 1 時間かかる場合、完了時の合計遅延は約 2 時間です。これは予想される遅延ですが、プライマリインスタンスのスロークエリログを監視してこの遅延を最小限に抑えることができます。また、実行時間の長いステートメントを特定して遅延を減らすこともできます。さらに、実行時間の長いステートメントを小さなステートメントまたはトランザクションに分割します。

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

レプリカ DB インスタンスクラスまたはストレージ構成がプライマリよりも低い場合、リソースが不足しているためにレプリカがスロットリングする可能性があります。これは、レプリカがプライマリインスタンスに加えられた変更に対応できないためです。レプリカの DB インスタンスタイプがプライマリ DB インスタンスと同じかそれ以上であることを確認してください。レプリケーションを効果的に機能させるには、各リードレプリカにソース DB インスタンスと同じ量のコンピューティングリソースとストレージリソースが必要です。詳細については、「DB インスタンスクラス」を参照してください。

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

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

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

マルチスレッドレプリケーションは、レプリケーションにギャップが生じる可能性があります。たとえば、マルチスレッドレプリケーションは、どのトランザクションをスキップするのかを特定するのが難しいため、レプリケーションエラーをスキップする場合にはお勧めできません。マルチスレッドレプリケーションにより、プライマリ DB インスタンスとレプリカ DB インスタンスの間でデータの一貫性にギャップが生じる可能性があります。

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

レプリカで自動バックアップを有効にすると、バイナリログをレプリカ上のディスクに同期するためのオーバーヘッドが発生する可能性があります。sync_binlog パラメータのデフォルト値は 1 に設定されています。この値を 0 に変更すると、MySQL サーバーによるバイナリログのディスクへの同期もオフになります。オペレーティングシステム (OS) は、ディスクにロギングする代わりに、バイナリログをディスクにフラッシュすることがあります。

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

Binlog_format は ROW に設定されています

SQL スレッドは、次の 2 つの条件が満たされる場合にレプリカに対してフルテーブルスキャンを実行してください。

  • プライマリ DB インスタンスの binlog_formatROW に設定されています。
  • ソーステーブルにプライマリキーがありません。

これは、パラメータ slave_rows_search_algorithms のデフォルト値が TABLE_SCAN、INDEX_SCAN であるために発生します。

この問題を短期間で解決するには、検索アルゴリズムを INDEX\ _SCAN、HASH\ _SCAN に変更して、フルテーブルスキャンのオーバーヘッドを軽減します。長期的には、各テーブルに明示的なプライマリキーを追加することをお勧めします。

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

レプリカ作成ラグ

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

Amazon RDS では、新しいリードレプリカの作成には時間がかかります。レプリケーションを確立した後、プライマリ DB インスタンスのバックアップを作成するのにかかる時間には遅延が生じます。この遅延を最小限に抑えるには、レプリカの作成を呼び出す前に手動バックアップを作成してください。これで、DB スナップショットはインクリメンタルバックアップになります。

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

**注:**Amazon RDS for MySQL レプリカ (EBS ベースのボリューム) では、最初はレプリカラグが長くなる可能性があります。これは、遅延読み込みの影響がレプリケーションのパフォーマンスに影響を与える可能性があるためです。

新しく作成したリードレプリカのテーブルに対する遅延読み込みの影響を軽減するために、フルテーブルスキャンを含む操作を実行できます。たとえば、特定のテーブルまたはデータベースのリードレプリカで mysqldump 操作を実行する場合などです。これにより、Amazon RDS はバックアップされたすべてのテーブルデータに優先順位を付け、Amazon シンプルストレージサービス (Amazon S3) からダウンロードできます。

また、「オンデマンド」の InnoDB キャッシュウォーミング機能の使用も検討してください。InnoDB キャッシュウォーミング機能は、バッファプールの状態をディスク上の InnoDB データディレクトリの ib\ _buffer\ _pool という名前のファイルに保存します。これにより、リードレプリカを作成する前にプライマリ DB インスタンスのバッファプールの現在の状態をダンプすることでパフォーマンスを向上させることができます。次に、リードレプリカを作成した後に、バッファプールをリロードします。

関連情報

Amazon RDS での MySQL レプリケーションの操作

MySQL リードレプリカの操作

コメントはありません

関連するコンテンツ