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カウンターとデータクリーニングの適用

推薦する

Docker で Zookeeper をインストールする (スタンドアロンおよびクラスター)

Docker を起動したら、利用できるオプションを見てみましょう。 公式のものがある場合は、もちろ...

フロントエンド開発者のための HTML 入門

1 HTML入門1.1 初めてのコード体験、最初のウェブページの作成XML/HTML コードコンテン...

Dockerイメージ内のnoneイメージ操作を削除する

普段はdocker buildコマンドでイメージを生成していますが、コードの更新が頻繁に行われるとn...

JavaScript は大容量ファイルのアップロード処理を実装します

数十 MB 程度の小さいものから 1G 以上の大きいものまで、ビデオ ファイルなどのファイルのアップ...

Vue で v-if と v-for を一緒に使用することが推奨されない理由の詳細な説明

この記事では主に、v-if と v-for を一緒に使用することが推奨されない理由を紹介します。詳細...

MySQL 5.7 でパスワードを変更する簡単な方法

これは公式のスクリーンショットです。MySQL 5.7 をインストールすると、デフォルトのパスワード...

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

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

HTMLハイパーリンクaタグのhrefジャンプとonclick間の実行順序の例

HTMLハイパーリンクaタグのhrefジャンプとonclickの実行関係htmlのaタグのhrefは...

YUMを使用してdockerをインストールする方法

次の図に示すように: Centos 7.0以上であれば問題ありません。現在のシステム カーネル バー...

アコーディオン効果を実現するネイティブ js

実際のWebページ開発でも、アコーディオンは頻繁に登場します。簡単なアコーディオンを作ったのですが、...

コンパイル/サーバーなしでブラウザにCommonJSモジュールを実装する

目次導入1. one-click.jsとは2. パッケージングツールはどのように機能しますか? 3....

知っておくべき 18 の Web ユーザビリティの原則

世界最高のビジュアル デザイン スキルを持っていたとしても、訪問者がページ間やアイテム間を快適に移...

JavaScript を使用した数独の完全な実装プロセス

目次序文数独の解き方最初のボックスに記入してください2番目のボックスに記入してください3番目のボック...

@Font-face の基本的な使い方と、すべてのブラウザと互換性を持たせる方法

@Font-face 基本紹介: @font-face は、Web ページにカスタム フォントを表示...

CSSは5つの一般的な2D変換を実装します

CSS の 2D 変換を使用すると、移動、回転、拡大縮小、変形などの基本的な変換操作を 2 次元空間...