基于MySQL row格式的复制现在趋于主流,因此可以使用此格式的binlog来跟踪改变而不是触发器。与percona toolkit的pt-online-schema-online相比,gh-ost做法更为干净,更安全。由于gh-ost不使用触发器,可能会产生更低的开销并且工作更快。
声明:这些基准对应于一个特定结构和硬件配置的表上的一个特定的ALTER TABLE。 我没有设置一套广泛的测试。
Benchmark Setup Details:
● pt-online-schema-change from Percona Toolkit 3.0.3
● gh-ost 1.0.36
● Percona Server 5.7.18 on Ubuntu 16.04 LTS
● Hardware: 28CPU cores/56 Threads. 128GB Memory. Samsung 960 Pro 512GB
● Sysbench 1.0.7
通过如下命令生成测试表:
sysbench --threads=40 --rate=0 --report-interval=1 --percentile=99 --events=0 --time=0 --db-ps-mode=auto --mysql-user=sbtest --mysql-password=sbtest /usr/share/sysbench/oltp_read_write.lua --table_size=10000000 prepare
表大小为3GB
设置如下参数以满足“full ACID”:
- sync_binlog=1
- innodb_flush_log_at_trx_commit=1
- innodb_doublewrite=1
使用pt-online-schema-online更改表结构:
time pt-online-schema-change --execute --alter "ADD COLUMN c1 INT" D=sbtest,t=sbtest1
使用gh-ost更改表结构:
time ./gh-ost --user="sbtest" --password="sbtest" --host=localhost --allow-on-master --database="sbtest" --table="sbtest1" --alter="ADD COLUMN c1 INT" --execute
测试细节:
对于每个测试,丢弃旧的sysbench表被并准备好一个新表。 在每次测量了所有情况下的alter table完成时间,以及alter所产生的开销(换句话说,通过通过工具运行alter table可以减少多少峰值吞吐量)。 在三种不同的情况下进行alter table测试:
● When nothing else was running (“Idle Load”) 空负载
● When the system handled about 2% of load it can handle at full capacity (“Light Background Load”)系统有2%左右的负载(低负载)
● When the system handled about 40% of the possible load, with sysbench injected about 25% of the transactions/sec the system could handle at full load (“Heavy Background Load”)系统处理40%左右的负载(高负载)
Idle Load(空负载)
对于空闲负载测试,pt-online-schema-change完成几乎比gh-ost快一倍。可以看到gh-ost的大部分CPU使用情况在MySQL服务器端。 也许差异与用于执行非阻塞alter table的SQL有关。
Light Background Load(低负载)
通过运行下面的sysbench命令生成了Light Background Load。 它对应于大约4%的负载,因为系统可以在满负荷的情况下处理这种并发的大约2500个事务/秒。 调整–rate值以缩放系统。
time sysbench --threads=40 --rate=100 --report-interval=1 --percentile=99 --events=0 --time=0 --db-ps-mode=auto --mysql-user=sbtest --mysql-password=sbtest /usr/share/sysbench/oltp_read_write.lua --table_size=10000000 run
时间变化如逾期一样,pt-osc仍然比gh-ost快一倍
在这种情况下真正有趣的是如何相对较轻的后台负载影响过程完成时间。
Heavy Background Load(高负载)
运行下面sysbench命令生成的Heavy Background Load。 它对应于大约40%的负载,因为系统可以在满负载的情况下处理这种并发性的大约2500个事务/秒。 调整–rate值以缩放系统。
![](/qrcode.jpg)
time sysbench --threads=40 --rate=1000 --report-interval=1 --percentile=99 --events=0 --time=0 --db-ps-mode=auto --mysql-user=sbtest --mysql-password=sbtest /usr/share/sysbench/oltp_read_write.lua --table_size=10000000 run
在这种情况下发生了什么?当负载变高时,gh-ost无法跟上二进制日志处理,而且永远完不成。
虽然这可能令人惊讶,但如果您更多地考虑这些工具的工作原理,这是有道理的。 pt-online-schema-change使用触发器,虽然它们有很多限制和开销,但它们可以并行执行。另一方面,gh-ost将二进制日志处理在单个线程中,可能无法跟上。
在MySQL 5.6中,我们无法并行复制同一个表中。对于该版本,第一个限制可能不是一个大的问题,因为这么大的负载会导致复制滞后。 MySQL 5.7具有并行复制功能。这使得快速复制对于gh-ost来说太重的工作负载更容易处理。
此时应该注意到,在这个基准测试中模拟的工作量是一个相当极端的情况。在这里由gh-ost更改的表同时处理一个后台加载,因此它不能在单个线程中复制。
gh-ost的未来版本可以通过并行应用binlog事件来改善这个问题,就想MySQL复制一样。
来自gh-ost日志的摘录,显示了如何完全备份尝试应用二进制日志:
root@rocky:/tmp# time ./gh-ost --user="sbtest" --password="sbtest" --host=localhost --allow-on-master --database="sbtest" --table="sbtest1" --alter="ADD COLUMN c1 INT" --execute
2017/06/25 19:16:05 binlogsyncer.go:75: [info] create BinlogSyncer with config &{99999 mysql localhost 3306 sbtest sbtest false false <nil>}
2017/06/25 19:16:05 binlogsyncer.go:241: [info] begin to sync binlog from position (rocky-bin.000018, 640881773)
2017/06/25 19:16:05 binlogsyncer.go:134: [info] register slave for master server localhost:3306
2017/06/25 19:16:05 binlogsyncer.go:568: [info] rotate to (rocky-bin.000018, 640881773)
2017-06-25 19:16:05 ERROR parsing time "" as "2006-01-02T15:04:05.999999999Z07:00": cannot parse "" as "2006"
# Migrating `sbtest`.`sbtest1`; Ghost table is `sbtest`.`_sbtest1_gho`
# Migrating rocky:3306; inspecting rocky:3306; executing on rocky
# Migration started at Sun Jun 25 19:16:05 -0400 2017
# chunk-size: 1000; max-lag-millis: 1500ms; max-load: ; critical-load: ; nice-ratio: 0.000000
# throttle-additional-flag-file: /tmp/gh-ost.throttle
# Serving on unix socket: /tmp/gh-ost.sbtest.sbtest1.sock
Copy: 0/9872432 0.0%; Applied: 0; Backlog: 0/100; Time: 0s(total), 0s(copy); streamer: rocky-bin.000018:641578191; State: migrating; ETA: N/A
Copy: 0/9872432 0.0%; Applied: 0; Backlog: 100/100; Time: 1s(total), 1s(copy); streamer: rocky-bin.000018:641626699; State: migrating; ETA: N/A
Copy: 0/9872432 0.0%; Applied: 640; Backlog: 100/100; Time: 2s(total), 2s(copy); streamer: rocky-bin.000018:641896215; State: migrating; ETA: N/A
Copy: 0/9872432 0.0%; Applied: 1310; Backlog: 100/100; Time: 3s(total), 3s(copy); streamer: rocky-bin.000018:642178659; State: migrating; ETA: N/A
Copy: 0/9872432 0.0%; Applied: 1920; Backlog: 100/100; Time: 4s(total), 4s(copy); streamer: rocky-bin.000018:642436043; State: migrating; ETA: N/A
Copy: 0/9872432 0.0%; Applied: 2600; Backlog: 100/100; Time: 5s(total), 5s(copy); streamer: rocky-bin.000018:642722777; State:
...
Copy: 0/9872432 0.0%; Applied: 120240; Backlog: 100/100; Time: 3m0s(total), 3m0s(copy); streamer: rocky-bin.000018:694142377; State: migrating; ETA: N/A
Copy: 0/9872432 0.0%; Applied: 140330; Backlog: 100/100; Time: 3m30s(total), 3m30s(copy); streamer: rocky-bin.000018:702948219; State: migrating; ETA: N/A
Copy: 0/9872432 0.0%; Applied: 160450; Backlog: 100/100; Time: 4m0s(total), 4m0s(copy); streamer: rocky-bin.000018:711775662; State: migrating; ETA: N/A
Copy: 0/9872432 0.0%; Applied: 180600; Backlog: 100/100; Time: 4m30s(total), 4m30s(copy); streamer: rocky-bin.000018:720626338; State: migrating; ETA: N/A
Copy: 0/9872432 0.0%; Applied: 200770; Backlog: 100/100; Time: 5m0s(total), 5m0s(copy); streamer: rocky-bin.000018:729509960; State: migrating; ETA: N/A
在线架构改变性能影响
对于这个测试,我启动了alter table,等待了60秒,然后全速运行sysbench五分钟。 然后我通过运行该工具来衡量性能受到的影响:
sysbench --threads=40 --rate=0 --report-interval=1 --percentile=99 --events=0 --time=300 --db-ps-mode=auto --mysql-user=sbtest --mysql-password=sbtest /usr/share/sysbench/oltp_read_write.lua --table_size=10000000 run
我们可以看到,在这种情况下,gh-ost的开销可以忽略不计。 另一方面,pt-osc模式性能下降了12%。 值得注意的是,尽管在这种情况下,pt-online-schema-change仍然取得进展(尽管缓慢),而gh-ost永远不会完成相应更改。
总结
虽然gh-ost引入了一些设计优势,并且在某些情况下给出了更好的结果,但是, 至少在某些情况下,pt-online-schema-change提供比gh-ost更好的性能,而且存在gh-ost无法完成的schema更改。