MySQL使用在线DDL添加列

时间:2017-04-30 20:07:17

标签: mysql alter-table

我目前正在尝试将一列添加到~25m行的表中。我需要有近0的停机时间,因此希望使用在线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 ...次操作。这似乎是known limitation

在此之后无效,我尝试使用Percona pt-online-schema-change工具,但不幸的是,因为我的表已经生成了列,但是这些列都没有用于错误:

The value specified for generated column 'my_generated_column' in table '_my_table_new' is not allowed.

所以,我现在不知所措。在不阻止DML操作的情况下添加列的其他选择是什么?

1 个答案:

答案 0 :(得分:1)

您的Alter语句正在创建一个不可为空的列,其默认值为false。我怀疑这会在你的表上放置一个独占锁,尝试创建列,然后在每行上将其设置为False。

如果您没有任何可用的停机时间,我建议您

  1. 将列添加为可为空且没有默认值

    public function updateStatus()
    {
    $output = null;
    $output = $this->ARequestModel->updateStatus($_POST);
    
    $this->output
        ->set_content_type('application/json')
        ->set_output(json_encode($output));
     exit();
    }
    
  2. 将现有行的值更新为false

    ALTER TABLE my_table ADD COLUMN my_coumn BOOL NULL;
    
  3. 第二次更改表不可为空并使用默认值。

    update my_table set my_coumn=false;
    
  4. 或者,您可以使用Percona之类的东西来管理使用触发器的架构更改,并且可以在不锁定表的情况下更新架构。

    任何一个选项我建议你在开发环境中测试一些进程写入表来模拟用户活动。