diff options
author | unknown <mats@kindahl-laptop.dnsalias.net> | 2007-06-11 22:18:10 +0200 |
---|---|---|
committer | unknown <mats@kindahl-laptop.dnsalias.net> | 2007-06-11 22:18:10 +0200 |
commit | 24eb04abea7e656091afba9eda0aa13c3ea7ea8c (patch) | |
tree | 648b2b5f243c10d9392b6763baf941c5b42ccaa7 /sql | |
parent | 1f89a70d0a3245c93b323913a9728c602666be49 (diff) | |
parent | abbf5941d950e3a857987785991b72f1040d0721 (diff) | |
download | mariadb-git-24eb04abea7e656091afba9eda0aa13c3ea7ea8c.tar.gz |
Merge mkindahl@bk-internal.mysql.com:/home/bk/mysql-5.1-rpl
into kindahl-laptop.dnsalias.net:/home/bk/b24954-mysql-5.1-new-rpl
mysql-test/r/rpl_rotate_logs.result:
Auto merged
mysql-test/t/rpl_rotate_logs.test:
Auto merged
sql/Makefile.am:
Auto merged
sql/log_event.cc:
Auto merged
sql/sql_repl.cc:
Auto merged
Diffstat (limited to 'sql')
-rw-r--r-- | sql/Makefile.am | 2 | ||||
-rw-r--r-- | sql/log_event.cc | 221 | ||||
-rw-r--r-- | sql/rpl_mi.cc | 3 | ||||
-rw-r--r-- | sql/rpl_mi.h | 3 | ||||
-rw-r--r-- | sql/rpl_record.cc | 11 | ||||
-rw-r--r-- | sql/rpl_record_old.cc | 11 | ||||
-rw-r--r-- | sql/rpl_reporting.cc | 48 | ||||
-rw-r--r-- | sql/rpl_reporting.h | 85 | ||||
-rw-r--r-- | sql/rpl_rli.cc | 17 | ||||
-rw-r--r-- | sql/rpl_rli.h | 8 | ||||
-rw-r--r-- | sql/rpl_utility.cc | 25 | ||||
-rw-r--r-- | sql/share/errmsg.txt | 14 | ||||
-rw-r--r-- | sql/slave.cc | 224 | ||||
-rw-r--r-- | sql/slave.h | 3 | ||||
-rw-r--r-- | sql/sql_repl.cc | 4 |
15 files changed, 410 insertions, 269 deletions
diff --git a/sql/Makefile.am b/sql/Makefile.am index fdf3f88c1f8..a379a950c41 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -53,6 +53,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ ha_ndbcluster_binlog.h ha_ndbcluster_tables.h \ ha_partition.h rpl_constants.h \ opt_range.h protocol.h rpl_tblmap.h rpl_utility.h \ + rpl_reporting.h \ log.h sql_show.h rpl_rli.h rpl_mi.h \ sql_select.h structs.h table.h sql_udf.h hash_filo.h \ lex.h lex_symbol.h sql_acl.h sql_crypt.h \ @@ -100,6 +101,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \ slave.cc sql_repl.cc rpl_filter.cc rpl_tblmap.cc \ rpl_utility.cc rpl_injector.cc rpl_rli.cc rpl_mi.cc \ + rpl_reporting.cc \ sql_union.cc sql_derived.cc \ client.c sql_client.cc mini_client_errors.c pack.c\ stacktrace.c repl_failsafe.h repl_failsafe.cc \ diff --git a/sql/log_event.cc b/sql/log_event.cc index 07251d338ce..1b9dae56fde 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -146,12 +146,11 @@ static void pretty_print_str(IO_CACHE* cache, char* str, int len) #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -static void clear_all_errors(THD *thd, struct st_relay_log_info *rli) +static void clear_all_errors(THD *thd, RELAY_LOG_INFO *rli) { thd->query_error = 0; thd->clear_error(); - *rli->last_slave_error = 0; - rli->last_slave_errno = 0; + rli->clear_error(); } @@ -2090,7 +2089,7 @@ int Query_log_event::do_apply_event(RELAY_LOG_INFO const *rli, clear_all_errors(thd, const_cast<RELAY_LOG_INFO*>(rli)); /* Can ignore query */ else { - slave_print_msg(ERROR_LEVEL, rli, expected_error, + rli->report(ERROR_LEVEL, expected_error, "\ Query partially completed on the master (error on master: %d) \ and was aborted. There is a chance that your master is inconsistent at this \ @@ -2119,7 +2118,7 @@ compare_errors: !ignored_error_code(actual_error) && !ignored_error_code(expected_error)) { - slave_print_msg(ERROR_LEVEL, rli, 0, + rli->report(ERROR_LEVEL, 0, "\ Query caused different errors on master and slave. \ Error on master: '%s' (%d), Error on slave: '%s' (%d). \ @@ -2145,7 +2144,7 @@ Default database: '%s'. Query: '%s'", */ else if (thd->query_error || thd->is_fatal_error) { - slave_print_msg(ERROR_LEVEL, rli, actual_error, + rli->report(ERROR_LEVEL, actual_error, "Error '%s' on query. Default database: '%s'. Query: '%s'", (actual_error ? thd->net.last_error : "unexpected success or fatal error"), @@ -2628,11 +2627,11 @@ int Format_description_log_event::do_apply_event(RELAY_LOG_INFO const *rli) if (!artificial_event && created && thd->transaction.all.nht) { /* This is not an error (XA is safe), just an information */ - slave_print_msg(INFORMATION_LEVEL, rli, 0, - "Rolling back unfinished transaction (no COMMIT " - "or ROLLBACK in relay log). A probable cause is that " - "the master died while writing the transaction to " - "its binary log, thus rolled back too."); + rli->report(INFORMATION_LEVEL, 0, + "Rolling back unfinished transaction (no COMMIT " + "or ROLLBACK in relay log). A probable cause is that " + "the master died while writing the transaction to " + "its binary log, thus rolled back too."); const_cast<RELAY_LOG_INFO*>(rli)->cleanup_context(thd, 1); } #endif @@ -3450,6 +3449,10 @@ error: thd->query_length= 0; VOID(pthread_mutex_unlock(&LOCK_thread_count)); close_thread_tables(thd); + + DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error", + thd->query_error= 0; thd->is_fatal_error= 1;); + if (thd->query_error) { /* this err/sql_errno code is copy-paste from net_send_error() */ @@ -3462,19 +3465,25 @@ error: sql_errno=ER_UNKNOWN_ERROR; err=ER(sql_errno); } - slave_print_msg(ERROR_LEVEL, rli, sql_errno,"\ + rli->report(ERROR_LEVEL, sql_errno,"\ 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)); return 1; } free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); - + if (thd->is_fatal_error) { - slave_print_msg(ERROR_LEVEL, rli, ER_UNKNOWN_ERROR, "\ -Fatal error running LOAD DATA INFILE on table '%s'. Default database: '%s'", - (char*)table_name, print_slave_db_safe(remember_db)); + char buf[256]; + my_snprintf(buf, sizeof(buf), + "Running LOAD DATA INFILE on table '%-.64s'." + " Default database: '%-.64s'", + (char*)table_name, + print_slave_db_safe(remember_db)); + + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER(ER_SLAVE_FATAL_ERROR), buf); return 1; } @@ -4834,8 +4843,9 @@ int Create_file_log_event::do_apply_event(RELAY_LOG_INFO const *rli) init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0, MYF(MY_WME|MY_NABP))) { - slave_print_msg(ERROR_LEVEL, rli, my_errno, "Error in Create_file event: " - "could not open file '%s'", fname_buf); + rli->report(ERROR_LEVEL, my_errno, + "Error in Create_file event: could not open file '%s'", + fname_buf); goto err; } @@ -4845,9 +4855,9 @@ int Create_file_log_event::do_apply_event(RELAY_LOG_INFO const *rli) if (write_base(&file)) { strmov(ext, ".info"); // to have it right in the error message - slave_print_msg(ERROR_LEVEL, rli, my_errno, - "Error in Create_file event: could not write to file '%s'", - fname_buf); + rli->report(ERROR_LEVEL, my_errno, + "Error in Create_file event: could not write to file '%s'", + fname_buf); goto err; } end_io_cache(&file); @@ -4859,14 +4869,16 @@ int Create_file_log_event::do_apply_event(RELAY_LOG_INFO const *rli) O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW, MYF(MY_WME))) < 0) { - slave_print_msg(ERROR_LEVEL, rli, my_errno, "Error in Create_file event: " - "could not open file '%s'", fname_buf); + rli->report(ERROR_LEVEL, my_errno, + "Error in Create_file event: could not open file '%s'", + fname_buf); goto err; } if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP))) { - slave_print_msg(ERROR_LEVEL, rli, my_errno, "Error in Create_file event: " - "write to '%s' failed", fname_buf); + rli->report(ERROR_LEVEL, my_errno, + "Error in Create_file event: write to '%s' failed", + fname_buf); goto err; } error=0; // Everything is ok @@ -5005,25 +5017,25 @@ int Append_block_log_event::do_apply_event(RELAY_LOG_INFO const *rli) O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW, MYF(MY_WME))) < 0) { - slave_print_msg(ERROR_LEVEL, rli, my_errno, - "Error in %s event: could not create file '%s'", - get_type_str(), fname); + rli->report(ERROR_LEVEL, my_errno, + "Error in %s event: could not create file '%s'", + get_type_str(), fname); goto err; } } else if ((fd = my_open(fname, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW, MYF(MY_WME))) < 0) { - slave_print_msg(ERROR_LEVEL, rli, my_errno, - "Error in %s event: could not open file '%s'", - get_type_str(), fname); + rli->report(ERROR_LEVEL, my_errno, + "Error in %s event: could not open file '%s'", + get_type_str(), fname); goto err; } if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP))) { - slave_print_msg(ERROR_LEVEL, rli, my_errno, - "Error in %s event: write to '%s' failed", - get_type_str(), fname); + rli->report(ERROR_LEVEL, my_errno, + "Error in %s event: write to '%s' failed", + get_type_str(), fname); goto err; } error=0; @@ -5231,8 +5243,9 @@ int Execute_load_log_event::do_apply_event(RELAY_LOG_INFO const *rli) init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0, MYF(MY_WME|MY_NABP))) { - slave_print_msg(ERROR_LEVEL, rli, my_errno, "Error in Exec_load event: " - "could not open file '%s'", fname); + rli->report(ERROR_LEVEL, my_errno, + "Error in Exec_load event: could not open file '%s'", + fname); goto err; } if (!(lev = (Load_log_event*)Log_event::read_log_event(&file, @@ -5240,7 +5253,7 @@ int Execute_load_log_event::do_apply_event(RELAY_LOG_INFO const *rli) rli->relay_log.description_event_for_exec)) || lev->get_type_code() != NEW_LOAD_EVENT) { - slave_print_msg(ERROR_LEVEL, rli, 0, "Error in Exec_load event: " + rli->report(ERROR_LEVEL, 0, "Error in Exec_load event: " "file '%s' appears corrupted", fname); goto err; } @@ -5265,13 +5278,11 @@ int Execute_load_log_event::do_apply_event(RELAY_LOG_INFO const *rli) don't want to overwrite it with the filename. What we want instead is add the filename to the current error message. */ - char *tmp= my_strdup(rli->last_slave_error,MYF(MY_WME)); + char *tmp= my_strdup(rli->last_error().message, MYF(MY_WME)); if (tmp) { - slave_print_msg(ERROR_LEVEL, rli, - rli->last_slave_errno, /* ok to re-use error code */ - "%s. Failed executing load from '%s'", - tmp, fname); + rli->report(ERROR_LEVEL, rli->last_error().number, + "%s. Failed executing load from '%s'", tmp, fname); my_free(tmp,MYF(0)); } goto err; @@ -5474,11 +5485,16 @@ Execute_load_query_log_event::do_apply_event(RELAY_LOG_INFO const *rli) char *fname_end; int error; + buf= (char*) my_malloc(q_len + 1 - (fn_pos_end - fn_pos_start) + + (FN_REFLEN + 10) + 10 + 8 + 5, MYF(MY_WME)); + + DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error", buf= NULL;); + /* Replace filename and LOCAL keyword in query before executing it */ - if (!(buf = (char*) my_malloc(q_len + 1 - (fn_pos_end - fn_pos_start) + - (FN_REFLEN + 10) + 10 + 8 + 5, MYF(MY_WME)))) + if (buf == NULL) { - slave_print_msg(ERROR_LEVEL, rli, my_errno, "Not enough memory"); + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER(ER_SLAVE_FATAL_ERROR), "Not enough memory"); return 1; } @@ -5740,7 +5756,7 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len, size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf); DBUG_PRINT("info",("m_table_id: %lu m_flags: %d m_width: %lu data_size: %lu", - m_table_id, m_flags, m_width, data_size)); + m_table_id, m_flags, m_width, (ulong) data_size)); m_rows_buf= (uchar*) my_malloc(data_size, MYF(MY_WME)); if (likely((bool)m_rows_buf)) @@ -5908,18 +5924,18 @@ int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli) simplifications (we don't honour --slave-skip-errors) */ uint actual_error= thd->net.last_errno; - slave_print_msg(ERROR_LEVEL, rli, actual_error, - "Error '%s' in %s event: when locking tables", - (actual_error ? thd->net.last_error : - "unexpected success or fatal error"), - get_type_str()); + rli->report(ERROR_LEVEL, actual_error, + "Error '%s' in %s event: when locking tables", + (actual_error ? thd->net.last_error : + "unexpected success or fatal error"), + get_type_str()); thd->is_fatal_error= 1; } else { - slave_print_msg(ERROR_LEVEL, rli, error, - "Error in %s event: when locking tables", - get_type_str()); + rli->report(ERROR_LEVEL, error, + "Error in %s event: when locking tables", + get_type_str()); } const_cast<RELAY_LOG_INFO*>(rli)->clear_tables_to_lock(); DBUG_RETURN(error); @@ -5952,10 +5968,10 @@ int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli) simplifications (we don't honour --slave-skip-errors) */ uint actual_error= thd->net.last_errno; - slave_print_msg(ERROR_LEVEL, rli, actual_error, - "Error '%s' on reopening tables", - (actual_error ? thd->net.last_error : - "unexpected success or fatal error")); + rli->report(ERROR_LEVEL, actual_error, + "Error '%s' on reopening tables", + (actual_error ? thd->net.last_error : + "unexpected success or fatal error")); thd->query_error= 1; } const_cast<RELAY_LOG_INFO*>(rli)->clear_tables_to_lock(); @@ -6087,9 +6103,9 @@ int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli) break; default: - slave_print_msg(ERROR_LEVEL, rli, thd->net.last_errno, - "Error in %s event: row application failed", - get_type_str()); + rli->report(ERROR_LEVEL, thd->net.last_errno, + "Error in %s event: row application failed", + get_type_str()); thd->query_error= 1; break; } @@ -6108,13 +6124,13 @@ int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli) if (error) { /* error has occured during the transaction */ - slave_print_msg(ERROR_LEVEL, rli, thd->net.last_errno, - "Error in %s event: error during transaction execution " - "on table %s.%s", - get_type_str(), table->s->db.str, - table->s->table_name.str); + rli->report(ERROR_LEVEL, thd->net.last_errno, + "Error in %s event: error during transaction execution " + "on table %s.%s", + get_type_str(), table->s->db.str, + table->s->table_name.str); - /* + /* If one day we honour --skip-slave-errors in row-based replication, and the error should be skipped, then we would clear mappings, rollback, close tables, but the slave SQL thread would not stop and then may @@ -6246,9 +6262,11 @@ Rows_log_event::do_update_pos(RELAY_LOG_INFO *rli) thd->clear_error(); } else - slave_print_msg(ERROR_LEVEL, rli, error, - "Error in %s event: commit of row events failed", - get_type_str()); + rli->report(ERROR_LEVEL, error, + "Error in %s event: commit of row events failed, " + "table `%s`.`%s`", + get_type_str(), m_table->s->db.str, + m_table->s->table_name.str); } else { @@ -6466,8 +6484,8 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len, m_colcnt= net_field_length(&ptr_after_colcnt); DBUG_PRINT("info",("m_dblen: %lu off: %ld m_tbllen: %lu off: %ld m_colcnt: %lu off: %ld", - m_dblen, (long) (ptr_dblen-(const uchar*)vpart), - m_tbllen, (long) (ptr_tbllen-(const uchar*)vpart), + (ulong) m_dblen, (long) (ptr_dblen-(const uchar*)vpart), + (ulong) m_tbllen, (long) (ptr_tbllen-(const uchar*)vpart), m_colcnt, (long) (ptr_colcnt-(const uchar*)vpart))); /* Allocate mem for all fields in one go. If fails, catched in is_valid() */ @@ -6594,11 +6612,11 @@ int Table_map_log_event::do_apply_event(RELAY_LOG_INFO const *rli) simplifications (we don't honour --slave-skip-errors) */ uint actual_error= thd->net.last_errno; - slave_print_msg(ERROR_LEVEL, rli, actual_error, - "Error '%s' on opening table `%s`.`%s`", - (actual_error ? thd->net.last_error : - "unexpected success or fatal error"), - table_list->db, table_list->table_name); + rli->report(ERROR_LEVEL, actual_error, + "Error '%s' on opening table `%s`.`%s`", + (actual_error ? thd->net.last_error : + "unexpected success or fatal error"), + table_list->db, table_list->table_name); thd->query_error= 1; } goto err; @@ -6855,11 +6873,14 @@ int Write_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO const *rli, DBUG_ASSERT(table != NULL); DBUG_ASSERT(row_start && row_end); - int error; - error= unpack_row(rli, table, m_width, row_start, &m_cols, row_end, - &m_master_reclength, table->write_set, WRITE_ROWS_EVENT); + if (int error= unpack_row(rli, table, m_width, row_start, &m_cols, row_end, + &m_master_reclength, table->write_set, WRITE_ROWS_EVENT)) + { + thd->net.last_errno= error; + return error; + } bitmap_copy(table->read_set, table->write_set); - return error; + return 0; } /* @@ -7567,7 +7588,6 @@ int Delete_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO const *rli, uchar const *const row_start, uchar const **const row_end) { - int error; DBUG_ASSERT(row_start && row_end); /* This assertion actually checks that there is at least as many @@ -7575,8 +7595,13 @@ int Delete_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO const *rli, */ DBUG_ASSERT(table->s->fields >= m_width); - error= unpack_row(rli, table, m_width, row_start, &m_cols, row_end, - &m_master_reclength, table->read_set, DELETE_ROWS_EVENT); + if (int error= unpack_row(rli, table, m_width, row_start, &m_cols, row_end, + &m_master_reclength, table->read_set, DELETE_ROWS_EVENT)) + { + thd->net.last_errno= error; + return error; + } + /* If we will access rows using the random access method, m_key will be set to NULL, so we do not need to make a key copy in that case. @@ -7588,7 +7613,7 @@ int Delete_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO const *rli, key_copy(m_key, table->record[0], key_info, 0); } - return error; + return 0; } int Delete_rows_log_event::do_exec_row(TABLE *table) @@ -7757,13 +7782,23 @@ int Update_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO const *rli, */ /* record[0] is the before image for the update */ - error= unpack_row(rli, table, m_width, row_start, &m_cols, row_end, - &m_master_reclength, table->read_set, UPDATE_ROWS_EVENT); + if ((error= unpack_row(rli, table, m_width, row_start, &m_cols, row_end, + &m_master_reclength, table->read_set, UPDATE_ROWS_EVENT))) + { + thd->net.last_errno= error; + return error; + } + store_record(table, record[1]); uchar const *next_start = *row_end; /* m_after_image is the after image for the update */ - error= unpack_row(rli, table, m_width, next_start, &m_cols_ai, row_end, - &m_master_reclength, table->write_set, UPDATE_ROWS_EVENT); + if ((error= unpack_row(rli, table, m_width, next_start, &m_cols_ai, row_end, + &m_master_reclength, table->write_set, UPDATE_ROWS_EVENT))) + { + thd->net.last_errno= error; + return error; + } + bmove_align(m_after_image, table->record[0], table->s->reclength); restore_record(table, record[1]); @@ -7918,10 +7953,10 @@ int Incident_log_event::do_apply_event(RELAY_LOG_INFO const *rli) { DBUG_ENTER("Incident_log_event::do_apply_event"); - slave_print_msg(ERROR_LEVEL, rli, ER_SLAVE_INCIDENT, - ER(ER_SLAVE_INCIDENT), - description(), - m_message.length > 0 ? m_message.str : "<none>"); + rli->report(ERROR_LEVEL, ER_SLAVE_INCIDENT, + ER(ER_SLAVE_INCIDENT), + description(), + m_message.length > 0 ? m_message.str : "<none>"); DBUG_RETURN(1); } #endif diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index bb9d0e6d953..f506a3c319d 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -28,7 +28,8 @@ int init_strvar_from_file(char *var, int max_size, IO_CACHE *f, const char *default_val); MASTER_INFO::MASTER_INFO() - :ssl(0), fd(-1), io_thd(0), inited(0), + :Slave_reporting_capability("I/O"), + ssl(0), fd(-1), io_thd(0), inited(0), abort_slave(0),slave_running(0), ssl_verify_server_cert(0), slave_run_id(0) { diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index 08435795a91..44ab0d1dc15 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -19,6 +19,7 @@ #ifdef HAVE_REPLICATION #include "rpl_rli.h" +#include "rpl_reporting.h" /***************************************************************************** @@ -54,7 +55,7 @@ *****************************************************************************/ -class MASTER_INFO +class MASTER_INFO : public Slave_reporting_capability { public: MASTER_INFO(); diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc index 45edb42374b..94778948bf9 100644 --- a/sql/rpl_record.cc +++ b/sql/rpl_record.cc @@ -14,6 +14,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "mysql_priv.h" +#include "rpl_rli.h" #include "rpl_record.h" #include "slave.h" // Need to pull in slave_print_msg @@ -263,11 +264,11 @@ unpack_row(RELAY_LOG_INFO const *rli, if (event_type == WRITE_ROWS_EVENT && ((*field_ptr)->flags & mask) == mask) { - slave_print_msg(ERROR_LEVEL, rli, ER_NO_DEFAULT_FOR_FIELD, - "Field `%s` of table `%s`.`%s` " - "has no default value and cannot be NULL", - (*field_ptr)->field_name, table->s->db.str, - table->s->table_name.str); + rli->report(ERROR_LEVEL, ER_NO_DEFAULT_FOR_FIELD, + "Field `%s` of table `%s`.`%s` " + "has no default value and cannot be NULL", + (*field_ptr)->field_name, table->s->db.str, + table->s->table_name.str); error = ER_NO_DEFAULT_FOR_FIELD; } else diff --git a/sql/rpl_record_old.cc b/sql/rpl_record_old.cc index b6f170082fe..377aec49113 100644 --- a/sql/rpl_record_old.cc +++ b/sql/rpl_record_old.cc @@ -1,5 +1,6 @@ #include "mysql_priv.h" +#include "rpl_rli.h" #include "rpl_record_old.h" size_t @@ -157,11 +158,11 @@ unpack_row_old(RELAY_LOG_INFO *rli, if (event_type == WRITE_ROWS_EVENT && ((*field_ptr)->flags & mask) == mask) { - slave_print_msg(ERROR_LEVEL, rli, ER_NO_DEFAULT_FOR_FIELD, - "Field `%s` of table `%s`.`%s` " - "has no default value and cannot be NULL", - (*field_ptr)->field_name, table->s->db.str, - table->s->table_name.str); + rli->report(ERROR_LEVEL, ER_NO_DEFAULT_FOR_FIELD, + "Field `%s` of table `%s`.`%s` " + "has no default value and cannot be NULL", + (*field_ptr)->field_name, table->s->db.str, + table->s->table_name.str); error = ER_NO_DEFAULT_FOR_FIELD; } else diff --git a/sql/rpl_reporting.cc b/sql/rpl_reporting.cc new file mode 100644 index 00000000000..28f257790c7 --- /dev/null +++ b/sql/rpl_reporting.cc @@ -0,0 +1,48 @@ + +#include "mysql_priv.h" +#include "rpl_reporting.h" + +void +Slave_reporting_capability::report(loglevel level, int err_code, + const char *msg, ...) const +{ + void (*report_function)(const char *, ...); + char buff[MAX_SLAVE_ERRMSG]; + char *pbuff= buff; + uint pbuffsize= sizeof(buff); + va_list args; + va_start(args, msg); + + switch (level) + { + case ERROR_LEVEL: + /* + It's an error, it must be reported in Last_error and Last_errno in SHOW + SLAVE STATUS. + */ + pbuff= m_last_error.message; + pbuffsize= sizeof(m_last_error.message); + m_last_error.number = err_code; + report_function= sql_print_error; + break; + case WARNING_LEVEL: + report_function= sql_print_warning; + break; + case INFORMATION_LEVEL: + report_function= sql_print_information; + break; + default: + DBUG_ASSERT(0); // should not come here + return; // don't crash production builds, just do nothing + } + + my_vsnprintf(pbuff, pbuffsize, msg, args); + + va_end(args); + + /* If the msg string ends with '.', do not add a ',' it would be ugly */ + report_function("Slave %s: %s%s Error_code: %d", + m_thread_name, pbuff, + (pbuff[0] && *(strend(pbuff)-1) == '.') ? "" : ",", + err_code); +} diff --git a/sql/rpl_reporting.h b/sql/rpl_reporting.h new file mode 100644 index 00000000000..2e3fa3cea83 --- /dev/null +++ b/sql/rpl_reporting.h @@ -0,0 +1,85 @@ +#ifndef RPL_REPORTING_H +#define RPL_REPORTING_H + +/** + Maximum size of an error message from a slave thread. + */ +#define MAX_SLAVE_ERRMSG 1024 + +/** + Mix-in to handle the message logging and reporting for relay log + info and master log info structures. + + By inheriting from this class, the class is imbued with + capabilities to do slave reporting. + */ +class Slave_reporting_capability +{ +public: + /** + Constructor. + + @param thread_name Printable name of the slave thread that is reporting. + */ + Slave_reporting_capability(char const *thread_name) + : m_thread_name(thread_name) + { + } + + /** + Writes a message and, if it's an error message, to Last_Error + (which will be displayed by SHOW SLAVE STATUS). + + @param level The severity level + @param err_code The error code + @param msg The message (usually related to the error + 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); + + /** + Clear errors. They will not show up under <code>SHOW SLAVE + STATUS</code>. + */ + void clear_error() { + m_last_error.clear(); + } + + /** + Error information structure. + */ + class Error { + friend class Slave_reporting_capability; + public: + Error() + { + clear(); + } + + void clear() + { + number= 0; + message[0]= '\0'; + } + + /** Error code */ + uint32 number; + /** Error message */ + char message[MAX_SLAVE_ERRMSG]; + }; + + Error const& last_error() const { return m_last_error; } + +private: + /** + Last error produced by the I/O or SQL thread respectively. + */ + mutable Error m_last_error; + + char const *const m_thread_name; +}; + +#endif // RPL_REPORTING_H + diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 0c8f74bb35e..41df3f63825 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -30,11 +30,12 @@ int init_strvar_from_file(char *var, int max_size, IO_CACHE *f, st_relay_log_info::st_relay_log_info() - :no_storage(FALSE), replicate_same_server_id(::replicate_same_server_id), + :Slave_reporting_capability("SQL"), + no_storage(FALSE), replicate_same_server_id(::replicate_same_server_id), info_fd(-1), cur_log_fd(-1), save_temporary_tables(0), cur_log_old_open_count(0), group_master_log_pos(0), log_space_total(0), ignore_log_space_limit(0), last_master_timestamp(0), slave_skip_counter(0), - abort_pos_wait(0), slave_run_id(0), sql_thd(0), last_slave_errno(0), + abort_pos_wait(0), slave_run_id(0), sql_thd(0), inited(0), abort_slave(0), slave_running(0), until_condition(UNTIL_NONE), until_log_pos(0), retried_trans(0), tables_to_lock(0), tables_to_lock_count(0), @@ -44,7 +45,7 @@ st_relay_log_info::st_relay_log_info() group_relay_log_name[0]= event_relay_log_name[0]= group_master_log_name[0]= 0; - last_slave_error[0]= until_log_name[0]= ign_master_log_name_end[0]= 0; + until_log_name[0]= ign_master_log_name_end[0]= 0; bzero((char*) &info_file, sizeof(info_file)); bzero((char*) &cache_buf, sizeof(cache_buf)); cached_charset_invalidate(); @@ -337,16 +338,6 @@ static int count_relay_log_space(RELAY_LOG_INFO* rli) } -void st_relay_log_info::clear_slave_error() -{ - DBUG_ENTER("clear_slave_error"); - - /* Clear the errors displayed by SHOW SLAVE STATUS */ - last_slave_error[0]= 0; - last_slave_errno= 0; - DBUG_VOID_RETURN; -} - /* Reset UNTIL condition for RELAY_LOG_INFO diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index fada45722f6..c458318594a 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -16,9 +16,8 @@ #ifndef RPL_RLI_H #define RPL_RLI_H -#define MAX_SLAVE_ERRMSG 1024 - #include "rpl_tblmap.h" +#include "rpl_reporting.h" struct RPL_TABLE_LIST; @@ -49,7 +48,7 @@ struct RPL_TABLE_LIST; *****************************************************************************/ -typedef struct st_relay_log_info +typedef struct st_relay_log_info : public Slave_reporting_capability { /** Flags for the state of the replication. @@ -186,7 +185,6 @@ typedef struct st_relay_log_info time_t last_master_timestamp; - void clear_slave_error(); void clear_until_condition(); /* @@ -200,11 +198,9 @@ typedef struct st_relay_log_info pthread_mutex_t log_space_lock; pthread_cond_t log_space_cond; THD * sql_thd; - int last_slave_errno; #ifndef DBUG_OFF int events_till_abort; #endif - char last_slave_error[MAX_SLAVE_ERRMSG]; /* if not set, the value of other members of the structure are undefined */ bool inited; diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc index dcbf85f5939..a04bcd1fab9 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -14,6 +14,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "rpl_utility.h" +#include "rpl_rli.h" uint32 field_length_from_packed(enum_field_types const field_type, @@ -128,11 +129,13 @@ table_def::compatible_with(RELAY_LOG_INFO const *rli_arg, TABLE *table) { DBUG_ASSERT(tsh->db.str && tsh->table_name.str); error= 1; - slave_print_msg(ERROR_LEVEL, rli, ER_BINLOG_ROW_WRONG_TABLE_DEF, - "Table width mismatch - " - "received %u columns, %s.%s has %u columns", - (uint) size(), tsh->db.str, tsh->table_name.str, - tsh->fields); + char buf[256]; + my_snprintf(buf, sizeof(buf), "Table width mismatch - " + "received %u columns, %s.%s has %u columns", + (uint) size(), tsh->db.str, tsh->table_name.str, + tsh->fields); + rli->report(ERROR_LEVEL, ER_BINLOG_ROW_WRONG_TABLE_DEF, + ER(ER_BINLOG_ROW_WRONG_TABLE_DEF), buf); } for (uint col= 0 ; col < cols_to_check ; ++col) @@ -142,11 +145,13 @@ table_def::compatible_with(RELAY_LOG_INFO const *rli_arg, TABLE *table) DBUG_ASSERT(col < size() && col < tsh->fields); DBUG_ASSERT(tsh->db.str && tsh->table_name.str); error= 1; - slave_print_msg(ERROR_LEVEL, rli, ER_BINLOG_ROW_WRONG_TABLE_DEF, - "Column %d type mismatch - " - "received type %d, %s.%s has type %d", - col, type(col), tsh->db.str, tsh->table_name.str, - table->field[col]->type()); + char buf[256]; + my_snprintf(buf, sizeof(buf), "Column %d type mismatch - " + "received type %d, %s.%s has type %d", + col, type(col), tsh->db.str, tsh->table_name.str, + table->field[col]->type()); + rli->report(ERROR_LEVEL, ER_BINLOG_ROW_WRONG_TABLE_DEF, + ER(ER_BINLOG_ROW_WRONG_TABLE_DEF), buf); } } diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 40744d0b07b..b5bfe8a691c 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5843,8 +5843,8 @@ ER_BINLOG_ROW_LOGGING_FAILED eng "Writing one row to the row-based binary log failed" ger "Schreiben einer Zeilen ins zeilenbasierte Binärlog fehlgeschlagen" ER_BINLOG_ROW_WRONG_TABLE_DEF - eng "Table definition on master and slave does not match" - ger "Tabellendefinition auf Master und Slave stimmt nicht überein" + eng "Table definition on master and slave does not match: %s" + ger "Tabellendefinition auf Master und Slave stimmt nicht überein: %s" ER_BINLOG_ROW_RBR_TO_SBR eng "Slave running with --log-slave-updates must use row-based binary logging to be able to replicate row-based binary log events" ger "Slave, die mit --log-slave-updates laufen, müssen zeilenbasiertes Loggen verwenden, um zeilenbasierte Binärlog-Ereignisse loggen zu können" @@ -6062,3 +6062,13 @@ ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT ER_BINLOG_UNSAFE_STATEMENT eng "Statement is not safe to log in statement format." swe "Detta är inte säkert att logga i statement-format." +ER_SLAVE_FATAL_ERROR + eng "Fatal error: %s" +ER_SLAVE_RELAY_LOG_READ_FAILURE + eng "Relay log read failure: %s" +ER_SLAVE_RELAY_LOG_WRITE_FAILURE + eng "Relay log write failure: %s" +ER_SLAVE_CREATE_EVENT_FAILURE + eng "Failed to create %s" +ER_SLAVE_MASTER_COM_FAILURE + eng "Master command %s failed: %s" diff --git a/sql/slave.cc b/sql/slave.cc index 72fb1b8d9ef..6c7968c2b3f 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -529,13 +529,13 @@ static bool sql_slave_killed(THD* thd, RELAY_LOG_INFO* rli) "it some grace period")); if (difftime(time(0), rli->last_event_start_time) > 60) { - slave_print_msg(ERROR_LEVEL, rli, 0, - "SQL thread had to stop in an unsafe situation, in " - "the middle of applying updates to a " - "non-transactional table without any primary key. " - "There is a risk of duplicate updates when the slave " - "SQL thread is restarted. Please check your tables' " - "contents after restart."); + rli->report(ERROR_LEVEL, 0, + "SQL thread had to stop in an unsafe situation, in " + "the middle of applying updates to a " + "non-transactional table without any primary key. " + "There is a risk of duplicate updates when the slave " + "SQL thread is restarted. Please check your tables' " + "contents after restart."); DBUG_RETURN(1); } } @@ -544,70 +544,6 @@ static bool sql_slave_killed(THD* thd, RELAY_LOG_INFO* rli) /* - Writes a message to stderr, and if it's an error message, to - rli->last_slave_error and rli->last_slave_errno (which will be displayed by - SHOW SLAVE STATUS). - - SYNOPSIS - slave_print_msg() - level The severity level - rli - err_code The error code - msg The message (usually related to the error code, but can - contain more information). - ... (this is printf-like format, with % symbols in msg) - - RETURN VALUES - void -*/ - -void slave_print_msg(enum loglevel level, RELAY_LOG_INFO const *rli, - int err_code, const char* msg, ...) -{ - void (*report_function)(const char *, ...); - char buff[MAX_SLAVE_ERRMSG], *pbuff= buff; - uint pbuffsize= sizeof(buff); - va_list args; - DBUG_ENTER("slave_print_msg"); - - va_start(args,msg); - switch (level) - { - case ERROR_LEVEL: - /* - This my_error call only has effect in client threads. - Slave threads do nothing in my_error(). - */ - my_error(ER_UNKNOWN_ERROR, MYF(0), msg); - /* - It's an error, it must be reported in Last_error and Last_errno in SHOW - SLAVE STATUS. - */ - pbuff= const_cast<RELAY_LOG_INFO*>(rli)->last_slave_error; - pbuffsize= sizeof(rli->last_slave_error); - const_cast<RELAY_LOG_INFO*>(rli)->last_slave_errno = err_code; - report_function= sql_print_error; - break; - case WARNING_LEVEL: - report_function= sql_print_warning; - break; - case INFORMATION_LEVEL: - report_function= sql_print_information; - break; - default: - DBUG_ASSERT(0); // should not come here - DBUG_VOID_RETURN; // don't crash production builds, just do nothing - } - my_vsnprintf(pbuff, pbuffsize, msg, args); - /* If the msg string ends with '.', do not add a ',' it would be ugly */ - if (pbuff[0] && (*(strend(pbuff)-1) == '.')) - (*report_function)("Slave: %s Error_code: %d", pbuff, err_code); - else - (*report_function)("Slave: %s. Error_code: %d", pbuff, err_code); - DBUG_VOID_RETURN; -} - -/* skip_load_data_infile() NOTES @@ -775,7 +711,9 @@ static int get_master_version_and_clock(MYSQL* mysql, MASTER_INFO* mi) /* as we are here, we tried to allocate the event */ if (!mi->rli.relay_log.description_event_for_queue) { - sql_print_error("Slave I/O thread failed to create a default Format_description_log_event"); + mi->report(ERROR_LEVEL, ER_SLAVE_CREATE_EVENT_FAILURE, + ER(ER_SLAVE_CREATE_EVENT_FAILURE), + "default Format_description_log_event"); DBUG_RETURN(1); } @@ -1138,18 +1076,21 @@ static void write_ignored_events_info_to_relay_log(THD *thd, MASTER_INFO *mi) { ev->server_id= 0; // don't be ignored by slave SQL thread if (unlikely(rli->relay_log.append(ev))) - sql_print_error("Slave I/O thread failed to write a Rotate event" - " to the relay log, " - "SHOW SLAVE STATUS may be inaccurate"); + mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, + ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), + "failed to write a Rotate event" + " to the relay log, SHOW SLAVE STATUS may be" + " inaccurate"); rli->relay_log.harvest_bytes_written(&rli->log_space_total); if (flush_master_info(mi, 1)) sql_print_error("Failed to flush master info file"); delete ev; } else - sql_print_error("Slave I/O thread failed to create a Rotate event" - " (out of memory?), " - "SHOW SLAVE STATUS may be inaccurate"); + mi->report(ERROR_LEVEL, ER_SLAVE_CREATE_EVENT_FAILURE, + ER(ER_SLAVE_CREATE_EVENT_FAILURE), + "Rotate_event (out of memory?)," + " SHOW SLAVE STATUS may be inaccurate"); } else pthread_mutex_unlock(log_lock); @@ -1157,7 +1098,7 @@ static void write_ignored_events_info_to_relay_log(THD *thd, MASTER_INFO *mi) } -int register_slave_on_master(MYSQL* mysql) +int register_slave_on_master(MYSQL* mysql, MASTER_INFO *mi) { uchar buf[1024], *pos= buf; uint report_host_len, report_user_len=0, report_password_len=0; @@ -1186,9 +1127,11 @@ int register_slave_on_master(MYSQL* mysql) if (simple_command(mysql, COM_REGISTER_SLAVE, buf, (size_t) (pos- buf), 0)) { - sql_print_error("Error on COM_REGISTER_SLAVE: %d '%s'", - mysql_errno(mysql), - mysql_error(mysql)); + 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, + ER(ER_SLAVE_MASTER_COM_FAILURE), "COM_REGISTER_SLAVE", buf); DBUG_RETURN(1); } DBUG_RETURN(0); @@ -1258,6 +1201,10 @@ bool show_master_info(THD* thd, MASTER_INFO* mi) MYSQL_TYPE_LONGLONG)); field_list.push_back(new Item_empty_string("Master_SSL_Verify_Server_Cert", 3)); + field_list.push_back(new Item_return_int("Last_IO_Errno", 4, MYSQL_TYPE_LONG)); + field_list.push_back(new Item_empty_string("Last_IO_Error", 20)); + field_list.push_back(new Item_return_int("Last_SQL_Errno", 4, MYSQL_TYPE_LONG)); + field_list.push_back(new Item_empty_string("Last_SQL_Error", 20)); if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) @@ -1306,8 +1253,8 @@ bool show_master_info(THD* thd, MASTER_INFO* mi) rpl_filter->get_wild_ignore_table(&tmp); protocol->store(&tmp); - protocol->store(mi->rli.last_slave_errno); - protocol->store(mi->rli.last_slave_error, &my_charset_bin); + protocol->store(mi->rli.last_error().number); + protocol->store(mi->rli.last_error().message, &my_charset_bin); protocol->store((uint32) mi->rli.slave_skip_counter); protocol->store((ulonglong) mi->rli.group_master_log_pos); protocol->store((ulonglong) mi->rli.log_space_total); @@ -1368,6 +1315,15 @@ bool show_master_info(THD* thd, MASTER_INFO* mi) } protocol->store(mi->ssl_verify_server_cert? "Yes":"No", &my_charset_bin); + // Last_IO_Errno + protocol->store(mi->last_error().number); + // Last_IO_Error + protocol->store(mi->last_error().message, &my_charset_bin); + // Last_SQL_Errno + protocol->store(mi->rli.last_error().number); + // Last_SQL_Error + protocol->store(mi->rli.last_error().message, &my_charset_bin); + pthread_mutex_unlock(&mi->rli.data_lock); pthread_mutex_unlock(&mi->data_lock); @@ -1824,13 +1780,13 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) */ if (error) { - slave_print_msg(ERROR_LEVEL, rli, ER_UNKNOWN_ERROR, - "It was not possible to update the positions" - " of the relay log information: the slave may" - " be in an inconsistent state." - " Stopped in %s position %s", - rli->group_relay_log_name, - llstr(rli->group_relay_log_pos, buf)); + rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR, + "It was not possible to update the positions" + " of the relay log information: the slave may" + " be in an inconsistent state." + " Stopped in %s position %s", + rli->group_relay_log_name, + llstr(rli->group_relay_log_pos, buf)); DBUG_RETURN(1); } } @@ -1909,7 +1865,8 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) DBUG_RETURN(exec_res); } pthread_mutex_unlock(&rli->data_lock); - slave_print_msg(ERROR_LEVEL, rli, 0, "\ + rli->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_READ_FAILURE, + 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 \ binary log), the slave's relay log is corrupted (you can check this by running \ @@ -1976,7 +1933,8 @@ pthread_handler_t handle_slave_io(void *arg) if (!(mi->mysql = mysql = mysql_init(NULL))) { - sql_print_error("Slave I/O thread: error in mysql_init()"); + mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER(ER_SLAVE_FATAL_ERROR), "error in mysql_init()"); goto err; } @@ -2017,7 +1975,7 @@ connected: Register ourselves with the master. */ thd->proc_info = "Registering slave on master"; - if (register_slave_on_master(mysql)) + if (register_slave_on_master(mysql, mi)) { sql_print_error("Slave I/O thread couldn't register on master"); goto err; @@ -2065,10 +2023,16 @@ dump"); } thd->proc_info = "Reconnecting after a failed binlog dump request"; - if (!suppress_warnings) - sql_print_error("Slave I/O thread: failed dump request, \ -reconnecting to try again, log '%s' at postion %s", IO_RPL_LOG_NAME, - llstr(mi->master_log_pos,llbuff)); + if (!suppress_warnings) { + char buf[256]; + my_snprintf(buf, sizeof(buf), + "failed dump request, reconnecting to try again," + " log '%s' at postion %s", + IO_RPL_LOG_NAME, + llstr(mi->master_log_pos,llbuff)); + mi->report(WARNING_LEVEL, ER_SLAVE_MASTER_COM_FAILURE, + ER(ER_SLAVE_MASTER_COM_FAILURE), "COM_BINLOG_DUMP", buf); + } if (safe_reconnect(thd, mysql, mi, suppress_warnings) || io_slave_killed(thd,mi)) { @@ -2158,7 +2122,9 @@ reconnect done to recover from failed read"); if (queue_event(mi,(const char*)mysql->net.read_pos + 1, event_len)) { - sql_print_error("Slave I/O thread could not queue event from master"); + mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, + ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), + "could not queue event from master"); goto err; } if (flush_master_info(mi, 1)) @@ -2327,7 +2293,7 @@ pthread_handler_t handle_slave_sql(void *arg) now. But the master timestamp is reset by RESET SLAVE & CHANGE MASTER. */ - rli->clear_slave_error(); + rli->clear_error(); //tell the I/O thread to take relay_log_space_limit into account from now on pthread_mutex_lock(&rli->log_space_lock); @@ -2411,22 +2377,22 @@ Slave SQL thread aborted. Can't execute init_slave query"); codes and warnings and print this to the error log as to allow the user to locate the error */ - DBUG_PRINT("info", ("thd->net.last_errno=%d; rli->last_slave_errno=%d", - thd->net.last_errno, rli->last_slave_errno)); + uint32 const last_errno= rli->last_error().number; + + DBUG_PRINT("info", ("thd->net.last_errno=%d; rli->last_error.number=%d", + thd->net.last_errno, last_errno)); if (thd->net.last_errno != 0) { - if (rli->last_slave_errno == 0) + char const *const errmsg= + thd->net.last_error ? thd->net.last_error : "<no message>"; + if (last_errno == 0) { - slave_print_msg(ERROR_LEVEL, rli, thd->net.last_errno, - thd->net.last_error ? - thd->net.last_error : "<no message>"); + rli->report(ERROR_LEVEL, thd->net.last_errno, errmsg); } - else if (rli->last_slave_errno != (int) thd->net.last_errno) + else if (last_errno != thd->net.last_errno) { sql_print_error("Slave (additional info): %s Error_code: %d", - thd->net.last_error ? - thd->net.last_error : "<no message>", - thd->net.last_errno); + errmsg, thd->net.last_errno); } } @@ -2595,8 +2561,9 @@ 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))) { - sql_print_error("Slave I/O: error writing Exec_load event to \ -relay log"); + mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, + ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), + "error writing Exec_load event to relay log"); goto err; } mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total); @@ -2608,8 +2575,9 @@ relay log"); cev->block_len = num_bytes; if (unlikely(mi->rli.relay_log.append(cev))) { - sql_print_error("Slave I/O: error writing Create_file event to \ -relay log"); + mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, + ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), + "error writing Create_file event to relay log"); goto err; } cev_not_written=0; @@ -2622,8 +2590,9 @@ relay log"); aev.log_pos = cev->log_pos; if (unlikely(mi->rli.relay_log.append(&aev))) { - sql_print_error("Slave I/O: error writing Append_block event to \ -relay log"); + mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, + ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), + "error writing Append_block event to relay log"); goto err; } mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total) ; @@ -2724,7 +2693,8 @@ 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))))) { - sql_print_error("Slave I/O: out of memory for Load event"); + mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER(ER_SLAVE_FATAL_ERROR), "Memory allocation failed"); DBUG_RETURN(1); } memcpy(tmp_buf,buf,event_len); @@ -3179,14 +3149,12 @@ static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi, { last_errno=mysql_errno(mysql); suppress_warnings= 0; - sql_print_error("Slave I/O thread: error %s to master " - "'%s@%s:%d': \ -Error: '%s' errno: %d retry-time: %d retries: %lu", - (reconnect ? "reconnecting" : "connecting"), - mi->user, mi->host, mi->port, - mysql_error(mysql), last_errno, - mi->connect_retry, - master_retry_count); + mi->report(ERROR_LEVEL, last_errno, + "error %s to master '%s@%s:%d'" + " - retry-time: %d retries: %lu", + (reconnect ? "reconnecting" : "connecting"), + mi->user, mi->host, mi->port, + mi->connect_retry, master_retry_count); } /* By default we try forever. The reason is that failure will trigger @@ -3764,9 +3732,9 @@ bool rpl_master_has_bug(RELAY_LOG_INFO *rli, uint bug_id) " so slave stops; check error log on slave" " for more info", MYF(0), bug_id); // a verbose message for the error log - slave_print_msg(ERROR_LEVEL, rli, ER_UNKNOWN_ERROR, - "According to the master's version ('%s')," - " it is probable that master suffers from this bug:" + rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR, + "According to the master's version ('%s')," + " it is probable that master suffers from this bug:" " http://bugs.mysql.com/bug.php?id=%u" " and thus replicating the current binary log event" " may make the slave's data become different from the" diff --git a/sql/slave.h b/sql/slave.h index 57806e65af7..731728bde4f 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -169,9 +169,6 @@ bool rpl_master_has_bug(RELAY_LOG_INFO *rli, uint bug_id); const char *print_slave_db_safe(const char *db); int check_expected_error(THD* thd, RELAY_LOG_INFO const *rli, int error_code); void skip_load_data_infile(NET* net); -void slave_print_msg(enum loglevel level, RELAY_LOG_INFO const *rli, - int err_code, const char* msg, ...) - ATTRIBUTE_FORMAT(printf, 4, 5); void end_slave(); /* clean up */ void clear_until_condition(RELAY_LOG_INFO* rli); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 3154cc1b4e9..1616e895107 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -991,7 +991,7 @@ int reset_slave(THD *thd, MASTER_INFO* mi) Reset errors (the idea is that we forget about the old master). */ - mi->rli.clear_slave_error(); + mi->rli.clear_error(); mi->rli.clear_until_condition(); // close master_info_file, relay_log_info_file, set mi->inited=rli->inited=0 @@ -1263,7 +1263,7 @@ bool change_master(THD* thd, MASTER_INFO* mi) pthread_mutex_lock(&mi->rli.data_lock); mi->rli.abort_pos_wait++; /* for MASTER_POS_WAIT() to abort */ /* Clear the errors, for a clean start */ - mi->rli.clear_slave_error(); + mi->rli.clear_error(); mi->rli.clear_until_condition(); /* If we don't write new coordinates to disk now, then old will remain in |