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

Przewodnik dla manekinów po blokowaniu w innodb

Oto moje notatki z pracy z obsługą MySQL w związku z niedawnym, dziwnym problemem z blokowaniem (wersja 5.1.37):

Wszystkie wiersze i wpisy indeksu, przez które przeszli, aby dostać się do zmienianych wierszy, zostaną zablokowane. Jest omówiony pod adresem:

http://dev.mysql.com/doc /refman/5.1/en/innodb-locks-set.html

„Odczyt blokujący, UPDATE lub DELETE zazwyczaj ustawiają blokady rekordów na każdym rekordzie indeksu, który jest skanowany podczas przetwarzania instrukcji SQL. Nie ma znaczenia, czy w instrukcji występują warunki WHERE, które wykluczają wiersz. InnoDB robi to nie pamięta dokładnego warunku WHERE, ale wie tylko, które zakresy indeksów zostały przeskanowane.... Jeśli nie masz indeksów odpowiednich dla twojej instrukcji, a MySQL musi przeskanować całą tabelę, aby przetworzyć instrukcję, każdy wiersz tabeli zostaje zablokowany, co w turn blokuje wszystkie wstawienia innych użytkowników do tabeli."

To jest. Często pomocnym rozwiązaniem jest:

AKTUALIZUJ którąkolwiek tabelę, ustaw cokolwiek na coś, w którym klucz podstawowy jest (wybierz klucz podstawowy z dowolnej tabeli, gdzie ograniczenia są uporządkowane według klucza podstawowego);

Wewnętrzna selekcja nie musi blokować, a aktualizacja będzie miała wtedy mniej pracy do wykonania. Klauzula order by zapewnia, że ​​aktualizacja jest wykonywana w kolejności klucza podstawowego zgodnej z fizyczną kolejnością InnoDB, co jest najszybszym sposobem na zrobienie tego.

Tam, gdzie w grę wchodzi duża liczba wierszy, jak w twoim przypadku, może być lepiej przechowywać wynik select w tabeli tymczasowej z dodaną kolumną flag. Następnie wybierz z tabeli tymczasowej, w której flaga nie jest ustawiona, aby pobrać każdą partię. Uruchom aktualizacje z limitem powiedzmy 1000 lub 10000 i ustaw flagę dla partii po aktualizacji. Limity utrzymają poziom blokowania na akceptowalnym poziomie, podczas gdy wybrana praca będzie musiała zostać wykonana tylko raz. Po każdej partii zobowiąż się do zwolnienia blokad.

Możesz również przyspieszyć tę pracę, wykonując wybraną sumę nieindeksowanej kolumny przed wykonaniem każdej partii aktualizacji. Spowoduje to załadowanie stron danych do puli buforów bez blokowania. Wtedy blokowanie będzie trwało krócej, ponieważ nie będzie żadnych odczytów dysku.

Nie zawsze jest to praktyczne, ale kiedy jest, może być bardzo pomocne. Jeśli nie możesz tego zrobić w partiach, możesz przynajmniej spróbować najpierw wybrać, aby wstępnie załadować dane, jeśli są one wystarczająco małe, aby zmieścić się w puli buforów.

Jeśli to możliwe, użyj trybu izolacji transakcji READ COMMITTED. Zobacz:

http://dev.mysql.com/doc/refman /5.1/pl/set-transaction.html

Aby uzyskać to zmniejszone blokowanie, należy użyć rejestrowania binarnego opartego na wierszach (zamiast domyślnego rejestrowania binarnego opartego na instrukcjach).

Dwa znane problemy:

  1. Podzapytania mogą być czasami mniej niż idealnie zoptymalizowane. W tym przypadku było to niepożądane podzapytanie zależne - z tego powodu sugestia użycia podzapytania okazała się nieprzydatna w porównaniu z alternatywą w tym przypadku.

  2. Usunięcia i aktualizacje nie mają takiego samego zakresu planów zapytań jak polecenia select, więc czasami trudno jest je odpowiednio zoptymalizować bez mierzenia wyników, aby dokładnie określić, co robią.

Obie te rzeczy stopniowo się poprawiają. Ten błąd jest jednym z przykładów, w którym właśnie ulepszyliśmy optymalizacje dostępne dla aktualizacji, chociaż zmiany są znaczące i nadal przechodzi kontrolę jakości, aby upewnić się, że nie ma żadnych negatywnych skutków:

http://bugs.mysql.com/bug.php?id=36569




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Konwertuj datę utworzoną przez jquery datepicker na standardowy format daty mysql

  2. Now() a GetDate()

  3. Highchart - Wyświetlanie danych JSON - MYSQL / PHP

  4. Jak zapobiec zaokrąglaniu pola dziesiętnego MySQL?

  5. MySQL - sortuj ciąg znaków oddzielonych przecinkami w kolumnie