Amazon RDS for MySQL でレプリカの遅延が大きい場合のトラブルシューティング方法を教えてください。
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 レプリケーションでは、バイナリログダンプ、レプリケーション I/O レシーバー、レプリケーション SQL アプライヤースレッドを使用します。スレッドが機能するしくみの詳細については、MySQL のウェブサイトで「レプリケーションスレッド」を参照してください。レプリケーションに遅延がある場合は、IO_THREAD レプリカと SQL_THREAD レプリカのどちらが遅延の原因であるかを特定します。その後、ラグの根本原因を特定します。
解決策
遅延しているレプリケーションスレッドを特定する
プライマリ DB インスタンスで SHOW MASTER STATUS コマンドを実行します。
mysql> SHOW MASTER STATUS;
出力例:
+----------------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +----------------------------+----------+--------------+------------------+-------------------+ | mysql-bin.066552 | 521 | | | | +----------------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
注: 上記の出力例では、ソースまたはプライマリ DB インスタンスがバイナリログを mysql-bin.066552 というファイルに書き込みます。
レプリカ DB インスタンスで SHOW SLAVE STATUS コマンドを実行します。
mysql> SHOW SLAVE STATUS\G;
出力例 1:
*************************** 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
注: 上記の出力例では、Master_Log_File: mysql-bin.066548 は IO_THREAD レプリカは、バイナリログファイル mysql-bin.066548 から読み取っていることを示しています。プライマリ DB インスタンスは、mysql-bin.066552 ファイルにバイナリログを書き込みます。IO_THREAD レプリカは 4 バイナリログ分遅れています。ただし、Relay_Master_Log_File は mysql-bin.066548 なので、SQL_THREAD レプリカは IO_THREAD と同じファイルから読み取っています。SQL_THREAD レプリカでは速度が維持されていますが、IO_THREAD レプリカには遅延があります。
出力例 2:
*************************** 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
上記の出力例は、プライマリインスタンスのログファイルは mysql-bin.066552 であることを示しています。IO_THREAD はプライマリ DB インスタンスの速度を維持しています。レプリカ出力では、SQL スレッドは Relay_Master_Log_File: mysql-bin.066530 を実行します。その結果、SQL_THREAD が 22 バイナリログ分遅れます。
一般には、IO_THREAD はプライマリインスタンスまたはソースインスタンスからのみバイナリログを読み取るため、IO_THREAD によって大きなレプリケーション遅延が発生することはありません。ただし、ネットワーク接続とネットワーク遅延により、サーバー間の読み取り速度が影響を受ける可能性はあります。帯域幅の使用量が多いと、IO_THREAD レプリカのパフォーマンスが遅くなる可能性があります。
SQL_THREAD レプリカがレプリケーションの遅延の原因となっている場合は、次のトラブルシューティング手順を使用して問題を解決してください。
プライマリインスタンスでクエリが長時間実行している
プライマリ DB インスタンスで長時間実行される書き込みクエリが、レプリカ DB インスタンスで実行するのと同じ時間がかかる場合、seconds_behind_master が増える可能性があります。たとえば、プライマリインスタンスへの変更の実行に 1 時間かかる場合、遅延は 1 時間です。レプリカでも変更が完了するまでに 1 時間かかる場合、合計遅延時間は約 2 時間になります。
遅延を最小限に抑えるには、プライマリインスタンスのスロークエリログを監視します。実行時間の長いステートメントを小さなステートメントまたはトランザクションに縮小することも検討してください。
DB インスタンスクラスのサイズまたはストレージが不足している
レプリカ DB インスタンスのクラスまたはストレージ構成がプライマリインスタンスよりも低い場合、リソース不足が原因でレプリカのスロットリングが発生する可能性があります。レプリカは、プライマリインスタンスでの変更の数を維持できなくなります。
この問題を解決するには、レプリカの DB インスタンスタイプがプライマリ DB インスタンスと同じものか、上位のものであることを確認してください。レプリケーションを効果的に機能させるには、各リードレプリカにソース DB インスタンスと同じ数のコンピューティングリソースとストレージリソースが必要です。詳細については、「DB インスタンスクラス」を参照してください。
プライマリ DB インスタンスで並列クエリを実行している
MySQL レプリケーションは、デフォルトではシングルスレッドです。そのため、プライマリインスタンスでクエリを並行して実行すると、クエリは順番にレプリカにコミットされます。ソースインスタンスへの大量の書き込みが並行して発生する場合、リードレプリカへの書き込みは単一の SQL_THREAD を使用してシリアル化されます。これにより、ソース DB インスタンスとリードレプリカの間に遅延が生じる可能性があります。
マルチスレッド (並列) レプリケーションは、MySQL 5.6 以降のバージョンで使用できます。マルチスレッドレプリケーションの詳細については、MySQL ウェブサイトで「バイナリログ黒くのオプションと変数」を参照してください。
マルチスレッドレプリケーションにより、レプリケーションにギャップが生じる可能性があります。たとえば、マルチスレッドレプリケーションでは、スキップしたトランザクションを特定することが難しいため、レプリケーションエラーをスキップする場合はベストプラクティスではありません。プライマリ DB インスタンスとレプリカ DB インスタンスの間でデータの一貫性にギャップが生じる可能性があります。
バイナリログがレプリカ DB インスタンスのディスクに同期されている
レプリカで自動バックアップを有効にすると、バイナリログをレプリカ上のディスクに同期するためにオーバーヘッドが発生します。sync_binlog パラメータのデフォルト値は 1 に設定されています。値を 0 に変更した場合は、MySQL サーバーがバイナリログをディスクに同期する機能も無効になります。代わりに、オペレーティングシステムが随時バイナリログをディスクにフラッシュするようになります。
バイナリログの同期を無効にすると、コミットのたびにバイナリログをディスクに同期するために必要なパフォーマンスのオーバーヘッドを減らすことができます。ただし、停電や OS のクラッシュが発生した場合、コミットの一部がバイナリログと同期しない場合があります。非同期により、ポイントインタイムリストア (PITR) 機能が影響を受ける可能性があります。詳細については、MySQL のウェブサイトで sync_binlog を参照してください。
Binlog_format が ROW に設定されている
次のシナリオにおいて、SQL スレッドはレプリケーションを行うときに、テーブル全体をスキャンします。
- プライマリ DB インスタンスの binlog_format が ROW に設定されている。
- ソーステーブルに主キーがない。
これは、パラメータ 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 スナップショットは増分バックアップになります。
スナップショットからリードレプリカを復元する際、レプリカはソースからすべてのデータが転送されるまで待機しません。レプリカ DB インスタンスを使用して DB 操作を行うことは可能です。既存の Amazon Elastic Block Store (Amazon EBS) スナップショットにより、バックグラウンドで新しいボリュームが作成されます。
注: Amazon RDS for MySQL のレプリカ (Amazon EBS ベースのボリューム) では、遅延読み込みがレプリケーションのパフォーマンスに影響する場合があるため、最初はレプリカの遅延が大きくなる可能性があります。
フルテーブルスキャンを使用する操作により、新しいリードレプリカのテーブルでの遅延読み込みの影響を減らすことができます。たとえば、特定のテーブルまたはデータベースのリードレプリカで mysqldump を実行することで、Amazon RDS が Amazon Simple Storage Service (Amazon S3) からバックアップされたすべてのテーブルデータを優先するようにします。
オンデマンドの InnoDB キャッシュウォーミング機能を使用することもできます。InnoDB キャッシュウォーミング機能は、バッファプールの状態をディスク上の InnoDB データディレクトリ内の ib_buffer_pool という名前のファイルに保存します。リードレプリカを作成する前に、Amazon RDS がプライマリ DB インスタンスバッファプールの現在の状態をダンプするため、パフォーマンスが向上します。その場合、リードレプリカを作成した後にバッファプールをリロードします。
関連情報
関連するコンテンツ
- 質問済み 1年前lg...
- 質問済み 7年前lg...
- AWS公式更新しました 2年前
- AWS公式更新しました 3年前