diff options
author | He Zhenxing <zhenxing.he@sun.com> | 2010-03-11 10:22:18 +0800 |
---|---|---|
committer | He Zhenxing <zhenxing.he@sun.com> | 2010-03-11 10:22:18 +0800 |
commit | 71e8549eb1a0d9ab7da2ea5ffb080c3f403344b4 (patch) | |
tree | d14d344c57fbb8202191417a45cb5675d67735da /plugin | |
parent | f6660539c24eabf7f784d1bdfedf8d01023c73c8 (diff) | |
parent | bd6cce8a7cdca95f448055c46a031f9b387c1cb2 (diff) | |
download | mariadb-git-71e8549eb1a0d9ab7da2ea5ffb080c3f403344b4.tar.gz |
Auto merge from 5.1-rep-semisync
Diffstat (limited to 'plugin')
-rw-r--r-- | plugin/semisync/semisync_master.cc | 210 |
1 files changed, 84 insertions, 126 deletions
diff --git a/plugin/semisync/semisync_master.cc b/plugin/semisync/semisync_master.cc index 8d7bda94ef0..cdf01854442 100644 --- a/plugin/semisync/semisync_master.cc +++ b/plugin/semisync/semisync_master.cc @@ -43,19 +43,16 @@ unsigned long long rpl_semi_sync_master_trx_wait_time = 0; 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 int gettimeofday(struct timeval *tv, void *tz) +static unsigned long long timespec_to_usec(const struct timespec *ts) { - unsigned int ticks; - ticks= GetTickCount(); - tv->tv_usec= ticks*1000; - tv->tv_sec= ticks/1000; - - return 0; -} +#ifndef __WIN__ + return (unsigned long long) ts->tv_sec * TIME_MILLION + ts->tv_nsec / TIME_THOUSAND; +#else + return ts->tv.i64 / 10; #endif /* __WIN__ */ +} /******************************************************************************* * @@ -606,12 +603,12 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name, if (getMasterEnabled() && trx_wait_binlog_name) { - struct timeval start_tv; + struct timespec start_ts; struct timespec abstime; - int wait_result, start_time_err; + int wait_result; const char *old_msg= 0; - start_time_err = gettimeofday(&start_tv, 0); + set_timespec(start_ts, 0); /* Acquire the mutex. */ lock(); @@ -679,98 +676,72 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name, kWho, wait_file_name_, (unsigned long)wait_file_pos_); } - if (start_time_err == 0) - { - int diff_usecs = start_tv.tv_usec + wait_timeout_ * TIME_THOUSAND; - - /* Calcuate the waiting period. */ + /* Calcuate the waiting period. */ #ifdef __WIN__ - abstime.tv.i64 = (__int64)start_tv.tv_sec * TIME_MILLION * 10; - abstime.tv.i64 += (__int64)diff_usecs * 10; - abstime.max_timeout_msec= (long)wait_timeout_; + 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_tv.tv_sec; - if (diff_usecs < TIME_MILLION) - { - abstime.tv_nsec = diff_usecs * TIME_THOUSAND; - } - else - { - while (diff_usecs >= TIME_MILLION) - { - abstime.tv_sec++; - diff_usecs -= TIME_MILLION; - } - abstime.tv_nsec = diff_usecs * TIME_THOUSAND; - } + 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__ */ - - /* In semi-synchronous replication, we wait until the binlog-dump - * thread has received the reply on the relevant binlog segment from the - * replication slave. - * - * Let us suspend this thread to wait on the condition; - * when replication has progressed far enough, we will release - * these waiting threads. - */ - rpl_semi_sync_master_wait_sessions++; - - if (trace_level_ & kTraceDetail) - sql_print_information("%s: wait %lu ms for binlog sent (%s, %lu)", - kWho, wait_timeout_, - wait_file_name_, (unsigned long)wait_file_pos_); - - wait_result = cond_timewait(&abstime); - rpl_semi_sync_master_wait_sessions--; - - if (wait_result != 0) - { - /* This is a real wait timeout. */ - sql_print_warning("Timeout waiting for reply of binlog (file: %s, pos: %lu), " - "semi-sync up to file %s, position %lu.", - trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos, - reply_file_name_, (unsigned long)reply_file_pos_); - rpl_semi_sync_master_wait_timeouts++; - - /* switch semi-sync 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; - } - } + + /* In semi-synchronous replication, we wait until the binlog-dump + * thread has received the reply on the relevant binlog segment from the + * replication slave. + * + * Let us suspend this thread to wait on the condition; + * when replication has progressed far enough, we will release + * these waiting threads. + */ + rpl_semi_sync_master_wait_sessions++; + + if (trace_level_ & kTraceDetail) + sql_print_information("%s: wait %lu ms for binlog sent (%s, %lu)", + kWho, wait_timeout_, + wait_file_name_, (unsigned long)wait_file_pos_); + + wait_result = cond_timewait(&abstime); + rpl_semi_sync_master_wait_sessions--; + + if (wait_result != 0) + { + /* This is a real wait timeout. */ + sql_print_warning("Timeout waiting for reply of binlog (file: %s, pos: %lu), " + "semi-sync up to file %s, position %lu.", + trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos, + reply_file_name_, (unsigned long)reply_file_pos_); + rpl_semi_sync_master_wait_timeouts++; + + /* switch semi-sync off */ + switch_off(); } else { - if (trace_level_ & kTraceGeneral) - { - /* This is a gettimeofday function call error. */ - sql_print_error("Replication semi-sync gettimeofday fail2 at " - "wait position (%s, %lu)", - trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos); + int wait_time; + + wait_time = getWaitTime(start_ts); + if (wait_time < 0) + { + 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, ulong packet_len; int result = -1; - struct timeval start_tv; - int start_time_err= 0; + struct timespec start_ts; ulong trc_level = trace_level_; function_enter(kWho); @@ -1095,7 +1065,7 @@ int ReplSemiSyncMaster::readSlaveReply(NET *net, uint32 server_id, } 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, * instead of being buffered in the TCP/IP stack. @@ -1120,28 +1090,17 @@ int ReplSemiSyncMaster::readSlaveReply(NET *net, uint32 server_id, 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 " - "gettimeofday fail to get start time"); + "fail to get wait time."); rpl_semi_sync_master_timefunc_fails++; } else { - int 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; - } + rpl_semi_sync_master_net_wait_num++; + rpl_semi_sync_master_net_wait_time += wait_time; } } @@ -1230,24 +1189,23 @@ void ReplSemiSyncMaster::setExportStats() * * Return: * >= 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; - struct timeval end_tv; - int end_time_err; - + struct timespec end_ts; + /* 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. */ - end_time_err = gettimeofday(&end_tv, 0); + set_timespec(end_ts, 0); /* 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 (int)(end_usecs - start_usecs); |