List:Commits« Previous MessageNext Message »
From:Magnus Svensson Date:November 18 2008 8:33am
Subject:bzr commit into mysql-5.1 branch (msvensson:2745)
View as plain text  
#At file:///home/msvensson/mysql/6.3/

 2745 Magnus Svensson	2008-11-18 [merge]
      Merge
added:
  mysql-test/suite/ndb/r/ndb_reconnect.result
  mysql-test/suite/ndb/t/ndb_reconnect.test
modified:
  sql/ha_ndbcluster.cc
  sql/ha_ndbcluster.h
  sql/ha_ndbcluster_binlog.cc
  sql/ha_ndbcluster_binlog.h
  sql/ha_ndbcluster_connection.cc
  sql/mysqld.cc
  storage/ndb/include/mgmapi/mgmapi.h
  storage/ndb/include/ndb_version.h.in
  storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
  storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
  storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
  storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
  storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp
  storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
  storage/ndb/src/mgmapi/LocalConfig.cpp
  storage/ndb/src/mgmapi/LocalConfig.hpp
  storage/ndb/src/mgmapi/mgmapi.cpp
  storage/ndb/src/mgmsrv/MgmtSrvr.cpp
  storage/ndb/src/ndbapi/NdbScanOperation.cpp
  storage/ndb/src/ndbapi/Ndbif.cpp
  storage/ndb/src/ndbapi/TransporterFacade.cpp

=== added file 'mysql-test/suite/ndb/r/ndb_reconnect.result'
--- a/mysql-test/suite/ndb/r/ndb_reconnect.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_reconnect.result	2008-11-14 19:29:36 +0000
@@ -0,0 +1,27 @@
+CREATE TABLE t1(a int primary key, b varchar(255), c int) engine=ndb;
+select * from t1;
+a	b	c
+insert into t1 values (1, "row 1", 2);
+select * from t1;
+a	b	c
+1	row 1	2
+select * from t1;
+a	b	c
+1	row 1	2
+select * from t1;
+a	b	c
+1	row 1	2
+select * from t1;
+ERROR HY000: Got error 157 'Unknown error code' from NDBCLUSTER
+select * from t1;
+ERROR HY000: Got error 157 'Unknown error code' from NDBCLUSTER
+select a,b,c from t1;
+a	b	c
+1	row 1	2
+select * from t1;
+a	b	c
+1	row 1	2
+select * from t1;
+a	b	c
+1	row 1	2
+insert into t1 values (2, "row 1", 37);

=== added file 'mysql-test/suite/ndb/t/ndb_reconnect.test'
--- a/mysql-test/suite/ndb/t/ndb_reconnect.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_reconnect.test	2008-11-14 19:29:36 +0000
@@ -0,0 +1,88 @@
+--source include/have_ndb.inc
+
+CREATE TABLE t1(a int primary key, b varchar(255), c int) engine=ndb;
+
+select * from t1;
+insert into t1 values (1, "row 1", 2);
+
+connect(con1, localhost, root,,);
+connect(con2, localhost, root,,);
+connect(con3, localhost, root,,);
+
+connection con1;
+select * from t1;
+connection con2;
+select * from t1;
+connection con3;
+select * from t1;
+
+# Restart cluster nodes "nostart"
+--exec $NDB_MGM --no-defaults --ndb-connectstring="localhost:$NDBCLUSTER_PORT" -e "all
restart -n" >> $NDB_TOOLS_OUTPUT
+# Wait for all nodes to enter "nostart"
+--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults
--ndb-connectstring="localhost:$NDBCLUSTER_PORT" --not-started >> $NDB_TOOLS_OUTPUT
+
+connection con1;
+--error 1296
+select * from t1;
+
+connection con2;
+--error 1296
+select * from t1;
+
+# Don't do anything with the third connection
+#connection con3;
+
+
+# Start cluster nodes again
+--exec $NDB_MGM --no-defaults --ndb-connectstring="localhost:$NDBCLUSTER_PORT" -e "all
start" >> $NDB_TOOLS_OUTPUT
+# Wait for all nodes to enter "started"
+--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults
--ndb-connectstring="localhost:$NDBCLUSTER_PORT" >> $NDB_TOOLS_OUTPUT
+
+
+#
+# Wait until the connection to the
+# cluster has been restored or timeout occurs
+#
+connection default;
+--disable_result_log
+--disable_query_log
+--disable_abort_on_error
+let $counter= 500;
+let $mysql_errno=37;
+while ($mysql_errno)
+{
+  select * from t1;
+
+  dec $counter;
+  if (!$counter)
+  {
+    --die Server failed to reconnect to cluster
+  }
+  --sleep 0.1
+}
+--enable_abort_on_error
+--enable_query_log
+--enable_result_log
+
+# Run selects to show that the cluster are back
+
+connection con1;
+select a,b,c from t1;
+
+connection con2;
+select * from t1;
+
+connection con3;
+select * from t1;
+
+#
+# Wait until mysqld has connected properly to cluster
+#
+--disable_result_log
+--disable_query_log
+source include/ndb_not_readonly.inc;
+--enable_query_log
+--enable_result_log
+
+# Do an insert to see table is writable
+insert into t1 values (2, "row 1", 37);

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2008-11-08 21:22:57 +0000
+++ b/sql/ha_ndbcluster.cc	2008-11-14 19:42:13 +0000
@@ -611,6 +611,7 @@ uchar *thd_ndb_share_get_key(THD_NDB_SHA
 Thd_ndb::Thd_ndb()
 {
   connection= ndb_get_cluster_connection();
+  m_connect_count= connection->get_connect_count();
   ndb= new Ndb(connection, "");
   lock_count= 0;
   start_stmt_count= 0;
@@ -8042,6 +8043,52 @@ void ha_ndbcluster::release_thd_ndb(Thd_
 }
 
 
+bool Thd_ndb::recycle_ndb(THD* thd)
+{
+  DBUG_ENTER("recycle_ndb");
+  DBUG_PRINT("enter", ("ndb: 0x%lx", (long)ndb));
+
+  DBUG_ASSERT(global_schema_lock_trans == NULL);
+
+  delete ndb;
+  if ((ndb= new Ndb(connection, "")) == NULL)
+  {
+    DBUG_PRINT("error",("failed to allocate Ndb object"));
+    DBUG_RETURN(false);
+  }
+
+  if (ndb->init(max_transactions) != 0)
+  {
+    delete ndb;
+    ndb= NULL;
+    DBUG_PRINT("error", ("Ndb::init failed, %d  message: %s",
+                         ndb->getNdbError().code,
+                         ndb->getNdbError().message));
+    DBUG_RETURN(false);
+  }
+
+  changed_tables.empty();
+  trans= NULL;
+
+  DBUG_RETURN(true);
+}
+
+
+bool
+Thd_ndb::valid_ndb(void)
+{
+  // The ndb object should be valid as long as a
+  // global schema lock transaction is ongoing
+  if (global_schema_lock_trans)
+    return true;
+
+  if (unlikely(m_connect_count != connection->get_connect_count()))
+    return false;
+  return true;
+}
+
+
+
 /**
   If this thread already has a Thd_ndb object allocated
   in current THD, reuse it. Otherwise
@@ -8049,7 +8096,7 @@ void ha_ndbcluster::release_thd_ndb(Thd_
  
 */
 
-Ndb* check_ndb_in_thd(THD* thd)
+Ndb* check_ndb_in_thd(THD* thd, bool validate_ndb)
 {
   Thd_ndb *thd_ndb= get_thd_ndb(thd);
   if (!thd_ndb)
@@ -8058,6 +8105,11 @@ Ndb* check_ndb_in_thd(THD* thd)
       return NULL;
     set_thd_ndb(thd, thd_ndb);
   }
+  else if (validate_ndb && !thd_ndb->valid_ndb())
+  {
+    if (!thd_ndb->recycle_ndb(thd))
+      return NULL;
+  }
   return thd_ndb->ndb;
 }
 
@@ -8068,7 +8120,7 @@ int ha_ndbcluster::check_ndb_connection(
   Ndb *ndb;
   DBUG_ENTER("check_ndb_connection");
   
-  if (!(ndb= check_ndb_in_thd(thd)))
+  if (!(ndb= check_ndb_in_thd(thd, true)))
     DBUG_RETURN(HA_ERR_NO_CONNECTION);
   if (ndb->setDatabaseName(m_dbname))
   {
@@ -10971,6 +11023,11 @@ pthread_handler_t ndb_util_thread_func(v
       have been created.
       If not try to create it
     */
+		if (!check_ndb_in_thd(thd, false))
+    {
+      set_timespec(abstime, 1);
+      continue;
+    }
     if (!ndb_binlog_tables_inited)
       ndbcluster_setup_binlog_table_shares(thd);
 

=== modified file 'sql/ha_ndbcluster.h'
--- a/sql/ha_ndbcluster.h	2008-10-15 14:27:13 +0000
+++ b/sql/ha_ndbcluster.h	2008-11-14 19:32:11 +0000
@@ -331,6 +331,10 @@ class Thd_ndb 
   NdbTransaction *global_schema_lock_trans;
   uint global_schema_lock_count;
   uint global_schema_lock_error;
+
+  unsigned m_connect_count;
+  bool valid_ndb(void);
+  bool recycle_ndb(THD* thd);
 };
 
 int ndbcluster_commit(handlerton *hton, THD *thd, bool all);

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2008-10-29 13:22:19 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2008-11-14 19:42:13 +0000
@@ -5364,6 +5364,42 @@ static void ndb_free_schema_object(NDB_S
 }
 
 
+static void
+remove_event_operations(Ndb* ndb)
+{
+  DBUG_ENTER("remove_event_operations");
+  NdbEventOperation *op;
+  while ((op= ndb->getEventOperation()))
+  {
+    DBUG_ASSERT(!IS_NDB_BLOB_PREFIX(op->getEvent()->getTable()->getName()));
+    DBUG_PRINT("info", ("removing event operation on %s",
+                        op->getEvent()->getName()));
+
+    Ndb_event_data *event_data= (Ndb_event_data *) op->getCustomData();
+    DBUG_ASSERT(event_data);
+
+    NDB_SHARE *share= event_data->share;
+    DBUG_ASSERT(share != NULL);
+    DBUG_ASSERT(share->op == op || share->new_op == op);
+
+    delete event_data;
+    op->setCustomData(NULL);
+
+    (void) pthread_mutex_lock(&share->mutex);
+    share->op= 0;
+    share->new_op= 0;
+    (void) pthread_mutex_unlock(&share->mutex);
+
+    DBUG_PRINT("NDB_SHARE", ("%s binlog free  use_count: %u",
+                             share->key, share->use_count));
+    free_share(&share);
+
+    ndb->dropEventOperation(op);
+  }
+  DBUG_VOID_RETURN;
+}
+
+
 pthread_handler_t ndb_binlog_thread_func(void *arg)
 {
   THD *thd; /* needs to be first for thread_stack */
@@ -5431,6 +5467,7 @@ pthread_handler_t ndb_binlog_thread_func
   pthread_mutex_unlock(&LOCK_thread_count);
   thd->lex->start_transaction_opt= 0;
 
+restart_cluster_failure:
   if (!(s_ndb= new Ndb(g_ndb_cluster_connection, "")) ||
       s_ndb->init())
   {
@@ -5743,6 +5780,32 @@ restart:
                                                 &post_epoch_log_list,
                                                 &post_epoch_unlock_list,
                                                 &mem_root);
+
+          if (unlikely(pOp->getEventType() == NDBEVENT::TE_CLUSTER_FAILURE))
+          {
+            sql_print_information("NDB Binlog: cluster failure detected");
+            pthread_mutex_lock(&LOCK_open);
+
+            pthread_mutex_lock(&injector_mutex);
+
+            remove_event_operations(s_ndb);
+            delete s_ndb;
+            s_ndb= 0;
+            schema_ndb= 0;
+
+            remove_event_operations(i_ndb);
+            delete i_ndb;
+            i_ndb= 0;
+            injector_ndb= 0;
+
+            hash_free(&ndb_schema_objects);
+
+            pthread_mutex_unlock(&LOCK_open);
+
+            sql_print_information("NDB Binlog: restarting");
+            goto restart_cluster_failure;
+          }
+
           DBUG_PRINT("info", ("s_ndb first: %s", s_ndb->getEventOperation() ?
                              
s_ndb->getEventOperation()->getEvent()->getTable()->getName() :
                               "<empty>"));
@@ -6133,63 +6196,13 @@ err:
   /* remove all event operations */
   if (s_ndb)
   {
-    NdbEventOperation *op;
-    DBUG_PRINT("info",("removing all event operations"));
-    while ((op= s_ndb->getEventOperation()))
-    {
-      DBUG_ASSERT(! IS_NDB_BLOB_PREFIX(op->getEvent()->getTable()->getName()));
-      DBUG_PRINT("info",("removing event operation on %s",
-                         op->getEvent()->getName()));
-      Ndb_event_data *event_data= (Ndb_event_data *) op->getCustomData();
-      NDB_SHARE *share= (event_data)?event_data->share:NULL;
-      DBUG_ASSERT(share != 0);
-      DBUG_ASSERT(share->op == op || share->new_op == op);
-      if (event_data)
-      {
-        delete event_data;
-        op->setCustomData(NULL);
-      }
-      (void) pthread_mutex_lock(&share->mutex);
-      share->op= 0;
-      share->new_op= 0;
-      (void) pthread_mutex_unlock(&share->mutex);
-      /* ndb_share reference binlog free */
-      DBUG_PRINT("NDB_SHARE", ("%s binlog free  use_count: %u",
-                               share->key, share->use_count));
-      free_share(&share);
-      s_ndb->dropEventOperation(op);
-    }
+    remove_event_operations(s_ndb);
     delete s_ndb;
     s_ndb= 0;
   }
   if (i_ndb)
   {
-    NdbEventOperation *op;
-    DBUG_PRINT("info",("removing all event operations"));
-    while ((op= i_ndb->getEventOperation()))
-    {
-      DBUG_ASSERT(! IS_NDB_BLOB_PREFIX(op->getEvent()->getTable()->getName()));
-      DBUG_PRINT("info",("removing event operation on %s",
-                         op->getEvent()->getName()));
-      Ndb_event_data *event_data= (Ndb_event_data *) op->getCustomData();
-      NDB_SHARE *share= (event_data)?event_data->share:NULL;
-      if (event_data)
-      {
-        delete event_data;
-        op->setCustomData(NULL);
-      }
-      DBUG_ASSERT(share != 0);
-      (void) pthread_mutex_lock(&share->mutex);
-      DBUG_ASSERT(share->op == op || share->new_op == op);
-      share->op= 0;
-      share->new_op= 0;
-      (void) pthread_mutex_unlock(&share->mutex);
-      /* ndb_share reference binlog free */
-      DBUG_PRINT("NDB_SHARE", ("%s binlog free  use_count: %u",
-                               share->key, share->use_count));
-      free_share(&share);
-      i_ndb->dropEventOperation(op);
-    }
+    remove_event_operations(i_ndb);
     delete i_ndb;
     i_ndb= 0;
   }

=== modified file 'sql/ha_ndbcluster_binlog.h'
--- a/sql/ha_ndbcluster_binlog.h	2008-10-29 14:12:28 +0000
+++ b/sql/ha_ndbcluster_binlog.h	2008-11-14 19:32:11 +0000
@@ -293,7 +293,7 @@ void
 set_thd_ndb(THD *thd, Thd_ndb *thd_ndb)
 { thd_set_ha_data(thd, ndbcluster_hton, thd_ndb); }
 
-Ndb* check_ndb_in_thd(THD* thd);
+Ndb* check_ndb_in_thd(THD* thd, bool validate_ndb= false);
 
 int ndbcluster_has_global_schema_lock(Thd_ndb *thd_ndb);
 int ndbcluster_no_global_schema_lock_abort(THD *thd, const char *msg);

=== modified file 'sql/ha_ndbcluster_connection.cc'
--- a/sql/ha_ndbcluster_connection.cc	2008-10-02 16:11:03 +0000
+++ b/sql/ha_ndbcluster_connection.cc	2008-11-17 14:20:48 +0000
@@ -138,7 +138,8 @@ int ndbcluster_connect(int (*connect_cal
     connect_callback();
     for (unsigned i= 0; i < g_ndb_cluster_connection_pool_alloc; i++)
     {
-      if (g_ndb_cluster_connection_pool[i]->node_id() == 0)
+      int node_id= g_ndb_cluster_connection_pool[i]->node_id();
+      if (node_id == 0)
       {
         // not connected to mgmd yet, try again
         g_ndb_cluster_connection_pool[i]->connect(0,0,0);
@@ -148,6 +149,7 @@ int ndbcluster_connect(int (*connect_cal
           g_ndb_cluster_connection_pool[i]->start_connect_thread();
           continue;
         }
+        node_id= g_ndb_cluster_connection_pool[i]->node_id();
       }
       DBUG_PRINT("info",
                  ("NDBCLUSTER storage engine (%u) at %s on port %d", i,
@@ -161,18 +163,21 @@ int ndbcluster_connect(int (*connect_cal
         gettimeofday(&now_time, 0);
       } while (res != 0 && end_time.tv_sec > now_time.tv_sec);
 
+      const char *msg;
       if (res == 0)
       {
-        sql_print_information("NDB[%u]: all storage nodes connected", i);
+        msg= "all storage nodes connected";
       }
       else if (res > 0)
       {
-        sql_print_information("NDB[%u]: some storage nodes connected", i);
+        msg= "some storage nodes connected";
       }
       else if (res < 0)
       {
-        sql_print_information("NDB[%u]: no storage nodes connected (timed out)", i);
+        msg= "no storage nodes connected (timed out)";
       }
+      sql_print_information("NDB[%u]: NodeID: %d, %s",
+                            i, node_id, msg);
     }
   }
   else if (res == 1)

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2008-10-31 14:22:11 +0000
+++ b/sql/mysqld.cc	2008-11-13 16:40:12 +0000
@@ -3765,12 +3765,12 @@ with --log-bin instead.");
     }
     else
     {
-      global_system_variables.binlog_format= BINLOG_FORMAT_STMT;
+      global_system_variables.binlog_format= BINLOG_FORMAT_MIXED;
     }
   }
   else
     if (opt_binlog_format_id == BINLOG_FORMAT_UNSPEC)
-      global_system_variables.binlog_format= BINLOG_FORMAT_STMT;
+      global_system_variables.binlog_format= BINLOG_FORMAT_MIXED;
     else
     { 
       DBUG_ASSERT(global_system_variables.binlog_format != BINLOG_FORMAT_UNSPEC);

=== modified file 'storage/ndb/include/mgmapi/mgmapi.h'
--- a/storage/ndb/include/mgmapi/mgmapi.h	2008-08-07 03:45:20 +0000
+++ b/storage/ndb/include/mgmapi/mgmapi.h	2008-11-17 14:20:48 +0000
@@ -554,6 +554,15 @@ extern "C" {
    */
   const char *ndb_mgm_get_connected_host(NdbMgmHandle handle);
 
+  /**
+   * Gets connection bind address
+   *
+   * @param   handle         Management handle
+   *
+   * @return                 hostname
+   */
+  const char *ndb_mgm_get_connected_bind_address(NdbMgmHandle handle);
+
 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
   /** @} *********************************************************************/
   /**

=== modified file 'storage/ndb/include/ndb_version.h.in'
--- a/storage/ndb/include/ndb_version.h.in	2008-09-12 07:21:54 +0000
+++ b/storage/ndb/include/ndb_version.h.in	2008-11-14 08:58:29 +0000
@@ -190,16 +190,18 @@ ndbd_suma_dictlock(Uint32 x)
   if (x >= NDB_VERSION_D)
     return 1;
   
-  const Uint32 major = (x >> 16) & 0xFF;
-  const Uint32 minor = (x >>  8) & 0xFF;
-  
-  if (major >= 6)
   {
-    if (minor == 2)
+    const Uint32 major = (x >> 16) & 0xFF;
+    const Uint32 minor = (x >>  8) & 0xFF;
+    
+    if (major >= 6)
+    {
+      if (minor == 2)
       return x >= NDBD_SUMA_DICT_LOCK_62;
+    }
+    
+    return x >= NDBD_SUMA_DICT_LOCK_63;
   }
-  
-  return x >= NDBD_SUMA_DICT_LOCK_63;
 }
 
 #define NDBD_LONG_LIST_TABLES_CONF_62 NDB_MAKE_VERSION(6,2,16)
@@ -213,19 +215,47 @@ ndbd_LIST_TABLES_CONF_long_signal(Uint32
   if (x >= NDB_VERSION_D)
     return 1;
 
-  const Uint32 major = (x >> 16) & 0xFF;
-  const Uint32 minor = (x >>  8) & 0xFF;
-
-  if (major >= 6)
   {
-    if (minor == 2)
-      return x >= NDBD_LONG_LIST_TABLES_CONF_62;
+    const Uint32 major = (x >> 16) & 0xFF;
+    const Uint32 minor = (x >>  8) & 0xFF;
+    
+    if (major >= 6)
+    {
+      if (minor == 2)
+        return x >= NDBD_LONG_LIST_TABLES_CONF_62;
+    }
+    
+    return x >= NDBD_LONG_LIST_TABLES_CONF_63;
   }
-
-  return x >= NDBD_LONG_LIST_TABLES_CONF_63;
 }
 
 #define NDBD_FILTER_INSTANCE_63 NDB_MAKE_VERSION(6,3,16)
 #define NDBD_COPY_GCI_RESTART_NR NDB_MAKE_VERSION(6,3,18)
 
+#define NDBD_API_TAKE_OVERTCCONF_60 NDB_MAKE_VERSION(5,2,4)
+#define NDBD_API_TAKE_OVERTCCONF_62 NDB_MAKE_VERSION(6,2,17)
+#define NDBD_API_TAKE_OVERTCCONF_63 NDB_MAKE_VERSION(6,3,19)
+
+static
+inline
+int
+ndb_takeovertc(Uint32 x)
+{
+  if (x >= NDB_VERSION_D)
+    return 1;
+
+  {
+    const Uint32 major = (x >> 16) & 0xFF;
+    const Uint32 minor = (x >>  8) & 0xFF;
+    
+    if (major >= 6)
+    {
+      if (minor == 2)
+        return x >= NDBD_API_TAKE_OVERTCCONF_62;
+    }
+    
+    return x >= NDBD_API_TAKE_OVERTCCONF_63;
+  }
+}
+
 #endif

=== modified file 'storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2008-05-30 06:35:19 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2008-11-14 11:19:35 +0000
@@ -2264,7 +2264,8 @@ private:
   void writeFileHeaderOpen(Signal* signal, Uint32 type);
   void writeInitMbyte(Signal* signal);
   void writeSinglePage(Signal* signal, Uint32 pageNo,
-                       Uint32 wordWritten, Uint32 place);
+                       Uint32 wordWritten, Uint32 place,
+                       bool sync = true);
   void buildLinkedLogPageList(Signal* signal);
   void changeMbyte(Signal* signal);
   Uint32 checkIfExecLog(Signal* signal);

=== modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2008-11-08 21:22:57 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2008-11-14 11:19:35 +0000
@@ -13418,7 +13418,7 @@ void Dblqh::openFileInitLab(Signal* sign
   logFilePtr.p->logFileStatus = LogFileRecord::OPEN_INIT;
   seizeLogpage(signal);
   writeSinglePage(signal, (clogFileSize * ZPAGES_IN_MBYTE) - 1,
-                  ZPAGE_SIZE - 1, __LINE__);
+                  ZPAGE_SIZE - 1, __LINE__, false);
   lfoPtr.p->lfoState = LogFileOperationRecord::INIT_WRITE_AT_END;
   return;
 }//Dblqh::openFileInitLab()
@@ -13459,7 +13459,7 @@ void Dblqh::initFirstPageLab(Signal* sig
     logPagePtr.p->logPageWord[ZPOS_LOG_LAP] = 1;
     logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE] = ZCOMPLETED_GCI_TYPE;
     logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + 1] = 1;
-    writeSinglePage(signal, 1, ZPAGE_SIZE - 1, __LINE__);
+    writeSinglePage(signal, 1, ZPAGE_SIZE - 1, __LINE__, false);
     lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_GCI_ZERO;
     return;
   }//if
@@ -13930,12 +13930,13 @@ void Dblqh::writeFileHeaderOpen(Signal* 
 /*       LOG FILE. THIS HAS SPECIAL SIGNIFANCE TO FIND     */
 /*       THE END OF THE LOG AT SYSTEM RESTART.             */
 /* ------------------------------------------------------- */
-  writeSinglePage(signal, 0, ZPAGE_SIZE - 1, __LINE__);
   if (wmoType == ZINIT) {
     jam();
+    writeSinglePage(signal, 0, ZPAGE_SIZE - 1, __LINE__, false);
     lfoPtr.p->lfoState = LogFileOperationRecord::INIT_FIRST_PAGE;
   } else {
     jam();
+    writeSinglePage(signal, 0, ZPAGE_SIZE - 1, __LINE__, true);
     lfoPtr.p->lfoState = LogFileOperationRecord::FIRST_PAGE_WRITE_IN_LOGFILE;
   }//if
   logFilePtr.p->filePosition = 1;
@@ -13965,7 +13966,7 @@ void Dblqh::writeInitMbyte(Signal* signa
 {
   initLogpage(signal);
   writeSinglePage(signal, logFilePtr.p->currentMbyte * ZPAGES_IN_MBYTE,
-                  ZPAGE_SIZE - 1, __LINE__);
+                  ZPAGE_SIZE - 1, __LINE__, false);
   lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_INIT_MBYTE;
 }//Dblqh::writeInitMbyte()
 
@@ -13976,7 +13977,8 @@ void Dblqh::writeInitMbyte(Signal* signa
 /*       SUBROUTINE SHORT NAME:  WSP                                         */
 /* ------------------------------------------------------------------------- */
 void Dblqh::writeSinglePage(Signal* signal, Uint32 pageNo,
-                            Uint32 wordWritten, Uint32 place) 
+                            Uint32 wordWritten, Uint32 place,
+                            bool sync) 
 {
   seizeLfo(signal);
   initLfo(signal);
@@ -13998,7 +14000,7 @@ void Dblqh::writeSinglePage(Signal* sign
   signal->theData[0] = logFilePtr.p->fileRef;
   signal->theData[1] = cownref;
   signal->theData[2] = lfoPtr.i;
-  signal->theData[3] = ZLIST_OF_PAIRS_SYNCH;
+  signal->theData[3] = sync ? ZLIST_OF_PAIRS_SYNCH : ZLIST_OF_PAIRS;
   signal->theData[4] = ZVAR_NO_LOG_PAGE_WORD;
   signal->theData[5] = 1;                     /* ONE PAGE WRITTEN */
   signal->theData[6] = logPagePtr.i;

=== modified file 'storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2008-11-11 09:34:56 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2008-11-13 13:20:59 +0000
@@ -7359,6 +7359,9 @@ Dbtc::checkNodeFailComplete(Signal* sign
     nfRep->failedNodeId = hostptr.i;
     sendSignal(cdihblockref, GSN_NF_COMPLETEREP, signal, 
 	       NFCompleteRep::SignalLength, JBB);
+
+    sendSignal(QMGR_REF, GSN_NF_COMPLETEREP, signal, 
+	       NFCompleteRep::SignalLength, JBB);
   }
 
   CRASH_INSERTION(8058);

=== modified file 'storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp'
--- a/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp	2008-08-11 10:41:11 +0000
+++ b/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp	2008-11-13 13:15:56 +0000
@@ -243,6 +243,7 @@ private:
   void execDUMP_STATE_ORD(Signal* signal);
   void execCONNECT_REP(Signal* signal);
   void execNDB_FAILCONF(Signal* signal);
+  void execNF_COMPLETEREP(Signal*);
   void execREAD_CONFIG_REQ(Signal* signal);
   void execSTTOR(Signal* signal);
   void execCM_INFOCONF(Signal* signal);

=== modified file 'storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp'
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp	2007-11-23 10:09:30 +0000
+++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp	2008-11-13 13:15:56 +0000
@@ -100,6 +100,7 @@ Qmgr::Qmgr(Block_context& ctx)
   // Received signals
   addRecSignal(GSN_CONNECT_REP, &Qmgr::execCONNECT_REP);
   addRecSignal(GSN_NDB_FAILCONF, &Qmgr::execNDB_FAILCONF);
+  addRecSignal(GSN_NF_COMPLETEREP, &Qmgr::execNF_COMPLETEREP);
   addRecSignal(GSN_READ_CONFIG_REQ, &Qmgr::execREAD_CONFIG_REQ);
   addRecSignal(GSN_STTOR, &Qmgr::execSTTOR);
   addRecSignal(GSN_CLOSE_COMCONF, &Qmgr::execCLOSE_COMCONF);

=== modified file 'storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp'
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp	2008-08-27 20:10:42 +0000
+++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp	2008-11-13 13:20:59 +0000
@@ -2724,12 +2724,47 @@ void Qmgr::execNDB_FAILCONF(Signal* sign
     if (nodePtr.p->phase == ZAPI_ACTIVE){
       jam();
       sendSignal(nodePtr.p->blockRef, GSN_NF_COMPLETEREP, signal, 
-                 NFCompleteRep::SignalLength, JBA);
+                 NFCompleteRep::SignalLength, JBB);
     }//if
   }//for
   return;
 }//Qmgr::execNDB_FAILCONF()
 
+void
+Qmgr::execNF_COMPLETEREP(Signal* signal)
+{
+  jamEntry();
+  NFCompleteRep rep = *(NFCompleteRep*)signal->getDataPtr();
+  if (rep.blockNo != DBTC)
+  {
+    jam();
+    ndbassert(false);
+    return;
+  }
+
+  /**
+   * This is a disgrace...but execNF_COMPLETEREP in ndbapi is a mess
+   *   actually equally messy as it is in ndbd...
+   *   this is therefore a simple way of having ndbapi to get
+   *   earlier information that transactions can be aborted
+   */
+  signal->theData[0] = rep.failedNodeId;
+  NodeRecPtr nodePtr;
+  for (nodePtr.i = 1; nodePtr.i < MAX_NODES; nodePtr.i++) 
+  {
+    jam();
+    ptrAss(nodePtr, nodeRec);
+    if (nodePtr.p->phase == ZAPI_ACTIVE && 
+        ndb_takeovertc(getNodeInfo(nodePtr.i).m_version))
+    {
+      jam();
+      sendSignal(nodePtr.p->blockRef, GSN_TAKE_OVERTCCONF, signal, 
+                 NFCompleteRep::SignalLength, JBB);
+    }//if
+  }//for
+  return;
+}
+
 /*******************************/
 /* DISCONNECT_REP             */
 /*******************************/

=== modified file 'storage/ndb/src/mgmapi/LocalConfig.cpp'
--- a/storage/ndb/src/mgmapi/LocalConfig.cpp	2008-10-24 11:00:37 +0000
+++ b/storage/ndb/src/mgmapi/LocalConfig.cpp	2008-11-17 14:20:48 +0000
@@ -22,6 +22,7 @@
 LocalConfig::LocalConfig(){
   error_line = 0; error_msg[0] = 0;
   _ownNodeId= 0;
+  bind_address_port= 0;
 }
 
 bool
@@ -153,6 +154,11 @@ const char *hostNameTokens[] = {
   0
 };
 
+const char *bindAddressTokens[] = {
+  "bind-address=%[^:]:%i",
+  0
+};
+
 const char *fileNameTokens[] = {
   "file://%s",
   "file=%s",
@@ -179,6 +185,10 @@ LocalConfig::parseHostName(const char * 
 	mgmtSrvrId.type = MgmId_TCP;
 	mgmtSrvrId.name.assign(tempString);
 	mgmtSrvrId.port = port;
+        /* assign default bind_address if available */
+        if (bind_address.length())
+          mgmtSrvrId.bind_address.assign(bind_address);
+	mgmtSrvrId.bind_address_port = bind_address_port;
 	ids.push_back(mgmtSrvrId);
 	return true;
       }
@@ -193,6 +203,41 @@ LocalConfig::parseHostName(const char * 
 }
 
 bool
+LocalConfig::parseBindAddress(const char * buf)
+{
+  char tempString[1024];
+  char tempString2[1024];
+  int port;
+  do
+  {
+    for(int i = 0; bindAddressTokens[i] != 0; i++)
+    {
+      if (sscanf(buf, bindAddressTokens[i], tempString, &port) == 2)
+      {
+        if (ids.size() == 0)
+        {
+          /* assign default bind_address */
+          bind_address.assign(tempString);
+          bind_address_port = port;
+          return true;
+        }
+        /* override bind_address on latest mgmd */
+        MgmtSrvrId &mgmtSrvrId= ids[ids.size()-1];
+	mgmtSrvrId.bind_address.assign(tempString);
+	mgmtSrvrId.bind_address_port = port;
+	return true;
+      }
+    }
+    if (buf == tempString2)
+      break;
+    // try to add port 0 to see if it works
+    snprintf(tempString2, sizeof(tempString2),"%s:0", buf);
+    buf= tempString2;
+  } while(1);
+  return false;
+}
+
+bool
 LocalConfig::parseFileName(const char * buf){
   char tempString[1024];
   for(int i = 0; fileNameTokens[i] != 0; i++) {
@@ -222,6 +267,8 @@ LocalConfig::parseString(const char * co
 	continue;
     if (parseHostName(tok))
       continue;
+    if (parseBindAddress(tok))
+      continue;
     if (parseFileName(tok))
       continue;
     

=== modified file 'storage/ndb/src/mgmapi/LocalConfig.hpp'
--- a/storage/ndb/src/mgmapi/LocalConfig.hpp	2006-12-23 19:20:40 +0000
+++ b/storage/ndb/src/mgmapi/LocalConfig.hpp	2008-11-17 14:20:48 +0000
@@ -33,6 +33,8 @@ struct MgmtSrvrId {
   MgmtSrvrId_Type type;
   BaseString name;
   unsigned int port;
+  BaseString bind_address;
+  unsigned int bind_address_port;
 };
 
 struct LocalConfig {
@@ -43,6 +45,9 @@ struct LocalConfig {
   int error_line;
   char error_msg[256];
 
+  BaseString bind_address;
+  unsigned int bind_address_port;
+
   LocalConfig();
   ~LocalConfig();
   bool init(const char *connectString = 0,
@@ -58,6 +63,7 @@ struct LocalConfig {
   
   bool parseNodeId(const char *buf);
   bool parseHostName(const char *buf);
+  bool parseBindAddress(const char *buf);
   bool parseFileName(const char *buf);
   bool parseString(const char *buf, BaseString &err);
   char * makeConnectString(char *buf, int sz);

=== modified file 'storage/ndb/src/mgmapi/mgmapi.cpp'
--- a/storage/ndb/src/mgmapi/mgmapi.cpp	2008-10-31 15:22:39 +0000
+++ b/storage/ndb/src/mgmapi/mgmapi.cpp	2008-11-17 14:20:48 +0000
@@ -106,6 +106,7 @@ struct ndb_mgm_handle {
   int mgmd_version_minor;
   int mgmd_version_build;
   char * m_bindaddress;
+  int m_bindaddress_port;
 };
 
 #define SET_ERROR(h, e, s) setError(h, e, __LINE__, s)
@@ -189,6 +190,7 @@ ndb_mgm_create_handle()
   h->errstream       = stdout;
   h->m_name          = 0;
   h->m_bindaddress   = 0;
+  h->m_bindaddress_port = 0;
 
   strncpy(h->last_error_desc, "No error", NDB_MGM_MAX_ERR_DESC_SIZE);
 
@@ -245,10 +247,22 @@ ndb_mgm_set_bindaddress(NdbMgmHandle han
     free(handle->m_bindaddress);
 
   if (arg)
+  {
     handle->m_bindaddress = strdup(arg);
+    char *port = strchr(handle->m_bindaddress, ':');
+    if (port != 0)
+    {
+      handle->m_bindaddress_port = atoi(port+1);
+      *port = 0;
+    }
+    else
+      handle->m_bindaddress_port = 0;
+  }
   else
+  {
     handle->m_bindaddress = 0;
-
+    handle->m_bindaddress_port = 0;
+  }
   DBUG_RETURN(0);
 }
 
@@ -522,50 +536,6 @@ ndb_mgm_connect(NdbMgmHandle handle, int
   LocalConfig &cfg= handle->cfg;
   NDB_SOCKET_TYPE sockfd= NDB_INVALID_SOCKET;
   Uint32 i;
-  SocketClient s(0, 0);
-  s.set_connect_timeout((handle->timeout+999)/1000);
-  if (!s.init())
-  {
-    fprintf(handle->errstream, 
-	    "Unable to create socket, "
-	    "while trying to connect with connect string: %s\n",
-	    cfg.makeConnectString(buf,sizeof(buf)));
-
-    setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
-	    "Unable to create socket, "
-	    "while trying to connect with connect string: %s\n",
-	    cfg.makeConnectString(buf,sizeof(buf)));
-    DBUG_RETURN(-1);
-  }
-
-  if (handle->m_bindaddress)
-  {
-    BaseString::snprintf(buf, sizeof(buf), handle->m_bindaddress);
-    unsigned short portno = 0;
-    char * port = strchr(buf, ':');
-    if (port != 0)
-    {
-      portno = atoi(port+1);
-      * port = 0;
-    }
-    int err;
-    if ((err = s.bind(buf, portno)) != 0)
-    {
-      fprintf(handle->errstream, 
-	      "Unable to bind local address %s errno: %d, "
-	      "while trying to connect with connect string: %s\n",
-	      handle->m_bindaddress, err,
-	      cfg.makeConnectString(buf,sizeof(buf)));
-      
-      setError(handle, NDB_MGM_BIND_ADDRESS, __LINE__,
-	       "Unable to bind local address %s errno: %d, "
-	       "while trying to connect with connect string: %s\n",
-	       handle->m_bindaddress, err,
-	       cfg.makeConnectString(buf,sizeof(buf)));
-      DBUG_RETURN(-1);
-    }
-  }
-  
   while (sockfd == NDB_INVALID_SOCKET)
   {
     // do all the mgmt servers
@@ -573,6 +543,58 @@ ndb_mgm_connect(NdbMgmHandle handle, int
     {
       if (cfg.ids[i].type != MgmId_TCP)
 	continue;
+
+      SocketClient s(0, 0);
+      const char *bind_address= NULL;
+      unsigned short bind_address_port= 0;
+      s.set_connect_timeout((handle->timeout+999)/1000);
+      if (!s.init())
+      {
+        fprintf(handle->errstream, 
+                "Unable to create socket, "
+                "while trying to connect with connect string: %s\n",
+                cfg.makeConnectString(buf,sizeof(buf)));
+
+        setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
+                 "Unable to create socket, "
+                 "while trying to connect with connect string: %s\n",
+                 cfg.makeConnectString(buf,sizeof(buf)));
+        DBUG_RETURN(-1);
+      }
+      if (handle->m_bindaddress)
+      {
+        bind_address= handle->m_bindaddress;
+        bind_address_port= handle->m_bindaddress_port;
+      }
+      else if (cfg.ids[i].bind_address.length())
+      {
+        bind_address= cfg.ids[i].bind_address.c_str();
+        bind_address_port= cfg.ids[i].bind_address_port;
+      }
+      if (bind_address)
+      {
+        int err;
+        if ((err = s.bind(bind_address, bind_address_port)) != 0)
+        {
+          if (!handle->m_bindaddress)
+          {
+            // retry with next mgmt server
+            continue;
+          }
+          fprintf(handle->errstream, 
+                  "Unable to bind local address '%s:%d' errno: %d, "
+                  "while trying to connect with connect string: '%s'\n",
+                  bind_address, (int)bind_address_port, err,
+                  cfg.makeConnectString(buf,sizeof(buf)));
+      
+          setError(handle, NDB_MGM_BIND_ADDRESS, __LINE__,
+                   "Unable to bind local address '%s:%d' errno: %d, "
+                   "while trying to connect with connect string: '%s'\n",
+                   bind_address, (int)bind_address_port, err,
+                   cfg.makeConnectString(buf,sizeof(buf)));
+          DBUG_RETURN(-1);
+        }
+      }
       sockfd = s.connect(cfg.ids[i].name.c_str(), cfg.ids[i].port);
       if (sockfd != NDB_INVALID_SOCKET)
 	break;
@@ -1712,8 +1734,33 @@ ndb_mgm_listen_event_internal(NdbMgmHand
 
   const char *hostname= ndb_mgm_get_connected_host(handle);
   int port= ndb_mgm_get_connected_port(handle);
-  SocketClient s(hostname, port);
-  const NDB_SOCKET_TYPE sockfd = s.connect();
+  const char *bind_address= ndb_mgm_get_connected_bind_address(handle);
+  SocketClient s(0, 0);
+  s.set_connect_timeout((handle->timeout+999)/1000);
+  if (!s.init())
+  {
+    fprintf(handle->errstream, "Unable to create socket");
+    setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
+             "Unable to create socket");
+    return -1;
+  }
+  if (bind_address)
+  {
+    int err;
+    if ((err = s.bind(bind_address, 0)) != 0)
+    {
+      fprintf(handle->errstream,
+              "Unable to bind local address '%s:0' err: %d, errno: %d, "
+              "while trying to connect with connect string: '%s:%d'\n",
+              bind_address, err, errno, hostname, port);
+      setError(handle, NDB_MGM_BIND_ADDRESS, __LINE__,
+               "Unable to bind local address '%s:0' errno: %d, errno: %d, "
+               "while trying to connect with connect string: '%s:%d'\n",
+               bind_address, err, errno, hostname, port);
+      return -1;
+    }
+  }
+  const NDB_SOCKET_TYPE sockfd = s.connect(hostname, port);
   if (sockfd == NDB_INVALID_SOCKET) {
     setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
 	     "Unable to connect to");
@@ -2321,6 +2368,19 @@ const char *ndb_mgm_get_connectstring(Nd
 }
 
 extern "C"
+const char *ndb_mgm_get_connected_bind_address(NdbMgmHandle handle)
+{
+  if (handle->cfg_i >= 0)
+  {
+    if (handle->m_bindaddress)
+      return handle->m_bindaddress;
+    if (handle->cfg.ids[handle->cfg_i].bind_address.length())
+      return handle->cfg.ids[handle->cfg_i].bind_address.c_str();
+  }
+  return 0;
+}
+
+extern "C"
 int
 ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, int nodetype,
                      int log_event)

=== modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.cpp'
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2008-09-02 09:28:24 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2008-11-13 13:20:59 +0000
@@ -855,6 +855,8 @@ MgmtSrvr::sendVersionReq(int v_nodeId, 
 	do_send = 1; // retry with other node
       continue;
     }
+    case GSN_TAKE_OVERTCCONF:
+      continue;
     default:
       report_unknown_signal(signal);
       return SEND_OR_RECEIVE_FAILED;
@@ -1169,6 +1171,8 @@ int MgmtSrvr::sendSTOP_REQ(const Vector<
 	stoppedNodes.bitOR(mask);
       break;
     }
+    case GSN_TAKE_OVERTCCONF:
+      continue;
     default:
       report_unknown_signal(signal);
 #ifdef VM_TRACE
@@ -1729,6 +1733,8 @@ MgmtSrvr::setEventReportingLevelImpl(int
       nodes.clear(rep->failedNodeId);
       break;
     }
+    case GSN_TAKE_OVERTCCONF:
+      continue;
     default:
       report_unknown_signal(signal);
       return SEND_OR_RECEIVE_FAILED;
@@ -2014,6 +2020,9 @@ MgmtSrvr::handleReceivedSignal(NdbApiSig
     ndbout << "TAMPER ORD" << endl;
     break;
 
+  case GSN_TAKE_OVERTCCONF:
+    break;
+
   default:
     g_eventLogger->error("Unknown signal received. SignalNumber: "
                          "%i from (%d, %x)",
@@ -2208,6 +2217,8 @@ MgmtSrvr::alloc_node_id_req(NodeId free_
       // ignore NF_COMPLETEREP will come
       continue;
     }
+    case GSN_TAKE_OVERTCCONF:
+      continue;
     default:
       report_unknown_signal(signal);
       return SEND_OR_RECEIVE_FAILED;
@@ -2728,6 +2739,8 @@ MgmtSrvr::startBackup(Uint32& backupId, 
       // master node will report aborted backup
       break;
     }
+    case GSN_TAKE_OVERTCCONF:
+      continue;
     default:
       report_unknown_signal(signal);
       return SEND_OR_RECEIVE_FAILED;

=== modified file 'storage/ndb/src/ndbapi/NdbScanOperation.cpp'
--- a/storage/ndb/src/ndbapi/NdbScanOperation.cpp	2008-11-08 21:22:57 +0000
+++ b/storage/ndb/src/ndbapi/NdbScanOperation.cpp	2008-11-14 22:26:16 +0000
@@ -95,7 +95,10 @@ int
 NdbScanOperation::init(const NdbTableImpl* tab, NdbTransaction* myConnection)
 {
   m_transConnection = myConnection;
-  //NdbConnection* aScanConnection = theNdb->startTransaction(myConnection);
+
+  if(NdbOperation::init(tab, NULL, false) != 0)
+    return -1;
+
   theNdb->theRemainingStartTransactions++; // will be checked in hupp...
   NdbTransaction* aScanConnection = theNdb->hupp(myConnection);
   if (!aScanConnection){
@@ -105,11 +108,8 @@ NdbScanOperation::init(const NdbTableImp
   }
 
   // NOTE! The hupped trans becomes the owner of the operation
-  if(NdbOperation::init(tab, aScanConnection, false) != 0){
-    theNdb->theRemainingStartTransactions--;
-    return -1;
-  }
-  
+  theNdbCon= aScanConnection;
+
   initInterpreter();
   
   theStatus = GetValue;

=== modified file 'storage/ndb/src/ndbapi/Ndbif.cpp'
--- a/storage/ndb/src/ndbapi/Ndbif.cpp	2008-11-06 16:46:27 +0000
+++ b/storage/ndb/src/ndbapi/Ndbif.cpp	2008-11-13 13:20:59 +0000
@@ -905,6 +905,9 @@ Ndb::handleReceivedSignal(NdbApiSignal* 
     goto InvalidSignal;
     return;
   } 
+  case GSN_TAKE_OVERTCCONF:
+    abortTransactionsAfterNodeFailure(tFirstData); // theData[0]
+    break;
   default:
     goto InvalidSignal;
   }//swich

=== modified file 'storage/ndb/src/ndbapi/TransporterFacade.cpp'
--- a/storage/ndb/src/ndbapi/TransporterFacade.cpp	2008-08-12 09:45:38 +0000
+++ b/storage/ndb/src/ndbapi/TransporterFacade.cpp	2008-11-13 13:20:59 +0000
@@ -377,6 +377,16 @@ execute(void * callbackObj, SignalHeader
        }
        break;
      }
+     case GSN_TAKE_OVERTCCONF:
+     {
+       /**
+	* Report
+	*/
+       NdbApiSignal tSignal(* header);
+       tSignal.setDataPtr(theData);
+       theFacade->for_each(&tSignal, ptr);
+       return;
+     }
      default:
        break;
        

Thread
bzr commit into mysql-5.1 branch (msvensson:2745) Magnus Svensson18 Nov