summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <aelkin/andrei@mysql1000.(none)>2008-01-31 17:02:29 +0200
committerunknown <aelkin/andrei@mysql1000.(none)>2008-01-31 17:02:29 +0200
commit64dbfdd7db718b0334e910892031f13ed5795a7b (patch)
tree834bba98e1d4335161f7f522e8dabdb9c8a067b5
parent6a873248d1d226b7610d2f3f0fa3c8d7e023ab87 (diff)
parentb6ec38cecc0285e8939e7b25aa5c63bada070974 (diff)
downloadmariadb-git-64dbfdd7db718b0334e910892031f13ed5795a7b.tar.gz
Merge mysql1000.(none):/mnt/nb/home/elkin/MySQL/TEAM/FIXES/5.1/bug32971-error_propag_slave
into mysql1000.(none):/home/andrei/MySQL/FIXES/5.1/bug32971-rbr_error_prop mysql-test/extra/rpl_tests/rpl_row_tabledefs.test: Auto merged sql/log_event.cc: Auto merged sql/log_event.h: Auto merged mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result: manual merge use local mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result: manual merge use local
-rw-r--r--include/my_base.h4
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_tabledefs.test6
-rw-r--r--sql/log_event.cc52
-rw-r--r--sql/log_event.h2
-rw-r--r--sql/log_event_old.cc4
-rw-r--r--sql/rpl_record.cc15
-rw-r--r--sql/rpl_record.h3
-rw-r--r--sql/share/errmsg.txt2
8 files changed, 57 insertions, 31 deletions
diff --git a/include/my_base.h b/include/my_base.h
index e65a04bb16d..69a6de67359 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -411,7 +411,9 @@ enum ha_base_keytype {
statement */
#define HA_ERR_CORRUPT_EVENT 171 /* The event was corrupt, leading to
illegal data being read */
-#define HA_ERR_LAST 171 /*Copy last error nr.*/
+#define HA_ERR_ROWS_EVENT_APPLY 172 /* The event could not be processed
+ no other hanlder error happened */
+#define HA_ERR_LAST 172 /*Copy last error nr.*/
/* Add error numbers before HA_ERR_LAST and change it accordingly. */
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)
diff --git a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test
index b5795cf525d..0e391cb0f37 100644
--- a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test
+++ b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test
@@ -46,7 +46,7 @@ ALTER TABLE t1_bit
ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test';
# ... and add one non-nullable INT column last in table 't1_text'
# with no default,
-ALTER TABLE t1_nodef ADD x INT NOT NULL;
+ALTER TABLE t1_nodef ADD x INT NOT NULL, ADD y INT NOT NULL, ADD z INT NOT NULL;
# ... and remove the last column in t2
ALTER TABLE t2 DROP b;
# ... change the type of the single column in table 't4'
@@ -222,8 +222,8 @@ sync_slave_with_master;
--echo **** On Slave ****
connection slave;
-INSERT INTO t1_nodef VALUES (1,2,3);
-INSERT INTO t1_nodef VALUES (2,4,6);
+INSERT INTO t1_nodef VALUES (1,2,3,4,5);
+INSERT INTO t1_nodef VALUES (2,4,6,8,10);
--echo **** On Master ****
connection master;
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 5b43016b679..c83edd8d22e 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -99,27 +99,51 @@ static const char *HA_ERR(int i)
case HA_ERR_RECORD_IS_THE_SAME: return "HA_ERR_RECORD_IS_THE_SAME";
case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE";
case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT";
+ case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY";
}
return 0;
}
/**
- macro to call from different branches of Rows_log_event::do_apply_event
+ Error reporting facility for Rows_log_event::do_apply_event
+
+ @param level error, warning or info
+ @param ha_error HA_ERR_ code
+ @param rli pointer to the active Relay_log_info instance
+ @param thd pointer to the slave thread's thd
+ @param table pointer to the event's table object
+ @param type the type of the event
+ @param log_name the master binlog file name
+ @param pos the master binlog file pos (the next after the event)
+
*/
static void inline slave_rows_error_report(enum loglevel level, int ha_error,
Relay_log_info const *rli, THD *thd,
TABLE *table, const char * type,
const char *log_name, ulong pos)
{
- const char *handler_error= HA_ERR(ha_error);
+ const char *handler_error= HA_ERR(ha_error);
+ char buff[MAX_SLAVE_ERRMSG], *slider;
+ const char *buff_end= buff + sizeof(buff);
+ uint len;
+ List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
+ MYSQL_ERROR *err;
+ buff[0]= 0;
+
+ for (err= it++, slider= buff; err && slider < buff_end - 1;
+ slider += len, err= it++)
+ {
+ len= my_snprintf(slider, buff_end - slider,
+ " %s, Error_code: %d;", err->msg, err->code);
+ }
+
rli->report(level, thd->net.last_errno,
"Could not execute %s event on table %s.%s;"
- "%s%s handler error %s; "
+ "%s handler error %s; "
"the event's master log %s, end_log_pos %lu",
type, table->s->db.str,
table->s->table_name.str,
- thd->net.last_error[0] != 0 ? thd->net.last_error : "",
- thd->net.last_error[0] != 0 ? ";" : "",
+ buff,
handler_error == NULL? "<unknown>" : handler_error,
log_name, pos);
}
@@ -7675,7 +7699,7 @@ Rows_log_event::write_row(const Relay_log_info *const rli,
/* fill table->record[0] with default values */
- if ((error= prepare_record(rli, table, m_width,
+ if ((error= prepare_record(table, m_width,
TRUE /* check if columns have def. values */)))
DBUG_RETURN(error);
@@ -7990,13 +8014,17 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
DBUG_ASSERT(m_table && m_table->in_use != NULL);
TABLE *table= m_table;
- int error;
-
- /* unpack row - missing fields get default values */
+ int error= 0;
- // TODO: shall we check and report errors here?
- prepare_record(NULL,table,m_width,FALSE /* don't check errors */);
- error= unpack_current_row(rli);
+ /*
+ rpl_row_tabledefs.test specifies that
+ if the extra field on the slave does not have a default value
+ and this is okay with Delete or Update events.
+ Todo: fix wl3228 hld that requires defauls for all types of events
+ */
+
+ prepare_record(table, m_width, FALSE);
+ error= unpack_current_row(rli);
#ifndef DBUG_OFF
DBUG_PRINT("info",("looking for the following record"));
diff --git a/sql/log_event.h b/sql/log_event.h
index efb8675780e..e0f7a0517c4 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -3131,6 +3131,8 @@ protected:
ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT);
int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols,
&m_curr_row_end, &m_master_reclength);
+ if (m_curr_row_end > m_rows_end)
+ my_error(ER_SLAVE_CORRUPT_EVENT, MYF(0));
ASSERT_OR_RETURN_ERROR(m_curr_row_end <= m_rows_end, HA_ERR_CORRUPT_EVENT);
return result;
}
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index 12c3b2a6dc3..87e593ac7d0 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -2077,7 +2077,7 @@ Old_rows_log_event::write_row(const Relay_log_info *const rli,
/* fill table->record[0] with default values */
- if ((error= prepare_record(rli, table, m_width,
+ if ((error= prepare_record(table, m_width,
TRUE /* check if columns have def. values */)))
DBUG_RETURN(error);
@@ -2288,7 +2288,7 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli)
/* unpack row - missing fields get default values */
// TODO: shall we check and report errors here?
- prepare_record(NULL,table,m_width,FALSE /* don't check errors */);
+ prepare_record(table, m_width, FALSE /* don't check errors */);
error= unpack_current_row(rli);
#ifndef DBUG_OFF
diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc
index ed0dc82cf01..7c74dcba5a0 100644
--- a/sql/rpl_record.cc
+++ b/sql/rpl_record.cc
@@ -307,17 +307,15 @@ unpack_row(Relay_log_info const *rli,
If @c check is true, fields are explicitly initialized only if they have
default value or can be NULL. Otherwise error is reported.
- @param log Used to report errors.
@param table Table whose record[0] buffer is prepared.
@param skip Number of columns for which default value initialization
should be skipped.
@param check Indicates if errors should be checked when setting default
values.
- @returns 0 on success.
+ @returns 0 on success or a handler level error code
*/
-int prepare_record(const Slave_reporting_capability *const log,
- TABLE *const table,
+int prepare_record(TABLE *const table,
const uint skip, const bool check)
{
DBUG_ENTER("prepare_record");
@@ -337,13 +335,8 @@ int prepare_record(const Slave_reporting_capability *const log,
if (check && ((f->flags & mask) == mask))
{
- DBUG_ASSERT(log);
- log->report(ERROR_LEVEL, ER_NO_DEFAULT_FOR_FIELD,
- "Field `%s` of table `%s`.`%s` "
- "has no default value and cannot be NULL",
- f->field_name, table->s->db.str,
- table->s->table_name.str);
- error = ER_NO_DEFAULT_FOR_FIELD;
+ my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), f->field_name);
+ error = HA_ERR_ROWS_EVENT_APPLY;
}
else
f->set_default();
diff --git a/sql/rpl_record.h b/sql/rpl_record.h
index 0d6ceda7433..f9e64f0ab1d 100644
--- a/sql/rpl_record.h
+++ b/sql/rpl_record.h
@@ -30,8 +30,7 @@ int unpack_row(Relay_log_info const *rli,
uchar const **const row_end, ulong *const master_reclength);
// Fill table's record[0] with default values.
-int prepare_record(const Slave_reporting_capability *const, TABLE *const,
- const uint =0, const bool =FALSE);
+int prepare_record(TABLE *const, const uint =0, const bool =FALSE);
#endif
#endif
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 026a0023660..ee3a7e6080a 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -6119,3 +6119,5 @@ ER_SLAVE_AMBIGOUS_EXEC_MODE
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT
eng "The BINLOG statement of type `%s` was not preceded by a format description BINLOG statement."
+ER_SLAVE_CORRUPT_EVENT
+ eng "Corrupted replication event was detected"