gh-ost,是github开源的一款在线修改MySQL表结构的工具https://github.com/github/gh-ost/,它不使用pt-osc的触发器机制,而是使用解析binlog来实现将增量数据复制到新表。

最近我抽空了解了一下它的源码,结合debug日志,整理出它的过程,如下:

1.检查过程:

a.连接验证:connection validated on...
b.检查用户权限:User has SUPER, REPLICATION SLAVE privileges, and has ALL privileges on `sbtest`.*
c.binlog验证:binary logs validated on...
d.检查表存储引擎及评估表数据量:Estimated number of rows via EXPLAIN
e.判断Master节点

2.准备过程

a.伪装成Slave节点,通过binlogsyncer连接到Master节点,拉取binlog
b.初始化Applier,Applier的用途是apply增量binlog至gho表,apply的方式,上面有介绍过。
c.创建ghc(change log表),创建gho(影子表),将alter语句应用到gho表
d.选择可以确定唯一行的字段,确定目标表的所有字段(Shared columns)
e.创建一个socket文件,用来执行如暂停、限流等操作,参考https://github.com/github/gh-ost/blob/master/doc/interactive-commands.md。
f.根据命令指定的参数,决定使用何种方式来计算表的数据量,并通过上面选择的唯一键来确定最大、最小值
g.监视throttle-additional-flag-file,以决定是否限流

3.数据同步过程

a.开始copy源表数据至gho表,示例语句:
insert /* gh-ost `sbtest`.`t1` */ ignore into `sbtest`.`_t1_gho` (`id`)
(select `id` from `sbtest`.`t1` force index (`PRIMARY`)
where (((`id` > _binary'1') or ((`id` = _binary'1'))) and ((`id` < _binary'4') or ((`id` = _binary'4')))) lock in share mode
b.同时,将binlog中与源表相关的dml操作,在gho表上面应用,以保持2表的数据一致。 在本文的最后部分会有较详细的分析。

4.交换表过程

gh-ost实现原子交换过程的逻辑,都在migrator.go的atomicCutOver()函数中,过程如下:
a.Copy线程使用select get_lock('gh-ost.989.lock', 0)方式创建锁,以确保ghost工具各线程之间的操作一致,其中989是Copy线程连接到MySQL的connection_id
b.Rename线程创建一个magic cut-over table,表名是源表名加上_del后缀。至于magic cut-over table名称的由来,是为了防止在rename操作成功之前,Copy线程意外断开与MySQL的连接,从而导致新数据被写入到源表,而这部分新数据无法同步到gho表。
c.Copy线程同时锁住源表和_del表
d.Rename线程等待所有的event在gho表上应用完毕
e.Rename线程交换表,此时因为表被Copy线程锁住,所以此时会一直等待锁释放,示例语句:rename /* gh-ost */ table `sbtest`.`t1` to `sbtest`.`_t1_del`, `sbtest`.`_t1_gho` to `sbtest`.`t1`
f.另外一个线程使用select is_used_lock('gh-ost.989.lock')方式判断Copy线程是否持有锁,因为必须要确保有锁,才能防止源表被写入新数据
g.Copy线程现在可以安全地同删除_del表了,然后unlock tables, 并rollback
h.上述步骤完成的同时,Rename线程获取锁,完成原子rename操作

交换表的过程,我粗略整理了一下流程如下:

5.收尾工作

删除ghc后缀的changelog表

ost期间,增量数据如何复制? 

这是gh-ost的特点之一。实现原理如下:

osc期间,源表新增的数据,是通过解析binlog中的DML Events,然后由logic/applier.go的buildDMLEventQuery调用sql/builder.go中相应的函数(例如insert操作对应的是BuildDMLInsertQuery函数),来生成相应的query语句,然后返回给logic/applier.go的ApplyDMLEventQueries(tx.Exec)执行,以实现同步数据到gho表。

gh-ost工具在线改表过程的详细解析的更多相关文章

  1. mysql在线改表结构 pt-online-schema-change

    https://www.percona.com/doc/percona-toolkit/2.1/pt-online-schema-change.html 不锁表更改数据库表结构 pt-online-s ...

  2. Hash表 算法的详细解析

    http://xingyunbaijunwei.blog.163.com/blog/static/76538067201111494524190/ 什么是HashHash,一般翻译做“散列”,也有直接 ...

  3. Apach Shiro MD5密码加密过程(明文生成密码过程)详细解析

    前言: 最近再项目当中使用的ApachShiro安全框架,对于权限和服务器资源的保护都有一个很好的管理.前期主要参考的文章有 项目中设计密码的加盐处理以及二次加密问题,跟着断点 一步步揭开Apach ...

  4. Linux MTD下获取Nand flash各个参数的过程的详细解析【转】

    本文转载自:https://www.crifan.com/files/doc/docbook/nand_get_type/release/html/nand_get_type.html 文章不错可以看 ...

  5. MySQL使用pt-online-change-schema工具在线修改1.6亿级数据表结构

    摘  要:本文阐述了MySQL DDL 的问题现状.pt-online-schema-change的工作原理,并实际利用pt-online-schema-change工具在线修改生产环境下1.6亿级数 ...

  6. pt-online-schema-change在线修改表结构

    工具简介 pt-osc模仿MySQL内部的改表方式进行改表,但整个改表过程是通过对原始表的拷贝来完成的,即在改表过程中原始表不会被锁定,并不影响对该表的读写操作.首先,osc创建与原始表相同的不包含数 ...

  7. ClickHouse(10)ClickHouse合并树MergeTree家族表引擎之ReplacingMergeTree详细解析

    目录 建表语法 数据处理策略 资料分享 参考文章 MergeTree拥有主键,但是它的主键却没有唯一键的约束.这意味着即便多行数据的主键相同,它们还是能够被正常写入.在某些使用场合,用户并不希望数据表 ...

  8. ClickHouse(11)ClickHouse合并树MergeTree家族表引擎之SummingMergeTree详细解析

    目录 建表语法 数据处理 汇总的通用规则 AggregateFunction 列中的汇总 嵌套结构数据的处理 资料分享 参考文章 SummingMergeTree引擎继承自MergeTree.区别在于 ...

  9. ClickHouse(13)ClickHouse合并树MergeTree家族表引擎之CollapsingMergeTree详细解析

    目录 建表 折叠 数据 算法 资料分享 参考文章 该引擎继承于MergeTree,并在数据块合并算法中添加了折叠行的逻辑.CollapsingMergeTree会异步的删除(折叠)这些除了特定列Sig ...

  10. 在线数据库表(sql语句)生成java实体类工具

    相信每个做java开发的读者,都接触过SQL建表语句,尤其是在项目开发初期,因为数据库是项目的基石. 在现代项目开发中,出现了许多ORM框架,通过简单的实体映射,即可实现与数据库的交互,然而我们最初设 ...

随机推荐

  1. Go context 介绍

    在 Go 编程语言中,context 包提供了一个用于在 goroutine 之间传递上下文信息的方法.它通常用于控制 goroutine 的生命周期.传递请求范围内的数据.以及处理超时或取消信号.c ...

  2. 使用 Quickwit 的搜索流功能为 ClickHouse 添加全文搜索

    本指南将帮助您使用 Quickwit 的搜索流功能为知名的 OLAP 数据库 ClickHouse 添加全文搜索.Quickwit 暴露了一个 REST 端点,可以极快地(每秒最多 5000 万条)流 ...

  3. LCD屏幕显示PNG图像

    正点原子LCD屏幕显示PNG图像 本文概要 这段时间在学习正点原子的IMX6ULL开发板,在应用编程中有一个代码练习是需要在LCD屏幕上显示PNG图像,但由于我的屏幕参数和教程中的有些出入,于是经过自 ...

  4. c程序设计语言 by K&R(四)输入与输出

    一.标准输入.输出 1. 简单的输入\输出机制 从标准输入中一次读取一个字符:int getchar(void) 将字符c送到标准输出中: int putchar(int) 2. 输入重定向 如果程序 ...

  5. css+div实现各种常见边框

    css+div实现各种常见边框 一.效果图如下 二.实现代码 div { width: 120px; height: 100px; margin: 10px; float: left; text-al ...

  6. Time Zone, Leap Year, Date Format, Epoch Time 时区, 闰年, 日期格式

    前言 以前有写过一篇了, 但很乱, 这篇就作为它的整理版吧. Leap Year 闰年 闰年是指那些有 366 天, 二月份有 29号 的年份. 比如 2020年 有 2月29日, 所以 2020 就 ...

  7. Java日期时间API系列20-----Jdk8中java.time包中的新的日期时间API类,ZoneId时区ID大全等。

    Java日期时间API系列19-----Jdk8中java.time包中的新的日期时间API类,ZonedDateTime与ZoneId和LocalDateTime的关系,ZonedDateTime格 ...

  8. feign在服务间传递header

    场景: 用户登陆后,再次访问网页,将用户信息loginToken放在request的header中,首先经过网关,然后到达A服务,然后A服务调用B服务时如何把loginToken传递给B服务 1.修改 ...

  9. flink同步MySQL数据的时候出现内存溢出

    flink同步MySQL数据的时候出现内存溢出 背景:需要将1000w的某类型数据同步到别的数据源里面,使用公司的大数据平台可以很快处理完毕,而且使用的内存只有很少很少量(公司的大数据平台的底层是fl ...

  10. Kubernetes 持久化存储之 NFS 终极实战指南

    作者:运维有术星主 在 Kubernetes 生态系统中,持久化存储扮演着至关重要的角色,它是支撑应用稳定运行的基石.对于那些选择自建 Kubernetes 集群的运维架构师而言,选择合适的后端持久化 ...