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 ec22bd23
This diff is collapsed.
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,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
--disable_warnings --disable_warnings
drop table if exists t1, t2; drop table if exists t1, t2;
...@@ -137,4 +136,34 @@ show binlog events from 0; ...@@ -137,4 +136,34 @@ 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
...@@ -1918,30 +1918,24 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event) ...@@ -1918,30 +1918,24 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
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(length > 0)) if (likely(length > 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 >= length) while (hdr_offs < length)
hdr_offs -= length;
else
{ {
/* process all event-headers in this (partial) cache. */
do {
/* /*
partial header only? save what we can get, process once partial header only? save what we can get, process once
we get the rest. we get the rest.
...@@ -1968,8 +1962,17 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event) ...@@ -1968,8 +1962,17 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
hdr_offs += uint4korr(log_pos); hdr_offs += uint4korr(log_pos);
} }
} while (hdr_offs < length);
} }
/*
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 -= length;
} }
/* 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