[MySQL] 在线 DDL 工具 gh-ost 原理简介

一、简介

gh-ost: github 提供的针对 MySQL 无触发器式在线架构迁移解决方案。

二、原理

目前的在线架构变更工具都使用了类似的方式:创建一个和源表一样的临时表,在临时表执行 DDL 语句,并慢慢的迁移老数据到临时表,同时传递源表 DML 变更 (INSERT, UPDATE, DELETE) 到临时表,最终使用临时表替换源表。

gh-ost 也使用了类似的方式,但它不同的地方在于使用了基于 row 的 binlog 方式捕获 DML 变更,并异步更新到临时表中。原理如下图所示:
[MySQL] 在线 DDL 工具 gh-ost 原理简介_第1张图片
gh-ost 可以直接连接到 MySQL master 服务器,但是官方建议连接到 replica 服务器(一般为 slave 服务器)上。

注:binlog 可用于主从复制(MySQL主从延迟现象及原理分析)、数据恢复,有三种格式:

  • row(默认):只记录数据行的变化。不需要记录上下文信息,但可能会产生大量日志,如 alter table 操作。
  • statement:只记录引起数据变更的 SQL 语句。日志量小,但需要记录数据上下文信息,同时有些函数在不同的环境下执行结果可能不一致。
  • mixed: 默认使用 statement 格式,在某些情况下会转换成 row 格式,如存在 UUID() 函数,修改了自增列等。

特性

通过这种 binlog 的方式迁移数据,gh-ost 可以更好地控制迁移过程,如真正的暂停、与 master 的写入负载解耦等。

问题

当对大表加字段时(如业务表几十上百G):

  1. 需要注意磁盘空间是否充足
  2. 由于binlog 是 row 格式,而每条数据从 original 表数据复制到 ghost 表,都相当于 dml 变更,因此会产生大量的 binlog 日志,注意从库延迟

三、其他工具

原理

目前已有的 MySQL 架构迁移工具:

  • pt-online-schema-change
  • Facebook OSC
  • LHM
  • oak-online-alter-table

都使用了触发器,通过触发器来传递源表 DML 变更,分为两种方式:

  • 同步:源表的所有 DML 变更同步更新到临时表中
  • 异步:源表的所有 DML 变更插入到一个 changelog 表中,再通过异步程序从 changelog 表取出 DML 信息,更新到临时表中

触发器式同步迁移原理:
[MySQL] 在线 DDL 工具 gh-ost 原理简介_第2张图片
触发器式异步迁移:
[MySQL] 在线 DDL 工具 gh-ost 原理简介_第3张图片

风险

使用触发器可以简化活跃表的数据迁移,但是也存在一些限制和风险,如触发器执行造成的额外资源开销、并发写入导致的锁竞争、无法真正暂停等。

参考文章:

GitHub’s gh-ost
gh-ost’s Triggerless design
Why gh-ost triggerless
Binary Logging Formats
Mixed Binary Logging Format
MySQL主从延迟现象及原理分析
MySQL InnoDB 修改表列Online DDL

你可能感兴趣的:(mysql)