创建索引锁 MySQL 5.6 表。如何避免这种情况?

use*_*003 4 mysql

我需要在大型 InnoDB 生产表上创建索引,并且希望在不以任何方式锁定表的情况下执行此操作。我正在使用 MySQL 5.6 (.38-83.90)。

我试过

create index my_index on my_table(col1, col2); 
Run Code Online (Sandbox Code Playgroud)

两列都不是主键。col1 是外键。

好吧,这完全锁定了桌子。其他查询因“等待表元数据锁定”而陷入停滞,导致我的网站瘫痪。我不得不终止创建索引查询。

从这个https://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-overview.html我认为它不会锁定表:“...不需要语法更改.. .在创建或删除索引时,该表仍可用于读写操作。”

我看到我可以设置 LOCK=NONE 或 LOCK=SHARED,但我不认为它应该是必要的,或者如果有的话,我需要使用哪一个。

“您可以指定 LOCK=NONE 来断言在 DDL 操作期间允许并发 DML。MySQL在可能的情况下自动允许并发 DML。

“您可以指定 LOCK=SHARED 来断言在 DDL 操作期间允许并发查询。如果可能,MySQL 会自动允许并发查询。

所有限制https://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-limitations.html似乎都不适用于我的情况。

我缺少什么?

spe*_*593 5

我的猜测(只是猜测)是您错过了声明ALGORITHM=INPLACE中的条款CREATE INDEX

CREATE INDEX my_index ON my_table(col1, col2) ALGORITHM=INPLACE ;
                                              ^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

还要注意事务获取和持有元数据锁。

https://dev.mysql.com/doc/refman/5.6/en/metadata-locking.html

任何已引用的事务my_table将继续持有该表上的元数据锁,直到该事务被提交或回滚。我建议检查输出TRANSACTIONS部分SHOW ENGINE INNODB STATUS