gh-ost使用说明
- 下载安装
源码地址:https://github.com/github/gh-ost
安装包下载地址:https://github.com/github/gh-ost/releases
下载binary-linux版本
直接下载解压可用。
二、基本使用
2.1获取帮助文档
./gh-ost help |
2.2使用示例:
|
参数说明:
--exact-rowcount :准确统计表行数(使用select count(*)的方式),得到更准确的预估时间。
--serve-socket-file:创建socket文件进行监听,执行操作的过程中可以通过scoket接口对参数进行动态调整。
#暂停
echo throttle | nc -U /tmp/gh-ost.test.t1.sock
#恢复
echo no-throttle | nc -U /tmp/gh-ost.test.t1.sock
# 限速参数
echo chunk-size=100 |nc -U /tmp/gh-ost.t1.sock
在每次迭代中处理的行数量(允许范围:100-100000),默认值为1000
echo max-lag-millis=200 | nc -U /tmp/gh-ost.t1.sock
主从复制最大延迟时间,当主从复制延迟时间超过该值后,gh-ost将采取节流(throttle)措施,默认值:1500s
三、原理说明
- gh-ost根据alter内容,新建一张”_源表名_gho”的幽灵表。
- 将原表内容分批次insert到ghost表(row-copy)。单批次1000条,由参数chunk-size控制
insert into ghost select * from tab where id >= batchminid and id< batchmin_id+1000;
- 另外一个线程读取binlog,捕捉该表的dml(binlog-apply)。并应用到ghost表。
- 最后进行cut-over,锁定原表,待binlog完全追上,进行rename操作。
存在问题说明:
- gh-ost设计是binlog应用优先级高于row copy,所以我们看到row copy进度一直没变,这样如果原表一直压力这么大,那么gh-ost DDL将无法完成。
- 操作完成后,原表将被rename成_tab_del表,该表需要手工删除。
四、压测数据
4.1压测说明:
测试表信息:
IP: 31.67.72.21
port: 3367
db_name: test_wan
table:wjf_test_ghost2
row_num: 40W
使用语句:
新增字段:alter table wjf_test_ghost2 add column test6 varchar2(10);
新增索引:alter table idx_wjf_ghost2_crt add index wjf_test_ghost2(created_at);
修改列类型:alter table wjf_test_ghost2 modify TRANSACTION_ID varchar(50);
sysbench说明:
lua文件单个查询sleep(0.01)------1个sysbench线程200TPS
4.2场景说明:
单一场景gh-ost执行时间测试:
序号 | 场景 | 操作 | 全库 TPS | 全库 QPS | 操作表TPS |
1 |
无TPS | 新增字段 | 0 | 0 | 0 |
2 | 新增索引 | ||||
3 | 修改列类型 | ||||
4 |
TPS不在操作表 | 新增字段 | 8K | 7W | 0 |
5 | 新增索引 | ||||
6 | 修改列类型 | ||||
7 |
TPS只在操作表 6.5K 无法完成 | 新增字段 | 4K | 4K | 4K |
8 | 新增索引 | ||||
9 | 修改列类型 |
单一场景mysql slave测试及数据:
序号 | TPS(120s) | Slave |
10 | 7.6K | 0 |
11 | 1.5W | 0 |
12 | 1.6W | 6s |
13 | 1.7W | 13s |
14 | 1.8W | 24s |
复合场景gh-ost测试:
序号 | 场景 | 操作 | 全库 TPS | 全库 QPS | 操作表TPS |
13 |
TPS部分在操作表 | 新增字段 | 10K | 7W | 2K |
14 | 新增索引 | ||||
15 | 修改列类型 | ||||
16 | TPS部分在操作表 | 新增字段 | 11K | 7W | 3K |
17 | 新增索引 | ||||
18 | 修改列类型 |
4.3压测结果:
场景序号 | Online 执行时间 | 从库 Lag最大值 | Gh-ost 执行时间 | 从库 Lag最大值 |
场景说明 |
1 | 1 m 56s | 100s | 2m19s | 0 | 无任何TPS |
2 | 11 s | 11s | 2m29s | 0 | |
3 | 2 m13s | 100s | 2m31s | 0 | |
4 | 2m12s | 150s | 2m38s | 0 | 有TPS 8K 不在操作表 |
5 | 11s | 11s | 2m54s | 0 | |
6 | 2m10s | 150s | 2m54s | 0 | |
7 | 2m44s | 150s | 5m11s | 0 | TPS只在操作表3K |
8 | 11s | 11s | 6m37s | 0 | |
9 | 2m14s | 147s | 5m10s | 0 | |
13 | 2m20s | 130s | 4m5s | 0 | TPS在操作表2K 在其他表8K |
14 | 11s | 11s | 3m34s | 0 | |
15 | 2m14s | 130s | 3m38s | 0 | |
16 | 2m45s | 128s | 5m32s | 0 | TPS在操作表3K 在其他表8K |
17 | 11s | 11s | 5m30s | 0 | |
18 | 2m14s | 130s | 5m39s | 0 |
五、结论:
- 当前mysql参数配置下,为保证slave无延迟,最大TPS不得大于1.5W。
- gh-ost 对个别表的操作时间受该表上的TPS影响较大,受全库其他表TPS影响很小。
- gh-ost操作表的最大TPS为4K,否则会出现永远无法完成的情况。
- 对于新增索引、新增字段、更改字段类型这类操作,建议使用gh-ost保证slave延时可控。
- 经测试,mysql可以一个语句操作多个ddl语句,如果可以,建议放在一个ddl中完成。
比如加两个字段,推荐使用 alter table test1 add column col1,add column col2;