web-dev-qa-db-fra.com

moyen d'empêcher les requêtes d'attendre le verrouillage de niveau table

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 de table 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 à quelques reprises et j'ai vu environ 60 entrées de différentes requêtes de sélection, qui étaient toutes à l'état en attente du verrouillage au niveau de la table.

1. Je ne comprends pas pourquoi cette mise à jour sur la table article_comments peut affecter les instructions de sélection de la table article pour attendre le verrouillage du 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 devraient 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.

10
32bitfloat

Le moteur de stockage MyISAM est furieusement connu pour effectuer des verrous de table complets pour tout DML (INSERT, UPDATE, DELETE). 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 et article_comments sont les deux tables MyISAM
  • article_comments a un ou plusieurs index avec status comme colonne
  • Mises à jour de la page d'index pour article_comments sont mis en cache dans le tampon de clé MyISAM (dimensionné par key_buffer_size ), ce qui entraîne la sortie des anciennes pages d'index du tampon de clé MyISAM
  • Vous avez des requêtes SELECT qui effectuent des JOIN entre article et article_comments

Dans mon scénario suggéré, les SELECT sur la table article peuvent être empêchés d'autoriser les écritures car ils doivent attendre article_comments pour être libre de tout DML (dans ce cas, un UPDATE)

8
RolandoMySQLDBA

À ce stade, la page entière devient lente. La base de données elle-même est occupée pendant quelques minutes.

Ça sent comme vous avez un gros Query_cache?

mysql> SHOW VARIABLES LIKE 'query_cache%';
+------------------------------+----------+
| Variable_name                | Value    |
+------------------------------+----------+
| query_cache_limit            | 1048576  |
| query_cache_min_res_unit     | 4096     |
| query_cache_size             | 16777216 | -- Not over 50M
| query_cache_type             | DEMAND   | -- Only if using SQL_CACHE
| query_cache_wlock_invalidate | OFF      |
+------------------------------+----------+

Pour les systèmes de production avec beaucoup d'écritures, vous pouvez également désactiver OFF le query_cache.

Toutes les entrées du query_cache pour la table donnée sont purgées lorsque n'importe quelle écriture se produit dans 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.

7
Rick James