List:Commits« Previous MessageNext Message »
From:Tatjana A Nuernberg Date:June 27 2007 6:18am
Subject:bk commit into 5.1 tree (tnurnberg:1.2516) BUG#22540
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 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-27 08:18:24+02:00, tnurnberg@stripped +2 -0
  Merge rkalimullin@stripped:/home/bk/mysql-5.0-maint
  into  mysql.com:/home/ram/work/b29079/b29079.5.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
  ---
  Bug#22540: Incorrect value in column End_log_pos of SHOW BINLOG EVENTS using InnoDB
  
  end_log_pos data within a transaction are relative to
  the start of the transaction rather than absolute.
  we fix those groups in situ before writing the log out.
  
  additional comments and handling for groups with very
  large single events, as suggested by Guilhem.
  ---
  Merge bk-internal.mysql.com:/home/bk/mysql-5.0-maint
  into  amd64.(none):/src/bug24732/my50-bug24732
  ---
  Merge maint1.mysql.com:/data/localhome/tsmith/bk/50
  into  maint1.mysql.com:/data/localhome/tsmith/bk/maint/50
  ---
  Bug#22540: Incorrect value in column End_log_pos of SHOW BINLOG EVENTS using InnoDB
   
  end_log_pos data within a transaction are relative to
  the start of the transaction rather than absolute.
  we fix those groups in situ before writing the log out.
   
  additional comments and handling for groups with very
  large single events, as suggested by Guilhem.
  ---
  Merge tnurnberg@stripped:/home/bk/mysql-5.0-maint
  into  sin.intern.azundris.com:/home/tnurnberg/22540/50-22540
  ---
  Merge tnurnberg@stripped:/home/bk/mysql-5.1-maint
  into  sin.intern.azundris.com:/home/tnurnberg/22540/51-22540
  ---
  Merge sin.intern.azundris.com:/home/tnurnberg/22540/50-22540
  into  sin.intern.azundris.com:/home/tnurnberg/22540/51-22540

  mysql-test/r/rpl_truncate_7ndb.result@stripped, 2007-06-27 08:18:23+02:00, tnurnberg@stripped +20 -20
    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.
    ---
    Bug#22540: Incorrect value in column End_log_pos of SHOW BINLOG EVENTS using InnoDB
    
    end_log_pos data within a transaction are relative to
    the start of the transaction rather than absolute.
    we fix those groups in situ before writing the log out.
    
    additional comments and handling for groups with very
    large single events, as suggested by Guilhem.
    ---
    Bug#22540: Incorrect value in column End_log_pos of SHOW BINLOG EVENTS using InnoDB
     
    end_log_pos data within a transaction are relative to
    the start of the transaction rather than absolute.
    we fix those groups in situ before writing the log out.
     
    additional comments and handling for groups with very
    large single events, as suggested by Guilhem.
    ---
    manual merge

  sql/log.cc@stripped, 2007-06-27 08:18:23+02:00, tnurnberg@stripped +74 -28
    Bug #22540: Incorrect value in column End_log_pos of SHOW BINLOG EVENTS using InnoDB
    
    show that output for SHOW BINLOG EVENTS is no correct
    even within transactions.

diff -Nrup a/mysql-test/r/rpl_truncate_7ndb.result b/mysql-test/r/rpl_truncate_7ndb.result
--- a/mysql-test/r/rpl_truncate_7ndb.result	2007-03-30 04:44:45 +02:00
+++ b/mysql-test/r/rpl_truncate_7ndb.result	2007-06-27 08:18:23 +02:00
@@ -32,11 +32,11 @@ Log_name	Pos	Event_type	Server_id	End_lo
 master-bin.000001	4	Format_desc	1	106	Server ver: SERVER_VERSION, Binlog ver: 4
 master-bin.000001	106	Query	1	223	use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB
 master-bin.000001	223	Query	1	287	BEGIN
-master-bin.000001	287	Table_map	1	40	table_id: # (test.t1)
-master-bin.000001	327	Table_map	1	98	table_id: # (mysql.ndb_apply_status)
-master-bin.000001	385	Write_rows	1	157	table_id: #
-master-bin.000001	444	Write_rows	1	195	table_id: #
-master-bin.000001	482	Write_rows	1	233	table_id: # flags: STMT_END_F
+master-bin.000001	287	Table_map	1	327	table_id: # (test.t1)
+master-bin.000001	327	Table_map	1	385	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	385	Write_rows	1	444	table_id: #
+master-bin.000001	444	Write_rows	1	482	table_id: #
+master-bin.000001	482	Write_rows	1	520	table_id: # flags: STMT_END_F
 master-bin.000001	520	Query	1	585	COMMIT
 master-bin.000001	585	Query	1	665	use `test`; TRUNCATE TABLE t1
 master-bin.000001	665	Query	1	741	use `test`; DROP TABLE t1
@@ -69,27 +69,27 @@ Log_name	Pos	Event_type	Server_id	End_lo
 master-bin.000001	4	Format_desc	1	106	Server ver: SERVER_VERSION, Binlog ver: 4
 master-bin.000001	106	Query	1	223	use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB
 master-bin.000001	223	Query	1	287	BEGIN
-master-bin.000001	287	Table_map	1	40	table_id: # (test.t1)
-master-bin.000001	327	Table_map	1	98	table_id: # (mysql.ndb_apply_status)
-master-bin.000001	385	Write_rows	1	157	table_id: #
-master-bin.000001	444	Write_rows	1	195	table_id: #
-master-bin.000001	482	Write_rows	1	233	table_id: # flags: STMT_END_F
+master-bin.000001	287	Table_map	1	327	table_id: # (test.t1)
+master-bin.000001	327	Table_map	1	385	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	385	Write_rows	1	444	table_id: #
+master-bin.000001	444	Write_rows	1	482	table_id: #
+master-bin.000001	482	Write_rows	1	520	table_id: # flags: STMT_END_F
 master-bin.000001	520	Query	1	585	COMMIT
 master-bin.000001	585	Query	1	665	use `test`; TRUNCATE TABLE t1
 master-bin.000001	665	Query	1	741	use `test`; DROP TABLE t1
 master-bin.000001	741	Query	1	858	use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB
 master-bin.000001	858	Query	1	922	BEGIN
-master-bin.000001	922	Table_map	1	40	table_id: # (test.t1)
-master-bin.000001	962	Table_map	1	98	table_id: # (mysql.ndb_apply_status)
-master-bin.000001	1020	Write_rows	1	157	table_id: #
-master-bin.000001	1079	Write_rows	1	195	table_id: #
-master-bin.000001	1117	Write_rows	1	233	table_id: # flags: STMT_END_F
+master-bin.000001	922	Table_map	1	962	table_id: # (test.t1)
+master-bin.000001	962	Table_map	1	1020	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	1020	Write_rows	1	1079	table_id: #
+master-bin.000001	1079	Write_rows	1	1117	table_id: #
+master-bin.000001	1117	Write_rows	1	1155	table_id: # flags: STMT_END_F
 master-bin.000001	1155	Query	1	1220	COMMIT
 master-bin.000001	1220	Query	1	1284	BEGIN
-master-bin.000001	1284	Table_map	1	40	table_id: # (test.t1)
-master-bin.000001	1324	Table_map	1	98	table_id: # (mysql.ndb_apply_status)
-master-bin.000001	1382	Write_rows	1	157	table_id: #
-master-bin.000001	1441	Delete_rows	1	191	table_id: #
-master-bin.000001	1475	Delete_rows	1	225	table_id: # flags: STMT_END_F
+master-bin.000001	1284	Table_map	1	1324	table_id: # (test.t1)
+master-bin.000001	1324	Table_map	1	1382	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	1382	Write_rows	1	1441	table_id: #
+master-bin.000001	1441	Delete_rows	1	1475	table_id: #
+master-bin.000001	1475	Delete_rows	1	1509	table_id: # flags: STMT_END_F
 master-bin.000001	1509	Query	1	1574	COMMIT
 master-bin.000001	1574	Query	1	1650	use `test`; DROP TABLE t1
diff -Nrup a/sql/log.cc b/sql/log.cc
--- a/sql/log.cc	2007-06-25 11:37:08 +02:00
+++ b/sql/log.cc	2007-06-27 08:18:23 +02:00
@@ -3949,65 +3949,111 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE 
   long val;
   uchar header[LOG_EVENT_HEADER_LEN];
 
+  /*
+    The events in the buffer have incorrect end_log_pos data
+    (relative to beginning of group rather than absolute),
+    so we'll recalculate them in situ so the binlog is always
+    correct, even in the middle of a group. This is possible
+    because we now know the start position of the group (the
+    offset of this cache in the log, if you will); all we need
+    to do is to find all event-headers, and add the position of
+    the group to the end_log_pos of each event.  This is pretty
+    straight forward, except that we read the cache in segments,
+    so an event-header might end up on the cache-border and get
+    split.
+  */
+
   group= my_b_tell(&log_file);
   hdr_offs= carry= 0;
 
   do
   {
-    if (likely(carry > 0))
+
+    /*
+      if we only got a partial header in the last iteration,
+      get the other half now and process a full header.
+    */
+    if (unlikely(carry > 0))
     {
       DBUG_ASSERT(carry < LOG_EVENT_HEADER_LEN);
 
+      /* assemble both halves */
       memcpy(&header[carry], (char *)cache->read_pos, LOG_EVENT_HEADER_LEN - carry);
 
+      /* fix end_log_pos */
       val= uint4korr(&header[LOG_POS_OFFSET]) + group;
       int4store(&header[LOG_POS_OFFSET], val);
 
+      /* write the first half of the split header */
       if (my_b_write(&log_file, header, carry))
         return ER_ERROR_ON_WRITE;
 
+      /*
+        copy fixed second half of header to cache so the correct
+        version will be written later.
+      */
       memcpy((char *)cache->read_pos, &header[carry], LOG_EVENT_HEADER_LEN - carry);
 
+      /* next event header at ... */
       hdr_offs = LOG_EVENT_HEADER_LEN - carry +
         uint4korr(&header[EVENT_LEN_OFFSET]);
 
       carry= 0;
     }
 
+    /* if there is anything to write, process it. */
+
     if(likely(bytes > 0))
     {
-      do {
-        DBUG_ASSERT((hdr_offs + max(EVENT_LEN_OFFSET, LOG_POS_OFFSET) + 4) <= bytes);
-
-        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 >= bytes)
-        {
-          hdr_offs -= bytes;
-          break;
-        }
-
-        /* split header? */
-        if (hdr_offs + LOG_EVENT_HEADER_LEN > bytes)
-        {
-          carry= bytes - hdr_offs;
-
-          memcpy(header, (char *)cache->read_pos + hdr_offs, carry);
-          bytes -= carry;
-        }
-
-      } while (hdr_offs < bytes);
+      /*
+        next header beyond current read-buffer? we'll get it later
+        (though not necessarily in the very next iteration).
+      */
+
+      if (hdr_offs >= bytes)
+        hdr_offs -= bytes;
+      else
+      {
+
+        /* process all event-headers in this (partial) cache. */
+
+        do {
+
+          /*
+            partial header only? save what we can get, process once
+            we get the rest.
+          */
+
+          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= cache->read_pos + hdr_offs + LOG_POS_OFFSET;
+
+            /* fix end_log_pos */
+            val= uint4korr(log_pos) + group;
+            int4store(log_pos, val);
+
+            /* next event header at ... */
+            log_pos= (uchar *)cache->read_pos + hdr_offs + EVENT_LEN_OFFSET;
+            hdr_offs += uint4korr(log_pos);
+
+          }
+        } while (hdr_offs < bytes);
+      }
     }
 
     /* Write data to the binary log file */
-
     if (my_b_write(&log_file, cache->read_pos, bytes))
       return ER_ERROR_ON_WRITE;
-    cache->read_pos= cache->read_end;
-  } while ((bytes= my_b_fill(cache)));
+    cache->read_pos=cache->read_end;		// Mark buffer used up
+  } while ((bytes=my_b_fill(cache)));
 
   if (sync_log)
     flush_and_sync();
Thread
bk commit into 5.1 tree (tnurnberg:1.2516) BUG#22540Tatjana A Nuernberg27 Jun