9

主キーを使用して 1 つのテーブルに対して 1 つの行をそれぞれ削除する 2 つの重複クエリがデッドロックする可能性があることを理解していません。誰でも説明できますか?

トランザクションの 1 つがロックを取得し、もう 1 つが待機する必要があるように思えます。

クエリを含むデッドロック レポートは次のとおりです。

Fri Jun 01 2012 13:50:23
*** (1) TRANSACTION:
TRANSACTION 3 1439005348, ACTIVE 0 sec, process no 22419, OS thread id 1166235968 starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 368
MySQL thread id 125597624, query id 3426379709 node3-int 10.5.1.119 application-devel updating
DELETE FROM `SessData` WHERE `SessKey` = '87EDF1479A275557AC8280DCA78AB886'
AND `Name` = 'CurrentRequestURL'

*** (2) TRANSACTION:
TRANSACTION 3 1439005340, ACTIVE 0 sec, process no 22419, OS thread id 1234073920 starting index read, thread declared inside InnoDB 0
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1216
MySQL thread id 125597622, query id 3426379705 node2-int 10.5.1.118 application-devel updating
DELETE FROM `SessData` WHERE `SessKey` = '87EDF1479A275557AC8280DCA78AB886'
AND `Name` = 'CurrentRequestURL'

*** WE ROLL BACK TRANSACTION (2)

テーブルのスキーマは次のとおりです。

CREATE TABLE  `application`.`SessData` (
  `SessKey` varchar(255) NOT NULL default '',
  `Name` varchar(255) NOT NULL default '',
  `Value` varchar(255) default NULL,
  PRIMARY KEY  (`SessKey`,`Name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

その他の詳細:

MySQL version: 4.1.21
Isolation level: REPEATABLE-READ
Character set on the the above columns: latin1
4

3 に答える 3

4

MySQL バージョン 4.1.21 を使用しています。4.1 はサポート終了となり、4.1.21 は最新の 4.1 バージョンではありません。( MySQL 4.1 の延長サポートは 2009 年 12 月 31 日に終了しました。) 少なくとも 5.0.96 にアップグレードする必要がありますが、5.5.25 に完全に更新することもできます。それができない場合は、 4.1.22へのアップグレードが最低限のことですが、おそらく問題は解決しません。

MySQL 4.1ドキュメントの最後の例を読むと、削除される行が以前にトランザクションで共有ロックを使用して選択されていた場合に、このデッドロックがどのように発生するかがわかります。同様に、関連する外部キー制約がある場合、共有ロックを取得できた可能性があります。一般的な問題は次のとおりです。

A は x の共有ロックを取得します

B は x の排他ロックを待ちます。A のロックのために待機する必要があります。

A は x の排他ロックを待ちます。排他ロックのキューで B が先行しているため、待機する必要があります。

InnoDB がロックを処理する方法では、B が同じ排他ロックを待機している間、A の共有ロックを排他にアップグレードしないため、これはデッドロックです。

または、2 つのステートメントの両方が存在しない行を削除しようとしている場合 (直前の 3 回目の重複削除によって削除された可能性があります)、バグが発生している可能性があります。おそらく関連しています:

于 2012-06-08T20:33:57.207 に答える
1

約 1 年前に、誰かが同様のデッドロック状況のトラブルシューティングを支援したことを覚えています。

InnoDB のデッドロックは、特定の状況下で SELECT ステートメントによって引き起こされる可能性があるという事実を見逃してはなりません。 4470#4470 (2011 年 8 月 8 日)

あなたのを見てくださいSHOW INNODB ENGINE STATUS\G。MySQL 4.1 を使用しているため、情報は問題を明らかにするのに必要なほど完全ではありません。

それにもかかわらず、ここで何が起こっているのですか?基本的に、クラスター化インデックス( gen_clust_indexとも呼ばれます) をロックしています。まったく同じ行に対する 2 つのロックは、クラスター化インデックス内の同じ行とその gen_clust_index エントリをロックします。

排他的にロックできるのは 1 つだけです。もう 1 つは排他的ですが待機中としてロックされます。もちろん、最後の排他ロックが勝たなければなりませんでした。両方のトランザクションが同時にタイムアウトした場合、これは一方または両方で 50 秒 (innodb_lock_wait_timeout のデフォルト) で発生したに違いありません。

では、誰がロールバックされるのでしょうか? SHOW INNODB ENGINE STATUS\GMySQL 4.1によると、最初にクラスター キー エントリを取得したTRANSACTION (2)ため、ほこりをかぶってロールバックします。TRANSACTION (1)

于 2012-06-14T17:02:18.747 に答える