MDEV-162 Enhanced semisync replication

Implement --semi-sync-master-wait-point=AFTER_SYNC|AFTER_COMMIT.

When AFTER_SYNC, the semi-sync wait will be done earlier, before the storage
engine commit rather than after. This means that a transaction will not be
visible on the master until at least one slave has received it.
This commit is contained in:
Jonas Oreland 2014-12-23 13:38:00 +01:00 committed by Kristian Nielsen
commit 0b87de124d
29 changed files with 1735 additions and 46 deletions

View file

@ -24,6 +24,8 @@
/* This indicates whether semi-synchronous replication is enabled. */
char rpl_semi_sync_master_enabled;
unsigned long rpl_semi_sync_master_wait_point =
SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT;
unsigned long rpl_semi_sync_master_timeout;
unsigned long rpl_semi_sync_master_trace_level;
char rpl_semi_sync_master_status = 0;

View file

@ -594,9 +594,15 @@ class ReplSemiSyncMaster
int resetMaster();
};
enum rpl_semi_sync_master_wait_point_t {
SEMI_SYNC_MASTER_WAIT_POINT_AFTER_BINLOG_SYNC,
SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT,
};
/* System and status variables for the master component */
extern char rpl_semi_sync_master_enabled;
extern char rpl_semi_sync_master_status;
extern unsigned long rpl_semi_sync_master_wait_point;
extern unsigned long rpl_semi_sync_master_clients;
extern unsigned long rpl_semi_sync_master_timeout;
extern unsigned long rpl_semi_sync_master_trace_level;

View file

@ -48,8 +48,27 @@ int repl_semi_request_commit(Trans_param *param)
return 0;
}
int repl_semi_report_binlog_sync(Binlog_storage_param *param,
const char *log_file,
my_off_t log_pos, uint32 flags)
{
int error= 0;
if (rpl_semi_sync_master_wait_point ==
SEMI_SYNC_MASTER_WAIT_POINT_AFTER_BINLOG_SYNC)
{
error = repl_semisync.commitTrx(log_file, log_pos);
}
return error;
}
int repl_semi_report_commit(Trans_param *param)
{
if (rpl_semi_sync_master_wait_point !=
SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT)
{
return 0;
}
bool is_real_trans= param->flags & TRANS_IS_REAL_TRANS;
@ -175,6 +194,33 @@ static MYSQL_SYSVAR_BOOL(enabled, rpl_semi_sync_master_enabled,
&fix_rpl_semi_sync_master_enabled, // update
0);
/* NOTE: must match order of rpl_semi_sync_master_wait_point_t */
static const char *rpl_semi_sync_master_wait_point_names[] =
{
"AFTER_SYNC",
"AFTER_COMMIT",
NullS
};
static TYPELIB rpl_semi_sync_master_wait_point_typelib =
{
array_elements(rpl_semi_sync_master_wait_point_names) - 1,
"",
rpl_semi_sync_master_wait_point_names,
NULL
};
static MYSQL_SYSVAR_ENUM(
wait_point,
rpl_semi_sync_master_wait_point,
PLUGIN_VAR_RQCMDARG,
"Should transaction wait for semi-sync ack after having synced binlog, "
"or after having committed in storeage engine.",
NULL, // check
NULL, // update
SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT,
&rpl_semi_sync_master_wait_point_typelib);
static MYSQL_SYSVAR_ULONG(timeout, rpl_semi_sync_master_timeout,
PLUGIN_VAR_OPCMDARG,
"The timeout value (in ms) for semi-synchronous replication in the master",
@ -198,6 +244,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(wait_point),
MYSQL_SYSVAR(timeout),
MYSQL_SYSVAR(wait_no_slave),
MYSQL_SYSVAR(trace_level),
@ -256,6 +303,7 @@ Binlog_storage_observer storage_observer = {
sizeof(Binlog_storage_observer), // len
repl_semi_report_binlog_update, // report_update
repl_semi_report_binlog_sync, // after_sync
};
Binlog_transmit_observer transmit_observer = {