圧力テスト環境データ テーブルのデッドロックにより、インターフェイスが長時間保留されました。

背景

ストレス テスト中に、テスト パートナーから、特定のページが長時間ロードされた後に開けないという報告がありました。次に確認してみましょう。ストレス テスト環境であるため、サーバー リソース レベルの要因を除外する必要があります。システムのリソースが不足している場合のテストでは、コードレベルから直接チェックを開始します。

トラブルシューティングのアイデア

ブラウザで F12 を開き、問題を再現し、インターフェイスにパフォーマンス上の問題があると判断します。次に、インターフェイスの内部実装ロジック、何が行われ、どのサービスが呼び出されるかを判断する必要があります。根本原因を分析します。インターフェイスのパフォーマンスの問題。トラブルシューティングのプロセスでは、データベース操作が for ループで実行されているか、サードパーティ インターフェイスの呼び出しが行われているか、サードパーティ インターフェイスの呼び出しに時間がかかっているか、実行された SQL にパフォーマンスの問題があるかどうかに注意してください。 。その後、最適化計画を決定し、効果を検証してバージョンをリリースします。

MyBatis foreach ラベルのデータ量が多い場合にはパフォーマンス上の問題が発生し、インターフェース解析では SQL パフォーマンス上の問題として扱われます。

バージョンの反復や要件の変更に伴い、インターフェイス内のロジックはますます肥大化する可能性があり、クエリに関連付けられるテーブルの数がますます増え、クエリ対象のデータ量が増加します。クローズド ループ ビジネスを確保するために、追加と更新には、N シートのテーブルに対する同時操作が必要になる場合があります。上記は、インターフェイスのパフォーマンスに影響を与える要因です。

トラブルシューティングのプロセス

再発調査中に、遅い SQL ステートメントの 1 つが実行に時間がかかりすぎ、その結果、クエリの対応するテーブルでデッドロックが発生したことが判明しました。そのため、これはインターフェイスが長期間保留されることを意図したものです。

解決

対応するテーブルがデッドロック状態にあるため、まずデッドロック状態のテーブルを解放し、対応するクエリ プロセスを強制終了する必要があります。次に、次のコマンドを実行する必要があります。

#以下命令需要同时执行
show OPEN TABLES where In_use > 0;
​
SHOW PROCESSLIST;
​
SELECT * FROM information_schema.INNODB_TRX;
​
SELECT * FROM information_schema.INNODB_LOCKs;
 
 #根据进程号kill
  kill  pid

ロックを解除した後、explainステートメントを使用して実行プランをクエリし、業務変更により関連するクエリ テーブルが多すぎて、データ量が多い場合に SQL のパフォーマンスが極端に低下することを確認します。時間が長すぎるため、他のトランザクションがロックを待機することになります。時間がかかりすぎて、デッドロックが発生します。

Alibaba 開発マニュアルでは、クエリを実行する際に関連付けられるテーブルは 3 つ以下であるべきであると推奨しています。

この提案に基づいて、長いトランザクションによって引き起こされるデータベース テーブルのデッドロックによって引き起こされるインターフェイスの長期保留問題を回避するために、元の SQL ステートメントを分割しました。テスト後に問題は解決されました。

知識の拡充 - デッドロックを回避する方法

MySQL デッドロックとは何ですか? デッドロックを回避するにはどうすればよいですか?

MYSQL でのデッドロックの原因

  1. 同時アクセス: 複数のトランザクションが同じリソースに同時にアクセスすると、デッドロックが発生しやすくなります。
  2. トランザクションによって要求されたリソースの不適切な順序: 複数のトランザクションが同じリソースを異なる順序でロックすると、デッドロックが発生しやすくなります。
  3. ロックのタイムアウト: トランザクションがロックを保持する時間が長すぎる場合、たとえば、1 つのトランザクションの処理に時間がかかりすぎると、他のトランザクションがロックを長時間待機することになり、最終的にデッドロックが発生する可能性があります。
  4. ロックの粒度が大きすぎる: ロックの粒度が大きすぎる場合、たとえば、トランザクションが数十のデータをロックしたり、テーブル ロックをロックしたりする場合、トランザクションが同じリソースに同時にアクセスすると、デッドロックが発生しやすくなります。

デッドロックを分析する方法

  1. エラー ログ: デッドロック情報は、デッドロックが発生した時刻、ロックを保持しているスレッド、ロックを待機しているスレッドなどを含む、MySQL エラー ログに記録されます。
  2. SHOW ENGINE INNODB STATUS: このコマンドを使用すると、デッドロックに関する詳細情報を含む、InnoDB エンジンのステータス情報を表示できます。このうち、LATEST DETECTED DEADLOCK の部分には、ロックを保持しているトランザクション ID やロックを待機しているトランザクション ID、ロックの詳細など、最新のデッドロック イベントがリストされます。
  3. information_schema テーブル: MySQL は、ロックとトランザクション ステータスを表示するためのシステム テーブルをいくつか提供します。たとえば、information_schema.INNODB_TRX テーブルには現在実行されているトランザクション リストが含まれ、information_schema.INNODB_LOCKS テーブルには現在のロック リストが含まれ、information_schema.INNODB_LOCK_WAITS テーブルには現在のロック待機リストが含まれます。
  4. Alibaba Cloud などのクラウド データベースを使用している場合、通常、監視システムはデッドロック情報をクエリできます。

MYSQLのデッドロックを解決する方法

  1. 再試行: デッドロックが発生した場合、トランザクションを再試行して実行を再試行できます。再試行の回数を制限したり、一定回数経過後にトランザクションを中止することを選択したりできます。
  2. ロック順序: デッドロックを回避するために、異なるトランザクションが同じ順序でロックにアクセスするようにしてください。たとえば、すべてのトランザクションは同じ順序または逆の順序でロックを取得します。
  3. トランザクションの範囲を減らす: 大規模なトランザクションを複数の小さなトランザクションに分割でき、各小さなトランザクションにはデータの一部のみが含まれるため、デッドロックの可能性を減らすことができます。
  4. 分離レベルを上げる: ビジネスが許可する場合は、分離レベルを SERIALIZABLE に増やすことができます。これにより、データ読み取り時の一貫性が保証され、他のトランザクションによって変更されているデータの読み取りが回避され、デッドロックの可能性が軽減されます。
  5. ロック時間を短縮する: トランザクションがロックを占有する時間を最小限に抑えます。たとえば、最初にロックを取得するのではなく、変更が必要なときにロックを取得できます。
  6. インデックスを使用する: 合理的なインデックス設計により、テーブル全体のスキャンが回避され、ロックの競合と待機時間が減少し、デッドロックの発生が減少します。

考えと提案

  • どのようなトラブルシューティング方法であっても、コードを書くときにもっと考え、限界条件の仮定をもう 1 つ増やすほど効果はありません。問題を解決する方法を見つけるだけでなく、起こり得る問題を回避するよう努める必要もあります。
  • プログラミングでは、大量のデータの下でバケツの最短ボードによって引き起こされる問題を回避および解決するために、「分割統治」の習慣を身につけるべきです。

最後に、私の記事を注意深く読んでくださった皆さんに感謝します。ファンの成長と関心をずっと見ていると、相互主義が常に必要になります。それほど価値のあるものではありませんが、もしあなたがそれを持っていれば、それを奪うことができますそれが必要:

これらの資料は、[ソフトウェア テスト] の友人にとって最も包括的で完全な準備倉庫となるはずです。この倉庫は、最も困難な旅を乗り越える何万人ものテスト エンジニアにも同行してきました。あなたにも役立つことを願っています。

私の QQ 技術交換グループ (技術交換とリソース共有、広告なし)

おすすめ

転載: blog.csdn.net/weixin_67553250/article/details/131275021
おすすめ