showprocesslist->;+------+----------+------------------+----- - ------+---------+------+------------------------------ - -----">
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 (presquedéfinitivement ; voir ci-dessous) la chose à faire. Mais ensuite ça s'est vu,
...et 1398n'est pasla 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, etle prochainthread essayant d'effectuer quelque choseégalements'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ètementrien.
La vraie raison est queun 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 queil n'y a pas deprocessus marqués "En attente du verrouillage des métadonnées". On peut dire que ces personnes sont des victimes.
SHOW FULL PROCESSLIST
WILLvous dit si un processusfaitquelque chose, oui. Habituellement, cela fonctionnera. Ici, le processus détenant le verroune fait rienet 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", alorsc'estest 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 coupableest presque certainementle processus1396, 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'entredansil 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 estordonnée.
Important: Si vous vous connectez à MySQL en tant qu'utilisateur restreint,
SHOW FULL PROCESSLIST
n'affichera pastous 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 processusen 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 attendsans raison apparenteet 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'esttoujoursun 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
Tueztous lesprocessus en état "en veille" sur la même base de données quisont plus anciens que lethread le plus ancien en état "en attente de verrouillage des métadonnées". Voici ce que feraitArnaud 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 lele plus jeunethread qui dort et plus âgé que l'ancien threaden attente du verrouillage des métadonnées :