sysbench花式采坑之一:自增值导致的TPS不可靠
作者 李文航·沃趣科技数据库技术专家
出品 沃趣科技
那是一个风和日丽的春天,本人在读了几篇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调优、数据库故障诊断、数据迁移、备份恢复
点击查看招聘信息
相关链接
18C新特性之PDB snapshot Carousel,够用吗?
沃趣微讲堂 | 深入浅出Kubernetes存储(三):源码分析
更多干货,欢迎来撩~