2016-10-18 9 views
1

次のトランザクションの並列に実行されているので、最近、私は起こってMySQLのデッドロックに実行した:は、さらに別のMySQLは、挿入のデッドロック/削除

(given `ei_id` and `dst_site`) 
    SELECT id from item_specifics WHERE ei_id=X AND dst_site=Y; 
(run only if any ids from above select) 
    DELETE FROM item_specifics WHERE id in (2,3,1); 
(next multiple inserts are executed) e.g. 
    INSERT INTO item_specifics (category_id, name, value, dst_name, dst_value, 
           src_site, dst_site, ebay_category_id, type, 
           ei_id, name_translation_source, value_translation_source) 
     VALUES (NULL, 'MPN', '65104703', 'MPN', '65104703', 
       'UK', 'IT', NULL, 'S', 
       72111556, 'Y', 'Y'); 
    INSERT INTO item_specifics (category_id, name, value, dst_name, dst_value, 
          src_site, dst_site, ebay_category_id, type, 
          ei_id, name_translation_source, value_translation_source) 
     VALUES (NULL, NULL, NULL, 'Talia', 'L', 
       'UK', 'IT', NULL, 'D', 
       72111556, 'Y', 'Y'); 

表の定義:

CREATE TABLE `item_specifics` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `when_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `category_id` int(11) DEFAULT NULL, 
    `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, 
    `value` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, 
    `dst_name` varchar(255) DEFAULT NULL, 
    `dst_value` varchar(255) DEFAULT NULL, 
    `src_site` varchar(4) NOT NULL, 
    `dst_site` varchar(4) NOT NULL, 
    `ebay_category_id` varchar(10) DEFAULT NULL, 
    `type` varchar(1) NOT NULL DEFAULT 'S' COMMENT 'S - source, D - destination', 
    `ei_id` int(11) DEFAULT NULL, 
    `state` varchar(1) NOT NULL DEFAULT 'A', 
    `name_translation_source` char(1) DEFAULT NULL, 
    `value_translation_source` char(1) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `ei_id` (`ei_id`,`dst_site`,`name`,`value`), 
    KEY `category_id` (`category_id`), 
    KEY `idx_item_specifics_dst` (`src_site`,`dst_site`,`dst_name`,`dst_value`,`ebay_category_id`), 
    KEY `ebay_category_id` (`ebay_category_id`), 
    KEY `name_dst_name` (`name`,`dst_name`), 
    KEY `value_dst_value` (`value`,`dst_value`), 
    KEY `dst_site` (`dst_site`), 
    KEY `idx_platform2` (`platform`,`value`,`name`,`src_site`), 
    CONSTRAINT `item_specifics_ibfk_2` FOREIGN KEY (`category_id`) 
     REFERENCES `ebay_categories` (`id`), 
    CONSTRAINT `item_specifics_ibfk_5` FOREIGN KEY (`ei_id`) 
     REFERENCES `original_items` (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=871759967 DEFAULT CHARSET=utf8 
      STATS_PERSISTENT=0 STATS_AUTO_RECALC=0 

SHOW ENGINE INNODB STATUS

------------------------ 
LATEST DETECTED DEADLOCK 
------------------------ 
2016-10-18 11:47:49 7f9e6f72c700 
*** (1) TRANSACTION: 
TRANSACTION 189044299927, ACTIVE 0 sec inserting 
mysql tables in use 2, locked 2 
LOCK WAIT 13 lock struct(s), heap size 2936, 24 row lock(s), undo log entries 11 
MySQL thread id 121701505, OS thread handle 0x7fa078764700, query id 89285938631 10.0.25.162 consumer update 
*** (1) WAITING FOR THIS LOCK TO BE GRANTED: 
RECORD LOCKS space id 153 page no 1422842 n bits 480 index `ei_id` of table `wi`.`item_specifics` trx id 189044299927 lock mode S waiting 
*** (2) TRANSACTION: 
TRANSACTION 189044300080, ACTIVE 0 sec inserting 
mysql tables in use 2, locked 2 
15 lock struct(s), heap size 2936, 35 row lock(s), undo log entries 17 
MySQL thread id 121711228, OS thread handle 0x7f9e6f72c700, query id 89285942437 10.0.27.182 consumer update 
INSERT INTO item_specifics (category_id, name, value, dst_name, dst_value, src_site, dst_site, ebay_category_id, type, ei_id, name_translation_source, value_translation_source) VALUES (NULL, NULL, NULL, 'MPN', '65104703', 'UK', 'IT', NULL, 'D', 72111556, 'Y', 'Y') 
*** (2) HOLDS THE LOCK(S): 
RECORD LOCKS space id 153 page no 1422842 n bits 480 index `ei_id` of table `wi`.`item_specifics` trx id 189044300080 lock_mode X locks rec but not gap 
*** (2) WAITING FOR THIS LOCK TO BE GRANTED: 
RECORD LOCKS space id 153 page no 1422842 n bits 480 index `ei_id` of table `wi`.`item_specifics` trx id 189044300080 lock_mode X locks gap before rec insert intention waiting 
*** WE ROLL BACK TRANSACTION (1) 

トランザクションは別個ので実行されます2つの並列トランザクションの場合、ei_idが共通で、dst_siteのみが異なることがあります。

innodbステータスで表示されるデッドロッククエリは、nameフィールドとvalueフィールドのNULL値を常に表示します(当然のことです)。また、(1)のトランザクションについてのクエリはまったくありません。

インサートは(エンドで行われるNULL namevalue挿入を意味する)を降順にnamevalueの順序で実行されています。

なぜ私にとって興味深いのは、そのようなデッドロックが発生する理由です。 再試行操作でジョブが完了するので問題はありませんが、これで数日間戦ってきました。理由は何か不思議で、ローカルで再現できるかどうかだけです。助けにはならなかった

アクション:

  • トランザクション外

答えて

0

を選択クエリを移動する選択クエリ

  • FOR UPDATEを追加SELECTの最後にFOR UPDATEを追加します。これは、あなたが何かしようとしているという手掛かりをエンジンに与えます。デッドロックを「待機」に変える可能性があります。これははるかに侵略的ではありません。

    (追加)FOR UPDATEがなければ、特定の行をロックする必要があることを認識する前に、トランザクションにさらに近づく可能性があります。その時点で、単に待つだけではなく、デッドロックができます。

    また、デッドロックが発生したときにトランザクション全体を再試行するようにアプリに指示します。

  • +0

    私はあなたの答えリックをありがとう。私が上に書いたように、私はデッドロックを修正することに本当に関心がありません(なぜなら、再試行は常に助けになるからです)。しかし、なぜそれが最初に起こるのかを知りたいです。 – matino

    +0

    私はこの問題のあいまいな説明を追加しました。おそらく理論的な議論が必要です。 –

    +0

    残念ながら 'FOR UPDATE'を追加しても役に立たなかった – matino

    関連する問題