2013-02-20 18 views
6

Miałem to wracając do sprawy przez lata i nigdy nie byłem w stanie dotrzeć do sedna. Nie mam pojęcia, co może powodować te blokady.Błąd MySql> Przekroczono limit czasu oczekiwania na blokadę; spróbuj ponownie uruchomić transakcję SQLState: 41000 VendorError: 1205

Błąd jest: Lock wait timeout exceeded; try restarting transaction SQLState: 41000 VendorError: 1205

Instrukcja SQL jest pojedynczym INSERT działa w ramach transakcji. Wszystkie wkłady są z tej postaci, więc nie ma wkładki luzem ani mieszać wkładki mode itp

INSERT INTO attachment( id, entityid, entitytype , addeduserid , deleteduserid , fullpath , filename, status, creationdate, lastupdated, deletiondate, hasfile,notes,history,type,mimeinfo,archivedby,archivedon, referencedate,changedby,changedon ) values (0,0,2,360,null,NULL,NULL,1,'2013-02-20 08:45:31','2013-02-20 08:45:31',NULL,0,NULL,'20/02/2013 08:45:UserA:File uploaded internally. <br>',0,NULL,null,NULL,NULL,null,NULL);

Konfiguracja systemu: Mysql wersja: 'Wersja serwera: 5.1.61 dystrybucji Źródło' (na RedHat)

przechowywania: InnoDB

konfiguracja InnoDB podobne (częściowo edytowane z my.cnf)

innodb_file_per_table=1 
innodb_buffer_pool_size=3G 
innodb_additional_mem_pool_size=20M 
innodb_log_file_size=512M 
innodb_log_files_in_group=2 
innodb_log_buffer_size=16M 
innodb_support_xa=1 
innodb_doublewrite=1 
innodb_thread_concurrency=0 
innodb_flush_log_at_trx_commit=2 
innodb_autoinc_lock_mode=2** 
innodb_rollback_on_timeout=1 
innodb_locks_unsafe_for_binlog=1** 
thread_cache_size=8 
query_cache_size=256M 
query_cache_limit=4M 
table_cache=2048 
table_definition_cache=1024 
tmp_table_size=512M 
max_heap_table_size=512M 
transaction-isolation=READ-COMMITTED** 
innodb_table_locks=0** 
innodb_lock_wait_timeout=50** 

** zostały one specjalnie dodane w odniesieniu do tego problemu.

Ogólnie:

System (czyli mają 6 wystąpień Każdy wniosek o tej samej strukturze bazy danych wszystkie działające na pojedynczej instancji MySQL) może działać dobrze przez kilka dni, a potem może mieć przebieg gdzie Blokada Waits Start, aby wystąpić zazwyczaj będą pojawiać się w grupach przez cały dzień. Każdy pojedynczy błąd będzie się powtarzać wielokrotnie, ponieważ gdy się nie powiedzie, spróbuję ponownie, a normalnie powtórna próba zakończy się niepowodzeniem. Skonfigurowałem ponowienie próby 4 razy. Często blokady będą występować tylko na kilku różnych stołach.

Dzisiejsze wystąpienie specyficznych kwestii:

Dziś rano na stole attachment, nie było wkładkę na stole od ostatniej nocy. Nie było również żadnych aktualizacji na stole od poprzedniej nocy. Jeśli blokady nie są powiązane z innymi użytkownikami aktualizującymi i wstawiającymi, czy niektóre instrukcje wyboru mogą powodować blokady? Próbowałem zapewnić wszystkie instrukcje wyboru używać attachment_general_index?

Ze względu na fakt, że głównie otrzymuję to na kilku różnych tabelach - tutaj jest struktura tego stołu.

CREATE TABLE `attachment` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
`entityid` int(10) unsigned DEFAULT NULL, 
`entitytype` tinyint(3) unsigned NOT NULL DEFAULT '0', 
`addeduserid` int(10) unsigned NOT NULL, 
`deleteduserid` int(10) unsigned DEFAULT NULL, 
`fullpath` varchar(255) DEFAULT NULL, 
`filename` varchar(255) DEFAULT NULL, 
`status` tinyint(3) unsigned NOT NULL DEFAULT '0', 
`creationdate` varchar(40) DEFAULT NULL, 
`lastupdated` varchar(40) DEFAULT NULL, 
`deletiondate` varchar(40) DEFAULT NULL, 
`hasfile` tinyint(3) unsigned NOT NULL DEFAULT '0', 
`notes` text, 
`history` text, 
`type` tinyint(3) unsigned DEFAULT '0', 
`lastupdatedby` int(10) DEFAULT '0', 
`lastupdatedinfo` varchar(255) DEFAULT NULL, 
`mimeinfo` varchar(255) DEFAULT NULL, 
`archivedby` int(10) unsigned DEFAULT NULL, 
`archivedon` varchar(40) DEFAULT NULL, 
`referencedate` varchar(40) DEFAULT NULL, 
`changedby` int(10) unsigned DEFAULT NULL, 
`changedon` varchar(40) DEFAULT NULL, 
PRIMARY KEY (`id`), 
KEY `attachment_addeduserid_fkey` (`addeduserid`), 
KEY `attachment_deleteduserid_fkey` (`deleteduserid`), 
KEY `attachment_archivedby_fkey` (`archivedby`), 
KEY `attachment_changedby_fkey` (`changedby`), 
KEY `attachment_general_index` (`entitytype`,`entityid`,`status`,`type`), 
CONSTRAINT `attachment_ibfk_1` FOREIGN KEY (`addeduserid`) REFERENCES `user` (`id`), 
CONSTRAINT `attachment_ibfk_2` FOREIGN KEY (`deleteduserid`) REFERENCES `user` (`id`), 
CONSTRAINT `attachment_ibfk_3` FOREIGN KEY (`archivedby`) REFERENCES `user` (`id`), 
CONSTRAINT `attachment_ibfk_4` FOREIGN KEY (`changedby`) REFERENCES `user` (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=3619 DEFAULT CHARSET=latin1$$ 

Mam załączeniu niedawnej InnoDB SHOW STATUS, to od dziś i nie było trzeba czekać zamek od wczoraj. Nie rozumiem wszystkich tych wyników, ale najważniejsze jest to, że zamki nigdy nie pojawiają się tutaj. Zakładam, że nie są one zaklasyfikowane jako zakleszczenia?

https://docs.google.com/document/d/1Hslf2B594n8ofAUYxN54Gh8FrSCIFNGGMtthVI_Lv4k/pub

Czy to tylko martwy obszar zamki, które jest interesujące dla tego problemu? Jeśli są inne obszary, spróbuję je zebrać, gdy się pojawią i będą mogły dostarczyć.

Każda pomoc zostanie doceniona.

Nick

+0

Co mówi napis "POKAŻ INNODB"? – Danack

+0

Ponadto, co jeszcze w transakcji, że błędy się? Zgaduję co najmniej jedną wstawkę, ponieważ może to łatwo doprowadzić do: http://www.xaprb.com/blog/2006/08/03/a-little-known-way-to-cause-a-database- deadlock/ – Danack

+0

@Danack, patrz link powyżej do niektórych wyników do SHOW INNODB STATUS. W przypadku transakcji zakończonej niepowodzeniem generalnie nie ma dużej liczby akcji, ale generalnie nigdy nie ma dwóch wstawień do tej samej tabeli w ramach tej samej transakcji. Odnośnie łącza xaprb (które czytałem dawno temu) - ale ze względu na charakter sytuacji nie myślałem, że to się stosuje? I dzięki za zainteresowanie! –

Odpowiedz

3

(Powinno to prawdopodobnie komentarz, ale nie mam zbyt dużo tekstu i potrzebują formatowania).

Myślę, że to bardzo podobny problem do jednej described at gdzie:

  1. Jedna transakcja ma blokady na końcu tabeli.
  2. Druga transakcja ma blokadę dla większości tabeli.
  3. Pierwsza transakcja próbuje zaktualizować/wstawić do blokady posiadanej przez drugą transakcję. To się nie udaje, więc jedna z transakcji zostaje wybrana na śmierć.

Dziękujemy za opublikowanie show status. Masz rację, że pokazany impas nie wydaje się być związany z tabelą, o którą pytasz, ale wydaje się, że jest taki sam jak w Xaprb.

Is it only the dead locks area that is interesting for this issue?

Tak, dokładne części są:

Transaction 1 

UPDATE operative SET lastupdated='2013-02-19 17:12:44'=N<EDITED> RECORD LOCKS space id 1789 page no 3622 n bits 112 index `PRIMARY` of table `<EDITED> `.`operative` trx id 0 233901602 lock_mode X locks rec but not gap waiting 

*** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 1789 page no 3622 n bits 112 index `PRIMARY` of table `<EDITED> `.`operative` trx id 0 233901602 lock_mode X locks rec but not gap waiting 


Transaction 2 

INSERT INTO opdate(operativeId,opdate,updatingUser,dategroup,type,notes,lastupdated) values (....) RECORD LOCKS space id 1789 page no 3622 n bits 112 index `PRIMARY` of table `<EDITED> `.`operative` trx id 0 233901603 lock mode S locks rec but not gap 


*** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 830 page no 112 n bits 808 index `opdate_unique` of table `<EDITED> `.`opdate` trx id 0 233901603 lock mode S waiting Record lock, heap no 739 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 

to czuje się bardzo podobny do problemu wymienionych w xaprb. tj.

  1. Transakcja 2 wykonała wstawienie do tabeli, a teraz blokuje klucz podstawowy.
  2. Transakcja 1 wykonuje skanowanie tabeli w celu wykonania aktualizacji i oczekuje na blokadę tego klucza podstawowego.
  3. Transakcja 2 próbuje wykonać inną wkładkę i musi uzyskać blokadę, ale nie można tego zrobić, ponieważ transakcja 1 już ją posiada (tak naprawdę zgaduję, ponieważ zasłoniła ona nazwę tabeli).

Najpierw zasugeruję naprawienie tego impasu, a także spróbuję rozwiązać problem, o który pytałeś.

Uważam, że Twój problem może nie pojawić się w stanie INNODB. Otrzymujesz kod błędu 1205 - czyli ER_LOCK_WAIT_TIMEOUT, a nie błąd 1213 ER_LOCK_DEADLOCK. Więc mimo, że skutecznie masz impas, to nie jest on klasyfikowany jako taki.

Myślę, że jeśli uda ci się zrobić SHOW ENGINE INNODB STATUS, gdy wystąpi problem, powinieneś być w stanie zobaczyć blokady tych transakcji, nawet jeśli nie są one wyświetlane jako ostatni impas.

+0

Ponieważ często mogę uzyskać powtarzającą się blokadę oczekującą po upływie 50 sekund, powinienem być w stanie uzyskać kopię, gdy wystąpi. Ale na przykład nie miałem dzisiaj żadnego - tak będzie ściśle monitorować. Główną różnicą w porównaniu z xaprb jest to, że nie ma żadnych zapisów żadnych innych aktualizacji danych (to jest na podstawie znaczników czasu wstawienia i aktualizacji), więc ta transakcja z opóźnieniem blokady jest jedyną transakcją aktualizującą tabelę. A jeśli jakieś aktualizacje są wykonywane, to zawsze używa klucza podstawowego (tj. Są to aktualizacje jednorzędowe). Tak więc jedynymi innymi możliwymi działaniami na stole byłyby pytania. Jeszcze raz –

+0

@se Twoja edycja uniemożliwia odczytanie całego tekstu bez przewijania poziomego. Czy to zamierzałeś? – Danack

+0

@Dankuj nie bezpośrednio. Edytowałem, ponieważ poprzedni stan rzeczy uniemożliwił odróżnienie "zwrotek" w dzienniku. To, jak zaginęły oryginalne przerwy w linii, jest dla mnie zagadką. Jeśli nie masz nic przeciwko, mógłbym spróbować zastąpić go czymś podobnym, ale mniej zepsutym. – sehe

4

Chciałbym podzielić się moją chwilą "Eureka" z tymi z was, którzy drapią wasze głowy ponad limitami czasu transakcji i stwierdzili, że żadna z sugerowanych zmian konfiguracji serwera nie pomaga.

Uderzyłem do punktu, w którym poważnie zastanawiałem się nad powtórzeniem niektórych z moich aplikacji, aby móc uwzględnić limity czasu transakcji (zbiorowy jęk słyszy się "na całym świecie").

Jestem paranoikiem w kwestii utraty czegokolwiek z transakcji biznesowych, więc uruchamiam zadanie cron, które wykonuje pełne mysqldump co 10 minut (jest to podwójna replikacja) przez cały dzień.

To, co odkryłem, to że mysqldump wiedzie na serwer, blokuje tabele i praktycznie zabrania wszystkim innym korzystania z bazy danych podczas jej wykonywania. Mój moment Eureka nadszedł, gdy odkryłem, że niepowodzenia transakcji zbiegły się z czasem uruchomienia mysqldump.

Krótko mówiąc, istnieją 3 opcje wiersza poleceń, które uniemożliwią mysqldump zabicie twojego serwera.Są

  1. --single transakcję
  2. --quick
  3. --lock Stoły = false

Wiele dzięki CA3LE @How can I slow down a MySQL dump as to not affect current load on the server? za oświecenie mnie.

Powiązane problemy