Bas*_*ass 6 java mysql innodb jdbc
在我的应用程序的一个用例中,我有两个并发的MySQL连接:
T(实际上,不断更新此表中的一行),和ALTER TABLE,添加8个新列和从延伸的一个列varchar(80)向varchar(2000)).预计DDL最终会完成.在列UPDATEDML都不会受到DDL.
该表只包含一行(一行是UPDATE'd).
分析
当运行涵盖此用例的集成测试时,我观察到的是测试超时(表正在如此主动地写入,以便DDL永远不会完成),但仅适用于MySQL 5.7.通常情况下,测试预计会在30秒内在我们的硬件上完成(对于MySQL 5.6和8.0 确实会发生),但对于MySQL 5.7甚至200秒是不够的.我已经尝试了不同的ALGORITHM和LOCK值(见13.1.8 ALTER TABLE语法),没有运气.
当我描述我的应用程序(MySQL 5.7案例)时,我发现99%的CPU时间用于从套接字读取(即等待MySQL响应表已被更改),但数据库实例是一种黑色盒子给我 - 当然我已经performance_schema启用并可以对它运行查询,但我不知道我正在寻找哪些确切的信息.
合成
与此同时,我没有将问题简化为最小的自包含单元测试 - 我发现,与其他MySQL版本相比,MySQL 5.7 测试所用时间增加了3倍到10倍,但DDL没有永远挂起:
所有MySQL版本都是Windows版的库存版或从www.mysql.com下载的Debian Linux版本,只有极少的更改或官方Docker镜像.my.cnf
问题:
ALTER TABLE永久延迟DDL 的执行?或者我正在观察的只是一个非常繁忙的数据库实例?是否有可能
ALTER TABLE可中断的方式执行,即如果超过某个超时,则数据库返回错误,或者SHARED锁定表或其某些行暂停,以便在执行DDL时它们不会干预?TL; DR - 提交您的事务以取消阻止您的ALTER TABLE.
是的,ALTER TABLE可以阻塞很长时间.它似乎永远.它实际上是lock_wait_timeout的值,默认为31536000秒,或365天.
在MySQL中,像ALTER TABLE这样的DDL语句需要对表进行独占元数据锁定.目的是确保您不会同时从两个并发会话中使用ALTER TABLE.
像SELECT,INSERT,UPDATE,DELETE这样的DML语句也包含"共享"元数据锁.共享锁可以由多个会话同时保留,但阻塞独占锁,因为排它锁要求它们是唯一一个在表上保存任何类型锁的锁.
文件说明:
这种锁定方法的含义是,在事务结束之前,其他会话不能在DDL语句中使用一个会话中的事务正在使用的表.
持有元数据锁的DML语句的目的是使它们可以保留它们对表的可重复读取视图,而不必担心另一个会话正在执行DROP TABLE或ALTER TABLE来破坏它们对表的视图.这种锁定是必要的,因为MySQL没有版本化的元数据(他们正在逐步努力).
这意味着运行简单SELECT并且不提交的事务将阻止需要锁定更改的DROP TABLE或ALTER TABLE.
在线DDL的引入有一些细微差别.
在线DDL性能和并发性更详细地描述了ALTER TABLE通过获取共享元数据锁开始,因此未提交的事务不会阻止它.但是,如果ALTER TABLE更改的性质需要,则下一阶段可以将共享元数据锁升级为独占元数据锁.此时,锁定获取被阻止,因为另一个事务仍然拥有自己的元数据锁定.
在线DDL不适用于每种类型的ALTER TABLE操作; 有些人还需要独家锁.例如,正如您所做的那样更改数据类型需要独占锁定.有关详细信息,请参阅在线DDL概述