#At file:///home/frazer/bzr/mysql-5.1-telco-6.2/
3019 Frazer Clement 2009-10-07
Bug#47674 : 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-29 14:25:03 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_variants.result 2009-10-07 16:26:17 +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-29 14:25:03 +0000
+++ b/mysql-test/suite/ndb_binlog/t/ndb_binlog_variants.test 2009-10-07 16:26:17 +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-10-07 16:26:17 +0000
@@ -2886,6 +2886,27 @@ ha_ndbcluster::eventSetAnyValue(THD *thd
}
}
+bool ha_ndbcluster::isManualBinlogExec(THD *thd)
+{
+ /* Are we executing handler methods as part of
+ * a mysql client BINLOG statement?
+ */
+#ifndef EMBEDDED_LIBRARY
+ return thd ?
+ ( thd->rli_fake?
+ thd->rli_fake->get_flag(Relay_log_info::IN_STMT) : false)
+ : false;
+#else
+ /* For Embedded library, we can't determine if we're
+ * executing Binlog manually
+ * TODO : Find better way to determine whether to use
+ * SQL REPLACE or Write_row semantics
+ */
+ return false;
+#endif
+
+}
+
int ha_ndbcluster::write_row(uchar *record)
{
DBUG_ENTER("ha_ndbcluster::write_row");
@@ -3042,27 +3063,28 @@ 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
+ */
+ 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-10-07 16:26:17 +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:3019) Bug#47674 | Frazer Clement | 7 Oct |