MySQL InnoDB Deadlock สำหรับการสืบค้นง่ายๆ 2 แบบ


10

ฉันมีการหยุดชะงักสำหรับข้อความค้นหาแทรกสองรายการนี้:

insert into PlayerClub (modifiedBy, timeCreated, currentClubId, endingLevelPosition, nextClubId, account_id) values (0, '2014-12-23 15:47:11.596', 180, 4, 181, 561)

insert into PlayerClub (modifiedBy, timeCreated, currentClubId, endingLevelPosition, nextClubId, account_id) values (0, '2014-12-23 15:47:11.611', 180, 4, 181, 563)

นี่คือสถานะ InnoDB:

------------------------
LATEST DETECTED DEADLOCK
------------------------
2014-12-23 15:47:11 1f4c
*** (1) TRANSACTION:
TRANSACTION 19896526, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 5 lock struct(s), heap size 1248, 3 row lock(s), undo log entries 1
MySQL thread id 17988, OS thread handle 0x17bc, query id 5701353 localhost 127.0.0.1 root update
insert into PlayerClub (modifiedBy, timeCreated, currentClubId, endingLevelPosition,  nextClubId, account_id) values (0, '2014-12-23 15:47:11.596', 180, 4, 181, 561)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 49735 page no 4 n bits 72 index `UK_cagoa3q409gsukj51ltiokjoh` of   table `db`.`playerclub` trx id 19896526 lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

*** (2) TRANSACTION:
TRANSACTION 19896542, ACTIVE 0 sec inserting, thread declared inside InnoDB 5000
mysql tables in use 1, locked 1
5 lock struct(s), heap size 1248, 3 row lock(s), undo log entries 1
MySQL thread id 17979, OS thread handle 0x1f4c, query id 5701360 localhost 127.0.0.1    root update
insert into PlayerClub (modifiedBy, timeCreated, currentClubId, endingLevelPosition,   nextClubId, account_id) values (0, '2014-12-23 15:47:11.611', 180, 4, 181, 563)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 49735 page no 4 n bits 72 index `UK_cagoa3q409gsukj51ltiokjoh` of   table `db`.`playerclub` trx id 19896542 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 49735 page no 4 n bits 72 index `UK_cagoa3q409gsukj51ltiokjoh` of    table `db`.`playerclub` trx id 19896542 lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

*** WE ROLL BACK TRANSACTION (2)

คีย์ foriegn เดียวในตารางนี้คือ "account_id"

ความคิดใด ๆ

แก้ไข: นี่คือข้อมูล PlayerClub ของฉัน:

CREATE TABLE `PlayerClub` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `modifiedBy` bigint(20) DEFAULT NULL,
  `timeCreated` datetime NOT NULL,
  `account_id` bigint(20) DEFAULT NULL,
  `currentClubId` bigint(20) DEFAULT NULL,
  `endingLevelPosition` int(11) NOT NULL,
  `nextClubId` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UK_cagoa3q409gsukj51ltiokjoh` (`account_id`),
  KEY `FK_cagoa3q409gsukj51ltiokjoh` (`account_id`),
  CONSTRAINT `FK_cagoa3q409gsukj51ltiokjoh` FOREIGN KEY (`account_id`) REFERENCES   `PlayerAccount` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1

คุณทำอะไรในแต่ละรายการก่อนที่จะถึงการหยุดชะงัก
Michael - sqlbot

เกิดอะไรขึ้นถ้าคุณออกคำสั่งหลังจากแทรกแต่ละครั้งแล้วลอง? แจ้งให้เราทราบ ..
Nawaz Sohail

SHOW CREATE TABLE PlayerClubโปรด. ซึ่งมักเกี่ยวข้องกับดัชนี
Jehad Keriaki

คำตอบ:


13

นี่คือข้อเท็จจริง

นี่คือ INSERT สองอัน

insert into PlayerClub (modifiedBy, timeCreated, currentClubId, endingLevelPosition, nextClubId, account_id) values (0, '2014-12-23 15:47:11.596', 180, 4, 181, 561)
insert into PlayerClub (modifiedBy, timeCreated, currentClubId, endingLevelPosition, nextClubId, account_id) values (0, '2014-12-23 15:47:11.611', 180, 4, 181, 563)

นี่คือสองบรรทัดจากคุณ SHOW ENGINE INNODB STATUS\G

RECORD LOCKS space id 49735 page no 4 n bits 72 index `UK_cagoa3q409gsukj51ltiokjoh` of   table `db`.`playerclub` trx id 19896526 lock_mode X insert intention waiting
RECORD LOCKS space id 49735 page no 4 n bits 72 index `UK_cagoa3q409gsukj51ltiokjoh` of   table `db`.`playerclub` trx id 19896542 lock_mode X

สังเกต

คุณทำ INSERT ด้วยสอง account_ids ที่แตกต่างกัน: 561 และ 563

พวกเขามีเอกลักษณ์และไม่ควรมีปัญหาใช่มั้ย ไม่ถูกต้อง !!!

เนื่องจากดัชนีกลุ่มของ InnoDB อาจมีการหยุดชะงักได้ ทำไม

มองย้อนกลับไปที่ INSERT ทั้งสองของคุณ PRIMARY KEYID บนในไม่ได้ระบุ มันจะต้องสร้างขึ้นโดยอัตโนมัติ คีย์อื่นที่ไม่ใช่คีย์หลัก (เฉพาะหรือไม่ซ้ำกัน) จะมีคีย์หลักติดอยู่

โปรดทราบว่าเอกสารประกอบ MySQL เกี่ยวกับวิธีการที่ดัชนีรองและ aa คีย์หลักมีความสัมพันธ์กัน :

ดัชนีทั้งหมดนอกเหนือจากดัชนีคลัสเตอร์รู้จักกันว่าดัชนีรอง ใน InnoDB แต่ละระเบียนในดัชนีรองประกอบด้วยคอลัมน์คีย์หลักสำหรับแถวรวมถึงคอลัมน์ที่ระบุสำหรับดัชนีรอง InnoDB ใช้ค่าคีย์หลักนี้เพื่อค้นหาแถวในดัชนีคลัสเตอร์

หากคีย์หลักยาวดัชนีรองจะใช้พื้นที่เพิ่มขึ้นดังนั้นจึงมีประโยชน์ที่จะมีคีย์หลักแบบสั้น

แม้ว่าคุณกำลังแทรก account_id 561 และ 563 ภายใต้ประทุนคุณจะแทรก561-(id)และ563-(id)เข้าสู่UK_cagoa3q409gsukj51ltiokjohดัชนี PRIMARY KEYกลายเป็นคอขวดเพราะดัชนีรองได้ต้องรอจนกว่าidคอลัมน์ auto_generated

คำแนะนำ

คุณมีตารางที่มีปุ่มผู้สมัครสองคน

  • PRIMARY KEY บน id
  • UNIQUE KEY บน UK_cagoa3q409gsukj51ltiokjoh

เนื่องจากทั้งสองอย่างนี้BIGINTคุณสามารถเพิ่มประสิทธิภาพและมีPlayerClubตารางที่เล็กลงโดยกำจัดidและยังคงความเป็นเอกลักษณ์ไว้UK_cagoa3q409gsukj51ltiokjohเช่นเดียวกับการหลีกเลี่ยงสถานการณ์การหยุดชะงักนี้


1
เฉพาะหลังจากลบคีย์ foriegn เดียวเท่านั้นในตารางนี้คือ "account_id" การหยุดชะงักเกิดขึ้น
Urbanleg
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.