千家信息网

如何理解gh-ost

发表于:2024-09-22 作者:千家信息网编辑
千家信息网最后更新 2024年09月22日,如何理解gh-ost,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。公司内部一直使用的online ddl工具是pt-on
千家信息网最后更新 2024年09月22日如何理解gh-ost

如何理解gh-ost,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

公司内部一直使用的online ddl工具是pt-online-schema-change,今天准备尝试一下另外一个工具gh-ost。

gh-ost 是 gitHub,s Online Schema Transmogrifier/Transfigurator/Transformer/Thingy 的缩写,意思是 GitHub 的在线表定义转换器。

我对gh-ost的感兴趣的原因是gh-ost可随时暂停。如果变更过程发现主库性能受影响,可以立刻停止拉binlog,停止应用 binlog,停止移动行数据,等性能稳定之后再继续;另外,gh-ost不依赖触发器,这是和pt-osc的最大区别。

大致的工作原理:

只以主库模式介绍:

1、 gh-ost 首先连接到主库上,根据 alter 语句创建幽灵表_tablename_gho;  2、 然后gh-ost作为一个备库连接到主库上,一边在主库上拷贝已有的数据到幽灵表,一边从主库上拉取增量数据的 binlog,然后不断的把 binlog 应用回主库幽灵表;  3、 等待全部数据同步完成,进行cut-over,即进行幽灵表和原表切换。cut-over是最后一步,锁住主库的源表,等待binlog应用完毕,然后替换gh-ost幽灵表为源表。gh-ost在执行中,会在原本的binlog event里面增加hint和心跳包,用来控制整个流程的进度,检测状态等。

下载安装

从 github 发布地址下载最新的 binary 包:https://github.com/github/gh-ost/releases

解压后就一个 gh-ost 二进制文件。

 tar -xvf  gh-ost-binary-linux-20190214020851.tar.gz cp gh-ost /usr/bin

常用命令组合

只以主库模式介绍,上生产可以直接用:

gh-ost \ --max-load=Threads_running=50 \ --critical-load=Threads_running=80 \ --critical-load-interval-millis=5000 \ --max-lag-millis=1500 \ --chunk-size=1000 \ --ok-to-drop-table \ --initially-drop-ghost-table \ --initially-drop-socket-file \ --host=172.18.6.2 \ --port=3306 \ --user="chenzhixin" \ --password="123456"\ --database="test" \ --table="user100w"  \ --verbose \ --alter="add column test_field6 varchar(256) default '';" \ --cut-over-lock-timeout-seconds=1 \ --dml-batch-size=10 \ --exact-rowcount  \ --serve-socket-file=/tmp/ghost.sock \ --panic-flag-file=/tmp/ghost.panic.flag  \ --allow-on-master \ --execute  ##########  特别提醒!!!!!!############################ 下面这个参数有需要再加,加了它就不会自动切换源表和幽灵表,需要手工删除/tmp/ghost.postpone.flag 文件后,才会发生自动切换,请理解该参数含义。 --postpone-cut-over-flag-file=/tmp/ghost.postpone.flag

操作过程中会生成两个中间状态的表 _tablename_ghc和_tablename_gho,其中 _tablename_ghc 是记录gh-ost 执行过程的表,_tablename_gho 是目标表,也即应用ddl语句的幽灵表_tablename_gho。

执行上述的gh-ost命令过程中,会看到如下的_user100w_ghc的执行过程表,和_user100w_gho幽灵表、

mysql> show tables;+----------------+| Tables_in_test |+----------------+| _user100w_ghc  || _user100w_gho  || fruits         || test_timestamp || user100w       |+----------------+5 rows in set (0.00 sec)

解释:

--max-load=Threads_running=50   表面如果在执行gh-ost的过程中出现Threads_running=50则暂停gh-ost的执行--critical-load=Threads_running=80  表明执行过程中出现Threads_running达到80则终止gh-ost的执行--critical-load-interval-millis 当值为0时,当达到-critical-load,gh-ost立即退出。当值不为0时,当达到-critical-load,gh-ost会在-critical-load-interval-millis秒数后,再次进行检查,再次检查依旧达到-critical-load,gh-ost将会退出--max-lag-millis  会监控从库的主从延迟情况,如果延迟秒数超过这个阀值,row copy不会退出,等待延迟秒数低于这个阀值继续迁移。--ok-to-drop-table go-ost 执行完以后是否删除老表,加上此参数会自动删除老表。默认不删除老表,会存在_tablename_del表--initially-drop-ghost-table gh-ost 执行前会创建两张 xx_ghc 和 xx_gho 表,如果这两张表存在,且加上了这个参数,那么会自动删除原 gh 表,从新创建,否则退出。xx_gho 表相当于老表的全量备份,xx_ghc 表数据是数据更改日志,理解成增量备份。--initially-drop-socket-file gh-ost 执行时会创建 socket 文件,退出时不会删除,下次执行 gh-ost 时会报错,加上这个参数会删除老的 socket 文件,重新创建。--throttle-flag-file 此文件存在时操作暂停,删除文件操作会继续。--verbose 执行过程输出日志--chunk-size 迁移过程是一步步分批次完成的,这个参数是指事务每次提交的行数,默认是 1000。--max-lag-millis 会监控从库的主从延迟情况,如果延迟秒数超过这个阀值,迁移不会退出,等待延迟秒数低于这个阀值继续迁移。--max-lag-millis 会监控从库的主从延迟情况,如果延迟秒数超过这个阀值,迁移不会退出,等待延迟秒数低于这个阀值继续迁移--throttle-control-replica  和--max-lag-millis 参数相结合,这个参数指定主从延迟的数据库实例。--cut-over-lock-timeout-seconds        gh-ost在cut-over阶段最大的锁等待时间,当锁超时时,gh-ost的cut-over将重试。(默认值:3)--allow-on-master 整个迁移所有操作在主库上执行--dml-batch-size     在单个事务中应用DML事件的批量大小(范围1-100)(默认值为10)--exact-rowcount   准确统计表行数(使用select count(*)的方式),得到更准确的预估时间。--postpone-cut-over-flag-file   当这个文件存在的时候,gh-ost的cut-over阶段将会被推迟,数据仍然在复制,直到该文件被删除。--throttle-flag-file string  当该文件被创建后,gh-ost操作立即停止。该参数适合控制单个gh-ost操作。-throttle-additional-flag-file string适合控制多个gh-ost操作。

进度提示

执行gh-ost中,会有输出信息,具体解释如下:

Copy: 27000/58707 46.0%;58707指需要迁移总行数,27000指已经迁移的行数,46%指迁移完成的百分比。Applied: 0,指在二进制日志中处理的event数量。在上面的例子中,迁移表没有流量,因此没有被处理日志event。Backlog: 0/1000,表示我们在读取二进制日志方面表现良好,在二进制日志队列中没有任何积压(Backlog)事件。Backlog: 7/1000,当复制行时,在二进制日志中积压了一些事件,并且需要应用。Backlog: 1000/1000,表示我们的1000个事件的缓冲区已满(程序写死的1000个事件缓冲区,低版本是100个),此时就注意binlog写入量非常大,gh-ost处理不过来event了,可能需要暂停binlog读取,需要优先应用缓冲区的事件。streamer: shvm-5-39.000040:338912890;表示当前已经应用到binlog文件位置

控制gh-ost的过程

#首先要安装socat工具

yum install socat -y

注意:上面gh-ost里面配置的--serve-socket-file=/tmp/ghost.sock,下面就用到了。

gh-ost 可以通过 unix socket 文件的方式来监听请求,DBA 可以在gh-ost命令运行后更改相应的参数进行限流操作等。

#暂停

echo throttle | socat - /tmp/ghost.sock

#恢复

echo no-throttle | socat - /tmp/ghost.sock

#终止

对应panic-flag-file参数文件,当tmp目录存在该文件立即停止touch /tmp/ghost.panic.flag

#延迟切换(cut-over阶段)

--postpone-cut-over-flag-file=/tmp/ghost.postpone.flag当设置该参数时cut-over一直延迟源表和幽灵表的切换,直到你删除该文件才进行切换。

适用场景:

你发起了一次修改操作,然后估计完成时间是凌晨 2 点钟,可是你又非常关心最后的切换操作,非常想看着它切换,这可怎么办?只需要一个标志位文件就可以告诉 gh-ost 推迟切换了,这样 gh-ost 会只做完拷贝数据的操作,但不会切换表。它还会仍然继续同步数据,保持幽灵表的数据处于同步状态。等第二天早上你回到办公室之后,删除标志位文件或者向gh-ost发送命令echo unpostpone,它就会做切换了。我们不希望软件强迫我们看着它做事情,它应该把我们解放出来,让人去做人该做的事。

#在线修改限速参数

echo max-load=Threads_connected=200  | socat - /tmp/ghost.sockecho max-load=Thread_running=3 | socat - /tmp/ghost.sockecho chunk-size=100 | socat - /tmp/ghost.sockecho max-lag-millis=200 | socat - /tmp/ghost.sock

适用场景:

当你执行了 gh-ost 之后,也许你会看见主库的负载变高了,那你可以发出暂停命令。用 echo throttle 命令生成一个文件,看看主库的负载会不会又变得正常。试一下这些命令,你就可以知道你可以怎样控制它的行为,你的心里就会安定许多。

gh-ost的限制

凡事有利必有弊,人不可能把所有好事都占有,下面是gh-ost的几个限制:

1、不支持没有主键或者唯一索引的表

2、不支持有外键约束的表(主表和子表都不支持)

3、不支持表上有触发器

5、表上存在大量写入的时候,gh-ost可能永远也完成不了

经过测试:当写入QPS 5000以上,gh-ost无法完成任务,其原因是apply binlog是单线程,可以理解为slave,当原表写入量巨大时(QPS=5000以上),一直在应用日志,而gh-ost设计是binlog应用优先级高于row copy,所以我们看到row copy进度一直没变,这样如果原表一直压力这么大,那么gh-ost DDL将无法完成。经过在s3710机器上测试如果原表写入的QPS大于5000将大概率出现此情况,小于5000的话没问题。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。

0