List:Commits« Previous MessageNext Message »
From:Magnus Blåudd Date:September 22 2009 7:56am
Subject:bzr commit into mysql-5.1-telco-7.0 branch (magnus.blaudd:3007)
View as plain text  
#At file:///home/msvensson/mysql/7.0-testMgmd/ based on revid:magnus.blaudd@stripped49-wducpp7ockq1zr7t

 3007 Magnus Blåudd	2009-09-22 [merge]
      Merge

    added:
      mysql-test/suite/rpl_ndb/r/rpl_ndb_slave_lsu.result
      mysql-test/suite/rpl_ndb/t/rpl_ndb_multi_binlog_update.cnf
      mysql-test/suite/rpl_ndb/t/rpl_ndb_multi_binlog_update.inc
      mysql-test/suite/rpl_ndb/t/rpl_ndb_slave_lsu.cnf
      mysql-test/suite/rpl_ndb/t/rpl_ndb_slave_lsu.test
      mysql-test/suite/rpl_ndb/t/rpl_ndb_wait_schema_logging.inc
      storage/ndb/include/kernel/signaldata/LocalRouteOrd.hpp
      storage/ndb/src/common/debugger/signaldata/LocalRouteOrd.cpp
      storage/ndb/test/run-test/conf-ndb07.cnf
    modified:
      mysql-test/suite/ndb/r/ndb_alter_table_online.result
      mysql-test/suite/ndb/r/ndb_multi.result
      mysql-test/suite/ndb/t/ndb_alter_table_online.test
      mysql-test/suite/ndb/t/ndb_multi.test
      mysql-test/suite/ndb_binlog/r/ndb_binlog_ddl_multi.result
      mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result
      mysql-test/suite/ndb_binlog/r/ndb_binlog_multi.result
      mysql-test/suite/rpl_ndb/r/rpl_ndb_circular.result
      mysql-test/suite/rpl_ndb/t/rpl_ndb_circular.test
      mysql-test/suite/rpl_ndb/t/rpl_ndb_circular_2ch.cnf
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster_binlog.cc
      sql/ha_ndbcluster_binlog.h
      storage/ndb/include/kernel/GlobalSignalNumbers.h
      storage/ndb/include/kernel/signaldata/BackupLockTab.hpp
      storage/ndb/include/kernel/signaldata/FsOpenReq.hpp
      storage/ndb/include/kernel/signaldata/SignalData.hpp
      storage/ndb/src/common/debugger/signaldata/CMakeLists.txt
      storage/ndb/src/common/debugger/signaldata/Makefile.am
      storage/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp
      storage/ndb/src/common/debugger/signaldata/SignalNames.cpp
      storage/ndb/src/common/portlib/NdbDir.cpp
      storage/ndb/src/kernel/blocks/ERROR_codes.txt
      storage/ndb/src/kernel/blocks/backup/Backup.cpp
      storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp
      storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
      storage/ndb/src/kernel/blocks/dbacc/DbaccProxy.cpp
      storage/ndb/src/kernel/blocks/dbacc/DbaccProxy.hpp
      storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
      storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
      storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp
      storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
      storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
      storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp
      storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
      storage/ndb/src/kernel/blocks/dblqh/DblqhProxy.cpp
      storage/ndb/src/kernel/blocks/dblqh/DblqhProxy.hpp
      storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
      storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupProxy.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupProxy.hpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp
      storage/ndb/src/kernel/blocks/dbtux/DbtuxProxy.cpp
      storage/ndb/src/kernel/blocks/dbtux/DbtuxProxy.hpp
      storage/ndb/src/kernel/blocks/ndbfs/PosixAsyncFile.cpp
      storage/ndb/src/kernel/blocks/ndbfs/Win32AsyncFile.cpp
      storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
      storage/ndb/src/kernel/vm/SimulatedBlock.cpp
      storage/ndb/src/kernel/vm/SimulatedBlock.hpp
      storage/ndb/src/kernel/vm/mt.cpp
      storage/ndb/src/mgmsrv/MgmtSrvr.cpp
      storage/ndb/src/ndbapi/DictCache.cpp
      storage/ndb/src/ndbapi/Ndb.cpp
      storage/ndb/test/ndbapi/testDict.cpp
      storage/ndb/test/ndbapi/testNodeRestart.cpp
      storage/ndb/test/ndbapi/testSystemRestart.cpp
      storage/ndb/test/run-test/Makefile.am
      storage/ndb/test/run-test/autotest-run.sh
      storage/ndb/test/run-test/daily-basic-tests.txt
      storage/ndb/test/run-test/daily-devel-tests.txt
      storage/ndb/test/src/UtilTransactions.cpp
=== modified file 'mysql-test/suite/ndb/r/ndb_alter_table_online.result'
--- a/mysql-test/suite/ndb/r/ndb_alter_table_online.result	2009-07-13 13:22:46 +0000
+++ b/mysql-test/suite/ndb/r/ndb_alter_table_online.result	2009-09-15 14:10:32 +0000
@@ -691,6 +691,30 @@ b INT COLUMN_FORMAT FIXED)ROW_FORMAT=DYN
 Attributes:
 pk1 Int PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY
 b Int NULL AT=FIXED ST=MEMORY
+DROP TABLE t1;
+********************
+* bug#44695 ALTER TABLE during START BACKUP crashes mysqld     
+********************
+CREATE TABLE t1(k INT NOT NULL PRIMARY KEY AUTO_INCREMENT) ROW_FORMAT=DYNAMIC ENGINE=NDB;
+INSERT INTO t1 VALUES (NULL);
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+16384
+ALTER ONLINE TABLE t1 ADD b INT;
 ********************
 * Cleanup Section
 ********************

=== modified file 'mysql-test/suite/ndb/r/ndb_multi.result'
--- a/mysql-test/suite/ndb/r/ndb_multi.result	2007-11-12 10:42:37 +0000
+++ b/mysql-test/suite/ndb/r/ndb_multi.result	2009-09-17 13:53:38 +0000
@@ -143,3 +143,39 @@ show tables like '%$%';
 Tables_in_test (%$%)
 show tables like '%$%';
 Tables_in_test (%$%)
+create table t1(s char(1)) engine = myisam;
+insert into t1 values ("a"),("b"),("c");
+create table t1(s char(1)) engine = ndb;
+insert into t1 values ("d"),("e"),("f");
+Restarting mysqld
+use test;
+select * from t1 order by s;
+s
+a
+b
+c
+select * from t1 order by s;
+s
+d
+e
+f
+drop table t1;
+select * from t1 order by s;
+s
+a
+b
+c
+create table t1(s char(1)) engine = ndb;
+insert into t1 values ("g"),("h"),("i");
+show tables;
+Tables_in_test
+t1
+Warnings:
+Warning	1050	Local table test.t1 shadows ndb table
+select * from t1 order by s;
+s
+a
+b
+c
+drop table t1;
+drop table t1;

=== modified file 'mysql-test/suite/ndb/t/ndb_alter_table_online.test'
--- a/mysql-test/suite/ndb/t/ndb_alter_table_online.test	2009-07-13 13:22:46 +0000
+++ b/mysql-test/suite/ndb/t/ndb_alter_table_online.test	2009-09-16 13:29:58 +0000
@@ -731,6 +731,39 @@ b INT COLUMN_FORMAT FIXED)ROW_FORMAT=DYN
 
 source show_attributes.inc;
 
+DROP TABLE t1;
+
+--echo ********************
+--echo * bug#44695 ALTER TABLE during START BACKUP crashes mysqld     
+--echo ********************
+# Testing failure of online alter during ongoing backup
+
+CREATE TABLE t1(k INT NOT NULL PRIMARY KEY AUTO_INCREMENT) ROW_FORMAT=DYNAMIC ENGINE=NDB;
+# create some data to slow down backup
+INSERT INTO t1 VALUES (NULL);
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+INSERT INTO t1 SELECT NULL FROM t1;
+SELECT COUNT(*) FROM t1;
+--exec $NDB_MGM --no-defaults --ndb-connectstring="$NDB_CONNECTSTRING" -e "start backup nowait" >> $NDB_TOOLS_OUTPUT
+--disable_warnings
+--error 0,762,1296
+ALTER ONLINE TABLE t1 ADD b INT;
+# waut for backup to complete
+--sleep 10
+
+--enable_warnings
 --echo ********************
 --echo * Cleanup Section
 --echo ********************

=== modified file 'mysql-test/suite/ndb/t/ndb_multi.test'
--- a/mysql-test/suite/ndb/t/ndb_multi.test	2008-09-08 14:34:10 +0000
+++ b/mysql-test/suite/ndb/t/ndb_multi.test	2009-09-21 13:53:09 +0000
@@ -155,3 +155,39 @@ show tables like '%$%';
 
 connection server1;
 show tables like '%$%';
+
+#
+# Bug #42614 Mysql auto locate databases can overwrite frm data.
+#
+connection server1;
+create table t1(s char(1)) engine = myisam;
+insert into t1 values ("a"),("b"),("c");
+connection server2;
+create table t1(s char(1)) engine = ndb;
+insert into t1 values ("d"),("e"),("f");
+connection server1;
+## Restart mysqld nodes
+--echo Restarting mysqld
+let $mysqld_name=mysqld.1.1;
+--source include/restart_mysqld.inc
+use test;
+select * from t1 order by s;
+connection server2;
+select * from t1 order by s;
+drop table t1;
+connection server1;
+select * from t1 order by s;
+connection server2;
+create table t1(s char(1)) engine = ndb;
+insert into t1 values ("g"),("h"),("i");
+connection server1;
+show tables;
+select * from t1 order by s;
+
+#
+# Clean-up
+#
+connection server1;
+drop table t1;
+connection server2;
+drop table t1;
\ No newline at end of file

=== modified file 'mysql-test/suite/ndb_binlog/r/ndb_binlog_ddl_multi.result'
--- a/mysql-test/suite/ndb_binlog/r/ndb_binlog_ddl_multi.result	2009-02-01 21:05:19 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_ddl_multi.result	2009-09-11 10:34:36 +0000
@@ -10,14 +10,14 @@ create table t1 (a int primary key) engi
 create table t2 (a int primary key) engine=ndb;
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-mysqld-bin.000001	#	Query	1	#	create database mysqltest
-mysqld-bin.000001	#	Query	1	#	use `mysqltest`; create table t1 (a int primary key) engine=ndb
+mysqld-bin.000001	#	Query	2	#	create database mysqltest
+mysqld-bin.000001	#	Query	2	#	use `mysqltest`; create table t1 (a int primary key) engine=ndb
 mysqld-bin.000001	#	Query	2	#	use `test`; create table t2 (a int primary key) engine=ndb
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
 mysqld-bin.000001	#	Query	1	#	create database mysqltest
 mysqld-bin.000001	#	Query	1	#	use `mysqltest`; create table t1 (a int primary key) engine=ndb
-mysqld-bin.000001	#	Query	2	#	use `test`; create table t2 (a int primary key) engine=ndb
+mysqld-bin.000001	#	Query	1	#	use `test`; create table t2 (a int primary key) engine=ndb
 reset master;
 reset master;
 alter table t2 add column (b int);
@@ -25,19 +25,19 @@ Warnings:
 Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-mysqld-bin.000001	#	Query	2	#	use `test`; alter table t2 add column (b int)
+mysqld-bin.000001	#	Query	1	#	use `test`; alter table t2 add column (b int)
 reset master;
 reset master;
 ALTER DATABASE mysqltest CHARACTER SET latin1;
 drop table mysqltest.t1;
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-mysqld-bin.000001	#	Query	2	#	ALTER DATABASE mysqltest CHARACTER SET latin1
-mysqld-bin.000001	#	Query	2	#	use `mysqltest`; drop table `mysqltest`.`t1`
+mysqld-bin.000001	#	Query	1	#	ALTER DATABASE mysqltest CHARACTER SET latin1
+mysqld-bin.000001	#	Query	1	#	use `mysqltest`; drop table `mysqltest`.`t1`
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-mysqld-bin.000001	#	Query	2	#	ALTER DATABASE mysqltest CHARACTER SET latin1
-mysqld-bin.000001	#	Query	2	#	use `mysqltest`; drop table `mysqltest`.`t1`
+mysqld-bin.000001	#	Query	1	#	ALTER DATABASE mysqltest CHARACTER SET latin1
+mysqld-bin.000001	#	Query	1	#	use `mysqltest`; drop table `mysqltest`.`t1`
 reset master;
 reset master;
 use test;
@@ -52,8 +52,8 @@ mysqld-bin.000001	#	Table_map	2	#	table_
 mysqld-bin.000001	#	Write_rows	2	#	table_id: #
 mysqld-bin.000001	#	Write_rows	2	#	table_id: # flags: STMT_END_F
 mysqld-bin.000001	#	Query	2	#	COMMIT
-mysqld-bin.000001	#	Query	1	#	drop database mysqltest
-mysqld-bin.000001	#	Query	1	#	use `test`; create table t1 (a int primary key) engine=ndb
+mysqld-bin.000001	#	Query	2	#	drop database mysqltest
+mysqld-bin.000001	#	Query	2	#	use `test`; create table t1 (a int primary key) engine=ndb
 drop table t2;
 reset master;
 reset master;
@@ -87,63 +87,63 @@ DROP LOGFILE GROUP lg1 
 ENGINE =NDB;
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-mysqld-bin.000001	#	Query	1	#	CREATE LOGFILE GROUP lg1
+mysqld-bin.000001	#	Query	2	#	CREATE LOGFILE GROUP lg1
 ADD UNDOFILE 'undofile.dat'
 INITIAL_SIZE 16M
 UNDO_BUFFER_SIZE = 1M
 ENGINE=NDB
-mysqld-bin.000001	#	Query	1	#	ALTER LOGFILE GROUP lg1
+mysqld-bin.000001	#	Query	2	#	ALTER LOGFILE GROUP lg1
 ADD UNDOFILE 'undofile02.dat'
 INITIAL_SIZE = 4M 
 ENGINE=NDB
-mysqld-bin.000001	#	Query	1	#	CREATE TABLESPACE ts1
+mysqld-bin.000001	#	Query	2	#	CREATE TABLESPACE ts1
 ADD DATAFILE 'datafile.dat'
 USE LOGFILE GROUP lg1
 INITIAL_SIZE 12M
 ENGINE NDB
-mysqld-bin.000001	#	Query	1	#	ALTER TABLESPACE ts1
+mysqld-bin.000001	#	Query	2	#	ALTER TABLESPACE ts1
 ADD DATAFILE 'datafile02.dat'
 INITIAL_SIZE = 4M 
 ENGINE=NDB
-mysqld-bin.000001	#	Query	1	#	ALTER TABLESPACE ts1 
+mysqld-bin.000001	#	Query	2	#	ALTER TABLESPACE ts1 
 DROP DATAFILE 'datafile.dat' 
 ENGINE = NDB
-mysqld-bin.000001	#	Query	1	#	ALTER TABLESPACE ts1 
+mysqld-bin.000001	#	Query	2	#	ALTER TABLESPACE ts1 
 DROP DATAFILE 'datafile02.dat' 
 ENGINE = NDB
-mysqld-bin.000001	#	Query	1	#	DROP TABLESPACE ts1 
+mysqld-bin.000001	#	Query	2	#	DROP TABLESPACE ts1 
 ENGINE = NDB
-mysqld-bin.000001	#	Query	1	#	DROP LOGFILE GROUP lg1 
+mysqld-bin.000001	#	Query	2	#	DROP LOGFILE GROUP lg1 
 ENGINE =NDB
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-mysqld-bin.000001	#	Query	1	#	CREATE LOGFILE GROUP lg1
+mysqld-bin.000001	#	Query	2	#	CREATE LOGFILE GROUP lg1
 ADD UNDOFILE 'undofile.dat'
 INITIAL_SIZE 16M
 UNDO_BUFFER_SIZE = 1M
 ENGINE=NDB
-mysqld-bin.000001	#	Query	1	#	ALTER LOGFILE GROUP lg1
+mysqld-bin.000001	#	Query	2	#	ALTER LOGFILE GROUP lg1
 ADD UNDOFILE 'undofile02.dat'
 INITIAL_SIZE = 4M 
 ENGINE=NDB
-mysqld-bin.000001	#	Query	1	#	CREATE TABLESPACE ts1
+mysqld-bin.000001	#	Query	2	#	CREATE TABLESPACE ts1
 ADD DATAFILE 'datafile.dat'
 USE LOGFILE GROUP lg1
 INITIAL_SIZE 12M
 ENGINE NDB
-mysqld-bin.000001	#	Query	1	#	ALTER TABLESPACE ts1
+mysqld-bin.000001	#	Query	2	#	ALTER TABLESPACE ts1
 ADD DATAFILE 'datafile02.dat'
 INITIAL_SIZE = 4M 
 ENGINE=NDB
-mysqld-bin.000001	#	Query	1	#	ALTER TABLESPACE ts1 
+mysqld-bin.000001	#	Query	2	#	ALTER TABLESPACE ts1 
 DROP DATAFILE 'datafile.dat' 
 ENGINE = NDB
-mysqld-bin.000001	#	Query	1	#	ALTER TABLESPACE ts1 
+mysqld-bin.000001	#	Query	2	#	ALTER TABLESPACE ts1 
 DROP DATAFILE 'datafile02.dat' 
 ENGINE = NDB
-mysqld-bin.000001	#	Query	1	#	DROP TABLESPACE ts1 
+mysqld-bin.000001	#	Query	2	#	DROP TABLESPACE ts1 
 ENGINE = NDB
-mysqld-bin.000001	#	Query	1	#	DROP LOGFILE GROUP lg1 
+mysqld-bin.000001	#	Query	2	#	DROP LOGFILE GROUP lg1 
 ENGINE =NDB
 drop table t1;
 reset master;
@@ -158,13 +158,13 @@ create table t3 (a int key) engine=ndb;
 rename table t3 to t4, t2 to t3, t1 to t2, t4 to t1;
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-mysqld-bin.000001	#	Query	1	#	use `test`; create table t1 (a int key) engine=ndb
-mysqld-bin.000001	#	Query	1	#	use `test`; create table t2 (a int key) engine=ndb
-mysqld-bin.000001	#	Query	1	#	use `test`; create table t3 (a int key) engine=ndb
-mysqld-bin.000001	#	Query	1	#	use `test`; rename table `test`.`t3` to `test`.`t4`
-mysqld-bin.000001	#	Query	1	#	use `test`; rename table `test`.`t2` to `test`.`t3`
-mysqld-bin.000001	#	Query	1	#	use `test`; rename table `test`.`t1` to `test`.`t2`
-mysqld-bin.000001	#	Query	1	#	use `test`; rename table `test`.`t4` to `test`.`t1`
+mysqld-bin.000001	#	Query	2	#	use `test`; create table t1 (a int key) engine=ndb
+mysqld-bin.000001	#	Query	2	#	use `test`; create table t2 (a int key) engine=ndb
+mysqld-bin.000001	#	Query	2	#	use `test`; create table t3 (a int key) engine=ndb
+mysqld-bin.000001	#	Query	2	#	use `test`; rename table `test`.`t3` to `test`.`t4`
+mysqld-bin.000001	#	Query	2	#	use `test`; rename table `test`.`t2` to `test`.`t3`
+mysqld-bin.000001	#	Query	2	#	use `test`; rename table `test`.`t1` to `test`.`t2`
+mysqld-bin.000001	#	Query	2	#	use `test`; rename table `test`.`t4` to `test`.`t1`
 drop table t1;
 drop table t2;
 drop table t3;
@@ -181,14 +181,14 @@ insert into t2 values(2);
 drop table t2;
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-mysqld-bin.000001	#	Query	1	#	use `test`; create table t1 (a int key) engine=ndb
+mysqld-bin.000001	#	Query	2	#	use `test`; create table t1 (a int key) engine=ndb
 mysqld-bin.000001	#	Query	2	#	BEGIN
 mysqld-bin.000001	#	Table_map	2	#	table_id: # (test.t1)
 mysqld-bin.000001	#	Table_map	2	#	table_id: # (mysql.ndb_apply_status)
 mysqld-bin.000001	#	Write_rows	2	#	table_id: #
 mysqld-bin.000001	#	Write_rows	2	#	table_id: # flags: STMT_END_F
 mysqld-bin.000001	#	Query	2	#	COMMIT
-mysqld-bin.000001	#	Query	1	#	use `test`; rename table `test`.`t1` to `test`.`t2`
+mysqld-bin.000001	#	Query	2	#	use `test`; rename table `test`.`t1` to `test`.`t2`
 mysqld-bin.000001	#	Query	2	#	BEGIN
 mysqld-bin.000001	#	Table_map	2	#	table_id: # (test.t2)
 mysqld-bin.000001	#	Table_map	2	#	table_id: # (mysql.ndb_apply_status)

=== modified file 'mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result'
--- a/mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result	2009-02-01 21:05:19 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result	2009-09-11 10:34:36 +0000
@@ -53,10 +53,10 @@ use mysqltest;
 insert into t2 values (1,1);
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-mysqld-bin.000001	#	Query	1	#	use `mysqltest`; drop table `mysqltest`.`t1`
-mysqld-bin.000001	#	Query	1	#	use `mysqltest`; drop table `mysqltest`.`t2`
-mysqld-bin.000001	#	Query	1	#	use `mysqltest`; create table t1 (d int key, e int) engine=ndb
-mysqld-bin.000001	#	Query	1	#	use `mysqltest`; create table t2 (d int key, e int) engine=ndb
+mysqld-bin.000001	#	Query	2	#	use `mysqltest`; drop table `mysqltest`.`t1`
+mysqld-bin.000001	#	Query	2	#	use `mysqltest`; drop table `mysqltest`.`t2`
+mysqld-bin.000001	#	Query	2	#	use `mysqltest`; create table t1 (d int key, e int) engine=ndb
+mysqld-bin.000001	#	Query	2	#	use `mysqltest`; create table t2 (d int key, e int) engine=ndb
 mysqld-bin.000001	#	Query	2	#	BEGIN
 mysqld-bin.000001	#	Table_map	2	#	table_id: # (mysqltest.t1)
 mysqld-bin.000001	#	Table_map	2	#	table_id: # (mysql.ndb_apply_status)

=== modified file 'mysql-test/suite/ndb_binlog/r/ndb_binlog_multi.result'
--- a/mysql-test/suite/ndb_binlog/r/ndb_binlog_multi.result	2009-02-01 21:05:19 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_multi.result	2009-09-11 10:34:36 +0000
@@ -30,7 +30,7 @@ a	b
 DROP TABLE t2;
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-mysqld-bin.000001	#	Query	2	#	use `test`; CREATE TABLE t2 (a INT PRIMARY KEY, b int) ENGINE = NDB
+mysqld-bin.000001	#	Query	1	#	use `test`; CREATE TABLE t2 (a INT PRIMARY KEY, b int) ENGINE = NDB
 mysqld-bin.000001	#	Query	1	#	BEGIN
 mysqld-bin.000001	#	Table_map	1	#	table_id: # (test.t2)
 mysqld-bin.000001	#	Table_map	1	#	table_id: # (mysql.ndb_apply_status)

=== modified file 'mysql-test/suite/rpl_ndb/r/rpl_ndb_circular.result'
--- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_circular.result	2009-02-11 10:27:14 +0000
+++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_circular.result	2009-09-11 15:44:36 +0000
@@ -57,6 +57,31 @@ Last_IO_Error	#
 Last_SQL_Errno	0
 Last_SQL_Error	
 Master_Bind	
+Slave Binlog contains all ops as log_slave_updates is on
+show variables like 'server_id';
+Variable_name	Value
+server_id	2
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	ON
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	ON
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-bin.000001	#	Query	2	#	use `test`; CREATE TABLE t1 (a int key, b int) ENGINE=ndb
+slave-bin.000001	#	Query	2	#	BEGIN
+slave-bin.000001	#	Table_map	2	#	table_id: # (test.t1)
+slave-bin.000001	#	Table_map	2	#	table_id: # (mysql.ndb_apply_status)
+slave-bin.000001	#	Write_rows	2	#	table_id: #
+slave-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+slave-bin.000001	#	Query	2	#	COMMIT
+slave-bin.000001	#	Query	2	#	BEGIN
+slave-bin.000001	#	Table_map	2	#	table_id: # (test.t1)
+slave-bin.000001	#	Table_map	2	#	table_id: # (mysql.ndb_apply_status)
+slave-bin.000001	#	Write_rows	2	#	table_id: #
+slave-bin.000001	#	Write_rows	2	#	table_id: # flags: STMT_END_F
+slave-bin.000001	#	Query	2	#	COMMIT
 SELECT * FROM t1 ORDER BY a;
 a	b
 1	2
@@ -101,5 +126,23 @@ Last_IO_Error	#
 Last_SQL_Errno	0
 Last_SQL_Error	
 Master_Bind	
+Master Binlog contains only Master ops as log_slave_updates is off
+show variables like 'server_id';
+Variable_name	Value
+server_id	1
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	ON
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	OFF
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	1	#	BEGIN
+master-bin.000001	#	Table_map	1	#	table_id: # (test.t1)
+master-bin.000001	#	Table_map	1	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	1	#	table_id: #
+master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	1	#	COMMIT
 STOP SLAVE;
 DROP TABLE t1;

=== added file 'mysql-test/suite/rpl_ndb/r/rpl_ndb_slave_lsu.result'
--- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_slave_lsu.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_slave_lsu.result	2009-09-16 16:04:14 +0000
@@ -0,0 +1,808 @@
+*** Configuring connections ***
+STOP SLAVE;
+*** Waiting for each cluster to startup ***
+*** Configuring replication via Slave ***
+RESET SLAVE;
+CHANGE MASTER TO MASTER_HOST="127.0.0.1",MASTER_PORT=MASTER_PORT,MASTER_USER="root";;
+START SLAVE;
+*** Generating slave cluster originated binloggable changes ***
+CREATE TABLE bug_45756_slave_logged_1 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_logged_1 VALUES (1);
+DROP TABLE bug_45756_slave_logged_1;
+CREATE TABLE bug_45756_slave_logged_2 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_logged_2 VALUES (1);
+DROP TABLE bug_45756_slave_logged_2;
+CREATE TABLE bug_45756_slave_logged_3 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_logged_3 VALUES (1);
+DROP TABLE bug_45756_slave_logged_3;
+***Generating slave cluster non-binloggable changes***
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug_45756_slave_not_logged_1 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_not_logged_1 VALUES (1);
+DROP TABLE bug_45756_slave_not_logged_1;
+SET SQL_LOG_BIN= 1;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug_45756_slave_not_logged_2 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_not_logged_2 VALUES (1);
+DROP TABLE bug_45756_slave_not_logged_2;
+SET SQL_LOG_BIN= 1;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug_45756_slave_not_logged_3 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_not_logged_3 VALUES (1);
+DROP TABLE bug_45756_slave_not_logged_3;
+SET SQL_LOG_BIN= 1;
+*** Generating data to be replicated ***
+CREATE TABLE bug45756_master_logged_1 (a int) engine = NDB;
+INSERT INTO bug45756_master_logged_1 VALUES (1);
+DROP TABLE bug45756_master_logged_1;
+CREATE TABLE bug45756_master_logged_2 (a int) engine = NDB;
+INSERT INTO bug45756_master_logged_2 VALUES (1);
+DROP TABLE bug45756_master_logged_2;
+CREATE TABLE bug45756_master_logged_3 (a int) engine = NDB;
+INSERT INTO bug45756_master_logged_3 VALUES (1);
+DROP TABLE bug45756_master_logged_3;
+*** Generating changes not to be replicated ***
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug45756_master_not_logged_1 (a int) engine = NDB;
+INSERT INTO bug45756_master_not_logged_1 VALUES (1);
+DROP TABLE bug45756_master_not_logged_1;
+SET SQL_LOG_BIN= 1;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug45756_master_not_logged_2 (a int) engine = NDB;
+INSERT INTO bug45756_master_not_logged_2 VALUES (1);
+DROP TABLE bug45756_master_not_logged_2;
+SET SQL_LOG_BIN= 1;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug45756_master_not_logged_3 (a int) engine = NDB;
+INSERT INTO bug45756_master_not_logged_3 VALUES (1);
+DROP TABLE bug45756_master_not_logged_3;
+SET SQL_LOG_BIN= 1;
+*** Checking binlog contents on every server in both clusters ***
+
+
+
+connection srv_master;
+show variables like 'server_id';
+Variable_name	Value
+server_id	1
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	ON
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	OFF
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	1	#	use `test`; CREATE TABLE bug45756_master_logged_1 (a int) engine = NDB
+master-bin.000001	#	Query	1	#	BEGIN
+master-bin.000001	#	Table_map	1	#	table_id: # (test.bug45756_master_logged_1)
+master-bin.000001	#	Table_map	1	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	1	#	table_id: #
+master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	1	#	COMMIT
+master-bin.000001	#	Query	1	#	use `test`; DROP TABLE bug45756_master_logged_1
+master-bin.000001	#	Query	1	#	use `test`; CREATE TABLE bug45756_master_logged_2 (a int) engine = NDB
+master-bin.000001	#	Query	1	#	BEGIN
+master-bin.000001	#	Table_map	1	#	table_id: # (test.bug45756_master_logged_2)
+master-bin.000001	#	Table_map	1	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	1	#	table_id: #
+master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	1	#	COMMIT
+master-bin.000001	#	Query	1	#	use `test`; drop table `test`.`bug45756_master_logged_2`
+master-bin.000001	#	Query	1	#	use `test`; CREATE TABLE bug45756_master_logged_3 (a int) engine = NDB
+master-bin.000001	#	Query	1	#	BEGIN
+master-bin.000001	#	Table_map	1	#	table_id: # (test.bug45756_master_logged_3)
+master-bin.000001	#	Table_map	1	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	1	#	table_id: #
+master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	1	#	COMMIT
+master-bin.000001	#	Query	1	#	use `test`; drop table `test`.`bug45756_master_logged_3`
+
+
+
+connection srv_master1;
+show variables like 'server_id';
+Variable_name	Value
+server_id	2
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	OFF
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	OFF
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+
+
+
+connection srv_master2;
+show variables like 'server_id';
+Variable_name	Value
+server_id	3
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	ON
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	OFF
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	3	#	use `test`; CREATE TABLE bug45756_master_logged_1 (a int) engine = NDB
+master-bin.000001	#	Query	3	#	BEGIN
+master-bin.000001	#	Table_map	3	#	table_id: # (test.bug45756_master_logged_1)
+master-bin.000001	#	Table_map	3	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	3	#	table_id: #
+master-bin.000001	#	Write_rows	3	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	3	#	COMMIT
+master-bin.000001	#	Query	3	#	use `test`; drop table `test`.`bug45756_master_logged_1`
+master-bin.000001	#	Query	3	#	use `test`; CREATE TABLE bug45756_master_logged_2 (a int) engine = NDB
+master-bin.000001	#	Query	3	#	BEGIN
+master-bin.000001	#	Table_map	3	#	table_id: # (test.bug45756_master_logged_2)
+master-bin.000001	#	Table_map	3	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	3	#	table_id: #

+master-bin.000001	#	Write_rows	3	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	3	#	COMMIT
+master-bin.000001	#	Query	3	#	use `test`; drop table `test`.`bug45756_master_logged_2`
+master-bin.000001	#	Query	3	#	use `test`; CREATE TABLE bug45756_master_logged_3 (a int) engine = NDB
+master-bin.000001	#	Query	3	#	BEGIN
+master-bin.000001	#	Table_map	3	#	table_id: # (test.bug45756_master_logged_3)
+master-bin.000001	#	Table_map	3	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	3	#	table_id: #
+master-bin.000001	#	Write_rows	3	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	3	#	COMMIT
+master-bin.000001	#	Query	3	#	use `test`; DROP TABLE bug45756_master_logged_3
+
+
+
+connection srv_slave;
+show variables like 'server_id';
+Variable_name	Value
+server_id	4
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	OFF
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	OFF
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+
+
+
+connection srv_slave1;
+show variables like 'server_id';
+Variable_name	Value
+server_id	5
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	ON
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	OFF
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-master-bin.000001	#	Query	5	#	use `test`; CREATE TABLE bug_45756_slave_logged_1 (a int) engine = NDB
+slave-master-bin.000001	#	Query	5	#	BEGIN
+slave-master-bin.000001	#	Table_map	5	#	table_id: # (test.bug_45756_slave_logged_1)
+slave-master-bin.000001	#	Table_map	5	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	5	#	table_id: #
+slave-master-bin.000001	#	Write_rows	5	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	5	#	COMMIT
+slave-master-bin.000001	#	Query	5	#	use `test`; drop table `test`.`bug_45756_slave_logged_1`
+slave-master-bin.000001	#	Query	5	#	use `test`; CREATE TABLE bug_45756_slave_logged_2 (a int) engine = NDB
+slave-master-bin.000001	#	Query	5	#	BEGIN
+slave-master-bin.000001	#	Table_map	5	#	table_id: # (test.bug_45756_slave_logged_2)
+slave-master-bin.000001	#	Table_map	5	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	5	#	table_id: #
+slave-master-bin.000001	#	Write_rows	5	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	5	#	COMMIT
+slave-master-bin.000001	#	Query	5	#	use `test`; DROP TABLE bug_45756_slave_logged_2
+slave-master-bin.000001	#	Query	5	#	use `test`; CREATE TABLE bug_45756_slave_logged_3 (a int) engine = NDB
+slave-master-bin.000001	#	Query	5	#	BEGIN
+slave-master-bin.000001	#	Table_map	5	#	table_id: # (test.bug_45756_slave_logged_3)
+slave-master-bin.000001	#	Table_map	5	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	5	#	table_id: #
+slave-master-bin.000001	#	Write_rows	5	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	5	#	COMMIT
+slave-master-bin.000001	#	Query	5	#	use `test`; drop table `test`.`bug_45756_slave_logged_3`
+
+
+
+connection srv_slave2;
+show variables like 'server_id';
+Variable_name	Value
+server_id	6
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	ON
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	ON
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-master-bin.000001	#	Query	6	#	use `test`; CREATE TABLE bug_45756_slave_logged_1 (a int) engine = NDB
+slave-master-bin.000001	#	Query	6	#	BEGIN
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (test.bug_45756_slave_logged_1)
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	6	#	table_id: #
+slave-master-bin.000001	#	Write_rows	6	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	6	#	COMMIT
+slave-master-bin.000001	#	Query	6	#	use `test`; drop table `test`.`bug_45756_slave_logged_1`
+slave-master-bin.000001	#	Query	6	#	use `test`; CREATE TABLE bug_45756_slave_logged_2 (a int) engine = NDB
+slave-master-bin.000001	#	Query	6	#	BEGIN
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (test.bug_45756_slave_logged_2)
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	6	#	table_id: #
+slave-master-bin.000001	#	Write_rows	6	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	6	#	COMMIT
+slave-master-bin.000001	#	Query	6	#	use `test`; drop table `test`.`bug_45756_slave_logged_2`
+slave-master-bin.000001	#	Query	6	#	use `test`; CREATE TABLE bug_45756_slave_logged_3 (a int) engine = NDB
+slave-master-bin.000001	#	Query	6	#	BEGIN
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (test.bug_45756_slave_logged_3)
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	6	#	table_id: #

+slave-master-bin.000001	#	Write_rows	6	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	6	#	COMMIT
+slave-master-bin.000001	#	Query	6	#	use `test`; DROP TABLE bug_45756_slave_logged_3
+slave-master-bin.000001	#	Query	1	#	use `test`; CREATE TABLE bug45756_master_logged_1 (a int) engine = NDB
+slave-master-bin.000001	#	Query	6	#	BEGIN
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (test.bug45756_master_logged_1)
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	6	#	table_id: #
+slave-master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	6	#	COMMIT
+slave-master-bin.000001	#	Query	1	#	use `test`; drop table `test`.`bug45756_master_logged_1`
+slave-master-bin.000001	#	Query	1	#	use `test`; CREATE TABLE bug45756_master_logged_2 (a int) engine = NDB
+slave-master-bin.000001	#	Query	6	#	BEGIN
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (test.bug45756_master_logged_2)
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	6	#	table_id: #
+slave-master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	6	#	COMMIT
+slave-master-bin.000001	#	Query	1	#	use `test`; drop table `test`.`bug45756_master_logged_2`
+slave-master-bin.000001	#	Query	1	#	use `test`; CREATE TABLE bug45756_master_logged_3 (a int) engine = NDB
+slave-master-bin.000001	#	Query	6	#	BEGIN
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (test.bug45756_master_logged_3)
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	6	#	table_id: #
+slave-master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	6	#	COMMIT
+slave-master-bin.000001	#	Query	1	#	use `test`; drop table `test`.`bug45756_master_logged_3`
+*** Configuring replication via Slave1 ***
+STOP SLAVE;
+STOP SLAVE;
+RESET SLAVE;
+CHANGE MASTER TO MASTER_HOST="127.0.0.1",MASTER_PORT=MASTER_PORT,MASTER_USER="root";
+START SLAVE;
+*** Generating slave cluster originated binloggable changes ***
+CREATE TABLE bug_45756_slave_logged_1 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_logged_1 VALUES (1);
+DROP TABLE bug_45756_slave_logged_1;
+CREATE TABLE bug_45756_slave_logged_2 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_logged_2 VALUES (1);
+DROP TABLE bug_45756_slave_logged_2;
+CREATE TABLE bug_45756_slave_logged_3 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_logged_3 VALUES (1);
+DROP TABLE bug_45756_slave_logged_3;
+***Generating slave cluster non-binloggable changes***
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug_45756_slave_not_logged_1 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_not_logged_1 VALUES (1);
+DROP TABLE bug_45756_slave_not_logged_1;
+SET SQL_LOG_BIN= 1;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug_45756_slave_not_logged_2 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_not_logged_2 VALUES (1);
+DROP TABLE bug_45756_slave_not_logged_2;
+SET SQL_LOG_BIN= 1;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug_45756_slave_not_logged_3 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_not_logged_3 VALUES (1);
+DROP TABLE bug_45756_slave_not_logged_3;
+SET SQL_LOG_BIN= 1;
+*** Generating data to be replicated ***
+CREATE TABLE bug45756_master_logged_1 (a int) engine = NDB;
+INSERT INTO bug45756_master_logged_1 VALUES (1);
+DROP TABLE bug45756_master_logged_1;
+CREATE TABLE bug45756_master_logged_2 (a int) engine = NDB;
+INSERT INTO bug45756_master_logged_2 VALUES (1);
+DROP TABLE bug45756_master_logged_2;
+CREATE TABLE bug45756_master_logged_3 (a int) engine = NDB;
+INSERT INTO bug45756_master_logged_3 VALUES (1);
+DROP TABLE bug45756_master_logged_3;
+*** Generating changes not to be replicated ***
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug45756_master_not_logged_1 (a int) engine = NDB;
+INSERT INTO bug45756_master_not_logged_1 VALUES (1);
+DROP TABLE bug45756_master_not_logged_1;
+SET SQL_LOG_BIN= 1;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug45756_master_not_logged_2 (a int) engine = NDB;
+INSERT INTO bug45756_master_not_logged_2 VALUES (1);
+DROP TABLE bug45756_master_not_logged_2;
+SET SQL_LOG_BIN= 1;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug45756_master_not_logged_3 (a int) engine = NDB;
+INSERT INTO bug45756_master_not_logged_3 VALUES (1);
+DROP TABLE bug45756_master_not_logged_3;
+SET SQL_LOG_BIN= 1;
+*** Checking binlog contents on every server in both clusters ***
+
+
+
+connection srv_master;
+show variables like 'server_id';
+Variable_name	Value
+server_id	1
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	ON
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	OFF
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	1	#	use `test`; CREATE TABLE bug45756_master_logged_1 (a int) engine = NDB
+master-bin.000001	#	Query	1	#	BEGIN
+master-bin.000001	#	Table_map	1	#	table_id: # (test.bug45756_master_logged_1)
+master-bin.000001	#	Table_map	1	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	1	#	table_id: #
+master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	1	#	COMMIT
+master-bin.000001	#	Query	1	#	use `test`; DROP TABLE bug45756_master_logged_1
+master-bin.000001	#	Query	1	#	use `test`; CREATE TABLE bug45756_master_logged_2 (a int) engine = NDB
+master-bin.000001	#	Query	1	#	BEGIN
+master-bin.000001	#	Table_map	1	#	table_id: # (test.bug45756_master_logged_2)
+master-bin.000001	#	Table_map	1	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	1	#	table_id: #
+master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	1	#	COMMIT
+master-bin.000001	#	Query	1	#	use `test`; drop table `test`.`bug45756_master_logged_2`
+master-bin.000001	#	Query	1	#	use `test`; CREATE TABLE bug45756_master_logged_3 (a int) engine = NDB
+master-bin.000001	#	Query	1	#	BEGIN
+master-bin.000001	#	Table_map	1	#	table_id: # (test.bug45756_master_logged_3)
+master-bin.000001	#	Table_map	1	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	1	#	table_id: #
+master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	1	#	COMMIT
+master-bin.000001	#	Query	1	#	use `test`; drop table `test`.`bug45756_master_logged_3`
+
+
+
+connection srv_master1;
+show variables like 'server_id';
+Variable_name	Value
+server_id	2
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	OFF
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	OFF
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+
+
+
+connection srv_master2;
+show variables like 'server_id';
+Variable_name	Value
+server_id	3
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	ON
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	OFF
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	3	#	use `test`; CREATE TABLE bug45756_master_logged_1 (a int) engine = NDB
+master-bin.000001	#	Query	3	#	BEGIN
+master-bin.000001	#	Table_map	3	#	table_id: # (test.bug45756_master_logged_1)
+master-bin.000001	#	Table_map	3	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	3	#	table_id: #
+master-bin.000001	#	Write_rows	3	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	3	#	COMMIT
+master-bin.000001	#	Query	3	#	use `test`; drop table `test`.`bug45756_master_logged_1`
+master-bin.000001	#	Query	3	#	use `test`; CREATE TABLE bug45756_master_logged_2 (a int) engine = NDB
+master-bin.000001	#	Query	3	#	BEGIN
+master-bin.000001	#	Table_map	3	#	table_id: # (test.bug45756_master_logged_2)
+master-bin.000001	#	Table_map	3	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	3	#	table_id: #
+master-bin.000001	#	Write_rows	3	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	3	#	COMMIT
+master-bin.000001	#	Query	3	#	use `test`; drop table `test`.`bug45756_master_logged_2`
+master-bin.000001	#	Query	3	#	use `test`; CREATE TABLE bug45756_master_logged_3 (a int) engine = NDB
+master-bin.000001	#	Query	3	#	BEGIN
+master-bin.000001	#	Table_map	3	#	table_id: # (test.bug45756_master_logged_3)
+master-bin.000001	#	Table_map	3	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	3	#	table_id: #
+master-bin.000001	#	Write_rows	3	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	3	#	COMMIT
+master-bin.000001	#	Query	3	#	use `test`; DROP TABLE bug45756_master_logged_3
+
+
+
+connection srv_slave;
+show variables like 'server_id';
+Variable_name	Value
+server_id	4
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	OFF
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	OFF
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+
+
+
+connection srv_slave1;
+show variables like 'server_id';
+Variable_name	Value
+server_id	5
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	ON
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	OFF
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-master-bin.000001	#	Query	5	#	use `test`; CREATE TABLE bug_45756_slave_logged_1 (a int) engine = NDB
+slave-master-bin.000001	#	Query	5	#	BEGIN
+slave-master-bin.000001	#	Table_map	5	#	table_id: # (test.bug_45756_slave_logged_1)
+slave-master-bin.000001	#	Table_map	5	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	5	#	table_id: #
+slave-master-bin.000001	#	Write_rows	5	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	5	#	COMMIT
+slave-master-bin.000001	#	Query	5	#	use `test`; drop table `test`.`bug_45756_slave_logged_1`
+slave-master-bin.000001	#	Query	5	#	use `test`; CREATE TABLE bug_45756_slave_logged_2 (a int) engine = NDB
+slave-master-bin.000001	#	Query	5	#	BEGIN
+slave-master-bin.000001	#	Table_map	5	#	table_id: # (test.bug_45756_slave_logged_2)
+slave-master-bin.000001	#	Table_map	5	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	5	#	table_id: #
+slave-master-bin.000001	#	Write_rows	5	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	5	#	COMMIT
+slave-master-bin.000001	#	Query	5	#	use `test`; DROP TABLE bug_45756_slave_logged_2
+slave-master-bin.000001	#	Query	5	#	use `test`; CREATE TABLE bug_45756_slave_logged_3 (a int) engine = NDB
+slave-master-bin.000001	#	Query	5	#	BEGIN
+slave-master-bin.000001	#	Table_map	5	#	table_id: # (test.bug_45756_slave_logged_3)
+slave-master-bin.000001	#	Table_map	5	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	5	#	table_id: #
+slave-master-bin.000001	#	Write_rows	5	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	5	#	COMMIT
+slave-master-bin.000001	#	Query	5	#	use `test`; drop table `test`.`bug_45756_slave_logged_3`
+
+
+
+connection srv_slave2;
+show variables like 'server_id';
+Variable_name	Value
+server_id	6
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	ON
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	ON
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-master-bin.000001	#	Query	6	#	use `test`; CREATE TABLE bug_45756_slave_logged_1 (a int) engine = NDB
+slave-master-bin.000001	#	Query	6	#	BEGIN
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (test.bug_45756_slave_logged_1)
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	6	#	table_id: #
+slave-master-bin.000001	#	Write_rows	6	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	6	#	COMMIT
+slave-master-bin.000001	#	Query	6	#	use `test`; drop table `test`.`bug_45756_slave_logged_1`
+slave-master-bin.000001	#	Query	6	#	use `test`; CREATE TABLE bug_45756_slave_logged_2 (a int) engine = NDB
+slave-master-bin.000001	#	Query	6	#	BEGIN
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (test.bug_45756_slave_logged_2)
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	6	#	table_id: #
+slave-master-bin.000001	#	Write_rows	6	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	6	#	COMMIT
+slave-master-bin.000001	#	Query	6	#	use `test`; drop table `test`.`bug_45756_slave_logged_2`
+slave-master-bin.000001	#	Query	6	#	use `test`; CREATE TABLE bug_45756_slave_logged_3 (a int) engine = NDB
+slave-master-bin.000001	#	Query	6	#	BEGIN
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (test.bug_45756_slave_logged_3)
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	6	#	table_id: #
+slave-master-bin.000001	#	Write_rows	6	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	6	#	COMMIT
+slave-master-bin.000001	#	Query	6	#	use `test`; DROP TABLE bug_45756_slave_logged_3
+slave-master-bin.000001	#	Query	1	#	use `test`; CREATE TABLE bug45756_master_logged_1 (a int) engine = NDB
+slave-master-bin.000001	#	Query	6	#	BEGIN
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (test.bug45756_master_logged_1)
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	6	#	table_id: #
+slave-master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	6	#	COMMIT
+slave-master-bin.000001	#	Query	1	#	use `test`; drop table `test`.`bug45756_master_logged_1`
+slave-master-bin.000001	#	Query	1	#	use `test`; CREATE TABLE bug45756_master_logged_2 (a int) engine = NDB
+slave-master-bin.000001	#	Query	6	#	BEGIN
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (test.bug45756_master_logged_2)
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	6	#	table_id: #
+slave-master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	6	#	COMMIT
+slave-master-bin.000001	#	Query	1	#	use `test`; drop table `test`.`bug45756_master_logged_2`
+slave-master-bin.000001	#	Query	1	#	use `test`; CREATE TABLE bug45756_master_logged_3 (a int) engine = NDB
+slave-master-bin.000001	#	Query	6	#	BEGIN
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (test.bug45756_master_logged_3)
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	6	#	table_id: #
+slave-master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	6	#	COMMIT
+slave-master-bin.000001	#	Query	1	#	use `test`; drop table `test`.`bug45756_master_logged_3`
+*** Configuring replication via Slave2 ***
+STOP SLAVE;
+STOP SLAVE;
+RESET SLAVE;
+CHANGE MASTER TO MASTER_HOST="127.0.0.1",MASTER_PORT=MASTER_PORT,MASTER_USER="root";;
+START SLAVE;
+*** Generating slave cluster originated binloggable changes ***
+CREATE TABLE bug_45756_slave_logged_1 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_logged_1 VALUES (1);
+DROP TABLE bug_45756_slave_logged_1;
+CREATE TABLE bug_45756_slave_logged_2 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_logged_2 VALUES (1);
+DROP TABLE bug_45756_slave_logged_2;
+CREATE TABLE bug_45756_slave_logged_3 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_logged_3 VALUES (1);
+DROP TABLE bug_45756_slave_logged_3;
+***Generating slave cluster non-binloggable changes***
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug_45756_slave_not_logged_1 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_not_logged_1 VALUES (1);
+DROP TABLE bug_45756_slave_not_logged_1;
+SET SQL_LOG_BIN= 1;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug_45756_slave_not_logged_2 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_not_logged_2 VALUES (1);
+DROP TABLE bug_45756_slave_not_logged_2;
+SET SQL_LOG_BIN= 1;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug_45756_slave_not_logged_3 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_not_logged_3 VALUES (1);
+DROP TABLE bug_45756_slave_not_logged_3;
+SET SQL_LOG_BIN= 1;
+*** Generating data to be replicated ***
+CREATE TABLE bug45756_master_logged_1 (a int) engine = NDB;
+INSERT INTO bug45756_master_logged_1 VALUES (1);
+DROP TABLE bug45756_master_logged_1;
+CREATE TABLE bug45756_master_logged_2 (a int) engine = NDB;
+INSERT INTO bug45756_master_logged_2 VALUES (1);
+DROP TABLE bug45756_master_logged_2;
+CREATE TABLE bug45756_master_logged_3 (a int) engine = NDB;
+INSERT INTO bug45756_master_logged_3 VALUES (1);
+DROP TABLE bug45756_master_logged_3;
+*** Generating changes not to be replicated ***
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug45756_master_not_logged_1 (a int) engine = NDB;
+INSERT INTO bug45756_master_not_logged_1 VALUES (1);
+DROP TABLE bug45756_master_not_logged_1;
+SET SQL_LOG_BIN= 1;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug45756_master_not_logged_2 (a int) engine = NDB;
+INSERT INTO bug45756_master_not_logged_2 VALUES (1);
+DROP TABLE bug45756_master_not_logged_2;
+SET SQL_LOG_BIN= 1;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug45756_master_not_logged_3 (a int) engine = NDB;
+INSERT INTO bug45756_master_not_logged_3 VALUES (1);
+DROP TABLE bug45756_master_not_logged_3;
+SET SQL_LOG_BIN= 1;
+*** Checking binlog contents on every server in both clusters ***
+
+
+
+connection srv_master;
+show variables like 'server_id';
+Variable_name	Value
+server_id	1
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	ON
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	OFF
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	1	#	use `test`; CREATE TABLE bug45756_master_logged_1 (a int) engine = NDB
+master-bin.000001	#	Query	1	#	BEGIN
+master-bin.000001	#	Table_map	1	#	table_id: # (test.bug45756_master_logged_1)
+master-bin.000001	#	Table_map	1	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	1	#	table_id: #
+master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	1	#	COMMIT
+master-bin.000001	#	Query	1	#	use `test`; DROP TABLE bug45756_master_logged_1
+master-bin.000001	#	Query	1	#	use `test`; CREATE TABLE bug45756_master_logged_2 (a int) engine = NDB
+master-bin.000001	#	Query	1	#	BEGIN
+master-bin.000001	#	Table_map	1	#	table_id: # (test.bug45756_master_logged_2)
+master-bin.000001	#	Table_map	1	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	1	#	table_id: #
+master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	1	#	COMMIT
+master-bin.000001	#	Query	1	#	use `test`; drop table `test`.`bug45756_master_logged_2`
+master-bin.000001	#	Query	1	#	use `test`; CREATE TABLE bug45756_master_logged_3 (a int) engine = NDB
+master-bin.000001	#	Query	1	#	BEGIN
+master-bin.000001	#	Table_map	1	#	table_id: # (test.bug45756_master_logged_3)
+master-bin.000001	#	Table_map	1	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	1	#	table_id: #
+master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	1	#	COMMIT
+master-bin.000001	#	Query	1	#	use `test`; drop table `test`.`bug45756_master_logged_3`
+
+
+
+connection srv_master1;
+show variables like 'server_id';
+Variable_name	Value
+server_id	2
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	OFF
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	OFF
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+
+
+
+connection srv_master2;
+show variables like 'server_id';
+Variable_name	Value
+server_id	3
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	ON
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	OFF
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	3	#	use `test`; CREATE TABLE bug45756_master_logged_1 (a int) engine = NDB
+master-bin.000001	#	Query	3	#	BEGIN
+master-bin.000001	#	Table_map	3	#	table_id: # (test.bug45756_master_logged_1)
+master-bin.000001	#	Table_map	3	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	3	#	table_id: #
+master-bin.000001	#	Write_rows	3	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	3	#	COMMIT
+master-bin.000001	#	Query	3	#	use `test`; drop table `test`.`bug45756_master_logged_1`
+master-bin.000001	#	Query	3	#	use `test`; CREATE TABLE bug45756_master_logged_2 (a int) engine = NDB
+master-bin.000001	#	Query	3	#	BEGIN
+master-bin.000001	#	Table_map	3	#	table_id: # (test.bug45756_master_logged_2)
+master-bin.000001	#	Table_map	3	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	3	#	table_id: #
+master-bin.000001	#	Write_rows	3	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	3	#	COMMIT
+master-bin.000001	#	Query	3	#	use `test`; drop table `test`.`bug45756_master_logged_2`
+master-bin.000001	#	Query	3	#	use `test`; CREATE TABLE bug45756_master_logged_3 (a int) engine = NDB
+master-bin.000001	#	Query	3	#	BEGIN
+master-bin.000001	#	Table_map	3	#	table_id: # (test.bug45756_master_logged_3)
+master-bin.000001	#	Table_map	3	#	table_id: # (mysql.ndb_apply_status)
+master-bin.000001	#	Write_rows	3	#	table_id: #
+master-bin.000001	#	Write_rows	3	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	3	#	COMMIT
+master-bin.000001	#	Query	3	#	use `test`; DROP TABLE bug45756_master_logged_3
+
+
+
+connection srv_slave;
+show variables like 'server_id';
+Variable_name	Value
+server_id	4
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	OFF
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	OFF
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+
+
+
+connection srv_slave1;
+show variables like 'server_id';
+Variable_name	Value
+server_id	5
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	ON
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	OFF
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-master-bin.000001	#	Query	5	#	use `test`; CREATE TABLE bug_45756_slave_logged_1 (a int) engine = NDB
+slave-master-bin.000001	#	Query	5	#	BEGIN
+slave-master-bin.000001	#	Table_map	5	#	table_id: # (test.bug_45756_slave_logged_1)
+slave-master-bin.000001	#	Table_map	5	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	5	#	table_id: #
+slave-master-bin.000001	#	Write_rows	5	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	5	#	COMMIT
+slave-master-bin.000001	#	Query	5	#	use `test`; drop table `test`.`bug_45756_slave_logged_1`
+slave-master-bin.000001	#	Query	5	#	use `test`; CREATE TABLE bug_45756_slave_logged_2 (a int) engine = NDB
+slave-master-bin.000001	#	Query	5	#	BEGIN
+slave-master-bin.000001	#	Table_map	5	#	table_id: # (test.bug_45756_slave_logged_2)
+slave-master-bin.000001	#	Table_map	5	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	5	#	table_id: #
+slave-master-bin.000001	#	Write_rows	5	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	5	#	COMMIT
+slave-master-bin.000001	#	Query	5	#	use `test`; DROP TABLE bug_45756_slave_logged_2
+slave-master-bin.000001	#	Query	5	#	use `test`; CREATE TABLE bug_45756_slave_logged_3 (a int) engine = NDB
+slave-master-bin.000001	#	Query	5	#	BEGIN
+slave-master-bin.000001	#	Table_map	5	#	table_id: # (test.bug_45756_slave_logged_3)
+slave-master-bin.000001	#	Table_map	5	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	5	#	table_id: #
+slave-master-bin.000001	#	Write_rows	5	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	5	#	COMMIT
+slave-master-bin.000001	#	Query	5	#	use `test`; drop table `test`.`bug_45756_slave_logged_3`
+
+
+
+connection srv_slave2;
+show variables like 'server_id';
+Variable_name	Value
+server_id	6
+show variables like 'log_bin';
+Variable_name	Value
+log_bin	ON
+show variables like 'log_slave_updates';
+Variable_name	Value
+log_slave_updates	ON
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-master-bin.000001	#	Query	6	#	use `test`; CREATE TABLE bug_45756_slave_logged_1 (a int) engine = NDB
+slave-master-bin.000001	#	Query	6	#	BEGIN
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (test.bug_45756_slave_logged_1)
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	6	#	table_id: #
+slave-master-bin.000001	#	Write_rows	6	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	6	#	COMMIT
+slave-master-bin.000001	#	Query	6	#	use `test`; drop table `test`.`bug_45756_slave_logged_1`
+slave-master-bin.000001	#	Query	6	#	use `test`; CREATE TABLE bug_45756_slave_logged_2 (a int) engine = NDB
+slave-master-bin.000001	#	Query	6	#	BEGIN
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (test.bug_45756_slave_logged_2)
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	6	#	table_id: #
+slave-master-bin.000001	#	Write_rows	6	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	6	#	COMMIT
+slave-master-bin.000001	#	Query	6	#	use `test`; drop table `test`.`bug_45756_slave_logged_2`
+slave-master-bin.000001	#	Query	6	#	use `test`; CREATE TABLE bug_45756_slave_logged_3 (a int) engine = NDB
+slave-master-bin.000001	#	Query	6	#	BEGIN
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (test.bug_45756_slave_logged_3)
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	6	#	table_id: #
+slave-master-bin.000001	#	Write_rows	6	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	6	#	COMMIT
+slave-master-bin.000001	#	Query	6	#	use `test`; DROP TABLE bug_45756_slave_logged_3
+slave-master-bin.000001	#	Query	1	#	use `test`; CREATE TABLE bug45756_master_logged_1 (a int) engine = NDB
+slave-master-bin.000001	#	Query	6	#	BEGIN
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (test.bug45756_master_logged_1)
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	6	#	table_id: #
+slave-master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	6	#	COMMIT
+slave-master-bin.000001	#	Query	1	#	use `test`; DROP TABLE bug45756_master_logged_1
+slave-master-bin.000001	#	Query	1	#	use `test`; CREATE TABLE bug45756_master_logged_2 (a int) engine = NDB
+slave-master-bin.000001	#	Query	6	#	BEGIN
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (test.bug45756_master_logged_2)
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	6	#	table_id: #
+slave-master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	6	#	COMMIT
+slave-master-bin.000001	#	Query	1	#	use `test`; drop table `test`.`bug45756_master_logged_2`
+slave-master-bin.000001	#	Query	1	#	use `test`; CREATE TABLE bug45756_master_logged_3 (a int) engine = NDB
+slave-master-bin.000001	#	Query	6	#	BEGIN
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (test.bug45756_master_logged_3)
+slave-master-bin.000001	#	Table_map	6	#	table_id: # (mysql.ndb_apply_status)
+slave-master-bin.000001	#	Write_rows	6	#	table_id: #
+slave-master-bin.000001	#	Write_rows	1	#	table_id: # flags: STMT_END_F
+slave-master-bin.000001	#	Query	6	#	COMMIT
+slave-master-bin.000001	#	Query	1	#	use `test`; drop table `test`.`bug45756_master_logged_3`

=== modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_circular.test'
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_circular.test	2008-03-14 14:42:27 +0000
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_circular.test	2009-09-11 15:39:22 +0000
@@ -25,6 +25,8 @@ SHOW TABLES;
 # insert some values on the slave and master
 --connection master
 INSERT INTO t1 VALUES (1,2);
+# Give time to propagate + close epoch, to ensure deterministic Binlog contents
+--sleep 1
 --connection slave
 INSERT INTO t1 VALUES (2,3);
 
@@ -42,6 +44,13 @@ SELECT * FROM t1 ORDER BY a;
 # BUG#34654 Last_IO_Errno is not reset - Mask columns 35 and 36
 --replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # 35 # 36 #
 --query_vertical show slave status;
+
+--echo Slave Binlog contains all ops as log_slave_updates is on
+show variables like 'server_id';
+show variables like 'log_bin';
+show variables like 'log_slave_updates';
+--source include/show_binlog_events2.inc
+
 # connect to master and ensure data it there.
 --connection master
 SELECT * FROM t1 ORDER BY a;
@@ -50,6 +59,12 @@ SELECT * FROM t1 ORDER BY a;
 --replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # 35 # 36 #
 --query_vertical show slave status;
 
+--echo Master Binlog contains only Master ops as log_slave_updates is off
+show variables like 'server_id';
+show variables like 'log_bin';
+show variables like 'log_slave_updates';
+--source include/show_binlog_events2.inc
+
 # stop replication on "master" as not to replicate
 # shutdown circularly, eg drop table
 --connection master

=== modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_circular_2ch.cnf'
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_circular_2ch.cnf	2008-10-31 14:11:44 +0000
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_circular_2ch.cnf	2009-09-11 10:34:36 +0000
@@ -1,16 +1,27 @@
 !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
+# To support > 2 clusters and/or different server-ids per
+# MySQLD server, we need some other loop breaking 
+# mechanism 
+
 [mysqld.1.1]
 server-id= 1
 log-bin
+log-slave-updates
 
 [mysqld.2.1]
 server-id= 1
 log-bin
+log-slave-updates
 
 [mysqld.1.slave]
 server-id= 2
 log-bin
+log-slave-updates
 skip-slave-start
 
 [mysqld.2.slave]
@@ -22,6 +33,7 @@ master-user=		@mysqld.2.1.#user
 master-connect-retry=	1
 init-rpl-role=		slave
 log-bin
+log-slave-updates
 skip-slave-start
 ndb_connectstring=	@mysql_cluster.slave.ndb_connectstring
 

=== added file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_multi_binlog_update.cnf'
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_multi_binlog_update.cnf	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_multi_binlog_update.cnf	2009-09-16 16:04:14 +0000
@@ -0,0 +1,112 @@
+!include include/default_ndbd.cnf
+
+[cluster_config.1]
+# NoOfReplicas refers to NDBD nodes/nodegroup
+NoOfReplicas=                  2
+ndbd=,
+ndb_mgmd=
+# 3 MySQLDS attached to Cluster 1
+mysqld=,,                   
+
+
+
+[cluster_config.slave]
+# NoOfReplicas refers to NDBD nodes/nodegroup
+NoOfReplicas=                  2
+ndbd=,
+ndb_mgmd=
+# 3 MySQLDs attached to Cluster 2
+mysqld=,,
+
+
+
+[mysqld]
+open-files-limit=           1024
+local-infile
+default-character-set=      latin1
+connect-timeout=            60
+log-bin-trust-function-creators=1
+key_buffer_size=            1M
+sort_buffer=                256K
+max_heap_table_size=        1M
+loose-innodb_data_file_path=      ibdata1:10M:autoextend
+slave-net-timeout=120
+ndbcluster
+
+
+
+[mysqld.1.1]
+server-id= 1
+log-bin= master-bin
+binlog_format=row
+
+
+
+[mysqld.2.1]
+server-id= 2
+# Note no binary log
+
+
+
+[mysqld.3.1]
+server-id= 3
+log-bin= master-bin
+binlog_format=row
+
+
+
+[mysqld.1.slave]
+# Note no binlog on this slave
+server-id= 4
+init-rpl-role= slave
+skip-slave-start
+loose-skip-innodb
+slave-load-tmpdir= ../../../tmp
+ndb_connectstring= @mysql_cluster.slave.ndb_connectstring
+
+
+
+[mysqld.2.slave]
+# Note binlog on this slave, but not logging slave updates
+server-id= 5
+init-rpl-role= slave
+skip-slave-start
+loose-skip-innodb
+slave-load-tmpdir= ../../../tmp
+ndb_connectstring= @mysql_cluster.slave.ndb_connectstring
+log-bin= slave-master-bin
+binlog_format=row
+
+
+
+[mysqld.3.slave]
+# Note binlog on this slave, with slave updates logged
+server-id= 6
+init-rpl-role= slave
+skip-slave-start
+loose-skip-innodb
+slave-load-tmpdir= ../../../tmp
+ndb_connectstring= @mysql_cluster.slave.ndb_connectstring
+log-bin= slave-master-bin
+binlog_format=row
+log-slave-updates
+
+
+
+[ENV]
+MASTER_MYPORT= @mysqld.1.1.port
+MASTER_MYPORT1= @mysqld.2.1.port
+MASTER_MYSOCK1= @mysqld.2.1.socket
+MASTER_MYPORT2= @mysqld.3.1.port
+MASTER_MYSOCK2= @mysqld.3.1.socket
+SLAVE_MYPORT= @mysqld.1.slave.port
+SLAVE_MYSOCK= @mysqld.1.slave.socket
+SLAVE_MYPORT1= @mysqld.2.slave.port
+SLAVE_MYSOCK1= @mysqld.2.slave.socket
+SLAVE_MYPORT2= @mysqld.3.slave.port
+SLAVE_MYSOCK2= @mysqld.3.slave.socket
+
+
+NDB_CONNECTSTRING= @mysql_cluster.1.ndb_connectstring
+NDB_CONNECTSTRING_SLAVE= @mysql_cluster.slave.ndb_connectstring
+NDB_BACKUP_DIR= @cluster_config.ndbd.1.1.BackupDataDir

=== added file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_multi_binlog_update.inc'
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_multi_binlog_update.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_multi_binlog_update.inc	2009-09-16 16:04:14 +0000
@@ -0,0 +1,196 @@
+###############################################################################
+# Description: Performs binloggable and non binloggable DDL and DML at each
+#              MySQLD in pair of clusters with (at least) 3 MySQLDs each.
+#              Then connects to each MySQLD and examines the contents of
+#              its Binlog.
+#              Expected contents depends on the configuration of Binlogging
+#              in the cluster used.
+#              Default from rpl_ndb_multi_binlog_update.test is as shown
+#              below. 
+# 
+# Testing scenario: Cluster 1 replicates to Cluster 2
+#
+#  Key : BL= Binlogging, LSU = LogSlaveUpdates = On
+#
+#                       BL                        BL
+#  cluster 1 [  srv_master  srv_master1  srv_master2  ]
+#                   |
+#                   |-----------------------
+#                   v          v            v
+#  cluster 2 [  srv_slave  srv_slave1  srv_slave2 ]
+#                                  BL      BL LSU
+#
+#  Cluster 1:
+#  - Schema change originates on all severs in Cluster 1
+#  - MySQLD1 which is binlogging master. 
+#    Identification: connection (srv_master), config (mysqld.1.1).
+#  - MySQLD2 which is not binlogging.
+#    Identification: connection (srv_master1), config (mysqld.1.2).
+#  - MySQLD3 which is binlogging but not currently master.
+#    Identification: connection (srv_master2), config (mysqld.1.3).
+#
+#  Cluster 2:
+#  - MySQLD1: 
+#    Can act as slave, not binlogging
+#    Identification: connection (srv_slave), config (mysqld.1.slave).
+#  - MySQLD2: 
+#    Can act as slave, binlogging, log-slave-updates = off
+#    Identification: connection (srv_slave1), config (mysqld.2.slave).
+#  - MySQLD3 
+#    Can act as slave, binlogging, log-slave-updates = on
+#    Identification: connection (srv_slave2), config (mysqld.3.slave).
+#
+# See rpl_ndb_multi_binlog_update.test for default configuration.
+# Originally motivated by bug#45756
+# See rpl_ndb_slave_lsu.test for full testcase
+#
+# Preconditions :
+#   - Connections srv_master, srv_master1, srv_master2, srv_slave, 
+#     srv_slave1, srv_slave2 exist.
+#   - $which_slave contains the name of the slave server performing
+#     the replication slave role.
+#
+###############################################################################
+
+###############################################################################
+#                            Checking Replication
+###############################################################################
+--echo *** Generating slave cluster originated binloggable changes ***
+connection srv_slave;
+CREATE TABLE bug_45756_slave_logged_1 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_logged_1 VALUES (1);
+DROP TABLE bug_45756_slave_logged_1;
+
+connection srv_slave1;
+CREATE TABLE bug_45756_slave_logged_2 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_logged_2 VALUES (1);
+DROP TABLE bug_45756_slave_logged_2;
+
+connection srv_slave2;
+CREATE TABLE bug_45756_slave_logged_3 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_logged_3 VALUES (1);
+DROP TABLE bug_45756_slave_logged_3;
+
+--echo ***Generating slave cluster non-binloggable changes***
+connection srv_slave;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug_45756_slave_not_logged_1 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_not_logged_1 VALUES (1);
+DROP TABLE bug_45756_slave_not_logged_1;
+SET SQL_LOG_BIN= 1;
+
+connection srv_slave1;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug_45756_slave_not_logged_2 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_not_logged_2 VALUES (1);
+DROP TABLE bug_45756_slave_not_logged_2;
+SET SQL_LOG_BIN= 1;
+
+connection srv_slave2;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug_45756_slave_not_logged_3 (a int) engine = NDB;
+INSERT INTO bug_45756_slave_not_logged_3 VALUES (1);
+DROP TABLE bug_45756_slave_not_logged_3;
+SET SQL_LOG_BIN= 1;
+
+--echo *** Generating data to be replicated ***
+connection srv_master;
+CREATE TABLE bug45756_master_logged_1 (a int) engine = NDB;
+INSERT INTO bug45756_master_logged_1 VALUES (1);
+DROP TABLE bug45756_master_logged_1;
+
+connection srv_master1;
+CREATE TABLE bug45756_master_logged_2 (a int) engine = NDB;
+INSERT INTO bug45756_master_logged_2 VALUES (1);
+DROP TABLE bug45756_master_logged_2;
+
+connection srv_master2;
+CREATE TABLE bug45756_master_logged_3 (a int) engine = NDB;
+INSERT INTO bug45756_master_logged_3 VALUES (1);
+DROP TABLE bug45756_master_logged_3;
+
+--echo *** Generating changes not to be replicated ***
+connection srv_master;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug45756_master_not_logged_1 (a int) engine = NDB;
+INSERT INTO bug45756_master_not_logged_1 VALUES (1);
+DROP TABLE bug45756_master_not_logged_1;
+SET SQL_LOG_BIN= 1;
+
+connection srv_master1;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug45756_master_not_logged_2 (a int) engine = NDB;
+INSERT INTO bug45756_master_not_logged_2 VALUES (1);
+DROP TABLE bug45756_master_not_logged_2;
+SET SQL_LOG_BIN= 1;
+
+connection srv_master2;
+SET SQL_LOG_BIN= 0;
+CREATE TABLE bug45756_master_not_logged_3 (a int) engine = NDB;
+INSERT INTO bug45756_master_not_logged_3 VALUES (1);
+DROP TABLE bug45756_master_not_logged_3;
+SET SQL_LOG_BIN= 1;
+
+connection srv_master;
+sync_slave_with_master $which_slave;
+
+--echo *** Checking binlog contents on every server in both clusters ***
+connection srv_master;
+--echo 
+--echo 
+--echo 
+--echo connection srv_master;
+show variables like 'server_id';
+show variables like 'log_bin';
+show variables like 'log_slave_updates';
+--source include/show_binlog_events2.inc
+
+connection srv_master1;
+--echo 
+--echo 
+--echo 
+--echo connection srv_master1;
+show variables like 'server_id';
+show variables like 'log_bin';
+show variables like 'log_slave_updates';
+--source include/show_binlog_events2.inc
+
+connection srv_master2;
+--echo 
+--echo 
+--echo 
+--echo connection srv_master2;
+show variables like 'server_id';
+show variables like 'log_bin';
+show variables like 'log_slave_updates';
+--source include/show_binlog_events2.inc
+
+connection srv_slave;
+--echo 
+--echo 
+--echo 
+--echo connection srv_slave;
+show variables like 'server_id';
+show variables like 'log_bin';
+show variables like 'log_slave_updates';
+--source include/show_binlog_events2.inc
+
+connection srv_slave1;
+--echo 
+--echo 
+--echo 
+--echo connection srv_slave1;
+show variables like 'server_id';
+show variables like 'log_bin';
+show variables like 'log_slave_updates';
+--source include/show_binlog_events2.inc
+
+connection srv_slave2;
+--echo 
+--echo 
+--echo 
+--echo connection srv_slave2;
+show variables like 'server_id';
+show variables like 'log_bin';
+show variables like 'log_slave_updates';
+--source include/show_binlog_events2.inc

=== added file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_slave_lsu.cnf'
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_slave_lsu.cnf	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_slave_lsu.cnf	2009-09-16 16:04:14 +0000
@@ -0,0 +1 @@
+!include suite/rpl_ndb/t/rpl_ndb_multi_binlog_update.cnf

=== added file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_slave_lsu.test'
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_slave_lsu.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_slave_lsu.test	2009-09-16 16:04:14 +0000
@@ -0,0 +1,219 @@
+###############################################################################
+# Description: Checks if DDL and DML statements are correctly logged by
+#              servers and slave servers according to log-slave-updates,
+#              and independent of their settings on the particular MySQLD
+#              acting in the slave role
+#
+# Testing scenario: Cluster 1 replicates to Cluster 2
+#   Key : BL = log-bin, LSU = log-slave-updates
+#
+#                       BL                        BL
+#  cluster 1 [  srv_master  srv_master1  srv_master2  ]
+#                   |----------+------------
+#                   v          v           v
+#  cluster 2 [  srv_slave  srv_slave1  srv_slave2 ]
+#                                  BL     BL LSU  
+#
+#  - First replicate via srv_slave and check all nodes' Binlog contents
+#  - Second replicate via srv_slave1 and check all nodes' Binlog contents
+#  - Third replicate via srv_slave2 and check all nodes' Binlog contents
+#
+# Makes use of suite/rpl_ndb/t/rpl_ndb_multi_binlog_update.inc
+# Originally motivated by bug#45756
+###############################################################################
+
+--source include/have_ndb.inc
+--source include/have_log_bin.inc
+
+###############################################################################
+#                           Configuring Environment
+###############################################################################
+--echo *** Configuring connections ***
+
+connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,);
+connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT,);
+
+connect (srv_master,127.0.0.1,root,,test,$MASTER_MYPORT,);
+connect (srv_master1,127.0.0.1,root,,test,$MASTER_MYPORT1,);
+connect (srv_master2,127.0.0.1,root,,test,$MASTER_MYPORT2,);
+connect (srv_slave,127.0.0.1,root,,test,$SLAVE_MYPORT,);
+connect (srv_slave1,127.0.0.1,root,,test,$SLAVE_MYPORT1,);
+connect (srv_slave2,127.0.0.1,root,,test,$SLAVE_MYPORT2,);
+
+connection slave;
+--disable_warnings
+STOP SLAVE;
+source include/wait_for_slave_to_stop.inc;
+--enable_warnings
+
+--echo *** Waiting for each cluster to startup ***
+
+# Check schema op binlogging enabled between servers on cluster1
+--let $source_server=srv_master
+--let $dest_server=srv_master2
+source suite/rpl_ndb/t/rpl_ndb_wait_schema_logging.inc;
+
+--let $source_server=srv_master1
+--let $dest_server=srv_master
+source suite/rpl_ndb/t/rpl_ndb_wait_schema_logging.inc;
+
+--let $source_server=srv_master1
+--let $dest_server=srv_master2
+source suite/rpl_ndb/t/rpl_ndb_wait_schema_logging.inc;
+
+--let $source_server=srv_master2
+--let $dest_server=srv_master
+source suite/rpl_ndb/t/rpl_ndb_wait_schema_logging.inc;
+
+# Check schema op binlogging enabled between servers on cluster2
+--let $source_server=srv_slave
+--let $dest_server=srv_slave1
+source suite/rpl_ndb/t/rpl_ndb_wait_schema_logging.inc;
+
+--let $source_server=srv_slave
+--let $dest_server=srv_slave2
+source suite/rpl_ndb/t/rpl_ndb_wait_schema_logging.inc;
+
+--let $source_server=srv_slave1
+--let $dest_server=srv_slave2
+source suite/rpl_ndb/t/rpl_ndb_wait_schema_logging.inc;
+
+--let $source_server=srv_slave2
+--let $dest_server=srv_slave1
+source suite/rpl_ndb/t/rpl_ndb_wait_schema_logging.inc;
+
+# Reset state of all Binlogging nodes
+--disable_query_log
+connection master;
+--disable_warnings
+RESET MASTER;
+--enable_warnings
+
+connection srv_master2;
+--disable_warnings
+RESET MASTER;
+--enable_warnings
+
+connection srv_slave1;
+--disable_warnings
+RESET MASTER;
+--enable_warnings
+
+connection srv_slave2;
+--disable_warnings
+RESET MASTER;
+--enable_warnings
+--enable_query_log
+
+--echo *** Configuring replication via Slave ***
+connection slave;
+--disable_warnings
+RESET SLAVE;
+--replace_result $MASTER_MYPORT MASTER_PORT
+--eval CHANGE MASTER TO MASTER_HOST="127.0.0.1",MASTER_PORT=$MASTER_MYPORT,MASTER_USER="root";
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+--enable_warnings
+
+--let $which_slave=srv_slave
+--source suite/rpl_ndb/t/rpl_ndb_multi_binlog_update.inc
+
+
+
+--echo *** Configuring replication via Slave1 ***
+connection slave;
+--disable_warnings
+STOP SLAVE;
+source include/wait_for_slave_to_stop.inc;
+--enable_warnings
+
+connection srv_slave1;
+--disable_warnings
+STOP SLAVE;
+source include/wait_for_slave_to_stop.inc;
+--enable_warnings
+
+# Reset state of all Binlogging nodes
+--disable_query_log
+connection master;
+--disable_warnings
+RESET MASTER;
+--enable_warnings
+
+connection srv_master2;
+--disable_warnings
+RESET MASTER;
+--enable_warnings
+
+connection srv_slave1;
+--disable_warnings
+RESET MASTER;
+--enable_warnings
+
+connection srv_slave2;
+--disable_warnings
+RESET MASTER;
+--enable_warnings
+--enable_query_log
+
+connection srv_slave1;
+--disable_warnings
+RESET SLAVE;
+--replace_result $MASTER_MYPORT MASTER_PORT
+--eval CHANGE MASTER TO MASTER_HOST="127.0.0.1",MASTER_PORT=$MASTER_MYPORT,MASTER_USER="root"
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+--enable_warnings
+
+--let $which_slave=srv_slave1
+--source suite/rpl_ndb/t/rpl_ndb_multi_binlog_update.inc
+
+
+
+--echo *** Configuring replication via Slave2 ***
+connection srv_slave1;
+--disable_warnings
+STOP SLAVE;
+source include/wait_for_slave_to_stop.inc;
+--enable_warnings
+
+connection srv_slave2;
+--disable_warnings
+STOP SLAVE;
+source include/wait_for_slave_to_stop.inc;
+--enable_warnings
+
+# Reset state of all Binlogging nodes
+--disable_query_log
+connection master;
+--disable_warnings
+RESET MASTER;
+--enable_warnings
+
+connection srv_master2;
+--disable_warnings
+RESET MASTER;
+--enable_warnings
+
+connection srv_slave1;
+--disable_warnings
+RESET MASTER;
+--enable_warnings
+
+connection srv_slave2;
+--disable_warnings
+RESET MASTER;
+--enable_warnings
+--enable_query_log
+
+connection srv_slave2;
+--disable_warnings
+RESET SLAVE;
+--replace_result $MASTER_MYPORT MASTER_PORT
+--eval CHANGE MASTER TO MASTER_HOST="127.0.0.1",MASTER_PORT=$MASTER_MYPORT,MASTER_USER="root";
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+--enable_warnings
+
+--let $which_slave=srv_slave2
+--source suite/rpl_ndb/t/rpl_ndb_multi_binlog_update.inc

=== added file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_wait_schema_logging.inc'
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_wait_schema_logging.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_wait_schema_logging.inc	2009-09-16 16:04:14 +0000
@@ -0,0 +1,78 @@
+# suite/t/rpl_ndb/rpl_ndb_wait_schema_logging.inc
+#
+# SUMMARY
+#   Waits until schema op performed on $source_server is
+#   being logged by $dest_server
+#   Assumes that source_server and dest_server are connected
+#   to the same cluster
+#   Assumes that $dest_server has binlogging enabled.
+#
+###############################################################
+# Include file to wait for schema logging setup, where schema
+# changes made on $source_server are logged on $dest_server
+###############################################################
+
+connection $dest_server;
+
+#--echo Waiting for schema event logging to be active between $source_server and $dest_server
+#--echo - First check that $dest_server has binary logging enabled
+
+let $binlog= query_get_value(show variables like 'log_bin', Value, 1);
+if (`SELECT "$binlog" != "ON"`)
+{
+  show variables like 'server_id';
+  show variables like 'log_bin';
+  --die ERROR: Binlogging not activated
+}
+
+--disable_query_log
+RESET MASTER;
+--enable_query_log
+
+# Following code 'inspired' by include/wait_for_binlog_event.inc
+
+--let $wait_binlog_event=drop table
+
+let $_loop_count= 10;
+let $_event= ;
+let $_event_pos= 1;
+
+while (`SELECT INSTR("$_event","$wait_binlog_event") = 0`)
+{
+  #--echo loop_count is $_loop_count;
+  dec $_loop_count;
+  if (!$_loop_count)
+  {
+    SHOW BINLOG EVENTS;
+    --die ERROR: failed while waiting local cluster schema event logging to start
+  }
+
+  connection $source_server;
+  --disable_query_log
+  create table rpl_ndb_wait_schema_logging (a int primary key) engine=ndb;
+  drop table rpl_ndb_wait_schema_logging;
+  --enable_query_log
+  connection $dest_server;
+
+  let $_event= query_get_value(SHOW BINLOG EVENTS, Info, $_event_pos);
+  #--echo Event is : $_event
+  while (`SELECT ("$_event" != "No such row") and (INSTR("$_event", "$wait_binlog_event") = 0)`)
+  {
+    inc $_event_pos;
+    let $_event= query_get_value(SHOW BINLOG EVENTS, Info, $_event_pos);
+    #--echo Event did not match- next event is $_event;
+  }
+}
+
+# Since we're attached to the same cluster, if we've seen the event
+# then synchronous binlogging of changes is on (i.e. synchronous with
+# the original schema change)
+# Therefore it should now be safe to reset the master on the destination
+# server as no more binlog changes are in-flight.
+connection $dest_server;
+
+--disable_query_log
+RESET MASTER;
+--enable_query_log
+
+#--echo - Schema event logging is active

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2009-09-08 12:10:53 +0000
+++ b/sql/ha_ndbcluster.cc	2009-09-21 14:23:46 +0000
@@ -8665,7 +8665,17 @@ int ndbcluster_discover(handlerton *hton
       goto err;
     }
   }
-
+#ifdef HAVE_NDB_BINLOG
+  if (ndbcluster_check_if_local_table(db, name))
+  {
+    DBUG_PRINT("info", ("ndbcluster_discover: Skipping locally defined table '%s.%s'",
+                        db, name));
+    sql_print_error("ndbcluster_discover: Skipping locally defined table '%s.%s'",
+                    db, name);
+    error= 1;
+    goto err;
+  }
+#endif
   *frmlen= len;
   *frmblob= data;
   
@@ -12609,6 +12619,7 @@ int ha_ndbcluster::alter_frm(THD *thd, c
     my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR));
     my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR));
     error= 1;
+    my_error(ER_FILE_NOT_FOUND, MYF(0), file); 
   }
   else
   {
@@ -12622,6 +12633,7 @@ int ha_ndbcluster::alter_frm(THD *thd, c
     {
       DBUG_PRINT("info", ("On-line alter of table %s failed", m_tabname));
       error= ndb_to_mysql_error(&dict->getNdbError());
+      my_error(error, MYF(0));
     }
     my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR));
     my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR));

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2009-08-26 13:25:41 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2009-09-21 14:23:46 +0000
@@ -149,12 +149,6 @@ static NDB_SCHEMA_OBJECT *ndb_get_schema
 static void ndb_free_schema_object(NDB_SCHEMA_OBJECT **ndb_schema_object,
                                    bool have_lock);
 
-/*
-  Helper functions
-*/
-static bool ndbcluster_check_if_local_table(const char *dbname, const char *tabname);
-static bool ndbcluster_check_if_local_tables_in_db(THD *thd, const char *dbname);
-
 #ifndef DBUG_OFF
 /* purecov: begin deadcode */
 static void print_records(TABLE *table, const uchar *record)
@@ -2000,10 +1994,34 @@ int ndbcluster_log_schema_op(THD *thd,
       r|= op->setValue(SCHEMA_TYPE_I, log_type);
       DBUG_ASSERT(r == 0);
       /* any value */
-      if (!(thd->options & OPTION_BIN_LOG))
-        r|= op->setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING);
+      Uint32 anyValue;
+      if (! thd->slave_thread)
+      {
+        /* Schema change originating from this MySQLD, check SQL_LOG_BIN
+         * variable and pass 'setting' to all logging MySQLDs via AnyValue  
+         */
+        if (thd->options & OPTION_BIN_LOG) /* e.g. SQL_LOG_BIN == on */
+        {
+          DBUG_PRINT("info", ("Schema event for binlogging"));
+          anyValue = 0;
+        }
+        else
+        {
+          DBUG_PRINT("info", ("Schema event not for binlogging")); 
+          anyValue = NDB_ANYVALUE_FOR_NOLOGGING;
+        }
+      }
       else
-        r|= op->setAnyValue(thd->server_id);
+      {
+        /* Slave applying replicated schema event
+         * Pass original applier's serverId in AnyValue
+         */
+        DBUG_PRINT("info", ("Replicated schema event with original server id %d",
+                            thd->server_id));
+        anyValue = thd->server_id;
+      }
+
+      r|= op->setAnyValue(anyValue);
       DBUG_ASSERT(r == 0);
 #if 0
       if (log_db != new_db && new_db && new_table_name)
@@ -2249,14 +2267,34 @@ ndb_handle_schema_change(THD *thd, Ndb *
 
 static void ndb_binlog_query(THD *thd, Cluster_schema *schema)
 {
-  if (schema->any_value & NDB_ANYVALUE_RESERVED)
+  /* any_value == 0 means local cluster sourced change that
+   * should be logged
+   */
+  if (schema->any_value != 0)
   {
-    if (schema->any_value != NDB_ANYVALUE_FOR_NOLOGGING)
-      sql_print_warning("NDB: unknown value for binlog signalling 0x%X, "
-                        "query not logged",
-                        schema->any_value);
-    return;
+    if (schema->any_value & NDB_ANYVALUE_RESERVED)
+    {
+      /* Originating SQL node did not want this query logged */
+      if (schema->any_value != NDB_ANYVALUE_FOR_NOLOGGING)
+        sql_print_warning("NDB: unknown value for binlog signalling 0x%X, "
+                          "query not logged",
+                          schema->any_value);
+      return;
+    }
+    else 
+    {
+      /* AnyValue is set to non-zero serverId, must be a query applied
+       * by a slave mysqld.
+       * TODO : Assert that we are running in the Binlog injector thread?
+       */
+      if (! g_ndb_log_slave_updates)
+      {
+        /* This MySQLD does not log slave updates */
+        return;
+      }
+    }
   }
+
   uint32 thd_server_id_save= thd->server_id;
   DBUG_ASSERT(sizeof(thd_server_id_save) == sizeof(thd->server_id));
   char *thd_db_save= thd->db;
@@ -3900,7 +3938,7 @@ err:
 }
 #endif /* HAVE_NDB_BINLOG */
 
-static bool
+bool
 ndbcluster_check_if_local_table(const char *dbname, const char *tabname)
 {
   char key[FN_REFLEN + 1];
@@ -3922,7 +3960,7 @@ ndbcluster_check_if_local_table(const ch
   DBUG_RETURN(false);
 }
 
-static bool
+bool
 ndbcluster_check_if_local_tables_in_db(THD *thd, const char *dbname)
 {
   DBUG_ENTER("ndbcluster_check_if_local_tables_in_db");
@@ -5791,6 +5829,7 @@ restart_cluster_failure:
     if (unlikely(schema_res > 0))
     {
       thd->proc_info= "Processing events from schema table";
+      g_ndb_log_slave_updates= opt_log_slave_updates;
       s_ndb->
         setReportThreshEventGCISlip(ndb_report_thresh_binlog_epoch_slip);
       s_ndb->

=== modified file 'sql/ha_ndbcluster_binlog.h'
--- a/sql/ha_ndbcluster_binlog.h	2009-05-27 15:21:45 +0000
+++ b/sql/ha_ndbcluster_binlog.h	2009-09-21 14:23:46 +0000
@@ -322,6 +322,14 @@ inline void free_share(NDB_SHARE **share
 
 void set_binlog_flags(NDB_SHARE *share);
 
+/*
+  Helper functions
+*/
+bool
+ndbcluster_check_if_local_table(const char *dbname, const char *tabname);
+bool
+ndbcluster_check_if_local_tables_in_db(THD *thd, const char *dbname);
+
 inline
 Thd_ndb *
 get_thd_ndb(THD *thd)

=== modified file 'storage/ndb/include/kernel/GlobalSignalNumbers.h'
--- a/storage/ndb/include/kernel/GlobalSignalNumbers.h	2009-08-24 08:18:43 +0000
+++ b/storage/ndb/include/kernel/GlobalSignalNumbers.h	2009-09-21 08:42:40 +0000
@@ -552,7 +552,7 @@ extern const GlobalSignalNumber NO_OF_SI
 #define GSN_DROP_FRAG_REQ               426 /* local */
 #define GSN_DROP_FRAG_REF               427 /* local */
 #define GSN_DROP_FRAG_CONF              428 /* local */
-/* 429 unused */
+#define GSN_LOCAL_ROUTE_ORD             429 /* local */
 /* 430 unused */
 #define GSN_TUPFRAGCONF                 431
 #define GSN_TUPFRAGREF                  432

=== modified file 'storage/ndb/include/kernel/signaldata/BackupLockTab.hpp'
--- a/storage/ndb/include/kernel/signaldata/BackupLockTab.hpp	2008-01-01 12:45:11 +0000
+++ b/storage/ndb/include/kernel/signaldata/BackupLockTab.hpp	2009-09-16 13:29:58 +0000
@@ -28,7 +28,7 @@ class BackupLockTab {
   friend class Dbdict;
 
 public:
-  STATIC_CONST( SignalLength = 6);
+  STATIC_CONST( SignalLength = 7 );
 
 private:
   /* Values for m_lock_unlock. */
@@ -47,6 +47,7 @@ private:
   Uint32 m_senderRef;
   Uint32 m_tableId;
   Uint32 m_lock_unlock;
+  Uint32 errorCode;
   /* The remaining words are used to keep track of state in block Backup. */
   Uint32 m_backup_state;
   Uint32 m_backupRecordPtr_I;

=== modified file 'storage/ndb/include/kernel/signaldata/FsOpenReq.hpp'
--- a/storage/ndb/include/kernel/signaldata/FsOpenReq.hpp	2009-08-21 10:39:15 +0000
+++ b/storage/ndb/include/kernel/signaldata/FsOpenReq.hpp	2009-09-14 12:43:17 +0000
@@ -231,7 +231,7 @@ Uint32 FsOpenReq::getVersion(const Uint3
 inline
 void FsOpenReq::setVersion(Uint32 fileNumber[], Uint8 val){
   const Uint32 t = fileNumber[3];
-  fileNumber[3] = t & 0x00FFFFFF | (((Uint32)val) << 24);
+  fileNumber[3] = (t & 0x00FFFFFF) | (((Uint32)val) << 24);
 }
 
 inline 
@@ -242,7 +242,7 @@ Uint32 FsOpenReq::getSuffix(const Uint32
 inline
 void FsOpenReq::setSuffix(Uint32 fileNumber[], Uint8 val){
   const Uint32 t = fileNumber[3];
-  fileNumber[3] = t & 0xFF00FFFF | (((Uint32)val) << 16);
+  fileNumber[3] = (t & 0xFF00FFFF) | (((Uint32)val) << 16);
 }
 
 inline 
@@ -253,7 +253,7 @@ Uint32 FsOpenReq::v1_getDisk(const Uint3
 inline
 void FsOpenReq::v1_setDisk(Uint32 fileNumber[], Uint8 val){
   const Uint32 t = fileNumber[3];
-  fileNumber[3] = t & 0xFFFF00FF | (((Uint32)val) << 8);
+  fileNumber[3] = (t & 0xFFFF00FF) | (((Uint32)val) << 8);
 }
 
 inline 
@@ -294,7 +294,7 @@ Uint32 FsOpenReq::v1_getP(const Uint32 f
 inline
 void FsOpenReq::v1_setP(Uint32 fileNumber[], Uint8 val){
   const Uint32 t = fileNumber[3];
-  fileNumber[3] = t & 0xFFFFFF00 | val;
+  fileNumber[3] = (t & 0xFFFFFF00) | val;
 }
 
 /****************/

=== added file 'storage/ndb/include/kernel/signaldata/LocalRouteOrd.hpp'
--- a/storage/ndb/include/kernel/signaldata/LocalRouteOrd.hpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/include/kernel/signaldata/LocalRouteOrd.hpp	2009-09-21 08:30:42 +0000
@@ -0,0 +1,34 @@
+/*
+   Copyright (C) 2003 MySQL AB
+    All rights reserved. Use is subject to license terms.
+
+   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 LOCAL_ROUTE_ORD_HPP
+#define LOCAL_ROUTE_ORD_HPP
+
+#include "SignalData.hpp"
+
+struct LocalRouteOrd
+{
+  STATIC_CONST( StaticLen = 3 );
+
+  Uint32 cnt; // 16-bit path, 16-bit destination
+  Uint32 gsn; // Final gsn
+  Uint32 prio;// Final prio
+  Uint32 path[1];
+};
+
+#endif

=== modified file 'storage/ndb/include/kernel/signaldata/SignalData.hpp'
--- a/storage/ndb/include/kernel/signaldata/SignalData.hpp	2009-06-06 12:01:09 +0000
+++ b/storage/ndb/include/kernel/signaldata/SignalData.hpp	2009-09-21 08:42:40 +0000
@@ -279,4 +279,6 @@ GSN_PRINT_SIGNATURE(printBUILD_INDX_IMPL
 GSN_PRINT_SIGNATURE(printAPI_VERSION_REQ);
 GSN_PRINT_SIGNATURE(printAPI_VERSION_CONF);
 
+GSN_PRINT_SIGNATURE(printLOCAL_ROUTE_ORD);
+
 #endif

=== modified file 'storage/ndb/src/common/debugger/signaldata/CMakeLists.txt'
--- a/storage/ndb/src/common/debugger/signaldata/CMakeLists.txt	2008-10-24 12:51:04 +0000
+++ b/storage/ndb/src/common/debugger/signaldata/CMakeLists.txt	2009-09-21 10:03:14 +0000
@@ -44,5 +44,6 @@ ADD_LIBRARY(ndbsignaldata STATIC
         SumaImpl.cpp NdbSttor.cpp CreateFragmentation.cpp
         UtilLock.cpp TuxMaint.cpp AccLock.cpp
         LqhTrans.cpp ReadNodesConf.cpp CntrStart.cpp
-        ScanFrag.cpp ApiVersion.cpp)
+        ScanFrag.cpp ApiVersion.cpp
+        LocalRouteOrd.cpp)
 

=== added file 'storage/ndb/src/common/debugger/signaldata/LocalRouteOrd.cpp'
--- a/storage/ndb/src/common/debugger/signaldata/LocalRouteOrd.cpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/common/debugger/signaldata/LocalRouteOrd.cpp	2009-09-21 08:30:42 +0000
@@ -0,0 +1,63 @@
+/*
+   Copyright (C) 2003 MySQL AB
+    All rights reserved. Use is subject to license terms.
+
+   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 <signaldata/LocalRouteOrd.hpp>
+#include <DebuggerNames.hpp>
+#include <RefConvert.hpp>
+
+bool
+printLOCAL_ROUTE_ORD(FILE* output,
+                     const Uint32* theData, Uint32 len,
+                     Uint16 rbn)
+{
+  const LocalRouteOrd * sig = (const LocalRouteOrd*)theData;
+  Uint32 pathcnt = sig->cnt >> 16;
+  Uint32 dstcnt = sig->cnt & 0xFFFF;
+
+  fprintf(output, " pathcnt: %u dstcnt: %u\n", pathcnt, dstcnt);
+  fprintf(output, " gsn: %u(%s) prio: %u\n",
+          sig->gsn, getSignalName(sig->gsn), sig->prio);
+
+  const Uint32 * ptr = sig->path;
+  fprintf(output, " path:");
+  for (Uint32 i = 0; i<pathcnt; i++)
+  {
+    fprintf(output, " [ hop: 0x%x(%s) prio: %u ]",
+            ptr[0], getBlockName(refToMain(ptr[0])), ptr[1]);
+    ptr += 2;
+  }
+
+  fprintf(output, "\n dst:");
+  for (Uint32 i = 0; i<dstcnt; i++)
+  {
+    fprintf(output, " [ 0x%x(%s) ]",
+            ptr[0], getBlockName(refToMain(ptr[0])));
+  }
+  fprintf(output, "\n");
+
+  if (ptr < (theData + len))
+  {
+    fprintf(output, " data:");
+    while (ptr < (theData + len))
+    {
+      fprintf(output, " %.8x", * ptr++);
+    }
+    fprintf(output, "\n");
+  }
+  return true;
+}

=== modified file 'storage/ndb/src/common/debugger/signaldata/Makefile.am'
--- a/storage/ndb/src/common/debugger/signaldata/Makefile.am	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/src/common/debugger/signaldata/Makefile.am	2009-09-21 08:42:40 +0000
@@ -46,7 +46,8 @@ libsignaldataprint_la_SOURCES = \
  	  CreateTab.cpp CreateTable.cpp DropTable.cpp \
   	  CreateTrigImpl.cpp DropTrigImpl.cpp \
  	  CreateIndxImpl.cpp DropIndxImpl.cpp AlterIndxImpl.cpp \
- 	  BuildIndx.cpp BuildIndxImpl.cpp ApiVersion.cpp
+ 	  BuildIndx.cpp BuildIndxImpl.cpp ApiVersion.cpp \
+          LocalRouteOrd.cpp
 
 include $(top_srcdir)/storage/ndb/config/common.mk.am
 include $(top_srcdir)/storage/ndb/config/type_ndbapi.mk.am

=== modified file 'storage/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp'
--- a/storage/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp	2009-09-21 08:42:40 +0000
@@ -251,6 +251,7 @@ SignalDataPrintFunctions[] = {
   ,{ GSN_API_VERSION_REQ, printAPI_VERSION_REQ }
   ,{ GSN_API_VERSION_CONF, printAPI_VERSION_CONF }
 
+  ,{ GSN_LOCAL_ROUTE_ORD, printLOCAL_ROUTE_ORD }
   ,{ 0, 0 }
 };
 

=== modified file 'storage/ndb/src/common/debugger/signaldata/SignalNames.cpp'
--- a/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp	2009-08-24 08:18:43 +0000
+++ b/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp	2009-09-21 08:42:40 +0000
@@ -747,5 +747,7 @@ const GsnName SignalNames [] = {
 
   ,{ GSN_SYNC_THREAD_REQ, "SYNC_THREAD_REQ" }
   ,{ GSN_SYNC_THREAD_CONF, "SYNC_THREAD_CONF" }
+
+  ,{ GSN_LOCAL_ROUTE_ORD, "LOCAL_ROUTE_ORD" }
 };
 const unsigned short NO_OF_SIGNAL_NAMES = sizeof(SignalNames)/sizeof(GsnName);

=== modified file 'storage/ndb/src/common/portlib/NdbDir.cpp'
--- a/storage/ndb/src/common/portlib/NdbDir.cpp	2009-09-11 08:02:07 +0000
+++ b/storage/ndb/src/common/portlib/NdbDir.cpp	2009-09-15 17:35:16 +0000
@@ -26,6 +26,7 @@
 class DirIteratorImpl {
   DIR* m_dirp;
   const char *m_path;
+  char* m_buf;
 
   bool is_regular_file(struct dirent* dp) const {
 #ifdef _DIRENT_HAVE_D_TYPE
@@ -37,12 +38,11 @@ class DirIteratorImpl {
       return (dp->d_type == DT_REG);
 #endif
     /* Using stat to read more info about the file */
-    char path_buf[PATH_MAX];
-    basestring_snprintf(path_buf, sizeof(path_buf),
+    basestring_snprintf(m_buf, PATH_MAX, 
                         "%s/%s", m_path, dp->d_name);
 
     struct stat buf;
-    if (stat(path_buf, &buf))
+    if (stat(m_buf, &buf))
       return false; // 'stat' failed
 
     return S_ISREG(buf.st_mode);
@@ -51,10 +51,13 @@ class DirIteratorImpl {
 
 public:
   DirIteratorImpl():
-    m_dirp(NULL) {};
+    m_dirp(NULL) {
+     m_buf = new char[PATH_MAX];
+  };
 
   ~DirIteratorImpl() {
     close();
+    delete [] m_buf;
   }
 
   int open(const char* path){
@@ -165,8 +168,11 @@ void NdbDir::Iterator::close(void)
 const char* NdbDir::Iterator::next_file(void)
 {
   bool is_dir;
-  while(m_impl.next_entry(is_dir) != NULL && is_dir)
-    ;
+  const char* name;
+  while((name = m_impl.next_entry(is_dir)) != NULL){
+    if (!is_dir)
+      return name; // Found  some sort of file 
+  } 
   return NULL;
 }
 
@@ -382,8 +388,28 @@ TAPTEST(DirIterator)
 
   printf("Using directory '%s'\n", path);
 
-  // Build dir tree and remove all of it
+  // Remove dir if it exists
+  if (access(path, F_OK) == 0)
+    CHECK(NdbDir::remove_recursive(path));
+
+  // Build dir tree 
   build_tree(path);
+  // Test to iterate over filesa
+  { 
+    NdbDir::Iterator iter;
+    CHECK(iter.open(path) == 0);
+    const char* name;
+    int num_files = 0;  
+    while((name = iter.next_file()) != NULL)
+    {
+      //printf("%s\n", name);
+      num_files++;
+    }
+    printf("Found %d files\n", num_files);
+    CHECK(num_files == 6); 
+  }
+  
+  // Remove all of tree
   CHECK(NdbDir::remove_recursive(path));
   CHECK(gone(path));
 

=== modified file 'storage/ndb/src/kernel/blocks/ERROR_codes.txt'
--- a/storage/ndb/src/kernel/blocks/ERROR_codes.txt	2009-09-01 11:42:04 +0000
+++ b/storage/ndb/src/kernel/blocks/ERROR_codes.txt	2009-09-15 16:59:09 +0000
@@ -5,8 +5,8 @@ Next DBACC 3002
 Next DBTUP 4029
 Next DBLQH 5054
 Next DBDICT 6013
-Next DBDIH 7220
-Next DBTC 8080
+Next DBDIH 7221
+Next DBTC 8081
 Next CMVMI 9000
 Next BACKUP 10042
 Next DBUTIL 11002
@@ -282,7 +282,7 @@ Delay execution of COMPLETECONF signal 2
 8045: (ABORTCONF only as part of take-over)
 Delay execution of ABORTCONF signal 2 seconds to generate time-out.
 
-8050: Send ZABORT_TIMEOUT_BREAK delayed
+8080: Send ZABORT_TIMEOUT_BREAK delayed
 
 8053: Crash in timeOutFoundLab, state CS_WAIT_COMMIT_CONF
 

=== modified file 'storage/ndb/src/kernel/blocks/backup/Backup.cpp'
--- a/storage/ndb/src/kernel/blocks/backup/Backup.cpp	2009-05-29 06:23:51 +0000
+++ b/storage/ndb/src/kernel/blocks/backup/Backup.cpp	2009-09-16 13:29:58 +0000
@@ -444,6 +444,13 @@ Backup::execBACKUP_LOCK_TAB_CONF(Signal 
   case BackupLockTab::GET_TABINFO_CONF:
   {
     jam();
+    if (conf->errorCode)
+    {
+      jam();
+      defineBackupRef(signal, ptr, conf->errorCode);
+      return;
+    }
+
     ptr.p->tables.next(tabPtr);
     afterGetTabinfoLockTab(signal, ptr, tabPtr);
     return;

=== modified file 'storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp'
--- a/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp	2009-09-19 06:30:50 +0000
@@ -623,6 +623,7 @@ struct Tabrec {
   Uint32 fragptrholder[MAX_FRAG_PER_NODE];
   Uint32 tabUserPtr;
   BlockReference tabUserRef;
+  Uint32 tabUserGsn;
 };
   typedef Ptr<Tabrec> TabrecPtr;
 

=== modified file 'storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp	2009-08-07 12:02:25 +0000
+++ b/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp	2009-09-19 06:30:50 +0000
@@ -679,7 +679,8 @@ Dbacc::execDROP_TAB_REQ(Signal* signal){
   
   tabPtr.p->tabUserRef = req->senderRef;
   tabPtr.p->tabUserPtr = req->senderData;
-  
+  tabPtr.p->tabUserGsn = GSN_DROP_TAB_REQ;
+
   signal->theData[0] = ZREL_ROOT_FRAG;
   signal->theData[1] = tabPtr.i;
   sendSignal(cownBlockref, GSN_CONTINUEB, signal, 2, JBB);
@@ -696,6 +697,7 @@ Dbacc::execDROP_FRAG_REQ(Signal* signal)
 
   tabPtr.p->tabUserRef = req->senderRef;
   tabPtr.p->tabUserPtr = req->senderData;
+  tabPtr.p->tabUserGsn = GSN_DROP_FRAG_REQ;
 
   for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++)
   {
@@ -718,19 +720,20 @@ void Dbacc::releaseRootFragResources(Sig
   tabPtr.i = tableId;
   ptrCheckGuard(tabPtr, ctablesize, tabrec);
 
-  const BlockNumber dictBlock = !isNdbMtLqh() ? DBDICT : DBACC;
-  if (refToBlock(tabPtr.p->tabUserRef) == dictBlock)
+  if (tabPtr.p->tabUserGsn == GSN_DROP_TAB_REQ)
   {
     jam();
-    for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
+    for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++)
+    {
       jam();
-      if (tabPtr.p->fragholder[i] != RNIL) {
+      if (tabPtr.p->fragholder[i] != RNIL)
+      {
         jam();
         tabPtr.p->fragholder[i] = RNIL;
         releaseFragResources(signal, tabPtr.p->fragptrholder[i]);
         return;
-      }//if
-    }//for
+      }
+    }
 
     /**
      * Finished...
@@ -744,7 +747,7 @@ void Dbacc::releaseRootFragResources(Sig
   }
   else
   {
-    ndbrequire(refToMain(tabPtr.p->tabUserRef) == DBLQH);
+    ndbrequire(tabPtr.p->tabUserGsn == GSN_DROP_FRAG_REQ);
 
     DropFragConf * conf = (DropFragConf *)signal->getDataPtrSend();
     conf->senderRef = reference();
@@ -756,6 +759,7 @@ void Dbacc::releaseRootFragResources(Sig
   
   tabPtr.p->tabUserPtr = RNIL;
   tabPtr.p->tabUserRef = 0;
+  tabPtr.p->tabUserGsn = 0;
 }//Dbacc::releaseRootFragResources()
 
 void Dbacc::releaseFragResources(Signal* signal, Uint32 fragIndex)

=== modified file 'storage/ndb/src/kernel/blocks/dbacc/DbaccProxy.cpp'
--- a/storage/ndb/src/kernel/blocks/dbacc/DbaccProxy.cpp	2008-08-11 11:53:43 +0000
+++ b/storage/ndb/src/kernel/blocks/dbacc/DbaccProxy.cpp	2009-09-19 06:30:50 +0000
@@ -19,9 +19,6 @@
 DbaccProxy::DbaccProxy(Block_context& ctx) :
   LocalProxy(DBACC, ctx)
 {
-  // GSN_DROP_TAB_REQ
-  addRecSignal(GSN_DROP_TAB_REQ, &DbaccProxy::execDROP_TAB_REQ);
-  addRecSignal(GSN_DROP_TAB_CONF, &DbaccProxy::execDROP_TAB_CONF);
 }
 
 DbaccProxy::~DbaccProxy()
@@ -34,63 +31,4 @@ DbaccProxy::newWorker(Uint32 instanceNo)
   return new Dbacc(m_ctx, instanceNo);
 }
 
-// GSN_DROP_TAB_REQ
-
-void
-DbaccProxy::execDROP_TAB_REQ(Signal* signal)
-{
-  const DropTabReq* req = (const DropTabReq*)signal->getDataPtr();
-  Uint32 ssId = getSsId(req);
-  Ss_DROP_TAB_REQ& ss = ssSeize<Ss_DROP_TAB_REQ>(ssId);
-  ss.m_req = *req;
-  ndbrequire(signal->getLength() == DropTabReq::SignalLength);
-  sendREQ(signal, ss);
-}
-
-void
-DbaccProxy::sendDROP_TAB_REQ(Signal* signal, Uint32 ssId)
-{
-  Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
-
-  DropTabReq* req = (DropTabReq*)signal->getDataPtrSend();
-  *req = ss.m_req;
-  req->senderRef = reference();
-  req->senderData = ssId; // redundant since tableId is used
-  sendSignal(workerRef(ss.m_worker), GSN_DROP_TAB_REQ,
-             signal, DropTabReq::SignalLength, JBB);
-}
-
-void
-DbaccProxy::execDROP_TAB_CONF(Signal* signal)
-{
-  const DropTabConf* conf = (const DropTabConf*)signal->getDataPtr();
-  Uint32 ssId = getSsId(conf);
-  Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
-  recvCONF(signal, ss);
-}
-
-void
-DbaccProxy::sendDROP_TAB_CONF(Signal* signal, Uint32 ssId)
-{
-  Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
-  BlockReference dictRef = ss.m_req.senderRef;
-
-  if (!lastReply(ss))
-    return;
-
-  if (ss.m_error == 0) {
-    jam();
-    DropTabConf* conf = (DropTabConf*)signal->getDataPtrSend();
-    conf->senderRef = reference();
-    conf->senderData = ss.m_req.senderData;
-    conf->tableId = ss.m_req.tableId;
-    sendSignal(dictRef, GSN_DROP_TAB_CONF,
-               signal, DropTabConf::SignalLength, JBB);
-  } else {
-    ndbrequire(false);
-  }
-
-  ssRelease<Ss_DROP_TAB_REQ>(ssId);
-}
-
 BLOCK_FUNCTIONS(DbaccProxy)

=== modified file 'storage/ndb/src/kernel/blocks/dbacc/DbaccProxy.hpp'
--- a/storage/ndb/src/kernel/blocks/dbacc/DbaccProxy.hpp	2008-08-11 11:53:43 +0000
+++ b/storage/ndb/src/kernel/blocks/dbacc/DbaccProxy.hpp	2009-09-19 06:30:50 +0000
@@ -27,30 +27,6 @@ public:
 
 protected:
   virtual SimulatedBlock* newWorker(Uint32 instanceNo);
-
-  // GSN_DROP_TAB_REQ
-  struct Ss_DROP_TAB_REQ : SsParallel {
-    DropTabReq m_req;
-    Ss_DROP_TAB_REQ() {
-      m_sendREQ = (SsFUNC)&DbaccProxy::sendDROP_TAB_REQ;
-      m_sendCONF = (SsFUNC)&DbaccProxy::sendDROP_TAB_CONF;
-    }
-    enum { poolSize = 1 };
-    static SsPool<Ss_DROP_TAB_REQ>& pool(LocalProxy* proxy) {
-      return ((DbaccProxy*)proxy)->c_ss_DROP_TAB_REQ;
-    }
-  };
-  SsPool<Ss_DROP_TAB_REQ> c_ss_DROP_TAB_REQ;
-  Uint32 getSsId(const DropTabReq* req) {
-    return SsIdBase | req->tableId;
-  }
-  Uint32 getSsId(const DropTabConf* conf) {
-    return SsIdBase | conf->tableId;
-  }
-  void execDROP_TAB_REQ(Signal*);
-  void sendDROP_TAB_REQ(Signal*, Uint32 ssId);
-  void execDROP_TAB_CONF(Signal*);
-  void sendDROP_TAB_CONF(Signal*, Uint32 ssId);
 };
 
 #endif

=== modified file 'storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp'
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2009-09-09 10:58:10 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2009-09-21 08:42:40 +0000
@@ -455,6 +455,54 @@ void Dbdict::packTableIntoPages(Signal* 
   const Uint32 type= signal->theData[2];
   const Uint32 pageId= signal->theData[3];
 
+  {
+    Uint32 transId = c_retrieveRecord.schemaTransId;
+    GetTabInfoReq req_copy;
+    req_copy.senderRef = c_retrieveRecord.blockRef;
+    req_copy.senderData = c_retrieveRecord.m_senderData;
+    req_copy.schemaTransId = c_retrieveRecord.schemaTransId;
+    req_copy.requestType = c_retrieveRecord.requestType;
+    req_copy.tableId = tableId;
+
+    SchemaFile::TableEntry *objEntry = 0;
+    if(tableId != RNIL)
+    {
+      XSchemaFile * xsf = &c_schemaFile[SchemaRecord::NEW_SCHEMA_FILE];
+      objEntry = getTableEntry(xsf, tableId);
+    }
+
+    // The table seached for was not found
+    if(objEntry == 0)
+    {
+      jam();
+      sendGET_TABINFOREF(signal, &req_copy,
+                         GetTabInfoRef::TableNotDefined, __LINE__);
+      initRetrieveRecord(0, 0, 0);
+      return;
+    }
+
+    if (transId != 0 && transId == objEntry->m_transId)
+    {
+      jam();
+      // see own trans always
+    }
+    else if (refToBlock(req_copy.senderRef) != DBUTIL && /** XXX cheat */
+             refToBlock(req_copy.senderRef) != SUMA)
+    {
+      jam();
+      Uint32 err;
+      if ((err = check_read_obj(objEntry)))
+      {
+        jam();
+        // cannot see another uncommitted trans
+        sendGET_TABINFOREF(signal, &req_copy,
+                           (GetTabInfoRef::ErrorCode)err, __LINE__);
+        initRetrieveRecord(0, 0, 0);
+        return;
+      }
+    }
+  }
+
   PageRecordPtr pagePtr;
   c_pageRecordArray.getPtr(pagePtr, pageId);
 
@@ -2313,6 +2361,12 @@ Dbdict::check_read_obj(Uint32 objId, Uin
 Uint32
 Dbdict::check_read_obj(SchemaFile::TableEntry* te, Uint32 transId)
 {
+  if (te->m_tableState == SchemaFile::SF_UNUSED)
+  {
+    jam();
+    return GetTabInfoRef::TableNotDefined;
+  }
+
   if (te->m_transId == 0 || te->m_transId == transId)
   {
     jam();
@@ -2323,6 +2377,7 @@ Dbdict::check_read_obj(SchemaFile::Table
   case SchemaFile::SF_CREATE:
     jam();
     return GetTabInfoRef::TableNotDefined;
+    break;
   case SchemaFile::SF_ALTER:
     jam();
     return 0;
@@ -2333,21 +2388,15 @@ Dbdict::check_read_obj(SchemaFile::Table
   case SchemaFile::SF_IN_USE:
     jam();
     return 0;
-  case SchemaFile::SF_UNUSED:
-    jam();
-    return GetTabInfoRef::TableNotDefined;   
   default:
-    jam();
     /** weird... */
-    return 0;
+    return GetTabInfoRef::TableNotDefined;
   }
-  return 0;
 }
 
+
 Uint32
-Dbdict::check_write_obj(Uint32 objId, Uint32 transId,
-                        SchemaFile::EntryState op,
-                        ErrorInfo& error)
+Dbdict::check_write_obj(Uint32 objId, Uint32 transId)
 {
   XSchemaFile * xsf = &c_schemaFile[SchemaRecord::NEW_SCHEMA_FILE];
   if (objId < (NDB_SF_PAGE_ENTRIES * xsf->noOfPages))
@@ -2358,7 +2407,6 @@ Dbdict::check_write_obj(Uint32 objId, Ui
     if (te->m_tableState == SchemaFile::SF_UNUSED)
     {
       jam();
-      setError(error, GetTabInfoRef::TableNotDefined, __LINE__);
       return GetTabInfoRef::TableNotDefined;
     }
     
@@ -2368,13 +2416,26 @@ Dbdict::check_write_obj(Uint32 objId, Ui
       return 0;
     }
 
-    setError(error, DropTableRef::ActiveSchemaTrans, __LINE__);
     return DropTableRef::ActiveSchemaTrans;
   }
-  setError(error, GetTabInfoRef::InvalidTableId, __LINE__);
   return GetTabInfoRef::InvalidTableId;
 }
 
+Uint32
+Dbdict::check_write_obj(Uint32 objId, Uint32 transId,
+                        SchemaFile::EntryState op,
+                        ErrorInfo& error)
+{
+  Uint32 err = check_write_obj(objId, transId);
+  if (err)
+  {
+    jam();
+    setError(error, err, __LINE__);
+  }
+
+  return err;
+}
+
 
 
 /* **************************************************************** */
@@ -4316,17 +4377,14 @@ void Dbdict::printTables()
 
 Dbdict::DictObject *
 Dbdict::get_object(const char * name, Uint32 len, Uint32 hash){
-  DictObject key;
-  key.m_key.m_name_ptr = name;
-  key.m_key.m_name_len = len;
-  key.m_key.m_pool = &c_rope_pool;
-  key.m_name.m_hash = hash;
   Ptr<DictObject> old_ptr;
-  c_obj_hash.find(old_ptr, key);
-  return old_ptr.p;
+  if (get_object(old_ptr, name, len, hash))
+  {
+    return old_ptr.p;
+  }
+  return 0;
 }
 
-//wl3600_todo remove the duplication
 bool
 Dbdict::get_object(DictObjectPtr& obj_ptr, const char* name, Uint32 len, Uint32 hash)
 {
@@ -6412,13 +6470,19 @@ Dbdict::createTable_abortPrepare(Signal*
   unlinkDictObject(op_ptr);
 
   dropTabPtr.p->m_block = 0;
+  dropTabPtr.p->m_blockNo[0] = DBTC;
+  dropTabPtr.p->m_blockNo[1] = DBLQH; // wait usage + LCP
+  dropTabPtr.p->m_blockNo[2] = DBDIH; //
+  dropTabPtr.p->m_blockNo[3] = DBLQH; // release
+  dropTabPtr.p->m_blockNo[4] = 0;
+
   dropTabPtr.p->m_callback.m_callbackData =
     oplnk_ptr.p->op_key;
   dropTabPtr.p->m_callback.m_callbackFunction =
     safe_cast(&Dbdict::createTable_abortLocalConf);
 
-  // invoke the "commit" phase of drop table
-  dropTab_nextStep(signal, oplnk_ptr);
+  // invoke the "complete" phase of drop table
+  dropTable_complete_nextStep(signal, oplnk_ptr);
 
   if (tabPtr.p->m_tablespace_id != RNIL) {
     FilegroupPtr ptr;
@@ -6760,8 +6824,6 @@ Dbdict::dropTable_prepare(Signal* signal
 
   D("dropTable_prepare" << *op_ptr.p);
 
-  dropTabPtr.p->m_block = 0;
-
   Mutex mutex(signal, c_mutexMgr, dropTabPtr.p->m_define_backup_mutex);
   Callback c = {
     safe_cast(&Dbdict::dropTable_backup_mutex_locked),
@@ -6803,11 +6865,60 @@ Dbdict::dropTable_backup_mutex_locked(Si
     return;
   }
 
-  prepDropTab_nextStep(signal, op_ptr);
+  sendTransConf(signal, op_ptr);
+}
+// DropTable: COMMIT
+
+void
+Dbdict::dropTable_commit(Signal* signal, SchemaOpPtr op_ptr)
+{
+  SchemaTransPtr trans_ptr = op_ptr.p->m_trans_ptr;
+
+  DropTableRecPtr dropTabPtr;
+  getOpRec(op_ptr, dropTabPtr);
+
+  D("dropTable_commit" << *op_ptr.p);
+
+  TableRecordPtr tablePtr;
+  c_tableRecordPool.getPtr(tablePtr, dropTabPtr.p->m_request.tableId);
+
+  if (tablePtr.p->m_tablespace_id != RNIL)
+  {
+    FilegroupPtr ptr;
+    ndbrequire(c_filegroup_hash.find(ptr, tablePtr.p->m_tablespace_id));
+    decrease_ref_count(ptr.p->m_obj_ptr_i);
+  }
+
+#if defined VM_TRACE || defined ERROR_INSERT
+  // from a newer execDROP_TAB_REQ version
+  {
+    char buf[1024];
+    Rope name(c_rope_pool, tablePtr.p->tableName);
+    name.copy(buf);
+    ndbout_c("Dbdict: drop name=%s,id=%u,obj_id=%u", buf, tablePtr.i,
+             tablePtr.p->m_obj_ptr_i);
+  }
+#endif
+
+  if (DictTabInfo::isIndex(tablePtr.p->tableType))
+  {
+    Ptr<TableRecord> basePtr;
+    c_tableRecordPool.getPtr(basePtr, tablePtr.p->primaryTableId);
+
+    LocalDLFifoList<TableRecord> list(c_tableRecordPool, basePtr.p->m_indexes);
+    list.remove(tablePtr);
+  }
+  dropTabPtr.p->m_block = 0;
+  dropTabPtr.p->m_blockNo[0] = DBLQH;
+  dropTabPtr.p->m_blockNo[1] = DBTC;
+  dropTabPtr.p->m_blockNo[2] = DBDIH;
+  dropTabPtr.p->m_blockNo[3] = 0;
+  dropTable_commit_nextStep(signal, op_ptr);
 }
 
+
 void
-Dbdict::prepDropTab_nextStep(Signal* signal, SchemaOpPtr op_ptr)
+Dbdict::dropTable_commit_nextStep(Signal* signal, SchemaOpPtr op_ptr)
 {
   DropTableRecPtr dropTabPtr;
   getOpRec(op_ptr, dropTabPtr);
@@ -6818,38 +6929,19 @@ Dbdict::prepDropTab_nextStep(Signal* sig
    */
   ndbrequire(!hasError(op_ptr.p->m_error));
 
-  Uint32& block = dropTabPtr.p->m_block; // ref
-  D("prepDropTab_nextStep" << hex << V(block) << *op_ptr.p);
+  Uint32 block = dropTabPtr.p->m_block;
+  Uint32 blockNo = dropTabPtr.p->m_blockNo[block];
+  D("dropTable_commit_nextStep" << hex << V(blockNo) << *op_ptr.p);
 
-  switch (block) {
-  case 0:
-    jam();
-    block = DBDICT;
-    prepDropTab_writeSchema(signal, op_ptr);
-    return;
-  case DBDICT:
-    jam();
-    block = DBLQH;
-    break;
-  case DBLQH:
-    jam();
-    block = DBTC;
-    break;
-  case DBTC:
-    jam();
-    block = DBDIH;
-    break;
-  case DBDIH:
+  if (blockNo == 0)
+  {
     jam();
-    prepDropTab_complete(signal, op_ptr);
+    dropTable_commit_done(signal, op_ptr);
     return;
-  default:
-    ndbrequire(false);
-    break;
   }
 
   if (ERROR_INSERTED(6131) &&
-      block == DBDIH) {
+      blockNo == DBDIH) {
     jam();
     CLEAR_ERROR_INSERT_VALUE;
 
@@ -6870,7 +6962,7 @@ Dbdict::prepDropTab_nextStep(Signal* sig
   prep->tableId = impl_req->tableId;
   prep->requestType = impl_req->requestType;
 
-  BlockReference ref = numberToRef(block, getOwnNodeId());
+  BlockReference ref = numberToRef(blockNo, getOwnNodeId());
   sendSignal(ref, GSN_PREP_DROP_TAB_REQ, signal,
              PrepDropTabReq::SignalLength, JBB);
 }
@@ -6883,14 +6975,6 @@ Dbdict::execPREP_DROP_TAB_REQ(Signal* si
 }
 
 void
-Dbdict::prepDropTab_writeSchema(Signal* signal, SchemaOpPtr op_ptr)
-{
-  jamEntry();
-
-  prepDropTab_fromLocal(signal, op_ptr.p->op_key, 0);
-}
-
-void
 Dbdict::execPREP_DROP_TAB_CONF(Signal * signal)
 {
   jamEntry();
@@ -6900,7 +6984,7 @@ Dbdict::execPREP_DROP_TAB_CONF(Signal * 
   Uint32 block = refToBlock(conf->senderRef);
   ndbrequire(nodeId == getOwnNodeId() && block != DBDICT);
 
-  prepDropTab_fromLocal(signal, conf->senderData, 0);
+  dropTable_commit_fromLocal(signal, conf->senderData, 0);
 }
 
 void
@@ -6925,11 +7009,11 @@ Dbdict::execPREP_DROP_TAB_REF(Signal* si
      */
     errorCode = 0;
   }
-  prepDropTab_fromLocal(signal, ref->senderData, errorCode);
+  dropTable_commit_fromLocal(signal, ref->senderData, errorCode);
 }
 
 void
-Dbdict::prepDropTab_fromLocal(Signal* signal, Uint32 op_key, Uint32 errorCode)
+Dbdict::dropTable_commit_fromLocal(Signal* signal, Uint32 op_key, Uint32 errorCode)
 {
   SchemaOpPtr op_ptr;
   DropTableRecPtr dropTabPtr;
@@ -6942,71 +7026,50 @@ Dbdict::prepDropTab_fromLocal(Signal* si
     setError(op_ptr, errorCode, __LINE__);
   }
 
-  prepDropTab_nextStep(signal, op_ptr);
+  dropTabPtr.p->m_block++;
+  dropTable_commit_nextStep(signal, op_ptr);
 }
 
 void
-Dbdict::prepDropTab_complete(Signal* signal, SchemaOpPtr op_ptr)
+Dbdict::dropTable_commit_done(Signal* signal, SchemaOpPtr op_ptr)
 {
   jam();
-  D("prepDropTab_complete");
+  D("dropTable_commit_done");
 
   sendTransConf(signal, op_ptr);
 }
 
-// DropTable: COMMIT
+// DropTable: COMPLETE
 
 void
-Dbdict::dropTable_commit(Signal* signal, SchemaOpPtr op_ptr)
+Dbdict::dropTable_complete(Signal* signal, SchemaOpPtr op_ptr)
 {
+  jam();
+
   SchemaTransPtr trans_ptr = op_ptr.p->m_trans_ptr;
 
   DropTableRecPtr dropTabPtr;
   getOpRec(op_ptr, dropTabPtr);
 
-  D("dropTable_commit" << *op_ptr.p);
-
   TableRecordPtr tablePtr;
   c_tableRecordPool.getPtr(tablePtr, dropTabPtr.p->m_request.tableId);
 
   dropTabPtr.p->m_block = 0;
+  dropTabPtr.p->m_blockNo[0] = DBTC;
+  dropTabPtr.p->m_blockNo[1] = DBLQH; // wait usage + LCP
+  dropTabPtr.p->m_blockNo[2] = DBDIH; //
+  dropTabPtr.p->m_blockNo[3] = DBLQH; // release
+  dropTabPtr.p->m_blockNo[4] = 0;
   dropTabPtr.p->m_callback.m_callbackData =
     op_ptr.p->op_key;
   dropTabPtr.p->m_callback.m_callbackFunction =
-    safe_cast(&Dbdict::dropTab_complete);
-
-  if (tablePtr.p->m_tablespace_id != RNIL)
-  {
-    FilegroupPtr ptr;
-    ndbrequire(c_filegroup_hash.find(ptr, tablePtr.p->m_tablespace_id));
-    decrease_ref_count(ptr.p->m_obj_ptr_i);
-  }
-
-#if defined VM_TRACE || defined ERROR_INSERT
-  // from a newer execDROP_TAB_REQ version
-  {
-    char buf[1024];
-    Rope name(c_rope_pool, tablePtr.p->tableName);
-    name.copy(buf);
-    ndbout_c("Dbdict: drop name=%s,id=%u,obj_id=%u", buf, tablePtr.i,
-             tablePtr.p->m_obj_ptr_i);
-  }
-#endif
-
-  if (DictTabInfo::isIndex(tablePtr.p->tableType))
-  {
-    Ptr<TableRecord> basePtr;
-    c_tableRecordPool.getPtr(basePtr, tablePtr.p->primaryTableId);
+    safe_cast(&Dbdict::dropTable_complete_done);
 
-    LocalDLFifoList<TableRecord> list(c_tableRecordPool, basePtr.p->m_indexes);
-    list.remove(tablePtr);
-  }
-
-  dropTab_nextStep(signal, op_ptr);
+  dropTable_complete_nextStep(signal, op_ptr);
 }
 
 void
-Dbdict::dropTab_nextStep(Signal* signal, SchemaOpPtr op_ptr)
+Dbdict::dropTable_complete_nextStep(Signal* signal, SchemaOpPtr op_ptr)
 {
   DropTableRecPtr dropTabPtr;
   getOpRec(op_ptr, dropTabPtr);
@@ -7020,47 +7083,15 @@ Dbdict::dropTab_nextStep(Signal* signal,
   TableRecordPtr tablePtr;
   c_tableRecordPool.getPtr(tablePtr, impl_req->tableId);
 
-  Uint32& block = dropTabPtr.p->m_block; // ref
-  D("dropTab_nextStep" << hex << V(block) << *op_ptr.p);
+  Uint32 block = dropTabPtr.p->m_block;
+  Uint32 blockNo = dropTabPtr.p->m_blockNo[block];
+  D("dropTable_complete_nextStep" << hex << V(blockNo) << *op_ptr.p);
 
-  switch (block) {
-  case 0:
-    jam();
-    block = DBTC;
-    break;
-  case DBTC:
-    jam();
-    if (tablePtr.p->isTable() || tablePtr.p->isHashIndex())
-      block = DBACC;
-    if (tablePtr.p->isOrderedIndex())
-      block = DBTUP;
-    break;
-  case DBACC:
-    jam();
-    block = DBTUP;
-    break;
-  case DBTUP:
-    jam();
-    if (tablePtr.p->isTable() || tablePtr.p->isHashIndex())
-      block = DBLQH;
-    if (tablePtr.p->isOrderedIndex())
-      block = DBTUX;
-    break;
-  case DBTUX:
-    jam();
-    block = DBLQH;
-    break;
-  case DBLQH:
-    jam();
-    block = DBDIH;
-    break;
-  case DBDIH:
+  if (blockNo == 0)
+  {
     jam();
     execute(signal, dropTabPtr.p->m_callback, 0);
     return;
-  default:
-    ndbrequire(false);
-    break;
   }
 
   DropTabReq* req = (DropTabReq*)signal->getDataPtrSend();
@@ -7069,7 +7100,7 @@ Dbdict::dropTab_nextStep(Signal* signal,
   req->tableId = impl_req->tableId;
   req->requestType = impl_req->requestType;
 
-  BlockReference ref = numberToRef(block, getOwnNodeId());
+  BlockReference ref = numberToRef(blockNo, getOwnNodeId());
   sendSignal(ref, GSN_DROP_TAB_REQ, signal,
              DropTabReq::SignalLength, JBB);
 }
@@ -7084,7 +7115,7 @@ Dbdict::execDROP_TAB_CONF(Signal* signal
   Uint32 block = refToBlock(conf->senderRef);
   ndbrequire(nodeId == getOwnNodeId() && block != DBDICT);
 
-  dropTab_fromLocal(signal, conf->senderData);
+  dropTable_complete_fromLocal(signal, conf->senderData);
 }
 
 void
@@ -7098,11 +7129,11 @@ Dbdict::execDROP_TAB_REF(Signal* signal)
   ndbrequire(nodeId == getOwnNodeId() && block != DBDICT);
   ndbrequire(ref->errorCode == DropTabRef::NoSuchTable);
 
-  dropTab_fromLocal(signal, ref->senderData);
+  dropTable_complete_fromLocal(signal, ref->senderData);
 }
 
 void
-Dbdict::dropTab_fromLocal(Signal* signal, Uint32 op_key)
+Dbdict::dropTable_complete_fromLocal(Signal* signal, Uint32 op_key)
 {
   jamEntry();
 
@@ -7112,15 +7143,16 @@ Dbdict::dropTab_fromLocal(Signal* signal
   ndbrequire(!op_ptr.isNull());
   //const DropTabReq* impl_req = &dropTabPtr.p->m_request;
 
-  D("dropTab_fromLocal" << *op_ptr.p);
+  D("dropTable_complete_fromLocal" << *op_ptr.p);
 
-  dropTab_nextStep(signal, op_ptr);
+  dropTabPtr.p->m_block++;
+  dropTable_complete_nextStep(signal, op_ptr);
 }
 
 void
-Dbdict::dropTab_complete(Signal* signal,
-                         Uint32 op_key,
-                         Uint32 ret)
+Dbdict::dropTable_complete_done(Signal* signal,
+                                Uint32 op_key,
+                                Uint32 ret)
 {
   jam();
 
@@ -7156,15 +7188,6 @@ Dbdict::dropTab_complete(Signal* signal,
   sendTransConf(signal, trans_ptr);
 }
 
-// DropTable: COMPLETE
-
-void
-Dbdict::dropTable_complete(Signal* signal, SchemaOpPtr op_ptr)
-{
-  jam();
-  sendTransConf(signal, op_ptr);
-}
-
 // DropTable: ABORT
 
 void
@@ -7180,9 +7203,6 @@ Dbdict::dropTable_abortPrepare(Signal* s
 {
   D("dropTable_abortPrepare" << *op_ptr.p);
 
-  // no errors currently allowed...
-  ndbrequire(false);
-
   sendTransConf(signal, op_ptr);
 }
 
@@ -8270,94 +8290,6 @@ Dbdict::alterTable_backup_mutex_locked(S
     return;
   }
 
-  jam();
-
-  TableRecordPtr newTablePtr = alterTabPtr.p->m_newTablePtr;
-
-  const Uint32 changeMask = impl_req->changeMask;
-  Uint32& changeMaskDone = alterTabPtr.p->m_changeMaskDone; // ref
-
-  if (AlterTableReq::getNameFlag(changeMask))
-  {
-    jam();
-    const Uint32 sz = MAX_TAB_NAME_SIZE;
-    D("alter name:"
-      << " old=" << copyRope<sz>(tablePtr.p->tableName)
-      << " new=" << copyRope<sz>(newTablePtr.p->tableName));
-
-    Ptr<DictObject> obj_ptr;
-    c_obj_pool.getPtr(obj_ptr, tablePtr.p->m_obj_ptr_i);
-
-    // remove old name from hash
-    c_obj_hash.remove(obj_ptr);
-
-    // save old name and replace it by new
-    bool ok =
-      copyRope<sz>(alterTabPtr.p->m_oldTableName, tablePtr.p->tableName) &&
-      copyRope<sz>(tablePtr.p->tableName, newTablePtr.p->tableName);
-    ndbrequire(ok);
-
-    // add new name to object hash
-    obj_ptr.p->m_name = tablePtr.p->tableName;
-    c_obj_hash.add(obj_ptr);
-
-    AlterTableReq::setNameFlag(changeMaskDone, true);
-  }
-
-  if (AlterTableReq::getFrmFlag(changeMask))
-  {
-    jam();
-    // save old frm and replace it by new
-    const Uint32 sz = MAX_FRM_DATA_SIZE;
-    bool ok =
-      copyRope<sz>(alterTabPtr.p->m_oldFrmData, tablePtr.p->frmData) &&
-      copyRope<sz>(tablePtr.p->frmData, newTablePtr.p->frmData);
-    ndbrequire(ok);
-
-    AlterTableReq::setFrmFlag(changeMaskDone, true);
-  }
-
-  if (AlterTableReq::getAddAttrFlag(changeMask))
-  {
-    jam();
-
-    /* Move the column definitions to the real table definitions. */
-    LocalDLFifoList<AttributeRecord>
-      list(c_attributeRecordPool, tablePtr.p->m_attributes);
-    LocalDLFifoList<AttributeRecord>
-      newlist(c_attributeRecordPool, newTablePtr.p->m_attributes);
-
-    const Uint32 noOfNewAttr = impl_req->noOfNewAttr;
-    ndbrequire(noOfNewAttr > 0);
-    Uint32 i;
-
-    /* Move back to find the first column to move. */
-    AttributeRecordPtr pPtr;
-    ndbrequire(newlist.last(pPtr));
-    for (i = 1; i < noOfNewAttr; i++) {
-      jam();
-      ndbrequire(newlist.prev(pPtr));
-    }
-
-    /* Move columns. */
-    for (i = 0; i < noOfNewAttr; i++) {
-      AttributeRecordPtr qPtr = pPtr;
-      newlist.next(pPtr);
-      newlist.remove(qPtr);
-      list.addLast(qPtr);
-    }
-    tablePtr.p->noOfAttributes += noOfNewAttr;
-  }
-
-  if (AlterTableReq::getAddFragFlag(changeMask))
-  {
-    jam();
-    Uint32 save = tablePtr.p->fragmentCount;
-    tablePtr.p->fragmentCount = newTablePtr.p->fragmentCount;
-    newTablePtr.p->fragmentCount = save;
-    AlterTableReq::setAddFragFlag(changeMaskDone, true);
-  }
-
   /**
    * Write new table definition on prepare
    */
@@ -8544,6 +8476,9 @@ Dbdict::alterTable_commit(Signal* signal
   if (op_ptr.p->m_sections)
   {
     jam();
+    // main-op
+    ndbrequire(AlterTableReq::getReorgSubOp(impl_req->changeMask) == false);
+
     const OpSection& tabInfoSec =
       getOpSection(op_ptr, CreateTabReq::DICT_TAB_INFO);
     const Uint32 size = tabInfoSec.getSize();
@@ -8552,6 +8487,87 @@ Dbdict::alterTable_commit(Signal* signal
     tablePtr.p->packedSize = size;
     tablePtr.p->tableVersion = impl_req->newTableVersion;
     tablePtr.p->gciTableCreated = impl_req->gci;
+
+    TableRecordPtr newTablePtr = alterTabPtr.p->m_newTablePtr;
+
+    const Uint32 changeMask = impl_req->changeMask;
+
+    // perform DICT memory changes
+    if (AlterTableReq::getNameFlag(changeMask))
+    {
+      jam();
+      const Uint32 sz = MAX_TAB_NAME_SIZE;
+      D("alter name:"
+        << " old=" << copyRope<sz>(tablePtr.p->tableName)
+        << " new=" << copyRope<sz>(newTablePtr.p->tableName));
+
+      Ptr<DictObject> obj_ptr;
+      c_obj_pool.getPtr(obj_ptr, tablePtr.p->m_obj_ptr_i);
+
+      // remove old name from hash
+      c_obj_hash.remove(obj_ptr);
+
+      // save old name and replace it by new
+      bool ok =
+        copyRope<sz>(alterTabPtr.p->m_oldTableName, tablePtr.p->tableName) &&
+        copyRope<sz>(tablePtr.p->tableName, newTablePtr.p->tableName);
+      ndbrequire(ok);
+
+      // add new name to object hash
+      obj_ptr.p->m_name = tablePtr.p->tableName;
+      c_obj_hash.add(obj_ptr);
+    }
+
+    if (AlterTableReq::getFrmFlag(changeMask))
+    {
+      jam();
+      // save old frm and replace it by new
+      const Uint32 sz = MAX_FRM_DATA_SIZE;
+      bool ok =
+        copyRope<sz>(alterTabPtr.p->m_oldFrmData, tablePtr.p->frmData) &&
+        copyRope<sz>(tablePtr.p->frmData, newTablePtr.p->frmData);
+      ndbrequire(ok);
+    }
+
+    if (AlterTableReq::getAddAttrFlag(changeMask))
+    {
+      jam();
+
+      /* Move the column definitions to the real table definitions. */
+      LocalDLFifoList<AttributeRecord>
+        list(c_attributeRecordPool, tablePtr.p->m_attributes);
+      LocalDLFifoList<AttributeRecord>
+        newlist(c_attributeRecordPool, newTablePtr.p->m_attributes);
+
+      const Uint32 noOfNewAttr = impl_req->noOfNewAttr;
+      ndbrequire(noOfNewAttr > 0);
+      Uint32 i;
+
+      /* Move back to find the first column to move. */
+      AttributeRecordPtr pPtr;
+      ndbrequire(newlist.last(pPtr));
+      for (i = 1; i < noOfNewAttr; i++) {
+        jam();
+        ndbrequire(newlist.prev(pPtr));
+      }
+
+      /* Move columns. */
+      for (i = 0; i < noOfNewAttr; i++) {
+        AttributeRecordPtr qPtr = pPtr;
+        newlist.next(pPtr);
+        newlist.remove(qPtr);
+        list.addLast(qPtr);
+      }
+      tablePtr.p->noOfAttributes += noOfNewAttr;
+    }
+
+    if (AlterTableReq::getAddFragFlag(changeMask))
+    {
+      jam();
+      Uint32 save = tablePtr.p->fragmentCount;
+      tablePtr.p->fragmentCount = newTablePtr.p->fragmentCount;
+      newTablePtr.p->fragmentCount = save;
+    }
   }
 
   alterTabPtr.p->m_blockIndex = 0;
@@ -8884,77 +8900,6 @@ Dbdict::alterTable_abortPrepare(Signal* 
     return;
   }
 
-  // reset DICT memory changes (there was no prepare to disk)
-  {
-    jam();
-
-    TableRecordPtr tablePtr;
-    c_tableRecordPool.getPtr(tablePtr, impl_req->tableId);
-    TableRecordPtr newTablePtr = alterTabPtr.p->m_newTablePtr;
-
-    const Uint32 changeMask = alterTabPtr.p->m_changeMaskDone;
-
-    if (AlterTableReq::getNameFlag(changeMask))
-    {
-      jam();
-      const Uint32 sz = MAX_TAB_NAME_SIZE;
-      D("reset name:"
-        << " new=" << copyRope<sz>(tablePtr.p->tableName)
-        << " old=" << copyRope<sz>(alterTabPtr.p->m_oldTableName));
-
-      Ptr<DictObject> obj_ptr;
-      c_obj_pool.getPtr(obj_ptr, tablePtr.p->m_obj_ptr_i);
-
-      // remove new name from hash
-      c_obj_hash.remove(obj_ptr);
-
-      // copy old name back
-      bool ok =
-        copyRope<sz>(tablePtr.p->tableName, alterTabPtr.p->m_oldTableName);
-      ndbrequire(ok);
-
-      // add old name to object hash
-      obj_ptr.p->m_name = tablePtr.p->tableName;
-      c_obj_hash.add(obj_ptr);
-    }
-
-    if (AlterTableReq::getFrmFlag(changeMask))
-    {
-      jam();
-      const Uint32 sz = MAX_FRM_DATA_SIZE;
-
-      // copy old frm back
-      bool ok =
-        copyRope<sz>(tablePtr.p->frmData, alterTabPtr.p->m_oldFrmData);
-      ndbrequire(ok);
-    }
-
-    if (AlterTableReq::getAddAttrFlag(changeMask))
-    {
-      jam();
-
-      /* Release the extra columns, not to be used anyway. */
-      LocalDLFifoList<AttributeRecord>
-        list(c_attributeRecordPool, tablePtr.p->m_attributes);
-
-      const Uint32 noOfNewAttr = impl_req->noOfNewAttr;
-      ndbrequire(noOfNewAttr > 0);
-      Uint32 i;
-
-      for (i= 0; i < noOfNewAttr; i++) {
-        AttributeRecordPtr pPtr;
-        ndbrequire(list.last(pPtr));
-        list.release(pPtr);
-      }
-    }
-
-    if (AlterTableReq::getAddFragFlag(changeMask))
-    {
-      jam();
-      tablePtr.p->fragmentCount = newTablePtr.p->fragmentCount;
-    }
-  }
-
   if (alterTabPtr.p->m_blockIndex > 0)
   {
     jam();
@@ -9274,9 +9219,11 @@ void Dbdict::execGET_TABINFOREQ(Signal* 
   else if (refToBlock(req->senderRef) != DBUTIL && /** XXX cheat */
            refToBlock(req->senderRef) != SUMA)
   {
+    jam();
     Uint32 err;
     if ((err = check_read_obj(objEntry)))
     {
+      jam();
       // cannot see another uncommitted trans
       sendGET_TABINFOREF(signal, req, (GetTabInfoRef::ErrorCode)err, __LINE__);
       return;
@@ -9290,6 +9237,8 @@ void Dbdict::execGET_TABINFOREQ(Signal* 
   c_retrieveRecord.currentSent = 0;
   c_retrieveRecord.m_useLongSig = useLongSig;
   c_retrieveRecord.m_table_type = objEntry->m_tableType;
+  c_retrieveRecord.schemaTransId = transId;
+  c_retrieveRecord.requestType = req->requestType;
   c_packTable.m_state = PackTable::PTS_GET_TAB;
 
   Uint32 len = 4;
@@ -17508,6 +17457,13 @@ void
 Dbdict::execDICT_TAKEOVER_REQ(Signal* signal)
  {
    jamEntry();
+
+   if (!checkNodeFailSequence(signal))
+   {
+     jam();
+     return;
+   }
+
    DictTakeoverReq* req = (DictTakeoverReq*)signal->getDataPtr();
    Uint32 masterRef = req->senderRef;
    Uint32 op_count = 0;
@@ -18482,7 +18438,7 @@ void
 Dbdict::execBACKUP_LOCK_TAB_REQ(Signal* signal)
 {
   jamEntry();
-  const BackupLockTab *req = (const BackupLockTab *)signal->getDataPtrSend();
+  BackupLockTab *req = (BackupLockTab *)signal->getDataPtrSend();
   Uint32 senderRef = req->m_senderRef;
   Uint32 tableId = req->m_tableId;
   Uint32 lock = req->m_lock_unlock;
@@ -18490,10 +18446,15 @@ Dbdict::execBACKUP_LOCK_TAB_REQ(Signal* 
   TableRecordPtr tablePtr;
   c_tableRecordPool.getPtr(tablePtr, tableId, true);
 
+  Uint32 err = 0;
   if(lock == BackupLockTab::LOCK_TABLE)
   {
     jam();
-    tablePtr.p->m_read_locked = 1;
+    if ((err = check_write_obj(tableId)) == 0)
+    {
+      jam();
+      tablePtr.p->m_read_locked = 1;
+    }
   }
   else
   {
@@ -18501,6 +18462,7 @@ Dbdict::execBACKUP_LOCK_TAB_REQ(Signal* 
     tablePtr.p->m_read_locked = 0;
   }
 
+  req->errorCode = err;
   sendSignal(senderRef, GSN_BACKUP_LOCK_TAB_CONF, signal,
              BackupLockTab::SignalLength, JBB);
 }

=== modified file 'storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp'
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2009-08-21 13:01:34 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2009-09-19 06:30:50 +0000
@@ -1079,6 +1079,9 @@ private:
      * Long signal stuff
      */
     bool m_useLongSig;
+
+    Uint32 schemaTransId;
+    Uint32 requestType;
   };
   RetrieveRecord c_retrieveRecord;
 
@@ -1876,6 +1879,7 @@ private:
 
   Uint32 check_read_obj(Uint32 objId, Uint32 transId = 0);
   Uint32 check_read_obj(SchemaFile::TableEntry*, Uint32 transId = 0);
+  Uint32 check_write_obj(Uint32 objId, Uint32 transId = 0);
   Uint32 check_write_obj(Uint32, Uint32, SchemaFile::EntryState, ErrorInfo&);
 
   ArrayPool<SchemaTrans> c_schemaTransPool;
@@ -2264,6 +2268,8 @@ private:
     MutexHandle2<BACKUP_DEFINE_MUTEX> m_define_backup_mutex;
 
     Uint32 m_block;
+    enum { BlockCount = 5 };
+    Uint32 m_blockNo[BlockCount];
     Callback m_callback;
 
     DropTableRec() :
@@ -2298,15 +2304,16 @@ private:
 
   // prepare
   void dropTable_backup_mutex_locked(Signal*, Uint32 op_key, Uint32 ret);
-  void prepDropTab_nextStep(Signal*, SchemaOpPtr);
-  void prepDropTab_writeSchema(Signal* signal, SchemaOpPtr);
-  void prepDropTab_fromLocal(Signal*, Uint32 op_key, Uint32 errorCode);
-  void prepDropTab_complete(Signal*, SchemaOpPtr);
 
   // commit
-  void dropTab_nextStep(Signal*, SchemaOpPtr);
-  void dropTab_fromLocal(Signal*, Uint32 op_key);
-  void dropTab_complete(Signal*, Uint32 op_key, Uint32 ret);
+  void dropTable_commit_nextStep(Signal*, SchemaOpPtr);
+  void dropTable_commit_fromLocal(Signal*, Uint32 op_key, Uint32 errorCode);
+  void dropTable_commit_done(Signal*, SchemaOpPtr);
+
+  // complete
+  void dropTable_complete_nextStep(Signal*, SchemaOpPtr);
+  void dropTable_complete_fromLocal(Signal*, Uint32 op_key);
+  void dropTable_complete_done(Signal*, Uint32 op_key, Uint32 ret);
 
   // MODULE: AlterTable
 
@@ -2334,9 +2341,6 @@ private:
     RopeHandle m_oldTableName;
     RopeHandle m_oldFrmData;
 
-    // what was actually changed so far
-    Uint32 m_changeMaskDone;
-
     // connect ptr towards TUP, DIH, LQH
     Uint32 m_dihAddFragPtr;
     Uint32 m_lqhFragPtr;
@@ -2362,7 +2366,6 @@ private:
       memset(&m_newAttrData, 0, sizeof(m_newAttrData));
       m_tablePtr.setNull();
       m_newTablePtr.setNull();
-      m_changeMaskDone = 0;
       m_dihAddFragPtr = RNIL;
       m_lqhFragPtr = RNIL;
       m_blockNo[0] = DBLQH;

=== modified file 'storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp'
--- a/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp	2009-08-24 08:18:43 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp	2009-09-19 06:30:50 +0000
@@ -522,12 +522,6 @@ public:
       Uint32 tabUserPtr;
     } m_dropTab;
 
-    struct DropTable {
-      Uint32 senderRef;
-      Uint32 senderData;
-      SignalCounter waitDropTabCount;
-    } m_prepDropTab;
-
     Uint8 kvalue;
     Uint8 noOfBackups;
     Uint8 noPages;
@@ -793,7 +787,7 @@ private:
   void execCREATE_FRAGMENTATION_REQ(Signal*);
   
   void waitDropTabWritingToFile(Signal *, TabRecordPtr tabPtr);
-  void checkPrepDropTabComplete(Signal *, TabRecordPtr tabPtr);
+  void checkDropTabComplete(Signal *, TabRecordPtr tabPtr);
 
   void execDICT_LOCK_CONF(Signal* signal);
   void execDICT_LOCK_REF(Signal* signal);

=== modified file 'storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2009-08-24 08:18:43 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2009-09-19 06:30:50 +0000
@@ -7699,7 +7699,8 @@ void Dbdih::addtabrefuseLab(Signal* sign
 /***********              DELETE TABLE  MODULE                   *************/
 /*****************************************************************************/
 void
-Dbdih::execDROP_TAB_REQ(Signal* signal){
+Dbdih::execDROP_TAB_REQ(Signal* signal)
+{
   jamEntry();
   DropTabReq* req = (DropTabReq*)signal->getDataPtr();
 
@@ -7716,17 +7717,91 @@ Dbdih::execDROP_TAB_REQ(Signal* signal){
   case DropTabReq::OnlineDropTab:
     jam();
     ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_DROPPING);
-    releaseTable(tabPtr);
     break;
   case DropTabReq::CreateTabDrop:
     jam();
-    releaseTable(tabPtr);
     break;
   case DropTabReq::RestartDropTab:
     break;
   }
   
-  startDeleteFile(signal, tabPtr);
+  if(isMaster())
+  {
+    /**
+     * Remove from queue
+     */
+    NodeRecordPtr nodePtr;
+    for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
+      jam();
+      ptrAss(nodePtr, nodeRecord);
+      if (c_lcpState.m_participatingLQH.get(nodePtr.i))
+      {
+
+	Uint32 index = 0;
+	Uint32 count = nodePtr.p->noOfQueuedChkpt;
+	while(index < count){
+	  if(nodePtr.p->queuedChkpt[index].tableId == tabPtr.i){
+	    jam();
+	    //	    g_eventLogger->info("Unqueuing %d", index);
+
+	    count--;
+	    for(Uint32 i = index; i<count; i++){
+	      jam();
+	      nodePtr.p->queuedChkpt[i] = nodePtr.p->queuedChkpt[i + 1];
+	    }
+	  } else {
+	    index++;
+	  }
+	}
+	nodePtr.p->noOfQueuedChkpt = count;
+      }
+    }
+  }
+
+  {
+    /**
+     * Check table lcp state
+     */
+    bool ok = false;
+    switch(tabPtr.p->tabLcpStatus){
+    case TabRecord::TLS_COMPLETED:
+    case TabRecord::TLS_WRITING_TO_FILE:
+      ok = true;
+      jam();
+      break;
+      return;
+    case TabRecord::TLS_ACTIVE:
+      ok = true;
+      jam();
+
+      tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
+
+      /**
+       * First check if all fragments are done
+       */
+      if (checkLcpAllTablesDoneInLqh(__LINE__))
+      {
+	jam();
+
+        g_eventLogger->info("This is the last table");
+
+	/**
+	 * Then check if saving of tab info is done for all tables
+	 */
+	LcpStatus a = c_lcpState.lcpStatus;
+	checkLcpCompletedLab(signal);
+
+        if(a != c_lcpState.lcpStatus)
+        {
+          g_eventLogger->info("And all tables are written to already written disk");
+        }
+      }
+      break;
+    }
+    ndbrequire(ok);
+  }
+
+  waitDropTabWritingToFile(signal, tabPtr);
 }
 
 void Dbdih::startDeleteFile(Signal* signal, TabRecordPtr tabPtr)
@@ -7781,6 +7856,7 @@ void Dbdih::tableDeleteLab(Signal* signa
   
   tabPtr.p->m_dropTab.tabUserPtr = RNIL;
   tabPtr.p->m_dropTab.tabUserRef = 0;
+  releaseTable(tabPtr);
 }//Dbdih::tableDeleteLab()
 
 
@@ -10192,7 +10268,8 @@ void Dbdih::initLcpLab(Signal* signal, U
 
     ptrAss(tabPtr, tabRecord);
 
-    if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE) {
+    if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
+    {
       jam();
       tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
       continue;
@@ -12224,9 +12301,9 @@ void Dbdih::execLCP_FRAG_REP(Signal* sig
     return;
   }//if
   
-  if(fromTimeQueue){
+  if(fromTimeQueue)
+  {
     jam();
-    
     ndbrequire(c_lcpState.noOfLcpFragRepOutstanding > 0);
     c_lcpState.noOfLcpFragRepOutstanding--;
   }
@@ -12250,14 +12327,19 @@ void Dbdih::execLCP_FRAG_REP(Signal* sig
    */
   m_local_lcp_state.lcp_frag_rep(lcpReport);
 
-  if(tableDone){
+  if (tableDone)
+  {
     jam();
 
-    if(tabPtr.p->tabStatus == TabRecord::TS_DROPPING){
+    if (tabPtr.p->tabStatus == TabRecord::TS_IDLE ||
+        tabPtr.p->tabStatus == TabRecord::TS_DROPPING)
+    {
       jam();
       g_eventLogger->info("TS_DROPPING - Neglecting to save Table: %d Frag: %d - ",
                           tableId, fragId);
-    } else {
+    }
+    else
+    {
       jam();
       /**
        * Write table description to file
@@ -12322,7 +12404,8 @@ void Dbdih::execLCP_FRAG_REP(Signal* sig
   /* ----------------------------------------------------------------------- */
   // Check if there are more LCP's to start up.
   /* ----------------------------------------------------------------------- */
-  if(isMaster()){
+  if(isMaster())
+  {
     jam();
 
     /**
@@ -12360,7 +12443,8 @@ Dbdih::checkLcpAllTablesDoneInLqh(Uint32
     jam();
     ptrAss(tabPtr, tabRecord);
     if ((tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) &&
-        (tabPtr.p->tabLcpStatus == TabRecord::TLS_ACTIVE)) {
+        (tabPtr.p->tabLcpStatus == TabRecord::TLS_ACTIVE))
+    {
       jam();
       /**
        * Nope, not finished with all tables
@@ -12478,6 +12562,13 @@ Dbdih::reportLcpCompletion(const LcpFrag
   tabPtr.i = tableId;
   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
   
+  if (tabPtr.p->tabStatus == TabRecord::TS_DROPPING ||
+      tabPtr.p->tabStatus == TabRecord::TS_IDLE)
+  {
+    jam();
+    return true;
+  }
+
   FragmentstorePtr fragPtr;
   getFragstore(tabPtr.p, fragId, fragPtr);
   
@@ -12601,7 +12692,8 @@ Dbdih::sendLCP_FRAG_ORD(Signal* signal, 
 
 void Dbdih::checkLcpCompletedLab(Signal* signal) 
 {
-  if(c_lcpState.lcpStatus < LCP_TAB_COMPLETED){
+  if(c_lcpState.lcpStatus < LCP_TAB_COMPLETED)
+  {
     jam();
     return;
   }
@@ -12610,13 +12702,12 @@ void Dbdih::checkLcpCompletedLab(Signal*
   for (tabPtr.i = 0; tabPtr.i < ctabFileSize; tabPtr.i++) {
     jam();
     ptrAss(tabPtr, tabRecord);
-    if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
-      if (tabPtr.p->tabLcpStatus != TabRecord::TLS_COMPLETED) {
-        jam();
-        return;
-      }//if
-    }//if
-  }//for
+    if (tabPtr.p->tabLcpStatus != TabRecord::TLS_COMPLETED)
+    {
+      jam();
+      return;
+    }
+  }
 
   CRASH_INSERTION2(7027, isMaster());
   CRASH_INSERTION2(7018, !isMaster());
@@ -15762,7 +15853,7 @@ void Dbdih::setNodeRestartInfoBits(Signa
   }//for
 
 #ifdef ERROR_INSERT
-  if (!tmp.isclear())
+  if (ERROR_INSERTED(7220) && !tmp.isclear())
   {
     jam();
 
@@ -16513,7 +16604,8 @@ Dbdih::execPREP_DROP_TAB_REQ(Signal* sig
     ndbrequire(ok);
   }
 
-  if(err != PrepDropTabRef::OK){
+  if(err != PrepDropTabRef::OK)
+  {
     jam();
     PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
     ref->senderRef = reference();
@@ -16526,88 +16618,19 @@ Dbdih::execPREP_DROP_TAB_REQ(Signal* sig
   }
 
   tabPtr.p->tabStatus = TabRecord::TS_DROPPING;
-  tabPtr.p->m_prepDropTab.senderRef = senderRef;
-  tabPtr.p->m_prepDropTab.senderData = senderData;
-  
-  if(isMaster()){
-    /**
-     * Remove from queue
-     */
-    NodeRecordPtr nodePtr;
-    for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
-      jam();
-      ptrAss(nodePtr, nodeRecord);
-      if (c_lcpState.m_participatingLQH.get(nodePtr.i)){
-	
-	Uint32 index = 0;
-	Uint32 count = nodePtr.p->noOfQueuedChkpt;
-	while(index < count){
-	  if(nodePtr.p->queuedChkpt[index].tableId == tabPtr.i){
-	    jam();
-	    //	    g_eventLogger->info("Unqueuing %d", index);
-	    
-	    count--;
-	    for(Uint32 i = index; i<count; i++){
-	      jam();
-	      nodePtr.p->queuedChkpt[i] = nodePtr.p->queuedChkpt[i + 1];
-	    }
-	  } else {
-	    index++;
-	  }
-	}
-	nodePtr.p->noOfQueuedChkpt = count;
-      }
-    }
-  }
-  
-  { /**
-     * Check table lcp state
-     */
-    
-    bool ok = false;
-    switch(tabPtr.p->tabLcpStatus){
-    case TabRecord::TLS_COMPLETED:
-    case TabRecord::TLS_WRITING_TO_FILE:
-      ok = true;
-      jam();
-      break;
-      return;
-    case TabRecord::TLS_ACTIVE:
-      ok = true;
-      jam();
-      
-      tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
-      
-      /**
-       * First check if all fragments are done
-       */
-      if(checkLcpAllTablesDoneInLqh(__LINE__)){
-	jam();
-	
-        g_eventLogger->info("This is the last table");
-	
-	/**
-	 * Then check if saving of tab info is done for all tables
-	 */
-	LcpStatus a = c_lcpState.lcpStatus;
-	checkLcpCompletedLab(signal);
-	
-        if(a != c_lcpState.lcpStatus){
-          g_eventLogger->info("And all tables are written to already written disk");
-        }
-      }
-      break;
-    }
-    ndbrequire(ok);
-  }  
-  
-  waitDropTabWritingToFile(signal, tabPtr);
+  PrepDropTabConf* conf = (PrepDropTabConf*)signal->getDataPtrSend();
+  conf->tableId = tabPtr.i;
+  conf->senderRef = reference();
+  conf->senderData = senderData;
+  sendSignal(senderRef, GSN_PREP_DROP_TAB_CONF,
+             signal, PrepDropTabConf::SignalLength, JBB);
 }
 
 void
 Dbdih::waitDropTabWritingToFile(Signal* signal, TabRecordPtr tabPtr){
   
-  if(tabPtr.p->tabLcpStatus == TabRecord::TLS_WRITING_TO_FILE){
+  if (tabPtr.p->tabLcpStatus == TabRecord::TLS_WRITING_TO_FILE)
+  {
     jam();
     signal->theData[0] = DihContinueB::WAIT_DROP_TAB_WRITING_TO_FILE;
     signal->theData[1] = tabPtr.i;
@@ -16616,33 +16639,13 @@ Dbdih::waitDropTabWritingToFile(Signal* 
   }
 
   ndbrequire(tabPtr.p->tabLcpStatus ==  TabRecord::TLS_COMPLETED);
-  checkPrepDropTabComplete(signal, tabPtr);
+  checkDropTabComplete(signal, tabPtr);
 }
 
 void
-Dbdih::checkPrepDropTabComplete(Signal* signal, TabRecordPtr tabPtr){
-  
-  if(tabPtr.p->tabLcpStatus !=  TabRecord::TLS_COMPLETED){
-    jam();
-    return;
-  }
-  
-  if(!tabPtr.p->m_prepDropTab.waitDropTabCount.done()){
-    jam();
-    return;
-  }
-  
-  const Uint32 ref = tabPtr.p->m_prepDropTab.senderRef;
-  if(ref != 0)
-  {
-    PrepDropTabConf* conf = (PrepDropTabConf*)signal->getDataPtrSend();
-    conf->tableId = tabPtr.i;
-    conf->senderRef = reference();
-    conf->senderData = tabPtr.p->m_prepDropTab.senderData;
-    sendSignal(tabPtr.p->m_prepDropTab.senderRef, GSN_PREP_DROP_TAB_CONF, 
-	       signal, PrepDropTabConf::SignalLength, JBB);
-    tabPtr.p->m_prepDropTab.senderRef = 0;
-  }
+Dbdih::checkDropTabComplete(Signal* signal, TabRecordPtr tabPtr)
+{
+  startDeleteFile(signal, tabPtr);
 }
 
 void

=== modified file 'storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2009-09-11 07:53:48 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2009-09-21 09:45:54 +0000
@@ -238,7 +238,7 @@ class Lgman;
 #define ZCHECK_LCP_STOP_BLOCKED 17
 #define ZSCAN_MARKERS 18
 #define ZOPERATION_EVENT_REP 19
-#define ZPREP_DROP_TABLE 20
+#define ZDROP_TABLE_WAIT_USAGE 20
 #define ZENABLE_EXPAND_CHECK 21
 #define ZRETRY_TCKEYREF 22
 #define ZWAIT_REORG_SUMA_FILTER_ENABLED 23
@@ -1819,8 +1819,12 @@ public:
       TABLE_DEFINED = 0,
       NOT_DEFINED = 1,
       ADD_TABLE_ONGOING = 2,
-      PREP_DROP_TABLE_ONGOING = 3,
-      PREP_DROP_TABLE_DONE = 4
+      PREP_DROP_TABLE_DONE = 3,
+      DROP_TABLE_WAIT_USAGE = 4,
+      DROP_TABLE_WAIT_DONE = 5,
+      DROP_TABLE_ACC = 6,
+      DROP_TABLE_TUP = 7,
+      DROP_TABLE_TUX = 8
     };
     
     UintR fragrec[MAX_FRAG_PER_NODE];
@@ -2186,6 +2190,9 @@ private:
 
   void execPREP_DROP_TAB_REQ(Signal* signal);
   void execDROP_TAB_REQ(Signal* signal);
+  void execDROP_TAB_REF(Signal*);
+  void execDROP_TAB_CONF(Signal*);
+  void dropTable_nextStep(Signal*, AddFragRecordPtr);
 
   void execLQH_ALLOCREQ(Signal* signal);
   void execTUP_DEALLOCREQ(Signal* signal);
@@ -2209,7 +2216,8 @@ private:
   void sendLCP_COMPLETE_REP(Signal* signal, Uint32 lcpId);
   void sendEMPTY_LCP_CONF(Signal* signal, bool idle);
   void sendLCP_FRAGIDREQ(Signal* signal);
-  void sendLCP_FRAG_REP(Signal * signal, const LcpRecord::FragOrd &) const;
+  void sendLCP_FRAG_REP(Signal * signal, const LcpRecord::FragOrd &,
+                        const Fragrecord*) const;
 
   void updatePackedList(Signal* signal, HostRecord * ahostptr, Uint16 hostId);
   void LQHKEY_abort(Signal* signal, int errortype);
@@ -2542,8 +2550,8 @@ private:
   void sendCreateTabReq(Signal*, AddFragRecordPtr);
   void sendAddAttrReq(Signal* signal);
   void sendAddFragReq(Signal* signal);
-  void checkDropTab(Signal*);
-  Uint32 checkDropTabState(Tablerec::TableStatus, Uint32) const;
+  void dropTab_wait_usage(Signal*);
+  Uint32 get_table_state_error(Ptr<Tablerec> tabPtr) const;
 
   void remove_commit_marker(TcConnectionrec * const regTcPtr);
   // Initialisation
@@ -2987,6 +2995,10 @@ public:
 #ifdef ERROR_INSERT
   void TRACE_OP_DUMP(const TcConnectionrec* regTcPtr, const char * pos);
 #endif
+
+#ifdef ERROR_INSERT
+  Uint32 c_master_node_id;
+#endif
 };
 
 inline

=== modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp	2009-09-21 09:45:54 +0000
@@ -27,6 +27,10 @@
 
 void Dblqh::initData() 
 {
+#ifdef ERROR_INSERT
+  c_master_node_id = RNIL;
+#endif
+
   caddfragrecFileSize = ZADDFRAGREC_FILE_SIZE;
   cgcprecFileSize = ZGCPREC_FILE_SIZE;
   chostFileSize = MAX_NDB_NODES;
@@ -318,6 +322,8 @@ Dblqh::Dblqh(Block_context& ctx, Uint32 
 
   addRecSignal(GSN_PREP_DROP_TAB_REQ, &Dblqh::execPREP_DROP_TAB_REQ);
   addRecSignal(GSN_DROP_TAB_REQ, &Dblqh::execDROP_TAB_REQ);
+  addRecSignal(GSN_DROP_TAB_REF, &Dblqh::execDROP_TAB_REF);
+  addRecSignal(GSN_DROP_TAB_CONF, &Dblqh::execDROP_TAB_CONF);
 
   addRecSignal(GSN_LQH_ALLOCREQ, &Dblqh::execLQH_ALLOCREQ);
   addRecSignal(GSN_LQH_WRITELOG_REQ, &Dblqh::execLQH_WRITELOG_REQ);

=== modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2009-09-11 07:53:48 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2009-09-21 09:45:54 +0000
@@ -473,9 +473,9 @@ void Dblqh::execCONTINUEB(Signal* signal
     signal->theData[1] = 0;
     sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 5000, 2);
     break;
-  case ZPREP_DROP_TABLE:
+  case ZDROP_TABLE_WAIT_USAGE:
     jam();
-    checkDropTab(signal);
+    dropTab_wait_usage(signal);
     return;
     break;
   case ZENABLE_EXPAND_CHECK:
@@ -1031,6 +1031,10 @@ void Dblqh::execREAD_NODESCONF(Signal* s
   ndbrequire(ind == cnoOfNodes);
   ndbrequire(cnoOfNodes >= 1 && cnoOfNodes < MAX_NDB_NODES);
   ndbrequire(!(cnoOfNodes == 1 && cstartType == NodeState::ST_NODE_RESTART));
+
+#ifdef ERROR_INSERT
+  c_master_node_id = readNodes->masterNodeId;
+#endif
   
   caddNodeState = ZFALSE;
   if (cstartType == NodeState::ST_SYSTEM_RESTART) 
@@ -2141,7 +2145,31 @@ Dblqh::execPREP_DROP_TAB_REQ(Signal* sig
   ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
   
   Uint32 errCode = 0;
-  errCode = checkDropTabState(tabPtr.p->tableStatus, GSN_PREP_DROP_TAB_REQ);
+  switch(tabPtr.p->tableStatus) {
+  case Tablerec::TABLE_DEFINED:
+    jam();
+    break;
+  case Tablerec::NOT_DEFINED:
+    jam();
+    // Fall through
+  case Tablerec::ADD_TABLE_ONGOING:
+    jam();
+    errCode = PrepDropTabRef::NoSuchTable;
+    break;
+  case Tablerec::PREP_DROP_TABLE_DONE:
+    jam();
+    errCode = PrepDropTabRef::DropInProgress;
+    break;
+  case Tablerec::DROP_TABLE_WAIT_USAGE:
+  case Tablerec::DROP_TABLE_WAIT_DONE:
+  case Tablerec::DROP_TABLE_ACC:
+  case Tablerec::DROP_TABLE_TUP:
+  case Tablerec::DROP_TABLE_TUX:
+    jam();
+    errCode = PrepDropTabRef::DropInProgress;
+    break;
+  }
+
   if(errCode != 0)
   {
     jam();
@@ -2156,17 +2184,18 @@ Dblqh::execPREP_DROP_TAB_REQ(Signal* sig
     return;
   }
   
-  tabPtr.p->tableStatus = Tablerec::PREP_DROP_TABLE_ONGOING;
+  tabPtr.p->tableStatus = Tablerec::PREP_DROP_TABLE_DONE;

   
-  signal->theData[0] = ZPREP_DROP_TABLE;
-  signal->theData[1] = tabPtr.i;
-  signal->theData[2] = senderRef;
-  signal->theData[3] = senderData;
-  checkDropTab(signal);
+  PrepDropTabConf * conf = (PrepDropTabConf*)signal->getDataPtrSend();
+  conf->tableId = tabPtr.i;
+  conf->senderRef = reference();
+  conf->senderData = senderData;
+  sendSignal(senderRef, GSN_PREP_DROP_TAB_CONF, signal,
+	     PrepDropTabConf::SignalLength, JBB);
 }
 
 void
-Dblqh::checkDropTab(Signal* signal){
+Dblqh::dropTab_wait_usage(Signal* signal){
 
   TablerecPtr tabPtr;
   tabPtr.i = signal->theData[1];
@@ -2175,9 +2204,10 @@ Dblqh::checkDropTab(Signal* signal){
   Uint32 senderRef = signal->theData[2];
   Uint32 senderData = signal->theData[3];
   
-  ndbrequire(tabPtr.p->tableStatus == Tablerec::PREP_DROP_TABLE_ONGOING);
+  ndbrequire(tabPtr.p->tableStatus == Tablerec::DROP_TABLE_WAIT_USAGE);
   
-  if(tabPtr.p->usageCount > 0){
+  if(tabPtr.p->usageCount > 0)
+  {
     jam();
     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 4);
     return;
@@ -2186,35 +2216,39 @@ Dblqh::checkDropTab(Signal* signal){
   bool lcpDone = true;
   lcpPtr.i = 0;
   ptrAss(lcpPtr, lcpRecord);
-  if(lcpPtr.p->lcpState != LcpRecord::LCP_IDLE){
+  if(lcpPtr.p->lcpState != LcpRecord::LCP_IDLE)
+  {
     jam();
 
-    if(lcpPtr.p->currentFragment.lcpFragOrd.tableId == tabPtr.i){
+    if(lcpPtr.p->currentFragment.lcpFragOrd.tableId == tabPtr.i)
+    {
       jam();
       lcpDone = false;
     }
     
     if(lcpPtr.p->lcpQueued && 
-       lcpPtr.p->queuedFragment.lcpFragOrd.tableId == tabPtr.i){
+       lcpPtr.p->queuedFragment.lcpFragOrd.tableId == tabPtr.i)
+    {
       jam();
       lcpDone = false;
     }
   }
   
-  if(!lcpDone){
+  if(!lcpDone)
+  {
     jam();
     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 4);
     return;
   }
   
-  tabPtr.p->tableStatus = Tablerec::PREP_DROP_TABLE_DONE;
+  tabPtr.p->tableStatus = Tablerec::DROP_TABLE_WAIT_DONE;
 
-  PrepDropTabConf * conf = (PrepDropTabConf*)signal->getDataPtrSend();
+  DropTabConf * conf = (DropTabConf*)signal->getDataPtrSend();
   conf->tableId = tabPtr.i;
   conf->senderRef = reference();
   conf->senderData = senderData;
-  sendSignal(senderRef, GSN_PREP_DROP_TAB_CONF, signal,
-	     PrepDropTabConf::SignalLength, JBB);
+  sendSignal(senderRef, GSN_DROP_TAB_CONF, signal,
+	     DropTabConf::SignalLength, JBB);
 }
 
 void
@@ -2230,98 +2264,173 @@ Dblqh::execDROP_TAB_REQ(Signal* signal){
   tabPtr.i = req->tableId;
   ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
   
-  do {
-    if(req->requestType == DropTabReq::RestartDropTab){
+  Uint32 errCode = 0;
+  switch((DropTabReq::RequestType)req->requestType) {
+  case DropTabReq::RestartDropTab:
+    jam();
+    tabPtr.p->tableStatus = Tablerec::DROP_TABLE_WAIT_DONE;
+    break;
+  case DropTabReq::CreateTabDrop:
+    jam();
+    tabPtr.p->tableStatus = Tablerec::DROP_TABLE_WAIT_DONE;
+    break;
+  case DropTabReq::OnlineDropTab:
+    jam();
+    switch(tabPtr.p->tableStatus) {
+    case Tablerec::TABLE_DEFINED:
       jam();
+      errCode = DropTabRef::DropWoPrep;
       break;
-    }
-    
-    if(req->requestType == DropTabReq::OnlineDropTab){
-      jam();
-      Uint32 errCode = 0;
-      errCode = checkDropTabState(tabPtr.p->tableStatus, GSN_DROP_TAB_REQ);
-      if(errCode != 0){
-	jam();
-	
-	DropTabRef* ref = (DropTabRef*)signal->getDataPtrSend();
-	ref->senderRef = reference();
-	ref->senderData = senderData;
-	ref->tableId = tabPtr.i;
-	ref->errorCode = errCode;
-	sendSignal(senderRef, GSN_DROP_TAB_REF, signal,
-		   DropTabRef::SignalLength, JBB);
-	return;
-      }
-    }
-
-    removeTable(tabPtr.i);
-    
-  } while(false);
-  
-  ndbrequire(tabPtr.p->usageCount == 0);
-  tabPtr.p->tableStatus = Tablerec::NOT_DEFINED;
-  
-  DropTabConf * const dropConf = (DropTabConf *)signal->getDataPtrSend();
-  dropConf->senderRef = reference();
-  dropConf->senderData = senderData;
-  dropConf->tableId = tabPtr.i;
-  sendSignal(senderRef, GSN_DROP_TAB_CONF,
-             signal, DropTabConf::SignalLength, JBB);
-}
-
-Uint32
-Dblqh::checkDropTabState(Tablerec::TableStatus status, Uint32 gsn) const{
-  
-  if(gsn == GSN_PREP_DROP_TAB_REQ){
-    switch(status){
     case Tablerec::NOT_DEFINED:
       jam();
-      // Fall through
-    case Tablerec::ADD_TABLE_ONGOING:
-      jam();
-      return PrepDropTabRef::NoSuchTable;
+      errCode = DropTabRef::NoSuchTable;
       break;
-    case Tablerec::PREP_DROP_TABLE_ONGOING:
+    case Tablerec::ADD_TABLE_ONGOING:
       jam();
-      return PrepDropTabRef::PrepDropInProgress;
-      break;
+      ndbassert(false);
     case Tablerec::PREP_DROP_TABLE_DONE:
       jam();
-      return PrepDropTabRef::DropInProgress;
+      tabPtr.p->tableStatus = Tablerec::DROP_TABLE_WAIT_USAGE;

+      signal->theData[0] = ZDROP_TABLE_WAIT_USAGE;
+      signal->theData[1] = tabPtr.i;
+      signal->theData[2] = senderRef;
+      signal->theData[3] = senderData;
+      dropTab_wait_usage(signal);
+      return;
       break;
-    case Tablerec::TABLE_DEFINED:
+    case Tablerec::DROP_TABLE_WAIT_USAGE:
+    case Tablerec::DROP_TABLE_ACC:
+    case Tablerec::DROP_TABLE_TUP:
+    case Tablerec::DROP_TABLE_TUX:
+      ndbrequire(false);
+    case Tablerec::DROP_TABLE_WAIT_DONE:
       jam();
-      return 0;
       break;
     }
-    ndbrequire(0);
   }
 
-  if(gsn == GSN_DROP_TAB_REQ){
-    switch(status){
-    case Tablerec::NOT_DEFINED:
-      jam();
-      // Fall through
-    case Tablerec::ADD_TABLE_ONGOING:
-      jam();
-      return DropTabRef::NoSuchTable;
-      break;
-    case Tablerec::PREP_DROP_TABLE_ONGOING:
+  if (errCode)
+  {
+    jam();
+    DropTabRef * ref = (DropTabRef*)signal->getDataPtrSend();
+    ref->tableId = tabPtr.i;
+    ref->senderRef = reference();
+    ref->senderData = senderData;
+    ref->errorCode = errCode;
+    sendSignal(senderRef, GSN_DROP_TAB_REF, signal,
+               DropTabRef::SignalLength, JBB);
+    return;
+  }
+
+  ndbrequire(tabPtr.p->usageCount == 0);
+  seizeAddfragrec(signal);
+  addfragptr.p->m_dropFragReq.tableId = tabPtr.i;
+  addfragptr.p->m_dropFragReq.senderRef = senderRef;
+  addfragptr.p->m_dropFragReq.senderData = senderData;
+
+  dropTable_nextStep(signal, addfragptr);
+}
+
+void
+Dblqh::execDROP_TAB_REF(Signal* signal)
+{
+  jamEntry();
+  DropTabRef * ref = (DropTabRef*)signal->getDataPtr();
+
+#if defined ERROR_INSERT || defined VM_TRACE
+  jamLine(ref->errorCode);
+  ndbrequire(false);
+#endif
+
+  Ptr<AddFragRecord> addFragPtr;
+  addFragPtr.i = ref->senderData;
+  ptrCheckGuard(addFragPtr, caddfragrecFileSize, addFragRecord);
+  dropTable_nextStep(signal, addFragPtr);
+}
+
+void
+Dblqh::execDROP_TAB_CONF(Signal* signal)
+{
+  jamEntry();
+  DropTabConf * conf = (DropTabConf*)signal->getDataPtr();
+
+  Ptr<AddFragRecord> addFragPtr;
+  addFragPtr.i = conf->senderData;
+  ptrCheckGuard(addFragPtr, caddfragrecFileSize, addFragRecord);
+  dropTable_nextStep(signal, addFragPtr);
+}
+
+void
+Dblqh::dropTable_nextStep(Signal* signal, Ptr<AddFragRecord> addFragPtr)
+{
+  jam();
+
+  TablerecPtr tabPtr;
+  tabPtr.i = addFragPtr.p->m_dropFragReq.tableId;
+  ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
+
+  Uint32 ref = 0;
+  if (tabPtr.p->tableStatus == Tablerec::DROP_TABLE_WAIT_DONE)
+  {
+    jam();
+    if (DictTabInfo::isTable(tabPtr.p->tableType) ||
+        DictTabInfo::isHashIndex(tabPtr.p->tableType))
+    {
       jam();
-      return DropTabRef::PrepDropInProgress;
-      break;
-    case Tablerec::PREP_DROP_TABLE_DONE:
+      ref = calcInstanceBlockRef(DBACC);
+      tabPtr.p->tableStatus = Tablerec::DROP_TABLE_ACC;
+    }
+    else
+    {
       jam();
-      return 0;
-      break;
-    case Tablerec::TABLE_DEFINED:
+      ref = calcInstanceBlockRef(DBTUP);
+      tabPtr.p->tableStatus = Tablerec::DROP_TABLE_TUP;
+    }
+  }
+  else if (tabPtr.p->tableStatus == Tablerec::DROP_TABLE_ACC)
+  {
+    jam();
+    ref = calcInstanceBlockRef(DBTUP);
+    tabPtr.p->tableStatus = Tablerec::DROP_TABLE_TUP;
+  }
+  else if (tabPtr.p->tableStatus == Tablerec::DROP_TABLE_TUP)
+  {
+    jam();
+    if (DictTabInfo::isOrderedIndex(tabPtr.p->tableType))
+    {
       jam();
-      return DropTabRef::DropWoPrep;
+      ref = calcInstanceBlockRef(DBTUX);
+      tabPtr.p->tableStatus = Tablerec::DROP_TABLE_TUX;
     }
-    ndbrequire(0);
   }
-  ndbrequire(0);
-  return RNIL;
+
+  if (ref)
+  {
+    jam();
+    DropTabReq* req = (DropTabReq*)signal->getDataPtrSend();
+    req->senderData = addFragPtr.i;
+    req->senderRef = reference();
+    req->tableId = tabPtr.i;
+    req->tableVersion = tabPtr.p->schemaVersion;
+    req->requestType = DropTabReq::OnlineDropTab;
+    sendSignal(ref, GSN_DROP_TAB_REQ, signal,
+               DropTabReq::SignalLength, JBB);
+    return;
+  }
+
+  removeTable(tabPtr.i);
+  tabPtr.p->tableStatus = Tablerec::NOT_DEFINED;
+
+  ref = addFragPtr.p->m_dropFragReq.senderRef;
+  DropTabConf* conf = (DropTabConf*)signal->getDataPtrSend();
+  conf->senderRef = reference();
+  conf->senderData = addFragPtr.p->m_dropFragReq.senderData;
+  conf->tableId = tabPtr.i;
+  sendSignal(ref, GSN_DROP_TAB_CONF, signal,
+             DropTabConf::SignalLength, JBB);
+
+  addfragptr = addFragPtr;
+  releaseAddfragrec(signal);
 }
 
 void Dblqh::removeTable(Uint32 tableId)
@@ -2424,7 +2533,14 @@ Dblqh::execALTER_TAB_REQ(Signal* signal)
   }
   else
   {
-    ndbrequire(false);
+    jam();
+    AlterTabRef* ref = (AlterTabRef*)signal->getDataPtrSend();
+    ref->senderRef = reference();
+    ref->senderData = senderData;
+    ref->connectPtr = connectPtr;
+    ref->errorCode = errCode;
+    sendSignal(senderRef, GSN_ALTER_TAB_REF, signal,
+               AlterTabRef::SignalLength, JBB);
   }
 }
 
@@ -2605,6 +2721,39 @@ void Dblqh::noFreeRecordLab(Signal* sign
   return;
 }//Dblqh::noFreeRecordLab()
 
+Uint32
+Dblqh::get_table_state_error(Ptr<Tablerec> tabPtr) const
+{
+  switch(tabPtr.p->tableStatus){
+  case Tablerec::NOT_DEFINED:
+    jam();
+    return ZTABLE_NOT_DEFINED;
+    break;
+  case Tablerec::ADD_TABLE_ONGOING:
+    jam();
+  case Tablerec::PREP_DROP_TABLE_DONE:
+    jam();
+  case Tablerec::DROP_TABLE_WAIT_USAGE:
+    jam();
+  case Tablerec::DROP_TABLE_WAIT_DONE:
+    jam();
+  case Tablerec::DROP_TABLE_ACC:
+    jam();
+  case Tablerec::DROP_TABLE_TUP:
+    jam();
+  case Tablerec::DROP_TABLE_TUX:
+    jam();
+    return PrepDropTabRef::DropInProgress;
+    break;
+  case Tablerec::TABLE_DEFINED:
+    ndbassert(0);
+    return ZTABLE_NOT_DEFINED;
+    break;
+  }
+  ndbassert(0);
+  return ~Uint32(0);
+}
+
 void Dblqh::LQHKEY_abort(Signal* signal, int errortype)
 {
   switch (errortype) {
@@ -2629,16 +2778,7 @@ void Dblqh::LQHKEY_abort(Signal* signal,
     break;
   case 4:
     jam();
-    if(tabptr.p->tableStatus == Tablerec::NOT_DEFINED){
-      jam();
-      terrorCode = ZTABLE_NOT_DEFINED;
-    } else if (tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_ONGOING ||
-	       tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_DONE){
-      jam();
-      terrorCode = ZDROP_TABLE_IN_PROGRESS;
-    } else {
-      ndbrequire(0);
-    }
+    terrorCode = get_table_state_error(tabptr);
     break;
   case 5:
     jam();
@@ -8172,6 +8312,10 @@ void Dblqh::execNODE_FAILREP(Signal* sig
     }//if
   }//for
 
+#ifdef ERROR_INSERT
+  c_master_node_id = nodeFail->masterNodeId;
+#endif
+  
   lcpPtr.i = 0;
   ptrAss(lcpPtr, lcpRecord);
   
@@ -8287,6 +8431,7 @@ void Dblqh::lqhTransNextLab(Signal* sign
        *
        * now scan markers
        */
+#ifdef ERROR_INSERT
       if (ERROR_INSERTED(5050))
       {
         ndbout_c("send ZSCAN_MARKERS with 5s delay and killing master");
@@ -8298,11 +8443,11 @@ void Dblqh::lqhTransNextLab(Signal* sign
         sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 5000, 4);
         
         signal->theData[0] = 9999;
-        sendSignal(numberToRef(CMVMI, 
-                               refToNode(tcNodeFailptr.p->newTcBlockref)), 
+        sendSignal(numberToRef(CMVMI, c_master_node_id), 
                    GSN_NDB_TAMPER, signal, 1, JBB);
         return;
       }
+#endif
       scanMarkers(signal, tcNodeFailptr.i, 0, RNIL);
       return;
     }//if
@@ -9296,16 +9441,8 @@ error_handler:
   return;
 
  error_handler_early_1:
-  if(tabptr.p->tableStatus == Tablerec::NOT_DEFINED){
-    jam();
-    errorCode = ZTABLE_NOT_DEFINED;
-  } else if (tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_ONGOING ||
-	     tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_DONE){
-    jam();
-    errorCode = ZDROP_TABLE_IN_PROGRESS;
-  } else {
-    ndbrequire(0);
-  }
+  errorCode = get_table_state_error(tabptr);
+
  error_handler_early:
   releaseSections(handle);
   ref = (ScanFragRef*)&signal->theData[0];
@@ -12177,7 +12314,8 @@ void Dblqh::execLCP_FRAG_ORD(Signal* sig
   ptrAss(lcpPtr, lcpRecord);
   
   lcpPtr.p->lastFragmentFlag = lcpFragOrd->lastFragmentFlag;
-  if (lcpFragOrd->lastFragmentFlag) {
+  if (lcpFragOrd->lastFragmentFlag)
+  {
     jam();
     if (lcpPtr.p->lcpState == LcpRecord::LCP_IDLE) {
       jam();
@@ -12198,17 +12336,12 @@ void Dblqh::execLCP_FRAG_ORD(Signal* sig
   tabptr.i = lcpFragOrd->tableId;
   ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
   
-  ndbrequire(tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_ONGOING ||
-	     tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_DONE ||
-	     tabptr.p->tableStatus == Tablerec::TABLE_DEFINED);
-
-  ndbrequire(getFragmentrec(signal, lcpFragOrd->fragmentId));
-  
   lcpPtr.i = 0;
   ptrAss(lcpPtr, lcpRecord);
   ndbrequire(!lcpPtr.p->lcpQueued);
 
-  if (c_lcpId < lcpFragOrd->lcpId) {
+  if (c_lcpId < lcpFragOrd->lcpId)
+  {
     jam();
 
     lcpPtr.p->firstFragmentFlag= true;
@@ -12220,18 +12353,25 @@ void Dblqh::execLCP_FRAG_ORD(Signal* sig
     clcpCompletedState = LCP_RUNNING;
   }
   
-  if(tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_DONE){
+  if (tabptr.p->tableStatus != Tablerec::TABLE_DEFINED)
+  {
     jam();
     LcpRecord::FragOrd fragOrd;
-    fragOrd.fragPtrI = fragptr.i;
+    fragOrd.fragPtrI = RNIL;
     fragOrd.lcpFragOrd = * lcpFragOrd;
-    sendLCP_FRAG_REP(signal, fragOrd);
+
+    Fragrecord tmp;
+    tmp.maxGciInLcp = cnewestGci;
+    tmp.maxGciCompletedInLcp = cnewestCompletedGci;
+    sendLCP_FRAG_REP(signal, fragOrd, &tmp);
     return;
   }
 
   cnoOfFragsCheckpointed++;
+  ndbrequire(getFragmentrec(signal, lcpFragOrd->fragmentId));
 
-  if (lcpPtr.p->lcpState != LcpRecord::LCP_IDLE) {
+  if (lcpPtr.p->lcpState != LcpRecord::LCP_IDLE)
+  {
     ndbrequire(lcpPtr.p->lcpQueued == false);
     lcpPtr.p->lcpQueued = true;
     lcpPtr.p->queuedFragment.fragPtrI = fragptr.i;
@@ -12490,10 +12630,9 @@ void Dblqh::execBACKUP_FRAGMENT_CONF(Sig
 
 void
 Dblqh::sendLCP_FRAG_REP(Signal * signal, 
-			const LcpRecord::FragOrd & fragOrd) const {
-  
-  const Fragrecord* fragPtrP = c_fragment_pool.getConstPtr(fragOrd.fragPtrI);
-  
+			const LcpRecord::FragOrd & fragOrd,
+                        const Fragrecord * fragPtrP) const
+{
   ndbrequire(fragOrd.lcpFragOrd.lcpNo < MAX_LCP_STORED);
   LcpFragRep * const lcpReport = (LcpFragRep *)&signal->theData[0];
   lcpReport->nodeId = cownNodeid;
@@ -12535,7 +12674,8 @@ void Dblqh::contChkpNextFragLab(Signal* 
   /**
    * Send rep when fragment is done + unblocked
    */
-  sendLCP_FRAG_REP(signal, lcpPtr.p->currentFragment);
+  sendLCP_FRAG_REP(signal, lcpPtr.p->currentFragment,
+                   c_fragment_pool.getPtr(lcpPtr.p->currentFragment.fragPtrI));
   
   /* ------------------------------------------------------------------------
    *       WE ALSO RELEASE THE LOCAL LCP RECORDS.
@@ -12577,8 +12717,9 @@ void Dblqh::sendLCP_FRAGIDREQ(Signal* si
   TablerecPtr tabPtr;
   tabPtr.i = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
   ptrAss(tabPtr, tablerec);
-  if(tabPtr.p->tableStatus == Tablerec::PREP_DROP_TABLE_ONGOING ||
-     tabPtr.p->tableStatus == Tablerec::PREP_DROP_TABLE_DONE){
+
+  if(tabPtr.p->tableStatus != Tablerec::TABLE_DEFINED)
+  {
     jam();
     /**
      * Fake that the fragment is done

=== modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhProxy.cpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhProxy.cpp	2009-03-20 09:58:04 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhProxy.cpp	2009-09-21 11:13:12 +0000
@@ -989,6 +989,12 @@ DblqhProxy::sendDROP_TAB_CONF(Signal* si
     conf->tableId = ss.m_req.tableId;
     sendSignal(dictRef, GSN_DROP_TAB_CONF,
                signal, DropTabConf::SignalLength, JBB);
+
+    // inform DBTUP proxy
+    DropTabReq* req = (DropTabReq*)signal->getDataPtrSend();
+    *req = ss.m_req;
+    EXECUTE_DIRECT(DBTUP, GSN_DROP_TAB_REQ,
+                   signal, DropTabReq::SignalLength);
   } else {
     jam();
     DropTabRef* ref = (DropTabRef*)signal->getDataPtrSend();
@@ -1285,6 +1291,22 @@ DblqhProxy::execLQH_TRANSREQ(Signal* sig
   ss.m_req = *req;
   ndbrequire(signal->getLength() == LqhTransReq::SignalLength);
   sendREQ(signal, ss);
+
+  /**
+   * See if this is a "resend" (i.e multi TC failure)
+   *   and if so, mark "old" record as invalid
+   */
+  Uint32 nodeId = ss.m_req.failedNodeId;
+  for (Uint32 i = 0; i<NDB_ARRAY_SIZE(c_ss_LQH_TRANSREQ.m_pool); i++)
+  {
+    if (c_ss_LQH_TRANSREQ.m_pool[i].m_ssId != 0 &&
+        c_ss_LQH_TRANSREQ.m_pool[i].m_ssId != ss.m_ssId &&
+        c_ss_LQH_TRANSREQ.m_pool[i].m_req.failedNodeId == nodeId)
+    {
+      jam();
+      c_ss_LQH_TRANSREQ.m_pool[i].m_valid = false;
+    }
+  }
 }
 
 void
@@ -1308,6 +1330,67 @@ DblqhProxy::execLQH_TRANSCONF(Signal* si
   Uint32 ssId = conf->tcRef;
   Ss_LQH_TRANSREQ& ss = ssFind<Ss_LQH_TRANSREQ>(ssId);
   ss.m_conf = *conf;
+
+  BlockReference ref = signal->getSendersBlockRef();
+  ndbrequire(refToMain(ref) == number());
+  const Uint32 ino = refToInstance(ref);
+  const Uint32 worker = workerIndex(ino);
+  
+  ndbrequire(ref == workerRef(worker));
+  ndbrequire(worker < c_workers);
+  
+  if (ss.m_valid == false)
+  {
+    jam();
+    /**
+     * This is an in-flight signal to an old take-over "session"
+     */
+    if (ss.m_conf.operationStatus == LqhTransConf::LastTransConf)
+    {
+      jam();
+      ndbrequire(ss.m_workerMask.get(worker));
+      ss.m_workerMask.clear(worker);
+      if (ss.m_workerMask.isclear())
+      {
+        jam();
+        ssRelease<Ss_LQH_TRANSREQ>(ssId);
+      }
+    }
+    return;
+  }
+  else if (ss.m_conf.operationStatus == LqhTransConf::LastTransConf)
+  {
+    jam();
+    /**
+     * When completing(LqhTransConf::LastTransConf) a LQH_TRANSREQ
+     *   also check if one can release obsoleteded records
+     *
+     * This could have been done on each LQH_TRANSCONF, but there is no
+     *   urgency, so it's ok todo only on LastTransConf
+     */
+    Uint32 nodeId = ss.m_req.failedNodeId;
+    for (Uint32 i = 0; i<NDB_ARRAY_SIZE(c_ss_LQH_TRANSREQ.m_pool); i++)
+    {
+      if (c_ss_LQH_TRANSREQ.m_pool[i].m_ssId != 0 &&
+          c_ss_LQH_TRANSREQ.m_pool[i].m_ssId != ssId &&
+          c_ss_LQH_TRANSREQ.m_pool[i].m_req.failedNodeId == nodeId &&
+          c_ss_LQH_TRANSREQ.m_pool[i].m_valid == false)
+      {
+        jam();
+        if (c_ss_LQH_TRANSREQ.m_pool[i].m_workerMask.get(worker))
+        {
+          jam();
+          c_ss_LQH_TRANSREQ.m_pool[i].m_workerMask.clear(worker);
+          if (c_ss_LQH_TRANSREQ.m_pool[i].m_workerMask.isclear())
+          {
+            jam();
+            ssRelease<Ss_LQH_TRANSREQ>(c_ss_LQH_TRANSREQ.m_pool[i].m_ssId);
+          }
+        }
+      }
+    }
+  }
+
   recvCONF(signal, ss);
 }
 

=== modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhProxy.hpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhProxy.hpp	2009-03-13 07:49:42 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhProxy.hpp	2009-09-21 11:13:12 +0000
@@ -307,13 +307,19 @@ protected:
   // GSN_LQH_TRANSREQ
   struct Ss_LQH_TRANSREQ : SsParallel {
     static const char* name() { return "LQH_TRANSREQ"; }
+    /**
+     * Is this entry valid, or has it been made obsolete by
+     *   a new LQH_TRANSREQ (i.e a new TC-failure)
+     */
+    bool m_valid; 
     LqhTransReq m_req;
     LqhTransConf m_conf; // latest conf
     Ss_LQH_TRANSREQ() {
+      m_valid = true;
       m_sendREQ = (SsFUNC)&DblqhProxy::sendLQH_TRANSREQ;
       m_sendCONF = (SsFUNC)&DblqhProxy::sendLQH_TRANSCONF;
     }
-    enum { poolSize = 1 };
+    enum { poolSize = MAX_NDB_NODES };
     static SsPool<Ss_LQH_TRANSREQ>& pool(LocalProxy* proxy) {
       return ((DblqhProxy*)proxy)->c_ss_LQH_TRANSREQ;
     }

=== modified file 'storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2009-09-01 12:32:10 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2009-09-21 08:42:40 +0000
@@ -7177,7 +7177,7 @@ void Dbtc::sendAbortedAfterTimeout(Signa
       signal->theData[0] = TcContinueB::ZABORT_TIMEOUT_BREAK;
       signal->theData[1] = tcConnectptr.i;
       signal->theData[2] = apiConnectptr.i;      
-      if (ERROR_INSERTED(8050))
+      if (ERROR_INSERTED(8080))
       {
 	ndbout_c("sending ZABORT_TIMEOUT_BREAK delayed (%d %d)", 
 		 Tcheck, apiConnectptr.p->counter);
@@ -7923,11 +7923,25 @@ Dbtc::checkScanFragList(Signal* signal,
 void Dbtc::execTAKE_OVERTCCONF(Signal* signal) 
 {
   jamEntry();
+
+  if (!checkNodeFailSequence(signal))
+  {
+    jam();
+    return;
+  }
+
   tfailedNodeId = signal->theData[0];
   hostptr.i = tfailedNodeId;
   ptrCheckGuard(hostptr, chostFilesize, hostRecord);
 
-  if (signal->getSendersBlockRef() != reference())
+  Uint32 senderRef = signal->theData[1];
+  if (signal->getLength() < 2)
+  {
+    jam();
+    senderRef = 0; // currently only used to see if it's from self
+  }
+
+  if (senderRef != reference())
   {
     jam();
 
@@ -8259,7 +8273,8 @@ void Dbtc::completeTransAtTakeOverDoLast
     /*------------------------------------------------------------*/
     NodeReceiverGroup rg(DBTC, c_alive_nodes);
     signal->theData[0] = tcNodeFailptr.p->takeOverNode;
-    sendSignal(rg, GSN_TAKE_OVERTCCONF, signal, 1, JBB);
+    signal->theData[1] = reference();
+    sendSignal(rg, GSN_TAKE_OVERTCCONF, signal, 2, JBB);
     
     if (tcNodeFailptr.p->queueIndex > 0) {
       jam();

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2009-09-04 11:33:38 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2009-09-16 11:12:55 +0000
@@ -440,10 +440,8 @@ typedef Ptr<Fragoperrec> FragoperrecPtr;
     Uint32 noOfDynFix;
     Uint32 noOfDynamic;
     Uint32 tabDesOffset[7];
-    Uint32 desAllocSize;
     Uint32 tableDescriptor;
     Uint32 dynTabDesOffset[3];
-    Uint32 dynDesAllocSize;
     Uint32 dynTableDescriptor;
   };
   typedef Ptr<AlterTabOperation> AlterTabOperationPtr;
@@ -2866,6 +2864,8 @@ private:
   Uint32 getTabDescrOffsets(Uint32, Uint32, Uint32, Uint32*);
   Uint32 getDynTabDescrOffsets(Uint32 MaskSize, Uint32* offset);
   Uint32 allocTabDescr(Uint32 allocSize);
+  void releaseTabDescr(Uint32 desc);
+
   void freeTabDescr(Uint32 retRef, Uint32 retNo, bool normal = true);
   Uint32 getTabDescrWord(Uint32 index);
   void setTabDescrWord(Uint32 index, Uint32 word);

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp	2009-09-09 10:58:10 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp	2009-09-21 12:17:02 +0000
@@ -724,6 +724,7 @@ Dbtup::initTab(Tablerec* const regTabPtr
 
   regTabPtr->tabDescriptor = RNIL;
   regTabPtr->readKeyArray = RNIL;
+  regTabPtr->dynTabDescriptor = RNIL;
 
   regTabPtr->m_bits = 0;
 

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp	2009-09-04 11:33:38 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp	2009-09-21 12:17:02 +0000
@@ -770,7 +770,6 @@ Dbtup::handleAlterTablePrepare(Signal *s
       return;
     }
     regAlterTabOpPtr.p->tableDescriptor= tableDescriptorRef;
-    regAlterTabOpPtr.p->desAllocSize= allocSize;
 
     /*
       Get new pointers into tableDescriptor, and copy over old data.
@@ -868,15 +867,26 @@ Dbtup::handleAlterTablePrepare(Signal *s
     /* Allocate the new (possibly larger) dynamic descriptor. */
     allocSize= getDynTabDescrOffsets((dyn_nullbits+31)>>5,
                                      regAlterTabOpPtr.p->dynTabDesOffset);
-    Uint32 dynTableDescriptorRef= allocTabDescr(allocSize);
+    Uint32 dynTableDescriptorRef = RNIL;
+    if (ERROR_INSERTED(4029))
+    {
+      jam();
+      dynTableDescriptorRef = RNIL;
+      terrorCode = ZMEM_NOTABDESCR_ERROR;
+      CLEAR_ERROR_INSERT_VALUE;
+    }
+    else
+    {
+      jam();
+      dynTableDescriptorRef = allocTabDescr(allocSize);
+    }
     if (dynTableDescriptorRef == RNIL) {
       jam();
-      freeTabDescr(tableDescriptorRef, regAlterTabOpPtr.p->desAllocSize);
+      releaseTabDescr(tableDescriptorRef);
       releaseAlterTabOpRec(regAlterTabOpPtr);
       sendAlterTabRef(signal, terrorCode);
       return;
     }
-    regAlterTabOpPtr.p->dynDesAllocSize= allocSize;
     regAlterTabOpPtr.p->dynTableDescriptor= dynTableDescriptorRef;
     connectPtr = regAlterTabOpPtr.i;
   }
@@ -1031,10 +1041,8 @@ Dbtup::handleAlterTableAbort(Signal *sig
       regAlterTabOpPtr.i= req->connectPtr;
       ptrCheckGuard(regAlterTabOpPtr, cnoOfAlterTabOps, alterTabOperRec);
 
-      freeTabDescr(regAlterTabOpPtr.p->tableDescriptor,
-                   regAlterTabOpPtr.p->desAllocSize);
-      freeTabDescr(regAlterTabOpPtr.p->dynTableDescriptor,
-                   regAlterTabOpPtr.p->dynDesAllocSize);
+      releaseTabDescr(regAlterTabOpPtr.p->tableDescriptor);
+      releaseTabDescr(regAlterTabOpPtr.p->dynTableDescriptor);
       releaseAlterTabOpRec(regAlterTabOpPtr);
     }
   }
@@ -1568,12 +1576,7 @@ void Dbtup::releaseTabDescr(Tablerec* co
 
     // move to start of descriptor
     descriptor -= offset[3];
-    Uint32 retNo= getTabDescrWord(descriptor + ZTD_DATASIZE);
-    ndbrequire(getTabDescrWord(descriptor + ZTD_HEADER) == ZTD_TYPE_NORMAL);
-    ndbrequire(retNo == getTabDescrWord((descriptor + retNo) - ZTD_TR_SIZE));
-    ndbrequire(ZTD_TYPE_NORMAL ==
-               getTabDescrWord((descriptor + retNo) - ZTD_TR_TYPE));
-    freeTabDescr(descriptor, retNo);
+    releaseTabDescr(descriptor);
   }
 
   descriptor= regTabPtr->dynTabDescriptor;
@@ -1583,12 +1586,7 @@ void Dbtup::releaseTabDescr(Tablerec* co
     regTabPtr->dynTabDescriptor= RNIL;
     regTabPtr->dynVarSizeMask= NULL;
     regTabPtr->dynFixSizeMask= NULL;
-    Uint32 retNo= getTabDescrWord(descriptor + ZTD_DATASIZE);
-    ndbrequire(getTabDescrWord(descriptor + ZTD_HEADER) == ZTD_TYPE_NORMAL);
-    ndbrequire(retNo == getTabDescrWord((descriptor + retNo) - ZTD_TR_SIZE));
-    ndbrequire(ZTD_TYPE_NORMAL ==
-               getTabDescrWord((descriptor + retNo) - ZTD_TR_TYPE));
-    freeTabDescr(descriptor, retNo);
+    releaseTabDescr(descriptor);
   }
 }
 

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupProxy.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupProxy.cpp	2009-04-17 19:02:12 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupProxy.cpp	2009-09-19 06:30:50 +0000
@@ -32,10 +32,7 @@ DbtupProxy::DbtupProxy(Block_context& ct
 {
   // GSN_CREATE_TAB_REQ
   addRecSignal(GSN_CREATE_TAB_REQ, &DbtupProxy::execCREATE_TAB_REQ);
-
-  // GSN_DROP_TAB_REQ
   addRecSignal(GSN_DROP_TAB_REQ, &DbtupProxy::execDROP_TAB_REQ);
-  addRecSignal(GSN_DROP_TAB_CONF, &DbtupProxy::execDROP_TAB_CONF);
 
   // GSN_BUILD_INDX_IMPL_REQ
   addRecSignal(GSN_BUILD_INDX_IMPL_REQ, &DbtupProxy::execBUILD_INDX_IMPL_REQ);
@@ -101,71 +98,14 @@ DbtupProxy::execCREATE_TAB_REQ(Signal* s
   D("proxy: created table" << V(tableId));
 }
 
-// GSN_DROP_TAB_REQ
-
 void
 DbtupProxy::execDROP_TAB_REQ(Signal* signal)
 {
   const DropTabReq* req = (const DropTabReq*)signal->getDataPtr();
-  Uint32 ssId = getSsId(req);
-  Ss_DROP_TAB_REQ& ss = ssSeize<Ss_DROP_TAB_REQ>(ssId);
-  ss.m_req = *req;
-  ndbrequire(signal->getLength() == DropTabReq::SignalLength);
-  sendREQ(signal, ss);
-}
-
-void
-DbtupProxy::sendDROP_TAB_REQ(Signal* signal, Uint32 ssId)
-{
-  Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
-
-  DropTabReq* req = (DropTabReq*)signal->getDataPtrSend();
-  *req = ss.m_req;
-  req->senderRef = reference();
-  req->senderData = ssId; // redundant since tableId is used
-  sendSignal(workerRef(ss.m_worker), GSN_DROP_TAB_REQ,
-             signal, DropTabReq::SignalLength, JBB);
-}
-
-void
-DbtupProxy::execDROP_TAB_CONF(Signal* signal)
-{
-  const DropTabConf* conf = (const DropTabConf*)signal->getDataPtr();
-  Uint32 ssId = getSsId(conf);
-  Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
-  recvCONF(signal, ss);
-}
-
-void
-DbtupProxy::sendDROP_TAB_CONF(Signal* signal, Uint32 ssId)
-{
-  Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
-  BlockReference dictRef = ss.m_req.senderRef;
-
-  if (!lastReply(ss))
-    return;
-
-  if (ss.m_error == 0) {
-    jam();
-    DropTabConf* conf = (DropTabConf*)signal->getDataPtrSend();
-    conf->senderRef = reference();
-    conf->senderData = ss.m_req.senderData;
-    conf->tableId = ss.m_req.tableId;
-    sendSignal(dictRef, GSN_DROP_TAB_CONF,
-               signal, DropTabConf::SignalLength, JBB);
-    // for completeness (not needed for UNDO code)
-    const Uint32 tableId = conf->tableId;
-    // make sure to not crash for nothing
-    if (tableId < c_tableRecSize && c_tableRec[tableId] == 1) {
-      jam();
-      c_tableRec[tableId] = 0;
-      D("proxy: dropped table" << V(tableId));
-    }
-  } else {
-    ndbrequire(false);
-  }
-
-  ssRelease<Ss_DROP_TAB_REQ>(ssId);
+  const Uint32 tableId = req->tableId;
+  ndbrequire(tableId < c_tableRecSize);
+  c_tableRec[tableId] = 0;
+  D("proxy: dropped table" << V(tableId));
 }
 
 // GSN_BUILD_INDX_IMPL_REQ

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupProxy.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupProxy.hpp	2009-04-17 19:02:12 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupProxy.hpp	2009-09-19 06:30:50 +0000
@@ -43,30 +43,8 @@ protected:
 
   // GSN_CREATE_TAB_REQ
   void execCREATE_TAB_REQ(Signal*);
-
   // GSN_DROP_TAB_REQ
-  struct Ss_DROP_TAB_REQ : SsParallel {
-    DropTabReq m_req;
-    Ss_DROP_TAB_REQ() {
-      m_sendREQ = (SsFUNC)&DbtupProxy::sendDROP_TAB_REQ;
-      m_sendCONF = (SsFUNC)&DbtupProxy::sendDROP_TAB_CONF;
-    }
-    enum { poolSize = 1 };
-    static SsPool<Ss_DROP_TAB_REQ>& pool(LocalProxy* proxy) {
-      return ((DbtupProxy*)proxy)->c_ss_DROP_TAB_REQ;
-    }
-  };
-  SsPool<Ss_DROP_TAB_REQ> c_ss_DROP_TAB_REQ;
-  Uint32 getSsId(const DropTabReq* req) {
-    return SsIdBase | req->tableId;
-  }
-  Uint32 getSsId(const DropTabConf* conf) {
-    return SsIdBase | conf->tableId;
-  }
   void execDROP_TAB_REQ(Signal*);
-  void sendDROP_TAB_REQ(Signal*, Uint32 ssId);
-  void execDROP_TAB_CONF(Signal*);
-  void sendDROP_TAB_CONF(Signal*, Uint32 ssId);
 
   // GSN_BUILD_INDX_IMPL_REQ
   struct Ss_BUILD_INDX_IMPL_REQ : SsParallel {

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp	2009-05-26 18:53:34 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp	2009-09-16 10:52:41 +0000
@@ -70,6 +70,20 @@ Dbtup::getDynTabDescrOffsets(Uint32 Mask
   return allocSize;
 }
 
+void
+Dbtup::releaseTabDescr(Uint32 descriptor)
+{
+  if (descriptor != RNIL)
+  {
+    Uint32 retNo= getTabDescrWord(descriptor + ZTD_DATASIZE);
+    ndbrequire(getTabDescrWord(descriptor + ZTD_HEADER) == ZTD_TYPE_NORMAL);
+    ndbrequire(retNo == getTabDescrWord((descriptor + retNo) - ZTD_TR_SIZE));
+    ndbrequire(ZTD_TYPE_NORMAL ==
+               getTabDescrWord((descriptor + retNo) - ZTD_TR_TYPE));
+    freeTabDescr(descriptor, retNo);
+  }
+}
+
 Uint32 Dbtup::allocTabDescr(Uint32 allocSize)
 {
   Uint32 reference = RNIL;

=== modified file 'storage/ndb/src/kernel/blocks/dbtux/DbtuxProxy.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtux/DbtuxProxy.cpp	2008-08-27 07:54:42 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtux/DbtuxProxy.cpp	2009-09-19 06:30:50 +0000
@@ -23,10 +23,6 @@ DbtuxProxy::DbtuxProxy(Block_context& ct
   addRecSignal(GSN_ALTER_INDX_IMPL_REQ, &DbtuxProxy::execALTER_INDX_IMPL_REQ);
   addRecSignal(GSN_ALTER_INDX_IMPL_CONF, &DbtuxProxy::execALTER_INDX_IMPL_CONF);
   addRecSignal(GSN_ALTER_INDX_IMPL_REF, &DbtuxProxy::execALTER_INDX_IMPL_REF);
-
-  // GSN_DROP_TAB_REQ
-  addRecSignal(GSN_DROP_TAB_REQ, &DbtuxProxy::execDROP_TAB_REQ);
-  addRecSignal(GSN_DROP_TAB_CONF, &DbtuxProxy::execDROP_TAB_CONF);
 }
 
 DbtuxProxy::~DbtuxProxy()
@@ -110,63 +106,4 @@ DbtuxProxy::sendALTER_INDX_IMPL_CONF(Sig
   ssRelease<Ss_ALTER_INDX_IMPL_REQ>(ssId);
 }
 
-// GSN_DROP_TAB_REQ
-

-void
-DbtuxProxy::execDROP_TAB_REQ(Signal* signal)
-{
-  const DropTabReq* req = (const DropTabReq*)signal->getDataPtr();
-  Uint32 ssId = getSsId(req);
-  Ss_DROP_TAB_REQ& ss = ssSeize<Ss_DROP_TAB_REQ>(ssId);
-  ss.m_req = *req;
-  ndbrequire(signal->getLength() == DropTabReq::SignalLength);
-  sendREQ(signal, ss);
-}
-
-void
-DbtuxProxy::sendDROP_TAB_REQ(Signal* signal, Uint32 ssId)
-{
-  Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
-
-  DropTabReq* req = (DropTabReq*)signal->getDataPtrSend();
-  *req = ss.m_req;
-  req->senderRef = reference();
-  req->senderData = ssId; // redundant since tableId is used
-  sendSignal(workerRef(ss.m_worker), GSN_DROP_TAB_REQ,
-             signal, DropTabReq::SignalLength, JBB);
-}
-
-void
-DbtuxProxy::execDROP_TAB_CONF(Signal* signal)
-{
-  const DropTabConf* conf = (const DropTabConf*)signal->getDataPtr();
-  Uint32 ssId = getSsId(conf);
-  Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
-  recvCONF(signal, ss);
-}
-
-void
-DbtuxProxy::sendDROP_TAB_CONF(Signal* signal, Uint32 ssId)
-{
-  Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
-  BlockReference dictRef = ss.m_req.senderRef;
-
-  if (!lastReply(ss))
-    return;
-
-  if (ss.m_error == 0) {
-    jam();
-    DropTabConf* conf = (DropTabConf*)signal->getDataPtrSend();
-    conf->senderRef = reference();
-    conf->senderData = ss.m_req.senderData;
-    conf->tableId = ss.m_req.tableId;
-    sendSignal(dictRef, GSN_DROP_TAB_CONF,
-               signal, DropTabConf::SignalLength, JBB);
-  } else {
-    ndbrequire(false);
-  }
-
-  ssRelease<Ss_DROP_TAB_REQ>(ssId);
-}
-
 BLOCK_FUNCTIONS(DbtuxProxy)

=== modified file 'storage/ndb/src/kernel/blocks/dbtux/DbtuxProxy.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtux/DbtuxProxy.hpp	2008-08-27 07:54:42 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtux/DbtuxProxy.hpp	2009-09-19 06:30:50 +0000
@@ -47,30 +47,6 @@ protected:
   void execALTER_INDX_IMPL_CONF(Signal*);
   void execALTER_INDX_IMPL_REF(Signal*);
   void sendALTER_INDX_IMPL_CONF(Signal*, Uint32 ssId);
-
-  // GSN_DROP_TAB_REQ
-  struct Ss_DROP_TAB_REQ : SsParallel {
-    DropTabReq m_req;
-    Ss_DROP_TAB_REQ() {
-      m_sendREQ = (SsFUNC)&DbtuxProxy::sendDROP_TAB_REQ;
-      m_sendCONF = (SsFUNC)&DbtuxProxy::sendDROP_TAB_CONF;
-    }
-    enum { poolSize = 1 };
-    static SsPool<Ss_DROP_TAB_REQ>& pool(LocalProxy* proxy) {
-      return ((DbtuxProxy*)proxy)->c_ss_DROP_TAB_REQ;
-    }
-  };
-  SsPool<Ss_DROP_TAB_REQ> c_ss_DROP_TAB_REQ;
-  Uint32 getSsId(const DropTabReq* req) {
-    return SsIdBase | req->tableId;
-  }
-  Uint32 getSsId(const DropTabConf* conf) {
-    return SsIdBase | conf->tableId;
-  }
-  void execDROP_TAB_REQ(Signal*);
-  void sendDROP_TAB_REQ(Signal*, Uint32 ssId);
-  void execDROP_TAB_CONF(Signal*);
-  void sendDROP_TAB_CONF(Signal*, Uint32 ssId);
 };
 
 #endif

=== modified file 'storage/ndb/src/kernel/blocks/ndbfs/PosixAsyncFile.cpp'
--- a/storage/ndb/src/kernel/blocks/ndbfs/PosixAsyncFile.cpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbfs/PosixAsyncFile.cpp	2009-09-14 12:43:30 +0000
@@ -85,7 +85,7 @@ int PosixAsyncFile::check_odirect_write(
   int ret;
   char * bufptr = (char*)((UintPtr(g_odirect_readbuf)+(GLOBAL_PAGE_SIZE - 1)) & ~(GLOBAL_PAGE_SIZE - 1));
   while (((ret = ::write(theFd, bufptr, GLOBAL_PAGE_SIZE)) == -1) &&
-         (errno == EINTR));
+         (errno == EINTR)) {};
   if (ret == -1)
   {
     new_flags &= ~O_DIRECT;
@@ -111,7 +111,7 @@ int PosixAsyncFile::check_odirect_read(U
   int ret;
   char * bufptr = (char*)((UintPtr(g_odirect_readbuf)+(GLOBAL_PAGE_SIZE - 1)) & ~(GLOBAL_PAGE_SIZE - 1));
   while (((ret = ::read(theFd, bufptr, GLOBAL_PAGE_SIZE)) == -1) &&
-         (errno == EINTR));
+         (errno == EINTR)) {};
   if (ret == -1)
   {
     ndbout_c("%s Failed to read using O_DIRECT, disabling",
@@ -501,7 +501,7 @@ int PosixAsyncFile::readBuffer(Request *
   if(!use_gz)
   {
     while((seek_val= lseek(theFd, offset, SEEK_SET)) == (off_t)-1
-          && errno == EINTR);
+          && errno == EINTR) {};
     if(seek_val == (off_t)-1)
     {
       return errno;
@@ -511,7 +511,7 @@ int PosixAsyncFile::readBuffer(Request *
   if(use_gz)
   {
     while((seek_val= azseek(&azf, offset, SEEK_SET)) == (off_t)-1
-          && errno == EINTR);
+          && errno == EINTR) {};
     if(seek_val == (off_t)-1)
     {
       return errno;
@@ -614,7 +614,7 @@ int PosixAsyncFile::writeBuffer(const ch
   FileGuard guard(this);
   off_t seek_val;
   while((seek_val= lseek(theFd, offset, SEEK_SET)) == (off_t)-1
-	&& errno == EINTR);
+	&& errno == EINTR) {};
   if(seek_val == (off_t)-1)
   {
     return errno;

=== modified file 'storage/ndb/src/kernel/blocks/ndbfs/Win32AsyncFile.cpp'
--- a/storage/ndb/src/kernel/blocks/ndbfs/Win32AsyncFile.cpp	2009-05-28 18:54:28 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbfs/Win32AsyncFile.cpp	2009-09-14 12:41:02 +0000
@@ -402,7 +402,7 @@ loop:
     {
       int len = strlen(path);
       strcat(path, ffd.cFileName);
-      if(DeleteFile(path)) 
+      if(DeleteFile(path) || RemoveDirectory(path)) 
       {
         path[len] = 0;
 	continue;

=== modified file 'storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp'
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp	2009-09-03 13:52:29 +0000
+++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp	2009-09-21 08:42:40 +0000
@@ -3947,7 +3947,7 @@ Qmgr::sendCommitFailReq(Signal* signal)
     ptrAss(nodePtr, nodeRec);
 
 #ifdef ERROR_INSERT    
-    if (ERROR_INSERTED(935) && nodePtr.i == c_error_insert_extra)
+    if (false && ERROR_INSERTED(935) && nodePtr.i == c_error_insert_extra)
     {
       ndbout_c("skipping node %d", c_error_insert_extra);
       CLEAR_ERROR_INSERT_VALUE;
@@ -4064,6 +4064,9 @@ void Qmgr::execCOMMIT_FAILREQ(Signal* si
 {
   NodeRecPtr nodePtr;
   jamEntry();
+
+  CRASH_INSERTION(935);
+
   BlockReference Tblockref = signal->theData[0];
   UintR TfailureNr = signal->theData[1];
   if (Tblockref != cpdistref) {

=== modified file 'storage/ndb/src/kernel/vm/SimulatedBlock.cpp'
--- a/storage/ndb/src/kernel/vm/SimulatedBlock.cpp	2009-08-24 08:18:43 +0000
+++ b/storage/ndb/src/kernel/vm/SimulatedBlock.cpp	2009-09-21 08:42:40 +0000
@@ -42,6 +42,7 @@
 #include <signaldata/NodeStateSignalData.hpp>
 #include <signaldata/FsRef.hpp>
 #include <signaldata/SignalDroppedRep.hpp>
+#include <signaldata/LocalRouteOrd.hpp>
 #include <DebuggerNames.hpp>
 #include "LongSignal.hpp"
 
@@ -214,6 +215,7 @@ SimulatedBlock::installSimulatedBlockFun
   a[GSN_CALLBACK_CONF] = &SimulatedBlock::execCALLBACK_CONF;
   a[GSN_SYNC_THREAD_REQ] = &SimulatedBlock::execSYNC_THREAD_REQ;
   a[GSN_SYNC_THREAD_CONF] = &SimulatedBlock::execSYNC_THREAD_CONF;
+  a[GSN_LOCAL_ROUTE_ORD] = &SimulatedBlock::execLOCAL_ROUTE_ORD;
 }
 
 void
@@ -3309,6 +3311,189 @@ SimulatedBlock::create_distr_key(Uint32 
 
 CArray<KeyDescriptor> g_key_descriptor_pool;
 
+void
+SimulatedBlock::sendRoutedSignal(RoutePath path[], Uint32 pathcnt,
+                                 Uint32 dst[],
+                                 Uint32 dstcnt,
+                                 Uint32 gsn,
+                                 Signal * signal,
+                                 Uint32 sigLen,
+                                 JobBufferLevel prio,
+                                 SectionHandle * userhandle)
+{
+  ndbrequire(pathcnt > 0); // don't support (now) directly multi-cast
+  pathcnt--; // first hop is made from here
+
+
+  Uint32 len = LocalRouteOrd::StaticLen + (2 * pathcnt) + dstcnt;
+  ndbrequire(len <= 25);
+
+  SectionHandle handle(this, signal);
+  if (userhandle)
+  {
+    ljam();
+    handle.m_cnt = userhandle->m_cnt;
+    for (Uint32 i = 0; i<handle.m_cnt; i++)
+      handle.m_ptr[i] = userhandle->m_ptr[i];
+    userhandle->m_cnt = 0;
+  }
+
+  if (len + sigLen > 25)
+  {
+    ljam();
+
+    /**
+     * we need to store theData in a section
+     */
+    ndbrequire(handle.m_cnt < 3);
+    handle.m_ptr[2] = handle.m_ptr[1];
+    handle.m_ptr[1] = handle.m_ptr[0];
+    Ptr<SectionSegment> tmp;
+    ndbrequire(import(tmp, signal->theData, sigLen));
+    handle.m_ptr[0].p = tmp.p;
+    handle.m_ptr[0].i = tmp.i;
+    handle.m_ptr[0].sz = sigLen;
+    handle.m_cnt ++;
+  }
+  else
+  {
+    ljam();
+    memmove(signal->theData + len, signal->theData, 4 * sigLen);
+    len += sigLen;
+  }
+
+  LocalRouteOrd * ord = (LocalRouteOrd*)signal->getDataPtrSend();
+  ord->cnt = (pathcnt << 16) | (dstcnt);
+  ord->gsn = gsn;
+  ord->prio = Uint32(prio);
+
+  Uint32 * dstptr = ord->path;
+  for (Uint32 i = 1; i <= pathcnt; i++)
+  {
+    ndbrequire(refToNode(path[i].ref) == 0 ||
+               refToNode(path[i].ref) == getOwnNodeId());
+
+    * dstptr++ = path[i].ref;
+    * dstptr++ = Uint32(path[i].prio);
+  }
+
+  for (Uint32 i = 0; i<dstcnt; i++)
+  {
+    ndbrequire(refToNode(dst[i]) == 0 ||
+               refToNode(dst[i]) == getOwnNodeId());
+
+    * dstptr++ = dst[i];
+  }
+
+  sendSignal(path[0].ref, GSN_LOCAL_ROUTE_ORD, signal, len,
+             path[0].prio, &handle);
+}
+
+void
+SimulatedBlock::execLOCAL_ROUTE_ORD(Signal* signal)
+{
+  ljamEntry();
+
+  if (!assembleFragments(signal))
+  {
+    ljam();
+    return;
+  }
+
+  if (ERROR_INSERTED(1001))
+  {
+    /**
+     * This NDBCNTR error code 1001
+     */
+    ljam();
+    SectionHandle handle(this, signal);
+    sendSignalWithDelay(reference(), GSN_LOCAL_ROUTE_ORD, signal, 200, 
+                        signal->getLength(), &handle);
+    return;
+  }
+
+  LocalRouteOrd* ord = (LocalRouteOrd*)signal->getDataPtr();
+  Uint32 pathcnt = ord->cnt >> 16;
+  Uint32 dstcnt = ord->cnt & 0xFFFF;
+  Uint32 sigLen = signal->getLength();
+
+  if (pathcnt == 0)
+  {
+    /**
+     * Send to final destination(s);
+     */
+    ljam();
+    Uint32 gsn = ord->gsn;
+    Uint32 prio = ord->prio;
+    memcpy(signal->theData+25, ord->path, 4*dstcnt);
+    SectionHandle handle(this, signal);
+    if (sigLen > LocalRouteOrd::StaticLen + dstcnt)
+    {
+      ljam();
+      /**
+       * Data is at end of this...
+       */
+      memmove(signal->theData,
+              signal->theData + LocalRouteOrd::StaticLen + dstcnt,
+              4 * (sigLen - (LocalRouteOrd::StaticLen + dstcnt)));
+      sigLen = sigLen - (LocalRouteOrd::StaticLen + dstcnt);
+    }
+    else
+    {
+      ljam();
+      /**
+       * Put section 0 in signal->theData
+       */
+      sigLen = handle.m_ptr[0].sz;
+      ndbrequire(sigLen <= 25);
+      copy(signal->theData, handle.m_ptr[0]);
+      release(handle.m_ptr[0]);
+
+      for (Uint32 i = 0; i < handle.m_cnt - 1; i++)
+        handle.m_ptr[i] = handle.m_ptr[i+1];
+      handle.m_cnt--;
+    }
+
+    /*
+     * The extra if-statement is as sendSignalNoRelease will copy sections
+     *   which is not necessary is only sending to one destination
+     */
+    if (dstcnt > 1)
+    {
+      jam();
+      for (Uint32 i = 0; i<dstcnt; i++)
+      {
+        ljam();
+        sendSignalNoRelease(signal->theData[25+i], gsn, signal, sigLen,
+                            JobBufferLevel(prio), &handle);
+      }
+      releaseSections(handle);
+    }
+    else
+    {
+      jam();
+      sendSignal(signal->theData[25+0], gsn, signal, sigLen,
+                 JobBufferLevel(prio), &handle);
+    }
+  }
+  else
+  {
+    /**
+     * Reroute
+     */
+    ljam();
+    SectionHandle handle(this, signal);
+    Uint32 ref = ord->path[0];
+    Uint32 prio = ord->path[1];
+    Uint32 len = sigLen - 2;
+    ord->cnt = ((pathcnt - 1) << 16) | dstcnt;
+    memmove(ord->path, ord->path+2, 4 * (len - LocalRouteOrd::StaticLen));
+    sendSignal(ref, GSN_LOCAL_ROUTE_ORD, signal, len,
+               JobBufferLevel(prio), &handle);
+  }
+}
+
+
 #ifdef VM_TRACE
 bool
 SimulatedBlock::debugOutOn()
@@ -3408,3 +3593,46 @@ SimulatedBlock::execSYNC_THREAD_CONF(Sig
   }
   ptr.p->m_cnt --;
 }
+
+bool
+SimulatedBlock::checkNodeFailSequence(Signal* signal)
+{
+  Uint32 ref = signal->getSendersBlockRef();
+
+  /**
+   * Make sure that a signal being part of node-failure handling
+   *   from a remote node, does not get to us before we got the NODE_FAILREP
+   *   (this to avoid tricky state handling)
+   *
+   * To ensure this, we send the signal via QMGR (GSN_COMMIT_FAILREQ)
+   *   and NDBCNTR (which sends NODE_FAILREP)
+   *
+   * The extra time should be negilable
+   *
+   * Note, make an exception for signals sent by our self
+   *       as they are only sent as a consequence of NODE_FAILREP
+   */
+  if (ref == reference() ||
+      (refToNode(ref) == getOwnNodeId() &&
+       refToMain(ref) == NDBCNTR))
+  {
+    ljam();
+    return true;
+  }
+
+  RoutePath path[2];
+  path[0].ref = QMGR_REF;
+  path[0].prio = JBB;
+  path[1].ref = NDBCNTR_REF;
+  path[1].prio = JBB;
+
+  Uint32 dst[1];
+  dst[0] = reference();
+
+  SectionHandle handle(this, signal);
+  Uint32 gsn = signal->header.theVerId_signalNumber;
+  Uint32 len = signal->getLength();
+
+  sendRoutedSignal(path, 2, dst, 1, gsn, signal, len, JBB, &handle);
+  return false;
+}

=== modified file 'storage/ndb/src/kernel/vm/SimulatedBlock.hpp'
--- a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp	2009-08-24 08:18:43 +0000
+++ b/storage/ndb/src/kernel/vm/SimulatedBlock.hpp	2009-09-21 08:42:40 +0000
@@ -329,6 +329,33 @@ protected:
   void handle_lingering_sections_after_execute(Signal*) const;
   void handle_lingering_sections_after_execute(SectionHandle*) const;
 
+  /**
+   * Send routed signals (ONLY LOCALLY)
+   *
+   * NOTE: Only localhost is allowed!
+   */
+  struct RoutePath
+  {
+    Uint32 ref;
+    JobBufferLevel prio;
+  };
+  void sendRoutedSignal(RoutePath path[],
+                        Uint32 pathcnt,      // #hops
+                        Uint32 dst[],        // Final destination(s)
+                        Uint32 dstcnt,       // #final destination(s)
+                        Uint32 gsn,          // Final GSN
+                        Signal*,
+                        Uint32 len,
+                        JobBufferLevel prio, // Final prio
+                        SectionHandle * handle = 0);
+
+
+  /**
+   * Check that signal sent from remote node
+   *   is guaranteed to be correctly serialized wrt to NODE_FAILREP
+   */
+  bool checkNodeFailSequence(Signal*);
+
   /**********************************************************
    * Fragmented signals
    */
@@ -669,6 +696,7 @@ protected:  
   void execAPI_START_REP(Signal* signal);
   void execNODE_START_REP(Signal* signal);
   void execSEND_PACKED(Signal* signal);
+  void execLOCAL_ROUTE_ORD(Signal*);
 private:
   /**
    * Node state

=== modified file 'storage/ndb/src/kernel/vm/mt.cpp'
--- a/storage/ndb/src/kernel/vm/mt.cpp	2009-08-24 08:18:43 +0000
+++ b/storage/ndb/src/kernel/vm/mt.cpp	2009-09-21 10:27:17 +0000
@@ -3690,7 +3690,10 @@ FastScheduler::traceDumpPrepare(NdbShutd
   }
   if (g_thr_repository.stopped_threads < waitFor_count)
   {
-    nst = NST_Watchdog; // Make this abort fast
+    if (nst != NST_ErrorInsert)
+    {
+      nst = NST_Watchdog; // Make this abort fast
+    }
     ndbout_c("Warning: %d thread(s) did not stop before starting crash dump.",
              waitFor_count - g_thr_repository.stopped_threads);
   }

=== modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.cpp'
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2009-09-08 15:12:34 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2009-09-15 19:21:25 +0000
@@ -757,15 +757,6 @@ MgmtSrvr::get_packed_config(ndb_mgm_node
 
 MgmtSrvr::~MgmtSrvr()
 {
-
-  /* Stop config manager */
-  if (m_config_manager != 0)
-  {
-    m_config_manager->stop();
-    delete m_config_manager;
-    m_config_manager= 0;
-  }
-
   /* Stop log level thread */
   void* res = 0;
   _isStopThread = true;
@@ -786,6 +777,14 @@ MgmtSrvr::~MgmtSrvr()
                          "continuing with shutdown anyway.");
   }
 
+  /* Stop config manager */
+  if (m_config_manager != 0)
+  {
+    m_config_manager->stop();
+    delete m_config_manager;
+    m_config_manager= 0;
+  }
+
   // Stop transporter
   if(theFacade != 0){
     theFacade->stop_instance();

=== modified file 'storage/ndb/src/ndbapi/DictCache.cpp'
--- a/storage/ndb/src/ndbapi/DictCache.cpp	2009-08-26 13:25:41 +0000
+++ b/storage/ndb/src/ndbapi/DictCache.cpp	2009-09-16 11:12:55 +0000
@@ -498,11 +498,8 @@ GlobalDictCache::chg_ref_count(const Ndb
   for(Uint32 i = 0; i < sz; i++)
   {
     TableVersion & ver = (* vers)[i];
-    if(ver.m_version == tableVersion && ver.m_impl && 
-       (Uint32) ver.m_impl->m_id == tableId)
+    if(ver.m_impl == impl)
     {
-      if (ver.m_impl != impl)
-        abort();
       if (value == +1)
       {
         DBUG_PRINT("info", ("%s id=%u ver=0x%x: inc old ref count %u",

=== modified file 'storage/ndb/src/ndbapi/Ndb.cpp'
--- a/storage/ndb/src/ndbapi/Ndb.cpp	2009-06-22 09:07:41 +0000
+++ b/storage/ndb/src/ndbapi/Ndb.cpp	2009-09-21 14:23:46 +0000
@@ -964,11 +964,22 @@ Ndb::closeTransaction(NdbTransaction* aC
     DBUG_VOID_RETURN;
   }
   
-  if (aConnection->theReleaseOnClose == false) {
+  /**
+   * NOTE: It's ok to call getNodeSequence() here wo/ having mutex,
+   */
+  Uint32 nodeId = aConnection->getConnectedNodeId();
+  TransporterFacade* tp = theImpl->m_transporter_facade;   
+  Uint32 seq = tp->getNodeSequence(nodeId);
+  if (aConnection->theNodeSequence != seq)
+  {
+    aConnection->theReleaseOnClose = true;
+  }
+  
+  if (aConnection->theReleaseOnClose == false) 
+  {
     /**
      * Put it back in idle list for that node
      */
-    Uint32 nodeId = aConnection->getConnectedNodeId();
     aConnection->theNext = theConnectionArray[nodeId];
     theConnectionArray[nodeId] = aConnection;
     DBUG_VOID_RETURN;
@@ -1595,19 +1606,10 @@ Ndb::opTupleIdOnNdb(const NdbTableImpl* 
   if (initAutoIncrement() == -1)
     goto error_handler;
 
-/*
-  Fix for
-  Bug #39268 No transaction hints used to update SYSTAB_0 for autoincrement and PK-less table
-  causes crash in 6.4
- */
-#if 0
   // Start transaction with table id as hint
-  tConnection = this->startTransaction(table,
+  tConnection = this->startTransaction(m_sys_tab_0,
                                        (const char *) &aTableId,
                                        sizeof(Uint32));
-#else
-  tConnection = this->startTransaction();
-#endif
 
   if (tConnection == NULL)
     goto error_handler;

=== modified file 'storage/ndb/test/ndbapi/testDict.cpp'
--- a/storage/ndb/test/ndbapi/testDict.cpp	2009-08-21 13:01:34 +0000
+++ b/storage/ndb/test/ndbapi/testDict.cpp	2009-09-21 11:45:18 +0000
@@ -1618,9 +1618,11 @@ int
 runTableAddAttrsDuring(NDBT_Context* ctx, NDBT_Step* step){
 
   int result = NDBT_OK;
+  int abortAlter = ctx->getProperty("AbortAlter", Uint32(0));
 
   int records = ctx->getNumRecords();
   const int loops = ctx->getNumLoops();
+  NdbRestarter res;
 
   ndbout << "|- " << ctx->getTab()->getName() << endl;  
 
@@ -1669,10 +1671,20 @@ runTableAddAttrsDuring(NDBT_Context* ctx
                              NdbDictionary::Column::StorageTypeMemory, true);
       newTable.addColumn(newcol1);
       //ToDo: check #loops, how many columns l
-      
-      CHECK2(dict->alterTable(*oldTable, newTable) == 0,
-	     "TableAddAttrsDuring failed");
-      
+
+      if (abortAlter == 0)
+      {
+        CHECK2(dict->alterTable(*oldTable, newTable) == 0,
+               "TableAddAttrsDuring failed");
+      }
+      else
+      {
+        int nodeId = res.getNode(NdbRestarter::NS_RANDOM);
+        res.insertErrorInNode(nodeId, 4029);
+        CHECK2(dict->alterTable(*oldTable, newTable) != 0,
+               "TableAddAttrsDuring failed");
+      }
+
       dict->invalidateTable(myTab.getName());
       const NdbDictionary::Table * newTab = dict->getTable(myTab.getName());
       HugoTransactions hugoTrans(* newTab);
@@ -6947,6 +6959,7 @@ runBug41905getTable(NDBT_Context* ctx, N
   }
 
 out:
+  (void)pDic->dropTable(tabName.c_str());
   return NDBT_OK;
 }
 
@@ -7261,6 +7274,16 @@ TESTCASE("TableAddAttrsDuring",
   STEP(runUseTableUntilStopped3);
   FINALIZER(runDropTheTable);
 }
+TESTCASE("TableAddAttrsDuringError",
+	 "Try to add attributes to the table when other thread is using it\n"
+	 "do this loop number of times\n"){
+  TC_PROPERTY("AbortAlter", 1);
+  INITIALIZER(runCreateTheTable);
+  STEP(runTableAddAttrsDuring);
+  STEP(runUseTableUntilStopped2);
+  STEP(runUseTableUntilStopped3);
+  FINALIZER(runDropTheTable);
+}
 TESTCASE("Bug21755",
          ""){
   INITIALIZER(runBug21755);

=== modified file 'storage/ndb/test/ndbapi/testNodeRestart.cpp'
--- a/storage/ndb/test/ndbapi/testNodeRestart.cpp	2009-05-28 07:08:44 +0000
+++ b/storage/ndb/test/ndbapi/testNodeRestart.cpp	2009-09-21 09:13:58 +0000
@@ -312,7 +312,10 @@ int runRestarter(NDBT_Context* ctx, NDBT
     return NDBT_FAILED;
   }
   
-  loops *= (restarter.getNumDbNodes() > 4 ? 4 : restarter.getNumDbNodes());
+  loops *= (restarter.getNumDbNodes() > 2 ? 2 : restarter.getNumDbNodes());
+  if (loops < restarter.getNumDbNodes())
+    loops = restarter.getNumDbNodes();
+
   while(i<loops && result != NDBT_FAILED && !ctx->isTestStopped()){
 
     int id = lastId % restarter.getNumDbNodes();
@@ -728,7 +731,7 @@ runBug18414(NDBT_Context* ctx, NDBT_Step
     
     if (loop & 1)
     {
-      if (restarter.insertErrorInNode(node1, 8050))
+      if (restarter.insertErrorInNode(node1, 8080))
 	goto err;
     }
     

=== modified file 'storage/ndb/test/ndbapi/testSystemRestart.cpp'
--- a/storage/ndb/test/ndbapi/testSystemRestart.cpp	2009-09-07 07:12:44 +0000
+++ b/storage/ndb/test/ndbapi/testSystemRestart.cpp	2009-09-15 16:59:09 +0000
@@ -2151,9 +2151,20 @@ loop:
     int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
     res.dumpStateAllNodes(val2, 2);
 
+    Bitmask<256/32> mask;
     for (Uint32 i = 0; i<(nodeCount / 2); i++)
     {
-      res.insertErrorInNode(nodes[(nodeCount / 2) - (i + 1)], 7218);
+      int node = nodes[(nodeCount / 2) - (i + 1)];
+      mask.set(node);
+      res.insertErrorInNode(node, 7218);
+    }
+    
+    for (Uint32 i = 0; i<nodeCount; i++)
+    {
+      int node = nodes[i];
+      if (mask.get(node))
+        continue;
+      res.insertErrorInNode(node, 7220);
     }
 
     int lcp = 7099;

=== modified file 'storage/ndb/test/run-test/Makefile.am'
--- a/storage/ndb/test/run-test/Makefile.am	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/test/run-test/Makefile.am	2009-09-15 20:02:22 +0000
@@ -25,7 +25,8 @@ test_PROGRAMS = atrt
 test_DATA=daily-basic-tests.txt daily-devel-tests.txt 16node-tests.txt \
           conf-ndbmaster.cnf \
           conf-fimafeng08.cnf conf-dl145a.cnf test-tests.txt conf-test.cnf \
-          conf-upgrade.cnf upgrade-tests.txt
+          conf-upgrade.cnf upgrade-tests.txt \
+	  conf-ndb07.cnf
 
 test_SCRIPTS=atrt-analyze-result.sh atrt-gather-result.sh atrt-setup.sh \
           autotest-run.sh atrt-backtrace.sh

=== modified file 'storage/ndb/test/run-test/autotest-run.sh'
--- a/storage/ndb/test/run-test/autotest-run.sh	2008-12-12 14:14:52 +0000
+++ b/storage/ndb/test/run-test/autotest-run.sh	2009-09-21 07:24:31 +0000
@@ -281,6 +281,7 @@ echo "date=$DATE" > info.txt
 echo "suite=$RUN" >> info.txt
 echo "clone=$clone0" >> info.txt
 echo "arch=$target" >> info.txt
+echo "host=$HOST" >> info.txt
 find . | xargs chmod ugo+r
 
 cd ..

=== added file 'storage/ndb/test/run-test/conf-ndb07.cnf'
--- a/storage/ndb/test/run-test/conf-ndb07.cnf	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/run-test/conf-ndb07.cnf	2009-09-21 08:44:14 +0000
@@ -0,0 +1,41 @@
+[atrt]
+basedir = CHOOSE_dir
+baseport = 14000
+clusters = .4node
+fix-nodeid=1
+mt = 2
+
+[ndb_mgmd]
+
+[mysqld]
+skip-innodb
+loose-skip-bdb
+skip-grant-tables
+socket=mysql.sock
+
+[client]
+protocol=tcp
+
+[cluster_config.4node]
+ndb_mgmd = CHOOSE_host1
+ndbd = CHOOSE_host2,CHOOSE_host3,CHOOSE_host4,CHOOSE_host5
+ndbapi= CHOOSE_host1,CHOOSE_host1,CHOOSE_host1
+mysqld = CHOOSE_host1,CHOOSE_host6
+
+NoOfReplicas = 2
+IndexMemory = 100M 
+DataMemory = 500M
+BackupMemory = 64M
+MaxNoOfConcurrentScans = 100
+MaxNoOfSavedMessages= 1000
+NoOfFragmentLogFiles = 8
+FragmentLogFileSize = 64M
+ODirect=1
+
+SharedGlobalMemory=256M
+DiskPageBufferMemory=256M
+FileSystemPath=/data0/autotest
+FileSystemPathDataFiles=/data1/autotest
+FileSystemPathUndoFiles=/data2/autotest
+InitialLogfileGroup=undo_buffer_size=64M;undofile01.dat:256M;undofile02.dat:256M
+InitialTablespace=datafile01.dat:256M;datafile02.dat:256M

=== modified file 'storage/ndb/test/run-test/daily-basic-tests.txt'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt	2009-09-07 07:07:15 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt	2009-09-16 11:12:55 +0000
@@ -597,6 +597,22 @@ max-time: 300
 cmd: testNodeRestart
 args: -n Bug32160 T1
 
+max-time: 2500
+cmd: testNodeRestart
+args: -n MixedPkRead T6 T13 
+
+max-time: 2500
+cmd: testIndex
+args: -n NFNR1 T6 T13 
+
+max-time: 2500
+cmd: testIndex
+args: -n NFNR1_O T6 T13 
+
+max-time: 2500
+cmd: testIndex
+args: -n NFNR2_O T6 T13 
+
 #
 # DICT TESTS

 max-time: 500
@@ -667,6 +683,14 @@ max-time: 500
 cmd: testDict
 args: -n Bug24631 T1
 
+max-time: 600
+cmd: testDict
+args: -n Bug41905 T1
+
+max-time: 600
+cmd: testDict
+args: -n TableAddAttrsDuringError
+
 #
 # TEST NDBAPI
 #
@@ -937,6 +961,31 @@ max-time: 600
 cmd: test_event_merge
 args: --no-implicit-nulls --no-multiops
 
+#
+max-time: 3600
+cmd: test_event
+args: -n EventOperationApplier -l 2
+
+#
+max-time: 3600
+cmd: test_event
+args: -n EventOperationApplier_NR -l 2
+
+#
+max-time: 3600
+cmd: test_event
+args: -n MergeEventOperationApplier_NR -l 2
+
+#
+max-time: 2500
+cmd: test_event
+args: -n Multi
+
+#
+max-time: 3600
+cmd: test_event
+args: -n CreateDropNR -l 1
+
 max-time: 600
 cmd: testBasic
 args: -n PkRead T1

=== modified file 'storage/ndb/test/run-test/daily-devel-tests.txt'
--- a/storage/ndb/test/run-test/daily-devel-tests.txt	2009-09-01 11:42:04 +0000
+++ b/storage/ndb/test/run-test/daily-devel-tests.txt	2009-09-15 10:13:15 +0000
@@ -59,10 +59,6 @@ args: -n SR_FULLDB T6 
 #
 max-time: 2500
 cmd: testNodeRestart
-args: -n MixedPkRead T6 T13 
-
-max-time: 2500
-cmd: testNodeRestart
 args: -l 1 -n MixedPkReadPkUpdate 
 
 max-time: 2500
@@ -100,10 +96,6 @@ args: -n Bug16772 T1
 #
 max-time: 2500
 cmd: testIndex
-args: -n NFNR1 T6 T13 
-
-max-time: 2500
-cmd: testIndex
 args: -n NFNR2 T6 T13 
 
 max-time: 2500
@@ -116,14 +108,6 @@ args: -l 2 -n SR1 T6 T13 
 
 max-time: 2500
 cmd: testIndex
-args: -n NFNR1_O T6 T13 
-
-max-time: 2500
-cmd: testIndex
-args: -n NFNR2_O T6 T13 
-
-max-time: 2500
-cmd: testIndex
 args: -n NFNR3_O T6 T13 
 
 max-time: 2500
@@ -134,35 +118,6 @@ max-time: 2500
 cmd: testIndex
 args: -l 2 -n SR1_O T6 T13 
 
-#
-max-time: 3600
-cmd: test_event
-args: -n EventOperationApplier -l 2
-
-#
-max-time: 3600
-cmd: test_event
-args: -n EventOperationApplier_NR -l 2
-
-#
-max-time: 3600
-cmd: test_event
-args: -n MergeEventOperationApplier_NR -l 2
-
-#
-max-time: 2500
-cmd: test_event
-args: -n Multi
-
-max-time: 600
-cmd: test_event
-args: -l 1 -n SubscribeNR T1
-
-#
-max-time: 3600
-cmd: test_event
-args: -n CreateDropNR -l 1
-
 # dict trans
 max-time: 1800
 cmd: testDict

=== modified file 'storage/ndb/test/src/UtilTransactions.cpp'
--- a/storage/ndb/test/src/UtilTransactions.cpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/test/src/UtilTransactions.cpp	2009-09-15 16:59:09 +0000
@@ -780,6 +780,9 @@ UtilTransactions::readRowFromTableAndInd
     if (pTrans1 == NULL) {
       const NdbError err = pNdb->getNdbError();
       
+      if (err.code == 4006)
+        goto close_all;
+
       if (err.status == NdbError::TemporaryError){
 	ERR(err);
 	NdbSleep_MilliSleep(50);

Attachment: [text/bzr-bundle] bzr/magnus.blaudd@sun.com-20090922075634-6zcrhybszzkwt2qf.bundle
Thread
bzr commit into mysql-5.1-telco-7.0 branch (magnus.blaudd:3007)Magnus Blåudd22 Sep