MySQL エラー: ロックを取得しようとしたときにデッドロックが見つかりました。トランザクションの解決策を再起動してください

MySQL エラー: ロックを取得しようとしたときにデッドロックが見つかりました。トランザクションの解決策を再起動してください

問題を見つける

最近、以前のデータを入力していたときに、プログラムが突然次のエラーを報告しました。

[2017-02-10 13:12:06.678] [INFO] mysqlLog - tbl_playerdata_error を更新: { [エラー: ER_LOCK_DEADLOCK: ロックを取得しようとしたときにデッドロックが見つかりました。トランザクションを再起動してください]
 コード: 'ER_LOCK_DEADLOCK'、
 エラー番号: 1213、
 SQL状態: '40001',
 インデックス: 0 }

一見すると、MySQL にデッドロックの問題があることは明らかです。実際、上で実行しているプログラムは、テストサーバーで長時間問題なく実行されています。公式サーバーで MySQL のデッドロック問題が発生するのはなぜでしょうか。最初の反応は、データ量が多すぎる (300 万件以上のレコード) ということですが、それはあり得ません。それに、デッドロックはこれらのこととどう関係があるのでしょうか。きちんと解決する必要があるようです。

問題分析

私の分析は、現在公式サーバーのデータを処理しており、公式サーバーで操作しているユーザーが多いため、ユーザーがクエリやその他の操作を実行しているときに、私の側のデータ更新でデッドロックが発生するはずだということです(まず、InnoDB ストレージ エンジンを使用していることを説明します。ユーザー側のクエリやその他の操作によって必要なリソースがロックされ、私の側の更新によってユーザーの操作のリソースの一部もロックされたため、両側がもう一方の側がリソースを解放するのを待機し、デッドロックが発生しました)。

回避策

エラーコードがわかったら、まずMySQLの説明を確認してください。上記のエラー: 1213 SQLSTATE: 40001については、サーバーエラーコードとメッセージを参照してください。

メッセージ: ロックを取得しようとしたときにデッドロックが見つかりました。トランザクションを再開してください

InnoDB は、トランザクションがデッドロックに遭遇し、自動的にロールバックされてアプリケーションが修正アクションを実行できる場合にこのエラーを報告します。このエラーから回復するには、このトランザクションのすべての操作を再度実行します。デッドロックは、ロック要求がトランザクション間で一貫性のない順序で到着すると発生します。ロールバックされたトランザクションはすべてのロックを解放し、他のトランザクションは要求したすべてのロックを取得できるようになりました。したがって、ロールバックされたトランザクションを再実行すると、他のトランザクションが完了するまで待機する必要がある場合がありますが、通常はデッドロックは再発しません。デッドロックが頻繁に発生する場合は、問題が発生しているさまざまなトランザクションまたはアプリケーション間で、ロック操作のシーケンス (LOCK TABLES、SELECT ... FOR UPDATE など) を一貫させます。詳細については、セクション14.8.5「InnoDB のデッドロック」を参照してください。

上記には2つの文があります:

このエラーから回復するには、このトランザクションのすべての操作を再度実行してください。<br><br>デッドロックが頻繁に発生する場合は、問題が発生しているさまざまなトランザクションまたはアプリケーション間で、ロック操作のシーケンス (<code class="literal">LOCK TABLES</code>、<code class="literal">SELECT ... FOR UPDATE</code> など) を一貫しているようにしてください。

この 2 つの文では、デッドロックの対処方法についても説明しています。デッドロック エラーが発生した場合は、タイマーを使用して操作を再更新し、上記の問題を回避します。

さらに、Stack Overflow の回答を参照してください: http://stackoverflow.com/questions/2332768/how-to-avoid-mysql-deadlock-found-when-trying-to-get-lock-try-restarting-trans

ほとんどのデッドロックを解決するのに役立つ簡単なトリックの 1 つは、操作を特定の順序で並べ替えることです。

2 つのトランザクションが反対の順序で 2 つのロックをロックしようとすると、デッドロックが発生します。

接続1: キー(1)をロックし、キー(2)をロックします。
接続2: キー(2)をロックし、キー(1)をロックします。
両方が同時に実行されると、接続 1 はキー (1) をロックし、接続 2 はキー (2) をロックし、各接続は他方がキーを解放するまで待機します -> デッドロック。

ここで、接続が同じ順序でキーをロックするようにクエリを変更した場合、次のようになります。

接続1: キー(1)をロックし、キー(2)をロックします。
接続2: キー(1)をロックし、キー(2)をロックします。
デッドロックを起こすことは不可能になります。

そこで私が提案するのは次のことです:

削除ステートメントを除いて、一度に複数のキーへのアクセスをロックする他のクエリがないことを確認してください。そのようなクエリがある場合 (おそらくあると思います)、WHERE in (k1,k2,..kn) を昇順に並べ替えます。
削除ステートメントを昇順で動作するように修正します。
変化

onlineusers から削除 WHERE datetime <= now() - 間隔 900 秒
に

DELETE FROM onlineusers WHERE id IN (SELECT id FROM onlineusers
 WHERE datetime <= now() - INTERVAL 900 SECOND order by id) u;
覚えておくべきもう 1 つの点は、mysql のドキュメントでは、デッドロックが発生した場合、クライアントは自動的に再試行する必要があると示されていることです。このロジックをクライアント コードに追加できます (たとえば、この特定のエラーでは、諦める前に 3 回再試行します)。

参考: http://blog.sina.com.cn/s/blog_4acbd39c01014gsq.html

要約する

上記はこの記事の全内容です。この記事の内容が皆さんの勉強や仕事に少しでもお役に立てれば幸いです。ご質問があれば、メッセージを残してコミュニケーションしてください。123WORDPRESS.COM をご愛顧いただき、ありがとうございます。

以下もご興味があるかもしれません:
  • C# の SqlTransaction - トランザクションの詳細な説明
  • mysql 非トランザクション データベースのみ (MyISAM のみをサポート)
  • Transact-SQL の簡単な紹介
  • MySQL データベースのトランザクション分離レベル (トランザクション分離レベル) の概要
  • Transact_SQL マニュアル
  • Sql Server データベースでよく使用される Transact-SQL スクリプト (推奨)

<<:  シェルスクリプト nginx 自動化スクリプト

>>:  Hadoopカウンターとデータクリーニングの適用

推薦する

Vueプロジェクトはログインと登録の効果を実現します

この記事の例では、ログインと登録の効果を実現するためのvueプロジェクトの具体的なコードを共有してい...

TypeScript 環境を構築して VSCode にデプロイする詳細な手順

目次TypeScript環境の構築ステップ1: Taobaoミラーをダウンロードするステップ2: T...

TypeScriptはvscodeを使用してコードのコンパイルプロセスを監視します

インストールtsコマンドをグローバルにインストールする npm install -g typescr...

SQLは、隣接する2行のデータに対して加算、減算、乗算、除算の演算を実行します。

SQL は、データを特定の順序で並べ替え、特定のフィールドでグループ化した後、隣接する 2 つのデ...

MySQL 学習ノート: 完全な SELECT ステートメントの使用例と詳細な説明

この記事では、MySQL 学習ノートの select ステートメントの完全な使用方法を例を使用して説...

新しい CSS display:box プロパティの詳細な説明

1. ディスプレイボックス;要素にこのプロパティを設定すると、display:inline-bloc...

Linux 編集の開始、停止、再起動の Springboot jar パッケージ スクリプトの例

序文springboot設定ファイルでは、設定ファイルの名前には独自の意味と用途があります。 dev...

CSS3はNESゲームコンソールのサンプルコードを実装します

成果を達成する実装コードhtml <input type="radio" ...

ページデザインにおけるテーブルとdivの適切な適用についての簡単な説明

この記事の冒頭で、以前書いた入門記事の間違いを訂正したいと思います。初心者を再び誤解させないように、...

HTML初心者や初級者向けの提案。専門家は無視してかまいません。

感想:私はバックエンド開発者です。静的 (HTML) ページを取得すると、ページ構造と命名規則が極端...

Faint: 「Web2.0 を使用して標準に準拠したページを作成する」

今日、ある人がウェブサイト開発プロジェクトについて話をしてくれました。具体的な要件について話すと、「...

JS 正規マッチングの落とし穴の記録

最近、JS の正規表現マッチングの落とし穴を発見したのですが、その時はあまりにも奇妙だったので、何か...

HTMLのセマンティクスといくつかの簡単な最適化についての簡単な説明

1. セマンティゼーションとは何ですか? Bing辞書の説明セマンティクス化とは、適切な HTML ...

Vueのsync修飾子の詳細な説明

目次1. 手順2. 修飾語3. .sync 修飾子4. まとめ1. 手順指示とは命令です。文字通りの...

Ubuntu 20.04 中国語入力方法のインストール手順

この記事では、Google 入力方法をインストールします。実は以前はSogou入力方式を使っていたの...