From: Martin Skold Date: November 1 2012 3:51pm Subject: bzr push into mysql-5.5-cluster-7.2 branch (Martin.Skold:4057 to 4058) List-Archive: http://lists.mysql.com/commits/145183 Message-Id: <20121101155116.613BE9F8259@quadfish> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 4058 Martin Skold 2012-11-01 [merge] Merge from 7.1 modified: mysql-test/include/wait_for_binlog_event.inc 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 sql/ndb_thd_ndb.h 4057 Dyre Tjeldvoll 2012-11-01 [merge] Merge to 7.2 modified: storage/ndb/memcache/unit/test_workqueue.c === modified file 'mysql-test/include/wait_for_binlog_event.inc' --- a/mysql-test/include/wait_for_binlog_event.inc 2010-12-20 14:15:01 +0000 +++ b/mysql-test/include/wait_for_binlog_event.inc 2012-11-01 15:38:48 +0000 @@ -7,6 +7,7 @@ # USAGE # # let $wait_binlog_event= DROP; +# [let $binlog_file= master-bin.000001;] # --source include/wait_for_binlog_event.inc let $_loop_count= 300; @@ -22,12 +23,26 @@ while (`SELECT INSTR("$_last_event","$wa --die ERROR: failed while waiting for $wait_binlog_event in binlog } real_sleep 0.1; - let $_event= query_get_value(SHOW BINLOG EVENTS, Info, $_event_pos); + if (!$binlog_file) + { + let $_event= query_get_value(SHOW BINLOG EVENTS, Info, $_event_pos); + } + if ($binlog_file) + { + let $_event= query_get_value(SHOW BINLOG EVENTS IN '$binlog_file', Info, $_event_pos); + } let $_last_event= $_event; while ($_event != "No such row") { inc $_event_pos; let $_last_event= $_event; - let $_event= query_get_value(SHOW BINLOG EVENTS, Info, $_event_pos); + if (!$binlog_file) + { + let $_event= query_get_value(SHOW BINLOG EVENTS, Info, $_event_pos); + } + if ($binlog_file) + { + let $_event= query_get_value(SHOW BINLOG EVENTS IN '$binlog_file', Info, $_event_pos); + } } } === modified file 'mysql-test/suite/ndb_binlog/r/ndb_binlog_variants.result' --- a/mysql-test/suite/ndb_binlog/r/ndb_binlog_variants.result 2011-02-15 10:38:28 +0000 +++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_variants.result 2012-11-01 15:38:48 +0000 @@ -96,3 +96,80 @@ select * from bah order by tst; tst cvy sqs 1 2 1 drop table bah; +reset master; +show variables like '%log_update%'; +Variable_name Value +ndb_log_update_as_write ON +ndb_log_updated_only ON +CREATE TABLE `t1` ( +`charId` varchar(60) NOT NULL, +`enumId` enum('A','B','C') NOT NULL, +`val` bigint(20) NOT NULL, +`version` int(11) NOT NULL, +PRIMARY KEY (`charId`,`enumId`) +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES ('', 'A', 0, 1); +FLUSH LOGS; +UPDATE t1 SET val = val + 1 WHERE charId = ''; +FLUSH LOGS; +DELETE FROM t1 WHERE charId = ''; +FLUSH LOGS; +Manually applying captured binlog +select * from t1; +charId enumId val version +drop table t1; +reset master; +show variables like '%log_update%'; +Variable_name Value +ndb_log_update_as_write ON +ndb_log_updated_only ON +create table t1 (pk int not null primary key, name varchar(256)) engine = ndb; +FLUSH LOGS; +insert into t1 values (0, "zero"),(1,"one"),(2,"two"),(3,"three"),(4,"four"),(5,"five"),(6,"six"),(7,"seven"),(8,"eight"),(9,"nine"); +select * from t1 order by pk; +pk name +0 zero +1 one +2 two +3 three +4 four +5 five +6 six +7 seven +8 eight +9 nine +update t1 set name = "even" where pk in (0,2,4,6,8); +update t1 set name = "odd" where pk in (1,3,5,7,9); +delete from t1 where name = "odd"; +select * from t1 order by pk; +pk name +0 even +2 even +4 even +6 even +8 even +FLUSH LOGS; +truncate t1; +insert into t1 values (0, "zero"),(1,"one"),(2,"two"),(3,"three"),(4,"four"),(5,"five"),(6,"six"),(7,"seven"),(8,"eight"),(9,"nine"); +select * from t1 order by pk; +pk name +0 zero +1 one +2 two +3 three +4 four +5 five +6 six +7 seven +8 eight +9 nine +FLUSH LOGS; +Manually applying captured binlog +select * from t1 order by pk; +pk name +0 even +2 even +4 even +6 even +8 even +drop table t1; === modified file 'mysql-test/suite/ndb_binlog/t/ndb_binlog_variants.test' --- a/mysql-test/suite/ndb_binlog/t/ndb_binlog_variants.test 2011-05-18 12:56:24 +0000 +++ b/mysql-test/suite/ndb_binlog/t/ndb_binlog_variants.test 2012-11-01 15:38:48 +0000 @@ -214,3 +214,152 @@ let $MYSQLD_DATADIR= `select @@datadir;` select * from bah order by tst; drop table bah; + +# Bug #14615095 ERROR 839 'ILLEGAL NULL ATTRIBUTE' WHEN REPLAYING BINLOG +# When applying WRITE_ROW events to tables where the rows are missing +# any errors should be ignored + +connection mysqld1; +reset master; +show variables like '%log_update%'; + +CREATE TABLE `t1` ( + `charId` varchar(60) NOT NULL, + `enumId` enum('A','B','C') NOT NULL, + `val` bigint(20) NOT NULL, + `version` int(11) NOT NULL, + PRIMARY KEY (`charId`,`enumId`) + ) ENGINE=ndbcluster DEFAULT CHARSET=latin1; + +INSERT INTO t1 VALUES ('', 'A', 0, 1); + +--disable_query_log +# Add an event-stream marker +create table stream_marker(a int) engine=ndb; +drop table stream_marker; +--let $wait_binlog_event=stream_marker +--enable_query_log + +# Wait until the INSERT statement is confirmed to have made it into the current binary log +--source include/wait_for_binlog_event.inc +FLUSH LOGS; + +UPDATE t1 SET val = val + 1 WHERE charId = ''; + +--disable_query_log +# Add an event-stream marker +create table stream_marker(a int) engine=ndb; +drop table stream_marker; +--let $wait_binlog_event=stream_marker +--enable_query_log + +# Wait until the UPDATE statement is confirmed to have made it into the current binary log +--sleep 5 +--let $binlog_file=mysqld-bin.000002 +--source include/wait_for_binlog_event.inc +FLUSH LOGS; + +DELETE FROM t1 WHERE charId = ''; + +--disable_query_log +# Add an event-stream marker +create table stream_marker(a int) engine=ndb; +drop table stream_marker; +--let $wait_binlog_event=stream_marker +--enable_query_log + +# Wait until the DELETE statement is confirmed to have made it into the current binary log +--sleep 5 +--let $binlog_file=mysqld-bin.000003 +--source include/wait_for_binlog_event.inc +FLUSH LOGS; + +# Now let's re-apply the binlog from the UPDATE +# Without fix, this fails with 'Illegal null attribute' +--echo Manually applying captured binlog +--disable_query_log +let $MYSQLD_DATADIR= `select @@datadir;`; +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/mysqld-bin.000002 > $MYSQLTEST_VARDIR/tmp/ndb_binlog_mysqlbinlog.sql +--exec $MYSQL -uroot < $MYSQLTEST_VARDIR/tmp/ndb_binlog_mysqlbinlog.sql + +--enable_query_log +# Check that the table is still empty +select * from t1; + +drop table t1; + +# Bug #14678088 CAN'T FIND RECORD IN +# We need to be idempotent when applying binlog +# test insert of existing row, update and delete +# of non-existing row + +connection mysqld1; +reset master; +show variables like '%log_update%'; + +create table t1 (pk int not null primary key, name varchar(256)) engine = ndb; + +--disable_query_log +# Add an event-stream marker +create table stream_marker(a int) engine=ndb; +drop table stream_marker; +--let $wait_binlog_event=stream_marker +--enable_query_log + +# Wait until all statements are confirmed to have made it into the current binary log +--let $binlog_file=mysqld-bin.000001 +--source include/wait_for_binlog_event.inc +FLUSH LOGS; + +insert into t1 values (0, "zero"),(1,"one"),(2,"two"),(3,"three"),(4,"four"),(5,"five"),(6,"six"),(7,"seven"),(8,"eight"),(9,"nine"); +select * from t1 order by pk; + +update t1 set name = "even" where pk in (0,2,4,6,8); +update t1 set name = "odd" where pk in (1,3,5,7,9); + +delete from t1 where name = "odd"; + +select * from t1 order by pk; + +--disable_query_log +# Add an event-stream marker +create table stream_marker(a int) engine=ndb; +drop table stream_marker; +--let $wait_binlog_event=stream_marker +--enable_query_log + +# Wait until all statements are confirmed to have made it into the current binary log +--let $binlog_file=mysqld-bin.000002 +--source include/wait_for_binlog_event.inc +FLUSH LOGS; + +truncate t1; +insert into t1 values (0, "zero"),(1,"one"),(2,"two"),(3,"three"),(4,"four"),(5,"five"),(6,"six"),(7,"seven"),(8,"eight"),(9,"nine"); +select * from t1 order by pk; + +--disable_query_log +# Add an event-stream marker +create table stream_marker(a int) engine=ndb; +drop table stream_marker; +--let $wait_binlog_event=stream_marker +--enable_query_log + +# Wait until all statements are confirmed to have made it into the current binary log +--let $binlog_file=mysqld-bin.000003 +--source include/wait_for_binlog_event.inc +FLUSH LOGS; + +# Now let's re-apply the binlog INSERT,UPDATE,DELETE +# Without fix, this fails with 'Illegal null attribute' +--echo Manually applying captured binlog +--disable_query_log +let $MYSQLD_DATADIR= `select @@datadir;`; +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/mysqld-bin.000002 > $MYSQLTEST_VARDIR/tmp/ndb_binlog_mysqlbinlog.sql +--exec $MYSQL -uroot < $MYSQLTEST_VARDIR/tmp/ndb_binlog_mysqlbinlog.sql + +--enable_query_log +select * from t1 order by pk; + +drop table t1; + + === modified file 'sql/ha_ndbcluster.cc' --- a/sql/ha_ndbcluster.cc 2012-09-24 14:57:07 +0000 +++ b/sql/ha_ndbcluster.cc 2012-11-01 15:38:48 +0000 @@ -4420,27 +4420,6 @@ ha_ndbcluster::eventSetAnyValue(THD *thd #endif } -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? - ndb_mi_get_in_relay_log_statement(thd->rli_fake) : 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 - -} - static inline bool thd_allow_batch(const THD* thd) { @@ -5041,15 +5020,7 @@ int ha_ndbcluster::ndb_write_row(uchar * * to avoid trampling unchanged columns when an update is * logged as a WRITE */ - bool useWriteSet= isManualBinlogExec(thd); - -#ifdef HAVE_NDB_BINLOG - /* Slave always uses writeset - * TODO : What about SBR replicating a - * REPLACE command? - */ - useWriteSet |= thd->slave_thread; -#endif + bool useWriteSet= applying_binlog(thd); uchar* mask; if (useWriteSet) @@ -5491,7 +5462,7 @@ int ha_ndbcluster::exec_bulk_update(uint DBUG_RETURN(ndb_err(trans)); } THD *thd= table->in_use; - if (!thd->slave_thread) + if (!applying_binlog(thd)) { DBUG_PRINT("info", ("ignore_count: %u", ignore_count)); assert(m_rows_changed >= ignore_count); @@ -5535,7 +5506,7 @@ int ha_ndbcluster::exec_bulk_update(uint no_uncommitted_rows_execute_failure(); DBUG_RETURN(ndb_err(trans)); } - if (!thd->slave_thread) + if (!applying_binlog(thd)) { assert(m_rows_changed >= ignore_count); assert(m_rows_updated >= ignore_count); @@ -5860,7 +5831,7 @@ int ha_ndbcluster::ndb_update_row(const m_rows_changed++; m_rows_updated++; - if (!thd->slave_thread) + if (!applying_binlog(thd)) { assert(m_rows_changed >= ignore_count); assert(m_rows_updated >= ignore_count); @@ -5921,7 +5892,7 @@ int ha_ndbcluster::end_bulk_delete() DBUG_RETURN(ndb_err(trans)); } THD *thd= table->in_use; - if (!thd->slave_thread) + if (!applying_binlog(thd)) { DBUG_PRINT("info", ("ignore_count: %u", ignore_count)); assert(m_rows_deleted >= ignore_count); @@ -5963,7 +5934,7 @@ int ha_ndbcluster::end_bulk_delete() DBUG_RETURN(ndb_err(trans)); } - if (!thd->slave_thread) + if (!applying_binlog(thd)) { assert(m_rows_deleted >= ignore_count); m_rows_deleted-= ignore_count; @@ -6173,7 +6144,7 @@ int ha_ndbcluster::ndb_delete_row(const } if (!primary_key_update) { - if (!thd->slave_thread) + if (!applying_binlog(thd)) { assert(m_rows_deleted >= ignore_count); m_rows_deleted-= ignore_count; @@ -7141,8 +7112,11 @@ int ha_ndbcluster::extra(enum ha_extra_f case HA_EXTRA_WRITE_CAN_REPLACE: DBUG_PRINT("info", ("HA_EXTRA_WRITE_CAN_REPLACE")); if (!m_has_unique_index || - current_thd->slave_thread || /* always set if slave, quick fix for bug 27378 */ - isManualBinlogExec(current_thd)) /* or if manual binlog application, for bug 46662 */ + /* + Always set if slave, quick fix for bug 27378 + or if manual binlog application, for bug 46662 + */ + applying_binlog(current_thd)) { DBUG_PRINT("info", ("Turning ON use of write instead of insert")); m_use_write= TRUE; @@ -7579,6 +7553,13 @@ static void transaction_checks(THD *thd, THDVAR(thd, optimized_node_selection)= THDVAR(NULL, optimized_node_selection) & 1; /* using global value */ } +#ifndef EMBEDDED_LIBRARY + bool applying_binlog= + thd->rli_fake? + ndb_mi_get_in_relay_log_statement(thd->rli_fake) : false; + if (applying_binlog) + thd_ndb->trans_options|= TNTO_APPLYING_BINLOG; +#endif } int ha_ndbcluster::start_statement(THD *thd, @@ -8044,7 +8025,6 @@ ha_ndbcluster::start_transaction_part_id DBUG_RETURN(NULL); } - /** Static error print function called from static handler method ndbcluster_commit and ndbcluster_rollback. @@ -8162,7 +8142,10 @@ int ndbcluster_commit(handlerton *hton, } } else - res= execute_commit(thd, thd_ndb, trans, THDVAR(thd, force_send), FALSE); + { + bool applying_binlog= (thd_ndb->trans_options & TNTO_APPLYING_BINLOG); + res= execute_commit(thd, thd_ndb, trans, THDVAR(thd, force_send), applying_binlog); + } } if (res != 0) === modified file 'sql/ha_ndbcluster.h' --- a/sql/ha_ndbcluster.h 2012-06-15 10:08:39 +0000 +++ b/sql/ha_ndbcluster.h 2012-11-01 15:38:48 +0000 @@ -537,8 +537,19 @@ private: ulonglong *nb_reserved_values); bool uses_blob_value(const MY_BITMAP *bitmap) const; - static inline bool isManualBinlogExec(THD *thd); - + /* + Check if we are applying a binlog, either as a slave or + by applying BINLOG statements (from mysqlbinlog command line tool) + */ + bool applying_binlog(THD* thd) + { + return +#ifdef HAVE_NDB_BINLOG + thd->slave_thread || +#endif + m_thd_ndb->trans_options & TNTO_APPLYING_BINLOG; + }; + char *update_table_comment(const char * comment); int write_ndb_file(const char *name) const; === modified file 'sql/ndb_thd_ndb.h' --- a/sql/ndb_thd_ndb.h 2012-06-15 10:08:39 +0000 +++ b/sql/ndb_thd_ndb.h 2012-11-01 15:38:48 +0000 @@ -47,6 +47,7 @@ enum THD_NDB_TRANS_OPTIONS ,TNTO_NO_LOGGING= 1 << 1 ,TNTO_TRANSACTIONS_OFF= 1 << 2 ,TNTO_NO_REMOVE_STRAY_FILES= 1 << 3 + ,TNTO_APPLYING_BINLOG= 1 << 4 }; class Thd_ndb No bundle (reason: useless for push emails).