sysbench花式采坑之一:自增值导致的TPS不可靠

性能测试是评估架构可用性的一大标准,如果性能测试的结果不够准确,会给日后的业务模型和高可用架构选型带来很大的影响。sysbench是MySQL数据库中常用的一款性能测试的工具,那sysbench在使用过程中会有什么不正确的打开方式导致性能测试结果不准确吗?

作者 李文航·沃趣科技数据库技术专家
出品 沃趣科技

那是一个风和日丽的春天,本人在读了几篇sysbench的使用文档,外加找朋友要了个sysbench安装包,装上跑了一下后,感觉sysbench也就这么回事,自己已经完全掌握了,可以游刃有余的应对公司交给我的测试项目了。没错,科学证明,真的不要乱立flag,这样会很扎心的。总之,怀着自信满满的心情,我遇到了测试过程中的第一个问题。

| MySQL异步复制性能低于MGR架构

这次测试需要测一下架构之间的性能对比,一开始走势是非常好的,异步复制性能高于半同步复制,嗯,很符合预期嘛,前景一片良好,那测一下MGR吧,我十分潇洒的搭架构,造数据,手起刀落,卧槽,什么鬼,MGR的性能竟然比异步复制的性能还要高?!

“感受停在我发端的指尖,如何瞬间冻结时间”,当时我的心情就像现在听的这首《光年之外》,啦啦啦啦,我没想到~。怀着慈悲为怀的心情,我回去对比了一下MGR和异步复制的配置文件,发现两者之间除了MGR的专用配置外,其他配置均相同,那么问题大概是出在MGR的专用配置上了,当时我忘记戴上的眼镜片上精光一闪,呵呵,又被我看穿了。

针对MGR的专用配置,本人又去回过头翻了一下文档,好吧,没找到什么,MGR就这么些配置项,不论哪个都看起来都和我性能测试没关系呀。

transaction_write_set_extraction = XXHASH64
#plugin-load='group_replication=group_replication.so'
## [group replication variables]
group_replication_group_name = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
group_replication_start_on_boot = off
group_replication_bootstrap_group = off
group_replication_local_address = '172.17.0.1:33061'
group_replication_group_seeds ='172.17.0.1:33061,172.17.0.2:33061,172.17.0.3:33061'
#group_replication_single_primary_mode = off
group_replication_single_primary_mode = on
#group_replication_enforce_update_everywhere_checks = on
group_replication_enforce_update_everywhere_checks = off
group_replication_ip_whitelist='127.0.0.1/32,172.17.0.0/16'

那会不会是造的数据量不一样?于是我select count统计了一下,发现确实都是500W行呀,保险起见,看一下最大ID吧,因此我执行了一下select max(id) from sbtest1;异步复制上得到了500W的结果,MGR上得到了3500W的结果,嗯,两个相等,看来不是这里…….呸,等下,哪里相等了?!

WTF,同样的造数语句竟然造出不一样的数据,此时歌曲切换到了小生的花伞还落在你家,好吧,歌词并没有表达出我当时的心意。于是我select * from sbtest1 limit 10看了一下,愣是用我的24K硬化氪金泰坦精钢,呵呵,我是不会说狗眼的,于细微处看出了不同,发现异步复制中ID列的结果是[1,2,3,4,5,6,7,8,9,10],在看MGR中,ID列的结果是[3,10,17,24,31,38,45,52,59,66],唉,这么不明显的差别也就只有我能看出来了。

既然找到了明显的不同,那会不会是这个问题造成了MGR性能高于异步复制的现象呢?于是我在周身用我仅剩的几块灵石摆了一个聚灵阵,在阵法内打坐冥想,神识先是在体内运行了12个小周天,过手太阴肺经,经列缺、天府、中府几大要穴,然后自头顶冲窍而出,于青莲幻境之中开始了推演,终于发现这就是我要的滑板鞋…

从ID列的结果可以看出,两种架构的自增值是不一样的,那自增值不同为什么会出现性能不同的现象呢,先耗费些许灵力把我冥想中的图炼化两幅出来吧。

(左为异步复制数据样图,右为MGR数据样图)

根据sysbench的源码来看,sysbench在做oltp的时候,select、update都是根据输入的行数大小随机生成一个ID来进行。

...
rs = db_query("SELECT c FROM ".. table_name .." WHERE id=" .. sb_rand(1, oltp_table_size))
...
query = "UPDATE " .. table_name .. " SET c='" .. c_val .. "' WHERE id=" .. sb_rand(1, oltp_table_size)
...

而delete和insert是对同一个随机生成的ID进行操作的。

i = sb_rand(1, oltp_table_size)
rs = db_query("DELETE FROM " .. table_name .. " WHERE id=" .. i)
...
rs = db_query("INSERT INTO " .. table_name .. " (id, k, c, pad) VALUES " .. string.format("(%d, %d, '%s', '%s')",i, sb_rand(1, oltp_table_size) , c_val, pad_val))

既然ID是随机生成的,那么问题就来了,在MGR架构中,如果生成一条ID为3或者10的SQL语句,这些语句是可以正常执行的,但如果生成了ID为4或5或6的SQL语句,在MGR架构中这些ID是不存在的,因此这就是一条空DML,这种空DML速度是非常快的,而且还会计入sysbench的tps的结果,这样自然会造成MGR架构的性能测试结果偏高。

既然找到了MGR性能偏高的原因,那造成MGR和异步复制中ID不一致的原因又是什么呢?在经验上来说,这种情况99.9%就是自增造成的,于是我又看了一下MGR的配置描述,果然注意到了之前一眼扫过去就排除嫌疑的MGR专门控制自增的参数。

group_replication_auto_increment_increment

把这个参数设置为1,重新进行造数,发现MGR中的数据和异步复制中的ID保持了一致,性能测试结果也恢复了正常。

总之,这是自增值对sysbench压测带来的一个坑,那自增值会不会还有其他坑呢?嗯,今日气冲斗府,微盈相冲,正是闭关的好时机,我必须去闭个关了,先升它一个小境界。

| 作者简介

李文航·沃趣科技数据库技术专家

熟悉MySQL体系结构和工作原理、SQL调优、数据库故障诊断、数据迁移、备份恢复

《sysbench花式采坑之一:自增值导致的TPS不可靠》有2个想法

  1. “在MGR架构中,如果生成一条ID为3或者10的SQL语句,这些语句是可以正常执行的,但如果生成了ID为4或5或6的SQL语句,在MGR架构中这些ID是不存在的。”
    请问一下,这个依据是什么,在网上没有搜索到相关资料

    1. 这句话的前提是MGR架构的自增步长设置的值不为1,当id列为自增列且步长为7时,通过自增生成的id值内容为3、10、17、24、31……,id值为1、2、4、5、6、7……的这些值由于自增的原因是不存在的

发表评论

电子邮件地址不会被公开。 必填项已用*标注