Nous avons rencontré un problème après avoir déplacé la base de données de notre client vers un serveur supplémentaire. Cela aurait dû avoir des effets positifs sur les performances du site, mais il y a un problème avec le verrouillage des tables dans MyISAM. (J'ai entendu parler d'InnoDB au lieu de MyISAM, mais nous ne pouvons pas changer le moteur dans un avenir proche).
Nous pourrions le repérer dans une mise à jour-requête qui est effectuée lorsqu'un modérateur active un commentaire sur le site d'articles. Voici le processus:
- la requête de mise à jour est traitée
SET status = 1 WHERE id = 5
(l'index est défini) - les fichiers mis en cache de la page sont supprimés
À ce stade, la page entière devient lente. La base de données elle-même est occupée pendant quelques minutes. J'ai récupéré la liste de processus à plusieurs reprises et j'ai vu environ 60 entrées de différentes requêtes de sélection, qui étaient toutes en attente de verrouillage au niveau de la table .
1. Je ne comprends pas pourquoi cette mise à jour sur la table article_comments
peut affecter les instructions select pour que la table article
attende le verrouillage au niveau de la table. Dans processlist, presque toutes les requêtes en attente provenaient de cette table. J'ai lu que les mises à jour / insertions sont préférées aux sélections et que cela peut causer de tels problèmes, mais le tableau des articles lui-même n'est pas mis à jour lorsque les commentaires sont activés, donc les sélections ne doivent pas attendre. Ai-je mal compris cela?
2. Y a-t-il autre chose que le passage à InnoDB pour empêcher ce comportement ou au moins pour obtenir un meilleur équilibre? Je suis très irrité du fait que ce problème ne soit pas apparu avant de déplacer la base de données vers le nouveau serveur. Je suppose qu'il y a une mauvaise configuration mais je ne sais pas comment l'identifier.
key_buffer_size
était réglé sur1GB
. Augmenter cela pour10GB
réduire le problème.Réponses:
Le moteur de stockage MyISAM est furieusement connu pour effectuer des verrous de table complets pour tout DML (INSERT, UPDATEs, DELETEs). InnoDB résoudrait définitivement ce problème à long terme.
J'ai écrit sur les avantages et les inconvénients de l'utilisation de MyISAM vs InnoDB
En ce qui concerne votre question actuelle, voici un scénario possible:
article
etarticle_comments
sont les deux tables MyISAMarticle_comments
a un ou plusieurs index avecstatus
comme colonnearticle_comments
sont mises en cache dans le tampon de clés MyISAM (dimensionnées par key_buffer_size ), entraînant la sortie des anciennes pages d'index du tampon de clés MyISAMarticle
etarticle_comments
Dans mon scénario suggéré, les SELECT sur la
article
table peuvent être empêchés d'autoriser les écritures car ils doivent attendrearticle_comments
d'être libres de tout DML (dans ce cas, unUPDATE
)la source
Ça sent comme vous avez un gros Query_cache?
Pour les systèmes de production avec beaucoup d'écritures, vous pouvez aussi désactiver le query_cache.
Toutes les entrées de la query_cache pour la table donnée sont purgés lorsque toute écriture se produit à cette table. Plus le QC est grand, plus cette tâche est lente.
MyISAM utilise des verrous de "niveau table". Les lectures et les écritures ne peuvent pas avoir lieu en même temps (sur la même table). Brut, mais efficace.
la source