読み取り専用 RDS インスタンスは、MySQL のネイティブなログベースの非同期または準同期レプリケーションを使用して、プライマリインスタンスと同期を維持します。このメカニズムにより遅延が発生し、一時的なデータ不整合を引き起こしたり、バイナリログが蓄積されるにつれて読み取り専用インスタンスのストレージ容量を使い果たしたりする可能性があります。
プライマリ RDS インスタンスで大量のログが生成されている場合、その読み取り専用 RDS インスタンスがロックされる可能性があります。
このドキュメントを使用して、レプリケーション遅延メトリックを解釈し、根本原因を特定して、問題を解決してください。
レプリケーション遅延の測定方法
SHOW SLAVE STATUS \G の出力にある Seconds_Behind_Master フィールドは、レプリケーション遅延を秒単位で報告します。
遅延の数式: 遅延 = 現在時刻 − 読み取り専用インスタンスで適用されているトランザクションがプライマリ RDS インスタンスでコミットされた時点
読み取り専用インスタンスで次のステートメントを実行して、現在のレプリケーションステータスを確認します。
SHOW SLAVE STATUS \G確認すべき主要なフィールド:
| フィールド | 確認事項 |
|---|---|
Slave_IO_Running | Yes である必要があります。No は、レプリケーションが中断されていることを示します。 |
Slave_SQL_Running | Yes である必要があります。No は、レプリケーションが中断されていることを示します。 |
Seconds_Behind_Master | レプリケーションの遅延 (秒単位)。0 は読み取り専用インスタンスが追いついていることを意味します。NULL はレプリケーションがアクティブでないことを意味します。 |
Exec_Master_Log_Pos | この値が変わらないまま Seconds_Behind_Master が上昇し続ける場合、SQL スレッドが大規模トランザクションまたは DDL 操作でスタックしています。 |
Last_IO_Error / Last_SQL_Error | I/O スレッドまたは SQL スレッドのエラーメッセージです (存在する場合)。 |
遅延が 1 秒以下の場合:無視すべきケース
報告される遅延が 1 秒以下の場合、通常は実際の問題を示すものではありません。これには 2 つの一般的な原因があります。
モニタリングの粒度。 モニタリングの時間範囲を 6 分を超えるように設定した場合、デフォルトのモニタリング粒度は最大で 30 秒まで粗くなります。表示される値は、その間隔における平均値であり、瞬間的な読み取り値ではありません。1 秒の粒度で読み取り値を取得するには、ApsaraDB RDS コンソールの [パフォーマンストレンド] タブに移動し、モニタリングの時間範囲を 6 分未満に設定してください。
秒をまたぐサンプリング。サンプリングポイントは常に最も近い秒に切り捨てられます。トランザクションが 1 秒で開始し、次の秒で完了する場合、実際のサブ秒の遅延に関係なく、遅延計算は 1 秒と報告されます。以下の表は、この動作を示しています。
| トランザクション | プライマリでのコミット時間 | 読み取り専用でのコミット時間 | 現在時刻 | 報告された遅延 |
|---|---|---|---|---|
| Trx1 | 00:00:00.30 | 00:00:00.50 | 00:00:00.35 | 0(0.35) - 0(0.30) = 0 s |
| 00:00:00.45 | 0(0.45) - 0(0.30) = 0 s | |||
| Trx2 | 00:00:00.90 | 00:00:01.10 | 00:00:00.95 | 0(0.95) - 0(0.90) = 0 s |
| 00:00:01.05 | 1(1.05) - 0(0.90) = 1 s |
誤検知を避けるため、読み取り遅延のアラートのしきい値を 1 秒より大きく設定してください。
遅延が 1 秒を超える場合:原因の特定と修正
1 秒を超える持続的な遅延は調査が必要です。以下のセクションでは、最も一般的な 5 つの原因、それぞれの確認方法、および解決方法について説明します。
インスタンスの仕様やデータを変更するなどの構成変更を行う前に、スナップショットを作成するか、ログバックアップを有効にしてデータを保護してください。Alibaba Cloud 管理コンソールで機密情報に対する権限を付与したり、機密情報を送信したりした場合は、できるだけ早く機密情報を変更することをお勧めします。機密情報には、ユーザー名とパスワードが含まれます。
原因 1:読み取り専用インスタンスの仕様が低すぎる
発生する事象。レプリケーションは、I/O スレッド (プライマリからバイナリログをフェッチするため) と SQL スレッド (ローカルで適用するため) を使用します。両方のスレッドは、1 秒あたりの入出力操作数 (IOPS) を含む I/O リソースを競合します。読み取り専用インスタンスが必要な IOPS を維持できない場合、遅延が発生します。
確認方法。ApsaraDB RDS コンソールで、読み取り専用インスタンスのモニタリングとアラートに移動します。CPU 使用率、メモリ使用量、I/O 帯域幅、または IOPS が継続的に上限に達しているかどうかを確認します。また、[設定情報]セクションの[基本情報]ページでインスタンスタイプを確認することもできます。詳細については、「読み取り専用 ApsaraDB RDS for MySQL インスタンスのインスタンスタイプ (x86)」および「読み取り専用 ApsaraDB RDS for MySQL インスタンスのインスタンスタイプ (ARM)」をご参照ください。
解決方法。読み取り専用インスタンスを、プライマリインスタンスと同等以上の仕様にスペックアップします。詳細については、「ApsaraDB RDS for MySQL インスタンスの仕様変更」をご参照ください。
原因 2:プライマリインスタンスでの 1 秒あたりのトランザクション数 (TPS) が高い
発生する事象。単一の SQL スレッドが、読み取り専用インスタンス上のすべてのレプリケートされたトランザクションをシリアルに適用します。プライマリインスタンスが大量の同時書き込みを処理する場合、読み取り専用インスタンスは追いつくことができません。
確認方法。 プライマリまたは読み取り専用インスタンスの [ダッシュボード] ページに移動し、TPS メトリックを確認します。詳細については、「ApsaraDB RDS for MySQL インスタンスでダッシュボード機能を使用する」をご参照ください。
解決方法。プライマリインスタンス上の大規模トランザクションを最適化または分割して、トランザクションあたりの書き込み量を減らし、各トランザクションが SQL スレッドを保持する時間を短縮します。
原因 3:プライマリインスタンスでの大規模トランザクション
発生する事象。大規模なデータ量に対する UPDATE、DELETE、INSERT...SELECT、および REPLACE...SELECT などの操作は、大規模なバイナリログエントリを生成します。読み取り専用インスタンスは、プライマリがトランザクションを実行するのにかかった時間と同じ時間をトランザクションの適用に費やす必要があります。たとえば、プライマリで 80 秒かかる削除は、レプリケートにも 80 秒かかります。
さらに、複数のテーブルでの同時実行トランザクションはサポートされていますが、特定のテーブルでのトランザクションをレプリケートするスレッドは一度に 1 つだけであり、これが遅延をさらに悪化させる可能性があります。
確認方法。読み取り専用インスタンスで SHOW SLAVE STATUS \G を実行し、Exec_Master_Log_Pos が同じままで Seconds_Behind_Master が継続的に増加しているかどうかを監視します。次に、SHOW PROCESSLIST を実行して、特定の SQL スレッドを特定します。バイナリロギングが ROW フォーマットに設定されている場合、バイナリログファイルが max_binlog_size のしきい値を超えているかどうかを確認します。
SHOW BINARY LOGS;File_size が max_binlog_size を超える場合、大規模トランザクションが原因である可能性が高いです。
また、SHOW SLAVE STATUS \G の出力でロック待機状態を調べて、メタデータロック (MDL) の競合を確認します。
解決方法。大規模トランザクションをより小さなバッチに分割します。たとえば、DELETE ステートメントに WHERE 句と行制限を追加して、各バッチが管理可能な数の行を処理できるようにし、読み取り専用インスタンスがペースを維持できるようにします。
原因 4:プライマリインスタンスでの長時間実行 DDL
発生する事象。レプリケーションは、データ定義言語 (DDL) ステートメントをシリアルに適用します。大規模なテーブルに対する CREATE INDEX、ALTER TABLE ADD COLUMN、または REPAIR TABLE などの DDL 操作は、完了するまですべての後続のレプリケーションをブロックする可能性があります。大量の一時テーブルを生成するスロークエリは、ディスク I/O を消費することで問題をさらに悪化させます。
これとは別に、読み取り専用インスタンスで実行中のクエリやオープンなトランザクションは、プライマリから到着する DDL ステートメントをブロックする MDL 競合を引き起こす可能性があります。
確認方法。
バイナリログファイルが切り捨てられずに蓄積されているかどうかを確認します。これは DDL バックログを示しています。
読み取り専用インスタンスで次のステートメントを実行して、ロック競合を確認します。
SHOW ENGINE INNODB STATUS \G次のステートメントを実行して、現在使用中のテーブルを特定します。
SHOW OPEN TABLES;in_use = 1のテーブルはロックされており、レプリケーションをブロックしている可能性があります。OPTIMIZE、ALTER、REPAIR、CREATEなどの DDL 関連操作についてスロークエリログを確認します。詳細については、「スロークエリログ分析」をご参照ください。
解決方法。
DDL 操作をオフピーク時間にスケジュールします。
ストレージの自動拡張機能を有効にするか、手動ストレージ拡張のしきい値を 90% に設定します。詳細については、「ApsaraDB RDS インスタンスをスケーリングするにはどうすればよいですか?」をご参照ください。
SQL Explorer を有効にして、SQL パフォーマンスを定期的にモニタリングします。詳細については、「ApsaraDB RDS for MySQL インスタンスで SQL Explorer および監査機能を使用する」をご参照ください。
ディスク使用率アラートを構成するか、インスタンスの仕様をスペックアップします。詳細については、「ApsaraDB RDS for MySQL インスタンスの仕様変更」をご参照ください。
プライマリからの DDL ステートメントが読み取り専用インスタンス上のメタデータロックによってブロックされている場合:
読み取り専用インスタンスで
SHOW PROCESSLIST;を実行して、メタデータロックを待機している SQL スレッドを見つけます。ロックを保持しているセッションを終了して、レプリケーションを再開します。詳細については、「DMS を使用してメタデータロックを解除する」をご参照ください。
原因 5:一意なインデックスはあるがプライマリキーがないテーブル
発生する事象。テーブルにプライマリキーがなく、NULL 値を含む一意なインデックスのみがある場合、レプリケーション SQL スレッドは、WHERE 句がより効率的なルックアップを可能にする場合でも、オプティマイザーの推奨プランではなく、一意なインデックスの実行計画を使用します。これにより、レプリケーション中に全表スキャンが強制され、論理読み込みが大幅に増加し、SQL スレッドが遅くなります。
確認方法。プライマリインスタンスで次のクエリを実行して、プライマリキーがないテーブルを特定します。
SELECT tab.table_schema AS database_name, tab.table_name
FROM information_schema.tables tab
LEFT JOIN information_schema.table_constraints tco
ON tab.table_schema = tco.table_schema
AND tab.table_name = tco.table_name
AND tco.constraint_type = 'PRIMARY KEY'
WHERE tco.constraint_type IS NULL
AND tab.table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')
AND tab.table_type = 'BASE TABLE'
ORDER BY tab.table_schema, tab.table_name;クエリによって返されたテーブルについては、sys.schema_index_statistics ビューを使用して、一意なインデックスに NULL 値が含まれているかどうかを確認します。
解決方法。プライマリキーがないテーブルには、明示的なプライマリキーを追加します。
よくある質問
一部の読み取り専用インスタンスで 1 秒の遅延が表示され、他のインスタンスでは表示されないのはなぜですか?
各読み取り専用インスタンスは、わずかに異なる時間にコレクションプロシージャを開始します。サンプリングポイントが秒の境界をまたぐ場合、1 秒の遅延が報告されます。そうでない場合、遅延は 0 秒と報告されます。これは測定アーティファクトであり、レプリケーション性能の実際の差ではありません。詳細については、「遅延が 1 秒以下の場合:無視すべきケース」をご参照ください。
1 秒の遅延は、ご利用のインスタンスが影響を受けていることを意味しますか?
いいえ。報告された 1 秒の遅延は、実際にラグが発生したことを意味しません。この値は、実際の同期遅延ではなく、計算の丸めを反映しています。これらの誤検知を除外するために、プロキシまたはアラートの読み取り遅延しきい値を 1 秒より大きく設定してください。
ReplicationInterrupted エラーが表示された場合、または Slave_SQL_Running もしくは Slave_IO_Running アラートがトリガーされた場合はどうすればよいですか?
次の項目を順番に確認します。
ストレージ容量。 読み取り専用インスタンスのストレージが不足すると、受信したバイナリログを書き込めなくなります。 [基本情報] ページの [使用量統計] セクションでストレージ使用量を確認してください。
レプリケーション遅延。 5 分間のウィンドウ内で、遅延が継続的に 5 秒を超えている場合、アラートがトリガーされます。プライマリでの書き込みボリュームが高いこと、または大規模トランザクションが実行されていることが、最も可能性の高い原因です。現在の遅延を表示するには、[モニタリングとアラート] > [標準モニタリング] に移動し、「セカンダリインスタンスのレプリケーション遅延 (秒)」メトリックを確認します。
スロークエリログ。 読み取り専用インスタンスでのスロークエリは、SQL スレッドのパフォーマンスを低下させ、レプリケーションラグを増大させる可能性があります。 ログは、[ログ] > [スロークエリログ]、または [自律サービス] > [スロークエリログ] で確認します。
上記のいずれも当てはまらない場合、システムはレプリケーションの中断を自動的に検出して解決します。