Commit 4371a788 authored by hezx@mail.hezx.com's avatar hezx@mail.hezx.com

Merge zhe@bk-internal.mysql.com:/home/bk/mysql-5.1-new-rpl

into  mail.hezx.com:/media/sda3/work/mysql/bkwork/bug33862_failed_drop_user/5.1
parents 43c4a4c3 de7e6d25
...@@ -411,7 +411,9 @@ enum ha_base_keytype { ...@@ -411,7 +411,9 @@ enum ha_base_keytype {
statement */ statement */
#define HA_ERR_CORRUPT_EVENT 171 /* The event was corrupt, leading to #define HA_ERR_CORRUPT_EVENT 171 /* The event was corrupt, leading to
illegal data being read */ 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. */ /* Add error numbers before HA_ERR_LAST and change it accordingly. */
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1) #define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)
......
...@@ -46,7 +46,7 @@ ALTER TABLE t1_bit ...@@ -46,7 +46,7 @@ ALTER TABLE t1_bit
ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test'; ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test';
# ... and add one non-nullable INT column last in table 't1_text' # ... and add one non-nullable INT column last in table 't1_text'
# with no default, # 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 # ... and remove the last column in t2
ALTER TABLE t2 DROP b; ALTER TABLE t2 DROP b;
# ... change the type of the single column in table 't4' # ... change the type of the single column in table 't4'
...@@ -222,8 +222,8 @@ sync_slave_with_master; ...@@ -222,8 +222,8 @@ sync_slave_with_master;
--echo **** On Slave **** --echo **** On Slave ****
connection slave; connection slave;
INSERT INTO t1_nodef VALUES (1,2,3); INSERT INTO t1_nodef VALUES (1,2,3,4,5);
INSERT INTO t1_nodef VALUES (2,4,6); INSERT INTO t1_nodef VALUES (2,4,6,8,10);
--echo **** On Master **** --echo **** On Master ****
connection master; connection master;
......
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
**** On Master ****
CREATE TABLE t1 (b CHAR(10));
**** On Slave ****
STOP SLAVE;
**** On Master ****
LOAD DATA INFILE FILENAME
SELECT COUNT(*) FROM t1;
COUNT(*)
3
SHOW BINLOG EVENTS;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Format_desc 1 # Server ver: #
master-bin.000001 # Query 1 # use `test`; CREATE TABLE t1 (b CHAR(10))
master-bin.000001 # Begin_load_query 1 # ;file_id=#;block_len=#
master-bin.000001 # Execute_load_query 1 # use `test`; LOAD DATA INFILE FILENAME ;file_id=#
**** On Slave ****
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
SELECT COUNT(*) FROM t1;
COUNT(*)
0
**** On Master ****
DROP TABLE t1;
# Bug#12691: Exec_master_log_pos corrupted with SQL_SLAVE_SKIP_COUNTER
# Date: 01/31/2008
# Added: Serge Kozlov <skozlov@mysql.com>
--source include/master-slave.inc
--connection master
--source include/have_binlog_format_mixed_or_statement.inc
--echo
--echo **** On Master ****
CREATE TABLE t1 (b CHAR(10));
--echo
--echo **** On Slave ****
--sync_slave_with_master
STOP SLAVE;
--source include/wait_for_slave_to_stop.inc
--connection master
--echo
--echo **** On Master ****
--exec cp $MYSQL_TEST_DIR/suite/bugs/data/rpl_bug12691.dat $MYSQLTEST_VARDIR/tmp/
--echo LOAD DATA INFILE FILENAME
--disable_query_log
--eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/rpl_bug12691.dat' INTO TABLE t1 FIELDS TERMINATED BY '|'
--enable_query_log
--remove_file $MYSQLTEST_VARDIR/tmp/rpl_bug12691.dat
SELECT COUNT(*) FROM t1;
--replace_column 2 # 5 #
--replace_regex /Server ver: .+/Server ver: #/ /table_id: [0-9]+/table_id: #/ /COMMIT.+xid=[0-9]+.+/#/ /file_id=[0-9]+/file_id=#/ /block_len=[0-9]+/block_len=#/ /'.+'/FILENAME/
SHOW BINLOG EVENTS;
--save_master_pos
--connection slave
--echo
--echo **** On Slave ****
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
--source include/wait_for_slave_to_start.inc
--sync_with_master
SELECT COUNT(*) FROM t1;
# Clean up
--connection master
--echo
--echo **** On Master ****
DROP TABLE t1;
--sync_slave_with_master
...@@ -26,7 +26,7 @@ ADD x BIT(3) DEFAULT b'011', ...@@ -26,7 +26,7 @@ ADD x BIT(3) DEFAULT b'011',
ADD y BIT(5) DEFAULT b'10101', ADD y BIT(5) DEFAULT b'10101',
ADD z BIT(2) DEFAULT b'10'; ADD z BIT(2) DEFAULT b'10';
ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test'; ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test';
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;
ALTER TABLE t2 DROP b; ALTER TABLE t2 DROP b;
ALTER TABLE t4 MODIFY a FLOAT; ALTER TABLE t4 MODIFY a FLOAT;
ALTER TABLE t5 MODIFY b FLOAT; ALTER TABLE t5 MODIFY b FLOAT;
...@@ -393,8 +393,8 @@ INSERT INTO t1_nodef VALUES (1,2); ...@@ -393,8 +393,8 @@ INSERT INTO t1_nodef VALUES (1,2);
INSERT INTO t1_nodef VALUES (2,4); INSERT INTO t1_nodef VALUES (2,4);
SET SQL_LOG_BIN=1; SET SQL_LOG_BIN=1;
**** On Slave **** **** On Slave ****
INSERT INTO t1_nodef VALUES (1,2,3); INSERT INTO t1_nodef VALUES (1,2,3,4,5);
INSERT INTO t1_nodef VALUES (2,4,6); INSERT INTO t1_nodef VALUES (2,4,6,8,10);
**** On Master **** **** On Master ****
UPDATE t1_nodef SET b=2*b WHERE a=1; UPDATE t1_nodef SET b=2*b WHERE a=1;
SELECT * FROM t1_nodef ORDER BY a; SELECT * FROM t1_nodef ORDER BY a;
...@@ -403,9 +403,9 @@ a b ...@@ -403,9 +403,9 @@ a b
2 4 2 4
**** On Slave **** **** On Slave ****
SELECT * FROM t1_nodef ORDER BY a; SELECT * FROM t1_nodef ORDER BY a;
a b x a b x y z
1 4 3 1 4 3 4 5
2 4 6 2 4 6 8 10
**** On Master **** **** On Master ****
DELETE FROM t1_nodef WHERE a=2; DELETE FROM t1_nodef WHERE a=2;
SELECT * FROM t1_nodef ORDER BY a; SELECT * FROM t1_nodef ORDER BY a;
...@@ -413,8 +413,8 @@ a b ...@@ -413,8 +413,8 @@ a b
1 4 1 4
**** On Slave **** **** On Slave ****
SELECT * FROM t1_nodef ORDER BY a; SELECT * FROM t1_nodef ORDER BY a;
a b x a b x y z
1 4 3 1 4 3 4 5
**** Cleanup **** **** Cleanup ****
DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef;
DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t7,t8,t9; DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t7,t8,t9;
......
...@@ -26,7 +26,7 @@ ADD x BIT(3) DEFAULT b'011', ...@@ -26,7 +26,7 @@ ADD x BIT(3) DEFAULT b'011',
ADD y BIT(5) DEFAULT b'10101', ADD y BIT(5) DEFAULT b'10101',
ADD z BIT(2) DEFAULT b'10'; ADD z BIT(2) DEFAULT b'10';
ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test'; ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test';
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;
ALTER TABLE t2 DROP b; ALTER TABLE t2 DROP b;
ALTER TABLE t4 MODIFY a FLOAT; ALTER TABLE t4 MODIFY a FLOAT;
ALTER TABLE t5 MODIFY b FLOAT; ALTER TABLE t5 MODIFY b FLOAT;
...@@ -393,8 +393,8 @@ INSERT INTO t1_nodef VALUES (1,2); ...@@ -393,8 +393,8 @@ INSERT INTO t1_nodef VALUES (1,2);
INSERT INTO t1_nodef VALUES (2,4); INSERT INTO t1_nodef VALUES (2,4);
SET SQL_LOG_BIN=1; SET SQL_LOG_BIN=1;
**** On Slave **** **** On Slave ****
INSERT INTO t1_nodef VALUES (1,2,3); INSERT INTO t1_nodef VALUES (1,2,3,4,5);
INSERT INTO t1_nodef VALUES (2,4,6); INSERT INTO t1_nodef VALUES (2,4,6,8,10);
**** On Master **** **** On Master ****
UPDATE t1_nodef SET b=2*b WHERE a=1; UPDATE t1_nodef SET b=2*b WHERE a=1;
SELECT * FROM t1_nodef ORDER BY a; SELECT * FROM t1_nodef ORDER BY a;
...@@ -403,9 +403,9 @@ a b ...@@ -403,9 +403,9 @@ a b
2 4 2 4
**** On Slave **** **** On Slave ****
SELECT * FROM t1_nodef ORDER BY a; SELECT * FROM t1_nodef ORDER BY a;
a b x a b x y z
1 4 3 1 4 3 4 5
2 4 6 2 4 6 8 10
**** On Master **** **** On Master ****
DELETE FROM t1_nodef WHERE a=2; DELETE FROM t1_nodef WHERE a=2;
SELECT * FROM t1_nodef ORDER BY a; SELECT * FROM t1_nodef ORDER BY a;
...@@ -413,8 +413,8 @@ a b ...@@ -413,8 +413,8 @@ a b
1 4 1 4
**** On Slave **** **** On Slave ****
SELECT * FROM t1_nodef ORDER BY a; SELECT * FROM t1_nodef ORDER BY a;
a b x a b x y z
1 4 3 1 4 3 4 5
**** Cleanup **** **** Cleanup ****
DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef;
DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t7,t8,t9; DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t7,t8,t9;
......
...@@ -99,27 +99,51 @@ static const char *HA_ERR(int i) ...@@ -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_RECORD_IS_THE_SAME: return "HA_ERR_RECORD_IS_THE_SAME";
case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE"; case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE";
case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT"; case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT";
case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY";
} }
return 0; 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, static void inline slave_rows_error_report(enum loglevel level, int ha_error,
Relay_log_info const *rli, THD *thd, Relay_log_info const *rli, THD *thd,
TABLE *table, const char * type, TABLE *table, const char * type,
const char *log_name, ulong pos) 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, rli->report(level, thd->net.last_errno,
"Could not execute %s event on table %s.%s;" "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", "the event's master log %s, end_log_pos %lu",
type, table->s->db.str, type, table->s->db.str,
table->s->table_name.str, table->s->table_name.str,
thd->net.last_error[0] != 0 ? thd->net.last_error : "", buff,
thd->net.last_error[0] != 0 ? ";" : "",
handler_error == NULL? "<unknown>" : handler_error, handler_error == NULL? "<unknown>" : handler_error,
log_name, pos); log_name, pos);
} }
...@@ -7675,7 +7699,7 @@ Rows_log_event::write_row(const Relay_log_info *const rli, ...@@ -7675,7 +7699,7 @@ Rows_log_event::write_row(const Relay_log_info *const rli,
/* fill table->record[0] with default values */ /* 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 */))) TRUE /* check if columns have def. values */)))
DBUG_RETURN(error); DBUG_RETURN(error);
...@@ -7990,13 +8014,17 @@ int Rows_log_event::find_row(const Relay_log_info *rli) ...@@ -7990,13 +8014,17 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
DBUG_ASSERT(m_table && m_table->in_use != NULL); DBUG_ASSERT(m_table && m_table->in_use != NULL);
TABLE *table= m_table; TABLE *table= m_table;
int error; int error= 0;
/* 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 */); rpl_row_tabledefs.test specifies that
error= unpack_current_row(rli); 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 #ifndef DBUG_OFF
DBUG_PRINT("info",("looking for the following record")); DBUG_PRINT("info",("looking for the following record"));
......
...@@ -3131,6 +3131,8 @@ class Rows_log_event : public Log_event ...@@ -3131,6 +3131,8 @@ class Rows_log_event : public Log_event
ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT); 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, int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols,
&m_curr_row_end, &m_master_reclength); &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); ASSERT_OR_RETURN_ERROR(m_curr_row_end <= m_rows_end, HA_ERR_CORRUPT_EVENT);
return result; return result;
} }
......
...@@ -2077,7 +2077,7 @@ Old_rows_log_event::write_row(const Relay_log_info *const rli, ...@@ -2077,7 +2077,7 @@ Old_rows_log_event::write_row(const Relay_log_info *const rli,
/* fill table->record[0] with default values */ /* 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 */))) TRUE /* check if columns have def. values */)))
DBUG_RETURN(error); DBUG_RETURN(error);
...@@ -2288,7 +2288,7 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) ...@@ -2288,7 +2288,7 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli)
/* unpack row - missing fields get default values */ /* unpack row - missing fields get default values */
// TODO: shall we check and report errors here? // 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); error= unpack_current_row(rli);
#ifndef DBUG_OFF #ifndef DBUG_OFF
......
...@@ -307,17 +307,15 @@ unpack_row(Relay_log_info const *rli, ...@@ -307,17 +307,15 @@ unpack_row(Relay_log_info const *rli,
If @c check is true, fields are explicitly initialized only if they have If @c check is true, fields are explicitly initialized only if they have
default value or can be NULL. Otherwise error is reported. 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 table Table whose record[0] buffer is prepared.
@param skip Number of columns for which default value initialization @param skip Number of columns for which default value initialization
should be skipped. should be skipped.
@param check Indicates if errors should be checked when setting default @param check Indicates if errors should be checked when setting default
values. values.
@returns 0 on success. @returns 0 on success or a handler level error code
*/ */
int prepare_record(const Slave_reporting_capability *const log, int prepare_record(TABLE *const table,
TABLE *const table,
const uint skip, const bool check) const uint skip, const bool check)
{ {
DBUG_ENTER("prepare_record"); DBUG_ENTER("prepare_record");
...@@ -337,13 +335,8 @@ int prepare_record(const Slave_reporting_capability *const log, ...@@ -337,13 +335,8 @@ int prepare_record(const Slave_reporting_capability *const log,
if (check && ((f->flags & mask) == mask)) if (check && ((f->flags & mask) == mask))
{ {
DBUG_ASSERT(log); my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), f->field_name);
log->report(ERROR_LEVEL, ER_NO_DEFAULT_FOR_FIELD, error = HA_ERR_ROWS_EVENT_APPLY;
"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;
} }
else else
f->set_default(); f->set_default();
......
...@@ -30,8 +30,7 @@ int unpack_row(Relay_log_info const *rli, ...@@ -30,8 +30,7 @@ int unpack_row(Relay_log_info const *rli,
uchar const **const row_end, ulong *const master_reclength); uchar const **const row_end, ulong *const master_reclength);
// Fill table's record[0] with default values. // Fill table's record[0] with default values.
int prepare_record(const Slave_reporting_capability *const, TABLE *const, int prepare_record(TABLE *const, const uint =0, const bool =FALSE);
const uint =0, const bool =FALSE);
#endif #endif
#endif #endif
...@@ -6119,3 +6119,5 @@ ER_SLAVE_AMBIGOUS_EXEC_MODE ...@@ -6119,3 +6119,5 @@ ER_SLAVE_AMBIGOUS_EXEC_MODE
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT
eng "The BINLOG statement of type `%s` was not preceded by a format description 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"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment