Commit 3760845b authored by He Zhenxing's avatar He Zhenxing

Auto merge from 5.1-rep-semisync

parents dbdd83a4 b2e3fb8a
...@@ -43,19 +43,16 @@ unsigned long long rpl_semi_sync_master_trx_wait_time = 0; ...@@ -43,19 +43,16 @@ unsigned long long rpl_semi_sync_master_trx_wait_time = 0;
char rpl_semi_sync_master_wait_no_slave = 1; char rpl_semi_sync_master_wait_no_slave = 1;
static int getWaitTime(const struct timeval& start_tv); static int getWaitTime(const struct timespec& start_ts);
#ifdef __WIN__ static unsigned long long timespec_to_usec(const struct timespec *ts)
static int gettimeofday(struct timeval *tv, void *tz)
{ {
unsigned int ticks; #ifndef __WIN__
ticks= GetTickCount(); return (unsigned long long) ts->tv_sec * TIME_MILLION + ts->tv_nsec / TIME_THOUSAND;
tv->tv_usec= ticks*1000; #else
tv->tv_sec= ticks/1000; return ts->tv.i64 / 10;
return 0;
}
#endif /* __WIN__ */ #endif /* __WIN__ */
}
/******************************************************************************* /*******************************************************************************
* *
...@@ -606,12 +603,12 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name, ...@@ -606,12 +603,12 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
if (getMasterEnabled() && trx_wait_binlog_name) if (getMasterEnabled() && trx_wait_binlog_name)
{ {
struct timeval start_tv; struct timespec start_ts;
struct timespec abstime; struct timespec abstime;
int wait_result, start_time_err; int wait_result;
const char *old_msg= 0; const char *old_msg= 0;
start_time_err = gettimeofday(&start_tv, 0); set_timespec(start_ts, 0);
/* Acquire the mutex. */ /* Acquire the mutex. */
lock(); lock();
...@@ -679,98 +676,72 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name, ...@@ -679,98 +676,72 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
kWho, wait_file_name_, (unsigned long)wait_file_pos_); kWho, wait_file_name_, (unsigned long)wait_file_pos_);
} }
if (start_time_err == 0) /* Calcuate the waiting period. */
{
int diff_usecs = start_tv.tv_usec + wait_timeout_ * TIME_THOUSAND;
/* Calcuate the waiting period. */
#ifdef __WIN__ #ifdef __WIN__
abstime.tv.i64 = (__int64)start_tv.tv_sec * TIME_MILLION * 10; abstime.tv.i64 = start_ts.tv.i64 + (__int64)wait_timeout_ * TIME_THOUSAND * 10;
abstime.tv.i64 += (__int64)diff_usecs * 10; abstime.max_timeout_msec= (long)wait_timeout_;
abstime.max_timeout_msec= (long)wait_timeout_;
#else #else
abstime.tv_sec = start_tv.tv_sec; unsigned long long diff_nsecs =
if (diff_usecs < TIME_MILLION) start_ts.tv_nsec + (unsigned long long)wait_timeout_ * TIME_MILLION;
{ abstime.tv_sec = start_ts.tv_sec;
abstime.tv_nsec = diff_usecs * TIME_THOUSAND; while (diff_nsecs >= TIME_BILLION)
} {
else abstime.tv_sec++;
{ diff_nsecs -= TIME_BILLION;
while (diff_usecs >= TIME_MILLION) }
{ abstime.tv_nsec = diff_nsecs;
abstime.tv_sec++;
diff_usecs -= TIME_MILLION;
}
abstime.tv_nsec = diff_usecs * TIME_THOUSAND;
}
#endif /* __WIN__ */ #endif /* __WIN__ */
/* In semi-synchronous replication, we wait until the binlog-dump /* In semi-synchronous replication, we wait until the binlog-dump
* thread has received the reply on the relevant binlog segment from the * thread has received the reply on the relevant binlog segment from the
* replication slave. * replication slave.
* *
* Let us suspend this thread to wait on the condition; * Let us suspend this thread to wait on the condition;
* when replication has progressed far enough, we will release * when replication has progressed far enough, we will release
* these waiting threads. * these waiting threads.
*/ */
rpl_semi_sync_master_wait_sessions++; rpl_semi_sync_master_wait_sessions++;
if (trace_level_ & kTraceDetail) if (trace_level_ & kTraceDetail)
sql_print_information("%s: wait %lu ms for binlog sent (%s, %lu)", sql_print_information("%s: wait %lu ms for binlog sent (%s, %lu)",
kWho, wait_timeout_, kWho, wait_timeout_,
wait_file_name_, (unsigned long)wait_file_pos_); wait_file_name_, (unsigned long)wait_file_pos_);
wait_result = cond_timewait(&abstime); wait_result = cond_timewait(&abstime);
rpl_semi_sync_master_wait_sessions--; rpl_semi_sync_master_wait_sessions--;
if (wait_result != 0) if (wait_result != 0)
{ {
/* This is a real wait timeout. */ /* This is a real wait timeout. */
sql_print_warning("Timeout waiting for reply of binlog (file: %s, pos: %lu), " sql_print_warning("Timeout waiting for reply of binlog (file: %s, pos: %lu), "
"semi-sync up to file %s, position %lu.", "semi-sync up to file %s, position %lu.",
trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos, trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos,
reply_file_name_, (unsigned long)reply_file_pos_); reply_file_name_, (unsigned long)reply_file_pos_);
rpl_semi_sync_master_wait_timeouts++; rpl_semi_sync_master_wait_timeouts++;
/* switch semi-sync off */ /* switch semi-sync off */
switch_off(); switch_off();
}
else
{
int wait_time;
wait_time = getWaitTime(start_tv);
if (wait_time < 0)
{
if (trace_level_ & kTraceGeneral)
{
/* This is a time/gettimeofday function call error. */
sql_print_error("Replication semi-sync gettimeofday fail1 at "
"wait position (%s, %lu)",
trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos);
}
rpl_semi_sync_master_timefunc_fails++;
}
else
{
rpl_semi_sync_master_trx_wait_num++;
rpl_semi_sync_master_trx_wait_time += wait_time;
}
}
} }
else else
{ {
if (trace_level_ & kTraceGeneral) int wait_time;
{
/* This is a gettimeofday function call error. */ wait_time = getWaitTime(start_ts);
sql_print_error("Replication semi-sync gettimeofday fail2 at " if (wait_time < 0)
"wait position (%s, %lu)", {
trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos); if (trace_level_ & kTraceGeneral)
{
sql_print_error("Replication semi-sync getWaitTime fail at "
"wait position (%s, %lu)",
trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos);
}
rpl_semi_sync_master_timefunc_fails++;
}
else
{
rpl_semi_sync_master_trx_wait_num++;
rpl_semi_sync_master_trx_wait_time += wait_time;
} }
rpl_semi_sync_master_timefunc_fails++;
/* switch semi-sync off */
switch_off();
} }
} }
...@@ -1080,8 +1051,7 @@ int ReplSemiSyncMaster::readSlaveReply(NET *net, uint32 server_id, ...@@ -1080,8 +1051,7 @@ int ReplSemiSyncMaster::readSlaveReply(NET *net, uint32 server_id,
ulong packet_len; ulong packet_len;
int result = -1; int result = -1;
struct timeval start_tv; struct timespec start_ts;
int start_time_err= 0;
ulong trc_level = trace_level_; ulong trc_level = trace_level_;
function_enter(kWho); function_enter(kWho);
...@@ -1095,7 +1065,7 @@ int ReplSemiSyncMaster::readSlaveReply(NET *net, uint32 server_id, ...@@ -1095,7 +1065,7 @@ int ReplSemiSyncMaster::readSlaveReply(NET *net, uint32 server_id,
} }
if (trc_level & kTraceNetWait) if (trc_level & kTraceNetWait)
start_time_err = gettimeofday(&start_tv, 0); set_timespec(start_ts, 0);
/* We flush to make sure that the current event is sent to the network, /* We flush to make sure that the current event is sent to the network,
* instead of being buffered in the TCP/IP stack. * instead of being buffered in the TCP/IP stack.
...@@ -1120,28 +1090,17 @@ int ReplSemiSyncMaster::readSlaveReply(NET *net, uint32 server_id, ...@@ -1120,28 +1090,17 @@ int ReplSemiSyncMaster::readSlaveReply(NET *net, uint32 server_id,
if (trc_level & kTraceNetWait) if (trc_level & kTraceNetWait)
{ {
if (start_time_err != 0) int wait_time = getWaitTime(start_ts);
if (wait_time < 0)
{ {
sql_print_error("Semi-sync master wait for reply " sql_print_error("Semi-sync master wait for reply "
"gettimeofday fail to get start time"); "fail to get wait time.");
rpl_semi_sync_master_timefunc_fails++; rpl_semi_sync_master_timefunc_fails++;
} }
else else
{ {
int wait_time; rpl_semi_sync_master_net_wait_num++;
rpl_semi_sync_master_net_wait_time += wait_time;
wait_time = getWaitTime(start_tv);
if (wait_time < 0)
{
sql_print_error("Semi-sync master wait for reply "
"gettimeofday fail to get wait time.");
rpl_semi_sync_master_timefunc_fails++;
}
else
{
rpl_semi_sync_master_net_wait_num++;
rpl_semi_sync_master_net_wait_time += wait_time;
}
} }
} }
...@@ -1230,24 +1189,23 @@ void ReplSemiSyncMaster::setExportStats() ...@@ -1230,24 +1189,23 @@ void ReplSemiSyncMaster::setExportStats()
* *
* Return: * Return:
* >= 0: the waiting time in microsecons(us) * >= 0: the waiting time in microsecons(us)
* < 0: error in gettimeofday or time back traverse * < 0: error in get time or time back traverse
*/ */
static int getWaitTime(const struct timeval& start_tv) static int getWaitTime(const struct timespec& start_ts)
{ {
unsigned long long start_usecs, end_usecs; unsigned long long start_usecs, end_usecs;
struct timeval end_tv; struct timespec end_ts;
int end_time_err;
/* Starting time in microseconds(us). */ /* Starting time in microseconds(us). */
start_usecs = start_tv.tv_sec * TIME_MILLION + start_tv.tv_usec; start_usecs = timespec_to_usec(&start_ts);
/* Get the wait time interval. */ /* Get the wait time interval. */
end_time_err = gettimeofday(&end_tv, 0); set_timespec(end_ts, 0);
/* Ending time in microseconds(us). */ /* Ending time in microseconds(us). */
end_usecs = end_tv.tv_sec * TIME_MILLION + end_tv.tv_usec; end_usecs = timespec_to_usec(&end_ts);
if (end_time_err != 0 || end_usecs < start_usecs) if (end_usecs < start_usecs)
return -1; return -1;
return (int)(end_usecs - start_usecs); return (int)(end_usecs - start_usecs);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment