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

tim*_*bat 7 mysql mysql-5.6

我们现在有一个varchar列,长度为255个字符.我们将使用此声明将其增加到400:

ALTER TABLE `resources` CHANGE `url` `url` varchar(400) NOT NULL;
Run Code Online (Sandbox Code Playgroud)

我读过有关的文档在线DDL其中规定

Operation                   In-Place?   Copies Table?   Allows Concurrent DML?  Allows Concurrent Query?
---------------------------|-----------|---------------|-----------------------|---------------------------------
Change data type of column  No          Yes             No                      Yes
Run Code Online (Sandbox Code Playgroud)

我有这两个问题:

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

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

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

小智 6

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

ALTER TABLE `resources` CHANGE `url` `url` varchar(400), ALGORITHM=INPLACE, LOCK=NONE;
Run Code Online (Sandbox Code Playgroud)

在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.
Run Code Online (Sandbox Code Playgroud)

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

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

ALTER TABLE `resources` CHANGE `url` `url` varchar(400), ALGORITHM=COPY, LOCK=NONE;
Run Code Online (Sandbox Code Playgroud)

我们得到:

[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.
Run Code Online (Sandbox Code Playgroud)

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


Mik*_*ell 0

我 99% 确信,无论引擎类型如何,对任何表的更改都会导致表被锁定,直到操作完成,即使使用 InnoDB 的“行级”锁定功能也是如此。

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

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

或者,如果您有一个具有浮动 ip 和 dns 的主主复制设置,您可以停止执行此操作:

  1. 停止备用主服务器上的复制
  2. 运行更改
  3. 将浮动ip切换为standby master
  4. 停止主服务器上的复制
  5. 运行更改
  6. 在两个主服务器上重新启动复制
  7. 将浮动ip切换回primary master