mysql无法更改正在被主动写入的表

uqzxnwby  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(260)

在我的应用程序的一个用例中,我有两个并发mysql连接:
一个正在向一个名为 T (实际上,不断更新表中的一行),以及
另一个对同一个表执行ddl( ALTER TABLE ,添加8个新列并从 varchar(80)varchar(2000) ). ddl最终有望完成。
中的列 UPDATE dml不受ddl的影响。
该表只包含一行(当前为 UPDATE “d”)。
分析
当一个包含这个用例的集成测试运行时,我观察到的是一个测试超时(表被如此积极地写入,以至于ddl永远不会完成),但只适用于mysql 5.7。通常情况下,在我们的硬件上测试预计在30秒内完成(MySQL5.6和8.0确实如此),但对于MySQL5.7来说,200秒是不够的。我尝试过不同的方法 ALGORITHM 以及 LOCK 值(见13.1.8 alter table syntax),没有运气。
当我分析我的应用程序(mysql 5.7案例)时,我发现99%的cpu时间都花在了从socket(i。e。等待mysql响应表已经被修改),但是数据库示例对我来说是一个黑盒子——当然我有 performance_schema 启用并可以对其运行查询,但我不知道我要查找的确切信息。
合成
同时,我未能将问题简化为一个最小的自包含单元测试——我观察到的唯一一点是mysql 5.7的测试运行时间比其他mysql版本增加了3到10倍,但ddl不会永远挂起:

所有mysql版本都是windows或debian linux的库存版本,下载自www.mysql.com 只需对 my.cnf ,或docker官方图片。
问题:
mysql在技术上确实有可能延迟 ALTER TABLE 永远的ddl?或者我观察到的只是一个非常繁忙的数据库示例?有没有可能
请求 ALTER TABLE 是可中断地执行的。e。如果超过某个超时时间,数据库将返回错误,或者
强制所有可能放置 SHARED 锁定表或其某些行以暂停,以便它们在执行ddl时不会干预?
在处理最初的集成测试超时时,如何从mysql方面进一步诊断这种情况?

s5a0g9ez

s5a0g9ez1#

热释光;dr-提交事务以取消阻止alter表。
是的,alter table可以阻塞很长时间。好像永远。它实际上是lock\u wait\u timeout的值,默认值为31536000秒,即365天。
在mysql中,像altertable这样的ddl语句需要表上的独占元数据锁。其目的是确保不会同时从两个并发会话中修改表。
select、insert、update、delete等dml语句也持有“共享”元数据锁。共享锁可以由多个会话同时持有,但会阻止独占锁,因为独占锁要求它们是唯一持有表上任何类型锁的会话。
文件说明:
这种锁定方法意味着,在事务结束之前,一个会话中的事务正在使用的表不能被其他会话在ddl语句中使用。
持有元数据锁的dml语句的目的是,它们可以保留表的可重复读取视图,而不必担心另一个会话正在执行drop table或alter table操作来破坏它们的表视图。这种锁定是必要的,因为mysql没有版本化的元数据(他们正逐渐朝这个方向努力)。
这意味着运行简单select但未提交的事务将阻止需要锁定更改的drop表或alter表。
在线ddl的引入有一些细微的差别。
联机ddl性能和并发性更详细地描述了alter表从获取共享元数据锁开始,因此未提交的事务不会阻止它。但下一阶段可能会将共享元数据锁升级为独占元数据锁,如果alter表更改的性质需要这样做的话。此时,锁获取被阻止,因为另一个事务仍然持有自己的元数据锁。
联机ddl并不适用于所有类型的alter table操作;有些仍然需要独占锁。例如,在更改数据类型时,需要一个独占锁。有关详细信息,请参阅联机ddl概述。

相关问题