次のシナリオをデバッグしようとしています。MySQL同時挿入により、(明示的な)トランザクションの外部でデッドロックが発生する
スキーマを次のように(?私はInnoDBは/自動内部コミットワット単一の文としてこれを扱うと仮定しても)これは、明示的なトランザクションの外部で行われます:あなたは上のユニーク索引がある見ることができるように
CREATE TABLE locks (
id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
lock_uid varchar(255) NOT NULL,
count smallint(6) NOT NULL,
processor_id varchar(255) DEFAULT NULL,
created_at timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
updated_at timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (id),
UNIQUE INDEX locks_lock_uid_unique (lock_uid)
)
lock_uid
を使用して、同じ値を持つ複数の行がテーブルに含まれないようにします。
スレッド1:
insert into `locks` (`lock_uid`, `count`, `processor_id`, `created_at`, `updated_at`)
values ('11161567', '0', NULL, '2017-11-07 10:46:36', '2017-11-07 10:46:36')
コマンドが実行され(コンテキストのために、これらは完全に正気のための一般的なクエリログから取得され、照合コマンドの外側のいずれかのスレッドには他の文はありません)
スレッド2:
insert into `locks` (`lock_uid`, `count`, `processor_id`, `created_at`, `updated_at`)
values ('11161567', '0', NULL, '2017-11-07 10:46:36', '2017-11-07 10:46:36')
これは、次のデッドロックになった:
LATEST DETECTED DEADLOCK
------------------------
2017-11-07 10:46:36 0x2ac88f791700
*** (1) TRANSACTION:
TRANSACTION 6089510736, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 4 lock struct(s), heap size 1136, 4 row lock(s), undo log entries 1
MySQL thread id 177584962, OS thread handle 47059008030464, query id 13109086103 ec2-34-232-58-13.compute-1.amazonaws.com 34.232.58.13 appserver update
insert into `locks` (`lock_uid`, `count`, `processor_id`, `created_at`, `updated_at`) values ('11161567', '0', NULL, '2017-11-07 10:46:36', '2017-11-07 10:46:36')
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 6403 page no 4 n bits 176 index locks_lock_uid_unique of table `core`.`locks` trx id 6089510736 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 107 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
0: len 30; hex 636865636b6f75745265636f7665727950726f636573735f313131363137; asc 111617; (total 32 bytes);
1: len 8; hex 0000000003266637; asc &f7;;
*** (2) TRANSACTION:
TRANSACTION 6089510734, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
4 lock struct(s), heap size 1136, 5 row lock(s), undo log entries 1
MySQL thread id 177584971, OS thread handle 47040888903424, query id 13109086092 ec2-34-237-3-244.compute-1.amazonaws.com 34.237.3.244 appserver update
insert into `locks` (`lock_uid`, `count`, `processor_id`, `created_at`, `updated_at`) values ('11161567', '0', NULL, '2017-11-07 10:46:36', '2017-11-07 10:46:36')
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 6403 page no 4 n bits 176 index locks_lock_uid_unique of table `core`.`locks` trx id 6089510734 lock mode S
Record lock, heap no 104 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
0: len 30; hex 636865636b6f75745265636f7665727950726f636573735f313131363135; asc 111615; (total 32 bytes);
1: len 8; hex 0000000003266632; asc &f2;;
Record lock, heap no 105 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
0: len 30; hex 636865636b6f75745265636f7665727950726f636573735f313131363135; asc 111615; (total 32 bytes);
1: len 8; hex 0000000003266634; asc &f4;;
Record lock, heap no 107 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
0: len 30; hex 636865636b6f75745265636f7665727950726f636573735f313131363137; asc 111617; (total 32 bytes);
1: len 8; hex 0000000003266637; asc &f7;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 6403 page no 4 n bits 176 index locks_lock_uid_unique of table `core`.`locks` trx id 6089510734 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 107 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
0: len 30; hex 636865636b6f75745265636f7665727950726f636573735f313131363137; asc 111617; (total 32 bytes);
1: len 8; hex 0000000003266637; asc &f7;;
*** WE ROLL BACK TRANSACTION (2)
私は同様の回答を読んでいます(例: MySQL locking in Duplicate Key Error)、このケースで何が起こっているのかよく分かりません。説明がデッドロック出力と一致しません。
- トランザクション外の2つの挿入でこのデッドロックが発生するのはなぜですか?
- Xに要求する前にT2がSロックを保持しているのはなぜですか?
「autocommit」の設定をもう一度確認してください。 'id'の必要性はありますか? –
潜在的に。私たちはORMを使用する代理キーがあれば、私たちのORMが私たちの意志に向かってかなり容易になるというトレードオフを持っています。 – AndySavage
私は2つの 'ユニーク'キー(1つが 'PRIMARY')を持つことが問題の一部であると心配しています。しかし、私はそれを証明することはできません。毎秒何百ものINSERTをやっていますか? –