「ロック待機タイムアウトを超えました。「スタックした」Mysqlテーブルのトランザクションを再起動してみてください。


131

スクリプトから、このようなクエリを何千回もローカルデータベースに送信しました。

update some_table set some_column = some_value

where部分を追加するのを忘れたので、同じ列がテーブル内のすべての行の同じaの値に設定され、これは何千回も実行され、列にインデックスが付けられたので、対応するインデックスがおそらく何度も更新されました。

時間がかかりすぎたため、問題が発生したため、スクリプトを強制終了しました。それ以来、コンピューターを再起動しましたが、単純なクエリの実行に非常に長い時間がかかり、関連するインデックスを削除しようとすると、次のメッセージが表示されて失敗するため、テーブルに何かが詰まっています。

Lock wait timeout exceeded; try restarting transaction

これはinnodbテーブルなので、トランザクションのスタックはおそらく暗黙的です。このテーブルを修正してスタックしたトランザクションを削除するにはどうすればよいですか?


3
の出力はSHOW FULL PROCESSLIST何ですか?
10

SHOW FULL PROCESSLISTコマンドのみが表示され、他には何も表示されません。これはローカル開発データベースです。何も実行されていません。そこからインデックスを削除しようとしたときに、コマンドラインに「lock wait ..」エラーメッセージが表示されました。
トム・

その場合、おそらく、相互に待機する必要のある異なるトランザクションで2つの個別の接続を作成します。
Wolph

その後、トランザクションを作成しませんでした。スクリプトを終了し、マシンを再起動し、コマンドラインからログインして見回しました。mysqlコマンドラインクライアント以外はデータベースを使用しなかったため、テーブルで何かがスタックしている必要があります。
トム

回答:


143

同様の問題があり、実行中のスレッドを確認することで解決しました。実行中のスレッドを表示するには、mysqlコマンドラインインターフェイスで次のコマンドを使用します。

SHOW PROCESSLIST;

mysqlコマンドラインインターフェイスにアクセスできない場合は、phpMyAdminから送信することもできます。
これにより、対応するIDと実行時間を持つスレッドのリストが表示されるため、実行に時間がかかりすぎるスレッドを強制終了できます。phpMyAdminには、KILLを使用してスレッドを停止するためのボタンがあります。コマンドラインインターフェースを使用している場合は、次の例のように、KILLコマンドの後にスレッドIDを指定するだけです。

KILL 115;

これにより、対応するスレッドの接続が終了します。


36
メモを取る!これは、この問題に関する多くのSOスレッドの1つで誰かによって言及されました:時々、テーブルをロックしたプロセスがプロセスリストでスリープしていると表示されます!問題のデータベースで開いているすべてのスレッドを(スリープ状態かどうかに関係なく)殺すまで、髪を引きちぎっていました。最後にテーブルのロックを解除し、更新クエリを実行しました。コメンターは、「MySQLスレッドがテーブルをロックし、MySQLに関連しない何かが発生するのを待つ間、スリープする場合がある」と述べました。
エリックL.

(私は関連する質問で、ここでその思考の断片を具体化するために私自身の回答を追加しました)
Eric L.

これは私を助けました。PHPStormデータベース管理/クエリ機能によって作成されたスリープ状態のスレッドがいくつかありました。
Ejaz 2016

すごい!5時間以降、特定して殺すことができる隠されたプロセスがありました。
Aldo Paradiso 2017年

2
これは解決策ではなく、感染した創傷をダクトでテーピングする以上の解決策はありません。根本的な問題に対処していない。
user2914191 2017

55

現在実行中のトランザクションを確認できます

SELECT * FROM `information_schema`.`innodb_trx` ORDER BY `trx_started`

それはリストの中で最も古いので、あなたのトランザクションは最初のものでなければなりません。次に、値を取得しtrx_mysql_thread_idKILLコマンドを送信します。

KILL 1234;

どのトランザクションが自分のものかわからない場合は、最初のクエリを頻繁に繰り返し、どのトランザクションが持続しているかを確認してください。


そのSQLを実行するためにrootアカウントを使用して、他のテーブルへのアクセスを実際にブロックしているトランザクションを確認する必要があるかもしれません
tom10271

40

ロックのInnoDBステータスを確認する

SHOW ENGINE InnoDB STATUS;

MySQLオープンテーブルを確認する

SHOW OPEN TABLES WHERE In_use > 0;

保留中のInnoDBトランザクションを確認する

SELECT * FROM `information_schema`.`innodb_trx` ORDER BY `trx_started`; 

ロックの依存関係を確認する-何が何をブロックするか

SELECT * FROM `information_schema`.`innodb_locks`;

上記の結果を調査すると、何がロックされているかを確認できるはずです。

問題の根本的な原因はコードにもある可能性があります-HibernateのようなJPAを使用している場合は、特に注釈について関連する関数を確認してください。

たとえば、ここで説明しいるように、次のアノテーションを誤用すると、データベースがロックされる可能性があります。

@Transactional(propagation = Propagation.REQUIRES_NEW) 

4
どうもありがとうございます!実行SELECT * FROM information_schema.innodb_trx t JOIN information_schema.processlist p ON t.trx_mysql_thread_id = p.idすると原因が明らかになりました:ロックスレッドが私のIPアドレスから送信されました...トランザクションの途中で残したデバッグコンソールを閉じるのを忘れていました...
Elias Strehle

40

これは、データベースのサイズが大きくなり、多くのトランザクションを実行していたときに起こりました。

真実は、おそらくクエリまたはDBのいずれかを最適化するいくつかの方法があるが、回避策の修正のためにこれらの2つのクエリを試してください。

これを実行してください:

SET GLOBAL innodb_lock_wait_timeout = 5000; 

そしてこれ:

SET innodb_lock_wait_timeout = 5000; 

2
参照リンク:innodb_lock_wait_timeout
culix

1
非常にビジーな11GBデータベースを実行しています。これは私のために働いた唯一のものです、ありがとう!
dongemus

永続的に保持したくない場合は、値を以前の値に変更することを忘れないでください。
Ricardo Martins

これは、一部のユーザーのエクスペリエンスが遅くなることを意味しますか?
アーノルドロア2018年

9

トランザクションの接続を確立すると、トランザクションを実行する前にロックを取得します。ロックを取得できない場合は、しばらくしてみてください。それでもロックを取得できない場合は、ロック待機時間超過エラーがスローされます。ロックを取得できないのは、接続を閉じていないためです。したがって、2回目にロックを取得しようとすると、以前の接続がまだ閉じられておらず、ロックを保持しているため、ロックを取得できません。

解決策: 接続を閉じるか、setAutoCommit(true)(設計に応じて)ロックを解放します。


7

MySQLを再起動します。正常に動作します。

しかし、このようなクエリがスタックしている場合は、問題のどこかにあることを注意してください:

  • クエリで(誤って配置された文字、デカルト積、...)
  • 編集する非常に多数のレコード
  • 複雑な結合またはテスト(MD5、部分文字列LIKE %...%など)
  • データ構造の問題
  • 外部キーモデル(チェーン/ループロック)
  • 誤ってインデックス化されたデータ

@syedrakibが言ったように、それは機能しますが、これはプロダクションにとって長生きするソリューションではありません。

注意:再起動を行うと、一貫性のない状態でデータに影響を与える可能性があります。

また、MySQLがEXPLAINキーワードを使用してクエリを処理する方法を確認し、クエリを高速化するために何か可能かどうかを確認できます(インデックス、複雑なテストなど)。


ありがとうございました。あなたは私の問題を直接解決しませんでしたが、私はテーブルロックに苦しみ、それはとても悪かったです。それはインターネット全体で唯一の投稿であり、外部キーをチェックするというアイデアに私を導きます。それで、主キーのキーは11で、外部キーは10であることがわかりました。それがどのように起こり、なぜすべてが以前は機能していたのかわかりません。
EscapeNetscape

@EscapeNetscapeどういたしまして。この小さな答えがあなたを助けてくれてうれしいです:)
Benj

3

mysqlでプロセスに移動します。

タスクがまだ機能していることがわかります。

特定のプロセスを強制終了するか、プロセスが完了するまで待ちます。


7
それは問題を解決します。しかし、これはLIVEプロダクションサーバーのソリューションにはなりません......このデッドロック処理を出力するにはどうすればよいですか または、このデッドロックの発生を回避するにはどうすればよいですか?
Rakib、2012年

1
まあ、たまたま、開発者によって書かれたものではなく、フレームワークのアクティブレコードインターフェースによって書かれた、完全に整形式で完全にエスケープされたmysqlクエリを使用しても、ロック待機タイムアウトの問題が発生する可能性があります。したがって、適切なmysqlクエリを記述しないことがここでの要因です。
Rakib

1

「更新」文で同じ問題に遭遇しました。私の解決策は、テーブルのphpMyAdminで使用可能な操作を単に実行することでした。テーブルを最適化、フラッシュ、および最適化しました(この順序ではありません)。テーブルを削除してバックアップから復元する必要はありません。:)


1
それは問題を解決するかもしれません。しかし、そのようなエラーが発生するたびにこれを実行しなければならないことは、LIVEプロダクションサーバーの解決策にはなりません。このデッドロック処理をどのように出力できますか?または、このデッドロックの発生を回避するにはどうすればよいですか?
Rakib、2012年

1

同じ問題がありました。SQLのデッドロックの問題だったと思います。タスクマネージャーからSQLプロセスを強制的に閉じることができます。それでも問題が解決しない場合は、コンピュータを再起動してください。テーブルを削除してデータをリロードする必要はありません。


それは問題を解決します。しかし、これはLIVEプロダクションサーバーのソリューションにはなりません......このデッドロック処理を出力するにはどうすればよいですか または、このデッドロックの発生を回避するにはどうすればよいですか?
Rakib、2012年

Apacheとそのサービス(または少なくともMySQL)を再起動します。再起動する必要はありません
Amjo

1

特定のグループのレコードを削除しようとすると、この問題が発生しました(Webサーバー上のMySQLへのODBC接続でMS Access 2007を使用)。通常、MySQLから特定のレコードを削除してから、更新されたレコードで置き換えます(複数の関連レコードをカスケード削除します。これにより、1つのレコードの削除ですべての関連レコードの削除が効率化されます)。

テーブルに対してphpMyAdminで使用可能な操作(optimize、flushなど)を実行しようとしましたが、フラッシュしようとすると、RELOADエラーの権限が必要になりました。データベースがWebサーバー上にあるため、データベースを再起動できませんでした。バックアップからの復元はオプションではありませんでした。

Web上のcPanel mySQLアクセスで、このレコードのグループに対して削除クエリを実行してみました。同じエラーメッセージが表示された。

私の解決策:Sun(Oracle)の無料のMySQLクエリブラウザ(以前に自分のコンピュータにインストールしたもの)を使用して、そこで削除クエリを実行しました。問題は解決しました。その後、MySQL接続へのODBCアクセスを使用して、Accessスクリプトを使用して機能をもう一度実行することができました。


-2

修正しました。

クエリに挿入するデータ型が一致していないことを確認してください。「ユーザーブラウザーエージェントのデータ」を試していて、VARCHAR(255)このロックに問題があるという問題がありましたが、変更するTEXT(255)と修正されました。

そのため、おそらくデータタイプの不一致です。


-151

テーブルを削除してバックアップから復元することで問題を解決しました。


20
ちなみに、この回答は、SOの史上最低スコアの「承認済み」回答であることを称えるものです。🏆
ashleedawg

1
これは、一般的に、スコアが最も低い回答でもあります
Bob Kerman
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.