Commit 921e3fe8 authored by Andrei Elkin's avatar Andrei Elkin

Bug#42977 RBR logs for rows with more than 250 column results in corrupt binlog

            
The issue happened to be two-fold.
The table map event was recorded into binlog having
an incorrect size when number of columns exceeded 251. 
The Row-based event had incorrect recording and restoring m_width member within
the same as above conditions.

Fixed with correcting m_data_size and m_width.
parent 18d22198
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;
DROP TABLE IF EXISTS t300;
create table t300 (
f1 int,
f2 int,
f3 int,
f4 int,
f5 int,
f6 int,
f7 int,
f8 int,
f9 int,
f10 int,
f11 int,
f12 int,
f13 int,
f14 int,
f15 int,
f16 int,
f17 int,
f18 int,
f19 int,
f20 int,
f21 int,
f22 int,
f23 int,
f24 int,
f25 int,
f26 int,
f27 int,
f28 int,
f29 int,
f30 int,
f31 int,
f32 int,
f33 int,
f34 int,
f35 int,
f36 int,
f37 int,
f38 int,
f39 int,
f40 int,
f41 int,
f42 int,
f43 int,
f44 int,
f45 int,
f46 int,
f47 int,
f48 int,
f49 int,
f50 int,
f51 int,
f52 int,
f53 int,
f54 int,
f55 int,
f56 int,
f57 int,
f58 int,
f59 int,
f60 int,
f61 int,
f62 int,
f63 int,
f64 int,
f65 int,
f66 int,
f67 int,
f68 int,
f69 int,
f70 int,
f71 int,
f72 int,
f73 int,
f74 int,
f75 int,
f76 int,
f77 int,
f78 int,
f79 int,
f80 int,
f81 int,
f82 int,
f83 int,
f84 int,
f85 int,
f86 int,
f87 int,
f88 int,
f89 int,
f90 int,
f91 int,
f92 int,
f93 int,
f94 int,
f95 int,
f96 int,
f97 int,
f98 int,
f99 int,
f100 int,
f101 int,
f102 int,
f103 int,
f104 int,
f105 int,
f106 int,
f107 int,
f108 int,
f109 int,
f110 int,
f111 int,
f112 int,
f113 int,
f114 int,
f115 int,
f116 int,
f117 int,
f118 int,
f119 int,
f120 int,
f121 int,
f122 int,
f123 int,
f124 int,
f125 int,
f126 int,
f127 int,
f128 int,
f129 int,
f130 int,
f131 int,
f132 int,
f133 int,
f134 int,
f135 int,
f136 int,
f137 int,
f138 int,
f139 int,
f140 int,
f141 int,
f142 int,
f143 int,
f144 int,
f145 int,
f146 int,
f147 int,
f148 int,
f149 int,
f150 int,
f151 int,
f152 int,
f153 int,
f154 int,
f155 int,
f156 int,
f157 int,
f158 int,
f159 int,
f160 int,
f161 int,
f162 int,
f163 int,
f164 int,
f165 int,
f166 int,
f167 int,
f168 int,
f169 int,
f170 int,
f171 int,
f172 int,
f173 int,
f174 int,
f175 int,
f176 int,
f177 int,
f178 int,
f179 int,
f180 int,
f181 int,
f182 int,
f183 int,
f184 int,
f185 int,
f186 int,
f187 int,
f188 int,
f189 int,
f190 int,
f191 int,
f192 int,
f193 int,
f194 int,
f195 int,
f196 int,
f197 int,
f198 int,
f199 int,
f200 int,
f201 int,
f202 int,
f203 int,
f204 int,
f205 int,
f206 int,
f207 int,
f208 int,
f209 int,
f210 int,
f211 int,
f212 int,
f213 int,
f214 int,
f215 int,
f216 int,
f217 int,
f218 int,
f219 int,
f220 int,
f221 int,
f222 int,
f223 int,
f224 int,
f225 int,
f226 int,
f227 int,
f228 int,
f229 int,
f230 int,
f231 int,
f232 int,
f233 int,
f234 int,
f235 int,
f236 int,
f237 int,
f238 int,
f239 int,
f240 int,
f241 int,
f242 int,
f243 int,
f244 int,
f245 int,
f246 int,
f247 int,
f248 int,
f249 int,
f250 int,
f251 int,
f252 int,
f253 int,
f254 int,
f255 int,
f256 int,
f257 int,
f258 int,
f259 int,
f260 int,
f261 int,
f262 int,
f263 int,
f264 int,
f265 int,
f266 int,
f267 int,
f268 int,
f269 int,
f270 int,
f271 int,
f272 int,
f273 int,
f274 int,
f275 int,
f276 int,
f277 int,
f278 int,
f279 int,
f280 int,
f281 int,
f282 int,
f283 int,
f284 int,
f285 int,
f286 int,
f287 int,
f288 int,
f289 int,
f290 int,
f291 int,
f292 int,
f293 int,
f294 int,
f295 int,
f296 int,
f297 int,
f298 int,
f299 int,
f300 int,
primary key (f1));
insert into t300 set f1= 1;
select f300 from t300;
f300
NULL
select count(*) as one from t300;
one
1
*** Cleanup ***
DROP TABLE t300;
##################################################################
# rpl_row_wide_table
#
# This test verifies that the table with number of attributes more
# than 250 is replicated.
# Related bugs:
# Bug #42977 RBR logs for rows with more than 250 column results
# in corrupt binlog
##################################################################
-- source include/master-slave.inc
-- source include/have_binlog_format_row.inc
--disable_warnings
DROP TABLE IF EXISTS t300;
--enable_warnings
connection master;
create table t300 (
f1 int,
f2 int,
f3 int,
f4 int,
f5 int,
f6 int,
f7 int,
f8 int,
f9 int,
f10 int,
f11 int,
f12 int,
f13 int,
f14 int,
f15 int,
f16 int,
f17 int,
f18 int,
f19 int,
f20 int,
f21 int,
f22 int,
f23 int,
f24 int,
f25 int,
f26 int,
f27 int,
f28 int,
f29 int,
f30 int,
f31 int,
f32 int,
f33 int,
f34 int,
f35 int,
f36 int,
f37 int,
f38 int,
f39 int,
f40 int,
f41 int,
f42 int,
f43 int,
f44 int,
f45 int,
f46 int,
f47 int,
f48 int,
f49 int,
f50 int,
f51 int,
f52 int,
f53 int,
f54 int,
f55 int,
f56 int,
f57 int,
f58 int,
f59 int,
f60 int,
f61 int,
f62 int,
f63 int,
f64 int,
f65 int,
f66 int,
f67 int,
f68 int,
f69 int,
f70 int,
f71 int,
f72 int,
f73 int,
f74 int,
f75 int,
f76 int,
f77 int,
f78 int,
f79 int,
f80 int,
f81 int,
f82 int,
f83 int,
f84 int,
f85 int,
f86 int,
f87 int,
f88 int,
f89 int,
f90 int,
f91 int,
f92 int,
f93 int,
f94 int,
f95 int,
f96 int,
f97 int,
f98 int,
f99 int,
f100 int,
f101 int,
f102 int,
f103 int,
f104 int,
f105 int,
f106 int,
f107 int,
f108 int,
f109 int,
f110 int,
f111 int,
f112 int,
f113 int,
f114 int,
f115 int,
f116 int,
f117 int,
f118 int,
f119 int,
f120 int,
f121 int,
f122 int,
f123 int,
f124 int,
f125 int,
f126 int,
f127 int,
f128 int,
f129 int,
f130 int,
f131 int,
f132 int,
f133 int,
f134 int,
f135 int,
f136 int,
f137 int,
f138 int,
f139 int,
f140 int,
f141 int,
f142 int,
f143 int,
f144 int,
f145 int,
f146 int,
f147 int,
f148 int,
f149 int,
f150 int,
f151 int,
f152 int,
f153 int,
f154 int,
f155 int,
f156 int,
f157 int,
f158 int,
f159 int,
f160 int,
f161 int,
f162 int,
f163 int,
f164 int,
f165 int,
f166 int,
f167 int,
f168 int,
f169 int,
f170 int,
f171 int,
f172 int,
f173 int,
f174 int,
f175 int,
f176 int,
f177 int,
f178 int,
f179 int,
f180 int,
f181 int,
f182 int,
f183 int,
f184 int,
f185 int,
f186 int,
f187 int,
f188 int,
f189 int,
f190 int,
f191 int,
f192 int,
f193 int,
f194 int,
f195 int,
f196 int,
f197 int,
f198 int,
f199 int,
f200 int,
f201 int,
f202 int,
f203 int,
f204 int,
f205 int,
f206 int,
f207 int,
f208 int,
f209 int,
f210 int,
f211 int,
f212 int,
f213 int,
f214 int,
f215 int,
f216 int,
f217 int,
f218 int,
f219 int,
f220 int,
f221 int,
f222 int,
f223 int,
f224 int,
f225 int,
f226 int,
f227 int,
f228 int,
f229 int,
f230 int,
f231 int,
f232 int,
f233 int,
f234 int,
f235 int,
f236 int,
f237 int,
f238 int,
f239 int,
f240 int,
f241 int,
f242 int,
f243 int,
f244 int,
f245 int,
f246 int,
f247 int,
f248 int,
f249 int,
f250 int,
f251 int,
f252 int,
f253 int,
f254 int,
f255 int,
f256 int,
f257 int,
f258 int,
f259 int,
f260 int,
f261 int,
f262 int,
f263 int,
f264 int,
f265 int,
f266 int,
f267 int,
f268 int,
f269 int,
f270 int,
f271 int,
f272 int,
f273 int,
f274 int,
f275 int,
f276 int,
f277 int,
f278 int,
f279 int,
f280 int,
f281 int,
f282 int,
f283 int,
f284 int,
f285 int,
f286 int,
f287 int,
f288 int,
f289 int,
f290 int,
f291 int,
f292 int,
f293 int,
f294 int,
f295 int,
f296 int,
f297 int,
f298 int,
f299 int,
f300 int,
primary key (f1));
insert into t300 set f1= 1;
sync_slave_with_master;
#
# prove that slave processed the create as well as the insert
#
eval select f300 from t300;
select count(*) as one from t300;
--echo *** Cleanup ***
connection master;
DROP TABLE t300;
sync_slave_with_master;
# END of Test Case
...@@ -6993,8 +6993,8 @@ int Rows_log_event::get_data_size() ...@@ -6993,8 +6993,8 @@ int Rows_log_event::get_data_size()
{ {
int const type_code= get_type_code(); int const type_code= get_type_code();
uchar buf[sizeof(m_width)+1]; uchar buf[sizeof(m_width) + 1];
uchar *end= net_store_length(buf, (m_width + 7) / 8); uchar *end= net_store_length(buf, m_width);
DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
return 6 + no_bytes_in_map(&m_cols) + (end - buf) + return 6 + no_bytes_in_map(&m_cols) + (end - buf) +
...@@ -7583,7 +7583,7 @@ bool Rows_log_event::write_data_body(IO_CACHE*file) ...@@ -7583,7 +7583,7 @@ bool Rows_log_event::write_data_body(IO_CACHE*file)
Note that this should be the number of *bits*, not the number of Note that this should be the number of *bits*, not the number of
bytes. bytes.
*/ */
uchar sbuf[sizeof(m_width)]; uchar sbuf[sizeof(m_width) + 1];
my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf; my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
bool res= false; bool res= false;
uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width); uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
...@@ -7745,6 +7745,8 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, ...@@ -7745,6 +7745,8 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
m_null_bits(0), m_null_bits(0),
m_meta_memory(NULL) m_meta_memory(NULL)
{ {
uchar cbuf[sizeof(m_colcnt) + 1];
uchar *cbuf_end;
DBUG_ASSERT(m_table_id != ~0UL); DBUG_ASSERT(m_table_id != ~0UL);
/* /*
In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in
...@@ -7761,7 +7763,9 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, ...@@ -7761,7 +7763,9 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", m_data_size= 6;); DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", m_data_size= 6;);
m_data_size+= m_dblen + 2; // Include length and terminating \0 m_data_size+= m_dblen + 2; // Include length and terminating \0
m_data_size+= m_tbllen + 2; // Include length and terminating \0 m_data_size+= m_tbllen + 2; // Include length and terminating \0
m_data_size+= 1 + m_colcnt; // COLCNT and column types cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
DBUG_ASSERT((cbuf_end - cbuf) <= sizeof(cbuf));
m_data_size+= (cbuf_end - cbuf) + m_colcnt; // COLCNT and column types
/* If malloc fails, caught in is_valid() */ /* If malloc fails, caught in is_valid() */
if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME)))) if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME))))
...@@ -8053,7 +8057,7 @@ bool Table_map_log_event::write_data_body(IO_CACHE *file) ...@@ -8053,7 +8057,7 @@ bool Table_map_log_event::write_data_body(IO_CACHE *file)
uchar const dbuf[]= { (uchar) m_dblen }; uchar const dbuf[]= { (uchar) m_dblen };
uchar const tbuf[]= { (uchar) m_tbllen }; uchar const tbuf[]= { (uchar) m_tbllen };
uchar cbuf[sizeof(m_colcnt)]; uchar cbuf[sizeof(m_colcnt) + 1];
uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt); uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf)); DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
......
...@@ -294,12 +294,14 @@ namespace { ...@@ -294,12 +294,14 @@ namespace {
} }
#endif #endif
// NB. number of printed bit values is limited to sizeof(buf) - 1
#define DBUG_PRINT_BITSET(N,FRM,BS) \ #define DBUG_PRINT_BITSET(N,FRM,BS) \
do { \ do { \
char buf[256]; \ char buf[256]; \
for (uint i = 0 ; i < (BS)->n_bits ; ++i) \ uint i; \
for (i = 0 ; i < min(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
buf[i] = bitmap_is_set((BS), i) ? '1' : '0'; \ buf[i] = bitmap_is_set((BS), i) ? '1' : '0'; \
buf[(BS)->n_bits] = '\0'; \ buf[i] = '\0'; \
DBUG_PRINT((N), ((FRM), buf)); \ DBUG_PRINT((N), ((FRM), buf)); \
} while (0) } while (0)
......
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