List:Commits« Previous MessageNext Message »
From:Magnus Blåudd Date:April 20 2011 1:51pm
Subject:bzr push into mysql-5.5-cluster branch (magnus.blaudd:3303 to 3308)
View as plain text  
 3308 Magnus Blåudd	2011-04-20
      rpl_ndb
       - fix .result file due to new rpl script output format

    modified:
      mysql-test/suite/rpl_ndb/r/rpl_ndb_2other.result
 3307 Magnus Blåudd	2011-04-20 [merge]
      Merge 7.0 -> 5.5-cluster

 3306 Magnus Blåudd	2011-04-20 [merge]
      ndb
       - merge in patch for bug 12380149
       - mark patch with MCP tags

    modified:
      sql/sql_partition.cc
 3305 Magnus Blåudd	2011-04-20 [merge]
      Merge 7.0 -> 5.5-cluster

    renamed:
      mysql-test/extra/rpl_tests/rpl_ndb_2multi_basic.test => mysql-test/suite/rpl_ndb/t/rpl_ndb_2multi_basic.inc
      mysql-test/extra/rpl_tests/rpl_ndb_2multi_eng.test => mysql-test/suite/rpl_ndb/t/rpl_ndb_2multi_eng.inc
    modified:
      mysql-test/suite/rpl_ndb/t/rpl_ndb_2innodb.test
      mysql-test/suite/rpl_ndb/t/rpl_ndb_2myisam.test
      mysql-test/suite/rpl_ndb/t/rpl_ndb_2ndb.test
      mysql-test/suite/rpl_ndb/t/rpl_ndb_2other.test
      mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb2ndb.test
      mysql-test/suite/rpl_ndb/t/rpl_ndb_myisam2ndb.test
 3304 Magnus Blåudd	2011-04-20 [merge]
      Merge 7.0 -> 5.5-cluster

    added:
      storage/ndb/include/kernel/signaldata/DihRestart.hpp
    renamed:
      mysql-test/extra/rpl_tests/rpl_ndb_apply_status.test => mysql-test/suite/rpl_ndb/t/rpl_ndb_xxx_innodb.inc
      mysql-test/extra/rpl_tests/select_ndb_apply_status.inc => mysql-test/suite/rpl_ndb/t/select_ndb_apply_status.inc
    modified:
      mysql-test/mysql-test-run.pl
      mysql-test/suite/rpl_ndb/t/rpl_ndb_mix_innodb.test
      mysql-test/suite/rpl_ndb/t/rpl_ndb_stm_innodb.test
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster.h
      storage/ndb/include/kernel/kernel_types.h
      storage/ndb/include/kernel/signaldata/AccLock.hpp
      storage/ndb/include/kernel/signaldata/NextScan.hpp
      storage/ndb/include/mgmapi/mgmapi_config_parameters.h
      storage/ndb/src/common/debugger/EventLogger.cpp
      storage/ndb/src/common/debugger/signaldata/AccLock.cpp
      storage/ndb/src/common/util/ndbzio.c
      storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp
      storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
      storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp
      storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
      storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
      storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
      storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp
      storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp
      storage/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp
      storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
      storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
      storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
      storage/ndb/src/kernel/vm/mt.cpp
      storage/ndb/src/mgmsrv/ConfigInfo.cpp
      storage/ndb/src/ndbapi/NdbScanOperation.cpp
      storage/ndb/test/ndbapi/testDict.cpp
      storage/ndb/test/run-test/daily-basic-tests.txt
      storage/ndb/test/src/HugoCalculator.cpp
      mysql-test/suite/rpl_ndb/t/rpl_ndb_xxx_innodb.inc
 3303 Magnus Blåudd	2011-04-19
      rpl_ndb
       - update .result file, SHWO INDEX has got a new column Index_comment

    modified:
      mysql-test/suite/rpl_ndb/r/rpl_ndb_ddl.result
=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl	2011-04-15 08:41:42 +0000
+++ b/mysql-test/mysql-test-run.pl	2011-04-20 09:58:58 +0000
@@ -396,10 +396,13 @@ sub main {
     my $sys_info= My::SysInfo->new();
 
     $opt_parallel= $sys_info->num_cpus();
+    print "num_cpus: $opt_parallel, min_bogomips: " .
+      $sys_info->min_bogomips(). "\n";
     for my $limit (2000, 1500, 1000, 500){
       $opt_parallel-- if ($sys_info->min_bogomips() < $limit);
     }
     my $max_par= $ENV{MTR_MAX_PARALLEL} || 8;
+    print "max_par: $max_par\n";
     $opt_parallel= $max_par if ($opt_parallel > $max_par);
     $opt_parallel= $num_tests if ($opt_parallel > $num_tests);
     $opt_parallel= 1 if (IS_WINDOWS and $sys_info->isvm());

=== modified file 'mysql-test/suite/rpl_ndb/r/rpl_ndb_2other.result'
--- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_2other.result	2011-04-14 15:40:04 +0000
+++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_2other.result	2011-04-20 13:47:55 +0000
@@ -1,9 +1,5 @@
-stop slave;
-drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
-reset master;
-reset slave;
-drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
-start slave;
+include/master-slave.inc
+[connection master]
 SET storage_engine=ndb;
 
 === NDB -> MYISAM ===

=== modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_2innodb.test'
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_2innodb.test	2011-04-14 15:40:04 +0000
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_2innodb.test	2011-04-20 12:30:30 +0000
@@ -42,7 +42,7 @@ set new=on;
 set storage_engine=ndbcluster;
 --enable_query_log
 
---source extra/rpl_tests/rpl_ndb_2multi_eng.test
+--source suite/rpl_ndb/t/rpl_ndb_2multi_eng.inc
 
 --connection slave
 set @@global.slave_exec_mode= 'STRICT';

=== renamed file 'mysql-test/extra/rpl_tests/rpl_ndb_2multi_basic.test' => 'mysql-test/suite/rpl_ndb/t/rpl_ndb_2multi_basic.inc'
=== renamed file 'mysql-test/extra/rpl_tests/rpl_ndb_2multi_eng.test' => 'mysql-test/suite/rpl_ndb/t/rpl_ndb_2multi_eng.inc'
=== modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_2myisam.test'
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_2myisam.test	2011-04-14 15:40:04 +0000
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_2myisam.test	2011-04-20 12:30:30 +0000
@@ -41,7 +41,7 @@ set new=on;
 set storage_engine=ndbcluster;
 --enable_query_log
 
---source extra/rpl_tests/rpl_ndb_2multi_eng.test
+--source suite/rpl_ndb/t/rpl_ndb_2multi_eng.inc
 
 --connection slave
 set @@global.slave_exec_mode= 'STRICT';

=== modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_2ndb.test'
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_2ndb.test	2011-04-08 11:06:53 +0000
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_2ndb.test	2011-04-20 12:10:50 +0000
@@ -16,5 +16,5 @@ SET storage_engine=ndb;
 --echo === NDB -> NDB ===
 --echo
 connection slave;
---source extra/rpl_tests/rpl_ndb_2multi_basic.test
+--source suite/rpl_ndb/t/rpl_ndb_2multi_basic.inc
 --source include/rpl_end.inc

=== modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_2other.test'
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_2other.test	2011-04-14 15:40:04 +0000
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_2other.test	2011-04-20 12:30:30 +0000
@@ -35,7 +35,7 @@ CREATE TABLE mysql.ndb_apply_status
                    end_pos BIGINT UNSIGNED NOT NULL,
                    PRIMARY KEY USING HASH (server_id)) ENGINE=MYISAM;
 SET storage_engine=myisam;
---source extra/rpl_tests/rpl_ndb_2multi_basic.test
+--source suite/rpl_ndb/t/rpl_ndb_2multi_basic.inc
 
 --echo
 --echo === NDB -> INNODB ===
@@ -43,7 +43,7 @@ SET storage_engine=myisam;
 connection slave;
 alter table mysql.ndb_apply_status engine=innodb;
 SET storage_engine=innodb;
---source extra/rpl_tests/rpl_ndb_2multi_basic.test
+--source suite/rpl_ndb/t/rpl_ndb_2multi_basic.inc
 
 connection slave;
 drop table mysql.ndb_apply_status;

=== modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb2ndb.test'
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb2ndb.test	2011-04-08 11:06:53 +0000
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb2ndb.test	2011-04-20 11:50:29 +0000
@@ -12,5 +12,5 @@
 -- source include/have_binlog_format_mixed_or_row.inc
 -- source suite/rpl_ndb/ndb_master-slave.inc
 SET storage_engine=innodb;
---source extra/rpl_tests/rpl_ndb_2multi_eng.test
+--source suite/rpl_ndb/t/rpl_ndb_2multi_eng.inc
 --source include/rpl_end.inc

=== modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_mix_innodb.test'
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_mix_innodb.test	2011-04-08 11:06:53 +0000
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_mix_innodb.test	2011-04-19 14:34:27 +0000
@@ -12,6 +12,6 @@
 --enable_query_log
 let $off_set = 9;
 let $rpl_format = 'MIX';
---source extra/rpl_tests/rpl_ndb_apply_status.test
+--source suite/rpl_ndb/t/rpl_ndb_xxx_innodb.inc
 
 --source include/rpl_end.inc

=== modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_myisam2ndb.test'
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_myisam2ndb.test	2011-04-08 11:06:53 +0000
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_myisam2ndb.test	2011-04-20 11:50:29 +0000
@@ -11,5 +11,5 @@
 -- source include/have_binlog_format_mixed_or_row.inc
 -- source suite/rpl_ndb/ndb_master-slave.inc
 SET storage_engine=myisam;
---source extra/rpl_tests/rpl_ndb_2multi_eng.test
+--source suite/rpl_ndb/t/rpl_ndb_2multi_eng.inc
 --source include/rpl_end.inc

=== modified file 'mysql-test/suite/rpl_ndb/t/rpl_ndb_stm_innodb.test'
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_stm_innodb.test	2011-04-14 15:40:04 +0000
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_stm_innodb.test	2011-04-20 09:58:58 +0000
@@ -16,5 +16,5 @@
 SET binlog_format = STATEMENT;
 let $off_set = 6;
 let $rpl_format = 'SBR';
---source extra/rpl_tests/rpl_ndb_apply_status.test
+--source suite/rpl_ndb/t/rpl_ndb_xxx_innodb.inc
 --source include/rpl_end.inc

=== renamed file 'mysql-test/extra/rpl_tests/rpl_ndb_apply_status.test' => 'mysql-test/suite/rpl_ndb/t/rpl_ndb_xxx_innodb.inc'
--- a/mysql-test/extra/rpl_tests/rpl_ndb_apply_status.test	2011-04-14 15:40:04 +0000
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_xxx_innodb.inc	2011-04-20 09:58:58 +0000
@@ -45,7 +45,7 @@ insert into t1 values (1,2);
 --echo
 
 --sync_slave_with_master
---source extra/rpl_tests/select_ndb_apply_status.inc
+--source suite/rpl_ndb/t/select_ndb_apply_status.inc
 
 --echo
 
@@ -85,7 +85,7 @@ commit;
 --echo
 
 --sync_slave_with_master
---source extra/rpl_tests/select_ndb_apply_status.inc
+--source suite/rpl_ndb/t/select_ndb_apply_status.inc
 
 connection master;
 --let $binlog_start= $start_pos
@@ -158,7 +158,7 @@ SET AUTOCOMMIT=1;
 --enable_query_log
 
 --sync_slave_with_master
---source extra/rpl_tests/select_ndb_apply_status.inc
+--source suite/rpl_ndb/t/select_ndb_apply_status.inc
 
 --echo
 
@@ -208,7 +208,7 @@ SET AUTOCOMMIT=1;
 --echo
 
 --sync_slave_with_master
---source extra/rpl_tests/select_ndb_apply_status.inc
+--source suite/rpl_ndb/t/select_ndb_apply_status.inc
 
 --echo
 
@@ -256,7 +256,7 @@ SET AUTOCOMMIT=1;
 --enable_query_log
 
 --sync_slave_with_master
---source extra/rpl_tests/select_ndb_apply_status.inc
+--source suite/rpl_ndb/t/select_ndb_apply_status.inc
 
 --echo
 
@@ -281,7 +281,7 @@ DROP DATABASE tpcb;
 
 ####### Commenting out until decision on Bug#27960 ###########
 
-#--source extra/rpl_tests/select_ndb_apply_status.inc
+#--source suite/rpl_ndb/t/select_ndb_apply_status.inc
 
 #connection master;
 #--eval SHOW BINLOG EVENTS in '$log_name' from $start_pos

=== renamed file 'mysql-test/extra/rpl_tests/select_ndb_apply_status.inc' => 'mysql-test/suite/rpl_ndb/t/select_ndb_apply_status.inc'
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2011-04-19 11:21:04 +0000
+++ b/sql/ha_ndbcluster.cc	2011-04-20 09:58:58 +0000
@@ -8115,7 +8115,6 @@ int ha_ndbcluster::create(const char *na
   bool use_disk= FALSE;
   NdbDictionary::Table::SingleUserMode single_user_mode= NdbDictionary::Table::SingleUserModeLocked;
   bool ndb_sys_table= FALSE;
-  partition_info *part_info;
   int result= 0;
   NdbDictionary::ObjectId objId;
 
@@ -8155,7 +8154,7 @@ int ha_ndbcluster::create(const char *na
     */
     if ((my_errno= write_ndb_file(name)))
       DBUG_RETURN(my_errno);
-    ndbcluster_create_binlog_setup(thd, get_ndb(thd), name, strlen(name),
+    ndbcluster_create_binlog_setup(thd, ndb, name, strlen(name),
                                    m_dbname, m_tabname, FALSE);
     DBUG_RETURN(my_errno);
   }
@@ -8435,8 +8434,7 @@ int ha_ndbcluster::create(const char *na
   }
 
   // Check partition info
-  part_info= form->part_info;
-  if ((my_errno= set_up_partition_info(part_info, form, (void*)&tab)))
+  if ((my_errno= set_up_partition_info(form->part_info, tab)))
     goto abort;
 
   if (tab.getFragmentType() == NDBTAB::HashMapPartition && 
@@ -13518,10 +13516,11 @@ void ha_ndbcluster::set_auto_partitions(
 }
 
 
-int ha_ndbcluster::set_range_data(void *tab_ref, partition_info *part_info)
+int
+ha_ndbcluster::set_range_data(const partition_info *part_info,
+                              NdbDictionary::Table& ndbtab) const
 {
   const uint num_parts = partition_info_num_parts(part_info);
-  NDBTAB *tab= (NDBTAB*)tab_ref;
   int error= 0;
   bool unsigned_flag= part_info->part_expr->unsigned_flag;
   DBUG_ENTER("set_range_data");
@@ -13550,16 +13549,18 @@ int ha_ndbcluster::set_range_data(void *
     }
     range_data[i]= (int32)range_val;
   }
-  tab->setRangeListData(range_data, num_parts);
+  ndbtab.setRangeListData(range_data, num_parts);
 error:
   my_free((char*)range_data, MYF(0));
   DBUG_RETURN(error);
 }
 
-int ha_ndbcluster::set_list_data(void *tab_ref, partition_info *part_info)
+
+int
+ha_ndbcluster::set_list_data(const partition_info *part_info,
+                             NdbDictionary::Table& ndbtab) const
 {
   const uint num_list_values = partition_info_num_list_values(part_info);
-  NDBTAB *tab= (NDBTAB*)tab_ref;
   int32 *list_data= (int32*)my_malloc(num_list_values*2*sizeof(int32), MYF(0));
   int error= 0;
   bool unsigned_flag= part_info->part_expr->unsigned_flag;
@@ -13585,7 +13586,7 @@ int ha_ndbcluster::set_list_data(void *t
     list_data[2*i]= (int32)list_val;
     list_data[2*i+1]= list_entry->partition_id;
   }
-  tab->setRangeListData(list_data, 2*num_list_values);
+  ndbtab.setRangeListData(list_data, 2*num_list_values);
 error:
   my_free((char*)list_data, MYF(0));
   DBUG_RETURN(error);
@@ -13604,18 +13605,15 @@ error:
   implement the function to map to a partition.
 */
 
-uint ha_ndbcluster::set_up_partition_info(partition_info *part_info,
-                                          TABLE *table,
-                                          void *tab_par)
+int
+ha_ndbcluster::set_up_partition_info(partition_info *part_info,
+                                     NdbDictionary::Table& ndbtab) const
 {
   uint32 frag_data[MAX_PARTITIONS];
   char *ts_names[MAX_PARTITIONS];
   ulong fd_index= 0, i, j;
-  NDBTAB *tab= (NDBTAB*)tab_par;
   NDBTAB::FragmentType ftype= NDBTAB::UserDefined;
   partition_element *part_elem;
-  bool first= TRUE;
-  uint tot_ts_name_len;
   List_iterator<partition_element> part_it(part_info->partitions);
   int error;
   DBUG_ENTER("ha_ndbcluster::set_up_partition_info");
@@ -13629,7 +13627,7 @@ uint ha_ndbcluster::set_up_partition_inf
 
     for (i= 0; i < part_info->part_field_list.elements; i++)
     {
-      NDBCOL *col= tab->getColumn(fields[i]->field_index);
+      NDBCOL *col= ndbtab.getColumn(fields[i]->field_index);
       DBUG_PRINT("info",("setting dist key on %s", col->getName()));
       col->setPartitionKey(TRUE);
     }
@@ -13661,25 +13659,24 @@ uint ha_ndbcluster::set_up_partition_inf
     col.setNullable(FALSE);
     col.setPrimaryKey(FALSE);
     col.setAutoIncrement(FALSE);
-    tab->addColumn(col);
+    ndbtab.addColumn(col);
     if (part_info->part_type == RANGE_PARTITION)
     {
-      if ((error= set_range_data((void*)tab, part_info)))
+      if ((error= set_range_data(part_info, ndbtab)))
       {
         DBUG_RETURN(error);
       }
     }
     else if (part_info->part_type == LIST_PARTITION)
     {
-      if ((error= set_list_data((void*)tab, part_info)))
+      if ((error= set_list_data(part_info, ndbtab)))
       {
         DBUG_RETURN(error);
       }
     }
   }
-  tab->setFragmentType(ftype);
+  ndbtab.setFragmentType(ftype);
   i= 0;
-  tot_ts_name_len= 0;
   do
   {
     uint ng;
@@ -13702,13 +13699,12 @@ uint ha_ndbcluster::set_up_partition_inf
         frag_data[fd_index++]= ng;
       } while (++j < partition_info_num_subparts(part_info));
     }
-    first= FALSE;
   } while (++i < partition_info_num_parts(part_info));
 
   const bool use_default_num_parts =
     partition_info_use_default_num_partitions(part_info);
-  tab->setDefaultNoPartitionsFlag(use_default_num_parts);
-  tab->setLinearFlag(part_info->linear_hash_ind);
+  ndbtab.setDefaultNoPartitionsFlag(use_default_num_parts);
+  ndbtab.setLinearFlag(part_info->linear_hash_ind);
   {
     ha_rows max_rows= table_share->max_rows;
     ha_rows min_rows= table_share->min_rows;
@@ -13716,12 +13712,12 @@ uint ha_ndbcluster::set_up_partition_inf
       max_rows= min_rows;
     if (max_rows != (ha_rows)0) /* default setting, don't set fragmentation */
     {
-      tab->setMaxRows(max_rows);
-      tab->setMinRows(min_rows);
+      ndbtab.setMaxRows(max_rows);
+      ndbtab.setMinRows(min_rows);
     }
   }
-  tab->setFragmentCount(fd_index);
-  tab->setFragmentData(frag_data, fd_index);
+  ndbtab.setFragmentCount(fd_index);
+  ndbtab.setFragmentData(frag_data, fd_index);
   DBUG_RETURN(0);
 }
 

=== modified file 'sql/ha_ndbcluster.h'
--- a/sql/ha_ndbcluster.h	2011-03-15 14:55:57 +0000
+++ b/sql/ha_ndbcluster.h	2011-04-20 09:58:58 +0000
@@ -452,11 +452,12 @@ private:
   bool has_null_in_unique_index(uint idx_no) const;
   bool check_index_fields_not_null(KEY *key_info);
 
-  uint set_up_partition_info(partition_info *part_info,
-                             TABLE *table,
-                             void *tab);
-  int set_range_data(void *tab, partition_info* part_info);
-  int set_list_data(void *tab, partition_info* part_info);
+  int set_up_partition_info(partition_info *part_info,
+                            NdbDictionary::Table&) const;
+  int set_range_data(const partition_info* part_info,
+                     NdbDictionary::Table&) const;
+  int set_list_data(const partition_info* part_info,
+                    NdbDictionary::Table&) const;
   int ndb_pk_update_row(THD *thd, 
                         const uchar *old_data, uchar *new_data,
                         uint32 old_part_id);

=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc	2011-04-14 15:40:04 +0000
+++ b/sql/sql_partition.cc	2011-04-20 12:59:50 +0000
@@ -4013,7 +4013,11 @@ void get_partition_set(const TABLE *tabl
   part_spec->start_part= 0;
   part_spec->end_part= num_parts - 1;
   if ((index < MAX_KEY) && 
+#ifndef MCP_BUG12380149
+       key_spec && key_spec->flag == (uint)HA_READ_KEY_EXACT &&
+#else
        key_spec->flag == (uint)HA_READ_KEY_EXACT &&
+#endif
        part_info->some_fields_in_PF.is_set(index))
   {
     key_info= table->key_info+index;

=== modified file 'storage/ndb/include/kernel/kernel_types.h'
--- a/storage/ndb/include/kernel/kernel_types.h	2011-02-01 23:27:25 +0000
+++ b/storage/ndb/include/kernel/kernel_types.h	2011-04-19 09:01:07 +0000
@@ -61,13 +61,24 @@ struct Local_key 
   bool isNull() const { return m_page_no == RNIL; }
   void setNull() { m_page_no= RNIL; m_file_no= m_page_idx= ~0;}
 
-  Uint32 ref() const { return (m_page_no << MAX_TUPLES_BITS) | m_page_idx ;}
+  Uint32 ref() const { return ref(m_page_no,m_page_idx) ;}
   
-  Local_key& assref (Uint32 ref) { 
-    m_page_no =ref >> MAX_TUPLES_BITS;
-    m_page_idx = ref & MAX_TUPLES_PER_PAGE;
+  Local_key& assref (Uint32 ref) {
+    m_page_no = ref2page_id(ref);
+    m_page_idx = ref2page_idx(ref);
     return *this;
   }
+
+  static Uint32 ref(Uint32 lk1, Uint32 lk2) {
+    return (lk1 << MAX_TUPLES_BITS) | lk2;
+  }
+
+  static Uint32 ref2page_id(Uint32 ref) { return ref >> MAX_TUPLES_BITS; }
+  static Uint32 ref2page_idx(Uint32 ref) { return ref & MAX_TUPLES_PER_PAGE; }
+
+  static bool isInvalid(Uint32 lk1, Uint32 lk2) {
+    return ref(lk1, lk2) == ~Uint32(0);
+  }
 };
 
 class NdbOut&

=== modified file 'storage/ndb/include/kernel/signaldata/AccLock.hpp'
--- a/storage/ndb/include/kernel/signaldata/AccLock.hpp	2011-02-01 23:27:25 +0000
+++ b/storage/ndb/include/kernel/signaldata/AccLock.hpp	2011-04-19 09:01:07 +0000
@@ -47,12 +47,12 @@ public:
     Refused = 3,
     NoFreeOp = 4
   };
-  STATIC_CONST( LockSignalLength = 12 );
+  STATIC_CONST( LockSignalLength = 13 );
   STATIC_CONST( UndoSignalLength = 3 );
 private:
   Uint32 returnCode;
   Uint32 requestInfo;
-  Uint32 accOpPtr; 
+  Uint32 accOpPtr;
   // rest only if lock request
   Uint32 userPtr;
   Uint32 userRef;
@@ -60,7 +60,8 @@ private:
   Uint32 fragId;
   Uint32 fragPtrI;
   Uint32 hashValue;
-  Uint32 tupAddr;
+  Uint32 page_id;
+  Uint32 page_idx;
   Uint32 transId1;
   Uint32 transId2;
 };

=== added file 'storage/ndb/include/kernel/signaldata/DihRestart.hpp'
--- a/storage/ndb/include/kernel/signaldata/DihRestart.hpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/include/kernel/signaldata/DihRestart.hpp	2011-04-15 13:52:53 +0000
@@ -0,0 +1,51 @@
+/*
+   Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+*/
+
+#ifndef DIH_RESTART_HPP
+#define DIH_RESTART_HPP
+
+#include "SignalData.hpp"
+
+struct DihRestartReq
+{
+  STATIC_CONST( SignalLength = 1 );
+  Uint32 senderRef;
+
+  /**
+   * Qmgr checks if it can continue...using EXECUTE_DIRECT
+   *   and fields below, setting senderRef == 0
+   */
+  STATIC_CONST( CheckLength = 1 + NdbNodeBitmask::Size + MAX_NDB_NODES);
+  Uint32 nodemask[NdbNodeBitmask::Size];
+  Uint32 node_gcis[MAX_NDB_NODES];
+};
+
+struct DihRestartRef
+{
+  STATIC_CONST( SignalLength = NdbNodeBitmask::Size );
+  Uint32 no_nodegroup_mask[NdbNodeBitmask::Size];
+};
+
+struct DihRestartConf
+{
+  STATIC_CONST( SignalLength = 2 + NdbNodeBitmask::Size );
+  Uint32 unused;
+  Uint32 latest_gci;
+  Uint32 no_nodegroup_mask[NdbNodeBitmask::Size];
+};
+
+#endif

=== modified file 'storage/ndb/include/kernel/signaldata/NextScan.hpp'
--- a/storage/ndb/include/kernel/signaldata/NextScan.hpp	2011-02-01 23:27:25 +0000
+++ b/storage/ndb/include/kernel/signaldata/NextScan.hpp	2011-04-19 09:01:07 +0000
@@ -49,13 +49,12 @@ class NextScanConf {
 public:
   // length is less if no keyinfo or no next result
   STATIC_CONST( SignalLength = 11 );
-  STATIC_CONST( SignalLengthNoKeyInfo = 7 );
+  STATIC_CONST( SignalLengthNoKeyInfo = 6 );
 private:
   Uint32 scanPtr;               // scan record in LQH
   Uint32 accOperationPtr;
   Uint32 fragId;
   Uint32 localKey[2];
-  Uint32 localKeyLength;
   Uint32 gci;
 };
 

=== modified file 'storage/ndb/include/mgmapi/mgmapi_config_parameters.h'
--- a/storage/ndb/include/mgmapi/mgmapi_config_parameters.h	2011-04-09 15:48:21 +0000
+++ b/storage/ndb/include/mgmapi/mgmapi_config_parameters.h	2011-04-15 13:52:53 +0000
@@ -184,6 +184,8 @@
 
 #define CFG_DB_CONNECT_CHECK_DELAY    618
 
+#define CFG_DB_START_NO_NODEGROUP_TIMEOUT 619
+
 #define CFG_NODE_ARBIT_RANK           200
 #define CFG_NODE_ARBIT_DELAY          201
 #define CFG_RESERVED_SEND_BUFFER_MEMORY 202

=== modified file 'storage/ndb/src/common/debugger/EventLogger.cpp'
--- a/storage/ndb/src/common/debugger/EventLogger.cpp	2011-04-09 15:48:21 +0000
+++ b/storage/ndb/src/common/debugger/EventLogger.cpp	2011-04-15 13:52:53 +0000
@@ -964,7 +964,13 @@ void getTextStartReport(QQQQ) {
     bstr0 = BaseString::getPrettyText(sz, theData + 4 + (0 * sz)), 
     bstr1 = BaseString::getPrettyText(sz, theData + 4 + (1 * sz)), 
     bstr2 = BaseString::getPrettyText(sz, theData + 4 + (2 * sz)), 
-    bstr3 = BaseString::getPrettyText(sz, theData + 4 + (3 * sz));
+    bstr3 = BaseString::getPrettyText(sz, theData + 4 + (3 * sz)),
+    bstr4 = BaseString::getPrettyText(sz, theData + 4 + (4 * sz));
+
+  if (len < 4 + 5 * sz)
+  {
+    bstr4.assign("<unknown>");
+  }
 
   switch(theData[1]){
   case 1: // Wait initial
@@ -1002,6 +1008,24 @@ void getTextStartReport(QQQQ) {
        "nodes [ all: %s connected: %s missing: %s no-wait: %s ]",
        time, bstr0.c_str(), bstr1.c_str(), bstr3.c_str(), bstr2.c_str());
     break;
+  case 6:
+    BaseString::snprintf
+      (m_text, m_text_len,
+       "Initial start, waiting %u for %s to connect, "
+       "nodes [ all: %s connected: %s missing: %s no-wait: %s no-nodegroup: %s ]",
+       time, bstr4.c_str(),
+       bstr0.c_str(), bstr1.c_str(), bstr3.c_str(), bstr2.c_str(),
+       bstr4.c_str());
+    break;
+  case 7: // Wait no-nodes/partial timeout
+    BaseString::snprintf
+      (m_text, m_text_len,
+       "Waiting %u sec for nodes %s to connect, "
+       "nodes [ all: %s connected: %s no-wait: %s no-nodegroup: %s ]",
+       time, bstr3.c_str(), bstr0.c_str(), bstr1.c_str(), bstr2.c_str(),
+       bstr4.c_str());
+    break;
+
   case 0x8000: // Do initial
     BaseString::snprintf
       (m_text, m_text_len,

=== modified file 'storage/ndb/src/common/debugger/signaldata/AccLock.cpp'
--- a/storage/ndb/src/common/debugger/signaldata/AccLock.cpp	2011-02-01 23:27:25 +0000
+++ b/storage/ndb/src/common/debugger/signaldata/AccLock.cpp	2011-04-19 09:01:07 +0000
@@ -70,7 +70,7 @@ printACC_LOCKREQ(FILE* output, const Uin
     fprintf(output, " userPtr: 0x%x userRef: 0x%x\n", sig->userPtr, sig->userRef);
     fprintf(output, " table: id=%u", sig->tableId);
     fprintf(output, " fragment: id=%u ptr=0x%x\n", sig->fragId, sig->fragPtrI);
-    fprintf(output, " tuple: addr=0x%x hashValue=%x\n", sig->tupAddr, sig->hashValue);
+    fprintf(output, " tuple: addr=%u/%u hashValue=%x\n", sig->page_id, sig->page_idx, sig->hashValue);
     fprintf(output, " transid: %08x %08x\n", sig->transId1, sig->transId2);
   }
   return true;

=== modified file 'storage/ndb/src/common/util/ndbzio.c'
--- a/storage/ndb/src/common/util/ndbzio.c	2011-04-04 09:37:59 +0000
+++ b/storage/ndb/src/common/util/ndbzio.c	2011-04-18 14:15:23 +0000
@@ -1069,5 +1069,5 @@ int ndbz_file_size(ndbzio_stream *s, siz
     return -1;
 
   *size = stat_buf.st_size;
-  return 0; // OK
+  return 0; /* OK */
 }

=== modified file 'storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp'
--- a/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp	2011-02-01 23:27:25 +0000
+++ b/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp	2011-04-19 09:01:07 +0000
@@ -773,7 +773,7 @@ private:
   void increaselistcont(Signal* signal);
   void seizeLeftlist(Signal* signal);
   void seizeRightlist(Signal* signal);
-  Uint32 readTablePk(Uint32 localkey1, Uint32 eh, OperationrecPtr);
+  Uint32 readTablePk(Uint32 lkey1, Uint32 lkey2, Uint32 eh, OperationrecPtr);
   Uint32 getElement(Signal* signal, OperationrecPtr& lockOwner);
   void getdirindex(Signal* signal);
   void commitdelete(Signal* signal);

=== modified file 'storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp	2011-02-01 23:27:25 +0000
+++ b/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp	2011-04-20 07:32:39 +0000
@@ -1020,10 +1020,8 @@ void Dbacc::sendAcckeyconf(Signal* signa
   signal->theData[2] = operationRecPtr.p->fid;
   signal->theData[3] = operationRecPtr.p->localdata[0];
   signal->theData[4] = operationRecPtr.p->localdata[1];
-  signal->theData[5] = fragrecptr.p->localkeylen;
 }//Dbacc::sendAcckeyconf()
 
-
 void 
 Dbacc::ACCKEY_error(Uint32 fromWhere)
 {
@@ -1516,8 +1514,9 @@ Dbacc::accIsLockedLab(Signal* signal, Op
   } 
   else 
   {
-    if (!(lockOwnerPtr.p->m_op_bits & Operationrec::OP_ELEMENT_DISAPPEARED) &&
-	lockOwnerPtr.p->localdata[0] != ~(Uint32)0) 
+    if (! (lockOwnerPtr.p->m_op_bits & Operationrec::OP_ELEMENT_DISAPPEARED) &&
+	! Local_key::isInvalid(lockOwnerPtr.p->localdata[0],
+                               lockOwnerPtr.p->localdata[1]))
     {
       jam();
       /* ---------------------------------------------------------------
@@ -1591,7 +1590,9 @@ void Dbacc::insertelementLab(Signal* sig
   tidrForward = ZTRUE;
   idrOperationRecPtr = operationRecPtr;
   clocalkey[0] = localKey;
+  clocalkey[1] = localKey;
   operationRecPtr.p->localdata[0] = localKey;
+  operationRecPtr.p->localdata[1] = localKey;
   /* ----------------------------------------------------------------------- */
   /* WE SET THE LOCAL KEY TO MINUS ONE TO INDICATE IT IS NOT YET VALID.      */
   /* ----------------------------------------------------------------------- */
@@ -2281,6 +2282,7 @@ void Dbacc::execACCMINUPDATE(Signal* sig
   operationRecPtr.i = signal->theData[0];
   tlocalkey1 = signal->theData[1];
   tlocalkey2 = signal->theData[2];
+  Uint32 localref = Local_key::ref(tlocalkey1, tlocalkey2);
   ptrCheckGuard(operationRecPtr, coprecsize, operationrec);
   Uint32 opbits = operationRecPtr.p->m_op_bits;
   fragrecptr.i = operationRecPtr.p->fragptr;
@@ -2294,17 +2296,18 @@ void Dbacc::execACCMINUPDATE(Signal* sig
     ptrCheckGuard(ulkPageidptr, cpagesize, page8);
     dbgWord32(ulkPageidptr, tulkLocalPtr, tlocalkey1);
     arrGuard(tulkLocalPtr, 2048);
-    ulkPageidptr.p->word32[tulkLocalPtr] = tlocalkey1;
     operationRecPtr.p->localdata[0] = tlocalkey1;
+    operationRecPtr.p->localdata[1] = tlocalkey2;
     if (likely(fragrecptr.p->localkeylen == 1))
     {
+      ulkPageidptr.p->word32[tulkLocalPtr] = localref;
       return;
-    } 
-    else if (fragrecptr.p->localkeylen == 2) 
+    }
+    else if (fragrecptr.p->localkeylen == 2)
     {
       jam();
+      ulkPageidptr.p->word32[tulkLocalPtr] = tlocalkey1;
       tulkLocalPtr = tulkLocalPtr + operationRecPtr.p->elementIsforward;
-      operationRecPtr.p->localdata[1] = tlocalkey2;
       dbgWord32(ulkPageidptr, tulkLocalPtr, tlocalkey2);
       arrGuard(tulkLocalPtr, 2048);
       ulkPageidptr.p->word32[tulkLocalPtr] = tlocalkey2;
@@ -2486,8 +2489,9 @@ void Dbacc::execACC_LOCKREQ(Signal* sign
       signal->theData[5] = req->transId1;
       signal->theData[6] = req->transId2;
       // enter local key in place of PK
-      signal->theData[7] = req->tupAddr;
-      EXECUTE_DIRECT(DBACC, GSN_ACCKEYREQ, signal, 8);
+      signal->theData[7] = req->page_id;
+      signal->theData[8] = req->page_idx;
+      EXECUTE_DIRECT(DBACC, GSN_ACCKEYREQ, signal, 9);
       // translate the result
       if (signal->theData[0] < RNIL) {
         jam();
@@ -3195,7 +3199,8 @@ void Dbacc::getdirindex(Signal* signal) 
 }//Dbacc::getdirindex()
 
 Uint32
-Dbacc::readTablePk(Uint32 localkey1, Uint32 eh, Ptr<Operationrec> opPtr)
+Dbacc::readTablePk(Uint32 localkey1, Uint32 localkey2,
+                   Uint32 eh, Ptr<Operationrec> opPtr)
 {
   int ret;
   Uint32 tableId = fragrecptr.p->myTableId;
@@ -3206,11 +3211,9 @@ Dbacc::readTablePk(Uint32 localkey1, Uin
   memset(ckeys, 0x1f, (fragrecptr.p->keyLength * MAX_XFRM_MULTIPLY) << 2);
 #endif
   
-  if (likely(localkey1 != ~(Uint32)0))
+  if (likely(! Local_key::isInvalid(localkey1, localkey2)))
   {
-    Uint32 fragPageId = localkey1 >> MAX_TUPLES_BITS;
-    Uint32 pageIndex = localkey1 & ((1 << MAX_TUPLES_BITS ) - 1);
-    ret = c_tup->accReadPk(tableId, fragId, fragPageId, pageIndex, 
+    ret = c_tup->accReadPk(tableId, fragId, localkey1, localkey2,
 			   ckeys, true);
   }
   else
@@ -3276,6 +3279,7 @@ Dbacc::getElement(Signal* signal, Operat
   register Uint32 tgeRemLen;
   register Uint32 TelemLen = fragrecptr.p->elementLength;
   register Uint32* Tkeydata = (Uint32*)&signal->theData[7];
+  const Uint32 localkeylen = fragrecptr.p->localkeylen;
 
   getdirindex(signal);
   tgePageindex = tgdiPageindex;
@@ -3287,7 +3291,7 @@ Dbacc::getElement(Signal* signal, Operat
    */
   const bool searchLocalKey = operationRecPtr.p->tupkeylen == 0;
 
-  ndbrequire(TelemLen == ZELEM_HEAD_SIZE + fragrecptr.p->localkeylen);
+  ndbrequire(TelemLen == ZELEM_HEAD_SIZE + localkeylen);
   tgeNextptrtype = ZLEFT;
 
   const Uint32 tmp = fragrecptr.p->k + fragrecptr.p->lhfragbits;
@@ -3298,7 +3302,7 @@ Dbacc::getElement(Signal* signal, Operat
       jam();
       tgeContainerptr = tgeContainerptr + ZHEAD_SIZE;
       tgeElementptr = tgeContainerptr + ZCON_HEAD_SIZE;
-      tgeKeyptr = (tgeElementptr + ZELEM_HEAD_SIZE) + fragrecptr.p->localkeylen;
+      tgeKeyptr = (tgeElementptr + ZELEM_HEAD_SIZE) + localkeylen;
       tgeElemStep = TelemLen;
       tgeForward = 1;
       if (unlikely(tgeContainerptr >= 2048)) 
@@ -3316,7 +3320,7 @@ Dbacc::getElement(Signal* signal, Operat
       jam();
       tgeContainerptr = tgeContainerptr + ((ZHEAD_SIZE + ZBUF_SIZE) - ZCON_HEAD_SIZE);
       tgeElementptr = tgeContainerptr - 1;
-      tgeKeyptr = (tgeElementptr - ZELEM_HEAD_SIZE) - fragrecptr.p->localkeylen;
+      tgeKeyptr = (tgeElementptr - ZELEM_HEAD_SIZE) - localkeylen;
       tgeElemStep = 0 - TelemLen;
       tgeForward = (Uint32)-1;
       if (unlikely(tgeContainerptr >= 2048)) 
@@ -3360,22 +3364,31 @@ Dbacc::getElement(Signal* signal, Operat
 	  localkey2 = lockOwnerPtr.p->localdata[1];
         } else {
           jam();
+          Uint32 pos = tgeElementptr + tgeForward;
           hashValuePart = ElementHeader::getHashValuePart(tgeElementHeader);
-          localkey1 = gePageptr.p->word32[tgeElementptr + tgeForward];
-          localkey2 = 0;
+          localkey1 = gePageptr.p->word32[pos];
+          if (likely(localkeylen == 1))
+          {
+            localkey2 = Local_key::ref2page_idx(localkey1);
+            localkey1 = Local_key::ref2page_id(localkey1);
+          }
+          else
+          {
+            localkey2 = gePageptr.p->word32[pos + tgeForward];
+          }
         }
         if (hashValuePart == opHashValuePart) {
           jam();
           bool found;
           if (! searchLocalKey) 
 	  {
-            Uint32 len = readTablePk(localkey1, tgeElementHeader, 
+            Uint32 len = readTablePk(localkey1, localkey2, tgeElementHeader,
 				     lockOwnerPtr);
             found = (len == operationRecPtr.p->xfrmtupkeylen) &&
 	      (memcmp(Tkeydata, ckeys, len << 2) == 0);
           } else {
             jam();
-            found = (localkey1 == Tkeydata[0]);
+            found = (localkey1 == Tkeydata[0] && localkey2 == Tkeydata[1]);
           }
           if (found) 
 	  {
@@ -3460,21 +3473,20 @@ error:
 void
 Dbacc::report_dealloc(Signal* signal, const Operationrec* opPtrP)
 {
-  Uint32 localKey = opPtrP->localdata[0];
+  Uint32 localKey1 = opPtrP->localdata[0];
+  Uint32 localKey2 = opPtrP->localdata[1];
   Uint32 opbits = opPtrP->m_op_bits;
   Uint32 userptr= opPtrP->userptr;
   Uint32 scanInd = 
     ((opbits & Operationrec::OP_MASK) == ZSCAN_OP) || 
     (opbits & Operationrec::OP_LOCK_REQ);
   
-  if (localKey != ~(Uint32)0)
+  if (! Local_key::isInvalid(localKey1, localKey2))
   {
     signal->theData[0] = fragrecptr.p->myfid;
     signal->theData[1] = fragrecptr.p->myTableId;
-    Uint32 pageId = localKey >> MAX_TUPLES_BITS;
-    Uint32 pageIndex = localKey & ((1 << MAX_TUPLES_BITS) - 1);
-    signal->theData[2] = pageId;
-    signal->theData[3] = pageIndex;
+    signal->theData[2] = localKey1;
+    signal->theData[3] = localKey2;
     signal->theData[4] = userptr;
     signal->theData[5] = scanInd;
     EXECUTE_DIRECT(DBLQH, GSN_TUP_DEALLOCREQ, signal, 6);
@@ -4686,6 +4698,7 @@ Dbacc::release_lockowner(Signal* signal,
 	  jam();
 	  report_dealloc(signal, opPtr.p);
 	  newOwner.p->localdata[0] = ~(Uint32)0;
+	  newOwner.p->localdata[1] = ~(Uint32)0;
 	}
 	else
 	{
@@ -4734,6 +4747,7 @@ Dbacc::release_lockowner(Signal* signal,
     {
       report_dealloc(signal, opPtr.p);
       newOwner.p->localdata[0] = ~(Uint32)0;
+      newOwner.p->localdata[1] = ~(Uint32)0;
     }
     else
     {
@@ -6553,7 +6567,8 @@ void Dbacc::checkNextBucketLab(Signal* s
       ElementHeader::getOpPtrI(nsPageptr.p->word32[tnsElementptr]);
     ptrCheckGuard(queOperPtr, coprecsize, operationrec);
     if (queOperPtr.p->m_op_bits & Operationrec::OP_ELEMENT_DISAPPEARED ||
-	queOperPtr.p->localdata[0] == ~(Uint32)0) 
+	Local_key::isInvalid(queOperPtr.p->localdata[0],
+                             queOperPtr.p->localdata[1]))
     {
       jam();
       /* ------------------------------------------------------------------ */
@@ -6983,9 +6998,8 @@ bool Dbacc::getScanElement(Signal* signa
 /* --------------------------------------------------------------------------------- */
 void Dbacc::initScanOpRec(Signal* signal) 
 {
-  Uint32 tisoTmp;
   Uint32 tisoLocalPtr;
-  Uint32 guard24;
+  Uint32 localkeylen = fragrecptr.p->localkeylen;
 
   scanPtr.p->scanOpsAllocated++;
 
@@ -7012,14 +7026,21 @@ void Dbacc::initScanOpRec(Signal* signal
   operationRecPtr.p->elementPage = isoPageptr.i;
   operationRecPtr.p->m_op_bits = opbits;
   tisoLocalPtr = tisoElementptr + tisoIsforward;
-  guard24 = fragrecptr.p->localkeylen - 1;
-  for (tisoTmp = 0; tisoTmp <= guard24; tisoTmp++) {
-    arrGuard(tisoTmp, 2);
-    arrGuard(tisoLocalPtr, 2048);
-    operationRecPtr.p->localdata[tisoTmp] = isoPageptr.p->word32[tisoLocalPtr];
-    tisoLocalPtr = tisoLocalPtr + tisoIsforward;
-  }//for
+
   arrGuard(tisoLocalPtr, 2048);
+  Uint32 Tkey1 = isoPageptr.p->word32[tisoLocalPtr];
+  tisoLocalPtr = tisoLocalPtr + tisoIsforward;
+  if (localkeylen == 1)
+  {
+    operationRecPtr.p->localdata[0] = Local_key::ref2page_id(Tkey1);
+    operationRecPtr.p->localdata[1] = Local_key::ref2page_idx(Tkey1);
+  }
+  else
+  {
+    arrGuard(tisoLocalPtr, 2048);
+    operationRecPtr.p->localdata[0] = Tkey1;
+    operationRecPtr.p->localdata[1] = isoPageptr.p->word32[tisoLocalPtr];
+  }
   operationRecPtr.p->tupkeylen = fragrecptr.p->keyLength;
   operationRecPtr.p->xfrmtupkeylen = 0; // not used
 }//Dbacc::initScanOpRec()
@@ -7369,6 +7390,7 @@ bool Dbacc::searchScanContainer(Signal* 
 void Dbacc::sendNextScanConf(Signal* signal) 
 {
   Uint32 blockNo = refToMain(scanPtr.p->scanUserblockref);
+
   jam();
   /** ---------------------------------------------------------------------
    * LQH WILL NOT HAVE ANY USE OF THE TUPLE KEY LENGTH IN THIS CASE AND 
@@ -7379,8 +7401,7 @@ void Dbacc::sendNextScanConf(Signal* sig
   signal->theData[2] = operationRecPtr.p->fid;
   signal->theData[3] = operationRecPtr.p->localdata[0];
   signal->theData[4] = operationRecPtr.p->localdata[1];
-  signal->theData[5] = fragrecptr.p->localkeylen;
-  EXECUTE_DIRECT(blockNo, GSN_NEXT_SCANCONF, signal, 6);
+  EXECUTE_DIRECT(blockNo, GSN_NEXT_SCANCONF, signal, 5);
   return;
 }//Dbacc::sendNextScanConf()
 

=== modified file 'storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp'
--- a/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp	2011-02-15 11:41:27 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp	2011-04-15 13:52:53 +0000
@@ -951,6 +951,7 @@ private:
   void replication(Uint32 noOfReplicas,
                    NodeGroupRecordPtr NGPtr,
                    FragmentstorePtr regFragptr);
+  void sendDihRestartRef(Signal*);
   void selectMasterCandidateAndSend(Signal *);
   void setLcpActiveStatusEnd(Signal*);
   void setLcpActiveStatusStart(Signal *);

=== modified file 'storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2011-02-23 19:28:26 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2011-04-15 13:52:53 +0000
@@ -79,6 +79,7 @@
 #include <signaldata/DropNodegroupImpl.hpp>
 #include <signaldata/DihGetTabInfo.hpp>
 #include <SectionReader.hpp>
+#include <signaldata/DihRestart.hpp>
 
 #include <EventLogger.hpp>
 extern EventLogger * g_eventLogger;
@@ -1455,15 +1456,18 @@ void Dbdih::execTAB_COMMITREQ(Signal* si
   3.2.1.1    LOADING   O W N   B L O C K  R E F E R E N C E (ABSOLUTE PHASE 1)
   *****************************************************************************
   */
-void Dbdih::execDIH_RESTARTREQ(Signal* signal) 
+void Dbdih::execDIH_RESTARTREQ(Signal* signal)
 {
   jamEntry();
-  if (signal->theData[0])
+  const DihRestartReq* req = CAST_CONSTPTR(DihRestartReq,
+                                           signal->getDataPtr());
+  if (req->senderRef != 0)
   {
     jam();
-    cntrlblockref = signal->theData[0];
-    if(m_ctx.m_config.getInitialStart()){
-      sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
+    cntrlblockref = req->senderRef;
+    if(m_ctx.m_config.getInitialStart())
+    {
+      sendDihRestartRef(signal);
     } else {
       readGciFileLab(signal);
     }
@@ -1476,8 +1480,8 @@ void Dbdih::execDIH_RESTARTREQ(Signal* s
      */
     Uint32 i;
     NdbNodeBitmask mask;
-    mask.assign(NdbNodeBitmask::Size, signal->theData + 1);
-    Uint32 *node_gcis = signal->theData+1+NdbNodeBitmask::Size;
+    mask.assign(NdbNodeBitmask::Size, req->nodemask);
+    const Uint32 *node_gcis = req->node_gcis;
     Uint32 node_group_gcis[MAX_NDB_NODES+1];
     bzero(node_group_gcis, sizeof(node_group_gcis));
     for (i = 0; i<MAX_NDB_NODES; i++)
@@ -4696,24 +4700,65 @@ void Dbdih::closingGcpLab(Signal* signal
     return;
   } else {
     jam();
-    sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
+    sendDihRestartRef(signal);
     return;
   }//if
 }//Dbdih::closingGcpLab()
 
+void
+Dbdih::sendDihRestartRef(Signal* signal)
+{
+  jam();
+
+  /**
+   * We couldn't read P0.Sysfile...
+   *   so compute no_nodegroup_mask from configuration
+   */
+  NdbNodeBitmask no_nodegroup_mask;
+
+  ndb_mgm_configuration_iterator * iter =
+    m_ctx.m_config.getClusterConfigIterator();
+  for(ndb_mgm_first(iter); ndb_mgm_valid(iter); ndb_mgm_next(iter))
+  {
+    jam();
+    Uint32 nodeId;
+    Uint32 nodeType;
+
+    ndbrequire(!ndb_mgm_get_int_parameter(iter,CFG_NODE_ID, &nodeId));
+    ndbrequire(!ndb_mgm_get_int_parameter(iter,CFG_TYPE_OF_SECTION,
+                                          &nodeType));
+
+    if (nodeType == NodeInfo::DB)
+    {
+      jam();
+      Uint32 ng;
+      if (ndb_mgm_get_int_parameter(iter, CFG_DB_NODEGROUP, &ng) == 0)
+      {
+        jam();
+        if (ng == NDB_NO_NODEGROUP)
+        {
+          no_nodegroup_mask.set(nodeId);
+        }
+      }
+    }
+  }
+  DihRestartRef * ref = CAST_PTR(DihRestartRef, signal->getDataPtrSend());
+  no_nodegroup_mask.copyto(NdbNodeBitmask::Size, ref->no_nodegroup_mask);
+  sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal,
+             DihRestartRef::SignalLength, JBB);
+}
+
 /* ------------------------------------------------------------------------- */
 /*       SELECT THE MASTER CANDIDATE TO BE USED IN SYSTEM RESTARTS.          */
 /* ------------------------------------------------------------------------- */
 void Dbdih::selectMasterCandidateAndSend(Signal* signal)
 {
   setNodeGroups();
-  signal->theData[0] = getOwnNodeId();
-  signal->theData[1] = SYSFILE->lastCompletedGCI[getOwnNodeId()];
-  sendSignal(cntrlblockref, GSN_DIH_RESTARTCONF, signal, 2, JBB);
-  
+
   NodeRecordPtr nodePtr;
   Uint32 node_groups[MAX_NDB_NODES];
   memset(node_groups, 0, sizeof(node_groups));
+  NdbNodeBitmask no_nodegroup_mask;
   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
     jam();
     if (Sysfile::getNodeStatus(nodePtr.i, SYSFILE->nodeStatus) == Sysfile::NS_NotDefined)
@@ -4722,12 +4767,24 @@ void Dbdih::selectMasterCandidateAndSend
       continue;
     }
     const Uint32 ng = Sysfile::getNodeGroup(nodePtr.i, SYSFILE->nodeGroups);
-    if(ng != NO_NODE_GROUP_ID){
+    if(ng != NO_NODE_GROUP_ID)
+    {
       ndbrequire(ng < MAX_NDB_NODES);
       node_groups[ng]++;
     }
+    else
+    {
+      no_nodegroup_mask.set(nodePtr.i);
+    }
   }
-  
+
+  DihRestartConf * conf = CAST_PTR(DihRestartConf, signal->getDataPtrSend());
+  conf->unused = getOwnNodeId();
+  conf->latest_gci = SYSFILE->lastCompletedGCI[getOwnNodeId()];
+  no_nodegroup_mask.copyto(NdbNodeBitmask::Size, conf->no_nodegroup_mask);
+  sendSignal(cntrlblockref, GSN_DIH_RESTARTCONF, signal,
+             DihRestartConf::SignalLength, JBB);
+
   for (nodePtr.i = 0; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
     jam();
     Uint32 count = node_groups[nodePtr.i];
@@ -4767,7 +4824,7 @@ void Dbdih::openingGcpErrorLab(Signal* s
     /*   CANNOT CONTINUE THE RESTART IN THIS CASE. TELL NDBCNTR OF OUR       */
     /*   FAILURE.                                                            */
     /*---------------------------------------------------------------------- */
-    sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
+    sendDihRestartRef(signal);
     return;
   }//if
 }//Dbdih::openingGcpErrorLab()
@@ -4799,7 +4856,7 @@ void Dbdih::closingGcpCrashLab(Signal* s
   /*     WE DISCOVERED A FAILURE WITH THE SECOND FILE AS WELL. THIS IS A     */
   /*     SERIOUS PROBLEM. REPORT FAILURE TO NDBCNTR.                         */
   /* ----------------------------------------------------------------------- */
-  sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
+  sendDihRestartRef(signal);
 }//Dbdih::closingGcpCrashLab()
 
 /*****************************************************************************/

=== modified file 'storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2011-04-05 09:38:31 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2011-04-19 09:01:07 +0000
@@ -2731,9 +2731,11 @@ public:
   Uint32 readPrimaryKeys(Uint32 opPtrI, Uint32 * dst, bool xfrm);
 private:
 
-  void acckeyconf_tupkeyreq(Signal*, TcConnectionrec*, Fragrecord*, Uint32, Uint32);
-  void acckeyconf_load_diskpage(Signal*,TcConnectionrecPtr,Fragrecord*,Uint32);
-  
+  void acckeyconf_tupkeyreq(Signal*, TcConnectionrec*, Fragrecord*,
+                            Uint32, Uint32, Uint32);
+  void acckeyconf_load_diskpage(Signal*,TcConnectionrecPtr,Fragrecord*,
+                                Uint32, Uint32);
+
   void handle_nr_copy(Signal*, Ptr<TcConnectionrec>);
   void exec_acckeyreq(Signal*, Ptr<TcConnectionrec>);
   int compare_key(const TcConnectionrec*, const Uint32 * ptr, Uint32 len);
@@ -3340,7 +3342,8 @@ Dblqh::accminupdate(Signal* signal, Uint
   regTcPtr.i= opId;
   ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec);
   signal->theData[0] = regTcPtr.p->accConnectrec;
-  signal->theData[1] = key->m_page_no << MAX_TUPLES_BITS | key->m_page_idx;
+  signal->theData[1] = key->m_page_no;
+  signal->theData[2] = key->m_page_idx;
   c_acc->execACCMINUPDATE(signal);
 
   if (ERROR_INSERTED(5714))

=== modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2011-04-07 07:22:49 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2011-04-19 09:01:07 +0000
@@ -5808,9 +5808,9 @@ void Dblqh::execACCKEYCONF(Signal* signa
   Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
   Uint32 tcIndex = signal->theData[0];
   Uint32 localKey1 = signal->theData[3];
-  //Uint32 localKey2 = signal->theData[4];
-  Uint32 localKeyFlag = signal->theData[5];
+  Uint32 localKey2 = signal->theData[4];
   jamEntry();
+
   tcConnectptr.i = tcIndex;
   ptrCheckGuard(tcConnectptr, ttcConnectrecFileSize, regTcConnectionrec);
   TcConnectionrec * const regTcPtr = tcConnectptr.p;
@@ -5865,17 +5865,18 @@ void Dblqh::execACCKEYCONF(Signal* signa
   regFragptr.i = regTcPtr->fragmentptr;
   c_fragment_pool.getPtr(regFragptr);
 
-  ndbrequire(localKeyFlag == 1);
   if(!regTcPtr->m_disk_table)
-    acckeyconf_tupkeyreq(signal, regTcPtr, regFragptr.p, localKey1, RNIL);
+    acckeyconf_tupkeyreq(signal, regTcPtr, regFragptr.p,
+                         localKey1, localKey2, RNIL);
   else
-    acckeyconf_load_diskpage(signal, tcConnectptr, regFragptr.p, localKey1);
+    acckeyconf_load_diskpage(signal, tcConnectptr, regFragptr.p,
+                             localKey1, localKey2);
 }
 
 void
 Dblqh::acckeyconf_tupkeyreq(Signal* signal, TcConnectionrec* regTcPtr,
-			    Fragrecord* regFragptrP, 
-			    Uint32 local_key,
+			    Fragrecord* regFragptrP,
+			    Uint32 lkey1, Uint32 lkey2,
 			    Uint32 disk_page)
 {
   Uint32 op = regTcPtr->operation;
@@ -5888,8 +5889,8 @@ Dblqh::acckeyconf_tupkeyreq(Signal* sign
    * IS NEEDED SINCE TWO SCHEMA VERSIONS CAN BE ACTIVE SIMULTANEOUSLY ON A 
    * TABLE.
    * ----------------------------------------------------------------------- */
-  Uint32 page_idx = local_key & MAX_TUPLES_PER_PAGE;
-  Uint32 page_no = local_key >> MAX_TUPLES_BITS;
+  Uint32 page_idx = lkey2;
+  Uint32 page_no = lkey1;
   Uint32 Ttupreq = regTcPtr->dirtyOp;
   Ttupreq = Ttupreq + (regTcPtr->opSimple << 1);
   Ttupreq = Ttupreq + (op << 6);
@@ -5969,21 +5970,23 @@ Dblqh::acckeyconf_tupkeyreq(Signal* sign
 
 void
 Dblqh::acckeyconf_load_diskpage(Signal* signal, TcConnectionrecPtr regTcPtr,
-				Fragrecord* regFragptrP, Uint32 local_key)
+				Fragrecord* regFragptrP,
+                                Uint32 lkey1, Uint32 lkey2)
 {
   int res;
   if((res= c_tup->load_diskpage(signal, 
 				regTcPtr.p->tupConnectrec,
-				regFragptrP->tupFragptr, 
-				local_key, 
+				regFragptrP->tupFragptr,
+				lkey1, lkey2,
 				regTcPtr.p->operation)) > 0)
   {
-    acckeyconf_tupkeyreq(signal, regTcPtr.p, regFragptrP, local_key, res);
+    acckeyconf_tupkeyreq(signal, regTcPtr.p, regFragptrP, lkey1, lkey2, res);
   }
   else if(res == 0)
   {
     regTcPtr.p->transactionState = TcConnectionrec::WAIT_TUP;
-    regTcPtr.p->m_row_id.assref(local_key);
+    regTcPtr.p->m_row_id.m_page_no = lkey1;
+    regTcPtr.p->m_row_id.m_page_idx = lkey2;
   }
   else 
   {
@@ -6011,8 +6014,9 @@ Dblqh::acckeyconf_load_diskpage_callback
     FragrecordPtr fragPtr;
     c_fragment_pool.getPtr(fragPtr, regTcPtr->fragmentptr);
     
-    acckeyconf_tupkeyreq(signal, regTcPtr, fragPtr.p, 
-			 regTcPtr->m_row_id.ref(),
+    acckeyconf_tupkeyreq(signal, regTcPtr, fragPtr.p,
+			 regTcPtr->m_row_id.m_page_no,
+			 regTcPtr->m_row_id.m_page_idx,
 			 disk_page);
   }
   else if (state != TcConnectionrec::WAIT_TUP)
@@ -9351,18 +9355,9 @@ void Dblqh::execNEXT_SCANCONF(Signal* si
   jamEntry();
   scanptr.i = nextScanConf->scanPtr;
   c_scanRecordPool.getPtr(scanptr);
-  if (likely(nextScanConf->localKeyLength == 1)) //XXX signal length ?
-  {
-    jam();
-    scanptr.p->m_row_id.assref(nextScanConf->localKey[0]);
-  }
-  else
-  {
-    jam();
-    scanptr.p->m_row_id.m_page_no = nextScanConf->localKey[0];
-    scanptr.p->m_row_id.m_page_idx = nextScanConf->localKey[1]; 
-  }
-  
+  scanptr.p->m_row_id.m_page_no = nextScanConf->localKey[0];
+  scanptr.p->m_row_id.m_page_idx = nextScanConf->localKey[1];
+
 #ifdef VM_TRACE
   if (signal->getLength() > 2 && nextScanConf->accOperationPtr != RNIL)
   {
@@ -10792,14 +10787,14 @@ Dblqh::next_scanconf_load_diskpage(Signa
 				   Fragrecord* fragPtrP)
 {
   jam();
-  
+
   int res;
-  Uint32 local_key = scanPtr.p->m_row_id.ref();
-  
-  if((res= c_tup->load_diskpage_scan(signal, 
+
+  if((res= c_tup->load_diskpage_scan(signal,
 				     regTcPtr.p->tupConnectrec,
-				     fragPtrP->tupFragptr, 
-				     local_key, 
+				     fragPtrP->tupFragptr,
+				     scanPtr.p->m_row_id.m_page_no,
+				     scanPtr.p->m_row_id.m_page_idx,
 				     0)) > 0)
   {
     next_scanconf_tupkeyreq(signal, scanptr, regTcPtr.p, fragPtrP, res);

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2011-02-10 10:16:09 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2011-04-20 07:07:02 +0000
@@ -1364,12 +1364,12 @@ typedef Ptr<HostBuffer> HostBufferPtr;
     STATIC_CONST( SZ32 = 1 );
 
     void copyout(Local_key* dst) const {
-      dst->m_page_no = m_ref >> MAX_TUPLES_BITS;
-      dst->m_page_idx = m_ref & MAX_TUPLES_PER_PAGE;
+      dst->m_page_no = Local_key::ref2page_id(m_ref);
+      dst->m_page_idx = Local_key::ref2page_idx(m_ref);
     }
 
     void assign(const Local_key* src) {
-      m_ref = (src->m_page_no << MAX_TUPLES_BITS) | src->m_page_idx;
+      m_ref = Local_key::ref(src->m_page_no, src->m_page_idx);
     }
 #else
     Uint32 m_page_no;
@@ -1671,7 +1671,8 @@ public:
   /*
    * TUX uses logical tuple address when talking to ACC and LQH.
    */
-  void tuxGetTupAddr(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32& tupAddr);
+  void tuxGetTupAddr(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset,
+                     Uint32& lkey1, Uint32& lkey2);
 
   /*
    * TUX index in TUP has single Uint32 array attribute which stores an
@@ -1711,11 +1712,11 @@ public:
    */
   bool tuxQueryTh(Uint32 fragPtrI, Uint32 pageId, Uint32 pageIndex, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, bool dirty, Uint32 savepointId);
 
-  int load_diskpage(Signal*, Uint32 opRec, Uint32 fragPtrI, 
-		    Uint32 local_key, Uint32 flags);
+  int load_diskpage(Signal*, Uint32 opRec, Uint32 fragPtrI,
+		    Uint32 lkey1, Uint32 lkey2, Uint32 flags);
 
-  int load_diskpage_scan(Signal*, Uint32 opRec, Uint32 fragPtrI, 
-			 Uint32 local_key, Uint32 flags);
+  int load_diskpage_scan(Signal*, Uint32 opRec, Uint32 fragPtrI,
+			 Uint32 lkey1, Uint32 lkey2, Uint32 flags);
 
   void start_restore_lcp(Uint32 tableId, Uint32 fragmentId);
   void complete_restore_lcp(Signal*, Uint32 ref, Uint32 data,
@@ -2933,7 +2934,7 @@ private:
   void   removeTdArea(Uint32 tabDesRef, Uint32 list);
   void   insertTdArea(Uint32 tabDesRef, Uint32 list);
   void   itdaMergeTabDescr(Uint32& retRef, Uint32& retNo, bool normal);
-#ifdef VM_TRACE
+#if defined VM_TRACE || defined ERROR_INSERT
   void verifytabdes();
 #endif
 

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp	2011-02-10 10:16:09 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp	2011-04-19 09:01:07 +0000
@@ -42,7 +42,7 @@ void Dbtup::execTUP_DEALLOCREQ(Signal* s
   getFragmentrec(regFragPtr, frag_id, regTabPtr.p);
   ndbassert(regFragPtr.p != NULL);
   
-  if (! (((frag_page_id << MAX_TUPLES_BITS) + page_index) == ~ (Uint32) 0))
+  if (! Local_key::isInvalid(frag_page_id, page_index))
   {
     Local_key tmp;
     tmp.m_page_no= getRealpid(regFragPtr.p, frag_page_id); 

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp	2011-04-04 08:03:41 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp	2011-04-19 09:01:07 +0000
@@ -325,9 +325,9 @@ Dbtup::setup_read(KeyReqStruct *req_stru
 }
 
 int
-Dbtup::load_diskpage(Signal* signal, 
-		     Uint32 opRec, Uint32 fragPtrI, 
-		     Uint32 local_key, Uint32 flags)
+Dbtup::load_diskpage(Signal* signal,
+		     Uint32 opRec, Uint32 fragPtrI,
+		     Uint32 lkey1, Uint32 lkey2, Uint32 flags)
 {
   Ptr<Tablerec> tabptr;
   Ptr<Fragrecord> fragptr;
@@ -336,15 +336,15 @@ Dbtup::load_diskpage(Signal* signal, 
   c_operation_pool.getPtr(operPtr, opRec);
   fragptr.i= fragPtrI;
   ptrCheckGuard(fragptr, cnoOfFragrec, fragrecord);
-  
+
   Operationrec *  regOperPtr= operPtr.p;
   Fragrecord * regFragPtr= fragptr.p;
-  
+
   tabptr.i = regFragPtr->fragTableId;
   ptrCheckGuard(tabptr, cnoOfTablerec, tablerec);
   Tablerec* regTabPtr = tabptr.p;
-  
-  if(local_key == ~(Uint32)0)
+
+  if (Local_key::ref(lkey1, lkey2) == ~(Uint32)0)
   {
     jam();
     regOperPtr->op_struct.m_wait_log_buffer= 1;
@@ -353,8 +353,8 @@ Dbtup::load_diskpage(Signal* signal, 
   }
   
   jam();
-  Uint32 page_idx= local_key & MAX_TUPLES_PER_PAGE;
-  Uint32 frag_page_id= local_key >> MAX_TUPLES_BITS;
+  Uint32 page_idx= lkey2;
+  Uint32 frag_page_id= lkey1;
   regOperPtr->m_tuple_location.m_page_no= getRealpid(regFragPtr,
 						     frag_page_id);
   regOperPtr->m_tuple_location.m_page_idx= page_idx;
@@ -424,9 +424,9 @@ Dbtup::disk_page_load_callback(Signal* s
 }
 
 int
-Dbtup::load_diskpage_scan(Signal* signal, 
-			  Uint32 opRec, Uint32 fragPtrI, 
-			  Uint32 local_key, Uint32 flags)
+Dbtup::load_diskpage_scan(Signal* signal,
+			  Uint32 opRec, Uint32 fragPtrI,
+			  Uint32 lkey1, Uint32 lkey2, Uint32 flags)
 {
   Ptr<Tablerec> tabptr;
   Ptr<Fragrecord> fragptr;
@@ -435,17 +435,17 @@ Dbtup::load_diskpage_scan(Signal* signal
   c_operation_pool.getPtr(operPtr, opRec);
   fragptr.i= fragPtrI;
   ptrCheckGuard(fragptr, cnoOfFragrec, fragrecord);
-  
+
   Operationrec *  regOperPtr= operPtr.p;
   Fragrecord * regFragPtr= fragptr.p;
-  
+
   tabptr.i = regFragPtr->fragTableId;
   ptrCheckGuard(tabptr, cnoOfTablerec, tablerec);
   Tablerec* regTabPtr = tabptr.p;
-  
+
   jam();
-  Uint32 page_idx= local_key & MAX_TUPLES_PER_PAGE;
-  Uint32 frag_page_id= local_key >> MAX_TUPLES_BITS;
+  Uint32 page_idx= lkey2;
+  Uint32 frag_page_id= lkey1;
   regOperPtr->m_tuple_location.m_page_no= getRealpid(regFragPtr,
 						     frag_page_id);
   regOperPtr->m_tuple_location.m_page_idx= page_idx;
@@ -627,8 +627,7 @@ void Dbtup::execTUPKEYREQ(Signal* signal
                 req_struct.attrinfo_len,
                 attrInfoIVal);
    
-   Uint32 localkey = (pageid << MAX_TUPLES_BITS) + pageidx;
-   if (Roptype == ZINSERT && localkey == ~ (Uint32) 0)
+   if (Roptype == ZINSERT && Local_key::isInvalid(pageid, pageidx))
    {
      // No tuple allocatated yet
      goto do_insert;

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp	2011-02-01 23:27:25 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp	2011-04-19 09:01:07 +0000
@@ -34,13 +34,14 @@ void
 Dbtup::tuxGetTupAddr(Uint32 fragPtrI,
                      Uint32 pageId,
                      Uint32 pageIndex,
-                     Uint32& tupAddr)
+                     Uint32& lkey1,
+                     Uint32& lkey2)
 {
   jamEntry();
   PagePtr pagePtr;
   c_page_pool.getPtr(pagePtr, pageId);
-  Uint32 fragPageId= pagePtr.p->frag_page_id;
-  tupAddr= (fragPageId << MAX_TUPLES_BITS) | pageIndex;
+  lkey1 = pagePtr.p->frag_page_id;
+  lkey2 = pageIndex;
 }
 
 int

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp	2011-04-07 07:22:49 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp	2011-04-18 15:36:25 +0000
@@ -1809,7 +1809,7 @@ Dbtup::execDROP_TAB_REQ(Signal* signal)
 {
   jamEntry();
   if (ERROR_INSERTED(4013)) {
-#ifdef VM_TRACE
+#if defined VM_TRACE || defined ERROR_INSERT
     verifytabdes();
 #endif
   }
@@ -2565,7 +2565,7 @@ Dbtup::execDROP_FRAG_REQ(Signal* signal)
 {
   jamEntry();
   if (ERROR_INSERTED(4013)) {
-#ifdef VM_TRACE
+#if defined VM_TRACE || defined ERROR_INSERT
     verifytabdes();
 #endif
   }

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp	2011-04-05 09:12:21 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp	2011-04-19 09:01:07 +0000
@@ -354,7 +354,8 @@ Dbtup::scanReply(Signal* signal, ScanOpP
       lockReq->fragId = frag.fragmentId;
       lockReq->fragPtrI = RNIL; // no cached frag ptr yet
       lockReq->hashValue = md5_hash((Uint64*)pkData, pkSize);
-      lockReq->tupAddr = key_mm.ref();
+      lockReq->page_id = key_mm.m_page_no;
+      lockReq->page_idx = key_mm.m_page_idx;
       lockReq->transId1 = scan.m_transId1;
       lockReq->transId2 = scan.m_transId2;
       EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ,
@@ -432,10 +433,9 @@ Dbtup::scanReply(Signal* signal, ScanOpP
     const ScanPos& pos = scan.m_scanPos;
     conf->accOperationPtr = accLockOp;
     conf->fragId = frag.fragmentId;
-    conf->localKey[0] = pos.m_key_mm.ref();
-    conf->localKey[1] = 0;
-    conf->localKeyLength = 1;
-    unsigned signalLength = 6;
+    conf->localKey[0] = pos.m_key_mm.m_page_no;
+    conf->localKey[1] = pos.m_key_mm.m_page_idx;
+    unsigned signalLength = 5;
     if (scan.m_bits & ScanOp::SCAN_LOCK) {
       sendSignal(scan.m_userRef, GSN_NEXT_SCANCONF,
           signal, signalLength, JBB);
@@ -478,17 +478,9 @@ Dbtup::execACCKEYCONF(Signal* signal)
 
   Uint32 localKey1 = signal->theData[3];
   Uint32 localKey2 = signal->theData[4];
-  Uint32 localKeyFlag = signal->theData[5];
   Local_key tmp;
-  if (localKeyFlag == 1)
-  {
-    tmp.assref(localKey1);
-  }
-  else
-  {
-    tmp.m_page_no = localKey1;
-    tmp.m_page_idx = localKey2;
-  }
+  tmp.m_page_no = localKey1;
+  tmp.m_page_idx = localKey2;
 
   c_scanOpPool.getPtr(scanPtr);
   ScanOp& scan = *scanPtr.p;
@@ -1107,12 +1099,11 @@ Dbtup::scanNext(Signal* signal, ScanOpPt
 	conf->scanPtr = scan.m_userPtr;
 	conf->accOperationPtr = RNIL;
 	conf->fragId = frag.fragmentId;
-	conf->localKey[0] = pos.m_key_mm.ref();
-	conf->localKey[1] = 0;
-	conf->localKeyLength = 1;
+	conf->localKey[0] = pos.m_key_mm.m_page_no;
+	conf->localKey[1] = pos.m_key_mm.m_page_idx;
 	conf->gci = foundGCI;
 	Uint32 blockNo = refToMain(scan.m_userRef);
-	EXECUTE_DIRECT(blockNo, GSN_NEXT_SCANCONF, signal, 7);
+	EXECUTE_DIRECT(blockNo, GSN_NEXT_SCANCONF, signal, 6);
 	jamEntry();
 
 	// TUPKEYREQ handles savepoint stuff
@@ -1170,12 +1161,11 @@ Dbtup::handle_lcp_keep(Signal* signal,
   conf->scanPtr = scanPtrP->m_userPtr;
   conf->accOperationPtr = (Uint32)-1;
   conf->fragId = fragPtrP->fragmentId;
-  conf->localKey[0] = lcp_list;
-  conf->localKey[1] = 0;
-  conf->localKeyLength = 1;
+  conf->localKey[0] = Local_key::ref2page_id(lcp_list);
+  conf->localKey[1] = Local_key::ref2page_idx(lcp_list);
   conf->gci = 0;
   Uint32 blockNo = refToMain(scanPtrP->m_userRef);
-  EXECUTE_DIRECT(blockNo, GSN_NEXT_SCANCONF, signal, 7);
+  EXECUTE_DIRECT(blockNo, GSN_NEXT_SCANCONF, signal, 6);
   
   fragPtrP->m_lcp_keep_list = next;
   ptr->m_header_bits |= Tuple_header::FREED; // RESTORE free flag

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp	2011-02-07 13:21:49 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp	2011-04-19 15:59:06 +0000
@@ -28,6 +28,9 @@
  * TABLE DESCRIPTOR MEMORY MANAGER
  *
  * Each table has a descriptor which is a contiguous array of words.
+ * Newer NDB versions also have additional "dynamic descriptors"
+ * which are allocated separately using the same method.
+ *
  * The descriptor is allocated from a global array using a buddy
  * algorithm.  Free lists exist for each power of 2 words.  Freeing
  * a piece first merges with free right and left neighbours and then
@@ -257,14 +260,15 @@ void Dbtup::removeTdArea(Uint32 tabDesRe
   }//if
 }//Dbtup::removeTdArea()
 
-#ifdef VM_TRACE
+#if defined VM_TRACE || defined ERROR_INSERT
 void
 Dbtup::verifytabdes()
 {
   struct WordType {
     short fl;   // free list 0-15
     short ti;   // table id
-    WordType() : fl(-1), ti(-1) {}
+    short td;   // table descriptor area 0 or >0 for dynamic
+    WordType() : fl(-1), ti(-1), td(-1) {}
   };
   WordType* wt = new WordType [cnoOfTabDescrRec];
   uint free_words = 0;
@@ -339,14 +343,16 @@ Dbtup::verifytabdes()
         for (uint j = 0; j < size; j++) {
           ndbrequire(wt[desc + j].ti == -1);
           wt[desc + j].ti = i;
+          wt[desc + j].td = 0;
         }
         used_words += size;
       }
+      for (uint k = 0; k < NO_DYNAMICS; k++)
       {
         Uint32 offset[3];
-        Uint32 MaskSize = (ptr.p->m_dyn_null_bits[MM] + 31) >> 5;
+        Uint32 MaskSize = (ptr.p->m_dyn_null_bits[k] + 31) >> 5;
         const Uint32 alloc = getDynTabDescrOffsets(MaskSize, offset);
-        const Uint32 desc = ptr.p->dynTabDescriptor[MM];
+        const Uint32 desc = ptr.p->dynTabDescriptor[k];
         Uint32 size = alloc;
         if (size % ZTD_FREE_SIZE != 0)
           size += ZTD_FREE_SIZE - size % ZTD_FREE_SIZE;
@@ -366,6 +372,7 @@ Dbtup::verifytabdes()
         for (uint j = 0; j < size; j++) {
           ndbrequire(wt[desc + j].ti == -1);
           wt[desc + j].ti = i;
+          wt[desc + j].td = 1 + k;
         }
         used_words += size;
       }

=== modified file 'storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp	2011-02-04 09:45:35 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp	2011-04-20 09:58:58 +0000
@@ -776,7 +776,7 @@ private:
 
   // inlined utils
   DescEnt& getDescEnt(Uint32 descPage, Uint32 descOff);
-  Uint32 getTupAddr(const Frag& frag, TreeEnt ent);
+  void getTupAddr(const Frag& frag, TreeEnt ent, Uint32& lkey1, Uint32& lkey2);
   static unsigned min(unsigned x, unsigned y);
   static unsigned max(unsigned x, unsigned y);
 
@@ -1242,15 +1242,15 @@ Dbtux::getDescEnt(Uint32 descPage, Uint3
   return *descEnt;
 }
 
-inline Uint32
-Dbtux::getTupAddr(const Frag& frag, TreeEnt ent)
+inline
+void
+Dbtux::getTupAddr(const Frag& frag, TreeEnt ent, Uint32& lkey1, Uint32& lkey2)
 {
   const Uint32 tableFragPtrI = frag.m_tupTableFragPtrI;
   const TupLoc tupLoc = ent.m_tupLoc;
-  Uint32 tupAddr = NullTupAddr;
-  c_tup->tuxGetTupAddr(tableFragPtrI, tupLoc.getPageId(), tupLoc.getPageOffset(), tupAddr);
+  c_tup->tuxGetTupAddr(tableFragPtrI, tupLoc.getPageId(),tupLoc.getPageOffset(),
+                       lkey1, lkey2);
   jamEntry();
-  return tupAddr;
 }
 
 inline unsigned

=== modified file 'storage/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp	2011-02-01 23:27:25 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp	2011-04-19 09:01:07 +0000
@@ -511,7 +511,10 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal
       const Uint32* const buf32 = static_cast<Uint32*>(pkData);
       const Uint64* const buf64 = reinterpret_cast<const Uint64*>(buf32);
       lockReq->hashValue = md5_hash(buf64, pkSize);
-      lockReq->tupAddr = getTupAddr(frag, ent);
+      Uint32 lkey1, lkey2;
+      getTupAddr(frag, ent, lkey1, lkey2);
+      lockReq->page_id = lkey1;
+      lockReq->page_idx = lkey2;
       lockReq->transId1 = scan.m_transId1;
       lockReq->transId2 = scan.m_transId2;
       // execute
@@ -599,10 +602,11 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal
     }
     conf->accOperationPtr = accLockOp;
     conf->fragId = frag.m_fragId;
-    conf->localKey[0] = getTupAddr(frag, ent);
-    conf->localKey[1] = 0;
-    conf->localKeyLength = 1;
-    unsigned signalLength = 6;
+    Uint32 lkey1, lkey2;
+    getTupAddr(frag, ent, lkey1, lkey2);
+    conf->localKey[0] = lkey1;
+    conf->localKey[1] = lkey2;
+    unsigned signalLength = 5;
     // add key info
     if (! scan.m_readCommitted) {
       sendSignal(scan.m_userRef, GSN_NEXT_SCANCONF,

=== modified file 'storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp'
--- a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp	2011-02-23 19:28:26 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp	2011-04-15 13:52:53 +0000
@@ -50,6 +50,7 @@
 #include <AttributeHeader.hpp>
 #include <Configuration.hpp>
 #include <DebuggerNames.hpp>
+#include <signaldata/DihRestart.hpp>
 
 #include <NdbOut.hpp>
 #include <NdbTick.h>
@@ -659,9 +660,11 @@ void Ndbcntr::startPhase2Lab(Signal* sig
 {
   c_start.m_lastGci = 0;
   c_start.m_lastGciNodeId = getOwnNodeId();
-  
-  signal->theData[0] = reference();
-  sendSignal(DBDIH_REF, GSN_DIH_RESTARTREQ, signal, 1, JBB);
+
+  DihRestartReq * req = CAST_PTR(DihRestartReq, signal->getDataPtrSend());
+  req->senderRef = reference();
+  sendSignal(DBDIH_REF, GSN_DIH_RESTARTREQ, signal,
+             DihRestartReq::SignalLength, JBB);
   return;
 }//Ndbcntr::startPhase2Lab()
 
@@ -671,8 +674,10 @@ void Ndbcntr::startPhase2Lab(Signal* sig
 void Ndbcntr::execDIH_RESTARTCONF(Signal* signal) 
 {
   jamEntry();
-  //cmasterDihId = signal->theData[0];
-  c_start.m_lastGci = signal->theData[1];
+
+  const DihRestartConf * conf = CAST_CONSTPTR(DihRestartConf,
+                                              signal->getDataPtrSend());
+  c_start.m_lastGci = conf->latest_gci;
   ctypeOfStart = NodeState::ST_SYSTEM_RESTART;
   cdihStartType = ctypeOfStart;
   ph2ALab(signal);

=== modified file 'storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp'
--- a/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp	2011-04-09 15:48:21 +0000
+++ b/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp	2011-04-15 13:52:53 +0000
@@ -127,6 +127,7 @@ public:
     NdbNodeBitmask m_skip_nodes;
     NdbNodeBitmask m_starting_nodes;
     NdbNodeBitmask m_starting_nodes_w_log;
+    NdbNodeBitmask m_no_nodegroup_nodes;
 
     Uint16 m_president_candidate;
     Uint32 m_president_candidate_gci;
@@ -508,6 +509,7 @@ private:
   Uint32 c_restartPartialTimeout;
   Uint32 c_restartPartionedTimeout;
   Uint32 c_restartFailureTimeout;
+  Uint32 c_restartNoNodegroupTimeout;
   Uint64 c_start_election_time;
 
   Uint16 creadyDistCom;

=== modified file 'storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp'
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp	2011-04-09 15:48:21 +0000
+++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp	2011-04-15 13:52:53 +0000
@@ -39,7 +39,7 @@
 #include <signaldata/EnableCom.hpp>
 #include <signaldata/RouteOrd.hpp>
 #include <signaldata/NodePing.hpp>
-
+#include <signaldata/DihRestart.hpp>
 #include <ndb_version.h>
 
 //#define DEBUG_QMGR_START
@@ -386,14 +386,15 @@ void Qmgr::startphase1(Signal* signal) 
 {
   jamEntry();
 
-  
   NodeRecPtr nodePtr;
   nodePtr.i = getOwnNodeId();
   ptrAss(nodePtr, nodeRec);
   nodePtr.p->phase = ZSTARTING;
-  
-  signal->theData[0] = reference();
-  sendSignal(DBDIH_REF, GSN_DIH_RESTARTREQ, signal, 1, JBB);
+
+  DihRestartReq * req = CAST_PTR(DihRestartReq, signal->getDataPtrSend());
+  req->senderRef = reference();
+  sendSignal(DBDIH_REF, GSN_DIH_RESTARTREQ, signal,
+             DihRestartReq::SignalLength, JBB);
   return;
 }
 
@@ -402,7 +403,11 @@ Qmgr::execDIH_RESTARTREF(Signal*signal)
 {
   jamEntry();
 
+  const DihRestartRef * ref = CAST_CONSTPTR(DihRestartRef,
+                                            signal->getDataPtr());
   c_start.m_latest_gci = 0;
+  c_start.m_no_nodegroup_nodes.assign(NdbNodeBitmask::Size,
+                                      ref->no_nodegroup_mask);
   execCM_INFOCONF(signal);
 }
 
@@ -410,8 +415,13 @@ void
 Qmgr::execDIH_RESTARTCONF(Signal*signal)
 {
   jamEntry();
-  
-  c_start.m_latest_gci = signal->theData[1];
+
+  const DihRestartConf * conf = CAST_CONSTPTR(DihRestartConf,
+                                              signal->getDataPtr());
+
+  c_start.m_latest_gci = conf->latest_gci;
+  c_start.m_no_nodegroup_nodes.assign(NdbNodeBitmask::Size,
+                                      conf->no_nodegroup_mask);
   execCM_INFOCONF(signal);
 }
 
@@ -1446,6 +1456,12 @@ Qmgr::check_startup(Signal* signal)
   Uint64 now = NdbTick_CurrentMillisecond();
   Uint64 partial_timeout = c_start_election_time + c_restartPartialTimeout;
   Uint64 partitioned_timeout = partial_timeout + c_restartPartionedTimeout;
+  Uint64 no_nodegroup_timeout = c_start_election_time +
+    c_restartNoNodegroupTimeout;
+
+  const bool no_nodegroup_active =
+    (c_restartNoNodegroupTimeout != ~Uint32(0)) &&
+    (! c_start.m_no_nodegroup_nodes.isclear());
 
   /**
    * First see if we should wait more...
@@ -1465,25 +1481,60 @@ Qmgr::check_startup(Signal* signal)
   if ((c_start.m_latest_gci == 0) || 
       (c_start.m_start_type == (1 << NodeState::ST_INITIAL_START)))
   {
-    if (!tmp.equal(c_definedNodes))
+    if (tmp.equal(c_definedNodes))
     {
       jam();
-      signal->theData[1] = 1;
-      signal->theData[2] = ~0;
-      report_mask.assign(wait);
-      retVal = 0;
+      signal->theData[1] = 0x8000;
+      report_mask.assign(c_definedNodes);
+      report_mask.bitANDC(c_start.m_starting_nodes);
+      retVal = 1;
       goto start_report;
     }
+    else if (no_nodegroup_active)
+    {
+      if (now < no_nodegroup_timeout)
+      {
+        signal->theData[1] = 6;
+        signal->theData[2] = Uint32((no_nodegroup_timeout - now + 500) / 1000);
+        report_mask.assign(wait);
+        retVal = 0;
+        goto start_report;
+      }
+      tmp.bitOR(c_start.m_no_nodegroup_nodes);
+      if (tmp.equal(c_definedNodes))
+      {
+        signal->theData[1] = 0x8000;
+        report_mask.assign(c_definedNodes);
+        report_mask.bitANDC(c_start.m_starting_nodes);
+        retVal = 1;
+        goto start_report;
+      }
+      else
+      {
+        jam();
+        signal->theData[1] = 1;
+        signal->theData[2] = ~0;
+        report_mask.assign(wait);
+        retVal = 0;
+        goto start_report;
+      }
+    }
     else
     {
       jam();
-      signal->theData[1] = 0x8000;
-      report_mask.assign(c_definedNodes);
-      report_mask.bitANDC(c_start.m_starting_nodes);
-      retVal = 1;
+      signal->theData[1] = 1;
+      signal->theData[2] = ~0;
+      report_mask.assign(wait);
+      retVal = 0;
       goto start_report;
     }
   }
+
+  if (now >= no_nodegroup_timeout)
+  {
+    tmp.bitOR(c_start.m_no_nodegroup_nodes);
+  }
+
   {
     const bool all = c_start.m_starting_nodes.equal(c_definedNodes);
     CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0];
@@ -1559,10 +1610,22 @@ Qmgr::check_startup(Signal* signal)
     if (now < partial_timeout)
     {
       jam();
+
       signal->theData[1] = c_restartPartialTimeout == (Uint32) ~0 ? 2 : 3;
       signal->theData[2] = Uint32((partial_timeout - now + 500) / 1000);
       report_mask.assign(wait);
       retVal = 0;
+
+      if (no_nodegroup_active && now < no_nodegroup_timeout)
+      {
+        signal->theData[1] = 7;
+        signal->theData[2] = Uint32((no_nodegroup_timeout - now + 500) / 1000);
+      }
+      else if (no_nodegroup_active && now >= no_nodegroup_timeout)
+      {
+        report_mask.bitANDC(c_start.m_no_nodegroup_nodes);
+      }
+
       goto start_report;
     }
   
@@ -1595,14 +1658,14 @@ check_log:
   {
     Uint32 save[4+4*NdbNodeBitmask::Size];
     memcpy(save, signal->theData, sizeof(save));
-    
-    signal->theData[0] = 0;
-    c_start.m_starting_nodes.copyto(NdbNodeBitmask::Size, signal->theData+1);
-    memcpy(signal->theData+1+NdbNodeBitmask::Size, c_start.m_node_gci,
-	   4*MAX_NDB_NODES);
-    EXECUTE_DIRECT(DBDIH, GSN_DIH_RESTARTREQ, signal, 
-		   1+NdbNodeBitmask::Size+MAX_NDB_NODES);
-    
+
+    DihRestartReq * req = CAST_PTR(DihRestartReq, signal->getDataPtrSend());
+    req->senderRef = 0;
+    c_start.m_starting_nodes.copyto(NdbNodeBitmask::Size, req->nodemask);
+    memcpy(req->node_gcis, c_start.m_node_gci, 4*MAX_NDB_NODES);
+    EXECUTE_DIRECT(DBDIH, GSN_DIH_RESTARTREQ, signal,
+		   DihRestartReq::CheckLength);
+
     incompleteng = signal->theData[0];
     memcpy(signal->theData, save, sizeof(save));
 
@@ -1650,8 +1713,9 @@ start_report:
     c_start.m_starting_nodes.copyto(sz, ptr); ptr += sz;
     c_start.m_skip_nodes.copyto(sz, ptr); ptr += sz;
     report_mask.copyto(sz, ptr); ptr+= sz;
-    sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 
-	       4+4*NdbNodeBitmask::Size, JBB);
+    c_start.m_no_nodegroup_nodes.copyto(sz, ptr); ptr += sz;
+    sendSignal(CMVMI_REF, GSN_EVENT_REP, signal,
+	       4+5*NdbNodeBitmask::Size, JBB);
   }
   return retVal;
   
@@ -2434,6 +2498,7 @@ void Qmgr::initData(Signal* signal) 
   c_restartPartialTimeout = 30000;
   c_restartPartionedTimeout = 60000;
   c_restartFailureTimeout = ~0;
+  c_restartNoNodegroupTimeout = 15000;
   ndb_mgm_get_int_parameter(p, CFG_DB_HEARTBEAT_INTERVAL, &hbDBDB);
   ndb_mgm_get_int_parameter(p, CFG_DB_ARBIT_TIMEOUT, &arbitTimeout);
   ndb_mgm_get_int_parameter(p, CFG_DB_ARBIT_METHOD, &arbitMethod);
@@ -2441,26 +2506,33 @@ void Qmgr::initData(Signal* signal) 
 			    &c_restartPartialTimeout);
   ndb_mgm_get_int_parameter(p, CFG_DB_START_PARTITION_TIMEOUT,
 			    &c_restartPartionedTimeout);
+  ndb_mgm_get_int_parameter(p, CFG_DB_START_NO_NODEGROUP_TIMEOUT,
+			    &c_restartNoNodegroupTimeout);
   ndb_mgm_get_int_parameter(p, CFG_DB_START_FAILURE_TIMEOUT,
 			    &c_restartFailureTimeout);
   ndb_mgm_get_int_parameter(p, CFG_DB_CONNECT_CHECK_DELAY,
                             &ccInterval);
- 
+
   if(c_restartPartialTimeout == 0)
   {
     c_restartPartialTimeout = ~0;
   }
-  
+
   if (c_restartPartionedTimeout ==0)
   {
     c_restartPartionedTimeout = ~0;
   }
-  
+
   if (c_restartFailureTimeout == 0)
   {
     c_restartFailureTimeout = ~0;
   }
 
+  if (c_restartNoNodegroupTimeout == 0)
+  {
+    c_restartNoNodegroupTimeout = ~0;
+  }
+
   setHbDelay(hbDBDB);
   setCCDelay(ccInterval);
   setArbitTimeout(arbitTimeout);

=== modified file 'storage/ndb/src/kernel/vm/mt.cpp'
--- a/storage/ndb/src/kernel/vm/mt.cpp	2011-02-23 19:28:26 +0000
+++ b/storage/ndb/src/kernel/vm/mt.cpp	2011-04-20 05:46:35 +0000
@@ -401,7 +401,7 @@ struct thr_safe_pool
 
   T* m_free_list;
   Uint32 m_cnt;
-  thr_spin_lock<NDB_CL - (sizeof(T*) + sizeof(Uint32))> m_lock;
+  thr_spin_lock<NDB_CL - (sizeof(void*) + sizeof(Uint32))> m_lock;
 
   T* seize(Ndbd_mem_manager *mm, Uint32 rg) {
     T* ret = 0;

=== modified file 'storage/ndb/src/mgmsrv/ConfigInfo.cpp'
--- a/storage/ndb/src/mgmsrv/ConfigInfo.cpp	2011-04-09 15:48:21 +0000
+++ b/storage/ndb/src/mgmsrv/ConfigInfo.cpp	2011-04-19 13:47:33 +0000
@@ -977,7 +977,19 @@ const ConfigInfo::ParamInfo ConfigInfo::
     "0",
     "0",
     STR_VALUE(MAX_INT_RNIL) },
-  
+
+  {
+    CFG_DB_START_NO_NODEGROUP_TIMEOUT,
+    "StartNoNodegroupTimeout",
+    DB_TOKEN,
+    "Time to wait for nodes wo/ nodegroup before trying to start (0=forever)",
+    ConfigInfo::CI_USED,
+    0,
+    ConfigInfo::CI_INT,
+    "15000",
+    "0",
+    STR_VALUE(MAX_INT_RNIL) },
+
   {
     CFG_DB_HEARTBEAT_INTERVAL,
     "HeartbeatIntervalDbDb",
@@ -1295,7 +1307,7 @@ const ConfigInfo::ParamInfo ConfigInfo::
     ConfigInfo::CI_USED,
     false,
     ConfigInfo::CI_ENUM,
-    0,
+    "Default", /* Default value */
     (const char*)arbit_method_typelib,
     0
   },
@@ -2171,12 +2183,17 @@ const ConfigInfo::ParamInfo ConfigInfo::
     CFG_DEFAULT_OPERATION_REDO_PROBLEM_ACTION,
     "DefaultOperationRedoProblemAction",
     API_TOKEN,
-    "If Redo-log is having problem, should operation default (unless overridden on transaction/operation level) abort or be put on queue"
-    " in a row times, transactions will be aborted",
+    "If Redo-log is having problem, should operation default "
+    "(unless overridden on transaction/operation level) abort "
+    "or be put on queue",
     ConfigInfo::CI_USED,
     false,
     ConfigInfo::CI_ENUM,
-    0, /* default for ENUM doesnt seem to work... */
+#if NDB_VERSION_D < NDB_MAKE_VERSION(7,2,0)
+    "abort", /* Default value */
+#else
+    "queue", /* Default value */
+#endif
     (const char*)default_operation_redo_problem_action_typelib,
     0
   },
@@ -3152,11 +3169,26 @@ ConfigInfo::ConfigInfo()
              entry->name != 0; entry++)
           values.put(entry->name, entry->value);
         require(pinfo.put("values", &values));
-        // fallthrough
+
+        if(param._default == MANDATORY)
+          pinfo.put("Mandatory", (Uint32)1);
+        else if(param._default)
+        {
+          /*
+            Map default value of enum from string to int since
+            enum is stored as int internally
+          */
+          Uint32 default_value;
+          require(values.get(param._default, &default_value));
+          require(pinfo.put("Default", default_value));
+
+          /* Also store the default as string */
+          require(pinfo.put("DefaultString", param._default));
+        }
+        break;
       }
       case CI_STRING:
-        assert(param._type == CI_ENUM || // Allow fallthrough from enum
-               param._min == 0); // String can't have min value
+        assert(param._min == 0); // String can't have min value
         assert(param._max == 0); // String can't have max value
 
         if(param._default == MANDATORY)
@@ -3206,7 +3238,6 @@ ConfigInfo::ConfigInfo()
         {
 	  case CI_SECTION:
 	    break;
-	  case CI_ENUM:
 	  case CI_STRING:
           case CI_BITMASK:
 	    require(p->put(param._fname, param._default));
@@ -3225,6 +3256,20 @@ ConfigInfo::ConfigInfo()
 	      require(p->put64(param._fname, Uint64(default_uint64)));
 	      break;
 	    }
+          case CI_ENUM:
+          {
+            /*
+              Map default value of enum from string to int since
+              enum is stored as int internally
+            */
+            Uint32 default_value;
+            require(verify_enum(getInfo(param._section),
+                                param._fname, param._default,
+                                default_value));
+            require(p->put(param._fname, default_value));
+            break;
+          }
+
 	}
       }
       require(m_systemDefaults.put(param._section, p, true));
@@ -3252,7 +3297,7 @@ ConfigInfo::ConfigInfo()
       ndbout << "Edit file " << __FILE__ << "." << endl;
       require(false);
     }
-  }
+   }
 
 }
 
@@ -3338,8 +3383,29 @@ ConfigInfo::getDefault(const Properties 
 
 const char*
 ConfigInfo::getDefaultString(const Properties * section,
-                             const char* fname) const {
-  return getInfoString(section, fname, "Default");
+                             const char* fname) const
+{
+  switch (getType(section, fname))
+  {
+  case ConfigInfo::CI_BITMASK:
+  case ConfigInfo::CI_STRING:
+    return getInfoString(section, fname, "Default");
+
+  case ConfigInfo::CI_ENUM:
+  {
+    /*
+      Default value for enum are stored as int internally
+      but also stores the orignal string, use different
+      key to get at the default value as string
+     */
+    return getInfoString(section, fname, "DefaultString");
+  }
+
+  default:
+    require(false);
+  }
+
+  return NULL;
 }
 
 bool
@@ -4143,6 +4209,7 @@ applyDefaultValues(InitConfigFileParser:
       else
       {
         switch (ctx.m_info->getType(ctx.m_currentInfo, name)){
+        case ConfigInfo::CI_ENUM:
         case ConfigInfo::CI_INT:
         case ConfigInfo::CI_BOOL:{
           Uint32 val = 0;
@@ -4157,7 +4224,6 @@ applyDefaultValues(InitConfigFileParser:
           break;
         }
         case ConfigInfo::CI_BITMASK:
-        case ConfigInfo::CI_ENUM:
         case ConfigInfo::CI_STRING:{
           const char * val;
           require(ctx.m_currentSection->get(name, &val));

=== modified file 'storage/ndb/src/ndbapi/NdbScanOperation.cpp'
--- a/storage/ndb/src/ndbapi/NdbScanOperation.cpp	2011-02-10 07:55:45 +0000
+++ b/storage/ndb/src/ndbapi/NdbScanOperation.cpp	2011-04-18 12:39:04 +0000
@@ -1771,9 +1771,9 @@ NdbScanOperation::nextResult(const char 
     NdbRecAttr *getvalue_recattr= theReceiver.theFirstRecAttr;
     if (((UintPtr)tBlob | (UintPtr)getvalue_recattr) != 0)
     {
-      Uint32 idx= m_current_api_receiver;
+      const Uint32 idx= m_current_api_receiver;
       assert(idx < m_api_receivers_count);
-      const NdbReceiver *receiver= m_api_receivers[m_current_api_receiver];
+      const NdbReceiver *receiver= m_api_receivers[idx];
       Uint32 pos= 0;
 
       /* First take care of any getValue(). */

=== modified file 'storage/ndb/test/ndbapi/testDict.cpp'
--- a/storage/ndb/test/ndbapi/testDict.cpp	2011-04-07 07:22:49 +0000
+++ b/storage/ndb/test/ndbapi/testDict.cpp	2011-04-18 11:09:11 +0000
@@ -31,6 +31,7 @@
 #include <NdbSqlUtil.hpp>
 #include <NdbEnv.h>
 #include <ndb_rand.h>
+#include <Bitmask.hpp>
 
 #define ERR_INSERT_MASTER_FAILURE1 6013
 #define ERR_INSERT_MASTER_FAILURE2 6014
@@ -294,31 +295,45 @@ int runCreateAndDropAtRandom(NDBT_Contex
   Ndb* pNdb = GETNDB(step);
   NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
   int loops = ctx->getNumLoops();
-  int numTables = NDBT_Tables::getNumTables();
-  bool* tabList = new bool [ numTables ];
-  int tabCount;
+  int records = ctx->getNumRecords();
 
-  {
-    for (int num = 0; num < numTables; num++) {
-      (void)pDic->dropTable(NDBT_Tables::getTable(num)->getName());
-      tabList[num] = false;
-    }
-    tabCount = 0;
+  int numAllTables = NDBT_Tables::getNumTables();
+  struct TabList {
+    int exists; // -1 = skip, 0 = no, 1 = yes
+    const NdbDictionary::Table* pTab; // retrieved
+    TabList() { exists = -1; pTab = 0; }
+  };
+  TabList* tabList = new TabList [ numAllTables ];
+  int numTables = 0;
+  int num;
+  for (num = 0; num < numAllTables; num++) {
+    const NdbDictionary::Table* pTab = NDBT_Tables::getTable(num);
+    if (pTab->checkColumns(0, 0) & 2) // skip disk
+      continue;
+    tabList[num].exists = 0;
+    (void)pDic->dropTable(pTab->getName());
+    numTables++;
   }
+  int numExists = 0;
+
+  const bool createIndexes = ctx->getProperty("CreateIndexes");
+  const bool loadData = ctx->getProperty("LoadData");
 
   NdbRestarter restarter;
   int result = NDBT_OK;
   int bias = 1; // 0-less 1-more
   int i = 0;
   
-  while (i < loops) {
-    g_info << "loop " << i << " tabs " << tabCount << "/" << numTables << endl;
-    int num = myRandom48(numTables);
+  while (i < loops && result == NDBT_OK) {
+    num = myRandom48(numAllTables);
+    if (tabList[num].exists == -1)
+      continue;
+    g_info << "loop " << i << " tabs " << numExists << "/" << numTables << endl;
     const NdbDictionary::Table* pTab = NDBT_Tables::getTable(num);
     char tabName[200];
     strcpy(tabName, pTab->getName());
 
-    if (tabList[num] == false) {
+    if (tabList[num].exists == 0) {
       if (bias == 0 && myRandom48(100) < 80)
         continue;
       g_info << tabName << ": create" << endl;
@@ -331,17 +346,110 @@ int runCreateAndDropAtRandom(NDBT_Contex
       const NdbDictionary::Table* pTab2 = pDic->getTable(tabName);
       if (pTab2 == NULL) {
         const NdbError err = pDic->getNdbError();
-        g_err << tabName << ": verify create: " << err << endl;
+        g_err << tabName << ": verify create failed: " << err << endl;
         result = NDBT_FAILED;
         break;
       }
-      tabList[num] = true;
-      assert(tabCount < numTables);
-      tabCount++;
-      if (tabCount == numTables)
+      tabList[num].pTab = pTab2;
+      if (loadData) {
+        g_info << tabName << ": load data" << endl;
+        HugoTransactions hugoTrans(*pTab2);
+        if (hugoTrans.loadTable(pNdb, records) != 0) {
+          g_err << tabName << ": loadTable failed" << endl;
+          result = NDBT_FAILED;
+          break;
+        }
+      }
+      if (createIndexes) {
+        int icount = myRandom48(10);
+        int inum;
+        for (inum = 0; inum < icount; inum++) {
+          const int tcols = pTab2->getNoOfColumns();
+          assert(tcols != 0);
+          int icols = 1 + myRandom48(tcols);
+          if (icols > NDB_MAX_ATTRIBUTES_IN_INDEX)
+            icols = NDB_MAX_ATTRIBUTES_IN_INDEX;
+          char indName[200];
+          sprintf(indName, "%s_X%d", tabName, inum);
+          NdbDictionary::Index ind(indName);
+          ind.setTable(tabName);
+          ind.setType(NdbDictionary::Index::OrderedIndex);
+          ind.setLogging(false);
+          Bitmask<MAX_ATTRIBUTES_IN_TABLE> mask;
+          char ilist[200];
+          ilist[0] = 0;
+          int ic;
+          for (ic = 0; ic < icols; ic++) {
+            int tc = myRandom48(tcols);
+            const NdbDictionary::Column* c = pTab2->getColumn(tc);
+            assert(c != 0);
+            if (mask.get(tc) ||
+                c->getType() == NdbDictionary::Column::Blob ||
+                c->getType() == NdbDictionary::Column::Text ||
+                c->getType() == NdbDictionary::Column::Bit ||
+                c->getStorageType() == NdbDictionary::Column::StorageTypeDisk)
+              continue;
+            ind.addColumn(*c);
+            mask.set(tc);
+            sprintf(ilist + strlen(ilist), " %d", tc);
+          }
+          if (mask.isclear())
+            continue;
+          g_info << indName << ": columns:" << ilist << endl;
+          if (pDic->createIndex(ind) == 0) {
+            g_info << indName << ": created" << endl;
+          } else {
+            const NdbError err = pDic->getNdbError();
+            g_err << indName << ": create index failed: " << err << endl;
+            if (err.code != 826 && // Too many tables and attributes..
+                err.code != 903 && // Too many ordered indexes..
+                err.code != 904 && // Out of fragment records..
+                err.code != 905 && // Out of attribute records..
+                err.code != 707 && // No more table metadata records..
+                err.code != 708)   // No more attribute metadata records..
+            {
+              result = NDBT_FAILED;
+              break;
+            }
+          }
+        }
+      }
+      if (loadData) {
+        // first update a random table to flush global variables
+        int num3 = 0;
+        while (1) {
+          num3 = myRandom48(numAllTables);
+          if (num == num3 || tabList[num3].exists == 1)
+            break;
+        }
+        const NdbDictionary::Table* pTab3 = tabList[num3].pTab;
+        assert(pTab3 != 0);
+        char tabName3[200];
+        strcpy(tabName3, pTab3->getName());
+        HugoTransactions hugoTrans(*pTab3);
+        g_info << tabName3 << ": update data" << endl;
+        if (hugoTrans.pkUpdateRecords(pNdb, records) != 0) {
+          g_err << tabName3 << ": pkUpdateRecords failed" << endl;
+          result = NDBT_FAILED;
+          break;
+        }
+      }
+      if (loadData) {
+        HugoTransactions hugoTrans(*pTab2);
+        g_info << tabName << ": update data" << endl;
+        if (hugoTrans.pkUpdateRecords(pNdb, records) != 0) {
+          g_err << "pkUpdateRecords failed" << endl;
+          result = NDBT_FAILED;
+          break;
+        }
+      }
+      tabList[num].exists = 1;
+      assert(numExists < numTables);
+      numExists++;
+      if (numExists == numTables)
         bias = 0;
     }
-    else {
+    else if (tabList[num].exists == 1) {
       if (bias == 1 && myRandom48(100) < 80)
         continue;
       g_info << tabName << ": drop" << endl;
@@ -369,19 +477,19 @@ int runCreateAndDropAtRandom(NDBT_Contex
         result = NDBT_FAILED;
         break;
       }
-      tabList[num] = false;
-      assert(tabCount > 0);
-      tabCount--;
-      if (tabCount == 0)
+      tabList[num].exists = 0;
+      assert(numExists > 0);
+      numExists--;
+      if (numExists == 0)
         bias = 1;
     }
     i++;
   }
-  
-  for (Uint32 i = 0; i<(Uint32)numTables; i++)
-    if (tabList[i])
-      pDic->dropTable(NDBT_Tables::getTable(i)->getName());
-  
+
+  for (num = 0; num < numAllTables; num++)
+    if (tabList[num].exists == 0)
+      pDic->dropTable(NDBT_Tables::getTable(num)->getName());
+
   delete [] tabList;
   return result;
 }
@@ -8737,6 +8845,13 @@ TESTCASE("CreateAndDropAtRandom",
          "Uses error insert 4013 to make TUP verify table descriptor"){
   INITIALIZER(runCreateAndDropAtRandom);
 }
+TESTCASE("CreateAndDropIndexes",
+	 "Like CreateAndDropAtRandom but also creates random ordered\n"
+         "indexes and loads data as a simple check of index operation"){
+  TC_PROPERTY("CreateIndexes", 1);
+  TC_PROPERTY("LoadData", 1);
+  INITIALIZER(runCreateAndDropAtRandom);
+}
 TESTCASE("CreateAndDropWithData", 
 	 "Try to create and drop the table when it's filled with data\n"
 	 "do this loop number of times\n"){

=== modified file 'storage/ndb/test/run-test/daily-basic-tests.txt'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt	2011-04-15 13:19:59 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt	2011-04-20 09:58:58 +0000
@@ -715,6 +715,10 @@ args: -n CreateAndDropAtRandom -l 200 T1
 
 max-time: 1500
 cmd: testDict
+args: -n CreateAndDropIndexes -l 200 T1
+
+max-time: 1500
+cmd: testDict
 args: -n CreateAndDropWithData 
 
 max-time: 1500

=== modified file 'storage/ndb/test/src/HugoCalculator.cpp'
--- a/storage/ndb/test/src/HugoCalculator.cpp	2011-04-01 14:34:28 +0000
+++ b/storage/ndb/test/src/HugoCalculator.cpp	2011-04-18 11:09:11 +0000
@@ -196,8 +196,6 @@ HugoCalculator::calcValue(int record, 
   case NdbDictionary::Column::Unsigned:
   case NdbDictionary::Column::Bigint:
   case NdbDictionary::Column::Bigunsigned:
-  case NdbDictionary::Column::Float:
-  case NdbDictionary::Column::Double:
   case NdbDictionary::Column::Olddecimal:
   case NdbDictionary::Column::Olddecimalunsigned:
   case NdbDictionary::Column::Decimal:
@@ -227,6 +225,22 @@ HugoCalculator::calcValue(int record, 
       memcpy(((Uint32*)buf)+tmp, &copy, 4);
     }
     break;
+  case NdbDictionary::Column::Float:
+    {
+      float x = (float)myRand(&seed);
+      memcpy(buf+pos, &x, 4);
+      pos += 4;
+      len -= 4;
+    }
+    break;
+  case NdbDictionary::Column::Double:
+    {
+      double x = (double)myRand(&seed);
+      memcpy(buf+pos, &x, 8);
+      pos += 8;
+      len -= 8;
+    }
+    break;
   case NdbDictionary::Column::Varbinary:
   case NdbDictionary::Column::Varchar:
     len = calc_len(myRand(&seed), len - 1);

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.5-cluster branch (magnus.blaudd:3303 to 3308) Magnus Blåudd20 Apr