diff --git a/server/core/monitor.cc b/server/core/monitor.cc index 06baec1a1..081a4594f 100644 --- a/server/core/monitor.cc +++ b/server/core/monitor.cc @@ -1162,6 +1162,7 @@ Monitor::ping_or_connect_to_db(const MonitorServer::ConnectionSettings& sett, SE mysql_optionsv(pConn, MYSQL_OPT_READ_TIMEOUT, &sett.read_timeout); mysql_optionsv(pConn, MYSQL_OPT_WRITE_TIMEOUT, &sett.write_timeout); mysql_optionsv(pConn, MYSQL_PLUGIN_DIR, get_connector_plugindir()); + mysql_optionsv(pConn, MARIADB_OPT_MULTI_STATEMENTS, nullptr); time_t start = time(NULL); if (mxs_mysql_real_connect(pConn, &server, uname.c_str(), dpwd)) diff --git a/server/modules/monitor/mariadbmon/mariadbserver.cc b/server/modules/monitor/mariadbmon/mariadbserver.cc index e98ef93e5..4abb10b58 100644 --- a/server/modules/monitor/mariadbmon/mariadbserver.cc +++ b/server/modules/monitor/mariadbmon/mariadbserver.cc @@ -104,18 +104,30 @@ bool MariaDBServer::execute_cmd_ex(const string& cmd, QueryRetryMode mode, bool rval = false; if (query_success) { - MYSQL_RES* result = mysql_store_result(conn); - if (result == NULL) + // In case query was a multiquery, loop for more resultsets. Error message is produced from first + // non-empty resultset and does not specify the subquery. + string results_errmsg; + do + { + MYSQL_RES* result = mysql_store_result(conn); + if (result) + { + int cols = mysql_num_fields(result); + int rows = mysql_num_rows(result); + if (results_errmsg.empty()) + { + results_errmsg = string_printf("Query '%s' on '%s' returned %d columns and %d rows " + "of data when none was expected.", + cmd.c_str(), name(), cols, rows); + } + } + } + while (mysql_next_result(conn) == 0); + + if (results_errmsg.empty()) { rval = true; } - else if (errmsg_out) - { - int cols = mysql_num_fields(result); - int rows = mysql_num_rows(result); - *errmsg_out = string_printf("Query '%s' on '%s' returned %d columns and %d rows of data when " - "none was expected.", cmd.c_str(), name(), cols, rows); - } } else { @@ -1285,6 +1297,12 @@ MariaDBServer::alter_events(BinlogMode binlog_mode, const EventStatusMapper& map { if (target_events > 0) { + // Reset character set and collation. + string charset_errmsg; + if (!execute_cmd("SET NAMES latin1 COLLATE latin1_swedish_ci;", &charset_errmsg)) + { + MXS_ERROR("Could not reset character set: %s", charset_errmsg.c_str()); + } warn_event_scheduler(); } if (target_events == events_altered) @@ -1350,7 +1368,10 @@ bool MariaDBServer::events_foreach(EventManipulator& func, json_t** error_out) auto event_name_ind = event_info->get_col_index("EVENT_NAME"); auto event_definer_ind = event_info->get_col_index("DEFINER"); auto event_status_ind = event_info->get_col_index("STATUS"); - mxb_assert(db_name_ind > 0 && event_name_ind > 0 && event_definer_ind > 0 && event_status_ind > 0); + auto charset_ind = event_info->get_col_index("CHARACTER_SET_CLIENT"); + auto collation_ind = event_info->get_col_index("COLLATION_CONNECTION"); + mxb_assert(db_name_ind > 0 && event_name_ind > 0 && event_definer_ind > 0 && event_status_ind > 0 + && charset_ind > 0 && collation_ind > 0); while (event_info->next_row()) { @@ -1358,6 +1379,8 @@ bool MariaDBServer::events_foreach(EventManipulator& func, json_t** error_out) event.name = event_info->get_string(db_name_ind) + "." + event_info->get_string(event_name_ind); event.definer = event_info->get_string(event_definer_ind); event.status = event_info->get_string(event_status_ind); + event.charset = event_info->get_string(charset_ind); + event.collation = event_info->get_string(collation_ind); func(event, error_out); } return true; @@ -1395,10 +1418,13 @@ bool MariaDBServer::alter_event(const EventInfo& event, const string& target_sta quoted_definer = event.definer; } - string alter_event_query = string_printf("ALTER DEFINER = %s EVENT %s %s;", - quoted_definer.c_str(), - event.name.c_str(), - target_status.c_str()); + // Change character set and collation to the values in the event description. Otherwise, the event + // values could be changed to whatever the monitor connection happens to be using. + string alter_event_query = string_printf( + "SET NAMES %s COLLATE %s; ALTER DEFINER = %s EVENT %s %s;", + event.charset.c_str(), event.collation.c_str(), quoted_definer.c_str(), event.name.c_str(), + target_status.c_str()); + if (execute_cmd(alter_event_query, &error_msg)) { rval = true; diff --git a/server/modules/monitor/mariadbmon/mariadbserver.hh b/server/modules/monitor/mariadbmon/mariadbserver.hh index 89de0eb03..eb7c18203 100644 --- a/server/modules/monitor/mariadbmon/mariadbserver.hh +++ b/server/modules/monitor/mariadbmon/mariadbserver.hh @@ -82,6 +82,8 @@ public: std::string name; /**< Event name in form */ std::string definer; /**< Definer of the event */ std::string status; /**< Status of the event */ + std::string charset; /**< character_set_client-field */ + std::string collation; /**< collation_connection-field */ }; enum class server_type