Napotkaliśmy problem po przeniesieniu bazy danych naszego klienta na dodatkowy serwer. Powinno to mieć pozytywny wpływ na wydajność witryny, ale występuje problem z blokowaniem tabel w MyISAM. (Słyszałem o używaniu InnoDB zamiast MyISAM, ale nie możemy zmienić silnika w najbliższej przyszłości).
Możemy wykryć to w zapytaniu o aktualizację, które jest wykonywane, gdy moderator aktywuje komentarz na stronie artykułów. Oto proces:
- zapytanie o aktualizację jest przetwarzane
SET status = 1 WHERE id = 5
(indeks jest ustawiony) - buforowane pliki strony są usuwane
W tym momencie cała strona staje się wolna. Sama baza danych jest zajęta przez kilka minut. Pobierałem listę procesów kilka razy i zobaczyłem około 60 wpisów z różnych zapytań select, które były w stanie oczekiwania na blokadę poziomu tabeli .
1. Nie rozumiem, dlaczego ta aktualizacja w tabeli article_comments
może wpływać na instrukcje select, aby tabela article
czekała na blokadę na poziomie tabeli. Na liście procesów prawie wszystkie oczekujące zapytania pochodziły z tej tabeli. Czytałem o tym, że aktualizacje / wstawki są lepsze niż selekcje i że może to powodować takie problemy, ale sama tabela artykułów nie jest aktualizowana po aktywowaniu komentarzy, więc selekcje nie powinny czekać. Czy źle to zrozumiałem?
2. Czy jest coś oprócz zmiany na InnoDB, aby zapobiec temu zachowaniu lub przynajmniej uzyskać lepszą równowagę? Jestem bardzo zirytowany faktem, że ten problem nie pojawił się przed przeniesieniem bazy danych na nowy serwer. Wydaje mi się, że jest trochę błędna konfiguracja, ale nie wiem, jak to zidentyfikować.
key_buffer_size
był ustawiony na1GB
. Zwiększenie tego, aby10GB
zmniejszyć problem.Odpowiedzi:
Silnik pamięci masowej MyISAM jest wściekle znany z wykonywania blokad pełnych tabel dla dowolnego DML (INSERT, UPDATEs, DELETE). InnoDB zdecydowanie rozwiąże ten problem w dłuższej perspektywie.
Pisałem o zaletach i wadach korzystania z MyISAM vs InnoDB
Jeśli chodzi o twoje aktualne pytanie, oto możliwy scenariusz:
article
iarticle_comments
są to tabele MyISAMarticle_comments
ma jeden lub więcej indeksów zstatus
jako kolumnąarticle_comments
są buforowane w buforze kluczy MyISAM (rozmiar według key_buffer_size ), co powoduje, że stare strony indeksów nie są przechowywane w buforze kluczy MyISAMarticle
iarticle_comments
W moim sugerowanym scenariuszu SELECTs względem
article
tabeli można powstrzymać od zezwolenia na zapisy z powodu konieczności oczekiwania naarticle_comments
uwolnienie się od dowolnego DML (w tym przypadku anUPDATE
)źródło
Pachnie jakbyś miał dużą pamięć podręczną?
W przypadku systemów produkcyjnych z dużą ilością zapisów, równie dobrze możesz WYŁĄCZYĆ cache_pytania.
Wszystkie wpisy w query_cache dla danej tabeli są usuwane, gdy każdy zapis występuje do tej tabeli. Im większa QC, tym wolniejsze jest to zadanie.
MyISAM używa blokad „na poziomie tabeli”. Odczyty i zapisy nie mogą wystąpić w tym samym czasie (na tej samej tabeli). Surowy, ale skuteczny.
źródło