diff options
author | Kristian Nielsen <knielsen@knielsen-hq.org> | 2014-06-25 15:17:03 +0200 |
---|---|---|
committer | Kristian Nielsen <knielsen@knielsen-hq.org> | 2014-06-25 15:17:03 +0200 |
commit | 86362129a2f70349cc79adb0825d5bc8f9a61f27 (patch) | |
tree | 85d72a6ee651f847400b98e8f1016b74dc51460e | |
parent | 00467e136e5080e8c175019534ad198b7dcc35d3 (diff) | |
download | mariadb-git-86362129a2f70349cc79adb0825d5bc8f9a61f27.tar.gz |
MDEV-6120: When slave stops with error, error message should indicate the failing GTID
If replication breaks in GTID mode, it is not trivial to determine the GTID of
the failing event group. This is a problem, as such GTID is needed eg. to
explicitly set @@gtid_slave_pos to skip to after that event group, or to
compare errors on different servers, etc.
Fix by ensuring that relevant slave errors logged to the error log include the
GTID of the event group containing the problem event.
-rw-r--r-- | mysql-test/suite/rpl/r/rpl_gtid_errorlog.result | 46 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_gtid_errorlog.test | 80 | ||||
-rw-r--r-- | sql/log_event.cc | 61 | ||||
-rw-r--r-- | sql/log_event_old.cc | 6 | ||||
-rw-r--r-- | sql/rpl_parallel.cc | 14 | ||||
-rw-r--r-- | sql/rpl_parallel.h | 2 | ||||
-rw-r--r-- | sql/rpl_reporting.cc | 4 | ||||
-rw-r--r-- | sql/rpl_reporting.h | 5 | ||||
-rw-r--r-- | sql/rpl_rli.cc | 22 | ||||
-rw-r--r-- | sql/rpl_rli.h | 3 | ||||
-rw-r--r-- | sql/rpl_utility.cc | 13 | ||||
-rw-r--r-- | sql/rpl_utility.h | 6 | ||||
-rw-r--r-- | sql/slave.cc | 110 | ||||
-rw-r--r-- | sql/slave.h | 2 |
14 files changed, 268 insertions, 106 deletions
diff --git a/mysql-test/suite/rpl/r/rpl_gtid_errorlog.result b/mysql-test/suite/rpl/r/rpl_gtid_errorlog.result new file mode 100644 index 00000000000..e68f5d65b93 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_gtid_errorlog.result @@ -0,0 +1,46 @@ +include/master-slave.inc +[connection master] +*** Test MDEV-6120, output of current GTID when a replication error is logged to the errorlog *** +CREATE TABLE t1(a INT PRIMARY KEY); +include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; +INSERT INTO t1 VALUES (1); +SET gtid_seq_no=100; +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (3); +INSERT INTO t1 VALUES (4); +SET sql_log_bin=0; +INSERT INTO t1 VALUES (2); +SET sql_log_bin=1; +START SLAVE; +include/wait_for_slave_sql_error.inc [errno=1062] +include/stop_slave.inc +SET GLOBAL gtid_slave_pos= "0-1-100"; +include/start_slave.inc +SELECT * FROM t1 ORDER BY a; +a +1 +2 +3 +4 +SET @dbug_save= @@debug_dbug; +SET debug_dbug= '+d,incident_database_resync_on_replace'; +REPLACE INTO t1 VALUES (5); +SET debug_dbug= @dbug_save; +include/wait_for_slave_sql_error.inc [errno=1590] +include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=no; +SET sql_slave_skip_counter=1; +include/start_slave.inc +include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +SELECT * FROM t1 ORDER BY a; +a +1 +2 +3 +4 +5 +DROP TABLE t1; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_errorlog.test b/mysql-test/suite/rpl/t/rpl_gtid_errorlog.test new file mode 100644 index 00000000000..3622dff8273 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_errorlog.test @@ -0,0 +1,80 @@ +--source include/have_debug.inc +--source include/master-slave.inc + +--echo *** Test MDEV-6120, output of current GTID when a replication error is logged to the errorlog *** +--connection master +CREATE TABLE t1(a INT PRIMARY KEY); +--sync_slave_with_master + +--connection slave +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; + +--connection master +INSERT INTO t1 VALUES (1); +SET gtid_seq_no=100; +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (3); +INSERT INTO t1 VALUES (4); +--save_master_pos + +--connection slave +SET sql_log_bin=0; +INSERT INTO t1 VALUES (2); +SET sql_log_bin=1; + +START SLAVE; +--let $slave_sql_errno=1062 +--source include/wait_for_slave_sql_error.inc + +--source include/stop_slave.inc +# Skip the problem event from the master. +SET GLOBAL gtid_slave_pos= "0-1-100"; +--source include/start_slave.inc +--sync_with_master + +SELECT * FROM t1 ORDER BY a; + +--connection master + +SET @dbug_save= @@debug_dbug; +SET debug_dbug= '+d,incident_database_resync_on_replace'; +REPLACE INTO t1 VALUES (5); +SET debug_dbug= @dbug_save; +--save_master_pos + +--connection slave +--let $slave_sql_errno=1590 +--source include/wait_for_slave_sql_error.inc +# ToDo no need to switch off GTID once MDEV-4937 is fixed +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=no; +SET sql_slave_skip_counter=1; +--source include/start_slave.inc +--sync_with_master +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +SELECT * FROM t1 ORDER BY a; + + +# Check error log for correct messages. +let $log_error_= `SELECT @@GLOBAL.log_error`; +if(!$log_error_) +{ + # MySQL Server on windows is started with --console and thus + # does not know the location of its .err log, use default location + let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.2.err; +} +--let SEARCH_FILE=$log_error_ +--let SEARCH_PATTERN=Slave SQL: Error 'Duplicate entry .* on query\. .*Query: '.*', Gtid 0-1-100, Internal MariaDB error code:|Slave SQL: Could not execute Write_rows.*table test.t1; Duplicate entry.*, Gtid 0-1-100, Internal MariaDB error +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=Slave SQL: The incident LOST_EVENTS occured on the master\. Message: <none>, Internal MariaDB error code: 1590 +--source include/search_pattern_in_file.inc + + +--connection master +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/sql/log_event.cc b/sql/log_event.cc index 373bf2c3548..e9cd0ee3179 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -204,7 +204,7 @@ static const char *HA_ERR(int i) */ static void inline slave_rows_error_report(enum loglevel level, int ha_error, - Relay_log_info const *rli, THD *thd, + rpl_group_info *rgi, THD *thd, TABLE *table, const char * type, const char *log_name, ulong pos) { @@ -214,6 +214,7 @@ static void inline slave_rows_error_report(enum loglevel level, int ha_error, uint len; Diagnostics_area::Sql_condition_iterator it= thd->get_stmt_da()->sql_conditions(); + Relay_log_info const *rli= rgi->rli; const Sql_condition *err; buff[0]= 0; @@ -227,6 +228,7 @@ static void inline slave_rows_error_report(enum loglevel level, int ha_error, if (ha_error != 0) rli->report(level, thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0, + rgi->gtid_info(), "Could not execute %s event on table %s.%s;" "%s handler error %s; " "the event's master log %s, end_log_pos %lu", @@ -235,6 +237,7 @@ static void inline slave_rows_error_report(enum loglevel level, int ha_error, log_name, pos); else rli->report(level, thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0, + rgi->gtid_info(), "Could not execute %s event on table %s.%s;" "%s the event's master log %s, end_log_pos %lu", type, table->s->db.str, table->s->table_name.str, @@ -4086,7 +4089,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, char llbuff[22]; if ((error= rows_event_stmt_cleanup(rgi, thd))) { - const_cast<Relay_log_info*>(rli)->report(ERROR_LEVEL, error, + rli->report(ERROR_LEVEL, error, rgi->gtid_info(), "Error in cleaning up after an event preceding the commit; " "the group log file/position: %s %s", const_cast<Relay_log_info*>(rli)->group_master_log_name, @@ -4241,6 +4244,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, if (rpl_global_gtid_slave_state.record_gtid(thd, >id, sub_id, true, false)) { rli->report(ERROR_LEVEL, ER_CANNOT_UPDATE_GTID_STATE, + rgi->gtid_info(), "Error during COMMIT: failed to update GTID state in " "%s.%s: %d: %s", "mysql", rpl_gtid_slave_state_table_name.str, @@ -4313,7 +4317,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */ else { - rli->report(ERROR_LEVEL, expected_error, + rli->report(ERROR_LEVEL, expected_error, rgi->gtid_info(), "\ Query partially completed on the master (error on master: %d) \ and was aborted. There is a chance that your master is inconsistent at this \ @@ -4369,7 +4373,7 @@ compare_errors: !ignored_error_code(actual_error) && !ignored_error_code(expected_error)) { - rli->report(ERROR_LEVEL, 0, + rli->report(ERROR_LEVEL, 0, rgi->gtid_info(), "\ Query caused different errors on master and slave. \ Error on master: message (format)='%s' error code=%d ; \ @@ -4399,7 +4403,7 @@ Default database: '%s'. Query: '%s'", */ else if (thd->is_slave_error || thd->is_fatal_error) { - rli->report(ERROR_LEVEL, actual_error, + rli->report(ERROR_LEVEL, actual_error, rgi->gtid_info(), "Error '%s' on query. Default database: '%s'. Query: '%s'", (actual_error ? thd->get_stmt_da()->message() : "unexpected success or fatal error"), @@ -5055,7 +5059,7 @@ int Format_description_log_event::do_apply_event(rpl_group_info *rgi) if (!is_artificial_event() && created && thd->transaction.all.ha_list) { /* This is not an error (XA is safe), just an information */ - rli->report(INFORMATION_LEVEL, 0, + rli->report(INFORMATION_LEVEL, 0, NULL, "Rolling back unfinished transaction (no COMMIT " "or ROLLBACK in relay log). A probable cause is that " "the master died while writing the transaction to " @@ -5996,7 +6000,7 @@ error: sql_errno=ER_UNKNOWN_ERROR; err=ER(sql_errno); } - rli->report(ERROR_LEVEL, sql_errno,"\ + rli->report(ERROR_LEVEL, sql_errno, rgi->gtid_info(), "\ Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'", err, (char*)table_name, print_slave_db_safe(remember_db)); free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); @@ -6013,7 +6017,7 @@ Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'", (char*)table_name, print_slave_db_safe(remember_db)); - rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, rgi->gtid_info(), ER(ER_SLAVE_FATAL_ERROR), buf); DBUG_RETURN(1); } @@ -7302,7 +7306,7 @@ int Xid_log_event::do_apply_event(rpl_group_info *rgi) err= rpl_global_gtid_slave_state.record_gtid(thd, >id, sub_id, true, false); if (err) { - rli->report(ERROR_LEVEL, ER_CANNOT_UPDATE_GTID_STATE, + rli->report(ERROR_LEVEL, ER_CANNOT_UPDATE_GTID_STATE, rgi->gtid_info(), "Error during XID COMMIT: failed to update GTID state in " "%s.%s: %d: %s", "mysql", rpl_gtid_slave_state_table_name.str, @@ -8323,7 +8327,7 @@ int Create_file_log_event::do_apply_event(rpl_group_info *rgi) init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0, MYF(MY_WME|MY_NABP))) { - rli->report(ERROR_LEVEL, my_errno, + rli->report(ERROR_LEVEL, my_errno, rgi->gtid_info(), "Error in Create_file event: could not open file '%s'", fname_buf); goto err; @@ -8335,7 +8339,7 @@ int Create_file_log_event::do_apply_event(rpl_group_info *rgi) if (write_base(&file)) { strmov(ext, ".info"); // to have it right in the error message - rli->report(ERROR_LEVEL, my_errno, + rli->report(ERROR_LEVEL, my_errno, rgi->gtid_info(), "Error in Create_file event: could not write to file '%s'", fname_buf); goto err; @@ -8351,14 +8355,14 @@ int Create_file_log_event::do_apply_event(rpl_group_info *rgi) O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW, MYF(MY_WME))) < 0) { - rli->report(ERROR_LEVEL, my_errno, + rli->report(ERROR_LEVEL, my_errno, rgi->gtid_info(), "Error in Create_file event: could not open file '%s'", fname_buf); goto err; } if (mysql_file_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP))) { - rli->report(ERROR_LEVEL, my_errno, + rli->report(ERROR_LEVEL, my_errno, rgi->gtid_info(), "Error in Create_file event: write to '%s' failed", fname_buf); goto err; @@ -8507,7 +8511,7 @@ int Append_block_log_event::do_apply_event(rpl_group_info *rgi) O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW, MYF(MY_WME))) < 0) { - rli->report(ERROR_LEVEL, my_errno, + rli->report(ERROR_LEVEL, my_errno, rgi->gtid_info(), "Error in %s event: could not create file '%s'", get_type_str(), fname); goto err; @@ -8518,7 +8522,7 @@ int Append_block_log_event::do_apply_event(rpl_group_info *rgi) O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW, MYF(MY_WME))) < 0) { - rli->report(ERROR_LEVEL, my_errno, + rli->report(ERROR_LEVEL, my_errno, rgi->gtid_info(), "Error in %s event: could not open file '%s'", get_type_str(), fname); goto err; @@ -8531,7 +8535,7 @@ int Append_block_log_event::do_apply_event(rpl_group_info *rgi) if (mysql_file_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP))) { - rli->report(ERROR_LEVEL, my_errno, + rli->report(ERROR_LEVEL, my_errno, rgi->gtid_info(), "Error in %s event: write to '%s' failed", get_type_str(), fname); goto err; @@ -8748,7 +8752,7 @@ int Execute_load_log_event::do_apply_event(rpl_group_info *rgi) init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0, MYF(MY_WME|MY_NABP))) { - rli->report(ERROR_LEVEL, my_errno, + rli->report(ERROR_LEVEL, my_errno, rgi->gtid_info(), "Error in Exec_load event: could not open file '%s'", fname); goto err; @@ -8760,7 +8764,7 @@ int Execute_load_log_event::do_apply_event(rpl_group_info *rgi) opt_slave_sql_verify_checksum)) || lev->get_type_code() != NEW_LOAD_EVENT) { - rli->report(ERROR_LEVEL, 0, "Error in Exec_load event: " + rli->report(ERROR_LEVEL, 0, rgi->gtid_info(), "Error in Exec_load event: " "file '%s' appears corrupted", fname); goto err; } @@ -8786,7 +8790,7 @@ int Execute_load_log_event::do_apply_event(rpl_group_info *rgi) char *tmp= my_strdup(rli->last_error().message, MYF(MY_WME)); if (tmp) { - rli->report(ERROR_LEVEL, rli->last_error().number, + rli->report(ERROR_LEVEL, rli->last_error().number, rgi->gtid_info(), "%s. Failed executing load from '%s'", tmp, fname); my_free(tmp); } @@ -9019,7 +9023,7 @@ Execute_load_query_log_event::do_apply_event(rpl_group_info *rgi) /* Replace filename and LOCAL keyword in query before executing it */ if (buf == NULL) { - rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, rgi->gtid_info(), ER(ER_SLAVE_FATAL_ERROR), "Not enough memory"); return 1; } @@ -9635,7 +9639,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) We should not honour --slave-skip-errors at this point as we are having severe errors which should not be skiped. */ - rli->report(ERROR_LEVEL, actual_error, + rli->report(ERROR_LEVEL, actual_error, rgi->gtid_info(), "Error executing row event: '%s'", (actual_error ? thd->get_stmt_da()->message() : "unexpected success or fatal error")); @@ -9676,8 +9680,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) { DBUG_ASSERT(ptr->m_tabledef_valid); TABLE *conv_table; - if (!ptr->m_tabledef.compatible_with(thd, const_cast<Relay_log_info*>(rli), - ptr->table, &conv_table)) + if (!ptr->m_tabledef.compatible_with(thd, rgi, ptr->table, &conv_table)) { DBUG_PRINT("debug", ("Table: %s.%s is not compatible with master", ptr->table->s->db.str, @@ -9833,7 +9836,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) if (idempotent_error || ignored_error) { if (global_system_variables.log_warnings) - slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table, + slave_rows_error_report(WARNING_LEVEL, error, rgi, thd, table, get_type_str(), RPL_LOG_NAME, (ulong) log_pos); clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); @@ -9889,7 +9892,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) { if (global_system_variables.log_warnings) - slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table, + slave_rows_error_report(WARNING_LEVEL, error, rgi, thd, table, get_type_str(), RPL_LOG_NAME, (ulong) log_pos); clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); @@ -9900,7 +9903,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) if (error) { - slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table, + slave_rows_error_report(ERROR_LEVEL, error, rgi, thd, table, get_type_str(), RPL_LOG_NAME, (ulong) log_pos); /* @@ -9922,7 +9925,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) if (get_flags(STMT_END_F) && (error= rows_event_stmt_cleanup(rgi, thd))) slave_rows_error_report(ERROR_LEVEL, thd->is_error() ? 0 : error, - rli, thd, table, + rgi, thd, table, get_type_str(), RPL_LOG_NAME, (ulong) log_pos); DBUG_RETURN(error); @@ -10905,7 +10908,7 @@ int Table_map_log_event::do_apply_event(rpl_group_info *rgi) table_list->table_id); if (thd->slave_thread) - rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, rgi->gtid_info(), ER(ER_SLAVE_FATAL_ERROR), buf); else /* @@ -12546,7 +12549,7 @@ Incident_log_event::do_apply_event(rpl_group_info *rgi) DBUG_RETURN(0); } - rli->report(ERROR_LEVEL, ER_SLAVE_INCIDENT, + rli->report(ERROR_LEVEL, ER_SLAVE_INCIDENT, NULL, ER(ER_SLAVE_INCIDENT), description(), m_message.length > 0 ? m_message.str : "<none>"); diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 0cb78686243..7a48bea7712 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -133,8 +133,7 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, rpl_group_info *rgi) { DBUG_ASSERT(ptr->m_tabledef_valid); TABLE *conv_table; - if (!ptr->m_tabledef.compatible_with(thd, const_cast<Relay_log_info*>(rli), - ptr->table, &conv_table)) + if (!ptr->m_tabledef.compatible_with(thd, rgi, ptr->table, &conv_table)) { ev_thd->is_slave_error= 1; rgi->slave_close_thread_tables(ev_thd); @@ -1530,8 +1529,7 @@ int Old_rows_log_event::do_apply_event(rpl_group_info *rgi) ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global), i++) { TABLE *conv_table; - if (ptr->m_tabledef.compatible_with(thd, const_cast<Relay_log_info*>(rli), - ptr->table, &conv_table)) + if (ptr->m_tabledef.compatible_with(thd, rgi, ptr->table, &conv_table)) { thd->is_slave_error= 1; rgi->slave_close_thread_tables(thd); diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index e72d3470a7f..974a02e3968 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -388,7 +388,7 @@ handle_rpl_parallel_thread(void *arg) { DEBUG_SYNC(thd, "rpl_parallel_start_waiting_for_prior_killed"); thd->send_kill_message(); - slave_output_error_info(rgi->rli, thd); + slave_output_error_info(rgi, thd); signal_error_to_sql_driver_thread(thd, rgi, 1); /* Even though we were killed, we need to continue waiting for the @@ -467,7 +467,7 @@ handle_rpl_parallel_thread(void *arg) if (res < 0) { /* Error. */ - slave_output_error_info(rgi->rli, thd); + slave_output_error_info(rgi, thd); signal_error_to_sql_driver_thread(thd, rgi, 1); } else if (!res) @@ -514,7 +514,7 @@ handle_rpl_parallel_thread(void *arg) if (unlikely(err) && !rgi->worker_error) { - slave_output_error_info(rgi->rli, thd); + slave_output_error_info(rgi, thd); signal_error_to_sql_driver_thread(thd, rgi, err); } if (end_of_group) @@ -1018,10 +1018,11 @@ rpl_parallel_thread_pool::release_thread(rpl_parallel_thread *rpt) if it is still available. Otherwise a new worker thread is allocated. */ rpl_parallel_thread * -rpl_parallel_entry::choose_thread(Relay_log_info *rli, bool *did_enter_cond, +rpl_parallel_entry::choose_thread(rpl_group_info *rgi, bool *did_enter_cond, PSI_stage_info *old_stage, bool reuse) { uint32 idx; + Relay_log_info *rli= rgi->rli; rpl_parallel_thread *thr; idx= rpl_thread_idx; @@ -1066,7 +1067,7 @@ rpl_parallel_entry::choose_thread(Relay_log_info *rli, bool *did_enter_cond, debug_sync_set_action(rli->sql_driver_thd, STRING_WITH_LEN("now SIGNAL wait_queue_killed")); };); - slave_output_error_info(rli, rli->sql_driver_thd); + slave_output_error_info(rgi, rli->sql_driver_thd); return NULL; } else @@ -1417,7 +1418,8 @@ rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev, instead re-use a thread that we queued for previously. */ cur_thread= - e->choose_thread(rli, &did_enter_cond, &old_stage, typ != GTID_EVENT); + e->choose_thread(serial_rgi, &did_enter_cond, &old_stage, + typ != GTID_EVENT); if (!cur_thread) { /* This means we were killed. The error is already signalled. */ diff --git a/sql/rpl_parallel.h b/sql/rpl_parallel.h index c4bb407e5eb..1808efd0926 100644 --- a/sql/rpl_parallel.h +++ b/sql/rpl_parallel.h @@ -208,7 +208,7 @@ struct rpl_parallel_entry { /* The group_commit_orderer object for the events currently being queued. */ group_commit_orderer *current_gco; - rpl_parallel_thread * choose_thread(Relay_log_info *rli, bool *did_enter_cond, + rpl_parallel_thread * choose_thread(rpl_group_info *rgi, bool *did_enter_cond, PSI_stage_info *old_stage, bool reuse); group_commit_orderer *get_gco(); void free_gco(group_commit_orderer *gco); diff --git a/sql/rpl_reporting.cc b/sql/rpl_reporting.cc index 96fe6242ac3..eb362941f3e 100644 --- a/sql/rpl_reporting.cc +++ b/sql/rpl_reporting.cc @@ -28,6 +28,7 @@ Slave_reporting_capability::Slave_reporting_capability(char const *thread_name) void Slave_reporting_capability::report(loglevel level, int err_code, + const char *extra_info, const char *msg, ...) const { void (*report_function)(const char *, ...); @@ -67,9 +68,10 @@ Slave_reporting_capability::report(loglevel level, int err_code, va_end(args); /* If the msg string ends with '.', do not add a ',' it would be ugly */ - report_function("Slave %s: %s%s Internal MariaDB error code: %d", + report_function("Slave %s: %s%s %s%sInternal MariaDB error code: %d", m_thread_name, pbuff, (pbuff[0] && *(strend(pbuff)-1) == '.') ? "" : ",", + (extra_info ? extra_info : ""), (extra_info ? ", " : ""), err_code); } diff --git a/sql/rpl_reporting.h b/sql/rpl_reporting.h index 2b5e0527b9b..d90b7ad6650 100644 --- a/sql/rpl_reporting.h +++ b/sql/rpl_reporting.h @@ -52,8 +52,9 @@ public: code, but can contain more information), in printf() format. */ - void report(loglevel level, int err_code, const char *msg, ...) const - ATTRIBUTE_FORMAT(printf, 4, 5); + void report(loglevel level, int err_code, const char *extra_info, + const char *msg, ...) const + ATTRIBUTE_FORMAT(printf, 5, 6); /** Clear errors. They will not show up under <code>SHOW SLAVE diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 9de23e3cca6..cc543f7c377 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -1303,7 +1303,7 @@ void Relay_log_info::stmt_done(my_off_t event_master_log_pos, inc_group_relay_log_pos(event_master_log_pos, rgi); if (rpl_global_gtid_slave_state.record_and_update_gtid(thd, rgi)) { - report(WARNING_LEVEL, ER_CANNOT_UPDATE_GTID_STATE, + report(WARNING_LEVEL, ER_CANNOT_UPDATE_GTID_STATE, rgi->gtid_info(), "Failed to update GTID state in %s.%s, slave state may become " "inconsistent: %d: %s", "mysql", rpl_gtid_slave_state_table_name.str, @@ -1805,6 +1805,26 @@ rpl_group_info::mark_start_commit() } +/* + Format the current GTID as a string suitable for printing in error messages. + + The string is stored in a buffer inside rpl_group_info, so remains valid + until next call to gtid_info() or until destruction of rpl_group_info. + + If no GTID is available, then NULL is returned. +*/ +char * +rpl_group_info::gtid_info() +{ + if (!gtid_sub_id || !current_gtid.seq_no) + return NULL; + my_snprintf(gtid_info_buf, sizeof(gtid_info_buf), "Gtid %u-%u-%llu", + current_gtid.domain_id, current_gtid.server_id, + current_gtid.seq_no); + return gtid_info_buf; +} + + rpl_sql_thread_info::rpl_sql_thread_info(Rpl_filter *filter) : rpl_filter(filter) { diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index 63791a6389c..00d16f52488 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -593,6 +593,8 @@ struct rpl_group_info */ time_t row_stmt_start_timestamp; bool long_find_row_note_printed; + /* Needs room for "Gtid D-S-N\x00". */ + char gtid_info_buf[5+10+1+10+1+20+1]; rpl_group_info(Relay_log_info *rli_); ~rpl_group_info(); @@ -681,6 +683,7 @@ struct rpl_group_info void slave_close_thread_tables(THD *); void mark_start_commit_no_lock(); void mark_start_commit(); + char *gtid_info(); time_t get_row_stmt_start_timestamp() { diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc index 05227a29775..25dff72090c 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -826,7 +826,7 @@ can_convert_field_to(Field *field, @retval false Master table is not compatible with slave table. */ bool -table_def::compatible_with(THD *thd, Relay_log_info *rli, +table_def::compatible_with(THD *thd, rpl_group_info *rgi, TABLE *table, TABLE **conv_table_var) const { @@ -834,6 +834,7 @@ table_def::compatible_with(THD *thd, Relay_log_info *rli, We only check the initial columns for the tables. */ uint const cols_to_check= MY_MIN(table->s->fields, size()); + Relay_log_info *rli= rgi->rli; TABLE *tmp_table= NULL; for (uint col= 0 ; col < cols_to_check ; ++col) @@ -857,7 +858,7 @@ table_def::compatible_with(THD *thd, Relay_log_info *rli, This will create the full table with all fields. This is necessary to ge the correct field lengths for the record. */ - tmp_table= create_conversion_table(thd, rli, table); + tmp_table= create_conversion_table(thd, rgi, table); if (tmp_table == NULL) return false; /* @@ -885,7 +886,7 @@ table_def::compatible_with(THD *thd, Relay_log_info *rli, String target_type(target_buf, sizeof(target_buf), &my_charset_latin1); show_sql_type(type(col), field_metadata(col), &source_type, field->charset()); field->sql_type(target_type); - rli->report(ERROR_LEVEL, ER_SLAVE_CONVERSION_FAILED, + rli->report(ERROR_LEVEL, ER_SLAVE_CONVERSION_FAILED, rgi->gtid_info(), ER(ER_SLAVE_CONVERSION_FAILED), col, db_name, tbl_name, source_type.c_ptr_safe(), target_type.c_ptr_safe()); @@ -927,12 +928,14 @@ table_def::compatible_with(THD *thd, Relay_log_info *rli, conversion table. */ -TABLE *table_def::create_conversion_table(THD *thd, Relay_log_info *rli, TABLE *target_table) const +TABLE *table_def::create_conversion_table(THD *thd, rpl_group_info *rgi, + TABLE *target_table) const { DBUG_ENTER("table_def::create_conversion_table"); List<Create_field> field_list; TABLE *conv_table= NULL; + Relay_log_info *rli= rgi->rli; /* At slave, columns may differ. So we should create MY_MIN(columns@master, columns@slave) columns in the @@ -1014,7 +1017,7 @@ TABLE *table_def::create_conversion_table(THD *thd, Relay_log_info *rli, TABLE * err: if (conv_table == NULL) - rli->report(ERROR_LEVEL, ER_SLAVE_CANT_CREATE_CONVERSION, + rli->report(ERROR_LEVEL, ER_SLAVE_CANT_CREATE_CONVERSION, rgi->gtid_info(), ER(ER_SLAVE_CANT_CREATE_CONVERSION), target_table->s->db.str, target_table->s->table_name.str); diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h index 7568a2d786c..ed0ce16363b 100644 --- a/sql/rpl_utility.h +++ b/sql/rpl_utility.h @@ -30,6 +30,7 @@ class Relay_log_info; class Log_event; +struct rpl_group_info; /** A table definition from the master. @@ -187,7 +188,7 @@ public: @retval 0 if the table definition is compatible with @c table */ #ifndef MYSQL_CLIENT - bool compatible_with(THD *thd, Relay_log_info *rli, TABLE *table, + bool compatible_with(THD *thd, rpl_group_info *rgi, TABLE *table, TABLE **conv_table_var) const; /** @@ -212,7 +213,8 @@ public: @return A pointer to a temporary table with memory allocated in the thread's memroot, NULL if the table could not be created */ - TABLE *create_conversion_table(THD *thd, Relay_log_info *rli, TABLE *target_table) const; + TABLE *create_conversion_table(THD *thd, rpl_group_info *rgi, + TABLE *target_table) const; #endif diff --git a/sql/slave.cc b/sql/slave.cc index 2160cfc3534..f755cb63558 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1089,21 +1089,21 @@ static bool sql_slave_killed(rpl_group_info *rgi) if (ret == 0) { - rli->report(WARNING_LEVEL, 0, + rli->report(WARNING_LEVEL, 0, rgi->gtid_info(), "Request to stop slave SQL Thread received while " "applying a group that has non-transactional " "changes; waiting for completion of the group ... "); } else { - rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, rgi->gtid_info(), ER(ER_SLAVE_FATAL_ERROR), msg_stopped); } } else { ret= TRUE; - rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, rgi->gtid_info(), ER(ER_SLAVE_FATAL_ERROR), msg_stopped); } @@ -1521,7 +1521,7 @@ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi) goto slave_killed_err; else if (is_network_error(mysql_errno(mysql))) { - mi->report(WARNING_LEVEL, mysql_errno(mysql), + mi->report(WARNING_LEVEL, mysql_errno(mysql), NULL, "Get master clock failed with error: %s", mysql_error(mysql)); goto network_err; } @@ -1586,7 +1586,7 @@ not always make sense; please check the manual before using it)."; goto slave_killed_err; else if (is_network_error(mysql_errno(mysql))) { - mi->report(WARNING_LEVEL, mysql_errno(mysql), + mi->report(WARNING_LEVEL, mysql_errno(mysql), NULL, "Get master SERVER_ID failed with error: %s", mysql_error(mysql)); goto network_err; } @@ -1599,7 +1599,7 @@ when it try to get the value of SERVER_ID variable from master."; } else if (!master_row && master_res) { - mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE, + mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE, NULL, "Unknown system variable 'SERVER_ID' on master, \ maybe it is a *VERY OLD MASTER*."); } @@ -1659,7 +1659,7 @@ be equal for the Statement-format replication to work"; goto slave_killed_err; else if (is_network_error(mysql_errno(mysql))) { - mi->report(WARNING_LEVEL, mysql_errno(mysql), + mi->report(WARNING_LEVEL, mysql_errno(mysql), NULL, "Get master COLLATION_SERVER failed with error: %s", mysql_error(mysql)); goto network_err; } @@ -1673,7 +1673,7 @@ when it try to get the value of COLLATION_SERVER global variable from master."; goto err; } else - mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE, + mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE, NULL, "Unknown system variable 'COLLATION_SERVER' on master, \ maybe it is a *VERY OLD MASTER*. *NOTE*: slave may experience \ inconsistency if replicated data deals with collation."); @@ -1722,7 +1722,7 @@ be equal for the Statement-format replication to work"; goto slave_killed_err; else if (is_network_error(err_code= mysql_errno(mysql))) { - mi->report(ERROR_LEVEL, err_code, + mi->report(ERROR_LEVEL, err_code, NULL, "Get master TIME_ZONE failed with error: %s", mysql_error(mysql)); goto network_err; @@ -1730,7 +1730,7 @@ be equal for the Statement-format replication to work"; else if (err_code == ER_UNKNOWN_SYSTEM_VARIABLE) { /* We use ERROR_LEVEL to get the error logged to file */ - mi->report(ERROR_LEVEL, err_code, + mi->report(ERROR_LEVEL, err_code, NULL, "MySQL master doesn't have a TIME_ZONE variable. Note that" "if your timezone is not same between master and slave, your " @@ -1807,7 +1807,7 @@ when it try to get the value of TIME_ZONE global variable from master."; if (global_system_variables.log_warnings > 1) { // this is tolerable as OM -> NS is supported - mi->report(WARNING_LEVEL, mysql_errno(mysql), + mi->report(WARNING_LEVEL, mysql_errno(mysql), NULL, "Notifying master by %s failed with " "error: %s", query, mysql_error(mysql)); } @@ -1816,7 +1816,7 @@ when it try to get the value of TIME_ZONE global variable from master."; { if (is_network_error(mysql_errno(mysql))) { - mi->report(WARNING_LEVEL, mysql_errno(mysql), + mi->report(WARNING_LEVEL, mysql_errno(mysql), NULL, "Notifying master by %s failed with " "error: %s", query, mysql_error(mysql)); mysql_free_result(mysql_store_result(mysql)); @@ -1852,7 +1852,7 @@ when it try to get the value of TIME_ZONE global variable from master."; goto slave_killed_err; else if (is_network_error(mysql_errno(mysql))) { - mi->report(WARNING_LEVEL, mysql_errno(mysql), + mi->report(WARNING_LEVEL, mysql_errno(mysql), NULL, "Get master BINLOG_CHECKSUM failed with error: %s", mysql_error(mysql)); goto network_err; } @@ -1889,7 +1889,7 @@ past_checksum: err_code= mysql_errno(mysql); if (is_network_error(err_code)) { - mi->report(ERROR_LEVEL, err_code, + mi->report(ERROR_LEVEL, err_code, NULL, "Setting master-side filtering of @@skip_replication failed " "with error: %s", mysql_error(mysql)); goto network_err; @@ -1933,7 +1933,7 @@ past_checksum: err_code= mysql_errno(mysql); if (is_network_error(err_code)) { - mi->report(ERROR_LEVEL, err_code, + mi->report(ERROR_LEVEL, err_code, NULL, "Setting @mariadb_slave_capability failed with error: %s", mysql_error(mysql)); goto network_err; @@ -1999,7 +1999,7 @@ after_set_capability: err_code= mysql_errno(mysql); if (is_network_error(err_code)) { - mi->report(ERROR_LEVEL, err_code, + mi->report(ERROR_LEVEL, err_code, NULL, "Setting @slave_connect_state failed with error: %s", mysql_error(mysql)); goto network_err; @@ -2032,7 +2032,7 @@ after_set_capability: err_code= mysql_errno(mysql); if (is_network_error(err_code)) { - mi->report(ERROR_LEVEL, err_code, + mi->report(ERROR_LEVEL, err_code, NULL, "Setting @slave_gtid_strict_mode failed with error: %s", mysql_error(mysql)); goto network_err; @@ -2065,7 +2065,7 @@ after_set_capability: err_code= mysql_errno(mysql); if (is_network_error(err_code)) { - mi->report(ERROR_LEVEL, err_code, + mi->report(ERROR_LEVEL, err_code, NULL, "Setting @slave_gtid_ignore_duplicates failed with " "error: %s", mysql_error(mysql)); goto network_err; @@ -2101,7 +2101,7 @@ after_set_capability: err_code= mysql_errno(mysql); if (is_network_error(err_code)) { - mi->report(ERROR_LEVEL, err_code, + mi->report(ERROR_LEVEL, err_code, NULL, "Setting @slave_until_gtid failed with error: %s", mysql_error(mysql)); goto network_err; @@ -2149,7 +2149,7 @@ after_set_capability: goto slave_killed_err; else if (is_network_error(mysql_errno(mysql))) { - mi->report(WARNING_LEVEL, mysql_errno(mysql), + mi->report(WARNING_LEVEL, mysql_errno(mysql), NULL, "Get master GTID position failed with error: %s", mysql_error(mysql)); goto network_err; } @@ -2179,7 +2179,7 @@ err: if (master_res) mysql_free_result(master_res); DBUG_ASSERT(err_code != 0); - mi->report(ERROR_LEVEL, err_code, "%s", err_buff); + mi->report(ERROR_LEVEL, err_code, NULL, "%s", err_buff); DBUG_RETURN(1); } @@ -2301,7 +2301,7 @@ static void write_ignored_events_info_to_relay_log(THD *thd, Master_info *mi) Rotate_log_event::DUP_NAME); rli->ign_master_log_name_end[0]= 0; if (unlikely(!(bool)rev)) - mi->report(ERROR_LEVEL, ER_SLAVE_CREATE_EVENT_FAILURE, + mi->report(ERROR_LEVEL, ER_SLAVE_CREATE_EVENT_FAILURE, NULL, ER(ER_SLAVE_CREATE_EVENT_FAILURE), "Rotate_event (out of memory?)," " SHOW SLAVE STATUS may be inaccurate"); @@ -2312,7 +2312,7 @@ static void write_ignored_events_info_to_relay_log(THD *thd, Master_info *mi) Gtid_list_log_event::FLAG_IGN_GTIDS); rli->ign_gtids.reset(); if (unlikely(!(bool)glev)) - mi->report(ERROR_LEVEL, ER_SLAVE_CREATE_EVENT_FAILURE, + mi->report(ERROR_LEVEL, ER_SLAVE_CREATE_EVENT_FAILURE, NULL, ER(ER_SLAVE_CREATE_EVENT_FAILURE), "Gtid_list_event (out of memory?)," " gtid_slave_pos may be inaccurate"); @@ -2325,7 +2325,7 @@ static void write_ignored_events_info_to_relay_log(THD *thd, Master_info *mi) DBUG_PRINT("info",("writing a Rotate event to track down ignored events")); rev->server_id= 0; // don't be ignored by slave SQL thread if (unlikely(rli->relay_log.append(rev))) - mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, + mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, NULL, ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), "failed to write a Rotate event" " to the relay log, SHOW SLAVE STATUS may be" @@ -2338,7 +2338,7 @@ static void write_ignored_events_info_to_relay_log(THD *thd, Master_info *mi) glev->server_id= 0; // don't be ignored by slave SQL thread glev->set_artificial_event(); // Don't mess up Exec_Master_Log_Pos if (unlikely(rli->relay_log.append(glev))) - mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, + mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, NULL, ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), "failed to write a Gtid_list event to the relay log, " "gtid_slave_pos may be inaccurate"); @@ -2423,7 +2423,7 @@ int register_slave_on_master(MYSQL* mysql, Master_info *mi, char buf[256]; my_snprintf(buf, sizeof(buf), "%s (Errno: %d)", mysql_error(mysql), mysql_errno(mysql)); - mi->report(ERROR_LEVEL, ER_SLAVE_MASTER_COM_FAILURE, + mi->report(ERROR_LEVEL, ER_SLAVE_MASTER_COM_FAILURE, NULL, ER(ER_SLAVE_MASTER_COM_FAILURE), "COM_REGISTER_SLAVE", buf); } DBUG_RETURN(1); @@ -3294,7 +3294,7 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, if (error) { char buf[22]; - rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR, + rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR, rgi->gtid_info(), "It was not possible to update the positions" " of the relay log information: the slave may" " be in an inconsistent state." @@ -3636,7 +3636,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli, DBUG_RETURN(exec_res); } mysql_mutex_unlock(&rli->data_lock); - rli->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_READ_FAILURE, + rli->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_READ_FAILURE, NULL, ER(ER_SLAVE_RELAY_LOG_READ_FAILURE), "\ Could not parse relay log event entry. The possible reasons are: the master's \ binary log is corrupted (you can check this by running 'mysqlbinlog' on the \ @@ -3731,7 +3731,7 @@ static int try_to_reconnect(THD *thd, MYSQL *mysql, Master_info *mi, */ if (messages[SLAVE_RECON_MSG_COMMAND][0]) { - mi->report(WARNING_LEVEL, ER_SLAVE_MASTER_COM_FAILURE, + mi->report(WARNING_LEVEL, ER_SLAVE_MASTER_COM_FAILURE, NULL, ER(ER_SLAVE_MASTER_COM_FAILURE), messages[SLAVE_RECON_MSG_COMMAND], buf); } @@ -3821,7 +3821,7 @@ pthread_handler_t handle_slave_io(void *arg) /* Load the set of seen GTIDs, if we did not already. */ if (rpl_load_gtid_slave_state(thd)) { - mi->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(), + mi->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(), NULL, "Unable to load replication GTID slave state from mysql.%s: %s", rpl_gtid_slave_state_table_name.str, thd->get_stmt_da()->message()); @@ -3837,14 +3837,14 @@ pthread_handler_t handle_slave_io(void *arg) if (RUN_HOOK(binlog_relay_io, thread_start, (thd, mi))) { - mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL, ER(ER_SLAVE_FATAL_ERROR), "Failed to run 'thread_start' hook"); goto err; } if (!(mi->mysql = mysql = mysql_init(NULL))) { - mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL, ER(ER_SLAVE_FATAL_ERROR), "error in mysql_init()"); goto err; } @@ -4026,18 +4026,18 @@ Log entry on master is longer than slave_max_allowed_packet (%lu) on \ slave. If the entry is correct, restart the server with a higher value of \ slave_max_allowed_packet", slave_max_allowed_packet); - mi->report(ERROR_LEVEL, ER_NET_PACKET_TOO_LARGE, + mi->report(ERROR_LEVEL, ER_NET_PACKET_TOO_LARGE, NULL, "%s", "Got a packet bigger than 'slave_max_allowed_packet' bytes"); goto err; case ER_MASTER_FATAL_ERROR_READING_BINLOG: - mi->report(ERROR_LEVEL, ER_MASTER_FATAL_ERROR_READING_BINLOG, + mi->report(ERROR_LEVEL, ER_MASTER_FATAL_ERROR_READING_BINLOG, NULL, ER(ER_MASTER_FATAL_ERROR_READING_BINLOG), mysql_error_number, mysql_error(mysql)); goto err; case ER_OUT_OF_RESOURCES: sql_print_error("\ Stopping slave I/O thread due to out-of-memory error from master"); - mi->report(ERROR_LEVEL, ER_OUT_OF_RESOURCES, + mi->report(ERROR_LEVEL, ER_OUT_OF_RESOURCES, NULL, "%s", ER(ER_OUT_OF_RESOURCES)); goto err; } @@ -4054,7 +4054,7 @@ Stopping slave I/O thread due to out-of-memory error from master"); (thd, mi,(const char*)mysql->net.read_pos + 1, event_len, &event_buf, &event_len))) { - mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL, ER(ER_SLAVE_FATAL_ERROR), "Failed to run 'after_read_event' hook"); goto err; @@ -4065,7 +4065,7 @@ Stopping slave I/O thread due to out-of-memory error from master"); bool synced= 0; if (queue_event(mi, event_buf, event_len)) { - mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, + mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, NULL, ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), "could not queue event from master"); goto err; @@ -4074,7 +4074,7 @@ Stopping slave I/O thread due to out-of-memory error from master"); if (RUN_HOOK(binlog_relay_io, after_queue_event, (thd, mi, event_buf, event_len, synced))) { - mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL, ER(ER_SLAVE_FATAL_ERROR), "Failed to run 'after_queue_event' hook"); goto err; @@ -4262,13 +4262,14 @@ end: void -slave_output_error_info(Relay_log_info *rli, THD *thd) +slave_output_error_info(rpl_group_info *rgi, THD *thd) { /* retrieve as much info as possible from the thd and, error codes and warnings and print this to the error log as to allow the user to locate the error */ + Relay_log_info *rli= rgi->rli; uint32 const last_errno= rli->last_error().number; char llbuff[22]; @@ -4285,7 +4286,8 @@ slave_output_error_info(Relay_log_info *rli, THD *thd) This function is reporting an error which was not reported while executing exec_relay_log_event(). */ - rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(), "%s", errmsg); + rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(), + rgi->gtid_info(), "%s", errmsg); } else if (last_errno != thd->get_stmt_da()->sql_errno()) { @@ -4414,7 +4416,7 @@ pthread_handler_t handle_slave_sql(void *arg) will be stuck if we fail here */ mysql_cond_broadcast(&rli->start_cond); - rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL, "Failed during slave thread initialization"); goto err_during_init; } @@ -4472,7 +4474,7 @@ pthread_handler_t handle_slave_sql(void *arg) 1 /*need data lock*/, &errmsg, 1 /*look for a description_event*/)) { - rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL, "Error initializing relay log position: %s", errmsg); goto err; } @@ -4524,7 +4526,7 @@ log '%s' at position %s, relay log '%s' position: %s%s", RPL_LOG_NAME, if (check_temp_dir(rli->slave_patternload_file)) { - rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(), + rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(), NULL, "Unable to use slave's temporary directory %s - %s", slave_load_tmpdir, thd->get_stmt_da()->message()); goto err; @@ -4533,7 +4535,7 @@ log '%s' at position %s, relay log '%s' position: %s%s", RPL_LOG_NAME, /* Load the set of seen GTIDs, if we did not already. */ if (rpl_load_gtid_slave_state(thd)) { - rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(), + rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(), NULL, "Unable to load replication GTID slave state from mysql.%s: %s", rpl_gtid_slave_state_table_name.str, thd->get_stmt_da()->message()); @@ -4552,7 +4554,7 @@ log '%s' at position %s, relay log '%s' position: %s%s", RPL_LOG_NAME, execute_init_command(thd, &opt_init_slave, &LOCK_sys_init_slave); if (thd->is_slave_error) { - rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(), + rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(), NULL, "Slave SQL thread aborted. Can't execute init_slave query"); goto err; } @@ -4609,7 +4611,7 @@ log '%s' at position %s, relay log '%s' position: %s%s", RPL_LOG_NAME, DBUG_PRINT("info", ("exec_relay_log_event() failed")); // do not scare the user if SQL thread was simply killed or stopped if (!sql_slave_killed(serial_rgi)) - slave_output_error_info(rli, thd); + slave_output_error_info(serial_rgi, thd); goto err; } } @@ -4778,7 +4780,7 @@ static int process_io_create_file(Master_info* mi, Create_file_log_event* cev) xev.log_pos = cev->log_pos; if (unlikely(mi->rli.relay_log.append(&xev))) { - mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, + mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, NULL, ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), "error writing Exec_load event to relay log"); goto err; @@ -4792,7 +4794,7 @@ static int process_io_create_file(Master_info* mi, Create_file_log_event* cev) cev->block_len = num_bytes; if (unlikely(mi->rli.relay_log.append(cev))) { - mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, + mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, NULL, ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), "error writing Create_file event to relay log"); goto err; @@ -4807,7 +4809,7 @@ static int process_io_create_file(Master_info* mi, Create_file_log_event* cev) aev.log_pos = cev->log_pos; if (unlikely(mi->rli.relay_log.append(&aev))) { - mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, + mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, NULL, ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), "error writing Append_block event to relay log"); goto err; @@ -4914,7 +4916,7 @@ static int queue_binlog_ver_1_event(Master_info *mi, const char *buf, { if (unlikely(!(tmp_buf=(char*)my_malloc(event_len+1,MYF(MY_WME))))) { - mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL, ER(ER_SLAVE_FATAL_ERROR), "Memory allocation failed"); DBUG_RETURN(1); } @@ -5697,7 +5699,7 @@ err: mysql_mutex_unlock(&mi->data_lock); DBUG_PRINT("info", ("error: %d", error)); if (error) - mi->report(ERROR_LEVEL, error, ER(error), + mi->report(ERROR_LEVEL, error, NULL, ER(error), (error == ER_SLAVE_RELAY_LOG_WRITE_FAILURE)? "could not queue event from master" : error_msg.ptr()); @@ -5842,7 +5844,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi, /* we disallow empty users */ if (mi->user == NULL || mi->user[0] == 0) { - mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL, ER(ER_SLAVE_FATAL_ERROR), "Invalid (empty) username when attempting to " "connect to the master server. Connection attempt " @@ -5859,7 +5861,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi, { last_errno=mysql_errno(mysql); suppress_warnings= 0; - mi->report(ERROR_LEVEL, last_errno, + mi->report(ERROR_LEVEL, last_errno, NULL, "error %s to master '%s@%s:%d'" " - retry-time: %d retries: %lu message: %s", (reconnect ? "reconnecting" : "connecting"), @@ -6672,7 +6674,7 @@ bool rpl_master_has_bug(const Relay_log_info *rli, uint bug_id, bool report, " so slave stops; check error log on slave" " for more info", MYF(0), bug_id); // a verbose message for the error log - rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR, + rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR, NULL, "According to the master's version ('%s')," " it is probable that master suffers from this bug:" " http://bugs.mysql.com/bug.php?id=%u" diff --git a/sql/slave.h b/sql/slave.h index aa3976f6e6c..7352ac0274b 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -234,7 +234,7 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, rpl_parallel_thread *rpt); pthread_handler_t handle_slave_io(void *arg); -void slave_output_error_info(Relay_log_info *rli, THD *thd); +void slave_output_error_info(rpl_group_info *rgi, THD *thd); pthread_handler_t handle_slave_sql(void *arg); bool net_request_file(NET* net, const char* fname); |