MySQL table_cache e Opened_tables


14

Ho visto persone usare il confronto tra Open_tables e Opened_tables per valutare se table_cache è troppo piccolo in MySQL. Tuttavia, ritengo che Opened_tables sia cumulativo nel tempo di attività, quindi questo non è un confronto valido. L'unico avvertimento è che forse Opened_tables è solo un errore - anche se anche se i tavoli che vengono aperti al secondo sono ancora piccoli, probabilmente non è un problema che cresca gradualmente.

Se il confronto tra Open_tables e Opened_tables non è valido, esiste un altro modo per ottenere dati misurati per questo?

Questo è su MySQL 5.0, ma anche le differenze tra le versioni sono benvenute.


Mi piace questa domanda perché è una domanda stimolante. Questo ottiene un +1 per ricordare agli sviluppatori MySQL di sfruttare appieno le variabili di stato per misurare l'integrità del DB Server.
RolandoMySQLDBA

Risposte:


7

Il motivo principale per avere un table_cache di grandi dimensioni è che il mutex di LOCK_open non è caldo. MySQL precedente alla 5.5 ha molte controversie quando si tenta di aprire / chiudere le tabelle, quindi si desidera limitare il più possibile questa operazione, ovvero disporre di una cache di tabelle di grandi dimensioni.

Quindi non ti interessa un particolare rapporto tra hit e miss (infatti dovresti ignorare del tutto i rapporti - questo post sul blog spiega perché ). Quello che ti interessa è la percentuale di mancanze , perché più volte ciò accade al secondo, maggiore è la possibilità che tu abbia una contesa (un thread deve attendere un altro thread per rilasciare il blocco).

Come si individua la percentuale di miss? Prendi alcuni campioni di Opened_Tables a pochi secondi di distanza durante il periodo più trafficato della giornata e se ci sono aumenti in ciascun campione, è probabilmente una buona idea vedere se riesci ad aumentare il table_cache.

Nota: in particolare, non consiglio di confrontare i tempi di attività.


5

Innanzitutto, consideriamo quelle variabili di stato:

Tabelle aperte : il numero di tabelle aperte.

Opened_tables : il numero di tabelle che sono state aperte. Se Opened_tables è grande, il valore di table_open_cache è probabilmente troppo piccolo.

Sorprendentemente, la risposta alla tua domanda sta nella domanda stessa.

Le due variabili avrebbero più senso solo se si aggiungesse un'altra variabile di stato nel mix: Uptime (o Uptime_since_flush status per medie fresche dopo FLUSH STATUS ).

Dovresti confrontare Open_tables agsinst (Opened_tables / Uptime) . Se Open_tables sale sopra (Opened_tables / Uptime) , ora hai motivo di preoccupazione e dovresti tenere d'occhio cose come le seguenti:

AGGIORNAMENTO 2011-08-31 12:18 EDT

Nota perché ho anche suggerito di utilizzare Uptime_since_flush_status anziché Uptime per ottenere un modello di crescita Opened_tables fisso per un determinato periodo.

Ad esempio, se si esegue FLUSH STATUS;ogni lunedì a mezzanotte, è possibile generare un 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;

Questo fattore di tabella aperta equivale al numero che rappresenta il numero di tabelle aperte in un dato momento rispetto al numero medio di tabelle aperte durante un determinato periodo. Con un FLUSH HOSTS;ogni settimana / giorno / host, quella media è contro la settimana / giorno / ora.

Ecco un esempio di uno dei clienti del mio datore di lavoro:

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)

Questo client mantiene normalmente circa 7745 OpenTableFactor al massimo. Se OpenTableFactor si abbassa improvvisamente (anche se un po '), potrebbe indicare modelli di traffico più bassi, alte concentrazioni interrotte e così via. Se OpenTableFactor non cambia mai (anche se un po '), potrebbe offrirti l'opportunità di modificare queste impostazioni:

Una volta regolato, OpenTableFactor può cambiare costantemente o colpire un altro soffitto o plateau. Pertanto, l'utilizzo di unità diverse all'interno delle variabili di stato diventa vitale per questo tipo di ottimizzazione.

AGGIORNAMENTO 2011-08-31 12:42 EDT

La query SQL che ho eseguito per OpenTableFactor non funziona per MySQL 5.0 e versioni successive. Se si utilizza MySQL Administrator o MONyog , è possibile personalizzare un grafico utilizzando la formula nella query e nel monitor. MONyog raccoglie la cronologia usando SQLLite per un successivo grafico storico. Questo può essere fatto per qualsiasi versione di MySQL.


Alcuni buoni suggerimenti, ma non credo che tu voglia confrontare due cose con unità diverse più di quanto tu voglia confrontare un valore cumulativo con uno attuale. E rimane il problema se questa misura solo i mancati.
Sam Brightman,

3

Da uno dei commenti dell'utente sulla pagina della documentazione di table_cache :

Opened_tables è una variabile di stato che mantiene un conteggio corrente del numero di descrittori di file aggiuntivi che sono stati allocati per l'apertura di tabelle a volte in cui i descrittori di file disponibili in table_cache sono stati esauriti. ...

Ciò significa che viene incrementato quando si supera il table_cachevalore. Quindi il modo che normalmente controllare questo è quello di confrontare opened_tablescon uptime, ma la chiave qui è quello di prendere in un intervallo di set (una volta al minuto più di dieci minuti, per esempio). Se aumenta, potrebbe essere un'indicazione che devi aumentaretable_cache .

Un paio di avvertimenti per menzionare:

  • Un altro commento nella suddetta documentazione: "Anche la variabile di stato 'Opened_tables' verrà incrementata di 2 ogni volta che crei una tabella temporanea." Quindi, se le tue query richiedono molte tabelle temporanee, questa potrebbe essere la causa di un rapido aumento di opened_tables. È possibile visualizzare l'utilizzo temporaneo della tabella utilizzando la seguente query:

    SHOW GLOBAL STATUS LIKE '%tmp%';

  • Non aumentare il table_cache troppo in alto

    La ragione di tale comportamento è che, se si dispone di un grande no. di tabelle con query complicate che uniscono più tabelle e connessioni multiple che eseguono quelle query complicate, si potrebbe finire per utilizzare la cache di tutti i descrittori di file (table_cache) in tal caso MySQL utilizza un algoritmo per trovare il descrittore utilizzato più di recente, chiuderlo e sostituirlo con un nuovo descrittore.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.