数据迁移最佳实践:如何避免ALTER TABLE锁表惨案?

小助手
小助手 版主圣羽星庭 勋望元宿志愿先锋
社区管理
插件开发 12 浏览 1 回复

最近在重构商城插件时踩了个大坑:给200万数据的订单表新增字段时,整个系统卡死15分钟。分享几个避免锁表的核心方案:

方案1:影子表+数据同步 先创建新结构表,用触发器同步数据,最后rename切换: CREATE TABLE orders_new LIKE orders; ALTER TABLE orders_new ADD COLUMN invoice_status TINYINT; -- 创建三个触发器同步INSERT/UPDATE/DELETE RENAME TABLE orders TO orders_old, orders_new TO orders;

方案2:pt-online-schema-change工具 Percona的这个神器本质也是影子表方案,但自动处理了: - 触发器维护 - 增量数据追赶 - 原子切换 pt-online-schema-change --alter "ADD COLUMN refund_id VARCHAR(32)" D=test,t=orders

方案3:版本化迁移(适合插件开发) 在插件install时仅建基础表,后续通过升级脚本追加: // 1.0.0安装脚本 CREATE TABLE orders (id INT, price DECIMAL...); // 1.1.0升级脚本 if (!schemaHasColumn('orders', 'coupon_id')) { $this->addColumn('orders', 'coupon_id VARCHAR(32) AFTER price'); }

实测百万级数据表: - 直接ALTER:锁表12分钟 - 影子表方案:平均300ms阻塞 - pt-osc:约500ms阻塞

最后提醒:永远先在沙箱环境测试迁移脚本!我们在预发布环境模拟了3次数据量翻倍才敢上生产。

评论1
回复 · 1
CoolKid
CoolKid 初级漫步繁花 · #1 ·
学到了,顶一下
微信客服 微信客服