私は MySQLエラーの回避策「ロックを取得しようとしたときにデッドロックが見つかりました。トランザクションを再起動してみてください」 。
デッドロックを許可するようにプログラムを更新する必要があります。 SELECT
ステートメントがデッドロックエラーを生成する可能性はありますか?私はそれが読み取りロックだけであることを知っているので、複数の選択は問題にはなりませんが、INSERT
、UPDATE
またはDELETE
ステートメントがある場合はどうですか(結合でサブクエリが可能)およびSELECT
ステートメント(結合またはサブクエリで可能)?
エラーがSELECT
、INSERT
またはUPDATE
ではなくDELETE
でスローされる可能性はありますか?.
質問のタイトルに対する直接の答えは「いいえ」です。
SELECTクエリは、クラスタードインデックスとも呼ばれる gen_clust_index に対してロックを実行できます。
以下は、これらの質問をした人である @ RedBlueThing で積極的に調べたDBAスタック交換に関する3つの質問です。 @RedBlueThingは彼の質問に対して回避策を見つけました。
質問の観点を維持するために、これらの回答をよく見ると(あまり深く見てはいけません。自分の複雑な回答を見てもめまいがします)、SELECTクエリがデータをロックできることがすぐにわかります。
必要に応じて特定の行をロックできるSELECTの特殊なケースもあります 。
UPDATE 2011-08-08 16:49 EDT
バリエーションに関する質問:「InnoDBのデッドロック例外はSELECTによってスローされる可能性がありますか?」これに対する答えは、特定の条件下では[はい]になります。その状態は何ですか? エラーの結果として単一のSQLステートメントがロールバックされた場合、ステートメントによって設定されたロックの一部が保持される可能性があります。これは、InnoDBが行ロックを後でどのロックを認識できないような形式で格納するために発生しますステートメントによって設定された 。
そのステートメントに基づいて、これを引き起こすイベントのシーケンスは理論的には次のようになります:
個人的には、その最後の発言は私を怖がらせます。 MySQLがこの気まぐれをすべての人に知らせるのはいいことでした。しかし、そのステートメントはMySQLドキュメントからのものです。 (そうそう、OracleはInnoDBを所有している)
その年の初めに、私は PerconaがクールなNagiosチェックを持っている がスリープ状態の接続の背後に隠れているこれらの厄介なロックを見つけることを学びました。あとは、そのリンクからコードを実行するだけです。
SELECT COALESCE(MAX(IF(p.command = 'Sleep', p.time, 0)), 0) AS idle_in_trx
FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS AS w
INNER JOIN INFORMATION_SCHEMA.INNODB_TRX AS b ON b.trx_id = w.blocking_trx_id
INNER JOIN INFORMATION_SCHEMA.INNODB_TRX AS r ON r.trx_id = w.requesting_trx_id
LEFT JOIN INFORMATION_SCHEMA.PROCESSLIST AS p ON p.id = b.trx_mysql_thread_id;
これはMySQL 5.5以降でのみ機能します。 MySQL 5.1以前を使用している場合、ロックを解放するには、スリープ状態の接続をすべて強制終了する必要があります。