如何理解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的大区别。

大致的工作原理:

只以主库模式介绍:

如何理解gh-ost

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.sock
echo max-load=Thread_running=3 | socat - /tmp/ghost.sock
echo chunk-size=100 | socat - /tmp/ghost.sock
echo 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的话没问题。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注创新互联-成都网站建设公司行业资讯频道,感谢您对创新互联的支持。


文章标题:如何理解gh-ost-创新互联
URL网址:http://myzitong.com/article/djddds.html