diff options
Diffstat (limited to 'plugin/semisync')
-rw-r--r-- | plugin/semisync/CMakeLists.txt | 9 | ||||
-rw-r--r-- | plugin/semisync/semisync.h | 5 | ||||
-rw-r--r-- | plugin/semisync/semisync_master.cc | 22 | ||||
-rw-r--r-- | plugin/semisync/semisync_master.h | 18 | ||||
-rw-r--r-- | plugin/semisync/semisync_master_plugin.cc | 98 | ||||
-rw-r--r-- | plugin/semisync/semisync_slave_plugin.cc | 11 |
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; + |