Lock wait timeout exceeded debug rubrika: Databáze: SQL

3 jan_4
položil/-a 10.6.2016
 
upravil/-a 10.6.2016

Ahoj,

stává se mi obden že zachytím podobný error:

SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction

Bohužel, přestože jsem googloval jak jsem mohl, nenašel jsem způsob jak tu chybu efektivně debugovat a odstranit. Znám query, která se snaží lock získat, ale bohužel nemůžu přijít na to, která query ten lock drží.

Umíte někdo poradit?

-- Výsledek innodb status:

------------------------
LATEST DETECTED DEADLOCK
------------------------
2016-06-06 15:57:05 0x2b6857791700
*** (1) TRANSACTION:
TRANSACTION 248164805, ACTIVE 0 sec fetching rows
mysql tables in use 1, locked 1
LOCK WAIT 10 lock struct(s), heap size 1136, 1610 row lock(s), undo log entries 1601
MySQL thread id 1894738, OS thread handle 47726145902336, query id 65697930 172.31.39.220 mydb updating
DELETE FROM bar WHERE list_id = 2
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 60041 page no 29 n bits 336 index PRIMARY of table `foo`.`bar` trx id 248164805 lock_mode X waiting
Record lock, heap no 128 PHYSICAL RECORD: n_fields 11; compact format; info bits 0
 0: len 4; hex 80000643; asc    C;;
 1: len 6; hex 00000ecab1c4; asc       ;;
 2: len 7; hex 750034ef51318e; asc u 4 Q1 ;;
 3: SQL NULL;
 4: len 4; hex 80000002; asc     ;;
 5: len 23; hex 6a696e6472612e6e6f76616b4074697363616c692e637a; asc baz@tiscali.cz;;
 6: len 4; hex 80000004; asc     ;;
 7: len 5; hex 99998cb305; asc      ;;
 8: SQL NULL;
 9: SQL NULL;
 10: SQL NULL;
 
*** (2) TRANSACTION:
TRANSACTION 248164804, ACTIVE 1 sec starting index read
mysql tables in use 1, locked 1
43 lock struct(s), heap size 3520, 62 row lock(s), undo log entries 90
MySQL thread id 1894734, OS thread handle 47727144146688, query id 65698328 172.31.39.220 mydb updating
update `bar` set `status` = '4' where `email` = 'foo.bar@seznam.cz' and `status` != '2'
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 60041 page no 29 n bits 336 index PRIMARY of table `foo`.`bar` trx id 248164804 lock_mode X locks rec but not gap
Record lock, heap no 128 PHYSICAL RECORD: n_fields 11; compact format; info bits 0
 0: len 4; hex 80000643; asc    C;;
 1: len 6; hex 00000ecab1c4; asc       ;;
 2: len 7; hex 750034ef51318e; asc u 4 Q1 ;;
 3: SQL NULL;
 4: len 4; hex 80000002; asc     ;;
 5: len 23; hex 6a696e6472612e6e6f76616b4074697363616c692e637a; asc foo.bar@tiscali.cz;;
 6: len 4; hex 80000004; asc     ;;
 7: len 5; hex 99998cb305; asc      ;;
 8: SQL NULL;
 9: SQL NULL;
 10: SQL NULL;
 
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 60041 page no 45 n bits 608 index email of table `foo`.`bar` trx id 248164804 lock_mode X waiting
Record lock, heap no 274 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
 0: len 25; hex 6b616c6f757370656b6172737476694073657a6e616d2e637a; asc baz@seznam.cz;;
 1: len 4; hex 8000032a; asc    *;;
 
*** WE ROLL BACK TRANSACTION (2)
------------
TRANSACTIONS
------------
Trx id counter 248969191
Purge done for trx's n:o < 248969185 undo n:o < 0 state: running but idle
History list length 1723
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 329197822152288, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 329197822151376, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 329197822150464, not started
0 lock struct(s), heap size 1136, 0 row lock(s)

Komentáře

  • messa : MySQL, že jo 10.6.2016
  • jan_4 : Jo, MySQL. 10.6.2016
odkaz
7 messa
odpověděl/-a 10.6.2016
 
upravil/-a 10.6.2016

Které transakce se kously by mělo být vidět v show engine innodb status.

Možná by pomohlo explicitní zamykání, úprava schématu, úprava toho, co se v těch transakcích dělá, změna isolation levelu... Tuhle chybu jsem kdysi řešil v databázi, do které se připojovala webovka a API, z druhé strany do ní bušily skripty provádějící hromadný import dat a z třetí strany se data neustále odlévaly jinam a občas se to všechno sešlo nad stejnými daty. Nicméně teď s MongoDB podobné problémy nejsou :D

Btw. píšou tam try restarting transaction, což i zní docela logicky, protože při určitých způsobech práce se sdílenými daty se tyhle chyby prostě stávají a jen aplikace (resp. její programátor) může vyhodnotit, co dál. Ideálně by každá transakce měla být obalena ve while cyklu, který většinou proběhne jen jednou, ale právě v případě této chyby se celá operace (transakce) provede znovu odzačátku. Dokonce jsem tenhle přístup viděl v nějakém C++ API, ale ještě jsem neviděl reálný kód (v jakémkoli jazyce), kde by se to takhle normálně dělalo :)

Komentáře

  • jan_4 : Já to právě v tom "show engine innodb status" nemůžu najít. Vidim tam něco z 2016-06-06, přitom poslední chyba nastala 2016-06-09 10.6.2016
  • jan_4 : Přidal jsem výpis "show engine innodb status" 10.6.2016

Pro zobrazení všech 2 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.