semi-sync replicaiton的一个“有趣”bug

上周MySQL 5.6.13发布,“貌似”Oracle又开始拥抱社区,有些bug直接使用了社区开发者提交的补丁,这着实让人感到有些困惑与惊喜。看来MariaDB的确很好的牵制了Oracle对于MySQL的负面影响。然而,不管怎么说,5.6.13版本变得更为成熟与稳定。然其中的一个关于semi-sync replication的bug吸引了我。

该bug由Facebook公司的MySQL工程师YOSHINORI MATSUNOBU提出。YOSHINORI MATSUNOBU何许人也?呵呵,在MySQL数据库界他可是真正的大拿。其开发影响力深远的产品非socket handler莫属,可以说对MySQL数据库本身产生了不可磨灭的影响。另外他也是MHA的开发者,相信很多公司都已根据MHA的原型实现了MySQL数据库的高可用。与此同时,他也是MySQL领域的Oracle ACE Director,可谓真正的名至实归。
若将参数rpl_semi_sync_master_timeout设置为一个很大的值就会触发该bug。为什么需要设置为很大的值呢?因为用户不希望replication“轻易地”转化为异步模式。在网易开发的virtual sync replcation中,若用户希望得到数据的一致性并且不考虑的服务可用性,同样需要将该值设置为很大的一个数值。因此,在这种情况下就会触发该bug。
在YOSHINORI MATSUNOBU的mysqlslap测试下,可以发现线程数越多,数据库性能的下降会非常明显:

1 client: 1239 inserts/s
10 clients: 767 inserts/s
20 clients: 478 inserts/s
50 clients: 216 inserts/s
100 clients: 90.0 inserts/s

该bug最后由Libing Song修复,其是中国人,目前就职于Oracle。修复的patch也不大:

+ /* Calcuate the waiting period. */
+#ifdef __WIN__
+ abstime.tv.i64 = start_ts.tv.i64 + (__int64)wait_timeout_ * TIME_THOUSAND * 10;
+ abstime.max_timeout_msec= (long)wait_timeout_;
+#else
+ abstime.tv_sec = start_ts.tv_sec + wait_timeout_ / TIME_THOUSAND;
+ abstime.tv_nsec = start_ts.tv_nsec +
+ (wait_timeout_ % TIME_THOUSAND) * TIME_MILLION;
+ if (abstime.tv_nsec >= TIME_BILLION)
+ {
+ abstime.tv_sec++;
+ abstime.tv_nsec -= TIME_BILLION;
+ }
+#endif /* __WIN__ */
+
while (is_on())
{
if (reply_file_name_inited_)
@@ -686,22 +701,6 @@
kWho, wait_file_name_, (unsigned long)wait_file_pos_);
}

- /* Calcuate the waiting period. */
-#ifdef __WIN__
- abstime.tv.i64 = start_ts.tv.i64 + (__int64)wait_timeout_ * TIME_THOUSAND * 10;
- abstime.max_timeout_msec= (long)wait_timeout_;
-#else
- unsigned long long diff_nsecs =
- start_ts.tv_nsec + (unsigned long long)wait_timeout_ * TIME_MILLION;
- abstime.tv_sec = start_ts.tv_sec;
- while (diff_nsecs >= TIME_BILLION)
- {
- abstime.tv_sec++;
- diff_nsecs -= TIME_BILLION;
- }
- abstime.tv_nsec = diff_nsecs;
-#endif /* __WIN__ */

可以发现patch对超时时间的判断进行了优化,之前需要通过变量tv_nsec来计算,因此需要不断地while。而当超时时间设置的比较大时,并且线程数比较多时,就会产生性能影响。

目前Oracle官方仅在MySQL 5.6中修复了该bug,MySQL 5.5.33版本中该问题依旧。不过相信聪明的小伙伴们已经知道如何修复了吧semi replicaiton的一个“有趣”bug - insidemysql - Inside MySQL

发表评论

坐等沙发
相关文章
MySQL 8.0 200W QPS!!!InnoDB大重构 #M1005#
MySQL 8.0 200W QPS!!!InnoDB大重构 …
滚蛋吧,MySQL主从复制延迟
滚蛋吧,MySQL主从复制延迟
MySQL 8.0.3性能大杀器 —— CATS
MySQL 8.0.3性能大杀器 —— CATS
2017年MySQL数据库技术嘉年华 —— 有态度的技术大会
2017年MySQL数据库技术嘉年华 —— 有态度…
IMG社区MySQL技术沙龙南京站圆满结束
IMG社区MySQL技术沙龙南京站圆满结束
改朝换代:MySQL Group Replication
改朝换代:MySQL Group Replication
myadmin 订阅者
我还没有学会写个人说明!

一触即发,2017年,数据库世界的诸神之战