List:Commits« Previous MessageNext Message »
From:Frazer Clement Date:September 28 2009 1:18pm
Subject:bzr commit into mysql-5.1-telco-6.2 branch (frazer:3008)
View as plain text  
#At file:///home/frazer/bzr/mysql-5.1-telco-6.2/

 3008 Frazer Clement	2009-09-28
      Bug47674 MySQL Cluster : Manually applying binlog zaps unmodified columns
      modified:
        mysql-test/suite/ndb_binlog/r/ndb_binlog_variants.result
        mysql-test/suite/ndb_binlog/t/ndb_binlog_variants.test
        sql/ha_ndbcluster.cc
        sql/ha_ndbcluster.h

=== modified file 'mysql-test/suite/ndb_binlog/r/ndb_binlog_variants.result'
--- a/mysql-test/suite/ndb_binlog/r/ndb_binlog_variants.result	2009-09-28 10:09:38 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_variants.result	2009-09-28 13:18:20 +0000
@@ -3,6 +3,10 @@ insert into ba values (1, 1, 1), (2,2,2)
 update ba set lp=40 where ks=4;
 delete from ba where ks=2;
 flush logs;
+flush logs;
+flush logs;
+flush logs;
+delete from ba;
 show variables like '%log_update%';
 Variable_name	Value
 sql_log_update	ON
@@ -14,7 +18,12 @@ INSERT INTO test.ba SET   @1=2   @2=2   
 INSERT INTO test.ba SET   @1=3   @2=3   @3=3
 INSERT INTO test.ba SET   @1=4   @2=4   @3=4
 INSERT INTO test.ba SET   @1=4   @3=40
-flush logs;
+select * from ba order by ks;
+ks	st	lp
+1	1	1
+3	3	3
+4	4	40
+delete from ba;
 show variables like '%log_update%';
 Variable_name	Value
 sql_log_update	ON
@@ -26,7 +35,12 @@ INSERT INTO test.ba SET   @1=2   @2=2   
 INSERT INTO test.ba SET   @1=3   @2=3   @3=3
 INSERT INTO test.ba SET   @1=4   @2=4   @3=4
 INSERT INTO test.ba SET   @1=4   @2=4   @3=40
-flush logs;
+select * from ba order by ks;
+ks	st	lp
+1	1	1
+3	3	3
+4	4	40
+delete from ba;
 show variables like '%log_update%';
 Variable_name	Value
 sql_log_update	ON
@@ -38,7 +52,12 @@ INSERT INTO test.ba SET   @1=2   @2=2   
 INSERT INTO test.ba SET   @1=3   @2=3   @3=3
 INSERT INTO test.ba SET   @1=4   @2=4   @3=4
 UPDATE test.ba WHERE   @1=4   @3=4 SET   @1=4   @3=40
-flush logs;
+select * from ba order by ks;
+ks	st	lp
+1	1	1
+3	3	3
+4	4	40
+delete from ba;
 show variables like '%log_update%';
 Variable_name	Value
 sql_log_update	ON
@@ -50,4 +69,9 @@ INSERT INTO test.ba SET   @1=2   @2=2   
 INSERT INTO test.ba SET   @1=3   @2=3   @3=3
 INSERT INTO test.ba SET   @1=4   @2=4   @3=4
 UPDATE test.ba WHERE   @1=4   @2=4   @3=4 SET   @1=4   @2=4   @3=40
+select * from ba order by ks;
+ks	st	lp
+1	1	1
+3	3	3
+4	4	40
 drop table ba;

=== modified file 'mysql-test/suite/ndb_binlog/t/ndb_binlog_variants.test'
--- a/mysql-test/suite/ndb_binlog/t/ndb_binlog_variants.test	2009-09-28 10:09:38 +0000
+++ b/mysql-test/suite/ndb_binlog/t/ndb_binlog_variants.test	2009-09-28 13:18:20 +0000
@@ -70,34 +70,85 @@ drop table stream_marker;
 --let $wait_binlog_event=stream_marker
 --enable_query_log
 
-# Now let's have a look at what's in the Binlog on each server
+# Now let's trim the Binlogs on each server
 
+connection mysqld1;
 --source include/wait_for_binlog_event.inc
 flush logs;
+connection mysqld2;
+--source include/wait_for_binlog_event.inc
+flush logs;
+connection mysqld3;
+--source include/wait_for_binlog_event.inc
+flush logs;
+connection mysqld4;
+--source include/wait_for_binlog_event.inc
+flush logs;
+
+# Empty the table
+delete from ba;
+
+# Now let's examine the contents of the first binlog
+# on each server
+# We'll also apply the Binlog and check that the
+# table contents are as expected in each case.
+# As each server is recording in a new binlog, the
+# new updates will go there.
+
+connection mysqld1;
+
 show variables like '%log_update%';
 --source suite/ndb_binlog/t/ndb_binlog_get_binlog_stmts.inc
 
+--disable_query_log
+let $MYSQLD_DATADIR= `select @@datadir;`;
+--exec $MYSQL_BINLOG $MYSQLD_DATADIR/mysqld-bin.000001 > $MYSQLTEST_VARDIR/tmp/ndb_binlog_mysqlbinlog.sql
+--exec $MYSQL -uroot < $MYSQLTEST_VARDIR/tmp/ndb_binlog_mysqlbinlog.sql
+
+--enable_query_log
+select * from ba order by ks;
+delete from ba;
+
 connection mysqld2;
 
---source include/wait_for_binlog_event.inc 
-flush logs;
 show variables like '%log_update%';
 --source suite/ndb_binlog/t/ndb_binlog_get_binlog_stmts.inc
 
+--disable_query_log
+let $MYSQLD_DATADIR= `select @@datadir;`;
+--exec $MYSQL_BINLOG $MYSQLD_DATADIR/mysqld-bin.000001 > $MYSQLTEST_VARDIR/tmp/ndb_binlog_mysqlbinlog.sql
+--exec $MYSQL -uroot < $MYSQLTEST_VARDIR/tmp/ndb_binlog_mysqlbinlog.sql
+
+--enable_query_log
+
+select * from ba order by ks;
+delete from ba;
+
 connection mysqld3;
 
---source include/wait_for_binlog_event.inc 
-flush logs;
 show variables like '%log_update%';
 --source suite/ndb_binlog/t/ndb_binlog_get_binlog_stmts.inc
 
+--disable_query_log
+let $MYSQLD_DATADIR= `select @@datadir;`;
+--exec $MYSQL_BINLOG $MYSQLD_DATADIR/mysqld-bin.000001 > $MYSQLTEST_VARDIR/tmp/ndb_binlog_mysqlbinlog.sql
+--exec $MYSQL -uroot < $MYSQLTEST_VARDIR/tmp/ndb_binlog_mysqlbinlog.sql
+
+--enable_query_log
+select * from ba order by ks;
+delete from ba;
+
 connection mysqld4;
 
---source include/wait_for_binlog_event.inc 
-flush logs;
 show variables like '%log_update%';
 --source suite/ndb_binlog/t/ndb_binlog_get_binlog_stmts.inc
 
+--disable_query_log
+let $MYSQLD_DATADIR= `select @@datadir;`;
+--exec $MYSQL_BINLOG $MYSQLD_DATADIR/mysqld-bin.000001 > $MYSQLTEST_VARDIR/tmp/ndb_binlog_mysqlbinlog.sql
+--exec $MYSQL -uroot < $MYSQLTEST_VARDIR/tmp/ndb_binlog_mysqlbinlog.sql
 
-drop table ba;
+--enable_query_log
+select * from ba order by ks;
 
+drop table ba;

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2009-09-24 14:32:40 +0000
+++ b/sql/ha_ndbcluster.cc	2009-09-28 13:18:20 +0000
@@ -2886,6 +2886,17 @@ ha_ndbcluster::eventSetAnyValue(THD *thd
   }
 }
 
+bool ha_ndbcluster::isManualBinlogExec(THD *thd)
+{
+  /* Are we executing handler methods as part of 
+   * a mysql client BINLOG statement?
+   */
+  return thd ? 
+    ( thd->rli_fake? 
+      thd->rli_fake->get_flag(Relay_log_info::IN_STMT) : false)
+    : false;
+}
+
 int ha_ndbcluster::write_row(uchar *record)
 {
   DBUG_ENTER("ha_ndbcluster::write_row");
@@ -3042,27 +3053,29 @@ int ha_ndbcluster::ndb_write_row(uchar *
   if (m_use_write)
   {
     const uchar *mask;
-#ifdef HAVE_NDB_BINLOG
-    /*
-      The use of table->write_set is tricky here. This is done as a temporary
-      workaround for BUG#22045.
-
-      There is some confusion on the precise meaning of write_set in write_row,
-      with REPLACE INTO and replication SQL thread having different opinions.
-      There is work on the way to sort that out, but until then we need to
-      implement different semantics depending on whether we are in the slave
-      SQL thread or not.
+    /* Should we use the supplied table writeset or not?
+     * For a REPLACE command, we should ignore it, and write
+     * all columns to get correct REPLACE behaviour.
+     * For applying Binlog events, we need to use the writeset
+     * to avoid trampling unchanged columns when an update is
+     * logged as a WRITE
+     * See Bug#22045, Bug#47674 etc.
+     */
+    bool useWriteSet= isManualBinlogExec(thd);
 
-      SQL thread -> use the write_set for writeTuple().
-      otherwise (REPLACE INTO) -> do not use write_set.
-    */
-    if (thd->slave_thread)
+#ifdef HAVE_NDB_BINLOG
+    /* Slave always uses writeset
+     * TODO : What about SBR replicating a
+     * REPLACE command?
+     */
+    useWriteSet |= thd->slave_thread;
+#endif
+    if (useWriteSet)
     {
       user_cols_written_bitmap= table->write_set;
       mask= (uchar *)(user_cols_written_bitmap->bitmap);
     }
     else
-#endif
     {
       user_cols_written_bitmap= NULL;
       mask= NULL;

=== modified file 'sql/ha_ndbcluster.h'
--- a/sql/ha_ndbcluster.h	2009-09-24 14:22:10 +0000
+++ b/sql/ha_ndbcluster.h	2009-09-28 13:18:20 +0000
@@ -616,6 +616,8 @@ private:
                                   ulonglong *nb_reserved_values);
   bool uses_blob_value(const MY_BITMAP *bitmap);
 
+  static inline bool isManualBinlogExec(THD *thd);
+
   char *update_table_comment(const char * comment);
 
   int write_ndb_file(const char *name);

Thread
bzr commit into mysql-5.1-telco-6.2 branch (frazer:3008)Frazer Clement28 Sep