it-swarm.dev

MySQL table_cache i Opened_tables

Widziałem, jak ludzie używają 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.

14
Sam Brightman

Największym powodem posiadania dużego table_cache jest to, że LOCK_open mutex nie jest gorący. MySQL w wersji wcześniejszej 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 ). Zależy Ci na wskaźniku chybienia , ponieważ im więcej razy zdarza się to na sekundę, tym większa szansa, że ​​będziesz miał spór (jeden wątek musi poczekaj, aż kolejny wątek zwolni blokadę.)

Jak oceniasz wskaźnik braków? Pobierasz kilka próbek Opened_Tables w odstępie kilku sekund w najbardziej obciążonym okresie 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.

7
Morgan Tocker

Najpierw rozważmy te zmienne statusu:

Otwórz 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.

Te dwie zmienne miałyby większy sens, jeśli wrzucisz do mieszanki jeszcze jedną zmienną statusu: ptime (lub ptime_since_flush status dla świeżych średnich po STATUS PŁUKANIA =).

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ć naprawiono wzór wzrostu Opened_tables dla danego okresu.

Na przykład, jeśli uruchomisz FLUSH STATUS; w 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. Z FLUSH HOSTS; co tydzień/dzień/gospodarz, 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, korzystając ze wzoru 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.

5
RolandoMySQLDBA

Od 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 przejdziesz przez swoje table_cache wartość. Tak więc zwykle sprawdzam, czy porównać opened_tables za pomocą uptime, ale kluczem tutaj jest przejęcie go w ustalonym przedziale (na przykład raz na minutę przez dziesięć minut). Jeśli rośnie, może wskazywać, że musisz zwiększyć swoje 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 też table_cache też high

    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.

3
Derek Downey