MySQL table_cache i Opened_tables

14

Widziałem ludzi używających porównania Open_tables i Opened_tables, aby ocenić, czy table_cache jest zbyt mały w MySQL. Uważam jednak, że Opened_tables kumuluje się w czasie pracy, więc nie jest to prawidłowe porównanie. Jedynym zastrzeżeniem jest to, że być może Opened_tables jest zderzany tylko z brakami - chociaż nawet wtedy, gdy tabele otwierane na sekundę są nadal małe, prawdopodobnie nie będzie problemu z tym, aby stopniowo się powiększał.

Jeśli porównanie Open_tables z Opened_tables nie jest prawidłowe, czy istnieje inny sposób na uzyskanie danych pomiarowych?

Dotyczy to MySQL 5.0, ale różnice między wersjami są również mile widziane.

Sam Brightman
źródło
Podoba mi się to pytanie, ponieważ jest to pytanie pobudzające do myślenia. Otrzymuje +1 za przypomnienie programistom MySQL, aby w pełni korzystali ze zmiennych statusu do mierzenia kondycji serwera DB.
RolandoMySQLDBA

Odpowiedzi:

7

Największym powodem posiadania dużego table_cache jest to, że mutex LOCK_open nie jest gorący. MySQL w wersjach wcześniejszych niż 5.5 ma wiele sprzeczności, gdy próbujesz otwierać / zamykać tabele, więc chcesz ograniczyć robienie tego w jak największym stopniu, tj. Mieć duży bufor tabeli.

Więc nie przejmujesz się żadnym szczególnym stosunkiem trafień do chybów (w rzeczywistości powinieneś całkowicie zignorować współczynniki - ten post na blogu wyjaśnia dlaczego ). To, na czym Ci zależy, to wskaźnik pominięć , ponieważ im więcej razy zdarza się to na sekundę, tym większa szansa, że ​​będziesz miał spór (jeden wątek musi poczekać, aż inny wątek zwolni blokadę).

Jak oceniasz wskaźnik braków? Pobierasz kilka próbek Opened_Tables w odstępie kilku sekund podczas najbardziej obciążonego okresu w ciągu dnia, a jeśli w każdej próbce jest wzrost, prawdopodobnie dobrym pomysłem jest sprawdzenie, czy możesz podnieść tabelę bufora tabeli.

Uwaga: bardzo nie polecam porównywania z czasem dostępności.

Morgan Tocker
źródło
5

Najpierw rozważmy te zmienne statusu:

Otwarte tabele : liczba otwartych tabel.

Opened_tables : liczba tabel, które zostały otwarte. Jeśli Opened_tables jest duży, twoja wartość table_open_cache jest prawdopodobnie zbyt mała.

Co zaskakujące, odpowiedź na twoje pytanie leży w samym pytaniu.

Obie zmienne spowodowałoby większy sens tylko jeśli rzucisz jeszcze jedną zmienną stanu do mix: Uptime (lub stanu Uptime_since_flush świeżych średnich po PŁUCZ STATUS ).

Powinieneś porównywać Open_tables agsinst (Opened_tables / Uptime) . Jeśli Open_tables wspina się wyżej (Opened_tables / Uptime) , teraz masz powód do niepokoju i powinieneś mieć oko na rzeczy takie jak:

AKTUALIZACJA 31.08.2011 12:18 EDT

Zwróć uwagę, dlaczego zasugerowałem również użycie Uptime_since_flush_status zamiast Uptime, aby uzyskać poprawny wzorzec wzrostu Opened_tables dla danego okresu.

Na przykład, jeśli uruchamiasz w FLUSH STATUS;każdy poniedziałek o północy, możesz wygenerować OpenTableFactor:

SELECT *, (Open_tables * Uptime / Opened_Tables) OpenTableFactor FROM
(SELECT variable_value Uptime FROM information_schema.global_status
WHERE variable_name = 'Uptime_since_flush_status') up,
(SELECT variable_value Open_tables FROM information_schema.global_status
WHERE variable_name = 'Open_tables') opn,
(SELECT IF(variable_value=0,1,variable_value) Opened_tables
FROM information_schema.global_status
WHERE variable_name = 'Opened_tables') opnd;

Ten współczynnik otwartej tabeli odpowiada liczbie reprezentującej liczbę otwartych tabel w danym momencie w porównaniu ze średnią liczbą otwartych tabel w danym okresie. W przypadku FLUSH HOSTS;każdego tygodnia / dnia / gospodarza ta średnia jest w stosunku do tygodnia / dnia / godziny.

Oto próbka jednego z klientów mojego pracodawcy:

mysql> SELECT *, (Open_tables * Uptime / Opened_Tables) OpenTableFactor FROM     (SELECT variable_value Uptime FROM information_sc    hema.global_status     WHERE variable_name = 'Uptime_since_flush_status') up,     (SELECT variable_value Open_tables FROM informat    ion_schema.global_status     WHERE variable_name = 'Open_tables') opn,     (SELECT IF(variable_value=0,1,variable_value) Opened_ta    bles     FROM information_schema.global_status     WHERE variable_name = 'Opened_tables') opnd;
+----------+-------------+---------------+-------------------+
| Uptime   | Open_tables | Opened_tables | OpenTableFactor   |
+----------+-------------+---------------+-------------------+
| 14385123 | 16326       | 30429078      | 7717.996519579068 |
+----------+-------------+---------------+-------------------+
1 row in set (0.00 sec)

Ten klient zwykle utrzymuje około 7745 OpenTableFactor na maks. Jeśli OpenTableFactor spadnie nagle (nawet trochę), może to wskazywać na niższe wzorce ruchu, wysokie przerwane połączenia i tak dalej. Jeśli OpenTableFactor nigdy się nie zmieni (choćby trochę), może dać Ci możliwość zmiany tych ustawień:

Po skorygowaniu OpenTableFactor może się ciągle zmieniać lub uderzać w inny sufit lub płaskowyż. Dlatego stosowanie różnych jednostek w zmiennych stanu staje się niezbędne dla tego rodzaju strojenia.

AKTUALIZACJA 31.08.2011 12:42 EDT

Zapytanie SQL, które uruchomiłem dla OpenTableFactor, nie działa dla MySQL 5.0 i starszych. Jeśli używasz MySQL Administrator lub MONyog , możesz dostosować wykres za pomocą formuły w zapytaniu i monitorze. MONyog zbiera historię za pomocą SQLLite do późniejszego tworzenia wykresów historycznych. Można to zrobić dla dowolnej wersji MySQL.

RolandoMySQLDBA
źródło
Kilka dobrych sugestii, ale nie sądzę, że chcesz porównać dwie rzeczy z różnymi jednostkami bardziej niż chcesz porównać wartość skumulowaną z bieżącą. I pozostaje kwestia, czy to po prostu pomija brak.
Sam Brightman
3

Z jednego z komentarzy użytkownika na stronie dokumentacji table_cache :

Opened_tables to zmienna stanu, która utrzymuje bieżącą liczbę dodatkowych deskryptorów plików, które zostały przydzielone do otwierania tabel, w momencie wyczerpania dostępnych deskryptorów plików w table_cache. ...

Oznacza to, że zwiększa się, gdy przekroczysz swoją table_cachewartość. Więc tak, jak zwykle to sprawdzić jest porównanie opened_tablesz uptime, ale kluczem jest tu ją przejąć ustalonych odstępach czasu (raz na minutę ponad dziesięć minut, na przykład). Jeśli rośnie, może to oznaczać , że musisz ją zwiększyć table_cache.

Kilka zastrzeżeń do wspomnienia:

  • Kolejny komentarz w powyższej dokumentacji: „Zmienna statusu„ Opened_tables ”będzie również zwiększana o 2 za każdym razem, gdy utworzysz tymczasową tabelę.” Więc jeśli twoje zapytania wymagają wielu tabel tymczasowych, może to być przyczyną szybkiego wzrostu opened_tables. Możesz zobaczyć tymczasowe użycie tabeli przy użyciu następującego zapytania:

    SHOW GLOBAL STATUS LIKE '%tmp%';

  • Nie zwiększaj zbyt wysoko table_cache

    Powodem takiego zachowania jest to, że jeśli masz duże nie. tabel ze skomplikowanymi zapytaniami łączącymi kilka tabel i wiele połączeń uruchamiających te skomplikowane zapytania, możesz w końcu użyć pamięci podręcznej wszystkich deskryptorów plików (table_cache). W takim przypadku MySQL używa algorytmu do znalezienia najrzadziej używanego deskryptora, zamyka go i zastępuje z nowym deskryptorem.

Derek Downey
źródło