Commit 59ab2d46 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.


mysql-test/r/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
mysql-test/t/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
parent 5d7082e1
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,58 +1918,61 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event) ...@@ -1918,58 +1918,61 @@ 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
{ {
/*
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 > length)
{
do { carry= length - hdr_offs;
memcpy(header, (char *)cache->read_pos + hdr_offs, carry);
/* length= 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 > length)
{
carry= length - hdr_offs;
memcpy(header, (char *)cache->read_pos + hdr_offs, carry);
length= hdr_offs;
}
else
{
/* we've got a full event-header, and it came in one piece */
char *log_pos= (char *)cache->read_pos + hdr_offs + LOG_POS_OFFSET; char *log_pos= (char *)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= (char *)cache->read_pos + hdr_offs + EVENT_LEN_OFFSET; log_pos= (char *)cache->read_pos + hdr_offs + EVENT_LEN_OFFSET;
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