web-dev-qa-db-fra.com

Afficher tous les verrous actuels de get_lock

Est-il possible de sélectionner/afficher tous les verrous actuels qui ont été supprimés à l'aide de la fonction GET_LOCK ?

Notez que les verrous GET_LOCK sont différents des verrous de table, comme ceux obtenus avec LOCK TABLES - les lecteurs qui veulent savoir comment voir ces verrous doivent lire Détection des tables verrouillées (verrouillé par LOCK TABLE)

54
braunbaer

À partir de MySQL 5.7, le schéma de performances expose tous les verrous de métadonnées, y compris les verrous liés à la fonction GET_LOCK().

Voir http://dev.mysql.com/doc/refman/5.7/fr/metadata-locks-table.html

17
Marc Alff
SHOW FULL PROCESSLIST;

Vous verrez les serrures à l'intérieur

15
Robert

À partir de MySQL 5.7, c'est possible, mais il faut d'abord activer l'instrument mdl dans la table performance_schema.setup_instruments . Vous pouvez le faire temporairement (jusqu'au prochain redémarrage du serveur) en exécutant:

UPDATE performance_schema.setup_instruments
SET enabled = 'YES'
WHERE name = 'wait/lock/metadata/sql/mdl';

Ou de manière permanente, en ajoutant l'incantation suivante à la section [mysqld] de votre fichier my.cnf (ou à tout autre fichier de configuration lu par MySQL lors de votre installation):

[mysqld]
performance_schema_instrument = 'wait/lock/metadata/sql/mdl=ON'

(Naturellement, MySQL devra être redémarré pour que le changement de configuration prenne effet si vous adoptez cette dernière approche.)

Les verrous que vous retirez après que l'instrument mdl a été activé sont visibles en exécutant un SELECT sur la table performance_schema.metadata_locks . Comme indiqué dans la documentation, les serrures GET_LOCK ont un OBJECT_TYPE de 'USER LEVEL LOCK', afin que nous puissions filtrer notre requête avec une clause WHERE:

mysql> SELECT GET_LOCK('foobarbaz', -1);
+---------------------------+
| GET_LOCK('foobarbaz', -1) |
+---------------------------+
|                         1 |
+---------------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM performance_schema.metadata_locks 
    -> WHERE OBJECT_TYPE='USER LEVEL LOCK'
    -> \G
*************************** 1. row ***************************
          OBJECT_TYPE: USER LEVEL LOCK
        OBJECT_SCHEMA: NULL
          OBJECT_NAME: foobarbaz
OBJECT_INSTANCE_BEGIN: 139872119610944
            LOCK_TYPE: EXCLUSIVE
        LOCK_DURATION: EXPLICIT
          LOCK_STATUS: GRANTED
               SOURCE: item_func.cc:5482
      OWNER_THREAD_ID: 35
       OWNER_EVENT_ID: 3
1 row in set (0.00 sec)

mysql> 

La signification des colonnes dans ce résultat est généralement documentée de manière adéquate à l'adresse suivante: https://dev.mysql.com/doc/refman/fr/metadata-locks-table.html , mais il convient de noter un point de confusion: la colonne OWNER_THREAD_ID ne contient pas l'ID connection (comme cela serait montré dans la PROCESSLIST ou retourné par CONNECTION_ID()) du thread qui détient le verrou. De manière confuse, le terme "ID de thread" est parfois utilisé comme synonyme de "ID de connexion" dans la documentation MySQL, mais c'est pas une de ces fois. Si vous voulez déterminer l'ID connection de la connexion qui détient un verrou (par exemple, pour supprimer cette connexion avec KILL ), vous devez rechercher le PROCESSLIST_ID qui correspond au THREAD_ID dans la table performance_schema.threads . Par exemple, pour tuer la connexion qui tenait mon verrou au-dessus ...

mysql> SELECT OWNER_THREAD_ID FROM performance_schema.metadata_locks
    -> WHERE OBJECT_TYPE='USER LEVEL LOCK'
    -> AND OBJECT_NAME='foobarbaz';
+-----------------+
| OWNER_THREAD_ID |
+-----------------+
|              35 |
+-----------------+
1 row in set (0.00 sec)

mysql> SELECT PROCESSLIST_ID FROM performance_schema.threads
    -> WHERE THREAD_ID=35;
+----------------+
| PROCESSLIST_ID |
+----------------+
|             10 |
+----------------+
1 row in set (0.00 sec)

mysql> KILL 10;
Query OK, 0 rows affected (0.00 sec)
11
Mark Amery

Si vous voulez simplement déterminer si un verrou nommé particulier est actuellement maintenu, vous pouvez utiliser IS_USED_LOCK :

SELECT IS_USED_LOCK('foobar');

Si une connexion détient le verrou, l'ID de cette connexion sera renvoyé; sinon, le résultat est NULL.

5
Mark Amery

J'ai trouvé le moyen suivant qui peut être utilisé si vous savez le nom du verrou

select IS_USED_LOCK('lockname');

cependant, je n'ai trouvé aucune information sur la façon de lister tous les noms.

1
arheops

Un autre moyen simple consiste à utiliser:

mysqladmin debug 

Cela vide beaucoup d’informations (y compris les verrous) dans le journal des erreurs.

0
Sonicthoughts

Référence tirée de ce post:

Vous pouvez également utiliser ce script pour trouver le verrou dans MySQL. 

SELECT 
    pl.id
    ,pl.user
    ,pl.state
    ,it.trx_id 
    ,it.trx_mysql_thread_id 
    ,it.trx_query AS query
    ,it.trx_id AS blocking_trx_id
    ,it.trx_mysql_thread_id AS blocking_thread
    ,it.trx_query AS blocking_query
FROM information_schema.processlist AS pl 
INNER JOIN information_schema.innodb_trx AS it
    ON pl.id = it.trx_mysql_thread_id
INNER JOIN information_schema.innodb_lock_waits AS ilw
    ON it.trx_id = ilw.requesting_trx_id 
        AND it.trx_id = ilw.blocking_trx_id
0
Anvesh