表新增字段如何减少影响业务影响
首先选择业务低峰期执行,如果24小时业务都频繁,有以下几种方式:
直接添加
如果该表读写不频繁,数据量较小(通常1G以内或百万以内),直接添加即可。
MySQL 5.6后自带OnlineDDL功能(MyISAM表无法使用,且不支持全文和空间索引),自身的OnlineDDL是inplace模式,当整个alter操作完成后才会将操作同步给从库,会有较高的主从延迟,不推荐采用。
Inplace模式流程如下:
准备阶段
- 对表加元数据锁,并升级为排他锁。(此时DML不能并行)
- 在原表所在的路径下创建.frm和.ibd临时中转文件(no-rebuild除创建二级索引外只创建.frm文件,其中添加二级索引操作最为特殊,该操作属于no-rebuild不会生成.ibd,但实际上对.ibd文件却做了修改,该操作会在参数tmpdir指定路径下生成临时文件,用于存储索引排序结果,然后再合并到.ibd文件中)
- 申请row log(innodb_online_alter_log)空间,用于存放DDL执行阶段产生的DML操作。(no-rebuild不需要)
执行阶段:
- 释放DML写锁,保留DML读锁(此时DML可以并行)。
- 扫描原表主键以及二级索引的所有数据页,生成 B+ 树,存储到临时文件中;
- 将所有对原表的DML操作记录在日志文件row log中
注:如果只修改元数据部分(no-rebuild)该阶段只是修改.frm文件,不需要其他操作,也不需要申请row log
提交阶段:
- 升级DML锁,产生DML写锁(此时DML不能并行)。
- 重做row log中的内容。(no-rebuild不需要)
- 重命名原表文件,将临时文件改名为原表文件名,删除原表文件
- 提交事务,变更完成。
使用pt_osc添加(推荐)
如果表较大 但是读写不是太大,且想尽量不影响原表的读写,可以用percona tools进行添加,相当于新建一张添加了字段的新表,再将原表的数据复制到新表中,复制历史数据期间的数据也会同步至新表,最后删除原表,将新表重命名为原表表名,实现字段添加。
PT流程:
- 创建一个和要执行 alter 操作的表一样的新的空表结构(是alter之前的结构)。
- 在新表执行alter table 语句(速度十分快)。
- 在原表中创建触发器3个触发器分别对应insert,update,delete操作。
- 以一定块大小从原表拷贝数据到临时表,拷贝过程中通过原表上的触发器在原表进行的写操作都会更新到新建的临时表。
- Rename 原表到old表中,在把临时表Rename为原表。
注: 如果有参考该表的外键,根据alter-foreign-keys-method参数的值,检测外键相关的表,做相应设置的处理,默认最后将旧原表删除。
先在从库添加,再进行主从切换
如果一张表数据量大且是热表(读写特别频繁),则可以考虑先在从库添加,再进行主从切换,切换后再将其他几个节点上添加字段。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?