mysql“等待表元数据锁定”与DROP INDEX的单一连接

时间:2018-08-10 05:04:12

标签: mysql

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

实际上,我已经尝试了很多次了。首先,数据库很忙,还有其他连接执行多项操作(都读和写)。我认为这可能是原因,所以我按顺序进行了尝试:

  1. 杀死在同一表和同一“等待表元数据锁定”上运行Query的任何进程
  2. 使用“睡眠”命令杀死进程
  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”.,但找不到任何人。

注意:除了drop index和我自己的root用户连接(用于检查进度和状态)之外,还有Binlog Dump复制查询正在运行

1 个答案:

答案 0 :(得分:1)

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

元数据锁定发生,当一个事务接触一个表而另一个事务(您的放置索引语句)希望拥有一个锁定,但第一个事务尚未提交时。听起来太普通了,但可以通过以下方式播放:

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

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

session2 > alter table foo add column bar int;

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

关于您尝试过的事情:

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

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

  • 详细了解元数据锁here

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