在修改/增加表字段的时候,发现很慢,

show processlist; 时, Waiting for table metadata lock 能一直锁很久。

官网的一段话,可以理解下

http://dev.mysql.com/doc/refman/5.5/en/metadata-locking.html

8.10.4. Metadata Locking
MySQL 5.5.3 and up uses metadata locking to manage access to objects (tables, triggers, and so forth). Metadata locking is used to ensure data consistency but does involve some overhead, which increases as query volume increases. Metadata contention increases the more that multiple queries attempt to access the same objects.

Metadata locking is not a replacement for the table definition case, and its mutxes and locks differ from the LOCK_open mutex. The following discussion provides some information about how metadata locking works.

To ensure transaction serializability, the server must not permit one session to perform a data definition language (DDL) statement on a table that is used in an uncompleted transaction in another session. The server achieves this by acquiring metadata locks on tables used within a transaction and deferring release of those locks until the transaction ends. A metadata lock on a table prevents changes to the table's structure. This locking approach has the implication that a table that is being used by a transaction within one session cannot be used in DDL statements by other sessions until the transaction ends.

This principle applies not only to transactional tables, but also to nontransactional tables. Suppose that a session begins a transaction that uses transactional table t and nontransactional table nt as follows:

START TRANSACTION;
SELECT * FROM t;
SELECT * FROM nt;
Metadata locks are held on both t and nt until the transaction ends. If another session attempts a DDL operation on either table, it blocks until metadata lock release at transaction end. For example, a second session blocks if it attempts any of these operations:

DROP TABLE t;
ALTER TABLE t ...;
DROP TABLE nt;
ALTER TABLE nt ...;
If the server acquires metadata locks for a statement that is syntactically valid but fails during execution, it does not release the locks early. Lock release is still deferred to the end of the transaction because the failed statement is written to the binary log and the locks protect log consistency.

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


MySQL版本为5.6.12。

在进行alter table操作时,有时会出现Waiting for table metadata lock的等待场景。而且,一旦alter table TableA的操作停滞在Waiting for table metadata lock的状态,后续对TableA的任何操作(包括读)都无法进行,也会在Opening tables的阶段进入Waiting for table metadata lock的队列。如果是产品环境的核心表出现了这样的锁等待队列,就会造成灾难性的后果。

造成alter table产生Waiting for table metadata lock的原因其实很简单,一般是以下几个简单的场景:

场景一:

通过show processlist可以看到TableA上有正在进行的操作(包括读),此时alter table语句无法获取到metadata 独占锁,会进行等待。
这是最基本的一种情形,这个和mysql 5.6中的online ddl并不冲突。一般alter table的操作过程中(见下图),在after create步骤会获取metadata 独占锁,当进行到altering table的过程时(通常是最花时间的步骤),对该表的读写都可以正常进行,这就是online ddl的表现,并不会像之前在整个alter table过程中阻塞写入。(当然,也并不是所有类型的alter操作都能online的,具体可以参见官方手册:http://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-overview.html)

场景二:

通过show processlist看不到TableA上有任何操作,但实际上存在有未提交的事务,可以在information_schema.innodb_trx中查看到。在事务没有完成之前,TableA上的锁不会释放,alter table同样获取不到metadata的独占锁。

场景三:

通过show processlist看不到TableA上有任何操作,在information_schema.innodb_trx中也没有任何进行中的事务。这很可能是因为在一个显式的事务中,对TableA进行了一个失败的操作(比如查询了一个不存在的字段),这时事务没有开始,但是失败语句获取到的锁依然有效。从performance_schema.events_statements_current表中可以查到失败的语句。

官方手册上对此的说明如下:

If the server acquires metadata locks for a statement that is syntactically valid but fails during execution, it does not release the locks early. Lock release is still deferred to the end of the transaction because the failed statement is written to the binary log and the locks protect log consistency.
也就是说除了语法错误,其他错误语句获取到的锁在这个事务提交或回滚之前,仍然不会释放掉。because the failed statement is written to the binary log and the locks protect log consistency 但是解释这一行为的原因很难理解,因为错误的语句根本不会被记录到二进制日志。

总之,alter table的语句是很危险的,在操作之前最好确认对要操作的表没有任何进行中的操作、没有未提交事务、也没有显式事务中的报错语句。如果有alter table的维护任务,在无人监管的时候运行,最好通过lock_wait_timeout设置好超时时间,避免长时间的metedata锁等待。

参考:

http://ctripmysqldba.iteye.com/blog/1938150

http://blog.csdn.net/cloudcraft/article/details/9343069

转载于:https://www.cnblogs.com/52php/p/5675886.html

alter table锁表,MySQL出现Waiting for table metadata lock的场景浅析及解决方案相关推荐

  1. mysql alter table 锁表_alter table锁表,MySQL出现Waiting for table metadata lock的场景浅析及解决方案...

    在修改/增加表字段的时候,发现很慢, show processlist; 时, Waiting for table metadata lock 能一直锁很久. 官网的一段话,可以理解下 8.10.4. ...

  2. 【MySQL】MySQL出现Waiting for table metadata lock的原因、解决方法

    Waiting for table metadata lock MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景 ...

  3. 架构师技能6:深入MySQL原理-Waiting for table metadata lock引发系统崩溃

    开篇语录:以架构师的能力标准去分析每个问题,过后由表及里分析问题的本质,复盘总结经验,并把总结内容记录下来.当你解决各种各样的问题,也就积累了丰富的解决问题的经验,解决问题的能力也将自然得到极大的提升 ...

  4. 记一次MySQL中Waiting for table metadata lock的解决方法

    记一次MySQL中Waiting for table metadata lock的解决方法 参考文章: (1)记一次MySQL中Waiting for table metadata lock的解决方法 ...

  5. MySQL出现Waiting for table metadata lock的原因以及解决方法

    MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景.而且,一旦alter table TableA的操作停滞在Wa ...

  6. 【转】【MySql】Waiting for table metadata lock原因分析

    MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景.而且,一旦alter table TableA的操作停滞在Wa ...

  7. 阿里云mysql不让锁表_MySQL中InnoDB锁不住表的原因

    MySQL中InnoDB锁不住表是因为如下两个参数的设置: mysql> show variables like '%timeout%'; +-------------------------- ...

  8. mysql MDL锁如何解决_MYSQL METADATA LOCK(MDL LOCK)MDL锁问题分析

    一.前言 MYSQL中MDL锁一直是一个比较让人比较头疼的问题,我们谈起锁一般更加倾向于INNODB下层的gap lock.next key lock.row lock等,因为它很好理解,也很好观察, ...

  9. MySQL笔记-MDL锁(metadata lock)

    MySQL5.5版本引入了MDL锁(metadata lock),用于解决或保证DDL操作与DML操作之间的一致性.在mysqldump的时候不能做DDL操作,会提示waiting for table ...

最新文章

  1. ASP.NET控件Repeater遍历
  2. js---html元素操作
  3. mock模拟的数据能增删改查吗_如何在Vue中使用Mockjs模拟数据的增删查改
  4. Docker+Jenkins+Gitlab+Django应用部署实践
  5. P3975-[TJOI2015]弦论【SAM】
  6. java 递归 时间复杂度_递归到底是怎么实现的?它的时间复杂度怎么算?
  7. 【Flink】RuntimeException: Row arity of from does not match serializers
  8. python自动化之djangoform表单验证
  9. 做数据中心,腾讯是认真的!
  10. [校内模拟] 201027 NOIP Practice T2 Clockwork 众人皆WA我独A(划去)
  11. 那些崩溃率低于万分之一的独角兽APP都作对了什么?
  12. 利用Kmeans聚类进行用户分层分析
  13. python+selenium设置chrome代理的方式
  14. Ubuntu完全卸载与安装Mysql
  15. 那些忍了很久的话——人工智能盲目跟风该休了
  16. VMware12安装图解
  17. UIPATH Orchestrator配置
  18. win10 安装 CH340驱动
  19. 如何使用Shiro实现不同用户登录成功后跳转到不同主页?
  20. 风景园林计算机辅助设计教案,风景园林计算机辅助设计.doc

热门文章

  1. php无极分类非递归_PHP中的无限级分类、无限嵌套评论
  2. wgan 不理解 损失函数_GAN:「太难的部分我就不生成了,在下告退」
  3. python编程入门教程第6讲_Python开发的入门教程(六)-函数
  4. xml中加html源码,从xml获取数据以插入html标签,但在源代码中未看到
  5. 罗盘时钟制作代码_抖音八卦时钟手机屏保设置方法!
  6. 服务链路追踪配置mysql_学习微服务的服务链路追踪——Spring Cloud Sleuth+zipkin
  7. JAVA反射机制、Class类及动态加载、成员变量构造方法其他方法的反射与调用、代理模式AOP
  8. 你能想到几种方式实现数组扁平化(越多越好)
  9. 最优判定树C/C++实现(二叉链表实现)
  10. C#基础2:简单乘法表