summaryrefslogtreecommitdiff
path: root/plugin/semisync
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/semisync')
-rw-r--r--plugin/semisync/CMakeLists.txt9
-rw-r--r--plugin/semisync/semisync.h5
-rw-r--r--plugin/semisync/semisync_master.cc22
-rw-r--r--plugin/semisync/semisync_master.h18
-rw-r--r--plugin/semisync/semisync_master_plugin.cc98
-rw-r--r--plugin/semisync/semisync_slave_plugin.cc11
6 files changed, 119 insertions, 44 deletions
diff --git a/plugin/semisync/CMakeLists.txt b/plugin/semisync/CMakeLists.txt
index d2d3327fb2e..1def8fdc682 100644
--- a/plugin/semisync/CMakeLists.txt
+++ b/plugin/semisync/CMakeLists.txt
@@ -17,11 +17,12 @@ SET(SEMISYNC_MASTER_SOURCES
semisync.cc semisync_master.cc semisync_master_plugin.cc
semisync.h semisync_master.h)
-MYSQL_ADD_PLUGIN(semisync_master ${SEMISYNC_MASTER_SOURCES}
- MODULE_ONLY MODULE_OUTPUT_NAME "semisync_master")
+MYSQL_ADD_PLUGIN(semisync_master ${SEMISYNC_MASTER_SOURCES}
+ RECOMPILE_FOR_EMBEDDED)
SET(SEMISYNC_SLAVE_SOURCES semisync.cc semisync_slave.cc
semisync_slave_plugin.cc semisync.h semisync_slave.h )
-MYSQL_ADD_PLUGIN(semisync_slave ${SEMISYNC_SLAVE_SOURCES}
- MODULE_ONLY MODULE_OUTPUT_NAME "semisync_slave")
+
+MYSQL_ADD_PLUGIN(semisync_slave ${SEMISYNC_SLAVE_SOURCES}
+ RECOMPILE_FOR_EMBEDDED)
diff --git a/plugin/semisync/semisync.h b/plugin/semisync/semisync.h
index 70ab8ce9cc3..abd0bb0787c 100644
--- a/plugin/semisync/semisync.h
+++ b/plugin/semisync/semisync.h
@@ -21,11 +21,10 @@
#define MYSQL_SERVER
#define HAVE_REPLICATION
+#include <my_pthread.h>
#include <sql_priv.h>
+#include <sql_class.h>
#include "unireg.h"
-#include <my_global.h>
-#include <my_pthread.h>
-#include <mysql/plugin.h>
#include <replication.h>
#include "log.h" /* sql_print_information */
diff --git a/plugin/semisync/semisync_master.cc b/plugin/semisync/semisync_master.cc
index 5175385b884..cd80e86140d 100644
--- a/plugin/semisync/semisync_master.cc
+++ b/plugin/semisync/semisync_master.cc
@@ -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;
@@ -429,12 +431,13 @@ int ReplSemiSyncMaster::disableMaster()
return 0;
}
-ReplSemiSyncMaster::~ReplSemiSyncMaster()
+void ReplSemiSyncMaster::cleanup()
{
if (init_done_)
{
mysql_mutex_destroy(&LOCK_binlog_);
mysql_cond_destroy(&COND_binlog_send_);
+ init_done_= 0;
}
delete active_tranxs_;
@@ -608,7 +611,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
struct timespec start_ts;
struct timespec abstime;
int wait_result;
- const char *old_msg= 0;
+ PSI_stage_info old_stage;
set_timespec(start_ts, 0);
@@ -617,8 +620,9 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
lock();
/* This must be called after acquired the lock */
- old_msg= thd_enter_cond(NULL, &COND_binlog_send_, &LOCK_binlog_,
- "Waiting for semi-sync ACK from slave");
+ THD_ENTER_COND(NULL, &COND_binlog_send_, &LOCK_binlog_,
+ & stage_waiting_for_semi_sync_ack_from_slave,
+ & old_stage);
/* This is the real check inside the mutex. */
if (!getMasterEnabled() || !is_on())
@@ -631,7 +635,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
(int)is_on());
}
- while (is_on() && !thd_killed(NULL))
+ while (is_on() && !thd_killed(current_thd))
{
if (reply_file_name_inited_)
{
@@ -742,9 +746,10 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
/*
At this point, the binlog file and position of this transaction
must have been removed from ActiveTranx.
+ active_tranxs_ may be NULL if someone disabled semi sync during
+ cond_timewait()
*/
- assert(thd_killed(NULL) ||
- !getMasterEnabled() ||
+ assert(thd_killed(current_thd) || !active_tranxs_ ||
!active_tranxs_->is_tranx_end_pos(trx_wait_binlog_name,
trx_wait_binlog_pos));
@@ -757,7 +762,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
/* The lock held will be released by thd_exit_cond, so no need to
call unlock() here */
- thd_exit_cond(NULL, old_msg);
+ THD_EXIT_COND(NULL, & old_stage);
}
return function_exit(kWho, 0);
@@ -1045,7 +1050,6 @@ int ReplSemiSyncMaster::readSlaveReply(NET *net, uint32 server_id,
int result = -1;
struct timespec start_ts;
ulong trc_level = trace_level_;
-
LINT_INIT_STRUCT(start_ts);
function_enter(kWho);
diff --git a/plugin/semisync/semisync_master.h b/plugin/semisync/semisync_master.h
index cd1c0507039..23d3140bf2f 100644
--- a/plugin/semisync/semisync_master.h
+++ b/plugin/semisync/semisync_master.h
@@ -26,6 +26,8 @@ extern PSI_mutex_key key_ss_mutex_LOCK_binlog_;
extern PSI_cond_key key_ss_cond_COND_binlog_send_;
#endif
+extern PSI_stage_info stage_waiting_for_semi_sync_ack_from_slave;
+
struct TranxNode {
char log_name_[FN_REFLEN];
my_off_t log_pos_;
@@ -100,7 +102,7 @@ public:
it are in use. A new Block is allocated and is put into the rear of the
Block link table if no Block is free.
- @return Return a TranxNode *, or NULL if an error occured.
+ @return Return a TranxNode *, or NULL if an error occurred.
*/
TranxNode *allocate_node()
{
@@ -132,7 +134,7 @@ public:
/**
All nodes are freed.
- @return Return 0, or 1 if an error occured.
+ @return Return 0, or 1 if an error occurred.
*/
int free_all_nodes()
{
@@ -148,7 +150,7 @@ public:
@param node All nodes before 'node' will be freed
- @return Return 0, or 1 if an error occured.
+ @return Return 0, or 1 if an error occurred.
*/
int free_nodes_before(TranxNode* node)
{
@@ -453,7 +455,9 @@ class ReplSemiSyncMaster
public:
ReplSemiSyncMaster();
- ~ReplSemiSyncMaster();
+ ~ReplSemiSyncMaster() {}
+
+ void cleanup();
bool getMasterEnabled() {
return master_enabled_;
@@ -590,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;
diff --git a/plugin/semisync/semisync_master_plugin.cc b/plugin/semisync/semisync_master_plugin.cc
index 4a085233939..4432b829c87 100644
--- a/plugin/semisync/semisync_master_plugin.cc
+++ b/plugin/semisync/semisync_master_plugin.cc
@@ -19,7 +19,7 @@
#include "semisync_master.h"
#include "sql_class.h" // THD
-ReplSemiSyncMaster repl_semisync;
+static ReplSemiSyncMaster repl_semisync;
C_MODE_START
@@ -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 = {
@@ -297,10 +345,10 @@ DEF_SHOW_FUNC(avg_trx_wait_time, SHOW_LONG)
static SHOW_VAR semi_sync_master_status_vars[]= {
{"Rpl_semi_sync_master_status",
(char*) &SHOW_FNAME(status),
- SHOW_FUNC},
+ SHOW_SIMPLE_FUNC},
{"Rpl_semi_sync_master_clients",
(char*) &SHOW_FNAME(clients),
- SHOW_FUNC},
+ SHOW_SIMPLE_FUNC},
{"Rpl_semi_sync_master_yes_tx",
(char*) &rpl_semi_sync_master_yes_transactions,
SHOW_LONG},
@@ -309,7 +357,7 @@ static SHOW_VAR semi_sync_master_status_vars[]= {
SHOW_LONG},
{"Rpl_semi_sync_master_wait_sessions",
(char*) &SHOW_FNAME(wait_sessions),
- SHOW_FUNC},
+ SHOW_SIMPLE_FUNC},
{"Rpl_semi_sync_master_no_times",
(char*) &rpl_semi_sync_master_off_times,
SHOW_LONG},
@@ -321,22 +369,22 @@ static SHOW_VAR semi_sync_master_status_vars[]= {
SHOW_LONG},
{"Rpl_semi_sync_master_tx_wait_time",
(char*) &SHOW_FNAME(trx_wait_time),
- SHOW_FUNC},
+ SHOW_SIMPLE_FUNC},
{"Rpl_semi_sync_master_tx_waits",
(char*) &SHOW_FNAME(trx_wait_num),
- SHOW_FUNC},
+ SHOW_SIMPLE_FUNC},
{"Rpl_semi_sync_master_tx_avg_wait_time",
(char*) &SHOW_FNAME(avg_trx_wait_time),
- SHOW_FUNC},
+ SHOW_SIMPLE_FUNC},
{"Rpl_semi_sync_master_net_wait_time",
(char*) &SHOW_FNAME(net_wait_time),
- SHOW_FUNC},
+ SHOW_SIMPLE_FUNC},
{"Rpl_semi_sync_master_net_waits",
(char*) &SHOW_FNAME(net_wait_num),
- SHOW_FUNC},
+ SHOW_SIMPLE_FUNC},
{"Rpl_semi_sync_master_net_avg_wait_time",
(char*) &SHOW_FNAME(avg_net_wait_time),
- SHOW_FUNC},
+ SHOW_SIMPLE_FUNC},
{NULL, NULL, SHOW_LONG},
};
@@ -354,20 +402,30 @@ static PSI_cond_info all_semisync_conds[]=
{
{ &key_ss_cond_COND_binlog_send_, "COND_binlog_send_", 0}
};
+#endif /* HAVE_PSI_INTERFACE */
+
+PSI_stage_info stage_waiting_for_semi_sync_ack_from_slave=
+{ 0, "Waiting for semi-sync ACK from slave", 0};
+
+#ifdef HAVE_PSI_INTERFACE
+PSI_stage_info *all_semisync_stages[]=
+{
+ & stage_waiting_for_semi_sync_ack_from_slave
+};
static void init_semisync_psi_keys(void)
{
const char* category= "semisync";
int count;
- if (PSI_server == NULL)
- return;
-
count= array_elements(all_semisync_mutexes);
- PSI_server->register_mutex(category, all_semisync_mutexes, count);
+ mysql_mutex_register(category, all_semisync_mutexes, count);
count= array_elements(all_semisync_conds);
- PSI_server->register_cond(category, all_semisync_conds, count);
+ mysql_cond_register(category, all_semisync_conds, count);
+
+ count= array_elements(all_semisync_stages);
+ mysql_stage_register(category, all_semisync_stages, count);
}
#endif /* HAVE_PSI_INTERFACE */
@@ -405,6 +463,7 @@ static int semi_sync_master_plugin_deinit(void *p)
sql_print_error("unregister_binlog_transmit_observer failed");
return 1;
}
+ repl_semisync.cleanup();
sql_print_information("unregister_replicator OK");
return 0;
}
@@ -416,7 +475,7 @@ struct Mysql_replication semi_sync_master_plugin= {
/*
Plugin library descriptor
*/
-mysql_declare_plugin(semi_sync_master)
+maria_declare_plugin(semisync_master)
{
MYSQL_REPLICATION_PLUGIN,
&semi_sync_master_plugin,
@@ -429,7 +488,8 @@ mysql_declare_plugin(semi_sync_master)
0x0100 /* 1.0 */,
semi_sync_master_status_vars, /* status variables */
semi_sync_master_system_vars, /* system variables */
- NULL, /* config options */
- 0, /* flags */
+ "1.0",
+ MariaDB_PLUGIN_MATURITY_STABLE
}
-mysql_declare_plugin_end;
+maria_declare_plugin_end;
+
diff --git a/plugin/semisync/semisync_slave_plugin.cc b/plugin/semisync/semisync_slave_plugin.cc
index 1d62bbdf7fc..b7a4c964c80 100644
--- a/plugin/semisync/semisync_slave_plugin.cc
+++ b/plugin/semisync/semisync_slave_plugin.cc
@@ -19,7 +19,7 @@
#include "semisync_slave.h"
#include <mysql.h>
-ReplSemiSyncSlave repl_semisync;
+static ReplSemiSyncSlave repl_semisync;
/*
indicate whether or not the slave should send a reply to the master.
@@ -213,7 +213,7 @@ struct Mysql_replication semi_sync_slave_plugin= {
/*
Plugin library descriptor
*/
-mysql_declare_plugin(semi_sync_slave)
+maria_declare_plugin(semisync_slave)
{
MYSQL_REPLICATION_PLUGIN,
&semi_sync_slave_plugin,
@@ -226,7 +226,8 @@ mysql_declare_plugin(semi_sync_slave)
0x0100 /* 1.0 */,
semi_sync_slave_status_vars, /* status variables */
semi_sync_slave_system_vars, /* system variables */
- NULL, /* config options */
- 0, /* flags */
+ "1.0",
+ MariaDB_PLUGIN_MATURITY_STABLE
}
-mysql_declare_plugin_end;
+maria_declare_plugin_end;
+