ALTER TABLE - ADD COLUMN 是否锁定表?

dr_*_*dr_ 8 mariadb alter-table amazon-rds

我有一个关于ALTER TABLE ... ADD COLUMNDDL 语句的问题。

在使用 MariaDB v10.2 的 Amazon RDS 实例上,我注意到INSERT语句完成并且行在表上完成SELECT之前正确插入表中(通过 验证)ALTER TABLE ... ADD COLUMN

ALTER TABLE操作完成之前,不应该将任何执行写入的 DML 语句排队吗?

我发布这个问题是因为我被要求执行一些测试来验证是否可以ALTER TABLE ... ADD COLUMN在工作时间内在实时生产数据库上运行,在频繁使用的数据库上,在有几百万行的表上运行——我觉得很不明智。即使ALTER TABLE没有在表上放置锁,它也必须等到任何连接不再使用该表(由于连接放置了元数据锁),这可能会在很久以后发生。
编辑:显然这个评估过于悲观。我一直在做几个测试,mysqlslap在表上执行繁重的操作 ( INSERT, UPDATE,DELETE语句和SELECT语句LIKE避免在ALTER TABLE ... ADD COLUMN运行时在 150 个模拟并发连接上使用索引;分析显示元数据锁定,但等待时间很短(每个 1 秒),表更改在大约 30 分钟内完成,而没有运行 SQL 语句时则需要 10 分钟。虽然这很令人满意,但另一方面,我想知道假设 DDL 语句是非阻塞的是否安全。

(可能值得注意的是InnoDB 上有一个InstantADD COLUMN功能,它允许立即向表中添加一列(在特定约束下),但在 v10.3.2 之前不可用。)

Eva*_*oll 4

是的,它锁定了表。从 MySQL 8 的文档来看,

前面提到的例外是ALTER TABLE在准备从表和表定义缓存中清除过时的表结构时阻止读取(而不仅仅是写入)。此时,它必须获取排他锁。为此,它会等待当前读取器完成,并阻止新的读取和写入。

您链接的文档来看,它非常明确

借助 instant ADD COLUMN,您可以享受结构化存储的所有优势,而无需重建表。

正如您所说,您使用的是 10.2。所以看起来添加一列需要重建整个表。

至于当你无法收到锁时会发生什么,

我注意到在表上的INSERT操作完成之前,语句已完成并且行已正确插入表中(通过 SELECT 进行验证) 。ALTER TABLE ... ADD COLUMN

是的,这通常是锁定期间发生的情况,但请注意,情况并非总是如此。有时报表和交易会放弃等待。有时,当后端和池陷入等待时,它们就会受到损失。在停机期间执行此操作、设置超时并在超时到期时捕获库中的错误总是更安全。只要您正在使用事务,如果某些事件被触发并且在超时之前无法获得锁定,事情就会回滚 - 一切都将是合理的。