Znalazłem bardzo kłopotliwą sytuację, w której potrzebuję pomocy, aby zrozumieć.Problem z impasem, gdy transakcja próbuje zdobyć blokadę, która już jest przechowywana.
Prowadzone są dwie transakcje:
(2) zawiera blokadę dla zapytania delete from myTable where id = NAME_CONST('p_id',10000)
. Jest to blokada PRIMARY KEY, chociaż nie jest to pełny klucz, ale zakres. Wygląda na to, że jest to pełna blokada zapisu, gdy jest napisane lock_mode X locks rec but not gap
.
(1) czeka na tę samą blokadę, również dla zapytania delete from myTable where id = NAME_CONST('p_id',10000)
.
(2) próbuje także uzyskać tę blokadę, a MySQL wykryje zakleszczenie.
Co nie mogę zrozumieć, dlaczego (2) musi ponownie nabyć blokadę jak to już trzyma go i to jest blokada zapisu (lock_mode X) we wszystkich przypadkach.
Wygląda również na to samo zapytanie.
Oto definicja tabeli
create myTable (
id int unsigned not null,
value1 char(8) not null,
value2 int unsigned,
primary key (id, value1)
);
i oto informacja z SHOW ENGINE INNODB STATUS\G
------------------------
LATEST DETECTED DEADLOCK
------------------------
130313 14:46:28
*** (1) TRANSACTION:
TRANSACTION 75ACB8A3, ACTIVE 0 sec, process no 6110, OS thread id 139973945382656 starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 376, 1 row lock(s)
MySQL thread id 5154970, query id 5201313618 192.168.0.2 user updating
delete from myTable where id = NAME_CONST('p_id',10000)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 22371 page no 1598 n bits 104 index `PRIMARY` of table `db`.`myTable` trx id 75ACB8A3 lock_mode X waiting
Record lock, heap no 32 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
0: len 4; hex 0005af3a; asc :;;
1: len 8; hex 2020202020202020; asc ;;
2: len 6; hex 000075acb890; asc u ;;
3: len 7; hex ea0000020d011e; asc ;;
4: len 4; hex 00000065; asc e;;
*** (2) TRANSACTION:
TRANSACTION 75ACB890, ACTIVE 0 sec, process no 6110, OS thread id 139973957895936 starting index read
mysql tables in use 1, locked 1
7 lock struct(s), hea
p size 1248, 6 row lock(s), undo log entries 4
MySQL thread id 5155967, query id 5201313625 192.168.0.1 user updating
delete from myTable where id = NAME_CONST('p_id',10000)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 22371 page no 1598 n bits 104 index `PRIMARY` of table `db`.`myTable` trx id 75ACB890 lock_mode X locks rec but not gap
Record lock, heap no 32 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
0: len 4; hex 0005af3a; asc :;;
1: len 8; hex 2020202020202020; asc ;;
2: len 6; hex 000075acb890; asc u ;;
3: len 7; hex ea0000020d011e; asc ;;
4: len 4; hex 00000065; asc e;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 22371 page no 1598 n bits 104 index `PRIMARY` of table `db`.`myTable` trx id 75ACB890 lock_mode X waiting
Record lock, heap no 32 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
0: len 4; hex 0005af3a; asc :;;
1: len 8; hex 2020202020202020; asc ;;
2: len 6; hex 000075acb890; asc u ;;
3: len 7; hex ea0000020d011e; asc ;;
4: len 4; hex 00000065; asc e;;
*** WE ROLL BACK TRANSACTION (1)
Czy próbowałeś odtworzyć błąd? Jeśli "tak" możesz pokazać nam scenariusz? – ravnur
Próbowałem usunąć to tak szybko, jak tylko mogę, za pomocą 'rozpocznij transakcję; kasować...; rollback; 'z dwóch wątków symulacji tak szybko, jak bash może je przekazać do mysql, ale ani razu nie dostałem zakleszczenia. Nie mam pojęcia, jak to się może stać. –
Zobacz to pytanie (opisuje, jak można złapać impas): http://stackoverflow.com/questions/2143873/how-to-explain-the-deadlock- better. Istnieje również niezły artykuł o wykrywaniu i odzyskiwaniu z impasu: http://dwachira.hubpages.com/hub/Process-Deadlock-Definition-Prevention-Detection-Recovery-and-Avoidance. Ogólnie rzecz biorąc, zakleszczenie jest kwestią architektury i projektowania. Powinieneś przejrzeć swoje procesy, które aktualizują dane. – ravnur