ALTER TABLE ... ADD COLUMN
我对DDL 语句有疑问。
在带有 MariaDB v10.2 的 Amazon RDS 实例上,我注意到INSERT
语句已完成,并且行已正确插入表中(通过 验证SELECT
),然后ALTER TABLE ... ADD COLUMN
表中的 a 完成。
执行写入的任何 DML 语句不应该在ALTER TABLE
操作完成之前排队吗?
我发布这个问题是因为有人要求我执行一些测试,以验证是否可以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 之前不可用。)
是的,它锁定了桌子。从 MySQL 8 的文档中,
从您链接的文档中,它非常明确
正如您所说,您使用的是 10.2。所以看起来添加一列需要重建整个表。
至于当你无法收到锁时会发生什么,
是的,这通常是在锁定期间发生的情况,但请注意,这并不总是会发生。有时报表和交易会放弃等待。有时,后端和池在等待时会收获。在停机期间执行此操作、超时以及在超时到期时从库中捕获错误总是更安全。只要您使用事务,如果触发了某些事情并且在超时之前无法获得它的锁定,事情就会回滚——一切都将是洁净的。
它实际上取决于特定的 alter table,但无论如何我建议查看在线模式更改工具,如 ghost(来自 GitHub)或 pt-online-schema-change(通过 percona)。
两种工具都在单独的表上进行更改并在最后切换到原始表 - 您甚至可以保留旧表以快速回滚。
这是一条更安全的路线,尤其是对于重载的桌子