system column十三Tech
← 返回技术专栏
TECH

MySQL大表在线变更字段实战:pt-osc与Online DDL方案对比

深入分析千万级大表在线增加字段的挑战,详解pt-osc工具的工作原理和使用方法,以及MySQL原生Online DDL的优化演进。

MySQL

线上有一张千万级数据量的大表,需要新增一个字段,你该怎么办?直接使用ALTER TABLE可能引发长时间锁表,导致生产事故。在十三Tech的数据库运维实践中,大表在线变更是一个高频且高风险的操作。本文将深入分析各种方案的优劣,重点讲解pt-osc工具的工作原理和使用方法,以及MySQL Online DDL的技术演进。

背景

在MySQL生产环境中,对大表执行DDL操作一直是DBA和开发者面临的棘手问题。表结构变更期间,传统ALTER TABLE会锁定表,阻塞读写操作。对于千万级甚至亿级的大表,锁表时间可能长达数小时,这对线上业务是不可接受的。因此,选择一种安全、高效的在线变更方案至关重要。

ps: 以下内容为参考业界成熟方案总结而来

实现

MySQL 在执行 ALTER TABLE 增加字段操作时,会对表进行短时间的写锁定以避免数据的修改冲突,但是锁定时间将取决于要添加的列的数量,列的大小以及表的大小。

在大表场景下,特别是千万级、亿级的大表,如果处理不当。这些操作往往会引发锁表的巨大隐患,特别是在生产环境中,一旦在变更表结构过程中,出现了长时间锁表,会导致用户产生的数据长时间无法正常变更到表中,进而导致服务功能异常,结果将是灾难性的

一般可能有以下想法

  • 停服, 在停服期间做表结构的变更,自然就可以防止对用户产生影响

  • 凌晨执行, 在用户较少的时间段内,做变更,尽量减少对用户产生影响

  • 使用换表, 但是缺点是复制数据到新表期间,如果用户在这期间做了update或delete操作,且数据发生在已经复制完成的部分,那么将无法感知到这部分数据,导致丢失掉用户的操作数据,风险太大

  • 使用存储过程, 缺点是执行时间会很久,且有可能影响到用户的DDL操作。因为为了防止每次循环修改时,锁住太多数据行,我们需要控制每次更新数据的行数,粒度不能太大,否则很有可能会锁住用户正在操作的数据行

以上的方案都有一定的缺陷,不够丝滑,会对线上业务造成一定的影响

pt-osc

pt-osc (在线模式更改表) 是一个来自 Percona Toolkit 工具包的命令行工具,用于在 MySQL 中进行在线模式更改表结构的操作。相比于传统的 ALTER TABLE 命令,pt-osc 有以下优势:

  • pt-osc 可以避免在执行修改表操作时对表的锁定,从而减小对服务器性能的影响。
  • pt-osc 可以同时进行多个表更改操作,从而避免了多次单独执行 ALTER TABLE 命令的繁琐工作。
  • pt-osc 可以监控表的修改操作,以便及时发现并修复可能出现的错误。

下面是使用 pt-osc 进行表更改的基本步骤

使用 pt-osc 工具修改表结构的主要步骤如下:

1、创建一个跟原表一模一样的新表,命名方式为'_正式表名_new';

2、使用alter语句将要变更的内容在新创建的新表上做变更,避免了对原表的alter操作;

3、在原表中创建3个触发器,分别是insert、update和delete,主要是用于原表在往新表复制数据时,如果用户有DDL操作,触发器能够将在这期间出现的DDL操作数据也写入到新表中,确保新表的数据是最新的,不会丢失掉用户的新操作数据;

4、按块拷贝数据到新表,拷贝过程对数据行持有S锁;

5、重命名,将原表重命名为老表,命名为“_正式表名_old”,将新表重命名为正式表,可通过配置决定执行完成后是否删除掉老表;

6、删除3个触发器;

pt-osc的使用

例如,如果要在名为 testdb 的数据库中的表 testtable 中添加一个名为 new_column 的字段,可以执行以下命令:

pt-online-schema-change --execute --alter "ADD COLUMN new_column INT" D=testdb,t=testtable 

该命令会在数据库 testdb 中对表 testtable 执行添加字段操作,并监控操作的细节。如果发现出现了错误,pt-osc 可以快速回滚修改操作,恢复原来的表结构

大体性能: 1600w的数据量级增加新字段,约7分钟

总结

  • pt-osc 可以帮助我们更好的对表字段进行变更

  • MySQL 5.6 以上版本支持并行索引创建,在执行新增索引操作时,在 ALTER TABLE 语句中添加 ALGORITHM=INPLACE, LOCK=NONE, ONLINE=ON 选项,指定使用 INPLACE 算法、禁用锁定、使用在线模式等选项,让 MySQL 引擎使用并行操作方式来创建索引,从而减少锁定表的时间

  • Mysql 8.0 的ALGORITHM=INSTANT 性能更好,可以达到秒级

总结

MySQL大表在线变更是一项考验工程经验的操作。pt-osc通过触发器+增量同步+原子换表的巧妙设计,实现了真正的在线无锁变更;而MySQL 5.6的Inplace算法和8.0的INSTANT算法则代表了官方在这方面的持续进化。在实际生产环境中,选择合适的工具、评估变更影响、制定回滚方案,缺一不可。更多MySQL运维与架构实战,敬请关注十三Tech。