【问题标题】:Single connection on mysql "Waiting for table metadata lock" to DROP INDEXmysql“等待表元数据锁定”上的单个连接到 DROP INDEX
【发布时间】:2018-08-10 15:56:46
【问题描述】:

我的 MySQL 服务器出现意外状态。我有一个单独的连接执行一个查询,它在“等待表元数据锁定”中停留了很长时间(超过 1643 秒)。该查询是我系统中一个非常繁忙的表上的 DROP INDEX。

其实这个命令我已经试过很多次了。首先,数据库很忙,并且还有其他连接执行多个操作(都读取和写入)。我认为可能是这个原因,所以我依次尝试了:

  1. 杀死在同一个表和同一个“等待表元数据锁”上运行 Query 的任何进程
  2. 使用 Sleep 命令杀死甚至进程
  3. 从远程主机中删除所有进程和所有授权(在此之后只有 root 可以连接并且没有其他用户连接,它自己的应用程序与数据库断开连接)
  4. 取消并重新运行命令(加强这将是唯一的活动命令)

即使在那种状态下,问题也持续了几分钟。唯一活着的进程查询是:

     ID: 2398884
   USER: root
   HOST: localhost
     DB: zoom
COMMAND: Query
   TIME: 1643
  STATE: Waiting for table metadata lock
   INFO: DROP INDEX index_x ON tb.schema

之后我们决定重启mysqld。当服务器回来时,问题就消失了。我能够运行 drop index 命令。

我还没有发现任何有类似情况的人。在某些情况下这是正常的吗?我试图找到which transaction is causing a “Waiting for table metadata lock”.,但无法识别任何人。

注意:除了删除索引和我自己的根连接来检查进度和状态之外,还有 Binlog Dump 复制查询正在运行

【问题讨论】:

    标签: mysql


    【解决方案1】:

    不,这不正常,我敢肯定你只是没有杀死正确的线程。不需要重新启动 MySQL。如果是这样,我和我工作的公司将是第一个放弃它的人。

    当一个事务接触到一个表而另一个事务(您的 drop index 语句)想要一个锁,但第一个事务尚未提交时,就会发生元数据锁。听起来太普通了,但玩一遍:

    session1 > start transaction;
    session1 > select * from foo;
    

    这就是我所说的“触摸”。一个简单的选择就足够了,它可以发生在事务的任何地方。没关系,如果在此之后不再运行语句或运行另一个语句(只要它不是commit;rollback;),此事务将阻止其他事务获取元数据的锁定。

    session2 > alter table foo add column bar int;
    

    现在 session2 正在等待元数据锁定。

    关于你的尝试:

    1. 你必须杀死的东西不能必须是一个当前在同一张表上运行语句的事务。杀死其他也在等待元数据锁的语句没有帮助,它们也只是受害者。但也无妨。
    2. 不错的主意。
    3. 不确定你的意思。但取消赠款肯定无济于事。新的授权或删除的授权不适用于仍在运行的事务。必须重新打开会话才能使更改的授权生效。
    4. 这根本没有帮助。

    话虽如此,我肯定不明白为什么您的链接问题中接受的答案有超过 100 个赞成票。这些查询确实根本没有显示锁。不过,第二个答案是对的。首先杀死运行时间最长的事务。
    但请注意,您必须在TRANSACTIONS 部分的SHOW ENGINE INNODB STATUS\G 的输出中检查ACTIVE x seconds 部分。不要在进程列表中使用time 值。这仅表示自该线程上次状态更改以来的时间。

    • 阅读有关元数据锁的更多信息here

    哦,如果您使用的是 MySQL 5.7 或更高版本,请务必阅读 this

    【讨论】:

    • 总是有可能我犯了一些错误并且没有杀死罪魁祸首线程。我已经和我的同事仔细检查过。剩下的唯一连接是我们自己的和 Binlog Dump 复制查询。 (我已经编辑了问题并在上面添加了这些注释)。
    • 您检查过show engine innodb status\G 的输出或进程列表吗? Processlist 不一定列出所有事务。
    • 我已经检查了 show engine innodb status\G 。但我主要使用的是完整的进程列表。那就是我把ID删除的地方。
    猜你喜欢
    • 1970-01-01
    • 2014-05-13
    • 2022-08-16
    • 2013-06-13
    • 1970-01-01
    • 1970-01-01
    • 2017-10-29
    • 2016-10-23
    • 2021-10-06
    相关资源
    最近更新 更多