Commit fc17829b authored by unknown's avatar unknown

Bug#22540: Incorrect value in column End_log_pos of SHOW BINLOG EVENTS using InnoDB

previous correction didn't. make sure "tail" is fixed up
when filling cache several times; rework formulae.
---
Merge sin.intern.azundris.com:/home/tnurnberg/22540/50-22540
into  sin.intern.azundris.com:/home/tnurnberg/22540/51-22540


mysql-test/extra/binlog_tests/binlog.test:
  Bug#22540: Incorrect value in column End_log_pos of SHOW BINLOG EVENTS using InnoDB
  
  show that fix for absolute end_log_pos in binlog also
  works when cache is read several times and headers are
  split across that boundary
  
  show that end_log_pos in SHOW BINLOG EVENTS is correct even in transactions.
  show that SHOW MASTER STATUS returns correct values while in transactions
  (so that mysqldump --master-data will work correctly).
  also remove bdb dependency.
mysql-test/r/binlog_row_binlog.result:
  Bug#22540: Incorrect value in column End_log_pos of SHOW BINLOG EVENTS using InnoDB
  
  show that fix for absolute end_log_pos in binlog also
  works when cache is read several times and headers are
  split across that boundary
  
  show that end_log_pos in SHOW BINLOG EVENTS is correct even in transactions.
  show that SHOW MASTER STATUS returns correct values while in transactions
  (so that mysqldump --master-data will work correctly).
  also remove bdb dependency.
mysql-test/r/binlog_stm_binlog.result:
  Bug#22540: Incorrect value in column End_log_pos of SHOW BINLOG EVENTS using InnoDB
  
  show that fix for absolute end_log_pos in binlog also
  works when cache is read several times and headers are
  split across that boundary
  
  show that end_log_pos in SHOW BINLOG EVENTS is correct even in transactions.
  show that SHOW MASTER STATUS returns correct values while in transactions
  (so that mysqldump --master-data will work correctly).
  also remove bdb dependency.
mysql-test/r/rpl_row_create_table.result:
  Bug#22540: Incorrect value in column End_log_pos of SHOW BINLOG EVENTS using InnoDB
  
  expect corrent end_log_pos in binlog
sql/log.cc:
  Bug#22540: Incorrect value in column End_log_pos of SHOW BINLOG EVENTS using InnoDB
  
  previous correction didn't. make sure "tail" is fixed up
  when filling cache several times; rework formulae.
parent 6ebf44d3
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
-- source include/have_log_bin.inc -- source include/have_log_bin.inc
-- source include/not_embedded.inc -- source include/not_embedded.inc
-- source include/have_innodb.inc -- source include/have_innodb.inc
-- source include/have_log_bin.inc
-- source include/have_debug.inc -- source include/have_debug.inc
--disable_warnings --disable_warnings
...@@ -139,6 +138,36 @@ show binlog events from 0; ...@@ -139,6 +138,36 @@ show binlog events from 0;
set session autocommit = @ac; set session autocommit = @ac;
# now show that nothing breaks if we need to read from the cache more
# than once, resulting in split event-headers
set @bcs = @@binlog_cache_size;
set @ac = @@autocommit;
set global binlog_cache_size=4096;
set autocommit= 0;
reset master;
create table t1 (a int) engine=innodb;
let $1=400;
disable_query_log;
begin;
while ($1)
{
eval insert into t1 values( $1 );
dec $1;
}
commit;
enable_query_log;
show binlog events from 0;
drop table t1;
set global binlog_cache_size=@bcs;
set session autocommit = @ac;
--echo End of 5.0 tests --echo End of 5.0 tests
# Test of a too big SET INSERT_ID: see if the truncated value goes # Test of a too big SET INSERT_ID: see if the truncated value goes
......
This diff is collapsed.
This diff is collapsed.
...@@ -279,25 +279,25 @@ Log_name Pos Event_type Server_id End_log_pos Info ...@@ -279,25 +279,25 @@ Log_name Pos Event_type Server_id End_log_pos Info
# 192 Table_map # 231 table_id: # (test.t1) # 192 Table_map # 231 table_id: # (test.t1)
# 231 Write_rows # 275 table_id: # flags: STMT_END_F # 231 Write_rows # 275 table_id: # flags: STMT_END_F
# 275 Query # 343 use `test`; BEGIN # 275 Query # 343 use `test`; BEGIN
# 343 Query # 125 use `test`; CREATE TABLE `t2` ( # 343 Query # 468 use `test`; CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL `a` int(11) DEFAULT NULL
) ENGINE=InnoDB ) ENGINE=InnoDB
# 468 Table_map # 164 table_id: # (test.t2) # 468 Table_map # 507 table_id: # (test.t2)
# 507 Write_rows # 208 table_id: # flags: STMT_END_F # 507 Write_rows # 551 table_id: # flags: STMT_END_F
# 551 Xid # 578 COMMIT /* XID */ # 551 Xid # 578 COMMIT /* XID */
# 578 Query # 646 use `test`; BEGIN # 578 Query # 646 use `test`; BEGIN
# 646 Query # 125 use `test`; CREATE TABLE `t3` ( # 646 Query # 771 use `test`; CREATE TABLE `t3` (
`a` int(11) DEFAULT NULL `a` int(11) DEFAULT NULL
) ENGINE=InnoDB ) ENGINE=InnoDB
# 771 Table_map # 164 table_id: # (test.t3) # 771 Table_map # 810 table_id: # (test.t3)
# 810 Write_rows # 208 table_id: # flags: STMT_END_F # 810 Write_rows # 854 table_id: # flags: STMT_END_F
# 854 Xid # 881 COMMIT /* XID */ # 854 Xid # 881 COMMIT /* XID */
# 881 Query # 949 use `test`; BEGIN # 881 Query # 949 use `test`; BEGIN
# 949 Query # 125 use `test`; CREATE TABLE `t4` ( # 949 Query # 1074 use `test`; CREATE TABLE `t4` (
`a` int(11) DEFAULT NULL `a` int(11) DEFAULT NULL
) ENGINE=InnoDB ) ENGINE=InnoDB
# 1074 Table_map # 164 table_id: # (test.t4) # 1074 Table_map # 1113 table_id: # (test.t4)
# 1113 Write_rows # 208 table_id: # flags: STMT_END_F # 1113 Write_rows # 1157 table_id: # flags: STMT_END_F
# 1157 Xid # 1184 COMMIT /* XID */ # 1157 Xid # 1184 COMMIT /* XID */
# 1184 Table_map # 1223 table_id: # (test.t1) # 1184 Table_map # 1223 table_id: # (test.t1)
# 1223 Write_rows # 1267 table_id: # flags: STMT_END_F # 1223 Write_rows # 1267 table_id: # flags: STMT_END_F
...@@ -371,10 +371,10 @@ Log_name Pos Event_type Server_id End_log_pos Info ...@@ -371,10 +371,10 @@ Log_name Pos Event_type Server_id End_log_pos Info
# 231 Write_rows # 275 table_id: # flags: STMT_END_F # 231 Write_rows # 275 table_id: # flags: STMT_END_F
# 275 Query # 375 use `test`; CREATE TABLE t2 (a INT) ENGINE=INNODB # 275 Query # 375 use `test`; CREATE TABLE t2 (a INT) ENGINE=INNODB
# 375 Query # 443 use `test`; BEGIN # 375 Query # 443 use `test`; BEGIN
# 443 Table_map # 39 table_id: # (test.t2) # 443 Table_map # 482 table_id: # (test.t2)
# 482 Write_rows # 83 table_id: # flags: STMT_END_F # 482 Write_rows # 526 table_id: # flags: STMT_END_F
# 526 Table_map # 122 table_id: # (test.t2) # 526 Table_map # 565 table_id: # (test.t2)
# 565 Write_rows # 161 table_id: # flags: STMT_END_F # 565 Write_rows # 604 table_id: # flags: STMT_END_F
# 604 Xid # 631 COMMIT /* XID */ # 604 Xid # 631 COMMIT /* XID */
SELECT * FROM t2 ORDER BY a; SELECT * FROM t2 ORDER BY a;
a a
...@@ -396,7 +396,7 @@ SELECT * FROM t2 ORDER BY a; ...@@ -396,7 +396,7 @@ SELECT * FROM t2 ORDER BY a;
a a
SHOW BINLOG EVENTS FROM 631; SHOW BINLOG EVENTS FROM 631;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
# 631 Query # 80 use `test`; TRUNCATE TABLE t2 # 631 Query # 711 use `test`; TRUNCATE TABLE t2
# 711 Xid # 738 COMMIT /* XID */ # 711 Xid # 738 COMMIT /* XID */
SELECT * FROM t2 ORDER BY a; SELECT * FROM t2 ORDER BY a;
a a
......
...@@ -3995,58 +3995,61 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log) ...@@ -3995,58 +3995,61 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log)
memcpy((char *)cache->read_pos, &header[carry], LOG_EVENT_HEADER_LEN - carry); memcpy((char *)cache->read_pos, &header[carry], LOG_EVENT_HEADER_LEN - carry);
/* next event header at ... */ /* next event header at ... */
hdr_offs = LOG_EVENT_HEADER_LEN - carry + hdr_offs = uint4korr(&header[EVENT_LEN_OFFSET]) - carry;
uint4korr(&header[EVENT_LEN_OFFSET]);
carry= 0; carry= 0;
} }
/* if there is anything to write, process it. */ /* if there is anything to write, process it. */
if(likely(bytes > 0)) if (likely(bytes > 0))
{ {
/* /*
next header beyond current read-buffer? we'll get it later process all event-headers in this (partial) cache.
(though not necessarily in the very next iteration). if next header is beyond current read-buffer,
we'll get it later (though not necessarily in the
very next iteration, just "eventually").
*/ */
if (hdr_offs >= bytes) while (hdr_offs < bytes)
hdr_offs -= bytes;
else
{ {
/*
partial header only? save what we can get, process once
we get the rest.
*/
/* process all event-headers in this (partial) cache. */ if (hdr_offs + LOG_EVENT_HEADER_LEN > bytes)
{
do { carry= bytes - hdr_offs;
memcpy(header, (char *)cache->read_pos + hdr_offs, carry);
/* bytes= hdr_offs;
partial header only? save what we can get, process once }
we get the rest. else
*/ {
/* we've got a full event-header, and it came in one piece */
if (hdr_offs + LOG_EVENT_HEADER_LEN > bytes)
{
carry= bytes - hdr_offs;
memcpy(header, (char *)cache->read_pos + hdr_offs, carry);
bytes= hdr_offs;
}
else
{
/* we've got a full event-header, and it came in one piece */
uchar *log_pos= (uchar *)cache->read_pos + hdr_offs + LOG_POS_OFFSET; uchar *log_pos= (uchar *)cache->read_pos + hdr_offs + LOG_POS_OFFSET;
/* fix end_log_pos */ /* fix end_log_pos */
val= uint4korr(log_pos) + group; val= uint4korr(log_pos) + group;
int4store(log_pos, val); int4store(log_pos, val);
/* next event header at ... */ /* next event header at ... */
log_pos= (uchar *)cache->read_pos + hdr_offs + EVENT_LEN_OFFSET; log_pos= (uchar *)cache->read_pos + hdr_offs + EVENT_LEN_OFFSET;
hdr_offs += uint4korr(log_pos); hdr_offs += uint4korr(log_pos);
} }
} while (hdr_offs < bytes);
} }
/*
Adjust hdr_offs. Note that this doesn't mean it will necessarily
be valid in the next iteration; if the current event is very long,
it may take a couple of read-iterations (and subsequent fixings
of hdr_offs) for it to become valid again.
if we had a split header, hdr_offs was already fixed above.
*/
if (carry == 0)
hdr_offs -= bytes;
} }
/* Write data to the binary log file */ /* Write data to the binary log file */
......
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