List:Commits« Previous MessageNext Message »
From:Tatjana A Nuernberg Date:June 25 2007 7:21am
Subject:bk commit into 5.0 tree (tnurnberg:1.2502) BUG#22540
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of tnurnberg. When tnurnberg does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-06-25 09:21:55+02:00, tnurnberg@stripped +3 -0
  Bug #22540: Incorrect value in column End_log_pos of SHOW BINLOG EVENTS using InnoDB
  
  fix binlog-writing so that end_log_pos is given correctly even
  within transactions for both SHOW BINLOG and SHOW MASTER STATUS,
  that is as absolute values (from log start) rather than relative
  values (from transaction's start).
  ---
  Merge tnurnberg@stripped:/home/bk/mysql-5.0-maint
  into  sin.intern.azundris.com:/home/tnurnberg/22540/50-22540

  mysql-test/r/binlog.result@stripped, 2007-06-25 09:21:53+02:00, tnurnberg@stripped +119 -3
    Bug #22540: Incorrect value in column End_log_pos of SHOW BINLOG EVENTS using InnoDB
    
    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.
    ---
    manual merge

  mysql-test/t/binlog.test@stripped, 2007-06-25 09:21:53+02:00, tnurnberg@stripped +91 -2
    Bug #22540: Incorrect value in column End_log_pos of SHOW BINLOG EVENTS using InnoDB
    
    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.

  sql/log.cc@stripped, 2007-06-25 09:21:53+02:00, tnurnberg@stripped +65 -10
    Bug #22540: Incorrect value in column End_log_pos of SHOW BINLOG EVENTS using InnoDB
    
    fix output for SHOW BINLOG EVENTS so that end_log_pos is given correctly
    even within transactions. do this by rewriting the commit-buffer in place.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	tnurnberg
# Host:	sin.intern.azundris.com
# Root:	/home/tnurnberg/22540/50-22540

--- 1.210/sql/log.cc	2007-04-27 15:33:46 +02:00
+++ 1.211/sql/log.cc	2007-06-25 09:21:53 +02:00
@@ -134,7 +134,7 @@ static int binlog_commit(THD *thd, bool 
     // we're here because trans_log was flushed in MYSQL_LOG::log_xid()
     DBUG_RETURN(0);
   }
-  if (all) 
+  if (all)
   {
     Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE);
     qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
@@ -1835,7 +1835,9 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE
 
   if (likely(is_open()))                       // Should always be true
   {
-    uint length;
+    uint length, group, carry, hdr_offs;
+    long val;
+    byte header[LOG_EVENT_HEADER_LEN];
 
     /*
       Log "BEGIN" at the beginning of the transaction.
@@ -1867,16 +1869,69 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE
     /* Read from the file used to cache the queries .*/
     if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
       goto err;
-    length=my_b_bytes_in_cache(cache);
+
+    length= my_b_bytes_in_cache(cache);
     DBUG_EXECUTE_IF("half_binlogged_transaction", length-=100;);
-    do
+
+    group= my_b_tell(&log_file);
+    hdr_offs= carry= 0;
+
+    if(likely(length > 0))
     {
-      /* Write data to the binary log file */
-      if (my_b_write(&log_file, cache->read_pos, length))
-	goto err;
-      cache->read_pos=cache->read_end;		// Mark buffer used up
-      DBUG_EXECUTE_IF("half_binlogged_transaction", goto DBUG_skip_commit;);
-    } while ((length=my_b_fill(cache)));
+      do
+      {
+        if (likely(carry > 0))
+        {
+          DBUG_ASSERT(carry < LOG_EVENT_HEADER_LEN);
+
+          memcpy(&header[carry], (char *)cache->read_pos, LOG_EVENT_HEADER_LEN - carry);
+
+          val= uint4korr(&header[LOG_POS_OFFSET]) + group;
+          int4store(&header[LOG_POS_OFFSET], val);
+
+          if (my_b_write(&log_file, header, carry))
+            goto err;
+
+          memcpy((char *)cache->read_pos, &header[carry], LOG_EVENT_HEADER_LEN - carry);
+
+          hdr_offs = LOG_EVENT_HEADER_LEN - carry +
+            uint4korr(&header[EVENT_LEN_OFFSET]);
+
+          carry= 0;
+        }
+
+        do {
+          DBUG_ASSERT((hdr_offs + max(EVENT_LEN_OFFSET, LOG_POS_OFFSET) + 4) <= length);
+
+          val= uint4korr((char *)cache->read_pos + hdr_offs + LOG_POS_OFFSET) + group;
+          int4store((char *)cache->read_pos + hdr_offs + LOG_POS_OFFSET, val);
+          hdr_offs += uint4korr((char *)cache->read_pos + hdr_offs + EVENT_LEN_OFFSET);
+
+          /* header beyond current read-buffer? */
+          if (hdr_offs >= length)
+          {
+            hdr_offs -= length;
+            break;
+          }
+
+          /* split header? */
+          if (hdr_offs + LOG_EVENT_HEADER_LEN > length)
+          {
+            carry= length - hdr_offs;
+
+            memcpy(header, (char *)cache->read_pos + hdr_offs, carry);
+            length -= carry;
+          }
+
+        } while (hdr_offs < length);
+
+        /* Write data to the binary log file */
+        if (my_b_write(&log_file, cache->read_pos, length))
+          goto err;
+        cache->read_pos=cache->read_end;		// Mark buffer used up
+        DBUG_EXECUTE_IF("half_binlogged_transaction", goto DBUG_skip_commit;);
+      } while ((length=my_b_fill(cache)));
+    }
 
     if (commit_event->write(&log_file))
       goto err;

--- 1.9/mysql-test/r/binlog.result	2007-06-15 23:57:23 +02:00
+++ 1.10/mysql-test/r/binlog.result	2007-06-25 09:21:53 +02:00
@@ -1,6 +1,6 @@
 drop table if exists t1, t2;
 reset master;
-create table t1 (a int) engine=bdb;
+create table t1 (a int) engine=innodb;
 create table t2 (a int) engine=innodb;
 begin;
 insert t1 values (5);
@@ -10,11 +10,11 @@ insert t2 values (5);
 commit;
 show binlog events from 98;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	1	#	use `test`; create table t1 (a int) engine=bdb
+master-bin.000001	#	Query	1	#	use `test`; create table t1 (a int) engine=innodb
 master-bin.000001	#	Query	1	#	use `test`; create table t2 (a int) engine=innodb
 master-bin.000001	#	Query	1	#	use `test`; BEGIN
 master-bin.000001	#	Query	1	#	use `test`; insert t1 values (5)
-master-bin.000001	#	Query	1	#	use `test`; COMMIT
+master-bin.000001	#	Xid	1	#	COMMIT /* XID */
 master-bin.000001	#	Query	1	#	use `test`; BEGIN
 master-bin.000001	#	Query	1	#	use `test`; insert t2 values (5)
 master-bin.000001	#	Xid	1	#	COMMIT /* XID */
@@ -133,3 +133,119 @@ master-bin.000001	#	Rotate	1	#	master-bi
 show binlog events in 'master-bin.000002' from 98;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
 master-bin.000002	#	Query	1	#	use `test`; drop table t1
+set @ac = @@autocommit;
+set autocommit= 0;
+reset master;
+create table t1(n int) engine=innodb;
+begin;
+insert into t1 values (1);
+insert into t1 values (2);
+insert into t1 values (3);
+commit;
+drop table t1;
+show binlog events from 0;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	4	Format_desc	1	98	Server version, Binlog ver: 4
+master-bin.000001	98	Query	1	197	use `test`; create table t1(n int) engine=innodb
+master-bin.000001	197	Query	1	265	use `test`; BEGIN
+master-bin.000001	265	Query	1	353	use `test`; insert into t1 values (1)
+master-bin.000001	353	Query	1	441	use `test`; insert into t1 values (2)
+master-bin.000001	441	Query	1	529	use `test`; insert into t1 values (3)
+master-bin.000001	529	Xid	1	556	COMMIT /* XID */
+master-bin.000001	556	Query	1	632	use `test`; drop table t1
+set autocommit= 1;
+reset master;
+create table t1(n int) engine=innodb;
+insert into t1 values (1);
+insert into t1 values (2);
+insert into t1 values (3);
+commit;
+drop table t1;
+show binlog events from 0;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	4	Format_desc	1	98	Server version, Binlog ver: 4
+master-bin.000001	98	Query	1	197	use `test`; create table t1(n int) engine=innodb
+master-bin.000001	197	Query	1	285	use `test`; insert into t1 values (1)
+master-bin.000001	285	Xid	1	312	COMMIT /* XID */
+master-bin.000001	312	Query	1	400	use `test`; insert into t1 values (2)
+master-bin.000001	400	Xid	1	427	COMMIT /* XID */
+master-bin.000001	427	Query	1	515	use `test`; insert into t1 values (3)
+master-bin.000001	515	Xid	1	542	COMMIT /* XID */
+master-bin.000001	542	Query	1	618	use `test`; drop table t1
+reset master;
+create table t1(n int) engine=myisam;
+begin;
+insert into t1 values (4);
+insert into t1 values (5);
+insert into t1 values (6);
+commit;
+drop table t1;
+show binlog events from 0;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	4	Format_desc	1	98	Server version, Binlog ver: 4
+master-bin.000001	98	Query	1	197	use `test`; create table t1(n int) engine=myisam
+master-bin.000001	197	Query	1	285	use `test`; insert into t1 values (4)
+master-bin.000001	285	Query	1	373	use `test`; insert into t1 values (5)
+master-bin.000001	373	Query	1	461	use `test`; insert into t1 values (6)
+master-bin.000001	461	Query	1	537	use `test`; drop table t1
+set autocommit= 1;
+reset master;
+create table t1(n int) engine=innodb;
+show master status;
+File	Position	Binlog_Do_DB	Binlog_Ignore_DB
+master-bin.000001	197		
+insert into t1 values (1);
+show master status;
+File	Position	Binlog_Do_DB	Binlog_Ignore_DB
+master-bin.000001	312		
+insert into t1 values (2);
+insert into t1 values (3);
+show master status;
+File	Position	Binlog_Do_DB	Binlog_Ignore_DB
+master-bin.000001	542		
+commit;
+show master status;
+File	Position	Binlog_Do_DB	Binlog_Ignore_DB
+master-bin.000001	542		
+drop table t1;
+show binlog events from 0;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	4	Format_desc	1	98	Server version, Binlog ver: 4
+master-bin.000001	98	Query	1	197	use `test`; create table t1(n int) engine=innodb
+master-bin.000001	197	Query	1	285	use `test`; insert into t1 values (1)
+master-bin.000001	285	Xid	1	312	COMMIT /* XID */
+master-bin.000001	312	Query	1	400	use `test`; insert into t1 values (2)
+master-bin.000001	400	Xid	1	427	COMMIT /* XID */
+master-bin.000001	427	Query	1	515	use `test`; insert into t1 values (3)
+master-bin.000001	515	Xid	1	542	COMMIT /* XID */
+master-bin.000001	542	Query	1	618	use `test`; drop table t1
+set autocommit= 0;
+reset master;
+create table t1(n int) engine=myisam;
+show master status;
+File	Position	Binlog_Do_DB	Binlog_Ignore_DB
+master-bin.000001	197		
+insert into t1 values (4);
+show master status;
+File	Position	Binlog_Do_DB	Binlog_Ignore_DB
+master-bin.000001	285		
+insert into t1 values (5);
+insert into t1 values (6);
+show master status;
+File	Position	Binlog_Do_DB	Binlog_Ignore_DB
+master-bin.000001	461		
+commit;
+show master status;
+File	Position	Binlog_Do_DB	Binlog_Ignore_DB
+master-bin.000001	461		
+drop table t1;
+show binlog events from 0;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	4	Format_desc	1	98	Server version, Binlog ver: 4
+master-bin.000001	98	Query	1	197	use `test`; create table t1(n int) engine=myisam
+master-bin.000001	197	Query	1	285	use `test`; insert into t1 values (4)
+master-bin.000001	285	Query	1	373	use `test`; insert into t1 values (5)
+master-bin.000001	373	Query	1	461	use `test`; insert into t1 values (6)
+master-bin.000001	461	Query	1	537	use `test`; drop table t1
+set session autocommit = @ac;
+End of 5.0 tests

--- 1.11/mysql-test/t/binlog.test	2007-06-15 23:57:23 +02:00
+++ 1.12/mysql-test/t/binlog.test	2007-06-25 09:21:53 +02:00
@@ -3,7 +3,6 @@
 #
 -- source include/have_log_bin.inc
 -- source include/not_embedded.inc
--- source include/have_bdb.inc
 -- source include/have_innodb.inc
 -- source include/have_log_bin.inc
 
@@ -12,7 +11,7 @@ drop table if exists t1, t2;
 --enable_warnings
 reset master;
 
-create table t1 (a int) engine=bdb;
+create table t1 (a int) engine=innodb;
 create table t2 (a int) engine=innodb;
 begin;
 insert t1 values (5);
@@ -49,3 +48,93 @@ show binlog events in 'master-bin.000001
 --replace_column 2 # 5 #
 show binlog events in 'master-bin.000002' from 98;
 
+#
+# Bug#22540 - Incorrect value in column End_log_pos of
+# SHOW BINLOG EVENTS using InnoDB
+#
+
+# the following tests will show that certain queries now return
+# absolute offsets (from binlog start, rather than relative to
+# the beginning of the current transaction).  under what
+# conditions it should be allowed / is sensible to put the
+# slider into the middle of a transaction is not our concern
+# here; we just guarantee that if and when it's done, the
+# user has valid offsets to use.  if the setter function still
+# wants to throw a "positioning into middle of transaction"
+# warning, that's its prerogative and handled elsewhere.
+
+set @ac = @@autocommit;
+
+# first show this to work for SHOW BINLOG EVENTS
+
+set autocommit= 0;
+reset master;
+create table t1(n int) engine=innodb;
+begin;
+insert into t1 values (1);
+insert into t1 values (2);
+insert into t1 values (3);
+commit;
+drop table t1;
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/
+show binlog events from 0;
+
+set autocommit= 1;
+reset master;
+create table t1(n int) engine=innodb;
+insert into t1 values (1);
+insert into t1 values (2);
+insert into t1 values (3);
+commit;
+drop table t1;
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/
+show binlog events from 0;
+
+reset master;
+create table t1(n int) engine=myisam;
+begin;
+insert into t1 values (4);
+insert into t1 values (5);
+insert into t1 values (6);
+commit;
+drop table t1;
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/
+show binlog events from 0;
+
+# now show this also works for SHOW MASTER STATUS
+# as this is what "mysqldump --master-data=1" uses.
+
+set autocommit= 1;
+reset master;
+create table t1(n int) engine=innodb;
+show master status;
+insert into t1 values (1);
+show master status;
+insert into t1 values (2);
+insert into t1 values (3);
+show master status;
+commit;
+show master status;
+drop table t1;
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/
+show binlog events from 0;
+
+set autocommit= 0;
+reset master;
+create table t1(n int) engine=myisam;
+show master status;
+insert into t1 values (4);
+show master status;
+insert into t1 values (5);
+insert into t1 values (6);
+
+show master status;
+commit;
+show master status;
+drop table t1;
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/
+show binlog events from 0;
+
+set session autocommit = @ac;
+
+--echo End of 5.0 tests
Thread
bk commit into 5.0 tree (tnurnberg:1.2502) BUG#22540Tatjana A Nuernberg30 Jun