我的MySQL服务器处于意外状态。我只有一个连接来执行查询,并且它在“ 等待表元数据锁定”中停留了很长时间(超过1643秒)。该查询是我系统中一个非常繁忙的表上的DROP INDEX。
实际上,我已经尝试了很多次了。首先,数据库很忙,还有其他连接执行多项操作(都读和写)。我认为这可能是原因,所以我按顺序进行了尝试:
即使在那种状态下,问题仍然存在几分钟。唯一有效的流程查询是:
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复制查询正在运行
答案 0 :(得分:1)
不,这是不正常的,我确定您只是没有杀死正确的线程。无需重启MySQL。如果是这样,我和我工作的公司将是第一个放弃它的人。
元数据锁定发生,当一个事务接触一个表而另一个事务(您的放置索引语句)希望拥有一个锁定,但第一个事务尚未提交时。听起来太普通了,但可以通过以下方式播放:
session1 > start transaction;
session1 > select * from foo;
这就是我所说的“触摸”的意思。一个简单的选择就足够了,它可以在事务中的任何地方发生。没关系,如果之后没有再运行任何语句,或者如果您运行了另一条语句(只要它不是commit;
或rollback;
),则此事务将阻止其他事务获取锁定元数据。
session2 > alter table foo add column bar int;
现在session2正在等待元数据锁定。
关于您尝试过的事情:
话虽如此,我肯定不明白为什么您的链接问题中接受的答案具有超过100个投票。这些查询确实根本不显示锁。不过,第二个答案是正确的。首先杀死运行时间最长的事务。
但是请注意,您必须在ACTIVE x seconds
部分中检查SHOW ENGINE INNODB STATUS\G
输出中的TRANSACTIONS
部分。不要在进程列表中使用time
值。这仅指示自该线程的上一次状态更改以来的时间。
哦,如果您使用的是MySQL 5.7或更高版本,请确保阅读 this 。