web-dev-qa-db-fra.com

MySQL table_cache et Opened_tables

J'ai vu des gens utiliser la comparaison d'Open_tables et d'Opened_tables pour évaluer si la table_cache est trop petite dans MySQL. Cependant, je crois que Opened_tables est cumulatif sur la disponibilité, donc ce n'est pas une comparaison valide. La seule mise en garde étant que peut-être Opened_tables ne se heurte qu'à des échecs - bien que même si les tables ouvertes par seconde sont encore petites, ce n'est probablement pas un problème pour qu'elle se développe progressivement.

Si la comparaison d'Open_tables à Opened_tables n'est pas valide, existe-t-il un autre moyen d'obtenir des données mesurées pour cela?

C'est sur MySQL 5.0, mais les différences entre les versions sont également les bienvenues.

14
Sam Brightman

La principale raison d'avoir un grand table_cache est que LOCK_open mutex n'est pas chaud. MySQL avant 5.5 a beaucoup de conflits lorsque vous essayez d'ouvrir/fermer des tables, vous voulez donc restreindre cela autant que possible, c'est-à-dire avoir un grand cache de table.

Donc, vous ne vous souciez pas d'un ratio particulier de succès par rapport aux échecs (en fait, vous devez ignorer complètement les ratios - ce billet de blog explique pourquoi ). Ce qui vous importe, c'est le taux d'échec , car plus il se produit par seconde, plus les chances de contention sont élevées (un thread doit attendez qu'un autre thread libère le verrou.)

Comment repérez-vous le taux de miss? Vous récupérez quelques échantillons d'Opened_Tables à quelques secondes d'intervalle pendant la période la plus occupée de la journée, et s'il y a des augmentations dans chaque échantillon, c'est probablement une bonne idée de voir si vous pouvez augmenter la table_cache.

Remarque: Je recommande très précisément de ne pas comparer avec la disponibilité.

7
Morgan Tocker

Tout d'abord, considérons ces variables d'état:

Tables ouvertes : nombre de tables ouvertes.

Opened_tables : Le nombre de tables qui ont été ouvertes. Si Opened_tables est grand, votre valeur table_open_cache est probablement trop petite.

Étonnamment, la réponse à votre question réside dans la question elle-même.

Les deux variables n'auraient plus de sens que si vous jetiez une autre variable d'état dans le mélange: ptime (ou ptime_since_flush status pour les moyennes fraîches après FLUSH STATUS =).

Vous devriez comparer Open_tables agsinst (Opened_tables/Uptime) . Si Open_tables grimpe au-dessus (Opened_tables/Uptime) , vous avez maintenant des raisons de vous inquiéter et devez garder un œil ouvert sur des choses comme les suivantes:

MISE À JOUR 2011-08-31 12:18 EDT

Veuillez noter pourquoi j'ai également suggéré d'utiliser Uptime_since_flush_status au lieu de Uptime pour obtenir un correction du modèle de croissance d'Opened_tables pour une période donnée.

Par exemple, si vous exécutez FLUSH STATUS; chaque lundi à minuit, vous pouvez générer 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;

Ce facteur de table ouverte correspond au nombre qui représente le nombre de tables ouvertes à un moment donné par rapport au nombre moyen de tables ouvertes tout au long d'une période donnée. Avec un FLUSH HOSTS; chaque semaine/jour/hôte, cette moyenne est par rapport à la semaine/jour/heure.

Voici un échantillon de l'un des clients de mon employeur:

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)

Ce client maintient normalement environ 7745 OpenTableFactor à max. Si OpenTableFactor tombe soudainement (même si c'est un peu), cela pourrait indiquer des modèles de trafic plus faibles, des connexions avortées élevées, etc. Si OpenTableFactor ne change jamais (même un peu), cela pourrait vous offrir la possibilité de modifier ces paramètres:

Une fois réglé, l'OpenTableFactor peut changer constamment ou atteindre un autre plafond ou plateau. Ainsi, l'utilisation de différentes unités dans les variables d'état devient vitale pour ce type de réglage.

MISE À JOUR 2011-08-31 12:42 EDT

La requête SQL que j'ai exécutée pour OpenTableFactor ne fonctionne pas pour MySQL 5.0 et inversement. Si vous utilisez Administrateur MySQL ou MONyog , vous pouvez personnaliser un graphique en utilisant la formule dans la requête et le moniteur. MONyog collecte l'historique à l'aide de SQLLite pour un graphique historique ultérieur. Cela peut être fait pour n'importe quelle version de MySQL.

5
RolandoMySQLDBA

À partir de l'un des commentaires des utilisateurs sur la page de documentation table_cache :

Opened_tables est une variable d'état qui conserve un décompte en cours du nombre de descripteurs de fichiers supplémentaires qui ont été alloués pour l'ouverture de tables lorsque les descripteurs de fichiers disponibles dans table_cache ont été épuisés. ...

Cela signifie qu'il est incrémenté lorsque vous passez votre table_cache valeur. Donc, la façon dont je vérifie normalement cela est de comparer opened_tables avec uptime, mais la clé ici est de le prendre sur un intervalle défini (une fois par minute sur dix minutes, par exemple). S'il augmente, cela peut être une indication que vous devez augmenter votre table_cache.

Quelques mises en garde à mentionner:

  • Un autre commentaire dans cette documentation ci-dessus: "La variable d'état 'Opened_tables' sera également incrémentée de 2 chaque fois que vous créez une table temporaire." Donc, si vos requêtes nécessitent de nombreuses tables temporaires, cela pourrait être la cause d'une augmentation rapide de opened_tables. Vous pouvez voir votre utilisation de table temporaire à l'aide de la requête suivante:

    SHOW GLOBAL STATUS LIKE '%tmp%';

  • N'augmentez pas le table_cache trop élevé

    La raison d'un tel comportement est que, si vous avez un grand non. de tables avec des requêtes compliquées joignant plusieurs tables et plusieurs connexions exécutant ces requêtes compliquées, vous pourriez finir par utiliser le cache de tous vos descripteurs de fichiers (table_cache) dans ce cas, MySQL utilise un algorithme pour trouver le descripteur le moins récemment utilisé, le ferme et remplace avec un nouveau descripteur.

3
Derek Downey