List:Commits« Previous MessageNext Message »
From:Jonas Oreland Date:September 23 2010 11:56am
Subject:bzr commit into mysql-5.1-telco-7.0-spj branch (jonas:3216)
View as plain text  
#At file:///home/jonas/src/70-spj/ based on revid:jonas@stripped

 3216 Jonas Oreland	2010-09-23 [merge]
      ndb - merge 70-main to 70-spj

    removed:
      storage/ndb/src/kernel/vm/ArenaPool.cpp
      storage/ndb/src/kernel/vm/ArenaPool.hpp
    added:
      storage/ndb/src/kernel/vm/ArenaPool.cpp
      storage/ndb/src/kernel/vm/ArenaPool.hpp
    renamed:
      mysql-test/include/ndb_desc_print.inc => mysql-test/suite/ndb/include/ndb_desc_print.inc
      mysql-test/include/ndb_execute_count.inc => mysql-test/suite/ndb/include/ndb_execute_count.inc
      mysql-test/include/ndb_init_execute_count.inc => mysql-test/suite/ndb/include/ndb_init_execute_count.inc
      mysql-test/include/ndb_init_scan_counts.inc => mysql-test/suite/ndb/include/ndb_init_scan_counts.inc
      mysql-test/include/ndb_scan_counts.inc => mysql-test/suite/ndb/include/ndb_scan_counts.inc
    modified:
      client/mysqldump.c
      include/sha1.h
      mysql-test/collections/default.experimental
      mysql-test/r/mysqldump.result
      mysql-test/suite/funcs_1/t/disabled.def
      mysql-test/suite/ndb/r/ndb_database.result
      mysql-test/suite/ndb/r/ndb_partition_range.result
      mysql-test/suite/ndb/t/ndb_bulk_delete.test
      mysql-test/suite/ndb/t/ndb_database.test
      mysql-test/suite/ndb/t/ndb_native_default_support.test
      mysql-test/suite/ndb/t/ndb_partition_hash.test
      mysql-test/suite/ndb/t/ndb_partition_key.test
      mysql-test/suite/ndb/t/ndb_partition_list.test
      mysql-test/suite/ndb/t/ndb_partition_range.test
      mysql-test/suite/ndb/t/ndb_read_multi_range.test
      mysql-test/suite/ndb/t/ndb_sql_allow_batching.test
      mysql-test/suite/ndb/t/ndb_update_no_read.test
      mysql-test/suite/ndb/t/test_mgmd.cnf
      mysql-test/t/mysqldump.test
      mysys/sha1.c
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster.h
      sql/ha_ndbcluster_binlog.cc
      sql/handler.cc
      sql/handler.h
      sql/sql_show.cc
      sql/sql_table.cc
      storage/ndb/include/kernel/GlobalSignalNumbers.h
      storage/ndb/include/kernel/signaldata/ConfigChange.hpp
      storage/ndb/include/kernel/signaldata/DiGetNodes.hpp
      storage/ndb/include/kernel/signaldata/FsReadWriteReq.hpp
      storage/ndb/include/mgmapi/mgmapi.h
      storage/ndb/include/ndb_global.h
      storage/ndb/include/ndbapi/NdbDictionary.hpp
      storage/ndb/include/portlib/NdbCondition.h
      storage/ndb/include/portlib/NdbDir.hpp
      storage/ndb/include/portlib/NdbSleep.h
      storage/ndb/include/util/BaseString.hpp
      storage/ndb/include/util/HashMap.hpp
      storage/ndb/include/util/NdbSqlUtil.hpp
      storage/ndb/include/util/NdbTap.hpp
      storage/ndb/include/util/ndb_opts.h
      storage/ndb/src/common/portlib/NdbCondition.c
      storage/ndb/src/common/portlib/NdbDir.cpp
      storage/ndb/src/common/util/BaseString.cpp
      storage/ndb/src/common/util/NdbSqlUtil.cpp
      storage/ndb/src/common/util/ndb_init.cpp
      storage/ndb/src/common/util/ndb_opts.c
      storage/ndb/src/cw/cpcd/main.cpp
      storage/ndb/src/kernel/angel.cpp
      storage/ndb/src/kernel/angel.hpp
      storage/ndb/src/kernel/blocks/ERROR_codes.txt
      storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
      storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
      storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
      storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
      storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp
      storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp
      storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
      storage/ndb/src/kernel/blocks/ndbfs/AsyncIoThread.cpp
      storage/ndb/src/kernel/blocks/ndbfs/AsyncIoThread.hpp
      storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp
      storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.hpp
      storage/ndb/src/kernel/blocks/ndbfs/VoidFs.cpp
      storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
      storage/ndb/src/kernel/blocks/suma/Suma.cpp
      storage/ndb/src/kernel/error/ErrorReporter.cpp
      storage/ndb/src/kernel/main.cpp
      storage/ndb/src/kernel/ndbd.cpp
      storage/ndb/src/kernel/vm/CMakeLists.txt
      storage/ndb/src/kernel/vm/Makefile.am
      storage/ndb/src/kernel/vm/Pool.hpp
      storage/ndb/src/kernel/vm/RWPool.hpp
      storage/ndb/src/kernel/vm/SafeCounter.hpp
      storage/ndb/src/kernel/vm/WOPool.hpp
      storage/ndb/src/kernel/vm/mt.cpp
      storage/ndb/src/mgmapi/mgmapi.cpp
      storage/ndb/src/mgmapi/mgmapi_internal.h
      storage/ndb/src/mgmapi/ndb_logevent.cpp
      storage/ndb/src/mgmclient/CommandInterpreter.cpp
      storage/ndb/src/mgmclient/main.cpp
      storage/ndb/src/mgmsrv/ConfigManager.cpp
      storage/ndb/src/mgmsrv/ConfigManager.hpp
      storage/ndb/src/mgmsrv/MgmtSrvr.cpp
      storage/ndb/src/mgmsrv/main.cpp
      storage/ndb/src/ndbapi/DictCache.cpp
      storage/ndb/src/ndbapi/DictCache.hpp
      storage/ndb/src/ndbapi/NdbDictionary.cpp
      storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
      storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
      storage/ndb/test/include/NdbRestarter.hpp
      storage/ndb/test/ndbapi/testMgmd.cpp
      storage/ndb/test/ndbapi/testOIBasic.cpp
      storage/ndb/test/ndbapi/testRestartGci.cpp
      storage/ndb/test/ndbapi/testSystemRestart.cpp
      storage/ndb/test/ndbapi/test_event.cpp
      storage/ndb/test/run-test/daily-basic-tests.txt
      storage/ndb/test/src/NDBT_Test.cpp
      storage/ndb/test/src/NdbBackup.cpp
      storage/ndb/test/src/NdbRestarter.cpp
      storage/ndb/tools/delete_all.cpp
      storage/ndb/tools/desc.cpp
      storage/ndb/tools/drop_index.cpp
      storage/ndb/tools/drop_tab.cpp
      storage/ndb/tools/listTables.cpp
      storage/ndb/tools/ndb_config.cpp
      storage/ndb/tools/restore/restore_main.cpp
      storage/ndb/tools/select_all.cpp
      storage/ndb/tools/select_count.cpp
      storage/ndb/tools/waiter.cpp
=== modified file 'client/mysqldump.c'
--- a/client/mysqldump.c	2010-08-30 12:14:48 +0000
+++ b/client/mysqldump.c	2010-09-09 13:36:06 +0000
@@ -101,7 +101,7 @@ static my_bool  verbose= 0, opt_no_creat
                 opt_replace_into= 0,
                 opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1,
                 opt_events= 0,
-                opt_alltspcs=0, opt_notspcs= 0;
+                opt_alltspcs=0, opt_notspcs= 0, opt_drop_trigger= 0;
 static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0;
 static ulong opt_max_allowed_packet, opt_net_buffer_length;
 static MYSQL mysql_connection,*mysql=0;
@@ -203,6 +203,8 @@ static struct my_option my_long_options[
   {"add-drop-table", OPT_DROP, "Add a DROP TABLE before each create.",
    (uchar**) &opt_drop, (uchar**) &opt_drop, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
    0},
+  {"add-drop-trigger", OPT_MAX_CLIENT_OPTION, "Add a DROP TRIGGER before each create.",
+   (uchar**) &opt_drop_trigger, (uchar**) &opt_drop_trigger, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
   {"add-locks", OPT_LOCKS, "Add locks around INSERT statements.",
    (uchar**) &opt_lock, (uchar**) &opt_lock, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
    0},
@@ -2778,6 +2780,9 @@ static void dump_trigger_old(FILE *sql_f
   if (opt_compact)
     fprintf(sql_file, "/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;\n");
 
+  if (opt_drop_trigger)
+    fprintf(sql_file, "/*!50032 DROP TRIGGER IF EXISTS %s */;\n", (*show_trigger_row)[0]);
+
   fprintf(sql_file,
           "DELIMITER ;;\n"
           "/*!50003 SET SESSION SQL_MODE=\"%s\" */;;\n"
@@ -2852,6 +2857,9 @@ static int dump_trigger(FILE *sql_file, 
 
     switch_sql_mode(sql_file, ";", row[1]);
 
+    if (opt_drop_trigger)
+      fprintf(sql_file, "/*!50032 DROP TRIGGER IF EXISTS %s */;\n", row[0]);
+
     fprintf(sql_file,
             "DELIMITER ;;\n"
             "/*!50003 %s */;;\n"

=== modified file 'include/sha1.h'
--- a/include/sha1.h	2009-05-26 18:53:34 +0000
+++ b/include/sha1.h	2010-09-07 06:39:03 +0000
@@ -1,19 +1,17 @@
-/*
-   Copyright (C) 2002, 2006 MySQL AB
-    All rights reserved. Use is subject to license terms.
+/* Copyright (C) 2002, 2006 MySQL AB
 
-   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
+ 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
 
 /*
@@ -28,8 +26,39 @@
  Please read the file sha1.c for more information.
 
  Modified 2002 by Peter Zaitsev to better follow MySQL standards
-*/
 
+  Original Source from: http://www.faqs.org/rfcs/rfc3174.html
+
+  Copyright (C) The Internet Society (2001).  All Rights Reserved.
+
+  This document and translations of it may be copied and furnished to
+  others, and derivative works that comment on or otherwise explain it
+  or assist in its implementation may be prepared, copied, published
+  and distributed, in whole or in part, without restriction of any
+  kind, provided that the above copyright notice and this paragraph are
+  included on all such copies and derivative works.  However, this
+  document itself may not be modified in any way, such as by removing
+  the copyright notice or references to the Internet Society or other
+  Internet organizations, except as needed for the purpose of
+  developing Internet standards in which case the procedures for
+  copyrights defined in the Internet Standards process must be
+  followed, or as required to translate it into languages other than
+  English.
+
+  The limited permissions granted above are perpetual and will not be
+  revoked by the Internet Society or its successors or assigns.
+
+  This document and the information contained herein is provided on an
+  "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+  TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+  BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+  HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+  MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+  Acknowledgement 
+  Funding for the RFC Editor function is currently provided by the 
+  Internet Society. 
+*/
 
 enum sha_result_codes
 {

=== modified file 'mysql-test/collections/default.experimental'
--- a/mysql-test/collections/default.experimental	2010-03-15 09:31:35 +0000
+++ b/mysql-test/collections/default.experimental	2010-09-14 06:54:47 +0000
@@ -3,6 +3,8 @@
 
 
 binlog.binlog_unsafe @solaris            # Bug #47128 Test "binlog_unsafe" exceds default stack allocation
+rpl_ndb.rpl_ndb_typeconv_all @solaris    # bug#52131
+rpl_ndb.rpl_ndb_typeconv_lossy @solaris  # bug#52131
 
 funcs_1.charset_collation_1              # depends on compile-time decisions
 
@@ -16,3 +18,6 @@ rpl.rpl_innodb_bug28430*  @solaris      
 rpl_ndb.rpl_ndb_2ndb   # rpl_ndb_2ndb fails sporadically
 
 binlog.binlog_unsafe @solaris            # Bug #47128 Test "binlog_unsafe" exceds default stack allocation
+
+rpl_ndb.rpl_ndb_typeconv_all @solaris    # bug#52131
+rpl_ndb.rpl_ndb_typeconv_lossy @solaris  # bug#52131

=== modified file 'mysql-test/r/mysqldump.result'
--- a/mysql-test/r/mysqldump.result	2009-07-31 17:14:52 +0000
+++ b/mysql-test/r/mysqldump.result	2010-09-09 13:33:37 +0000
@@ -4563,3 +4563,53 @@ DROP TABLE t1, t2;
 #
 # End of 5.1 tests
 #
+#
+# Test for --add-drop-trigger
+#
+CREATE TABLE t1 (a int, b int);
+CREATE TRIGGER tt1_t1 BEFORE INSERT ON t1 FOR EACH ROW 
+SET NEW.b=NEW.a + 10;
+INSERT INTO t1 (a) VALUES (1),(2),(3);
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET latin1 */;
+
+USE `test`;
+/*!50003 SET @saved_cs_client      = @@character_set_client */ ;
+/*!50003 SET @saved_cs_results     = @@character_set_results */ ;
+/*!50003 SET @saved_col_connection = @@collation_connection */ ;
+/*!50003 SET character_set_client  = latin1 */ ;
+/*!50003 SET character_set_results = latin1 */ ;
+/*!50003 SET collation_connection  = latin1_swedish_ci */ ;
+/*!50003 SET @saved_sql_mode       = @@sql_mode */ ;
+/*!50003 SET sql_mode              = '' */ ;
+/*!50032 DROP TRIGGER IF EXISTS tt1_t1 */;
+DELIMITER ;;
+/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER tt1_t1 BEFORE INSERT ON t1 FOR EACH ROW 
+SET NEW.b=NEW.a + 10 */;;
+DELIMITER ;
+/*!50003 SET sql_mode              = @saved_sql_mode */ ;
+/*!50003 SET character_set_client  = @saved_cs_client */ ;
+/*!50003 SET character_set_results = @saved_cs_results */ ;
+/*!50003 SET collation_connection  = @saved_col_connection */ ;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+DROP TABLE t1;

=== modified file 'mysql-test/suite/funcs_1/t/disabled.def'
--- a/mysql-test/suite/funcs_1/t/disabled.def	2009-08-25 19:44:04 +0000
+++ b/mysql-test/suite/funcs_1/t/disabled.def	2010-09-07 07:58:29 +0000
@@ -10,4 +10,3 @@
 #
 ##############################################################################
 
-ndb_trig_1011ext:  Bug#32656 NDB: Duplicate key error aborts transaction in handler. Doesn't talk back to SQL

=== renamed file 'mysql-test/include/ndb_desc_print.inc' => 'mysql-test/suite/ndb/include/ndb_desc_print.inc'
=== renamed file 'mysql-test/include/ndb_execute_count.inc' => 'mysql-test/suite/ndb/include/ndb_execute_count.inc'
=== renamed file 'mysql-test/include/ndb_init_execute_count.inc' => 'mysql-test/suite/ndb/include/ndb_init_execute_count.inc'
=== renamed file 'mysql-test/include/ndb_init_scan_counts.inc' => 'mysql-test/suite/ndb/include/ndb_init_scan_counts.inc'
=== renamed file 'mysql-test/include/ndb_scan_counts.inc' => 'mysql-test/suite/ndb/include/ndb_scan_counts.inc'
=== modified file 'mysql-test/suite/ndb/r/ndb_database.result'
--- a/mysql-test/suite/ndb/r/ndb_database.result	2010-07-26 14:41:18 +0000
+++ b/mysql-test/suite/ndb/r/ndb_database.result	2010-09-22 12:06:29 +0000
@@ -59,4 +59,5 @@ create table newdb.t1(a int primary key)
 show tables;
 Tables_in_newdb
 t1
+drop table t1;
 drop database newdb;

=== modified file 'mysql-test/suite/ndb/r/ndb_partition_range.result'
--- a/mysql-test/suite/ndb/r/ndb_partition_range.result	2009-05-16 08:26:43 +0000
+++ b/mysql-test/suite/ndb/r/ndb_partition_range.result	2010-09-16 10:53:40 +0000
@@ -177,7 +177,7 @@ ENGINE=NDB;
 CREATE TABLESPACE ts1
 ADD DATAFILE 'datafile.dat'
   USE LOGFILE GROUP lg1
-INITIAL_SIZE 12M
+INITIAL_SIZE 16M
 ENGINE NDB;
 CREATE TABLE test.t1 (
 a1 INT,

=== modified file 'mysql-test/suite/ndb/t/ndb_bulk_delete.test'
--- a/mysql-test/suite/ndb/t/ndb_bulk_delete.test	2008-09-24 14:44:11 +0000
+++ b/mysql-test/suite/ndb/t/ndb_bulk_delete.test	2010-09-22 11:36:01 +0000
@@ -29,9 +29,9 @@ insert into t1 select a+128 from t1;
 --echo # 0 - delete the rows (without bulk update this is 5 + 1 for execute no commit)
 --echo # 1 - delete the row + commit the transaction
 --echo
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 delete from t1 where a in (1,7, 90, 100, 130);
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 # Test delete with non existant pk
 # Bug 37153
@@ -42,9 +42,9 @@ delete from t1 where a in (1,7, 90, 100,
 --echo # 1 - commit
 --echo # affected = 0
 --echo
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 delete from t1 where a=1000;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 --echo # expected result 1 roundtrips
 --echo # 0 - info call
@@ -53,9 +53,9 @@ delete from t1 where a=1000;
 --echo # 1 - commit
 --echo # affected = 0
 --echo
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 delete from t1 where a in (1000, 1001, 1002, 1003, 1004);
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 
 # cleanup

=== modified file 'mysql-test/suite/ndb/t/ndb_database.test'
--- a/mysql-test/suite/ndb/t/ndb_database.test	2010-07-26 14:41:18 +0000
+++ b/mysql-test/suite/ndb/t/ndb_database.test	2010-09-22 12:06:29 +0000
@@ -103,4 +103,5 @@ show tables;
 # Check that we can reuse the table name etc.
 create table newdb.t1(a int primary key) engine=ndb;
 show tables;
-drop database newdb;
\ No newline at end of file
+drop table t1;
+drop database newdb;

=== modified file 'mysql-test/suite/ndb/t/ndb_native_default_support.test'
--- a/mysql-test/suite/ndb/t/ndb_native_default_support.test	2010-08-19 13:35:45 +0000
+++ b/mysql-test/suite/ndb/t/ndb_native_default_support.test	2010-09-22 15:27:31 +0000
@@ -151,9 +151,9 @@ DROP TABLE IF EXISTS t1, bit1;
 --sorted_result
 SHOW TABLES;
 --let ndb_desc_opts= -d mysqltest t1
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 --let ndb_desc_opts= -d mysqltest bit1
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 SELECT pk,BIN(b1),BIN(b2),BIN(b3),BIN(b4),BIN(b5) FROM bit1 ORDER BY pk;
 --replace_column 12 CURRENT_TIMESTAMP
 SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c, ch2 FROM t1 ORDER BY i;
@@ -200,10 +200,10 @@ DROP DATABASE mysqltest;
 
 # Show that restored tables have no native defaults
 --let ndb_desc_opts= -d test t1
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 
 --let ndb_desc_opts= -d test bit1
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 
 USE test;
 --sorted_result
@@ -225,7 +225,7 @@ SHOW CREATE TABLE t1;
 
 # Show that the defaults are now native
 --let ndb_desc_opts= -d test t1
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 
 --disable_warnings
 INSERT INTO t1 VALUES();
@@ -252,12 +252,12 @@ SELECT pk,BIN(b1),BIN(b2),BIN(b3),BIN(b4
 #--echo * Alter table restoring from 6.3 backup to new table with native default support
 #--echo ********************************************************************************
 #--let ndb_desc_opts= -d test t1
-#--source include/ndb_desc_print.inc
+#--source suite/ndb/include/ndb_desc_print.inc
 #
 #ALTER TABLE t1 CHANGE COLUMN j j INT DEFAULT 6;
 #
 #--let ndb_desc_opts= -d test t1
-#--source include/ndb_desc_print.inc
+#--source suite/ndb/include/ndb_desc_print.inc
 
 --disable_warnings
 INSERT INTO t1(i, ch) VALUES(99, "native default support");
@@ -288,7 +288,7 @@ SELECT * FROM t2 ORDER BY i;
 ALTER TABLE t2 MODIFY COLUMN j INT DEFAULT 666;
 
 --let ndb_desc_opts= -d test t2
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 INSERT INTO t2 VALUES();
 SELECT * FROM t2 ORDER BY i;
 
@@ -306,7 +306,7 @@ DROP TABLE IF EXISTS t2;
 
 CREATE TABLE t1 (a int primary key, b int default 12, c char not null) engine=ndb;
 --let ndb_desc_opts= -d test t1
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 
 DROP TABLE t1;
 
@@ -324,7 +324,7 @@ CREATE TABLE t1 (a int primary key, 
                  h enum('Pig','Lion') not null,
                  i char(2) default '66') engine=ndb;
 --let ndb_desc_opts= -d test t1
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 
 DROP TABLE t1;
 
@@ -339,7 +339,7 @@ CREATE TABLE t1 (a int primary key,
 SHOW CREATE TABLE t1;
 
 --let ndb_desc_opts= -d test t1
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 
 DROP TABLE t1;
 
@@ -353,7 +353,7 @@ CREATE TABLE variant (a int primary key,
                       b timestamp) engine =ndb;
 SHOW CREATE TABLE variant;
 --let ndb_desc_opts= -d test variant
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 INSERT INTO variant (a) VALUES (1);
 --replace_column 2 CURRENT_TIMESTAMP
 SELECT * from variant;
@@ -364,7 +364,7 @@ CREATE TABLE variant (a int primary key,
                       b timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP) engine =ndb;
 SHOW CREATE TABLE variant;
 --let ndb_desc_opts= -d test variant
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 INSERT INTO variant (a) VALUES (1);
 --replace_column 2 CURRENT_TIMESTAMP
 SELECT * from variant;
@@ -375,7 +375,7 @@ CREATE TABLE variant (a int primary key,
                       b timestamp DEFAULT CURRENT_TIMESTAMP) engine = ndb;
 SHOW CREATE TABLE variant;
 --let ndb_desc_opts= -d test variant
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 INSERT INTO variant (a) VALUES (1);
 --replace_column 2 CURRENT_TIMESTAMP
 SELECT * from variant;
@@ -387,7 +387,7 @@ CREATE TABLE variant (a int primary key,
                       c int) engine = ndb;
 SHOW CREATE TABLE variant;
 --let ndb_desc_opts= -d test variant
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 INSERT INTO variant (a,c) VALUES (1,1);
 SELECT * from variant;
 UPDATE variant SET c=2;
@@ -400,7 +400,7 @@ CREATE TABLE variant (a int primary key,
                       b timestamp DEFAULT 0) engine = ndb;
 SHOW CREATE TABLE variant;
 --let ndb_desc_opts= -d test variant
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 INSERT INTO variant (a) VALUES (1);
 SELECT * from variant;
 DROP TABLE variant;
@@ -410,7 +410,7 @@ CREATE TABLE variant (a int primary key,
                       b timestamp DEFAULT 19770623000001) engine = ndb;
 SHOW CREATE TABLE variant;
 --let ndb_desc_opts= -d test variant
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 INSERT INTO variant (a) VALUES (1);
 SELECT * from variant;
 DROP TABLE variant;
@@ -421,7 +421,7 @@ CREATE TABLE variant (a int primary key,
                       c timestamp DEFAULT CURRENT_TIMESTAMP) engine = ndb;
 SHOW CREATE TABLE variant;
 --let ndb_desc_opts= -d test variant
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 INSERT INTO variant (a) VALUES (1);
 --replace_column 3 CURRENT_TIMESTAMP
 SELECT * from variant;
@@ -433,7 +433,7 @@ CREATE TABLE variant (a int primary key,
                       c timestamp ON UPDATE CURRENT_TIMESTAMP) engine = ndb;
 SHOW CREATE TABLE variant;
 --let ndb_desc_opts= -d test variant
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 INSERT INTO variant (a) VALUES (1);
 SELECT * from variant;
 UPDATE variant SET b=20100603000001;
@@ -447,7 +447,7 @@ CREATE TABLE variant (a int primary key,
                       c timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP) engine = ndb;
 SHOW CREATE TABLE variant;
 --let ndb_desc_opts= -d test variant
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 INSERT INTO variant (a) VALUES (1);
 --replace_column 3 CURRENT_TIMESTAMP
 SELECT * from variant;
@@ -458,7 +458,7 @@ CREATE TABLE variant (a int primary key,
                       b timestamp NULL) engine = ndb;
 SHOW CREATE TABLE variant;
 --let ndb_desc_opts= -d test variant
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 INSERT INTO variant (a) VALUES (1);
 SELECT * from variant;
 DROP TABLE variant;
@@ -468,7 +468,7 @@ CREATE TABLE variant (a int primary key,
                       b timestamp NULL DEFAULT 0) engine = ndb;
 SHOW CREATE TABLE variant;
 --let ndb_desc_opts= -d test variant
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 INSERT INTO variant (a) VALUES (1);
 SELECT * from variant;
 DROP TABLE variant;
@@ -478,7 +478,7 @@ CREATE TABLE variant (a int primary key,
                       b timestamp NULL DEFAULT 19770623000001) engine = ndb;
 SHOW CREATE TABLE variant;
 --let ndb_desc_opts= -d test variant
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 INSERT INTO variant (a) VALUES (1);
 SELECT * from variant;
 DROP TABLE variant;
@@ -488,7 +488,7 @@ CREATE TABLE variant (a int primary key,
                       b timestamp NULL DEFAULT CURRENT_TIMESTAMP) engine = ndb;
 SHOW CREATE TABLE variant;
 --let ndb_desc_opts= -d test variant
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 INSERT INTO variant (a) VALUES (1);
 --replace_column 2 CURRENT_TIMESTAMP
 SELECT * from variant;
@@ -500,7 +500,7 @@ CREATE TABLE variant (a int primary key,
                       c int) engine = ndb;
 SHOW CREATE TABLE variant;
 --let ndb_desc_opts= -d test variant
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 INSERT INTO variant (a,c) VALUES (1,1);
 SELECT * from variant;
 UPDATE variant SET c=2;
@@ -513,7 +513,7 @@ CREATE TABLE variant (a int primary key,
                       b timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP) engine = ndb;
 SHOW CREATE TABLE variant;
 --let ndb_desc_opts= -d test variant
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 INSERT INTO variant (a) VALUES (1);
 --replace_column 2 CURRENT_TIMESTAMP
 SELECT * from variant;
@@ -567,7 +567,7 @@ CREATE TABLE bit1 (
 SHOW CREATE TABLE t1;
 
 --let ndb_desc_opts= -d test t1
---source include/ndb_desc_print.inc
+--source suite/ndb/include/ndb_desc_print.inc
 
 --exec $NDB_RESTORE --no-defaults -b 1 -n 1 -r --promote-attribute --exclude-missing-columns $MYSQL_TEST_DIR/std_data/ndb_backup_before_native_default >> $NDB_TOOLS_OUTPUT
 --exec $NDB_RESTORE --no-defaults -b 1 -n 2 -r --promote-attribute --exclude-missing-columns $MYSQL_TEST_DIR/std_data/ndb_backup_before_native_default >> $NDB_TOOLS_OUTPUT

=== modified file 'mysql-test/suite/ndb/t/ndb_partition_hash.test'
--- a/mysql-test/suite/ndb/t/ndb_partition_hash.test	2009-04-08 17:41:18 +0000
+++ b/mysql-test/suite/ndb/t/ndb_partition_hash.test	2010-09-22 12:12:14 +0000
@@ -41,18 +41,18 @@ insert into t1 values (1,0,0,0,0),(1,0,0
 insert into t1 values (2,0,0,0,0),(4,0,0,0,0),(4,0,0,1,0);
 insert into t1 values (0,1,1,4,0),(0,1,1,5,0); # Only rows affected.
 
---source include/ndb_init_scan_counts.inc
+--source suite/ndb/include/ndb_init_scan_counts.inc
 UPDATE t1 force index (primary) SET ol_tmp = 1
 WHERE ol_o_id = 0 AND ol_d_id = 1 AND ol_w_id = 1;
---source include/ndb_scan_counts.inc
+--source suite/ndb/include/ndb_scan_counts.inc
 
---source include/ndb_init_scan_counts.inc
+--source suite/ndb/include/ndb_init_scan_counts.inc
 SELECT * FROM t1 WHERE ol_w_id = 1 AND ol_d_id = 1 AND ol_o_id = 0;
---source include/ndb_scan_counts.inc
+--source suite/ndb/include/ndb_scan_counts.inc
 
---source include/ndb_init_scan_counts.inc
+--source suite/ndb/include/ndb_init_scan_counts.inc
 SELECT SUM(ol_number) FROM t1 WHERE ol_o_id = 0 AND ol_w_id = 1 AND ol_d_id = 1;
---source include/ndb_scan_counts.inc
+--source suite/ndb/include/ndb_scan_counts.inc
 
 drop table t1;
 

=== modified file 'mysql-test/suite/ndb/t/ndb_partition_key.test'
--- a/mysql-test/suite/ndb/t/ndb_partition_key.test	2009-07-13 13:22:46 +0000
+++ b/mysql-test/suite/ndb/t/ndb_partition_key.test	2010-09-22 12:12:14 +0000
@@ -262,25 +262,25 @@ insert into nott1 values (1,2,6);
 insert into nott1 values (2,22,7);
 
 --echo All partitions scan
---source include/ndb_init_scan_counts.inc
+--source suite/ndb/include/ndb_init_scan_counts.inc
 select * from nott1 order by c;
---source include/ndb_scan_counts.inc
+--source suite/ndb/include/ndb_scan_counts.inc
 
 --echo Single partition scan
---source include/ndb_init_scan_counts.inc
+--source suite/ndb/include/ndb_init_scan_counts.inc
 select * from nott1 where a=0 order by c;
---source include/ndb_scan_counts.inc
+--source suite/ndb/include/ndb_scan_counts.inc
 
 --echo Single partition scan
---source include/ndb_init_scan_counts.inc
+--source suite/ndb/include/ndb_init_scan_counts.inc
 select * from nott1 where a=4 order by c;
---source include/ndb_scan_counts.inc
+--source suite/ndb/include/ndb_scan_counts.inc
 
 --echo MRR scan on one partition
---source include/ndb_init_scan_counts.inc
+--source suite/ndb/include/ndb_init_scan_counts.inc
 select * from nott1 where a=0 and (( b > 0 and b < 3) or 
                                    ( b > 5 and b < 10) or 
                                    ( b > 22 and b < 50)) order by c;
---source include/ndb_scan_counts.inc
+--source suite/ndb/include/ndb_scan_counts.inc
 
 drop table nott1;

=== modified file 'mysql-test/suite/ndb/t/ndb_partition_list.test'
--- a/mysql-test/suite/ndb/t/ndb_partition_list.test	2009-05-16 08:26:43 +0000
+++ b/mysql-test/suite/ndb/t/ndb_partition_list.test	2010-09-22 12:12:14 +0000
@@ -61,23 +61,23 @@ insert into t1 values (4, 1, 7);
 insert into t1 values (4, 2, 8);
 
 --echo All partitions scan
---source include/ndb_init_scan_counts.inc
+--source suite/ndb/include/ndb_init_scan_counts.inc
 select * from t1 order by c;
---source include/ndb_scan_counts.inc
+--source suite/ndb/include/ndb_scan_counts.inc
 
 --echo Single partition scan
---source include/ndb_init_scan_counts.inc
+--source suite/ndb/include/ndb_init_scan_counts.inc
 select * from t1 where a=0 order by c;
---source include/ndb_scan_counts.inc
+--source suite/ndb/include/ndb_scan_counts.inc
 
 --echo Single partition scan
---source include/ndb_init_scan_counts.inc
+--source suite/ndb/include/ndb_init_scan_counts.inc
 select * from t1 where a=4 order by c;
---source include/ndb_scan_counts.inc
+--source suite/ndb/include/ndb_scan_counts.inc
 
 --echo MRR single partition scan
---source include/ndb_init_scan_counts.inc
+--source suite/ndb/include/ndb_init_scan_counts.inc
 select * from t1 where a in (0, 2) order by c;
---source include/ndb_scan_counts.inc
+--source suite/ndb/include/ndb_scan_counts.inc
 
 drop table t1;

=== modified file 'mysql-test/suite/ndb/t/ndb_partition_range.test'
--- a/mysql-test/suite/ndb/t/ndb_partition_range.test	2009-05-16 08:26:43 +0000
+++ b/mysql-test/suite/ndb/t/ndb_partition_range.test	2010-09-22 12:12:14 +0000
@@ -147,7 +147,7 @@ CREATE LOGFILE GROUP lg1
 CREATE TABLESPACE ts1
   ADD DATAFILE 'datafile.dat'
   USE LOGFILE GROUP lg1
-  INITIAL_SIZE 12M
+  INITIAL_SIZE 16M
   ENGINE NDB;
 
 CREATE TABLE test.t1 (
@@ -294,28 +294,28 @@ insert into t1 values (4, 1, 7);
 insert into t1 values (4, 2, 8);
 
 --echo All partitions scan
---source include/ndb_init_scan_counts.inc
+--source suite/ndb/include/ndb_init_scan_counts.inc
 select * from t1 order by c;
---source include/ndb_scan_counts.inc
+--source suite/ndb/include/ndb_scan_counts.inc
 
 --echo Single partition scan
---source include/ndb_init_scan_counts.inc
+--source suite/ndb/include/ndb_init_scan_counts.inc
 select * from t1 where a=0 order by c;
---source include/ndb_scan_counts.inc
+--source suite/ndb/include/ndb_scan_counts.inc
 
 --echo Single partition scan
---source include/ndb_init_scan_counts.inc
+--source suite/ndb/include/ndb_init_scan_counts.inc
 select * from t1 where a=4 order by c;
---source include/ndb_scan_counts.inc
+--source suite/ndb/include/ndb_scan_counts.inc
 
 --echo Single partition scan
---source include/ndb_init_scan_counts.inc
+--source suite/ndb/include/ndb_init_scan_counts.inc
 select * from t1 where a<3 order by c;
---source include/ndb_scan_counts.inc
+--source suite/ndb/include/ndb_scan_counts.inc
 
 --echo MRR single partition scan
---source include/ndb_init_scan_counts.inc
+--source suite/ndb/include/ndb_init_scan_counts.inc
 select * from t1 where a in (0, 2) order by c;
---source include/ndb_scan_counts.inc
+--source suite/ndb/include/ndb_scan_counts.inc
 
 drop table t1;

=== modified file 'mysql-test/suite/ndb/t/ndb_read_multi_range.test'
--- a/mysql-test/suite/ndb/t/ndb_read_multi_range.test	2009-02-03 13:35:56 +0000
+++ b/mysql-test/suite/ndb/t/ndb_read_multi_range.test	2010-09-22 11:36:01 +0000
@@ -14,98 +14,98 @@ create table t1 (
   c int not null,
   index(b), unique index using hash(c)
 ) engine = ndb;
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 insert into t1 values
   (1,2,1),(2,3,2),(3,4,3),(4,5,4),
   (5,2,12),(6,3,11),(7,4,10),(8,5,9),
   (9,2,8),(10,3,7),(11,4,6),(12,5,5);
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 # batch on primary key
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 create table r1 as select * from t1 where a in (2,8,12);
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 select * from r1 order by a;
 drop table r1;
 
 # batch on ordered index
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 create table r1 as select * from t1 where b in (1,2,5);
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 select * from r1 order by a;
 drop table r1;
 
 # batch on unique hash index
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 create table r1 as select * from t1 where c in (2,8,12);
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 select * from r1 order by a;
 drop table r1;
 
 # batch mixed
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 create table r1 as select * from t1 where a in (2,8) or (a > 11) or (a <= 1);
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 select * from r1 order by a;
 drop table r1;
 
 # batch on primary key, missing values
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 create table r1 as select * from t1 where a in (33,8,12);
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 select * from r1 order by a;
 drop table r1;
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 create table r1 as select * from t1 where a in (2,33,8,12,34);
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 select * from r1 order by a;
 drop table r1;
 
 # batch on ordered index, missing values
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 create table r1 as select * from t1 where b in (1,33,5);
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 select * from r1 order by a;
 drop table r1;
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 select * from t1 where b in (1,33,5) order by a;
---source include/ndb_execute_count.inc
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 create table r1 as select * from t1 where b in (45,1,33,5,44);
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 select * from r1 order by a;
 drop table r1;
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 select * from t1 where b in (45,22) order by a;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 # batch on unique hash index, missing values
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 create table r1 as select * from t1 where c in (2,8,33);
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 select * from r1 order by a;
 drop table r1;
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 create table r1 as select * from t1 where c in (13,2,8,33,12);
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 select * from r1 order by a;
 drop table r1;
 
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 select * from t1 where a in (33,8,12) order by a;
---source include/ndb_execute_count.inc
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 select * from t1 where a in (33,34,35) order by a;
---source include/ndb_execute_count.inc
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 select * from t1 where a in (2,8) or (a > 11) or (a <= 1) order by a;
---source include/ndb_execute_count.inc
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 select * from t1 where b in (6,7) or (b <= 5) or (b >= 10) order by b,a;
---source include/ndb_execute_count.inc
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 select * from t1 where c in (13,2,8,33,12) order by c,a;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 drop table t1;
 
 #
@@ -121,7 +121,7 @@ create table t1 (
   primary key (a,b,c,d), index (d)
 ) engine = ndb;
 
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 insert into t1 values
   (1,2,1,1,1),(2,3,2,3,1),(3,4,3,1,1),(4,5,4,7,1),
   (5,2,12,12,1),(6,3,11,1,1),(7,4,10,3,1),(8,5,9,5,1),
@@ -130,13 +130,13 @@ insert into t1 values
   (1,2,1,3,1),
   (1,2,1,4,1),
   (1,2,1,5,1);
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 # batch on primary key
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 create table r1 as select * from t1
   where a=1 and b=2 and c=1 and d in (1,4,3,2);
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 select * from r1 order by a,b,c,d;
 drop table r1;
 

=== modified file 'mysql-test/suite/ndb/t/ndb_sql_allow_batching.test'
--- a/mysql-test/suite/ndb/t/ndb_sql_allow_batching.test	2008-05-08 08:39:40 +0000
+++ b/mysql-test/suite/ndb/t/ndb_sql_allow_batching.test	2010-09-22 11:36:01 +0000
@@ -13,36 +13,36 @@ create table t2 (a int key, b int) engin
 insert into t1 values (0,0),(1,1),(2,2);
 insert into t2 select * from t1;
 
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 begin;
 set transaction_allow_batching=1;
 update t1 set b=0 where a=2;
 commit;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 select * from t1 order by a;
 
 --echo
 --echo With batching only 1 roundtrip
 --echo
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 begin;
 set transaction_allow_batching=1;
 insert into t1 values (10,10);
 insert into t2 values (10,10);
 commit;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 select * from t1 order by a;
 
 --echo
 --echo Without batching only 3 roundtrips
 --echo
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 begin;
 set transaction_allow_batching=0;
 insert into t1 values (11,11);
 insert into t2 values (11,11);
 commit;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 select * from t1 order by a;
 
 # cleanup

=== modified file 'mysql-test/suite/ndb/t/ndb_update_no_read.test'
--- a/mysql-test/suite/ndb/t/ndb_update_no_read.test	2008-12-05 09:46:39 +0000
+++ b/mysql-test/suite/ndb/t/ndb_update_no_read.test	2010-09-22 11:36:01 +0000
@@ -34,9 +34,9 @@ insert into t1 values (1,10,1),(2,9,1),(
 --echo # 0 - update the row (deferred to commit)
 --echo # 1 - update + commit the transaction
 --echo
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 update t1 set c = 111, b = 20 where a = 1;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 select * from t1 where a = 1 order by a;
 
@@ -47,9 +47,9 @@ select * from t1 where a = 1 order by a;
 --echo # 0 - delete the row (deferred to commit)
 --echo # 1 - delete + commit the transaction
 --echo
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 delete from t1 where a = 1;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 select * from t1 where a = 1 order by a;
 
@@ -60,9 +60,9 @@ select * from t1 where a = 1 order by a;
 --echo # 0 - update the row (deferred to commit)
 --echo # 1 - update + commit the transaction
 --echo
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 update t1 set c = 1111 where b = 2;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 select * from t1 where b = 2 order by a;
 
@@ -73,9 +73,9 @@ select * from t1 where b = 2 order by a;
 --echo # 0 - update the row (deferred to commit)
 --echo # 1 - update + commit the transaction
 --echo
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 update t1 set c = 12, b = 19 where b = 2;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 select * from t1 where b = 2 order by a;
 
@@ -86,9 +86,9 @@ select * from t1 where b = 2 order by a;
 --echo # 0 - delete the row (deferred to commit)
 --echo # 1 - delete and commit the transaction
 --echo
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 delete from t1 where b = 19;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 select * from t1 where b = 19 order by a;
 
@@ -99,9 +99,9 @@ select * from t1 where b = 19 order by a
 --echo # 0 - update the rows (deferred to commit)
 --echo # 1 - update + commit the transaction
 --echo
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 update t1 set c = 22 where a = 10 or a >= 10;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 select * from t1 order by a;
 
@@ -112,9 +112,9 @@ select * from t1 order by a;
 --echo # 0 - update the rows (2 if no bulk update + 1 deferred to commit)
 --echo # 1 - update + commit the transaction
 --echo
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 update t1 set c = 23 where a in (8,10);
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 select * from t1 order by a;
 
@@ -125,9 +125,9 @@ select * from t1 order by a;
 --echo # 0 - update the rows (executed during read)
 --echo # 1 - commit the transaction
 --echo
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 update t1 set c = 23 where a in (7,8) or a >= 10;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 select * from t1 order by a;
 
@@ -141,11 +141,11 @@ select * from t1 order by a;
 --echo # 0 - update the rows (deferred to commit)
 --echo # 1 - update + commit the transaction
 --echo
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 update t1 set c = 11 where a = 3 or b = 7;
 ### Disable this test, as it's unpredictable...
 ### cause scan can get one or two batches...
-#--source include/ndb_execute_count.inc
+#--source suite/ndb/include/ndb_execute_count.inc
 
 select * from t1 where a = 3 or b = 7 order by a;
 
@@ -158,9 +158,9 @@ select * from t1 where a = 3 or b = 7 or
 --echo # 1 - insert the row (pk update)
 --echo # 1 - commit the transaction
 --echo
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 update t1 set a = 13, b = 20 where a = 3;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 select * from t1 where a = 13 order by a;
 
@@ -173,9 +173,9 @@ select * from t1 where a = 13 order by a
 --echo # 1 - insert the row (pk update)
 --echo # 1 - commit the transaction
 --echo
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 update t1 set a = 12, b = 19 where b = 7;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 select * from t1 where b = 19 order by a;
 
@@ -188,9 +188,9 @@ select * from t1 where b = 7 order by a;
 --echo # 0 - update the rows (deferred to commit)
 --echo # 1 - update + commit the transaction
 --echo
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 update t1 set c = 12, b = 29 where a = 5 and b = 6;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 select * from t1 where b = 19 order by a;
 
@@ -201,9 +201,9 @@ select * from t1 where b = 19 order by a
 --echo # 0 - delete the rows (no row found)
 --echo # 1 - commit the transaction
 --echo
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 delete from t1 where b = 6 and c = 12;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 select * from t1 where b = 6 order by a;
 
@@ -227,9 +227,9 @@ insert into t1 values (1, '1'), (2, '2')
 --echo # 1 - update+commit the row
 --echo # Rows matched=changed=affected=1
 --echo 
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 update t1 set b='two' where a=2;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 
 # Autocommit, unsuccessful update
@@ -241,9 +241,9 @@ update t1 set b='two' where a=2;
 --echo # 1 - update+commit the row
 --echo # Rows matched=changed=affected=0
 --echo 
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 update t1 set b='lots' where a=2000;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 # Autocommit, successful update + warning
 --echo
@@ -255,9 +255,9 @@ update t1 set b='lots' where a=2000;
 --echo # Rows matched=changed=affected=1
 --echo # 1 warning
 --echo 
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 update t1 set b='one plus one' where a=2;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 
 # Autocommit, unsuccessful update + warning
@@ -271,10 +271,10 @@ update t1 set b='one plus one' where a=2
 --echo # 1 warning
 --echo 
 --disable_warnings # Workaround to bug#39663
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 update t1 set b='two thousand' where a=2000;
 show warnings; # Workaround to bug#39663
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 --enable_warnings # Workaround to bug#39663
 
 
@@ -287,11 +287,11 @@ show warnings; # Workaround to bug#39663
 --echo # 1 - commit
 --echo # Rows matched=changed=affected=1
 --echo 
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 begin;
 update t1 set b='two' where a=2;
 commit;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 
 # No autocommit, unsuccessful update
@@ -303,11 +303,11 @@ commit;
 --echo # 1 - commit
 --echo # Rows matched=changed=affected=0
 --echo 
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 begin;
 update t1 set b='lots' where a=2000;
 commit;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 
 # No autocommit, successful update + warning
@@ -320,11 +320,11 @@ commit;
 --echo # Rows matched=changed=affected=1
 --echo 1 warning
 --echo 
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 begin;
 update t1 set b='one plus one' where a=2;
 commit;
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 
 
 # No autocommit, unsuccessful update + warning
@@ -338,12 +338,12 @@ commit;
 --echo # 1 warning
 --echo 
 --disable_warnings # Workaround to bug#39663
---source include/ndb_init_execute_count.inc
+--source suite/ndb/include/ndb_init_execute_count.inc
 begin;
 update t1 set b='two thousand' where a=2000;
 commit;
 show warnings; # Workaround to bug#39663
---source include/ndb_execute_count.inc
+--source suite/ndb/include/ndb_execute_count.inc
 --enable_warnings # Workaround to bug#39663
 
 drop table t1;

=== modified file 'mysql-test/suite/ndb/t/test_mgmd.cnf'
--- a/mysql-test/suite/ndb/t/test_mgmd.cnf	2009-09-25 10:40:45 +0000
+++ b/mysql-test/suite/ndb/t/test_mgmd.cnf	2010-09-14 09:38:41 +0000
@@ -7,3 +7,4 @@
 [ENV]
 # The started ndb_mgmd's will be started from base + 1
 NDBT_BASE_PORT= @mysqld.1.port
+NDBAPITEST_MAXLINES=512

=== modified file 'mysql-test/t/mysqldump.test'
--- a/mysql-test/t/mysqldump.test	2009-09-30 18:51:17 +0000
+++ b/mysql-test/t/mysqldump.test	2010-09-09 13:33:37 +0000
@@ -2138,5 +2138,17 @@ DROP TABLE t1, t2;
 --echo # End of 5.1 tests
 --echo #
 
+--echo #
+--echo # Test for --add-drop-trigger
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+CREATE TRIGGER tt1_t1 BEFORE INSERT ON t1 FOR EACH ROW 
+  SET NEW.b=NEW.a + 10;
+
+INSERT INTO t1 (a) VALUES (1),(2),(3);
+--exec $MYSQL_DUMP --triggers --no-data --no-create-info --add-drop-trigger --skip-comments --databases test
+DROP TABLE t1;
+
 # Wait till we reached the initial number of concurrent sessions
 --source include/wait_until_count_sessions.inc

=== modified file 'mysys/sha1.c'
--- a/mysys/sha1.c	2009-05-26 18:53:34 +0000
+++ b/mysys/sha1.c	2010-09-07 06:39:57 +0000
@@ -1,35 +1,65 @@
-/*
-   Copyright (C) 2002, 2004, 2006 MySQL AB
-    All rights reserved. Use is subject to license terms.
+/* Copyright (c) 2002, 2004, 2006 MySQL AB
 
-   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
+ 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
 
 /*
   Original Source from: http://www.faqs.org/rfcs/rfc3174.html
 
+  Copyright (C) The Internet Society (2001).  All Rights Reserved.
+
+  This document and translations of it may be copied and furnished to
+  others, and derivative works that comment on or otherwise explain it
+  or assist in its implementation may be prepared, copied, published
+  and distributed, in whole or in part, without restriction of any
+  kind, provided that the above copyright notice and this paragraph are
+  included on all such copies and derivative works.  However, this
+  document itself may not be modified in any way, such as by removing
+  the copyright notice or references to the Internet Society or other
+  Internet organizations, except as needed for the purpose of
+  developing Internet standards in which case the procedures for
+  copyrights defined in the Internet Standards process must be
+  followed, or as required to translate it into languages other than
+  English.
+
+  The limited permissions granted above are perpetual and will not be
+  revoked by the Internet Society or its successors or assigns.
+
+  This document and the information contained herein is provided on an
+  "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+  TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+  BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+  HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+  MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+  Acknowledgement 
+  Funding for the RFC Editor function is currently provided by the 
+  Internet Society. 
+
  DESCRIPTION
-   This file implements the Secure Hashing Algorithm 1 as
-   defined in FIPS PUB 180-1 published April 17, 1995.
+  This file implements the Secure Hashing Algorithm 1 as
+  defined in FIPS PUB 180-1 published April 17, 1995.
 
-   The SHA-1, produces a 160-bit message digest for a given data
-   stream.  It should take about 2**n steps to find a message with the
-   same digest as a given message and 2**(n/2) to find any two
-   messages with the same digest, when n is the digest size in bits.
-   Therefore, this algorithm can serve as a means of providing a
-   "fingerprint" for a message.
+  The SHA-1, produces a 160-bit message digest for a given data
+  stream.  It should take about 2**n steps to find a message with the
+  same digest as a given message and 2**(n/2) to find any two
+  messages with the same digest, when n is the digest size in bits.
+  Therefore, this algorithm can serve as a means of providing a
+  "fingerprint" for a message.
+*/
 
+/*
  PORTABILITY ISSUES
    SHA-1 is defined in terms of 32-bit "words".  This code uses
    <stdint.h> (included via "sha1.h" to define 32 and 8 bit unsigned

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2010-09-03 08:59:02 +0000
+++ b/sql/ha_ndbcluster.cc	2010-09-23 11:55:42 +0000
@@ -2053,8 +2053,7 @@ check_completed_operations(Thd_ndb *thd_
 }
 
 void
-ha_ndbcluster::release_completed_operations(Thd_ndb *thd_ndb,
-                                            NdbTransaction *trans)
+ha_ndbcluster::release_completed_operations(NdbTransaction *trans)
 {
   DBUG_ENTER("ha_ndbcluster::release_completed_operations");
   /**
@@ -2079,7 +2078,7 @@ int execute_no_commit(Thd_ndb *thd_ndb, 
                       uint *ignore_count)
 {
   DBUG_ENTER("execute_no_commit");
-  ha_ndbcluster::release_completed_operations(thd_ndb, trans);
+  ha_ndbcluster::release_completed_operations(trans);
   const NdbOperation *first= trans->getFirstDefinedOperation();
   thd_ndb->m_execute_count++;
   DBUG_PRINT("info", ("execute_count: %u", thd_ndb->m_execute_count));
@@ -2141,7 +2140,7 @@ inline
 int execute_no_commit_ie(Thd_ndb *thd_ndb, NdbTransaction *trans)
 {
   DBUG_ENTER("execute_no_commit_ie");
-  ha_ndbcluster::release_completed_operations(thd_ndb, trans);
+  ha_ndbcluster::release_completed_operations(trans);
   int res= trans->execute(NdbTransaction::NoCommit,
                           NdbOperation::AO_IgnoreError,
                           thd_ndb->m_force_send);
@@ -4513,7 +4512,7 @@ inline int ha_ndbcluster::fetch_next(Ndb
        nextResult() on Blobs generates Blob part read ops,
        so we will free them here
     */
-    release_completed_operations(m_thd_ndb, trans);
+    release_completed_operations(trans);
     
     if ((local_check= cursor->nextResult(&_m_next_row,
                                          contact_ndb,
@@ -11305,7 +11304,9 @@ int ndbcluster_drop_database_impl(THD *t
     }
     pthread_mutex_unlock(&LOCK_open);
   }
-  DBUG_RETURN(ret);      
+
+  dict->invalidateDbGlobal(dbname);
+  DBUG_RETURN(ret);
 }
 
 static void ndbcluster_drop_database(handlerton *hton, char *path)
@@ -11324,9 +11325,20 @@ static void ndbcluster_drop_database(han
   ndbcluster_drop_database_impl(thd, path);
   char db[FN_REFLEN];
   ha_ndbcluster::set_dbname(path, db);
+  uint32 table_id= 0, table_version= 0;
+  /*
+    Since databases aren't real ndb schema object
+    they don't have any id/version
+
+    But since that id/version is used to make sure that event's on SCHEMA_TABLE
+    is correct, we set random numbers
+  */
+  table_id = (uint32)rand();
+  table_version = (uint32)rand();
   ndbcluster_log_schema_op(thd,
                            thd->query(), thd->query_length(),
-                           db, "", 0, 0, SOT_DROP_DB, 0, 0, 0);
+                           db, "", table_id, table_version,
+                           SOT_DROP_DB, 0, 0, 0);
   DBUG_VOID_RETURN;
 }
 
@@ -15421,42 +15433,84 @@ err:
     /* ndb_share reference schema free */
     DBUG_PRINT("NDB_SHARE", ("%s binlog schema free  use_count: %u",
                              m_share->key, m_share->use_count));
+    delete alter_data;
+    alter_info->data= 0;
   }
   set_ndb_share_state(m_share, NSS_INITIAL);
   free_share(&m_share); // Decrease ref_count
-  delete alter_data;
   DBUG_RETURN(error);
 }
 
-int ha_ndbcluster::alter_table_phase3(THD *thd, TABLE *table)
+int ha_ndbcluster::alter_table_phase3(THD *thd, TABLE *table,
+                                      HA_CREATE_INFO *create_info,
+                                      HA_ALTER_INFO *alter_info,
+                                      HA_ALTER_FLAGS *alter_flags)
 {
   DBUG_ENTER("alter_table_phase3");
 
+  NDB_ALTER_DATA *alter_data= (NDB_ALTER_DATA *) alter_info->data;
   if (!ndbcluster_has_global_schema_lock(get_thd_ndb(thd)))
+  {
+    delete alter_data;
+    alter_info->data= 0;
     DBUG_RETURN(ndbcluster_no_global_schema_lock_abort
                 (thd, "ha_ndbcluster::alter_table_phase3"));
+  }
 
   const char *db= table->s->db.str;
   const char *name= table->s->table_name.str;
+
   /*
     all mysqld's will read frms from disk and setup new
     event operation for the table (new_op)
   */
+  uint32 table_id= 0, table_version= 0;
+  DBUG_ASSERT(alter_data != 0);
+  if (alter_data)
+  {
+    table_id= alter_data->table_id;
+    table_version= alter_data->old_table_version;
+  }
   ndbcluster_log_schema_op(thd, thd->query(), thd->query_length(),
                            db, name,
-                           0, 0,
+                           table_id, table_version,
                            SOT_ONLINE_ALTER_TABLE_PREPARE,
                            0, 0, 0);
+
+  /*
+    Get table id/version for new table
+  */
+  table_id= 0;
+  table_version= 0;
+  {
+    Ndb* ndb= get_ndb(thd);
+    DBUG_ASSERT(ndb != 0);
+    if (ndb)
+    {
+      ndb->setDatabaseName(db);
+      Ndb_table_guard ndbtab(ndb->getDictionary(), name);
+      const NDBTAB *new_tab= ndbtab.get_table();
+      DBUG_ASSERT(new_tab != 0);
+      if (new_tab)
+      {
+        table_id= new_tab->getObjectId();
+        table_version= new_tab->getObjectVersion();
+      }
+    }
+  }
+
   /*
     all mysqld's will switch to using the new_op, and delete the old
     event operation
   */
   ndbcluster_log_schema_op(thd, thd->query(), thd->query_length(),
                            db, name,
-                           0, 0,
+                           table_id, table_version,
                            SOT_ONLINE_ALTER_TABLE_COMMIT,
                            0, 0, 0);
 
+  delete alter_data;
+  alter_info->data= 0;
   DBUG_RETURN(0);
 }
 
@@ -15531,6 +15585,7 @@ int ndbcluster_alter_tablespace(handlert
   }
   dict= ndb->getDictionary();
 
+  uint32 table_id= 0, table_version= 0;
   switch (alter_info->ts_cmd_type){
   case (CREATE_TABLESPACE):
   {
@@ -15553,6 +15608,8 @@ int ndbcluster_alter_tablespace(handlert
       DBUG_PRINT("error", ("createTablespace returned %d", error));
       goto ndberror;
     }
+    table_id = objid.getObjectId();
+    table_version = objid.getObjectVersion();
     if (dict->getWarningFlags() &
         NdbDictionary::Dictionary::WarnExtentRoundUp)
     {
@@ -15605,10 +15662,13 @@ int ndbcluster_alter_tablespace(handlert
 	DBUG_RETURN(1);
       }
       errmsg= " CREATE DATAFILE";
-      if (dict->createDatafile(ndb_df))
+      NdbDictionary::ObjectId objid;
+      if (dict->createDatafile(ndb_df, false, &objid))
       {
 	goto ndberror;
       }
+      table_id= objid.getObjectId();
+      table_version= objid.getObjectVersion();
       if (dict->getWarningFlags() &
           NdbDictionary::Dictionary::WarnDatafileRoundUp)
       {
@@ -15631,6 +15691,8 @@ int ndbcluster_alter_tablespace(handlert
       NdbDictionary::Datafile df= dict->getDatafile(0, alter_info->data_file_name);
       NdbDictionary::ObjectId objid;
       df.getTablespaceId(&objid);
+      table_id = df.getObjectId();
+      table_version = df.getObjectVersion();
       if (ts.getObjectId() == objid.getObjectId() && 
 	  strcmp(df.getPath(), alter_info->data_file_name) == 0)
       {
@@ -15678,6 +15740,8 @@ int ndbcluster_alter_tablespace(handlert
     {
       goto ndberror;
     }
+    table_id = objid.getObjectId();
+    table_version = objid.getObjectVersion();
     if (dict->getWarningFlags() &
         NdbDictionary::Dictionary::WarnUndobufferRoundUp)
     {
@@ -15728,10 +15792,13 @@ int ndbcluster_alter_tablespace(handlert
       DBUG_RETURN(1);
     }
     errmsg= "CREATE UNDOFILE";
-    if (dict->createUndofile(ndb_uf))
+    NdbDictionary::ObjectId objid;
+    if (dict->createUndofile(ndb_uf, false, &objid))
     {
       goto ndberror;
     }
+    table_id = objid.getObjectId();
+    table_version = objid.getObjectVersion();
     if (dict->getWarningFlags() &
         NdbDictionary::Dictionary::WarnUndofileRoundDown)
     {
@@ -15745,7 +15812,11 @@ int ndbcluster_alter_tablespace(handlert
   {
     error= ER_DROP_FILEGROUP_FAILED;
     errmsg= "TABLESPACE";
-    if (dict->dropTablespace(dict->getTablespace(alter_info->tablespace_name)))
+    NdbDictionary::Tablespace ts=
+      dict->getTablespace(alter_info->tablespace_name);
+    table_id= ts.getObjectId();
+    table_version= ts.getObjectVersion();
+    if (dict->dropTablespace(ts))
     {
       goto ndberror;
     }
@@ -15756,7 +15827,11 @@ int ndbcluster_alter_tablespace(handlert
   {
     error= ER_DROP_FILEGROUP_FAILED;
     errmsg= "LOGFILE GROUP";
-    if (dict->dropLogfileGroup(dict->getLogfileGroup(alter_info->logfile_group_name)))
+    NdbDictionary::LogfileGroup lg=
+      dict->getLogfileGroup(alter_info->logfile_group_name);
+    table_id= lg.getObjectId();
+    table_version= lg.getObjectVersion();
+    if (dict->dropLogfileGroup(lg))
     {
       goto ndberror;
     }
@@ -15779,13 +15854,13 @@ int ndbcluster_alter_tablespace(handlert
     ndbcluster_log_schema_op(thd,
                              thd->query(), thd->query_length(),
                              "", alter_info->tablespace_name,
-                             0, 0,
+                             table_id, table_version,
                              SOT_TABLESPACE, 0, 0, 0);
   else
     ndbcluster_log_schema_op(thd,
                              thd->query(), thd->query_length(),
                              "", alter_info->logfile_group_name,
-                             0, 0,
+                             table_id, table_version,
                              SOT_LOGFILE_GROUP, 0, 0, 0);
   DBUG_RETURN(FALSE);
 

=== modified file 'sql/ha_ndbcluster.h'
--- a/sql/ha_ndbcluster.h	2010-06-22 05:24:36 +0000
+++ b/sql/ha_ndbcluster.h	2010-09-23 11:55:42 +0000
@@ -109,13 +109,17 @@ public:
 		 const NdbDictionary::Table *table) :
     dictionary(dict),
     old_table(table),
-    new_table(new NdbDictionary::Table(*table))
+    new_table(new NdbDictionary::Table(*table)),
+      table_id(table->getObjectId()),
+      old_table_version(table->getObjectVersion())
   {}
   ~NDB_ALTER_DATA()
   { delete new_table; }
   NdbDictionary::Dictionary *dictionary;
   const  NdbDictionary::Table *old_table;
   NdbDictionary::Table *new_table;
+  Uint32 table_id;
+  Uint32 old_table_version;
 };
 
 typedef union { const NdbRecAttr *rec; NdbBlob *blob; void *ptr; } NdbValue;
@@ -541,7 +545,7 @@ static void set_tabname(const char *path
     static member function as it needs to access private
     NdbTransaction methods
   */
-  static void release_completed_operations(Thd_ndb*, NdbTransaction*);
+  static void release_completed_operations(NdbTransaction*);
 
   /*
     Condition pushdown
@@ -624,7 +628,10 @@ static void set_tabname(const char *path
                          HA_ALTER_INFO *alter_info,
                          HA_ALTER_FLAGS *alter_flags);
 
-  int alter_table_phase3(THD *thd, TABLE *table);
+  int alter_table_phase3(THD *thd, TABLE *table,
+                         HA_CREATE_INFO *create_info,
+                         HA_ALTER_INFO *alter_info,
+                         HA_ALTER_FLAGS *alter_flags);
 
 private:
 #ifdef HAVE_NDB_BINLOG

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2010-09-01 10:08:49 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2010-09-15 18:38:13 +0000
@@ -140,6 +140,8 @@ typedef struct st_ndb_schema_object {
   uint use_count;
   MY_BITMAP slock_bitmap;
   uint32 slock[256/32]; // 256 bits for lock status of table
+  uint32 table_id;
+  uint32 table_version;
 } NDB_SCHEMA_OBJECT;
 static NDB_SCHEMA_OBJECT *ndb_get_schema_object(const char *key,
                                                 my_bool create_if_not_exists,
@@ -670,6 +672,16 @@ ndbcluster_binlog_log_query(handlerton *
                        db, table_name, query));
   enum SCHEMA_OP_TYPE type;
   int log= 0;
+  uint32 table_id= 0, table_version= 0;
+  /*
+    Since databases aren't real ndb schema object
+    they don't have any id/version
+
+    But since that id/version is used to make sure that event's on SCHEMA_TABLE
+    is correct, we set random numbers
+  */
+  table_id = (uint32)rand();
+  table_version = (uint32)rand();
   switch (binlog_command)
   {
   case LOGCOM_CREATE_TABLE:
@@ -704,7 +716,7 @@ ndbcluster_binlog_log_query(handlerton *
   if (log)
   {
     ndbcluster_log_schema_op(thd, query, query_length,
-                             db, table_name, 0, 0, type,
+                             db, table_name, table_id, table_version, type,
                              0, 0, 0);
   }
   DBUG_VOID_RETURN;
@@ -932,6 +944,10 @@ static int ndbcluster_global_schema_lock
 
   if (thd_ndb->global_schema_lock_trans)
   {
+    if (opt_ndb_extra_logging > 19)
+    {
+      sql_print_information("NDB: Global schema lock acquired");
+    }
     DBUG_RETURN(0);
   }
 
@@ -991,6 +1007,10 @@ static int ndbcluster_global_schema_unlo
                           "ndb. Releasing global schema lock");
       DBUG_RETURN(-1);
     }
+    if (opt_ndb_extra_logging > 19)
+    {
+      sql_print_information("NDB: Global schema lock release");
+    }
   }
   DBUG_RETURN(0);
 }
@@ -1656,7 +1676,9 @@ char *ndb_pack_varchar(const NDBCOL *col
 static int
 ndbcluster_update_slock(THD *thd,
                         const char *db,
-                        const char *table_name)
+                        const char *table_name,
+                        uint32 table_id,
+                        uint32 table_version)
 {
   DBUG_ENTER("ndbcluster_update_slock");
   if (!ndb_schema_share)
@@ -1734,7 +1756,24 @@ ndbcluster_update_slock(THD *thd,
     }
     if (trans->execute(NdbTransaction::NoCommit))
       goto err;
-    bitmap_clear_bit(&slock, node_id);
+
+    if (opt_ndb_extra_logging > 19)
+    {
+      uint32 copy[SCHEMA_SLOCK_SIZE/4];
+      memcpy(copy, bitbuf, sizeof(copy));
+      bitmap_clear_bit(&slock, node_id);
+      sql_print_information("NDB: reply to %s.%s(%u/%u) from %x%x to %x%x",
+                            db, table_name,
+                            table_id, table_version,
+                            copy[0], copy[1],
+                            slock.bitmap[0],
+                            slock.bitmap[1]);
+    }
+    else
+    {
+      bitmap_clear_bit(&slock, node_id);
+    }
+
     {
       NdbOperation *op= 0;
       int r= 0;
@@ -1764,10 +1803,12 @@ ndbcluster_update_slock(THD *thd,
       r|= op->setValue(SCHEMA_TYPE_I, (uint32)SOT_CLEAR_SLOCK);
       DBUG_ASSERT(r == 0);
     }
-    if (trans->execute(NdbTransaction::Commit) == 0)
+    if (trans->execute(NdbTransaction::Commit, 
+                       NdbOperation::DefaultAbortOption, 1 /*force send*/) == 0)
     {
       DBUG_PRINT("info", ("node %d cleared lock on '%s.%s'",
                           node_id, db, table_name));
+      dict->forceGCPWait(1);
       break;
     }
   err:
@@ -1807,7 +1848,8 @@ ndbcluster_update_slock(THD *thd,
 static void ndb_report_waiting(const char *key,
                                int the_time,
                                const char *op,
-                               const char *obj)
+                               const char *obj,
+                               const MY_BITMAP * map)
 {
   ulonglong ndb_latest_epoch= 0;
   const char *proc_info= "<no info>";
@@ -1817,19 +1859,79 @@ static void ndb_report_waiting(const cha
   if (injector_thd)
     proc_info= injector_thd->proc_info;
   pthread_mutex_unlock(&injector_mutex);
-  sql_print_information("NDB %s:"
-                        " waiting max %u sec for %s %s."
-                        "  epochs: (%u/%u,%u/%u,%u/%u)"
-                        "  injector proc_info: %s"
-                        ,key, the_time, op, obj
-                        ,(uint)(ndb_latest_handled_binlog_epoch >> 32)
-                        ,(uint)(ndb_latest_handled_binlog_epoch)
-                        ,(uint)(ndb_latest_received_binlog_epoch >> 32)
-                        ,(uint)(ndb_latest_received_binlog_epoch)
-                        ,(uint)(ndb_latest_epoch >> 32)
-                        ,(uint)(ndb_latest_epoch)
-                        ,proc_info
-                        );
+  if (map == 0)
+  {
+    sql_print_information("NDB %s:"
+                          " waiting max %u sec for %s %s."
+                          "  epochs: (%u/%u,%u/%u,%u/%u)"
+                          "  injector proc_info: %s"
+                          ,key, the_time, op, obj
+                          ,(uint)(ndb_latest_handled_binlog_epoch >> 32)
+                          ,(uint)(ndb_latest_handled_binlog_epoch)
+                          ,(uint)(ndb_latest_received_binlog_epoch >> 32)
+                          ,(uint)(ndb_latest_received_binlog_epoch)
+                          ,(uint)(ndb_latest_epoch >> 32)
+                          ,(uint)(ndb_latest_epoch)
+                          ,proc_info
+                          );
+  }
+  else
+  {
+    sql_print_information("NDB %s:"
+                          " waiting max %u sec for %s %s."
+                          "  epochs: (%u/%u,%u/%u,%u/%u)"
+                          "  injector proc_info: %s map: %x%x"
+                          ,key, the_time, op, obj
+                          ,(uint)(ndb_latest_handled_binlog_epoch >> 32)
+                          ,(uint)(ndb_latest_handled_binlog_epoch)
+                          ,(uint)(ndb_latest_received_binlog_epoch >> 32)
+                          ,(uint)(ndb_latest_received_binlog_epoch)
+                          ,(uint)(ndb_latest_epoch >> 32)
+                          ,(uint)(ndb_latest_epoch)
+                          ,proc_info
+                          ,map->bitmap[0]
+                          ,map->bitmap[1]
+                          );
+  }
+}
+
+static
+const char*
+get_schema_type_name(uint type)
+{
+  switch(type){
+  case SOT_DROP_TABLE:
+    return "DROP_TABLE";
+  case SOT_CREATE_TABLE:
+    return "CREATE_TABLE";
+  case SOT_RENAME_TABLE_NEW:
+    return "RENAME_TABLE_NEW";
+  case SOT_ALTER_TABLE_COMMIT:
+    return "ALTER_TABLE_COMMIT";
+  case SOT_DROP_DB:
+    return "DROP_DB";
+  case SOT_CREATE_DB:
+    return "CREATE_DB";
+  case SOT_ALTER_DB:
+    return "ALTER_DB";
+  case SOT_CLEAR_SLOCK:
+    return "CLEAR_SLOCK";
+  case SOT_TABLESPACE:
+    return "TABLESPACE";
+  case SOT_LOGFILE_GROUP:
+    return "LOGFILE_GROUP";
+  case SOT_RENAME_TABLE:
+    return "RENAME_TABLE";
+  case SOT_TRUNCATE_TABLE:
+    return "TRUNCATE_TABLE";
+  case SOT_RENAME_TABLE_PREPARE:
+    return "RENAME_TABLE_PREPARE";
+  case SOT_ONLINE_ALTER_TABLE_PREPARE:
+    return "ONLINE_ALTER_TABLE_PREPARE";
+  case SOT_ONLINE_ALTER_TABLE_COMMIT:
+    return "ONLINE_ALTER_TABLE_COMMIT";
+  }
+  return "<unknown>";
 }
 
 int ndbcluster_log_schema_op(THD *thd,
@@ -1864,6 +1966,7 @@ int ndbcluster_log_schema_op(THD *thd,
   char tmp_buf2[FN_REFLEN];
   const char *type_str;
   int also_internal= 0;
+  uint32 log_type= (uint32)type;
   switch (type)
   {
   case SOT_DROP_TABLE:
@@ -1933,20 +2036,16 @@ int ndbcluster_log_schema_op(THD *thd,
     char key[FN_REFLEN + 1];
     build_table_filename(key, sizeof(key) - 1, db, table_name, "", 0);
     ndb_schema_object= ndb_get_schema_object(key, TRUE, FALSE);
+    ndb_schema_object->table_id= ndb_table_id;
+    ndb_schema_object->table_version= ndb_table_version;
   }
 
   const NdbError *ndb_error= 0;
   uint32 node_id= g_ndb_cluster_connection->node_id();
   Uint64 epoch= 0;
-  MY_BITMAP schema_subscribers;
-  uint32 bitbuf[sizeof(ndb_schema_object->slock)/4];
-  char bitbuf_e[sizeof(bitbuf)];
-  bzero(bitbuf_e, sizeof(bitbuf_e));
   {
-    int i, updated= 0;
+    int i;
     int no_storage_nodes= g_ndb_cluster_connection->no_db_nodes();
-    bitmap_init(&schema_subscribers, bitbuf, sizeof(bitbuf)*8, FALSE);
-    bitmap_set_all(&schema_subscribers);
 
     /* begin protect ndb_schema_share */
     pthread_mutex_lock(&ndb_schema_share_mutex);
@@ -1960,48 +2059,20 @@ int ndbcluster_log_schema_op(THD *thd,
     pthread_mutex_lock(&ndb_schema_share->mutex);
     for (i= 0; i < no_storage_nodes; i++)
     {
-      MY_BITMAP *table_subscribers= &ndb_schema_share->subscriber_bitmap[i];
-      if (!bitmap_is_clear_all(table_subscribers))
-      {
-        bitmap_intersect(&schema_subscribers,
-                         table_subscribers);
-        updated= 1;
-      }
+      bitmap_union(&ndb_schema_object->slock_bitmap,
+                   &ndb_schema_share->subscriber_bitmap[i]);
     }
     pthread_mutex_unlock(&ndb_schema_share->mutex);
     pthread_mutex_unlock(&ndb_schema_share_mutex);
     /* end protect ndb_schema_share */
 
-    if (updated)
-    {
-      bitmap_clear_bit(&schema_subscribers, node_id);
-      /*
-        if setting own acknowledge bit it is important that
-        no other mysqld's are registred, as subsequent code
-        will cause the original event to be hidden (by blob
-        merge event code)
-      */
-      if (bitmap_is_clear_all(&schema_subscribers))
-          bitmap_set_bit(&schema_subscribers, node_id);
-    }
-    else
-      bitmap_clear_all(&schema_subscribers);
-
     if (also_internal)
-      bitmap_set_bit(&schema_subscribers, node_id);        
-
-    if (ndb_schema_object)
-    {
-      pthread_mutex_lock(&ndb_schema_object->mutex);
-      memcpy(ndb_schema_object->slock, schema_subscribers.bitmap,
-             sizeof(ndb_schema_object->slock));
-      pthread_mutex_unlock(&ndb_schema_object->mutex);
-    }
+      bitmap_set_bit(&ndb_schema_object->slock_bitmap, node_id);
+    else
+      bitmap_clear_bit(&ndb_schema_object->slock_bitmap, node_id);
 
-    DBUG_DUMP("schema_subscribers", (uchar*)schema_subscribers.bitmap,
-              no_bytes_in_map(&schema_subscribers));
-    DBUG_PRINT("info", ("bitmap_is_clear_all(&schema_subscribers): %d",
-                        bitmap_is_clear_all(&schema_subscribers)));
+    DBUG_DUMP("schema_subscribers", (uchar*)&ndb_schema_object->slock,
+              no_bytes_in_map(&ndb_schema_object->slock_bitmap));
   }
 
   Ndb *ndb= thd_ndb->ndb;
@@ -2046,8 +2117,7 @@ int ndbcluster_log_schema_op(THD *thd,
   {
     const char *log_db= db;
     const char *log_tab= table_name;
-    const char *log_subscribers= (char*)schema_subscribers.bitmap;
-    uint32 log_type= (uint32)type;
+    const char *log_subscribers= (char*)ndb_schema_object->slock;
     if ((trans= ndb->startTransaction()) == 0)
       goto err;
     while (1)
@@ -2069,7 +2139,8 @@ int ndbcluster_log_schema_op(THD *thd,
       r|= op->equal(SCHEMA_NAME_I, tmp_buf);
       DBUG_ASSERT(r == 0);
       /* slock */
-      DBUG_ASSERT(sz[SCHEMA_SLOCK_I] == sizeof(bitbuf));
+      DBUG_ASSERT(sz[SCHEMA_SLOCK_I] ==
+                  no_bytes_in_map(&ndb_schema_object->slock_bitmap));
       r|= op->setValue(SCHEMA_SLOCK_I, log_subscribers);
       DBUG_ASSERT(r == 0);
       /* query */
@@ -2146,21 +2217,13 @@ int ndbcluster_log_schema_op(THD *thd,
 
       r|= op->setAnyValue(anyValue);
       DBUG_ASSERT(r == 0);
-#if 0
-      if (log_db != new_db && new_db && new_table_name)
-      {
-        log_db= new_db;
-        log_tab= new_table_name;
-        log_subscribers= bitbuf_e; // no ack expected on this
-        log_type= (uint32)SOT_RENAME_TABLE_NEW;
-        continue;
-      }
-#endif
       break;
     }
-    if (trans->execute(NdbTransaction::Commit) == 0)
+    if (trans->execute(NdbTransaction::Commit, NdbOperation::DefaultAbortOption,
+                       1 /* force send */) == 0)
     {
       DBUG_PRINT("info", ("logged: %s", query));
+      dict->forceGCPWait(1);
       break;
     }
 err:
@@ -2191,21 +2254,25 @@ end:
     ndb->closeTransaction(trans);
   ndb->setDatabaseName(save_db);
 
+  if (opt_ndb_extra_logging > 19)
+  {
+    sql_print_information("NDB: distributed %s.%s(%u/%u) type: %s(%u) query: \'%s\' to %x%x",
+                          db,
+                          table_name,
+                          ndb_table_id,
+                          ndb_table_version,
+                          get_schema_type_name(log_type),
+                          log_type,
+                          query,
+                          ndb_schema_object->slock_bitmap.bitmap[0],
+                          ndb_schema_object->slock_bitmap.bitmap[1]);
+  }
+
   /*
     Wait for other mysqld's to acknowledge the table operation
   */
-  if (ndb_error == 0 &&
-      !bitmap_is_clear_all(&schema_subscribers))
+  if (ndb_error == 0 && !bitmap_is_clear_all(&ndb_schema_object->slock_bitmap))
   {
-    if (!also_internal)
-    {
-      /*
-        if own nodeid is set we are a single mysqld registred
-        as an optimization we update the slock directly
-      */
-      if (bitmap_is_set(&schema_subscribers, node_id))
-        ndbcluster_update_slock(thd, db, table_name);
-    }
     int max_timeout= DEFAULT_SYNC_TIMEOUT;
     pthread_mutex_lock(&ndb_schema_object->mutex);
     if (have_lock_open)
@@ -2232,24 +2299,24 @@ end:
         pthread_mutex_unlock(&ndb_schema_share_mutex);
         break;
       }
+      MY_BITMAP servers;
+      bitmap_init(&servers, 0, 256, FALSE);
+      bitmap_clear_all(&servers);
+      bitmap_set_bit(&servers, node_id); // "we" are always alive
       pthread_mutex_lock(&ndb_schema_share->mutex);
       for (i= 0; i < no_storage_nodes; i++)
       {
         /* remove any unsubscribed from schema_subscribers */
         MY_BITMAP *tmp= &ndb_schema_share->subscriber_bitmap[i];
-        if (!bitmap_is_clear_all(tmp))
-          bitmap_intersect(&schema_subscribers, tmp);
+        bitmap_union(&servers, tmp);
       }
       pthread_mutex_unlock(&ndb_schema_share->mutex);
       pthread_mutex_unlock(&ndb_schema_share_mutex);
       /* end protect ndb_schema_share */
 
       /* remove any unsubscribed from ndb_schema_object->slock */
-      bitmap_intersect(&ndb_schema_object->slock_bitmap, &schema_subscribers);
-
-      DBUG_DUMP("ndb_schema_object->slock_bitmap.bitmap",
-                (uchar*)ndb_schema_object->slock_bitmap.bitmap,
-                no_bytes_in_map(&ndb_schema_object->slock_bitmap));
+      bitmap_intersect(&ndb_schema_object->slock_bitmap, &servers);
+      bitmap_free(&servers);
 
       if (bitmap_is_clear_all(&ndb_schema_object->slock_bitmap))
         break;
@@ -2261,11 +2328,13 @@ end:
         {
           sql_print_error("NDB %s: distributing %s timed out. Ignoring...",
                           type_str, ndb_schema_object->key);
+          DBUG_ASSERT(false);
           break;
         }
         if (opt_ndb_extra_logging)
           ndb_report_waiting(type_str, max_timeout,
-                             "distributing", ndb_schema_object->key);
+                             "distributing", ndb_schema_object->key,
+                             &ndb_schema_object->slock_bitmap);
       }
     }
     if (have_lock_open)
@@ -2274,10 +2343,34 @@ end:
     }
     pthread_mutex_unlock(&ndb_schema_object->mutex);
   }
+  else if (ndb_error)
+  {
+    sql_print_error("NDB %s: distributing %s err: %u",
+                    type_str, ndb_schema_object->key,
+                    ndb_error->code);
+  }
+  else if (opt_ndb_extra_logging > 19)
+  {
+    sql_print_information("NDB %s: not waiting for distributing %s",
+                          type_str, ndb_schema_object->key);
+  }
 
   if (ndb_schema_object)
     ndb_free_schema_object(&ndb_schema_object, FALSE);
 
+  if (opt_ndb_extra_logging > 19)
+  {
+    sql_print_information("NDB: distribution of %s.%s(%u/%u) type: %s(%u) query: \'%s\'"
+                          " - complete!",
+                          db,
+                          table_name,
+                          ndb_table_id,
+                          ndb_table_version,
+                          get_schema_type_name(log_type),
+                          log_type,
+                          query);
+  }
+
   DBUG_RETURN(0);
 }
 
@@ -2486,6 +2579,19 @@ ndb_binlog_thread_handle_schema_event(TH
                   schema->db, schema->name,
                   schema->query_length, schema->query,
                   schema_type));
+
+      if (opt_ndb_extra_logging > 19)
+      {
+        sql_print_information("NDB: got schema event on %s.%s(%u/%u) query: '%s' type: %s(%d) node: %u slock: %x%x",
+                              schema->db, schema->name,
+                              schema->id, schema->version,
+                              schema->query,
+                              get_schema_type_name(schema_type),
+                              schema_type,
+                              schema->node_id,
+                              slock.bitmap[0], slock.bitmap[1]);
+      }
+
       if ((schema->db[0] == 0) && (schema->name[0] == 0))
         DBUG_RETURN(0);
       switch (schema_type)
@@ -2694,7 +2800,8 @@ ndb_binlog_thread_handle_schema_event(TH
           if (post_epoch_unlock)
             post_epoch_unlock_list->push_back(schema, mem_root);
           else
-            ndbcluster_update_slock(thd, schema->db, schema->name);
+            ndbcluster_update_slock(thd, schema->db, schema->name,
+                                    schema->id, schema->version);
         }
       }
       DBUG_RETURN(0);
@@ -2844,9 +2951,21 @@ ndb_binlog_thread_handle_schema_event_po
         NDB_SCHEMA_OBJECT *ndb_schema_object=
           (NDB_SCHEMA_OBJECT*) my_hash_search(&ndb_schema_objects,
                                               (const uchar*) key, strlen(key));
-        if (ndb_schema_object)
+        if (ndb_schema_object &&
+            (ndb_schema_object->table_id == schema->id &&
+             ndb_schema_object->table_version == schema->version))
         {
           pthread_mutex_lock(&ndb_schema_object->mutex);
+          if (opt_ndb_extra_logging > 19)
+          {
+            sql_print_information("NDB: CLEAR_SLOCK key: %s(%u/%u) from"
+                                  " %x%x to %x%x",
+                                  key, schema->id, schema->version,
+                                  ndb_schema_object->slock[0],
+                                  ndb_schema_object->slock[1],
+                                  schema->slock[0],
+                                  schema->slock[1]);
+          }
           memcpy(ndb_schema_object->slock, schema->slock,
                  sizeof(ndb_schema_object->slock));
           DBUG_DUMP("ndb_schema_object->slock_bitmap.bitmap",
@@ -2855,6 +2974,24 @@ ndb_binlog_thread_handle_schema_event_po
           pthread_mutex_unlock(&ndb_schema_object->mutex);
           pthread_cond_signal(&injector_cond);
         }
+        else if (opt_ndb_extra_logging > 19)
+        {
+          if (ndb_schema_object == 0)
+          {
+            sql_print_information("NDB: Discarding event...no obj: %s (%u/%u)",
+                                  key, schema->id, schema->version);
+          }
+          else
+          {
+            sql_print_information("NDB: Discarding event...key: %s "
+                                  "non matching id/version [%u/%u] != [%u/%u]",
+                                  key,
+                                  ndb_schema_object->table_id,
+                                  ndb_schema_object->table_version,
+                                  schema->id,
+                                  schema->version);
+          }
+        }
         pthread_mutex_unlock(&ndbcluster_mutex);
         continue;
       }
@@ -3179,7 +3316,8 @@ ndb_binlog_thread_handle_schema_event_po
   }
   while ((schema= post_epoch_unlock_list->pop()))
   {
-    ndbcluster_update_slock(thd, schema->db, schema->name);
+    ndbcluster_update_slock(thd, schema->db, schema->name,
+                            schema->id, schema->version);
   }
   DBUG_VOID_RETURN;
 }
@@ -4808,11 +4946,12 @@ ndbcluster_handle_alter_table(THD *thd, 
       {
         sql_print_error("NDB %s: %s timed out. Ignoring...",
                         type_str, share->key);
+        DBUG_ASSERT(false);
         break;
       }
       if (opt_ndb_extra_logging)
         ndb_report_waiting(type_str, max_timeout,
-                           type_str, share->key);
+                           type_str, share->key, 0);
     }
   }
   pthread_mutex_unlock(&share->mutex);
@@ -4881,11 +5020,12 @@ ndbcluster_handle_drop_table(THD *thd, N
       {
         sql_print_error("NDB %s: %s timed out. Ignoring...",
                         type_str, share->key);
+        DBUG_ASSERT(false);
         break;
       }
       if (opt_ndb_extra_logging)
         ndb_report_waiting(type_str, max_timeout,
-                           type_str, share->key);
+                           type_str, share->key, 0);
     }
   }
   pthread_mutex_lock(&LOCK_open);

=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2010-08-26 16:01:10 +0000
+++ b/sql/handler.cc	2010-09-23 11:55:42 +0000
@@ -3565,7 +3565,10 @@ handler::alter_table_phase2(THD *thd,
 }
 
 int
-handler::alter_table_phase3(THD *thd, TABLE *table)
+handler::alter_table_phase3(THD *thd, TABLE *table,
+                            HA_CREATE_INFO *create_info,
+                            HA_ALTER_INFO *alter_info,
+                            HA_ALTER_FLAGS *alter_flags)
 {
   DBUG_ENTER("alter_table_phase3");
   DBUG_RETURN(0);

=== modified file 'sql/handler.h'
--- a/sql/handler.h	2010-09-03 08:59:02 +0000
+++ b/sql/handler.h	2010-09-23 11:55:42 +0000
@@ -1935,7 +1935,7 @@ public:
    @param     altered_table     A temporary table show what table is to
                                 change to
    @param     alter_info        Storage place for data used during phase1
-                                and phase2
+                                and phase2 and phase3
    @param     alter_flags       Bitmask that shows what will be changed
 
    @retval   0      OK
@@ -1953,8 +1953,10 @@ public:
     @param    thd               The thread handle
     @param    altered_table     A temporary table show what table is to
                                 change to
+    @param    create_info       Information from the parsing phase about new
+                                table properties.
     @param    alter_info        Storage place for data used during phase1
-                                and phase2
+                                and phase2 and phase3
     @param    alter_flags       Bitmask that shows what will be changed
 
     @retval  0      OK
@@ -1977,8 +1979,16 @@ public:
 
     @param    thd               The thread handle
     @param    table             The altered table, re-opened
+    @param    create_info       Information from the parsing phase about new
+                                table properties.
+    @param    alter_info        Storage place for data used during phase1
+                                and phase2 and phase3
+    @param    alter_flags       Bitmask that shows what has been changed
  */
- virtual int alter_table_phase3(THD *thd, TABLE *table);
+ virtual int alter_table_phase3(THD *thd, TABLE *table,
+                                HA_CREATE_INFO *create_info,
+                                HA_ALTER_INFO *alter_info,
+                                HA_ALTER_FLAGS *alter_flags);
 
   /**
     use_hidden_primary_key() is called in case of an update/delete when

=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc	2010-06-09 21:11:56 +0000
+++ b/sql/sql_show.cc	2010-09-17 14:01:17 +0000
@@ -3353,6 +3353,9 @@ int get_all_tables(THD *thd, TABLE_LIST 
   uint table_open_method;
   DBUG_ENTER("get_all_tables");
 
+  Ha_global_schema_lock_guard global_schema_lock_guard(thd);
+  global_schema_lock_guard.lock();
+
   lex->view_prepare_mode= TRUE;
   lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
 

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2010-09-02 06:50:05 +0000
+++ b/sql/sql_table.cc	2010-09-15 18:38:13 +0000
@@ -6444,7 +6444,10 @@ int mysql_fast_or_online_alter_table(THD
       Tell the handler that the changed frm is on disk and table
       has been re-opened
    */
-    if ((error= t_table->file->alter_table_phase3(thd, t_table)))
+    if ((error= t_table->file->alter_table_phase3(thd, t_table,
+                                                  create_info,
+                                                  alter_info,
+                                                  ha_alter_flags)))
     {
       goto err;
     }

=== modified file 'storage/ndb/include/kernel/GlobalSignalNumbers.h'
--- a/storage/ndb/include/kernel/GlobalSignalNumbers.h	2010-06-28 08:40:27 +0000
+++ b/storage/ndb/include/kernel/GlobalSignalNumbers.h	2010-09-20 13:09:18 +0000
@@ -192,7 +192,7 @@ extern const GlobalSignalNumber NO_OF_SI
 #define GSN_ROUTE_ORD                   121
 #define GSN_NODE_VERSION_REP            122
 /* 123 not unused */
-/* 124 unused */
+#define GSN_FSSUSPENDORD                124 /* local */
 #define GSN_CHECK_LCP_STOP              125
 #define GSN_CLOSE_COMCONF               126 /* local */
 #define GSN_CLOSE_COMREQ                127 /* local */

=== modified file 'storage/ndb/include/kernel/signaldata/ConfigChange.hpp'
--- a/storage/ndb/include/kernel/signaldata/ConfigChange.hpp	2009-11-17 18:13:29 +0000
+++ b/storage/ndb/include/kernel/signaldata/ConfigChange.hpp	2010-09-21 06:04:04 +0000
@@ -18,7 +18,8 @@
 
 #include "SignalData.hpp"
 
-class ConfigChangeReq {
+struct ConfigChangeReq
+{
   /**
    * Sender
    */
@@ -29,15 +30,14 @@ class ConfigChangeReq {
    */
   friend class ConfigManager;
 
-public:
   STATIC_CONST( SignalLength = 1 );
 
-private:
   Uint32 length; // Length of the config data in long signal
 };
 
 
-class ConfigChangeConf {
+struct ConfigChangeConf 
+{
   /**
    * Sender
    */
@@ -48,16 +48,14 @@ class ConfigChangeConf {
    */
   friend class MgmtSrvr;
 
-public:
   STATIC_CONST( SignalLength = 1 );
 
-private:
-
   Uint32 unused;
 };
 
 
-class ConfigChangeRef {
+struct ConfigChangeRef 
+{
   /**
    * Sender
    */
@@ -89,7 +87,6 @@ class ConfigChangeRef {
     SendFailed              = 16
   };
 
-public:
   STATIC_CONST( SignalLength = 1 );
 
   static const char* errorMessage(Uint32 error) {
@@ -132,13 +129,12 @@ public:
     }
   }
 
-private:
-
   Uint32 errorCode;
 };
 
 
-class ConfigChangeImplReq {
+struct ConfigChangeImplReq
+{
   /**
    * Receiver and sender
    */
@@ -150,11 +146,8 @@ class ConfigChangeImplReq {
     Abort
   };
 
-public:
   STATIC_CONST( SignalLength = 3 );
 
-private:
-
   Uint32 requestType;
   Uint32 initial; // Valid when requestType = Prepare
   Uint32 length; // Length of the config data in long signal
@@ -162,37 +155,34 @@ private:
 };
 
 
-class ConfigChangeImplConf  {
+struct ConfigChangeImplConf
+{
   /**
    * Receiver and sender
    */
   friend class ConfigManager;
 
-public:
   STATIC_CONST( SignalLength = 1 );
 
-private:
-
   Uint32 requestType;
 };
 
 
-class ConfigChangeImplRef  {
+struct ConfigChangeImplRef
+{
   /**
    * Receiver and sender
    */
   friend class ConfigManager;
 
-public:
   STATIC_CONST( SignalLength = 1 );
 
-private:
-
   Uint32 errorCode;
 };
 
 
-class ConfigCheckReq  {
+struct ConfigCheckReq
+{
   /**
    * Sender
    */
@@ -203,18 +193,17 @@ class ConfigCheckReq  {
    */
   friend class ConfigManager;
 
-public:
   STATIC_CONST( SignalLengthBeforeChecksum = 2 );
   STATIC_CONST( SignalLength = 3 );
 
-private:
   Uint32 state;
   Uint32 generation;
   Uint32 checksum;
 };
 
 
-class ConfigCheckConf {
+struct ConfigCheckConf
+{
   /**
    * Sender
    */
@@ -225,17 +214,15 @@ class ConfigCheckConf {
    */
   friend class MgmtSrvr;
 
-public:
   STATIC_CONST( SignalLength = 2 );
 
-private:
-
   Uint32 state;
   Uint32 generation;
 };
 
 
-class ConfigCheckRef  {
+struct ConfigCheckRef
+{
   /**
    * Sender
    */
@@ -266,10 +253,9 @@ class ConfigCheckRef  {
     }
   }
 
-public:
   STATIC_CONST( SignalLength = 5 );
   STATIC_CONST( SignalLengthWithConfig = 6 );
-private:
+
   Uint32 error;
   Uint32 generation;
   Uint32 expected_generation;
@@ -278,5 +264,4 @@ private:
   Uint32 length; // Length of the config data in long signal
 };
 
-
 #endif

=== modified file 'storage/ndb/include/kernel/signaldata/DiGetNodes.hpp'
--- a/storage/ndb/include/kernel/signaldata/DiGetNodes.hpp	2009-06-12 12:01:12 +0000
+++ b/storage/ndb/include/kernel/signaldata/DiGetNodes.hpp	2010-09-23 11:55:42 +0000
@@ -43,7 +43,7 @@ struct DiGetNodesConf {
   Uint32 zero;
   Uint32 fragId;
   Uint32 reqinfo;
-  Uint32 nodes[MAX_REPLICAS]; //+1
+  Uint32 nodes[MAX_REPLICAS + (2 + MAX_REPLICAS)]; //+1
 };
 /**
  * 

=== modified file 'storage/ndb/include/kernel/signaldata/FsReadWriteReq.hpp'
--- a/storage/ndb/include/kernel/signaldata/FsReadWriteReq.hpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/include/kernel/signaldata/FsReadWriteReq.hpp	2010-09-20 13:09:18 +0000
@@ -173,5 +173,12 @@ FsReadWriteReq::getPartialReadFlag(UintR
   return (opFlag >> PARTIAL_READ_SHIFT) & 1;
 }
 
+struct FsSuspendOrd
+{
+  UintR filePointer;          // DATA 0
+  Uint32 milliseconds;
+
+  STATIC_CONST(SignalLength = 2);
+};
 
 #endif

=== modified file 'storage/ndb/include/mgmapi/mgmapi.h'
--- a/storage/ndb/include/mgmapi/mgmapi.h	2010-03-02 09:16:27 +0000
+++ b/storage/ndb/include/mgmapi/mgmapi.h	2010-09-22 14:19:12 +0000
@@ -583,6 +583,25 @@ extern "C" {
    */
   const char *ndb_mgm_get_connected_bind_address(NdbMgmHandle handle);
 
+  /**
+   * Get the version of the mgm server we're talking to.
+   *
+   * @param   handle         Management handle
+   * @param   major          Returns the major version number for NDB
+   * @param   minor          Returns the minor version number for NDB
+   * @param   build          Returns the build version number for NDB
+   * @param   len            Specifies the max size of the buffer
+   *                         available to return version string in
+   * @param   str            Pointer to buffer where to return the
+   *                         version string which is in the
+   *                         form "mysql-X.X.X ndb-Y.Y.Y-status"
+   *
+   * @return  0 for error and 1 for success
+   */
+  int ndb_mgm_get_version(NdbMgmHandle handle,
+                          int *major, int *minor, int* build,
+                          int len, char* str);
+
 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
   /** @} *********************************************************************/
   /**
@@ -1217,15 +1236,6 @@ extern "C" {
   Uint32 ndb_mgm_get_mgmd_nodeid(NdbMgmHandle handle);
 
   /**
-   * Get the version of the mgm server we're talking to.
-   * Designed to allow switching of protocol depending on version
-   * so that new clients can speak to old servers in a compat mode
-   */
-  int ndb_mgm_get_version(NdbMgmHandle handle,
-                          int *major, int *minor, int* build,
-                          int len, char* str);
-
-  /**
    * Config iterator
    */
   typedef struct ndb_mgm_configuration_iterator ndb_mgm_configuration_iterator;

=== modified file 'storage/ndb/include/ndb_global.h'
--- a/storage/ndb/include/ndb_global.h	2010-08-30 09:51:49 +0000
+++ b/storage/ndb/include/ndb_global.h	2010-09-22 13:28:20 +0000
@@ -20,6 +20,13 @@
 #ifndef NDB_GLOBAL_H
 #define NDB_GLOBAL_H
 
+#ifdef _WIN32
+/* Workaround for Bug#32082: VOID refdefinition results in compile errors */
+#ifndef DONT_DEFINE_VOID
+#define DONT_DEFINE_VOID
+#endif
+#endif
+
 #include <my_global.h>
 #include <mysql_com.h>
 #include <ndb_types.h>

=== modified file 'storage/ndb/include/ndbapi/NdbDictionary.hpp'
--- a/storage/ndb/include/ndbapi/NdbDictionary.hpp	2010-05-28 19:56:57 +0000
+++ b/storage/ndb/include/ndbapi/NdbDictionary.hpp	2010-09-23 11:55:42 +0000
@@ -2327,6 +2327,7 @@ public:
      * Force gcp and wait for gcp complete
      */
     int forceGCPWait();
+    int forceGCPWait(int type);
 #endif
 
     /** @} *******************************************************************/
@@ -2513,6 +2514,7 @@ public:
     int dropIndexGlobal(const Index &index);
     int removeIndexGlobal(const Index &ndbidx, int invalidate) const;
     int removeTableGlobal(const Table &ndbtab, int invalidate) const;
+    void invalidateDbGlobal(const char * dbname);
 #endif
 
     /*

=== modified file 'storage/ndb/include/portlib/NdbCondition.h'
--- a/storage/ndb/include/portlib/NdbCondition.h	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/include/portlib/NdbCondition.h	2010-08-13 12:31:20 +0000
@@ -25,8 +25,10 @@
 extern "C" {
 #endif
 
-struct NdbCondition;
-
+struct NdbCondition
+{
+  pthread_cond_t cond;
+};
 
 /**
  * Create a condition
@@ -36,6 +38,13 @@ struct NdbCondition;
 struct NdbCondition* NdbCondition_Create(void);
 
 /**
+ * Initialize a condition created with file-storage or on the stack
+ *
+ * returnvalue: 0 = success
+ */
+int NdbCondition_Init(struct NdbCondition* p_cond);
+
+/**
  * Wait for a condition, allows a thread to wait for
  * a condition and atomically releases the associated mutex.
  *

=== modified file 'storage/ndb/include/portlib/NdbDir.hpp'
--- a/storage/ndb/include/portlib/NdbDir.hpp	2010-08-23 11:20:11 +0000
+++ b/storage/ndb/include/portlib/NdbDir.hpp	2010-09-23 07:31:51 +0000
@@ -89,6 +89,11 @@ public:
   */
   static bool remove(const char* path);
 
+  /*
+    Change working directory
+  */
+  static int chdir(const char* path);
+
 };
 
 #endif

=== modified file 'storage/ndb/include/portlib/NdbSleep.h'
--- a/storage/ndb/include/portlib/NdbSleep.h	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/include/portlib/NdbSleep.h	2010-08-13 12:42:51 +0000
@@ -19,25 +19,27 @@
 #ifndef NDBSLEEP_H
 #define NDBSLEEP_H
 
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
 #include <ndb_global.h>
-#include <my_sys.h>
 
-static inline void NdbSleep_MilliSleep(int milliseconds)
+static inline
+void NdbSleep_MilliSleep(int milliseconds)
 {
-  my_sleep(ulong(milliseconds)*1000UL);
+#ifdef _WIN32
+  Sleep(milliseconds);
+#elif defined(HAVE_SELECT)
+  struct timeval t;
+  t.tv_sec =  milliseconds / 1000L;
+  t.tv_usec = (milliseconds % 1000L) * 1000L;
+  select(0,0,0,0,&t);
+#else
+#error No suitable function found to implement millisecond sleep.
+#endif
 }
-static inline void NdbSleep_SecSleep(int seconds)
+
+static inline
+void NdbSleep_SecSleep(int seconds)
 {
   NdbSleep_MilliSleep(seconds*1000);
 }
 
-#ifdef	__cplusplus
-}
-#endif
-
-
 #endif

=== modified file 'storage/ndb/include/util/BaseString.hpp'
--- a/storage/ndb/include/util/BaseString.hpp	2009-11-08 12:52:27 +0000
+++ b/storage/ndb/include/util/BaseString.hpp	2010-09-21 07:36:08 +0000
@@ -325,12 +325,6 @@ BaseString::assign(const Vector<BaseStri
  * Return pointer and length for key to use when BaseString is
  * used as Key in HashMap
  */
-inline
-const void* BaseString_get_key(const void* key, size_t* key_length)
-{
-  const BaseString* str = (const BaseString*)key;
-  *key_length = str->length();
-  return str->c_str();
-}
+const void * BaseString_get_key(const void* key, size_t* key_length);
 
 #endif /* !__UTIL_BASESTRING_HPP_INCLUDED__ */

=== modified file 'storage/ndb/include/util/HashMap.hpp'
--- a/storage/ndb/include/util/HashMap.hpp	2009-11-08 12:52:27 +0000
+++ b/storage/ndb/include/util/HashMap.hpp	2010-09-21 07:36:08 +0000
@@ -67,8 +67,8 @@ class HashMap {
   */
   static uchar* _get_key(const uchar* ptr,
                          size_t* key_length, my_bool first) {
-    Entry* entry = (Entry*)ptr;
-    const void* key_ptr = G((const void*)&entry->m_key, key_length);
+    const Entry * entry = reinterpret_cast<const Entry*>(ptr);
+    const void* key_ptr = G(&entry->m_key, key_length);
     return (uchar*)key_ptr;
   }
 

=== modified file 'storage/ndb/include/util/NdbSqlUtil.hpp'
--- a/storage/ndb/include/util/NdbSqlUtil.hpp	2010-05-12 11:56:28 +0000
+++ b/storage/ndb/include/util/NdbSqlUtil.hpp	2010-08-16 10:25:27 +0000
@@ -143,6 +143,13 @@ public:
   static int strnxfrm_bug7284(CHARSET_INFO* cs, unsigned char* dst, unsigned dstLen, const unsigned char*src, unsigned srcLen);
 
   /**
+   * Wrapper for 'strnxfrm' who change prototype in 5.6
+   */
+  static size_t ndb_strnxfrm(struct charset_info_st * cs,
+                             uchar *dst, size_t dstlen,
+                             const uchar *src, size_t srclen);
+
+  /**
    * Compare decimal numbers.
    */
   static int cmp_olddecimal(const uchar* s1, const uchar* s2, unsigned n);

=== modified file 'storage/ndb/include/util/NdbTap.hpp'
--- a/storage/ndb/include/util/NdbTap.hpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/include/util/NdbTap.hpp	2010-09-22 13:28:20 +0000
@@ -37,5 +37,8 @@ int main(int argc, const char** argv){  
 }                                               \
 int name##_test()
 
+/* tap.c needs my_print_stacktrace */
+#undef DONT_DEFINE_VOID // stacktrace.c turns off VOID redefinition if needed
+#include <../../../mysys/stacktrace.c>
 
 #endif

=== modified file 'storage/ndb/include/util/ndb_opts.h'
--- a/storage/ndb/include/util/ndb_opts.h	2010-05-04 14:34:54 +0000
+++ b/storage/ndb/include/util/ndb_opts.h	2010-08-16 17:02:58 +0000
@@ -19,12 +19,14 @@
 #ifndef _NDB_OPTS_H
 #define _NDB_OPTS_H
 
+#include <ndb_global.h>
+
+#include <my_sys.h> /* loglevel needed by my_getopt.h */
+#include <my_getopt.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
-#include <ndb_global.h>
-#include <my_sys.h>
-#include <my_getopt.h>
 
 #ifdef OPTEXPORT
 #define OPT_EXTERN(T,V,I) T V I
@@ -118,8 +120,7 @@ enum ndb_std_options {
   NDB_STD_OPTIONS_LAST
 };
 
-void ndb_opt_set_usage_funcs(const char* my_progname,
-                             void (*short_usage)(void),
+void ndb_opt_set_usage_funcs(void (*short_usage)(void),
                              void (*usage)(void));
 my_bool
 ndb_std_get_one_option(int optid,
@@ -128,7 +129,8 @@ ndb_std_get_one_option(int optid,
 
 void ndb_usage(void (*usagefunc)(void), const char *load_default_groups[],
                struct my_option *my_long_options);
-void ndb_short_usage_sub(const char* my_progname, const char* extra);
+void ndb_short_usage_sub(const char* extra);
+
 
 
 #ifdef __cplusplus

=== modified file 'storage/ndb/src/common/portlib/NdbCondition.c'
--- a/storage/ndb/src/common/portlib/NdbCondition.c	2009-08-12 18:10:54 +0000
+++ b/storage/ndb/src/common/portlib/NdbCondition.c	2010-09-22 11:52:37 +0000
@@ -20,17 +20,8 @@
 #include <ndb_global.h>
 
 #include <NdbCondition.h>
-#include <NdbThread.h>
 #include <NdbMutex.h>
 #include <NdbMem.h>
-#ifdef NDB_WIN
-#include <my_pthread.h>
-#endif
-struct NdbCondition
-{
-  pthread_cond_t cond;
-};
-
 
 static int init = 0;
 #ifdef HAVE_CLOCK_GETTIME
@@ -38,7 +29,7 @@ static int clock_id = CLOCK_REALTIME;
 #endif
 
 void
-NdbCondition_Init(int need_monotonic)
+NdbCondition_initialize(int need_monotonic)
 {
   init = 1;
 #if defined HAVE_CLOCK_GETTIME && defined HAVE_PTHREAD_CONDATTR_SETCLOCK && \
@@ -84,18 +75,13 @@ nogo:
 #endif
 }
 
-struct NdbCondition* 
-NdbCondition_Create(void)
+int
+NdbCondition_Init(struct NdbCondition* ndb_cond)
 {
-  struct NdbCondition* tmpCond;
   int result;
-  
-  assert(init);
-  tmpCond = (struct NdbCondition*)NdbMem_Allocate(sizeof(struct NdbCondition));
-  
-  if (tmpCond == NULL)
-    return NULL;
- 
+
+  assert(init); /* Make sure library has been initialized */
+
 #if defined HAVE_CLOCK_GETTIME && defined HAVE_PTHREAD_CONDATTR_SETCLOCK && \
     defined CLOCK_MONOTONIC
   if (clock_id == CLOCK_MONOTONIC)
@@ -103,22 +89,34 @@ NdbCondition_Create(void)
     pthread_condattr_t attr;
     pthread_condattr_init(&attr);
     pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
-    result = pthread_cond_init(&tmpCond->cond, &attr);
+    result = pthread_cond_init(&ndb_cond->cond, &attr);
     pthread_condattr_destroy(&attr);
   }
   else
   {
-    result = pthread_cond_init(&tmpCond->cond, NULL);
+    result = pthread_cond_init(&ndb_cond->cond, NULL);
   }
 #else
-  result = pthread_cond_init(&tmpCond->cond, NULL);
+  result = pthread_cond_init(&ndb_cond->cond, NULL);
 #endif
-  
   assert(result==0);
-  return tmpCond;
+  return result;
 }
 
 
+struct NdbCondition*
+NdbCondition_Create(void)
+{
+  struct NdbCondition* tmpCond;
+
+  tmpCond = (struct NdbCondition*)NdbMem_Allocate(sizeof(struct NdbCondition));
+
+  if (tmpCond == NULL)
+    return NULL;
+
+  (void)NdbCondition_Init(tmpCond);
+  return tmpCond;
+}
 
 int 
 NdbCondition_Wait(struct NdbCondition* p_cond,

=== modified file 'storage/ndb/src/common/portlib/NdbDir.cpp'
--- a/storage/ndb/src/common/portlib/NdbDir.cpp	2010-08-26 06:45:37 +0000
+++ b/storage/ndb/src/common/portlib/NdbDir.cpp	2010-09-23 07:31:51 +0000
@@ -347,6 +347,16 @@ loop:
   return true;
 }
 
+#ifdef _WIN32
+#include <direct.h> // chdir
+#endif
+
+int
+NdbDir::chdir(const char* path)
+{
+  return ::chdir(path);
+}
+
 
 #ifdef TEST_NDBDIR
 #include <NdbTap.hpp>
@@ -439,7 +449,7 @@ TAPTEST(DirIterator)
   CHECK(NdbDir::remove_recursive(path, true));
   CHECK(!gone(path));
 
-  // Remoe also the empty dir
+  // Remove also the empty dir
   CHECK(NdbDir::remove_recursive(path));
   CHECK(gone(path));
 
@@ -454,6 +464,23 @@ TAPTEST(DirIterator)
   CHECK(NdbDir::remove_recursive(path));
   CHECK(gone(path));
 
+  printf("Testing NdbDir::chdir...\n");
+  // Try chdir to the non existing dir, should fail
+  CHECK(NdbDir::chdir(path) != 0);
+
+  // Build dir tree
+  build_tree(path);
+
+  // Try chdir to the now existing dir, should work
+  CHECK(NdbDir::chdir(path) == 0);
+
+  // Try chdir to the root of tmpdir, should work
+  CHECK(NdbDir::chdir(tempdir.path()) == 0);
+
+  // Remove the dir tree again to leave clean
+  CHECK(NdbDir::remove_recursive(path));
+  CHECK(gone(path));
+
   return 1; // OK
 }
 #endif

=== modified file 'storage/ndb/src/common/util/BaseString.cpp'
--- a/storage/ndb/src/common/util/BaseString.cpp	2009-11-13 11:11:12 +0000
+++ b/storage/ndb/src/common/util/BaseString.cpp	2010-09-21 07:36:08 +0000
@@ -535,7 +535,13 @@ BaseString::getPrettyTextShort(unsigned 
   return to;
 }
 
-
+const void*
+BaseString_get_key(const void* key, size_t* key_length)
+{
+  const BaseString* str = (const BaseString*)key;
+  *key_length = str->length();
+  return str->c_str();
+}
 
 #ifdef TEST_BASE_STRING
 

=== modified file 'storage/ndb/src/common/util/NdbSqlUtil.cpp'
--- a/storage/ndb/src/common/util/NdbSqlUtil.cpp	2010-05-12 13:13:34 +0000
+++ b/storage/ndb/src/common/util/NdbSqlUtil.cpp	2010-08-16 10:25:27 +0000
@@ -17,8 +17,8 @@
 */
 
 #include <NdbSqlUtil.hpp>
-#include <NdbOut.hpp>
 #include <my_sys.h>
+#include <ndb_version.h>
 
 /*
  * Data types.  The entries must be in the numerical order.
@@ -1139,6 +1139,25 @@ NdbSqlUtil::get_var_length(Uint32 typeId
   return false;
 }
 
+
+size_t
+NdbSqlUtil::ndb_strnxfrm(struct charset_info_st * cs,
+                         uchar *dst, size_t dstlen,
+                         const uchar *src, size_t srclen)
+{
+#if NDB_MYSQL_VERSION_D < NDB_MAKE_VERSION(5,6,0)
+  return (*cs->coll->strnxfrm)(cs, dst, dstlen, src, srclen);
+#else
+  /*
+    strnxfrm has got two new parameters in 5.6, we are using the
+    defaults for those and can thus easily calculate them from
+    existing params
+  */
+  return  (*cs->coll->strnxfrm)(cs, dst, dstlen, dstlen,
+                                src, srclen, MY_STRXFRM_PAD_WITH_SPACE);
+#endif
+}
+
 // workaround
 
 int
@@ -1155,13 +1174,13 @@ NdbSqlUtil::strnxfrm_bug7284(CHARSET_INF
   if (n1 <= 0)
     return -1;
   // strxfrm to binary
-  int n2 = (*cs->coll->strnxfrm)(cs, xsp, sizeof(xsp), nsp, n1);
+  int n2 = ndb_strnxfrm(cs, xsp, sizeof(xsp), nsp, n1);
   if (n2 <= 0)
     return -1;
   // XXX bug workaround - strnxfrm may not write full string
   memset(dst, 0x0, dstLen);
   // strxfrm argument string - returns no error indication
-  int n3 = (*cs->coll->strnxfrm)(cs, dst, dstLen, src, srcLen);
+  int n3 = ndb_strnxfrm(cs, dst, dstLen, src, srcLen);
   // pad with strxfrm-ed space chars
   int n4 = n3;
   while (n4 < (int)dstLen) {

=== modified file 'storage/ndb/src/common/util/ndb_init.cpp'
--- a/storage/ndb/src/common/util/ndb_init.cpp	2010-08-20 11:10:25 +0000
+++ b/storage/ndb/src/common/util/ndb_init.cpp	2010-09-22 08:48:10 +0000
@@ -33,7 +33,7 @@ int g_ndb_init_need_monotonic = 0;
 
 static int ndb_init_called = 0;
 
-extern "C" void NdbCondition_Init(int need_monotonic);
+extern "C" void NdbCondition_initialize(int need_monotonic);
 extern "C" void NdbTick_Init(int need_monotonic);
 extern "C" int NdbThread_Init();
 extern "C" void NdbThread_End();
@@ -64,7 +64,7 @@ ndb_init_internal()
   g_ndb_init_need_monotonic = 1;
 #endif
   NdbTick_Init(g_ndb_init_need_monotonic);
-  NdbCondition_Init(g_ndb_init_need_monotonic);
+  NdbCondition_initialize(g_ndb_init_need_monotonic);
   NdbThread_Init();
 }
 

=== modified file 'storage/ndb/src/common/util/ndb_opts.c'
--- a/storage/ndb/src/common/util/ndb_opts.c	2010-05-05 09:30:08 +0000
+++ b/storage/ndb/src/common/util/ndb_opts.c	2010-08-16 17:02:58 +0000
@@ -1,15 +1,12 @@
-#include <my_global.h>
 #define OPTEXPORT
 #include <ndb_opts.h>
 
-#include <mysql_version.h>
 #include <ndb_version.h>
 
-static const char* g_ndb_opt_progname= "ndbapi_program";
 
 static void default_ndb_opt_short(void)
 {
-  ndb_short_usage_sub(g_ndb_opt_progname,NULL);
+  ndb_short_usage_sub(NULL);
 }
 
 static void default_ndb_opt_usage(void)
@@ -26,21 +23,29 @@ static void default_ndb_opt_usage(void)
 static void (*g_ndb_opt_short_usage)(void)= default_ndb_opt_short;
 static void (*g_ndb_opt_usage)(void)= default_ndb_opt_usage;
 
-void ndb_opt_set_usage_funcs(const char* my_progname,
-                             void (*short_usage)(void),
+void ndb_opt_set_usage_funcs(void (*short_usage)(void),
                              void (*usage)(void))
 {
-  if(my_progname)
-    g_ndb_opt_progname= (char*)my_progname;
+  /* Check that the program name has been set already */
+  assert(my_progname);
+
   if(short_usage)
     g_ndb_opt_short_usage= short_usage;
   if(usage)
     g_ndb_opt_usage= usage;
 }
 
-void ndb_short_usage_sub(const char* my_progname, const char* extra)
+static inline
+const char* ndb_progname(void)
+{
+  if (my_progname)
+    return my_progname;
+  return "<unknown program>";
+}
+
+void ndb_short_usage_sub(const char* extra)
 {
-  printf("Usage: %s [OPTIONS]%s%s\n", my_progname,
+  printf("Usage: %s [OPTIONS]%s%s\n", ndb_progname(),
          (extra)?" ":"",
          (extra)?extra:"");
 }

=== modified file 'storage/ndb/src/cw/cpcd/main.cpp'
--- a/storage/ndb/src/cw/cpcd/main.cpp	2010-08-23 08:46:34 +0000
+++ b/storage/ndb/src/cw/cpcd/main.cpp	2010-09-23 07:31:51 +0000
@@ -140,10 +140,10 @@ int main(int argc, char** argv){
   }
 
   if(strlen(work_dir) > 0){
-    int err;
     logger.debug("Changing dir to '%s'", work_dir);
-    if((err = my_setwd(work_dir, MYF(0))) != 0){
-      logger.error("Cannot change directory to '%s', terminating!", work_dir);
+    if(NdbDir::chdir(work_dir) != 0){
+      logger.error("Cannot change directory to '%s', error: %d, terminating!",
+                   work_dir, errno);
       exit(1);
     }
   }

=== modified file 'storage/ndb/src/kernel/angel.cpp'
--- a/storage/ndb/src/kernel/angel.cpp	2010-08-31 11:46:48 +0000
+++ b/storage/ndb/src/kernel/angel.cpp	2010-09-23 07:31:51 +0000
@@ -24,6 +24,7 @@
 #include <NdbAutoPtr.hpp>
 #include <portlib/ndb_daemon.h>
 #include <portlib/NdbSleep.h>
+#include <portlib/NdbDir.hpp>
 
 #include <ConfigRetriever.hpp>
 
@@ -453,7 +454,12 @@ configure(const ndb_mgm_configuration* c
 
   NdbConfig_SetPath(datadir);
 
-  my_setwd(NdbConfig_get_path(0), MYF(0));
+  if (NdbDir::chdir(NdbConfig_get_path(NULL)) != 0)
+  {
+    g_eventLogger->warning("Cannot change directory to '%s', error: %d",
+                           NdbConfig_get_path(NULL), errno);
+    // Ignore error
+  }
 
   return true;
 }
@@ -461,7 +467,8 @@ configure(const ndb_mgm_configuration* c
 bool stop_child = false;
 
 void
-angel_run(const BaseString& original_args,
+angel_run(const char* progname,
+          const BaseString& original_args,
           const char* connect_str,
           int force_nodeid,
           const char* bind_address,
@@ -573,7 +580,7 @@ angel_run(const BaseString& original_arg
     args.appfmt(" --initial=%d", initial);
     args.appfmt(" --nostart=%d", no_start);
 
-    pid_t child = spawn_process(my_progname, args);
+    pid_t child = spawn_process(progname, args);
     if (child == -1)
       angel_exit(1);
 

=== modified file 'storage/ndb/src/kernel/angel.hpp'
--- a/storage/ndb/src/kernel/angel.hpp	2010-06-11 12:08:57 +0000
+++ b/storage/ndb/src/kernel/angel.hpp	2010-08-16 17:06:06 +0000
@@ -19,7 +19,8 @@
 #include <util/BaseString.hpp>
 
 void
-angel_run(const BaseString& original_args,
+angel_run(const char* progname,
+          const BaseString& original_args,
           const char* connect_str,
           int force_nodeid,
           const char* bind_address,

=== modified file 'storage/ndb/src/kernel/blocks/ERROR_codes.txt'
--- a/storage/ndb/src/kernel/blocks/ERROR_codes.txt	2010-09-03 08:59:02 +0000
+++ b/storage/ndb/src/kernel/blocks/ERROR_codes.txt	2010-09-23 11:55:42 +0000
@@ -3,7 +3,7 @@ Next NDBCNTR 1002
 Next NDBFS 2000
 Next DBACC 3002
 Next DBTUP 4035
-Next DBLQH 5057
+Next DBLQH 5060
 Next DBDICT 6025
 Next DBDIH 7226
 Next DBTC 8088
@@ -11,7 +11,7 @@ Next CMVMI 9000
 Next BACKUP 10042
 Next DBUTIL 11002
 Next DBTUX 12008
-Next SUMA 13044
+Next SUMA 13047
 Next LGMAN 15001
 Next TSMAN 16001
 

=== modified file 'storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp'
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2010-08-20 11:33:06 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2010-09-21 07:36:08 +0000
@@ -15656,22 +15656,32 @@ void Dbdict::completeSubStartReq(Signal*
     ndbout_c("SUB_START_REF");
 #endif
 
-    NodeReceiverGroup rg(DBDICT, subbPtr.p->m_reqTracker.m_confs);
-    RequestTracker & p = subbPtr.p->m_reqTracker;
-    ndbrequire(p.init<SubStopRef>(c_counterMgr, rg, GSN_SUB_STOP_REF,
-                                  subbPtr.i));
-
-    SubStopReq* req = (SubStopReq*) signal->getDataPtrSend();
-
-    req->senderRef  = reference();
-    req->senderData = subbPtr.i;
-    req->subscriptionId = subbPtr.p->m_subscriptionId;
-    req->subscriptionKey = subbPtr.p->m_subscriptionKey;
-    req->subscriberRef = subbPtr.p->m_subscriberRef;
-    req->subscriberData = subbPtr.p->m_subscriberData;
-    req->requestInfo = SubStopReq::RI_ABORT_START;
-    sendSignal(rg, GSN_SUB_STOP_REQ, signal, SubStopReq::SignalLength, JBB);
-    return;
+    if (subbPtr.p->m_reqTracker.hasConf())
+    {
+      jam();
+      NodeReceiverGroup rg(DBDICT, subbPtr.p->m_reqTracker.m_confs);
+      RequestTracker & p = subbPtr.p->m_reqTracker;
+      ndbrequire(p.init<SubStopRef>(c_counterMgr, rg, GSN_SUB_STOP_REF,
+                                    subbPtr.i));
+
+      SubStopReq* req = (SubStopReq*) signal->getDataPtrSend();
+
+      req->senderRef  = reference();
+      req->senderData = subbPtr.i;
+      req->subscriptionId = subbPtr.p->m_subscriptionId;
+      req->subscriptionKey = subbPtr.p->m_subscriptionKey;
+      req->subscriberRef = subbPtr.p->m_subscriberRef;
+      req->subscriberData = subbPtr.p->m_subscriberData;
+      req->requestInfo = SubStopReq::RI_ABORT_START;
+      sendSignal(rg, GSN_SUB_STOP_REQ, signal, SubStopReq::SignalLength, JBB);
+      return;
+    }
+    else
+    {
+      jam();
+      completeSubStopReq(signal, subbPtr.i, 0);
+      return;
+    }
   }
 #ifdef EVENT_DEBUG
   ndbout_c("SUB_START_CONF");
@@ -18686,7 +18696,7 @@ void Dbdict::check_takeover_replies(Sign
       jam();
       c_nodes.getPtr(nodePtr, i);
       {
-	DictTakeoverConf* conf = conf = &nodePtr.p->takeOverConf;
+	DictTakeoverConf* conf = &nodePtr.p->takeOverConf;
         Uint32 clientRef = conf->clientRef;
 	Uint32 rollforward_op = conf->rollforward_op;
 	Uint32 rollforward_op_state = conf->rollforward_op_state;
@@ -25068,6 +25078,9 @@ Dbdict::trans_commit_first(Signal* signa
     signal->theData[2] = gci_hi;
     signal->theData[3] = gci_lo;
     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 20, 4);
+
+    signal->theData[0] = 6099;
+    sendSignal(DBDIH_REF, GSN_DUMP_STATE_ORD, signal, 1, JBB);
   }
   else
   {
@@ -27247,7 +27260,7 @@ Dbdict::get_default_fragments(Uint32 ext
   bzero(&signalT, sizeof(signalT));
   Signal* signal = new (&signalT) Signal(0); // placement new
 
-  CheckNodeGroups * sd = CAST_PTR(CheckNodeGroups, signal->getDataPtrSend());
+  CheckNodeGroups * sd = CAST_PTR(CheckNodeGroups, &signal->theData[0]);
   sd->extraNodeGroups = extranodegroups;
   sd->requestType = CheckNodeGroups::Direct | CheckNodeGroups::GetDefaultFragments;
   EXECUTE_DIRECT(DBDIH, GSN_CHECKNODEGROUPSREQ, signal,

=== modified file 'storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2010-08-26 16:01:10 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2010-09-23 11:55:42 +0000
@@ -17455,6 +17455,20 @@ Dbdih::execDUMP_STATE_ORD(Signal* signal
     SET_ERROR_INSERT_VALUE2(7216, signal->theData[1]);
     return;
   }
+  DECLARE_DUMP0(DBDIH, 6099, "Start microgcp")
+  {
+    if (isMaster())
+    {
+      jam();
+      m_micro_gcp.m_master.m_start_time = 0;
+    }
+    else
+    {
+      jam();
+      sendSignal(cmasterdihref, GSN_DUMP_STATE_ORD, signal, 1, JBB);
+    }
+    return;
+  }
 }//Dbdih::execDUMP_STATE_ORD()
 
 void

=== modified file 'storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2010-09-03 08:59:02 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2010-09-23 11:55:42 +0000
@@ -1419,10 +1419,13 @@ public:
       OPEN_SR_READ_INVALIDATE_PAGES = 21,
       CLOSE_SR_READ_INVALIDATE_PAGES = 22,
       OPEN_SR_WRITE_INVALIDATE_PAGES = 23,
-      CLOSE_SR_WRITE_INVALIDATE_PAGES = 24
+      CLOSE_SR_WRITE_INVALIDATE_PAGES = 24,
+      OPEN_SR_READ_INVALIDATE_SEARCH_FILES = 25,
+      CLOSE_SR_READ_INVALIDATE_SEARCH_FILES = 26,
+      CLOSE_SR_READ_INVALIDATE_SEARCH_LAST_FILE = 27
 #ifndef NO_REDO_OPEN_FILE_CACHE
-      ,OPEN_EXEC_LOG_CACHED = 25
-      ,CLOSING_EXEC_LOG_CACHED = 26
+      ,OPEN_EXEC_LOG_CACHED = 28
+      ,CLOSING_EXEC_LOG_CACHED = 29
 #endif
     };
     
@@ -1596,6 +1599,7 @@ public:
       READ_SR_INVALIDATE_PAGES = 18,
       WRITE_SR_INVALIDATE_PAGES = 19,
       WRITE_SR_INVALIDATE_PAGES_UPDATE_PAGE0 = 20
+      ,READ_SR_INVALIDATE_SEARCH_FILES = 21
     };
     /**
      * We have to remember the log pages read. 
@@ -2430,6 +2434,8 @@ private:
   Uint32 nextLogFilePtr(Uint32 logFilePtrI);
   void readFileInInvalidate(Signal *signal, int stepNext);
   void writeFileInInvalidate(Signal *signal, int stepPrev);
+  bool invalidateCloseFile(Signal*, Ptr<LogPartRecord>, Ptr<LogFileRecord>,
+                           LogFileRecord::LogFileStatus status);
   void exitFromInvalidate(Signal* signal);
   Uint32 calcPageCheckSum(LogPageRecordPtr logP);
   Uint32 handleLongTupKey(Signal* signal, Uint32* dataPtr, Uint32 len);
@@ -3178,6 +3184,9 @@ public:
 
   Uint32 get_node_status(Uint32 nodeId) const;
   bool check_ndb_versions() const;
+
+  void suspendFile(Signal* signal, Uint32 filePtrI, Uint32 millis);
+  void suspendFile(Signal* signal, Ptr<LogFileRecord> logFile, Uint32 millis);
 };
 
 inline

=== modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2010-09-03 08:59:02 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2010-09-23 11:55:42 +0000
@@ -14202,6 +14202,23 @@ void Dblqh::execFSCLOSECONF(Signal* sign
     readFileInInvalidate(signal, 2);
     return;
 
+  case LogFileRecord::CLOSE_SR_READ_INVALIDATE_SEARCH_FILES:
+    jam();
+    logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
+
+    logPartPtr.i = logFilePtr.p->logPartRec;
+    ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
+
+    readFileInInvalidate(signal, 4);
+    return;
+  case LogFileRecord::CLOSE_SR_READ_INVALIDATE_SEARCH_LAST_FILE:
+    logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
+
+    logPartPtr.i = logFilePtr.p->logPartRec;
+    ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
+
+    readFileInInvalidate(signal, 7);
+    return;
   case LogFileRecord::CLOSE_SR_WRITE_INVALIDATE_PAGES:
     jam();
     logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
@@ -14264,6 +14281,11 @@ void Dblqh::execFSOPENCONF(Signal* signa
     logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
     readFileInInvalidate(signal, 0);
     return;
+  case LogFileRecord::OPEN_SR_READ_INVALIDATE_SEARCH_FILES:
+    jam();
+    logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
+    readFileInInvalidate(signal, 5);
+    return;
   case LogFileRecord::OPEN_SR_WRITE_INVALIDATE_PAGES:
     jam();
     logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
@@ -14401,6 +14423,10 @@ void Dblqh::execFSREADCONF(Signal* signa
     jam();
     invalidateLogAfterLastGCI(signal);
     return;
+  case LogFileOperationRecord::READ_SR_INVALIDATE_SEARCH_FILES:
+    jam();
+    invalidateLogAfterLastGCI(signal);
+    return;
   case LogFileOperationRecord::READ_SR_FOURTH_PHASE:
     jam();
     releaseLfo(signal);
@@ -15729,7 +15755,7 @@ void Dblqh::writeSinglePage(Signal* sign
   if (DEBUG_REDO)
   {
     ndbout_c("writeSingle 1 page at part: %u file: %u pos: %u",
-             logPartPtr.i,
+             logPartPtr.p->logPartNo,
              logFilePtr.p->fileNo,
              pageNo);
   }
@@ -15801,7 +15827,7 @@ void Dblqh::readSrLastFileLab(Signal* si
   if (DEBUG_REDO)
   {
     ndbout_c("readSrLastFileLab part: %u logExecState: %u logPartState: %u logLap: %u",
-             logPartPtr.i,
+             logPartPtr.p->logPartNo,
              logPartPtr.p->logExecState,
              logPartPtr.p->logPartState,
              logPartPtr.p->logLap);
@@ -17494,7 +17520,7 @@ void Dblqh::execSr(Signal* signal) 
       {
         ndbout_c("found gci: %u part: %u file: %u page: %u",
                  logWord,
-                 logPartPtr.i,
+                 logPartPtr.p->logPartNo,
                  logFilePtr.p->fileNo,
                  logFilePtr.p->currentFilepage);
       }
@@ -17518,7 +17544,7 @@ void Dblqh::execSr(Signal* signal) 
           if (DEBUG_REDO)
           {
             ndbout_c("execSr part: %u logLap: %u",
-                     logPartPtr.i, logPartPtr.p->logLap);
+                     logPartPtr.p->logPartNo, logPartPtr.p->logLap);
           }
         }//if
 /*---------------------------------------------------------------------------*/
@@ -17566,7 +17592,7 @@ crash:
 		       "Error while reading REDO log. from %d\n"
 		       "part: %u D=%d, F=%d Mb=%d FP=%d W1=%d W2=%d : %s gci: %u",
 		       signal->theData[8],
-                       logPartPtr.i,
+                       logPartPtr.p->logPartNo,
 		       signal->theData[2], 
 		       signal->theData[3], 
 		       signal->theData[4],
@@ -17710,7 +17736,8 @@ Dblqh::nextLogFilePtr(Uint32 logFilePtrI
   return tmp.p->nextLogFile;
 }
 
-void Dblqh::invalidateLogAfterLastGCI(Signal* signal)
+void
+Dblqh::invalidateLogAfterLastGCI(Signal* signal)
 {
   jam();
   if (logPartPtr.p->logExecState != LogPartRecord::LES_EXEC_LOG_INVALIDATE) {
@@ -17724,6 +17751,34 @@ void Dblqh::invalidateLogAfterLastGCI(Si
   }
 
   switch (lfoPtr.p->lfoState) {
+  case LogFileOperationRecord::READ_SR_INVALIDATE_SEARCH_FILES:
+  {
+    jam();
+    // Check if this file contains pages needing to be invalidated
+    ndbrequire(logPartPtr.p->invalidatePageNo == 1);
+    bool ok = logPagePtr.p->logPageWord[ZPOS_LOG_LAP] == logPartPtr.p->logLap;
+    releaseLfo(signal);
+    releaseLogpage(signal);
+    if (ok)
+    {
+      jam();
+      // This page must be invalidated.
+      // We search next file
+      readFileInInvalidate(signal, 3);
+      return;
+    }
+    else
+    {
+      jam();
+      /**
+       * This file doest not need to be invalidated...move to previous
+       *   file and search forward linear
+       */
+      readFileInInvalidate(signal, 6);
+      return;
+    }
+    break;
+  }
   case LogFileOperationRecord::READ_SR_INVALIDATE_PAGES:
     jam();
     // Check if this page must be invalidated.
@@ -17774,26 +17829,14 @@ void Dblqh::invalidateLogAfterLastGCI(Si
         if (DEBUG_REDO)
         {
           ndbout_c("invalidateLogAfterLastGCI part: %u wrap from file 0 -> logLap: %u",
-                   logPartPtr.i, logPartPtr.p->logLap);
+                   logPartPtr.p->logPartNo, logPartPtr.p->logLap);
         }
       }
       
-      if (logFilePtr.p->fileNo != 0 &&
-          logFilePtr.i != logPartPtr.p->currentLogfile &&
-          logFilePtr.i != nextLogFilePtr(logPartPtr.p->currentLogfile))
+      if (invalidateCloseFile(signal, logPartPtr, logFilePtr,
+                              LogFileRecord::CLOSE_SR_WRITE_INVALIDATE_PAGES))
       {
         jam();
-        if (DEBUG_REDO)
-        {
-          ndbout_c("invalidate part: %u close %u(%u) (write) (%u)",
-                   logPartPtr.i,
-                   logFilePtr.p->fileNo,
-                   logFilePtr.i,
-                   logPartPtr.p->currentLogfile);
-        }
-        logFilePtr.p->logFileStatus =
-          LogFileRecord::CLOSE_SR_WRITE_INVALIDATE_PAGES;
-        closeFile(signal, logFilePtr, __LINE__);
         return;
       }
       writeFileInInvalidate(signal, 1); // step prev
@@ -17845,7 +17888,7 @@ Dblqh::writeFileInInvalidate(Signal* sig
     if (DEBUG_REDO)
     {
       ndbout_c("invalidate part: %u open for write %u",
-               logPartPtr.i, logFilePtr.p->fileNo);
+               logPartPtr.p->logPartNo, logFilePtr.p->fileNo);
     }
     logFilePtr.p->logFileStatus =LogFileRecord::OPEN_SR_WRITE_INVALIDATE_PAGES;
     openFileRw(signal, logFilePtr);
@@ -17865,31 +17908,53 @@ Dblqh::writeFileInInvalidate(Signal* sig
   return;
 }//Dblqh::invalidateLogAfterLastGCI
 
+bool
+Dblqh::invalidateCloseFile(Signal* signal,
+                           Ptr<LogPartRecord> partPtr,
+                           Ptr<LogFileRecord> filePtr,
+                           LogFileRecord::LogFileStatus status)
+{
+  jam();
+  if (filePtr.p->fileNo != 0 &&
+      filePtr.i != partPtr.p->currentLogfile &&
+      filePtr.i != nextLogFilePtr(logPartPtr.p->currentLogfile))
+  {
+    jam();
+    if (DEBUG_REDO)
+    {
+      ndbout_c("invalidate part: %u close %u(%u) state: %u (%u)",
+               logPartPtr.p->logPartNo,
+               logFilePtr.p->fileNo,
+               logFilePtr.i,
+               (Uint32)status,
+               logPartPtr.p->currentLogfile);
+    }
+    filePtr.p->logFileStatus = status;
+    closeFile(signal, filePtr, __LINE__);
+    return true;
+  }
+  return false;
+}
+
 void Dblqh::readFileInInvalidate(Signal* signal, int stepNext)
 {
   jam();
 
+  if (DEBUG_REDO)
+  {
+    ndbout_c("readFileInInvalidate part: %u file: %u stepNext: %u",
+             logPartPtr.p->logPartNo, logFilePtr.p->fileNo, stepNext);
+  }
+
   if (stepNext == 1)
   {
     logPartPtr.p->invalidatePageNo++;
     if (logPartPtr.p->invalidatePageNo == (clogFileSize * ZPAGES_IN_MBYTE))
     {
-      if (logFilePtr.p->fileNo != 0 &&
-          logFilePtr.i != logPartPtr.p->currentLogfile &&
-          logFilePtr.i != nextLogFilePtr(logPartPtr.p->currentLogfile))
+      if (invalidateCloseFile(signal, logPartPtr, logFilePtr,
+                              LogFileRecord::CLOSE_SR_READ_INVALIDATE_PAGES))
       {
         jam();
-        if (DEBUG_REDO)
-        {
-          ndbout_c("invalidate part: %u close %u(%u) (read) (%u)",
-                   logPartPtr.i,
-                   logFilePtr.p->fileNo,
-                   logFilePtr.i,
-                   logPartPtr.p->currentLogfile);
-        }
-        logFilePtr.p->logFileStatus =
-          LogFileRecord::CLOSE_SR_READ_INVALIDATE_PAGES;
-        closeFile(signal, logFilePtr, __LINE__);
         return;
       }
       else
@@ -17898,6 +17963,14 @@ void Dblqh::readFileInInvalidate(Signal*
         stepNext = 2; // After close
       }
     }
+    else
+    {
+      jam();
+      // Contact NDBFS. Real time break.
+      readSinglePage(signal, logPartPtr.p->invalidatePageNo);
+      lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_INVALIDATE_PAGES;
+      return;
+    }
   }
   
   if (stepNext == 2)
@@ -17919,28 +17992,144 @@ void Dblqh::readFileInInvalidate(Signal*
       logPartPtr.p->logLap++;
       if (DEBUG_REDO)
       {
-        ndbout_c("readFileInInvalidate part: %u wrap to file 0 -> logLap: %u",
-                 logPartPtr.i, logPartPtr.p->logLap);
+        ndbout_c("readFileInInvalidate part: %u step: %u wrap to file 0 -> logLap: %u",
+                 logPartPtr.p->logPartNo, stepNext, logPartPtr.p->logLap);
       }
     }
 
+stepNext_2:
     if (logFilePtr.p->logFileStatus != LogFileRecord::OPEN)
     {
       jam();
       if (DEBUG_REDO)
       {
-        ndbout_c("invalidate part: %u open for read %u",
-                 logPartPtr.i, logFilePtr.p->fileNo);
+        ndbout_c("invalidate part: %u step: %u open for read %u",
+                 logPartPtr.p->logPartNo, stepNext, logFilePtr.p->fileNo);
       }
       logFilePtr.p->logFileStatus =LogFileRecord::OPEN_SR_READ_INVALIDATE_PAGES;
       openFileRw(signal, logFilePtr);
       return;
     }
+
+    // Contact NDBFS. Real time break.
+    readSinglePage(signal, logPartPtr.p->invalidatePageNo);
+    lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_INVALIDATE_PAGES;
+    return;
+  }
+
+  if (stepNext == 3)
+  {
+    jam();
+    if (invalidateCloseFile
+        (signal, logPartPtr, logFilePtr,
+         LogFileRecord::CLOSE_SR_READ_INVALIDATE_SEARCH_FILES))
+    {
+      jam();
+      return;
+    }
+    stepNext = 4;
+  }
+
+  if (stepNext == 4)
+  {
+    jam();
+    logFilePtr.i = logFilePtr.p->nextLogFile;
+    ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
+    logPartPtr.p->invalidateFileNo = logFilePtr.p->fileNo;
+    // Page 0 is used for file descriptors.
+    logPartPtr.p->invalidatePageNo = 1;
+
+    if (logFilePtr.p->fileNo == 0)
+    {
+      /**
+       * We're wrapping in the log...
+       *   update logLap
+       */
+      logPartPtr.p->logLap++;
+      if (DEBUG_REDO)
+      {
+        ndbout_c("readFileInInvalidate part: %u step: %u wrap to file 0 -> logLap: %u",
+                 logPartPtr.p->logPartNo, stepNext, logPartPtr.p->logLap);
+      }
+    }
+
+    if (logFilePtr.p->logFileStatus != LogFileRecord::OPEN)
+    {
+      jam();
+      if (DEBUG_REDO)
+      {
+        ndbout_c("invalidate part: %u step: %u open for read %u",
+                 logPartPtr.p->logPartNo, stepNext, logFilePtr.p->fileNo);
+      }
+      logFilePtr.p->logFileStatus =
+        LogFileRecord::OPEN_SR_READ_INVALIDATE_SEARCH_FILES;
+      openFileRw(signal, logFilePtr);
+      return;
+    }
+    stepNext = 5;
   }
 
-  // Contact NDBFS. Real time break.
-  readSinglePage(signal, logPartPtr.p->invalidatePageNo); 
-  lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_INVALIDATE_PAGES;
+  if (stepNext == 5)
+  {
+    jam();
+    // Contact NDBFS. Real time break.
+    readSinglePage(signal, logPartPtr.p->invalidatePageNo);
+    lfoPtr.p->lfoState =
+      LogFileOperationRecord::READ_SR_INVALIDATE_SEARCH_FILES;
+    return;
+  }
+
+  if (stepNext == 6)
+  {
+    jam();
+    if (invalidateCloseFile
+        (signal, logPartPtr, logFilePtr,
+         LogFileRecord::CLOSE_SR_READ_INVALIDATE_SEARCH_LAST_FILE))
+    {
+      jam();
+      return;
+    }
+    stepNext = 7;
+  }
+
+  if (stepNext == 7)
+  {
+    jam();
+
+    if (logFilePtr.p->fileNo == 0)
+    {
+      jam();
+      /**
+       * We're wrapping in the log...
+       *   update logLap
+       */
+      logPartPtr.p->logLap--;
+      ndbrequire(logPartPtr.p->logLap); // Should always be > 0
+      if (DEBUG_REDO)
+      {
+        ndbout_c("invalidateLogAfterLastGCI part: %u step: %u wrap from file 0 -> logLap: %u",
+                 logPartPtr.p->logPartNo, stepNext, logPartPtr.p->logLap);
+      }
+    }
+
+    logFilePtr.i = logFilePtr.p->prevLogFile;
+    ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
+
+    logPartPtr.p->invalidateFileNo = logFilePtr.p->fileNo;
+    // Page 0 is used for file descriptors.
+    logPartPtr.p->invalidatePageNo = 1;
+
+    if (logPartPtr.p->invalidateFileNo == logPartPtr.p->headFileNo)
+    {
+      jam();
+      logPartPtr.p->invalidatePageNo = logPartPtr.p->headPageNo;
+      readFileInInvalidate(signal, 1);
+      return;
+    }
+
+    goto stepNext_2;
+  }
+  ndbrequire(false);
 }
 
 void Dblqh::exitFromInvalidate(Signal* signal)
@@ -17951,7 +18140,7 @@ void Dblqh::exitFromInvalidate(Signal* s
   {
     jam();
     printf("exitFromInvalidate part: %u head file: %u page: %u open: ",
-           logPartPtr.i,
+           logPartPtr.p->logPartNo,
            logPartPtr.p->headFileNo,
            logPartPtr.p->headPageNo);
 
@@ -18432,7 +18621,7 @@ void Dblqh::readSrFourthZeroLab(Signal* 
   logPartPtr.p->invalidatePageNo = logPartPtr.p->headPageNo;
   logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOG_INVALIDATE;
    
-  readFileInInvalidate(signal, 1);
+  readFileInInvalidate(signal, 3);
   return;
 }//Dblqh::readSrFourthZeroLab()
 
@@ -18945,7 +19134,7 @@ void Dblqh::completedLogPage(Signal* sig
   {
     ndbout_c("writing %d pages at part: %u file: %u pos: %u",
              twlpNoPages,
-             logPartPtr.i,
+             logPartPtr.p->logPartNo,
              logFilePtr.p->fileNo,
              logFilePtr.p->filePosition);
   }
@@ -20138,7 +20327,7 @@ void Dblqh::readExecLog(Signal* signal) 
   {
     ndbout_c("readExecLog %u page at part: %u file: %u pos: %u",
              lfoPtr.p->noPagesRw,
-             logPartPtr.i,
+             logPartPtr.p->logPartNo,
              logFilePtr.p->fileNo,
              logPartPtr.p->execSrStartPageNo);
   }
@@ -20209,7 +20398,7 @@ void Dblqh::readExecSr(Signal* signal) 
   {
     ndbout_c("readExecSr %u page at part: %u file: %u pos: %u",
              8,
-             logPartPtr.i,
+             logPartPtr.p->logPartNo,
              logFilePtr.p->fileNo,
              tresPageid);
   }
@@ -20370,7 +20559,7 @@ void Dblqh::readSinglePage(Signal* signa
   if (DEBUG_REDO)
   {
     ndbout_c("readSinglePage 1 page at part: %u file: %u pos: %u",
-             logPartPtr.i,
+             logPartPtr.p->logPartNo,
              logFilePtr.p->fileNo,
              pageNo);
   }
@@ -20903,7 +21092,7 @@ void Dblqh::writeCompletedGciLog(Signal*
   {
     ndbout_c("writeCompletedGciLog gci: %u part: %u file: %u page: %u",
              cnewestCompletedGci,
-             logPartPtr.i,
+             logPartPtr.p->logPartNo,
              logFilePtr.p->fileNo,
              logFilePtr.p->currentFilepage);
   }
@@ -20950,7 +21139,7 @@ void Dblqh::writeDirty(Signal* signal, U
   if (DEBUG_REDO)
   {
     ndbout_c("writeDirty 1 page at part: %u file: %u pos: %u",
-             logPartPtr.i,
+             logPartPtr.p->logPartNo,
              logFilePtr.p->fileNo,
              logPartPtr.p->prevFilepage);
   }
@@ -21150,7 +21339,7 @@ void Dblqh::writeNextLog(Signal* signal)
       BaseString::snprintf(buf, sizeof(buf), 
                            "Head/Tail met in REDO log, logpart: %u"
                            " file: %u mbyte: %u state: %u tail-problem: %u",
-                           logPartPtr.i,
+                           logPartPtr.p->logPartNo,
                            logFilePtr.p->fileNo,
                            logFilePtr.p->currentMbyte,
                            logPartPtr.p->logPartState,
@@ -21191,6 +21380,31 @@ void Dblqh::writeNextLog(Signal* signal)
     jam();
     logPartPtr.p->m_tail_problem = true;
   }
+
+  if (ERROR_INSERTED(5058) &&
+      (twnlNextMbyte + 3 >= clogFileSize) &&
+      logFilePtr.p->fileNo != 0 &&
+      logFilePtr.p->nextLogFile != logPartPtr.p->firstLogfile)
+  {
+    jam();
+    srand((int)time(0));
+    Uint32 wait = 3 + (rand() % 5);
+
+    suspendFile(signal, logFilePtr, /* forever */ 0);
+    suspendFile(signal, logPartPtr.p->firstLogfile, /* forever */ 0);
+    signal->theData[0] = 9999;
+    sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, wait * 1000, 1);
+    CLEAR_ERROR_INSERT_VALUE;
+  }
+
+  if (ERROR_INSERTED(5059) &&
+      twnlNextMbyte == 4 &&
+      logFilePtr.p->fileNo != 0)
+  {
+    signal->theData[0] = 9999;
+    sendSignal(CMVMI_REF, GSN_NDB_TAMPER, signal, 1, JBA);
+  }
+
 }//Dblqh::writeNextLog()
 
 bool
@@ -22162,7 +22376,7 @@ Dblqh::execDUMP_STATE_ORD(Signal* signal
       return;
     }
 
-    for(Uint32 i = 0; i<4; i++)
+    for(Uint32 i = 0; i<clogPartFileSize; i++)
     {
       logPartPtr.i = i;
       ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
@@ -22176,7 +22390,7 @@ Dblqh::execDUMP_STATE_ORD(Signal* signal
       Uint64 mb = free_log(head, tail, logPartPtr.p->noLogFiles, clogFileSize);
       Uint64 total = logPartPtr.p->noLogFiles * Uint64(clogFileSize);
       ndbout_c("REDO part: %u HEAD: file: %u mbyte: %u TAIL: file: %u mbyte: %u total: %llu free: %llu (mb)",
-               i, 
+               logPartPtr.p->logPartNo, 
                head.m_file_no, head.m_mbyte,
                tail.m_file_no, tail.m_mbyte,
                total, mb);
@@ -22829,3 +23043,22 @@ Dblqh::check_ndb_versions() const
   }
   return true;
 }
+
+void
+Dblqh::suspendFile(Signal* signal, Uint32 filePtrI, Uint32 millis)
+{
+  Ptr<LogFileRecord> tmp;
+  tmp.i = filePtrI;
+  ptrCheckGuard(tmp, clogFileFileSize, logFileRecord);
+  suspendFile(signal, tmp, millis);
+}
+
+void
+Dblqh::suspendFile(Signal* signal, Ptr<LogFileRecord> logFilePtr, Uint32 millis)
+{
+  SaveSignal<FsSuspendOrd::SignalLength> tmp(signal);
+  signal->theData[0] = logFilePtr.p->fileRef;
+  signal->theData[1] = millis;
+  sendSignal(NDBFS_REF, GSN_FSSUSPENDORD, signal, 2, JBA);
+}
+

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2010-09-03 08:59:02 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2010-09-23 11:55:42 +0000
@@ -463,9 +463,7 @@ typedef Ptr<Fragoperrec> FragoperrecPtr;
       Get_next_page_dd,
       Get_page_dd,
       Get_next_tuple,
-      Get_tuple,
-      Get_next_tuple_fs,
-      Get_tuple_fs
+      Get_tuple
     };
     Get m_get;                  // entry point in scanNext
     Local_key m_key;            // scan position pointer MM or DD
@@ -972,13 +970,13 @@ ArrayPool<TupTriggerData> c_triggerPool;
     Uint32 dynTabDescriptor;
 
     /* Mask of variable-sized dynamic attributes. */
-    Uint32* dynVarSizeMask;
+    Uint32* dynVarSizeMask[2];
     /*
       Mask of fixed-sized dynamic attributes. There is one bit set for each
       32-bit word occupied by fixed-size attributes, so fixed-size dynamic
       attributes >32bit have multiple bits here.
     */
-    Uint32* dynFixSizeMask;
+    Uint32* dynFixSizeMask[2];
 
     ReadFunction* readFunctionArray;
     UpdateFunction* updateFunctionArray;

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp	2010-09-03 08:59:02 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp	2010-09-23 11:55:42 +0000
@@ -1140,6 +1140,8 @@ error:
   Both variable-sized and fixed-size attributes are stored in the same way
   in the expanded form as variable-sized attributes (in expand_var_part()).
 
+  This method is used for both mem and disk dynamic data.
+
     dst         Destination for expanded data
     tabPtrP     Table descriptor
     src         Pointer to the start of dynamic bitmap in source row
@@ -1154,8 +1156,8 @@ expand_dyn_part(Dbtup::KeyReqStruct::Var
 		Uint32 row_len,
 		const Uint32 * tabDesc,
 		const Uint16* order,
-		Uint32 mm_dynvar,
-		Uint32 mm_dynfix,
+		Uint32 dynvar,
+		Uint32 dynfix,
 		Uint32 max_bmlen)
 {
   /* Copy the bitmap, zeroing out any words not stored in the row. */
@@ -1188,11 +1190,11 @@ expand_dyn_part(Dbtup::KeyReqStruct::Var
   Uint16* dst_len_ptr= dst_off_ptr + no_attr;
   Uint16 this_src_off= row_len ? * src_off_ptr++ : 0;
   /* We need to reserve room for the offsets written by shrink_tuple+padding.*/
-  Uint16 dst_off= 4 * (max_bmlen + ((mm_dynvar+2)>>1));
+  Uint16 dst_off= 4 * (max_bmlen + ((dynvar+2)>>1));
   char *dst_ptr= (char*)dst_bm_ptr + dst_off;
-  for(Uint32 i= 0; i<mm_dynvar; i++)
+  for(Uint32 i= 0; i<dynvar; i++)
   {
-    Uint16 j= order[mm_dynfix+i];
+    Uint16 j= order[dynfix+i];
     Uint32 max_len= 4 *AttributeDescriptor::getSizeInWords(tabDesc[j]);
     Uint32 len;
     Uint32 pos = AttributeOffset::getNullFlagPos(tabDesc[j+1]);
@@ -1226,12 +1228,12 @@ expand_dyn_part(Dbtup::KeyReqStruct::Var
     dynamic part of the row. This is true both for the stored/shrunken and
     for the expanded form.
   */
-  for(Uint32 i= mm_dynfix; i>0; )
+  for(Uint32 i= dynfix; i>0; )
   {
     i--;
     Uint16 j= order[i];
     Uint32 fix_size= 4*AttributeDescriptor::getSizeInWords(tabDesc[j]);
-    dst_off_ptr[mm_dynvar+i]= dst_off;
+    dst_off_ptr[dynvar+i]= dst_off;
     /* len offset array is not used for fixed size. */
     Uint32 pos = AttributeOffset::getNullFlagPos(tabDesc[j+1]);
     if(bm_len > (pos >> 5) && BitmaskImpl::get(bm_len, src, pos))
@@ -3408,7 +3410,7 @@ Dbtup::shrink_tuple(KeyReqStruct* req_st
         /* ToDo: Put all of the dynattr code inside if(bm_len>0) { ... }, 
          * split to separate function. */
         Uint16 dyn_dst_data_offset= 0;
-        const Uint32 *dyn_bm_var_mask_ptr= tabPtrP->dynVarSizeMask;
+        const Uint32 *dyn_bm_var_mask_ptr= tabPtrP->dynVarSizeMask[MM];
         for(Uint16 i= 0; i< bm_len; i++)
         {
           Uint32 v= src_bm_ptr[i];

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp	2010-08-20 11:26:54 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp	2010-09-07 06:44:00 +0000
@@ -772,6 +772,10 @@ Dbtup::initTab(Tablerec* const regTabPtr
   regTabPtr->tabDescriptor = RNIL;
   regTabPtr->readKeyArray = RNIL;
   regTabPtr->dynTabDescriptor = RNIL;
+  regTabPtr->dynFixSizeMask[MM] = NULL;
+  regTabPtr->dynVarSizeMask[MM] = NULL;
+  regTabPtr->dynFixSizeMask[DD] = NULL;
+  regTabPtr->dynVarSizeMask[DD] = NULL;
 
   regTabPtr->m_bits = 0;
 

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp	2010-09-03 05:35:51 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp	2010-09-21 07:36:08 +0000
@@ -676,8 +676,8 @@ void Dbtup::execTUPFRAGREQ(Signal* signa
     goto sendref;
   }
 
-  if (ERROR_INSERTED(4007) && regTabPtr.p->fragid[0] == fragId ||
-      ERROR_INSERTED(4008) && regTabPtr.p->fragid[1] == fragId ||
+  if ((ERROR_INSERTED(4007) && regTabPtr.p->fragid[0] == fragId) ||
+      (ERROR_INSERTED(4008) && regTabPtr.p->fragid[1] == fragId) ||
       ERROR_INSERTED(4050))
   {
     jam();
@@ -1414,8 +1414,8 @@ Dbtup::computeTableMetaData(Tablerec *re
   Uint32 dynamic_count= 0;
   regTabPtr->blobAttributeMask.clear();
   regTabPtr->notNullAttributeMask.clear();
-  bzero(regTabPtr->dynVarSizeMask, dyn_null_words<<2);
-  bzero(regTabPtr->dynFixSizeMask, dyn_null_words<<2);
+  bzero(regTabPtr->dynVarSizeMask[MM], dyn_null_words<<2);
+  bzero(regTabPtr->dynFixSizeMask[MM], dyn_null_words<<2);
 
   for(Uint32 i= 0; i<regTabPtr->m_no_of_attributes; i++)
   {
@@ -1477,7 +1477,7 @@ Dbtup::computeTableMetaData(Tablerec *re
           while(size_in_words-- > 0)
 	  {
 	    BitmaskImpl::set(dyn_null_words, 
-			     regTabPtr->dynFixSizeMask, null_pos++);
+			     regTabPtr->dynFixSizeMask[ind], null_pos++);
 	  }
         }
         else
@@ -1488,7 +1488,7 @@ Dbtup::computeTableMetaData(Tablerec *re
       treat_as_varsize:
         jam();
         off= dynvar_count++;
-	BitmaskImpl::set(dyn_null_words, regTabPtr->dynVarSizeMask, null_pos);
+	BitmaskImpl::set(dyn_null_words, regTabPtr->dynVarSizeMask[ind], null_pos);
       }
     }
     AttributeOffset::setOffset(attrDes2, off);
@@ -1651,8 +1651,8 @@ void Dbtup::setupDynDescriptorReferences
 {
   regTabPtr->dynTabDescriptor= dynDescr;
   Uint32* desc= &tableDescriptor[dynDescr].tabDescr;
-  regTabPtr->dynVarSizeMask= desc+offset[0];
-  regTabPtr->dynFixSizeMask= desc+offset[1];
+  regTabPtr->dynVarSizeMask[MM] = desc+offset[0];
+  regTabPtr->dynFixSizeMask[MM] = desc+offset[1];
 }
 
 Uint32
@@ -1838,8 +1838,8 @@ void Dbtup::releaseTabDescr(Tablerec* co
   {
     jam();
     regTabPtr->dynTabDescriptor= RNIL;
-    regTabPtr->dynVarSizeMask= NULL;
-    regTabPtr->dynFixSizeMask= NULL;
+    regTabPtr->dynVarSizeMask[MM]= NULL;
+    regTabPtr->dynFixSizeMask[MM]= NULL;
     releaseTabDescr(descriptor);
   }
 }
@@ -2438,8 +2438,15 @@ Dbtup::start_restore_lcp(Uint32 tableId,
   tabPtr.i= tableId;
   ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
   
-  tabPtr.p->m_dropTable.tabUserPtr= tabPtr.p->m_attributes[DD].m_no_of_fixsize;
-  tabPtr.p->m_dropTable.tabUserRef= tabPtr.p->m_attributes[DD].m_no_of_varsize;
+  ndbassert(tabPtr.p->m_attributes[DD].m_no_of_fixsize < (1 << 16));
+  ndbassert(tabPtr.p->m_attributes[DD].m_no_of_varsize < (1 << 16));
+  
+  Uint32 saveAttrCounts = 
+    (tabPtr.p->m_attributes[DD].m_no_of_fixsize << 16) |
+    (tabPtr.p->m_attributes[DD].m_no_of_varsize << 0);
+  
+  tabPtr.p->m_dropTable.tabUserPtr= saveAttrCounts;
+  tabPtr.p->m_dropTable.tabUserRef= (tabPtr.p->m_bits & Tablerec::TR_RowGCI)? 1 : 0;
   tabPtr.p->m_createTable.defValLocation = tabPtr.p->m_default_value_location;
   
   Uint32 *tabDesc = (Uint32*)(tableDescriptor+tabPtr.p->tabDescriptor);
@@ -2457,6 +2464,8 @@ Dbtup::start_restore_lcp(Uint32 tableId,
   tabPtr.p->m_no_of_disk_attributes = 0;
   tabPtr.p->m_attributes[DD].m_no_of_fixsize = 0;
   tabPtr.p->m_attributes[DD].m_no_of_varsize = 0;
+  /* Avoid LQH trampling GCI restored in raw format */
+  tabPtr.p->m_bits &= ~((Uint16) Tablerec::TR_RowGCI);
   tabPtr.p->m_default_value_location.setNull();
 }
 void
@@ -2468,9 +2477,12 @@ Dbtup::complete_restore_lcp(Signal* sign
   tabPtr.i= tableId;
   ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
   
-  tabPtr.p->m_attributes[DD].m_no_of_fixsize= tabPtr.p->m_dropTable.tabUserPtr;
-  tabPtr.p->m_attributes[DD].m_no_of_varsize= tabPtr.p->m_dropTable.tabUserRef;
-  
+  Uint32 restoreAttrCounts = tabPtr.p->m_dropTable.tabUserPtr;
+
+  tabPtr.p->m_attributes[DD].m_no_of_fixsize= restoreAttrCounts >> 16;
+  tabPtr.p->m_attributes[DD].m_no_of_varsize= restoreAttrCounts & 0xffff;
+  tabPtr.p->m_bits |= ((tabPtr.p->m_dropTable.tabUserRef & 1) ? Tablerec::TR_RowGCI : 0);
+
   tabPtr.p->m_no_of_disk_attributes = 
     tabPtr.p->m_attributes[DD].m_no_of_fixsize + 
     tabPtr.p->m_attributes[DD].m_no_of_varsize;

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp	2010-08-26 16:01:10 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp	2010-09-23 11:55:42 +0000
@@ -625,11 +625,15 @@ Dbtup::readFixedSizeTHZeroWordNULLable(U
 bool
 Dbtup::nullFlagCheck(KeyReqStruct *req_struct, Uint32  attrDes2)
 {
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
   Tablerec* const regTabPtr = req_struct->tablePtrP;
-  Uint32 *bits= req_struct->m_tuple_ptr->get_null_bits(regTabPtr);
+  Uint32 *bits= (ind) ? req_struct->m_disk_ptr->get_null_bits(regTabPtr, DD) :
+                        req_struct->m_tuple_ptr->get_null_bits(regTabPtr);
   Uint32 pos= AttributeOffset::getNullFlagPos(attrDes2);
   
-  return BitmaskImpl::get(regTabPtr->m_offsets[MM].m_null_words, bits, pos);
+  return BitmaskImpl::get(regTabPtr->m_offsets[ind].m_null_words, bits, pos);
 }
 
 bool
@@ -856,12 +860,17 @@ Dbtup::readDynFixedSizeExpandedNotNULL(U
     using different data base pointer and offset/lenght arrays.
   */
   thrjam(req_struct->jamBuffer);
-  char *src_ptr= req_struct->m_var_data[MM].m_dyn_data_ptr;
+  Uint32 attr_descriptor= req_struct->attr_descriptor;
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
+  char *src_ptr= req_struct->m_var_data[ind].m_dyn_data_ptr;
   Uint32 var_index= AttributeOffset::getOffset(attrDes2);
-  Uint16* off_arr= req_struct->m_var_data[MM].m_dyn_offset_arr_ptr;
+  Uint16* off_arr= req_struct->m_var_data[ind].m_dyn_offset_arr_ptr;
   Uint32 var_attr_pos= off_arr[var_index];
   Uint32 vsize_in_bytes=
-    AttributeDescriptor::getSizeInBytes(req_struct->attr_descriptor);
+    AttributeDescriptor::getSizeInBytes(attr_descriptor);
   return varsize_reader(outBuffer, req_struct, ahOut, attrDes2,
                         src_ptr + var_attr_pos, vsize_in_bytes);
 }
@@ -876,7 +885,12 @@ Dbtup::readDynFixedSizeExpandedNULLable(
     Check for NULL. In the expanded format, the bitmap is guaranteed
     to be stored in full length.
   */
-  Uint32 *src_ptr= (Uint32 *)(req_struct->m_var_data[MM].m_dyn_data_ptr);
+
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
+  Uint32 *src_ptr= (Uint32 *)(req_struct->m_var_data[ind].m_dyn_data_ptr);
   Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
   if(!BitmaskImpl::get((* src_ptr) & DYN_BM_LEN_MASK, src_ptr, pos))
   {
@@ -895,8 +909,13 @@ Dbtup::readDynFixedSizeShrunkenNotNULL(U
                                        AttributeHeader* ahOut,
                                        Uint32  attrDes2)
 {
-  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[MM].m_dyn_data_ptr);
-  Uint32 dyn_len= req_struct->m_var_data[MM].m_dyn_part_len;
+  Uint32 attr_descriptor= req_struct->attr_descriptor;
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
+  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[ind].m_dyn_data_ptr);
+  Uint32 dyn_len= req_struct->m_var_data[ind].m_dyn_part_len;
   ndbrequire(dyn_len != 0);
   Uint32 bm_len= (* bm_ptr) & DYN_BM_LEN_MASK; // In 32-bit words
   Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
@@ -916,7 +935,7 @@ Dbtup::readDynFixedSizeShrunkenNotNULL(U
   */
   thrjam(req_struct->jamBuffer);
   Tablerec * regTabPtr = req_struct->tablePtrP;
-  Uint32 *bm_mask_ptr= regTabPtr->dynFixSizeMask;
+  Uint32 *bm_mask_ptr= regTabPtr->dynFixSizeMask[ind];
   Uint32 bm_pos= AttributeOffset::getNullFlagOffset(attrDes2);
   Uint32 prevMask= (1 << (pos & 31)) - 1;
   Uint32 bit_count= BitmaskImpl::count_bits(prevMask & bm_mask_ptr[bm_pos] & bm_ptr[bm_pos]);
@@ -924,7 +943,6 @@ Dbtup::readDynFixedSizeShrunkenNotNULL(U
     bit_count+= BitmaskImpl::count_bits(bm_mask_ptr[i] & bm_ptr[i]);
 
   /* Now compute the data pointer from the row length. */
-  Uint32 attr_descriptor= req_struct->attr_descriptor;
   Uint32 vsize_in_bytes= AttributeDescriptor::getSizeInBytes(attr_descriptor);
   Uint32 vsize_in_words= (vsize_in_bytes+3)>>2;
   Uint32 *data_ptr= bm_ptr + dyn_len - bit_count - vsize_in_words;
@@ -948,8 +966,12 @@ Dbtup::readDynFixedSizeShrunkenNULLable(
                                         AttributeHeader* ahOut,
                                         Uint32  attrDes2)
 {
-  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[MM].m_dyn_data_ptr);
-  Uint32 dyn_len= req_struct->m_var_data[MM].m_dyn_part_len;
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
+  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[ind].m_dyn_data_ptr);
+  Uint32 dyn_len= req_struct->m_var_data[ind].m_dyn_part_len;
   Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
   /* Check for NULL (including the case of an empty bitmap). */
   if(dyn_len == 0 || dynCheckNull(dyn_len, (* bm_ptr) & DYN_BM_LEN_MASK,
@@ -1005,13 +1027,18 @@ Dbtup::readDynBigFixedSizeExpandedNotNUL
     using different data base pointer and offset/lenght arrays.
   */
   thrjam(req_struct->jamBuffer);
-  char *src_ptr= req_struct->m_var_data[MM].m_dyn_data_ptr;
+  Uint32 attr_descriptor= req_struct->attr_descriptor;
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
+  char *src_ptr= req_struct->m_var_data[ind].m_dyn_data_ptr;
   Uint32 var_index= AttributeOffset::getOffset(attrDes2);
-  Uint16* off_arr= req_struct->m_var_data[MM].m_dyn_offset_arr_ptr;
+  Uint16* off_arr= req_struct->m_var_data[ind].m_dyn_offset_arr_ptr;
   Uint32 var_attr_pos= off_arr[var_index];
   Uint32 vsize_in_bytes=
-    AttributeDescriptor::getSizeInBytes(req_struct->attr_descriptor);
-  Uint32 idx= req_struct->m_var_data[MM].m_dyn_len_offset;
+    AttributeDescriptor::getSizeInBytes(attr_descriptor);
+  Uint32 idx= req_struct->m_var_data[ind].m_dyn_len_offset;
   ndbrequire(vsize_in_bytes <= off_arr[var_index+idx] - var_attr_pos);
   return varsize_reader(outBuffer, req_struct, ahOut, attrDes2,
                         src_ptr + var_attr_pos, vsize_in_bytes);
@@ -1027,7 +1054,12 @@ Dbtup::readDynBigFixedSizeExpandedNULLab
     Check for NULL. In the expanded format, the bitmap is guaranteed
     to be stored in full length.
   */
-  Uint32 *src_ptr= (Uint32 *)(req_struct->m_var_data[MM].m_dyn_data_ptr);
+
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
+  Uint32 *src_ptr= (Uint32 *)(req_struct->m_var_data[ind].m_dyn_data_ptr);
   Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
   if(!BitmaskImpl::get((* src_ptr) & DYN_BM_LEN_MASK, src_ptr, pos))
   {
@@ -1046,8 +1078,13 @@ Dbtup::readDynBigFixedSizeShrunkenNotNUL
                                           AttributeHeader* ahOut,
                                           Uint32  attrDes2)
 {
-  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[MM].m_dyn_data_ptr);
-  Uint32 dyn_len= req_struct->m_var_data[MM].m_dyn_part_len;
+  Uint32 attr_descriptor= req_struct->attr_descriptor;
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
+  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[ind].m_dyn_data_ptr);
+  Uint32 dyn_len= req_struct->m_var_data[ind].m_dyn_part_len;
   ndbrequire(dyn_len!=0);
   Uint32 bm_len = (* bm_ptr) & DYN_BM_LEN_MASK;
   Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
@@ -1062,7 +1099,7 @@ Dbtup::readDynBigFixedSizeShrunkenNotNUL
     any trailing non-bitmap bytes to save a few conditionals.
   */
   Tablerec * regTabPtr = req_struct->tablePtrP;
-  Uint32 *bm_mask_ptr= regTabPtr->dynVarSizeMask;
+  Uint32 *bm_mask_ptr= regTabPtr->dynVarSizeMask[ind];
   Uint32 bm_pos= AttributeOffset::getNullFlagOffset(attrDes2);
   Uint32 prevMask= (1 << (pos & 31)) - 1;
   Uint32 bit_count= BitmaskImpl::count_bits(prevMask & bm_mask_ptr[bm_pos] & bm_ptr[bm_pos]);
@@ -1070,7 +1107,6 @@ Dbtup::readDynBigFixedSizeShrunkenNotNUL
     bit_count+= BitmaskImpl::count_bits(bm_mask_ptr[i] & bm_ptr[i]);
 
   /* Now find the data pointer and length from the offset array. */
-  Uint32 attr_descriptor= req_struct->attr_descriptor;
   Uint32 vsize_in_bytes= AttributeDescriptor::getSizeInBytes(attr_descriptor);
   //Uint16 *offset_array= req_struct->m_var_data[MM].m_dyn_offset_arr_ptr;
   Uint16* offset_array = (Uint16*)(bm_ptr + bm_len);
@@ -1092,8 +1128,12 @@ Dbtup::readDynBigFixedSizeShrunkenNULLab
                                            AttributeHeader* ahOut,
                                            Uint32  attrDes2)
 {
-  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[MM].m_dyn_data_ptr);
-  Uint32 dyn_len= req_struct->m_var_data[MM].m_dyn_part_len;
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
+  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[ind].m_dyn_data_ptr);
+  Uint32 dyn_len= req_struct->m_var_data[ind].m_dyn_part_len;
   /* Check for NULL (including the case of an empty bitmap). */
   Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
   if(dyn_len == 0 || dynCheckNull(dyn_len, (* bm_ptr) & DYN_BM_LEN_MASK,
@@ -1140,12 +1180,17 @@ Dbtup::readDynBitsShrunkenNotNULL(Uint8*
                                   AttributeHeader* ahOut,
                                   Uint32 attrDes2)
 {
-  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[MM].m_dyn_data_ptr);
-  Uint32 dyn_len= req_struct->m_var_data[MM].m_dyn_part_len;
+  Uint32 attr_descriptor= req_struct->attr_descriptor;
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
+  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[ind].m_dyn_data_ptr);
+  Uint32 dyn_len= req_struct->m_var_data[ind].m_dyn_part_len;
   ndbrequire(dyn_len != 0);
   Uint32 bm_len = (* bm_ptr) & DYN_BM_LEN_MASK;
   Uint32 bitCount =
-    AttributeDescriptor::getArraySize(req_struct->attr_descriptor);
+    AttributeDescriptor::getArraySize(attr_descriptor);
   Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
   /* Make sure we have sufficient data in the row. */
   ndbrequire((pos>>5)<bm_len);
@@ -1164,8 +1209,12 @@ Dbtup::readDynBitsShrunkenNULLable(Uint8
                                    AttributeHeader* ahOut,
                                    Uint32 attrDes2)
 {
-  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[MM].m_dyn_data_ptr);
-  Uint32 dyn_len= req_struct->m_var_data[MM].m_dyn_part_len;
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
+  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[ind].m_dyn_data_ptr);
+  Uint32 dyn_len= req_struct->m_var_data[ind].m_dyn_part_len;
   /* Check for NULL (including the case of an empty bitmap). */
   Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
   if(dyn_len == 0 || dynCheckNull(dyn_len, (* bm_ptr) & DYN_BM_LEN_MASK,
@@ -1185,10 +1234,15 @@ Dbtup::readDynBitsExpandedNotNULL(Uint8*
                                   AttributeHeader* ahOut,
                                   Uint32 attrDes2)
 {
-  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[MM].m_dyn_data_ptr);
+  Uint32 attr_descriptor= req_struct->attr_descriptor;
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
+  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[ind].m_dyn_data_ptr);
   Uint32 bm_len = (* bm_ptr) & DYN_BM_LEN_MASK;
   Uint32 bitCount =
-    AttributeDescriptor::getArraySize(req_struct->attr_descriptor);
+    AttributeDescriptor::getArraySize(attr_descriptor);
   Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
   /* The bit data is stored just before the NULL bit. */
   ndbassert(pos>bitCount);
@@ -1205,7 +1259,12 @@ Dbtup::readDynBitsExpandedNULLable(Uint8
                                    AttributeHeader* ahOut,
                                    Uint32 attrDes2)
 {
-  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[MM].m_dyn_data_ptr);
+
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
+  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[ind].m_dyn_data_ptr);
   Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
   if(!BitmaskImpl::get((* bm_ptr) & DYN_BM_LEN_MASK, bm_ptr, pos))
   {
@@ -1258,11 +1317,15 @@ Dbtup::readDynVarSizeExpandedNotNULL(Uin
     using different data base pointer and offset/lenght arrays.
   */
   thrjam(req_struct->jamBuffer);
-  char *src_ptr= req_struct->m_var_data[MM].m_dyn_data_ptr;
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
+  char *src_ptr= req_struct->m_var_data[ind].m_dyn_data_ptr;
   Uint32 var_index= AttributeOffset::getOffset(attrDes2);
-  Uint16* off_arr= req_struct->m_var_data[MM].m_dyn_offset_arr_ptr;
+  Uint16* off_arr= req_struct->m_var_data[ind].m_dyn_offset_arr_ptr;
   Uint32 var_attr_pos= off_arr[var_index];
-  Uint32 idx= req_struct->m_var_data[MM].m_dyn_len_offset;
+  Uint32 idx= req_struct->m_var_data[ind].m_dyn_len_offset;
   Uint32 vsize_in_bytes= off_arr[var_index+idx] - var_attr_pos;
   return varsize_reader(outBuffer, req_struct, ahOut, attrDes2,
                         src_ptr + var_attr_pos, vsize_in_bytes);
@@ -1278,7 +1341,12 @@ Dbtup::readDynVarSizeExpandedNULLable(Ui
     Check for NULL. In the expanded format, the bitmap is guaranteed
     to be stored in full length.
   */
-  Uint32 *src_ptr= (Uint32 *)(req_struct->m_var_data[MM].m_dyn_data_ptr);
+
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
+  Uint32 *src_ptr= (Uint32 *)(req_struct->m_var_data[ind].m_dyn_data_ptr);
   Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
   if(!BitmaskImpl::get((* src_ptr) & DYN_BM_LEN_MASK, src_ptr, pos))
   {
@@ -1297,8 +1365,12 @@ Dbtup::readDynVarSizeShrunkenNotNULL(Uin
                                      AttributeHeader* ahOut,
                                      Uint32  attrDes2)
 {
-  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[MM].m_dyn_data_ptr);
-  Uint32 dyn_len= req_struct->m_var_data[MM].m_dyn_part_len;
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
+  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[ind].m_dyn_data_ptr);
+  Uint32 dyn_len= req_struct->m_var_data[ind].m_dyn_part_len;
   ndbrequire(dyn_len!=0);
   Uint32 bm_len = (* bm_ptr) & DYN_BM_LEN_MASK;
   Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
@@ -1313,7 +1385,7 @@ Dbtup::readDynVarSizeShrunkenNotNULL(Uin
     any trailing non-bitmap bytes to save a few conditionals.
   */
   Tablerec * regTabPtr = req_struct->tablePtrP;
-  Uint32 *bm_mask_ptr= regTabPtr->dynVarSizeMask;
+  Uint32 *bm_mask_ptr= regTabPtr->dynVarSizeMask[ind];
   Uint32 bm_pos= AttributeOffset::getNullFlagOffset(attrDes2);
   Uint32 prevMask= (1 << (pos & 31)) - 1;
   Uint32 bit_count= BitmaskImpl::count_bits(prevMask & bm_mask_ptr[bm_pos] & bm_ptr[bm_pos]);
@@ -1341,8 +1413,12 @@ Dbtup::readDynVarSizeShrunkenNULLable(Ui
                                       AttributeHeader* ahOut,
                                       Uint32  attrDes2)
 {
-  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[MM].m_dyn_data_ptr);
-  Uint32 dyn_len= req_struct->m_var_data[MM].m_dyn_part_len;
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
+  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[ind].m_dyn_data_ptr);
+  Uint32 dyn_len= req_struct->m_var_data[ind].m_dyn_part_len;
   /* Check for NULL (including the case of an empty bitmap). */
   Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
   if(dyn_len == 0 || dynCheckNull(dyn_len, (* bm_ptr) & DYN_BM_LEN_MASK,
@@ -2033,10 +2109,14 @@ Dbtup::updateDynFixedSizeNotNULL(Uint32*
                                  Uint32  attrDes2)
 {
   Uint32 attrDescriptor= req_struct->attr_descriptor;
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
   Uint32 pos= AttributeOffset::getNullFlagPos(attrDes2);
   Uint32 nullbits= AttributeDescriptor::getSizeInWords(attrDescriptor);
-  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[MM].m_dyn_data_ptr);
 
+  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[ind].m_dyn_data_ptr);
   ndbassert(nullbits && nullbits <= 16);
 
   /*
@@ -2064,10 +2144,10 @@ Dbtup::updateDynFixedSizeNotNULL(Uint32*
 
   /* Compute the data and offset location and write the actual data. */
   Uint32 off_index= AttributeOffset::getOffset(attrDes2);
-  Uint16* off_arr= req_struct->m_var_data[MM].m_dyn_offset_arr_ptr;
+  Uint16* off_arr= req_struct->m_var_data[ind].m_dyn_offset_arr_ptr;
   Uint32 offset= off_arr[off_index];
-  Uint32 *dst_ptr= (Uint32 *)(req_struct->m_var_data[MM].m_dyn_data_ptr);
-  Uint32 check_offset= req_struct->m_var_data[MM].m_max_dyn_offset;
+  Uint32 *dst_ptr= (Uint32 *)(req_struct->m_var_data[ind].m_dyn_data_ptr);
+  Uint32 check_offset= req_struct->m_var_data[ind].m_max_dyn_offset;
 
   ndbassert((offset&3)==0);
   ndbassert((check_offset&3)==0);
@@ -2088,9 +2168,13 @@ Dbtup::updateDynFixedSizeNULLable(Uint32
     return updateDynFixedSizeNotNULL(inBuffer, req_struct, attrDes2);
 
   Uint32 attrDescriptor= req_struct->attr_descriptor;
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
   Uint32 pos= AttributeOffset::getNullFlagPos(attrDes2);
   Uint32 nullbits= AttributeDescriptor::getSizeInWords(attrDescriptor);
-  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[MM].m_dyn_data_ptr);
+  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[ind].m_dyn_data_ptr);
 
   ndbassert(nullbits && nullbits <= 16);
 
@@ -2129,17 +2213,21 @@ Dbtup::updateDynBigFixedSizeNotNULL(Uint
                                   Uint32  attrDes2)
 {
   Uint32 attrDescriptor= req_struct->attr_descriptor;
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
   Uint32 pos= AttributeOffset::getNullFlagPos(attrDes2);
-  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[MM].m_dyn_data_ptr);
+  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[ind].m_dyn_data_ptr);
   
   jam();
   BitmaskImpl::set((* bm_ptr) & DYN_BM_LEN_MASK, bm_ptr, pos);
   /* Compute the data and offset location and write the actual data. */
   Uint32 off_index= AttributeOffset::getOffset(attrDes2);
   Uint32 noOfWords= AttributeDescriptor::getSizeInWords(attrDescriptor);
-  Uint16* off_arr= req_struct->m_var_data[MM].m_dyn_offset_arr_ptr;
+  Uint16* off_arr= req_struct->m_var_data[ind].m_dyn_offset_arr_ptr;
   Uint32 offset= off_arr[off_index];
-  Uint32 idx= req_struct->m_var_data[MM].m_dyn_len_offset;
+  Uint32 idx= req_struct->m_var_data[ind].m_dyn_len_offset;
 
   ndbassert((offset&3)==0);
   bool res= fixsize_updater(inBuffer,
@@ -2147,7 +2235,7 @@ Dbtup::updateDynBigFixedSizeNotNULL(Uint
                             attrDes2,
                             bm_ptr,
                             offset>>2,
-                            req_struct->m_var_data[MM].m_max_dyn_offset);
+                            req_struct->m_var_data[ind].m_max_dyn_offset);
   /* Set the correct size for fixsize data. */
   off_arr[off_index+idx]= offset+(noOfWords<<2);
   return res;
@@ -2158,10 +2246,14 @@ Dbtup::updateDynBigFixedSizeNULLable(Uin
                                    KeyReqStruct *req_struct,
                                    Uint32  attrDes2)
 {
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
   AttributeHeader ahIn(inBuffer[req_struct->in_buf_index]);
   Uint32 nullIndicator= ahIn.isNULL();
   Uint32 pos= AttributeOffset::getNullFlagPos(attrDes2);
-  Uint32 *bm_ptr= (Uint32*)req_struct->m_var_data[MM].m_dyn_data_ptr;
+  Uint32 *bm_ptr= (Uint32*)req_struct->m_var_data[ind].m_dyn_data_ptr;
   
   if (!nullIndicator)
     return updateDynBigFixedSizeNotNULL(inBuffer, req_struct, attrDes2);
@@ -2185,9 +2277,13 @@ Dbtup::updateDynBitsNotNULL(Uint32* inBu
                             Uint32  attrDes2)
 {
   Uint32 attrDescriptor= req_struct->attr_descriptor;
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
   Uint32 pos= AttributeOffset::getNullFlagPos(attrDes2);
   Uint32 bitCount = AttributeDescriptor::getArraySize(attrDescriptor);
-  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[MM].m_dyn_data_ptr);
+  Uint32 *bm_ptr= (Uint32 *)(req_struct->m_var_data[ind].m_dyn_data_ptr);
   Uint32 bm_len = (* bm_ptr) & DYN_BM_LEN_MASK;
   jam();
   BitmaskImpl::set(bm_len, bm_ptr, pos);
@@ -2223,6 +2319,10 @@ Dbtup::updateDynBitsNULLable(Uint32* inB
                              KeyReqStruct *req_struct,
                              Uint32  attrDes2)
 {
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
   AttributeHeader ahIn(inBuffer[req_struct->in_buf_index]);
   Uint32 nullIndicator= ahIn.isNULL();
 
@@ -2230,7 +2330,7 @@ Dbtup::updateDynBitsNULLable(Uint32* inB
     return updateDynBitsNotNULL(inBuffer, req_struct, attrDes2);
 
   Uint32 pos= AttributeOffset::getNullFlagPos(attrDes2);
-  Uint32 *bm_ptr= (Uint32*)req_struct->m_var_data[MM].m_dyn_data_ptr;
+  Uint32 *bm_ptr= (Uint32*)req_struct->m_var_data[ind].m_dyn_data_ptr;
 
   Uint32 newIndex= req_struct->in_buf_index + 1;
   if (newIndex <= req_struct->in_buf_len) {
@@ -2250,23 +2350,27 @@ Dbtup::updateDynVarSizeNotNULL(Uint32* i
                                KeyReqStruct *req_struct,
                                Uint32  attrDes2)
 {
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
   Uint32 pos= AttributeOffset::getNullFlagPos(attrDes2);
-  Uint32 *bm_ptr= (Uint32*)req_struct->m_var_data[MM].m_dyn_data_ptr;
+  Uint32 *bm_ptr= (Uint32*)req_struct->m_var_data[ind].m_dyn_data_ptr;
   
   jam();
   BitmaskImpl::set((* bm_ptr) & DYN_BM_LEN_MASK, bm_ptr, pos);
   /* Compute the data and offset location and write the actual data. */
   Uint32 off_index= AttributeOffset::getOffset(attrDes2);
-  Uint16* off_arr= req_struct->m_var_data[MM].m_dyn_offset_arr_ptr;
+  Uint16* off_arr= req_struct->m_var_data[ind].m_dyn_offset_arr_ptr;
   Uint32 offset= off_arr[off_index];
-  Uint32 idx= req_struct->m_var_data[MM].m_dyn_len_offset;
+  Uint32 idx= req_struct->m_var_data[ind].m_dyn_len_offset;
 
   bool res= varsize_updater(inBuffer,
                             req_struct,
                             (char*)bm_ptr,
                             offset,
                             &(off_arr[off_index+idx]),
-                            req_struct->m_var_data[MM].m_max_dyn_offset);
+                            req_struct->m_var_data[ind].m_max_dyn_offset);
   return res;
 }
 
@@ -2275,10 +2379,14 @@ Dbtup::updateDynVarSizeNULLable(Uint32* 
                                 KeyReqStruct *req_struct,
                                 Uint32  attrDes2)
 {
+  Uint32 ind =
+    (AttributeDescriptor::getDiskBased(req_struct->attr_descriptor)) ?
+    Uint32(DD) : Uint32(MM);
+
   AttributeHeader ahIn(inBuffer[req_struct->in_buf_index]);
   Uint32 nullIndicator= ahIn.isNULL();
   Uint32 pos= AttributeOffset::getNullFlagPos(attrDes2);
-  Uint32 *bm_ptr= (Uint32*)req_struct->m_var_data[MM].m_dyn_data_ptr;
+  Uint32 *bm_ptr= (Uint32*)req_struct->m_var_data[ind].m_dyn_data_ptr;
   
   if (!nullIndicator)
     return updateDynVarSizeNotNULL(inBuffer, req_struct, attrDes2);

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp	2009-10-20 16:10:06 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp	2010-09-07 09:54:47 +0000
@@ -86,11 +86,14 @@ Dbtup::execACC_SCANREQ(Signal* signal)
     if ((tablePtr.p->m_attributes[mm].m_no_of_varsize +
          tablePtr.p->m_attributes[mm].m_no_of_dynamic) > 0) 
     {
-      bits |= ScanOp::SCAN_VS;
-	
-      // disk pages have fixed page format
-      ndbrequire(! (bits & ScanOp::SCAN_DD));
+      if (bits & ScanOp::SCAN_DD)
+      {
+        // only dd scan varsize pages
+        // mm always has a fixed part
+        bits |= ScanOp::SCAN_VS;
+      }
     }
+
     if (! AccScanReq::getReadCommittedFlag(req->requestInfo)) 
     {
       if (AccScanReq::getLockMode(req->requestInfo) == 0)
@@ -124,6 +127,12 @@ Dbtup::execACC_SCANREQ(Signal* signal)
       ndbrequire((bits & ScanOp::SCAN_DD) == 0);
       ndbrequire((bits & ScanOp::SCAN_LOCK) == 0);
     }
+
+    if (bits & ScanOp::SCAN_VS)
+    {
+      ndbrequire((bits & ScanOp::SCAN_NR) == 0);
+      ndbrequire((bits & ScanOp::SCAN_LCP) == 0);
+    }
     
     // set up scan op
     ScanOp& scan = *scanPtr.p;
@@ -619,7 +628,7 @@ Dbtup::scanFirst(Signal*, ScanOpPtr scan
     key.m_page_no = ext->m_first_page_no;
     pos.m_get = ScanPos::Get_page_dd;
   }
-  key.m_page_idx = 0;
+  key.m_page_idx = ((bits & ScanOp::SCAN_VS) == 0) ? 0 : 1;
   // let scanNext() do the work
   scan.m_state = ScanOp::Next;
 }
@@ -652,7 +661,9 @@ Dbtup::scanNext(Signal* signal, ScanOpPt
   const bool lcp = (bits & ScanOp::SCAN_LCP);
   
   Uint32 lcp_list = fragPtr.p->m_lcp_keep_list;
-  Uint32 size = table.m_offsets[mm].m_fix_header_size;
+  const Uint32 size = ((bits & ScanOp::SCAN_VS) == 0) ?
+    table.m_offsets[mm].m_fix_header_size : 1;
+  const Uint32 first = ((bits & ScanOp::SCAN_VS) == 0) ? 0 : 1;
 
   if (lcp && lcp_list != RNIL)
   {
@@ -666,12 +677,10 @@ Dbtup::scanNext(Signal* signal, ScanOpPt
 
   switch(pos.m_get){
   case ScanPos::Get_next_tuple:
-  case ScanPos::Get_next_tuple_fs:
     jam();
     key.m_page_idx += size;
     // fall through
   case ScanPos::Get_tuple:
-  case ScanPos::Get_tuple_fs:
     jam();
     /**
      * We need to refetch page after timeslice
@@ -729,7 +738,7 @@ Dbtup::scanNext(Signal* signal, ScanOpPt
           return true;
         }
     cont:
-        key.m_page_idx = 0;
+        key.m_page_idx = first;
         pos.m_get = ScanPos::Get_page_mm;
         // clear cached value
         pos.m_realpid_mm = RNIL;
@@ -791,7 +800,7 @@ Dbtup::scanNext(Signal* signal, ScanOpPt
             key.m_page_no = ext->m_first_page_no;
           }
         }
-        key.m_page_idx = 0;
+        key.m_page_idx = first;
         pos.m_get = ScanPos::Get_page_dd;
         /*
           read ahead for scan in disk order
@@ -906,23 +915,22 @@ Dbtup::scanNext(Signal* signal, ScanOpPt
       // get tuple
       // move to next tuple
     case ScanPos::Get_next_tuple:
-    case ScanPos::Get_next_tuple_fs:
       // move to next fixed size tuple
       jam();
       {
         key.m_page_idx += size;
-        pos.m_get = ScanPos::Get_tuple_fs;
+        pos.m_get = ScanPos::Get_tuple;
       }
       /*FALLTHRU*/
     case ScanPos::Get_tuple:
-    case ScanPos::Get_tuple_fs:
       // get fixed size tuple
       jam();
+      if ((bits & ScanOp::SCAN_VS) == 0)
       {
         Fix_page* page = (Fix_page*)pos.m_page;
         if (key.m_page_idx + size <= Fix_page::DATA_WORDS) 
 	{
-	  pos.m_get = ScanPos::Get_next_tuple_fs;
+	  pos.m_get = ScanPos::Get_next_tuple;
 #ifdef VM_TRACE
           if (! (bits & ScanOp::SCAN_DD))
           {
@@ -977,6 +985,29 @@ Dbtup::scanNext(Signal* signal, ScanOpPt
           pos.m_get = ScanPos::Get_next_page;
         }
       }
+      else
+      {
+        jam();
+        Var_page * page = (Var_page*)pos.m_page;
+        if (key.m_page_idx < page->high_index)
+        {
+          jam();
+          pos.m_get = ScanPos::Get_next_tuple;
+          if (!page->is_free(key.m_page_idx))
+          {
+            th = (Tuple_header*)page->get_ptr(key.m_page_idx);
+            thbits = th->m_header_bits;
+            goto found_tuple;
+          }
+        }
+        else
+        {
+          jam();
+          // no more tuples on this page
+          pos.m_get = ScanPos::Get_next_page;
+          break;
+        }
+      }
       break; // incr loop count
   found_tuple:
       // found possible tuple to return

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp	2009-10-08 11:41:21 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp	2010-09-07 09:54:47 +0000
@@ -255,6 +255,11 @@ struct Tup_varsize_page
   Uint32 get_entry_chain(Uint32 page_idx) const {
     return get_index_word(page_idx) & CHAIN;
   }
+
+  bool is_free(Uint32 page_idx) const
+  {
+    return ((get_index_word(page_idx) & FREE) != 0) ? true : false;
+  }
 };
 
 NdbOut& operator<< (NdbOut& out, const Tup_varsize_page& page);

=== modified file 'storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp'
--- a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp	2010-08-26 16:01:10 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp	2010-09-23 11:55:42 +0000
@@ -1757,6 +1757,7 @@ Ndbcntr::wait_sp_rep(Signal* signal)
    * Check if we should allow someone to start...
    */
   Uint32 node = c_start.m_starting.find(0);
+  ndbrequire(node < NDB_ARRAY_SIZE(c_start.m_wait_sp));
   Uint32 min = c_start.m_wait_sp[node];
   for (; node != NdbNodeBitmask::NotFound;
        node = c_start.m_starting.find(node + 1))
@@ -2258,7 +2259,7 @@ Ndbcntr::createDDObjects(Signal * signal
 
     DictFilegroupInfo::Filegroup fg; fg.init();
     BaseString::snprintf(fg.FilegroupName, sizeof(fg.FilegroupName),
-                         entry->name);
+                         "%s", entry->name);
     fg.FilegroupType = entry->type;
     if (entry->type == DictTabInfo::LogfileGroup)
     {
@@ -2303,7 +2304,7 @@ Ndbcntr::createDDObjects(Signal * signal
     Uint32 propPage[256];
     LinearWriter w(propPage, 256);
     DictFilegroupInfo::File f; f.init();
-    BaseString::snprintf(f.FileName, sizeof(f.FileName), entry->name);
+    BaseString::snprintf(f.FileName, sizeof(f.FileName), "%s", entry->name);
     f.FileType = entry->type;
     f.FilegroupId = RNIL;
     f.FilegroupVersion = RNIL;

=== modified file 'storage/ndb/src/kernel/blocks/ndbfs/AsyncIoThread.cpp'
--- a/storage/ndb/src/kernel/blocks/ndbfs/AsyncIoThread.cpp	2009-12-14 22:14:34 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbfs/AsyncIoThread.cpp	2010-09-20 13:09:18 +0000
@@ -28,6 +28,10 @@
 #include <signaldata/FsReadWriteReq.hpp>
 #include <Configuration.hpp>
 #include "Ndbfs.hpp"
+#include <NdbSleep.h>
+
+#include <EventLogger.hpp>
+extern EventLogger * g_eventLogger;
 
 AsyncIoThread::AsyncIoThread(class Ndbfs& fs, AsyncFile* file)
   : m_fs(fs)
@@ -202,6 +206,22 @@ AsyncIoThread::run()
     case Request::buildindx:
       buildIndxReq(request);
       break;
+    case Request::suspend:
+      if (request->par.suspend.milliseconds)
+      {
+        g_eventLogger->debug("Suspend %s %u ms",
+                             file->theFileName.c_str(),
+                             request->par.suspend.milliseconds);
+        NdbSleep_MilliSleep(request->par.suspend.milliseconds);
+        continue;
+      }
+      else
+      {
+        g_eventLogger->debug("Suspend %s",
+                             file->theFileName.c_str());
+        theStartFlag = false;
+        return;
+      }
     default:
       DEBUG(ndbout_c("Invalid Request"));
       abort();

=== modified file 'storage/ndb/src/kernel/blocks/ndbfs/AsyncIoThread.hpp'
--- a/storage/ndb/src/kernel/blocks/ndbfs/AsyncIoThread.hpp	2009-12-14 22:14:34 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbfs/AsyncIoThread.hpp	2010-09-20 13:09:18 +0000
@@ -64,7 +64,8 @@ public:
     rmrf,
     readPartial,
     allocmem,
-    buildindx
+    buildindx,
+    suspend
   };
   Action action;
   union {
@@ -97,6 +98,9 @@ public:
     struct {
       struct mt_BuildIndxReq m_req;
     } build;
+    struct {
+      Uint32 milliseconds;
+    } suspend;
   } par;
   int error;
 

=== modified file 'storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp'
--- a/storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp	2010-08-23 08:46:34 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp	2010-09-20 13:09:18 +0000
@@ -83,6 +83,7 @@ Ndbfs::Ndbfs(Block_context& ctx) :
   addRecSignal(GSN_SEND_PACKED, &Ndbfs::execSEND_PACKED, true);
   addRecSignal(GSN_BUILD_INDX_IMPL_REQ, &Ndbfs::execBUILD_INDX_IMPL_REQ);
    // Set send signals
+  addRecSignal(GSN_FSSUSPENDORD, &Ndbfs::execFSSUSPENDORD);
 
   theRequestPool = new Pool<Request>;
 }
@@ -790,6 +791,34 @@ Ndbfs::execFSSYNCREQ(Signal * signal)
   ndbrequire(forward(openFile,request));
 }
 
+/*
+ * PR0: File Pointer DR0: User reference DR1: User Pointer
+ */
+void
+Ndbfs::execFSSUSPENDORD(Signal * signal)
+{
+  jamEntry();
+  Uint16 filePointer =  (Uint16)signal->theData[0];
+  Uint32 millis = signal->theData[1];
+  AsyncFile* openFile = theOpenFiles.find(filePointer);
+
+  if (openFile == NULL)
+  {
+    jam(); //file not open
+    return;
+  }
+
+  Request *request = theRequestPool->get();
+  request->error = 0;
+  request->action = Request::suspend;
+  request->set(0, 0, filePointer);
+  request->file = openFile;
+  request->theTrace = signal->getTrace();
+  request->par.suspend.milliseconds = millis;
+
+  ndbrequire(forward(openFile,request));
+}
+
 void 
 Ndbfs::execFSAPPENDREQ(Signal * signal)
 {
@@ -1133,6 +1162,7 @@ Ndbfs::report(Request * request, Signal*
     }
     
     case Request:: end: {
+    case Request:: suspend:
       // Report nothing
       break;
     }
@@ -1227,6 +1257,7 @@ Ndbfs::report(Request * request, Signal*
       break;
     }
     case Request:: end: {
+    case Request:: suspend:
       // Report nothing
       break;
     }

=== modified file 'storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.hpp'
--- a/storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.hpp	2009-12-14 22:14:34 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.hpp	2010-09-20 13:09:18 +0000
@@ -59,6 +59,7 @@ protected:
   void execALLOC_MEM_REQ(Signal* signal);
   void execSEND_PACKED(Signal*);
   void execBUILD_INDX_IMPL_REQ(Signal* signal);
+  void execFSSUSPENDORD(Signal*);
 
   bool scanningInProgress;
   Uint16 newId();
@@ -129,6 +130,7 @@ protected:
   void execSTTOR(Signal* signal);
   void execALLOC_MEM_REQ(Signal*);
   void execSEND_PACKED(Signal*);
+  void execFSSUSPENDORD(Signal*);
 
 private:
   // Declared but not defined

=== modified file 'storage/ndb/src/kernel/blocks/ndbfs/VoidFs.cpp'
--- a/storage/ndb/src/kernel/blocks/ndbfs/VoidFs.cpp	2010-08-20 11:10:25 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbfs/VoidFs.cpp	2010-09-20 13:09:18 +0000
@@ -53,7 +53,7 @@ VoidFs::VoidFs(Block_context & ctx) :
   addRecSignal(GSN_FSSYNCREQ, &VoidFs::execFSSYNCREQ, true);
   addRecSignal(GSN_FSAPPENDREQ, &VoidFs::execFSAPPENDREQ, true);
   addRecSignal(GSN_FSREMOVEREQ, &VoidFs::execFSREMOVEREQ, true);
-
+  addRecSignal(GSN_FSSUSPENDORD, &VoidFs::execFSSUSPENDORD, true);
    // Set send signals
 }
 
@@ -213,6 +213,15 @@ VoidFs::execFSAPPENDREQ(Signal * signal)
   sendSignal(userRef, GSN_FSAPPENDCONF, signal, 2, JBB);
 }
 
+/*
+ * PR0: File Pointer DR0: User reference DR1: User Pointer
+ */
+void
+VoidFs::execFSSUSPENDORD(Signal * signal)
+{
+  jamEntry();
+}
+
 void
 VoidFs::execDUMP_STATE_ORD(Signal* signal)
 {

=== modified file 'storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp'
--- a/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp	2010-06-22 05:24:36 +0000
+++ b/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp	2010-09-23 11:55:42 +0000
@@ -33,7 +33,6 @@
 #include <signaldata/FailRep.hpp>
 #include <signaldata/AllocNodeId.hpp>
 
-#include <SafeCounter.hpp>
 #include <RequestTracker.hpp>
 #include <signaldata/StopReq.hpp>
 

=== modified file 'storage/ndb/src/kernel/blocks/suma/Suma.cpp'
--- a/storage/ndb/src/kernel/blocks/suma/Suma.cpp	2010-08-26 12:41:30 +0000
+++ b/storage/ndb/src/kernel/blocks/suma/Suma.cpp	2010-09-06 08:20:33 +0000
@@ -2771,6 +2771,15 @@ Suma::execSUB_START_REQ(Signal* signal){
                     senderRef, senderData, SubStartRef::NoSuchSubscription);
     return;
   }
+
+  if (ERROR_INSERTED(13046))
+  {
+    jam();
+    CLEAR_ERROR_INSERT_VALUE;
+    sendSubStartRef(signal,
+                    senderRef, senderData, SubStartRef::NoSuchSubscription);
+    return;
+  }
   
   switch(subPtr.p->m_state){
   case Subscription::UNDEFINED:

=== modified file 'storage/ndb/src/kernel/error/ErrorReporter.cpp'
--- a/storage/ndb/src/kernel/error/ErrorReporter.cpp	2010-08-20 11:10:25 +0000
+++ b/storage/ndb/src/kernel/error/ErrorReporter.cpp	2010-09-22 13:28:20 +0000
@@ -111,6 +111,8 @@ ErrorReporter::get_trace_no(){
   return traceFileNo;
 }
 
+// Using my_progname without including all of mysys
+extern "C" const char* my_progname;
 
 void
 ErrorReporter::formatMessage(int thr_no,

=== modified file 'storage/ndb/src/kernel/main.cpp'
--- a/storage/ndb/src/kernel/main.cpp	2010-08-28 09:37:09 +0000
+++ b/storage/ndb/src/kernel/main.cpp	2010-09-22 13:28:20 +0000
@@ -95,7 +95,7 @@ const char *load_default_groups[]= { "my
 
 static void short_usage_sub(void)
 {
-  ndb_short_usage_sub(my_progname, NULL);
+  ndb_short_usage_sub(NULL);
   ndb_service_print_options("ndbd");
 }
 
@@ -133,14 +133,15 @@ real_main(int argc, char** argv)
   // Turn on max loglevel for startup messages
   g_eventLogger->m_logLevel.setLogLevel(LogLevel::llStartUp, 15);
 
-  ndb_opt_set_usage_funcs("ndbd", short_usage_sub, usage);
+  ndb_opt_set_usage_funcs(short_usage_sub, usage);
   load_defaults("my",load_default_groups,&argc,&argv);
 
 #ifndef DBUG_OFF
   opt_debug= "d:t:O,/tmp/ndbd.trace";
 #endif
 
-  // Save the original arguments for angel
+  // Save the original program name and arguments for angel
+  const char* progname = argv[0];
   BaseString original_args;
   for (int i = 0; i < argc; i++)
     original_args.appfmt("%s ", argv[i]);
@@ -186,7 +187,8 @@ real_main(int argc, char** argv)
              opt_allocated_nodeid);
   }
 
-  angel_run(original_args,
+  angel_run(progname,
+            original_args,
             opt_ndb_connectstring,
             opt_ndb_nodeid,
             opt_bind_address,

=== modified file 'storage/ndb/src/kernel/ndbd.cpp'
--- a/storage/ndb/src/kernel/ndbd.cpp	2010-08-20 08:35:41 +0000
+++ b/storage/ndb/src/kernel/ndbd.cpp	2010-09-23 07:31:51 +0000
@@ -18,6 +18,7 @@
 #include <NdbEnv.h>
 #include <NdbConfig.h>
 #include <NdbSleep.h>
+#include <portlib/NdbDir.hpp>
 #include <NdbAutoPtr.hpp>
 
 #include "vm/SimBlockList.hpp"
@@ -404,9 +405,11 @@ extern "C"
 void
 handler_error(int signum){
   // only let one thread run shutdown
-  static long thread_id= 0;
+  static bool handling_error = false;
+  static pthread_t thread_id; // Valid when handling_error is true
 
-  if (thread_id != 0 && thread_id == my_thread_id())
+  if (handling_error &&
+      pthread_equal(thread_id, pthread_self()))
   {
     // Shutdown thread received signal
 #ifndef NDB_WIN32
@@ -419,7 +422,10 @@ handler_error(int signum){
   if(theShutdownMutex && NdbMutex_Trylock(theShutdownMutex) != 0)
     while(true)
       NdbSleep_MilliSleep(10);
-  thread_id= my_thread_id();
+
+  thread_id = pthread_self();
+  handling_error = true;
+
   g_eventLogger->info("Received signal %d. Running error handler.", signum);
   childReportSignal(signum);
   // restart the system
@@ -586,7 +592,12 @@ ndbd_run(bool foreground, int report_fd,
   theConfig->fetch_configuration(connect_str, force_nodeid, bind_address,
                                  allocated_nodeid);
 
-  my_setwd(NdbConfig_get_path(0), MYF(0));
+  if (NdbDir::chdir(NdbConfig_get_path(NULL)) != 0)
+  {
+    g_eventLogger->warning("Cannot change directory to '%s', error: %d",
+                           NdbConfig_get_path(NULL), errno);
+    // Ignore error
+  }
 
   if (get_multithreaded_config(globalEmulatorData))
     ndbd_exit(-1);

=== removed file 'storage/ndb/src/kernel/vm/ArenaPool.cpp'
--- a/storage/ndb/src/kernel/vm/ArenaPool.cpp	2009-06-22 14:29:27 +0000
+++ b/storage/ndb/src/kernel/vm/ArenaPool.cpp	1970-01-01 00:00:00 +0000
@@ -1,174 +0,0 @@
-/* Copyright (C) 2003 MySQL AB
-
-   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-
-#include "ArenaPool.hpp"
-#include <ndbd_exit_codes.h>
-#include <NdbOut.hpp>
-
-static
-Uint32
-computeBlockSize(Uint32 blockSz, Uint32 wpp)
-{
-  Uint32 minspill = wpp % blockSz;
-  Uint32 minspill_bs = blockSz;
-
-  for (Uint32 i = 16; i<blockSz/4; i += 16)
-  {
-    Uint32 spillsz = wpp % (blockSz - i);
-    if (spillsz == 0)
-    {
-      return blockSz - i;
-    }
-    else if (spillsz < minspill)
-    {
-      minspill = spillsz;
-      minspill_bs = blockSz -i;
-    }
-  }
-  ndbout_c("blockSz: %u, wpp: %u -> %u (%u)",
-           blockSz, wpp, minspill_bs, minspill);
-  return minspill_bs;
-}
-
-void
-ArenaAllocator::init(Uint32 sz, Uint32 type_id, const Pool_context& pc)
-{
-  Uint32 blocksz = ArenaBlock::computeBlockSizeInWords(sz);
-  Uint32 wpp = m_pool.WORDS_PER_PAGE;
-
-  Uint32 bs = computeBlockSize(blocksz, wpp);
-  Record_info ri;
-  ri.m_size = 4 * bs;
-  {
-    ArenaBlock tmp;
-    const char * off_base = (char*)&tmp;
-    const char * off_next = (char*)&tmp.nextPool;
-    const char * off_magic = (char*)&tmp.m_magic;
-
-    ri.m_offset_next_pool = Uint32(off_next - off_base);
-    ri.m_offset_magic = Uint32(off_magic - off_base);
-  }
-  ri.m_type_id = type_id;
-  m_pool.init(ri, pc);
-  m_block_size = bs - ArenaBlock::HeaderSize;
-}
-
-bool
-ArenaAllocator::seize(ArenaHead& ah)
-{
-  Ptr<void> tmp;
-  if (m_pool.seize(tmp))
-  {
-    ah.m_first_block = tmp.i;
-    ah.m_current_block = tmp.i;
-    ah.m_block_size = m_block_size;
-    ah.m_current_block_ptr = static_cast<ArenaBlock*>(tmp.p);
-    ah.m_current_block_ptr->m_next_block = RNIL;
-    return true;
-  }
-  return false;
-}
-
-void
-ArenaAllocator::release(ArenaHead& ah)
-{
-  Ptr<void> curr;
-  curr.i = ah.m_first_block;
-  while (curr.i != RNIL)
-  {
-    curr.p = m_pool.getPtr(curr.i);
-    Uint32 next = static_cast<ArenaBlock*>(curr.p)->m_next_block;
-    m_pool.release(curr);
-    curr.i = next;
-  }
-
-  new (&ah) ArenaHead();
-}
-
-void
-ArenaPool::init(ArenaAllocator * alloc,
-                const Record_info& ri, const Pool_context&)
-{
-  m_record_info = ri;
-  m_record_info.m_size = ((ri.m_size + 3) >> 2); // Align to word boundary
-  m_record_info.m_offset_magic = ((ri.m_offset_magic + 3) >> 2);
-  m_record_info.m_offset_next_pool = ((ri.m_offset_next_pool + 3) >> 2);
-  m_allocator = alloc;
-}
-
-bool
-ArenaPool::seize(ArenaHead & ah, Ptr<void>& ptr)
-{
-  Uint32 pos = ah.m_first_free;
-  Uint32 bs = ah.m_block_size;
-  Uint32 ptrI = ah.m_current_block;
-  ArenaBlock * block = ah.m_current_block_ptr;
-
-  Uint32 sz = m_record_info.m_size;
-  Uint32 off = m_record_info.m_offset_magic;
-
-  if (0)
-    ndbout_c("pos: %u sz: %u (sum: %u) bs: %u",
-             pos, sz, (pos + sz), bs);
-
-  if (pos + sz <= bs)
-  {
-    /**
-     * Alloc in this block
-     */
-    ptr.i =
-      ((ptrI >> POOL_RECORD_BITS) << POOL_RECORD_BITS) +
-      (ptrI & POOL_RECORD_MASK) + pos + ArenaBlock::HeaderSize;
-    ptr.p = block->m_data + pos;
-    block->m_data[pos+off] = ~(Uint32)m_record_info.m_type_id;
-
-    ah.m_first_free = pos + sz;
-    return true;
-  }
-  else
-  {
-    Ptr<void> tmp;
-    if (m_allocator->m_pool.seize(tmp))
-    {
-      ah.m_first_free = 0;
-      ah.m_current_block = tmp.i;
-      ah.m_current_block_ptr->m_next_block = tmp.i;
-      ah.m_current_block_ptr = static_cast<ArenaBlock*>(tmp.p);
-      ah.m_current_block_ptr->m_next_block = RNIL;
-      bool ret = seize(ah, ptr);
-      (void)ret;
-      assert(ret == true);
-      return true;
-    }
-  }
-  return false;
-}
-
-void
-ArenaPool::handle_invalid_release(Ptr<void> ptr)
-{
-  char buf[255];
-
-  Uint32 pos = ptr.i & POOL_RECORD_MASK;
-  Uint32 pageI = ptr.i >> POOL_RECORD_BITS;
-  Uint32 * record_ptr_p = (Uint32*)ptr.p;
-
-  Uint32 magic = * (record_ptr_p + m_record_info.m_offset_magic);
-  BaseString::snprintf(buf, sizeof(buf),
-                       "Invalid memory release: ptr (%x %p) magic: (%.8x %.8x)",
-                       ptr.i, ptr.p, magic, m_record_info.m_type_id);
-
-  m_allocator->m_pool.m_ctx.handleAbort(NDBD_EXIT_PRGERR, buf);
-}

=== added file 'storage/ndb/src/kernel/vm/ArenaPool.cpp'
--- a/storage/ndb/src/kernel/vm/ArenaPool.cpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/kernel/vm/ArenaPool.cpp	2010-09-07 10:13:06 +0000
@@ -0,0 +1,178 @@
+/* Copyright (C) 2003 MySQL AB
+
+   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#include "ArenaPool.hpp"
+#include <ndbd_exit_codes.h>
+#include <NdbOut.hpp>
+
+static
+Uint32
+computeBlockSize(Uint32 blockSz, Uint32 wpp)
+{
+  Uint32 minspill = wpp % blockSz;
+  Uint32 minspill_bs = blockSz;
+
+  for (Uint32 i = 16; i<blockSz/4; i += 16)
+  {
+    Uint32 spillsz = wpp % (blockSz - i);
+    if (spillsz == 0)
+    {
+      return blockSz - i;
+    }
+    else if (spillsz < minspill)
+    {
+      minspill = spillsz;
+      minspill_bs = blockSz -i;
+    }
+  }
+  ndbout_c("blockSz: %u, wpp: %u -> %u (%u)",
+           blockSz, wpp, minspill_bs, minspill);
+  return minspill_bs;
+}
+
+void
+ArenaAllocator::init(Uint32 sz, Uint32 type_id, const Pool_context& pc)
+{
+  Uint32 blocksz = ArenaBlock::computeBlockSizeInWords(sz);
+  Uint32 wpp = m_pool.WORDS_PER_PAGE;
+
+  Uint32 bs = computeBlockSize(blocksz, wpp);
+  Record_info ri;
+  ri.m_size = 4 * bs;
+  {
+    ArenaBlock tmp;
+    const char * off_base = (char*)&tmp;
+    const char * off_next = (char*)&tmp.nextPool;
+    const char * off_magic = (char*)&tmp.m_magic;
+
+    ri.m_offset_next_pool = Uint32(off_next - off_base);
+    ri.m_offset_magic = Uint32(off_magic - off_base);
+  }
+  ri.m_type_id = type_id;
+  m_pool.init(ri, pc);
+  m_block_size = bs - ArenaBlock::HeaderSize;
+}
+
+bool
+ArenaAllocator::seize(ArenaHead& ah)
+{
+  Ptr<void> tmp;
+  if (m_pool.seize(tmp))
+  {
+    ah.m_first_block = tmp.i;
+    ah.m_current_block = tmp.i;
+    ah.m_block_size = m_block_size;
+    ah.m_current_block_ptr = static_cast<ArenaBlock*>(tmp.p);
+    ah.m_current_block_ptr->m_next_block = RNIL;
+    return true;
+  }
+  return false;
+}
+
+void
+ArenaAllocator::release(ArenaHead& ah)
+{
+  Ptr<void> curr;
+  curr.i = ah.m_first_block;
+  while (curr.i != RNIL)
+  {
+    curr.p = m_pool.getPtr(curr.i);
+    Uint32 next = static_cast<ArenaBlock*>(curr.p)->m_next_block;
+    m_pool.release(curr);
+    curr.i = next;
+  }
+
+  new (&ah) ArenaHead();
+}
+
+void
+ArenaPool::init(ArenaAllocator * alloc,
+                const Record_info& ri, const Pool_context&)
+{
+  m_record_info = ri;
+#if SIZEOF_CHARP == 4
+  m_record_info.m_size = ((ri.m_size + 3) >> 2); // Align to word boundary
+#else
+  m_record_info.m_size = ((ri.m_size + 7) >> 3) << 1; // align 8-byte
+#endif
+  m_record_info.m_offset_magic = ((ri.m_offset_magic + 3) >> 2);
+  m_record_info.m_offset_next_pool = ((ri.m_offset_next_pool + 3) >> 2);
+  m_allocator = alloc;
+}
+
+bool
+ArenaPool::seize(ArenaHead & ah, Ptr<void>& ptr)
+{
+  Uint32 pos = ah.m_first_free;
+  Uint32 bs = ah.m_block_size;
+  Uint32 ptrI = ah.m_current_block;
+  ArenaBlock * block = ah.m_current_block_ptr;
+
+  Uint32 sz = m_record_info.m_size;
+  Uint32 off = m_record_info.m_offset_magic;
+
+  if (0)
+    ndbout_c("pos: %u sz: %u (sum: %u) bs: %u",
+             pos, sz, (pos + sz), bs);
+
+  if (pos + sz <= bs)
+  {
+    /**
+     * Alloc in this block
+     */
+    ptr.i =
+      ((ptrI >> POOL_RECORD_BITS) << POOL_RECORD_BITS) +
+      (ptrI & POOL_RECORD_MASK) + pos + ArenaBlock::HeaderSize;
+    ptr.p = block->m_data + pos;
+    block->m_data[pos+off] = ~(Uint32)m_record_info.m_type_id;
+
+    ah.m_first_free = pos + sz;
+    return true;
+  }
+  else
+  {
+    Ptr<void> tmp;
+    if (m_allocator->m_pool.seize(tmp))
+    {
+      ah.m_first_free = 0;
+      ah.m_current_block = tmp.i;
+      ah.m_current_block_ptr->m_next_block = tmp.i;
+      ah.m_current_block_ptr = static_cast<ArenaBlock*>(tmp.p);
+      ah.m_current_block_ptr->m_next_block = RNIL;
+      bool ret = seize(ah, ptr);
+      (void)ret;
+      assert(ret == true);
+      return true;
+    }
+  }
+  return false;
+}
+
+void
+ArenaPool::handle_invalid_release(Ptr<void> ptr)
+{
+  char buf[255];
+
+  //Uint32 pos = ptr.i & POOL_RECORD_MASK;
+  //Uint32 pageI = ptr.i >> POOL_RECORD_BITS;
+  Uint32 * record_ptr_p = (Uint32*)ptr.p;
+
+  Uint32 magic = * (record_ptr_p + m_record_info.m_offset_magic);
+  BaseString::snprintf(buf, sizeof(buf),
+                       "Invalid memory release: ptr (%x %p) magic: (%.8x %.8x)",
+                       ptr.i, ptr.p, magic, m_record_info.m_type_id);
+
+  m_allocator->m_pool.m_ctx.handleAbort(NDBD_EXIT_PRGERR, buf);
+}

=== removed file 'storage/ndb/src/kernel/vm/ArenaPool.hpp'
--- a/storage/ndb/src/kernel/vm/ArenaPool.hpp	2009-06-22 14:29:27 +0000
+++ b/storage/ndb/src/kernel/vm/ArenaPool.hpp	1970-01-01 00:00:00 +0000
@@ -1,128 +0,0 @@
-/* Copyright (C) 2003 MySQL AB
-
-   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-
-#ifndef ARENA_POOL_HPP
-#define ARENA_POOL_HPP
-
-#include "Pool.hpp"
-#include "RWPool.hpp"
-
-struct ArenaBlock
-{
-  Uint32 m_magic;
-  union {
-    Uint32 m_next_block;
-    Uint32 nextPool;
-  };
-
-  Uint32 m_data[1];
-
-  STATIC_CONST( HeaderSize = 2 );
-
-  static Uint32 computeBlockSizeInWords(Uint32 datasz) {
-    return 16 * (((datasz + 2) + 8) / 16);
-  }
-};
-
-struct ArenaHead
-{
-  ArenaHead() {
-    m_first_free = ~(Uint16)0;
-    m_block_size = 0;
-    m_first_block = RNIL;
-    m_current_block = RNIL;
-    m_current_block_ptr = 0;
-  }
-
-  ArenaBlock * m_current_block_ptr;
-  Uint32 m_first_block;
-  Uint32 m_current_block;
-  Uint16 m_first_free;
-  Uint16 m_block_size;
-};
-
-class ArenaPool; // forward
-
-class ArenaAllocator
-{
-  RWPool m_pool;
-  Uint32 m_block_size;
-  friend class ArenaPool;
-public:
-  ArenaAllocator() {}
-  void init(Uint32 blockSize, Uint32 type_id, const Pool_context& pc);
-
-  bool seize(ArenaHead&);
-  void release(ArenaHead&);
-};
-
-class ArenaPool
-{
-public:
-  ArenaPool() {}
-
-  void init(ArenaAllocator*, const Record_info& ri, const Pool_context& pc);
-
-  bool seize(Ptr<void>&) { assert(false); return false; } // Not implemented...
-
-  bool seize(ArenaHead&, Ptr<void>&);
-  void release(Ptr<void>);
-  void * getPtr(Uint32 i);
-
-private:
-  void handle_invalid_release(Ptr<void>);
-
-  Record_info m_record_info;
-  ArenaAllocator * m_allocator;
-};
-
-class LocalArenaPoolImpl
-{
-  ArenaHead & m_head;
-  ArenaPool & m_pool;
-public:
-  LocalArenaPoolImpl(ArenaHead& head, ArenaPool & pool)
-    : m_head(head), m_pool(pool) {}
-
-  bool seize(Ptr<void> & ptr) { return m_pool.seize(m_head, ptr); }
-  void release(Ptr<void> ptr) { m_pool.release(ptr); }
-  void * getPtr(Uint32 i) { return m_pool.getPtr(i); }
-};
-
-inline
-void*
-ArenaPool::getPtr(Uint32 i)
-{
-  return m_allocator->m_pool.getPtr(m_record_info, i);
-}
-
-inline
-void
-ArenaPool::release(Ptr<void> ptr)
-{
-  Uint32 * record_ptr = static_cast<Uint32*>(ptr.p);
-  Uint32 off = m_record_info.m_offset_magic;
-  Uint32 type_id = m_record_info.m_type_id;
-  Uint32 magic_val = * (record_ptr + off);
-
-  if (likely(magic_val == ~type_id))
-  {
-    * (record_ptr + off) = 0;
-    return;
-  }
-  handle_invalid_release(ptr);
-}
-
-#endif

=== added file 'storage/ndb/src/kernel/vm/ArenaPool.hpp'
--- a/storage/ndb/src/kernel/vm/ArenaPool.hpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/kernel/vm/ArenaPool.hpp	2010-09-07 10:13:06 +0000
@@ -0,0 +1,128 @@
+/* Copyright (C) 2003 MySQL AB
+
+   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifndef ARENA_POOL_HPP
+#define ARENA_POOL_HPP
+
+#include "Pool.hpp"
+#include "RWPool.hpp"
+
+struct ArenaBlock
+{
+  Uint32 m_magic;
+  union {
+    Uint32 m_next_block;
+    Uint32 nextPool;
+  };
+
+  Uint32 m_data[1];
+
+  STATIC_CONST( HeaderSize = 2 );
+
+  static Uint32 computeBlockSizeInWords(Uint32 datasz) {
+    return 16 * (((datasz + 2) + 8) / 16);
+  }
+};
+
+struct ArenaHead
+{
+  ArenaHead() {
+    m_first_free = ~(Uint16)0;
+    m_block_size = 0;
+    m_first_block = RNIL;
+    m_current_block = RNIL;
+    m_current_block_ptr = 0;
+  }
+
+  ArenaBlock * m_current_block_ptr;
+  Uint32 m_first_block;
+  Uint32 m_current_block;
+  Uint16 m_first_free;
+  Uint16 m_block_size;
+};
+
+class ArenaPool; // forward
+
+class ArenaAllocator
+{
+  RWPool m_pool;
+  Uint32 m_block_size;
+  friend class ArenaPool;
+public:
+  ArenaAllocator() {}
+  void init(Uint32 blockSize, Uint32 type_id, const Pool_context& pc);
+
+  bool seize(ArenaHead&);
+  void release(ArenaHead&);
+};
+
+class ArenaPool
+{
+public:
+  ArenaPool() {}
+
+  void init(ArenaAllocator*, const Record_info& ri, const Pool_context& pc);
+
+  bool seize(Ptr<void>&) { assert(false); return false; } // Not implemented...
+
+  bool seize(ArenaHead&, Ptr<void>&);
+  void release(Ptr<void>);
+  void * getPtr(Uint32 i);
+
+private:
+  void handle_invalid_release(Ptr<void>) ATTRIBUTE_NORETURN;
+
+  Record_info m_record_info;
+  ArenaAllocator * m_allocator;
+};
+
+class LocalArenaPoolImpl
+{
+  ArenaHead & m_head;
+  ArenaPool & m_pool;
+public:
+  LocalArenaPoolImpl(ArenaHead& head, ArenaPool & pool)
+    : m_head(head), m_pool(pool) {}
+
+  bool seize(Ptr<void> & ptr) { return m_pool.seize(m_head, ptr); }
+  void release(Ptr<void> ptr) { m_pool.release(ptr); }
+  void * getPtr(Uint32 i) { return m_pool.getPtr(i); }
+};
+
+inline
+void*
+ArenaPool::getPtr(Uint32 i)
+{
+  return m_allocator->m_pool.getPtr(m_record_info, i);
+}
+
+inline
+void
+ArenaPool::release(Ptr<void> ptr)
+{
+  Uint32 * record_ptr = static_cast<Uint32*>(ptr.p);
+  Uint32 off = m_record_info.m_offset_magic;
+  Uint32 type_id = m_record_info.m_type_id;
+  Uint32 magic_val = * (record_ptr + off);
+
+  if (likely(magic_val == ~type_id))
+  {
+    * (record_ptr + off) = 0;
+    return;
+  }
+  handle_invalid_release(ptr);
+}
+
+#endif

=== modified file 'storage/ndb/src/kernel/vm/CMakeLists.txt'
--- a/storage/ndb/src/kernel/vm/CMakeLists.txt	2010-01-11 13:25:53 +0000
+++ b/storage/ndb/src/kernel/vm/CMakeLists.txt	2010-09-23 11:55:42 +0000
@@ -38,6 +38,7 @@ ADD_LIBRARY(ndbkernel STATIC
     SafeMutex.cpp
     Ndbinfo.cpp
     NdbinfoTables.cpp
+    ArenaPool.cpp
 )
 
 ADD_LIBRARY(ndbsched STATIC

=== modified file 'storage/ndb/src/kernel/vm/Makefile.am'
--- a/storage/ndb/src/kernel/vm/Makefile.am	2010-01-11 13:25:53 +0000
+++ b/storage/ndb/src/kernel/vm/Makefile.am	2010-09-23 11:55:42 +0000
@@ -45,7 +45,8 @@ libkernel_a_SOURCES = VMSignal.cpp \
                       GlobalData.cpp \
                       SafeMutex.cpp \
                       Ndbinfo.cpp \
-                      NdbinfoTables.cpp
+                      NdbinfoTables.cpp \
+                      ArenaPool.cpp
 
 libsched_a_SOURCES = TimeQueue.cpp \
                      ThreadConfig.cpp \

=== modified file 'storage/ndb/src/kernel/vm/Pool.hpp'
--- a/storage/ndb/src/kernel/vm/Pool.hpp	2009-06-12 14:12:30 +0000
+++ b/storage/ndb/src/kernel/vm/Pool.hpp	2010-09-23 11:55:42 +0000
@@ -119,7 +119,7 @@ struct Pool_context
   /**
    * Abort
    */
-  void handleAbort(int code, const char* msg);
+  void handleAbort(int code, const char* msg) ATTRIBUTE_NORETURN;
 };
 
 template <typename T>

=== modified file 'storage/ndb/src/kernel/vm/RWPool.hpp'
--- a/storage/ndb/src/kernel/vm/RWPool.hpp	2009-06-12 12:01:12 +0000
+++ b/storage/ndb/src/kernel/vm/RWPool.hpp	2010-09-23 11:55:42 +0000
@@ -59,8 +59,8 @@ public:
   STATIC_CONST( WORDS_PER_PAGE = RWPage::RWPAGE_WORDS );
 
 private:  
-  void handle_invalid_release(Ptr<void>);
-  void handle_invalid_get_ptr(Uint32 i);
+  void handle_invalid_release(Ptr<void>) ATTRIBUTE_NORETURN;
+  void handle_invalid_get_ptr(Uint32 i) ATTRIBUTE_NORETURN;
 };
 
 inline

=== modified file 'storage/ndb/src/kernel/vm/SafeCounter.hpp'
--- a/storage/ndb/src/kernel/vm/SafeCounter.hpp	2009-05-26 18:53:34 +0000
+++ b/storage/ndb/src/kernel/vm/SafeCounter.hpp	2010-09-06 09:44:48 +0000
@@ -237,6 +237,12 @@ SafeCounter::init(NodeReceiverGroup rg, 
   {
     m_nodes = rg.m_nodes;
     m_count = m_nodes.count();
+
+    if (unlikely(m_count == 0))
+    {
+      ErrorReporter::handleAssert("SafeCounter::empty node list",
+                                  __FILE__, __LINE__);
+    }
     return true;
   }
   return false;
@@ -245,12 +251,18 @@ SafeCounter::init(NodeReceiverGroup rg, 
 template<typename Ref>
 inline
 bool
-SafeCounter::init(NodeReceiverGroup rg, Uint32 senderData){
-  
+SafeCounter::init(NodeReceiverGroup rg, Uint32 senderData)
+{
   if (init<Ref>(rg.m_block, Ref::GSN, senderData))
   {
     m_nodes = rg.m_nodes;
     m_count = m_nodes.count();
+
+    if (unlikely(m_count == 0))
+    {
+      ErrorReporter::handleAssert("SafeCounter::empty node list",
+                                  __FILE__, __LINE__);
+    }
     return true;
   }
   return false;

=== modified file 'storage/ndb/src/kernel/vm/WOPool.hpp'
--- a/storage/ndb/src/kernel/vm/WOPool.hpp	2009-05-26 18:53:34 +0000
+++ b/storage/ndb/src/kernel/vm/WOPool.hpp	2010-09-07 10:10:36 +0000
@@ -54,9 +54,9 @@ private:  
   bool seize_new_page(Ptr<void>&);
   void release_not_current(Ptr<void>);
 
-  void handle_invalid_release(Ptr<void>);
-  void handle_invalid_get_ptr(Uint32 i);
-  void handle_inconsistent_release(Ptr<void>);
+  void handle_invalid_release(Ptr<void>) ATTRIBUTE_NORETURN;
+  void handle_invalid_get_ptr(Uint32 i) ATTRIBUTE_NORETURN;
+  void handle_inconsistent_release(Ptr<void>) ATTRIBUTE_NORETURN;
 };
 
 inline

=== modified file 'storage/ndb/src/kernel/vm/mt.cpp'
--- a/storage/ndb/src/kernel/vm/mt.cpp	2010-09-03 08:59:02 +0000
+++ b/storage/ndb/src/kernel/vm/mt.cpp	2010-09-23 11:55:42 +0000
@@ -851,6 +851,9 @@ struct trp_callback : public Transporter
 extern trp_callback g_trp_callback;             // Forward declaration
 extern struct thr_repository g_thr_repository;
 
+#include <NdbMutex.h>
+#include <NdbCondition.h>
+
 struct thr_repository
 {
   thr_repository()
@@ -919,10 +922,9 @@ struct thr_repository
   /*
    * These are used to synchronize during crash / trace dumps.
    *
-   * ToDo: Replace pthread stuff with portable wrappers in portlib.
    */
-  pthread_mutex_t stop_for_crash_mutex;
-  pthread_cond_t stop_for_crash_cond;
+  NdbMutex stop_for_crash_mutex;
+  NdbCondition stop_for_crash_cond;
   Uint32 stopped_threads;
 };
 
@@ -3343,8 +3345,8 @@ rep_init(struct thr_repository* rep, uns
   }
 
   rep->stopped_threads = 0;
-  pthread_mutex_init(&rep->stop_for_crash_mutex, NULL);
-  pthread_cond_init(&rep->stop_for_crash_cond, NULL);
+  NdbMutex_Init(&rep->stop_for_crash_mutex);
+  NdbCondition_Init(&rep->stop_for_crash_cond);
 
   for (int i = 0 ; i < MAX_NTRANSPORTERS; i++)
   {
@@ -3685,7 +3687,7 @@ FastScheduler::traceDumpPrepare(NdbShutd
   /* The selfptr might be NULL, or pointer to thread that crashed. */
 
   Uint32 waitFor_count = 0;
-  pthread_mutex_lock(&g_thr_repository.stop_for_crash_mutex);
+  NdbMutex_Lock(&g_thr_repository.stop_for_crash_mutex);
   g_thr_repository.stopped_threads = 0;
 
   for (Uint32 thr_no = 0; thr_no < num_threads; thr_no++)
@@ -3703,13 +3705,11 @@ FastScheduler::traceDumpPrepare(NdbShutd
 
   static const Uint32 max_wait_seconds = 2;
   NDB_TICKS start = NdbTick_CurrentMillisecond();
-  struct timespec waittime;
-  set_timespec_nsec(waittime, 10*1000*1000);
   while (g_thr_repository.stopped_threads < waitFor_count)
   {
-    pthread_cond_timedwait(&g_thr_repository.stop_for_crash_cond,
-                           &g_thr_repository.stop_for_crash_mutex,
-                           &waittime);
+    NdbCondition_WaitTimeout(&g_thr_repository.stop_for_crash_cond,
+                             &g_thr_repository.stop_for_crash_mutex,
+                             10);
     NDB_TICKS now = NdbTick_CurrentMillisecond();
     if (now > start + max_wait_seconds * 1000)
       break;                    // Give up
@@ -3723,7 +3723,7 @@ FastScheduler::traceDumpPrepare(NdbShutd
     ndbout_c("Warning: %d thread(s) did not stop before starting crash dump.",
              waitFor_count - g_thr_repository.stopped_threads);
   }
-  pthread_mutex_unlock(&g_thr_repository.stop_for_crash_mutex);
+  NdbMutex_Unlock(&g_thr_repository.stop_for_crash_mutex);
 
   /* Now we are ready (or as ready as can be) for doing crash dump. */
 }
@@ -3734,10 +3734,10 @@ void mt_execSTOP_FOR_CRASH()
   const thr_data *selfptr = reinterpret_cast<const thr_data *>(value);
   require(selfptr != NULL);
 
-  pthread_mutex_lock(&g_thr_repository.stop_for_crash_mutex);
+  NdbMutex_Lock(&g_thr_repository.stop_for_crash_mutex);
   g_thr_repository.stopped_threads++;
-  pthread_cond_signal(&g_thr_repository.stop_for_crash_cond);
-  pthread_mutex_unlock(&g_thr_repository.stop_for_crash_mutex);
+  NdbCondition_Signal(&g_thr_repository.stop_for_crash_cond);
+  NdbMutex_Unlock(&g_thr_repository.stop_for_crash_mutex);
 
   /* ToDo: is this correct? */
   globalEmulatorData.theWatchDog->unregisterWatchedThread(selfptr->m_thr_no);

=== modified file 'storage/ndb/src/mgmapi/mgmapi.cpp'
--- a/storage/ndb/src/mgmapi/mgmapi.cpp	2010-08-20 11:10:25 +0000
+++ b/storage/ndb/src/mgmapi/mgmapi.cpp	2010-09-22 10:07:28 +0000
@@ -17,10 +17,8 @@
 */
 
 #include <ndb_global.h>
-#include <my_sys.h>
 
 #include <LocalConfig.hpp>
-#include <NdbAutoPtr.hpp>
 
 #include <NdbSleep.h>
 #include <NdbTCP.h>
@@ -169,8 +167,10 @@ NdbMgmHandle
 ndb_mgm_create_handle()
 {
   DBUG_ENTER("ndb_mgm_create_handle");
-  NdbMgmHandle h     =
-    (NdbMgmHandle)my_malloc(sizeof(ndb_mgm_handle),MYF(MY_WME));
+  NdbMgmHandle h = (NdbMgmHandle)malloc(sizeof(ndb_mgm_handle));
+  if (!h)
+    return NULL;
+
   h->connected       = 0;
   h->last_error      = 0;
   h->last_error_line = 0;
@@ -178,7 +178,7 @@ ndb_mgm_create_handle()
   h->timeout         = 60000;
   h->cfg_i           = -1;
   h->errstream       = stdout;
-  h->m_name          = 0;
+  h->m_name          = NULL;
   h->m_bindaddress   = 0;
   h->m_bindaddress_port = 0;
   h->ignore_sigpipe  = true;
@@ -204,8 +204,8 @@ extern "C"
 void
 ndb_mgm_set_name(NdbMgmHandle handle, const char *name)
 {
-  my_free(handle->m_name, MYF(MY_ALLOW_ZERO_PTR));
-  handle->m_name= my_strdup(name, MYF(MY_WME));
+  free(handle->m_name);
+  handle->m_name= strdup(name);
 }
 
 extern "C"
@@ -237,8 +237,7 @@ int
 ndb_mgm_set_bindaddress(NdbMgmHandle handle, const char * arg)
 {
   DBUG_ENTER("ndb_mgm_set_bindaddress");
-  if (handle->m_bindaddress)
-    free(handle->m_bindaddress);
+  free(handle->m_bindaddress);
 
   if (arg)
   {
@@ -304,10 +303,9 @@ ndb_mgm_destroy_handle(NdbMgmHandle * ha
   }
 #endif
   (*handle)->cfg.~LocalConfig();
-  my_free((*handle)->m_name, MYF(MY_ALLOW_ZERO_PTR));
-  if ((*handle)->m_bindaddress)
-    free((*handle)->m_bindaddress);
-  my_free((char*)* handle,MYF(MY_ALLOW_ZERO_PTR));
+  free((*handle)->m_name);
+  free((*handle)->m_bindaddress);
+  free(*handle);
   * handle = 0;
   DBUG_VOID_RETURN;
 }
@@ -3358,7 +3356,7 @@ ndb_mgm_create_logevent_handle_same_sock
 static void
 free_log_handle(NdbLogEventHandle log_handle)
 {
-  my_free(log_handle, 0);
+  free(log_handle);
 }
 
 

=== modified file 'storage/ndb/src/mgmapi/mgmapi_internal.h'
--- a/storage/ndb/src/mgmapi/mgmapi_internal.h	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/src/mgmapi/mgmapi_internal.h	2010-08-16 13:54:16 +0000
@@ -19,12 +19,12 @@
 #ifndef MGMAPI_INTERNAL_H
 #define MGMAPI_INTERNAL_H
 
+#include <portlib/NdbTCP.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#include <NdbTCP.h>
-
   /**
    * Set an integer parameter for a connection
    *

=== modified file 'storage/ndb/src/mgmapi/ndb_logevent.cpp'
--- a/storage/ndb/src/mgmapi/ndb_logevent.cpp	2010-04-13 16:01:38 +0000
+++ b/storage/ndb/src/mgmapi/ndb_logevent.cpp	2010-08-13 13:04:47 +0000
@@ -17,7 +17,6 @@
 */
 
 #include <ndb_global.h>
-#include <my_sys.h>
 #include <mgmapi.h>
 #include <mgmapi_internal.h>
 
@@ -63,7 +62,9 @@ NdbLogEventHandle
 ndb_mgm_create_logevent_handle_same_socket(NdbMgmHandle mh)
 {
   NdbLogEventHandle h=
-    (NdbLogEventHandle)my_malloc(sizeof(ndb_logevent_handle),MYF(MY_WME));
+    (NdbLogEventHandle)malloc(sizeof(ndb_logevent_handle));
+  if (!h)
+    return NULL;
 
   h->socket= _ndb_mgm_get_socket(mh);
 
@@ -75,12 +76,17 @@ NdbLogEventHandle
 ndb_mgm_create_logevent_handle(NdbMgmHandle mh,
 			       const int filter[])
 {
+  NdbLogEventHandle h=
+    (NdbLogEventHandle)malloc(sizeof(ndb_logevent_handle));
+  if (!h)
+    return NULL;
+
   NDB_SOCKET_TYPE sock;
   if(ndb_mgm_listen_event_internal(mh, filter, 1, &sock) < 0)
+  {
+    free(h);
     return 0;
-
-  NdbLogEventHandle h=
-    (NdbLogEventHandle)my_malloc(sizeof(ndb_logevent_handle),MYF(MY_WME));
+  }
 
   h->socket= sock;
 
@@ -111,7 +117,7 @@ void ndb_mgm_destroy_logevent_handle(Ndb
   if ( *h )
     my_socket_close((*h)->socket);
 
-  my_free((char*)* h,MYF(MY_ALLOW_ZERO_PTR));
+  free(*h);
   * h = 0;
 }
 

=== modified file 'storage/ndb/src/mgmclient/CommandInterpreter.cpp'
--- a/storage/ndb/src/mgmclient/CommandInterpreter.cpp	2010-03-04 12:32:16 +0000
+++ b/storage/ndb/src/mgmclient/CommandInterpreter.cpp	2010-08-16 13:51:31 +0000
@@ -113,13 +113,8 @@ public:
   int  executeLogLevel(int processId, const char* parameters, bool all);
   int  executeError(int processId, const char* parameters, bool all);
   int  executeLog(int processId, const char* parameters, bool all);
-  int  executeLogIn(int processId, const char* parameters, bool all);
-  int  executeLogOut(int processId, const char* parameters, bool all);
-  int  executeLogOff(int processId, const char* parameters, bool all);
   int  executeTestOn(int processId, const char* parameters, bool all);
   int  executeTestOff(int processId, const char* parameters, bool all);
-  int  executeSet(int processId, const char* parameters, bool all);
-  int  executeGetStat(int processId, const char* parameters, bool all);
   int  executeStatus(int processId, const char* parameters, bool all);
   int  executeEventReporting(int processId, const char* parameters, bool all);
   int  executeDumpState(int processId, const char* parameters, bool all);
@@ -220,10 +215,6 @@ static const char* helpText =
 "HELP DEBUG                             Help for debug compiled version\n"
 #endif
 "SHOW                                   Print information about cluster\n"
-#if 0
-"SHOW CONFIG                            Print configuration\n"
-"SHOW PARAMETERS                        Print configuration parameters\n"
-#endif
 "CREATE NODEGROUP <id>,<id>...          Add a Nodegroup containing nodes\n"
 "DROP NODEGROUP <NG>                    Drop nodegroup with id NG\n"
 "START BACKUP [NOWAIT | WAIT STARTED | WAIT COMPLETED]\n"
@@ -256,11 +247,7 @@ static const char* helpTextShow =
 "SHOW Print information about cluster\n\n"
 "SHOW               Print information about cluster.The status reported is from\n"
 "                   the perspective of the data nodes. API and Management Server nodes\n"
-"                   are only reported as connected once the data nodes have started.\n" 
-#if 0
-"SHOW CONFIG        Print configuration (in initial config file format)\n" 
-"SHOW PARAMETERS    Print information about configuration parameters\n\n"
-#endif
+"                   are only reported as connected once the data nodes have started.\n"
 ;
 
 static const char* helpTextHelp =
@@ -572,14 +559,9 @@ static const char* helpTextDebug =
 "<id> ERROR <errorNo>                  Inject error into NDB node\n"
 #endif
 "<id> LOG [BLOCK = {ALL|<block>+}]     Set logging on in & out signals\n"
-"<id> LOGIN [BLOCK = {ALL|<block>+}]   Set logging on in signals\n"
-"<id> LOGOUT [BLOCK = {ALL|<block>+}]  Set logging on out signals\n"
-"<id> LOGOFF [BLOCK = {ALL|<block>+}]  Unset signal logging\n"
 "<id> TESTON                           Start signal logging\n"
 "<id> TESTOFF                          Stop signal logging\n"
-"<id> SET <configParamName> <value>    Update configuration variable\n"
 "<id> DUMP <arg>                       Dump system state to cluster.log\n"
-"<id> GETSTAT                          Print statistics\n"
 "\n"
 "<id>       = ALL | Any database node id\n"
 ;
@@ -1336,13 +1318,8 @@ static const CommandInterpreter::Command
   ,{ "ERROR", &CommandInterpreter::executeError }
 #endif
   ,{ "LOG", &CommandInterpreter::executeLog }
-  ,{ "LOGIN", &CommandInterpreter::executeLogIn }
-  ,{ "LOGOUT", &CommandInterpreter::executeLogOut }
-  ,{ "LOGOFF", &CommandInterpreter::executeLogOff }
   ,{ "TESTON", &CommandInterpreter::executeTestOn }
   ,{ "TESTOFF", &CommandInterpreter::executeTestOff }
-  ,{ "SET", &CommandInterpreter::executeSet }
-  ,{ "GETSTAT", &CommandInterpreter::executeGetStat }
   ,{ "DUMP", &CommandInterpreter::executeDumpState }
   ,{ "REPORT", &CommandInterpreter::executeReport }
 };
@@ -1838,25 +1815,10 @@ CommandInterpreter::executeShow(char* pa
     print_nodes(state, it, "ndbd",     ndb_nodes, NDB_MGM_NODE_TYPE_NDB, master_id);
     print_nodes(state, it, "ndb_mgmd", mgm_nodes, NDB_MGM_NODE_TYPE_MGM, 0);
     print_nodes(state, it, "mysqld",   api_nodes, NDB_MGM_NODE_TYPE_API, 0);
-    //    ndbout << helpTextShow;
     ndb_mgm_destroy_configuration(conf);
     return 0;
-  } else if (strcasecmp(parameters, "PROPERTIES") == 0 ||
-	     strcasecmp(parameters, "PROP") == 0) {
-    ndbout << "SHOW PROPERTIES is not yet implemented." << endl;
-    //  ndbout << "_mgmtSrvr.getConfig()->print();" << endl; /* XXX */
-  } else if (strcasecmp(parameters, "CONFIGURATION") == 0 ||
-	     strcasecmp(parameters, "CONFIG") == 0){
-    ndbout << "SHOW CONFIGURATION is not yet implemented." << endl;
-    //nbout << "_mgmtSrvr.getConfig()->printConfigFile();" << endl; /* XXX */
-  } else if (strcasecmp(parameters, "PARAMETERS") == 0 ||
-	     strcasecmp(parameters, "PARAMS") == 0 ||
-	     strcasecmp(parameters, "PARAM") == 0) {
-    ndbout << "SHOW PARAMETERS is not yet implemented." << endl;
-    //    ndbout << "_mgmtSrvr.getConfig()->getConfigInfo()->print();" 
-    //           << endl; /* XXX */
   } else {
-    ndbout << "Invalid argument." << endl;
+    ndbout << "Invalid argument: '" << parameters << "'" << endl;
     return -1;
   }
   return 0;
@@ -2731,35 +2693,6 @@ CommandInterpreter::executeLog(int proce
   return 0;
 }
 
-//*****************************************************************************
-//*****************************************************************************
-int
-CommandInterpreter::executeLogIn(int /* processId */,
-				 const char* parameters, bool /* all */) 
-{
-  ndbout << "Command LOGIN not implemented." << endl;
-  return 0;
-}
-
-//*****************************************************************************
-//*****************************************************************************
-int
-CommandInterpreter::executeLogOut(int /*processId*/, 
-				  const char* parameters, bool /*all*/) 
-{
-  ndbout << "Command LOGOUT not implemented." << endl;
-  return 0;
-}
-
-//*****************************************************************************
-//*****************************************************************************
-int
-CommandInterpreter::executeLogOff(int /*processId*/,
-				  const char* parameters, bool /*all*/) 
-{
-  ndbout << "Command LOGOFF not implemented." << endl;
-  return 0;
-}
 
 //*****************************************************************************
 //*****************************************************************************
@@ -2804,109 +2737,7 @@ CommandInterpreter::executeTestOff(int p
 
 //*****************************************************************************
 //*****************************************************************************
-int 
-CommandInterpreter::executeSet(int /*processId*/, 
-			       const char* parameters, bool /*all*/) 
-{
-  if (emptyString(parameters)) {
-    ndbout << "Missing parameter name." << endl;
-    return -1;
-  }
-#if 0
-  // Copy parameters since strtok will modify it
-  char* newpar = my_strdup(parameters,MYF(MY_WME));
-  My_auto_ptr<char> ap1(newpar);
-  char* configParameterName = strtok(newpar, " ");
-
-  char* allAfterParameterName = strtok(NULL, "\0");
-  if (emptyString(allAfterParameterName)) {
-    ndbout << "Missing parameter value." << endl;
-    return;
-  }
-
-  char* value = strtok(allAfterParameterName, " ");
-
-  char* allAfterValue = strtok(NULL, "\0");
-  if (! emptyString(allAfterValue)) {
-    ndbout << "Nothing expected after parameter value." << endl;
-    return;
-  }
-
-  bool configBackupFileUpdated;
-  bool configPrimaryFileUpdated;
-  
-  // TODO The handling of the primary and backup config files should be 
-  // analysed further.
-  // How it should be handled if only the backup is possible to write.
-
-  int result = _mgmtSrvr.updateConfigParam(processId, configParameterName, 
-					   value, configBackupFileUpdated, 
-					   configPrimaryFileUpdated);
-  if (result == 0) {
-    if (configBackupFileUpdated && configPrimaryFileUpdated) {
-      ndbout << "The configuration is updated." << endl;
-    }
-    else if (configBackupFileUpdated && !configPrimaryFileUpdated) {
-      ndbout << "The configuration is updated but it was only possible " 
-	     << "to update the backup configuration file, not the primary." 
-	     << endl;
-    }
-    else {
-      assert(false);
-    }
-  }
-  else {
-    ndbout << get_error_text(result) << endl;
-    if (configBackupFileUpdated && configPrimaryFileUpdated) {
-      ndbout << "The configuration files are however updated and "
-	     << "the value will be used next time the process is restarted." 
-	     << endl;
-    }
-    else if (configBackupFileUpdated && !configPrimaryFileUpdated) {
-      ndbout << "It was only possible to update the backup "
-	     << "configuration file, not the primary." << endl;
-    }
-    else if (!configBackupFileUpdated && !configPrimaryFileUpdated) {
-      ndbout << "The configuration files are not updated." << endl;
-    }
-    else {
-      // The primary is not tried to write if the write of backup file fails
-      abort();
-    }
-  }
-#endif 
-  return 0;
-}
-
-//*****************************************************************************
-//*****************************************************************************
-int CommandInterpreter::executeGetStat(int /*processId*/,
-					const char* parameters, bool /*all*/) 
-{
-  if (! emptyString(parameters)) {
-    ndbout << "No parameters expected to this command." << endl;
-    return -1;
-  }
-
-#if 0
-  MgmtSrvr::Statistics statistics;
-  int result = _mgmtSrvr.getStatistics(processId, statistics);
-  if (result != 0) {
-    ndbout << get_error_text(result) << endl;
-    return;
-  }
-#endif
-  // Print statistic...
-  /*
-  ndbout << "Number of GETSTAT commands: " 
-  << statistics._test1 << endl;
-  */
-  return 0;
-}
 
-//*****************************************************************************
-//*****************************************************************************
-				 
 int
 CommandInterpreter::executeEventReporting(int processId,
 					  const char* parameters, 

=== modified file 'storage/ndb/src/mgmclient/main.cpp'
--- a/storage/ndb/src/mgmclient/main.cpp	2010-05-04 14:34:54 +0000
+++ b/storage/ndb/src/mgmclient/main.cpp	2010-08-16 17:02:58 +0000
@@ -71,7 +71,7 @@ static struct my_option my_long_options[
 
 static void short_usage_sub(void)
 {
-  ndb_short_usage_sub(my_progname,"[hostname [port]]");
+  ndb_short_usage_sub("[hostname [port]]");
 }
 
 static void usage()
@@ -115,7 +115,7 @@ read_and_execute(int try_reconnect)
 int main(int argc, char** argv){
   NDB_INIT(argv[0]);
 
-  ndb_opt_set_usage_funcs(NULL, short_usage_sub, usage);
+  ndb_opt_set_usage_funcs(short_usage_sub, usage);
   load_defaults("my",load_default_groups,&argc,&argv);
   int ho_error;
 #ifndef DBUG_OFF

=== modified file 'storage/ndb/src/mgmsrv/ConfigManager.cpp'
--- a/storage/ndb/src/mgmsrv/ConfigManager.cpp	2010-08-13 11:56:05 +0000
+++ b/storage/ndb/src/mgmsrv/ConfigManager.cpp	2010-09-21 12:02:05 +0000
@@ -39,7 +39,6 @@ ConfigManager::ConfigManager(const MgmtS
   m_ss(NULL),
   m_config_mutex(NULL),
   m_config(NULL),
-  m_new_config(NULL),
   m_config_retriever(opt_ndb_connectstring,
                      opt_ndb_nodeid,
                      NDB_VERSION,
@@ -47,8 +46,6 @@ ConfigManager::ConfigManager(const MgmtS
                      opts.bind_address),
   m_config_state(CS_UNINITIALIZED),
   m_previous_state(CS_UNINITIALIZED),
-  m_config_change_error(ConfigChangeRef::OK),
-  m_client_ref(RNIL),
   m_prepared_config(NULL),
   m_node_id(0),
   m_configdir(configdir)
@@ -59,7 +56,6 @@ ConfigManager::ConfigManager(const MgmtS
 ConfigManager::~ConfigManager()
 {
   delete m_config;
-  delete m_new_config;
   delete m_prepared_config;
   if (m_ss)
     delete m_ss;
@@ -361,44 +357,13 @@ ConfigManager::init(void)
       if (new_conf == NULL)
         DBUG_RETURN(false);
 
-
-      /* Copy the necessary values from old to new config */
-      if (!new_conf->setGeneration(m_config->getGeneration()))
-      {
-        g_eventLogger->error("Failed to copy generation from old config");
-        DBUG_RETURN(false);
-      }
-
-      if (!new_conf->setName(m_config->getName()))
-      {
-        g_eventLogger->error("Failed to copy name from old config");
-        DBUG_RETURN(false);
-      }
-
-      if (!new_conf->setPrimaryMgmNode(m_config->getPrimaryMgmNode()))
-      {
-        g_eventLogger->error("Failed to copy primary mgm node from old config");
-        DBUG_RETURN(false);
-      }
-
-      /* Check if config has changed */
-      if (!m_config->equal(new_conf))
-      {
-        /* Loaded config is different */
-        BaseString buf;
-        g_eventLogger->info("Detected change of %s on disk, will try to " \
-                            "set it when all ndb_mgmd(s) started. "     \
-                            "This is the actual diff:\n%s",
-                            m_opts.mycnf ? "my.cnf" : m_opts.config_filename,
-                            m_config->diff2str(new_conf, buf));
-        m_new_config= new_conf;
-      }
-      else
-      {
-        /* Loaded config was equal to current */
-        g_eventLogger->info("Config equal!");
-        delete new_conf;
-      }
+      /**
+       * Add config to set once ConfigManager is fully started
+       */
+      m_config_change.config_loaded(new_conf);
+      g_eventLogger->info("Loaded configuration from '%s', will try "   \
+                          "to set it once started",
+                          m_opts.mycnf ? "my.cnf" : m_opts.config_filename);
     }
   }
   else
@@ -429,10 +394,10 @@ ConfigManager::init(void)
       g_eventLogger->info("Got initial configuration from '%s', will try " \
                           "to set it when all ndb_mgmd(s) started",
                           m_opts.mycnf ? "my.cnf" : m_opts.config_filename);
-      m_new_config = new Config(conf); // Copy config
+      m_config_change.m_initial_config = new Config(conf); // Copy config
       m_config_state = CS_INITIAL;
 
-      if (!init_checkers(m_new_config))
+      if (!init_checkers(m_config_change.m_initial_config))
         DBUG_RETURN(false);
     }
     else
@@ -464,9 +429,9 @@ ConfigManager::init(void)
                             "Will try to set it when all ndb_mgmd(s) started",
                             m_config->getGeneration(), m_config->getName());
         m_config_state= CS_INITIAL;
-        m_new_config = new Config(conf); // Copy config
+        m_config_change.m_initial_config = new Config(conf); // Copy config
 
-        if (!init_checkers(m_new_config))
+        if (!init_checkers(m_config_change.m_initial_config))
           DBUG_RETURN(false);
       }
       else
@@ -802,31 +767,33 @@ ConfigManager::execCONFIG_CHANGE_IMPL_RE
       new_generation = 1;
 
       // Check config is equal to our initial config
+      // but skip check if message is from self...
+      if (nodeId != refToNode(ss.getOwnRef()))
       {
         Config new_config_copy(&new_config);
         require(new_config_copy.setName(new_name));
         unsigned exclude[]= {CFG_SECTION_SYSTEM, 0};
-        if (!new_config_copy.equal(m_new_config, exclude))
+        if (!new_config_copy.equal(m_config_change.m_initial_config, exclude))
         {
           BaseString buf;
-          g_eventLogger->warning("Refusing to start initial config "    \
-                                 "change when nodes have different "    \
-                                 "config\n"                             \
-                                 "This is the actual diff:\n%s",
-                                 new_config_copy.diff2str(m_new_config, buf));
+          g_eventLogger->warning
+            ("Refusing to start initial config "                        \
+             "change when nodes have different "                        \
+             "config\n"                                                 \
+             "This is the actual diff:\n%s",
+             new_config_copy.diff2str(m_config_change.m_initial_config, buf));
           sendConfigChangeImplRef(ss, nodeId,
                                   ConfigChangeRef::DifferentInitial);
           return;
         }
-      }
-
-      /*
-         Scrap the m_new_config, it's been used to check that other node
-         started from equal initial config, now it's not needed anymore
-      */
-      delete m_new_config;
-      m_new_config = NULL;
 
+        /*
+          Scrap the new_config, it's been used to check that other node
+          started from equal initial config, now it's not needed anymore
+        */
+        delete m_config_change.m_initial_config;
+        m_config_change.m_initial_config = NULL;
+      }
     }
     else
     {
@@ -936,7 +903,7 @@ void ConfigManager::set_config_change_st
     m_config->get_nodemask(m_all_mgm, NDB_MGM_NODE_TYPE_MGM);
   }
 
-  m_config_change_state.m_current_state = state;
+  m_config_change.m_state.m_current_state = state;
 }
 
 
@@ -952,69 +919,28 @@ ConfigManager::execCONFIG_CHANGE_IMPL_RE
                          nodeId, ref->errorCode);
 
   /* Remember the original error code */
-  if (m_config_change_error == 0)
-    m_config_change_error = (ConfigChangeRef::ErrorCode)ref->errorCode;
-
-  switch(m_config_change_state){
+  if (m_config_change.m_error == 0)
+    m_config_change.m_error = (ConfigChangeRef::ErrorCode)ref->errorCode;
 
+  switch(m_config_change.m_state){
+  case ConfigChangeState::ABORT:
   case ConfigChangeState::PREPARING:{
-    /* Got ref while preparing */
+    /* Got ref while preparing (or already decided to abort) */
+    m_config_change.m_contacted_nodes.clear(nodeId);
     set_config_change_state(ConfigChangeState::ABORT);
+
     m_waiting_for.clear(nodeId);
     if (!m_waiting_for.isclear())
       return;
 
-    /* Abort all other nodes */
-    SimpleSignal ssig;
-    ConfigChangeImplReq* const req =
-      CAST_PTR(ConfigChangeImplReq, ssig.getDataPtrSend());
-    req->requestType = ConfigChangeImplReq::Abort;
-
-    g_eventLogger->debug("Sending CONFIG_CHANGE_IMPL_REQ(abort) to node %d",
-                         nodeId);
-    require(m_waiting_for.isclear());
-    m_waiting_for = ss.broadcastSignal(m_all_mgm, ssig,
-                                  MGM_CONFIG_MAN,
-                                  GSN_CONFIG_CHANGE_IMPL_REQ,
-                                  ConfigChangeImplReq::SignalLength);
-    if (m_waiting_for.isclear())
-      set_config_change_state(ConfigChangeState::IDLE);
-    else
-      set_config_change_state(ConfigChangeState::ABORTING);
+    startAbortConfigChange(ss);
     break;
   }
-
   case ConfigChangeState::COMITTING:
     /* Got ref while comitting, impossible */
     abort();
     break;
 
-  case ConfigChangeState::ABORT:{
-    /* Got ref(another) while already decided to abort */
-    m_waiting_for.clear(nodeId);
-    if (!m_waiting_for.isclear())
-      return;
-
-    /* Abort all other nodes */
-    SimpleSignal ssig;
-    ConfigChangeImplReq* const req =
-      CAST_PTR(ConfigChangeImplReq, ssig.getDataPtrSend());
-    req->requestType = ConfigChangeImplReq::Abort;
-
-    g_eventLogger->debug("Sending CONFIG_CHANGE_IMPL_REQ(abort) to node %d",
-                         nodeId);
-    require(m_waiting_for.isclear());
-    m_waiting_for = ss.broadcastSignal(m_all_mgm, ssig,
-                                  MGM_CONFIG_MAN,
-                                  GSN_CONFIG_CHANGE_IMPL_REQ,
-                                  ConfigChangeImplReq::SignalLength);
-    if (m_waiting_for.isclear())
-      set_config_change_state(ConfigChangeState::IDLE);
-    else
-      set_config_change_state(ConfigChangeState::ABORTING);
-    break;
-  }
-
   case ConfigChangeState::ABORTING:
     /* Got ref while aborting, impossible */
     abort();
@@ -1036,13 +962,34 @@ ConfigManager::execCONFIG_CHANGE_IMPL_CO
     CAST_CONSTPTR(ConfigChangeImplConf, sig->getDataPtr());
   g_eventLogger->debug("Got CONFIG_CHANGE_IMPL_CONF from node %d", nodeId);
 
-  switch(m_config_change_state){
+  switch(m_config_change.m_state){
   case ConfigChangeState::PREPARING:{
     require(conf->requestType == ConfigChangeImplReq::Prepare);
     m_waiting_for.clear(nodeId);
     if (!m_waiting_for.isclear())
       return;
 
+    // send to next
+    int res = sendConfigChangeImplReq(ss, m_config_change.m_new_config);
+    if (res > 0)
+    {
+      // sent to new node...
+      return;
+    }
+    else if (res < 0)
+    {
+      // send failed, start abort
+      startAbortConfigChange(ss);
+      return;
+    }
+
+    /**
+     * All node has received new config..
+     *   ok to delete it...
+     */
+    delete m_config_change.m_new_config;
+    m_config_change.m_new_config = 0;
+
     /* Send commit to all nodes */
     SimpleSignal ssig;
     ConfigChangeImplReq* const req =
@@ -1052,10 +999,10 @@ ConfigManager::execCONFIG_CHANGE_IMPL_CO
 
     g_eventLogger->debug("Sending CONFIG_CHANGE_IMPL_REQ(commit)");
     require(m_waiting_for.isclear());
-    m_waiting_for = ss.broadcastSignal(m_all_mgm, ssig,
-                                  MGM_CONFIG_MAN,
-                                  GSN_CONFIG_CHANGE_IMPL_REQ,
-                                  ConfigChangeImplReq::SignalLength);
+    m_waiting_for = ss.broadcastSignal(m_config_change.m_contacted_nodes, ssig,
+                                       MGM_CONFIG_MAN,
+                                       GSN_CONFIG_CHANGE_IMPL_REQ,
+                                       ConfigChangeImplReq::SignalLength);
     if (m_waiting_for.isclear())
       set_config_change_state(ConfigChangeState::IDLE);
     else
@@ -1070,9 +1017,9 @@ ConfigManager::execCONFIG_CHANGE_IMPL_CO
     if (!m_waiting_for.isclear())
       return;
 
-    require(m_client_ref != RNIL);
-    require(m_config_change_error == 0);
-    if (m_client_ref == ss.getOwnRef())
+    require(m_config_change.m_client_ref != RNIL);
+    require(m_config_change.m_error == 0);
+    if (m_config_change.m_client_ref == ss.getOwnRef())
     {
       g_eventLogger->info("Config change completed! New generation: %d",
                           m_config->getGeneration());
@@ -1080,9 +1027,9 @@ ConfigManager::execCONFIG_CHANGE_IMPL_CO
     else
     {
       /* Send CONF to requestor */
-      sendConfigChangeConf(ss, m_client_ref);
+      sendConfigChangeConf(ss, m_config_change.m_client_ref);
     }
-    m_client_ref = RNIL;
+    m_config_change.m_client_ref = RNIL;
     set_config_change_state(ConfigChangeState::IDLE);
     break;
   }
@@ -1092,22 +1039,7 @@ ConfigManager::execCONFIG_CHANGE_IMPL_CO
     if (!m_waiting_for.isclear())
       return;
 
-    /* Abort all other nodes */
-    SimpleSignal ssig;
-    ConfigChangeImplReq* const req =
-      CAST_PTR(ConfigChangeImplReq, ssig.getDataPtrSend());
-    req->requestType = ConfigChangeImplReq::Abort;
-
-    g_eventLogger->debug("Sending CONFIG_CHANGE_IMPL_REQ(abort)");
-    require(m_waiting_for.isclear());
-    m_waiting_for = ss.broadcastSignal(m_all_mgm, ssig,
-                                  MGM_CONFIG_MAN,
-                                  GSN_CONFIG_CHANGE_IMPL_REQ,
-                                  ConfigChangeImplReq::SignalLength);
-    if (m_waiting_for.isclear())
-      set_config_change_state(ConfigChangeState::IDLE);
-    else
-      set_config_change_state(ConfigChangeState::ABORTING);
+    startAbortConfigChange(ss);
     break;
   }
 
@@ -1116,24 +1048,24 @@ ConfigManager::execCONFIG_CHANGE_IMPL_CO
     if (!m_waiting_for.isclear())
       return;
 
-    require(m_client_ref != RNIL);
-    require(m_config_change_error);
-    if (m_client_ref == ss.getOwnRef())
+    require(m_config_change.m_client_ref != RNIL);
+    require(m_config_change.m_error);
+    if (m_config_change.m_client_ref == ss.getOwnRef())
     {
       g_eventLogger->
         error("Configuration change failed! error: %d '%s'",
-              m_config_change_error,
-              ConfigChangeRef::errorMessage(m_config_change_error));
+              m_config_change.m_error,
+              ConfigChangeRef::errorMessage(m_config_change.m_error));
       exit(1);
     }
     else
     {
       /* Send ref to the requestor */
-      sendConfigChangeRef(ss, m_client_ref,
-                          m_config_change_error);
+      sendConfigChangeRef(ss, m_config_change.m_client_ref,
+                          m_config_change.m_error);
     }
-    m_config_change_error= ConfigChangeRef::OK;
-    m_client_ref = RNIL;
+    m_config_change.m_error= ConfigChangeRef::OK;
+    m_config_change.m_client_ref = RNIL;
     set_config_change_state(ConfigChangeState::IDLE);
     break;
   }
@@ -1178,44 +1110,85 @@ ConfigManager::sendConfigChangeConf(Sign
 
 
 void
-ConfigManager::startInitConfigChange(SignalSender& ss)
+ConfigManager::startConfigChange(SignalSender& ss)
 {
-  require(m_config_state == CS_INITIAL);
-  g_eventLogger->info("Starting initial configuration change");
-  m_client_ref = ss.getOwnRef();
-  if (!sendConfigChangeImplReq(ss, m_new_config))
+  if (m_config_state == CS_INITIAL)
+  {
+    g_eventLogger->info("Starting initial configuration change");
+  }
+  else
   {
-    g_eventLogger->error("Failed to start initial configuration change!");
+    require(m_config_state == CS_CONFIRMED);
+    g_eventLogger->info("Starting configuration change, generation: %d",
+                        m_config_change.m_new_config->getGeneration());
+  }
+  m_config_change.m_contacted_nodes.clear();
+  m_config_change.m_client_ref = ss.getOwnRef();
+  if (sendConfigChangeImplReq(ss, m_config_change.m_new_config) <= 0)
+  {
+    g_eventLogger->error("Failed to start configuration change!");
     exit(1);
   }
 }
 
-
 void
-ConfigManager::startNewConfigChange(SignalSender& ss)
+ConfigManager::startAbortConfigChange(SignalSender& ss)
 {
-  require(m_config_state == CS_CONFIRMED);
-  g_eventLogger->info("Starting configuration change, generation: %d",
-                      m_new_config->getGeneration());
-  m_client_ref = ss.getOwnRef();
-  if (!sendConfigChangeImplReq(ss, m_new_config))
+  /* Abort all other nodes */
+  SimpleSignal ssig;
+  ConfigChangeImplReq* const req =
+    CAST_PTR(ConfigChangeImplReq, ssig.getDataPtrSend());
+  req->requestType = ConfigChangeImplReq::Abort;
+
+  g_eventLogger->debug
+    ("Sending CONFIG_CHANGE_IMPL_REQ(abort) to %s",
+     BaseString::getPrettyText(m_config_change.m_contacted_nodes).c_str());
+
+  require(m_waiting_for.isclear());
+  m_waiting_for = ss.broadcastSignal(m_config_change.m_contacted_nodes, ssig,
+                                     MGM_CONFIG_MAN,
+                                     GSN_CONFIG_CHANGE_IMPL_REQ,
+                                     ConfigChangeImplReq::SignalLength);
+  if (m_waiting_for.isclear())
+    set_config_change_state(ConfigChangeState::IDLE);
+  else
+    set_config_change_state(ConfigChangeState::ABORTING);
+
+  if (m_config_change.m_new_config)
   {
-    g_eventLogger->error("Failed to start configuration change!");
-    exit(1);
+    delete m_config_change.m_new_config;
+    m_config_change.m_new_config = 0;
   }
-
-  /* The new config has been sent and can now be discarded */
-  delete m_new_config;
-  m_new_config = NULL;
 }
 
-
-bool
+int
 ConfigManager::sendConfigChangeImplReq(SignalSender& ss, const Config* conf)
 {
-  require(m_client_ref != RNIL);
+  require(m_waiting_for.isclear());
+  require(m_config_change.m_client_ref != RNIL);
 
-  /* Send prepare to all MGM nodes */
+  if (m_config_change.m_contacted_nodes.isclear())
+  {
+    require(m_config_change.m_state == ConfigChangeState::IDLE);
+  }
+  else
+  {
+    require(m_config_change.m_state == ConfigChangeState::PREPARING);
+  }
+
+  set_config_change_state(ConfigChangeState::PREPARING);
+
+  NodeBitmask nodes = m_all_mgm;
+  nodes.bitANDC(m_config_change.m_contacted_nodes);
+  if (nodes.isclear())
+  {
+    return 0; // all done
+  }
+
+  /**
+   * Send prepare to all MGM nodes 1 by 1
+   *   keep track of which I sent to in m_contacted_nodes
+   */
   SimpleSignal ssig;
 
   UtilBuffer buf;
@@ -1230,55 +1203,25 @@ ConfigManager::sendConfigChangeImplReq(S
   req->initial = (m_config_state == CS_INITIAL);
   req->length = buf.length();
 
-  require(m_waiting_for.isclear());
-  require(m_config_change_state == ConfigChangeState::IDLE);
-
-  g_eventLogger->debug("Sending CONFIG_CHANGE_IMPL_REQ(prepare)");
-  unsigned i = 0;
-  while((i = m_all_mgm.find(i+1)) != NodeBitmask::NotFound)
-  {
-    g_eventLogger->debug(" - to node %d", i);
-    int result =
-      ss.sendFragmentedSignal(i, ssig, MGM_CONFIG_MAN,
-                              GSN_CONFIG_CHANGE_IMPL_REQ,
-                              ConfigChangeImplReq::SignalLength);
-    if (result != 0)
-    {
-      g_eventLogger->warning("Failed to send configuration change "
-                             "prepare to node: %d, result: %d",
-                             i, result);
-      break;
-    }
-    ssig.header.m_noOfSections = 1; // reset by sendFragmentedSignal
-
-    m_waiting_for.set(i);
-  }
-
-  if (!m_all_mgm.equal(m_waiting_for))
+  Uint32 i = nodes.find(0);
+  g_eventLogger->debug("Sending CONFIG_CHANGE_IMPL_REQ(prepare) to %u", i);
+  int result = ss.sendFragmentedSignal(i, ssig, MGM_CONFIG_MAN,
+                                       GSN_CONFIG_CHANGE_IMPL_REQ,
+                                       ConfigChangeImplReq::SignalLength);
+  if (result != 0)
   {
-    // Could not send prepare to all nodes
-    m_config_change_error = ConfigChangeRef::SendFailed;
-    if (!m_waiting_for.isclear())
-    {
-      // Some nodes got prepare, set state to
-      // abort and continue abort when result
-      // of prepare arrives
-      set_config_change_state(ConfigChangeState::ABORT);
-      return false;
-    }
-
-    // No node has got prepare
-    return false;
+    g_eventLogger->warning("Failed to send configuration change "
+                           "prepare to node: %d, result: %d",
+                           i, result);
+    return -1;
   }
 
-  // Prepare has been sent to all mgm nodes
-  // continue and wait for prepare conf(s)
-  set_config_change_state(ConfigChangeState::PREPARING);
-  return true;
+  m_waiting_for.set(i);
+  m_config_change.m_contacted_nodes.set(i);
 
+  return 1;
 }
 
-
 void
 ConfigManager::execCONFIG_CHANGE_REQ(SignalSender& ss, SimpleSignal* sig)
 {
@@ -1301,12 +1244,12 @@ ConfigManager::execCONFIG_CHANGE_REQ(Sig
     return;
   }
 
-  if (m_config_change_state != ConfigChangeState::IDLE)
+  if (m_config_change.m_state != ConfigChangeState::IDLE)
   {
     sendConfigChangeRef(ss, from, ConfigChangeRef::ConfigChangeOnGoing);
     return;
   }
-  require(m_config_change_error == ConfigChangeRef::OK);
+  require(m_config_change.m_error == ConfigChangeRef::OK);
 
   if (sig->header.m_noOfSections != 1)
   {
@@ -1321,23 +1264,19 @@ ConfigManager::execCONFIG_CHANGE_REQ(Sig
     return;
   }
 
-  Config new_config(cf.getConfigValues());
-  if (!config_ok(&new_config))
+  Config * new_config = new Config(cf.getConfigValues());
+  if (!config_ok(new_config))
   {
     g_eventLogger->warning("Refusing to start config change, the config "\
                            "is not ok");
     sendConfigChangeRef(ss, from, ConfigChangeRef::ConfigNotOk);
+    delete new_config;
     return;
   }
 
-  m_client_ref = from;
-  if (!sendConfigChangeImplReq(ss, &new_config))
-  {
-    assert(m_config_change_error);
-    sendConfigChangeRef(ss, from,
-                        m_config_change_error);
-    return;
-  }
+  m_config_change.m_client_ref = from;
+  m_config_change.m_new_config = new_config;
+  startConfigChange(ss);
 
   return;
 }
@@ -1691,8 +1630,8 @@ ConfigManager::execCONFIG_CHECK_REF(Sign
       g_eventLogger->info("The fetched configuration has been saved!");
       m_waiting_for.clear(nodeId);
       m_checked.set(nodeId);
-      delete m_new_config;
-      m_new_config = NULL;
+      delete m_config_change.m_initial_config;
+      m_config_change.m_initial_config = NULL;
       return;
     }
     break;
@@ -1728,6 +1667,62 @@ ConfigManager::set_facade(TransporterFac
   require(m_ss != 0);
 }
 
+bool
+ConfigManager::ConfigChange::config_loaded(Config* config)
+{
+  if (m_loaded_config != 0)
+    return false;
+  m_loaded_config = config;
+  return true;
+}
+
+Config*
+ConfigManager::prepareLoadedConfig(Config * new_conf)
+{
+  /* Copy the necessary values from old to new config */
+  if (!new_conf->setGeneration(m_config->getGeneration()))
+  {
+    g_eventLogger->error("Failed to copy generation from old config");
+    delete new_conf;
+    return 0;
+  }
+
+  if (!new_conf->setName(m_config->getName()))
+  {
+    g_eventLogger->error("Failed to copy name from old config");
+    delete new_conf;
+    return 0;
+  }
+
+  if (!new_conf->setPrimaryMgmNode(m_config->getPrimaryMgmNode()))
+  {
+    g_eventLogger->error("Failed to copy primary mgm node from old config");
+    delete new_conf;
+    return 0;
+  }
+
+  /* Check if config has changed */
+  if (!m_config->equal(new_conf))
+  {
+    /* Loaded config is different */
+    BaseString buf;
+    g_eventLogger->info("Detected change of %s on disk, will try to "
+                        "set it. "
+                        "This is the actual diff:\n%s",
+                        m_opts.mycnf ? "my.cnf" : m_opts.config_filename,
+                        m_config->diff2str(new_conf, buf));
+
+    return new_conf;
+  }
+  else
+  {
+    /* Loaded config was equal to current */
+    g_eventLogger->info("Config equal!");
+    delete new_conf;
+  }
+  return 0;
+}
+
 void
 ConfigManager::run()
 {
@@ -1743,7 +1738,7 @@ ConfigManager::run()
 
     /* Confirm the present config, free the space that was allocated for a
        new one, and terminate the manager thread */
-    delete m_new_config; 
+    m_config_change.release();
     m_config_state = CS_CONFIRMED;
     ndbout_c("== ConfigManager disabled -- manager thread will exit ==");
     return;
@@ -1765,7 +1760,7 @@ ConfigManager::run()
   while (!is_stopped())
   {
 
-    if (m_config_change_state == ConfigChangeState::IDLE)
+    if (m_config_change.m_state == ConfigChangeState::IDLE)
     {
       bool print_state = false;
       if (m_previous_state != m_config_state)
@@ -1796,12 +1791,15 @@ ConfigManager::run()
         if (print_state)
           ndbout_c("==INITIAL==");
 
-        if (m_new_config &&                     // Updated config.ini was found
+        if (m_config_change.m_initial_config && // Updated config.ini was found
             m_started.equal(m_all_mgm) &&       // All mgmd started
             m_checked.equal(m_started) &&       // All nodes checked
             m_all_mgm.find(0) == m_facade->ownId()) // Lowest nodeid
         {
-            startInitConfigChange(ss);
+          Config* new_conf = m_config_change.m_initial_config;
+          m_config_change.m_initial_config = 0;
+          m_config_change.m_new_config = new_conf;
+          startConfigChange(ss);
         }
         break;
 
@@ -1809,11 +1807,21 @@ ConfigManager::run()
         if (print_state)
           ndbout_c("==CONFIRMED==");
 
-        if (m_new_config &&                 // Updated config.ini was found
+        if (m_config_change.m_loaded_config != 0 &&
+            m_config_change.m_new_config == 0    &&
+            m_started.equal(m_all_mgm)           &&
+            m_checked.equal(m_started))
+        {
+          Config* new_conf = m_config_change.m_loaded_config;
+          m_config_change.m_loaded_config = 0;
+          m_config_change.m_new_config = prepareLoadedConfig(new_conf);
+        }
+
+        if (m_config_change.m_new_config && // Updated config.ini was found
             m_started.equal(m_all_mgm) &&   // All mgmd started
             m_checked.equal(m_started))     // All nodes checked
         {
-          startNewConfigChange(ss);
+          startConfigChange(ss);
         }
 
         break;
@@ -1823,8 +1831,9 @@ ConfigManager::run()
       }
 
       // Send CHECK_CONFIG to all nodes not yet checked
-      if (m_waiting_for.isclear() &&    // Nothing else ongoing
-          !m_checked.equal(m_started))  // Some nodes have not been checked
+      if (m_waiting_for.isclear() &&   // Nothing outstanding
+          m_prepared_config == 0 &&    //   and no config change ongoing
+          !m_checked.equal(m_started)) // Some nodes have not been checked
       {
         NodeBitmask not_checked;
         not_checked.assign(m_started);
@@ -1870,7 +1879,7 @@ ConfigManager::run()
       m_checked.clear(nodeId);
       m_defragger.node_failed(nodeId);
 
-      if (m_config_change_state != ConfigChangeState::IDLE)
+      if (m_config_change.m_state != ConfigChangeState::IDLE)
       {
         g_eventLogger->info("Node %d failed during config change!!",
                             nodeId);
@@ -2205,7 +2214,7 @@ ConfigManager::get_packed_config(ndb_mgm
     {
       error.assign("The cluster configuration is not yet confirmed "
                    "by all defined management servers. ");
-      if (m_config_change_state != ConfigChangeState::IDLE)
+      if (m_config_change.m_state != ConfigChangeState::IDLE)
       {
         error.append("Initial configuration change is in progress.");
       }

=== modified file 'storage/ndb/src/mgmsrv/ConfigManager.hpp'
--- a/storage/ndb/src/mgmsrv/ConfigManager.hpp	2010-01-14 14:32:29 +0000
+++ b/storage/ndb/src/mgmsrv/ConfigManager.hpp	2010-09-17 14:30:59 +0000
@@ -37,7 +37,6 @@ class ConfigManager : public MgmtThread 
 
   NdbMutex *m_config_mutex;
   const Config * m_config;
-  const Config * m_new_config;
   BaseString m_packed_config; // base64 packed
 
   ConfigRetriever m_config_retriever;
@@ -55,7 +54,7 @@ class ConfigManager : public MgmtThread 
       m_current_state(IDLE) {}
 
     operator int() const { return m_current_state; }
-  } m_config_change_state;
+  };
 
   void set_config_change_state(ConfigChangeState::States state);
 
@@ -71,10 +70,44 @@ class ConfigManager : public MgmtThread 
   ConfigState m_config_state;
   ConfigState m_previous_state;
 
-  /* The original error that caused config change to be aborted */
-  ConfigChangeRef::ErrorCode m_config_change_error;
+  struct ConfigChange
+  {
+    ConfigChange() :
+      m_client_ref(RNIL),
+      m_error(ConfigChangeRef::OK),
+      m_new_config(0),
+      m_loaded_config(0),
+      m_initial_config(0)
+      {}
+
+    void release() {
+      if (m_new_config)
+        delete m_new_config;
+      if (m_loaded_config)
+        delete m_loaded_config;
+      if (m_initial_config)
+        delete m_initial_config;
+      m_new_config = 0;
+      m_loaded_config = 0;
+      m_initial_config = 0;
+    }
+
+    virtual ~ConfigChange() {
+      release();
+    }
+
+    ConfigChangeState m_state;
+    BlockReference m_client_ref;
+    /* The original error that caused config change to be aborted */
+    ConfigChangeRef::ErrorCode m_error;
+    const Config * m_new_config;
+
+    bool config_loaded(Config* config);
+    Config* m_loaded_config;
+    Config* m_initial_config;
+    NodeBitmask m_contacted_nodes;
+  } m_config_change;
 
-  BlockReference m_client_ref;
   BaseString m_config_name;
   Config* m_prepared_config;
 
@@ -111,14 +144,17 @@ class ConfigManager : public MgmtThread 
   /* Check config is ok */
   bool config_ok(const Config* conf);
 
+  /* Prepare loaded config */
+  Config* prepareLoadedConfig(Config* config);
+
   /* Functions for writing config.bin to disk */
   bool prepareConfigChange(const Config* config);
   void commitConfigChange();
   void abortConfigChange();
 
   /* Functions for starting config change from ConfigManager */
-  void startInitConfigChange(SignalSender& ss);
-  void startNewConfigChange(SignalSender& ss);
+  void startConfigChange(SignalSender& ss);
+  void startAbortConfigChange(SignalSender&);
 
   /* CONFIG_CHANGE - controlling config change from other node */
   void execCONFIG_CHANGE_REQ(SignalSender& ss, SimpleSignal* sig);
@@ -136,7 +172,7 @@ class ConfigManager : public MgmtThread 
   void execCONFIG_CHANGE_IMPL_CONF(SignalSender& ss, SimpleSignal* sig);
   void sendConfigChangeImplRef(SignalSender& ss, NodeId nodeId,
                                ConfigChangeRef::ErrorCode) const;
-  bool sendConfigChangeImplReq(SignalSender& ss, const Config* conf);
+  int sendConfigChangeImplReq(SignalSender& ss, const Config* conf);
 
   /*
     CONFIG_CHECK - protocol for exchanging and checking config state

=== modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.cpp'
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2010-08-30 09:51:49 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2010-09-23 07:31:51 +0000
@@ -45,6 +45,7 @@
 #include <signaldata/DropNodegroup.hpp>
 #include <signaldata/DbinfoScan.hpp>
 #include <NdbSleep.h>
+#include <portlib/NdbDir.hpp>
 #include <EventLogger.hpp>
 #include <DebuggerNames.hpp>
 #include <ndb_version.h>
@@ -594,8 +595,6 @@ MgmtSrvr::start()
 void
 MgmtSrvr::setClusterLog(const Config* config)
 {
-  g_eventLogger->close();
-
   DBUG_ASSERT(_ownNodeId);
 
   ConfigIter iter(config, CFG_SECTION_NODE);
@@ -605,7 +604,13 @@ MgmtSrvr::setClusterLog(const Config* co
   const char *datadir;
   require(iter.get(CFG_NODE_DATADIR, &datadir) == 0);
   NdbConfig_SetPath(datadir);
-  my_setwd(NdbConfig_get_path(0), MYF(0));
+
+  if (NdbDir::chdir(NdbConfig_get_path(NULL)) != 0)
+  {
+    g_eventLogger->warning("Cannot change directory to '%s', error: %d",
+                           NdbConfig_get_path(NULL), errno);
+    // Ignore error
+  }
 
   // Get log destination from config
   BaseString logdest;
@@ -624,6 +629,8 @@ MgmtSrvr::setClusterLog(const Config* co
     logdest_configured = false;
   }
 
+  g_eventLogger->close();
+
   int err= 0;
   char errStr[100]= {0};
   if(!g_eventLogger->addHandler(logdest, &err, sizeof(errStr), errStr)) {

=== modified file 'storage/ndb/src/mgmsrv/main.cpp'
--- a/storage/ndb/src/mgmsrv/main.cpp	2010-08-28 09:37:09 +0000
+++ b/storage/ndb/src/mgmsrv/main.cpp	2010-09-23 07:31:51 +0000
@@ -28,6 +28,7 @@
 #include <portlib/ndb_daemon.h>
 #include <NdbConfig.h>
 #include <NdbSleep.h>
+#include <portlib/NdbDir.hpp>
 #include <ndb_version.h>
 #include <mgmapi_config_parameters.h>
 #include <NdbAutoPtr.hpp>
@@ -156,7 +157,7 @@ static struct my_option my_long_options[
 
 static void short_usage_sub(void)
 {
-  ndb_short_usage_sub(my_progname, NULL);
+  ndb_short_usage_sub(NULL);
   ndb_service_print_options("ndb_mgmd");
 }
 
@@ -187,7 +188,7 @@ static int mgmd_main(int argc, char** ar
 
   printf("MySQL Cluster Management Server %s\n", NDB_VERSION_STRING);
 
-  ndb_opt_set_usage_funcs(NULL, short_usage_sub, usage);
+  ndb_opt_set_usage_funcs(short_usage_sub, usage);
 
   load_defaults("my",load_default_groups,&argc,&argv);
   defaults_argv= argv; /* Must be freed by 'free_defaults' */
@@ -267,7 +268,12 @@ static int mgmd_main(int argc, char** ar
       mgmd_exit(1);
     }
 
-    my_setwd(NdbConfig_get_path(0), MYF(0));
+    if (NdbDir::chdir(NdbConfig_get_path(NULL)) != 0)
+    {
+      g_eventLogger->warning("Cannot change directory to '%s', error: %d",
+                             NdbConfig_get_path(NULL), errno);
+      // Ignore error
+    }
 
     if (opts.daemon)
     {

=== modified file 'storage/ndb/src/ndbapi/DictCache.cpp'
--- a/storage/ndb/src/ndbapi/DictCache.cpp	2009-09-16 11:12:55 +0000
+++ b/storage/ndb/src/ndbapi/DictCache.cpp	2010-09-22 12:10:34 +0000
@@ -361,6 +361,36 @@ GlobalDictCache::invalidate_all()
 }
 
 void
+GlobalDictCache::invalidateDb(const char * name, size_t len)
+{
+  DBUG_ENTER("GlobalDictCache::invalidateDb");
+  NdbElement_t<Vector<TableVersion> > * curr = m_tableHash.getNext(0);
+  while(curr != 0)
+  {
+    Vector<TableVersion> * vers = curr->theData;
+    if (vers->size())
+    {
+      TableVersion * ver = & vers->back();
+      if (ver->m_status != RETREIVING)
+      {
+        if (ver->m_impl->matchDb(name, len))
+        {
+          ver->m_impl->m_status = NdbDictionary::Object::Invalid;
+          ver->m_status = DROPPED;
+          if (ver->m_refCount == 0)
+          {
+            delete ver->m_impl;
+            vers->erase(vers->size() - 1);
+          }
+        }
+      }
+    }
+    curr = m_tableHash.getNext(curr);
+  }
+  DBUG_VOID_RETURN;
+}
+
+void
 GlobalDictCache::release(const NdbTableImpl * tab, int invalidate)
 {
   DBUG_ENTER("GlobalDictCache::release");

=== modified file 'storage/ndb/src/ndbapi/DictCache.hpp'
--- a/storage/ndb/src/ndbapi/DictCache.hpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/src/ndbapi/DictCache.hpp	2010-09-22 12:10:34 +0000
@@ -88,6 +88,8 @@ public:
     return chg_ref_count(impl, -1);
   }
 
+  void invalidateDb(const char * name, size_t len);
+
 public:
   enum Status {
     OK = 0,

=== modified file 'storage/ndb/src/ndbapi/NdbDictionary.cpp'
--- a/storage/ndb/src/ndbapi/NdbDictionary.cpp	2010-08-26 16:01:10 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionary.cpp	2010-09-23 11:55:42 +0000
@@ -2561,7 +2561,13 @@ NdbDictionary::Dictionary::invalidateInd
 int
 NdbDictionary::Dictionary::forceGCPWait()
 {
-  return m_impl.forceGCPWait();
+  return forceGCPWait(0);
+}
+
+int
+NdbDictionary::Dictionary::forceGCPWait(int type)
+{
+  return m_impl.forceGCPWait(type);
 }
 
 void
@@ -3459,6 +3465,18 @@ NdbDictionary::Dictionary::getUndofile(U
   return tmp;
 }
 
+void
+NdbDictionary::Dictionary::invalidateDbGlobal(const char * name)
+{
+  if (m_impl.m_globalHash && name != 0)
+  {
+    size_t len = strlen(name);
+    m_impl.m_globalHash->lock();
+    m_impl.m_globalHash->invalidateDb(name, len);
+    m_impl.m_globalHash->unlock();
+  }
+}
+
 int
 NdbDictionary::Dictionary::beginSchemaTrans()
 {

=== modified file 'storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp'
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2010-08-30 09:51:49 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2010-09-14 09:57:29 +0000
@@ -2280,7 +2280,7 @@ NdbDictInterface::dictSignal(NdbApiSigna
     }    
     
     m_error.code= 0;
-    int ret_val= poll_guard.wait_n_unlock(timeout, node, wst);
+    int ret_val= poll_guard.wait_n_unlock(timeout, node, wst, true);
     // End of Protected area  
     
     if(ret_val == 0 && m_error.code == 0){
@@ -5654,7 +5654,8 @@ NdbDictInterface::listObjects(NdbApiSign
     }
     m_error.code= 0;
     int ret_val= poll_guard.wait_n_unlock(DICT_WAITFOR_TIMEOUT,
-                                          aNodeId, WAIT_LIST_TABLES_CONF);
+                                          aNodeId, WAIT_LIST_TABLES_CONF,
+                                          true);
     // end protected
     if (ret_val == 0 && m_error.code == 0)
       return 0;
@@ -5760,42 +5761,74 @@ NdbDictInterface::execOLD_LIST_TABLES_CO
 }
 
 int
-NdbDictionaryImpl::forceGCPWait()
+NdbDictionaryImpl::forceGCPWait(int type)
 {
-  return m_receiver.forceGCPWait();
+  return m_receiver.forceGCPWait(type);
 }
 
 int
-NdbDictInterface::forceGCPWait()
+NdbDictInterface::forceGCPWait(int type)
 {
   NdbApiSignal tSignal(m_reference);
-  WaitGCPReq* const req = CAST_PTR(WaitGCPReq, tSignal.getDataPtrSend());
-  req->senderRef = m_reference;
-  req->senderData = 0;
-  req->requestType = WaitGCPReq::CompleteForceStart;
-  tSignal.theReceiversBlockNumber = DBDIH;
-  tSignal.theVerId_signalNumber = GSN_WAIT_GCP_REQ;
-  tSignal.theLength = WaitGCPReq::SignalLength;
-
-  const Uint32 RETRIES = 100;
-  for (Uint32 i = 0; i < RETRIES; i++)
+  if (type == 0)
   {
-    m_transporter->lock_mutex();
-    Uint16 aNodeId = m_transporter->get_an_alive_node();
-    if (aNodeId == 0) {
-      m_error.code= 4009;
+    WaitGCPReq* const req = CAST_PTR(WaitGCPReq, tSignal.getDataPtrSend());
+    req->senderRef = m_reference;
+    req->senderData = 0;
+    req->requestType = WaitGCPReq::CompleteForceStart;
+    tSignal.theReceiversBlockNumber = DBDIH;
+    tSignal.theVerId_signalNumber = GSN_WAIT_GCP_REQ;
+    tSignal.theLength = WaitGCPReq::SignalLength;
+
+    const Uint32 RETRIES = 100;
+    for (Uint32 i = 0; i < RETRIES; i++)
+    {
+      m_transporter->lock_mutex();
+      Uint16 aNodeId = m_transporter->get_an_alive_node();
+      if (aNodeId == 0) {
+        m_error.code= 4009;
+        m_transporter->unlock_mutex();
+        return -1;
+      }
+      if (m_transporter->sendSignal(&tSignal, aNodeId) != 0) {
+        m_transporter->unlock_mutex();
+        continue;
+      }
+
+      m_error.code= 0;
+      m_waiter.m_node = aNodeId;
+      m_waiter.m_state = WAIT_LIST_TABLES_CONF;
+      m_waiter.wait(DICT_WAITFOR_TIMEOUT);
       m_transporter->unlock_mutex();
-      return -1;
+      return 0;
     }
-    if (m_transporter->sendSignal(&tSignal, aNodeId) != 0) {
+    return -1;
+  }
+  else if (type == 1)
+  {
+    tSignal.getDataPtrSend()[0] = 6099;
+    tSignal.theReceiversBlockNumber = DBDIH;
+    tSignal.theVerId_signalNumber = GSN_DUMP_STATE_ORD;
+    tSignal.theLength = 1;
+
+    const Uint32 RETRIES = 100;
+    for (Uint32 i = 0; i < RETRIES; i++)
+    {
+      m_transporter->lock_mutex();
+      Uint16 aNodeId = m_transporter->get_an_alive_node();
+      if (aNodeId == 0) {
+        m_error.code= 4009;
+        m_transporter->unlock_mutex();
+        return -1;
+      }
+      if (m_transporter->sendSignal(&tSignal, aNodeId) != 0) {
+        m_transporter->unlock_mutex();
+        continue;
+      }
+
+      m_transporter->forceSend(refToBlock(m_reference));
       m_transporter->unlock_mutex();
-      continue;
     }
-    m_error.code= 0;
-    m_waiter.m_node = aNodeId;
-    m_waiter.m_state = WAIT_LIST_TABLES_CONF;
-    m_waiter.wait(DICT_WAITFOR_TIMEOUT);
-    m_transporter->unlock_mutex();    
     return 0;
   }
   return -1;

=== modified file 'storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp	2010-07-26 12:08:40 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp	2010-09-22 12:10:34 +0000
@@ -181,6 +181,8 @@ public:
   const char * getMysqlName() const;
   int updateMysqlName();
 
+  bool matchDb(const char * name, size_t len) const;
+
   int aggregate(NdbError& error);
   int validate(NdbError& error);
 
@@ -658,7 +660,7 @@ public:
 			  LinearSectionPtr ptr[3],
 			  Uint32 noOfSections, bool fullyQualifiedNames);
 
-  int forceGCPWait();
+  int forceGCPWait(int type);
 
   static int parseTableInfo(NdbTableImpl ** dst, 
 			    const Uint32 * data, Uint32 len,
@@ -833,7 +835,7 @@ public:
   int executeSubscribeEvent(NdbEventOperationImpl &, Uint32 & buckets);
   int stopSubscribeEvent(NdbEventOperationImpl &);
 
-  int forceGCPWait();
+  int forceGCPWait(int type);
 
   int listObjects(List& list, NdbDictionary::Object::Type type, 
                   bool fullyQualified);
@@ -1089,6 +1091,15 @@ NdbTableImpl::getMysqlName() const
 }
 
 inline
+bool
+NdbTableImpl::matchDb(const char * name, size_t len) const
+{
+  return 
+    len < m_internalName.length() &&
+    memcmp(name, m_internalName.c_str(), len) == 0;
+}
+
+inline
 Uint32
 Hash( const char* str ){
   Uint32 h = 0;

=== modified file 'storage/ndb/test/include/NdbRestarter.hpp'
--- a/storage/ndb/test/include/NdbRestarter.hpp	2010-02-18 23:50:31 +0000
+++ b/storage/ndb/test/include/NdbRestarter.hpp	2010-09-20 13:09:18 +0000
@@ -96,6 +96,8 @@ public:
   int getMasterNodeVersion(int& version);
   int getNodeTypeVersionRange(ndb_mgm_node_type type, int& minVer, int& maxVer);
   
+  int getNodeStatus(int nodeId); // return NDB_MGM_NODE_STATUS_*
+
   NdbMgmHandle handle;  
 
   enum NodeSelector

=== modified file 'storage/ndb/test/ndbapi/testMgmd.cpp'
--- a/storage/ndb/test/ndbapi/testMgmd.cpp	2010-05-10 19:31:55 +0000
+++ b/storage/ndb/test/ndbapi/testMgmd.cpp	2010-09-22 11:53:53 +0000
@@ -26,7 +26,7 @@
 #include <NDBT_Find.hpp>
 #include <NDBT_Workingdir.hpp>
 
-static bool file_exists(const char* path)
+static bool file_exists(const char* path, Uint32 timeout = 1)
 {
   g_info << "File '" << path << "' ";
   /**
@@ -35,7 +35,7 @@ static bool file_exists(const char* path
    *   which means that it can be on disk, wo/ being visible
    *   remedy this by retrying some
    */
-  for (int i = 0; i<10; i++)
+  for (Uint32 i = 0; i < 10 * timeout; i++)
   {
     if (access(path, F_OK) == 0)
     {
@@ -548,12 +548,13 @@ int runTestBug45495(NDBT_Context* ctx, N
                          "ndb_2_config.bin.1",
                          NULL).c_str()));
 
+  Uint32 timeout = 30;
   CHECK(file_exists(path(wd.path(),
                          "ndb_1_config.bin.2",
-                         NULL).c_str()));
+                         NULL).c_str(), timeout));
   CHECK(file_exists(path(wd.path(),
                          "ndb_2_config.bin.2",
-                         NULL).c_str()));
+                         NULL).c_str(), timeout));
 
   g_err << "** Reload mgmd initial(from generation=2)" << endl;
   for (unsigned i = 0; i < mgmds.size(); i++)
@@ -578,14 +579,16 @@ int runTestBug45495(NDBT_Context* ctx, N
       tmp.assfmt("ndb_%d_config.bin.2", j+1);
       CHECK(file_exists(path(wd.path(),
                              tmp.c_str(),
-                             NULL).c_str()));
+                             NULL).c_str(),
+                        timeout));
     }
   }
 
   return NDBT_OK;
-
 }
 
+
+
 int runTestBug42015(NDBT_Context* ctx, NDBT_Step* step)
 {
   NDBT_Workingdir wd("test_mgmd"); // temporary working directory
@@ -838,6 +841,100 @@ int runTestNowaitNodes2(NDBT_Context* ct
   return NDBT_OK;
 }
 
+int
+runBug56844(NDBT_Context* ctx, NDBT_Step* step)
+{
+  NDBT_Workingdir wd("test_mgmd"); // temporary working directory
+
+  g_err << "** Create config.ini" << endl;
+  Properties config = ConfigFactory::create(2);
+  CHECK(ConfigFactory::write_config_ini(config,
+                                        path(wd.path(),
+                                             "config.ini",
+                                             NULL).c_str()));
+  // Start ndb_mgmd(s)
+  MgmdProcessList mgmds;
+  for (int i = 1; i <= 2; i++)
+  {
+    Mgmd* mgmd = new Mgmd(i);
+    mgmds.push_back(mgmd);
+    CHECK(mgmd->start_from_config_ini(wd.path()));
+  }
+
+  // Connect the ndb_mgmd(s)
+  for (unsigned i = 0; i < mgmds.size(); i++)
+  {
+    CHECK(mgmds[i]->connect(config));
+  }
+
+  // wait for confirmed config
+  for (unsigned i = 0; i < mgmds.size(); i++)
+  {
+    CHECK(mgmds[i]->wait_confirmed_config());
+  }
+
+  // stop them
+  for (unsigned i = 0; i < mgmds.size(); i++)
+  {
+    CHECK(mgmds[i]->stop());
+  }
+
+  // Check binary config files created
+  CHECK(file_exists(path(wd.path(),
+                         "ndb_1_config.bin.1",
+                         NULL).c_str()));
+  CHECK(file_exists(path(wd.path(),
+                         "ndb_2_config.bin.1",
+                         NULL).c_str()));
+
+  CHECK(ConfigFactory::put(config, "ndb_mgmd", 1, "ArbitrationDelay", 100));
+  CHECK(ConfigFactory::write_config_ini(config,
+                                        path(wd.path(),
+                                             "config2.ini",
+                                             NULL).c_str()));
+  Uint32 no = 2;
+  int loops = ctx->getNumLoops();
+  for (int l = 0; l < loops; l++, no++)
+  {
+    g_err << l << ": *** Reload from config.ini" << endl;
+    for (unsigned i = 0; i < mgmds.size(); i++)
+    {
+      // Start from config2.ini
+      CHECK(mgmds[i]->start_from_config_ini(wd.path(),
+                                            (l & 1) == 1 ?
+                                            "-f config.ini" :
+                                            "-f config2.ini",
+                                            "--reload", NULL));
+    }
+    for (unsigned i = 0; i < mgmds.size(); i++)
+    {
+      CHECK(mgmds[i]->connect(config));
+      CHECK(mgmds[i]->wait_confirmed_config());
+    }
+
+    /**
+     * Since it will first be confirmed...
+     *   and then once connected to other ndb_nmgmd start a config
+     *   change, it can take a bit until new config exists...
+     *   allow 30s
+     */
+    Uint32 timeout = 30;
+    for (unsigned i = 0; i < mgmds.size(); i++)
+    {
+      BaseString p = path(wd.path(), "", NULL);
+      p.appfmt("ndb_%u_config.bin.%u", i+1, no);
+      g_err << "CHECK(" << p.c_str() << ")" << endl;
+      CHECK(file_exists(p.c_str(), timeout));
+    }
+
+    for (unsigned i = 0; i < mgmds.size(); i++)
+    {
+      CHECK(mgmds[i]->stop());
+    }
+  }
+  return NDBT_OK;
+}
+
 NDBT_TESTSUITE(testMgmd);
 DRIVER(DummyDriver); /* turn off use of NdbApi */
 
@@ -847,12 +944,6 @@ TESTCASE("Basic2Mgm",
   INITIALIZER(runTestBasic2Mgm);
 }
 
-TESTCASE("Bug45495",
-         "Test that mgmd can be restarted in any order")
-{
-  INITIALIZER(runTestBug45495);
-}
-
 TESTCASE("Bug42015",
          "Test that mgmd can fetch configuration from another mgmd")
 {
@@ -880,6 +971,17 @@ TESTCASE("NoCfgCache",
   INITIALIZER(runTestNoConfigCache);
 }
 
+TESTCASE("Bug56844",
+         "Test that mgmd can be restarted in any order")
+{
+  INITIALIZER(runBug56844);
+}
+
+TESTCASE("Bug45495",
+         "Test that mgmd can be restarted in any order")
+{
+  INITIALIZER(runTestBug45495);
+}
 
 NDBT_TESTSUITE_END(testMgmd);
 

=== modified file 'storage/ndb/test/ndbapi/testOIBasic.cpp'
--- a/storage/ndb/test/ndbapi/testOIBasic.cpp	2010-01-18 19:20:01 +0000
+++ b/storage/ndb/test/ndbapi/testOIBasic.cpp	2010-08-16 10:25:27 +0000
@@ -550,7 +550,7 @@ Chs::Chs(CHARSET_INFO* cs) :
     // normalize
     memset(xbytes, 0, sizeof(xbytes));
     // currently returns buffer size always
-    int xlen = (*cs->coll->strnxfrm)(cs, xbytes, m_xmul * size, bytes, size);
+    int xlen = NdbSqlUtil::ndb_strnxfrm(cs, xbytes, m_xmul * size, bytes, size);
     // check we got something
     ok = false;
     for (uint j = 0; j < (uint)xlen; j++) {

=== modified file 'storage/ndb/test/ndbapi/testRestartGci.cpp'
--- a/storage/ndb/test/ndbapi/testRestartGci.cpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/test/ndbapi/testRestartGci.cpp	2010-09-15 09:43:39 +0000
@@ -76,25 +76,16 @@ int runInsertRememberGci(NDBT_Context* c
 
     CHECK(hugoOps.closeTransaction(pNdb) == 0);
     i++;
+    /* Sleep so that records will have > 1 GCI between them */
+    NdbSleep_MilliSleep(10);
   };
 
   return result;
 }
 
-int runRestartGciControl(NDBT_Context* ctx, NDBT_Step* step){
-  int records = ctx->getNumRecords();
+int runRestart(NDBT_Context* ctx, NDBT_Step* step){
   Ndb* pNdb = GETNDB(step);
-  UtilTransactions utilTrans(*ctx->getTab());
   NdbRestarter restarter;
-  
-  // Wait until we have enough records in db
-  int count = 0;
-  while (count < records){
-    if (utilTrans.selectCount(pNdb, 64, &count) != 0){
-      ctx->stopTest();
-      return NDBT_FAILED;
-    }
-  }
 
   // Restart cluster with abort
   if (restarter.restartAll(false, false, true) != 0){
@@ -102,9 +93,6 @@ int runRestartGciControl(NDBT_Context* c
     return NDBT_FAILED;
   }
 
-  // Stop the other thread
-  ctx->stopTest();
-
   if (restarter.waitClusterStarted(300) != 0){
     return NDBT_FAILED;
   }
@@ -116,6 +104,27 @@ int runRestartGciControl(NDBT_Context* c
   return NDBT_OK;
 }
 
+int runRestartGciControl(NDBT_Context* ctx, NDBT_Step* step){
+  int records = ctx->getNumRecords();
+  Ndb* pNdb = GETNDB(step);
+  UtilTransactions utilTrans(*ctx->getTab());
+  
+  // Wait until we have enough records in db
+  int count = 0;
+  while (count < records){
+    if (utilTrans.selectCount(pNdb, 64, &count) != 0){
+      ctx->stopTest();
+      return NDBT_FAILED;
+    }
+    NdbSleep_MilliSleep(10);
+  }
+
+  // Stop the other thread
+  ctx->stopTest();
+
+  return runRestart(ctx,step);
+}
+
 int runVerifyInserts(NDBT_Context* ctx, NDBT_Step* step){
   int result = NDBT_OK;
   Ndb* pNdb = GETNDB(step);
@@ -147,9 +156,19 @@ int runVerifyInserts(NDBT_Context* ctx, 
 
   // RULE2: The records found in db should have same or lower 
   // gci as in the vector
+  int recordsWithIncorrectGci = 0;
   for (i = 0; i < savedRecords.size(); i++){
     CHECK(hugoOps.startTransaction(pNdb) == 0);
+    /* First read of row to check contents */
     CHECK(hugoOps.pkReadRecord(pNdb, i) == 0);
+    /* Second read of row to get GCI */
+    NdbTransaction* trans = hugoOps.getTransaction();
+    NdbOperation* readOp = trans->getNdbOperation(ctx->getTab());
+    CHECK(readOp != NULL);
+    CHECK(readOp->readTuple() == 0);
+    CHECK(hugoOps.equalForRow(readOp, i) == 0);
+    NdbRecAttr* rowGci = readOp->getValue(NdbDictionary::Column::ROW_GCI);
+    CHECK(rowGci != NULL);
     if (hugoOps.execute_Commit(pNdb) != 0){
       // Record was not found in db'
 
@@ -158,6 +177,14 @@ int runVerifyInserts(NDBT_Context* ctx, 
 	ndbout << "ERR: Record "<<i<<" should have existed" << endl;
 	result = NDBT_FAILED;
       }
+      else
+      {
+        /* It didn't exist, but that was expected.
+         * Let's disappear it, so that it doesn't cause confusion
+         * after further restarts.
+         */
+        savedRecords[i].m_gci = (Uint32(1) << 31) -1; // Big number
+      }
     } else {
       // Record was found in db
       BaseString str = hugoOps.getRecordStr(0);
@@ -166,11 +193,19 @@ int runVerifyInserts(NDBT_Context* ctx, 
 	ndbout << "ERR: Record "<<i<<" str did not match "<< endl;
 	result = NDBT_FAILED;
       }
-      // Check record gci
+      // Check record gci in range
       if (savedRecords[i].m_gci > restartGCI){
 	ndbout << "ERR: Record "<<i<<" should not have existed" << endl;
 	result = NDBT_FAILED;
       }
+      // Check record gci is exactly correct
+      if (savedRecords[i].m_gci != rowGci->int32_value()){
+        ndbout << "ERR: Record "<<i<<" should have GCI " <<
+          savedRecords[i].m_gci << ", but has " << 
+          rowGci->int32_value() << endl;
+        recordsWithIncorrectGci++;
+        result = NDBT_FAILED;
+      }
     }
 
     CHECK(hugoOps.closeTransaction(pNdb) == 0);    
@@ -184,6 +219,9 @@ int runVerifyInserts(NDBT_Context* ctx, 
   ndbout << "There are " << recordsWithLowerOrSameGci 
 	 << " records with lower or same gci than " << restartGCI <<  endl;
   
+  ndbout << "There are " << recordsWithIncorrectGci
+         << " records with incorrect Gci on recovery." << endl;
+
   return result;
 }
 
@@ -212,6 +250,11 @@ TESTCASE("InsertRestartGci", 
   STEP(runInsertRememberGci);
   STEP(runRestartGciControl);
   VERIFIER(runVerifyInserts);
+  /* Restart again - LCP after first restart will mean that this
+   * time we recover from LCP, not Redo
+   */
+  VERIFIER(runRestart);
+  VERIFIER(runVerifyInserts);  // Check GCIs again
   FINALIZER(runClearTable);
 }
 NDBT_TESTSUITE_END(testRestartGci);

=== modified file 'storage/ndb/test/ndbapi/testSystemRestart.cpp'
--- a/storage/ndb/test/ndbapi/testSystemRestart.cpp	2010-06-18 10:57:02 +0000
+++ b/storage/ndb/test/ndbapi/testSystemRestart.cpp	2010-09-23 06:22:44 +0000
@@ -2347,6 +2347,52 @@ runBug54611(NDBT_Context* ctx, NDBT_Step
   return NDBT_OK;
 }
 
+int
+runBug56961(NDBT_Context* ctx, NDBT_Step* step)
+{
+  NdbRestarter res;
+  Uint32 loops = ctx->getNumLoops();
+  Ndb* pNdb = GETNDB(step);
+  int rows = ctx->getNumRecords();
+
+  int node = res.getNode(NdbRestarter::NS_RANDOM);
+  int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
+  HugoTransactions hugoTrans(*ctx->getTab());
+
+  for (Uint32 l = 0; l<loops; l++)
+  {
+    ndbout_c("Waiting for %d to restart (5058)", node);
+    res.dumpStateOneNode(node, val2, 2);
+    res.insertErrorInNode(node, 5058);
+
+    hugoTrans.clearTable(pNdb);
+    hugoTrans.loadTable(pNdb, rows);
+    while (hugoTrans.scanUpdateRecords(pNdb, rows) == NDBT_OK &&
+           res.getNodeStatus(node) != NDB_MGM_NODE_STATUS_NOT_STARTED &&
+           res.getNodeStatus(node) != NDB_MGM_NODE_STATUS_NO_CONTACT);
+    res.waitNodesNoStart(&node, 1);
+    res.startNodes(&node, 1);
+    ndbout_c("Waiting for %d to start", node);
+    res.waitClusterStarted();
+
+    ndbout_c("Waiting for %d to restart (5059)", node);
+    res.dumpStateOneNode(node, val2, 2);
+    res.insertErrorInNode(node, 5059);
+
+    hugoTrans.clearTable(pNdb);
+    hugoTrans.loadTable(pNdb, rows);
+    while (hugoTrans.scanUpdateRecords(pNdb, rows) == NDBT_OK &&
+           res.getNodeStatus(node) != NDB_MGM_NODE_STATUS_NOT_STARTED &&
+           res.getNodeStatus(node) != NDB_MGM_NODE_STATUS_NO_CONTACT);
+    res.waitNodesNoStart(&node, 1);
+    res.startNodes(&node, 1);
+    ndbout_c("Waiting for %d to start", node);
+    res.waitClusterStarted();
+  }
+
+  return NDBT_OK;
+}
+
 NDBT_TESTSUITE(testSystemRestart);
 TESTCASE("SR1", 
 	 "Basic system restart test. Focus on testing restart from REDO log.\n"
@@ -2695,6 +2741,11 @@ TESTCASE("Bug54611", "")
   INITIALIZER(runLoadTable);
   INITIALIZER(runBug54611);
 }
+TESTCASE("Bug56961", "")
+{
+  INITIALIZER(runLoadTable);
+  INITIALIZER(runBug56961);
+}
 NDBT_TESTSUITE_END(testSystemRestart);
 
 int main(int argc, const char** argv){

=== modified file 'storage/ndb/test/ndbapi/test_event.cpp'
--- a/storage/ndb/test/ndbapi/test_event.cpp	2010-08-26 12:33:33 +0000
+++ b/storage/ndb/test/ndbapi/test_event.cpp	2010-09-06 08:20:33 +0000
@@ -3281,7 +3281,7 @@ runBug44915(NDBT_Context* ctx, NDBT_Step
   
   NdbRestarter res;
   int error[] = { 13031, 13044, 13045, 0 };
-  for (int i = 0; error[i]; i++)
+  for (int i = 0; error[i] && result == NDBT_OK; i++)
   {
     ndbout_c("error: %d", error[i]);
     res.insertErrorInNode(res.getDbNodeId(rand() % res.getNumDbNodes()),
@@ -3289,6 +3289,29 @@ runBug44915(NDBT_Context* ctx, NDBT_Step
     
     result = runCreateEvent(ctx, step); // should fail due to error insert
     result = runCreateEvent(ctx, step); // should pass
+    result = runDropEvent(ctx, step);
+  }
+  return result;
+}
+
+int
+runBug56579(NDBT_Context* ctx, NDBT_Step* step)
+{
+  int result = NDBT_OK;
+
+  NdbRestarter res;
+  Ndb* pNdb = GETNDB(step);
+
+  int error_all[] = { 13046, 0 };
+  for (int i = 0; error_all[i] && result == NDBT_OK; i++)
+  {
+    ndbout_c("error: %d", error_all[i]);
+    res.insertErrorInAllNodes(error_all[i]);
+
+    if (createEventOperation(pNdb, *ctx->getTab()) != 0)
+    {
+      return NDBT_FAILED;
+    }
   }
 
   return result;
@@ -3516,6 +3539,12 @@ TESTCASE("Bug44915", "")
 {
   INITIALIZER(runBug44915);
 }
+TESTCASE("Bug56579", "")
+{
+  INITIALIZER(runCreateEvent);
+  STEP(runBug56579);
+  FINALIZER(runDropEvent);
+}
 NDBT_TESTSUITE_END(test_event);
 
 int main(int argc, const char** argv){

=== modified file 'storage/ndb/test/run-test/daily-basic-tests.txt'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt	2010-09-03 08:59:02 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt	2010-09-23 11:55:42 +0000
@@ -1488,6 +1488,10 @@ max-time: 1200
 cmd: test_event
 args: -n Bug44915 T1
 
+max-time: 1200
+cmd: test_event
+args: -n Bug56579 T1
+
 max-time: 3600
 cmd: testNodeRestart
 args: -n Bug44952 T1

=== modified file 'storage/ndb/test/src/NDBT_Test.cpp'
--- a/storage/ndb/test/src/NDBT_Test.cpp	2010-09-03 08:59:02 +0000
+++ b/storage/ndb/test/src/NDBT_Test.cpp	2010-09-23 11:55:42 +0000
@@ -1343,7 +1343,7 @@ const char *load_default_groups[]= { "my
 
 static void short_usage_sub(void)
 {
-  ndb_short_usage_sub(my_progname, "[tabname1 tabname2 ... tabnameN]");
+  ndb_short_usage_sub("[tabname1 tabname2 ... tabnameN]");
 }
 static void usage()
 {
@@ -1377,7 +1377,7 @@ int NDBT_TestSuite::execute(int argc, co
   if (!my_progname)
     my_progname= _argv[0];
 
-  ndb_opt_set_usage_funcs(NULL, short_usage_sub, usage);
+  ndb_opt_set_usage_funcs(short_usage_sub, usage);
 
   load_defaults("my",load_default_groups,&argc,&_argv);
 

=== modified file 'storage/ndb/test/src/NdbBackup.cpp'
--- a/storage/ndb/test/src/NdbBackup.cpp	2010-06-14 12:16:32 +0000
+++ b/storage/ndb/test/src/NdbBackup.cpp	2010-09-23 08:24:52 +0000
@@ -64,7 +64,7 @@ NdbBackup::clearOldBackups()
      * Clear old backup files
      */ 
     BaseString tmp;
-    tmp.assfmt("ssh -v %s rm -rfv %s/BACKUP", host, path);
+    tmp.assfmt("ssh -v %s rm -rf %s/BACKUP", host, path);
   
     ndbout << "buf: "<< tmp.c_str() <<endl;
     int res = system(tmp.c_str());  

=== modified file 'storage/ndb/test/src/NdbRestarter.cpp'
--- a/storage/ndb/test/src/NdbRestarter.cpp	2010-02-18 23:50:31 +0000
+++ b/storage/ndb/test/src/NdbRestarter.cpp	2010-09-20 13:09:18 +0000
@@ -971,4 +971,18 @@ NdbRestarter::getNodeTypeVersionRange(nd
   return 0;
 }
 
+int
+NdbRestarter::getNodeStatus(int nodeid)
+{
+  if (getStatus() != 0)
+    return -1;
+
+  for (size_t n = 0; n < ndbNodes.size(); n++)
+  {
+    if (ndbNodes[n].node_id == nodeid)
+      return ndbNodes[n].node_status;
+  }
+  return -1;
+}
+
 template class Vector<ndb_mgm_node_state>;

=== modified file 'storage/ndb/tools/delete_all.cpp'
--- a/storage/ndb/tools/delete_all.cpp	2010-05-04 14:34:54 +0000
+++ b/storage/ndb/tools/delete_all.cpp	2010-08-16 17:02:58 +0000
@@ -54,7 +54,7 @@ static struct my_option my_long_options[
 
 static void short_usage_sub(void)
 {
-  ndb_short_usage_sub(my_progname, NULL);
+  ndb_short_usage_sub(NULL);
 }
 
 static void usage()
@@ -64,7 +64,7 @@ static void usage()
 
 int main(int argc, char** argv){
   NDB_INIT(argv[0]);
-  ndb_opt_set_usage_funcs(NULL, short_usage_sub, usage);
+  ndb_opt_set_usage_funcs(short_usage_sub, usage);
   load_defaults("my",load_default_groups,&argc,&argv);
   int ho_error;
 #ifndef DBUG_OFF

=== modified file 'storage/ndb/tools/desc.cpp'
--- a/storage/ndb/tools/desc.cpp	2010-05-04 14:34:54 +0000
+++ b/storage/ndb/tools/desc.cpp	2010-08-16 17:02:58 +0000
@@ -66,7 +66,7 @@ static struct my_option my_long_options[
 
 static void short_usage_sub(void)
 {
-  ndb_short_usage_sub(my_progname, NULL);
+  ndb_short_usage_sub(NULL);
 }
 
 static void usage()
@@ -79,7 +79,7 @@ static void print_part_info(Ndb* pNdb, N
 int main(int argc, char** argv){
   NDB_INIT(argv[0]);
 
-  ndb_opt_set_usage_funcs(NULL, short_usage_sub, usage);
+  ndb_opt_set_usage_funcs(short_usage_sub, usage);
   load_defaults("my",load_default_groups,&argc,&argv);
   int ho_error;
 #ifndef DBUG_OFF

=== modified file 'storage/ndb/tools/drop_index.cpp'
--- a/storage/ndb/tools/drop_index.cpp	2010-05-04 14:34:54 +0000
+++ b/storage/ndb/tools/drop_index.cpp	2010-08-16 17:02:58 +0000
@@ -38,7 +38,7 @@ static struct my_option my_long_options[
 
 static void short_usage_sub(void)
 {
-  ndb_short_usage_sub(my_progname, NULL);
+  ndb_short_usage_sub(NULL);
 }
 
 static void usage()
@@ -48,7 +48,7 @@ static void usage()
 
 int main(int argc, char** argv){
   NDB_INIT(argv[0]);
-  ndb_opt_set_usage_funcs(NULL, short_usage_sub, usage);
+  ndb_opt_set_usage_funcs(short_usage_sub, usage);
   load_defaults("my",load_default_groups,&argc,&argv);
   int ho_error;
   if ((ho_error=handle_options(&argc, &argv, my_long_options,

=== modified file 'storage/ndb/tools/drop_tab.cpp'
--- a/storage/ndb/tools/drop_tab.cpp	2010-05-04 14:34:54 +0000
+++ b/storage/ndb/tools/drop_tab.cpp	2010-08-16 17:02:58 +0000
@@ -38,7 +38,7 @@ static struct my_option my_long_options[
 
 static void short_usage_sub(void)
 {
-  ndb_short_usage_sub(my_progname, NULL);
+  ndb_short_usage_sub(NULL);
 }
 
 static void usage()
@@ -48,7 +48,7 @@ static void usage()
 
 int main(int argc, char** argv){
   NDB_INIT(argv[0]);
-  ndb_opt_set_usage_funcs(NULL, short_usage_sub, usage);
+  ndb_opt_set_usage_funcs(short_usage_sub, usage);
   load_defaults("my",load_default_groups,&argc,&argv);
   int ho_error;
   if ((ho_error=handle_options(&argc, &argv, my_long_options,

=== modified file 'storage/ndb/tools/listTables.cpp'
--- a/storage/ndb/tools/listTables.cpp	2010-05-04 14:34:54 +0000
+++ b/storage/ndb/tools/listTables.cpp	2010-08-16 17:02:58 +0000
@@ -282,7 +282,7 @@ static struct my_option my_long_options[
 
 static void short_usage_sub(void)
 {
-  ndb_short_usage_sub(my_progname, NULL);
+  ndb_short_usage_sub(NULL);
 }
 
 static void usage()
@@ -293,7 +293,7 @@ static void usage()
 int main(int argc, char** argv){
   NDB_INIT(argv[0]);
   const char* _tabname;
-  ndb_opt_set_usage_funcs(NULL, short_usage_sub, usage);
+  ndb_opt_set_usage_funcs(short_usage_sub, usage);
   load_defaults("my",load_default_groups,&argc,&argv);
   int ho_error;
 #ifndef DBUG_OFF

=== modified file 'storage/ndb/tools/ndb_config.cpp'
--- a/storage/ndb/tools/ndb_config.cpp	2010-08-27 07:42:36 +0000
+++ b/storage/ndb/tools/ndb_config.cpp	2010-09-22 13:28:20 +0000
@@ -101,7 +101,7 @@ static struct my_option my_long_options[
 
 static void short_usage_sub(void)
 {
-  ndb_short_usage_sub(my_progname, NULL);
+  ndb_short_usage_sub(NULL);
 }
 
 static void usage()
@@ -162,7 +162,7 @@ static ndb_mgm_configuration* load_confi
 int
 main(int argc, char** argv){
   NDB_INIT(argv[0]);
-  ndb_opt_set_usage_funcs(NULL, short_usage_sub, usage);
+  ndb_opt_set_usage_funcs(short_usage_sub, usage);
   load_defaults("my",load_default_groups,&argc,&argv);
   int ho_error;
   if ((ho_error=handle_options(&argc, &argv, my_long_options,

=== modified file 'storage/ndb/tools/restore/restore_main.cpp'
--- a/storage/ndb/tools/restore/restore_main.cpp	2010-08-30 07:25:44 +0000
+++ b/storage/ndb/tools/restore/restore_main.cpp	2010-09-22 13:28:20 +0000
@@ -380,7 +380,7 @@ static bool analyse_nodegroup_map(const 
 
 static void short_usage_sub(void)
 {
-  ndb_short_usage_sub(my_progname,"[<path to backup files>]");
+  ndb_short_usage_sub("[<path to backup files>]");
 }
 static void usage()
 {
@@ -512,7 +512,7 @@ readArguments(int *pargc, char*** pargv)
   load_defaults("my",load_default_groups,pargc,pargv);
   debug << "handle_options" << endl;
 
-  ndb_opt_set_usage_funcs(NULL, short_usage_sub, usage);
+  ndb_opt_set_usage_funcs(short_usage_sub, usage);
 
   if (handle_options(pargc, pargv, my_long_options, get_one_option))
   {

=== modified file 'storage/ndb/tools/select_all.cpp'
--- a/storage/ndb/tools/select_all.cpp	2010-05-04 14:34:54 +0000
+++ b/storage/ndb/tools/select_all.cpp	2010-08-16 17:02:58 +0000
@@ -99,7 +99,7 @@ static struct my_option my_long_options[
 
 static void short_usage_sub(void)
 {
-  ndb_short_usage_sub(my_progname, NULL);
+  ndb_short_usage_sub(NULL);
 }
 
 static void usage()
@@ -109,7 +109,7 @@ static void usage()
 
 int main(int argc, char** argv){
   NDB_INIT(argv[0]);
-  ndb_opt_set_usage_funcs(NULL, short_usage_sub, usage);
+  ndb_opt_set_usage_funcs(short_usage_sub, usage);
   load_defaults("my",load_default_groups,&argc,&argv);
   const char* _tabname;
   int ho_error;

=== modified file 'storage/ndb/tools/select_count.cpp'
--- a/storage/ndb/tools/select_count.cpp	2010-05-04 14:34:54 +0000
+++ b/storage/ndb/tools/select_count.cpp	2010-08-16 17:02:58 +0000
@@ -57,7 +57,7 @@ static struct my_option my_long_options[
 
 static void short_usage_sub(void)
 {
-  ndb_short_usage_sub(my_progname, NULL);
+  ndb_short_usage_sub(NULL);
 }
 
 static void usage()
@@ -67,7 +67,7 @@ static void usage()
 
 int main(int argc, char** argv){
   NDB_INIT(argv[0]);
-  ndb_opt_set_usage_funcs(NULL, short_usage_sub, usage);
+  ndb_opt_set_usage_funcs(short_usage_sub, usage);
   load_defaults("my",load_default_groups,&argc,&argv);
   int ho_error;
 #ifndef DBUG_OFF

=== modified file 'storage/ndb/tools/waiter.cpp'
--- a/storage/ndb/tools/waiter.cpp	2010-08-28 09:37:09 +0000
+++ b/storage/ndb/tools/waiter.cpp	2010-09-22 13:28:20 +0000
@@ -71,7 +71,7 @@ static struct my_option my_long_options[
 
 static void short_usage_sub(void)
 {
-  ndb_short_usage_sub(my_progname, NULL);
+  ndb_short_usage_sub(NULL);
 }
 
 static void usage()
@@ -88,7 +88,7 @@ void catch_signal(int signum)
 
 int main(int argc, char** argv){
   NDB_INIT(argv[0]);
-  ndb_opt_set_usage_funcs(NULL, short_usage_sub, usage);
+  ndb_opt_set_usage_funcs(short_usage_sub, usage);
   load_defaults("my",load_default_groups,&argc,&argv);
 
 #ifndef DBUG_OFF


Attachment: [text/bzr-bundle] bzr/jonas@mysql.com-20100923115542-bv9613k9uw5dolxf.bundle
Thread
bzr commit into mysql-5.1-telco-7.0-spj branch (jonas:3216) Jonas Oreland23 Sep