MySQL 8.0.36如何添加允许空的唯一列且不锁定生产表?
MySQL 8.0.36大表添加允许为空的唯一列+唯一约束解决方案
针对你的场景,以下是MySQL 8专属的原生解决方案,无需关联新表的繁琐操作:
核心思路:利用在线DDL的共享锁+并行索引构建缩短锁表影响
方案1:创建唯一索引(与唯一约束功能等价)并启用并行构建
- 先调整InnoDB并行读取线程数,加快索引构建速度(根据服务器CPU核数调整,比如8核设为8):
SET GLOBAL innodb_parallel_read_threads = 8; - 执行创建唯一索引的操作,指定共享锁避免完全阻塞读写:
CREATE UNIQUE INDEX idx_mytable_new_col ON mytable(new_col) ALGORITHM=INPLACE LOCK=SHARED;- 此操作仅加共享锁:所有读操作正常执行,写操作会进入等待队列,但索引构建时间因并行特性(MySQL 8.0.23+支持)会比之前7分钟的普通索引更短,对生产影响可控。
方案2:直接添加唯一约束并指定共享锁
如果你更倾向于用约束语法,同样可以指定共享锁:
ALTER TABLE mytable ADD UNIQUE KEY idx_mytable_new_col(new_col), ALGORITHM=INPLACE LOCK=SHARED;
- 共享锁下读操作不受影响,仅写操作等待,相比默认的排他锁(完全阻塞读写),对业务的影响大幅降低。
关键注意事项
- MySQL的唯一约束允许多个
NULL值(因为NULL != NULL),所以即使你的新列全为NULL,添加约束时不会触发唯一性冲突,检查速度极快。 - 建议在业务低峰期执行操作,避免写请求排队累积。
内容的提问来源于stack exchange,提问作者user984003
相关产品推荐
相关产品推荐

