MySQL在线DDL添加列

4

我目前正在尝试给一个大约有2500万行的表格添加一列。我需要实现几乎零停机时间,因此希望使用在线DDL。它运行了一段时间,但最终遇到了以下问题:

"Duplicate entry '1234' for key 'PRIMARY'" 
[SQL: u'ALTER TABLE my_table ADD COLUMN my_coumn BOOL NOT NULL DEFAULT false']

我认为出现这种情况是因为在操作期间针对该表运行了INSERT ... ON DUPLICATE KEY UPDATE ...操作。这似乎是一个已知的限制
在此无法正常工作后,我尝试使用Percona pt-online-schema-change工具,但不幸的是,由于我的表具有生成列,因此也无法使用并出现错误:
The value specified for generated column 'my_generated_column' in table '_my_table_new' is not allowed.

所以,我现在有些困惑。如何在不阻塞DML操作的情况下添加一列?

1个回答

3
你的 ALTER 语句创建了一个默认值为 False 的非空列。我猜测这会在你的表上放置一个排他锁,尝试创建该列,然后在每行中将其设置为 False。
如果你没有任何可用的停机时间,我建议你:
  1. Add the column as nullable and with no default

    ALTER TABLE my_table ADD COLUMN my_coumn BOOL NULL;
    
  2. Update the values for existing rows to false

    update my_table set my_coumn=false;
    
  3. Alter the table a second time to be not nullable and with a default.

    ALTER TABLE my_table modify my_coumn BOOL NOT NULL DEFAULT false;
    

或者,您可以使用类似Percona的工具,该工具使用触发器来管理模式更改,并旨在提供更新模式而无需锁定表的功能。

无论哪种选择,我建议您在开发环境中进行测试,其中一些进程会写入表以模拟用户活动。


我会点踩是因为我认为你没有仔细阅读问题。错误是关于重复条目的,与任何可空性无关。问题还明确表示我尝试使用pt-online-schema-change(Percona),这也是你建议我使用的。 - Eli
2
你的具体问题是,“在不阻塞DML操作的情况下,我有哪些其他选项可以添加列?”提供的要求是“我需要几乎零停机时间,所以希望使用在线DDL。” 这就是我试图回答的,没有任何详细的DDL。我向您提供的是一种我过去用过的方法,用于限制对活动表的列添加的影响。如果您想要我的进一步反馈,请发送具体的DDL和表定义。我还想提到,Percona工具专门用于解决这个问题。请分享您如何使用它以及遇到了什么错误。 - Dom DaFonte
你还没有仔细阅读问题。你提出的每个观点都与问题无关,或者已经在问题中得到了回答。我并不是想冒犯你。我只是真的不知道该怎么告诉你了。 - Eli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接