update lock from for ejemplo and mysql locking

lock - mysql select for update ejemplo



Mostrar todos los bloqueos actuales de get_lock (7)

A partir de MySQL 5.7, el esquema de rendimiento expone todos los bloqueos de metadatos, incluidos los bloqueos relacionados con la función GET_LOCK() .

Consulte http://dev.mysql.com/doc/refman/5.7/en/metadata-locks-table.html

¿Hay alguna forma de seleccionar / mostrar todos los bloqueos actuales que se han eliminado utilizando la función GET_LOCK ?

Tenga en cuenta que los bloqueos GET_LOCK son diferentes de los bloqueos de tabla, como los que se GET_LOCK con las LOCK TABLES : los lectores que quieran saber cómo ver esos bloqueos deben leer Detectar tablas bloqueadas (bloqueado por TABLA DE BLOQUEO)


Desde MySQL 5.7 en adelante, esto es posible, pero requiere primero habilitar el instrumento mdl en la tabla performance_schema.setup_instruments . Puede hacerlo temporalmente (hasta que el servidor se reinicie) ejecutando:

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

O permanentemente, agregando el siguiente encantamiento a la sección [mysqld] de su archivo my.cnf (o cualquier archivo de configuración que MySQL lea en su instalación):

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

(Naturalmente, será necesario reiniciar MySQL para que el cambio de configuración surta efecto si adopta este último enfoque).

Los bloqueos que saca después de que se haya habilitado el instrumento mdl se pueden ver ejecutando un SELECT en la tabla performance_schema.metadata_locks . Como se señala en los documentos, los bloqueos GET_LOCK tienen un OBJECT_TYPE de ''USER LEVEL LOCK'' , por lo que podemos filtrar nuestra consulta hacia ellos con una cláusula 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 mayoría de los significados de las columnas en este resultado están adecuadamente documentados en performance_schema.metadata_locks , pero vale la pena señalar un punto de confusión: la columna OWNER_THREAD_IDno contiene la ID de conexión (como se mostraría en la PROCESSLIST o devuelta por CONNECTION_ID() ) del hilo que contiene el bloqueo. Confusamente, el término "ID de hilo" se usa a veces como sinónimo de "ID de conexión" en la documentación de MySQL, pero esta no es una de esas veces. Si desea determinar el ID de conexión de la conexión que mantiene un bloqueo (por ejemplo, para anular esa conexión con KILL ), deberá buscar el PROCESSLIST_ID que corresponde al THREAD_ID en la tabla performance_schema.threads . Por ejemplo, para matar la conexión que mantenía mi cerradura arriba ...

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)


Encontré la siguiente forma que se puede usar si SABES el nombre de la cerradura

select IS_USED_LOCK(''lockname'');

Sin embargo, no he encontrado ninguna información sobre cómo enumerar todos los nombres.


Otra forma fácil es usar:

mysqladmin debug

Esto descarga mucha información (incluidos los bloqueos) en el registro de errores.


Si solo desea determinar si un bloqueo con nombre en particular se mantiene actualmente, puede usar IS_USED_LOCK :

SELECT IS_USED_LOCK(''foobar'');

Si alguna conexión mantiene el bloqueo, se devolverá la ID de esa conexión; de lo contrario, el resultado es NULL .


Referencia tomada de este post:

También puede usar este script para encontrar el bloqueo en 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


SHOW FULL PROCESSLIST;

Verás las cerraduras allí.