MXS-1703 Move more functions to MariaDBServer
Also, the QueryResult integer reading method now only reads non-negative integers since the server rarely returns negative values. This frees negative values for indicating parsing error(s). Gtid-class was moved back to utility.hh/.cc because the QueryResult-class requires it.
This commit is contained in:
@ -17,7 +17,6 @@
|
||||
#include "utilities.hh"
|
||||
|
||||
static int add_slave_to_master(long *slaves_list, int list_size, long node_id);
|
||||
static void read_server_variables(MariaDBServer* serv_info);
|
||||
|
||||
static bool report_version_err = true;
|
||||
|
||||
@ -655,11 +654,11 @@ void MariaDBMonitor::monitor_database(MariaDBServer* serv_info)
|
||||
serv_info->version = MYSQL_SERVER_VERSION_51;
|
||||
}
|
||||
/* Query a few settings. */
|
||||
read_server_variables(serv_info);
|
||||
serv_info->read_server_variables();
|
||||
/* If gtid domain exists and server is 10.0, update gtid:s */
|
||||
if (m_master_gtid_domain >= 0 && serv_info->version == MYSQL_SERVER_VERSION_100)
|
||||
{
|
||||
update_gtids(serv_info);
|
||||
serv_info->update_gtids(m_master_gtid_domain);
|
||||
}
|
||||
/* Check for MariaDB 10.x.x and get status for multi-master replication */
|
||||
if (serv_info->version == MYSQL_SERVER_VERSION_100 || serv_info->version == MYSQL_SERVER_VERSION_55)
|
||||
@ -682,45 +681,6 @@ void MariaDBMonitor::monitor_database(MariaDBServer* serv_info)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read server_id, read_only and (if 10.X) gtid_domain_id. TODO: Move to MariaDBServer
|
||||
*
|
||||
* @param serv_info Where to save results
|
||||
*/
|
||||
static void read_server_variables(MariaDBServer* serv_info)
|
||||
{
|
||||
MXS_MONITORED_SERVER* database = serv_info->server_base;
|
||||
string query = "SELECT @@global.server_id, @@read_only;";
|
||||
int columns = 2;
|
||||
if (serv_info->version == MYSQL_SERVER_VERSION_100)
|
||||
{
|
||||
query.erase(query.end() - 1);
|
||||
query += ", @@global.gtid_domain_id;";
|
||||
columns = 3;
|
||||
}
|
||||
|
||||
int ind_id = 0;
|
||||
int ind_ro = 1;
|
||||
int ind_domain = 2;
|
||||
StringVector row;
|
||||
if (query_one_row(database, query.c_str(), columns, &row))
|
||||
{
|
||||
int64_t server_id = scan_server_id(row[ind_id].c_str());
|
||||
database->server->node_id = server_id;
|
||||
serv_info->server_id = server_id;
|
||||
|
||||
ss_dassert(row[ind_ro] == "0" || row[ind_ro] == "1");
|
||||
serv_info->read_only = (row[ind_ro] == "1");
|
||||
if (columns == 3)
|
||||
{
|
||||
uint32_t domain = 0;
|
||||
ss_debug(int rv = ) sscanf(row[ind_domain].c_str(), "%" PRIu32, &domain);
|
||||
ss_dassert(rv == 1);
|
||||
serv_info->gtid_domain_id = domain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Monitor a database with given server info.
|
||||
*
|
||||
@ -747,34 +707,6 @@ void MariaDBMonitor::monitor_mysql_db(MariaDBServer* serv_info)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Query gtid_current_pos and gtid_binlog_pos and save the values to the server info object.
|
||||
* Only the cluster master domain is parsed.
|
||||
*
|
||||
* @param info Server info structure for saving result TODO: move to MariaDBServer
|
||||
* @return True if successful
|
||||
*/
|
||||
bool MariaDBMonitor::update_gtids(MariaDBServer* info)
|
||||
{
|
||||
MXS_MONITORED_SERVER* database = info->server_base;
|
||||
StringVector row;
|
||||
const char query[] = "SELECT @@gtid_current_pos, @@gtid_binlog_pos;";
|
||||
const int ind_current_pos = 0;
|
||||
const int ind_binlog_pos = 1;
|
||||
int64_t domain = m_master_gtid_domain;
|
||||
ss_dassert(domain >= 0);
|
||||
bool rval = false;
|
||||
if (query_one_row(database, query, 2, &row))
|
||||
{
|
||||
info->gtid_current_pos = (row[ind_current_pos] != "") ?
|
||||
Gtid(row[ind_current_pos].c_str(), domain) : Gtid();
|
||||
info->gtid_binlog_pos = (row[ind_binlog_pos] != "") ?
|
||||
Gtid(row[ind_binlog_pos].c_str(), domain) : Gtid();
|
||||
rval = true;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update replication settings and gtid:s of the slave server.
|
||||
*
|
||||
@ -785,31 +717,11 @@ MariaDBServer* MariaDBMonitor::update_slave_info(MXS_MONITORED_SERVER* server)
|
||||
{
|
||||
MariaDBServer* info = get_server_info(server);
|
||||
if (info->slave_status.slave_sql_running &&
|
||||
update_replication_settings(server, info) &&
|
||||
update_gtids(info) &&
|
||||
info->update_replication_settings() &&
|
||||
info->update_gtids(m_master_gtid_domain) &&
|
||||
info->do_show_slave_status(m_master_gtid_domain))
|
||||
{
|
||||
return info;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query a few miscellaneous replication settings.
|
||||
*
|
||||
* @param database The slave server to query
|
||||
* @param info Where to save results
|
||||
* @return True on success
|
||||
*/
|
||||
bool MariaDBMonitor::update_replication_settings(MXS_MONITORED_SERVER *database, MariaDBServer* info)
|
||||
{
|
||||
StringVector row;
|
||||
bool ok = query_one_row(database, "SELECT @@gtid_strict_mode, @@log_bin, @@log_slave_updates;", 3, &row);
|
||||
if (ok)
|
||||
{
|
||||
info->rpl_settings.gtid_strict_mode = (row[0] == "1");
|
||||
info->rpl_settings.log_bin = (row[1] == "1");
|
||||
info->rpl_settings.log_slave_updates = (row[2] == "1");
|
||||
}
|
||||
return ok;
|
||||
}
|
@ -156,7 +156,7 @@ bool MariaDBMonitor::manual_rejoin(SERVER* rejoin_server, json_t** output)
|
||||
|
||||
if (server_is_rejoin_suspect(mon_server, master_info, output))
|
||||
{
|
||||
if (update_gtids(master_info))
|
||||
if (master_info->update_gtids(m_master_gtid_domain))
|
||||
{
|
||||
if (can_replicate_from(mon_server, server_info, master_info))
|
||||
{
|
||||
@ -433,7 +433,7 @@ bool MariaDBMonitor::get_joinable_servers(ServerVector* output)
|
||||
bool comm_ok = true;
|
||||
if (!suspects.empty())
|
||||
{
|
||||
if (update_gtids(master_info))
|
||||
if (master_info->update_gtids(m_master_gtid_domain))
|
||||
{
|
||||
for (size_t i = 0; i < suspects.size(); i++)
|
||||
{
|
||||
@ -814,7 +814,7 @@ bool MariaDBMonitor::failover_wait_relay_log(MXS_MONITORED_SERVER* new_master, i
|
||||
Gtid old_gtid_io_pos = master_info->slave_status.gtid_io_pos;
|
||||
// Update gtid:s first to make sure Gtid_IO_Pos is the more recent value.
|
||||
// It doesn't matter here, but is a general rule.
|
||||
query_ok = update_gtids(master_info) &&
|
||||
query_ok = master_info->update_gtids(m_master_gtid_domain) &&
|
||||
master_info->do_show_slave_status(m_master_gtid_domain);
|
||||
io_pos_stable = (old_gtid_io_pos == master_info->slave_status.gtid_io_pos);
|
||||
}
|
||||
@ -903,7 +903,7 @@ bool MariaDBMonitor::switchover_demote_master(MXS_MONITORED_SERVER* current_mast
|
||||
if (!query_error)
|
||||
{
|
||||
query = "";
|
||||
if (update_gtids(info))
|
||||
if (info->update_gtids(m_master_gtid_domain))
|
||||
{
|
||||
success = true;
|
||||
}
|
||||
@ -1071,7 +1071,7 @@ bool MariaDBMonitor::wait_cluster_stabilization(MXS_MONITORED_SERVER* new_master
|
||||
MariaDBServer* new_master_info = get_server_info(new_master);
|
||||
|
||||
if (mxs_mysql_query(new_master->con, "FLUSH TABLES;") == 0 &&
|
||||
update_gtids(new_master_info))
|
||||
new_master_info->update_gtids(m_master_gtid_domain))
|
||||
{
|
||||
int query_fails = 0;
|
||||
int repl_fails = 0;
|
||||
@ -1094,7 +1094,8 @@ bool MariaDBMonitor::wait_cluster_stabilization(MXS_MONITORED_SERVER* new_master
|
||||
{
|
||||
MXS_MONITORED_SERVER* slave = wait_list[i];
|
||||
MariaDBServer* slave_info = get_server_info(slave);
|
||||
if (update_gtids(slave_info) && slave_info->do_show_slave_status(m_master_gtid_domain))
|
||||
if (slave_info->update_gtids(m_master_gtid_domain) &&
|
||||
slave_info->do_show_slave_status(m_master_gtid_domain))
|
||||
{
|
||||
if (!slave_info->slave_status.last_error.empty())
|
||||
{
|
||||
@ -1157,7 +1158,7 @@ bool MariaDBMonitor::switchover_check_preferred_master(MXS_MONITORED_SERVER* pre
|
||||
ss_dassert(preferred);
|
||||
bool rval = true;
|
||||
MariaDBServer* preferred_info = update_slave_info(preferred);
|
||||
if (preferred_info == NULL || !check_replication_settings(preferred, preferred_info))
|
||||
if (preferred_info == NULL || !preferred_info->check_replication_settings())
|
||||
{
|
||||
PRINT_MXS_JSON_ERROR(err_out, "The requested server '%s' is not a valid promotion candidate.",
|
||||
preferred->server->unique_name);
|
||||
@ -1234,14 +1235,14 @@ MXS_MONITORED_SERVER* MariaDBMonitor::select_new_master(ServerVector* slaves_out
|
||||
{
|
||||
slaves_out->push_back(cand);
|
||||
// Check that server is not in the exclusion list while still being a valid choice.
|
||||
if (server_is_excluded(cand) && check_replication_settings(cand, cand_info, WARNINGS_OFF))
|
||||
if (server_is_excluded(cand) && cand_info->check_replication_settings(WARNINGS_OFF))
|
||||
{
|
||||
valid_but_excluded.push_back(cand);
|
||||
const char CANNOT_SELECT[] = "Promotion candidate '%s' is excluded from new "
|
||||
"master selection.";
|
||||
MXS_INFO(CANNOT_SELECT, cand->server->unique_name);
|
||||
}
|
||||
else if (check_replication_settings(cand, cand_info))
|
||||
else if (cand_info->check_replication_settings())
|
||||
{
|
||||
// If no new master yet, accept any valid candidate. Otherwise check.
|
||||
if (current_best == NULL || is_candidate_better(current_best_info, cand_info))
|
||||
@ -1482,49 +1483,6 @@ bool MariaDBMonitor::failover_check(json_t** error_out)
|
||||
return !error && slaves > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if server has binary log enabled. Print warnings if gtid_strict_mode or log_slave_updates is off.
|
||||
*
|
||||
* @param server Server to check
|
||||
* @param server_info Server info
|
||||
* @param print_on Print warnings or not
|
||||
* @return True if log_bin is on
|
||||
*/
|
||||
bool check_replication_settings(const MXS_MONITORED_SERVER* server, MariaDBServer* server_info,
|
||||
print_repl_warnings_t print_warnings)
|
||||
{
|
||||
bool rval = true;
|
||||
const char* servername = server->server->unique_name;
|
||||
if (server_info->rpl_settings.log_bin == false)
|
||||
{
|
||||
if (print_warnings == WARNINGS_ON)
|
||||
{
|
||||
const char NO_BINLOG[] =
|
||||
"Slave '%s' has binary log disabled and is not a valid promotion candidate.";
|
||||
MXS_WARNING(NO_BINLOG, servername);
|
||||
}
|
||||
rval = false;
|
||||
}
|
||||
else if (print_warnings == WARNINGS_ON)
|
||||
{
|
||||
if (server_info->rpl_settings.gtid_strict_mode == false)
|
||||
{
|
||||
const char NO_STRICT[] =
|
||||
"Slave '%s' has gtid_strict_mode disabled. Enabling this setting is recommended. "
|
||||
"For more information, see https://mariadb.com/kb/en/library/gtid/#gtid_strict_mode";
|
||||
MXS_WARNING(NO_STRICT, servername);
|
||||
}
|
||||
if (server_info->rpl_settings.log_slave_updates == false)
|
||||
{
|
||||
const char NO_SLAVE_UPDATES[] =
|
||||
"Slave '%s' has log_slave_updates disabled. It is a valid candidate but replication "
|
||||
"will break for lagging slaves if '%s' is promoted.";
|
||||
MXS_WARNING(NO_SLAVE_UPDATES, servername, servername);
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if slave can replicate from master. Only considers gtid:s and only detects obvious errors. The
|
||||
* non-detected errors will mostly be detected once the slave tries to start replicating.
|
||||
@ -1538,7 +1496,7 @@ bool MariaDBMonitor::can_replicate_from(MXS_MONITORED_SERVER* slave,
|
||||
MariaDBServer* slave_info, MariaDBServer* master_info)
|
||||
{
|
||||
bool rval = false;
|
||||
if (update_gtids(slave_info))
|
||||
if (slave_info->update_gtids(m_master_gtid_domain))
|
||||
{
|
||||
Gtid slave_gtid = slave_info->gtid_current_pos;
|
||||
Gtid master_gtid = master_info->gtid_binlog_pos;
|
||||
|
@ -37,12 +37,6 @@ typedef std::tr1::unordered_map<MXS_MONITORED_SERVER*, MariaDBServer*> ServerInf
|
||||
// Server container, owns the server objects.
|
||||
typedef std::vector<MariaDBServer> ServerContainer; // TODO: Rename/get rid of ServerVector typedef!
|
||||
|
||||
enum print_repl_warnings_t
|
||||
{
|
||||
WARNINGS_ON,
|
||||
WARNINGS_OFF
|
||||
};
|
||||
|
||||
enum slave_down_setting_t
|
||||
{
|
||||
ACCEPT_DOWN,
|
||||
@ -51,8 +45,6 @@ enum slave_down_setting_t
|
||||
|
||||
// TODO: Most of following should be class methods
|
||||
void print_redirect_errors(MXS_MONITORED_SERVER* first_server, const ServerVector& servers, json_t** err_out);
|
||||
bool check_replication_settings(const MXS_MONITORED_SERVER* server, MariaDBServer* server_info,
|
||||
print_repl_warnings_t print_warnings = WARNINGS_ON);
|
||||
MXS_MONITORED_SERVER* getServerByNodeId(MXS_MONITORED_SERVER *, long);
|
||||
MXS_MONITORED_SERVER* getSlaveOfNodeId(MXS_MONITORED_SERVER *, long, slave_down_setting_t);
|
||||
|
||||
@ -217,7 +209,6 @@ private:
|
||||
bool server_is_excluded(const MXS_MONITORED_SERVER* server);
|
||||
bool is_candidate_better(const MariaDBServer* current_best_info, const MariaDBServer* candidate_info);
|
||||
MariaDBServer* update_slave_info(MXS_MONITORED_SERVER* server);
|
||||
bool update_replication_settings(MXS_MONITORED_SERVER *database, MariaDBServer* info);
|
||||
void init_server_info();
|
||||
bool slave_receiving_events();
|
||||
void monitor_database(MariaDBServer* param_db);
|
||||
@ -247,7 +238,6 @@ private:
|
||||
json_t** output);
|
||||
bool cluster_can_be_joined();
|
||||
bool failover_check(json_t** error_out);
|
||||
bool update_gtids(MariaDBServer* info);
|
||||
void disable_setting(const char* setting);
|
||||
bool switchover_check_new(const MXS_MONITORED_SERVER* monitored_server, json_t** error);
|
||||
bool switchover_check_current(const MXS_MONITORED_SERVER* suggested_curr_master,
|
||||
|
@ -18,68 +18,6 @@
|
||||
#include <maxscale/mysql_utils.h>
|
||||
#include "utilities.hh"
|
||||
|
||||
Gtid::Gtid()
|
||||
: domain(0)
|
||||
, server_id(SERVER_ID_UNKNOWN)
|
||||
, sequence(0)
|
||||
{}
|
||||
|
||||
Gtid::Gtid(const char* str, int64_t search_domain)
|
||||
: domain(0)
|
||||
, server_id(SERVER_ID_UNKNOWN)
|
||||
, sequence(0)
|
||||
{
|
||||
// Autoselect only allowed with one triplet
|
||||
ss_dassert(search_domain >= 0 || strchr(str, ',') == NULL);
|
||||
parse_triplet(str);
|
||||
if (search_domain >= 0 && domain != search_domain)
|
||||
{
|
||||
// Search for the correct triplet.
|
||||
bool found = false;
|
||||
for (const char* next_triplet = strchr(str, ',');
|
||||
next_triplet != NULL && !found;
|
||||
next_triplet = strchr(next_triplet, ','))
|
||||
{
|
||||
parse_triplet(++next_triplet);
|
||||
if (domain == search_domain)
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
ss_dassert(found);
|
||||
}
|
||||
}
|
||||
|
||||
bool Gtid::operator == (const Gtid& rhs) const
|
||||
{
|
||||
return domain == rhs.domain &&
|
||||
server_id != SERVER_ID_UNKNOWN && server_id == rhs.server_id &&
|
||||
sequence == rhs.sequence;
|
||||
}
|
||||
|
||||
string Gtid::to_string() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
if (server_id != SERVER_ID_UNKNOWN)
|
||||
{
|
||||
ss << domain << "-" << server_id << "-" << sequence;
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void Gtid::parse_triplet(const char* str)
|
||||
{
|
||||
ss_debug(int rv = ) sscanf(str, "%" PRIu32 "-%" PRId64 "-%" PRIu64, &domain, &server_id, &sequence);
|
||||
ss_dassert(rv == 3);
|
||||
}
|
||||
|
||||
string Gtid::generate_master_gtid_wait_cmd(double timeout) const
|
||||
{
|
||||
std::stringstream query_ss;
|
||||
query_ss << "SELECT MASTER_GTID_WAIT(\"" << to_string() << "\", " << timeout << ");";
|
||||
return query_ss.str();
|
||||
}
|
||||
|
||||
SlaveStatusInfo::SlaveStatusInfo()
|
||||
: master_server_id(SERVER_ID_UNKNOWN)
|
||||
, master_port(0)
|
||||
@ -214,7 +152,7 @@ bool MariaDBServer::do_show_slave_status(int64_t gtid_domain)
|
||||
{
|
||||
/** Only check binlog name for the first running slave */
|
||||
string master_log_file = result->get_string(i_master_log_file);
|
||||
uint64_t read_master_log_pos = result->get_int(i_read_master_log_pos);
|
||||
uint64_t read_master_log_pos = result->get_uint(i_read_master_log_pos);
|
||||
if (slave_status.master_log_file != master_log_file ||
|
||||
slave_status.read_master_log_pos != read_master_log_pos)
|
||||
{
|
||||
@ -233,7 +171,7 @@ bool MariaDBServer::do_show_slave_status(int64_t gtid_domain)
|
||||
* root master server.
|
||||
* Please note, there could be no slaves at all if Slave_SQL_Running == 'No'
|
||||
*/
|
||||
int64_t last_io_errno = result->get_int(i_last_io_errno);
|
||||
int64_t last_io_errno = result->get_uint(i_last_io_errno);
|
||||
int io_errno = last_io_errno;
|
||||
const int connection_errno = 2003;
|
||||
|
||||
@ -247,18 +185,18 @@ bool MariaDBServer::do_show_slave_status(int64_t gtid_domain)
|
||||
if (server_version == MYSQL_SERVER_VERSION_100)
|
||||
{
|
||||
slave_status.master_host = result->get_string(i_master_host);
|
||||
slave_status.master_port = result->get_int(i_master_port);
|
||||
slave_status.master_port = result->get_uint(i_master_port);
|
||||
|
||||
string last_io_error = result->get_string(i_last_io_error);
|
||||
string last_sql_error = result->get_string(i_last_sql_error);
|
||||
slave_status.last_error = !last_io_error.empty() ? last_io_error : last_sql_error;
|
||||
|
||||
int heartbeats = result->get_int(i_slave_rec_hbs);
|
||||
int heartbeats = result->get_uint(i_slave_rec_hbs);
|
||||
if (slave_heartbeats < heartbeats)
|
||||
{
|
||||
latest_event = time(NULL);
|
||||
slave_heartbeats = heartbeats;
|
||||
heartbeat_period = result->get_int(i_slave_hb_period);
|
||||
heartbeat_period = result->get_uint(i_slave_hb_period);
|
||||
}
|
||||
string using_gtid = result->get_string(i_using_gtid);
|
||||
if (gtid_domain >= 0 && (using_gtid == "Current_Pos" || using_gtid == "Slave_Pos"))
|
||||
@ -291,3 +229,103 @@ bool MariaDBServer::do_show_slave_status(int64_t gtid_domain)
|
||||
n_slaves_running = nrunning;
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool MariaDBServer::update_gtids(int64_t gtid_domain)
|
||||
{
|
||||
ss_dassert(gtid_domain >= 0);
|
||||
static const string query = "SELECT @@gtid_current_pos, @@gtid_binlog_pos;";
|
||||
const int ind_current_pos = 0;
|
||||
const int ind_binlog_pos = 1;
|
||||
|
||||
bool rval = false;
|
||||
auto result = execute_query(query);
|
||||
if (result.get() != NULL && result->next_row())
|
||||
{
|
||||
gtid_current_pos = result->get_gtid(ind_current_pos, gtid_domain);
|
||||
gtid_binlog_pos = result->get_gtid(ind_binlog_pos, gtid_domain);
|
||||
rval = true;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool MariaDBServer::update_replication_settings()
|
||||
{
|
||||
static const string query = "SELECT @@gtid_strict_mode, @@log_bin, @@log_slave_updates;";
|
||||
bool rval = false;
|
||||
auto result = execute_query(query);
|
||||
if (result.get() != NULL && result->next_row())
|
||||
{
|
||||
rpl_settings.gtid_strict_mode = result->get_bool(0);
|
||||
rpl_settings.log_bin = result->get_bool(1);
|
||||
rpl_settings.log_slave_updates = result->get_bool(2);
|
||||
rval = true;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
void MariaDBServer::read_server_variables()
|
||||
{
|
||||
MXS_MONITORED_SERVER* database = server_base;
|
||||
string query = "SELECT @@global.server_id, @@read_only;";
|
||||
int columns = 2;
|
||||
if (version == MYSQL_SERVER_VERSION_100)
|
||||
{
|
||||
query.erase(query.end() - 1);
|
||||
query += ", @@global.gtid_domain_id;";
|
||||
columns = 3;
|
||||
}
|
||||
|
||||
int ind_id = 0;
|
||||
int ind_ro = 1;
|
||||
int ind_domain = 2;
|
||||
auto result = execute_query(query);
|
||||
if (result.get() != NULL && result->next_row())
|
||||
{
|
||||
int64_t server_id_parsed = result->get_uint(ind_id);
|
||||
if (server_id_parsed < 0)
|
||||
{
|
||||
server_id_parsed = SERVER_ID_UNKNOWN;
|
||||
}
|
||||
database->server->node_id = server_id_parsed;
|
||||
server_id = server_id_parsed;
|
||||
read_only = result->get_bool(ind_ro);
|
||||
if (columns == 3)
|
||||
{
|
||||
gtid_domain_id = result->get_uint(ind_domain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MariaDBServer::check_replication_settings(print_repl_warnings_t print_warnings)
|
||||
{
|
||||
bool rval = true;
|
||||
const char* servername = server_base->server->unique_name;
|
||||
if (rpl_settings.log_bin == false)
|
||||
{
|
||||
if (print_warnings == WARNINGS_ON)
|
||||
{
|
||||
const char NO_BINLOG[] =
|
||||
"Slave '%s' has binary log disabled and is not a valid promotion candidate.";
|
||||
MXS_WARNING(NO_BINLOG, servername);
|
||||
}
|
||||
rval = false;
|
||||
}
|
||||
else if (print_warnings == WARNINGS_ON)
|
||||
{
|
||||
if (rpl_settings.gtid_strict_mode == false)
|
||||
{
|
||||
const char NO_STRICT[] =
|
||||
"Slave '%s' has gtid_strict_mode disabled. Enabling this setting is recommended. "
|
||||
"For more information, see https://mariadb.com/kb/en/library/gtid/#gtid_strict_mode";
|
||||
MXS_WARNING(NO_STRICT, servername);
|
||||
}
|
||||
if (rpl_settings.log_slave_updates == false)
|
||||
{
|
||||
const char NO_SLAVE_UPDATES[] =
|
||||
"Slave '%s' has log_slave_updates disabled. It is a valid candidate but replication "
|
||||
"will break for lagging slaves if '%s' is promoted.";
|
||||
MXS_WARNING(NO_SLAVE_UPDATES, servername, servername);
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
}
|
@ -27,38 +27,10 @@ enum mysql_server_version
|
||||
MYSQL_SERVER_VERSION_51
|
||||
};
|
||||
|
||||
class Gtid
|
||||
enum print_repl_warnings_t
|
||||
{
|
||||
public:
|
||||
uint32_t domain;
|
||||
int64_t server_id; // Is actually 32bit unsigned. 0 is only used by server versions <= 10.1
|
||||
uint64_t sequence;
|
||||
Gtid();
|
||||
|
||||
/**
|
||||
* Parse a Gtid-triplet from a string. In case of a multi-triplet value, only the triplet with
|
||||
* the given domain is returned.
|
||||
*
|
||||
* @param str Gtid string
|
||||
* @param search_domain The Gtid domain whose triplet should be returned. Negative domain stands for
|
||||
* autoselect, which is only allowed when the string contains one triplet.
|
||||
*/
|
||||
Gtid(const char* str, int64_t search_domain = -1);
|
||||
|
||||
bool operator == (const Gtid& rhs) const;
|
||||
|
||||
std::string to_string() const;
|
||||
|
||||
/**
|
||||
* Generate a MASTER_GTID_WAIT()-query to this gtid.
|
||||
*
|
||||
* @param timeout Maximum wait time in seconds
|
||||
* @return The query
|
||||
*/
|
||||
std::string generate_master_gtid_wait_cmd(double timeout) const;
|
||||
|
||||
private:
|
||||
void parse_triplet(const char* str);
|
||||
WARNINGS_ON,
|
||||
WARNINGS_OFF
|
||||
};
|
||||
|
||||
// Contains data returned by one row of SHOW ALL SLAVES STATUS
|
||||
@ -155,4 +127,33 @@ public:
|
||||
* @return True on success
|
||||
*/
|
||||
bool do_show_slave_status(int64_t gtid_domain);
|
||||
|
||||
/**
|
||||
* Query gtid_current_pos and gtid_binlog_pos and save the values to the server.
|
||||
* Only the given domain is parsed.
|
||||
*
|
||||
* @param gtid_domain Which gtid domain should be parsed
|
||||
* @return True if successful
|
||||
*/
|
||||
bool update_gtids(int64_t gtid_domain);
|
||||
|
||||
/**
|
||||
* Query a few miscellaneous replication settings.
|
||||
*
|
||||
* @return True on success
|
||||
*/
|
||||
bool update_replication_settings();
|
||||
|
||||
/**
|
||||
* Query and save server_id, read_only and (if 10.X) gtid_domain_id.
|
||||
*/
|
||||
void read_server_variables();
|
||||
|
||||
/**
|
||||
* Check if server has binary log enabled. Print warnings if gtid_strict_mode or log_slave_updates is off.
|
||||
*
|
||||
* @param print_on Print warnings or not
|
||||
* @return True if log_bin is on
|
||||
*/
|
||||
bool check_replication_settings(print_repl_warnings_t print_warnings = WARNINGS_ON);
|
||||
};
|
||||
|
@ -177,12 +177,21 @@ string QueryResult::get_string(int64_t column_ind) const
|
||||
return data ? data : "";
|
||||
}
|
||||
|
||||
int64_t QueryResult::get_int(int64_t column_ind) const
|
||||
int64_t QueryResult::get_uint(int64_t column_ind) const
|
||||
{
|
||||
ss_dassert(column_ind < m_columns);
|
||||
char* data = m_rowdata[column_ind];
|
||||
errno = 0; // strtoll sets this
|
||||
return data ? strtoll(data, NULL, 10) : 0;
|
||||
int64_t rval = -1;
|
||||
if (data)
|
||||
{
|
||||
errno = 0; // strtoll sets this
|
||||
auto parsed = strtoll(data, NULL, 10);
|
||||
if (parsed >= 0 && errno == 0)
|
||||
{
|
||||
rval = parsed;
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool QueryResult::get_bool(int64_t column_ind) const
|
||||
@ -191,3 +200,77 @@ bool QueryResult::get_bool(int64_t column_ind) const
|
||||
char* data = m_rowdata[column_ind];
|
||||
return data ? (strcmp(data,"Y") == 0 || strcmp(data, "1") == 0) : false;
|
||||
}
|
||||
|
||||
Gtid QueryResult::get_gtid(int64_t column_ind, int64_t gtid_domain) const
|
||||
{
|
||||
ss_dassert(column_ind < m_columns);
|
||||
char* data = m_rowdata[column_ind];
|
||||
Gtid rval;
|
||||
if (data && *data)
|
||||
{
|
||||
rval = Gtid(data, gtid_domain);
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
Gtid::Gtid()
|
||||
: domain(0)
|
||||
, server_id(SERVER_ID_UNKNOWN)
|
||||
, sequence(0)
|
||||
{}
|
||||
|
||||
Gtid::Gtid(const char* str, int64_t search_domain)
|
||||
: domain(0)
|
||||
, server_id(SERVER_ID_UNKNOWN)
|
||||
, sequence(0)
|
||||
{
|
||||
// Autoselect only allowed with one triplet
|
||||
ss_dassert(search_domain >= 0 || strchr(str, ',') == NULL);
|
||||
parse_triplet(str);
|
||||
if (search_domain >= 0 && domain != search_domain)
|
||||
{
|
||||
// Search for the correct triplet.
|
||||
bool found = false;
|
||||
for (const char* next_triplet = strchr(str, ',');
|
||||
next_triplet != NULL && !found;
|
||||
next_triplet = strchr(next_triplet, ','))
|
||||
{
|
||||
parse_triplet(++next_triplet);
|
||||
if (domain == search_domain)
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
ss_dassert(found);
|
||||
}
|
||||
}
|
||||
|
||||
bool Gtid::operator == (const Gtid& rhs) const
|
||||
{
|
||||
return domain == rhs.domain &&
|
||||
server_id != SERVER_ID_UNKNOWN && server_id == rhs.server_id &&
|
||||
sequence == rhs.sequence;
|
||||
}
|
||||
|
||||
string Gtid::to_string() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
if (server_id != SERVER_ID_UNKNOWN)
|
||||
{
|
||||
ss << domain << "-" << server_id << "-" << sequence;
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void Gtid::parse_triplet(const char* str)
|
||||
{
|
||||
ss_debug(int rv = ) sscanf(str, "%" PRIu32 "-%" PRId64 "-%" PRIu64, &domain, &server_id, &sequence);
|
||||
ss_dassert(rv == 3);
|
||||
}
|
||||
|
||||
string Gtid::generate_master_gtid_wait_cmd(double timeout) const
|
||||
{
|
||||
std::stringstream query_ss;
|
||||
query_ss << "SELECT MASTER_GTID_WAIT(\"" << to_string() << "\", " << timeout << ");";
|
||||
return query_ss.str();
|
||||
}
|
@ -72,6 +72,40 @@ string get_connection_errors(const ServerVector& servers);
|
||||
*/
|
||||
string monitored_servers_to_string(const ServerVector& array);
|
||||
|
||||
class Gtid
|
||||
{
|
||||
public:
|
||||
uint32_t domain;
|
||||
int64_t server_id; // Is actually 32bit unsigned. 0 is only used by server versions <= 10.1
|
||||
uint64_t sequence;
|
||||
Gtid();
|
||||
|
||||
/**
|
||||
* Parse a Gtid-triplet from a string. In case of a multi-triplet value, only the triplet with
|
||||
* the given domain is returned.
|
||||
*
|
||||
* @param str Gtid string
|
||||
* @param search_domain The Gtid domain whose triplet should be returned. Negative domain stands for
|
||||
* autoselect, which is only allowed when the string contains one triplet.
|
||||
*/
|
||||
Gtid(const char* str, int64_t search_domain = -1);
|
||||
|
||||
bool operator == (const Gtid& rhs) const;
|
||||
|
||||
std::string to_string() const;
|
||||
|
||||
/**
|
||||
* Generate a MASTER_GTID_WAIT()-query to this gtid.
|
||||
*
|
||||
* @param timeout Maximum wait time in seconds
|
||||
* @return The query
|
||||
*/
|
||||
std::string generate_master_gtid_wait_cmd(double timeout) const;
|
||||
|
||||
private:
|
||||
void parse_triplet(const char* str);
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper class for simplifying working with resultsets. Used in MariaDBServer.
|
||||
*/
|
||||
@ -124,13 +158,12 @@ public:
|
||||
string get_string(int64_t column_ind) const;
|
||||
|
||||
/**
|
||||
* Read an integer value from the current row and given column. No error checking is done on the parsing.
|
||||
* The parsing is performed by @c strtoll(), so the caller may check errno for errors.
|
||||
* Read a non-negative integer value from the current row and given column.
|
||||
*
|
||||
* @param column_ind Column index
|
||||
* @return Value as integer
|
||||
* @return Value as integer. 0 or greater indicates success, -1 is returned on error.
|
||||
*/
|
||||
int64_t get_int(int64_t column_ind) const;
|
||||
int64_t get_uint(int64_t column_ind) const;
|
||||
|
||||
/**
|
||||
* Read a boolean value from the current row and given column.
|
||||
@ -140,6 +173,16 @@ public:
|
||||
*/
|
||||
bool get_bool(int64_t column_ind) const;
|
||||
|
||||
/**
|
||||
* Read a gtid values from the current row and given column. If the field is empty, will return an invalid
|
||||
* gtid.
|
||||
*
|
||||
* @param column_ind Column index
|
||||
* @param gtid_domain Which gtid domain to parse
|
||||
* @return Value as a gtid.
|
||||
*/
|
||||
Gtid get_gtid(int64_t column_ind, int64_t gtid_domain) const;
|
||||
|
||||
private:
|
||||
MYSQL_RES* m_resultset; // Underlying result set, freed at dtor.
|
||||
std::tr1::unordered_map<string, int64_t> m_col_indexes; // Map of column name -> index
|
||||
|
Reference in New Issue
Block a user