Description:
Hi,all
When i enlarged the rpl_semi_sync_master_timeout in mysql semi sync replication deployment,
i found the write performance become pool.
rpl_semi_sync_master_timeout qps
10000 3637.16
21600000 3583.02
43200000 3211.17
86400000 2146.96
214748364 1251.67
2147483648 196.3
21474836480 13.99
Note:test by sysbench's insert.lua
This is because of a inappropriate while loop in the semisync_master.cc, show as below:
plugin\semisync\semisync_master.cc:
-------------------------------------------------
#define TIME_THOUSAND 1000
#define TIME_MILLION 1000000
#define TIME_BILLION 1000000000
...
int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
my_off_t trx_wait_binlog_pos)
{
...
/* Calcuate the waiting period. */
...
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)//here is a large loop!!!
{
abstime.tv_sec++;
diff_nsecs -= TIME_BILLION;
}
abstime.tv_nsec = diff_nsecs;
...
}
How to repeat:
1. setup semi sync replication
2. rpl_semi_sync_master_timeout to a large value
3. run benchmark for write
Suggested fix:
By the following modify, the problem can be fixed.
diff plugin/semisync/semisync_master.cc plugin/semisync/semisync_master.cc_bak
687,688c687,688
< start_ts.tv_nsec + ((unsigned long long)wait_timeout_ % TIME_THOUSAND) * TIME_MILLION;
< abstime.tv_sec = start_ts.tv_sec + (unsigned long long)wait_timeout_ / TIME_THOUSAND;
---
> start_ts.tv_nsec + (unsigned long long)wait_timeout_ * TIME_MILLION;
> abstime.tv_sec = start_ts.tv_sec;