首页 >> 基础教程
MySQL 中为千万级大表添加字段
在 MySQL 中为千万级大表添加字段时,直接使用 ALTER TABLE 可能导致长时间锁表,影响线上服务。以下是几种安全高效的方案:
方案一:使用 Online DDL (MySQL 5.6+ 推荐)
ALTER TABLE your_table
ADD COLUMN new_column INT DEFAULT 0,ALGORITHM=INPLACE, LOCK=NONE;
优势:
-
支持并发 DML(读写不阻塞)
-
操作快速(仅修改元数据,不重建表)
限制:
-
添加列必须满足
ALGORITHM=INPLACE条件(如非压缩表、非全文索引等) -
默认值若为
NULL或 常量(如DEFAULT 0)可生效 -
MySQL 8.0 优化更好,建议优先升级
方案二:Percona Toolkit 工具 (通用推荐)
使用 pt-online-schema-change 无锁操作:
pt-online-schema-change \
--alter "ADD COLUMN new_column INT DEFAULT 0" \
D=database_name,t=your_table \
--execute
原理:
-
创建影子表(新结构)
-
同步原表数据到影子表
-
增量同步通过触发器捕获变更
-
原子切换新旧表
优势:
-
几乎零锁表(仅切换瞬间短暂锁)
-
支持所有 MySQL 版本
方案三:gh-ost 工具 (高并发场景)
GitHub 开源的更安全的工具:
gh-ost \
--allow-on-master \
--database="database_name" \
--table="your_table" \
--alter="ADD COLUMN new_column INT DEFAULT 0" \
--execute
优势:
-
无触发器,通过 binlog 同步变更
-
动态控制负载(暂停/恢复/限流)
-
更安全的切换机制
方案四:分阶段部署 (业务层配合)
若无法使用工具,可手动分阶段操作:
-
初始加列(允许 NULL)
-
ALTER TABLE your_table ADD COLUMN new_column INT NULL; -
(速度较快,仅元数据变更)
-
业务层双写
代码同时更新新旧字段,确保数据一致 -
回填历史数据
-
UPDATE your_table SET new_column = 0 WHERE new_column IS NULL; -- 分批次执行(如每次 10k 行 -
设置 NOT NULL
-
ALTER TABLE your_table MODIFY new_column INT NOT NULL DEFAULT 0;
对比
方法
锁表时间
磁盘开销
主从延迟风险
复杂度
Online DDL (INPLACE)
秒级
低
中
低
pt-online-schema-change
毫秒级
高
中
中等
gh-ost
毫秒级
高
低
中等
分阶段部署
秒级
低
高
高
如果使用高版本mysql直接使用ddl语句就好了,如果使用5.6及以下版本就需要使用另外的方法了。
最新文章
20.5 性能优化建议2026-05-08
20.4 复杂查询实现2026-05-08
20.3 表创建与数据初始化2026-05-08
20.2 数据库设计2026-05-08
20.1 项目需求分析:博客系统2026-05-08
19.4 自动化备份策略2026-05-08
19.3 导出和导入数据2026-05-08
19.2 恢复备份数据2026-05-05
19.1 使用mysqldump备份数据2026-05-05
18.4 实战:开发简单的学生管理系统2026-05-05

发表评论
所有评论