首页 >> 基础教程
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及以下版本就需要使用另外的方法了。
最新文章
mysql分页问题2025-08-04
千万数据先insert和先建索引哪个快2025-08-04
MySQL 中大小表关联查询如何优化2025-08-04
sql技巧-每个班年龄排前两名的人2025-08-03
MySQL 导致 cpu 飙升的话,要怎么处理呢?2025-07-29
MySQL 中为千万级大表添加字段2025-07-29
mysql中百万级别以上的数据如何删除2025-07-29
分库分表带来的问题2025-07-29
mysql中常用的分库分表中间件有哪些2025-07-29
mysql不停机扩容2025-07-29