List:Commits« Previous MessageNext Message »
From:Jonas Oreland Date:August 26 2010 12:44pm
Subject:bzr push into mysql-5.1-telco-7.0 branch (jonas:3719 to 3721)
View as plain text  
 3721 Jonas Oreland	2010-08-26 [merge]
      ndb - merge 63 to 70

    modified:
      storage/ndb/src/kernel/blocks/suma/Suma.cpp
      support-files/compiler_warnings.supp
 3720 Jonas Oreland	2010-08-26 [merge]
      ndb - merge 63 to 70

    modified:
      storage/ndb/include/kernel/signaldata/StopMe.hpp
      storage/ndb/include/kernel/signaldata/SumaImpl.hpp
      storage/ndb/include/mgmapi/ndbd_exit_codes.h
      storage/ndb/include/ndb_version.h.in
      storage/ndb/src/kernel/blocks/ERROR_codes.txt
      storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
      storage/ndb/src/kernel/blocks/suma/Suma.cpp
      storage/ndb/src/kernel/blocks/suma/Suma.hpp
      storage/ndb/src/kernel/blocks/suma/SumaInit.cpp
      storage/ndb/src/kernel/error/ndbd_exit_codes.c
      storage/ndb/src/ndbapi/Ndb.cpp
      storage/ndb/src/ndbapi/Ndbif.cpp
      storage/ndb/src/ndbapi/TransporterFacade.hpp
      storage/ndb/test/ndbapi/testDict.cpp
      storage/ndb/test/ndbapi/test_event.cpp
      storage/ndb/test/run-test/daily-basic-tests.txt
 3719 Magnus Blåudd	2010-08-26 [merge]
      Null merge changes already in 7.0

    modified:
      support-files/compiler_warnings.supp
=== modified file 'storage/ndb/include/kernel/signaldata/StopMe.hpp'
--- a/storage/ndb/include/kernel/signaldata/StopMe.hpp	2009-05-26 18:53:34 +0000
+++ b/storage/ndb/include/kernel/signaldata/StopMe.hpp	2010-08-26 09:00:51 +0000
@@ -28,27 +28,28 @@
  * @see StartMeReq
  * @see StartPermReq
  */
-class StopMeReq {
+struct StopMeReq
+{
   
   /**
    * Sender(s) / Reciver(s)
    */
   friend class Dbdih;
+  friend class Suma;
   
   /**
    * Sender
    */
   friend class Ndbcntr;
 
-public:
   STATIC_CONST( SignalLength = 2 );
-private:
   
   Uint32 senderRef;
   Uint32 senderData;
 };
 
-class StopMeConf {
+struct StopMeConf
+{
 
   /**
    * Sender(s) / Reciver(s)
@@ -60,10 +61,8 @@ class StopMeConf {
    */
   friend class Ndbcntr;
 
-public:
   STATIC_CONST( SignalLength = 2 );
   
-private:
   Uint32 senderRef;
   Uint32 senderData;
 };

=== modified file 'storage/ndb/include/kernel/signaldata/SumaImpl.hpp'
--- a/storage/ndb/include/kernel/signaldata/SumaImpl.hpp	2010-05-27 09:56:43 +0000
+++ b/storage/ndb/include/kernel/signaldata/SumaImpl.hpp	2010-08-26 12:33:33 +0000
@@ -519,18 +519,28 @@ struct SumaStartMeConf {
   Uint32 unused;
 };
 
-struct SumaHandoverReq {
-  STATIC_CONST( SignalLength = 3 );
+struct SumaHandoverReq
+{
+  STATIC_CONST( SignalLength = 4 );
   Uint32 gci;
   Uint32 nodeId;
   Uint32 theBucketMask[1];
+  Uint32 requestType;
+
+  enum RequestType
+  {
+    RT_START_NODE = 0,
+    RT_STOP_NODE = 1
+  };
 };
 
-struct SumaHandoverConf {
-  STATIC_CONST( SignalLength = 3 );
+struct SumaHandoverConf
+{
+  STATIC_CONST( SignalLength = 4 );
   Uint32 gci;
   Uint32 nodeId;
   Uint32 theBucketMask[1];
+  Uint32 requestType;
 };
 
 struct SumaContinueB

=== modified file 'storage/ndb/include/mgmapi/ndbd_exit_codes.h'
--- a/storage/ndb/include/mgmapi/ndbd_exit_codes.h	2009-10-26 14:40:19 +0000
+++ b/storage/ndb/include/mgmapi/ndbd_exit_codes.h	2010-08-26 12:33:33 +0000
@@ -123,6 +123,8 @@ typedef ndbd_exit_classification_enum nd
 #define NDBD_EXIT_NO_RESTORABLE_REPLICA       6303
 #define NDBD_EXIT_UNSUPPORTED_VERSION         6304
 
+#define NDBD_EXIT_GRACEFUL_SHUTDOWN_ERROR     6305
+
 /* ACC 6600-> */
 #define NDBD_EXIT_SR_OUT_OF_INDEXMEMORY       6600
 /* TUP 6800-> */

=== modified file 'storage/ndb/include/ndb_version.h.in'
--- a/storage/ndb/include/ndb_version.h.in	2010-08-05 08:12:31 +0000
+++ b/storage/ndb/include/ndb_version.h.in	2010-08-26 12:33:33 +0000
@@ -477,4 +477,29 @@ ndb_dih_get_tabinfo(Uint32 x)
   }
 }
 
+#define NDBD_SUMA_STOP_ME_63 NDB_MAKE_VERSION(6,3,37)
+#define NDBD_SUMA_STOP_ME_70 NDB_MAKE_VERSION(7,0,18)
+#define NDBD_SUMA_STOP_ME_71 NDB_MAKE_VERSION(7,1,7)
+
+static
+inline
+int
+ndbd_suma_stop_me(Uint32 x)
+{
+  {
+    const Uint32 major = (x >> 16) & 0xFF;
+    const Uint32 minor = (x >>  8) & 0xFF;
+
+    if (major == 6)
+    {
+      return x >= NDBD_SUMA_STOP_ME_63;
+    }
+    if (major == 7 && minor == 0)
+    {
+      return x >= NDBD_SUMA_STOP_ME_70;
+    }
+    return x >= NDBD_SUMA_STOP_ME_71;
+  }
+}
+
 #endif

=== modified file 'storage/ndb/src/kernel/blocks/ERROR_codes.txt'
--- a/storage/ndb/src/kernel/blocks/ERROR_codes.txt	2010-08-17 10:11:01 +0000
+++ b/storage/ndb/src/kernel/blocks/ERROR_codes.txt	2010-08-26 12:33:33 +0000
@@ -11,7 +11,7 @@ Next CMVMI 9000
 Next BACKUP 10042
 Next DBUTIL 11002
 Next DBTUX 12008
-Next SUMA 13043
+Next SUMA 13044
 Next LGMAN 15001
 Next TSMAN 16001
 

=== modified file 'storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp'
--- a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp	2010-06-24 21:42:03 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp	2010-08-26 12:33:33 +0000
@@ -3309,11 +3309,17 @@ Ndbcntr::StopRecord::checkLqhTimeout_1(S
   cntr.sendSignalWithDelay(cntr.reference(), GSN_CONTINUEB, signal, 100, 1);
 }
 
-void Ndbcntr::execCHANGE_NODE_STATE_CONF(Signal* signal){
+void
+Ndbcntr::execCHANGE_NODE_STATE_CONF(Signal* signal)
+{
   jamEntry();
+
+  /**
+   * stop replication stream
+   */
   signal->theData[0] = reference();
   signal->theData[1] = 12;
-  sendSignal(DBDIH_REF, GSN_STOP_ME_REQ, signal, 2, JBB);
+  sendSignal(SUMA_REF, GSN_STOP_ME_REQ, signal, 2, JBB);
 }
 
 void Ndbcntr::execSTOP_ME_REF(Signal* signal){
@@ -3325,6 +3331,18 @@ void Ndbcntr::execSTOP_ME_REF(Signal* si
 void Ndbcntr::execSTOP_ME_CONF(Signal* signal){
   jamEntry();
 
+  const StopMeConf * conf = CAST_CONSTPTR(StopMeConf, signal->getDataPtr());
+  if (conf->senderData == 12)
+  {
+    /**
+     * Remove node from transactions
+     */
+    signal->theData[0] = reference();
+    signal->theData[1] = 13;
+    sendSignal(DBDIH_REF, GSN_STOP_ME_REQ, signal, 2, JBB);
+    return;
+  }
+
   NodeState newState(NodeState::SL_STOPPING_4, 
 		     StopReq::getSystemStop(c_stopRec.stopReq.requestInfo));
   updateNodeState(signal, newState);

=== modified file 'storage/ndb/src/kernel/blocks/suma/Suma.cpp'
--- a/storage/ndb/src/kernel/blocks/suma/Suma.cpp	2010-08-17 11:47:55 +0000
+++ b/storage/ndb/src/kernel/blocks/suma/Suma.cpp	2010-08-26 12:41:30 +0000
@@ -47,6 +47,7 @@
 #include <signaldata/DihScanTab.hpp>
 #include <signaldata/SystemError.hpp>
 #include <signaldata/GCP.hpp>
+#include <signaldata/StopMe.hpp>
 
 #include <signaldata/DictLock.hpp>
 #include <ndbapi/NdbDictionary.hpp>
@@ -402,7 +403,7 @@ Suma::execDICT_LOCK_CONF(Signal* signal)
     return;
   case DictLockReq::SumaHandOver:
     jam();
-    send_handover_req(signal);
+    send_handover_req(signal, SumaHandoverReq::RT_START_NODE);
     return;
   default:
     jam();
@@ -772,7 +773,7 @@ Suma::check_start_handover(Signal* signa
 }
 
 void
-Suma::send_handover_req(Signal* signal)
+Suma::send_handover_req(Signal* signal, Uint32 type)
 {
   jam();
   c_startup.m_handover_nodes.assign(c_alive_nodes);
@@ -783,12 +784,15 @@ Suma::send_handover_req(Signal* signal)
   SumaHandoverReq* req= (SumaHandoverReq*)signal->getDataPtrSend();
   char buf[255];
   c_startup.m_handover_nodes.getText(buf);
-  infoEvent("Suma: initiate handover with nodes %s GCI: %d",
-            buf, gci);
+  infoEvent("Suma: initiate handover for %s with nodes %s GCI: %u",
+            (type == SumaHandoverReq::RT_START_NODE ? "startup" : "shutdown"),
+            buf,
+            gci);
 
   req->gci = gci;
   req->nodeId = getOwnNodeId();
-  
+  req->requestType = type;
+
   NodeReceiverGroup rg(SUMA, c_startup.m_handover_nodes);
   sendSignal(rg, GSN_SUMA_HANDOVER_REQ, signal, 
              SumaHandoverReq::SignalLength, JBB);
@@ -1247,6 +1251,14 @@ Suma::execNODE_FAILREP(Signal* signal){
 	  progError(__LINE__, NDBD_EXIT_SYSTEM_ERROR, 
 		    "Nodefailure during SUMA takeover");
 	}
+        else if (state & Bucket::BUCKET_SHUTDOWN)
+        {
+          jam();
+          c_buckets[i].m_state &= ~Uint32(Bucket::BUCKET_SHUTDOWN);
+          m_switchover_buckets.clear(i);
+          ndbrequire(get_responsible_node(i, tmp) == getOwnNodeId());
+          start_resend(signal, i);
+        }
       }
       else if(get_responsible_node(i, tmp) == getOwnNodeId())
       {
@@ -4335,7 +4347,6 @@ found:
   if(!m_switchover_buckets.isclear())
   {
     bool unlock = false;
-    NdbNodeBitmask handover_nodes;
     Uint32 i = m_switchover_buckets.find(0);
     for(; i != Bucket_mask::NotFound; i = m_switchover_buckets.find(i + 1))
     {
@@ -4394,7 +4405,6 @@ found:
 	   */
           jam();
 	  c_buckets[i].m_state &= ~(Uint32)Bucket::BUCKET_HANDOVER;
-	  handover_nodes.set(c_buckets[i].m_switchover_node);
           m_gcp_complete_rep_count--;
 	  ndbout_c("handover");
 	}
@@ -4432,15 +4442,53 @@ found:
             drop = true;
           }
         }
+        else if (state & Bucket::BUCKET_SHUTDOWN)
+        {
+          Uint32 nodeId = c_buckets[i].m_switchover_node;
+          if (nodeId == getOwnNodeId())
+          {
+            jam();
+            m_active_buckets.clear(i);
+            m_gcp_complete_rep_count--;
+            ndbout_c("shutdown handover");
+          }
+          else
+          {
+            jam();
+            NdbNodeBitmask nodegroup = c_nodes_in_nodegroup_mask;
+            nodegroup.clear(nodeId);
+            ndbrequire(get_responsible_node(i) == nodeId &&
+                       get_responsible_node(i, nodegroup) == getOwnNodeId());
+            m_active_buckets.set(i);
+            m_gcp_complete_rep_count++;
+            ndbout_c("shutdown takover");
+          }
+          c_buckets[i].m_state &= ~(Uint32)Bucket::BUCKET_SHUTDOWN;
+        }
       }
     }
 
-    if(getNodeState().startLevel == NodeState::SL_STARTING && 
-       m_switchover_buckets.isclear() && 
-       c_startup.m_handover_nodes.isclear())
+    if (m_switchover_buckets.isclear())
     {
       jam();
-      sendSTTORRY(signal);
+      if(getNodeState().startLevel == NodeState::SL_STARTING && 
+         c_startup.m_handover_nodes.isclear())
+      {
+        jam();
+        sendSTTORRY(signal);
+      }
+      else if (getNodeState().startLevel >= NodeState::SL_STOPPING_1)
+      {
+        jam();
+        ndbrequire(c_shutdown.m_wait_handover);
+        StopMeConf * conf = CAST_PTR(StopMeConf, signal->getDataPtrSend());
+        conf->senderData = c_shutdown.m_senderData;
+        conf->senderRef = reference();
+        sendSignal(c_shutdown.m_senderRef, GSN_STOP_ME_CONF, signal,
+                   StopMeConf::SignalLength, JBB);
+        c_shutdown.m_wait_handover = false;
+        infoEvent("Suma: handover complete");
+      }
     }
 
     if (unlock)
@@ -5363,49 +5411,97 @@ Suma::execSUMA_HANDOVER_REQ(Signal* sign
   jamEntry();
   DBUG_ENTER("Suma::execSUMA_HANDOVER_REQ");
   //  Uint32 sumaRef = signal->getSendersBlockRef();
-  SumaHandoverReq const * req = (SumaHandoverReq *)signal->getDataPtr();
+  const SumaHandoverReq * req = CAST_CONSTPTR(SumaHandoverReq,
+                                              signal->getDataPtr());
 
   Uint32 gci = req->gci;
   Uint32 nodeId = req->nodeId;
   Uint32 new_gci = Uint32(m_last_complete_gci >> 32) + MAX_CONCURRENT_GCP + 1;
+  Uint32 requestType = req->requestType;
+  if (!ndbd_suma_stop_me(getNodeInfo(nodeId).m_version))
+  {
+    jam();
+    requestType = SumaHandoverReq::RT_START_NODE;
+  }
   
   Uint32 start_gci = (gci > new_gci ? gci : new_gci);
   // mark all active buckets really belonging to restarting SUMA
 
-  c_alive_nodes.set(nodeId);
-  if (DBG_3R)
-    ndbout_c("%u c_alive_nodes.set(%u)", __LINE__, nodeId);
-
   Bucket_mask tmp;
-  for( Uint32 i = 0; i < c_no_of_buckets; i++) 
+  if (requestType == SumaHandoverReq::RT_START_NODE)
   {
-    if(get_responsible_node(i) == nodeId)
+    jam();
+    c_alive_nodes.set(nodeId);
+    if (DBG_3R)
+      ndbout_c("%u c_alive_nodes.set(%u)", __LINE__, nodeId);
+
+    for( Uint32 i = 0; i < c_no_of_buckets; i++)
     {
-      if (m_active_buckets.get(i))
+      if(get_responsible_node(i) == nodeId)
       {
-	// I'm running this bucket but it should really be the restarted node
-	tmp.set(i);
-	m_active_buckets.clear(i);
-	m_switchover_buckets.set(i);
-	c_buckets[i].m_switchover_gci = (Uint64(start_gci) << 32) - 1;
-	c_buckets[i].m_state |= Bucket::BUCKET_HANDOVER;
-	c_buckets[i].m_switchover_node = nodeId;
-	ndbout_c("prepare to handover bucket: %d", i);
+        if (m_active_buckets.get(i))
+        {
+          // I'm running this bucket but it should really be the restarted node
+          tmp.set(i);
+          m_active_buckets.clear(i);
+          m_switchover_buckets.set(i);
+          c_buckets[i].m_switchover_gci = (Uint64(start_gci) << 32) - 1;
+          c_buckets[i].m_state |= Bucket::BUCKET_HANDOVER;
+          c_buckets[i].m_switchover_node = nodeId;
+          ndbout_c("prepare to handover bucket: %d", i);
+        }
+        else if(m_switchover_buckets.get(i))
+        {
+          ndbout_c("dont handover bucket: %d %d", i, nodeId);
+        }
       }
-      else if(m_switchover_buckets.get(i))
+    }
+  }
+  else if (requestType == SumaHandoverReq::RT_STOP_NODE)
+  {
+    jam();
+
+    for( Uint32 i = 0; i < c_no_of_buckets; i++)
+    {
+      NdbNodeBitmask nodegroup = c_nodes_in_nodegroup_mask;
+      nodegroup.clear(nodeId);
+      if(get_responsible_node(i) == nodeId &&
+         get_responsible_node(i, nodegroup) == getOwnNodeId())
       {
-	ndbout_c("dont handover bucket: %d %d", i, nodeId);
+        // I'm will be running this bucket when nodeId shutdown
+        jam();
+        tmp.set(i);
+        m_switchover_buckets.set(i);
+        c_buckets[i].m_switchover_gci = (Uint64(start_gci) << 32) - 1;
+        c_buckets[i].m_state |= Bucket::BUCKET_SHUTDOWN;
+        c_buckets[i].m_switchover_node = nodeId;
+        ndbout_c("prepare to takeover bucket: %d", i);
       }
     }
   }
-  
-  SumaHandoverConf* conf= (SumaHandoverConf*)signal->getDataPtrSend();
-  tmp.copyto(BUCKET_MASK_SIZE, conf->theBucketMask);
-  conf->gci = start_gci;
-  conf->nodeId = getOwnNodeId();
-  sendSignal(calcSumaBlockRef(nodeId), GSN_SUMA_HANDOVER_CONF, signal,
-	     SumaHandoverConf::SignalLength, JBB);
-  
+  else
+  {
+    jam();
+    goto ref;
+  }
+
+  {
+    SumaHandoverConf *conf= CAST_PTR(SumaHandoverConf,signal->getDataPtrSend());
+    tmp.copyto(BUCKET_MASK_SIZE, conf->theBucketMask);
+    conf->gci = start_gci;
+    conf->nodeId = getOwnNodeId();
+    conf->requestType = requestType;
+    sendSignal(calcSumaBlockRef(nodeId), GSN_SUMA_HANDOVER_CONF, signal,
+               SumaHandoverConf::SignalLength, JBB);
+  }
+
+  DBUG_VOID_RETURN;
+
+ref:
+  signal->theData[0] = 111;
+  signal->theData[1] = getOwnNodeId();
+  signal->theData[2] = nodeId;
+  sendSignal(calcSumaBlockRef(nodeId), GSN_SUMA_HANDOVER_REF, signal, 3, JBB);
   DBUG_VOID_RETURN;
 }
 
@@ -5421,40 +5517,114 @@ Suma::execSUMA_HANDOVER_CONF(Signal* sig
   jamEntry();
   DBUG_ENTER("Suma::execSUMA_HANDOVER_CONF");
 
-  SumaHandoverConf const * conf = (SumaHandoverConf *)signal->getDataPtr();
+  const SumaHandoverConf * conf = CAST_CONSTPTR(SumaHandoverConf,
+                                                signal->getDataPtr());
+
+  CRASH_INSERTION(13043);
 
   Uint32 gci = conf->gci;
   Uint32 nodeId = conf->nodeId;
+  Uint32 requestType = conf->requestType;
   Bucket_mask tmp;
   tmp.assign(BUCKET_MASK_SIZE, conf->theBucketMask);
 #ifdef HANDOVER_DEBUG
   ndbout_c("Suma::execSUMA_HANDOVER_CONF, gci = %u", gci);
 #endif
 
-  char buf[255];
-  tmp.getText(buf);
-  infoEvent("Suma: handover from node %d gci: %d buckets: %s (%d)",
-	    nodeId, gci, buf, c_no_of_buckets);
-  g_eventLogger->info("Suma: handover from node %d gci: %d buckets: %s (%d)",
-                      nodeId, gci, buf, c_no_of_buckets);
+  if (!ndbd_suma_stop_me(getNodeInfo(nodeId).m_version))
+  {
+    jam();
+    requestType = SumaHandoverReq::RT_START_NODE;
+  }
 
-  for( Uint32 i = 0; i < c_no_of_buckets; i++) 
+  if (requestType == SumaHandoverReq::RT_START_NODE)
   {
-    if (tmp.get(i))
+    jam();
+    for (Uint32 i = 0; i < c_no_of_buckets; i++)
     {
-      if (DBG_3R)
-        ndbout_c("%u : %u %u", i, get_responsible_node(i), getOwnNodeId());
-
-      ndbrequire(get_responsible_node(i) == getOwnNodeId());
-      // We should run this bucket, but _nodeId_ is
-      c_buckets[i].m_switchover_gci = (Uint64(gci) << 32) - 1;
-      c_buckets[i].m_state |= Bucket::BUCKET_STARTING;
+      if (tmp.get(i))
+      {
+        if (DBG_3R)
+          ndbout_c("%u : %u %u", i, get_responsible_node(i), getOwnNodeId());
+        ndbrequire(get_responsible_node(i) == getOwnNodeId());
+        // We should run this bucket, but _nodeId_ is
+        c_buckets[i].m_switchover_gci = (Uint64(gci) << 32) - 1;
+        c_buckets[i].m_state |= Bucket::BUCKET_STARTING;
+      }
     }
+
+    char buf[255];
+    tmp.getText(buf);
+    infoEvent("Suma: handover from node %u gci: %u buckets: %s (%u)",
+              nodeId, gci, buf, c_no_of_buckets);
+    g_eventLogger->info("Suma: handover from node %u gci: %u buckets: %s (%u)",
+                        nodeId, gci, buf, c_no_of_buckets);
+    m_switchover_buckets.bitOR(tmp);
+    c_startup.m_handover_nodes.clear(nodeId);
+    DBUG_VOID_RETURN;
   }
+  else if (requestType == SumaHandoverReq::RT_STOP_NODE)
+  {
+    jam();
+    for (Uint32 i = 0; i < c_no_of_buckets; i++)
+    {
+      if (tmp.get(i))
+      {
+        ndbrequire(get_responsible_node(i) == getOwnNodeId());
+        // We should run this bucket, but _nodeId_ is
+        c_buckets[i].m_switchover_node = getOwnNodeId();
+        c_buckets[i].m_switchover_gci = (Uint64(gci) << 32) - 1;
+        c_buckets[i].m_state |= Bucket::BUCKET_SHUTDOWN;
+      }
+    }
   
-  m_switchover_buckets.bitOR(tmp);
-  c_startup.m_handover_nodes.clear(nodeId);
-  DBUG_VOID_RETURN;
+    char buf[255];
+    tmp.getText(buf);
+    infoEvent("Suma: handover to node %u gci: %u buckets: %s (%u)",
+              nodeId, gci, buf, c_no_of_buckets);
+    g_eventLogger->info("Suma: handover to node %u gci: %u buckets: %s (%u)",
+                        nodeId, gci, buf, c_no_of_buckets);
+    m_switchover_buckets.bitOR(tmp);
+    c_startup.m_handover_nodes.clear(nodeId);
+    DBUG_VOID_RETURN;
+  }
+}
+
+void
+Suma::execSTOP_ME_REQ(Signal* signal)
+{
+  jam();
+  StopMeReq req = * CAST_CONSTPTR(StopMeReq, signal->getDataPtr());
+
+  ndbrequire(refToNode(req.senderRef) == getOwnNodeId());
+  ndbrequire(c_shutdown.m_wait_handover == false);
+  c_shutdown.m_wait_handover = true;
+  c_shutdown.m_senderRef = req.senderRef;
+  c_shutdown.m_senderData = req.senderData;
+
+  for (Uint32 i = c_nodes_in_nodegroup_mask.find(0);
+       i != c_nodes_in_nodegroup_mask.NotFound ;
+       i = c_nodes_in_nodegroup_mask.find(i + 1))
+  {
+    /**
+     * Check that all SUMA nodes support graceful shutdown...
+     *   and it's too late to stop it...
+     * Shutdown instead...
+     */
+    if (!ndbd_suma_stop_me(getNodeInfo(i).m_version))
+    {
+      jam();
+      char buf[255];
+      BaseString::snprintf(buf, sizeof(buf),
+			   "Not all versions support graceful shutdown (suma)."
+			   " Shutdown directly instead");
+      progError(__LINE__,
+		NDBD_EXIT_GRACEFUL_SHUTDOWN_ERROR,
+		buf);
+      ndbrequire(false);
+    }
+  }
+  send_handover_req(signal, SumaHandoverReq::RT_STOP_NODE);
 }
 
 #ifdef NOT_USED
@@ -5692,8 +5862,8 @@ Suma::release_gci(Signal* signal, Uint32
   if(unlikely(bucket->m_state & mask))
   {
     jam();
-    ndbout_c("release_gci(%d, %llu) 0x%x-> node failure -> abort", 
-             buck, gci, bucket->m_state);
+    ndbout_c("release_gci(%d, %u/%u) 0x%x-> node failure -> abort", 
+             buck, Uint32(gci >> 32), Uint32(gci), bucket->m_state);
     return;
   }
   

=== modified file 'storage/ndb/src/kernel/blocks/suma/Suma.hpp'
--- a/storage/ndb/src/kernel/blocks/suma/Suma.hpp	2010-05-27 09:56:43 +0000
+++ b/storage/ndb/src/kernel/blocks/suma/Suma.hpp	2010-08-26 12:33:33 +0000
@@ -473,6 +473,8 @@ public:
   void execSUMA_START_ME_REF(Signal* signal);
   void execSUMA_START_ME_CONF(Signal* signal);
 
+  void execSTOP_ME_REQ(Signal*);
+
   void copySubscription(Signal* signal, DLHashTable<Subscription>::Iterator);
   void sendSubCreateReq(Signal* signal, Ptr<Subscription>);
   void copySubscriber(Signal*, Ptr<Subscription>, Ptr<Subscriber>);
@@ -517,6 +519,16 @@ private:
     NdbNodeBitmask m_handover_nodes;
   } c_startup;
 
+  /**
+   * for graceful shutdown
+   */
+  struct Shutdown
+  {
+    bool m_wait_handover;
+    Uint32 m_senderRef;
+    Uint32 m_senderData;
+  } c_shutdown;
+
   struct Restart
   {
     Uint16 m_abort;
@@ -545,7 +557,7 @@ private:
   void send_dict_unlock_ord(Signal* signal, Uint32 state);
   void send_start_me_req(Signal* signal);
   void check_start_handover(Signal* signal);
-  void send_handover_req(Signal* signal);
+  void send_handover_req(Signal* signal, Uint32 type);
 
   Uint32 get_responsible_node(Uint32 B) const;
   Uint32 get_responsible_node(Uint32 B, const NdbNodeBitmask& mask) const;
@@ -576,6 +588,7 @@ private:
       ,BUCKET_DROPPED_SELF  = 0x40 // New nodegroup (me) uses hi 8 bit for cnt
       ,BUCKET_DROPPED_OTHER = 0x80 // New nodegroup (not me)
       ,BUCKET_DROPPED_MASK  = (BUCKET_DROPPED_SELF | BUCKET_DROPPED_OTHER)
+      ,BUCKET_SHUTDOWN = 0x100 // Graceful shutdown
     };
     Uint16 m_state;
     Uint16 m_switchover_node;

=== modified file 'storage/ndb/src/kernel/blocks/suma/SumaInit.cpp'
--- a/storage/ndb/src/kernel/blocks/suma/SumaInit.cpp	2010-02-18 06:30:45 +0000
+++ b/storage/ndb/src/kernel/blocks/suma/SumaInit.cpp	2010-08-26 12:33:33 +0000
@@ -64,6 +64,9 @@ Suma::Suma(Block_context& ctx) :
   addRecSignal(GSN_SUB_GCP_COMPLETE_ACK, 
 	       &Suma::execSUB_GCP_COMPLETE_ACK);
   
+  addRecSignal(GSN_STOP_ME_REQ,
+               &Suma::execSTOP_ME_REQ);
+
   /**
    * SUMA participant if
    */
@@ -134,6 +137,7 @@ Suma::Suma(Block_context& ctx) :
   c_current_seq = 0;
   c_restart.m_ref = 0;
   c_startup.m_restart_server_node_id = RNIL; // Server for my NR
+  c_shutdown.m_wait_handover = false;
 
 #ifdef VM_TRACE
   m_gcp_monitor = 0;

=== modified file 'storage/ndb/src/kernel/error/ndbd_exit_codes.c'
--- a/storage/ndb/src/kernel/error/ndbd_exit_codes.c	2009-10-26 14:40:19 +0000
+++ b/storage/ndb/src/kernel/error/ndbd_exit_codes.c	2010-08-26 12:33:33 +0000
@@ -174,6 +174,9 @@ static const ErrStruct errArray[] =
    
    {NDBD_EXIT_RESTORE_SCHEMA, XCR, "Failure to restore schema" },
    
+   {NDBD_EXIT_GRACEFUL_SHUTDOWN_ERROR, XNE,
+    "Graceful shutdown not 100% possible due to mixed ndbd versions" },
+
    /* Sentinel */
    {0, XUE,
     "No message slogan found (please report a bug if you get this error code)"}

=== modified file 'storage/ndb/src/ndbapi/Ndb.cpp'
--- a/storage/ndb/src/ndbapi/Ndb.cpp	2010-06-10 07:21:34 +0000
+++ b/storage/ndb/src/ndbapi/Ndb.cpp	2010-08-26 12:33:33 +0000
@@ -151,6 +151,14 @@ Ndb::NDB_connect(Uint32 tNode) 
 
   DBUG_ENTER("Ndb::NDB_connect");
 
+  {
+    TransporterFacade *tp = theImpl->m_transporter_facade;
+    if (tp->get_node_stopping(tNode))
+    {
+      DBUG_RETURN(0);
+    }
+  }
+
   NdbTransaction * tConArray = theConnectionArray[tNode];
   if (tConArray != NULL) {
     DBUG_RETURN(2);

=== modified file 'storage/ndb/src/ndbapi/Ndbif.cpp'
--- a/storage/ndb/src/ndbapi/Ndbif.cpp	2010-01-28 15:16:46 +0000
+++ b/storage/ndb/src/ndbapi/Ndbif.cpp	2010-08-26 12:33:33 +0000
@@ -1184,13 +1184,9 @@ Ndb::sendPrepTrans(int forceSend)
     NdbTransaction * a_con = thePreparedTransactionsArray[i];
     thePreparedTransactionsArray[i] = NULL;
     Uint32 node_id = a_con->getConnectedNodeId();
-    if (((tp->getNodeSequence(node_id) == a_con->theNodeSequence) &&
-         tp->get_node_alive(node_id)) ||
-        ((tp->get_node_stopping(node_id) && 
-          ((a_con->theSendStatus == NdbTransaction::sendABORT) ||
-           (a_con->theSendStatus == NdbTransaction::sendABORTfail) ||
-           (a_con->theSendStatus == NdbTransaction::sendCOMMITstate) ||
-           (a_con->theSendStatus == NdbTransaction::sendCompleted))))) {
+    if ((tp->getNodeSequence(node_id) == a_con->theNodeSequence) &&
+        (tp->get_node_alive(node_id) || tp->get_node_stopping(node_id)))
+    {
       /*
       We will send if
       1) Node is alive and sequences are correct OR
@@ -1236,27 +1232,15 @@ Ndb::sendPrepTrans(int forceSend)
 #ifdef VM_TRACE
       a_con->printState();
 #endif
-      if ((tp->getNodeSequence(node_id) == a_con->theNodeSequence) &&
-          tp->get_node_stopping(node_id)) {
-        /*
-        The node we are connected to is currently in an early stopping phase
-        of a graceful stop. We will not send the prepared transactions. We
-        will simply refuse and let the application code handle the abort.
-        */
-        TRACE_DEBUG("Abort a transaction when stopping a node");
-        a_con->setOperationErrorCodeAbort(4023);
-        a_con->theCommitStatus = NdbTransaction::NeedAbort;
-      } else {
-        /*
+      /*
         The node is hard dead and we cannot continue. We will also release
         the connection to the free pool.
-        */
-        TRACE_DEBUG("The node was stone dead, inform about abort");
-        a_con->setOperationErrorCodeAbort(4025);
-        a_con->theReleaseOnClose = true;
-        a_con->theTransactionIsStarted = false;
-        a_con->theCommitStatus = NdbTransaction::Aborted;
-      }//if
+      */
+      TRACE_DEBUG("The node was stone dead, inform about abort");
+      a_con->setOperationErrorCodeAbort(4025);
+      a_con->theReleaseOnClose = true;
+      a_con->theTransactionIsStarted = false;
+      a_con->theCommitStatus = NdbTransaction::Aborted;
     }//if
     a_con->theReturnStatus = NdbTransaction::ReturnFailure;
     a_con->theCompletionStatus = NdbTransaction::CompletedFailure;

=== modified file 'storage/ndb/src/ndbapi/TransporterFacade.hpp'
--- a/storage/ndb/src/ndbapi/TransporterFacade.hpp	2010-01-28 15:16:46 +0000
+++ b/storage/ndb/src/ndbapi/TransporterFacade.hpp	2010-08-26 12:33:33 +0000
@@ -414,8 +414,7 @@ TransporterFacade::get_node_stopping(Nod
   const ClusterMgr::Node & node = theClusterMgr->getNodeInfo(n);
   assert(node.m_info.getType() == NodeInfo::DB);
   return (!node.m_state.getSingleUserMode() &&
-          ((node.m_state.startLevel == NodeState::SL_STOPPING_1) ||
-           (node.m_state.startLevel == NodeState::SL_STOPPING_2)));
+          node.m_state.startLevel >= NodeState::SL_STOPPING_1);
 }
 
 inline

=== modified file 'storage/ndb/test/ndbapi/testDict.cpp'
--- a/storage/ndb/test/ndbapi/testDict.cpp	2010-06-21 09:56:51 +0000
+++ b/storage/ndb/test/ndbapi/testDict.cpp	2010-08-26 12:33:33 +0000
@@ -175,7 +175,8 @@ int runCreateTheTable(NDBT_Context* ctx,
   }
   ctx->setTab(pTab2);
 
-  BaseString::snprintf(f_tablename, sizeof(f_tablename), pTab->getName());
+  BaseString::snprintf(f_tablename, sizeof(f_tablename), 
+                       "%s", pTab->getName());
 
   return NDBT_OK;
 }
@@ -3336,9 +3337,8 @@ runDropDDObjects(NDBT_Context* ctx, NDBT
         tableFound = list.elements[i].name;
         if(tableFound != 0){
           if(strcmp(list.elements[i].database, "TEST_DB") == 0 &&
-             strcmp(tableFound, "ndb_apply_status") != 0 &&
-             strcmp(tableFound, "NDB$BLOB_2_3") != 0 &&
-             strcmp(tableFound, "ndb_schema") != 0){
+             !is_prefix(tableFound, "NDB$BLOB"))
+          { 
       	    if(pDict->dropTable(tableFound) != 0){
               g_err << "Failed to drop table: " << tableFound << pDict->getNdbError() << endl;
               return NDBT_FAILED;

=== modified file 'storage/ndb/test/ndbapi/test_event.cpp'
--- a/storage/ndb/test/ndbapi/test_event.cpp	2010-08-20 11:10:25 +0000
+++ b/storage/ndb/test/ndbapi/test_event.cpp	2010-08-26 12:33:33 +0000
@@ -1008,6 +1008,7 @@ int runRestarter(NDBT_Context* ctx, NDBT
   NdbRestarter restarter;
   int i = 0;
   int lastId = 0;
+  bool abort = ctx->getProperty("Graceful", Uint32(0)) == 0;
 
   if (restarter.getNumDbNodes() < 2){
     ctx->stopTest();
@@ -1024,7 +1025,12 @@ int runRestarter(NDBT_Context* ctx, NDBT
     int id = lastId % restarter.getNumDbNodes();
     int nodeId = restarter.getDbNodeId(id);
     ndbout << "Restart node " << nodeId << endl; 
-    if(restarter.restartOneDbNode(nodeId, false, false, true) != 0){
+    if (abort == false && ((i % 3) == 0))
+    {
+      restarter.insertErrorInNode(nodeId, 13043);
+    }
+
+    if(restarter.restartOneDbNode(nodeId, false, false, abort) != 0){
       g_err << "Failed to restartNextDbNode" << endl;
       result = NDBT_FAILED;
       break;
@@ -3346,6 +3352,20 @@ TESTCASE("EventOperationApplier_NR", 
   FINALIZER(runVerify);
   FINALIZER(runDropShadowTable);
 }
+TESTCASE("EventOperationApplier_NS",
+	 "Verify that if we apply the data we get from event "
+	 "operation is the same as the original table"
+	 "NOTE! No errors are allowed!" ){
+  TC_PROPERTY("Graceful", 1);
+  INITIALIZER(runCreateEvent);
+  INITIALIZER(runCreateShadowTable);
+  STEP(runEventApplier);
+  STEP(runEventMixedLoad);
+  STEP(runRestarter);
+  FINALIZER(runDropEvent);
+  FINALIZER(runVerify);
+  FINALIZER(runDropShadowTable);
+}
 TESTCASE("MergeEventOperationApplier", 
 	 "Verify that if we apply the data we get from merged event "
 	 "operation is the same as the original table"

=== modified file 'storage/ndb/test/run-test/daily-basic-tests.txt'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt	2010-08-17 10:11:01 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt	2010-08-26 12:33:33 +0000
@@ -1016,6 +1016,11 @@ cmd: test_event
 args: -n EventOperationApplier_NR -l 2
 
 #
+max-time: 600
+cmd: test_event
+args: -n EventOperationApplier_NS T1
+
+#
 max-time: 3600
 cmd: test_event
 args: -n MergeEventOperationApplier_NR -l 2

=== modified file 'support-files/compiler_warnings.supp'
--- a/support-files/compiler_warnings.supp	2010-08-26 06:47:22 +0000
+++ b/support-files/compiler_warnings.supp	2010-08-26 12:41:30 +0000
@@ -86,4 +86,24 @@ listener.cc : .*conversion from 'SOCKET'
 
 # Ignore warnings in innodb_plugin
 .*/storage/innodb_plugin/.* : .*
-
+pars0grm.c : .*
+lexyy.c : .*
+handler/i_s.cc : .*
+handler/handler0alter.cc : .*
+handler/ha_innodb.cc : .*
+trx/trx0trx.c : .*
+trx/trx0rec.c : .*
+srv/srv0start.c : .*
+row/row0upd.c : .*
+row/row0mysql.c : .*
+row/row0ins.c : .*
+page/page0zip.c : .*
+os/os0file.c : .*
+log/log0recv.c : .*
+dict/dict0mem.c : .*
+dict/dict0dict.c : .*
+dict/dict0crea.c : .*
+buf/buf0lru.c : .*
+buf/buf0buf.c : .*
+btr/btr0sea.c : .*
+btr/btr0cur.c : .*

Attachment: [text/bzr-bundle] bzr/jonas@mysql.com-20100826124130-kuw81qy5le9lpl7o.bundle
Thread
bzr push into mysql-5.1-telco-7.0 branch (jonas:3719 to 3721) Jonas Oreland26 Aug