2015-09-09 17 views
17

Używam Laravel 5.1.Jak uniknąć zadań Blokady tabel DB podczas korzystania z kolejek Laravel?

Kolejki służą do pobierania/synchronizowania danych między kilkoma systemami.

Używam sterownika bazy danych, 3 procesy "rzemieślnik kolejki: praca - idemon" działają cały czas.

Zadania są wysyłane zarówno przez użytkowników systemu, jak i program planujący (cron). Trzy kolejki są używane do priorytetyzacji zadań.

Wszystko wydaje się działać dobrze - tabela zadań jest wypełniona rekordami, system zajmuje się nimi i usuwa te, które są wykonywane.

kwestie Jednak po pewnym czasie zaczynają blokujące przeszkadzają:

SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction

i

'RuntimeException' with message 'Can't swap PDO instance while within transaction.'

i

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

nie próbowałem jeszcze innego kierowcę za pomocą kolejki. Naprawdę chciałbym zostać w bazie danych. Silnik to InnoDB, tabela zadań ma domyślną strukturę i indeksy.

Czy istnieje sposób rozwiązania tego problemu? Jakie są Twoje myśli?

Warto wspomnieć, że nazywam DB::reconnect() w moich zajęciach, ponieważ pracownicy kolejkowi działają jako demony.

Zadania są wywoływane z wykorzystaniem cechy DispatchesJobs, tak jak można się było spodziewać. Nie ingeruję w algorytm kolejek w żaden inny sposób.

+0

Każde rozwiązanie dla tego? –

+1

Nie. Przeniesiono na beanstalkd na teraz. Chociaż podobał mi się sterownik DB lepiej, ponieważ mogłem śledzić zadania i nieudane zadania, po prostu patrząc na tabele DB ... – MaGnetas

+0

Dowiedz się, jak Laravel radzi sobie z "transakcjami" MySQL. Wygląda na to, że rozpocząłeś transakcję, a potem siedziałeś przez długi czas. Transakcje 'COMMIT 'tak szybko, jak to możliwe. Sprawdź użycie 'autocommit'. –

Odpowiedz

0

Możesz przełączyć się na MyISAM, co spowoduje usunięcie błędów transakcji; ale w tym samym czasie straciłbyś wiele wspaniałej funkcjonalności i niezawodności, która towarzyszy innoDB.

* To nie jest opcją, jeśli tabele mają klucze obce i opierając się na rzeczy, takich jak usuwaniem i aktualizacji kaskadowych, które znajdują się tylko w InnoDB

+1

domyślam się, że klucze obce nie są problemem w tym przypadku. Tabela nie ma żadnych powiązań. A migracja tworząca tabelę "zadań" nie określa silnika. To może być faktycznie rozwiązanie. Jednak brak transakcji może oznaczać kolizje, które ledwo można śledzić ... – MaGnetas

1

To nie może być odpowiedź, ale niektóre informacje.

Podczas korzystania z instrukcji SELECT ... FOR UPDATE można zaobserwować rywalizację o blokady (martwe blokady itp.).

select … for update where x <= y 

jej, że zakres skanowania z < = zamków baz danych wszystkich wierszy < = y, w tym wszelkich luk więc jeśli masz wiersze z Y tak: 1, 3, 5 zaskoczy nawet pustą przestrzeń między 1 a 3 w indeksie blokowania jego nazwie luka

widzę problemu z tym poleceniem:

SHOW ENGINE INNODB STATUS; 

---TRANSACTION 72C, ACTIVE 755 sec 
4 lock struct(s), heap size 1248, 3 row lock(s), undo log entries 1 
MySQL thread id 3, OS thread handle 0x7f84a78ba700, query id 163 localhost msandbox 
TABLE LOCK table test.t trx id 72C lock mode IX 
RECORD LOCKS space id 19 page no 4 n bits 80 index age of table test.t trx id 72C lock_mode X 
RECORD LOCKS space id 19 page no 3 n bits 80 index GEN_CLUST_INDEX of table test.t trx id 72C lock_mode X locks rec but not gap 
RECORD LOCKS space id 19 page no 4 n bits 80 index age of table test.t trx id 72C lock_mode X locks gap before rec 

ostatniej linii

Jeśli masz dużo luk zablokowania transakcji wpływających na współbieżność i wydajność można je wyłączyć na dwa różne sposoby:

1- Change the ISOLATION level to READ COMMITTED. In this isolation level, it is normal and expected that query results can change during a transaction, so there is no need to create locks to prevent that from happening. 

2- innodb_locks_unsafe_for_binlog = 1. Disables the gap locks except for foreign-key constraint checking or duplicate-key checking. 

https://www.percona.com/blog/2012/03/27/innodbs-gap-locks/

+0

Wszystko to może być pomocne, dziękuję. Ale naprawdę nie chciałabym mieszać z rdzeniem laravel. Uważam, że powinno to być jakoś rozwiązane "po wyjęciu z pudełka". Chociaż mogłem wprowadzić pewne zmiany w "dobrych praktykach" do mojego kodu lub przepływu pracy, aby uniknąć problemu. – MaGnetas