List:Commits« Previous MessageNext Message »
From:jonas Date:August 11 2008 1:30pm
Subject:bzr push into mysql-5.1 branch (jonas:2659) Bug#30780
View as plain text  
 2659 jonas@stripped	2008-08-11 [merge]
      ndb - 
        merge bug#30780 to 6.3
modified:
  storage/ndb/src/kernel/blocks/ERROR_codes.txt
  storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
  storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
  storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
  storage/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp
  storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
  storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp
  storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
  storage/ndb/src/kernel/vm/SimulatedBlock.cpp
  storage/ndb/src/kernel/vm/pc.hpp
  storage/ndb/test/ndbapi/test_event.cpp
  storage/ndb/test/run-test/daily-basic-tests.txt

=== modified file 'storage/ndb/src/kernel/blocks/ERROR_codes.txt'
--- a/storage/ndb/src/kernel/blocks/ERROR_codes.txt	2008-05-30 08:09:43 +0000
+++ b/storage/ndb/src/kernel/blocks/ERROR_codes.txt	2008-08-11 11:24:12 +0000
@@ -5,7 +5,7 @@ Next DBACC 3002
 Next DBTUP 4029
 Next DBLQH 5051
 Next DBDICT 6008
-Next DBDIH 7211
+Next DBDIH 7215
 Next DBTC 8064
 Next CMVMI 9000
 Next BACKUP 10041
@@ -182,6 +182,9 @@ And crash when all have "not" been sent
 7191: Crash when receiving LCP_COMPLETE_REP
 7192: Crash in setLcpActiveStatusStart - when dead node missed to LCP's
 
+7213: in GCP_COMMIT Kill specified node and self, stop processing
+7214: in GCP_TCFINISHED kill specified node
+     
 ERROR CODES FOR TESTING NODE FAILURE, FAILURE IN COPY FRAGMENT PROCESS:
 -----------------------------------------------------------------------
 

=== modified file 'storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2008-06-09 14:31:19 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2008-08-11 11:24:12 +0000
@@ -5181,6 +5181,21 @@ void Dbdih::execMASTER_GCPREQ(Signal* si
   case MicroGcp::M_GCP_COMMITTED:
     jam();
     gcpState = MasterGCPConf::GCP_COMMITTED;
+
+    /**
+     * Change state to GCP_COMMIT_RECEIVEDn and rerun GSN_GCP_NOMORETRANS
+     */
+    gcpState = MasterGCPConf::GCP_COMMIT_RECEIVED;
+    m_micro_gcp.m_state = MicroGcp::M_GCP_COMMIT;
+
+    {
+      GCPNoMoreTrans* req2 = (GCPNoMoreTrans*)signal->getDataPtrSend();
+      req2->senderData = m_micro_gcp.m_master_ref;
+      req2->gci_hi = m_micro_gcp.m_old_gci >> 32;
+      req2->gci_lo = m_micro_gcp.m_old_gci & 0xFFFFFFFF;
+      sendSignal(clocaltcblockref, GSN_GCP_NOMORETRANS, signal,
+                 GCPNoMoreTrans::SignalLength, JBB);
+    }
     break;
   };
 
@@ -8429,6 +8444,28 @@ void Dbdih::execGCP_COMMIT(Signal* signa
   }
   Uint64 gci = gci_lo | (Uint64(gci_hi) << 32);
 
+#ifdef ERROR_INSERT
+  if (ERROR_INSERTED(7213))
+  {
+    ndbout_c("err 7213 killing %d", c_error_insert_extra);
+    Uint32 save = signal->theData[0];
+    signal->theData[0] = 5048;
+    sendSignal(numberToRef(DBLQH, c_error_insert_extra),
+               GSN_NDB_TAMPER, signal, 1, JBB);
+    signal->theData[0] = save;
+    CLEAR_ERROR_INSERT_VALUE;
+
+    signal->theData[0] = 9999;
+    sendSignal(numberToRef(CMVMI, c_error_insert_extra),
+               GSN_DUMP_STATE_ORD, signal, 1, JBB);
+
+    signal->theData[0] = save;
+    CLEAR_ERROR_INSERT_VALUE;
+
+    return;
+  }
+#endif
+
   Uint32 masterRef = calcDihBlockRef(masterNodeId);
   ndbrequire(masterNodeId = cmasterNodeId);
   if (isMaster())
@@ -8507,6 +8544,19 @@ void Dbdih::execGCP_TCFINISHED(Signal* s
     return;
   }
 
+#ifdef ERROR_INSERT
+  if (ERROR_INSERTED(7214))
+  {
+    ndbout_c("err 7214 killing %d", c_error_insert_extra);
+    Uint32 save = signal->theData[0];
+    signal->theData[0] = 9999;
+    sendSignal(numberToRef(CMVMI, c_error_insert_extra),
+               GSN_NDB_TAMPER, signal, 1, JBB);
+    signal->theData[0] = save;
+    CLEAR_ERROR_INSERT_VALUE;
+  }
+#endif
+
 #ifdef GCP_TIMER_HACK
   NdbTick_getMicroTimer(&globalData.gcp_timer_commit[1]);
 #endif
@@ -15155,7 +15205,6 @@ Dbdih::execDUMP_STATE_ORD(Signal* signal
   if (signal->theData[0] == 7901)
     globalData.gcp_timer_limit = signal->theData[1];
 #endif
-
   if (arg == 7023)
   {
     /**
@@ -15193,6 +15242,18 @@ Dbdih::execDUMP_STATE_ORD(Signal* signal
     signal->theData[0] = arg;
     signal->theData[1] = ptr.i;
   }
+
+  DECLARE_DUMP0(DBDIH, 7213, "Set error 7213 with extra arg")
+  {
+    SET_ERROR_INSERT_VALUE2(7213, signal->theData[1]);
+    return;
+  }
+
+  DECLARE_DUMP0(DBDIH, 7214, "Set error 7214 with extra arg")
+  {
+    SET_ERROR_INSERT_VALUE2(7214, signal->theData[1]);
+    return;
+  }
 }//Dbdih::execDUMP_STATE_ORD()
 
 void

=== modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2008-07-23 11:25:03 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2008-08-11 11:24:12 +0000
@@ -6162,9 +6162,8 @@ void Dblqh::execCOMPLETE(Signal* signal)
     errorReport(signal, 1);
     return;
   }//if
-  if (ERROR_INSERTED(5042)) {
-    ndbrequire(false);
-  }
+  CRASH_INSERTION(5042);
+
   if (ERROR_INSERTED(5013)) {
     CLEAR_ERROR_INSERT_VALUE;
     sendSignalWithDelay(cownref, GSN_COMPLETE, signal, 2000, 3);

=== modified file 'storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp	2008-03-27 21:38:55 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp	2008-08-11 11:24:12 +0000
@@ -1437,10 +1437,10 @@ private:
   
   void checkGcp(Signal* signal);
   void commitGciHandling(Signal* signal, Uint64 Tgci);
-  void copyApi(Signal* signal);
+  void copyApi(Ptr<ApiConnectRecord> dst, Ptr<ApiConnectRecord> src);
   void DIVER_node_fail_handling(Signal* signal, Uint64 Tgci);
-  void gcpTcfinished(Signal* signal);
-  void handleGcp(Signal* signal);
+  void gcpTcfinished(Signal* signal, Uint64 gci);
+  void handleGcp(Signal* signal, Ptr<ApiConnectRecord>);
   void hash(Signal* signal);
   bool handle_special_hash(Uint32 dstHash[4], 
 			     Uint32* src, Uint32 srcLen, 
@@ -1459,8 +1459,8 @@ private:
   void initialiseScanOprec(Signal* signal);
   void initTable(Signal* signal);
   void initialiseTcConnect(Signal* signal);
-  void linkApiToGcp(Signal* signal);
-  void linkGciInGcilist(Signal* signal);
+  void linkApiToGcp(Ptr<GcpRecord>, Ptr<ApiConnectRecord>);
+  void linkGciInGcilist(Ptr<GcpRecord>);
   void linkKeybuf(Signal* signal);
   void linkTcInConnectionlist(Signal* signal);
   void releaseAbortResources(Signal* signal);
@@ -1468,7 +1468,6 @@ private:
   void releaseApiConCopy(Signal* signal);
   void releaseApiConnectFail(Signal* signal);
   void releaseAttrinfo();
-  void releaseGcp(Signal* signal);
   void releaseKeys();
   void releaseDirtyRead(Signal*, ApiConnectRecordPtr, TcConnectRecord*);
   void releaseDirtyWrite(Signal* signal);
@@ -1480,10 +1479,10 @@ private:
   void seizeApiConnectCopy(Signal* signal);
   void seizeApiConnectFail(Signal* signal);
   void seizeDatabuf(Signal* signal);
-  void seizeGcp(Signal* signal);
+  void seizeGcp(Ptr<GcpRecord> & dst, Uint64 gci);
   void seizeTcConnect(Signal* signal);
   void seizeTcConnectFail(Signal* signal);
-  void sendApiCommit(Signal* signal);
+  Ptr<ApiConnectRecord> sendApiCommit(Signal* signal);
   void sendAttrinfo(Signal* signal,
                     UintR TattrinfoPtr,
                     AttrbufRecord * const regAttrPtr,
@@ -1494,8 +1493,8 @@ private:
   void sendSystemError(Signal* signal, int line);
   void sendtckeyconf(Signal* signal, UintR TcommitFlag);
   void sendTcIndxConf(Signal* signal, UintR TcommitFlag);
-  void unlinkApiConnect(Signal* signal);
-  void unlinkGcp(Signal* signal);
+  void unlinkApiConnect(Ptr<GcpRecord>, Ptr<ApiConnectRecord>);
+  void unlinkGcp(Ptr<GcpRecord>);
   void unlinkReadyTcCon(Signal* signal);
   void handleFailedOperation(Signal* signal,
 			     const LqhKeyRef * const lqhKeyRef, 
@@ -1667,8 +1666,8 @@ private:
   UintR chostFilesize;
   NdbNodeBitmask c_alive_nodes;
 
+  Uint32 c_ongoing_take_over_cnt;
   GcpRecord *gcpRecord;
-  GcpRecordPtr gcpPtr;
   UintR cgcpFilesize;
 
   TableRecord *tableRecord;
@@ -1683,7 +1682,6 @@ private:
   UintR ctcTimer;
   UintR cDbHbInterval;
 
-  ApiConnectRecordPtr tmpApiConnectptr;
   Uint64 tcheckGcpId;
 
   struct TransCounters {

=== modified file 'storage/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp	2007-11-02 16:23:17 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp	2008-08-11 11:24:12 +0000
@@ -292,6 +292,7 @@ Dbtc::Dbtc(Block_context& ctx):
   tcFailRecord = 0;
   c_apiConTimer = 0;
   c_apiConTimer_line = 0;
+  c_ongoing_take_over_cnt = 0;
 
 #ifdef VM_TRACE
   {
@@ -300,8 +301,6 @@ Dbtc::Dbtc(Block_context& ctx):
 		    &cachePtr,
 		    &attrbufptr,
 		    &hostptr,
-		    &gcpPtr,
-		    &tmpApiConnectptr,
 		    &timeOutptr,
 		    &scanFragptr,
 		    &databufptr,

=== modified file 'storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2008-05-27 19:50:49 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2008-08-11 11:24:12 +0000
@@ -4402,22 +4402,21 @@ void Dbtc::commitGciHandling(Signal* sig
 
   UintR TgcpFilesize = cgcpFilesize;
   UintR Tfirstgcp = cfirstgcp;
-  ApiConnectRecord * const regApiPtr = apiConnectptr.p;
+  Ptr<ApiConnectRecord> regApiPtr = apiConnectptr;
   GcpRecord *localGcpRecord = gcpRecord;
 
-  regApiPtr->globalcheckpointid = Tgci;
+  regApiPtr.p->globalcheckpointid = Tgci;
   if (Tfirstgcp != RNIL) {
     /* IF THIS GLOBAL CHECKPOINT ALREADY EXISTS */
     localGcpPointer.i = Tfirstgcp;
     ptrCheckGuard(localGcpPointer, TgcpFilesize, localGcpRecord);
     do {
-      if (regApiPtr->globalcheckpointid == localGcpPointer.p->gcpId) {
+      if (regApiPtr.p->globalcheckpointid == localGcpPointer.p->gcpId) {
         jam();
-        gcpPtr.i = localGcpPointer.i;
-        gcpPtr.p = localGcpPointer.p;
-        linkApiToGcp(signal);
+        linkApiToGcp(localGcpPointer, regApiPtr);
         return;
       } else {
+        ndbrequire(regApiPtr.p->globalcheckpointid > localGcpPointer.p->gcpId);
         localGcpPointer.i = localGcpPointer.p->nextGcp;
         jam();
         if (localGcpPointer.i != RNIL) {
@@ -4426,14 +4425,14 @@ void Dbtc::commitGciHandling(Signal* sig
           continue;
         }//if
       }//if
-      seizeGcp(signal);
-      linkApiToGcp(signal);
+      seizeGcp(localGcpPointer, Tgci);
+      linkApiToGcp(localGcpPointer, regApiPtr);
       return;
     } while (1);
   } else {
     jam();
-    seizeGcp(signal);
-    linkApiToGcp(signal);
+    seizeGcp(localGcpPointer, Tgci);
+    linkApiToGcp(localGcpPointer, regApiPtr);
   }//if
 }//Dbtc::commitGciHandling()
 
@@ -4442,46 +4441,43 @@ void Dbtc::commitGciHandling(Signal* sig
 /* CHECKPOINTS. WHEN THE TRANSACTION I COMPLETED THE API CONNECT RECORD IS   */
 /* LINKED OUT OF THE LIST.                                                   */
 /*---------------------------------------------------------------------------*/
-void Dbtc::linkApiToGcp(Signal* signal) 
+void Dbtc::linkApiToGcp(Ptr<GcpRecord> regGcpPtr,
+                        Ptr<ApiConnectRecord> regApiPtr)
 {
   ApiConnectRecordPtr localApiConnectptr;
-  ApiConnectRecord * const regApiPtr = apiConnectptr.p;
-  GcpRecord * const regGcpPtr = gcpPtr.p;
-  UintR TapiConnectptrIndex = apiConnectptr.i;
   ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
 
-  regApiPtr->nextGcpConnect = RNIL;
-  if (regGcpPtr->firstApiConnect == RNIL) {
-    regGcpPtr->firstApiConnect = TapiConnectptrIndex;
+  regApiPtr.p->nextGcpConnect = RNIL;
+  if (regGcpPtr.p->firstApiConnect == RNIL) {
+    regGcpPtr.p->firstApiConnect = regApiPtr.i;
     jam();
   } else {
     UintR TapiConnectFilesize = capiConnectFilesize;
-    localApiConnectptr.i = regGcpPtr->lastApiConnect;
+    localApiConnectptr.i = regGcpPtr.p->lastApiConnect;
     jam();
     ptrCheckGuard(localApiConnectptr,
                   TapiConnectFilesize, localApiConnectRecord);
-    localApiConnectptr.p->nextGcpConnect = TapiConnectptrIndex;
+    localApiConnectptr.p->nextGcpConnect = regApiPtr.i;
   }//if
-  UintR TlastApiConnect = regGcpPtr->lastApiConnect;
-  regApiPtr->gcpPointer = gcpPtr.i;
-  regApiPtr->prevGcpConnect = TlastApiConnect;
-  regGcpPtr->lastApiConnect = TapiConnectptrIndex;
+  UintR TlastApiConnect = regGcpPtr.p->lastApiConnect;
+  regApiPtr.p->gcpPointer = regGcpPtr.i;
+  regApiPtr.p->prevGcpConnect = TlastApiConnect;
+  regGcpPtr.p->lastApiConnect = regApiPtr.i;
 }//Dbtc::linkApiToGcp()
 
-void Dbtc::seizeGcp(Signal* signal) 
+void Dbtc::seizeGcp(Ptr<GcpRecord> & dst, Uint64 Tgci)
 {
   GcpRecordPtr tmpGcpPointer;
   GcpRecordPtr localGcpPointer;
 
   UintR Tfirstgcp = cfirstgcp;
-  Uint64 Tglobalcheckpointid = apiConnectptr.p->globalcheckpointid;
   UintR TgcpFilesize = cgcpFilesize;
   GcpRecord *localGcpRecord = gcpRecord;
 
   localGcpPointer.i = cfirstfreeGcp;
   ptrCheckGuard(localGcpPointer, TgcpFilesize, localGcpRecord);
   UintR TfirstfreeGcp = localGcpPointer.p->nextGcp;
-  localGcpPointer.p->gcpId = Tglobalcheckpointid;
+  localGcpPointer.p->gcpId = Tgci;
   localGcpPointer.p->nextGcp = RNIL;
   localGcpPointer.p->firstApiConnect = RNIL;
   localGcpPointer.p->lastApiConnect = RNIL;
@@ -4498,7 +4494,7 @@ void Dbtc::seizeGcp(Signal* signal) 
     tmpGcpPointer.p->nextGcp = localGcpPointer.i;
   }//if
   clastgcp = localGcpPointer.i;
-  gcpPtr = localGcpPointer;
+  dst = localGcpPointer;
 }//Dbtc::seizeGcp()
 
 /*---------------------------------------------------------------------------*/
@@ -4626,6 +4622,7 @@ void Dbtc::execCOMMITTED(Signal* signal)
 {
   TcConnectRecordPtr localTcConnectptr;
   ApiConnectRecordPtr localApiConnectptr;
+  ApiConnectRecordPtr localCopyPtr;
 
   UintR TtcConnectFilesize = ctcConnectFilesize;
   UintR TapiConnectFilesize = capiConnectFilesize;
@@ -4701,14 +4698,14 @@ void Dbtc::execCOMMITTED(Signal* signal)
   /*-------------------------------------------------------*/
 
   apiConnectptr = localApiConnectptr;
-  sendApiCommit(signal);
+  localCopyPtr = sendApiCommit(signal);
 
-  ApiConnectRecord * const regApiPtr = apiConnectptr.p;
-  localTcConnectptr.i = regApiPtr->firstTcConnect;
-  UintR Tlqhkeyconfrec = regApiPtr->lqhkeyconfrec;
+  localTcConnectptr.i = localCopyPtr.p->firstTcConnect;
+  UintR Tlqhkeyconfrec = localCopyPtr.p->lqhkeyconfrec;
   ptrCheckGuard(localTcConnectptr, TtcConnectFilesize, localTcConnectRecord);
-  regApiPtr->counter = Tlqhkeyconfrec;
+  localCopyPtr.p->counter = Tlqhkeyconfrec;
 
+  apiConnectptr = localCopyPtr;
   tcConnectptr = localTcConnectptr;
   complete010Lab(signal);
   return;
@@ -4719,9 +4716,10 @@ void Dbtc::execCOMMITTED(Signal* signal)
 /*                       SEND_API_COMMIT                 */
 /*       SEND COMMIT DECISION TO THE API.                */
 /*-------------------------------------------------------*/
-void Dbtc::sendApiCommit(Signal* signal) 
+Ptr<Dbtc::ApiConnectRecord>
+Dbtc::sendApiCommit(Signal* signal)
 {
-  ApiConnectRecord * const regApiPtr = apiConnectptr.p;
+  ApiConnectRecordPtr regApiPtr = apiConnectptr;
 
   if (ERROR_INSERTED(8055))
   {
@@ -4732,16 +4730,19 @@ void Dbtc::sendApiCommit(Signal* signal)
      */
     signal->theData[0] = 9999;
     sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 1000, 1);
-
-    Uint32 node = refToNode(regApiPtr->ndbapiBlockref);
+    Uint32 node = refToNode(regApiPtr.p->ndbapiBlockref);
     signal->theData[0] = node;
     sendSignal(QMGR_REF, GSN_API_FAILREQ, signal, 1, JBB);
 
     SET_ERROR_INSERT_VALUE(8056);
-    return;
+
+    Ptr<ApiConnectRecord> copyPtr;
+    copyPtr.i = regApiPtr.p->apiCopyRecord;
+    ptrCheckGuard(copyPtr, capiConnectFilesize, apiConnectRecord);
+    return copyPtr;
   }
 
-  if (regApiPtr->returnsignal == RS_TCKEYCONF)
+  if (regApiPtr.p->returnsignal == RS_TCKEYCONF)
   {
     if (ERROR_INSERTED(8054))
     {
@@ -4750,49 +4751,57 @@ void Dbtc::sendApiCommit(Signal* signal)
       sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 5000, 1);
     }
     else
+    {
       sendtckeyconf(signal, 1);
-  } else if (regApiPtr->returnsignal == RS_TC_COMMITCONF) {
+    }
+  }
+  else if (regApiPtr.p->returnsignal == RS_TC_COMMITCONF) 
+  {
     jam();
     TcCommitConf * const commitConf = (TcCommitConf *)&signal->theData[0];
-    if(regApiPtr->commitAckMarker == RNIL){
+    if(regApiPtr.p->commitAckMarker == RNIL)
+    {
       jam();
-      commitConf->apiConnectPtr = regApiPtr->ndbapiConnect;
-    } else {
+      commitConf->apiConnectPtr = regApiPtr.p->ndbapiConnect;
+    } 
+    else 
+    {
       jam();
-      commitConf->apiConnectPtr = regApiPtr->ndbapiConnect | 1;
+      commitConf->apiConnectPtr = regApiPtr.p->ndbapiConnect | 1;
     }
-    commitConf->transId1 = regApiPtr->transid[0];
-    commitConf->transId2 = regApiPtr->transid[1];
-    commitConf->gci_hi = Uint32(regApiPtr->globalcheckpointid >> 32);
-    commitConf->gci_lo = Uint32(regApiPtr->globalcheckpointid);
+    commitConf->transId1 = regApiPtr.p->transid[0];
+    commitConf->transId2 = regApiPtr.p->transid[1];
+    commitConf->gci_hi = Uint32(regApiPtr.p->globalcheckpointid >> 32);
+    commitConf->gci_lo = Uint32(regApiPtr.p->globalcheckpointid);
 
-    sendSignal(regApiPtr->ndbapiBlockref, GSN_TC_COMMITCONF, signal,
+    sendSignal(regApiPtr.p->ndbapiBlockref, GSN_TC_COMMITCONF, signal,
 	       TcCommitConf::SignalLength, JBB);
-  } else if (regApiPtr->returnsignal == RS_NO_RETURN) {
+  } 
+  else if (regApiPtr.p->returnsignal == RS_NO_RETURN) 
+  {
     jam();
-  } else {
+  } 
+  else 
+  {
     TCKEY_abort(signal, 37);
-    return;
+    return regApiPtr;
   }//if
+  Ptr<ApiConnectRecord> copyPtr;
   UintR TapiConnectFilesize = capiConnectFilesize;
   UintR TcommitCount = c_counters.ccommitCount;
-  UintR TapiIndex = apiConnectptr.i;
-  UintR TnewApiIndex = regApiPtr->apiCopyRecord;
-  UintR TapiFailState = regApiPtr->apiFailState;
+  copyPtr.i = regApiPtr.p->apiCopyRecord;
+  UintR TapiFailState = regApiPtr.p->apiFailState;
   ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
 
-  tmpApiConnectptr.p = apiConnectptr.p;
-  tmpApiConnectptr.i = TapiIndex;
   c_counters.ccommitCount = TcommitCount + 1;
-  apiConnectptr.i = TnewApiIndex;
-  ptrCheckGuard(apiConnectptr, TapiConnectFilesize, localApiConnectRecord);
-  copyApi(signal);
+  ptrCheckGuard(copyPtr, TapiConnectFilesize, localApiConnectRecord);
+  copyApi(copyPtr, regApiPtr);
   if (TapiFailState != ZTRUE) {
-    return;
+    return copyPtr;
   } else {
     jam();
-    handleApiFailState(signal, tmpApiConnectptr.i);
-    return;
+    handleApiFailState(signal, regApiPtr.i);
+    return copyPtr;
   }//if
 }//Dbtc::sendApiCommit()
 
@@ -4801,54 +4810,52 @@ void Dbtc::sendApiCommit(Signal* signal)
 /*   COPY API RECORD ALSO RESET THE OLD API RECORD SO THAT IT                */
 /*   IS PREPARED TO RECEIVE A NEW TRANSACTION.                               */
 /*===========================================================================*/
-void Dbtc::copyApi(Signal* signal) 
+void Dbtc::copyApi(ApiConnectRecordPtr copyPtr, ApiConnectRecordPtr regApiPtr)
 {
-  ApiConnectRecord * const regApiPtr = apiConnectptr.p;
-  ApiConnectRecord * const regTmpApiPtr = tmpApiConnectptr.p;
-
-  UintR TndbapiConnect = regTmpApiPtr->ndbapiConnect;
-  UintR TfirstTcConnect = regTmpApiPtr->firstTcConnect;
-  UintR Ttransid1 = regTmpApiPtr->transid[0];
-  UintR Ttransid2 = regTmpApiPtr->transid[1];
-  UintR Tlqhkeyconfrec = regTmpApiPtr->lqhkeyconfrec;
-  UintR TgcpPointer = regTmpApiPtr->gcpPointer;
+  UintR TndbapiConnect = regApiPtr.p->ndbapiConnect;
+  UintR TfirstTcConnect = regApiPtr.p->firstTcConnect;
+  UintR Ttransid1 = regApiPtr.p->transid[0];
+  UintR Ttransid2 = regApiPtr.p->transid[1];
+  UintR Tlqhkeyconfrec = regApiPtr.p->lqhkeyconfrec;
+  UintR TgcpPointer = regApiPtr.p->gcpPointer;
   UintR TgcpFilesize = cgcpFilesize;
-  UintR TcommitAckMarker = regTmpApiPtr->commitAckMarker;
-  NdbNodeBitmask Tnodes = regTmpApiPtr->m_transaction_nodes;
+  UintR TcommitAckMarker = regApiPtr.p->commitAckMarker;
+  NdbNodeBitmask Tnodes = regApiPtr.p->m_transaction_nodes;
   GcpRecord *localGcpRecord = gcpRecord;
 
-  regApiPtr->ndbapiBlockref = regTmpApiPtr->ndbapiBlockref;
-  regApiPtr->ndbapiConnect = TndbapiConnect;
-  regApiPtr->firstTcConnect = TfirstTcConnect;
-  regApiPtr->apiConnectstate = CS_COMPLETING;
-  regApiPtr->transid[0] = Ttransid1;
-  regApiPtr->transid[1] = Ttransid2;
-  regApiPtr->lqhkeyconfrec = Tlqhkeyconfrec;
-  regApiPtr->commitAckMarker = TcommitAckMarker;
-  regApiPtr->m_transaction_nodes = Tnodes;
-  regApiPtr->singleUserMode = 0;
+  copyPtr.p->ndbapiBlockref = regApiPtr.p->ndbapiBlockref;
+  copyPtr.p->ndbapiConnect = TndbapiConnect;
+  copyPtr.p->firstTcConnect = TfirstTcConnect;
+  copyPtr.p->apiConnectstate = CS_COMPLETING;
+  copyPtr.p->transid[0] = Ttransid1;
+  copyPtr.p->transid[1] = Ttransid2;
+  copyPtr.p->lqhkeyconfrec = Tlqhkeyconfrec;
+  copyPtr.p->commitAckMarker = TcommitAckMarker;
+  copyPtr.p->m_transaction_nodes = Tnodes;
+  copyPtr.p->singleUserMode = 0;
 
+  Ptr<GcpRecord> gcpPtr;
   gcpPtr.i = TgcpPointer;
   ptrCheckGuard(gcpPtr, TgcpFilesize, localGcpRecord);
-  unlinkApiConnect(signal);
-  linkApiToGcp(signal);
-  setApiConTimer(tmpApiConnectptr.i, 0, __LINE__);
-  regTmpApiPtr->apiConnectstate = CS_CONNECTED;
-  regTmpApiPtr->commitAckMarker = RNIL;
-  regTmpApiPtr->firstTcConnect = RNIL;
-  regTmpApiPtr->lastTcConnect = RNIL;
-  regTmpApiPtr->m_transaction_nodes.clear();
-  regTmpApiPtr->singleUserMode = 0;
-  releaseAllSeizedIndexOperations(regTmpApiPtr);
+  unlinkApiConnect(gcpPtr, regApiPtr);
+  linkApiToGcp(gcpPtr, copyPtr);
+  setApiConTimer(regApiPtr.i, 0, __LINE__);
+  regApiPtr.p->apiConnectstate = CS_CONNECTED;
+  regApiPtr.p->commitAckMarker = RNIL;
+  regApiPtr.p->firstTcConnect = RNIL;
+  regApiPtr.p->lastTcConnect = RNIL;
+  regApiPtr.p->m_transaction_nodes.clear();
+  regApiPtr.p->singleUserMode = 0;
+  releaseAllSeizedIndexOperations(regApiPtr.p);
 }//Dbtc::copyApi()
 
-void Dbtc::unlinkApiConnect(Signal* signal) 
+void Dbtc::unlinkApiConnect(Ptr<GcpRecord> gcpPtr,
+                            Ptr<ApiConnectRecord> regApiPtr)
 {
   ApiConnectRecordPtr localApiConnectptr;
-  ApiConnectRecord * const regTmpApiPtr = tmpApiConnectptr.p;
   UintR TapiConnectFilesize = capiConnectFilesize;
-  UintR TprevGcpConnect = regTmpApiPtr->prevGcpConnect;
-  UintR TnextGcpConnect = regTmpApiPtr->nextGcpConnect;
+  UintR TprevGcpConnect = regApiPtr.p->prevGcpConnect;
+  UintR TnextGcpConnect = regApiPtr.p->nextGcpConnect;
   ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
 
   if (TprevGcpConnect == RNIL) {
@@ -5110,7 +5117,7 @@ void Dbtc::releaseTransResources(Signal*
     localTcConnectptr.i = rtrTcConnectptrIndex;
     releaseTcCon();
   } while (localTcConnectptr.i != RNIL);
-  handleGcp(signal);
+  handleGcp(signal, apiConnectptr);
   releaseFiredTriggerData(&apiConnectptr.p->theFiredTriggers);
   releaseAllSeizedIndexOperations(apiConnectptr.p);
   releaseApiConCopy(signal);
@@ -5123,27 +5130,24 @@ void Dbtc::releaseTransResources(Signal*
 /*       SENDS GCP_TCFINISHED WHEN ALL TRANSACTIONS BELONGING TO A CERTAIN */
 /*       GLOBAL CHECKPOINT HAVE COMPLETED.                                 */
 /* *********************************************************************>> */
-void Dbtc::handleGcp(Signal* signal) 
+void Dbtc::handleGcp(Signal* signal, Ptr<ApiConnectRecord> regApiPtr)
 {
   GcpRecord *localGcpRecord = gcpRecord;
   GcpRecordPtr localGcpPtr;
-  UintR TapiConnectptrIndex = apiConnectptr.i;
   UintR TgcpFilesize = cgcpFilesize;
   localGcpPtr.i = apiConnectptr.p->gcpPointer;
-  tmpApiConnectptr.i = TapiConnectptrIndex;
-  tmpApiConnectptr.p = apiConnectptr.p;
   ptrCheckGuard(localGcpPtr, TgcpFilesize, localGcpRecord);
-  gcpPtr.i = localGcpPtr.i;
-  gcpPtr.p = localGcpPtr.p;
-  unlinkApiConnect(signal);
+  unlinkApiConnect(localGcpPtr, regApiPtr);
   if (localGcpPtr.p->firstApiConnect == RNIL) {
     if (localGcpPtr.p->gcpNomoretransRec == ZTRUE) {
-      jam();
-      tcheckGcpId = localGcpPtr.p->gcpId;
-      gcpTcfinished(signal);
-      unlinkGcp(signal);
+      if (c_ongoing_take_over_cnt == 0)
+      {
+        jam();
+        gcpTcfinished(signal, localGcpPtr.p->gcpId);
+        unlinkGcp(localGcpPtr);
+      }
     }//if
-  }//if
+  }
 }//Dbtc::handleGcp()
 
 void Dbtc::releaseApiConCopy(Signal* signal) 
@@ -7119,35 +7123,136 @@ void Dbtc::execGCP_NOMORETRANS(Signal* s
   Uint32 gci_lo = req->gci_lo;
   Uint32 gci_hi = req->gci_hi;
   tcheckGcpId = gci_lo | (Uint64(gci_hi) << 32);
+
+  Ptr<GcpRecord> gcpPtr;
   if (cfirstgcp != RNIL) {
     jam();
                                       /* A GLOBAL CHECKPOINT IS GOING ON */
     gcpPtr.i = cfirstgcp;             /* SET POINTER TO FIRST GCP IN QUEUE*/
     ptrCheckGuard(gcpPtr, cgcpFilesize, gcpRecord);
-    if (gcpPtr.p->gcpId == tcheckGcpId) {
+    if (gcpPtr.p->gcpId == tcheckGcpId)
+    {
       jam();
-      if (gcpPtr.p->firstApiConnect != RNIL) {
+      bool empty = gcpPtr.p->firstApiConnect == RNIL;
+      bool nfhandling = c_ongoing_take_over_cnt;
+
+      if (empty && nfhandling)
+      {
+        jam();
+        ndbout_c("NOT returning gcpTcfinished due to nfhandling %u/%u",
+                 gci_hi, gci_lo);
+      }
+
+      if (!empty || c_ongoing_take_over_cnt)
+      {
         jam();
         gcpPtr.p->gcpNomoretransRec = ZTRUE;
       } else {
         jam();
-        gcpTcfinished(signal);
-        unlinkGcp(signal);
+        gcpTcfinished(signal, tcheckGcpId);
+        unlinkGcp(gcpPtr);
       }//if
-    } else {
+    }
+    else if (c_ongoing_take_over_cnt == 0)
+    {
       jam();
       /*------------------------------------------------------------*/
       /*       IF IT IS NOT THE FIRST THEN THERE SHOULD BE NO       */
       /*       RECORD FOR THIS GLOBAL CHECKPOINT. WE ALWAYS REMOVE  */
       /*       THE GLOBAL CHECKPOINTS IN ORDER.                     */
       /*------------------------------------------------------------*/
-      gcpTcfinished(signal);
-    }//if
-  } else {
+      gcpTcfinished(signal, tcheckGcpId);
+    }
+    else
+    {
+      jam();
+      goto outoforder;
+    }
+  }
+  else if (c_ongoing_take_over_cnt == 0)
+  {
     jam();
-    gcpTcfinished(signal);
-  }//if
+    gcpTcfinished(signal, tcheckGcpId);
+  }
+  else
+  {
+seize:
+    jam();
+    ndbout_c("execGCP_NOMORETRANS(%u/%u) c_ongoing_take_over_cnt -> seize",
+             gci_hi, gci_lo);
+    seizeGcp(gcpPtr, tcheckGcpId);
+    gcpPtr.p->gcpNomoretransRec = ZTRUE;
+  }
   return;
+  
+outoforder:
+  printf("ooo: execGCP_NOMORETRANS tcheckGcpId: %u/%u cfirstgcp: %u/%u",
+         gci_hi, gci_lo,
+         Uint32(gcpPtr.p->gcpId >> 32), Uint32(gcpPtr.p->gcpId));
+
+  if (tcheckGcpId < gcpPtr.p->gcpId)
+  {
+    jam();
+
+    Ptr<GcpRecord> tmp;
+    tmp.i = cfirstfreeGcp;
+    ptrCheckGuard(tmp, cgcpFilesize, gcpRecord);
+    cfirstfreeGcp = tmp.p->nextGcp;
+
+    tmp.p->gcpId = tcheckGcpId;
+    tmp.p->nextGcp = cfirstgcp;
+    tmp.p->firstApiConnect = RNIL;
+    tmp.p->lastApiConnect = RNIL;
+    tmp.p->gcpNomoretransRec = ZTRUE;
+    cfirstgcp = tmp.i;
+    ndbout_c("LINK FIRST");
+    return;
+  }
+  else
+  {
+    Ptr<GcpRecord> prev = gcpPtr;
+    while (tcheckGcpId > gcpPtr.p->gcpId)
+    {
+      jam();
+      if (gcpPtr.p->nextGcp == RNIL)
+      {
+        printf("nextGcp == RNIL -> ");
+        goto seize;
+      }
+
+      prev = gcpPtr;
+      gcpPtr.i = gcpPtr.p->nextGcp;
+      ptrCheckGuard(gcpPtr, cgcpFilesize, gcpRecord);
+    }
+
+    if (tcheckGcpId == gcpPtr.p->gcpId)
+    {
+      jam();
+      gcpPtr.p->gcpNomoretransRec = ZTRUE;
+      ndbout_c("found");
+      return;
+    }
+    ndbrequire(prev.i != gcpPtr.i); // checked earlier with initial "<"
+    ndbrequire(prev.p->gcpId < tcheckGcpId);
+    ndbrequire(gcpPtr.p->gcpId > tcheckGcpId);
+
+    Ptr<GcpRecord> tmp;
+    tmp.i = cfirstfreeGcp;
+    ptrCheckGuard(tmp, cgcpFilesize, gcpRecord);
+    cfirstfreeGcp = tmp.p->nextGcp;
+
+    tmp.p->gcpId = tcheckGcpId;
+    tmp.p->nextGcp = gcpPtr.i;
+    tmp.p->firstApiConnect = RNIL;
+    tmp.p->lastApiConnect = RNIL;
+    tmp.p->gcpNomoretransRec = ZTRUE;
+    prev.p->nextGcp = tmp.i;
+    ndbout_c("link middle %u/%u < %u/%u < %u/%u",
+             Uint32(prev.p->gcpId >> 32), Uint32(prev.p->gcpId),
+             gci_hi, gci_lo,
+             Uint32(gcpPtr.p->gcpId >> 32), Uint32(gcpPtr.p->gcpId));
+    return;
+  }
 }//Dbtc::execGCP_NOMORETRANS()
 
 /*****************************************************************************/
@@ -7205,6 +7310,7 @@ void Dbtc::execNODE_FAILREP(Signal* sign
     /*------------------------------------------------------------*/
     hostptr.p->hostStatus = HS_DEAD;
     hostptr.p->m_nf_bits = HostRecord::NF_NODE_FAIL_BITS;
+    c_ongoing_take_over_cnt++;
     c_alive_nodes.clear(hostptr.i);
 
     if (tcNodeFailptr.p->failStatus == FS_LISTENING) 
@@ -7408,8 +7514,31 @@ void Dbtc::execTAKE_OVERTCCONF(Signal* s
     tcNodeFailptr.p->queueList[i] = tcNodeFailptr.p->queueList[end-1];
     tcNodeFailptr.p->queueIndex = end - 1;
   }
-  
+
+  Uint32 cnt = c_ongoing_take_over_cnt;
+  ndbrequire(cnt);
+  c_ongoing_take_over_cnt = cnt - 1;
   checkNodeFailComplete(signal, hostptr.i, HostRecord::NF_TAKEOVER);
+
+  if (cnt == 1 && cfirstgcp != RNIL)
+  {
+    /**
+     * Check if there are any hanging GCP_NOMORETRANS
+     */
+    GcpRecordPtr tmpGcpPointer;
+    tmpGcpPointer.i = cfirstgcp;
+    ptrCheckGuard(tmpGcpPointer, cgcpFilesize, gcpRecord);
+    if (tmpGcpPointer.p->gcpNomoretransRec &&
+        tmpGcpPointer.p->firstApiConnect == RNIL)
+    {
+      jam();
+      ndbout_c("completing gcp %u/%u in execTAKE_OVERTCCONF",
+               Uint32(tmpGcpPointer.p->gcpId >> 32),
+               Uint32(tmpGcpPointer.p->gcpId));
+      gcpTcfinished(signal, tmpGcpPointer.p->gcpId);
+      unlinkGcp(tmpGcpPointer);
+    }
+  }
 }//Dbtc::execTAKE_OVERTCCONF()
 
 void Dbtc::execTAKE_OVERTCREQ(Signal* signal) 
@@ -7461,7 +7590,16 @@ void Dbtc::startTakeOverLab(Signal* sign
       signal->theData[0] = tcNodeFailptr.i;
       signal->theData[1] = cownref;
       signal->theData[2] = tfailedNodeId;
-      sendSignal(tblockref, GSN_LQH_TRANSREQ, signal, 3, JBB);
+      if (ERROR_INSERTED(8064) && hostptr.i == getOwnNodeId())
+      {
+        ndbout_c("sending delayed GSN_LQH_TRANSREQ to self");
+        sendSignalWithDelay(tblockref, GSN_LQH_TRANSREQ, signal, 100, 3);
+        CLEAR_ERROR_INSERT_VALUE;
+      }
+      else
+      {
+        sendSignal(tblockref, GSN_LQH_TRANSREQ, signal, 3, JBB);
+      }
     }//if
   }//for
 }//Dbtc::startTakeOverLab()
@@ -7715,6 +7853,7 @@ void Dbtc::completeTransAtTakeOverDoOne(
     apiConnectptr.p->currentTcConnect = tcConnectptr.i;
     apiConnectptr.p->currentReplicaNo = tcConnectptr.p->lastReplicaNo;
     tcurrentReplicaNo = tcConnectptr.p->lastReplicaNo;
+    commitGciHandling(signal, apiConnectptr.p->globalcheckpointid);
     toCompleteHandlingLab(signal);
     return;
   case CS_FAIL_COMMITTING:
@@ -7729,6 +7868,7 @@ void Dbtc::completeTransAtTakeOverDoOne(
     apiConnectptr.p->currentTcConnect = tcConnectptr.i;
     apiConnectptr.p->currentReplicaNo = tcConnectptr.p->lastReplicaNo;
     tcurrentReplicaNo = tcConnectptr.p->lastReplicaNo;
+    commitGciHandling(signal, apiConnectptr.p->globalcheckpointid);
     toCommitHandlingLab(signal);
     return;
   case CS_FAIL_ABORTING:
@@ -8189,7 +8329,7 @@ void Dbtc::toCommitHandlingLab(Signal* s
 	  sendTCKEY_FAILCONF(signal, apiConnectptr.p);
 	} else {
           jam();
-          sendApiCommit(signal);
+          apiConnectptr = sendApiCommit(signal);
         }//if
         apiConnectptr.p->currentTcConnect = apiConnectptr.p->firstTcConnect;
         tcConnectptr.i = apiConnectptr.p->firstTcConnect;
@@ -8325,6 +8465,7 @@ void Dbtc::toCompleteHandlingLab(Signal*
           signal->theData[1] = (UintR)apiConnectptr.p->takeOverRec;
           signal->theData[2] = apiConnectptr.p->takeOverInd;
           sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
+          handleGcp(signal, apiConnectptr);
           releaseTakeOver(signal);
         } else {
           jam();
@@ -10322,12 +10463,12 @@ void Dbtc::sendScanTabConf(Signal* signa
 }//Dbtc::sendScanTabConf()
 
 
-void Dbtc::gcpTcfinished(Signal* signal) 
+void Dbtc::gcpTcfinished(Signal* signal, Uint64 gci)
 {
   GCPTCFinished* conf = (GCPTCFinished*)signal->getDataPtrSend();
   conf->senderData = c_gcp_ref;
-  conf->gci_hi = Uint32(tcheckGcpId >> 32);
-  conf->gci_lo = Uint32(tcheckGcpId);
+  conf->gci_hi = Uint32(gci >> 32);
+  conf->gci_lo = Uint32(gci);
   sendSignal(cdihblockref, GSN_GCP_TCFINISHED, signal, 
              GCPTCFinished::SignalLength, JBB);
 }//Dbtc::gcpTcfinished()
@@ -10473,6 +10614,7 @@ void Dbtc::initdatabuf(Signal* signal) 
 
 void Dbtc::initgcp(Signal* signal) 
 {
+  Ptr<GcpRecord> gcpPtr;
   ndbrequire(cgcpFilesize > 0);
   for (gcpPtr.i = 0; gcpPtr.i < cgcpFilesize; gcpPtr.i++) {
     ptrAss(gcpPtr, gcpRecord);
@@ -10674,7 +10816,7 @@ void Dbtc::initialiseTcConnect(Signal* s
 /* ----     LINK A GLOBAL CHECKPOINT RECORD INTO THE LIST WITH TRANSACTIONS  */
 /*          WAITING FOR COMPLETION.                                          */
 /* ------------------------------------------------------------------------- */
-void Dbtc::linkGciInGcilist(Signal* signal) 
+void Dbtc::linkGciInGcilist(Ptr<GcpRecord> gcpPtr)
 {
   GcpRecordPtr tmpGcpPointer;
   if (cfirstgcp == RNIL) {
@@ -10847,13 +10989,6 @@ void Dbtc::releaseApiConnectFail(Signal*
   cfirstfreeApiConnectFail = apiConnectptr.i;
 }//Dbtc::releaseApiConnectFail()
 
-void Dbtc::releaseGcp(Signal* signal) 
-{
-  ptrGuard(gcpPtr);
-  gcpPtr.p->nextGcp = cfirstfreeGcp;
-  cfirstfreeGcp = gcpPtr.i;
-}//Dbtc::releaseGcp()
-
 void Dbtc::releaseKeys() 
 {
   UintR Tmp;
@@ -11046,25 +11181,18 @@ void Dbtc::sendSystemError(Signal* signa
 /* ========================================================================= */
 /* -------             LINK ACTUAL GCP OUT OF LIST                   ------- */
 /* ------------------------------------------------------------------------- */
-void Dbtc::unlinkGcp(Signal* signal) 
+void Dbtc::unlinkGcp(Ptr<GcpRecord> tmpGcpPtr)
 {
-  if (cfirstgcp == gcpPtr.i) {
-    jam();
-    cfirstgcp = gcpPtr.p->nextGcp;
-    if (gcpPtr.i == clastgcp) {
-      jam();
-      clastgcp = RNIL;
-    }//if
-  } else {
+  ndbrequire(cfirstgcp == tmpGcpPtr.i);
+
+  cfirstgcp = tmpGcpPtr.p->nextGcp;
+  if (tmpGcpPtr.i == clastgcp) {
     jam();
-    /* -------------------------------------------------------------------- 
-     * WE ARE TRYING TO REMOVE A GLOBAL CHECKPOINT WHICH WAS NOT THE OLDEST. 
-     * THIS IS A SYSTEM ERROR.                                              
-     * ------------------------------------------------------------------- */
-    sendSystemError(signal, __LINE__);
+    clastgcp = RNIL;
   }//if
-  gcpPtr.p->nextGcp = cfirstfreeGcp;
-  cfirstfreeGcp = gcpPtr.i;
+
+  tmpGcpPtr.p->nextGcp = cfirstfreeGcp;
+  cfirstfreeGcp = tmpGcpPtr.i;
 }//Dbtc::unlinkGcp()
 
 void

=== modified file 'storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp'
--- a/storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp	2008-04-25 09:18:49 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp	2008-08-11 11:24:12 +0000
@@ -382,10 +382,6 @@ private:
   void execREAD_CONFIG_CONF(Signal*);
 
   friend struct UpgradeStartup;
-
-#ifdef ERROR_INSERT
-  Uint32 c_error_insert_extra;
-#endif
 };
 
 #endif

=== modified file 'storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp'
--- a/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp	2008-04-25 09:17:15 +0000
+++ b/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp	2008-08-11 10:41:11 +0000
@@ -456,10 +456,6 @@ private:
   StopReq c_stopReq;
   bool check_multi_node_shutdown(Signal* signal);
 
-#ifdef ERROR_INSERT
-  Uint32 c_error_insert_extra;
-#endif
-
   void recompute_version_info(Uint32 type);
   void recompute_version_info(Uint32 type, Uint32 version);
   void execNODE_VERSION_REP(Signal* signal);

=== modified file 'storage/ndb/src/kernel/vm/SimulatedBlock.cpp'
--- a/storage/ndb/src/kernel/vm/SimulatedBlock.cpp	2008-04-22 20:09:38 +0000
+++ b/storage/ndb/src/kernel/vm/SimulatedBlock.cpp	2008-08-11 11:24:12 +0000
@@ -1147,7 +1147,14 @@ SimulatedBlock::execCHANGE_NODE_STATE_RE
 
 void
 SimulatedBlock::execNDB_TAMPER(Signal * signal){
-  SET_ERROR_INSERT_VALUE(signal->theData[0]);
+  if (signal->getLength() == 1)
+  {
+    SET_ERROR_INSERT_VALUE(signal->theData[0]);
+  }
+  else
+  {
+    SET_ERROR_INSERT_VALUE2(signal->theData[0], signal->theData[1]);
+  }
 }
 
 void

=== modified file 'storage/ndb/src/kernel/vm/pc.hpp'
--- a/storage/ndb/src/kernel/vm/pc.hpp	2008-02-04 13:36:54 +0000
+++ b/storage/ndb/src/kernel/vm/pc.hpp	2008-08-11 10:41:11 +0000
@@ -122,19 +122,23 @@
 
 // -------- ERROR INSERT MACROS -------
 #ifdef ERROR_INSERT
-#define ERROR_INSERT_VARIABLE UintR cerrorInsert
+#define ERROR_INSERT_VARIABLE UintR cerrorInsert, c_error_insert_extra
 #define ERROR_INSERTED(x) (cerrorInsert == (x))
 #define ERROR_INSERTED_CLEAR(x) (cerrorInsert == (x) ? (cerrorInsert = 0, true) : false)
 #define SET_ERROR_INSERT_VALUE(x) cerrorInsert = x
+#define SET_ERROR_INSERT_VALUE2(x,y) cerrorInsert = x; c_error_insert_extra = y
 #define CLEAR_ERROR_INSERT_VALUE cerrorInsert = 0
 #else
 #define ERROR_INSERT_VARIABLE typedef void * cerrorInsert // Will generate compiler error
if used
 #define ERROR_INSERTED(x) false
 #define ERROR_INSERTED_CLEAR(x) false
 #define SET_ERROR_INSERT_VALUE(x)
+#define SET_ERROR_INSERT_VALUE2(x,y)
 #define CLEAR_ERROR_INSERT_VALUE
 #endif
 
+#define DECLARE_DUMP0(BLOCK, CODE, DESC) if (arg == CODE)
+
 /* ------------------------------------------------------------------------- */
 /*       COMMONLY USED CONSTANTS.                                            */
 /* ------------------------------------------------------------------------- */

=== modified file 'storage/ndb/test/ndbapi/test_event.cpp'
--- a/storage/ndb/test/ndbapi/test_event.cpp	2008-08-05 10:13:56 +0000
+++ b/storage/ndb/test/ndbapi/test_event.cpp	2008-08-11 11:24:12 +0000
@@ -22,6 +22,7 @@
 #include <NdbRestarter.hpp>
 #include <NdbRestarts.hpp>
 #include <signaldata/DumpStateOrd.hpp>
+#include <NdbEnv.h>
 
 #define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb()
 
@@ -858,6 +859,82 @@ end:
   DBUG_RETURN(result);
 }
 
+int runEventConsumer(NDBT_Context* ctx, NDBT_Step* step)
+{
+  DBUG_ENTER("runEventConsumer");
+  int result = NDBT_OK;
+  const NdbDictionary::Table * table= ctx->getTab();
+  HugoTransactions hugoTrans(* table);
+
+  char buf[1024];
+  sprintf(buf, "%s_EVENT", table->getName());
+  NdbEventOperation *pOp, *pCreate = 0;
+  pCreate = pOp = GETNDB(step)->createEventOperation(buf);
+  if ( pOp == NULL ) {
+    g_err << "Event operation creation failed on %s" << buf << endl;
+    DBUG_RETURN(NDBT_FAILED);
+  }
+  bool merge_events = ctx->getProperty("MergeEvents");
+  pOp->mergeEvents(merge_events);
+
+  int i;
+  int n_columns= table->getNoOfColumns();
+  NdbRecAttr* recAttr[1024];
+  NdbRecAttr* recAttrPre[1024];
+  for (i = 0; i < n_columns; i++) {
+    recAttr[i]    = pOp->getValue(table->getColumn(i)->getName());
+    recAttrPre[i] = pOp->getPreValue(table->getColumn(i)->getName());
+  }
+
+  if (pOp->execute()) { // This starts changes to "start flowing"
+    g_err << "execute operation execution failed: \n";
+    g_err << pOp->getNdbError().code << " "
+	  << pOp->getNdbError().message << endl;
+    result = NDBT_FAILED;
+    goto end;
+  }
+
+  ctx->setProperty("LastGCI_hi", ~(Uint32)0);
+  ctx->broadcast();
+
+  while(!ctx->isTestStopped())
+  {
+    int count= 0;
+    Ndb* ndb= GETNDB(step);
+
+    Uint64 last_gci = 0;
+    while(!ctx->isTestStopped())
+    {
+      Uint32 count = 0;
+      Uint64 curr_gci;
+      ndb->pollEvents(100, &curr_gci);
+      if (curr_gci != last_gci)
+      {
+        while ((pOp= ndb->nextEvent()) != 0)
+        {
+          count++;
+        }
+        last_gci = curr_gci;
+      }
+      ndbout_c("Consumed gci: %u/%u, %d events",
+               Uint32(last_gci >> 32), Uint32(last_gci), count);
+    }
+  }
+
+end:
+  if(pCreate)
+  {
+    if (GETNDB(step)->dropEventOperation(pCreate)) {
+      g_err << "dropEventOperation execution failed "
+	    << GETNDB(step)->getNdbError().code << " "
+	    << GETNDB(step)->getNdbError().message << endl;
+      result = NDBT_FAILED;
+    }
+  }
+  ctx->stopTest();
+  DBUG_RETURN(result);
+}
+
 int runEventListenerUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
 {
   
@@ -1745,6 +1822,17 @@ runSubscribeUnsubscribe(NDBT_Context* ct
   return NDBT_OK;
 }
 
+int
+runLoadTable(NDBT_Context* ctx, NDBT_Step* step)
+{
+  int records = ctx->getNumRecords();
+  HugoTransactions hugoTrans(*ctx->getTab());
+  if (hugoTrans.loadTable(GETNDB(step), records) != 0){
+    return NDBT_FAILED;
+  }
+  return NDBT_OK;
+}
+
 int 
 runScanUpdateUntilStopped(NDBT_Context* ctx, NDBT_Step* step){
   int records = ctx->getNumRecords();
@@ -3039,6 +3127,83 @@ runBug37672(NDBT_Context* ctx, NDBT_Step
 }
 
 
+int
+runBug30780(NDBT_Context* ctx, NDBT_Step* step)
+{
+  int result = NDBT_OK;
+
+  NdbRestarter res;
+
+  if (res.getNumDbNodes() < 2)
+  {
+    ctx->stopTest();
+    return NDBT_OK;
+  }
+
+  const int cases = 4;
+  int loops = ctx->getNumLoops();
+  if (loops <= cases)
+    loops = cases + 1;
+  for (int i = 0; i<loops; i++)
+  {
+    int master = res.getMasterNodeId();
+    int next = res.getNextMasterNodeId(master);
+
+    res.insertErrorInNode(next, 8064);
+    int val1[] = { 7213, 0 };
+    int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
+    if (res.dumpStateOneNode(master, val2, 2))
+      return NDBT_FAILED;
+
+    int c = i % cases;
+    {
+      char buf[100];
+      const char * off = NdbEnv_GetEnv("NDB_ERR", buf, sizeof(buf));
+      if (off)
+      {
+        c = atoi(off);
+      }
+    }
+    switch(c){
+    case 0:
+      ndbout_c("stopping %u", master);
+      res.restartOneDbNode(master,
+                           /** initial */ false,
+                           /** nostart */ true,
+                           /** abort   */ true);
+      break;
+    case 1:
+      ndbout_c("stopping %u, err 7213", master);
+      val1[0] = 7213;
+      val1[1] = master;
+      res.dumpStateOneNode(next, val1, 2);
+      break;
+    case 2:
+      ndbout_c("stopping %u, err 7214", master);
+      val1[0] = 7214;
+      val1[1] = master;
+      res.dumpStateOneNode(next, val1, 2);
+      break;
+    case 3:
+      ndbout_c("stopping %u, err 7007", master);
+      res.insertErrorInNode(master, 7007);
+      break;
+    }
+    ndbout_c("waiting for %u", master);
+    res.waitNodesNoStart(&master, 1);
+    ndbout_c("starting %u", master);
+    res.startNodes(&master, 1);
+    ndbout_c("waiting for cluster started");
+    if (res.waitClusterStarted())
+    {
+      return NDBT_FAILED;
+    }
+  }
+
+  ctx->stopTest();
+  return NDBT_OK;
+}
+
 NDBT_TESTSUITE(test_event);
 TESTCASE("BasicEventOperation", 
 	 "Verify that we can listen to Events"
@@ -3234,6 +3399,15 @@ TESTCASE("Bug37672", "NdbRecord option O
 {
   INITIALIZER(runBug37672);
 }
+TESTCASE("Bug30780", "")
+{
+  INITIALIZER(runCreateEvent);
+  INITIALIZER(runLoadTable);
+  STEP(runEventConsumer);
+  STEPS(runScanUpdateUntilStopped, 3);
+  STEP(runBug30780);
+  FINALIZER(runDropEvent);
+}
 NDBT_TESTSUITE_END(test_event);
 
 int main(int argc, const char** argv){

=== modified file 'storage/ndb/test/run-test/daily-basic-tests.txt'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt	2008-08-06 15:39:54 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt	2008-08-11 11:24:12 +0000
@@ -1177,3 +1177,9 @@ cmd: testScanFilter
 args: 
 
 #EOF 2008-07-09
+
+max-time: 600
+cmd: test_event
+args -r 5000 -n Bug30780 T1
+
+#EOF 2008-08-11

Thread
bzr push into mysql-5.1 branch (jonas:2659) Bug#30780jonas11 Aug