mysql 5.6在没有表锁定的情况下将varchar长度调整为更长的值

时间:2015-05-13 16:57:27

标签: mysql mysql-5.6

我们现在有一个varchar列,长度为255个字符。我们将使用此声明将其提升至400:

ALTER TABLE `resources` CHANGE `url` `url` varchar(400) NOT NULL;

我已阅读有关online ddl哪些州

的文档
Operation                   In-Place?   Copies Table?   Allows Concurrent DML?  Allows Concurrent Query?
---------------------------|-----------|---------------|-----------------------|---------------------------------
Change data type of column  No          Yes             No                      Yes

我有这两个问题:

  • 将col从varchar(255)更改为varchar(400)是否构成数据类型的更改?
  • 这会锁定表以进行写入吗?

我想在第二个问题上,似乎不清楚DML的并发意味着什么。这是否意味着我根本无法写入此表,或者该表是否经历了复制/交换过程?

我们在此表中只有大约250万行,因此迁移只需要大约30秒,但我希望在此期间不会锁定表格。

2 个答案:

答案 0 :(得分:6)

我有同样的问题,并根据Percona的建议进行了一些测试。以下是我的发现:

ALTER TABLE `resources` CHANGE `url` `url` varchar(400), ALGORITHM=INPLACE, LOCK=NONE;

在5.6上运行它应该产生类似于:

的东西
[SQL]ALTER TABLE `resources` CHANGE `url` `url` varchar(400), ALGORITHM=INPLACE, LOCK=NONE;
[Err] 1846 - ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.

这意味着您无法执行此操作,因为MySQL将此视为列类型更改,因此必须执行完整的表复制。

因此,让我们尝试使用输出中建议的COPY算法,但设置LOCK = NONE:

ALTER TABLE `resources` CHANGE `url` `url` varchar(400), ALGORITHM=COPY, LOCK=NONE;

我们得到:

[SQL]ALTER `resources` CHANGE `url` `url` varchar(400), ALGORITHM=COPY, LOCK=NONE;
[Err] 1846 - LOCK=NONE is not supported. Reason: COPY algorithm requires a lock. Try LOCK=SHARED.

尝试设置LOCK=SHARED并尝试在表上插入会导致查询等待元数据锁定。

答案 1 :(得分:0)

我99%确定无论引擎类型如何对任何表进行更改都会导致表被锁定,直到操作完成,即使InnoDB的行级别为'锁定功能。

如果你可以忍受30-45秒的中断,某些连接可能会最终丢失,那么最简单的选择就是拉动扳机。或者您可以实施以下内容:

将您的网站置于'维护模式'在操作前几分钟,执行操作,然后使网站退出维护模式。

或者,如果您使用浮动ip和dns进行主主复制设置,则可以停止执行此操作:

  1. 在备用主服务器上停止复制
  2. 运行alter
  3. 将浮动ip切换到备用主服务器
  4. 停止在主控主机上复制
  5. 运行alter
  6. 在两个主服务器上重新启动复制
  7. 将浮动IP切换回主要主人