初试GH-OST

最近老板让作一个gh-ost和pt-osc 的对比测试,本文将对二者作对比。mysql

一。原理和所用说明git

  PT-OSC GH-OST
原理

1.建立一个和要执行 alter 操做的表同样的新的空表结构(是alter以前的结构)
2.在新表执行alter table 语句
3.在原表中建立触发器3个触发器分别对应insert,update,delete操做
4.以必定块大小从原表拷贝数据到临时表,拷贝过程当中经过原表上的触发器在原表进行的写操做都会更新到新建的临时表
5.Rename 原表到old表中,在把临时表Rename为原表
6.若是有参考该表的外键,根据alter-foreign-keys-method参数的值,检测外键相关的表,作相应设置的处理
7.默认最后将旧原表删除github

1.在变动的服务器上 建立 ghost table( _tbname_gho like tbname)
2.更改 _tbname_gho 结构为新表结构
3.做为mysql的slave链接mysql server,并记录新增binlog event
4.交替执行: 应用新增events到 ghost table 和 复制老表的记录到 ghost table
5.table重命名(ghost table 替代 老表)sql

其中有2种经常使用用法:
1.链接从库,变动主库 - 默认方式,slave须要开启log-slave-update
2.链接主库,变动主库 - 必须ROW格式,带上参数--allow-on-master"服务器

使用限制

1.原表必需要有主键或者惟一索引(不含NULL)
2.原表上不能有触发器存在
3.使用前需保证有足够的磁盘容量,由于复制原表须要一倍的空间
4.在阿里RDS 上使用须要增长参数no-version-check异步

1.原表必需要有主键或者惟一索引(不含NULL)
2.不支持外键
3.不支持触发器
4.不支持虚拟列
5.不支持 5.7 point类型的列
6. 5.7 JSON列不能是主键
7.不能存在另一个table名字同样,只是大小写有区别
8.不支持多源复制
9.不支持M-M 双写
10.不支持FEDERATED enginesocket

重要参数说明

--max-load,默认threads_running=25,能够指定多个指标来限速,每一个chunk拷贝完会检查,超过阀值会暂停复制。若是不指定该参数,工具会检查当前运行值并增长20%
--critical-load,默认为threads_running=50,若是不指定,则工具检查当前运行值并当运行到200%是退出工具运行
--max-lag,默认1s,若是发现延迟大于该值,则暂停复制数据。
--check-interval,配合max-lag使用,检查从库超过延时后,该工具睡眠多久
--recursion-method,指定从库的发现机制,processlist,dsn,none 等
--chunk-time,默认0.5秒,拷贝数据行的时候为了保证0.5秒内拷贝完一个chunk,动态调整下一次chunk-size的大小
--[no]check-replication-filters,若是工具检查到服务器选项中有任何复制相关的筛选,工具会报错退出,默认为yes
--chunk-size,指定块大小,默认1000行。工具

--max-load=Threads_running=25 表面若是在执行gh-ost的过程当中出现Threads_running=25则暂停gh-ost的执行
--critical-load=Threads_running=60 代表执行过程当中出现Threads_running达到60则终止gh-ost的执行
--chunk-size=1000 设置每次从原表copy到 ghost table的行数
--ok-to-drop-table 执行完以后删除原表
--allow-on-master 直连主库执行性能

优势  1.执行速度快,业界使用比较普遍,较稳定

1.读binlog能够放在从库执行,减小主库的压力
2.不须要建立触发器,对原表没有改动测试

风险点  

1.须要建立触发器,对原表有改动
2.涉及主键的更改须要review

1.当系统负载极高时,gh-ost有可能没法跟上binlog日志的处理(未测试过该场景)
2.限制比较多,见上文
3.涉及主键的更改须要review

运行命令实例 pt-online-schema-change --user=db_monitor --password=xxx --host=127.0.0.1 --port=xxx --alter "add COLUMN c2 varchar (120) not null default ''" D=sbtest,t=sbtest1 --no-check-replication-filters --alter-foreign-keys-method=auto --recursion-method=none --print --execute ./gh-ost --assume-master-host=ip:port --master-user=db_monitor --master-password=xxx --user=db_monitor --password=yyy --host=10.xxx --port=port  --alter="ADD COLUMN c2 varchar(120)"   --database=sbtest --table="sbtest1" -execute --initially-drop-old-table --initially-drop-socket-file --initially-drop-ghost-table

 

二,性能测试对比

1. 测试场景

       16core CPU,2G buffer pool的测试实例,5.5的MySQL版本异步主从,2kw行记录,4.8GB 测试表大小

2. 测试结果(不限速),复制延时用zabbix 监控seconds behind master 的值

        

3. 结果展现

 

三, 最后说一下GH-OST的 cut over

gh-ost利用了MySQL的一个特性,就是原子性的rename请求,在全部被blocked的请求中,优先级永远是最高的。
gh-ost基于此设计了该方案:一个链接对原表加锁,另启一个链接尝试rename操做,此时会被阻塞住,当释放lock的时候,rename会首先被执行,其余被阻塞的请求会继续应用到新表。

 

参考资料:

https://github.com/github/gh-ost

https://m.aliyun.com/yunqi/articles/62928

http://www.tabdba.com/?p=175

相关文章
相关标签/搜索