InnoDBデッドロックはINSERT / UPDATE / DELETE専用ですか?


8

私は「ロックを取得しようとすると、デッドロックが見つかっ、トランザクションを再起動してみてください」MySQLのエラーを回避作業

デッドロックを許可するようにプログラムを更新する必要があります。SELECTステートメントがデッドロックエラーを生成する可能性はありますか?私はそれが読み取りロックであることを知っているので、複数の選択は問題になりませんがINSERTUPDATEまたは、DELETEステートメント(結合でサブクエリが可能)SELECTステートメント(結合またはサブクエリで可能)がある場合はどうなりますか?

それがエラーがでスローされる可能性がありますSELECT代わりにINSERTUPDATEまたはDELETE

好奇心旺盛な人なら、ここに物語があります。


これに対する+1は良い質問です。これは、InnoDBテーブルに対するSELECTと組み合わせて、ほとんどの人が知らないInnoDBの癖を明らかにするためです。
RolandoMySQLDBA 2011

回答:


5

質問のタイトルに対する直接の答えは「いいえ」です。

SELECTクエリは、クラスター化インデックスとも呼ばれるgen_clust_indexに対してロックを実行できます。

以下は、これらの質問をした人である@RedBlueThing積極的に調べた3つのDBA Stack Exchanges 質問です。@RedBlueThingは、彼の質問に対する回避策を見つけました。

質問の全体像を保つために、これらの回答をよく見ると(あまり深く見てはいけません。自分の複雑な回答を見てもめまいがします)、SELECTクエリがデータをロックできることがすぐにわかります。

また、特定の行をオンデマンドでロックできるSELECTの特殊なケースもあります

UPDATE 2011-08-08 16:49 EDT

バリエーションに関する質問:「InnoDBデッドロック例外がSELECTによってスローされる可能性がありますか?」これに対する答えは、特定の条件下では[はい]になります。その状態は何ですか?エラーの結果として単一のSQLステートメントのみがロールバックされた場合、ステートメントによって設定されたロックの一部が保持される可能性があります。これは、InnoDBが行ロックを、どのロックがどのステートメントによって設定されたのか後で確認できないような形式で格納するために発生します

そのステートメントに基づくと、これを引き起こすイベントのシーケンスは理論的には次のようになります。

  • SQLは単一行を更新しますが、エラーを生成します
  • UPDATEは1行のロールバックを引き起こします
  • 行に残っているロックがあります

個人的には、その最後の発言は私を怖がらせます。MySQLがこの癖をすべての人に知らせるのは良かったでしょう。しかし、そのステートメントはMySQLドキュメントからのものです。(そうそう、OracleはInnoDBを所有している)

UPDATE 2015-09-22 18:40 EST

その年の初めに、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以前を使用している場合、ロックを解放するには、スリープ状態のすべての接続を強制終了する必要があります。


@Rolando-読み取りをブロックしないInnoDBのMVCCでは(for updateもちろん、使用する場合を除いて)、そうではありませんか?
ジャックはtopanswers.xyzしようと言う

@ジャック-最初の3つの箇条書きのリンクを読むと、MVCCが問題になっていないことがわかります。これは、MVCCでも軽減できないクラスター化インデックスの深いデッドロックです。
RolandoMySQLDBA

@Rolando-リンクをもう少し注意深く読みましたが、正常selectが行をロックしたり、別のトランザクションのDMLによって何らかの方法でブロックされたりする可能性を示す兆候がまだありません。これは確かにOracleに当てはまり、私が知る限りInnoDBにも当てはまりますか?selectもちろん、ステートメントが実際に関数または他の何らかの迂回ルートを介してDML を実行する場合を除きます。
ジャックはtopanswers.xyzを試してみると11

@ジャック-SELECTがインデックスをブロックできる場合、最初の3つのリンクで示されているように、UPDATEはさらにどれほど多くなります。
RolandoMySQLDBA 2011
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.