summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHe Zhenxing <zhenxing.he@sun.com>2009-10-12 21:15:32 +0800
committerHe Zhenxing <zhenxing.he@sun.com>2009-10-12 21:15:32 +0800
commit1a7c7a4066c99e24adfc7d4e11d84fe21dec1959 (patch)
treea2150617b4f510fe038d64c8408831fd2187a538
parent26b47d9347449ffba9dcc0a36aee91379f12e604 (diff)
downloadmariadb-git-1a7c7a4066c99e24adfc7d4e11d84fe21dec1959.tar.gz
Backport BUG#47298 Semisync: always wait until timeout if no semi-sync slave available
Add an option to control whether the master should keep waiting until timeout when it detected that there is no semi-sync slave available. The bool option 'rpl_semi_sync_master_wait_no_slave' is 1 by defalt, and will keep waiting until timeout. When set to 0, the master will switch to asynchronous replication immediately when no semi-sync slave is available.
-rw-r--r--mysql-test/suite/rpl/r/rpl_semi_sync.result14
-rw-r--r--mysql-test/suite/rpl/t/rpl_semi_sync.test7
-rw-r--r--plugin/semisync/semisync_master.cc23
-rw-r--r--plugin/semisync/semisync_master.h8
-rw-r--r--plugin/semisync/semisync_master_plugin.cc10
-rw-r--r--plugin/semisync/semisync_slave_plugin.cc7
6 files changed, 49 insertions, 20 deletions
diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync.result b/mysql-test/suite/rpl/r/rpl_semi_sync.result
index 6e57086a639..607b77fbd04 100644
--- a/mysql-test/suite/rpl/r/rpl_semi_sync.result
+++ b/mysql-test/suite/rpl/r/rpl_semi_sync.result
@@ -29,13 +29,13 @@ set global rpl_semi_sync_master_enabled = 1;
show variables like 'rpl_semi_sync_master_enabled';
Variable_name Value
rpl_semi_sync_master_enabled ON
-[ status of semi-sync on master should be OFF without any semi-sync slaves ]
+[ status of semi-sync on master should be ON even without any semi-sync slaves ]
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
Rpl_semi_sync_master_clients 0
show status like 'Rpl_semi_sync_master_status';
Variable_name Value
-Rpl_semi_sync_master_status OFF
+Rpl_semi_sync_master_status ON
show status like 'Rpl_semi_sync_master_yes_tx';
Variable_name Value
Rpl_semi_sync_master_yes_tx 0
@@ -210,7 +210,7 @@ include/stop_slave.inc
[ Semi-sync master status variables before FLUSH STATUS ]
SHOW STATUS LIKE 'Rpl_semi_sync_master_no_tx';
Variable_name Value
-Rpl_semi_sync_master_no_tx 3
+Rpl_semi_sync_master_no_tx 302
SHOW STATUS LIKE 'Rpl_semi_sync_master_yes_tx';
Variable_name Value
Rpl_semi_sync_master_yes_tx 302
@@ -355,7 +355,7 @@ Variable_name Value
Rpl_semi_sync_master_clients 0
show status like 'Rpl_semi_sync_master_status';
Variable_name Value
-Rpl_semi_sync_master_status OFF
+Rpl_semi_sync_master_status ON
set global rpl_semi_sync_master_enabled= 0;
[ on slave ]
SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled';
@@ -364,17 +364,17 @@ rpl_semi_sync_slave_enabled ON
include/start_slave.inc
[ on master ]
insert into t1 values (8);
-[ master semi-sync clients should be 0, status should be OFF ]
+[ master semi-sync clients should be 1, status should be OFF ]
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
-Rpl_semi_sync_master_clients 0
+Rpl_semi_sync_master_clients 1
show status like 'Rpl_semi_sync_master_status';
Variable_name Value
Rpl_semi_sync_master_status OFF
[ on slave ]
show status like 'Rpl_semi_sync_slave_status';
Variable_name Value
-Rpl_semi_sync_slave_status OFF
+Rpl_semi_sync_slave_status ON
include/stop_slave.inc
[ on master ]
set sql_log_bin=0;
diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync.test b/mysql-test/suite/rpl/t/rpl_semi_sync.test
index 52e6a309b12..8f1d4ccaa42 100644
--- a/mysql-test/suite/rpl/t/rpl_semi_sync.test
+++ b/mysql-test/suite/rpl/t/rpl_semi_sync.test
@@ -74,7 +74,7 @@ echo [ enable semi-sync on master ];
set global rpl_semi_sync_master_enabled = 1;
show variables like 'rpl_semi_sync_master_enabled';
-echo [ status of semi-sync on master should be OFF without any semi-sync slaves ];
+echo [ status of semi-sync on master should be ON even without any semi-sync slaves ];
show status like 'Rpl_semi_sync_master_clients';
show status like 'Rpl_semi_sync_master_status';
show status like 'Rpl_semi_sync_master_yes_tx';
@@ -497,7 +497,10 @@ source include/start_slave.inc;
connection master;
echo [ on master ];
insert into t1 values (8);
-echo [ master semi-sync clients should be 0, status should be OFF ];
+let $status_var= Rpl_semi_sync_master_clients;
+let $status_var_value= 1;
+source include/wait_for_status_var.inc;
+echo [ master semi-sync clients should be 1, status should be OFF ];
show status like 'Rpl_semi_sync_master_clients';
show status like 'Rpl_semi_sync_master_status';
sync_slave_with_master;
diff --git a/plugin/semisync/semisync_master.cc b/plugin/semisync/semisync_master.cc
index a51c1e5bc5c..1a7106621a4 100644
--- a/plugin/semisync/semisync_master.cc
+++ b/plugin/semisync/semisync_master.cc
@@ -40,6 +40,7 @@ unsigned long long rpl_semi_sync_master_net_wait_num = 0;
unsigned long rpl_semi_sync_master_clients = 0;
unsigned long long rpl_semi_sync_master_net_wait_time = 0;
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);
@@ -525,6 +526,14 @@ void ReplSemiSyncMaster::remove_slave()
{
lock();
rpl_semi_sync_master_clients--;
+
+ /* If user has chosen not to wait if no semi-sync slave available
+ and the last semi-sync slave exits, turn off semi-sync on master
+ immediately.
+ */
+ if (!rpl_semi_sync_master_wait_no_slave &&
+ rpl_semi_sync_master_clients == 0)
+ switch_off();
unlock();
}
@@ -812,7 +821,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
trx_wait_binlog_pos));
/* Update the status counter. */
- if (is_on() && rpl_semi_sync_master_clients)
+ if (is_on())
rpl_semi_sync_master_yes_transactions++;
else
rpl_semi_sync_master_no_transactions++;
@@ -1078,7 +1087,7 @@ int ReplSemiSyncMaster::writeTranxInBinlog(const char* log_file_name,
commit_file_name_inited_ = true;
}
- if (is_on() && rpl_semi_sync_master_clients)
+ if (is_on())
{
assert(active_tranxs_ != NULL);
if(active_tranxs_->insert_tranx_node(log_file_name, log_file_pos))
@@ -1153,7 +1162,7 @@ int ReplSemiSyncMaster::readSlaveReply(NET *net, uint32 server_id,
{
sql_print_error("Semi-sync master wait for reply "
"gettimeofday fail to get start time");
- timefunc_fails_++;
+ rpl_semi_sync_master_timefunc_fails++;
}
else
{
@@ -1164,12 +1173,12 @@ int ReplSemiSyncMaster::readSlaveReply(NET *net, uint32 server_id,
{
sql_print_error("Semi-sync master wait for reply "
"gettimeofday fail to get wait time.");
- timefunc_fails_++;
+ rpl_semi_sync_master_timefunc_fails++;
}
else
{
- total_net_wait_num_++;
- total_net_wait_time_ += wait_time;
+ rpl_semi_sync_master_net_wait_num++;
+ rpl_semi_sync_master_net_wait_time += wait_time;
}
}
}
@@ -1242,7 +1251,7 @@ void ReplSemiSyncMaster::setExportStats()
{
lock();
- rpl_semi_sync_master_status = state_ && rpl_semi_sync_master_clients;
+ rpl_semi_sync_master_status = state_;
rpl_semi_sync_master_avg_trx_wait_time=
((rpl_semi_sync_master_trx_wait_num) ?
(unsigned long)((double)rpl_semi_sync_master_trx_wait_time /
diff --git a/plugin/semisync/semisync_master.h b/plugin/semisync/semisync_master.h
index 28c0041ff72..d2b87745600 100644
--- a/plugin/semisync/semisync_master.h
+++ b/plugin/semisync/semisync_master.h
@@ -363,4 +363,12 @@ extern unsigned long long rpl_semi_sync_master_trx_wait_num;
extern unsigned long long rpl_semi_sync_master_net_wait_time;
extern unsigned long long rpl_semi_sync_master_trx_wait_time;
+/*
+ This indicates whether we should keep waiting if no semi-sync slave
+ is available.
+ 0 : stop waiting if detected no avaialable semi-sync slave.
+ 1 (default) : keep waiting until timeout even no available semi-sync slave.
+*/
+extern char rpl_semi_sync_master_wait_no_slave;
+
#endif /* SEMISYNC_MASTER_H */
diff --git a/plugin/semisync/semisync_master_plugin.cc b/plugin/semisync/semisync_master_plugin.cc
index 4b98ec5d835..d2ef500d932 100644
--- a/plugin/semisync/semisync_master_plugin.cc
+++ b/plugin/semisync/semisync_master_plugin.cc
@@ -76,7 +76,7 @@ int repl_semi_binlog_dump_start(Binlog_transmit_param *param,
/*
Let's assume this semi-sync slave has already received all
binlog events before the filename and position it requests.
- */
+ */
repl_semisync.reportReplyBinlog(param->server_id, log_file, log_pos);
}
sql_print_information("Start %s binlog_dump to slave (server_id: %d), pos(%s, %lu)",
@@ -176,6 +176,13 @@ static MYSQL_SYSVAR_ULONG(timeout, rpl_semi_sync_master_timeout,
fix_rpl_semi_sync_master_timeout, // update
10000, 0, ~0L, 1);
+static MYSQL_SYSVAR_BOOL(wait_no_slave, rpl_semi_sync_master_wait_no_slave,
+ PLUGIN_VAR_OPCMDARG,
+ "Wait until timeout when no semi-synchronous replication slave available (enabled by default). ",
+ NULL, // check
+ NULL, // update
+ 1);
+
static MYSQL_SYSVAR_ULONG(trace_level, rpl_semi_sync_master_trace_level,
PLUGIN_VAR_OPCMDARG,
"The tracing level for semi-sync replication.",
@@ -186,6 +193,7 @@ static MYSQL_SYSVAR_ULONG(trace_level, rpl_semi_sync_master_trace_level,
static SYS_VAR* semi_sync_master_system_vars[]= {
MYSQL_SYSVAR(enabled),
MYSQL_SYSVAR(timeout),
+ MYSQL_SYSVAR(wait_no_slave),
MYSQL_SYSVAR(trace_level),
NULL,
};
diff --git a/plugin/semisync/semisync_slave_plugin.cc b/plugin/semisync/semisync_slave_plugin.cc
index ef508596698..0bd9e1b8b21 100644
--- a/plugin/semisync/semisync_slave_plugin.cc
+++ b/plugin/semisync/semisync_slave_plugin.cc
@@ -56,10 +56,11 @@ int repl_semi_slave_request_dump(Binlog_relay_IO_param *param,
}
row= mysql_fetch_row(res);
- if (!row || strcmp(row[1], "ON"))
+ if (!row)
{
- /* Master does not support or not configured semi-sync */
- sql_print_warning("Master server does not support or not configured semi-sync replication, fallback to asynchronous");
+ /* Master does not support semi-sync */
+ sql_print_warning("Master server does not support semi-sync, "
+ "fallback to asynchronous replication");
rpl_semi_sync_slave_status= 0;
return 0;
}