MySQL InnoDB тупик Для двох простих запитів вставки


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)

Єдиним попереднім ключем у цій таблиці є "account_id".

Будь-які ідеї?

EDIT: Ось моя інформація про 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будь ласка. Зазвичай це стосується індексів.
Джехад Керіакі

Відповіді:


13

ТУТ Є ФАКТИ

Ось два ВСТАВКИ

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 все ще може бути глухий кут. Чому?

Погляньте на свої два ВСТАВКИ. Ідентифікатор PRIMARY KEYввімкнення не вказаний. Він повинен бути створений автоматично. Будь-який ключ, окрім ПЕРВИЧНОГО КЛЮЧА (унікальний чи не унікальний), додасть PRIMARY KEY.

Зверніть увагу на Документацію MySQL про те, як вторинний індекс та первинний ключ переплітаються :

Усі індекси, крім кластеризованого індексу, відомі як вторинні індекси. У InnoDB кожен запис у вторинному індексі містить стовпці первинного ключа для рядка, а також стовпці, визначені для вторинного індексу. InnoDB використовує це значення основного ключа для пошуку рядка в кластерному індексі.

Якщо первинний ключ довгий, вторинні індекси використовують більше місця, тому вигідно мати короткий первинний ключ.

Хоча ви вставляєте account_id 561 і 563, під кришкою ви вставляєте 561-(id)і 563-(id)в UK_cagoa3q409gsukj51ltiokjohіндекс. Це PRIMARY KEYстає вузьким місцем, тому що вторинний індекс повинен зачекати, поки idстовпець не автоматично сформується.

РЕКОМЕНДАЦІЯ

У вас є таблиця з двома ключами-кандидатами

  • PRIMARY KEY на id
  • UNIQUE KEY на UK_cagoa3q409gsukj51ltiokjoh

Оскільки і те, і інше BIGINT, ви можете збільшити продуктивність і створити меншу PlayerClubтаблицю, позбувшись idі зберігаючи унікальність UK_cagoa3q409gsukj51ltiokjoh, а також уникнути цієї ситуації в тупиковому стані.


1
Тільки після вилучення Єдиним попереднім ключем у цій таблиці є "account_id" тупик, що припиняється.
Urbanleg
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.