Ma base de données MySQL sert de backend de stockage pour trois applications Web. Cependant, j'ai récemment rencontré l'erreur "En attente du verrouillage des métadonnées de la table" de manière permanente. Cela arrive presque tout le temps et je ne comprends pas pourquoi.
mysql> show processlist -> ; +------+-----------+-----------------+------------+---------+------+---------------------------------+------------------------------------------------------------------------------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +------+-----------+-----------------+------------+---------+------+---------------------------------+------------------------------------------------------------------------------------------------------+ | 36 | root | localhost:33444 | bookmaker2 | Sleep | 139 | | NULL | | 37 | root | localhost:33445 | bookmaker2 | Sleep | 139 | | NULL | | 38 | root | localhost:33446 | bookmaker2 | Sleep | 139 | | NULL | | 39 | root | localhost:33447 | bookmaker2 | Sleep | 49 | | NULL | | 40 | root | localhost:33448 | bookmaker2 | Sleep | 139 | | NULL | | 1315 | bookmaker | localhost:34869 | bookmaker | Sleep | 58 | | NULL | | 1316 | root | localhost:34874 | bookmaker3 | Sleep | 56 | | NULL | | 1395 | bookmaker | localhost:34953 | bookmaker | Sleep | 58 | | NULL | | 1396 | root | localhost:34954 | bookmaker3 | Sleep | 46 | | NULL | | 1398 | root | localhost:34956 | bookmaker3 | Query | 28 | Waiting for table metadata lock | CREATE TABLE IF NOT EXISTS LogEntries ( lid INT NOT NULL AUTO_INCREMEN | | 1399 | root | localhost | NULL | Query | 0 | NULL | show processlist | +------+-----------+-----------------+------------+---------+------+---------------------------------+------------------------------------------------------------------------------------------------------+
Bien sûr, vous pouvez tuer le processus correspondant. Cependant, si je redémarre le programme qui tente de créer la structure de table pour la base de données "bookmaker3", le processus nouvellement créé est à nouveau dans Metallock.
Je ne peux même pas supprimer la base de données :
mysql> drop database bookmaker3;
Cela créera également un verrou métallique.
Comment résoudre ce problème ?
Malheureusement, la solution acceptée est fausse. C'est tout à fait exact
C'est définitivement (presque définitivement ; voir ci-dessous) la chose à faire. Mais ensuite ça s'est vu,
...et 1398 n'est pas la connexion à la serrure. comment ça? 1398 est une connexion en attente d'être verrouillée. Cela signifie qu'il n'a pas encore acquis le verrou, donc le tuer n'a aucun effet. Le processus détenant le verrou détiendra toujours le verrou, et le prochain thread essayant d'effectuer quelque chose également s'arrêtera et entrera "attendre le verrouillage des métadonnées" dans l'ordre approprié.
Vous ne pouvez pas garantir qu'un processus "En attente de verrouillage des métadonnées" (WFML) ne se bloquera pas également, mais vous pouvez être sûr que le simple fait de tuer le processus WFML ne fera complètement rien .
La vraie raison est que un autre processus détient le verrou, et plus important encore,
SHOW FULL PROCESSLIST
ne vous dira pas directement quel processus .Une chose dont vous pouvez être sûr est que il n'y a pas de processus marqués "En attente du verrouillage des métadonnées". On peut dire que ces personnes sont des victimes.
SHOW FULL PROCESSLIST
WILL vous dit si un processus fait quelque chose, oui. Habituellement, cela fonctionnera. Ici, le processus détenant le verrou ne fait rien et est caché dans d'autres threads qui ne font rien non plus et sont signalés comme "en veille".Si
SHOW FULL PROCESSLIST
vous montre un processus exécutant DML, ou dans un état "envoi de données", alors c'est est presque certainement le coupable. D'autres processus attendent qu'il libère le verrou (il peut s'agir de verrous implicites ; le processus n'a pas du tout besoin d'émettre LOCK TABLE, qui se verrouille en fait d'une manière différente). Mais un processus peut détenir un verrou sans effectuer aucune opération et être marqué de manière appropriée comme « en veille ».Dans le cas d'OP, le coupable est presque certainement le processus 1396, qui a été démarré avant le processus 1398, est maintenant dans l'état
睡眠
et ce depuis 46 secondes. Depuis que 1396 a apparemment fait tout ce qu'il devait faire (il s'avère qu'il dort maintenant, et ce depuis 46 secondes, en ce qui concerne MySQL), aucun thread n'entre dans il peut maintenir le verrou et pourtant maintenez-le endormi avant (sinon 1396 s'arrêterait également).En raison de la politique de verrouillage « sans blocage » de MySQL, aucun processus ne peut détenir un verrou, le libérer et le restaurer à nouveau. Par conséquent, les attentes de verrouillage sont toujours causées par des processus qui détiennent toujours le verrou et ne l'ont jamais détenu auparavant. Ceci est utile (nous exploiterons ce fait ci-dessous) car cela garantit que la "file d'attente" de verrouillage est ordonnée.
Important : Si vous vous connectez à MySQL en tant qu'utilisateur restreint,
SHOW FULL PROCESSLIST
n'affichera pas tous les processus. Le verrou peut donc être détenu par un processus que vous ne voyez pas.Donc : si
SHOW FULL PROCESSLIST
vous montre tout et montre un processus en cours, alors ce processus est probablement responsable et vous devez attendre qu'il termine ce qu'il fait (ou vous pouvez le tuer - à vos propres risques).Le reste de cette réponse traite d'une situation confuse où un processus attend sans raison apparente et personne ne semble faire quoi que ce soit.
Mieux
显示进程列表
Ce qui précède peut être ajusté pour afficher uniquement les processus qui sont en SOMMEIL, et il les triera de toute façon par ordre temporel décroissant, il est donc plus facile de trouver les processus bloqués (qui, en raison de l'ordre, sont généralement
que n'importe quel temps d'attente.immédiatement avant "en attente de métadonnées lock" Dormez un ; et c'est toujours un sommeil de plus
Choses importantes
Gardez tous les processus « en attente de verrouillage des métadonnées » séparés.
Solution rapide et sale, pas vraiment recommandée, mais rapide
Tuez tous les processus en état "en veille" sur la même base de données qui sont plus anciens que le thread le plus ancien en état "en attente de verrouillage des métadonnées". Voici ce que ferait Arnaud Amaury :
KILL
KILL, réévaluez la situation et redémarrez le processus en conséquence. Les processus en attente peuvent être en cours d'exécution maintenant, ou ils ont peut-être été exécutés brièvement et sont maintenant en veille. Ils peuvent même détenir de nouveaux verrous de métadonnées maintenant.Quatre-vingt-dix-neuf fois sur cent, le thread à tuer est le le plus jeunethread qui dort et plus âgé que l'ancien thread en attente du verrouillage des métadonnées :