mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
BUG#31583 (5.1-telco-6.1 -> 5.1.22. Slave returns Error in unknown event):
In the patch for BUG#21842, the code for handling old rows events were refactored. There were a bug in the refactored code (possibly introduced after the patch for BUG#21842) that caused caused the refactored old events to read a columns bitmap after image even though there is no such bitmap for old events. As a result, the reading got out of sync, and started reading invalid data. This patch removes all trace of the after image column bitmap from the refactored old events and removes functions that are no longer needed because they are empty. sql/log_event.cc: Adding debug printouts and adding old rows events names to output so that they are not printed as unknown events. sql/log_event_old.cc: Adding debug printouts to see how the old events are partitioned when being decoded. Removing all traces of the column bitmap for the after image in the old events since there is none. Removing the following functions since they are no longer needed: - Update_rows_log_event_old::init() - Update_rows_log_event_old::~Update_rows_log_event_old() Removing unused local variable. sql/log_event_old.h: Removing all traces of the column bitmap for the after image in the old events since there is none. Removing the following functions since they are no longer needed: - Update_rows_log_event_old::init() - Update_rows_log_event_old::is_valid() - Update_rows_log_event_old::~Update_rows_log_event_old() Removing unused local variable. mysql-test/suite/bugs/r/rpl_bug31583.result: New BitKeeper file ``mysql-test/suite/bugs/r/rpl_bug31583.result'' mysql-test/suite/bugs/t/rpl_bug31583.test: New BitKeeper file ``mysql-test/suite/bugs/t/rpl_bug31583.test''
This commit is contained in:
parent
a196adacfd
commit
7a5f3f12bc
5 changed files with 44 additions and 90 deletions
15
mysql-test/suite/bugs/r/rpl_bug31583.result
Normal file
15
mysql-test/suite/bugs/r/rpl_bug31583.result
Normal file
|
@ -0,0 +1,15 @@
|
|||
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;
|
||||
CREATE TABLE t1 ( a INT, b INT DEFAULT -3 );
|
||||
INSERT INTO t1 VALUES (1, DEFAULT);
|
||||
UPDATE t1 SET a = 3;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a b
|
||||
3 -3
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a b
|
||||
3 -3
|
21
mysql-test/suite/bugs/t/rpl_bug31583.test
Normal file
21
mysql-test/suite/bugs/t/rpl_bug31583.test
Normal file
|
@ -0,0 +1,21 @@
|
|||
#
|
||||
# BUG#31583: 5.1-telco-6.1 -> 5.1.22. Slave returns Error in unknown event
|
||||
|
||||
# This is a problem for any update statement replicating from an old
|
||||
# server to a new server. The bug consisted of a new slave trying to
|
||||
# read two column bitmaps, but there is only one available in the old
|
||||
# format.
|
||||
|
||||
# This test case should be executed replicating from an old server to
|
||||
# a new server, so make sure you have one handy.
|
||||
|
||||
source include/master-slave.inc;
|
||||
|
||||
CREATE TABLE t1 ( a INT, b INT DEFAULT -3 );
|
||||
|
||||
INSERT INTO t1 VALUES (1, DEFAULT);
|
||||
UPDATE t1 SET a = 3;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
sync_slave_with_master;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
|
@ -490,6 +490,9 @@ const char* Log_event::get_type_str()
|
|||
case USER_VAR_EVENT: return "User var";
|
||||
case FORMAT_DESCRIPTION_EVENT: return "Format_desc";
|
||||
case TABLE_MAP_EVENT: return "Table_map";
|
||||
case PRE_GA_WRITE_ROWS_EVENT: return "Write_rows_event_old";
|
||||
case PRE_GA_UPDATE_ROWS_EVENT: return "Update_rows_event_old";
|
||||
case PRE_GA_DELETE_ROWS_EVENT: return "Delete_rows_event_old";
|
||||
case WRITE_ROWS_EVENT: return "Write_rows";
|
||||
case UPDATE_ROWS_EVENT: return "Update_rows";
|
||||
case DELETE_ROWS_EVENT: return "Delete_rows";
|
||||
|
@ -1015,6 +1018,8 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
|
|||
DBUG_ENTER("Log_event::read_log_event(char*,...)");
|
||||
DBUG_ASSERT(description_event != 0);
|
||||
DBUG_PRINT("info", ("binlog_version: %d", description_event->binlog_version));
|
||||
DBUG_DUMP("data", (unsigned char*) buf, event_len);
|
||||
|
||||
/* Check the integrity */
|
||||
if (event_len < EVENT_LEN_OFFSET ||
|
||||
buf[EVENT_TYPE_OFFSET] >= ENUM_END_EVENT ||
|
||||
|
|
|
@ -1317,6 +1317,7 @@ Old_rows_log_event::Old_rows_log_event(const char *buf, uint event_len,
|
|||
post_header_len));
|
||||
|
||||
const char *post_start= buf + common_header_len;
|
||||
DBUG_DUMP("post_header", (uchar*) post_start, post_header_len);
|
||||
post_start+= RW_MAPID_OFFSET;
|
||||
if (post_header_len == 6)
|
||||
{
|
||||
|
@ -1358,38 +1359,11 @@ Old_rows_log_event::Old_rows_log_event(const char *buf, uint event_len,
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
m_cols_ai.bitmap= m_cols.bitmap; /* See explanation in is_valid() */
|
||||
|
||||
if (event_type == PRE_GA_UPDATE_ROWS_EVENT)
|
||||
{
|
||||
DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
|
||||
|
||||
/* if bitmap_init fails, caught in is_valid() */
|
||||
if (likely(!bitmap_init(&m_cols_ai,
|
||||
m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
|
||||
m_width,
|
||||
false)))
|
||||
{
|
||||
DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
|
||||
memcpy(m_cols_ai.bitmap, ptr_after_width, (m_width + 7) / 8);
|
||||
create_last_word_mask(&m_cols_ai);
|
||||
ptr_after_width+= (m_width + 7) / 8;
|
||||
DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
|
||||
no_bytes_in_map(&m_cols_ai));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Needed because bitmap_init() does not set it to null on failure
|
||||
m_cols_ai.bitmap= 0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
}
|
||||
|
||||
const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
|
||||
|
||||
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, (ulong) data_size));
|
||||
DBUG_DUMP("rows_data", (uchar*) ptr_rows_data, data_size);
|
||||
|
||||
m_rows_buf= (uchar*) my_malloc(data_size, MYF(MY_WME));
|
||||
if (likely((bool)m_rows_buf))
|
||||
|
@ -1419,22 +1393,16 @@ Old_rows_log_event::~Old_rows_log_event()
|
|||
|
||||
int Old_rows_log_event::get_data_size()
|
||||
{
|
||||
int const type_code= get_type_code();
|
||||
|
||||
uchar buf[sizeof(m_width)+1];
|
||||
uchar *end= net_store_length(buf, (m_width + 7) / 8);
|
||||
|
||||
DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
|
||||
return 6 + no_bytes_in_map(&m_cols) + (end - buf) +
|
||||
(type_code == PRE_GA_UPDATE_ROWS_EVENT ? no_bytes_in_map(&m_cols_ai) : 0) +
|
||||
(m_rows_cur - m_rows_buf););
|
||||
int data_size= ROWS_HEADER_LEN;
|
||||
data_size+= no_bytes_in_map(&m_cols);
|
||||
data_size+= end - buf;
|
||||
|
||||
if (type_code == PRE_GA_UPDATE_ROWS_EVENT)
|
||||
data_size+= no_bytes_in_map(&m_cols_ai);
|
||||
|
||||
data_size+= (m_rows_cur - m_rows_buf);
|
||||
return data_size;
|
||||
}
|
||||
|
@ -2011,16 +1979,6 @@ bool Old_rows_log_event::write_data_body(IO_CACHE*file)
|
|||
DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
|
||||
res= res || my_b_safe_write(file, (uchar*) m_cols.bitmap,
|
||||
no_bytes_in_map(&m_cols));
|
||||
/*
|
||||
TODO[refactor write]: Remove the "down cast" here (and elsewhere).
|
||||
*/
|
||||
if (get_type_code() == PRE_GA_UPDATE_ROWS_EVENT)
|
||||
{
|
||||
DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
|
||||
no_bytes_in_map(&m_cols_ai));
|
||||
res= res || my_b_safe_write(file, (uchar*) m_cols_ai.bitmap,
|
||||
no_bytes_in_map(&m_cols_ai));
|
||||
}
|
||||
DBUG_DUMP("rows", m_rows_buf, data_size);
|
||||
res= res || my_b_safe_write(file, m_rows_buf, (size_t) data_size);
|
||||
|
||||
|
@ -2831,38 +2789,10 @@ Update_rows_log_event_old::Update_rows_log_event_old(THD *thd_arg,
|
|||
|
||||
// This constructor should not be reached.
|
||||
assert(0);
|
||||
|
||||
init(cols);
|
||||
}
|
||||
|
||||
|
||||
void Update_rows_log_event_old::init(MY_BITMAP const *cols)
|
||||
{
|
||||
/* if bitmap_init fails, caught in is_valid() */
|
||||
if (likely(!bitmap_init(&m_cols_ai,
|
||||
m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
|
||||
m_width,
|
||||
false)))
|
||||
{
|
||||
/* Cols can be zero if this is a dummy binrows event */
|
||||
if (likely(cols != NULL))
|
||||
{
|
||||
memcpy(m_cols_ai.bitmap, cols->bitmap, no_bytes_in_map(cols));
|
||||
create_last_word_mask(&m_cols_ai);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* !defined(MYSQL_CLIENT) */
|
||||
|
||||
|
||||
Update_rows_log_event_old::~Update_rows_log_event_old()
|
||||
{
|
||||
if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened
|
||||
m_cols_ai.bitmap= 0; // so no my_free in bitmap_free
|
||||
bitmap_free(&m_cols_ai); // To pair with bitmap_init().
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Constructor used by slave to read the event from the binary log.
|
||||
*/
|
||||
|
|
|
@ -175,14 +175,6 @@ protected:
|
|||
ulong m_table_id; /* Table ID */
|
||||
MY_BITMAP m_cols; /* Bitmap denoting columns available */
|
||||
ulong m_width; /* The width of the columns bitmap */
|
||||
/*
|
||||
Bitmap for columns available in the after image, if present. These
|
||||
fields are only available for Update_rows events. Observe that the
|
||||
width of both the before image COLS vector and the after image
|
||||
COLS vector is the same: the number of columns of the table on the
|
||||
master.
|
||||
*/
|
||||
MY_BITMAP m_cols_ai;
|
||||
|
||||
ulong m_master_reclength; /* Length of record on master side */
|
||||
|
||||
|
@ -442,12 +434,8 @@ public:
|
|||
Update_rows_log_event_old(THD*, TABLE*, ulong table_id,
|
||||
MY_BITMAP const *cols,
|
||||
bool is_transactional);
|
||||
|
||||
void init(MY_BITMAP const *cols);
|
||||
#endif
|
||||
|
||||
virtual ~Update_rows_log_event_old();
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
Update_rows_log_event_old(const char *buf, uint event_len,
|
||||
const Format_description_log_event *description_event);
|
||||
|
@ -466,11 +454,6 @@ public:
|
|||
}
|
||||
#endif
|
||||
|
||||
virtual bool is_valid() const
|
||||
{
|
||||
return Old_rows_log_event::is_valid() && m_cols_ai.bitmap;
|
||||
}
|
||||
|
||||
protected:
|
||||
#ifdef MYSQL_CLIENT
|
||||
void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
|
||||
|
|
Loading…
Reference in a new issue