Qt开发环境Qt开发环境01-20 12:29

truncate被Waiting for table metadata lock的解决方法

场景

调研环境下,对一张千万条数据的表做了一个truncate操作,发现长时间无反应。

解决思路

操作一直执行,决定查询下正在执行的sql的状态

shop processlist;

发现truncate操作的状态是:Waiting for table metadata lock。

查询正在执行的事务:

select * from information_schema.innodb_trx\G

找到了操作表的那个事务,有insert语句没有提交,查看事务的trx_mysql_thread_id,然后执行kill [id]删除。

卡住的sql就都执行成功了。

思考

MDL是为了保护database objects而设计的。

MDL和事务的关系是,在事务中,当访问一个database object时都先要获得其MDL,在事务结束后才会释放MDL。

这样做有几个目的:

第一是为了进一步保证事务的一致性,比如事务A对某一行记录进行了更新,还没有提交,但这时另外一个会话2要修改表名,如果事务 A 持有MDL,那另一个会话2将无法修改,show processlist会发现它在Waiting for table metadata lock。直到事务 A 提交或回滚后,才能获得MDL修改成功。

第二是为了解决 binlog 同步的一个 bug,这个和上面的原因一样。binlog 的操作是基于事务的提交顺序的。事务 A 还未提交,另一个会话删除了相关表,这样 binlog 先记录的是删除表的操作,从库执行的顺序就不对了。

程序之家二维码

小额赞赏

000
评论