• gh-ost工具在线改表过程的详细解析


    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表。

    本博客内容都会在微信公众号(dba John)同步发布,欢迎关注

  • 相关阅读:
    mysql触发器实时检测一条语句进行备份删除
    ORA-12560: TNS: 协议适配器错误 windows
    DG:windows密码文件
    vim already exists!
    k8s 集群升级
    部署 k8s 备份工具 velero
    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
    lens 添加 k8s 集群
    redis系列
    s3c2440裸机-I2c编程-3.i2c中断服务程序
  • 原文地址:https://www.cnblogs.com/dba-john/p/12803679.html
Copyright © 2020-2023  润新知