CPU はデータベースの中核となるリソースであり、日常運用時の主要な監視対象です。CPU 使用率が過剰になると、アプリケーションの応答時間が長くなり、サービスが遅延する可能性があります。深刻な場合は、データベースインスタンスが一部サービス停止状態になったり、高可用性に問題が生じたりして、本番ワークロードに重大な影響を及ぼします。そのため、CPU 使用率の安全なしきい値を設定し、そのしきい値を超えた場合には直ちに対応して、予期せぬ深刻な事態を防ぐ必要があります。
ビジネス成長に伴う CPU 使用率の増加
ビジネスが成長すると、現在のクラスター仕様では対応しきれなくなる場合があります。パフォーマンスチャートには通常、QPS や IOPS などのメトリックが、CPU 使用率の推移と同様のパターンで上昇傾向を示します
CPU がボトルネックになっている場合、ご利用のクラスター仕様がビジネストラフィックに対して不十分である可能性があります。この問題は、データベースクラスターに読み取り専用ノードを追加するか、クラスター仕様をスケールアップすることで解決できます。
データベースクラスターに接続できない場合や、実行中の DML ステートメントが失敗する場合は、現在のクラスター仕様の CPU リソースがワークロードに対して十分かどうかを確認してください。CPU リソースが不十分であると判断された場合は、システムの安定性を維持するために速やかにクラスターをスケールアップしてください。
ワークロードが主に読み取りリクエストで構成されている場合は、クラスターをスケールアウトして読み取りトラフィックを分散させるために、読み取り専用ノードを追加できます。詳細については、「ノードの追加または削除」をご参照ください。
ワークロードが主に書き込みリクエストで構成されている場合は、読み取り専用ノードを追加してもパフォーマンスは向上しません。このような場合は、クラスター仕様を手動でスケールアップする必要があります。たとえば、4 コア仕様から 8 コア仕様へアップグレードします。
CPU 使用率の高騰に関するトラブルシューティング
CPU 使用率が予期せず急上昇した場合のトラブルシューティングは複雑になることがあります。本トピックでは、スロークエリ、アクティブスレッド数の増加、カーネル構成の不適切さ、システムバグなど、いくつかの一般的な原因について説明します。
スロークエリ
CPU 使用率の高騰は、多くの場合、非効率な SQL ステートメントによってスロークエリが発生し、アクティブスレッドが蓄積されることで引き起こされます。ただし、まずスロークエリが CPU 使用率の高騰の根本原因であるのか、それとも別のリソースボトルネックによってクエリが遅くなり、間接的に CPU 使用率が上昇しているのかを特定する必要があります。
PolarDBコンソールで、 の順に移動することで、スロークエリを確認できます。スローログの詳細 タブで、スキャンされた行数の値が返された行数の値を大幅に上回っている場合、スロークエリが CPU 使用率の高騰を引き起こしていることを示しています。
この分析は TP クエリに焦点を当てており、count クエリは除外されます。一部の AP クエリも非常に大きなスキャンされた行数を持つことがあります。
TP クエリはごく少量のデータの読み取りおよび書き込みを伴います。クエリが大量のデータをスキャンしている場合、インデックスが欠落している可能性が極めて高いです。たとえば、スロークエリリスト内のクエリで 10,000 行以上がスキャンされたにもかかわらず、1 行しか返されていない場合、name 列にインデックスが欠落している明確な兆候です。
SELECT * FROM table1 WHERE name='testname';次のステートメントを使用して、name 列にインデックスが存在するかどうかを確認できます。
SHOW index FROM table1;name列にインデックスがない場合は、次のステートメントでインデックスを追加して、このような大規模なデータスキャンによるスロークエリを解消できます。ALTER TABLE table1 ADD KEY ix_name (name);name列にインデックスがある場合は、次のステートメントを使用して SQL ステートメントの実行計画を確認し、正しいインデックスが使用されているかどうかを検証できます。EXPLAIN SELECT * FROM table1 WHERE name='testname';name列にインデックスが存在するにもかかわらず使用されていない場合は、統計情報が不正確であるために誤った実行計画が生成されている可能性があります。次のステートメントを実行してテーブルの統計情報を再生成し、実行計画を修正できます。ANALYZE TABLE table1;コマンドが完了したら、再度実行計画を確認して、正しいインデックスが使用されるようになったことを確認してください。
EXPLAIN SELECT * FROM table1 WHERE name='testname';
アクティブスレッド数の増加
アクティブスレッド数が増加すると、常に CPU 使用率が上昇します。MySQL では、各 CPU コアが一度に処理できるリクエストは 1 つだけです。たとえば、16 コアのクラスターは、カーネルレベルで最大 16 の同時リクエストを処理できます。これはアプリケーションレベルの同時実行数とは異なります。PolarDBコンソールで、 の順に移動することで、セッション情報を確認できます。
リクエスト処理の失敗原因としてスロークエリを除外した場合、アクティブスレッドの蓄積は通常、本番トラフィックの増加によるものです。パフォーマンス曲線を表示してこれを検証できます。全体的なトラフィックおよびリクエストのトレンドがアクティブスレッドの蓄積トレンドと一致している場合、クラスターリソースが限界に達していることを示しています。この問題を解決するには、データベースクラスターに読み取り専用ノードを追加するか、クラスター仕様をスケールアップする必要があります。
アクティブスレッド数が重大なポイントに達すると、CPU 競合が発生し、カーネル内で多数のミューテックスロックが生成されます。パフォーマンスチャートには通常、CPU 使用率の高騰、アクティブスレッド数の増加、IOPS または QPS の低下が表示されます。もう 1 つの原因は、突然のトラフィックスパイクです。新規接続の急増も CPU 競合およびリクエストのバックログを引き起こします。この問題は、通常、クラスターのスレッドプール機能を有効にしてフロー制御を行うことで軽減できます。アクティブスレッド数が減少した場合は、アプリケーション側でタスクがまだバックログされていないかを確認してください。CPU 負荷およびアクティブスレッド数が依然として高い場合は、クラスターのスケールアップも検討する必要があります。
フロントエンド接続の急増も、クラスター上で瞬間的なトラフィックスパイクを引き起こすことがあります。これは Web クローラーなどによって引き起こされる異常トラフィックです。SQL スロットリングを使用してリクエストを拒否できます。詳細については、「セッション管理」をご参照ください。
不適切なカーネル構成
セルフマネージド MySQL インスタンスのデフォルトパラメーターは汎用シナリオ向けに構成されており、すべてのワークロードに最適とは限りません。そのため、ファインチューニングが必要になる場合があります。一部の問題は、アプリケーションの初期段階ではデータ量が少ないため発生しませんが、時間の経過とともにデータが増加し、特定の条件が満たされると顕在化することがあります。
メモリ競合は一般的な問題です。MySQL アーキテクチャでは、メモリは主にデータキャッシングに使用されます。最もよく使用されるメモリ領域は、buffer pool および innodb_adaptive_hash_index です。データベースシステム全体のキャッシュ領域は、データのやり取りが最も頻繁に行われる場所です。メモリが不足している場合やメモリページ競合が発生している場合、さまざまな例外およびスロークエリが蓄積する可能性があります。典型的な症状は、CPU 使用率が最大値まで急上昇し、スロークエリが同時に発生することです。調査の結果、インデックスの欠落ではないことが判明した場合、問題はメモリシステムにある可能性があります。
たとえば、truncate table 操作を実行すると、MySQL は buffer pool を走査して、truncate されるテーブルのすべてのデータページを破棄します。大規模なクラスターで、innodb_buffer_pool_instances が 1 に設定されており、同時実行数が比較的高い場合、競合問題が発生する可能性があります。この問題はサービスライフサイクルの早い段階で発見でき、通常は innodb_buffer_pool_instances の値を CPU コア数に合わせて、buffer pool をバケットにパーティション分割することで回避できます。
もう 1 つのシナリオは、innodb_adaptive_hash_index の競合です。明確な症状は、大量の hash0hash.cc 待ちが発生することです。
SHOW ENGINE innodb STATUS;出力の AHI セクションでは、顕著なデータスキューが確認されます。
insert 0, delete mark 0, delete 0
Hash table size 25499819, node heap has 20720 buffer(s)
Hash table size 25499819, node heap has 25111 buffer(s)
Hash table size 25499819, node heap has 23884 buffer(s)
Hash table size 25499819, node heap has 16835 buffer(s)
Hash table size 25499819, node heap has 23132 buffer(s)
Hash table size 25499819, node heap has 189284 buffer(s)
Hash table size 25499819, node heap has 38864 buffer(s)
Hash table size 25499819, node heap has 49094 buffer(s)
5469.32 hash searches/s, 5282.36 non-hash searches/sこのような問題に対しては、innodb_adaptive_hash_index パラメーターを無効化することで、AHI 機能を無効化できます。データによると、読み取りおよび書き込みが混在するシナリオでは、AHI がパフォーマンスへの悪影響を及ぼす可能性がありますが、これを無効化してもビジネス全体への影響は大きくありません。
システムバグ
システムバグは、CPU 使用率の高騰を引き起こす比較的まれな原因です。過去のバージョンの例としては、プロセスのデッドロックや、テーブル統計情報がゼロにリセットされることによる全表スキャンなどがあります。プロダクトの進化に伴い、システムバグによる CPU 問題は減少しています。ただし、これらの問題のトラブルシューティングには、通常、深いカーネルレベルの情報が必要であり、ユーザー自身での解決は困難です。テクニカルサポートへのお問い合わせを推奨します。