Mysql RDS alter table enum 短暂中断了我的数据库连接

问题描述 投票:0回答:1

背景

我们使用的是 RDS mysql 8.0。

我们有一个高吞吐量的写/读表。昨天我们确实发布了

alter table
声明来修改
enum
值。我们在枚举列表中又添加了一个值
at the end of the list
。我们用
no lock
inplace
算法做到了。在过去,我们曾经这样做过,而且它曾经工作得非常好,在几毫秒内完成。但昨天花了一个多小时。完成该操作的表大小为 42 GB。当这个操作完成后,我可以看到我们得到了很多
Lock wait timeout exceeded; try restarting transaction'

现在这提示我在该操作的最后阶段发生了某种表锁定。我无法将手指放在上面。这里到底发生了什么。

调查

这个链接谈论

通过将新的枚举或集合成员添加到有效成员值列表的末尾来修改 ENUM 或 SET 列的定义,只要数据类型的存储大小不变。例如,向具有 8 个成员的 SET 列添加一个成员会将每个值所需的存储从 1 个字节更改为 2 个字节;这需要一个表副本。在列表中间添加成员会导致现有成员重新编号,这需要表副本。

这是当时 RDS 性能洞察针对此交易显示的结果

此期间来自 RDS 性能洞察的另一个等待片段

列排序规则是

utf8_unicode_ci
现在基于上面,我尝试了解 ENUM 值中的值的存储要求是什么。来到这张桌子了

现在上图中的最后一行是我们添加的行。所以我可以看到这里的存储需求确实发生了变化。因此,如果我没理解错的话,我们现在这个枚举至少需要 42 个字节。因此,根据 mysql 文档,复制表可能会触发,这可能会解释该行为。

问题 现在我的问题是,如果上述解释确实是正确的,那么添加一个更长的值(就字符串值中的字符数而言)然后最后一个值(基本上比当前集合中最长的值更长)必须重现这种行为。但如果我再添加一个字符,那么它就无法重现。我缺少什么?我该如何解释锁等待?

mysql enums alter
1个回答
0
投票

如果将 NOT NULL 列更改为 NULL,则修改列也会触发表复制,反之亦然。我在您的 alter 命令中看到,您将该列设置为可为空。在你改变它之前它不是NOT NULL吗?

确实该列之前不是 NULL,但在这次更改中将其设置为 NULL!

如果您需要在生产中进行 ALTER TABLE,这将在大型表上产生表副本,我建议使用开源在线架构更改工具之一。这意味着表复制在后台运行,您可以同时继续读写表。

当然,与任何新工具一样,首先在测试环境中(而不是在生产环境中)进行试验,直到您有信心使用它为止。

在我之前的工作中,我们每周使用 pt-online-schema-change 在生产环境中运行数百次架构更改,而不会阻塞任何应用程序。

© www.soinside.com 2019 - 2024. All rights reserved.