mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
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.
This commit is contained in:
parent
26b47d9347
commit
1a7c7a4066
6 changed files with 49 additions and 20 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 /
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue