List:Commits« Previous MessageNext Message »
From:Mats Kindahl Date:August 16 2006 12:56pm
Subject:bk commit into 5.1 tree (mats:1.2234) BUG#20863
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of mats. When mats 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, 2006-08-16 14:55:57+02:00, mats@romeo.(none) +4 -0
  BUG#20863 (if binlog format is changed between update and unlock table, wrong binlogging):
  Fix to allow the binlog format to be changed between the LOCK and
  UNLOCK tables, as well as under MIXED mode.

  mysql-test/r/rpl_switch_stm_row_mixed.result@stripped, 2006-08-16 14:55:52+02:00, mats@romeo.(none) +29 -6
    Result change

  mysql-test/t/rpl_switch_stm_row_mixed.test@stripped, 2006-08-16 14:55:52+02:00, mats@romeo.(none) +32 -1
    Adding test to see that binlog format can be changed when using
    LOCK/UNLOCK TABLES both under ROW format and MIXED format.

  sql/log.cc@stripped, 2006-08-16 14:55:52+02:00, mats@romeo.(none) +1 -1
    Removing pre-condition assertion since binlog can now be
    statement based.

  sql/sql_class.cc@stripped, 2006-08-16 14:55:53+02:00, mats@romeo.(none) +21 -19
    Adding code to always flush pending event regardless of the binlog
    format used. The only exception is if we are inside a stored routine,
    where the pending event is never flushed. 

# 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:	mats
# Host:	romeo.(none)
# Root:	/home/bk/b20863-mysql-5.1-new-rpl

--- 1.218/sql/log.cc	2006-08-16 14:56:03 +02:00
+++ 1.219/sql/log.cc	2006-08-16 14:56:03 +02:00
@@ -3153,7 +3153,7 @@
   flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event)
 {
   DBUG_ENTER("MYSQL_BIN_LOG::flush_and_set_pending_rows_event(event)");
-  DBUG_ASSERT(thd->current_stmt_binlog_row_based && mysql_bin_log.is_open());
+  DBUG_ASSERT(mysql_bin_log.is_open());
   DBUG_PRINT("enter", ("event=%p", event));
 
   int error= 0;

--- 1.272/sql/sql_class.cc	2006-08-16 14:56:03 +02:00
+++ 1.273/sql/sql_class.cc	2006-08-16 14:56:03 +02:00
@@ -2649,7 +2649,12 @@
 int THD::binlog_flush_pending_rows_event(bool stmt_end)
 {
   DBUG_ENTER("THD::binlog_flush_pending_rows_event");
-  if (!current_stmt_binlog_row_based || !mysql_bin_log.is_open())
+  /*
+    We shall flush the pending event even if we are not in row-based
+    mode: it might be the case that we left row-based mode before
+    flushing anything (e.g., if we have explicitly locked tables).
+   */
+  if (!mysql_bin_log.is_open())
     DBUG_RETURN(0);
 
   /*
@@ -2715,6 +2720,21 @@
   DBUG_PRINT("enter", ("qtype=%d, query='%s'", qtype, query));
   DBUG_ASSERT(query && mysql_bin_log.is_open());
 
+  /*
+    If we are not in prelocked mode, mysql_unlock_tables() will be
+    called after this binlog_query(), so we have to flush the pending
+    rows event with the STMT_END_F set to unlock all tables at the
+    slave side as well.
+
+    If we are in prelocked mode, the flushing will be done inside the
+    top-most close_thread_tables().
+  */
+#ifdef HAVE_ROW_BASED_REPLICATION
+  if (this->prelocked_mode == NON_PRELOCKED)
+    if (int error= binlog_flush_pending_rows_event(TRUE))
+      DBUG_RETURN(error);
+#endif /*HAVE_ROW_BASED_REPLICATION*/
+
   switch (qtype) {
   case THD::MYSQL_QUERY_TYPE:
     /*
@@ -2728,25 +2748,7 @@
   case THD::ROW_QUERY_TYPE:
 #ifdef HAVE_ROW_BASED_REPLICATION
     if (current_stmt_binlog_row_based)
-    {
-      /*
-        If thd->lock is set, then we are not inside a stored function.
-        In that case, mysql_unlock_tables() will be called after this
-        binlog_query(), so we have to flush the pending rows event
-        with the STMT_END_F set to unlock all tables at the slave side
-        as well.
-
-        We will not flush the pending event, if thd->lock is NULL.
-        This means that we are inside a stored function or trigger, so
-        the flushing will be done inside the top-most
-        close_thread_tables().
-       */
-#ifdef HAVE_ROW_BASED_REPLICATION
-      if (this->lock)
-        DBUG_RETURN(binlog_flush_pending_rows_event(TRUE));
-#endif /*HAVE_ROW_BASED_REPLICATION*/
       DBUG_RETURN(0);
-    }
 #endif
     /* Otherwise, we fall through */
   case THD::STMT_QUERY_TYPE:

--- 1.5/mysql-test/r/rpl_switch_stm_row_mixed.result	2006-08-16 14:56:03 +02:00
+++ 1.6/mysql-test/r/rpl_switch_stm_row_mixed.result	2006-08-16 14:56:03 +02:00
@@ -7,6 +7,8 @@
 drop database if exists mysqltest1;
 create database mysqltest1;
 use mysqltest1;
+set session binlog_format=row;
+set global binlog_format=row;
 show global variables like "binlog_format%";
 Variable_name	Value
 binlog_format	ROW
@@ -157,11 +159,29 @@
 select count(*) from t5;
 count(*)
 58
+SET SESSION BINLOG_FORMAT=STATEMENT;
+CREATE TABLE t11 (song VARCHAR(255));
+LOCK TABLES t11 WRITE;
+SET SESSION BINLOG_FORMAT=ROW;
+INSERT INTO t11 VALUES('Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict');
+SET SESSION BINLOG_FORMAT=STATEMENT;
+INSERT INTO t11 VALUES('Careful With That Axe, Eugene');
+UNLOCK TABLES;
+SELECT * FROM t11;
+song	Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict
+song	Careful With That Axe, Eugene
+USE mysqltest1;
+SELECT * FROM t11;
+song	Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict
+song	Careful With That Axe, Eugene
+SET SESSION BINLOG_FORMAT=MIXED;
+CREATE TABLE t12 (data LONG);
+LOCK TABLES t12 WRITE;
+INSERT INTO t12 VALUES(UUID());
+UNLOCK TABLES;
 show binlog events from 102;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
 master-bin.000001	#	Query	1	#	drop database if exists mysqltest1
-master-bin.000001	#	Table_map	1	#	table_id: # (mysql.proc)
-master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
 master-bin.000001	#	Query	1	#	create database mysqltest1
 master-bin.000001	#	Query	1	#	use `mysqltest1`; CREATE TABLE t1 (a varchar(100))
 master-bin.000001	#	Table_map	1	#	table_id: # (mysqltest1.t1)
@@ -178,10 +198,6 @@
 master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
 master-bin.000001	#	Table_map	1	#	table_id: # (mysqltest1.t1)
 master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
-master-bin.000001	#	Table_map	1	#	table_id: # (mysqltest1.t1)
-master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
-master-bin.000001	#	Table_map	1	#	table_id: # (mysqltest1.t1)
-master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
 master-bin.000001	#	Query	1	#	use `mysqltest1`; insert into t1 values("work")
 master-bin.000001	#	User var	1	#	@`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci
 master-bin.000001	#	Query	1	#	use `mysqltest1`; insert into t1 select @'string'
@@ -268,5 +284,12 @@
 master-bin.000001	#	Table_map	1	#	table_id: # (mysqltest1.t1)
 master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
 master-bin.000001	#	Table_map	1	#	table_id: # (mysqltest1.t1)
+master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	1	#	use `mysqltest1`; CREATE TABLE t11 (song VARCHAR(255))
+master-bin.000001	#	Table_map	1	#	table_id: # (mysqltest1.t11)
+master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	1	#	use `mysqltest1`; INSERT INTO t11 VALUES('Careful With That Axe, Eugene')
+master-bin.000001	#	Query	1	#	use `mysqltest1`; CREATE TABLE t12 (data LONG)
+master-bin.000001	#	Table_map	1	#	table_id: # (mysqltest1.t12)
 master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
 drop database mysqltest1;

--- 1.4/mysql-test/t/rpl_switch_stm_row_mixed.test	2006-08-16 14:56:03 +02:00
+++ 1.5/mysql-test/t/rpl_switch_stm_row_mixed.test	2006-08-16 14:56:03 +02:00
@@ -1,4 +1,4 @@
--- source include/have_binlog_format_row.inc
+-- source include/have_row_based.inc
 -- source include/master-slave.inc
 
 connection master;
@@ -8,6 +8,9 @@
 --enable_warnings
 use mysqltest1;
 
+set session binlog_format=row;
+set global binlog_format=row;
+
 show global variables like "binlog_format%";
 show session variables like "binlog_format%";
 select @@global.binlog_format, @@session.binlog_format;
@@ -196,10 +199,38 @@
   select count(*) from t9;
 }
 
+#
+# Bug#20863 If binlog format is changed between update and unlock of
+#           tables, wrong binlog
+#
+
+connection master;
+SET SESSION BINLOG_FORMAT=STATEMENT;
+CREATE TABLE t11 (song VARCHAR(255));
+LOCK TABLES t11 WRITE;
+SET SESSION BINLOG_FORMAT=ROW;
+INSERT INTO t11 VALUES('Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict');
+SET SESSION BINLOG_FORMAT=STATEMENT;
+INSERT INTO t11 VALUES('Careful With That Axe, Eugene');
+UNLOCK TABLES;
+
+--query_vertical SELECT * FROM t11
+sync_slave_with_master;
+USE mysqltest1;
+--query_vertical SELECT * FROM t11
+
+connection master;
+SET SESSION BINLOG_FORMAT=MIXED;
+CREATE TABLE t12 (data LONG);
+LOCK TABLES t12 WRITE;
+INSERT INTO t12 VALUES(UUID());
+UNLOCK TABLES;
+
 --replace_column 2 # 5 #
 --replace_regex /table_id: [0-9]+/table_id: #/
 show binlog events from 102;
 sync_slave_with_master;
+
 # as we're using UUID we don't SELECT but use "diff" like in rpl_row_UUID
 --exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_master.sql
 --exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_slave.sql
Thread
bk commit into 5.1 tree (mats:1.2234) BUG#20863Mats Kindahl16 Aug