[前][次][番号順一覧][スレッド一覧]

mysql:15005

From: goto <goto <gotou1213@xxxxxxxxxx>>
Date: Tue, 1 Sep 2009 00:53:02 +0900
Subject: [mysql 15005] 1行も削除されないDELETE文によるロック

こんばんは。ごとうと申します。

INNODBで下の様な主キーが複合のテーブルに対して、
・第1キーを指定して一括DELETE
・同じ第1キーで複数件INSERT
という処理を1トランザクションで行おうとしています。

--
CREATE TABLE test
(
  a INT NOT NULL,
  b INT NOT NULL,

  PRIMARY KEY (a, b)
) TYPE = INNODB;

BEGIN;
DELETE FROM test WHERE a = 1;

INSERT INTO test (a, b) VALUES (1, 1);
INSERT INTO test (a, b) VALUES (1, 2);
...
COMMIT;
--

この処理が↓のような順番で2接続で同時に実行されたとき、デッドロックしました。

--
接続1> BEGIN;
接続1> DELETE FROM test WHERE a = 1;            <-- 該当行なし

接続2> BEGIN;
接続2> DELETE FROM test WHERE a = 2;            <-- 該当行なし
接続2> INSERT INTO test (a, b) VALUES (2, 1);   <-- ブロックされる

接続1> INSERT INTO test (a, b) VALUES (1, 1);   <-- デッドロック
ERROR 1213 (40001): Deadlock found when trying to get lock; try
restarting transaction
--

詳しく調べたところ、上の両方のDELETEで1行も削除されなかったときだけ
(テーブルが空だった場合など)デッドロックが発生するようでした。
接続1は a=1 のみ処理し、接続2は a=2 のみ処理しているので問題ないように思うのですが・・・

ひとまず、DELETEの前に SELECT 〜 FOR UPDATE で行が存在するかを確認するようにすると
デッドロックはしなくなりましたが、上記のような「一括削除→複数挿入」の
処理をする場合、どのようにするのが一般的でしょうか?



また、色々実験してみたところ、
↓の様な、主キーが一つだけのテーブルでも同じ現象が発生しました。

--
CREATE TABLE test
(
  id INT NOT NULL,
  PRIMARY KEY (id)
) TYPE = INNODB;

接続1> BEGIN;
接続1> DELETE FROM test WHERE id = 1; <-- 該当行なし

接続2> BEGIN;
接続2> DELETE FROM test WHERE id = 2; <-- 該当行なし
接続2> INSERT INTO test VALUES (2);   <-- ブロックされる

接続1> INSERT INTO test VALUES (1);   <-- デッドロック
ERROR 1213 (40001): Deadlock found when trying to get lock; try
restarting transaction
--

これも削除される行があればデッドロックはしなかったので、
DELETE文で削除される行がある場合は、その行のみロックされ、
削除される行が無い場合はそのテーブル全体へのINSERTがブロックされる
ような気がするのですが、そういうものなのでしょうか?


MySQLのバージョンは「5.0.51a」と「5.1.32」で試しています。
トランザクション隔離レベルは最初デフォルトの「REPEATABLE READ」で試していましたが、
「READ UNCOMMITTED」でも同じ結果になりました。

よろしくお願いします。

[前][次][番号順一覧][スレッド一覧]

->   15005 2009-09-01 00:53 [goto <gotou1213@xxxx] 1行も削除されないDELETE文によるロック  
     15006 2009-09-01 10:01 ┗[HIRATSUKA Sadao <hir]                                       
     15007 2009-09-01 22:42  ┗[<gotou1213@xxxxxxxxx]