MySQL 5.6 - 即使使用ALGORITHM = inplace时表锁也是如此

jef*_*eon 9 mysql table-locking

ALTER在一个有6000万行的大表上的MySQL 5.6数据库上运行以下命令:

ALTER TABLE `large_table` ADD COLUMN `note` longtext NULL, 
ALGORITHM=INPLACE, LOCK=NONE;
Run Code Online (Sandbox Code Playgroud)

尽管同时指定ALGORITHM=INPLACELOCK=NONE,表被锁定,并且基本上是删除了应用,直到迁移完成.

我通过检查命令In_use输出中列的值来验证表确实已锁定SHOW OPEN TABLES.它被设定为1.

根据我在MySQL文档中收集的内容,此操作不应该锁定表.并且,如果没有锁定,MySQL无法继续执行命令.我将数据库升级到MySQL 5.7以查看它是否更好,但我在5.7上也遇到了同样的问题.

这是预期的行为吗?我怎么知道这里出了什么问题?

Ric*_*mes 6

我假设您没有同时在该表上执行其他一些 DDL?

为将来:

8.0.12 已ALTER TABLE .. ALGORITHM=INSTANT用于ADD COLUMN. 请参阅讨论ALTER 参考以及在线 DDL 参考

使用 INSTANT 算法添加列时,以下限制适用:

  • 添加列不能与不支持 ALGORITHM=INSTANT 的其他 ALTER TABLE 操作组合在同一语句中。
  • 一列只能添加为表格的最后一列。不支持将一列添加到其他列中的任何其他位置。
  • 不能向使用 ROW_FORMAT=COMPRESSED 的表添加列。
  • 不能将列添加到包含 FULLTEXT 索引的表中。
  • 不能将列添加到临时表。临时表仅支持 ALGORITHM=COPY。
  • 不能将列添加到驻留在数据字典表空间中的表。
  • 添加列时不评估行大小限制。但是,在表中插入和更新行的 DML 操作期间会检查行大小限制。

可以在同一个 ALTER TABLE 语句中添加多个列。

如果您无法升级,请考虑 Perconapt-online-schema-change或新的竞争产品gh-ost(使用 binlog)。


Chr*_*ris 6

即使在ALGORITHM=INPLACE, LOCK=NONE;使用MySQL 5.6 锁定时,我也遇到过问题。我会首先检查以下内容:


检查表上的约束

如果表上存在 ON...CASCADE 或 ON...SET NULL 约束,则不允许使用 ALTER TABLE 子句 LOCK=NONE。

来源:https : //dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-limitations.html


表有外键关系吗?

在外键关系中的表上的在线 DDL 操作不会等待在外键关系中的另一个表上执行的事务提交或回滚。事务在它正在更新的表上持有独占元数据锁,并在外键相关表上共享元数据锁(外键检查需要)。当需要独占元数据锁来更新表定义时,共享元数据锁允许在线 DDL 操作继续进行,但会在其最后阶段阻止操作。这种情况可能会导致死锁,因为其他事务等待在线 DDL 操作完成。

来源:https : //dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-limitations.html

并在此处阅读元数据锁定:https : //dev.mysql.com/doc/refman/5.6/en/metadata-locking.html


首先从旧时间格式更改表

如果您在 MySQL 5.6 之前创建了带有 DATETIME 或 TIMESTAMP 字段的表,则需要将它们升级到 MySQL 5.6 的新格式。

在 MySQL 5.6 之前创建的 InnoDB 表不支持 ALTER TABLE ... ALGORITHM=INPLACE 对于包含临时列(DATE、DATETIME 或 TIMESTAMP)并且尚未使用 ALTER TABLE ... ALGORITHM=COPY 重建的表。在这种情况下,ALTER TABLE ... ALGORITHM=INPLACE 操作返回以下错误:

错误 1846 (0A000):不支持 ALGORITHM=INPLACE。原因:无法更改列类型 INPLACE。尝试算法=复制。

来源:https : //dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-limitations.html


检查表是否有分区

分区会更改更改表规则的应用方式。检查表的分区状态

show table status;

寻找不等于 InnoDB 的“引擎”

来源:https : //dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-operations.html#online-ddl-partitioning


最后,正如 Rick James 在他的回答中提到的,从 5.6 升级到 8.0 可能是一种选择,因为它提供了其他改进。