Razones y soluciones para esperar el bloqueo de metadatos de la tabla en mysql

http://www.cnblogs.com/dyllove98/archive/2013/07/16/3194332.html


最近 经常 遇到 mysql 数据库 死锁 , 郁闷 死 , 
muestra lista de procesos; 时 Esperando el bloqueo de metadatos de la tabla 能 一直 锁 很久 下面 


有 官 网 的 一段 话 , 可以 理解 下 
http://dev.mysql.com/doc/refman/5.5/en/metadata-locking.html 


8.10.4. Bloqueo de metadatos 
MySQL 5.5.3 y versiones posteriores utilizan el bloqueo de metadatos para administrar el acceso a los objetos (tablas, activadores, etc.). El bloqueo de metadatos se utiliza para garantizar la coherencia de los datos, pero implica algunos gastos generales, que aumentan a medida que aumenta el volumen de consultas. La contención de metadatos aumenta cuanto más múltiples consultas intentan acceder a los mismos objetos. 


El bloqueo de metadatos no reemplaza el caso de definición de tabla, y sus mutxes y bloqueos difieren del mutex LOCK_open. La siguiente discusión proporciona información sobre cómo funciona el bloqueo de metadatos. 


Para garantizar la serialización de la transacción, el servidor no debe permitir que una sesión realice una declaración de lenguaje de definición de datos (DDL) en una tabla que se utiliza en una transacción incompleta en otra sesión. El servidor logra esto adquiriendo bloqueos de metadatos en las tablas utilizadas dentro de una transacción y postergando la liberación de esos bloqueos hasta que finalice la transacción. Un bloqueo de metadatos en una tabla evita cambios en la estructura de la tabla. Este enfoque de bloqueo tiene la implicación de que una tabla que está siendo utilizada por una transacción dentro de una sesión no puede ser utilizada en declaraciones DDL por otras sesiones hasta que finalice la transacción. 


Este principio se aplica no solo a las tablas transaccionales, sino también a las tablas no transaccionales. Suponga que una sesión comienza una transacción que usa la tabla transaccional ty la tabla no transaccional nt de la siguiente manera: 


INICIAR TRANSACCIÓN; 
SELECCIONAR * DE t; 
SELECCIONAR * FROM nt; 
Los bloqueos de metadatos se mantienen tanto en t como en nt hasta que finaliza la transacción. Si otra sesión intenta una operación DDL en cualquiera de las tablas, se bloquea hasta que se libera el bloqueo de metadatos al final de la transacción. Por ejemplo, una segunda sesión se bloquea si intenta alguna de estas operaciones: 


DROP TABLE t; 
ALTER TABLE t ...; 
DROP TABLE nt; 
ALTER TABLE nt ...; 
Si el servidor adquiere bloqueos de metadatos para una declaración que es sintácticamente válida pero falla durante la ejecución, no libera los bloqueos antes. La liberación del bloqueo aún se aplaza hasta el final de la transacción porque la declaración fallida se escribe en el registro binario y los bloqueos protegen la coherencia del registro. 


In autocommit mode, each statement is in effect a complete transaction, so metadata locks acquired for the statement are held only to the end of the statement. 


Metadata locks acquired during a PREPARE statement are released once the statement has been prepared, even if preparation occurs within a multiple-statement transaction. 


Before MySQL 5.5.3, when a transaction acquired the equivalent of a metadata lock for a table used within a statement, it released the lock at the end of the statement. This approach had the disadvantage that if a DDL statement occurred for a table that was being used by another session in an active transaction, statements could be written to the binary log in the wrong order 


一个没提交的事务使用了A表, 另外一个session 对A表进行alter,出现waiting for table metadata lock 


在insert into t select * from share 运行时, 同时执行alter table t add index(play_count), 
alter table语句会Waiting for table metadata lock, 直到insert into … select 语句结束。 


不是传说5.6支持online DDL么? 怎么还会Waiting for table metadata lock? 
后来想想, online DDL应该是指在alter table进行的时候, 插入/修改/删除数据的sql语句不会Waiting for table metadata lock. 


MySQL 5.6 enhances many other types OF ALTER TABLE operations TO avoid copying the TABLE.  
Another enhancement allows SELECT queries AND INSERT, UPDATE, AND DELETE (DML) statements TO proceed while the TABLE IS being altered.  
This combination OF features IS now known AS online DDL. 
那么就让alter table wait去吧。 


后来又发现另外一个神奇的事: 
mysql [localhost] {msandbox} (spc) > SHOW processlist; 
+----+----------+-----------+------+---------+------+---------------------------------+-------------------------------------+ 
| Id | USER     | Host      | db   | Command | TIME | State                           | Info                                | 
+----+----------+-----------+------+---------+------+---------------------------------+-------------------------------------+ 
|  5 | msandbox | localhost | spc  | Query   |    1 | Waiting FOR TABLE metadata LOCK | ALTER TABLE t ADD INDEX(play_count) | 
|  8 | msandbox | localhost | spc  | Query   |    3 | USER sleep                      | SELECT sleep(100) FROM t            | 
| 10 | msandbox | localhost | spc  | Query   |    0 | init                            | SHOW processlist                    | 
+----+----------+-----------+------+---------+------+---------------------------------+-------------------------------------+ 


重启后再试一次: 
mysql [localhost] {msandbox} (spc) > SHOW processlist; 
+----+----------+-----------+------+---------+------+---------------------------------+-------------------------------------+ 
| Id | USER     | Host      | db   | Command | TIME | State                           | Info                                | 
+----+----------+-----------+------+---------+------+---------------------------------+-------------------------------------+ 
|  1 | msandbox | localhost | spc  | Query   |  129 | USER sleep                      | SELECT sleep(100) FROM t            | 
|  2 | msandbox | localhost | spc  | Query   |  102 | Waiting FOR TABLE metadata LOCK | ALTER TABLE t DROP INDEX play_count | 
|  3 | msandbox | localhost | spc  | Query   |    0 | init                            | SHOW processlist                    | 
+----+----------+-----------+------+---------+------+---------------------------------+-------------------------------------+ 


这个sleep的时间。。。已经超过100秒了… 


结论: 
在准备alter table tbl 的时候,先观察一下,有没有正在运行的,且在短时间内无法结束的sql语句在操作tbl表

Supongo que te gusta

Origin blog.csdn.net/huochuangchuang/article/details/49423893
Recomendado
Clasificación