gh-ost学习笔记 试验&&代码学习

本文是关于gh-ost的学习笔记,它是一个MySQL的在线DDL工具。文章介绍了gh-ost相对于传统DDL的优势,以及其工作流程,包括在主库或从库上的转换模式。同时,提到了gh-ost的代码结构如atomic和cutOverTwoStep,并讨论了rename操作与DML锁的获取顺序问题。最后,提供了相关参考资料链接。
摘要由CSDN通过智能技术生成

gh-ost学习笔记

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J7hhPnvg-1641550092432)(https://github.com/WQMysqlDBA/gh-ost/blob/master/doc/images/gh-ost-logo-light-160.png?raw=true)]

"开始吧"

gh-ost github开源的一个online ddl工具

某位业内不太知名,朋友圈内比较知名的同学,关于何时使用gh-ost,做了一个经典的描述

"100万行数据一下,,可以使用online ddl

超过百万,,可以使用gh-ost"

(。。。就这么几个字,他还写个错别字)

"了解一下mysql的ddl的几种方式"

1、MySQL 5.6 InnoDB 存储引擎在线DDL功能:

优点:
添加、删除字段或索引、添加主键、修改字段名字不会锁表。
局限性:
修改列数据类型 、删除表主键、修改字符集、添加全文索引会锁表
Online ddl是一个事务操作(从库延迟会严重)、取消会造成事务回滚影响数据库性能

2、pt-online-schema-change:

1)表不能存在其他触发器,否则报错
2)触发器存在锁竞争问题,对MySQL的性能造成比较大的影响,严重时甚至会拖垮数据库。
3)Rename可能出各种问题:阻塞原始表业务操作过久、丢数据、切换失败等
4)大表copy 造成内存热数据溢出
5)无法暂停:当主库业务负载开始增高时,你可能会想要暂停还没完成的修改表定义的任务。可是基于触发器的方案没办法这么做,只能取消操作,删除临时表、删除触发器。
6)当数据量增多、业务压力增大之后,就会碰到了越来越多的问题,有一些操作只敢在非业务低峰期才敢执行。

3、gh-ost有以下特点:

1)轻量,无触发器,因此对原表只copy,影响小
2)可以测试(在从库执行一遍)
3)提供暂停服务(业务忙了接着暂停,注意binlog清理期限)
4)伪装成从库,流方式读取变更的binlog,异步复制原理,应用到幽灵表

好处
gh-ost 承担一些其他工具留给数据库执行的任务,无触发器。
gh-ost可以更好地控制迁移过程;
可以真正暂停它;
可以真正将迁移的写入负载与主服务器的工作负载分离。
此外,它还提供了许多可操作的特权,使其更安全、可信赖且易于使用。
(异步,都是异步,只要binlog是全的,随便停止随便应用,就是玩)

gh-ost的工作流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ulSIh5fN-1641550092434)(https://github.com/WQMysqlDBA/gh-ost/blob/master/doc/images/gh-ost-general-flow.png?raw=true)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bLNo6P6W-1641550092434)(https://github.com/WQMysqlDBA/gh-ost/blob/master/doc/images/gh-ost-operation-modes.png?raw=true)]

(深颜色表示Priamry节点,浅颜色表示Secondary节点)

gh-ost有三种工作模式

1、连接从库,在主库转换 b

2、连接主库,在主库转换 a

3、在从库上测试和转换 c

  • 1、连接从库,在主库转换 (default)

    这是gh-ost的默认模式
    1、gh-ost 将会检查从库状态,找到集群结构中的主库并连接,接下来进行迁移操作
    2、在主库上创建 _xxx_gho(和原表表结构一致)、_xxx_ghc(记录变更日志),并修改 _xxx_gho 表结构
    例如:
    _sbtest1_ghc   变更日志,即binlog应用的日志
    _sbtest1_gho   幽灵表
    sbtest1        原表
    3、业务正常进行,行数据在主库上读写,读取从库的二进制日志,将变更应用到主库的幽灵表上
    4、在从库收集表格式,字段&索引,行数等信息
    5、在从库上读取内部的变更事件(如心跳事件)
    6、在主库切换表
    ./gh-ost --max-load=Threads_running=20 \
    --critical-load=Threads_running=200 \
    --critical-load-interval-millis=5000 \
    --chunk-size=10000  \
    --user="root" \
    --password="xxxx" \
    --host='xxxxxxxxxxxx' --port=3306 \
    --database="test" --table="sbtest1" \
    --verbose --debug --stack  \
    --alter="add key idx_datetime(datetime)" \
    --initially-drop-ghost-table \
    --initially-drop-old-table \
    --execute 2>&1  | tee  rebuild_t1.log
    
  • 2、连接主库,在主库转换

    需要使用 --allow-on-master 选项:
    在主库上创建 _xxx_gho、_xxx_ghc,并修改 _xxx_gho 表结构;
    在主库上读源表的数据写入 _xxx_gho 表中;
    从主库上读取二进制日志事件,将变更应用到主库上的 _xxx_gho 表;
    在主库上完成表切换。
    如果你没有从库,或者不想使用从库,你可以直接在主库上操作。
    gh-ost 将会直接在主库上进行所有操作。你需要持续关注复制延迟问题。
    你的主库的二进制日志必须是 RBR 格式。
    在这个模式中你必须指定 --allow-on-master 参数
    
    ./gh-ost --max-load=Threads_running=20 \
    --critical-load=Threads_running=200 \
    --critical-load-interval-millis=5000 \
    --chunk-size=10000  \
    --user="root" --password="taotao" \
    --host=127.0.0.1 --port=3306 \
    --database="test" --table="sbtest1" \
    --verbose --debug --stack 
    --allow-on-master \   
    --alter="add key idx_createtime(createtime) " 
    --initially-drop-ghost-table --initially-drop-old-table \
    --execute 2>&1  | tee  rebuild_t1.log
    
  • 3、在从库进行测试和转换

    这种模式会在从库上做修改。gh-ost 仍然会连上主库,但所有操作都是在从库上做的,不会对主库产生任何影响。
    在操作过程中,gh-ost 也会不时地暂停,以便从库的数据可以保持最新。gh-ost 将控制速度保证从库可以及时的进行数据同步
    --migrate-on-replica 选项让 gh-ost 直接在从库上修改表。最终的切换过程也是在从库正常复制的状态下完成的。
    --migrate-on-replica 表示 gh-ost 会直接在从库上进行迁移操作。即使在复制运行阶段也可以进行表的切换操作
    --test-on-replica 表明操作只是为了测试目的。在进行最终的切换操作之前,复制会被停止。原始表和临时表会相互切换,再切换回来,最终相当于原始表没被动过。主从复制暂停的状态下,你可以检查和对比这两张表中的数据。
    --test-on-replica 表示 迁移操作只是为了测试在切换之前复制会停止,然后会进行切换操作,然后在切换回来,你的原始表最终还是原始表。两个表都会保存下来,复制操作是停止的。你可以对这两个表进行一致性检查等测试操作。
    
    gh-ost限制条件
    违反限制条件gh-ost会报错,所以工具还是比较安全的。
    1.做的过程会间隙的锁部分记录(记录数chunk-size参数定义),:因为copy数据使用了 insert ..select from ... where pk >? and pk< ? lock in share mode
    2.Master-master setup is only supported in active-passive setup. Active-active (where table is being written to on both masters concurrently) is unsupported. It may be supported in the future.
       这个原因估计时gh-ost代码实现使用了显式加锁的方式。
    3.The two before & after tables must share a PRIMARY KEY or other UNIQUE KEY
    4.Foreign keys not supported
    5.Triggers are not supported.
    

暂停操作:

#暂停
echo throttle | socat - /tmp/gh-ost.test.t1.sock
#恢复
echo no-throttle | socat - /tmp/gh-ost.test.t1.sock

修改限速参数:

echo chunk-size=100 | socat - /tmp/gh-ost.t1.sock

echo max-lag-millis=200 | socat - /tmp/gh-ost.t1.sock

echo max-load=Thread_running=3 | socat - /tmp/gh-ost.t1.sock
2022-01-07 11:53:33 INFO starting gh-ost 1.1.2
2022-01-07 11:53:33 INFO Migrating `qdump`.`sbtest2`
2022-01-07 11:53:33 INFO inspector connection validated on 10.244.0.43:3306
2022-01-07 11:53:33 INFO User has ALL privileges
2022-01-07 11:53:33 INFO binary logs validated on 10.244.0.43:3306
2022-01-07 11:53:33 INFO Inspector initiated on gh-ost-f4d1c00-0:3306, version 5.7.26-log
2022-01-07 11:53:33 INFO Table found. Engine=InnoDB
2022-01-07 11:53:33 DEBUG Estimated number of rows via STATUS: 1000
2022-01-07 11:53:33 DEBUG Validated no foreign keys exist on table
2022-01-07 11:53:33 DEBUG Validated no triggers exist on table
2022-01-07 11:53:33 INFO Estimated number of rows via EXPLAIN: 1000
2022-01-07 11:53:33 DEBUG Potential unique keys in sbtest2: [PRIMARY (auto_increment): [id]; has nullable: false]
2022-01-07 11:53:33 INFO Recursively searching for replication master
2022-01-07 11:53:33 DEBUG Looking for master on 10.244.0.43:3306
2022-01-07 11:53:33 INFO Master found to be gh-ost-f4d1c00-0:3306
2022-01-07 11:53:33 INFO log_slave_updates validated on 10.244.0.43:3306
2022-01-07 11:53:33 INFO streamer connection validated on 10.244.0.43:3306
2022-01-07 11:53:33 DEBUG Streamer binlog coordinates: mysql-bin.000030:486171970
2022-01-07 11:53:33 INFO Connecting binlog streamer at mysql-bin.000030:486171970
[2022/01/07 11:53:33] [info] binlogsyncer.go:133 create BinlogSyncer with config {
   99999 mysql 10.244.0.43 3306 gh-ost    false false <nil> false UTC true 0 0s 0s 0 false}
[2022/01/07 11:53:33] [info] binlogsyncer.go:354 begin to sync binlog from position (mysql-bin.000030, 486171970)
[2022/01/07 11:53:33] [info] binlogsyncer.go:203 register slave for master server 10.244.0.43:3306
2022-01-07 11:53:33 DEBUG Beginning streaming
2022-01-07 11:53:33 INFO rotate to next log from mysql-bin.000030:0 to mysql-bin.000030
[2022/01/07 11:53:33] [info] binlogsyncer.go:723 rotate to (mysql-bin.000030, 486171970)
2022-01-07 11:53:33 INFO applier connection validated on 10.244.0.43:3306
2022-01-07 11:53:33 INFO applier connection validated on 10.244.0.43:3306
2022-01-07 11:53:33 INFO will use time_zone='+08:00' on applier
2022-01-07 11:53:33 INFO Examining table structure on applier
2022-01-07 11:53:33 INFO Applier initiated on gh-ost-f4d1c00-0:3306, version 5.7.26-log
2022-01-07 11:53:33 INFO Dropping table `qdump`.`_sbtest2_gho`
2022-01-07 11:53:33 INFO Table dropped
2022-01-07 11:53:33 INFO Dropping table `qdump`.`_sbtest2_del`
2022-01-07 11:53:33 INFO Table dropped
2022-01-07 11:53:33 INFO Dropping table `qdump`.`_sbtest2_ghc`
2022-01-07 11:53:33 INFO Table dropped
2022-01-07 11:53:33 INFO Creating changelog table `qdump`.`_sbtest2_ghc`
2022-01-07 11:53:33 INFO Changelog table created
2022-01-07 11:53:33 INFO Creating ghost table `qdump`.`_sbtest2_gho`
2022-01-07 11:53:33 INFO Ghost table created
2022-01-07 11:53:33 INFO Altering ghost table `qdump`.`_sbtest2_gho`
2022-01-07 11:53:33 DEBUG ALTER statement: alter /* gh-ost */ table `qdump`.`_sbtest2_gho` ADD COLUMN o2 varchar(10)
2022-01-07 11:53:33 INFO Ghost table altered
2022-01-07 11:53:33 INFO Altering ghost table AUTO_INCREMENT value `qdump`.`_sbtest2_gho`
2022-01-07 11:53:33 DEBUG AUTO_INCREMENT ALTER statement: alter /* gh-ost */ table `qdump`.`_sbtest2_gho` AUTO_INCREMENT=1000001
2022-01-07 11:53:34 INFO Ghost table AUTO_INCREMENT altered
2022-01-07 11:53:34 INFO Intercepted changelog state GhostTableMigrated
2022-01-07 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值