Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Problem z zakleszczeniem MySQL w InnoDB

Powoduje to zakleszczenie, ponieważ UPDATE zapytanie blokuje wszystkie wiersze w tabeli i w zależności od użytych indeksów (lub ich braku) dwie różne sesje potencjalnie zablokują je w nieco innej kolejności. Pamiętaj, że UPDATE , DELETE i SELECT ... FOR UPDATE zablokuje wszystkie napotkane wiersze, niezależnie od tego, czy pasują one do wszystkich WHERE warunki, czy nie. Dlatego używając ich, powinieneś starać się, aby napotkały jak najmniej wierszy, używając indeksów (najlepiej klucza podstawowego) i unikając niejasnych lub szeroko zaznaczonych warunków.

Moja sugestia dotycząca kolejek roboczych jest dość uniwersalna:blokuj tak mało, jak to możliwe, tak rzadko, jak to możliwe i zawsze w deterministycznej kolejności. Tak więc ogólnie:

  1. Używaj odczytów bez blokowania (zwykłe SELECT ), aby znaleźć pracę do zrobienia, szukając rzeczy, które Twój pracownik wie, jak robić i obecnie nie odebrano jej (lease_owner IS NULL AND lease_expiry IS NULL -- lub podobne).
  2. Wybierz jeden element pracy (lub kilka, jeśli się odważysz, ale jeden jest znacznie prostszy i zwykle pozwala na doskonale akceptowalną wydajność).
  3. Zaktualizuj swój element pracy (aby go odebrać, ale w każdym przypadku wymaga on również aktualizacji):
    1. Otwórz transakcję.
    2. Zablokuj wybrany element pracy za pomocą SELECT ... FOR UPDATE -- Jeśli nie jest już nieodebrany, przerwij i wybierz inny.
    3. Zaktualizuj wybrany element pracy o swój identyfikator pracownika i czas wygaśnięcia dzierżawy.
    4. Zatwierdź transakcję natychmiast.
  4. Rozpocznij pracę nad wydzierżawionymi przedmiotami pracy.
  5. W innym procesie inny ankieter szuka porzuconej pracy i cofa ją (poprzez ten sam proces aktualizacji powyżej).

Dzięki temu projektowi można łatwo uzyskać bardzo wysoką przepustowość (tysiące zadań na sekundę) i zasadniczo bez rywalizacji i problemów z kolejnością. Optymalizacje w celu wybrania pracy, która jest mniej podatna na konflikty z innymi ankieterami, są proste i skuteczne (np. moduł na ID stanowiska lub podobny, wybrany, aby uniknąć głodu w pracy). Najważniejsze jest, aby pamiętać, że konflikt przy wyborze pracy jest w porządku -- po prostu przerwij i spróbuj ponownie, a wszystko potoczy się bardzo szybko.

Wszystkie blokujące zapisy dla pozycji/zadań kolejki pracy powinny być wykonywane tylko w pojedynczych wierszach i kluczem podstawowym tylko .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dziwny wyjątek SQLException:nie znaleziono kolumny

  2. Zmień tabelę za pomocą wyboru podrzędnego

  3. Baza zapytań Java Mysql z połączeniem

  4. Używanie UUID jako klucza podstawowego z Laravel 5

  5. PHP Zaktualizuj tabelę MySQL za pomocą formularza HTML