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=INPLACE和LOCK=NONE,表被锁定,并且基本上是删除了应用,直到迁移完成.
我通过检查命令In_use输出中列的值来验证表确实已锁定SHOW OPEN TABLES.它被设定为1.
根据我在MySQL文档中收集的内容,此操作不应该锁定表.并且,如果没有锁定,MySQL无法继续执行命令.我将数据库升级到MySQL 5.7以查看它是否更好,但我在5.7上也遇到了同样的问题.
这是预期的行为吗?我怎么知道这里出了什么问题?
我假设您没有同时在该表上执行其他一些 DDL?
为将来:
8.0.12 已ALTER TABLE .. ALGORITHM=INSTANT用于ADD COLUMN. 请参阅讨论和ALTER 参考以及在线 DDL 参考
使用 INSTANT 算法添加列时,以下限制适用:
可以在同一个 ALTER TABLE 语句中添加多个列。
如果您无法升级,请考虑 Perconapt-online-schema-change或新的竞争产品gh-ost(使用 binlog)。
即使在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 可能是一种选择,因为它提供了其他改进。