MySQL table_cache und Opened_tables

14

Ich habe Leute gesehen, die den Vergleich von Open_tables und Opened_tables verwendeten, um festzustellen, ob der table_cache in MySQL zu klein ist. Ich bin jedoch der Meinung, dass Opened_tables über die gesamte Betriebszeit hinweg kumulativ ist, sodass dies kein gültiger Vergleich ist. Die einzige Einschränkung besteht darin, dass Opened_tables möglicherweise nur auf Auslassungen stößt - auch wenn die pro Sekunde geöffneten Tische noch klein sind, ist es wahrscheinlich kein Problem, dass sie allmählich anwachsen.

Wenn der Vergleich von Open_tables mit Opened_tables nicht gültig ist, gibt es dafür eine andere Möglichkeit, Messdaten zu erhalten?

Dies ist auf MySQL 5.0, aber auch Unterschiede zwischen den Versionen sind willkommen.

Sam Brightman
quelle
Ich mag diese Frage, weil sie zum Nachdenken anregt. Dies wird mit +1 bewertet, um MySQL-Entwickler daran zu erinnern, die Statusvariablen besser zu nutzen, um den Zustand des DB-Servers zu messen.
RolandoMySQLDBA

Antworten:

7

Der Hauptgrund für einen großen table_cache ist der LOCK_open-Mutex nicht heiß ist. MySQL vor 5.5 ist sehr umstritten, wenn Sie versuchen, Tabellen zu öffnen / schließen, und Sie möchten dies so weit wie möglich einschränken, dh einen großen Tabellen-Cache haben.

So dass Sie nicht über ein bestimmtes Verhältnis von Treffern zu Misses egal (infact Sie Verhältnisse völlig ignorieren sollen - diese Blog - Post erklärt , warum ). Was Sie interessiert, ist die Miss-Rate , denn je öfter dies pro Sekunde passiert, desto höher ist die Wahrscheinlichkeit, dass Sie Konflikte haben (ein Thread muss warten, bis ein anderer Thread die Sperre aufhebt).

Wie erkennt man die Missrate? Sie holen ein paar Beispiele von Opened_Tables im Abstand von ein paar Sekunden während der geschäftigsten Zeit des Tages, und wenn es in jedem Beispiel Erhöhungen gibt, ist es wahrscheinlich eine gute Idee, zu prüfen, ob Sie den table_cache auffrischen können.

Hinweis: Ich rate ausdrücklich davon ab, mit der Betriebszeit zu vergleichen.

Morgan Tocker
quelle
5

Betrachten wir zunächst die folgenden Statusvariablen:

Offene Tabellen : Die Anzahl der offenen Tabellen.

Opened_tables : Die Anzahl der Tabellen, die geöffnet wurden. Wenn Opened_tables groß ist, ist Ihr table_open_cache-Wert wahrscheinlich zu klein.

Überraschenderweise liegt die Antwort auf Ihre Frage in der Frage selbst.

Die beiden Variablen wären nur dann sinnvoller, wenn Sie eine weitere Statusvariable in den Mix werfen: Uptime (oder Uptime_since_flush-Status für frische Durchschnitte nach FLUSH STATUS) ).

Sie sollten Open_tables gegen Opened_tables / Uptime vergleichen . Wenn Open_tables übersteigt (Opened_tables / Uptime) , haben Sie jetzt Anlass zur Sorge und sollten nach Dingen wie dem Folgenden Ausschau halten:

UPDATE 2011-08-31 12:18 EDT

Bitte beachten Sie, warum ich auch vorgeschlagen habe, Uptime_since_flush_status anstelle von Uptime zu verwenden, um ein festes Opened_tables-Wachstumsmuster für einen bestimmten Zeitraum zu erhalten.

Wenn Sie beispielsweise FLUSH STATUS;jeden Montag um Mitternacht ausführen , können Sie einen OpenTableFactor generieren:

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;

Dieser Faktor für offene Tische entspricht der Anzahl offener Tische zu einem bestimmten Zeitpunkt und der durchschnittlichen Anzahl offener Tische während eines bestimmten Zeitraums. Mit einerFLUSH HOSTS; pro Woche / Tag / Gastgeber ist dieser Durchschnitt gegen die Woche / Tag / Stunde.

Hier ein Auszug aus einem Kunden meines Arbeitgebers:

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)

Dieser Client verwaltet normalerweise ungefähr 7745 OpenTableFactor bei max. Wenn OpenTableFactor plötzlich abfällt (auch wenn ein wenig), kann dies auf geringere Verkehrsmuster, stark abgebrochene Verbindungen usw. hinweisen. Wenn sich OpenTableFactor nie ändert (selbst wenn ein wenig), bietet sich Ihnen möglicherweise die Möglichkeit, folgende Einstellungen zu ändern:

Einmal eingestellt, kann sich der OpenTableFactor ständig ändern oder eine andere Decke oder ein anderes Plateau treffen. Die Verwendung unterschiedlicher Einheiten innerhalb der Statusvariablen ist daher für diese Art der Abstimmung von entscheidender Bedeutung.

UPDATE 2011-08-31 12:42 EDT

Die SQL-Abfrage, die ich für den OpenTableFactor ausgeführt habe, funktioniert nicht für MySQL 5.0 und höher. Wenn Sie MySQL Administrator oder MONyog verwenden , können Sie ein Diagramm mithilfe der Formel in der Abfrage und im Monitor anpassen. MONyog sammelt den Verlauf mithilfe von SQLLite für eine spätere Verlaufsdarstellung. Dies kann für jede Version von MySQL durchgeführt werden.

RolandoMySQLDBA
quelle
Einige gute Vorschläge, aber ich glaube nicht, dass Sie zwei Dinge mehr mit verschiedenen Einheiten vergleichen möchten, als dass Sie einen kumulativen Wert mit einem aktuellen vergleichen möchten. Und es bleibt die Frage, ob dies nur Messfehler sind.
Sam Brightman
3

Aus einem der Benutzerkommentare auf der table_cache- Dokumentationsseite:

Opened_tables ist eine Statusvariable, die die Anzahl der zusätzlichen Dateideskriptoren aufzeichnet, die zum Öffnen von Tabellen zugewiesen wurden, wenn die verfügbaren Dateideskriptoren in table_cache erschöpft sind. ...

Dies bedeutet, dass es erhöht wird, wenn Sie Ihren table_cacheWert überschreiten. So ist der Weg , dies ich normalerweise überprüfen , ist zu vergleichen opened_tablesmit uptime, aber der Schlüssel hier ist es über einen festgelegten Intervall zu nehmen (einmal pro Minute über 10 Minuten, zum Beispiel). Wenn es zunimmt, kann es ein Hinweis darauf sein, dass Sie Ihr erhöhen müssentable_cache .

Ein paar Vorsichtsmaßnahmen zu erwähnen:

  • Ein weiterer Kommentar in dieser Dokumentation oben: "Die Statusvariable 'Opened_tables' wird jedes Mal um 2 erhöht, wenn Sie eine temporäre Tabelle erstellen." Wenn Ihre Abfragen also viele temporäre Tabellen erfordern, kann dies zu einem raschen Anstieg von führen opened_tables. Sie können Ihre temporäre Tabellenverwendung mit der folgenden Abfrage anzeigen:

    SHOW GLOBAL STATUS LIKE '%tmp%';

  • Erhöhen Sie den table_cache nicht zu hoch

    Der Grund für ein solches Verhalten ist, dass, wenn Sie große nein haben. Bei Tabellen mit komplizierten Abfragen, die mehrere Tabellen verbinden, und mehreren Verbindungen, die diese komplizierten Abfragen ausführen, wird möglicherweise der gesamte Cache Ihrer Dateideskriptoren (table_cache) verwendet. In diesem Fall verwendet MySQL einen Algorithmus, um den zuletzt verwendeten Deskriptor zu finden, ihn zu schließen und zu ersetzen es mit einem neuen Deskriptor.

Derek Downey
quelle