List:Commits« Previous MessageNext Message »
From:John David Duncan Date:July 14 2011 4:37am
Subject:bzr push into mysql-5.5-cluster branch (john.duncan:3422 to 3436)
View as plain text  
 3436 John David Duncan	2011-07-13
      Merge revised Multi-NDB-wait API from cluster-7.2-multiwait

    renamed:
      storage/ndb/include/ndbapi/NdbPollGroup.hpp => storage/ndb/include/ndbapi/NdbWaitGroup.hpp
      storage/ndb/src/ndbapi/NdbPollGroup.cpp => storage/ndb/src/ndbapi/NdbWaitGroup.cpp
    modified:
      storage/ndb/include/ndbapi/Ndb.hpp
      storage/ndb/include/ndbapi/NdbApi.hpp
      storage/ndb/include/ndbapi/ndb_cluster_connection.hpp
      storage/ndb/src/ndbapi/API.hpp
      storage/ndb/src/ndbapi/CMakeLists.txt
      storage/ndb/src/ndbapi/WakeupHandler.cpp
      storage/ndb/src/ndbapi/WakeupHandler.hpp
      storage/ndb/src/ndbapi/ndb_cluster_connection.cpp
      storage/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp
      storage/ndb/test/ndbapi/testAsynchMultiwait.cpp
      storage/ndb/test/run-test/daily-devel-tests.txt
      storage/ndb/include/ndbapi/NdbWaitGroup.hpp
      storage/ndb/src/ndbapi/NdbWaitGroup.cpp
 3435 John David Duncan	2011-07-13 [merge]
      Pull in Jonas' 71-to-55 merge

    added:
      mysql-test/suite/ndb_rpl/r/ndb_rpl_conflict_epoch.result
      mysql-test/suite/ndb_rpl/t/ndb_rpl_conflict_epoch.cnf
      mysql-test/suite/ndb_rpl/t/ndb_rpl_conflict_epoch.test
      mysql-test/suite/ndb_rpl/t/ndb_rpl_conflict_epoch_1.inc
    modified:
      mysql-test/suite/ndb/r/ndb_basic.result
      mysql-test/suite/ndb_rpl/r/ndb_rpl_conflict_max.result
      mysql-test/suite/ndb_rpl/r/ndb_rpl_conflict_max_delete_win.result
      mysql-test/suite/ndb_rpl/r/ndb_rpl_conflict_old.result
      mysql-test/suite/ndb_rpl/t/disabled.def
      mysql-test/suite/ndb_rpl/t/ndb_conflict_info.inc
      mysql-test/suite/ndb_rpl/t/ndb_conflict_info_init.inc
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster_binlog.cc
      sql/ndb_share.h
      storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
 3434 John David Duncan	2011-07-08
      Merge from 7.2: multiwait API.

    added:
      storage/ndb/include/ndbapi/NdbPollGroup.hpp
      storage/ndb/src/ndbapi/NdbPollGroup.cpp
      storage/ndb/src/ndbapi/WakeupHandler.cpp
      storage/ndb/src/ndbapi/WakeupHandler.hpp
      storage/ndb/test/ndbapi/testAsynchMultiwait.cpp
    modified:
      storage/ndb/include/ndbapi/Ndb.hpp
      storage/ndb/include/ndbapi/NdbApi.hpp
      storage/ndb/include/ndbapi/ndb_cluster_connection.hpp
      storage/ndb/include/transporter/TransporterCallback.hpp
      storage/ndb/src/common/transporter/TransporterRegistry.cpp
      storage/ndb/src/ndbapi/API.hpp
      storage/ndb/src/ndbapi/CMakeLists.txt
      storage/ndb/src/ndbapi/NdbImpl.hpp
      storage/ndb/src/ndbapi/Ndbif.cpp
      storage/ndb/src/ndbapi/Ndbinit.cpp
      storage/ndb/src/ndbapi/TransporterFacade.cpp
      storage/ndb/src/ndbapi/TransporterFacade.hpp
      storage/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp
      storage/ndb/src/ndbapi/trp_client.hpp
      storage/ndb/test/ndbapi/CMakeLists.txt
      storage/ndb/test/run-test/daily-devel-tests.txt
 3433 John David Duncan	2011-07-07
      Merge from 7.2: adjustable wait time in TransporterFacade's send thread.

    modified:
      storage/ndb/include/ndbapi/ndb_cluster_connection.hpp
      storage/ndb/src/ndbapi/TransporterFacade.cpp
      storage/ndb/src/ndbapi/TransporterFacade.hpp
      storage/ndb/src/ndbapi/ndb_cluster_connection.cpp
 3432 John David Duncan	2011-07-07
      Merge from 7.2: new adaptive send statistics for Ndb objects

    modified:
      sql/ha_ndbcluster.cc
      storage/ndb/include/ndbapi/Ndb.hpp
      storage/ndb/src/ndbapi/Ndb.cpp
      storage/ndb/src/ndbapi/Ndbif.cpp
      storage/ndb/src/ndbapi/TransporterFacade.cpp
      storage/ndb/src/ndbapi/TransporterFacade.hpp
      storage/ndb/src/ndbapi/trp_client.cpp
      storage/ndb/src/ndbapi/trp_client.hpp
 3431 Jonas Oreland	2011-07-07
      ndb - wl#3749 - fix an missing close_temporary (cause trailing share). Then found what must be an incorrect #ifdef. Changed that and had to change a couple of lines in sql_partition (which makes sense)

    modified:
      sql/sql_partition.cc
      sql/sql_table.cc
 3430 Jonas Oreland	2011-07-07 [merge]
      ndb - merge 71 to 55

    modified:
      mysql-test/suite/ndb/r/ndb_share.result
      mysql-test/suite/ndb/t/ndb_share.cnf
      mysql-test/suite/ndb/t/ndb_share.test
 3429 jonas oreland	2011-07-06
      add suppression for running with "--mysqld=--binlog-format=mixed" as pb-swei does

    modified:
      mysql-test/suite/ndb/t/ndb_share.test
 3428 jonas oreland	2011-07-06
      ndb - reenabled tests

    modified:
      mysql-test/suite/ndb_rpl/t/disabled.def
      mysql-test/suite/ndb_rpl/t/ndb_rpl_break_3_chain.cnf
 3427 jonas oreland	2011-07-06
      ndb 55 - reenable ndb_multi after having MCP:ed bug-44529. Also fix error with missing thd->clear_error()

    modified:
      mysql-test/suite/ndb/t/disabled.def
      sql/ha_ndbcluster_binlog.cc
      sql/ndb_local_connection.cc
      sql/sql_db.cc
 3426 jonas oreland	2011-07-06 [merge]
      ndb - merge 71 to 55

    added:
      mysql-test/suite/ndb/r/ndb_ddl_open_trans.result
      mysql-test/suite/ndb/t/ndb_ddl_open_trans.test
    modified:
      mysql-test/mysql-test-run.pl
      mysql-test/suite/ndb/r/ndb_alter_table3.result
      mysql-test/suite/ndb/t/disabled.def
      mysql-test/suite/ndb/t/ndb_alter_table3.test
      mysql-test/suite/ndb/t/ndb_restore_compat_downward.test
      mysql-test/suite/ndb/t/ndb_share.test
      mysql-test/suite/ndb_rpl/t/ndb_rpl_bank.test
      mysql-test/suite/ndb_team/t/ndb_autodiscover.test
      storage/ndb/src/ndbjtie/jtie/jtie_tconv_idcache_impl.hpp
 3425 jonas oreland	2011-07-06
      ndb - allow more errors in ndb_not_readonly.inc

    modified:
      mysql-test/include/ndb_not_readonly.inc
 3424 jonas oreland	2011-07-06
      ndb - 55 - remove extra ha_prepare_for_alter
        The call is not present in 7.0...and causes an extra share-reference
          to be created in ndb (found by new testcase ndb_share)
      
        MARTIN: Please check!!

    modified:
      sql/sql_table.cc
 3423 jonas oreland	2011-07-06 [merge]
      ndb - merge 71 to 55

    added:
      mysql-test/suite/ndb/include/ndb_share_check_shares.inc
      mysql-test/suite/ndb/r/ndb_share.result
      mysql-test/suite/ndb/t/ndb_share.cnf
      mysql-test/suite/ndb/t/ndb_share.test
    modified:
      mysql-test/suite/ndb/r/ndb_basic.result
      mysql-test/suite/ndb/t/ndb_basic.test
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster.h
      sql/ha_ndbcluster_binlog.cc
      storage/ndb/clusterj/clusterj-api/pom.xml
      storage/ndb/clusterj/clusterj-bindings/pom.xml
      storage/ndb/clusterj/clusterj-core/pom.xml
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/SessionImpl.java
      storage/ndb/clusterj/clusterj-jdbc/pom.xml
      storage/ndb/clusterj/clusterj-jpatest/pom.xml
      storage/ndb/clusterj/clusterj-openjpa/pom.xml
      storage/ndb/clusterj/clusterj-test/pom.xml
      storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/AbstractClusterJModelTest.java
      storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/AbstractQueryTest.java
      storage/ndb/clusterj/clusterj-tie/pom.xml
      storage/ndb/clusterj/pom.xml
      storage/ndb/src/ndbjtie/jtie/jtie_tconv_idcache_impl.hpp
 3422 Jonas Oreland	2011-07-05 [merge]
      ndb - merge 71 to 55

    modified:
      storage/ndb/clusterj/clusterj-jdbc/src/main/antlr3/imports/MySQL51Functions.g
      storage/ndb/clusterj/clusterj-test/src/main/resources/META-INF/services/com.mysql.clusterj.core.spi.DomainTypeHandlerFactory
      storage/ndb/clusterj/clusterj-test/src/main/resources/schema.sql
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/Utility.java
=== modified file 'mysql-test/include/ndb_not_readonly.inc'
--- a/mysql-test/include/ndb_not_readonly.inc	2011-04-14 15:40:04 +0000
+++ b/mysql-test/include/ndb_not_readonly.inc	2011-07-06 08:37:47 +0000
@@ -7,14 +7,14 @@
 
 set @saved_log = @@sql_log_bin;
 set sql_log_bin = 0;
---error 0,ER_NO_SUCH_TABLE,ER_OPEN_AS_READONLY,ER_GET_ERRMSG,ER_KEY_NOT_FOUND
+--error 0,ER_NO_SUCH_TABLE,ER_OPEN_AS_READONLY,ER_GET_ERRMSG,ER_TABLE_DEF_CHANGED,ER_NOT_FORM_FILE,ER_KEY_NOT_FOUND
 delete from mysql.ndb_schema where db="" and name="";
 let $mysql_errno= 1;
 let $counter= 600;
 while ($mysql_errno)
 {
   # Table is readonly until the mysqld has connected properly
-  --error 0,ER_NO_SUCH_TABLE,ER_OPEN_AS_READONLY,ER_GET_ERRMSG,ER_TABLE_DEF_CHANGED
+  --error 0,ER_NO_SUCH_TABLE,ER_OPEN_AS_READONLY,ER_GET_ERRMSG,ER_TABLE_DEF_CHANGED,ER_NOT_FORM_FILE,
   replace into mysql.ndb_schema values("","",0,"",0,0,0,0,0);
   if ($mysql_errno)
   {

=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl	2011-07-05 12:46:07 +0000
+++ b/mysql-test/mysql-test-run.pl	2011-07-06 11:11:57 +0000
@@ -2255,10 +2255,6 @@ sub environment_setup {
 		  ["storage/ndb/tools", "bin"],
 		  "ndb_show_tables");
 
-    $ENV{'NDB_TOOLS_DIR'}=
-      my_find_dir($bindir,
-		  ["storage/ndb/tools", "bin"]);
-
     $ENV{'NDB_EXAMPLES_DIR'}=
       my_find_dir($basedir,
 		  ["storage/ndb/ndbapi-examples", "bin"]);

=== added file 'mysql-test/suite/ndb/include/ndb_share_check_shares.inc'
--- a/mysql-test/suite/ndb/include/ndb_share_check_shares.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/include/ndb_share_check_shares.inc	2011-07-06 06:47:16 +0000
@@ -0,0 +1,12 @@
+connection server1;
+--error 0,1193
+set global ndb_check_shares=1;
+connection server2;
+--error 0,1193
+set global ndb_check_shares=1;
+connection server3;
+--error 0,1193
+set global ndb_check_shares=1;
+connection server4;
+--error 0,1193
+set global ndb_check_shares=1;

=== modified file 'mysql-test/suite/ndb/r/ndb_alter_table3.result'
--- a/mysql-test/suite/ndb/r/ndb_alter_table3.result	2011-04-20 12:53:27 +0000
+++ b/mysql-test/suite/ndb/r/ndb_alter_table3.result	2011-07-06 11:11:57 +0000
@@ -21,10 +21,8 @@ a	b	c
 2	two	two
 drop table t1;
 create table t3 (a int primary key) engine=ndbcluster;
-begin;
 insert into t3 values (1);
 alter table t3 rename t4;
-commit;
 select * from t3;
 ERROR 42S02: Table 'test.t3' doesn't exist
 select * from t4;

=== modified file 'mysql-test/suite/ndb/r/ndb_basic.result'
--- a/mysql-test/suite/ndb/r/ndb_basic.result	2011-06-30 12:19:14 +0000
+++ b/mysql-test/suite/ndb/r/ndb_basic.result	2011-07-08 15:05:28 +0000
@@ -65,6 +65,7 @@ Ndb_api_wait_scan_result_count_slave	#
 Ndb_cluster_node_id	#
 Ndb_config_from_host	#
 Ndb_config_from_port	#
+Ndb_conflict_fn_epoch	#
 Ndb_conflict_fn_max	#
 Ndb_conflict_fn_max_del_win	#
 Ndb_conflict_fn_old	#
@@ -83,7 +84,8 @@ Ndb_scan_count	#
 Ndb_schema_locks_count	#
 Ndb_slave_max_replicated_epoch	#
 Ndb_sorted_scan_count	#
-SHOW GLOBAL VARIABLES LIKE 'ndb\_%';
+SHOW GLOBAL VARIABLES WHERE Variable_name LIKE 'ndb\_%' and 
+Variable_name NOT LIKE 'ndb_check_shares';
 Variable_name	Value
 ndb_autoincrement_prefetch_sz	#
 ndb_batch_size	#

=== added file 'mysql-test/suite/ndb/r/ndb_ddl_open_trans.result'
--- a/mysql-test/suite/ndb/r/ndb_ddl_open_trans.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_ddl_open_trans.result	2011-07-06 10:40:14 +0000
@@ -0,0 +1,50 @@
+create table t1 ( a int ) engine = ndb;
+begin;
+insert into t1 values(1);
+alter table t1 rename t2;
+commit;
+drop table t2;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 ( a int primary key) engine = ndb;
+begin;
+insert into t1 values(1);
+alter online table t1 add column b int column_format dynamic;
+commit;
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 ( a int primary key) engine = ndb;
+begin;
+insert into t1 values(1);
+alter offline table t1 add column b int column_format dynamic;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+commit;
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 ( a int primary key, b int) engine = ndb;
+begin;
+insert into t1 values(1, 1);
+create online index ind_b on t1(b);
+commit;
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 ( a int primary key, b int, index ind_b (b)) engine = ndb;
+begin;
+insert into t1 values(1, 1);
+drop index ind_b on t1;
+commit;
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create database testdb;
+create table testdb.t1 (a int) engine = ndb;
+begin;
+insert into testdb.t1 values(1);
+alter database testdb charset = latin1;
+commit;
+drop database testdb;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;

=== added file 'mysql-test/suite/ndb/r/ndb_share.result'
--- a/mysql-test/suite/ndb/r/ndb_share.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_share.result	2011-07-07 10:00:25 +0000
@@ -0,0 +1,328 @@
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	ON
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	ON
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	OFF
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	OFF
+create table t1 (a int) engine=ndbcluster;
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine=ndbcluster;
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine=ndbcluster;
+rename table t1 to t2;
+drop table t2;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine=ndbcluster;
+rename table t1 to t2;
+drop table t2;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine=ndbcluster;
+alter offline table t1 add column b int default 77;
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine=ndbcluster;
+alter offline table t1 add column b int default 77;
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int primary key) engine=ndbcluster
+partition by list(a) (partition p0 values in (0));
+alter offline table t1 add partition (partition p1 values in (1));
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int primary key) engine=ndbcluster
+partition by list(a) (partition p0 values in (0));
+alter offline table t1 add partition (partition p1 values in (1));
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int primary key) engine=ndbcluster;
+alter online table t1 add column b int column_format dynamic;
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int primary key) engine=ndbcluster;
+alter offline table t1 add column b int column_format dynamic;
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine=ndbcluster;
+create table t2 (a int) engine=ndbcluster;
+rename table t1 to tmp, t2 to t1, tmp to t2;
+drop table t1, t2;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine=ndbcluster;
+create table t2 (a int) engine=ndbcluster;
+rename table t1 to tmp, t2 to t1, tmp to t2;
+drop table t1, t2;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine=myisam;
+create table t1 (a int) engine=myisam;
+create table t1 (a int) engine = ndb;
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine = ndb;
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine = ndb;
+drop table t1;
+desc t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+drop table t1;
+desc t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine=myisam;
+create table t1 (a int) engine=myisam;
+create table t1 (a int) engine = ndb;
+alter offline table t1 add column b int column_format dynamic;
+drop table t1;
+desc t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+b	int(11)	YES		NULL	
+drop table t1;
+desc t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+b	int(11)	YES		NULL	
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine=myisam;
+create table t1 (a int) engine=myisam;
+create table t1 (a int primary key) engine = ndb;
+alter online table t1 add column b int column_format dynamic;
+drop table t1;
+desc t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	NO	PRI	NULL	
+b	int(11)	YES		NULL	
+drop table t1;
+desc t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	NO	PRI	NULL	
+b	int(11)	YES		NULL	
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine=myisam;
+create table t1 (a int) engine=myisam;
+create table t1 (a int) engine = ndb;
+rename table t1 to t2;
+desc t2;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+desc t2;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+drop table t2;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+drop table t1;
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table if not exists t1 (a int) engine=ndbcluster;
+create table if not exists t1 (a int) engine=ndbcluster;
+create table if not exists t1 (a int) engine=ndbcluster;
+create table if not exists t1 (a int) engine=ndbcluster;
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table if not exists t1 (a int) engine=ndbcluster;
+create table if not exists t1 (a int) engine=ndbcluster;
+create table if not exists t1 (a int) engine=ndbcluster;
+create table if not exists t1 (a int) engine=ndbcluster;
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table if not exists t1 (a int) engine=ndbcluster;
+create table if not exists t1 (a int) engine=ndbcluster;
+create table if not exists t1 (a int) engine=ndbcluster;
+create table if not exists t1 (a int) engine=ndbcluster;
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table if not exists t1 (a int) engine=ndbcluster;
+create table if not exists t1 (a int) engine=ndbcluster;
+create table if not exists t1 (a int) engine=ndbcluster;
+create table if not exists t1 (a int) engine=ndbcluster;
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table if not exists t1 (a int) engine=ndbcluster;
+create table if not exists t1 (a int) engine=ndbcluster;
+create table if not exists t1 (a int) engine=ndbcluster;
+create table if not exists t1 (a int) engine=ndbcluster;
+drop table t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine=ndbcluster;
+drop table if exists t1;
+drop table if exists t1;
+drop table if exists t1;
+drop table if exists t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine=ndbcluster;
+drop table if exists t1;
+drop table if exists t1;
+drop table if exists t1;
+drop table if exists t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine=ndbcluster;
+drop table if exists t1;
+drop table if exists t1;
+drop table if exists t1;
+drop table if exists t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine=ndbcluster;
+drop table if exists t1;
+drop table if exists t1;
+drop table if exists t1;
+drop table if exists t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine=ndbcluster;
+drop table if exists t1;
+drop table if exists t1;
+drop table if exists t1;
+drop table if exists t1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine=ndbcluster;
+create table t2 (a int) engine=ndbcluster;
+desc t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+desc t2;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+desc t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+desc t2;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+desc t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+desc t2;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+desc t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+desc t2;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+drop table t1, t2;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+create table t1 (a int) engine=ndbcluster;
+create table t2 (a int) engine=ndbcluster;
+desc t1;
+ERROR 42S02: Table 'test.t1' doesn't exist
+desc t2;
+ERROR 42S02: Table 'test.t2' doesn't exist
+desc t1;
+ERROR 42S02: Table 'test.t1' doesn't exist
+desc t2;
+ERROR 42S02: Table 'test.t2' doesn't exist
+desc t1;
+ERROR 42S02: Table 'test.t1' doesn't exist
+desc t2;
+ERROR 42S02: Table 'test.t2' doesn't exist
+desc t1;
+ERROR 42S02: Table 'test.t1' doesn't exist
+desc t2;
+ERROR 42S02: Table 'test.t2' doesn't exist
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;
+set global ndb_check_shares=1;

=== modified file 'mysql-test/suite/ndb/t/disabled.def'
--- a/mysql-test/suite/ndb/t/disabled.def	2011-06-29 14:14:47 +0000
+++ b/mysql-test/suite/ndb/t/disabled.def	2011-07-06 13:02:17 +0000
@@ -16,11 +16,10 @@ ndb_partition_error2 : Bug#40989 ndb_par
 ndb_cache_trans           : Bug#42197 Query cache and autocommit
 ndb_disconnect_ddl        : Bug#31853 flaky testcase...
 
-ndb_multi		 : SEAGULL schema distribution 
-
 ndb_sql_allow_batching   : SEAGULL WL3733 xxx_allow_batching
 
 ndb_temporary : SEAGULL patch to disallow temporary tables does not work
 
 ndb_dbug_lock : SEAGULL gsl locking order
 
+ndb_ddl_open_trans : SEAGULL mdl locking...

=== modified file 'mysql-test/suite/ndb/t/ndb_alter_table3.test'
--- a/mysql-test/suite/ndb/t/ndb_alter_table3.test	2011-06-09 13:42:10 +0000
+++ b/mysql-test/suite/ndb/t/ndb_alter_table3.test	2011-07-06 11:11:57 +0000
@@ -25,7 +25,6 @@ connection server1;
 create table t3 (a int primary key) engine=ndbcluster;
 
 connection server2;
-begin;
 insert into t3 values (1);
 
 connection server1;
@@ -37,7 +36,6 @@ connection server2;
 ## This should work as transaction is ongoing...
 #delete from t3;
 #insert into t3 values (1);
-commit; 
 
 # This should fail as its a new transaction
 --error 1146

=== modified file 'mysql-test/suite/ndb/t/ndb_basic.test'
--- a/mysql-test/suite/ndb/t/ndb_basic.test	2011-06-22 08:09:31 +0000
+++ b/mysql-test/suite/ndb/t/ndb_basic.test	2011-07-06 07:14:46 +0000
@@ -18,7 +18,8 @@ drop database if exists mysqltest;
 SHOW GLOBAL STATUS LIKE 'ndb\_%';
 --replace_column 2 #
 --sorted_result
-SHOW GLOBAL VARIABLES LIKE 'ndb\_%';
+SHOW GLOBAL VARIABLES WHERE Variable_name LIKE 'ndb\_%' and 
+                            Variable_name NOT LIKE 'ndb_check_shares';
 
 #
 # Create a normal table with primary key

=== added file 'mysql-test/suite/ndb/t/ndb_ddl_open_trans.test'
--- a/mysql-test/suite/ndb/t/ndb_ddl_open_trans.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_ddl_open_trans.test	2011-07-06 10:40:14 +0000
@@ -0,0 +1,166 @@
+-- source include/have_multi_ndb.inc
+
+
+#
+# alter - rename
+#
+connection server1;
+create table t1 ( a int ) engine = ndb;
+
+connection server2;
+begin;
+insert into t1 values(1);
+
+connection server1;
+alter table t1 rename t2;
+
+connection server2;
+commit;
+
+connection server1;
+drop table t2;
+
+connection server1;
+--error 0,1193
+set global ndb_check_shares=1;
+
+connection server2;
+--error 0,1193
+set global ndb_check_shares=1;
+
+#
+# alter online add column
+#
+connection server1;
+create table t1 ( a int primary key) engine = ndb;
+
+connection server2;
+begin;
+insert into t1 values(1);
+
+connection server1;
+alter online table t1 add column b int column_format dynamic;
+
+connection server2;
+commit;
+
+connection server1;
+drop table t1;
+
+connection server1;
+--error 0,1193
+set global ndb_check_shares=1;
+
+connection server2;
+--error 0,1193
+set global ndb_check_shares=1;
+
+#
+# alter offline add column
+#
+connection server1;
+create table t1 ( a int primary key) engine = ndb;
+
+connection server2;
+begin;
+insert into t1 values(1);
+
+connection server1;
+--error ER_LOCK_WAIT_TIMEOUT
+alter offline table t1 add column b int column_format dynamic;
+
+connection server2;
+commit;
+
+connection server1;
+drop table t1;
+
+connection server1;
+--error 0,1193
+set global ndb_check_shares=1;
+
+connection server2;
+--error 0,1193
+set global ndb_check_shares=1;
+
+#
+# online create index
+#
+connection server1;
+create table t1 ( a int primary key, b int) engine = ndb;
+
+connection server2;
+begin;
+insert into t1 values(1, 1);
+
+connection server1;
+create online index ind_b on t1(b);
+
+connection server2;
+commit;
+
+connection server1;
+drop table t1;
+
+connection server1;
+--error 0,1193
+set global ndb_check_shares=1;
+
+connection server2;
+--error 0,1193
+set global ndb_check_shares=1;
+
+#
+# online drop index
+#
+connection server1;
+create table t1 ( a int primary key, b int, index ind_b (b)) engine = ndb;
+
+connection server2;
+begin;
+insert into t1 values(1, 1);
+
+connection server1;
+drop index ind_b on t1;
+
+connection server2;
+commit;
+
+connection server1;
+drop table t1;
+
+connection server1;
+--error 0,1193
+set global ndb_check_shares=1;
+
+connection server2;
+--error 0,1193
+set global ndb_check_shares=1;
+
+#
+# alter db
+#
+connection server1;
+create database testdb;
+create table testdb.t1 (a int) engine = ndb;
+
+connection server2;
+begin;
+insert into testdb.t1 values(1);
+
+connection server1;
+alter database testdb charset = latin1;
+
+connection server2;
+commit;
+
+connection server1;
+drop database testdb;
+
+connection server1;
+--error 0,1193
+set global ndb_check_shares=1;
+
+connection server2;
+--error 0,1193
+set global ndb_check_shares=1;

=== modified file 'mysql-test/suite/ndb/t/ndb_restore_compat_downward.test'
--- a/mysql-test/suite/ndb/t/ndb_restore_compat_downward.test	2011-05-06 14:11:46 +0000
+++ b/mysql-test/suite/ndb/t/ndb_restore_compat_downward.test	2011-07-06 09:20:17 +0000
@@ -96,7 +96,7 @@ drop table t1;
 # bug#54613
 
 --error 1
---exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 2 -n 2 -m --core=0 --include-databases=ham --skip-unknown-objects $backup_data_dir/bug54613 >> $NDB_TOOLS_OUTPUT
+--exec $NDB_RESTORE --no-defaults -b 2 -n 2 -m --core=0 --include-databases=ham --skip-unknown-objects $backup_data_dir/bug54613 >> $NDB_TOOLS_OUTPUT
 
 --error 0
---exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 2 -n 2 -m --core=0 --include-databases=ham --skip-unknown-objects --skip-broken-objects $backup_data_dir/bug54613 >> $NDB_TOOLS_OUTPUT
+--exec $NDB_RESTORE --no-defaults -b 2 -n 2 -m --core=0 --include-databases=ham --skip-unknown-objects --skip-broken-objects $backup_data_dir/bug54613 >> $NDB_TOOLS_OUTPUT

=== added file 'mysql-test/suite/ndb/t/ndb_share.cnf'
--- a/mysql-test/suite/ndb/t/ndb_share.cnf	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_share.cnf	2011-07-07 10:00:25 +0000
@@ -0,0 +1,32 @@
+!include ../my.cnf
+
+[cluster_config.1]
+mysqld=,,,
+
+[mysqld.1.1]
+new
+log-bin=mysqld-bin
+
+[mysqld.2.1]
+new
+log-bin=mysqld-bin
+
+[mysqld.3.1]
+new
+skip-log-bin
+
+[mysqld.4.1]
+new
+skip-log-bin
+
+[ENV]
+
+NDB_CONNECTSTRING=             @mysql_cluster.1.ndb_connectstring
+MYSQLD1_SOCK=                  @mysqld.1.1.socket
+MYSQLD1_PORT=                  @mysqld.1.1.port
+MYSQLD2_SOCK=                  @mysqld.2.1.socket
+MYSQLD2_PORT=                  @mysqld.2.1.port
+MYSQLD3_SOCK=                  @mysqld.3.1.socket
+MYSQLD3_PORT=                  @mysqld.3.1.port
+MYSQLD4_SOCK=                  @mysqld.4.1.socket
+MYSQLD4_PORT=                  @mysqld.4.1.port

=== added file 'mysql-test/suite/ndb/t/ndb_share.test'
--- a/mysql-test/suite/ndb/t/ndb_share.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_share.test	2011-07-07 10:12:54 +0000
@@ -0,0 +1,386 @@
+-- source include/not_embedded.inc
+-- source include/have_ndb.inc
+-- source include/have_log_bin.inc
+
+-- disable_query_log
+call mtr.add_suppression('.*You need to use --log-bin to make --binlog-format work.*');
+-- enable_query_log
+
+connect (server1,127.0.0.1,root,,test,$MYSQLD1_PORT,);
+connect (server2,127.0.0.1,root,,test,$MYSQLD2_PORT,);
+connect (server3,127.0.0.1,root,,test,$MYSQLD3_PORT,);
+connect (server4,127.0.0.1,root,,test,$MYSQLD4_PORT,);
+
+connection server1;
+show variables like 'log_bin';
+connection server2;
+show variables like 'log_bin';
+connection server3;
+show variables like 'log_bin';
+connection server4;
+show variables like 'log_bin';
+
+#
+# Basic create+drop (from with and without log-bin)
+#   no share should be present
+#
+connection server1;
+create table t1 (a int) engine=ndbcluster;
+drop table t1;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+connection server3;
+create table t1 (a int) engine=ndbcluster;
+drop table t1;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+#
+# Basic create+rename+drop (from with and without log-bin)
+#   no share should be present
+#
+connection server1;
+create table t1 (a int) engine=ndbcluster;
+rename table t1 to t2;
+drop table t2;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+connection server2;
+create table t1 (a int) engine=ndbcluster;
+rename table t1 to t2;
+drop table t2;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+#
+# Basic create+offline-alter+drop (from with and without log-bin)
+#   no share should be present
+#
+connection server1;
+create table t1 (a int) engine=ndbcluster;
+alter offline table t1 add column b int default 77;
+drop table t1;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+connection server2;
+create table t1 (a int) engine=ndbcluster;
+alter offline table t1 add column b int default 77;
+drop table t1;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+#
+# Basic create+offline-alter-partitions+drop (from with and without log-bin)
+#   no share should be present
+#
+connection server1;
+create table t1 (a int primary key) engine=ndbcluster
+partition by list(a) (partition p0 values in (0));
+alter offline table t1 add partition (partition p1 values in (1));
+drop table t1;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+connection server2;
+create table t1 (a int primary key) engine=ndbcluster
+partition by list(a) (partition p0 values in (0));
+alter offline table t1 add partition (partition p1 values in (1));
+drop table t1;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+#
+# Basic create+online-alter+drop (from with and without log-bin)
+#   no share should be present
+#
+connection server1;
+create table t1 (a int primary key) engine=ndbcluster;
+alter online table t1 add column b int column_format dynamic;
+drop table t1;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+connection server2;
+create table t1 (a int primary key) engine=ndbcluster;
+alter offline table t1 add column b int column_format dynamic;
+drop table t1;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+#
+# Basic create+multi-rename+drop (from with and without log-bin)
+#   no share should be present
+#
+connection server1;
+create table t1 (a int) engine=ndbcluster;
+create table t2 (a int) engine=ndbcluster;
+rename table t1 to tmp, t2 to t1, tmp to t2;
+drop table t1, t2;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+connection server2;
+create table t1 (a int) engine=ndbcluster;
+create table t2 (a int) engine=ndbcluster;
+rename table t1 to tmp, t2 to t1, tmp to t2;
+drop table t1, t2;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+#
+# Now...lets get nastier 1
+#   create myisam tables on other servers...and then create ndb table
+#
+connection server2;
+create table t1 (a int) engine=myisam;
+connection server4;
+create table t1 (a int) engine=myisam;
+
+connection server1;
+create table t1 (a int) engine = ndb;
+drop table t1;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+connection server3;
+create table t1 (a int) engine = ndb;
+drop table t1;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+connection server1;
+create table t1 (a int) engine = ndb;
+
+connection server2;
+drop table t1;
+desc t1; # force discovery
+
+connection server4;
+drop table t1;
+desc t1; # force discovery
+
+connection server1;
+drop table t1;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+#
+# Now...lets get nastier 2
+#   create myisam tables on other servers...and then create ndb table
+#   and off-line alter them
+connection server2;
+create table t1 (a int) engine=myisam;
+connection server4;
+create table t1 (a int) engine=myisam;
+
+connection server1;
+create table t1 (a int) engine = ndb;
+alter offline table t1 add column b int column_format dynamic;
+
+connection server2;
+drop table t1;
+desc t1; # force discovery
+
+connection server4;
+drop table t1;
+desc t1; # force discovery
+
+connection server1;
+drop table t1;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+#
+# Now...lets get nastier 3
+#   create myisam tables on other servers...and then create ndb table
+#   and online alter them
+connection server2;
+create table t1 (a int) engine=myisam;
+connection server4;
+create table t1 (a int) engine=myisam;
+
+connection server1;
+create table t1 (a int primary key) engine = ndb;
+alter online table t1 add column b int column_format dynamic;
+
+connection server2;
+drop table t1;
+desc t1; # force discovery
+
+connection server4;
+drop table t1;
+desc t1; # force discovery
+
+connection server1;
+drop table t1;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+#
+# Now...lets get nastier 4
+#   create myisam tables on other servers...and then create ndb table
+#   and rename them
+connection server2;
+create table t1 (a int) engine=myisam;
+connection server4;
+create table t1 (a int) engine=myisam;
+
+connection server1;
+create table t1 (a int) engine = ndb;
+rename table t1 to t2;
+
+connection server2;
+desc t2; # force discovery
+
+connection server4;
+desc t2; # force discovery
+
+connection server1;
+drop table t2;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+connection server2;
+drop table t1;
+
+connection server4;
+drop table t1;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+#
+# Now...create table if not exists
+#
+--disable_warnings
+let $1=5;
+while ($1)
+{
+  dec $1;
+  connection server1;
+  --send create table if not exists t1 (a int) engine=ndbcluster
+  connection server2;
+  --send create table if not exists t1 (a int) engine=ndbcluster
+  connection server3;
+  --send create table if not exists t1 (a int) engine=ndbcluster
+  connection server4;
+  --send create table if not exists t1 (a int) engine=ndbcluster
+  connection server1;
+  --reap
+  connection server2;
+  --reap
+  connection server3;
+  --reap
+  connection server4;
+  --reap
+  connection server1;
+  drop table t1;
+  --source suite/ndb/include/ndb_share_check_shares.inc
+}
+--enable_warnings
+
+#
+# Now...drop table if exists
+#
+--disable_warnings
+let $1=5;
+while ($1)
+{
+  dec $1;
+  connection server1;
+  create table t1 (a int) engine=ndbcluster;
+
+  connection server1;
+  --send drop table if exists t1
+  connection server2;
+  --send drop table if exists t1
+  connection server3;
+  --send drop table if exists t1
+  connection server4;
+  --send drop table if exists t1
+  connection server1;
+  --reap
+  connection server2;
+  --reap
+  connection server3;
+  --reap
+  connection server4;
+  --reap
+  --source suite/ndb/include/ndb_share_check_shares.inc
+}
+--enable_warnings
+
+#
+# Now...restart
+#
+connection server1;
+create table t1 (a int) engine=ndbcluster;
+
+connection server3;
+create table t2 (a int) engine=ndbcluster;
+
+--exec $NDB_MGM --no-defaults -e "all restart -n" >> $NDB_TOOLS_OUTPUT
+--exec $NDB_WAITER --no-defaults --ndb-connectstring="$NDB_CONNECTSTRING" --not-started >> $NDB_TOOLS_OUTPUT
+--exec $NDB_MGM --no-defaults -e "all start" >> $NDB_TOOLS_OUTPUT
+--exec $NDB_WAITER --no-defaults --ndb-connectstring="$NDB_CONNECTSTRING" >> $NDB_TOOLS_OUTPUT
+
+# Wait for mysqld to reconnect and exit from readonly mode
+--disable_query_log
+connection server1;
+--source include/ndb_not_readonly.inc
+connection server2;
+--source include/ndb_not_readonly.inc
+connection server3;
+--source include/ndb_not_readonly.inc
+connection server4;
+--source include/ndb_not_readonly.inc
+--enable_query_log
+
+connection server1;
+desc t1;
+desc t2;
+connection server2;
+desc t1;
+desc t2;
+connection server3;
+desc t1;
+desc t2;
+connection server4;
+desc t1;
+desc t2;
+
+connection server1;
+drop table t1, t2;
+--source suite/ndb/include/ndb_share_check_shares.inc
+
+#
+# Now...restart -i
+#
+connection server1;
+create table t1 (a int) engine=ndbcluster;
+
+connection server3;
+create table t2 (a int) engine=ndbcluster;
+
+--exec $NDB_MGM --no-defaults -e "all restart -i -n" >> $NDB_TOOLS_OUTPUT
+--exec $NDB_WAITER --no-defaults --ndb-connectstring="$NDB_CONNECTSTRING" --not-started >> $NDB_TOOLS_OUTPUT
+--exec $NDB_MGM --no-defaults -e "all start" >> $NDB_TOOLS_OUTPUT
+--exec $NDB_WAITER --no-defaults --ndb-connectstring="$NDB_CONNECTSTRING" >> $NDB_TOOLS_OUTPUT
+
+# Wait for mysqld to reconnect and exit from readonly mode
+--disable_query_log
+connection server1;
+--source include/ndb_not_readonly.inc
+connection server2;
+--source include/ndb_not_readonly.inc
+connection server3;
+--source include/ndb_not_readonly.inc
+connection server4;
+--source include/ndb_not_readonly.inc
+--enable_query_log
+
+connection server1;
+--error 1146
+desc t1;
+--error 1146
+desc t2;
+connection server2;
+--error 1146
+desc t1;
+--error 1146
+desc t2;
+connection server3;
+--error 1146
+desc t1;
+--error 1146
+desc t2;
+connection server4;
+--error 1146
+desc t1;
+--error 1146
+desc t2;
+
+--source suite/ndb/include/ndb_share_check_shares.inc

=== added file 'mysql-test/suite/ndb_rpl/r/ndb_rpl_conflict_epoch.result'
--- a/mysql-test/suite/ndb_rpl/r/ndb_rpl_conflict_epoch.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb_rpl/r/ndb_rpl_conflict_epoch.result	2011-07-07 14:48:06 +0000
@@ -0,0 +1,2879 @@
+include/master-slave.inc
+[connection master]
+Setup circular replication
+RESET MASTER;
+select @slave_server_id:=(variable_value+0)
+from information_schema.global_variables
+where variable_name like 'server_id';
+@slave_server_id:=(variable_value+0)
+3
+CHANGE MASTER TO master_host="127.0.0.1",master_port=SLAVE_PORT,master_user="root";
+START SLAVE;
+select @master_server_id:=(variable_value+0)
+from information_schema.global_variables
+where variable_name like 'server_id';
+@master_server_id:=(variable_value+0)
+1
+Setup ndb_replication and t1 exceptions table
+Populate ndb_replication table as necessary
+-- 0 extra gci bits
+replace into mysql.ndb_replication values
+("test", "t1", 3, 7, NULL),
+("test", "t1", 1, 7, "NDB$EPOCH(0)");
+create table `test`.`t1$EX`
+  (server_id int unsigned,
+master_server_id int unsigned,
+master_epoch bigint unsigned,
+count int unsigned,
+a int not null,
+d int,
+primary key(server_id, master_server_id, master_epoch, count)) engine ndb;
+Create table
+create table test.t1(a int primary key, b varchar(255)) engine = ndb;
+Create other table
+create table test.t2(a int primary key, b int) engine = ndb;
+----------------------------------
+Test 1 : Basic two-way replication
+----------------------------------
+insert into test.t1 values (1, "Metropole");
+-- Give time for a new epoch on the Master
+-- Insert something to ensure the new epoch is noticed
+replace into test.t2 values (2, 1);
+-- Flushed to slave
+select * from test.t1 order by a;
+a	b
+1	Metropole
+-- Flushed back to Master
+select * from test.t1 order by a;
+a	b
+1	Metropole
+-- Now update data on slave
+update test.t1 set b="Favorit" where a=1;
+-- Now check data on master
+select * from test.t1 order by a;
+a	b
+1	Favorit
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Now perform multiple consecutive updates on the slave
+update test.t1 set b="Elephant house" where a=1;
+update test.t1 set b="Beach house" where a=1;
+select * from test.t1 order by a;
+a	b
+1	Beach house
+-- Now check they've applied on the master
+select * from test.t1 order by a;
+a	b
+1	Beach house
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+--------------------------------------------
+Test 2 : Normal Insert from Secondary Master
+--------------------------------------------
+-- Insert a new row on the Slave
+insert into test.t1 values (2, "Forrest");
+-- Check it exists on the Master
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Forrest
+-- Update from the slave
+update test.t1 set b="Reds" where a=2;
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Reds
+delete from test.t1 where a=2;
+select * from test.t1 order by a;
+a	b
+1	Beach house
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-------------------------------
+Test 3 : Insert-Insert conflict
+-------------------------------
+stop slave;
+-- Insert a row on the Primary Master
+insert into test.t1 values (2, "Loopy Lornas");
+-- Insert a row on the secondary Master
+insert into test.t1 values (2, "Cloisters");
+-- Examine data on Primary Master (should be unaffected)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Loopy Lornas
+-- Examine conflict indicators on Primary Master
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+1
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on isolated secondary Master (should be as-set)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Cloisters
+-- Restart secondary Masters slave
+start slave;
+-- Reexamine secondary Master's data (should be same as Primary Masters)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Loopy Lornas
+-------------------------------
+Test 4 : Update-Update conflict
+-------------------------------
+-- Stop replication to secondary master
+stop slave;
+-- Update row on Primary Master
+update test.t1 set b="Peters Yard" where a=2;
+-- Show data on Primary Master
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Peters Yard
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+1
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Update row on Secondary Master
+update test.t1 set b="Toast" where a=2;
+-- Examine data on Primary Master - should be unaffected
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Peters Yard
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+2
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Check data on secondary - should be as set
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Toast
+-- Now restart slave, will re-align row
+start slave;
+-- Check that Secondary is re-aligned
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Peters Yard
+-------------------------------
+Test 5 : Update-Delete conflict
+-------------------------------
+-- Stop Secondary slave
+stop slave;
+-- Update on Primary Master
+update test.t1 set b="Pear tree" where a = 2;
+-- Delete on Secondary Master
+delete from test.t1 where a = 2;
+-- Examine data on Primary Master, should be unaffected
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Pear tree
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+3
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on Secondary Master before slave restart, still missing
+select * from test.t1 order by a;
+a	b
+1	Beach house
+-- Restart Secondary Master slave
+start slave;
+-- Examine data on Secondary Master after slave restart, aligned with Master
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Pear tree
+-------------------------------
+Test 6 : Delete-Update conflict
+-------------------------------
+-- Stop Secondary slave
+stop slave;
+-- Delete on Primary Master
+delete from test.t1 where a=2;
+-- Update on Secondary Master
+update test.t1 set b="Black pig" where a=2;
+-- Examine data on Primary Master, should be unaffected (no row)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+4
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on Secondary Master before slave restart, should be as inserted
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Black pig
+-- Restart Secondary Master slave
+start slave;
+-- Examine data on Secondary Master after slave restart, aligned with Master (deleted)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+-------------------------------
+Test 7 : Delete-Delete conflict
+-------------------------------
+-- Stop Secondary slave
+stop slave;
+-- Delete on Primary Master
+delete from test.t1 where a=1;
+-- Delete on Secondary Master
+delete from test.t1 where a=1;
+-- Examine data on Primary Master, no row
+select * from test.t1 order by a;
+a	b
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+5
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on Secondary Master before slave restart, no row
+select * from test.t1 order by a;
+a	b
+-- Restart Secondary Master slave
+start slave;
+-- Examine data on Secondary Master after slave restart, no row
+select * from test.t1 order by a;
+a	b
+------------------------------------------------
+Test 8 : Delete-Delete, Insert conflict exposure
+------------------------------------------------
+-- Insert a row on Secondary Master
+insert into test.t1 values (3, "Espy");
+-- Check it's present on Primary Master
+select * from test.t1 order by a;
+a	b
+3	Espy
+-- Stop replication in both directions
+stop slave;
+stop slave;
+-- Delete row from both clusters
+delete from test.t1 where a=3;
+delete from test.t1 where a=3;
+-- Follow up with Insert from Secondary master
+insert into test.t1 values (3, "Dalriada");
+-- Restart replication in both directions
+start slave;
+start slave;
+-- Check data on both sites - diverged
+-- Secondary master :
+select * from test.t1 order by a;
+a	b
+-- Primary master :
+select * from test.t1 order by a;
+a	b
+3	Dalriada
+--Remove extra row
+delete from test.t1 where a=3;
+-- Note that Delete-Delete conflict detected below
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+6
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+------------------------------------------------
+Test 9 : Insert, Insert-Update-Delete conflict
+------------------------------------------------
+-- Stop replication on Secondary Master
+stop slave;
+-- Insert row on Primary Master
+insert into test.t1 values (4, "Haymarket");
+-- Insert row on Secondary Master
+insert into test.t1 values (4, "Outhouse");
+-- Update row on Secondary Master
+update test.t1 set b="Mathers" where a = 4;
+-- Delete row on Secondary Master
+delete from test.t1 where a=4;
+-- Examine data (none) on Secondary Master
+select * from test.t1 order by a;
+a	b
+-- Examine data on Primary Master, should be unaffected
+select * from test.t1 order by a;
+a	b
+4	Haymarket
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+9
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+1	3	#	7	#	#
+1	3	#	8	#	#
+1	3	#	9	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on Secondary Master (none)
+select * from test.t1 order by a;
+a	b
+-- Restart Secondary Master's slave
+start slave;
+-- Check data on Secondary Master, should be same as Primary Master
+select * from test.t1;
+a	b
+4	Haymarket
+------------------------------------------------
+Test 10 : Update, Delete-Insert-Update conflict
+------------------------------------------------
+-- Stop replication on Secondary Master
+stop slave;
+-- Update row on Primary Master
+update test.t1 set b="Blind poet" where a=4;
+-- Delete row on Secondary Master
+delete from test.t1 where a=4;
+-- Insert row on Secondary Master
+insert into test.t1 values (4, "Drouthy Neebors");
+-- Update row on Secondary Master
+update test.t1 set b="The Tankard" where a=4;
+-- Check data on Primary Master, should be unaffected
+select * from test.t1 order by a;
+a	b
+4	Blind poet
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+12
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+1	3	#	7	#	#
+1	3	#	8	#	#
+1	3	#	9	#	#
+1	3	#	10	#	#
+1	3	#	11	#	#
+1	3	#	12	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Check data on Secondary Master, as set
+select * from test.t1 order by a;
+a	b
+4	The Tankard
+-- Restart Secondary Master slave
+start slave;
+-- Check data on Secondary Master - should be as Primary
+select * from test.t1 order by a;
+a	b
+4	Blind poet
+------------------------------------------------------------------------
+Test 11 : Test Secondary insert-update-delete accepted
+------------------------------------------------------------------------
+Insert row on Secondary
+insert into test.t1 values (5, "Minders");
+Update row on Secondary
+update test.t1 set b="Southsider" where a=5;
+Delete row on Secondary
+delete from test.t1 where a=5;
+Check data on Primary, should be none.  No new conflicts
+select * from test.t1 order by a;
+a	b
+4	Blind poet
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+12
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+1	3	#	7	#	#
+1	3	#	8	#	#
+1	3	#	9	#	#
+1	3	#	10	#	#
+1	3	#	11	#	#
+1	3	#	12	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+12
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+1	3	#	7	#	#
+1	3	#	8	#	#
+1	3	#	9	#	#
+1	3	#	10	#	#
+1	3	#	11	#	#
+1	3	#	12	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+drop table test.t1;
+drop table test.t2;
+drop table test.t1$EX;
+Populate ndb_replication table as necessary
+-- 1 extra gci bits
+replace into mysql.ndb_replication values
+("test", "t1", 3, 7, NULL),
+("test", "t1", 1, 7, "NDB$EPOCH(1)");
+create table `test`.`t1$EX`
+  (server_id int unsigned,
+master_server_id int unsigned,
+master_epoch bigint unsigned,
+count int unsigned,
+a int not null,
+d int,
+primary key(server_id, master_server_id, master_epoch, count)) engine ndb;
+Create table
+create table test.t1(a int primary key, b varchar(255)) engine = ndb;
+Create other table
+create table test.t2(a int primary key, b int) engine = ndb;
+----------------------------------
+Test 1 : Basic two-way replication
+----------------------------------
+insert into test.t1 values (1, "Metropole");
+-- Give time for a new epoch on the Master
+-- Insert something to ensure the new epoch is noticed
+replace into test.t2 values (2, 1);
+-- Flushed to slave
+select * from test.t1 order by a;
+a	b
+1	Metropole
+-- Flushed back to Master
+select * from test.t1 order by a;
+a	b
+1	Metropole
+-- Now update data on slave
+update test.t1 set b="Favorit" where a=1;
+-- Now check data on master
+select * from test.t1 order by a;
+a	b
+1	Favorit
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Now perform multiple consecutive updates on the slave
+update test.t1 set b="Elephant house" where a=1;
+update test.t1 set b="Beach house" where a=1;
+select * from test.t1 order by a;
+a	b
+1	Beach house
+-- Now check they've applied on the master
+select * from test.t1 order by a;
+a	b
+1	Beach house
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+--------------------------------------------
+Test 2 : Normal Insert from Secondary Master
+--------------------------------------------
+-- Insert a new row on the Slave
+insert into test.t1 values (2, "Forrest");
+-- Check it exists on the Master
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Forrest
+-- Update from the slave
+update test.t1 set b="Reds" where a=2;
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Reds
+delete from test.t1 where a=2;
+select * from test.t1 order by a;
+a	b
+1	Beach house
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-------------------------------
+Test 3 : Insert-Insert conflict
+-------------------------------
+stop slave;
+-- Insert a row on the Primary Master
+insert into test.t1 values (2, "Loopy Lornas");
+-- Insert a row on the secondary Master
+insert into test.t1 values (2, "Cloisters");
+-- Examine data on Primary Master (should be unaffected)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Loopy Lornas
+-- Examine conflict indicators on Primary Master
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+1
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on isolated secondary Master (should be as-set)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Cloisters
+-- Restart secondary Masters slave
+start slave;
+-- Reexamine secondary Master's data (should be same as Primary Masters)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Loopy Lornas
+-------------------------------
+Test 4 : Update-Update conflict
+-------------------------------
+-- Stop replication to secondary master
+stop slave;
+-- Update row on Primary Master
+update test.t1 set b="Peters Yard" where a=2;
+-- Show data on Primary Master
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Peters Yard
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+1
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Update row on Secondary Master
+update test.t1 set b="Toast" where a=2;
+-- Examine data on Primary Master - should be unaffected
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Peters Yard
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+2
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Check data on secondary - should be as set
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Toast
+-- Now restart slave, will re-align row
+start slave;
+-- Check that Secondary is re-aligned
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Peters Yard
+-------------------------------
+Test 5 : Update-Delete conflict
+-------------------------------
+-- Stop Secondary slave
+stop slave;
+-- Update on Primary Master
+update test.t1 set b="Pear tree" where a = 2;
+-- Delete on Secondary Master
+delete from test.t1 where a = 2;
+-- Examine data on Primary Master, should be unaffected
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Pear tree
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+3
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on Secondary Master before slave restart, still missing
+select * from test.t1 order by a;
+a	b
+1	Beach house
+-- Restart Secondary Master slave
+start slave;
+-- Examine data on Secondary Master after slave restart, aligned with Master
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Pear tree
+-------------------------------
+Test 6 : Delete-Update conflict
+-------------------------------
+-- Stop Secondary slave
+stop slave;
+-- Delete on Primary Master
+delete from test.t1 where a=2;
+-- Update on Secondary Master
+update test.t1 set b="Black pig" where a=2;
+-- Examine data on Primary Master, should be unaffected (no row)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+4
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on Secondary Master before slave restart, should be as inserted
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Black pig
+-- Restart Secondary Master slave
+start slave;
+-- Examine data on Secondary Master after slave restart, aligned with Master (deleted)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+-------------------------------
+Test 7 : Delete-Delete conflict
+-------------------------------
+-- Stop Secondary slave
+stop slave;
+-- Delete on Primary Master
+delete from test.t1 where a=1;
+-- Delete on Secondary Master
+delete from test.t1 where a=1;
+-- Examine data on Primary Master, no row
+select * from test.t1 order by a;
+a	b
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+5
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on Secondary Master before slave restart, no row
+select * from test.t1 order by a;
+a	b
+-- Restart Secondary Master slave
+start slave;
+-- Examine data on Secondary Master after slave restart, no row
+select * from test.t1 order by a;
+a	b
+------------------------------------------------
+Test 8 : Delete-Delete, Insert conflict exposure
+------------------------------------------------
+-- Insert a row on Secondary Master
+insert into test.t1 values (3, "Espy");
+-- Check it's present on Primary Master
+select * from test.t1 order by a;
+a	b
+3	Espy
+-- Stop replication in both directions
+stop slave;
+stop slave;
+-- Delete row from both clusters
+delete from test.t1 where a=3;
+delete from test.t1 where a=3;
+-- Follow up with Insert from Secondary master
+insert into test.t1 values (3, "Dalriada");
+-- Restart replication in both directions
+start slave;
+start slave;
+-- Check data on both sites - diverged
+-- Secondary master :
+select * from test.t1 order by a;
+a	b
+-- Primary master :
+select * from test.t1 order by a;
+a	b
+3	Dalriada
+--Remove extra row
+delete from test.t1 where a=3;
+-- Note that Delete-Delete conflict detected below
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+6
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+------------------------------------------------
+Test 9 : Insert, Insert-Update-Delete conflict
+------------------------------------------------
+-- Stop replication on Secondary Master
+stop slave;
+-- Insert row on Primary Master
+insert into test.t1 values (4, "Haymarket");
+-- Insert row on Secondary Master
+insert into test.t1 values (4, "Outhouse");
+-- Update row on Secondary Master
+update test.t1 set b="Mathers" where a = 4;
+-- Delete row on Secondary Master
+delete from test.t1 where a=4;
+-- Examine data (none) on Secondary Master
+select * from test.t1 order by a;
+a	b
+-- Examine data on Primary Master, should be unaffected
+select * from test.t1 order by a;
+a	b
+4	Haymarket
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+9
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+1	3	#	7	#	#
+1	3	#	8	#	#
+1	3	#	9	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on Secondary Master (none)
+select * from test.t1 order by a;
+a	b
+-- Restart Secondary Master's slave
+start slave;
+-- Check data on Secondary Master, should be same as Primary Master
+select * from test.t1;
+a	b
+4	Haymarket
+------------------------------------------------
+Test 10 : Update, Delete-Insert-Update conflict
+------------------------------------------------
+-- Stop replication on Secondary Master
+stop slave;
+-- Update row on Primary Master
+update test.t1 set b="Blind poet" where a=4;
+-- Delete row on Secondary Master
+delete from test.t1 where a=4;
+-- Insert row on Secondary Master
+insert into test.t1 values (4, "Drouthy Neebors");
+-- Update row on Secondary Master
+update test.t1 set b="The Tankard" where a=4;
+-- Check data on Primary Master, should be unaffected
+select * from test.t1 order by a;
+a	b
+4	Blind poet
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+12
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+1	3	#	7	#	#
+1	3	#	8	#	#
+1	3	#	9	#	#
+1	3	#	10	#	#
+1	3	#	11	#	#
+1	3	#	12	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Check data on Secondary Master, as set
+select * from test.t1 order by a;
+a	b
+4	The Tankard
+-- Restart Secondary Master slave
+start slave;
+-- Check data on Secondary Master - should be as Primary
+select * from test.t1 order by a;
+a	b
+4	Blind poet
+------------------------------------------------------------------------
+Test 11 : Test Secondary insert-update-delete accepted
+------------------------------------------------------------------------
+Insert row on Secondary
+insert into test.t1 values (5, "Minders");
+Update row on Secondary
+update test.t1 set b="Southsider" where a=5;
+Delete row on Secondary
+delete from test.t1 where a=5;
+Check data on Primary, should be none.  No new conflicts
+select * from test.t1 order by a;
+a	b
+4	Blind poet
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+12
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+1	3	#	7	#	#
+1	3	#	8	#	#
+1	3	#	9	#	#
+1	3	#	10	#	#
+1	3	#	11	#	#
+1	3	#	12	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+12
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+1	3	#	7	#	#
+1	3	#	8	#	#
+1	3	#	9	#	#
+1	3	#	10	#	#
+1	3	#	11	#	#
+1	3	#	12	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+drop table test.t1;
+drop table test.t2;
+drop table test.t1$EX;
+Populate ndb_replication table as necessary
+-- 31 extra gci bits
+replace into mysql.ndb_replication values
+("test", "t1", 3, 7, NULL),
+("test", "t1", 1, 7, "NDB$EPOCH(31)");
+create table `test`.`t1$EX`
+  (server_id int unsigned,
+master_server_id int unsigned,
+master_epoch bigint unsigned,
+count int unsigned,
+a int not null,
+d int,
+primary key(server_id, master_server_id, master_epoch, count)) engine ndb;
+Create table
+create table test.t1(a int primary key, b varchar(255)) engine = ndb;
+Create other table
+create table test.t2(a int primary key, b int) engine = ndb;
+----------------------------------
+Test 1 : Basic two-way replication
+----------------------------------
+insert into test.t1 values (1, "Metropole");
+-- Give time for a new epoch on the Master
+-- Insert something to ensure the new epoch is noticed
+replace into test.t2 values (2, 1);
+-- Flushed to slave
+select * from test.t1 order by a;
+a	b
+1	Metropole
+-- Flushed back to Master
+select * from test.t1 order by a;
+a	b
+1	Metropole
+-- Now update data on slave
+update test.t1 set b="Favorit" where a=1;
+-- Now check data on master
+select * from test.t1 order by a;
+a	b
+1	Favorit
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Now perform multiple consecutive updates on the slave
+update test.t1 set b="Elephant house" where a=1;
+update test.t1 set b="Beach house" where a=1;
+select * from test.t1 order by a;
+a	b
+1	Beach house
+-- Now check they've applied on the master
+select * from test.t1 order by a;
+a	b
+1	Beach house
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+--------------------------------------------
+Test 2 : Normal Insert from Secondary Master
+--------------------------------------------
+-- Insert a new row on the Slave
+insert into test.t1 values (2, "Forrest");
+-- Check it exists on the Master
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Forrest
+-- Update from the slave
+update test.t1 set b="Reds" where a=2;
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Reds
+delete from test.t1 where a=2;
+select * from test.t1 order by a;
+a	b
+1	Beach house
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-------------------------------
+Test 3 : Insert-Insert conflict
+-------------------------------
+stop slave;
+-- Insert a row on the Primary Master
+insert into test.t1 values (2, "Loopy Lornas");
+-- Insert a row on the secondary Master
+insert into test.t1 values (2, "Cloisters");
+-- Examine data on Primary Master (should be unaffected)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Loopy Lornas
+-- Examine conflict indicators on Primary Master
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+1
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on isolated secondary Master (should be as-set)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Cloisters
+-- Restart secondary Masters slave
+start slave;
+-- Reexamine secondary Master's data (should be same as Primary Masters)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Loopy Lornas
+-------------------------------
+Test 4 : Update-Update conflict
+-------------------------------
+-- Stop replication to secondary master
+stop slave;
+-- Update row on Primary Master
+update test.t1 set b="Peters Yard" where a=2;
+-- Show data on Primary Master
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Peters Yard
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+1
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Update row on Secondary Master
+update test.t1 set b="Toast" where a=2;
+-- Examine data on Primary Master - should be unaffected
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Peters Yard
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+2
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Check data on secondary - should be as set
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Toast
+-- Now restart slave, will re-align row
+start slave;
+-- Check that Secondary is re-aligned
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Peters Yard
+-------------------------------
+Test 5 : Update-Delete conflict
+-------------------------------
+-- Stop Secondary slave
+stop slave;
+-- Update on Primary Master
+update test.t1 set b="Pear tree" where a = 2;
+-- Delete on Secondary Master
+delete from test.t1 where a = 2;
+-- Examine data on Primary Master, should be unaffected
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Pear tree
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+3
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on Secondary Master before slave restart, still missing
+select * from test.t1 order by a;
+a	b
+1	Beach house
+-- Restart Secondary Master slave
+start slave;
+-- Examine data on Secondary Master after slave restart, aligned with Master
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Pear tree
+-------------------------------
+Test 6 : Delete-Update conflict
+-------------------------------
+-- Stop Secondary slave
+stop slave;
+-- Delete on Primary Master
+delete from test.t1 where a=2;
+-- Update on Secondary Master
+update test.t1 set b="Black pig" where a=2;
+-- Examine data on Primary Master, should be unaffected (no row)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+4
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on Secondary Master before slave restart, should be as inserted
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Black pig
+-- Restart Secondary Master slave
+start slave;
+-- Examine data on Secondary Master after slave restart, aligned with Master (deleted)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+-------------------------------
+Test 7 : Delete-Delete conflict
+-------------------------------
+-- Stop Secondary slave
+stop slave;
+-- Delete on Primary Master
+delete from test.t1 where a=1;
+-- Delete on Secondary Master
+delete from test.t1 where a=1;
+-- Examine data on Primary Master, no row
+select * from test.t1 order by a;
+a	b
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+5
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on Secondary Master before slave restart, no row
+select * from test.t1 order by a;
+a	b
+-- Restart Secondary Master slave
+start slave;
+-- Examine data on Secondary Master after slave restart, no row
+select * from test.t1 order by a;
+a	b
+------------------------------------------------
+Test 8 : Delete-Delete, Insert conflict exposure
+------------------------------------------------
+-- Insert a row on Secondary Master
+insert into test.t1 values (3, "Espy");
+-- Check it's present on Primary Master
+select * from test.t1 order by a;
+a	b
+3	Espy
+-- Stop replication in both directions
+stop slave;
+stop slave;
+-- Delete row from both clusters
+delete from test.t1 where a=3;
+delete from test.t1 where a=3;
+-- Follow up with Insert from Secondary master
+insert into test.t1 values (3, "Dalriada");
+-- Restart replication in both directions
+start slave;
+start slave;
+-- Check data on both sites - diverged
+-- Secondary master :
+select * from test.t1 order by a;
+a	b
+-- Primary master :
+select * from test.t1 order by a;
+a	b
+3	Dalriada
+--Remove extra row
+delete from test.t1 where a=3;
+-- Note that Delete-Delete conflict detected below
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+6
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+------------------------------------------------
+Test 9 : Insert, Insert-Update-Delete conflict
+------------------------------------------------
+-- Stop replication on Secondary Master
+stop slave;
+-- Insert row on Primary Master
+insert into test.t1 values (4, "Haymarket");
+-- Insert row on Secondary Master
+insert into test.t1 values (4, "Outhouse");
+-- Update row on Secondary Master
+update test.t1 set b="Mathers" where a = 4;
+-- Delete row on Secondary Master
+delete from test.t1 where a=4;
+-- Examine data (none) on Secondary Master
+select * from test.t1 order by a;
+a	b
+-- Examine data on Primary Master, should be unaffected
+select * from test.t1 order by a;
+a	b
+4	Haymarket
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+9
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+1	3	#	7	#	#
+1	3	#	8	#	#
+1	3	#	9	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on Secondary Master (none)
+select * from test.t1 order by a;
+a	b
+-- Restart Secondary Master's slave
+start slave;
+-- Check data on Secondary Master, should be same as Primary Master
+select * from test.t1;
+a	b
+4	Haymarket
+------------------------------------------------
+Test 10 : Update, Delete-Insert-Update conflict
+------------------------------------------------
+-- Stop replication on Secondary Master
+stop slave;
+-- Update row on Primary Master
+update test.t1 set b="Blind poet" where a=4;
+-- Delete row on Secondary Master
+delete from test.t1 where a=4;
+-- Insert row on Secondary Master
+insert into test.t1 values (4, "Drouthy Neebors");
+-- Update row on Secondary Master
+update test.t1 set b="The Tankard" where a=4;
+-- Check data on Primary Master, should be unaffected
+select * from test.t1 order by a;
+a	b
+4	Blind poet
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+12
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+1	3	#	7	#	#
+1	3	#	8	#	#
+1	3	#	9	#	#
+1	3	#	10	#	#
+1	3	#	11	#	#
+1	3	#	12	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Check data on Secondary Master, as set
+select * from test.t1 order by a;
+a	b
+4	The Tankard
+-- Restart Secondary Master slave
+start slave;
+-- Check data on Secondary Master - should be as Primary
+select * from test.t1 order by a;
+a	b
+4	Blind poet
+------------------------------------------------------------------------
+Test 11 : Test Secondary insert-update-delete accepted
+------------------------------------------------------------------------
+Insert row on Secondary
+insert into test.t1 values (5, "Minders");
+Update row on Secondary
+update test.t1 set b="Southsider" where a=5;
+Delete row on Secondary
+delete from test.t1 where a=5;
+Check data on Primary, should be none.  No new conflicts
+select * from test.t1 order by a;
+a	b
+4	Blind poet
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+12
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+1	3	#	7	#	#
+1	3	#	8	#	#
+1	3	#	9	#	#
+1	3	#	10	#	#
+1	3	#	11	#	#
+1	3	#	12	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+12
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+1	3	#	7	#	#
+1	3	#	8	#	#
+1	3	#	9	#	#
+1	3	#	10	#	#
+1	3	#	11	#	#
+1	3	#	12	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+drop table test.t1;
+drop table test.t2;
+drop table test.t1$EX;
+Populate ndb_replication table as necessary
+-- Default extra Gci bits
+replace into mysql.ndb_replication values
+("test", "t1", 3, 7, NULL),
+("test", "t1", 1, 7, "NDB$EPOCH()");
+create table `test`.`t1$EX`
+  (server_id int unsigned,
+master_server_id int unsigned,
+master_epoch bigint unsigned,
+count int unsigned,
+a int not null,
+d int,
+primary key(server_id, master_server_id, master_epoch, count)) engine ndb;
+Create table
+create table test.t1(a int primary key, b varchar(255)) engine = ndb;
+Create other table
+create table test.t2(a int primary key, b int) engine = ndb;
+----------------------------------
+Test 1 : Basic two-way replication
+----------------------------------
+insert into test.t1 values (1, "Metropole");
+-- Give time for a new epoch on the Master
+-- Insert something to ensure the new epoch is noticed
+replace into test.t2 values (2, 1);
+-- Flushed to slave
+select * from test.t1 order by a;
+a	b
+1	Metropole
+-- Flushed back to Master
+select * from test.t1 order by a;
+a	b
+1	Metropole
+-- Now update data on slave
+update test.t1 set b="Favorit" where a=1;
+-- Now check data on master
+select * from test.t1 order by a;
+a	b
+1	Favorit
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Now perform multiple consecutive updates on the slave
+update test.t1 set b="Elephant house" where a=1;
+update test.t1 set b="Beach house" where a=1;
+select * from test.t1 order by a;
+a	b
+1	Beach house
+-- Now check they've applied on the master
+select * from test.t1 order by a;
+a	b
+1	Beach house
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+--------------------------------------------
+Test 2 : Normal Insert from Secondary Master
+--------------------------------------------
+-- Insert a new row on the Slave
+insert into test.t1 values (2, "Forrest");
+-- Check it exists on the Master
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Forrest
+-- Update from the slave
+update test.t1 set b="Reds" where a=2;
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Reds
+delete from test.t1 where a=2;
+select * from test.t1 order by a;
+a	b
+1	Beach house
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-------------------------------
+Test 3 : Insert-Insert conflict
+-------------------------------
+stop slave;
+-- Insert a row on the Primary Master
+insert into test.t1 values (2, "Loopy Lornas");
+-- Insert a row on the secondary Master
+insert into test.t1 values (2, "Cloisters");
+-- Examine data on Primary Master (should be unaffected)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Loopy Lornas
+-- Examine conflict indicators on Primary Master
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+1
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on isolated secondary Master (should be as-set)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Cloisters
+-- Restart secondary Masters slave
+start slave;
+-- Reexamine secondary Master's data (should be same as Primary Masters)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Loopy Lornas
+-------------------------------
+Test 4 : Update-Update conflict
+-------------------------------
+-- Stop replication to secondary master
+stop slave;
+-- Update row on Primary Master
+update test.t1 set b="Peters Yard" where a=2;
+-- Show data on Primary Master
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Peters Yard
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+1
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Update row on Secondary Master
+update test.t1 set b="Toast" where a=2;
+-- Examine data on Primary Master - should be unaffected
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Peters Yard
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+2
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Check data on secondary - should be as set
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Toast
+-- Now restart slave, will re-align row
+start slave;
+-- Check that Secondary is re-aligned
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Peters Yard
+-------------------------------
+Test 5 : Update-Delete conflict
+-------------------------------
+-- Stop Secondary slave
+stop slave;
+-- Update on Primary Master
+update test.t1 set b="Pear tree" where a = 2;
+-- Delete on Secondary Master
+delete from test.t1 where a = 2;
+-- Examine data on Primary Master, should be unaffected
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Pear tree
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+3
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on Secondary Master before slave restart, still missing
+select * from test.t1 order by a;
+a	b
+1	Beach house
+-- Restart Secondary Master slave
+start slave;
+-- Examine data on Secondary Master after slave restart, aligned with Master
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Pear tree
+-------------------------------
+Test 6 : Delete-Update conflict
+-------------------------------
+-- Stop Secondary slave
+stop slave;
+-- Delete on Primary Master
+delete from test.t1 where a=2;
+-- Update on Secondary Master
+update test.t1 set b="Black pig" where a=2;
+-- Examine data on Primary Master, should be unaffected (no row)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+4
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on Secondary Master before slave restart, should be as inserted
+select * from test.t1 order by a;
+a	b
+1	Beach house
+2	Black pig
+-- Restart Secondary Master slave
+start slave;
+-- Examine data on Secondary Master after slave restart, aligned with Master (deleted)
+select * from test.t1 order by a;
+a	b
+1	Beach house
+-------------------------------
+Test 7 : Delete-Delete conflict
+-------------------------------
+-- Stop Secondary slave
+stop slave;
+-- Delete on Primary Master
+delete from test.t1 where a=1;
+-- Delete on Secondary Master
+delete from test.t1 where a=1;
+-- Examine data on Primary Master, no row
+select * from test.t1 order by a;
+a	b
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+5
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on Secondary Master before slave restart, no row
+select * from test.t1 order by a;
+a	b
+-- Restart Secondary Master slave
+start slave;
+-- Examine data on Secondary Master after slave restart, no row
+select * from test.t1 order by a;
+a	b
+------------------------------------------------
+Test 8 : Delete-Delete, Insert conflict exposure
+------------------------------------------------
+-- Insert a row on Secondary Master
+insert into test.t1 values (3, "Espy");
+-- Check it's present on Primary Master
+select * from test.t1 order by a;
+a	b
+3	Espy
+-- Stop replication in both directions
+stop slave;
+stop slave;
+-- Delete row from both clusters
+delete from test.t1 where a=3;
+delete from test.t1 where a=3;
+-- Follow up with Insert from Secondary master
+insert into test.t1 values (3, "Dalriada");
+-- Restart replication in both directions
+start slave;
+start slave;
+-- Check data on both sites - diverged
+-- Secondary master :
+select * from test.t1 order by a;
+a	b
+-- Primary master :
+select * from test.t1 order by a;
+a	b
+3	Dalriada
+--Remove extra row
+delete from test.t1 where a=3;
+-- Note that Delete-Delete conflict detected below
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+6
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+------------------------------------------------
+Test 9 : Insert, Insert-Update-Delete conflict
+------------------------------------------------
+-- Stop replication on Secondary Master
+stop slave;
+-- Insert row on Primary Master
+insert into test.t1 values (4, "Haymarket");
+-- Insert row on Secondary Master
+insert into test.t1 values (4, "Outhouse");
+-- Update row on Secondary Master
+update test.t1 set b="Mathers" where a = 4;
+-- Delete row on Secondary Master
+delete from test.t1 where a=4;
+-- Examine data (none) on Secondary Master
+select * from test.t1 order by a;
+a	b
+-- Examine data on Primary Master, should be unaffected
+select * from test.t1 order by a;
+a	b
+4	Haymarket
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+9
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+1	3	#	7	#	#
+1	3	#	8	#	#
+1	3	#	9	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Examine data on Secondary Master (none)
+select * from test.t1 order by a;
+a	b
+-- Restart Secondary Master's slave
+start slave;
+-- Check data on Secondary Master, should be same as Primary Master
+select * from test.t1;
+a	b
+4	Haymarket
+------------------------------------------------
+Test 10 : Update, Delete-Insert-Update conflict
+------------------------------------------------
+-- Stop replication on Secondary Master
+stop slave;
+-- Update row on Primary Master
+update test.t1 set b="Blind poet" where a=4;
+-- Delete row on Secondary Master
+delete from test.t1 where a=4;
+-- Insert row on Secondary Master
+insert into test.t1 values (4, "Drouthy Neebors");
+-- Update row on Secondary Master
+update test.t1 set b="The Tankard" where a=4;
+-- Check data on Primary Master, should be unaffected
+select * from test.t1 order by a;
+a	b
+4	Blind poet
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+12
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+1	3	#	7	#	#
+1	3	#	8	#	#
+1	3	#	9	#	#
+1	3	#	10	#	#
+1	3	#	11	#	#
+1	3	#	12	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+-- Check data on Secondary Master, as set
+select * from test.t1 order by a;
+a	b
+4	The Tankard
+-- Restart Secondary Master slave
+start slave;
+-- Check data on Secondary Master - should be as Primary
+select * from test.t1 order by a;
+a	b
+4	Blind poet
+------------------------------------------------------------------------
+Test 11 : Test Secondary insert-update-delete accepted
+------------------------------------------------------------------------
+Insert row on Secondary
+insert into test.t1 values (5, "Minders");
+Update row on Secondary
+update test.t1 set b="Southsider" where a=5;
+Delete row on Secondary
+delete from test.t1 where a=5;
+Check data on Primary, should be none.  No new conflicts
+select * from test.t1 order by a;
+a	b
+4	Blind poet
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+12
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+1	3	#	7	#	#
+1	3	#	8	#	#
+1	3	#	9	#	#
+1	3	#	10	#	#
+1	3	#	11	#	#
+1	3	#	12	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+12
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	1	#	#
+1	3	#	2	#	#
+1	3	#	3	#	#
+1	3	#	4	#	#
+1	3	#	5	#	#
+1	3	#	6	#	#
+1	3	#	7	#	#
+1	3	#	8	#	#
+1	3	#	9	#	#
+1	3	#	10	#	#
+1	3	#	11	#	#
+1	3	#	12	#	#
+SELECT * FROM `t1$EX` ORDER BY a, d;
+server_id	master_server_id	master_epoch	count	a	d
+1	3	#	#	1	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	2	NULL
+1	3	#	#	3	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+1	3	#	#	4	NULL
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+drop table test.t1;
+drop table test.t2;
+drop table test.t1$EX;
+Now test batched conflict detection/handling
+create table test.t1 (
+a int primary key,
+b int,
+c varchar(2000)) engine=ndb;
+-- Stop replication from Primary -> Secondary
+stop slave;
+-- Insert a row on Primary
+insert into test.t1 values (1,1,repeat('B', 2000));
+-- Generate a large batch of inserts with early + late conflicts
+create procedure test.doit (rows int)
+begin
+set @x = 0;
+START TRANSACTION;
+repeat
+insert into test.t1 values (@x, @x, repeat('B', 2000));
+set @x = @x + 1;
+until @x = rows
+end repeat;
+COMMIT;
+START TRANSACTION;
+update test.t1 set b=999, c=repeat('E',2000) where a=1;
+COMMIT;
+START TRANSACTION;
+delete from test.t1 where a=1;
+COMMIT;
+START TRANSACTION;
+insert into test.t1 values (1,1,'A');
+COMMIT;
+end%
+call test.doit(100);
+drop procedure test.doit;
+-- Look at Primary status, expect 4 conflicts
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
+VARIABLE_VALUE-@init_ndb_conflict_fn_old
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
+0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+4
+SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t1$EX` ORDER BY a, d;
+SELECT * FROM `t2$EX` ORDER BY server_id, master_server_id, master_epoch, count;
+SELECT * FROM `t2$EX` ORDER BY a, d;
+start slave;
+-- Look at Seconday row
+select a,b,sha1(c) from test.t1 where a=1;
+a	b	sha1(c)
+1	1	6d41e1d402596dff36396d1f0f288d17a4b9800a
+-- Check it's the same on the Secondary
+select a,b,sha1(c) from test.t1 where a=1;
+a	b	sha1(c)
+1	1	6d41e1d402596dff36396d1f0f288d17a4b9800a
+Test batching of DELETE vs DELETE with following INSERT
+delete from test.t1;
+insert into test.t1 values (1, 1, "Ma Brows");
+-- Stop Slave in both directions
+stop slave;
+stop slave;
+-- Delete row on Primary Cluster
+delete from test.t1 where a=1;
+-- Delete row on Secondary Cluster, followed by Insert in later 'batch'
+create procedure test.doit (rows int)
+begin
+set @x = 2;
+START TRANSACTION;
+delete from test.t1 where a=1;
+repeat
+insert into test.t1 values (@x, @x, repeat('B', 2000));
+set @x = @x + 1;
+until @x = (rows + 2)
+end repeat;
+COMMIT;
+START TRANSACTION;
+insert into test.t1 values (1, 1, 'Malleny arms');
+COMMIT;
+end%
+call test.doit(200);
+-- Restart slave on Primary Cluster
+start slave;
+-- Show data on Primary Cluster (should have row inserted on Secondary)
+select * from test.t1 where a=1;
+a	b	c
+1	1	Malleny arms
+-- Show data on Secondary Cluster (should have row inserted on Secondary)
+select * from test.t1 where a=1;
+a	b	c
+1	1	Malleny arms
+--Restart slave on Secondary Cluster
+start slave;
+-- Show data on Secondary Cluster (should now be missing)
+Clusters are diverged as expected with delete vs delete conflict
+followed closely by Insert
+select * from test.t1 where a=1;
+a	b	c
+-- Force wait for master to be in-sync with slave
+To avoid race between DML and table drop
+flush logs;
+drop procedure test.doit;
+drop table test.t1;
+delete from mysql.ndb_replication;
+insert into mysql.ndb_replication values
+("test", "t3", 0, 7, "NDB\$EPOCH(32)"),
+("test", "t4", 0, 7, "NDB\$EPOCH(-1)");
+create table test.t3 (a int primary key) engine=ndb;
+ERROR HY000: Can't create table 'test.t3' (errno: 1627)
+show warnings;
+Level	Code	Message
+Error	1627	Error in parsing conflict function. Message: NDB$EPOCH(32), Too many extra Gci bits at ')'
+Error	1005	Can't create table 'test.t3' (errno: 1627)
+create table test.t4 (a int primary key) engine=ndb;
+ERROR HY000: Can't create table 'test.t4' (errno: 1627)
+show warnings;
+Level	Code	Message
+Error	1627	Error in parsing conflict function. Message: NDB$EPOCH(-1), Too many extra Gci bits at ')'
+Error	1005	Can't create table 'test.t4' (errno: 1627)
+-- Force sync before dropping table to avoid race
+flush logs;
+flush logs;
+drop table mysql.ndb_replication;
+-- Attempt to get system back in pre-test state
+stop slave;
+reset slave;
+change master to master_host='';
+include/rpl_end.inc

=== modified file 'mysql-test/suite/ndb_rpl/r/ndb_rpl_conflict_max.result'
--- a/mysql-test/suite/ndb_rpl/r/ndb_rpl_conflict_max.result	2011-06-16 14:34:56 +0000
+++ b/mysql-test/suite/ndb_rpl/r/ndb_rpl_conflict_max.result	2011-07-07 14:48:06 +0000
@@ -44,6 +44,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -73,6 +76,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -96,6 +102,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -126,6 +135,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -177,6 +189,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -222,6 +237,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -292,6 +310,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -321,6 +342,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -344,6 +368,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -374,6 +401,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -425,6 +455,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -470,6 +503,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -540,6 +576,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -575,6 +614,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -606,6 +648,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -644,6 +689,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -695,6 +743,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	5	#	#
@@ -740,6 +791,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	5	#	#
@@ -814,6 +868,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -843,6 +900,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -866,6 +926,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -896,6 +959,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -947,6 +1013,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -995,6 +1064,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#

=== modified file 'mysql-test/suite/ndb_rpl/r/ndb_rpl_conflict_max_delete_win.result'
--- a/mysql-test/suite/ndb_rpl/r/ndb_rpl_conflict_max_delete_win.result	2011-06-16 14:34:56 +0000
+++ b/mysql-test/suite/ndb_rpl/r/ndb_rpl_conflict_max_delete_win.result	2011-07-07 14:48:06 +0000
@@ -44,6 +44,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -73,6 +76,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -96,6 +102,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -126,6 +135,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -177,6 +189,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 3
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -222,6 +237,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 3
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -292,6 +310,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -321,6 +342,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -344,6 +368,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -374,6 +401,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -425,6 +455,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 3
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -470,6 +503,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 3
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -540,6 +576,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 3
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -575,6 +614,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 4
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -606,6 +648,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 4
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -644,6 +689,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -695,6 +743,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 3
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	5	#	#
@@ -740,6 +791,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 6
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	5	#	#
@@ -814,6 +868,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -843,6 +900,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -866,6 +926,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -896,6 +959,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -947,6 +1013,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 3
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -992,6 +1061,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 3
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#

=== modified file 'mysql-test/suite/ndb_rpl/r/ndb_rpl_conflict_old.result'
--- a/mysql-test/suite/ndb_rpl/r/ndb_rpl_conflict_old.result	2011-06-16 14:34:56 +0000
+++ b/mysql-test/suite/ndb_rpl/r/ndb_rpl_conflict_old.result	2011-07-07 14:48:06 +0000
@@ -44,6 +44,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -73,6 +76,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -96,6 +102,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -126,6 +135,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -177,6 +189,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -222,6 +237,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -296,6 +314,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -325,6 +346,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -348,6 +372,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -378,6 +405,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -429,6 +459,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -474,6 +507,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -548,6 +584,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -583,6 +622,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -614,6 +656,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -652,6 +697,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -703,6 +751,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	5	#	#
@@ -748,6 +799,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	5	#	#
@@ -822,6 +876,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -851,6 +908,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -874,6 +934,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -904,6 +967,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 SELECT * FROM `t1$EX` ORDER BY a, d;
@@ -955,6 +1021,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#
@@ -1003,6 +1072,9 @@ VARIABLE_VALUE-@init_ndb_conflict_fn_old
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
 VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win
 0
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
+VARIABLE_VALUE-@init_ndb_conflict_fn_epoch
+0
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;
 server_id	master_server_id	master_epoch	count	a	d
 2	1	#	1	#	#

=== modified file 'mysql-test/suite/ndb_rpl/t/disabled.def'
--- a/mysql-test/suite/ndb_rpl/t/disabled.def	2011-05-24 13:05:14 +0000
+++ b/mysql-test/suite/ndb_rpl/t/disabled.def	2011-07-08 15:05:28 +0000
@@ -12,11 +12,7 @@
 
 ndb_rpl_ctype_ucs2_def : bug #34661 rpl_ndb_ctype_ucs2_def fails in 6.2
 
-ndb_rpl_break_3_chain : SEAGULL ndb-force-binlog-format-statement
 ndb_rpl_slave_lsu : SEAGULL ndb-force-binlog-format-statement
 ndb_rpl_slave_lsu_anyval : SEAGULL ndb-force-binlog-format-statement
 ndb_rpl_row_implicit_commit_binlog : SEAGULL ndb-force-binlog-format-statement
-
-ndb_rpl_circular_2ch : SEAGULL update test to new rpl scripts
-ndb_rpl_dd_advance : SEAGULL hangs on test hosts
-
+ndb_rpl_conflict_epoch : needs new replication setup....

=== modified file 'mysql-test/suite/ndb_rpl/t/ndb_conflict_info.inc'
--- a/mysql-test/suite/ndb_rpl/t/ndb_conflict_info.inc	2011-06-16 14:34:56 +0000
+++ b/mysql-test/suite/ndb_rpl/t/ndb_conflict_info.inc	2011-07-07 14:48:06 +0000
@@ -1,6 +1,7 @@
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_old FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
 SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_max_del_win FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+SELECT VARIABLE_VALUE-@init_ndb_conflict_fn_epoch FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
 --replace_column 3 # 5 # 6 #
 --error 0,1146
 SELECT server_id, master_server_id, master_epoch, count, a, d FROM `t1$EX` ORDER BY server_id, master_server_id, master_epoch, count;

=== modified file 'mysql-test/suite/ndb_rpl/t/ndb_conflict_info_init.inc'
--- a/mysql-test/suite/ndb_rpl/t/ndb_conflict_info_init.inc	2011-06-16 14:34:56 +0000
+++ b/mysql-test/suite/ndb_rpl/t/ndb_conflict_info_init.inc	2011-07-07 14:48:06 +0000
@@ -3,6 +3,7 @@
 SELECT @init_ndb_conflict_fn_max:=(VARIABLE_VALUE+0) FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX";
 SELECT @init_ndb_conflict_fn_old:=(VARIABLE_VALUE+0) FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_OLD";
 SELECT @init_ndb_conflict_fn_max_del_win:=(VARIABLE_VALUE+0) FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_MAX_DEL_WIN";
+SELECT @init_ndb_conflict_fn_epoch:=(VARIABLE_VALUE+0) FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE "NDB_CONFLICT_FN_EPOCH";
 --error 0,1146
 DELETE FROM `t1$EX`;
 --enable_query_log

=== modified file 'mysql-test/suite/ndb_rpl/t/ndb_rpl_bank.test'
--- a/mysql-test/suite/ndb_rpl/t/ndb_rpl_bank.test	2011-05-13 07:40:50 +0000
+++ b/mysql-test/suite/ndb_rpl/t/ndb_rpl_bank.test	2011-07-06 09:20:17 +0000
@@ -117,7 +117,7 @@ RESET MASTER;
 --exec $NDB_MGM --no-defaults --ndb-connectstring="$NDB_CONNECTSTRING" -e "start backup" >> $NDB_TOOLS_OUTPUT
 
 # there is no neat way to find the backupid, this is a hack to find it...
---exec $NDB_TOOLS_DIR/ndb_select_all --ndb-connectstring="$NDB_CONNECTSTRING" -d sys --delimiter=',' SYSTAB_0 | grep 520093696 > $MYSQLTEST_VARDIR/tmp.dat
+--exec $NDB_SELECT_ALL --ndb-connectstring="$NDB_CONNECTSTRING" -d sys --delimiter=',' SYSTAB_0 | grep 520093696 > $MYSQLTEST_VARDIR/tmp.dat
 CREATE TABLE IF NOT EXISTS mysql.backup_info (id INT, backup_id INT) ENGINE = HEAP;
 DELETE FROM mysql.backup_info;
 LOAD DATA INFILE '../tmp.dat' INTO TABLE mysql.backup_info FIELDS TERMINATED BY ',';

=== modified file 'mysql-test/suite/ndb_rpl/t/ndb_rpl_break_3_chain.cnf'
--- a/mysql-test/suite/ndb_rpl/t/ndb_rpl_break_3_chain.cnf	2011-06-08 19:28:34 +0000
+++ b/mysql-test/suite/ndb_rpl/t/ndb_rpl_break_3_chain.cnf	2011-07-06 15:54:35 +0000
@@ -35,6 +35,7 @@ log-bin=                       cluster1-
 # for performance reasons
 ndb-table-temporary=1
 ndb-extra-logging=99
+binlog-format=row
 
 [mysqld.1.cluster1]
 

=== added file 'mysql-test/suite/ndb_rpl/t/ndb_rpl_conflict_epoch.cnf'
--- a/mysql-test/suite/ndb_rpl/t/ndb_rpl_conflict_epoch.cnf	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb_rpl/t/ndb_rpl_conflict_epoch.cnf	2011-07-07 14:48:06 +0000
@@ -0,0 +1,40 @@
+!include ../my.cnf
+
+# 2 clusters, each with 2 MySQLDs
+# All MySQLDs log-slave-updates
+# Potential infinite loops are broken by both servers
+# on each cluster having the same server-id
+
+[mysqld]
+log-slave-updates
+ndb-log-apply-status
+
+[mysqld.1.1]
+server-id= 1
+log-bin = pref-master-1
+
+[mysqld.2.1]
+server-id= 2
+log-bin = pref-master-2
+
+[mysqld.1.slave]
+server-id= 3
+log-bin = sec-master-1
+skip-slave-start
+
+[mysqld.2.slave]
+server-id= 4
+log-bin = sec-master-2
+master-host=		127.0.0.1
+master-port=		@mysqld.2.1.port
+master-password=	@mysqld.2.1.#password
+master-user=		@mysqld.2.1.#user
+master-connect-retry=	1
+init-rpl-role=		slave
+skip-slave-start
+ndb_connectstring=	@mysql_cluster.slave.ndb_connectstring
+
+[ENV]
+
+SLAVE_MYPORT1=		@mysqld.2.slave.port
+SLAVE_MYSOCK1=		@mysqld.2.slave.socket

=== added file 'mysql-test/suite/ndb_rpl/t/ndb_rpl_conflict_epoch.test'
--- a/mysql-test/suite/ndb_rpl/t/ndb_rpl_conflict_epoch.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb_rpl/t/ndb_rpl_conflict_epoch.test	2011-07-07 14:48:06 +0000
@@ -0,0 +1,261 @@
+#
+# Test engine native conflict resolution for ndb
+#   NDB$EPOCH() function
+#
+#
+--source include/have_ndb.inc
+--source include/have_binlog_format_mixed_or_row.inc
+--source suite/ndb_rpl/ndb_master-slave.inc
+
+--echo Setup circular replication
+
+--connection slave
+RESET MASTER;
+select @slave_server_id:=(variable_value+0)
+       from information_schema.global_variables
+       where variable_name like 'server_id';
+let $SLAVE_SERVER_ID= query_get_value('select @slave_server_id as v',v,1);
+
+--connection master
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+--eval CHANGE MASTER TO master_host="127.0.0.1",master_port=$SLAVE_MYPORT,master_user="root"
+START SLAVE;
+select @master_server_id:=(variable_value+0)
+       from information_schema.global_variables
+       where variable_name like 'server_id';
+let $MASTER_SERVER_ID= query_get_value('select @master_server_id as v',v,1);
+
+--echo Setup ndb_replication and t1$EX exceptions table
+
+--disable_warnings
+--disable_query_log
+--connection master
+drop table if exists mysql.ndb_replication;
+CREATE TABLE mysql.ndb_replication
+  (db VARBINARY(63),
+   table_name VARBINARY(63),
+   server_id INT UNSIGNED,
+   binlog_type INT UNSIGNED,
+   conflict_fn VARBINARY(128),
+   PRIMARY KEY USING HASH (db,table_name,server_id))
+  ENGINE=NDB PARTITION BY KEY(db,table_name);
+--enable_warnings
+--enable_query_log
+
+--echo Populate ndb_replication table as necessary
+--echo -- 0 extra gci bits
+eval replace into mysql.ndb_replication values
+  ("test", "t1", $SLAVE_SERVER_ID, 7, NULL),
+  ("test", "t1", $MASTER_SERVER_ID, 7, "NDB\$EPOCH(0)");
+
+--source suite/ndb_rpl/t/ndb_rpl_conflict_epoch_1.inc
+
+--echo Populate ndb_replication table as necessary
+--echo -- 1 extra gci bits
+eval replace into mysql.ndb_replication values
+  ("test", "t1", $SLAVE_SERVER_ID, 7, NULL),
+  ("test", "t1", $MASTER_SERVER_ID, 7, "NDB\$EPOCH(1)");
+
+--source suite/ndb_rpl/t/ndb_rpl_conflict_epoch_1.inc
+
+--echo Populate ndb_replication table as necessary
+--echo -- 31 extra gci bits
+eval replace into mysql.ndb_replication values
+  ("test", "t1", $SLAVE_SERVER_ID, 7, NULL),
+  ("test", "t1", $MASTER_SERVER_ID, 7, "NDB\$EPOCH(31)");
+
+--source suite/ndb_rpl/t/ndb_rpl_conflict_epoch_1.inc
+
+--echo Populate ndb_replication table as necessary
+--echo -- Default extra Gci bits
+eval replace into mysql.ndb_replication values
+  ("test", "t1", $SLAVE_SERVER_ID, 7, NULL),
+  ("test", "t1", $MASTER_SERVER_ID, 7, "NDB\$EPOCH()");
+
+--source suite/ndb_rpl/t/ndb_rpl_conflict_epoch_1.inc
+
+--source suite/ndb_rpl/t/ndb_conflict_info_init.inc
+
+--echo Now test batched conflict detection/handling
+--connection master
+
+create table test.t1 (
+  a int primary key,
+  b int,
+  c varchar(2000)) engine=ndb;
+
+--sync_slave_with_master slave
+--connection slave
+--echo -- Stop replication from Primary -> Secondary
+stop slave;
+--connection master
+--echo -- Insert a row on Primary
+insert into test.t1 values (1,1,repeat('B', 2000));
+
+--connection slave
+--echo -- Generate a large batch of inserts with early + late conflicts
+delimiter %;
+
+create procedure test.doit (rows int)
+begin
+  set @x = 0;
+  START TRANSACTION;
+    repeat
+      insert into test.t1 values (@x, @x, repeat('B', 2000));
+      set @x = @x + 1;
+    until @x = rows
+    end repeat;
+  COMMIT;
+  START TRANSACTION;
+    update test.t1 set b=999, c=repeat('E',2000) where a=1;
+  COMMIT;
+  START TRANSACTION;
+    delete from test.t1 where a=1;
+  COMMIT;
+  START TRANSACTION;
+    insert into test.t1 values (1,1,'A');
+  COMMIT;
+end%
+
+delimiter ;%
+
+call test.doit(100);
+
+drop procedure test.doit;
+
+--sync_slave_with_master master
+--connection master
+
+--echo -- Look at Primary status, expect 4 conflicts
+--source suite/ndb_rpl/t/ndb_conflict_info.inc
+
+--connection slave
+start slave;
+
+--connection master
+--echo -- Look at Seconday row
+select a,b,sha1(c) from test.t1 where a=1;
+
+--sync_slave_with_master slave
+--echo -- Check it's the same on the Secondary
+select a,b,sha1(c) from test.t1 where a=1;
+
+--connection master
+--echo Test batching of DELETE vs DELETE with following INSERT
+--connection master
+delete from test.t1;
+insert into test.t1 values (1, 1, "Ma Brows");
+--sync_slave_with_master slave
+--connection slave
+--sync_slave_with_master master
+--connection master
+--echo -- Stop Slave in both directions
+stop slave;
+--connection slave
+stop slave;
+--connection master
+--echo -- Delete row on Primary Cluster
+delete from test.t1 where a=1;
+
+--connection slave
+--echo -- Delete row on Secondary Cluster, followed by Insert in later 'batch'
+delimiter %;
+
+create procedure test.doit (rows int)
+begin
+  set @x = 2;
+  START TRANSACTION;
+    delete from test.t1 where a=1;
+    repeat
+      insert into test.t1 values (@x, @x, repeat('B', 2000));
+      set @x = @x + 1;
+    until @x = (rows + 2)
+    end repeat;
+  COMMIT;
+  START TRANSACTION;
+    insert into test.t1 values (1, 1, 'Malleny arms');
+  COMMIT;
+end%
+
+delimiter ;%
+
+call test.doit(200);
+
+--echo -- Restart slave on Primary Cluster
+--connection master
+# TODO : Reenable with new slave counts
+#--source suite/ndb_rpl/include/ndb_init_slave_counts.inc
+start slave;
+
+--connection slave
+--sync_slave_with_master master
+
+--connection master
+# TODO : Reenable with new slave counts
+#--disable_result_log
+# Don't include results as they vary depending on epoch boundaries
+#--source suite/ndb_rpl/include/ndb_slave_counts.inc
+#--enable_result_log
+#--echo -- Verify that batching occurred when replicating the above
+#select (@ndb_slave_execute_count - @ndb_slave_commit_count) > 1;
+--echo -- Show data on Primary Cluster (should have row inserted on Secondary)
+select * from test.t1 where a=1;
+
+--echo -- Show data on Secondary Cluster (should have row inserted on Secondary)
+--connection slave
+select * from test.t1 where a=1;
+
+--echo --Restart slave on Secondary Cluster
+start slave;
+--connection master
+--sync_slave_with_master slave
+--connection slave
+
+--echo -- Show data on Secondary Cluster (should now be missing)
+--echo    Clusters are diverged as expected with delete vs delete conflict
+--echo    followed closely by Insert
+--connection slave
+select * from test.t1 where a=1;
+
+--echo -- Force wait for master to be in-sync with slave
+--echo    To avoid race between DML and table drop
+flush logs;
+--sync_slave_with_master master
+
+--connection master
+drop procedure test.doit;
+drop table test.t1;
+
+delete from mysql.ndb_replication;
+insert into mysql.ndb_replication values
+  ("test", "t3", 0, 7, "NDB\$EPOCH(32)"),
+  ("test", "t4", 0, 7, "NDB\$EPOCH(-1)");
+
+--error 1005
+create table test.t3 (a int primary key) engine=ndb;
+show warnings;
+
+--error 1005
+create table test.t4 (a int primary key) engine=ndb;
+show warnings;
+
+--echo -- Force sync before dropping table to avoid race
+--connection master
+flush logs;
+--sync_slave_with_master slave
+--connection slave
+flush logs;
+--sync_slave_with_master master
+
+--connection master
+drop table mysql.ndb_replication;
+
+--sync_slave_with_master slave
+
+--echo -- Attempt to get system back in pre-test state
+--connection master
+stop slave;
+reset slave;
+change master to master_host='';
+
+--source include/rpl_end.inc

=== added file 'mysql-test/suite/ndb_rpl/t/ndb_rpl_conflict_epoch_1.inc'
--- a/mysql-test/suite/ndb_rpl/t/ndb_rpl_conflict_epoch_1.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb_rpl/t/ndb_rpl_conflict_epoch_1.inc	2011-07-07 14:48:06 +0000
@@ -0,0 +1,490 @@
+#
+# Include file for testing ndb$epoch conflict function
+#
+#
+
+create table `test`.`t1$EX`
+  (server_id int unsigned,
+   master_server_id int unsigned,
+   master_epoch bigint unsigned,
+   count int unsigned,
+   a int not null,
+   d int,
+   primary key(server_id, master_server_id, master_epoch, count)) engine ndb;
+
+
+--echo Create table
+create table test.t1(a int primary key, b varchar(255)) engine = ndb;
+
+--echo Create other table
+create table test.t2(a int primary key, b int) engine = ndb;
+
+--source suite/ndb_rpl/t/ndb_conflict_info_init.inc
+
+--echo ----------------------------------
+--echo Test 1 : Basic two-way replication
+--echo ----------------------------------
+
+insert into test.t1 values (1, "Metropole");
+
+--echo -- Give time for a new epoch on the Master
+# This is 3 seconds to be > GCP_Save time, so that the next epoch
+# will be visibly greater than the one inserted above
+# (e.g. if we have 4 bits of extra GCI resolution, the max
+#  representable GCI is XXX/15.  If we insert at XXX/16, we
+#  need to wait until we get to XXX+1/0 at least, to avoid
+#  the Primary Master undoing the update)
+#
+--sleep 3
+
+--echo -- Insert something to ensure the new epoch is noticed
+#
+# Required in case our initial insert's epoch gets rounded up to
+# 0xffffffff, in which case 'later' updates from the slave will
+# be in conflict until some newer gci_hi is the MaxReplicatedEpoch
+#
+replace into test.t2 values (2, 1);
+--sync_slave_with_master slave
+--connection slave
+--echo -- Flushed to slave
+select * from test.t1 order by a;
+--sync_slave_with_master master
+--connection master
+--echo -- Flushed back to Master
+select * from test.t1 order by a;
+--connection slave
+
+--echo -- Now update data on slave
+update test.t1 set b="Favorit" where a=1;
+
+--sync_slave_with_master master
+
+--connection master
+--echo -- Now check data on master
+select * from test.t1 order by a;
+
+--source suite/ndb_rpl/t/ndb_conflict_info.inc
+
+--connection slave
+--echo -- Now perform multiple consecutive updates on the slave
+
+update test.t1 set b="Elephant house" where a=1;
+update test.t1 set b="Beach house" where a=1;
+
+select * from test.t1 order by a;
+
+--sync_slave_with_master master
+--connection master
+--echo -- Now check they've applied on the master
+select * from test.t1 order by a;
+
+--source suite/ndb_rpl/t/ndb_conflict_info.inc
+
+--echo --------------------------------------------
+--echo Test 2 : Normal Insert from Secondary Master
+--echo --------------------------------------------
+
+--connection slave
+--echo -- Insert a new row on the Slave
+insert into test.t1 values (2, "Forrest");
+
+--sync_slave_with_master master
+--connection master
+--echo -- Check it exists on the Master
+select * from test.t1 order by a;
+
+--connection slave
+--echo -- Update from the slave
+update test.t1 set b="Reds" where a=2;
+
+--sync_slave_with_master master
+--connection master
+select * from test.t1 order by a;
+
+--connection slave
+delete from test.t1 where a=2;
+
+--sync_slave_with_master master
+--connection master
+select * from test.t1 order by a;
+
+--source suite/ndb_rpl/t/ndb_conflict_info.inc
+
+--echo -------------------------------
+--echo Test 3 : Insert-Insert conflict
+--echo -------------------------------
+
+--connection slave
+stop slave;
+--connection master
+
+--echo -- Insert a row on the Primary Master
+insert into test.t1 values (2, "Loopy Lornas");
+
+--connection slave
+--echo -- Insert a row on the secondary Master
+insert into test.t1 values (2, "Cloisters");
+
+--sync_slave_with_master master
+--connection master
+--echo -- Examine data on Primary Master (should be unaffected)
+select * from test.t1 order by a;
+
+--echo -- Examine conflict indicators on Primary Master
+--source suite/ndb_rpl/t/ndb_conflict_info.inc
+
+--echo -- Examine data on isolated secondary Master (should be as-set)
+--connection slave
+select * from test.t1 order by a;
+
+--echo -- Restart secondary Masters slave
+start slave;
+
+--connection master
+--sync_slave_with_master slave
+--connection slave
+
+--echo -- Reexamine secondary Master's data (should be same as Primary Masters)
+select * from test.t1 order by a;
+
+--echo -------------------------------
+--echo Test 4 : Update-Update conflict
+--echo -------------------------------
+
+--connection slave
+--echo -- Stop replication to secondary master
+stop slave;
+
+--connection master
+--echo -- Update row on Primary Master
+
+update test.t1 set b="Peters Yard" where a=2;
+
+--echo -- Show data on Primary Master
+
+select * from test.t1 order by a;
+--source suite/ndb_rpl/t/ndb_conflict_info.inc
+
+--connection slave
+
+--echo -- Update row on Secondary Master
+update test.t1 set b="Toast" where a=2;
+
+--sync_slave_with_master master
+
+--echo -- Examine data on Primary Master - should be unaffected
+
+select * from test.t1 order by a;
+--source suite/ndb_rpl/t/ndb_conflict_info.inc
+
+--connection slave
+--echo -- Check data on secondary - should be as set
+
+select * from test.t1 order by a;
+
+--echo -- Now restart slave, will re-align row
+start slave;
+
+--connection master
+--sync_slave_with_master slave
+
+--connection slave
+--echo -- Check that Secondary is re-aligned
+
+select * from test.t1 order by a;
+
+
+--echo -------------------------------
+--echo Test 5 : Update-Delete conflict
+--echo -------------------------------
+
+--connection slave
+--echo -- Stop Secondary slave
+stop slave;
+
+--connection master
+--echo -- Update on Primary Master
+
+update test.t1 set b="Pear tree" where a = 2;
+
+--connection slave
+--echo -- Delete on Secondary Master
+
+delete from test.t1 where a = 2;
+
+--sync_slave_with_master master
+
+--echo -- Examine data on Primary Master, should be unaffected
+
+select * from test.t1 order by a;
+--source suite/ndb_rpl/t/ndb_conflict_info.inc
+
+--echo -- Examine data on Secondary Master before slave restart, still missing
+--connection slave
+select * from test.t1 order by a;
+
+--echo -- Restart Secondary Master slave
+start slave;
+
+--connection master
+--sync_slave_with_master slave
+--connection slave
+
+--echo -- Examine data on Secondary Master after slave restart, aligned with Master
+select * from test.t1 order by a;
+
+--echo -------------------------------
+--echo Test 6 : Delete-Update conflict
+--echo -------------------------------
+
+--connection slave
+--echo -- Stop Secondary slave
+stop slave;
+
+--connection master
+--echo -- Delete on Primary Master
+
+delete from test.t1 where a=2;
+
+--connection slave
+--echo -- Update on Secondary Master
+
+update test.t1 set b="Black pig" where a=2;
+
+--sync_slave_with_master master
+
+--echo -- Examine data on Primary Master, should be unaffected (no row)
+
+select * from test.t1 order by a;
+--source suite/ndb_rpl/t/ndb_conflict_info.inc
+
+--echo -- Examine data on Secondary Master before slave restart, should be as inserted
+--connection slave
+select * from test.t1 order by a;
+
+--echo -- Restart Secondary Master slave
+start slave;
+
+--connection master
+--sync_slave_with_master slave
+--connection slave
+
+--echo -- Examine data on Secondary Master after slave restart, aligned with Master (deleted)
+select * from test.t1 order by a;
+
+--echo -------------------------------
+--echo Test 7 : Delete-Delete conflict
+--echo -------------------------------
+
+--connection slave
+--echo -- Stop Secondary slave
+stop slave;
+
+--connection master
+--echo -- Delete on Primary Master
+
+delete from test.t1 where a=1;
+
+--connection slave
+--echo -- Delete on Secondary Master
+
+delete from test.t1 where a=1;
+
+--sync_slave_with_master master
+
+--echo -- Examine data on Primary Master, no row
+
+select * from test.t1 order by a;
+--source suite/ndb_rpl/t/ndb_conflict_info.inc
+
+--echo -- Examine data on Secondary Master before slave restart, no row
+--connection slave
+select * from test.t1 order by a;
+
+--echo -- Restart Secondary Master slave
+start slave;
+
+--connection master
+--sync_slave_with_master slave
+--connection slave
+
+--echo -- Examine data on Secondary Master after slave restart, no row
+select * from test.t1 order by a;
+
+
+--echo ------------------------------------------------
+--echo Test 8 : Delete-Delete, Insert conflict exposure
+--echo ------------------------------------------------
+# This occurs as the Primary Master's Delete is still
+# in-flight when the Secondary Master's Insert arrives,
+# but as there is no knowledge of this at the Primary
+# Master, it accepts the Insert.
+#
+
+--connection slave
+--echo -- Insert a row on Secondary Master
+insert into test.t1 values (3, "Espy");
+--sync_slave_with_master master
+
+--connection master
+--echo -- Check it's present on Primary Master
+select * from test.t1 order by a;
+
+--echo -- Stop replication in both directions
+stop slave;
+
+--connection slave
+stop slave;
+
+--echo -- Delete row from both clusters
+delete from test.t1 where a=3;
+
+--connection master
+delete from test.t1 where a=3;
+
+--echo -- Follow up with Insert from Secondary master
+--connection slave
+
+insert into test.t1 values (3, "Dalriada");
+
+--echo -- Restart replication in both directions
+start slave;
+
+--connection master
+start slave;
+
+--sync_slave_with_master slave
+--connection slave
+--sync_slave_with_master master
+
+--connection slave
+--echo -- Check data on both sites - diverged
+--echo -- Secondary master :
+select * from test.t1 order by a;
+--echo -- Primary master :
+--connection master
+select * from test.t1 order by a;
+
+--echo --Remove extra row
+delete from test.t1 where a=3;
+
+--echo -- Note that Delete-Delete conflict detected below
+--source suite/ndb_rpl/t/ndb_conflict_info.inc
+
+--echo ------------------------------------------------
+--echo Test 9 : Insert, Insert-Update-Delete conflict
+--echo ------------------------------------------------
+
+--connection slave
+--echo -- Stop replication on Secondary Master
+stop slave;
+
+--connection master
+--echo -- Insert row on Primary Master
+insert into test.t1 values (4, "Haymarket");
+
+--connection slave
+--echo -- Insert row on Secondary Master
+insert into test.t1 values (4, "Outhouse");
+--echo -- Update row on Secondary Master
+update test.t1 set b="Mathers" where a = 4;
+--echo -- Delete row on Secondary Master
+delete from test.t1 where a=4;
+
+--echo -- Examine data (none) on Secondary Master
+select * from test.t1 order by a;
+
+--sync_slave_with_master master
+--connection master
+--echo -- Examine data on Primary Master, should be unaffected
+
+select * from test.t1 order by a;
+--source suite/ndb_rpl/t/ndb_conflict_info.inc
+
+--connection slave
+--echo -- Examine data on Secondary Master (none)
+select * from test.t1 order by a;
+
+--echo -- Restart Secondary Master's slave
+start slave;
+
+--connection master
+--sync_slave_with_master slave
+--connection slave
+--echo -- Check data on Secondary Master, should be same as Primary Master
+select * from test.t1;
+
+--echo ------------------------------------------------
+--echo Test 10 : Update, Delete-Insert-Update conflict
+--echo ------------------------------------------------
+--connection slave
+--echo -- Stop replication on Secondary Master
+stop slave;
+
+--connection master
+--echo -- Update row on Primary Master
+update test.t1 set b="Blind poet" where a=4;
+
+--connection slave
+--echo -- Delete row on Secondary Master
+delete from test.t1 where a=4;
+
+--echo -- Insert row on Secondary Master
+insert into test.t1 values (4, "Drouthy Neebors");
+
+--echo -- Update row on Secondary Master
+update test.t1 set b="The Tankard" where a=4;
+
+--sync_slave_with_master master
+
+--connection master
+
+--echo -- Check data on Primary Master, should be unaffected
+select * from test.t1 order by a;
+--source suite/ndb_rpl/t/ndb_conflict_info.inc
+
+--connection slave
+--echo -- Check data on Secondary Master, as set
+
+select * from test.t1 order by a;
+
+--echo -- Restart Secondary Master slave
+start slave;
+
+--connection master
+--sync_slave_with_master slave
+--connection slave
+
+--echo -- Check data on Secondary Master - should be as Primary
+select * from test.t1 order by a;
+
+--sync_slave_with_master master
+
+--echo ------------------------------------------------------------------------
+--echo Test 11 : Test Secondary insert-update-delete accepted
+--echo ------------------------------------------------------------------------
+--connection slave
+--echo Insert row on Secondary
+insert into test.t1 values (5, "Minders");
+--echo Update row on Secondary
+update test.t1 set b="Southsider" where a=5;
+--echo Delete row on Secondary
+delete from test.t1 where a=5;
+
+--sync_slave_with_master master
+
+--connection master
+--echo Check data on Primary, should be none.  No new conflicts
+select * from test.t1 order by a;
+--source suite/ndb_rpl/t/ndb_conflict_info.inc
+
+--connection master
+--source suite/ndb_rpl/t/ndb_conflict_info.inc
+
+drop table test.t1;
+drop table test.t2;
+drop table test.t1$EX;
+
+--sync_slave_with_master slave
+
+--connection master
\ No newline at end of file

=== modified file 'mysql-test/suite/ndb_team/t/ndb_autodiscover.test'
--- a/mysql-test/suite/ndb_team/t/ndb_autodiscover.test	2009-05-09 07:32:26 +0000
+++ b/mysql-test/suite/ndb_team/t/ndb_autodiscover.test	2011-07-06 09:20:17 +0000
@@ -550,6 +550,6 @@ create table t10 (
 
 insert into t10 values (1, 'kalle');
 
---exec $NDB_DROP_TABLE --no-defaults -d test `$NDB_TOOLS_DIR/ndb_show_tables --no-defaults | grep BLOB | while read a b c d e f g; do echo $g; done` >> $NDB_TOOLS_OUTPUT 2>&1 || true
+--exec $NDB_DROP_TABLE --no-defaults -d test `$NDB_SHOW_TABLES --no-defaults | grep BLOB | while read a b c d e f g; do echo $g; done` >> $NDB_TOOLS_OUTPUT 2>&1 || true
 
 # End of 4.1 tests

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2011-07-05 12:46:07 +0000
+++ b/sql/ha_ndbcluster.cc	2011-07-14 03:23:12 +0000
@@ -808,9 +808,18 @@ static int update_status_variables(Thd_n
    SHOW_LONGLONG},                                                      \
   {"api_trans_local_read_row_count" NAME_SUFFIX,                        \
    (char*) ARRAY_LOCATION[ Ndb::TransLocalReadRowCount ],               \
+   SHOW_LONGLONG},                                                      \
+  {"api_adaptive_send_forced_count" NAME_SUFFIX,                        \
+   (char *) ARRAY_LOCATION[ Ndb::ForcedSendsCount ],                    \
+   SHOW_LONGLONG},                                                      \
+  {"api_adaptive_send_unforced_count" NAME_SUFFIX,                      \
+   (char *) ARRAY_LOCATION[ Ndb::UnforcedSendsCount ],                  \
+   SHOW_LONGLONG},                                                      \
+  {"api_adaptive_send_deferred_count" NAME_SUFFIX,                      \
+   (char *) ARRAY_LOCATION[ Ndb::DeferredSendsCount ],                  \
    SHOW_LONGLONG}
-
-SHOW_VAR ndb_status_variables_dynamic[]= {
+   
+ SHOW_VAR ndb_status_variables_dynamic[]= {
   {"cluster_node_id",     (char*) &g_ndb_status.cluster_node_id,      SHOW_LONG},
   {"config_from_host",    (char*) &g_ndb_status.connected_host,       SHOW_CHAR_PTR},
   {"config_from_port",    (char*) &g_ndb_status.connected_port,       SHOW_LONG},
@@ -839,6 +848,7 @@ SHOW_VAR ndb_status_conflict_variables[]
   {"fn_max",       (char*) &g_ndb_slave_state.total_violation_count[CFT_NDB_MAX], SHOW_LONGLONG},
   {"fn_old",       (char*) &g_ndb_slave_state.total_violation_count[CFT_NDB_OLD], SHOW_LONGLONG},
   {"fn_max_del_win", (char*) &g_ndb_slave_state.total_violation_count[CFT_NDB_MAX_DEL_WIN], SHOW_LONGLONG},
+  {"fn_epoch",     (char*) &g_ndb_slave_state.total_violation_count[CFT_NDB_EPOCH], SHOW_LONGLONG},
   {NullS, NullS, SHOW_LONG}
 };
 
@@ -1017,6 +1027,7 @@ handle_conflict_op_error(Thd_ndb* thd_nd
 
 int
 handle_row_conflict(NDB_CONFLICT_FN_SHARE* cfn_share,
+                    const char* tab_name,
                     const NdbRecord* key_rec,
                     const uchar* pk_row,
                     enum_conflicting_op_type op_type,
@@ -1026,6 +1037,8 @@ handle_row_conflict(NDB_CONFLICT_FN_SHAR
                     NdbError& err);
 #endif
 
+static const Uint32 error_op_after_refresh_op = 920;
+
 inline int
 check_completed_operations_pre_commit(Thd_ndb *thd_ndb, NdbTransaction *trans,
                                       const NdbOperation *first,
@@ -1099,6 +1112,8 @@ check_completed_operations_pre_commit(Th
   */
   if (trans->getLastDefinedOperation() != lastUserOp)
   {
+    const NdbOperation* last_conflict_op = trans->getLastDefinedOperation();
+
     if (trans->execute(NdbTransaction::NoCommit,
                        NdbOperation::AO_IgnoreError,
                        thd_ndb->m_force_send))
@@ -1106,9 +1121,41 @@ check_completed_operations_pre_commit(Th
       abort();
       //err= trans->getNdbError();
     }
+
     if (trans->getNdbError().code)
     {
-      sql_print_error("NDB slave: write conflict row error code %d", trans->getNdbError().code);
+      /* Check the result codes of the operations we added */
+      const NdbOperation* conflict_op = NULL;
+      do
+      {
+        conflict_op = trans->getNextCompletedOperation(conflict_op);
+        assert(conflict_op != NULL);
+        /* We will ignore 920 which represents a refreshOp or other op
+         * arriving after a refreshOp
+         */
+        const NdbError& err = conflict_op->getNdbError();
+        if ((err.code != 0) &&
+            (err.code != (int) error_op_after_refresh_op))
+        {
+          if (err.status == NdbError::TemporaryError)
+          {
+            /* Slave will roll back and retry entire transaction. */
+            ERR_RETURN(err);
+          }
+          else
+          {
+            char msg[FN_REFLEN];
+            my_snprintf(msg, sizeof(msg), "Executing extra operations for "
+                        "conflict handling hit Ndb error %d '%s'",
+                        err.code, err.message);
+            push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+                                ER_EXCEPTIONS_WRITE_ERROR,
+                                ER(ER_EXCEPTIONS_WRITE_ERROR), msg);
+            /* Slave will stop replication. */
+            DBUG_RETURN(ER_EXCEPTIONS_WRITE_ERROR);
+          }
+        }
+      } while (conflict_op != last_conflict_op);
     }
   }
 #endif
@@ -1141,7 +1188,9 @@ check_completed_operations(Thd_ndb *thd_
         err.classification != NdbError::NoDataFound)
     {
 #ifdef HAVE_NDB_BINLOG
-      DBUG_ASSERT(err.code != 9999 && err.code != 9998);
+      /* All conflict detection etc should be done before commit */
+      DBUG_ASSERT((err.code != (int) error_conflict_fn_violation) &&
+                  (err.code != (int) error_op_after_refresh_op));
 #endif
       DBUG_RETURN(err.code);
     }
@@ -2230,7 +2279,8 @@ int ha_ndbcluster::get_metadata(THD *thd
     my_free(pack_data, MYF(MY_ALLOW_ZERO_PTR));
     DBUG_RETURN(1);
   }
-    
+
+  ndb->setDatabaseName(m_dbname);
   Ndb_table_guard ndbtab_g(dict, m_tabname);
   if (!(tab= ndbtab_g.get_table()))
     ERR_RETURN(dict->getNdbError());
@@ -4634,6 +4684,7 @@ handle_conflict_op_error(Thd_ndb* thd_nd
   DBUG_PRINT("info", ("ndb error: %d", err.code));
 
   if ((err.code == (int) error_conflict_fn_violation) ||
+      (err.code == (int) error_op_after_refresh_op) ||
       (err.classification == NdbError::ConstraintViolation) ||
       (err.classification == NdbError::NoDataFound))
   {
@@ -4649,7 +4700,8 @@ handle_conflict_op_error(Thd_ndb* thd_nd
 
     enum_conflict_cause conflict_cause;
 
-    if (err.code == (int) error_conflict_fn_violation)
+    if ((err.code == (int) error_conflict_fn_violation) ||
+        (err.code == (int) error_op_after_refresh_op))
     {
       conflict_cause= ROW_IN_CONFLICT;
     }
@@ -4684,6 +4736,7 @@ handle_conflict_op_error(Thd_ndb* thd_nd
       {
         NdbError handle_error;
         if (handle_row_conflict(cfn_share,
+                                share->table_name,
                                 key_rec,
                                 row,
                                 op_type,
@@ -4821,7 +4874,7 @@ int ha_ndbcluster::ndb_write_row(uchar *
   NdbTransaction *trans;
   uint32 part_id;
   int error;
-  NdbOperation::SetValueSpec sets[2];
+  NdbOperation::SetValueSpec sets[3];
   Uint32 num_sets= 0;
   DBUG_ENTER("ha_ndbcluster::ndb_write_row");
 
@@ -4950,6 +5003,16 @@ int ha_ndbcluster::ndb_write_row(uchar *
   eventSetAnyValue(thd, &options); 
   bool need_flush= add_row_check_if_batch_full(thd_ndb);
 
+  const Uint32 authorValue = 1;
+  if ((thd->slave_thread) &&
+      (m_table->getExtraRowAuthorBits()))
+  {
+    /* Set author to indicate slave updated last */
+    sets[num_sets].column= NdbDictionary::Column::ROW_AUTHOR;
+    sets[num_sets].value= &authorValue;
+    num_sets++;
+  }
+
   if (m_user_defined_partitioning)
   {
     options.optionsPresent |= NdbOperation::OperationOptions::OO_PARTITION_ID;
@@ -5182,9 +5245,9 @@ int ha_ndbcluster::primary_key_cmp(const
 }
 
 #ifdef HAVE_NDB_BINLOG
-
 int
 handle_row_conflict(NDB_CONFLICT_FN_SHARE* cfn_share,
+                    const char* table_name,
                     const NdbRecord* key_rec,
                     const uchar* pk_row,
                     enum_conflicting_op_type op_type,
@@ -5195,6 +5258,90 @@ handle_row_conflict(NDB_CONFLICT_FN_SHAR
 {
   DBUG_ENTER("handle_row_conflict");
 
+  if (cfn_share->m_flags & CFF_REFRESH_ROWS)
+  {
+    /* A conflict has been detected between an applied replicated operation
+     * and the data in the DB.
+     * The attempt to change the local DB will have been rejected.
+     * We now take steps to generate a refresh Binlog event so that
+     * other clusters will be re-aligned.
+     */
+    DBUG_PRINT("info", ("Conflict on table %s.  Operation type : %s, "
+                        "conflict cause :%s, conflict error : %u : %s",
+                        table_name,
+                        ((op_type == WRITE_ROW)? "WRITE_ROW":
+                         (op_type == UPDATE_ROW)? "UPDATE_ROW":
+                         "DELETE_ROW"),
+                        ((conflict_cause == ROW_ALREADY_EXISTS)?"ROW_ALREADY_EXISTS":
+                         (conflict_cause == ROW_DOES_NOT_EXIST)?"ROW_DOES_NOT_EXIST":
+                         "ROW_IN_CONFLICT"),
+                        conflict_error.code,
+                        conflict_error.message));
+
+    assert(key_rec != NULL);
+    assert(pk_row != NULL);
+
+    /* When the slave splits an epoch into batches, a conflict row detected
+     * and refreshed in an early batch can be written to by operations in
+     * a later batch.  As the operations will not have applied, and the
+     * row has already been refreshed, we need not attempt to refresh
+     * it again
+     */
+    if ((conflict_cause == ROW_IN_CONFLICT) &&
+        (conflict_error.code == (int) error_op_after_refresh_op))
+    {
+      /* Attempt to apply an operation after the row was refreshed
+       * Ignore the error
+       */
+      DBUG_PRINT("info", ("Operation after refresh error - ignoring"));
+      DBUG_RETURN(0);
+    }
+
+    /* When a delete operation finds that the row does not exist, it indicates
+     * a DELETE vs DELETE conflict.  If we refresh the row then we can get
+     * non deterministic behaviour depending on slave batching as follows :
+     *   Row is deleted
+     *
+     *     Case 1
+     *       Slave applied DELETE, INSERT in 1 batch
+     *
+     *         After first batch, the row is present (due to INSERT), it is
+     *         refreshed.
+     *
+     *     Case 2
+     *       Slave applied DELETE in 1 batch, INSERT in 2nd batch
+     *
+     *         After first batch, the row is not present, it is refreshed
+     *         INSERT is then rejected.
+     *
+     * The problem of not being able to 'record' a DELETE vs DELETE conflict
+     * is known.  We attempt at least to give consistent behaviour for
+     * DELETE vs DELETE conflicts by :
+     *   NOT refreshing a row when a DELETE vs DELETE conflict is detected
+     * This should map all batching scenarios onto Case1.
+     */
+    if ((op_type == DELETE_ROW) &&
+        (conflict_cause == ROW_DOES_NOT_EXIST))
+    {
+      DBUG_PRINT("info", ("Delete vs Delete detected, NOT refreshing"));
+      DBUG_RETURN(0);
+    }
+
+    /* Create a refresh to operation to realign other clusters */
+    // TODO AnyValue
+    // TODO Do we ever get non-PK key?
+    //      Keyless table?
+    //      Unique index
+    const NdbOperation* refresh_op= conflict_trans->refreshTuple(key_rec,
+                                                                 (const char*) pk_row);
+
+    if (!refresh_op)
+    {
+      err= conflict_trans->getNdbError();
+      DBUG_RETURN(1);
+    }
+  } /* if (cfn_share->m_flags & CFF_REFRESH_ROWS) */
+
   DBUG_RETURN(0);
 };
 #endif /* HAVE_NDB_BINLOG */
@@ -5369,7 +5516,8 @@ int ha_ndbcluster::ndb_update_row(const 
                    primary_key_cmp(old_data, new_data));
   bool batch_allowed= !m_update_cannot_batch && 
     (is_bulk_update || thd_allow_batch(thd));
-  NdbOperation::SetValueSpec sets[1];
+  NdbOperation::SetValueSpec sets[2];
+  Uint32 num_sets= 0;
 
   DBUG_ENTER("ndb_update_row");
   DBUG_ASSERT(trans);
@@ -5476,11 +5624,9 @@ int ha_ndbcluster::ndb_update_row(const 
       func_value_uint32= INT_MAX32;
     else
       func_value_uint32= (uint32)func_value;
-    sets[0].column= get_partition_id_column();
-    sets[0].value= &func_value_uint32;
-    options.optionsPresent|= NdbOperation::OperationOptions::OO_SETVALUE;
-    options.extraSetValues= sets;
-    options.numExtraSetValues= 1;
+    sets[num_sets].column= get_partition_id_column();
+    sets[num_sets].value= &func_value_uint32;
+    num_sets++;
 
     if (!cursor)
     {
@@ -5493,6 +5639,23 @@ int ha_ndbcluster::ndb_update_row(const 
   
   bool need_flush= add_row_check_if_batch_full(thd_ndb);
 
+ const Uint32 authorValue = 1;
+ if ((thd->slave_thread) &&
+     (m_table->getExtraRowAuthorBits()))
+ {
+   /* Set author to indicate slave updated last */
+   sets[num_sets].column= NdbDictionary::Column::ROW_AUTHOR;
+   sets[num_sets].value= &authorValue;
+   num_sets++;
+ }
+
+ if (num_sets)
+ {
+   options.optionsPresent|= NdbOperation::OperationOptions::OO_SETVALUE;
+   options.extraSetValues= sets;
+   options.numExtraSetValues= num_sets;
+ }
+
   if (thd->slave_thread || THDVAR(thd, deferred_constraints))
   {
     options.optionsPresent |=
@@ -9048,6 +9211,35 @@ int ha_ndbcluster::create(const char *na
   ndb->setDatabaseName(m_dbname);
 
   /* Use ndb_replication information as required */
+  if (conflict_fn != NULL)
+  {
+    switch(conflict_fn->type)
+    {
+    case CFT_NDB_EPOCH:
+    {
+      /* Default 6 extra Gci bits allows 2^6 == 64
+       * epochs / saveGCP, a comfortable default
+       */
+      Uint32 numExtraGciBits = 6;
+      Uint32 numExtraAuthorBits = 1;
+
+      if ((num_args == 1) &&
+          (args[0].type == CFAT_EXTRA_GCI_BITS))
+      {
+        numExtraGciBits = args[0].extraGciBits;
+      }
+      DBUG_PRINT("info", ("Setting ExtraRowGciBits to %u, "
+                          "ExtraAuthorBits to %u",
+                          numExtraGciBits,
+                          numExtraAuthorBits));
+
+      tab.setExtraRowGciBits(numExtraGciBits);
+      tab.setExtraRowAuthorBits(numExtraAuthorBits);
+    }
+    default:
+      break;
+    }
+  }
 #endif
 
   if ((dict->beginSchemaTrans() == -1))
@@ -9981,13 +10173,50 @@ int ha_ndbcluster::rename_table(const ch
   Delete table from NDB Cluster.
 */
 
+static
+void
+delete_table_drop_share(NDB_SHARE* share, const char * path)
+{
+  if (share)
+  {
+    pthread_mutex_lock(&ndbcluster_mutex);
+do_drop:
+    if (share->state != NSS_DROPPED)
+    {
+      /*
+        The share kept by the server has not been freed, free it
+      */
+      share->state= NSS_DROPPED;
+      /* ndb_share reference create free */
+      DBUG_PRINT("NDB_SHARE", ("%s create free  use_count: %u",
+                               share->key, share->use_count));
+      free_share(&share, TRUE);
+    }
+    /* ndb_share reference temporary free */
+    DBUG_PRINT("NDB_SHARE", ("%s temporary free  use_count: %u",
+                             share->key, share->use_count));
+    free_share(&share, TRUE);
+    pthread_mutex_unlock(&ndbcluster_mutex);
+  }
+  else if (path)
+  {
+    pthread_mutex_lock(&ndbcluster_mutex);
+    share= get_share(path, 0, FALSE, TRUE);
+    if (share)
+    {
+      goto do_drop;
+    }
+    pthread_mutex_unlock(&ndbcluster_mutex);
+  }
+}
+
 /* static version which does not need a handler */
 
 int
-ha_ndbcluster::delete_table(THD *thd, ha_ndbcluster *h, Ndb *ndb,
-                            const char *path,
-                            const char *db,
-                            const char *table_name)
+ha_ndbcluster::drop_table(THD *thd, ha_ndbcluster *h, Ndb *ndb,
+                          const char *path,
+                          const char *db,
+                          const char *table_name)
 {
   DBUG_ENTER("ha_ndbcluster::ndbcluster_delete_table");
   NDBDICT *dict= ndb->getDictionary();
@@ -10081,26 +10310,7 @@ retry_temporary_error1:
   if (res)
   {
     /* the drop table failed for some reason, drop the share anyways */
-    if (share)
-    {
-      pthread_mutex_lock(&ndbcluster_mutex);
-      if (share->state != NSS_DROPPED)
-      {
-        /*
-          The share kept by the server has not been freed, free it
-        */
-        share->state= NSS_DROPPED;
-        /* ndb_share reference create free */
-        DBUG_PRINT("NDB_SHARE", ("%s create free  use_count: %u",
-                                 share->key, share->use_count));
-        free_share(&share, TRUE);
-      }
-      /* ndb_share reference temporary free */
-      DBUG_PRINT("NDB_SHARE", ("%s temporary free  use_count: %u",
-                               share->key, share->use_count));
-      free_share(&share, TRUE);
-      pthread_mutex_unlock(&ndbcluster_mutex);
-    }
+    delete_table_drop_share(share, 0);
     DBUG_RETURN(res);
   }
 
@@ -10140,26 +10350,7 @@ retry_temporary_error1:
                              SOT_DROP_TABLE, NULL, NULL);
   }
 
-  if (share)
-  {
-    pthread_mutex_lock(&ndbcluster_mutex);
-    if (share->state != NSS_DROPPED)
-    {
-      /*
-        The share kept by the server has not been freed, free it
-      */
-      share->state= NSS_DROPPED;
-      /* ndb_share reference create free */
-      DBUG_PRINT("NDB_SHARE", ("%s create free  use_count: %u",
-                               share->key, share->use_count));
-      free_share(&share, TRUE);
-    }
-    /* ndb_share reference temporary free */
-    DBUG_PRINT("NDB_SHARE", ("%s temporary free  use_count: %u",
-                             share->key, share->use_count));
-    free_share(&share, TRUE);
-    pthread_mutex_unlock(&ndbcluster_mutex);
-  }
+  delete_table_drop_share(share, 0);
   DBUG_RETURN(0);
 }
 
@@ -10180,6 +10371,7 @@ int ha_ndbcluster::delete_table(const ch
       dropped inside ndb.
       Just drop local files.
     */
+    delete_table_drop_share(0, name);
     DBUG_RETURN(handler::delete_table(name));
   }
 
@@ -10216,8 +10408,8 @@ int ha_ndbcluster::delete_table(const ch
     If it was already gone it might have been dropped
     remotely, give a warning and then drop .ndb file.
    */
-  if (!(error= delete_table(thd, this, ndb, name,
-                            m_dbname, m_tabname)) ||
+  if (!(error= drop_table(thd, this, ndb, name,
+                          m_dbname, m_tabname)) ||
       error == HA_ERR_NO_SUCH_TABLE)
   {
     /* Call ancestor function to delete .ndb file */
@@ -10470,26 +10662,47 @@ int ha_ndbcluster::open(const char *name
     m_key_fields[i]= NULL;
   }
 
-  // Init table lock structure 
-  /* ndb_share reference handler */
-  if (!(m_share=get_share(name, table)))
+  set_dbname(name);
+  set_tabname(name);
+
+  if ((res= check_ndb_connection(thd)) != 0)
   {
     local_close(thd, FALSE);
-    DBUG_RETURN(1);
+    DBUG_RETURN(res);
+  }
+
+  // Init table lock structure
+  /* ndb_share reference handler */
+  if ((m_share=get_share(name, table, FALSE)) == 0)
+  {
+    /**
+     * No share present...we must create one
+     */
+    if (opt_ndb_extra_logging > 19)
+    {
+      sql_print_information("Calling ndbcluster_create_binlog_setup(%s) in ::open",
+                            name);
+    }
+    Ndb* ndb= check_ndb_in_thd(thd);
+    ndbcluster_create_binlog_setup(thd, ndb, name, strlen(name),
+                                   m_dbname, m_tabname, FALSE);
+    if ((m_share=get_share(name, table, FALSE)) == 0)
+    {
+      local_close(thd, FALSE);
+      DBUG_RETURN(1);
+    }
   }
+
   DBUG_PRINT("NDB_SHARE", ("%s handler  use_count: %u",
                            m_share->key, m_share->use_count));
   thr_lock_data_init(&m_share->lock,&m_lock,(void*) 0);
-  
-  set_dbname(name);
-  set_tabname(name);
-  
-  if ((res= check_ndb_connection(thd)) ||
-      (res= get_metadata(thd, name)))
+
+  if ((res= get_metadata(thd, name)))
   {
     local_close(thd, FALSE);
     DBUG_RETURN(res);
   }
+
   if ((res= update_stats(thd, 1, true)) ||
       (res= info(HA_STATUS_CONST)))
   {
@@ -11000,7 +11213,7 @@ int ndbcluster_drop_database_impl(THD *t
   while ((tabname=it++))
   {
     tablename_to_filename(tabname, tmp, FN_REFLEN - (tmp - full_path)-1);
-    if (ha_ndbcluster::delete_table(thd, 0, ndb, full_path, dbname, tabname))
+    if (ha_ndbcluster::drop_table(thd, 0, ndb, full_path, dbname, tabname))
     {
       const NdbError err= dict->getNdbError();
       if (err.code != 709 && err.code != 723)
@@ -11701,6 +11914,24 @@ ndbcluster_init_error:
   DBUG_RETURN(TRUE);
 }
 
+#ifndef DBUG_OFF
+static
+const char*
+get_share_state_string(NDB_SHARE_STATE s)
+{
+  switch(s) {
+  case NSS_INITIAL:
+    return "NSS_INITIAL";
+  case NSS_ALTERED:
+    return "NSS_ALTERED";
+  case NSS_DROPPED:
+    return "NSS_DROPPED";
+  }
+  assert(false);
+  return "<unknown>";
+}
+#endif
+
 int ndbcluster_binlog_end(THD *thd);
 
 static int ndbcluster_end(handlerton *hton, ha_panic_function type)
@@ -11725,17 +11956,22 @@ static int ndbcluster_end(handlerton *ht
 
   {
     pthread_mutex_lock(&ndbcluster_mutex);
+    uint save = ndbcluster_open_tables.records; (void)save;
     while (ndbcluster_open_tables.records)
     {
       NDB_SHARE *share=
         (NDB_SHARE*) my_hash_element(&ndbcluster_open_tables, 0);
 #ifndef DBUG_OFF
-      fprintf(stderr, "NDB: table share %s with use_count %d not freed\n",
-              share->key, share->use_count);
+      fprintf(stderr,
+              "NDB: table share %s with use_count %d state: %s(%u) not freed\n",
+              share->key, share->use_count,
+              get_share_state_string(share->state),
+              (uint)share->state);
 #endif
       ndbcluster_real_free_share(&share);
     }
     pthread_mutex_unlock(&ndbcluster_mutex);
+    DBUG_ASSERT(save == 0);
   }
   my_hash_free(&ndbcluster_open_tables);
 
@@ -16579,7 +16815,6 @@ SHOW_VAR ndb_status_variables_export[]= 
   {NullS, NullS, SHOW_LONG}
 };
 
-
 static MYSQL_SYSVAR_ULONG(
   cache_check_time,                  /* name */
   opt_ndb_cache_check_time,              /* var */
@@ -16802,7 +17037,6 @@ bool ndb_log_empty_epochs(void)
   return opt_ndb_log_empty_epochs;
 }
 
-
 my_bool opt_ndb_log_apply_status;
 static MYSQL_SYSVAR_BOOL(
   log_apply_status,                 /* name */
@@ -16851,6 +17085,46 @@ static MYSQL_SYSVAR_UINT(
   0                                 /* block */
 );
 
+#ifndef DBUG_OFF
+
+static
+void
+dbug_check_shares(THD*, st_mysql_sys_var*, void*, const void*)
+{
+  sql_print_information("dbug_check_shares");
+  for (uint i= 0; i < ndbcluster_open_tables.records; i++)
+  {
+    NDB_SHARE * share = (NDB_SHARE*)my_hash_element(&ndbcluster_open_tables, i);
+    sql_print_information("  %s.%s: state: %s(%u) use_count: %u",
+                          share->db, share->table_name,
+                          get_share_state_string(share->state),
+                          (unsigned)share->state,
+                          share->use_count);
+  }
+
+  /**
+   * Only shares in mysql database may be open...
+   */
+  for (uint i= 0; i < ndbcluster_open_tables.records; i++)
+  {
+    NDB_SHARE * share = (NDB_SHARE*)my_hash_element(&ndbcluster_open_tables, i);
+    DBUG_ASSERT(strcmp(share->db, "mysql") == 0);
+  }
+}
+
+static MYSQL_THDVAR_UINT(
+  check_shares,              /* name */
+  PLUGIN_VAR_RQCMDARG,
+  "Debug, only...check that no shares are lingering...",
+  NULL,                              /* check func */
+  dbug_check_shares,                 /* update func */
+  0,                                 /* default */
+  0,                                 /* min */
+  1,                                 /* max */
+  0                                  /* block */
+);
+
+#endif
 
 static struct st_mysql_sys_var* system_variables[]= {
   MYSQL_SYSVAR(cache_check_time),
@@ -16889,10 +17163,12 @@ static struct st_mysql_sys_var* system_v
   MYSQL_SYSVAR(blob_write_batch_bytes),
   MYSQL_SYSVAR(deferred_constraints),
   MYSQL_SYSVAR(join_pushdown),
+#ifndef DBUG_OFF
+  MYSQL_SYSVAR(check_shares),
+#endif
   NULL
 };
 
-
 struct st_mysql_storage_engine ndbcluster_storage_engine=
 { MYSQL_HANDLERTON_INTERFACE_VERSION };
 

=== modified file 'sql/ha_ndbcluster.h'
--- a/sql/ha_ndbcluster.h	2011-07-05 12:46:07 +0000
+++ b/sql/ha_ndbcluster.h	2011-07-08 15:05:28 +0000
@@ -485,10 +485,11 @@ private:
                                       NDB_SHARE *share);
 
   void check_read_before_write_removal();
-  static int delete_table(THD *thd, ha_ndbcluster *h, Ndb *ndb,
-			  const char *path,
-			  const char *db,
-			  const char *table_name);
+  static int drop_table(THD *thd, ha_ndbcluster *h, Ndb *ndb,
+                        const char *path,
+                        const char *db,
+                        const char *table_name);
+
   int add_index_impl(THD *thd, TABLE *table_arg,
                      KEY *key_info, uint num_of_keys);
   int create_ndb_index(THD *thd, const char *name, KEY *key_info, bool unique);

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2011-07-05 12:46:07 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2011-07-08 15:05:28 +0000
@@ -1005,8 +1005,6 @@ ndb_schema_table__create(THD *thd)
   DBUG_RETURN(res);
 }
 
-
-
 class Thd_ndb_options_guard
 {
 public:
@@ -3764,6 +3762,73 @@ row_conflict_fn_max_del_win(NDB_CONFLICT
   }
 };
 
+
+/**
+  CFT_NDB_EPOCH
+
+*/
+
+int
+row_conflict_fn_epoch(NDB_CONFLICT_FN_SHARE* cfn_share,
+                      enum_conflicting_op_type op_type,
+                      const uchar* old_data,
+                      const uchar* new_data,
+                      const MY_BITMAP* write_set,
+                      NdbInterpretedCode* code)
+{
+  DBUG_ENTER("row_conflict_fn_epoch");
+  switch(op_type)
+  {
+  case WRITE_ROW:
+    abort();
+    DBUG_RETURN(1);
+  case UPDATE_ROW:
+  case DELETE_ROW:
+  {
+    const uint label_0= 0;
+    const Uint32
+      RegAuthor= 1, RegZero= 2,
+      RegMaxRepEpoch= 1, RegRowEpoch= 2;
+    int r;
+
+    r= code->load_const_u32(RegZero, 0);
+    assert(r == 0);
+    r= code->read_attr(RegAuthor, NdbDictionary::Column::ROW_AUTHOR);
+    assert(r == 0);
+    /* If last author was not local, assume no conflict */
+    r= code->branch_ne(RegZero, RegAuthor, label_0);
+    assert(r == 0);
+
+    /*
+     * Load registers RegMaxRepEpoch and RegRowEpoch
+     */
+    r= code->load_const_u64(RegMaxRepEpoch, g_ndb_slave_state.max_rep_epoch);
+    assert(r == 0);
+    r= code->read_attr(RegRowEpoch, NdbDictionary::Column::ROW_GCI64);
+    assert(r == 0);
+
+    /*
+     * if RegRowEpoch <= RegMaxRepEpoch goto label_0
+     * else raise error for this row
+     */
+    r= code->branch_le(RegRowEpoch, RegMaxRepEpoch, label_0);
+    assert(r == 0);
+    r= code->interpret_exit_nok(error_conflict_fn_violation);
+    assert(r == 0);
+    r= code->def_label(label_0);
+    assert(r == 0);
+    r= code->interpret_exit_ok();
+    assert(r == 0);
+    r= code->finalise();
+    assert(r == 0);
+    DBUG_RETURN(r);
+  }
+  default:
+    abort();
+    DBUG_RETURN(1);
+  }
+};
+
 static const st_conflict_fn_arg_def resolve_col_args[]=
 {
   /* Arg type              Optional */
@@ -3771,6 +3836,13 @@ static const st_conflict_fn_arg_def reso
   { CFAT_END,              false }
 };
 
+static const st_conflict_fn_arg_def epoch_fn_args[]=
+{
+  /* Arg type              Optional */
+  { CFAT_EXTRA_GCI_BITS,   true  },
+  { CFAT_END,              false }
+};
+
 static const st_conflict_fn_def conflict_fns[]=
 {
   { "NDB$MAX_DELETE_WIN", CFT_NDB_MAX_DEL_WIN,
@@ -3779,6 +3851,8 @@ static const st_conflict_fn_def conflict
     &resolve_col_args[0], row_conflict_fn_max         },
   { "NDB$OLD",            CFT_NDB_OLD,
     &resolve_col_args[0], row_conflict_fn_old         },
+  { "NDB$EPOCH",          CFT_NDB_EPOCH,
+    &epoch_fn_args[0],    row_conflict_fn_epoch       }
 };
 
 static unsigned n_conflict_fns=
@@ -3908,6 +3982,24 @@ parse_conflict_fn_spec(const char* confl
         }
         break;
       }
+      case CFAT_EXTRA_GCI_BITS:
+      {
+        /* Map string to number and check it's in range etc */
+        char* end_of_arg = (char*) end_arg;
+        Uint32 bits = strtoul(start_arg, &end_of_arg, 0);
+        DBUG_PRINT("info", ("Using %u as the number of extra bits", bits));
+
+        if (bits > 31)
+        {
+          arg_processing_error= true;
+          error_str= "Too many extra Gci bits";
+          DBUG_PRINT("info", ("%s", error_str));
+          break;
+        }
+        /* Num bits seems ok */
+        args[no_args].extraGciBits = bits;
+        break;
+      }
       case CFAT_END:
         abort();
       }
@@ -4014,6 +4106,57 @@ setup_conflict_fn(THD *thd, NDB_SHARE *s
     }
     break;
   }
+  case CFT_NDB_EPOCH:
+  {
+    if (num_args > 1)
+    {
+      my_snprintf(msg, msg_len,
+                  "Too many arguments to conflict function");
+      DBUG_PRINT("info", ("%s", msg));
+      DBUG_RETURN(-1);
+    }
+
+    /* Check that table doesn't have Blobs as we don't support that */
+    if (share->flags & NSF_BLOB_FLAG)
+    {
+      my_snprintf(msg, msg_len, "Table has Blob column(s), not suitable for NDB$EPOCH.");
+      DBUG_PRINT("info", ("%s", msg));
+      DBUG_RETURN(-1);
+    }
+
+    /* Check that table has required extra meta-columns */
+    /* Todo : Could warn if extra gcibits is insufficient to
+     * represent SavePeriod/EpochPeriod
+     */
+    if (ndbtab->getExtraRowGciBits() == 0)
+      sql_print_information("Ndb Slave : CFT_NDB_EPOCH, low epoch resolution");
+
+    if (ndbtab->getExtraRowAuthorBits() == 0)
+    {
+      my_snprintf(msg, msg_len, "No extra row author bits in table.");
+      DBUG_PRINT("info", ("%s", msg));
+      DBUG_RETURN(-1);
+    }
+
+    if (slave_set_resolve_fn(thd, share, ndbtab,
+                             0, // field_no
+                             0, // resolve_col_sz
+                             conflict_fn, table, CFF_REFRESH_ROWS))
+    {
+      my_snprintf(msg, msg_len,
+                  "unable to setup conflict resolution");
+      DBUG_PRINT("info", ("%s", msg));
+      DBUG_RETURN(-1);
+    }
+    if (opt_ndb_extra_logging)
+    {
+      sql_print_information("NDB Slave: Table %s.%s using conflict_fn %s.",
+                            table->s->db.str,
+                            table->s->table_name.str,
+                            conflict_fn->name);
+    }
+    break;
+  }
   case CFT_NUMBER_OF_CFTS:
   case CFT_NDB_UNDEF:
     abort();
@@ -4517,6 +4660,7 @@ ndbcluster_check_if_local_tables_in_db(T
   build_table_filename(path, sizeof(path) - 1, dbname, "", "", 0);
   if (find_files(thd, &files, dbname, path, NullS, 0) != FIND_FILES_OK)
   {
+    thd->clear_error();
     DBUG_PRINT("info", ("Failed to find files"));
     DBUG_RETURN(true);
   }
@@ -4696,10 +4840,15 @@ int ndbcluster_create_binlog_setup(THD *
                       "FAILED CREATE (DISCOVER) EVENT OPERATIONS Event: %s",
                       event_name.c_ptr());
       /* a warning has been issued to the client */
-      DBUG_RETURN(0);
+      break;
     }
     DBUG_RETURN(0);
   }
+
+  if (share)
+  {
+    free_share(&share);
+  }
   DBUG_RETURN(-1);
 }
 
@@ -7029,6 +7178,58 @@ restart_cluster_failure:
     thd_ndb= NULL;
   }
 
+  /**
+   * release all extra references from tables
+   */
+  {
+    if (opt_ndb_extra_logging > 9)
+      sql_print_information("NDB Binlog: Release extra share references");
+
+    pthread_mutex_lock(&ndbcluster_mutex);
+    for (uint i= 0; i < ndbcluster_open_tables.records;)
+    {
+      NDB_SHARE * share = (NDB_SHARE*)my_hash_element(&ndbcluster_open_tables,
+                                                      i);
+      if (share->state != NSS_DROPPED)
+      {
+        /*
+          The share kept by the server has not been freed, free it
+        */
+        share->state= NSS_DROPPED;
+        /* ndb_share reference create free */
+        DBUG_PRINT("NDB_SHARE", ("%s create free  use_count: %u",
+                                 share->key, share->use_count));
+        free_share(&share, TRUE);
+
+        /**
+         * This might have altered hash table...not sure if it's stable..
+         *   so we'll restart instead
+         */
+        i = 0;
+      }
+      else
+      {
+        i++;
+      }
+    }
+    pthread_mutex_unlock(&ndbcluster_mutex);
+  }
+
+  close_cached_tables((THD*) 0, (TABLE_LIST*) 0, FALSE, FALSE, FALSE);
+  if (opt_ndb_extra_logging > 15)
+  {
+    sql_print_information("NDB Binlog: remaining open tables: ");
+    for (uint i= 0; i < ndbcluster_open_tables.records; i++)
+    {
+      NDB_SHARE* share = (NDB_SHARE*)my_hash_element(&ndbcluster_open_tables,i);
+      sql_print_information("  %s.%s state: %u use_count: %u",
+                            share->db,
+                            share->table_name,
+                            (uint)share->state,
+                            share->use_count);
+    }
+  }
+
   if (do_ndbcluster_binlog_close_connection == BCCC_restart)
   {
     pthread_mutex_lock(&injector_mutex);

=== modified file 'sql/ndb_local_connection.cc'
--- a/sql/ndb_local_connection.cc	2011-07-01 09:56:57 +0000
+++ b/sql/ndb_local_connection.cc	2011-07-06 13:02:17 +0000
@@ -89,6 +89,7 @@ Ndb_local_connection::execute_query(MYSQ
         should_ignore_error(ignore_mysql_errors, last_errno))
     {
       /* MySQL level error suppressed -> return success */
+      m_thd->clear_error();
       DBUG_RETURN(false);
     }
 
@@ -100,6 +101,7 @@ Ndb_local_connection::execute_query(MYSQ
          suppressor->should_ignore_error(con))
     {
       /* Error suppressed -> return sucess */
+      m_thd->clear_error();
       DBUG_RETURN(false);
     }
 

=== modified file 'sql/ndb_share.h'
--- a/sql/ndb_share.h	2011-06-22 08:09:31 +0000
+++ b/sql/ndb_share.h	2011-07-08 15:05:28 +0000
@@ -38,6 +38,7 @@ enum enum_conflict_fn_type
   ,CFT_NDB_MAX
   ,CFT_NDB_OLD
   ,CFT_NDB_MAX_DEL_WIN
+  ,CFT_NDB_EPOCH
   ,CFT_NUMBER_OF_CFTS /* End marker */
 };
 
@@ -48,6 +49,7 @@ enum enum_conflict_fn_arg_type
 {
   CFAT_END
   ,CFAT_COLUMN_NAME
+  ,CFAT_EXTRA_GCI_BITS
 };
 
 struct st_conflict_fn_arg
@@ -55,7 +57,11 @@ struct st_conflict_fn_arg
   enum_conflict_fn_arg_type type;
   const char *ptr;
   uint32 len;
-  uint32 fieldno; // CFAT_COLUMN_NAME
+  union
+  {
+    uint32 fieldno;      // CFAT_COLUMN_NAME
+    uint32 extraGciBits; // CFAT_EXTRA_GCI_BITS
+  };
 };
 
 struct st_conflict_fn_arg_def
@@ -111,7 +117,8 @@ struct Ndb_exceptions_data {
 
 enum enum_conflict_fn_flags
 {
-  CFF_NONE = 0
+  CFF_NONE = 0,
+  CFF_REFRESH_ROWS = 1
 };
 
 struct NDB_CONFLICT_FN_SHARE {

=== modified file 'sql/sql_db.cc'
--- a/sql/sql_db.cc	2011-07-05 12:46:07 +0000
+++ b/sql/sql_db.cc	2011-07-06 13:02:17 +0000
@@ -42,7 +42,12 @@
 
 #define MAX_DROP_TABLE_Q_LEN      1024
 
+#ifdef MCP_BUG44529
 const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS};
+#else
+const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", ".ndb", NullS};
+#endif
+
 static TYPELIB deletable_extentions=
 {array_elements(del_exts)-1,"del_exts", del_exts, NULL};
 

=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc	2011-05-30 21:13:02 +0000
+++ b/sql/sql_partition.cc	2011-07-07 12:25:26 +0000
@@ -4674,7 +4674,11 @@ uint prep_alter_part_table(THD *thd, TAB
           without any changes at all.
         */
 #ifndef MCP_WL3749
-        *is_fast_alter_partitioning= TRUE;
+        flags= new_table->file->alter_table_flags(alter_info->flags);
+        if ((flags & (HA_FAST_CHANGE_PARTITION | HA_PARTITION_ONE_PHASE)) != 0)
+        {
+          *is_fast_alter_partitioning= TRUE;
+        }
 #else
         *fast_alter_table= new_table;
 #endif
@@ -4711,6 +4715,7 @@ uint prep_alter_part_table(THD *thd, TAB
 #else
       *fast_alter_table= new_table;
 #endif
+
 #ifndef MCP_WL3749
     DBUG_PRINT("info", ("*is_fast_alter_partitioning: %u  flags: 0x%x",
                         *is_fast_alter_partitioning, flags));

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2011-07-05 12:46:07 +0000
+++ b/sql/sql_table.cc	2011-07-07 12:25:26 +0000
@@ -6051,7 +6051,6 @@ int mysql_fast_or_online_alter_table(THD
    /*
       Tell the handler to prepare for the online alter
     */
-    table->file->ha_prepare_for_alter();
     if ((error= table->file->alter_table_phase1(thd,
                                                 altered_table,
                                                 create_info,
@@ -7105,10 +7104,11 @@ bool mysql_alter_table(THD *thd,char *ne
                             db, table_name, path,
 #ifndef MCP_WL3749
                             &table_for_fast_alter_partition,
-                            &is_fast_alter_partitioning))
+                            &is_fast_alter_partitioning
 #else
-                            &table_for_fast_alter_partition))
+                            &table_for_fast_alter_partition
 #endif
+                            ))
     goto err;
 #endif
   /*
@@ -7135,13 +7135,13 @@ bool mysql_alter_table(THD *thd,char *ne
 #endif
   set_table_default_charset(thd, create_info, db);
 
+#ifdef MCP_WL3749
   if (thd->variables.old_alter_table
       || (table->s->db_type() != create_info->db_type)
 #ifdef WITH_PARTITION_STORAGE_ENGINE
       || partition_changed
 #endif
-     )
-#ifdef MCP_WL3749
+      )
     need_copy_table= ALTER_TABLE_DATA_CHANGED;
   else
   {
@@ -7998,6 +7998,11 @@ bool mysql_alter_table(THD *thd,char *ne
 end_online:
 #endif
 
+#ifndef MCP_WL3749
+  if (table_for_fast_alter_partition)
+    close_temporary(table_for_fast_alter_partition, 1, 0);
+#endif
+
   if (thd->locked_tables_list.reopen_tables(thd))
     goto err_with_mdl;
 

=== modified file 'storage/ndb/clusterj/clusterj-api/pom.xml'
--- a/storage/ndb/clusterj/clusterj-api/pom.xml	2011-05-26 21:07:43 +0000
+++ b/storage/ndb/clusterj/clusterj-api/pom.xml	2011-07-05 22:25:18 +0000
@@ -20,13 +20,13 @@
   <parent>
     <groupId>com.mysql.clusterj</groupId>
     <artifactId>clusterj-aggregate</artifactId>
-    <version>7.1.15-SNAPSHOT</version>
+    <version>7.1.16-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.mysql.clusterj</groupId>
   <artifactId>clusterj-api</artifactId>
   <packaging>bundle</packaging>
-  <version>7.1.15-SNAPSHOT</version>
+  <version>7.1.16-SNAPSHOT</version>
   <name>ClusterJ API</name>
   <description>The API for ClusterJ</description>
   <build>

=== modified file 'storage/ndb/clusterj/clusterj-bindings/pom.xml'
--- a/storage/ndb/clusterj/clusterj-bindings/pom.xml	2011-05-26 21:07:43 +0000
+++ b/storage/ndb/clusterj/clusterj-bindings/pom.xml	2011-07-05 22:25:18 +0000
@@ -20,13 +20,13 @@
   <parent>
     <groupId>com.mysql.clusterj</groupId>
     <artifactId>clusterj-aggregate</artifactId>
-    <version>7.1.15-SNAPSHOT</version>
+    <version>7.1.16-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.mysql.clusterj</groupId>
   <artifactId>clusterj-bindings</artifactId>
   <packaging>bundle</packaging>
-  <version>7.1.15-SNAPSHOT</version>
+  <version>7.1.16-SNAPSHOT</version>
   <name>ClusterJ Bindings</name>
   <description>The ndb-bindings implementation of ClusterJ storage spi</description>
   <build>

=== modified file 'storage/ndb/clusterj/clusterj-core/pom.xml'
--- a/storage/ndb/clusterj/clusterj-core/pom.xml	2011-05-26 21:07:43 +0000
+++ b/storage/ndb/clusterj/clusterj-core/pom.xml	2011-07-05 22:25:18 +0000
@@ -20,13 +20,13 @@
   <parent>
     <groupId>com.mysql.clusterj</groupId>
     <artifactId>clusterj-aggregate</artifactId>
-    <version>7.1.15-SNAPSHOT</version>
+    <version>7.1.16-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.mysql.clusterj</groupId>
   <artifactId>clusterj-core</artifactId>
   <packaging>bundle</packaging>
-  <version>7.1.15-SNAPSHOT</version>
+  <version>7.1.16-SNAPSHOT</version>
   <name>ClusterJ Core</name>
   <description>The core implementation of ClusterJ</description>
   <build>

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/SessionImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/SessionImpl.java	2011-05-10 19:33:25 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/SessionImpl.java	2011-07-05 17:19:11 +0000
@@ -406,7 +406,7 @@ public class SessionImpl implements Sess
             op = clusterTransaction.getInsertOperation(storeTable);
             // set all values in the operation, keys first
             domainTypeHandler.operationSetKeys(valueHandler, op);
-            domainTypeHandler.operationSetNonPKValues(valueHandler, op);
+            domainTypeHandler.operationSetModifiedNonPKValues(valueHandler, op);
             // reset modified bits in instance
             domainTypeHandler.objectResetModified(valueHandler);
         } catch (ClusterJUserException cjuex) {

=== modified file 'storage/ndb/clusterj/clusterj-jdbc/pom.xml'
--- a/storage/ndb/clusterj/clusterj-jdbc/pom.xml	2011-05-26 21:07:43 +0000
+++ b/storage/ndb/clusterj/clusterj-jdbc/pom.xml	2011-07-05 22:25:18 +0000
@@ -19,13 +19,13 @@
   <parent>
     <groupId>com.mysql.clusterj</groupId>
     <artifactId>clusterj-aggregate</artifactId>
-    <version>7.1.15-SNAPSHOT</version>
+    <version>7.1.16-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>clusterj</groupId>
   <artifactId>clusterj-jdbc</artifactId>
   <name>ClusterJ JDBC Plugin</name>
-  <version>7.1.15-SNAPSHOT</version>
+  <version>7.1.16-SNAPSHOT</version>
   <dependencies>
     <dependency>
       <groupId>junit</groupId>
@@ -52,7 +52,7 @@
     <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
-      <scope>provided</scope>
+      <scope>compile</scope>
     </dependency>
     <dependency>
     	<groupId>com.mysql.clusterj</groupId>

=== modified file 'storage/ndb/clusterj/clusterj-jpatest/pom.xml'
--- a/storage/ndb/clusterj/clusterj-jpatest/pom.xml	2011-05-26 21:07:43 +0000
+++ b/storage/ndb/clusterj/clusterj-jpatest/pom.xml	2011-07-05 22:25:18 +0000
@@ -28,12 +28,12 @@
   <parent>
     <groupId>com.mysql.clusterj</groupId>
     <artifactId>clusterj-aggregate</artifactId>
-    <version>7.1.15-SNAPSHOT</version>
+    <version>7.1.16-SNAPSHOT</version>
   </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.mysql.clusterj</groupId>
     <artifactId>clusterj-jpatest</artifactId>
-    <version>7.1.15-SNAPSHOT</version>
+    <version>7.1.16-SNAPSHOT</version>
     <packaging>jar</packaging>
     <name>ClusterJ JPA Integration Tests</name>
 

=== modified file 'storage/ndb/clusterj/clusterj-openjpa/pom.xml'
--- a/storage/ndb/clusterj/clusterj-openjpa/pom.xml	2011-05-26 21:07:43 +0000
+++ b/storage/ndb/clusterj/clusterj-openjpa/pom.xml	2011-07-05 22:25:18 +0000
@@ -24,12 +24,12 @@
   <parent>
     <groupId>com.mysql.clusterj</groupId>
     <artifactId>clusterj-aggregate</artifactId>
-    <version>7.1.15-SNAPSHOT</version>
+    <version>7.1.16-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.mysql.clusterj</groupId>
   <artifactId>clusterj-openjpa</artifactId>
-  <version>7.1.15-SNAPSHOT</version>
+  <version>7.1.16-SNAPSHOT</version>
   <packaging>bundle</packaging>
   <name>ClusterJ OpenJPA Integration</name>
 

=== modified file 'storage/ndb/clusterj/clusterj-test/pom.xml'
--- a/storage/ndb/clusterj/clusterj-test/pom.xml	2011-05-26 21:07:43 +0000
+++ b/storage/ndb/clusterj/clusterj-test/pom.xml	2011-07-05 22:25:18 +0000
@@ -20,13 +20,13 @@
   <parent>
     <groupId>com.mysql.clusterj</groupId>
     <artifactId>clusterj-aggregate</artifactId>
-    <version>7.1.15-SNAPSHOT</version>
+    <version>7.1.16-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.mysql.clusterj</groupId>
   <artifactId>clusterj-test</artifactId>
   <packaging>jar</packaging>
-  <version>7.1.15-SNAPSHOT</version>
+  <version>7.1.16-SNAPSHOT</version>
   <name>ClusterJ Test Suite</name>
   <build>
     <plugins>

=== modified file 'storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/AbstractClusterJModelTest.java'
--- a/storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/AbstractClusterJModelTest.java	2011-07-05 12:46:07 +0000
+++ b/storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/AbstractClusterJModelTest.java	2011-07-06 07:14:46 +0000
@@ -152,12 +152,16 @@ public abstract class AbstractClusterJMo
         columnDescriptors = getColumnDescriptors();
     }
 
+    protected boolean getCleanupAfterTest() {
+        return true;
+    }
+
     @Override
     public void localSetUp() {
         createSessionFactory();
         session = sessionFactory.getSession();
         setAutoCommit(connection, false);
-        if (getModelClass() != null) {
+        if (getModelClass() != null && getCleanupAfterTest()) {
             addTearDownClasses(getModelClass());
         }
     }
@@ -455,6 +459,10 @@ public abstract class AbstractClusterJMo
      * @param actuals the actual results
      */
     protected void verify(String where, List<Object[]> expecteds, List<Object[]> actuals) {
+        if (expecteds.size() != actuals.size()) {
+            error(where + " failure on size of results: expected: " + expecteds.size() + " actual: " + actuals.size());
+            return;
+        }
         for (int i = 0; i < expecteds.size(); ++i) {
             Object[] expected = expecteds.get(i);
             Object[] actual = actuals.get(i);

=== modified file 'storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/AbstractQueryTest.java'
--- a/storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/AbstractQueryTest.java	2011-05-26 21:04:45 +0000
+++ b/storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/AbstractQueryTest.java	2011-07-05 22:11:45 +0000
@@ -76,10 +76,6 @@ abstract public class AbstractQueryTest 
         autotransaction = b;
     }
 
-    protected boolean getCleanupAfterTest() {
-        return true;
-    }
-
     class QueryHolder {
         public QueryBuilder builder;
         public QueryDomainType<?> dobj;

=== modified file 'storage/ndb/clusterj/clusterj-tie/pom.xml'
--- a/storage/ndb/clusterj/clusterj-tie/pom.xml	2011-06-20 23:34:36 +0000
+++ b/storage/ndb/clusterj/clusterj-tie/pom.xml	2011-07-05 22:25:18 +0000
@@ -20,13 +20,13 @@
   <parent>
     <groupId>com.mysql.clusterj</groupId>
     <artifactId>clusterj-aggregate</artifactId>
-    <version>7.1.15-SNAPSHOT</version>
+    <version>7.1.16-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.mysql.clusterj</groupId>
   <artifactId>clusterj-tie</artifactId>
   <packaging>bundle</packaging>
-  <version>7.1.15-SNAPSHOT</version>
+  <version>7.1.16-SNAPSHOT</version>
   <name>ClusterJ Tie</name>
   <description>The ndbj-tie implementation of ClusterJ storage spi</description>
   <build>

=== modified file 'storage/ndb/clusterj/pom.xml'
--- a/storage/ndb/clusterj/pom.xml	2011-05-26 21:07:43 +0000
+++ b/storage/ndb/clusterj/pom.xml	2011-07-05 22:25:18 +0000
@@ -24,7 +24,7 @@
   <groupId>com.mysql.clusterj</groupId>
   <artifactId>clusterj-aggregate</artifactId>
   <packaging>pom</packaging>
-  <version>7.1.15-SNAPSHOT</version>
+  <version>7.1.16-SNAPSHOT</version>
   <name>ClusterJ Aggregate</name>
   <description>The aggregate maven project of ClusterJ</description>
   <modules>
@@ -82,32 +82,32 @@
     <dependency>
       <groupId>com.mysql.clusterj</groupId>
       <artifactId>clusterj-api</artifactId>
-      <version>7.1.15-SNAPSHOT</version>
+      <version>7.1.16-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>com.mysql.clusterj</groupId>
       <artifactId>clusterj-core</artifactId>
-      <version>7.1.15-SNAPSHOT</version>
+      <version>7.1.16-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>com.mysql.clusterj</groupId>
       <artifactId>clusterj-test</artifactId>
-      <version>7.1.15-SNAPSHOT</version>
+      <version>7.1.16-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>com.mysql.clusterj</groupId>
       <artifactId>clusterj-tie</artifactId>
-      <version>7.1.15-SNAPSHOT</version>
+      <version>7.1.16-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>com.mysql.clusterj</groupId>
       <artifactId>clusterj-jpatest</artifactId>
-      <version>7.1.15-SNAPSHOT</version>
+      <version>7.1.16-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>ndbjtie</groupId>
       <artifactId>ndbjtie</artifactId>
-      <version>7.1.15-SNAPSHOT</version>
+      <version>7.1.16-SNAPSHOT</version>
     </dependency>
     </dependencies>
   </dependencyManagement>

=== modified file 'storage/ndb/include/ndbapi/Ndb.hpp'
--- a/storage/ndb/include/ndbapi/Ndb.hpp	2011-07-05 12:46:07 +0000
+++ b/storage/ndb/include/ndbapi/Ndb.hpp	2011-07-14 04:34:22 +0000
@@ -1074,6 +1074,9 @@ class Ndb
   friend class PollGuard;
   friend class NdbQueryImpl;
   friend class NdbQueryOperationImpl;
+  friend class DefaultWakeupHandler;
+  friend class MultiNdbWakeupHandler;
+  friend class NdbWaitGroup;
 #endif
 
 public:
@@ -1801,7 +1804,12 @@ public:
     NonDataEventsRecvdCount  = 19, /* Number of non-data events received */
     EventBytesRecvdCount     = 20, /* Number of bytes of event data received */
     
-    NumClientStatistics      = 21   /* End marker */
+    /* Adaptive Send */
+    ForcedSendsCount         = 21, /* Number of sends with force-send set */
+    UnforcedSendsCount       = 22, /* Number of sends without force-send */
+    DeferredSendsCount       = 23, /* Number of adaptive send calls not actually sent */
+    
+    NumClientStatistics      = 24   /* End marker */
   };
   
   Uint64 getClientStat(Uint32 id) const;

=== modified file 'storage/ndb/include/ndbapi/NdbApi.hpp'
--- a/storage/ndb/include/ndbapi/NdbApi.hpp	2011-07-05 12:46:07 +0000
+++ b/storage/ndb/include/ndbapi/NdbApi.hpp	2011-07-14 04:34:22 +0000
@@ -36,4 +36,5 @@
 #include "NdbEventOperation.hpp"
 #include "NdbPool.hpp"
 #include "NdbBlob.hpp"
+#include "NdbWaitGroup.hpp"
 #endif

=== added file 'storage/ndb/include/ndbapi/NdbWaitGroup.hpp'
--- a/storage/ndb/include/ndbapi/NdbWaitGroup.hpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/include/ndbapi/NdbWaitGroup.hpp	2011-07-14 04:34:22 +0000
@@ -0,0 +1,104 @@
+/*
+ Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ 
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+ 
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+#ifndef NdbWaitGroup_H
+#define NdbWaitGroup_H
+
+class Ndb_cluster_connection;
+class Ndb;
+class MultiNdbWakeupHandler;
+
+/* NdbWaitGroup extends the Asynchronous NDB API, allowing you to wait 
+   for asynchronous operations to complete on multiple Ndb objects at once.
+
+   All Ndb objects within a poll group must belong to the same cluster 
+   connection, and only one poll group per cluster connection is currently
+   supported.  You instantiate this poll group using 
+   Ndb_cluster_connection::create_multi_ndb_wait_group(). 
+   
+   Then, after using Ndb::sendPreparedTransactions() to send async operations
+   on a particular Ndb object, you can use NdbWaitGroup::addNdb() to add it
+   to the group. 
+  
+   NdbWaitGroup::wait() returns whenever some Ndb's are ready for polling; you can
+   then call Ndb::pollNdb(0, 1) on the ones that are ready. 
+*/
+
+class NdbWaitGroup {
+friend class Ndb_cluster_connection; 
+friend class Ndb_cluster_connection_impl;
+private:
+
+  /** The private constructor is used only by ndb_cluster_connection.
+      It allocates an initializes an NdbWaitGroup with an array of size
+      max_ndb_objects.
+  */
+  NdbWaitGroup(Ndb_cluster_connection *conn, int max_ndb_objects); 
+ 
+  /** The destructor is also private */
+  ~NdbWaitGroup();
+
+public: 
+
+  /** Add an Ndb object to the group.
+      
+      Returns true on success, false on error.  Error could be that the Ndb
+      is created from the wrong Ndb_cluster_connection, or is already in the
+      group, or that the group is full.
+  */
+  bool addNdb(Ndb *);
+  
+  /** Wake up the thread that is currently waiting on this group. 
+      This can be used by other threads to signal a condition to the
+      waiting thread.  
+      If no thread is currently waiting, then delivery is not guaranteed.
+  */
+  void wakeup(); 
+
+  /** wait for Ndbs to be ready.
+      arrayhead (OUT): on return will hold the list of ready Ndbs.
+      The call will return when:
+        (a) at least min_ready Ndbs are ready for polling, or
+        (b) timeout milliseconds have elapsed, or  
+        (c) another thread has called NdbWaitGroup::wakeup() 
+
+      The return value is the number of Ndb objects ready for polling, or -1
+      if a timeout occured.
+
+      On return, arrayHead is set to point to the first element of 
+      the array of Ndb object pointers that are ready for polling, and those 
+      objects are implicitly no longer in the group.  These Ndb *'s must be 
+      read from arrayHead before before any further calls to addNdb().
+  */
+  int wait(Ndb ** & arrayHead, Uint32 timeout_millis, int min_ready = 1 ); 
+  
+private:   /* private internal methods */
+   int topDownIdx(int n) { return m_array_size - n; }
+
+private:  /* private instance variables */
+   Ndb_cluster_connection *m_conn;
+   MultiNdbWakeupHandler *m_multiWaitHandler;
+   Ndb *m_wakeNdb;
+   Ndb **m_array;
+   int m_array_size;
+   int m_count;
+   int m_nodeId;
+};
+
+
+#endif
+

=== modified file 'storage/ndb/include/ndbapi/ndb_cluster_connection.hpp'
--- a/storage/ndb/include/ndbapi/ndb_cluster_connection.hpp	2011-07-05 12:46:07 +0000
+++ b/storage/ndb/include/ndbapi/ndb_cluster_connection.hpp	2011-07-14 04:34:22 +0000
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -34,6 +34,7 @@ private:
 };
 
 class Ndb;
+class NdbWaitGroup;
 
 /**
  * @class Ndb_cluster_connection
@@ -180,6 +181,15 @@ public:
    */
   Uint32 collect_client_stats(Uint64* statsArr, Uint32 sz);
 
+ /**
+  * Get/set the minimum time in milliseconds that can lapse until the adaptive 
+  * send mechanism forces all pending signals to be sent. 
+  * The default value is 10, and the allowed range is from 1 to 10.
+  */
+ void set_max_adaptive_send_time(Uint32 milliseconds);
+ Uint32 get_max_adaptive_send_time();
+
+
 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
   int get_no_ready();
   const char *get_connectstring(char *buf, int buf_sz) const;
@@ -200,6 +210,9 @@ public:
   unsigned get_active_ndb_objects() const;
   
   Uint64 *get_latest_trans_gci();
+  NdbWaitGroup * create_ndb_wait_group(int size);
+  bool release_ndb_wait_group(NdbWaitGroup *);
+
 #endif
 
 private:
@@ -207,6 +220,7 @@ private:
   friend class NdbImpl;
   friend class Ndb_cluster_connection_impl;
   friend class SignalSender;
+  friend class NdbWaitGroup;
   class Ndb_cluster_connection_impl & m_impl;
   Ndb_cluster_connection(Ndb_cluster_connection_impl&);
 

=== modified file 'storage/ndb/include/transporter/TransporterCallback.hpp'
--- a/storage/ndb/include/transporter/TransporterCallback.hpp	2011-07-05 12:46:07 +0000
+++ b/storage/ndb/include/transporter/TransporterCallback.hpp	2011-07-08 15:16:50 +0000
@@ -402,6 +402,14 @@ public:
    */
 
   /**
+   * Notify upper layer of explicit wakeup request
+   * 
+   * The is called from the thread holding receiving data from the 
+   * transporter, under the protection of the transporter lock.
+   */
+  virtual void reportWakeup() { }
+
+  /**
    * Ask upper layer to supply a list of struct iovec's with data to
    * send to a node.
    *

=== modified file 'storage/ndb/src/common/transporter/TransporterRegistry.cpp'
--- a/storage/ndb/src/common/transporter/TransporterRegistry.cpp	2011-07-05 12:46:07 +0000
+++ b/storage/ndb/src/common/transporter/TransporterRegistry.cpp	2011-07-08 15:16:50 +0000
@@ -1351,6 +1351,9 @@ TransporterRegistry::consume_extra_socke
     ret = my_recv(sock, buf, sizeof(buf), 0);
     err = my_socket_errno();
   } while (ret == sizeof(buf) || (ret == -1 && err == EINTR));
+  
+  /* Notify upper layer of explicit wakeup */
+  callbackObj->reportWakeup();
 }
 
 void

=== modified file 'storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2011-06-23 06:59:40 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2011-07-08 15:05:28 +0000
@@ -13890,7 +13890,8 @@ void Dbtc::execFIRE_TRIG_ORD(Signal* sig
 
     if(likely( ok ))
     {
-      jam();      
+      jam();
+      setApiConTimer(transPtr.i, ctcTimer, __LINE__);
       opPtr.p->noReceivedTriggers++;
       opPtr.p->triggerExecutionCount++; // Default 1 LQHKEYREQ per trigger
 

=== modified file 'storage/ndb/src/ndbapi/API.hpp'
--- a/storage/ndb/src/ndbapi/API.hpp	2011-07-05 12:46:07 +0000
+++ b/storage/ndb/src/ndbapi/API.hpp	2011-07-14 04:34:22 +0000
@@ -42,6 +42,7 @@
 #include <NdbBlob.hpp>
 #include <NdbBlobImpl.hpp>
 #include <NdbInterpretedCode.hpp>
+#include <NdbWaitGroup.hpp>
 
 #include <NdbEventOperation.hpp>
 #include "NdbEventOperationImpl.hpp"

=== modified file 'storage/ndb/src/ndbapi/CMakeLists.txt'
--- a/storage/ndb/src/ndbapi/CMakeLists.txt	2011-07-05 12:46:07 +0000
+++ b/storage/ndb/src/ndbapi/CMakeLists.txt	2011-07-14 04:34:22 +0000
@@ -50,6 +50,7 @@ ADD_CONVENIENCE_LIBRARY(ndbapi
             NdbQueryOperation.cpp
             NdbApiSignal.cpp
             NdbRecAttr.cpp
+            NdbWaitGroup.cpp
             NdbUtil.cpp
             NdbReceiver.cpp
             NdbDictionary.cpp
@@ -59,6 +60,7 @@ ADD_CONVENIENCE_LIBRARY(ndbapi
             NdbBlob.cpp
             SignalSender.cpp
             ObjectMap.cpp
+            WakeupHandler.cpp
             NdbInfo.cpp
             NdbInfoScanOperation.cpp
             ndb_internal.cpp

=== modified file 'storage/ndb/src/ndbapi/Ndb.cpp'
--- a/storage/ndb/src/ndbapi/Ndb.cpp	2011-07-05 12:46:07 +0000
+++ b/storage/ndb/src/ndbapi/Ndb.cpp	2011-07-08 05:06:27 +0000
@@ -2290,7 +2290,10 @@ const char* ClientStatNames [] =
   "TransLocalReadRowCount",
   "DataEventsRecvdCount",
   "NonDataEventsRecvdCount",
-  "EventBytesRecvdCount"
+  "EventBytesRecvdCount",
+  "ForcedSendsCount",
+  "UnforcedSendsCount",
+  "DeferredSendsCount"
 };
 
 Uint64

=== modified file 'storage/ndb/src/ndbapi/NdbImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbImpl.hpp	2011-07-05 12:46:07 +0000
+++ b/storage/ndb/src/ndbapi/NdbImpl.hpp	2011-07-08 15:16:50 +0000
@@ -31,6 +31,7 @@
 #include "trp_client.hpp"
 #include "trp_node.hpp"
 #include "NdbWaiter.hpp"
+#include "WakeupHandler.hpp"
 
 template <class T>
 struct Ndb_free_list_t 
@@ -80,7 +81,11 @@ public:
   Uint32 the_release_ind[MAX_NDB_NODES];
 
   NdbWaiter             theWaiter;
-
+ 
+  DefaultWakeupHandler normalWakeHandler;
+  WakeupHandler* wakeHandler;
+  Uint32 wakeContext;
+  
   NdbEventOperationImpl *m_ev_op;
 
   int m_optimized_node_selection;
@@ -191,6 +196,7 @@ public:
    */
   virtual void trp_deliver_signal(const NdbApiSignal*,
                                   const LinearSectionPtr p[3]);
+  virtual void trp_wakeup();
   virtual void recordWaitTimeNanos(Uint64 nanos);
   // Is node available for running transactions
   bool   get_node_alive(NodeId nodeId) const;
@@ -601,4 +607,12 @@ NdbImpl::sendFragmentedSignal(NdbApiSign
   return -1;
 }
 
+inline 
+void
+NdbImpl::trp_wakeup() 
+{
+  wakeHandler->notifyWakeup();
+}
+
+
 #endif

=== added file 'storage/ndb/src/ndbapi/NdbWaitGroup.cpp'
--- a/storage/ndb/src/ndbapi/NdbWaitGroup.cpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/ndbapi/NdbWaitGroup.cpp	2011-07-14 04:34:22 +0000
@@ -0,0 +1,121 @@
+/*
+ Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ 
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+ 
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+#include <ndb_global.h>
+#include "NdbWaitGroup.hpp"
+#include "WakeupHandler.hpp"
+#include "ndb_cluster_connection.hpp"
+#include "TransporterFacade.hpp"
+#include "ndb_cluster_connection_impl.hpp"
+#include "NdbImpl.hpp"
+
+NdbWaitGroup::NdbWaitGroup(Ndb_cluster_connection *_conn, int _ndbs) :
+  m_conn(_conn),
+  m_array_size(_ndbs),
+  m_count(0),
+  m_nodeId(0),
+  m_multiWaitHandler(0)
+{
+  /* Allocate the array of Ndbs */
+  m_array = new Ndb *[m_array_size];
+
+  /* Call into the TransporterFacade to set up wakeups */
+  bool rc = m_conn->m_impl.m_transporter_facade->setupWakeup();
+  assert(rc);
+  
+  /* Get a new Ndb object to be the dedicated "wakeup object" for the group */
+  m_wakeNdb = new Ndb(m_conn);
+  assert(m_wakeNdb);
+  m_wakeNdb->init(1);
+  m_nodeId = m_wakeNdb->theNode;
+  
+  /* Get a wakeup handler */
+  m_multiWaitHandler = new MultiNdbWakeupHandler(m_wakeNdb);
+}
+
+
+NdbWaitGroup::~NdbWaitGroup() 
+{
+  while(m_count > 0)
+  {
+    m_multiWaitHandler->unregisterNdb(m_array[topDownIdx(m_count--)]);
+  }
+
+  delete m_multiWaitHandler;
+  delete m_wakeNdb;
+  delete[] m_array;
+}
+
+
+bool NdbWaitGroup::addNdb(Ndb *ndb)
+{
+  if(unlikely(ndb->theNode != m_nodeId))
+  {
+    return false; // Ndb belongs to wrong ndb_cluster_connection
+  }  
+
+  if(unlikely(m_count == m_array_size))
+  {
+    return false; // array is full
+  }
+
+  if(unlikely(m_multiWaitHandler->ndbIsRegistered(ndb)))
+  {
+    return false; // duplicate of item already in group
+  }
+
+  m_count++;
+  m_array[topDownIdx(m_count)] = ndb;
+  return true;
+}
+
+
+void NdbWaitGroup::wakeup() 
+{
+  m_conn->m_impl.m_transporter_facade->requestWakeup();
+}
+
+
+int NdbWaitGroup::wait(Ndb ** & arrayHead    /* out */,
+                       Uint32 timeout_millis,
+                       int min_ndbs)
+{
+  arrayHead = NULL;
+  Ndb ** ndblist = m_array + topDownIdx(m_count);
+  
+  int wait_rc;
+  int nready;
+  {
+    PollGuard pg(* m_wakeNdb->theImpl);   // get ready to poll
+    wait_rc = m_multiWaitHandler->waitForInput(ndblist, m_count, min_ndbs,
+                                               & pg, timeout_millis);
+    nready = m_multiWaitHandler->getNumReadyNdbs();
+
+    if(wait_rc == 0) 
+    {
+      arrayHead = ndblist;   // success
+      for(int i = 0 ; i < nready ; i++)  // remove ready Ndbs from group
+      {
+        m_multiWaitHandler->unregisterNdb(m_array[topDownIdx(m_count)]);
+        m_count--;
+      }
+    }
+  }   /* release PollGuard */
+
+  return wait_rc ? -1 : nready;
+}
+

=== modified file 'storage/ndb/src/ndbapi/Ndbif.cpp'
--- a/storage/ndb/src/ndbapi/Ndbif.cpp	2011-06-07 12:19:47 +0000
+++ b/storage/ndb/src/ndbapi/Ndbif.cpp	2011-07-08 15:16:50 +0000
@@ -1014,12 +1014,8 @@ Ndb::completedTransaction(NdbTransaction
     theNoOfSentTransactions = tNoSentTransactions - 1;
     aCon->theListState = NdbTransaction::InCompletedList;
     aCon->handleExecuteCompletion();
-    if ((theMinNoOfEventsToWakeUp != 0) &&
-        (theNoOfCompletedTransactions >= theMinNoOfEventsToWakeUp)) {
-      theMinNoOfEventsToWakeUp = 0;
-      theImpl->theWaiter.signal(NO_WAIT);
-      return;
-    }//if
+    
+    theImpl->wakeHandler->notifyTransactionCompleted(this);
   } else {
     ndbout << "theNoOfSentTransactions = " << (int) theNoOfSentTransactions;
     ndbout << " theListState = " << (int) aCon->theListState;
@@ -1247,7 +1243,13 @@ Ndb::sendPrepTrans(int forceSend)
     insert_completed_list(a_con);
   }//for
   theNoOfPreparedTransactions = 0;
-  theImpl->do_forceSend(forceSend);
+  int did_send = theImpl->do_forceSend(forceSend);
+  if(forceSend) {
+    theImpl->incClientStat(Ndb::ForcedSendsCount, 1);
+  }
+  else {
+    theImpl->incClientStat(did_send ? Ndb::UnforcedSendsCount : Ndb::DeferredSendsCount, 1);
+  }
   return;
 }//Ndb::sendPrepTrans()
 

=== modified file 'storage/ndb/src/ndbapi/Ndbinit.cpp'
--- a/storage/ndb/src/ndbapi/Ndbinit.cpp	2011-07-05 12:46:07 +0000
+++ b/storage/ndb/src/ndbapi/Ndbinit.cpp	2011-07-08 15:16:50 +0000
@@ -204,6 +204,8 @@ NdbImpl::NdbImpl(Ndb_cluster_connection 
     theNdbObjectIdMap(1024,1024),
     theNoOfDBnodes(0),
     theWaiter(this),
+    wakeHandler(&normalWakeHandler),
+    wakeContext(~Uint32(0)),
     m_ev_op(0),
     customDataPtr(0)
 {

=== modified file 'storage/ndb/src/ndbapi/TransporterFacade.cpp'
--- a/storage/ndb/src/ndbapi/TransporterFacade.cpp	2011-06-23 06:59:40 +0000
+++ b/storage/ndb/src/ndbapi/TransporterFacade.cpp	2011-07-08 15:16:50 +0000
@@ -425,6 +425,19 @@ TransporterFacade::doStop(){
   DBUG_VOID_RETURN;
 }
 
+void TransporterFacade::setSendThreadInterval(Uint32 ms)
+{
+  if(ms > 0 && ms <= 10) 
+  { 
+    sendThreadWaitMillisec = ms;
+  }
+}
+
+Uint32 TransporterFacade::getSendThreadInterval(void)
+{
+  return sendThreadWaitMillisec;
+}
+
 extern "C" 
 void* 
 runSendRequest_C(void * me)
@@ -444,7 +457,7 @@ void TransporterFacade::threadMainSend(v
   m_socket_server.startServer();
 
   while(!theStopReceive) {
-    NdbSleep_MilliSleep(10);
+    NdbSleep_MilliSleep(sendThreadWaitMillisec);
     NdbMutex_Lock(theMutexPtr);
     if (sendPerformedLastInterval == 0) {
       theTransporterRegistry->performSend();
@@ -533,11 +546,13 @@ TransporterFacade::TransporterFacade(Glo
   theClusterMgr(NULL),
   checkCounter(4),
   currentSendLimit(1),
+  dozer(NULL),
   theStopReceive(0),
   theSendThread(NULL),
   theReceiveThread(NULL),
   m_fragmented_signal_id(0),
-  m_globalDictCache(cache)
+  m_globalDictCache(cache),
+  sendThreadWaitMillisec(10)
 {
   DBUG_ENTER("TransporterFacade::TransporterFacade");
   theMutexPtr = NdbMutex_CreateWithName("TTFM");
@@ -815,7 +830,7 @@ void TransporterFacade::forceSend(Uint32
 //-------------------------------------------------
 // Improving API performance
 //-------------------------------------------------
-void
+int
 TransporterFacade::checkForceSend(Uint32 block_number) {  
   m_threads.m_statusNext[numberToIndex(block_number)] = ThreadData::ACTIVE;
   //-------------------------------------------------
@@ -828,14 +843,16 @@ TransporterFacade::checkForceSend(Uint32
   // time to increase so therefore we have to keep track of
   // how the users are performing adaptively.
   //-------------------------------------------------
-  
-  if (theTransporterRegistry->forceSendCheck(currentSendLimit) == 1) {
+
+  int did_send = theTransporterRegistry->forceSendCheck(currentSendLimit);
+  if(did_send == 1) {
     sendPerformedLastInterval = 1;
   }
   checkCounter--;
   if (checkCounter < 0) {
     calculateSendLimit();
   }
+  return did_send;
 }
 
 
@@ -2031,3 +2048,64 @@ TransporterFacade::ext_doConnect(int aNo
   theClusterMgr->unlock();
 }
 
+bool
+TransporterFacade::setupWakeup()
+{
+  /* Ask TransporterRegistry to setup wakeup sockets */
+  bool rc;
+  lock_mutex();
+  {
+    rc = theTransporterRegistry->setup_wakeup_socket();
+  }
+  unlock_mutex();
+  return rc;
+}
+
+bool 
+TransporterFacade::registerForWakeup(trp_client* _dozer)
+{
+  /* Called with Transporter lock */
+  /* In future use a DLList for dozers.
+   * Ideally with some way to wake one rather than all
+   * For now, we just have one/TransporterFacade
+   */
+  if (dozer != NULL)
+    return false;
+
+  dozer = _dozer;
+  return true;
+}
+
+bool
+TransporterFacade::unregisterForWakeup(trp_client* _dozer)
+{
+  /* Called with Transporter lock */
+  if (dozer != _dozer)
+    return false;
+
+  dozer = NULL;
+  return true;
+}
+
+void
+TransporterFacade::requestWakeup()
+{
+  /* Forward to TransporterRegistry
+   * No need for locks, assuming only one client at a time will use
+   */
+  theTransporterRegistry->wakeup();
+}
+
+
+void
+TransporterFacade::reportWakeup()
+{
+  /* Explicit wakeup callback
+   * Called with Transporter Mutex held
+   */
+  /* Notify interested parties */
+  if (dozer != NULL)
+  {
+    dozer->trp_wakeup();
+  };
+}

=== modified file 'storage/ndb/src/ndbapi/TransporterFacade.hpp'
--- a/storage/ndb/src/ndbapi/TransporterFacade.hpp	2011-06-23 06:59:40 +0000
+++ b/storage/ndb/src/ndbapi/TransporterFacade.hpp	2011-07-08 15:16:50 +0000
@@ -71,6 +71,12 @@ public:
 
   Uint32 get_active_ndb_objects() const;
 
+  /** 
+   * Get/Set wait time in the send thread.
+   */
+ void setSendThreadInterval(Uint32 ms);
+ Uint32 getSendThreadInterval(void);
+
   // Only sends to nodes which are alive
 private:
   int sendSignal(const NdbApiSignal * signal, NodeId nodeId);
@@ -126,7 +132,7 @@ public:
 
   // Improving the API performance
   void forceSend(Uint32 block_number);
-  void checkForceSend(Uint32 block_number);
+  int checkForceSend(Uint32 block_number);
 
   TransporterRegistry* get_registry() { return theTransporterRegistry;};
 
@@ -197,6 +203,21 @@ public:
   {
     theTransporterRegistry->reset_send_buffer(node, should_be_empty);
   }
+  /**
+   * Wakeup
+   *
+   * Clients normally block waiting for a pattern of signals,
+   * or until a timeout expires.
+   * This Api allows them to be woken early.
+   * To use it, a setupWakeup() call must be made once prior
+   * to using the Apis in any client.
+   * 
+   */
+  bool setupWakeup();
+  bool registerForWakeup(trp_client* dozer);
+  bool unregisterForWakeup(trp_client* dozer);
+  void requestWakeup();
+  void reportWakeup();
 
 private:
 
@@ -223,8 +244,14 @@ private:
   
   void calculateSendLimit();
 
+  /* Single dozer supported currently.
+   * In future, use a DLList to support > 1
+   */
+  trp_client * dozer;
+
   // Declarations for the receive and send thread
   int  theStopReceive;
+  Uint32 sendThreadWaitMillisec;
 
   void threadMainSend(void);
   NdbThread* theSendThread;

=== added file 'storage/ndb/src/ndbapi/WakeupHandler.cpp'
--- a/storage/ndb/src/ndbapi/WakeupHandler.cpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/ndbapi/WakeupHandler.cpp	2011-07-14 04:34:22 +0000
@@ -0,0 +1,220 @@
+
+/*
+ Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ 
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+ 
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+#include "WakeupHandler.hpp"
+#include "Ndb.hpp"
+#include "NdbImpl.hpp"
+#include "trp_client.hpp"
+
+//  ****** Default handler ****
+void DefaultWakeupHandler::notifyTransactionCompleted(Ndb *from) 
+{
+  if ((from->theMinNoOfEventsToWakeUp != 0) &&
+      (from->theNoOfCompletedTransactions >= from->theMinNoOfEventsToWakeUp)) {
+    from->theMinNoOfEventsToWakeUp = 0;
+    from->theImpl->theWaiter.signal(NO_WAIT);
+  }
+}
+
+
+
+// ***** Multiwait handler ****
+
+/**
+ * An instance of this class is used when a single thread
+ * wants to wait for the asynchronous completion of transactions
+ * on multiple Ndb objects.
+ * When the thread starts waiting, all Ndb objects are checked
+ * for CompletedTransactions, and their wakeHandler is set to
+ * poin to the same MultiNdbWakeupHandler object.  The thread
+ * is then put to sleep / polls on a designated Ndb object.
+ *
+ * As transactions complete, the MultiNdbWakeHandler object
+ * moves their Ndb objects to the start of the passed Ndb
+ * object list and determines whether enough have completed 
+ * to wake the waiting thread.
+ * When enough have completed, the waiting thread is woken via
+ * the designated Ndb object.
+ */
+
+MultiNdbWakeupHandler::MultiNdbWakeupHandler(Ndb* _wakeNdb)
+ : wakeNdb(_wakeNdb),
+   woken(false)
+{
+  /* Register the waiter Ndb to receive wakeups for all Ndbs in the group */
+  PollGuard pg(* wakeNdb->theImpl);   // Hold mutex before calling into Facade
+  bool rc = wakeNdb->theImpl->m_transporter_facade->registerForWakeup(wakeNdb->theImpl);
+  assert(rc);
+  wakeNdb->theImpl->wakeHandler = this;
+}
+
+
+MultiNdbWakeupHandler::~MultiNdbWakeupHandler()
+{
+  PollGuard pg(* wakeNdb->theImpl); // Hold mutex before calling into Facade  
+  bool rc = wakeNdb->theImpl->m_transporter_facade->
+            unregisterForWakeup(wakeNdb->theImpl);
+  assert(rc);
+}
+
+
+bool MultiNdbWakeupHandler::ndbIsRegistered(Ndb *obj) 
+{
+  return (obj->theImpl->wakeHandler == this);
+}
+
+
+bool MultiNdbWakeupHandler::unregisterNdb(Ndb *obj) 
+{
+  if(obj->theImpl->wakeHandler == this) 
+  {   
+    obj->theImpl->wakeHandler = & obj->theImpl->normalWakeHandler;
+    obj->theImpl->wakeContext = ~ Uint32(0);
+    return true;
+  }
+  return false;
+}
+
+
+Uint32 MultiNdbWakeupHandler::getNumReadyNdbs() const
+{
+  return numNdbsWithCompletedTrans;
+}
+
+    
+int MultiNdbWakeupHandler::waitForInput(Ndb** _objs, int _cnt, int min_req,
+                                        PollGuard* pg, int timeout_millis)
+{
+  woken = false;
+  numNdbsWithCompletedTrans = 0;
+  minNdbsToWake = min_req;
+  objs = _objs;
+  cnt = _cnt;
+  
+  /* Before sleeping, we register each Ndb, and check whether it already 
+     has any completed transactions.
+  */ 
+  for (Uint32 ndbcnt = 0; ndbcnt < cnt; ndbcnt ++)
+  {
+    Ndb* obj = objs [ndbcnt];
+    
+    /* Register the Ndb */
+    obj->theImpl->wakeHandler = this;
+
+    /* Store its list position */
+    obj->theImpl->wakeContext = ndbcnt;
+    
+    /* It may already have some completed transactions */
+    if (obj->theNoOfCompletedTransactions)
+    {
+      /* Move that ndb to the start of the array */
+      swapNdbsInArray(ndbcnt, numNdbsWithCompletedTrans);
+      numNdbsWithCompletedTrans++;
+    }
+  }
+  
+  if(isReadyToWake())  // already enough
+  {
+    woken = false;
+    return 0;
+  }
+  
+  wakeNdb->theImpl->theWaiter.set_node(0);
+  wakeNdb->theImpl->theWaiter.set_state(WAIT_TRANS);
+
+  NDB_TICKS currTime = NdbTick_CurrentMillisecond();
+  NDB_TICKS maxTime = currTime + (NDB_TICKS) timeout_millis;
+
+  do {
+    /* PollGuard will put us to sleep until something relevant happens */
+    pg->wait_for_input(timeout_millis > 10 ? 10 : timeout_millis);
+    wakeNdb->theImpl->incClientStat(Ndb::WaitExecCompleteCount, 1);
+
+    if (isReadyToWake())
+    {
+      woken = false;  // reset for next time
+      return 0;
+    }
+    timeout_millis = (int) (maxTime - NdbTick_CurrentMillisecond());
+  } while (timeout_millis > 0);
+  
+  return -1;  // timeout occured
+}
+
+
+void MultiNdbWakeupHandler::swapNdbsInArray(Uint32 indexA, Uint32 indexB)
+{
+  /* Generally used to move an Ndb object down the list
+   * (bubble sort), so that it is part of a contiguous
+   * list of Ndbs with completed transactions to return
+   * to caller.
+   * If it's already in the given position, no effect
+   */
+  assert(indexA < cnt);
+  assert(indexB < cnt);
+  
+  Ndb* a = objs[ indexA ];
+  Ndb* b = objs[ indexB ];
+  
+  assert(a->theImpl->wakeContext == indexA);
+  assert(b->theImpl->wakeContext == indexB);
+  
+  objs[ indexA ] = b;
+  b->theImpl->wakeContext = indexA;
+  
+  objs[ indexB ] = a;
+  a->theImpl->wakeContext = indexB;
+}
+    
+      
+void MultiNdbWakeupHandler::notifyTransactionCompleted(Ndb* from)
+{
+  Uint32 & completedNdbListPos = from->theImpl->wakeContext;
+
+  /* TODO : assert that transporter lock is held */
+  assert(completedNdbListPos < cnt);
+  assert(wakeNdb->theImpl->wakeHandler == this);  
+  assert(from != wakeNdb); 
+  
+  /* Some Ndb object has just completed another transaction.
+     Ensure that it's in the completed Ndbs list 
+   */
+  if (completedNdbListPos >= numNdbsWithCompletedTrans)
+  {
+    /* It's not, swap it with Ndb in 'next' position */
+    swapNdbsInArray(completedNdbListPos, numNdbsWithCompletedTrans);    
+    numNdbsWithCompletedTrans ++;
+  }
+    
+  if (numNdbsWithCompletedTrans >= minNdbsToWake)
+  {
+    wakeNdb->theImpl->theWaiter.signal(NO_WAIT);    // wakeup client thread
+  }
+  
+  return;
+}
+
+    
+void MultiNdbWakeupHandler::notifyWakeup()
+{
+  assert(wakeNdb->theImpl->wakeHandler == this);
+
+  /* Wakeup client thread, using 'waiter' Ndb */
+  woken = true;
+  wakeNdb->theImpl->theWaiter.signal(NO_WAIT);
+}

=== added file 'storage/ndb/src/ndbapi/WakeupHandler.hpp'
--- a/storage/ndb/src/ndbapi/WakeupHandler.hpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/ndbapi/WakeupHandler.hpp	2011-07-14 04:34:22 +0000
@@ -0,0 +1,86 @@
+/*
+ Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ 
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+ 
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+#ifndef WakeupHandler_H
+#define WakeupHandler_H
+
+#include <ndb_types.h>
+class Ndb;
+class Ndb_cluster_connection;
+class PollGuard;
+
+/**
+ * WakeupHandler
+ *
+ * Help Ndb objects respond to wakeups from the TransporterFacade
+ * when transactions have completed.
+ *
+ * Each Ndb will own an instance of the DefaultWakeupHandler,
+ * and each NdbWaitGroup will create an instance of a more specialized
+ * WakeupHandler.
+ */
+
+class WakeupHandler
+{
+  public:
+    virtual void notifyTransactionCompleted(Ndb* from) = 0;
+    virtual void notifyWakeup() = 0;
+    virtual ~WakeupHandler() {};
+};
+
+
+class DefaultWakeupHandler : public WakeupHandler
+{
+  void notifyTransactionCompleted(Ndb* from);
+  void notifyWakeup() {};
+};
+
+
+class MultiNdbWakeupHandler : public WakeupHandler
+{
+  public:
+    MultiNdbWakeupHandler(Ndb* _wakeNdb);
+    ~MultiNdbWakeupHandler();
+    bool unregisterNdb(Ndb *);
+    bool ndbIsRegistered(Ndb *);
+    void notifyTransactionCompleted(Ndb* from);
+    void notifyWakeup();
+    Uint32 getNumReadyNdbs() const; 
+    /** returns 0 on success, -1 on timeout: */
+    int waitForInput(Ndb **objs, int cnt, int min_requested, 
+                     PollGuard* pg, int timeout_millis);
+
+  private:   // private methods
+    void swapNdbsInArray(Uint32 indexA, Uint32 indexB);
+    bool isReadyToWake() const;
+ 
+  private:   // private instance variables
+    Uint32 numNdbsWithCompletedTrans;
+    Uint32 minNdbsToWake;
+    Ndb* wakeNdb;
+    Ndb** objs;
+    Uint32 cnt;
+    volatile bool woken;
+};
+
+
+inline bool MultiNdbWakeupHandler::isReadyToWake() const
+{
+  return (numNdbsWithCompletedTrans >= minNdbsToWake) || woken;
+}
+
+#endif

=== modified file 'storage/ndb/src/ndbapi/ndb_cluster_connection.cpp'
--- a/storage/ndb/src/ndbapi/ndb_cluster_connection.cpp	2011-07-05 12:46:07 +0000
+++ b/storage/ndb/src/ndbapi/ndb_cluster_connection.cpp	2011-07-14 04:34:22 +0000
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -363,7 +363,8 @@ Ndb_cluster_connection_impl(const char *
     m_first_ndb_object(0),
     m_latest_error_msg(),
     m_latest_error(0),
-    m_max_trans_id(0)
+    m_max_trans_id(0),
+    m_multi_wait_group(0)
 {
   DBUG_ENTER("Ndb_cluster_connection");
   DBUG_PRINT("enter",("Ndb_cluster_connection this=0x%lx", (long) this));
@@ -497,6 +498,10 @@ Ndb_cluster_connection_impl::~Ndb_cluste
     NdbMutex_Destroy(m_new_delete_ndb_mutex);
   m_new_delete_ndb_mutex = 0;
   
+  if(m_multi_wait_group) 
+    delete m_multi_wait_group;
+  m_multi_wait_group = 0;
+  
   DBUG_VOID_RETURN;
 }
 
@@ -981,5 +986,46 @@ Ndb_cluster_connection::collect_client_s
   return relevant;
 }
 
-template class Vector<Ndb_cluster_connection_impl::Node>;
+void
+Ndb_cluster_connection::set_max_adaptive_send_time(Uint32 milliseconds)
+{
+  m_impl.m_transporter_facade->setSendThreadInterval(milliseconds);
+}
+
+Uint32
+Ndb_cluster_connection::get_max_adaptive_send_time()
+{
+  return m_impl.m_transporter_facade->getSendThreadInterval();
+}
 
+NdbWaitGroup *
+Ndb_cluster_connection::create_ndb_wait_group(int size) 
+{
+  if(m_impl.m_multi_wait_group == NULL) 
+  {
+    m_impl.m_multi_wait_group = new NdbWaitGroup(this, size);
+    return m_impl.m_multi_wait_group;
+  }
+  else
+  {
+    return NULL;  // NdbWaitGroup already exists
+  }
+}
+
+bool
+Ndb_cluster_connection::release_ndb_wait_group(NdbWaitGroup *group)
+{
+  if(m_impl.m_multi_wait_group && m_impl.m_multi_wait_group == group)
+  {
+    delete m_impl.m_multi_wait_group;
+    m_impl.m_multi_wait_group = 0;
+    return true;
+  }
+  else
+  {
+    return false;
+  }
+}
+
+
+template class Vector<Ndb_cluster_connection_impl::Node>;

=== modified file 'storage/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp'
--- a/storage/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp	2011-07-05 12:46:07 +0000
+++ b/storage/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp	2011-07-14 04:34:22 +0000
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -74,6 +74,7 @@ public:
 private:
   friend class Ndb;
   friend class NdbImpl;
+  friend class NdbWaitGroup;
   friend void* run_ndb_cluster_connection_connect_thread(void*);
   friend class Ndb_cluster_connection;
   friend class NdbEventBuffer;
@@ -131,6 +132,8 @@ private:
   // Base offset for stats, from Ndb objects that are no 
   // longer with us
   Uint64 globalApiStatsBaseline[ Ndb::NumClientStatistics ];
+
+  NdbWaitGroup *m_multi_wait_group;
 };
 
 #endif

=== modified file 'storage/ndb/src/ndbapi/trp_client.cpp'
--- a/storage/ndb/src/ndbapi/trp_client.cpp	2011-02-24 22:07:05 +0000
+++ b/storage/ndb/src/ndbapi/trp_client.cpp	2011-07-08 05:06:27 +0000
@@ -101,17 +101,19 @@ trp_client::complete_poll()
   m_facade->complete_poll(this);
 }
 
-void
+int
 trp_client::do_forceSend(int val)
 {
+  int did_send = 1;
   if (val == 0)
   {
-    m_facade->checkForceSend(m_blockNo);
+    did_send = m_facade->checkForceSend(m_blockNo);
   }
   else if (val == 1)
   {
     m_facade->forceSend(m_blockNo);
   }
+  return did_send;
 }
 
 int

=== modified file 'storage/ndb/src/ndbapi/trp_client.hpp'
--- a/storage/ndb/src/ndbapi/trp_client.hpp	2011-02-24 22:07:05 +0000
+++ b/storage/ndb/src/ndbapi/trp_client.hpp	2011-07-08 15:16:50 +0000
@@ -35,6 +35,8 @@ public:
 
   virtual void trp_deliver_signal(const NdbApiSignal *,
                                   const LinearSectionPtr ptr[3]) = 0;
+  virtual void trp_wakeup()
+    {};
 
   Uint32 open(class TransporterFacade*, int blockNo = -1);
   void close();
@@ -44,7 +46,7 @@ public:
   void complete_poll();
   void wakeup();
 
-  void do_forceSend(int val = 1);
+  int do_forceSend(int val = 1);
 
   int raw_sendSignal(const NdbApiSignal*, Uint32 nodeId);
   int raw_sendSignal(const NdbApiSignal*, Uint32 nodeId,

=== modified file 'storage/ndb/src/ndbjtie/jtie/jtie_tconv_idcache_impl.hpp'
--- a/storage/ndb/src/ndbjtie/jtie/jtie_tconv_idcache_impl.hpp	2011-07-05 12:46:07 +0000
+++ b/storage/ndb/src/ndbjtie/jtie/jtie_tconv_idcache_impl.hpp	2011-07-06 11:11:57 +0000
@@ -198,6 +198,20 @@ struct MemberId {
         jclass cls = env->FindClass(C::class_name);
         if (cls == NULL) { // break out for better diagnostics
             assert(env->ExceptionCheck() != JNI_OK); // exception pending
+
+//#ifndef NDEBUG // XXX for debugging
+            // print error diagnostics
+            char m[256];
+#ifndef _WIN32
+            snprintf(m, 256, "JTie: failed to find Java class '%s'\n",
+#else
+            _snprintf(m, 256, "JTie: failed to find Java class '%s'\n",
+#endif
+                     (C::class_name == NULL ? "NULL" : C::class_name));
+            fprintf(stderr, m);
+            env->ExceptionDescribe();
+            env->FatalError(m); // XXX for debugging
+//#endif // NDEBUG
         } else {
             assert(env->ExceptionCheck() == JNI_OK); // ok
         }
@@ -331,7 +345,11 @@ struct MemberIdStrongCache : MemberIdCac
         jclass cls = Base::gClassRef;
         if (cls == NULL) {
             cls = A::getClass(env);
-            setClass(env, cls);
+            if (cls == NULL) {
+                // exception pending
+            } else {
+                setClass(env, cls);
+            }
         }
         return cls;
     }

=== modified file 'storage/ndb/test/ndbapi/CMakeLists.txt'
--- a/storage/ndb/test/ndbapi/CMakeLists.txt	2011-07-05 12:46:07 +0000
+++ b/storage/ndb/test/ndbapi/CMakeLists.txt	2011-07-08 15:16:50 +0000
@@ -64,6 +64,7 @@ Add_EXECUTABLE(testNdbinfo testNdbinfo.c
 ADD_EXECUTABLE(testNativeDefault testNativeDefault.cpp)
 ADD_EXECUTABLE(testSpj testSpj.cpp)
 ADD_EXECUTABLE(testMgmd testMgmd.cpp)
+ADD_EXECUTABLE(testAsynchMultiwait testAsynchMultiwait.cpp)
 TARGET_LINK_LIBRARIES(testBackup ndbbank)
 TARGET_LINK_LIBRARIES(testSRBank ndbbank)
 ADD_EXECUTABLE(testLimits testLimits.cpp)
@@ -79,7 +80,7 @@ SET(BINS create_all_tabs create_tab
   testDeadlock test_event ndbapi_slow_select testReadPerf
   testLcp testPartitioning testBitfield DbCreate
   DbAsyncGenerator test_event_merge testNdbinfo
-  testNativeDefault testLimits testSpj testMgmd)
+  testNativeDefault testLimits testSpj testMgmd testAsynchMultiwait)
 
 FOREACH(B ${BINS})
   TARGET_LINK_LIBRARIES(${B} ndbNDBT)

=== added file 'storage/ndb/test/ndbapi/testAsynchMultiwait.cpp'
--- a/storage/ndb/test/ndbapi/testAsynchMultiwait.cpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/ndbapi/testAsynchMultiwait.cpp	2011-07-14 04:34:22 +0000
@@ -0,0 +1,303 @@
+/*
+ Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ 
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+ 
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+*/
+
+
+#include "NDBT_Test.hpp"
+#include "NDBT_ReturnCodes.h"
+#include "HugoTransactions.hpp"
+#include "HugoAsynchTransactions.hpp"
+#include "UtilTransactions.hpp"
+#include "random.h"
+
+NdbWaitGroup * global_poll_group;
+
+#define check(b, e) \
+  if (!(b)) { g_err << "ERR: " << step->getName() << " failed on line " \
+  << __LINE__ << ": " << e.getNdbError() << endl; return NDBT_FAILED; }
+
+
+int runSetup(NDBT_Context* ctx, NDBT_Step* step){
+  
+  int records = ctx->getNumRecords();
+  int batchSize = ctx->getProperty("BatchSize", 1);
+  int transactions = (records / 100) + 1;
+  int operations = (records / transactions) + 1;
+  Ndb* pNdb = GETNDB(step);
+  
+  HugoAsynchTransactions hugoTrans(*ctx->getTab());
+  if (hugoTrans.loadTableAsynch(pNdb, records, batchSize, 
+				transactions, operations) != 0){
+    return NDBT_FAILED;
+  }
+
+  Ndb_cluster_connection* conn = &pNdb->get_ndb_cluster_connection();
+
+  /* The first call to create_multi_ndb_wait_group() should succeed ... */
+  global_poll_group = conn->create_ndb_wait_group(1000);
+  if(global_poll_group == 0) {
+    return NDBT_FAILED;
+  }
+
+  /* and subsequent calls should fail */
+  if(conn->create_ndb_wait_group(1000) != 0) {
+    return NDBT_FAILED;
+  }
+
+  return NDBT_OK;
+}
+
+int runCleanup(NDBT_Context* ctx, NDBT_Step* step){
+  int records = ctx->getNumRecords();
+  int batchSize = ctx->getProperty("BatchSize", 1);
+  int transactions = (records / 100) + 1;
+  int operations = (records / transactions) + 1;
+  Ndb* pNdb = GETNDB(step);
+  
+  HugoAsynchTransactions hugoTrans(*ctx->getTab());
+  if (hugoTrans.pkDelRecordsAsynch(pNdb,  records, batchSize, 
+				   transactions, operations) != 0){
+    return NDBT_FAILED;
+  }
+
+  pNdb->get_ndb_cluster_connection().release_ndb_wait_group(global_poll_group);
+    
+  return NDBT_OK;
+}
+
+
+int runPkReadMultiBasic(NDBT_Context* ctx, NDBT_Step* step){
+  int loops = ctx->getNumLoops();
+  int records = ctx->getNumRecords();
+  const int MAX_NDBS = 200;
+  Ndb* pNdb = GETNDB(step);
+  Ndb_cluster_connection* conn = &pNdb->get_ndb_cluster_connection();
+  
+  int i = 0;
+  HugoOperations hugoOps(*ctx->getTab());
+  
+  Ndb* ndbObjs[ MAX_NDBS ];  
+  NdbTransaction* transArray[ MAX_NDBS ];
+  Ndb ** ready_ndbs;
+  
+  for (int j=0; j < MAX_NDBS; j++)
+  {
+    Ndb* ndb = new Ndb(conn);
+    check(ndb->init() == 0, (*ndb));
+    ndbObjs[ j ] = ndb;
+  }
+  
+  while (i<loops) {
+    ndbout << "Loop : " << i << ": ";
+    int recordsLeft = records;
+    
+    do
+    {
+      /* Define and execute Pk read requests on 
+       * different Ndb objects
+       */
+      int ndbcnt = 0;
+      int pollcnt = 0;
+      int lumpsize = 1 + myRandom48(MIN(recordsLeft, MAX_NDBS));
+      while(lumpsize &&
+            recordsLeft && 
+            ndbcnt < MAX_NDBS)
+      {
+        Ndb* ndb = ndbObjs[ ndbcnt ];
+        NdbTransaction* trans = ndb->startTransaction();
+        check(trans != NULL, (*ndb));
+        NdbOperation* readOp = trans->getNdbOperation(ctx->getTab());
+        check(readOp != NULL, (*trans));
+        check(readOp->readTuple() == 0, (*readOp));
+        check(hugoOps.equalForRow(readOp, recordsLeft) == 0, hugoOps);
+        
+        /* Read all other cols */
+        for (int k=0; k < ctx->getTab()->getNoOfColumns(); k++)
+        {
+          check(readOp->getValue(ctx->getTab()->getColumn(k)) != NULL,
+                (*readOp));
+        }
+        
+        /* Now send em off */
+        trans->executeAsynchPrepare(NdbTransaction::Commit,
+                                    NULL,
+                                    NULL,
+                                    NdbOperation::AbortOnError);
+        ndb->sendPreparedTransactions();
+        
+        transArray[ndbcnt] = trans;
+        global_poll_group->addNdb(ndb);
+        
+        ndbcnt++;
+        pollcnt++;
+        recordsLeft--;
+        lumpsize--;
+      };
+      
+      /* Ok, now wait for the Ndbs to complete */
+      while (pollcnt)
+      {
+        /* Occasionally check with no timeout */
+        Uint32 timeout_millis = myRandom48(2)?10000:0;
+        int count = global_poll_group->wait(ready_ndbs, timeout_millis);
+
+        if (count > 0)
+        {
+          for (int y=0; y < count; y++)
+          {
+            Ndb *ndb = ready_ndbs[y];
+            check(ndb->pollNdb(0, 1) != 0, (*ndb));
+          }
+          pollcnt -= count;
+        }
+      }
+      
+      /* Ok, now close the transactions */
+      for (int t=0; t < ndbcnt; t++)
+      {
+        transArray[t]->close();
+      }
+    } while (recordsLeft);
+    
+    i++;
+  }
+  
+  for (int j=0; j < MAX_NDBS; j++)
+  {
+    delete ndbObjs[ j ];
+  }
+  
+  return NDBT_OK;
+}
+
+int runPkReadMultiWakeupT1(NDBT_Context* ctx, NDBT_Step* step)
+{
+  HugoOperations hugoOps(*ctx->getTab());
+  Ndb* ndb = GETNDB(step);
+  Uint32 phase = ctx->getProperty("PHASE");
+  
+  if (phase != 0)
+  {
+    ndbout << "Thread 1 : Error, initial phase should be 0 not " << phase << endl;
+    return NDBT_FAILED;
+  };
+  
+  /* We now start a transaction, locking row 0 */
+  ndbout << "Thread 1 : Starting transaction locking row 0..." << endl;
+  check(hugoOps.startTransaction(ndb) == 0, hugoOps);
+  check(hugoOps.pkReadRecord(ndb, 0, 1, NdbOperation::LM_Exclusive) == 0,
+        hugoOps);
+  check(hugoOps.execute_NoCommit(ndb) == 0, hugoOps);
+  
+  ndbout << "Thread 1 : Lock taken." << endl;
+  ndbout << "Thread 1 : Triggering Thread 2 by move to phase 1" << endl;
+  /* Ok, now get thread 2 to try to read row */
+  ctx->incProperty("PHASE"); /* Set to 1 */
+  
+  /* Here, loop waking up waiter on the cluster connection */
+  /* Check the property has not moved to phase 2 */
+  ndbout << "Thread 1 : Performing async wakeup until phase changes to 2"
+  << endl;
+  while (ctx->getProperty("PHASE") != 2)
+  {
+    global_poll_group->wakeup();
+    NdbSleep_MilliSleep(500);
+  }
+  
+  ndbout << "Thread 1 : Phase changed to 2, committing transaction "
+  << "and releasing lock" << endl;
+  
+  /* Ok, give them a break, commit transaction */
+  check(hugoOps.execute_Commit(ndb) ==0, hugoOps);
+  hugoOps.closeTransaction(ndb);
+  
+  ndbout << "Thread 1 : Finished" << endl;
+  return NDBT_OK;
+}  
+
+int runPkReadMultiWakeupT2(NDBT_Context* ctx, NDBT_Step* step)
+{
+  ndbout << "Thread 2 : Waiting for phase 1 notification from Thread 1" << endl;
+  ctx->getPropertyWait("PHASE", 1);
+  
+  /* Ok, now thread 1 has locked row 1, we'll attempt to read
+   * it, using the multi_ndb_wait Api to block
+   */
+  HugoOperations hugoOps(*ctx->getTab());
+  Ndb* ndb = GETNDB(step);
+  
+  ndbout << "Thread 2 : Starting async transaction to read row" << endl;
+  check(hugoOps.startTransaction(ndb) == 0, hugoOps);
+  check(hugoOps.pkReadRecord(ndb, 0, 1, NdbOperation::LM_Exclusive) == 0,
+        hugoOps);
+  /* Prepare, Send */
+  check(hugoOps.execute_async(ndb, 
+                              NdbTransaction::Commit, 
+                              NdbOperation::AbortOnError) == 0,
+        hugoOps);
+
+  global_poll_group->addNdb(ndb);
+  Ndb ** ready_ndbs;
+  int wait_rc = 0;
+  int acknowledged = 0;
+  do
+  {
+    ndbout << "Thread 2 : Calling NdbWaitGroup::wait()" << endl;
+    wait_rc = global_poll_group->wait(ready_ndbs, 10000);
+    ndbout << "           Result : " << wait_rc << endl;
+    if (wait_rc == 0)
+    {
+      if (!acknowledged)
+      {
+        ndbout << "Thread 2 : Woken up, moving to phase 2" << endl;
+        ctx->incProperty("PHASE");
+        acknowledged = 1;
+      }
+    }
+    else if (wait_rc > 0)
+    {
+      ndbout << "Thread 2 : Transaction completed" << endl;
+      ndb->pollNdb(1,0);
+      hugoOps.closeTransaction(ndb);
+    }
+  } while (wait_rc == 0);
+  
+  return (wait_rc == 1 ? NDBT_OK : NDBT_FAILED);
+}
+
+NDBT_TESTSUITE(testAsynchMultiwait);
+TESTCASE("AsynchMultiwaitPkRead",
+         "Verify NdbWaitGroup API (1 thread)") {
+  INITIALIZER(runSetup);
+  STEP(runPkReadMultiBasic);
+  FINALIZER(runCleanup);
+}
+TESTCASE("AsynchMultiwaitWakeup",
+         "Verify wait-multi-ndb wakeup Api code") {
+  INITIALIZER(runSetup);
+  TC_PROPERTY("PHASE", Uint32(0));
+  STEP(runPkReadMultiWakeupT1);
+  STEP(runPkReadMultiWakeupT2);
+  FINALIZER(runCleanup);
+}
+NDBT_TESTSUITE_END(testAsynchMultiwait);
+
+int main(int argc, const char** argv){
+  ndb_init();
+  NDBT_TESTSUITE_INSTANCE(testAsynchMultiwait);
+  return testAsynchMultiwait.execute(argc, argv);
+}
+

=== modified file 'storage/ndb/test/run-test/daily-devel-tests.txt'
--- a/storage/ndb/test/run-test/daily-devel-tests.txt	2011-07-05 12:46:07 +0000
+++ b/storage/ndb/test/run-test/daily-devel-tests.txt	2011-07-14 04:34:22 +0000
@@ -129,3 +129,13 @@ max-time: 1800
 cmd: testDict
 args: -n SchemaTrans -l 1
 
+# async api extensions
+
+max-time : 500
+cmd : testAsynchMultiwait
+args: -nAsynchMultiwaitPkRead T1
+
+max-time : 500
+cmd : testAsynchMultiwait
+args: -nAsynchMultiwaitWakeup T1
+

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.5-cluster branch (john.duncan:3422 to 3436) John David Duncan17 Jul