我的 MySQL 服务器出现意外状态。我有一个连接正在执行查询,并且它长时间处于“等待表元数据锁定”状态(超过 1643 秒)。该查询是我系统中一个非常繁忙的表上的 DROP INDEX。
其实这个命令我已经尝试过很多次了。首先,数据库很忙,并且有其他连接执行多个操作(都在读取和写入)。我认为这可能是原因,所以我按顺序尝试了:
- 终止在同一个表和同一个“等待表元数据锁”上运行查询的任何进程
- 使用 Sleep 命令杀死进程
- 删除远程主机的每个进程和任何授权(此后只有 root 可以连接并且没有其他用户连接,应用程序本身与数据库断开连接)
- 取消并重新运行命令(强化这将是唯一的事件命令)
即使在这种状态下,问题仍然持续了几分钟。唯一事件的进程查询是:
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。如果是的话,我和我工作的公司将是第一个放弃它的人。
当一个事务接触表而另一个事务(您的删除索引语句)想要锁定,但第一个事务尚未提交时,就会发生元数据锁定。听起来太常见了,但是玩一下:
session1 > start transaction;
session1 > select * from foo;
这就是我所说的“触摸”。一个简单的选择就足够了,它可以发生在事务中的任何地方。没关系,如果您在此之后不再运行任何语句,或者如果您运行另一个语句(只要它不是 commit;
或 rollback;
),此事务防止其他事务获取元数据的锁。
session2 > alter table foo add column bar int;
现在session2正在等待元数据锁。
关于您的尝试:
- 您必须终止的事务不一定是当前正在同一个表上运行语句的事务。杀死其他也在等待元数据锁的语句没有帮助,它们也只是受害者。但这也没有什么坏处。
- 这主意不错。
- 不确定您的意思。但取消补助金肯定没有帮助。新的授权或删除的授权不适用于仍在运行的交易。必须重新打开 session 才能使更改的授权生效。
- 这根本没有帮助。
话虽这么说,我当然不明白为什么您链接的问题中接受的答案有超过 100 个赞成票。这些查询确实根本不显示锁。不过,第二个答案是正确的。首先终止运行时间最长的事务。
但请注意,您必须检查 TRANSACTIONS
部分中 SHOW ENGINE INNODB STATUS\G
输出中的 ACTIVE x 秒
部分。不要在进程列表中使用time
值。这仅指示自该线程上次状态更改以来的时间。
- 了解有关元数据锁的更多信息 here
哦,还要确保阅读 this 如果您使用的是 MySQL 5.7 或更高版本。
关于mysql - mysql "Waiting for table metadata lock"上的单个连接到 DROP INDEX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51779289/