MySQL生产环境百万行表:安全复制列最后4位至新列(无锁表)
生产环境MySQL百万行表安全复制列最后4位到新列的实现方案
你的原代码在生产环境存在明显风险,所以没通过审核:
- 直接执行
ALTER TABLE在MySQL 5.6及以前版本会锁表,哪怕是5.6+的Online DDL,不指定参数也可能产生锁; - 全表
UPDATE会触发长时间表锁,阻塞所有读写操作,完全不符合生产环境的可用性要求。
下面是安全的实现步骤:
1. 在线添加新列(无锁)
MySQL 5.6及以上支持Online DDL,显式指定参数确保添加列时不锁表、不阻塞业务:
ALTER TABLE tokens ADD COLUMN last4_token VARCHAR(4) NULL, ALGORITHM=INPLACE, LOCK=NONE;
ALGORITHM=INPLACE:避免拷贝全表,大幅提升操作速度;LOCK=NONE:允许添加列的同时,表仍能正常读写。
2. 分批更新数据(避免全表锁)
一次性更新百万行会长时间占用锁,改成分批小批量更新,每次只处理1000行(可根据数据库负载调整):
SET @row_count = 1; WHILE @row_count > 0 DO UPDATE tokens SET last4_token = SUBSTRING(full_token, -4) WHERE last4_token IS NULL LIMIT 1000; SET @row_count = ROW_COUNT(); SELECT SLEEP(0.1); -- 可选,根据负载调整间隔,避免数据库压力突增 END WHILE;
- 用
last4_token IS NULL过滤未更新的行,确保不会重复处理; LIMIT控制单次更新行数,锁的持有时间极短,不会影响业务;SLEEP可选,给数据库留出资源处理其他请求。
3. 可选:设置列非空(若业务需要)
等所有数据更新完成后,再把列改为非空,同样用Online DDL:
ALTER TABLE tokens MODIFY COLUMN last4_token VARCHAR(4) NOT NULL, ALGORITHM=INPLACE, LOCK=NONE;
额外注意事项
- 操作前必须在测试环境验证逻辑和性能;
- 避开业务高峰时段执行;
- 实时监控数据库CPU、连接数、锁状态,发现异常立即暂停;
- 主从架构下,确保DDL和分批更新在主库执行后同步正常。
内容的提问来源于stack exchange,提问作者Bill Software Engineer
相关产品推荐
相关产品推荐

