首页 >> 基础教程

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(读写不阻塞)

  • 操作快速(仅修改元数据,不重建表)

限制

  1. 添加列必须满足 ALGORITHM=INPLACE 条件(如非压缩表、非全文索引等)

  2. 默认值若为 NULL 或 常量(如 DEFAULT 0)可生效

  3. 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

原理

  1. 创建影子表(新结构)

  2. 同步原表数据到影子表

  3. 增量同步通过触发器捕获变更

  4. 原子切换新旧表

优势

  • 几乎零锁表(仅切换瞬间短暂锁)

  • 支持所有 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 同步变更

  • 动态控制负载(暂停/恢复/限流)

  • 更安全的切换机制

方案四:分阶段部署 (业务层配合)

若无法使用工具,可手动分阶段操作:

  1. 初始加列(允许 NULL)

    1. ALTER TABLE your_table ADD COLUMN new_column INT NULL;
    2. (速度较快,仅元数据变更)

  2. 业务层双写
    代码同时更新新旧字段,确保数据一致

  3. 回填历史数据

    1. UPDATE your_table SET new_column = 0 WHERE new_column IS NULL;
      -- 分批次执行(如每次 10k 行
  4. 设置 NOT NULL

    1. 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
备案号:蜀ICP备2023042032号-1