List:Commits« Previous MessageNext Message »
From:jonas Date:March 22 2006 2:24pm
Subject:bk commit into 5.0 tree (jonas:1.2089)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of jonas. When jonas does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2089 06/03/22 15:24:32 jonas@stripped +19 -0
  Merge perch.ndb.mysql.com:/home/jonas/src/41-work
  into  perch.ndb.mysql.com:/home/jonas/src/50-work

  ndb/tools/desc.cpp
    1.19 06/03/22 15:24:29 jonas@stripped +1 -0
    merge

  ndb/test/run-test/daily-basic-tests.txt
    1.35 06/03/22 15:24:29 jonas@stripped +2 -6
    merge

  ndb/test/ndbapi/testTimeout.cpp
    1.13 06/03/22 15:24:29 jonas@stripped +0 -5
    merge

  ndb/src/ndbapi/TransporterFacade.cpp
    1.42 06/03/22 15:24:29 jonas@stripped +0 -0
    merge

  ndb/src/ndbapi/Ndbif.cpp
    1.31 06/03/22 15:24:29 jonas@stripped +1 -2
    merge

  ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
    1.90 06/03/22 15:24:29 jonas@stripped +0 -2
    merge

  ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
    1.84 06/03/22 15:24:29 jonas@stripped +18 -17
    merge

  sql/ha_innodb.cc
    1.287 06/03/22 15:10:35 jonas@stripped +0 -0
    Auto merged

  ndb/test/src/NdbRestarter.cpp
    1.12 06/03/22 15:10:35 jonas@stripped +0 -0
    Auto merged

  ndb/test/run-test/Makefile.am
    1.23 06/03/22 15:10:35 jonas@stripped +0 -0
    Auto merged

  ndb/test/ndbapi/testNodeRestart.cpp
    1.18 06/03/22 15:10:35 jonas@stripped +0 -0
    Auto merged

  ndb/src/ndbapi/TransporterFacade.hpp
    1.25 06/03/22 15:10:35 jonas@stripped +0 -0
    Auto merged

  ndb/src/ndbapi/NdbTransaction.cpp
    1.47 06/03/22 15:10:35 jonas@stripped +0 -0
    Auto merged

  ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
    1.24 06/03/22 15:10:35 jonas@stripped +0 -0
    Auto merged

  ndb/src/ndbapi/NdbTransaction.cpp
    1.30.6.2 06/03/22 15:10:34 jonas@stripped +0 -0
    Merge rename: ndb/src/ndbapi/NdbConnection.cpp -> ndb/src/ndbapi/NdbTransaction.cpp

  ndb/src/kernel/blocks/dbtc/Dbtc.hpp
    1.33 06/03/22 15:10:34 jonas@stripped +0 -0
    Auto merged

  ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
    1.44 06/03/22 15:10:34 jonas@stripped +0 -0
    Auto merged

  ndb/src/kernel/blocks/dbdih/Dbdih.hpp
    1.10 06/03/22 15:10:34 jonas@stripped +0 -0
    Auto merged

  ndb/src/kernel/blocks/ERROR_codes.txt
    1.16 06/03/22 15:10:34 jonas@stripped +0 -0
    Auto merged

  mysql-test/lib/mtr_timer.pl
    1.7 06/03/22 15:10:34 jonas@stripped +0 -0
    Auto merged

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	jonas
# Host:	perch.ndb.mysql.com
# Root:	/home/jonas/src/50-work/RESYNC

--- 1.34/ndb/test/run-test/daily-basic-tests.txt	2005-12-13 11:54:40 +01:00
+++ 1.35/ndb/test/run-test/daily-basic-tests.txt	2006-03-22 15:24:29 +01:00
@@ -425,14 +425,26 @@
 cmd: testNodeRestart
 args: -n Bug15685 T1
 
+max-time: 500
+cmd: testNodeRestart
+args: -n Bug16772 T1
+
+max-time: 500
+cmd: testSystemRestart
+args: -n Bug18385 T1
+
+max-time: 500
+cmd: testNodeRestart
+args: -n Bug18414 T1
+
 # OLD FLEX
 max-time: 500
 cmd: flexBench
-args: -c 25 -t 10
+args: -c 25 -t 10 
 
 max-time: 500
 cmd: flexHammer
-args: -r 5 -t 32
+args: -r 5 -t 32 
 
 #
 # DICT TESTS

--- 1.6/mysql-test/lib/mtr_timer.pl	2005-09-02 02:08:41 +02:00
+++ 1.7/mysql-test/lib/mtr_timer.pl	2006-03-22 15:10:34 +01:00
@@ -78,6 +78,12 @@
     {
       # Child, redirect output and exec
       # FIXME do we need to redirect streams?
+
+      # Don't do the ^C cleanup in the timeout child processes!
+      # There is actually a race here, if we get ^C after fork(), but before
+      # clearing the signal handler.
+      $SIG{INT}= 'DEFAULT';
+
       $0= "mtr_timer(timers,$name,$duration)";
       sleep($duration);
       exit(0);

--- 1.15/ndb/src/kernel/blocks/ERROR_codes.txt	2005-12-21 16:32:32 +01:00
+++ 1.16/ndb/src/kernel/blocks/ERROR_codes.txt	2006-03-22 15:10:34 +01:00
@@ -228,6 +228,8 @@
 8045: (ABORTCONF only as part of take-over)
 Delay execution of ABORTCONF signal 2 seconds to generate time-out.
 
+8050: Send ZABORT_TIMEOUT_BREAK delayed
+
 ERROR CODES FOR TESTING TIME-OUT HANDLING IN DBTC
 -------------------------------------------------
 
@@ -304,6 +306,8 @@
 7130: Crash starting node after receiving START_MECONF
 7131: Crash when receiving START_COPYREQ in master node
 7132: Crash when receiving START_COPYCONF in starting node
+
+7170: Crash when receiving START_PERMREF (InitialStartRequired)
 
 DICT:
 6000  Crash during NR when receiving DICTSTARTREQ

--- 1.9/ndb/src/kernel/blocks/dbdih/Dbdih.hpp	2006-02-10 09:38:07 +01:00
+++ 1.10/ndb/src/kernel/blocks/dbdih/Dbdih.hpp	2006-03-22 15:10:34 +01:00
@@ -81,7 +81,6 @@
 #define ZWRONG_FAILURE_NUMBER_ERROR 302
 #define ZWRONG_START_NODE_ERROR 303
 #define ZNO_REPLICA_FOUND_ERROR 304
-#define ZNODE_ALREADY_STARTING_ERROR 305
 #define ZNODE_START_DISALLOWED_ERROR 309
 
 // --------------------------------------
@@ -1038,7 +1037,8 @@
   void prepareReplicas(FragmentstorePtr regFragptr);
   void removeNodeFromStored(Uint32 nodeId,
                             FragmentstorePtr regFragptr,
-                            ReplicaRecordPtr replicaPtr);
+                            ReplicaRecordPtr replicaPtr,
+			    bool temporary);
   void removeOldStoredReplica(FragmentstorePtr regFragptr,
                               ReplicaRecordPtr replicaPtr);
   void removeStoredReplica(FragmentstorePtr regFragptr,

--- 1.43/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2006-02-10 19:25:40 +01:00
+++ 1.44/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2006-03-22 15:10:34 +01:00
@@ -1428,6 +1428,33 @@
     return;
   }
   
+  NodeRecordPtr nodePtr;
+  Uint32 gci = SYSFILE->lastCompletedGCI[getOwnNodeId()];
+  for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) 
+  {
+    jam();
+    ptrAss(nodePtr, nodeRecord);
+    if (SYSFILE->lastCompletedGCI[nodePtr.i] > gci) 
+    {
+      jam();
+      /**
+       * Since we're starting(is master) and there 
+       *   there are other nodes with higher GCI...
+       *   there gci's must be invalidated...
+       *   and they _must_ do an initial start
+       *   indicate this by setting lastCompletedGCI = 0
+       */
+      SYSFILE->lastCompletedGCI[nodePtr.i] = 0;
+      ndbrequire(nodePtr.p->nodeStatus != NodeRecord::ALIVE);
+      warningEvent("Making filesystem for node %d unusable",
+		   nodePtr.i);
+    }
+  }
+  /**
+   * This set which GCI we will try to restart to
+   */
+  SYSFILE->newestRestorableGCI = gci;
+  
   ndbrequire(isMaster());
   copyGciLab(signal, CopyGCIReq::RESTART); // We have already read the file!
 }//Dbdih::ndbStartReqLab()
@@ -1563,7 +1590,7 @@
 {
   jamEntry();
   Uint32 errorCode = signal->theData[1];
-  if (errorCode == ZNODE_ALREADY_STARTING_ERROR) {
+  if (errorCode == StartPermRef::ZNODE_ALREADY_STARTING_ERROR) {
     jam();
     /*-----------------------------------------------------------------------*/
     // The master was busy adding another node. We will wait for a second and
@@ -1573,6 +1600,20 @@
     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 3000, 1);
     return;
   }//if
+
+  if (errorCode == StartPermRef::InitialStartRequired)
+  {
+    CRASH_INSERTION(7170);
+    char buf[255];
+    BaseString::snprintf(buf, sizeof(buf), 
+			 "Cluster requires this node to be started "
+			 " with --initial as partial start has been performed"
+			 " and this filesystem is unusable");
+    progError(__LINE__, 
+	      ERR_SR_RESTARTCONFLICT,
+	      buf);
+    ndbrequire(false);
+  }
   /*------------------------------------------------------------------------*/
   // Some node process in another node involving our node was still active. We
   // will recover from this by crashing here. 
@@ -1663,7 +1704,7 @@
       (c_nodeStartMaster.wait != ZFALSE)) {
     jam();
     signal->theData[0] = nodeId;
-    signal->theData[1] = ZNODE_ALREADY_STARTING_ERROR;
+    signal->theData[1] = StartPermRef::ZNODE_ALREADY_STARTING_ERROR;
     sendSignal(retRef, GSN_START_PERMREF, signal, 2, JBB);
     return;
   }//if
@@ -1673,6 +1714,16 @@
     ndbrequire(false);
   }//if
 
+  if (SYSFILE->lastCompletedGCI[nodeId] == 0 &&
+      typeStart != NodeState::ST_INITIAL_NODE_RESTART)
+  {
+    jam();
+    signal->theData[0] = nodeId;
+    signal->theData[1] = StartPermRef::InitialStartRequired;
+    sendSignal(retRef, GSN_START_PERMREF, signal, 2, JBB);
+    return;
+  }
+
   /*----------------------------------------------------------------------
    * WE START THE INCLUSION PROCEDURE 
    * ---------------------------------------------------------------------*/
@@ -3521,24 +3572,12 @@
 /* ------------------------------------------------------------------------- */
 void Dbdih::selectMasterCandidateAndSend(Signal* signal)
 {
-  Uint32 gci = 0;
-  Uint32 masterCandidateId = 0;
-  NodeRecordPtr nodePtr;
-  for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
-    jam();
-    ptrAss(nodePtr, nodeRecord);
-    if (SYSFILE->lastCompletedGCI[nodePtr.i] > gci) {
-      jam();
-      masterCandidateId = nodePtr.i;
-      gci = SYSFILE->lastCompletedGCI[nodePtr.i];
-    }//if
-  }//for
-  ndbrequire(masterCandidateId != 0);
   setNodeGroups();
-  signal->theData[0] = masterCandidateId;
-  signal->theData[1] = gci;
+  signal->theData[0] = getOwnNodeId();
+  signal->theData[1] = SYSFILE->lastCompletedGCI[getOwnNodeId()];
   sendSignal(cntrlblockref, GSN_DIH_RESTARTCONF, signal, 2, JBB);
-
+  
+  NodeRecordPtr nodePtr;
   Uint32 node_groups[MAX_NDB_NODES];
   memset(node_groups, 0, sizeof(node_groups));
   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
@@ -3556,10 +3595,10 @@
     if(count != 0 && count != cnoReplicas){
       char buf[255];
       BaseString::snprintf(buf, sizeof(buf), 
-	       "Illegal configuration change."
-	       " Initial start needs to be performed "
-	       " when changing no of replicas (%d != %d)", 
-	       node_groups[nodePtr.i], cnoReplicas);
+			   "Illegal configuration change."
+			   " Initial start needs to be performed "
+			   " when changing no of replicas (%d != %d)", 
+			   node_groups[nodePtr.i], cnoReplicas);
       progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
     }
   }
@@ -5220,6 +5259,7 @@
 
   //const Uint32 lcpId = SYSFILE->latestLCP_ID;
   const bool lcpOngoingFlag = (tabPtr.p->tabLcpStatus== TabRecord::TLS_ACTIVE);
+  const bool temporary = !tabPtr.p->storedTable;
   
   FragmentstorePtr fragPtr;
   for(Uint32 fragNo = 0; fragNo < tabPtr.p->totalfragments; fragNo++){
@@ -5240,7 +5280,7 @@
         jam();
 	found = true;
 	noOfRemovedReplicas++;
-	removeNodeFromStored(nodeId, fragPtr, replicaPtr);
+	removeNodeFromStored(nodeId, fragPtr, replicaPtr, temporary);
 	if(replicaPtr.p->lcpOngoingFlag){
 	  jam();
 	  /**
@@ -5950,9 +5990,6 @@
   signal->theData[0] = 7012;
   execDUMP_STATE_ORD(signal);
 
-  signal->theData[0] = 7015;
-  execDUMP_STATE_ORD(signal);
-
   c_lcpMasterTakeOverState.set(LMTOS_IDLE, __LINE__);
 
   checkLocalNodefailComplete(signal, failedNodePtr.i, NF_LCP_TAKE_OVER);
@@ -12164,9 +12201,18 @@
 /*---------------------------------------------------------------*/
 void Dbdih::removeNodeFromStored(Uint32 nodeId,
                                  FragmentstorePtr fragPtr,
-                                 ReplicaRecordPtr replicatePtr)
+                                 ReplicaRecordPtr replicatePtr,
+				 bool temporary)
 {
-  newCrashedReplica(nodeId, replicatePtr);
+  if (!temporary)
+  {
+    jam();
+    newCrashedReplica(nodeId, replicatePtr);
+  }
+  else
+  {
+    jam();
+  }
   removeStoredReplica(fragPtr, replicatePtr);
   linkOldStoredReplica(fragPtr, replicatePtr);
   ndbrequire(fragPtr.p->storedReplicas != RNIL);
@@ -13100,7 +13146,8 @@
 Dbdih::execDUMP_STATE_ORD(Signal* signal)
 {
   DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0];
-  if (dumpState->args[0] == DumpStateOrd::DihDumpNodeRestartInfo) {
+  Uint32 arg = dumpState->args[0];
+  if (arg == DumpStateOrd::DihDumpNodeRestartInfo) {
     infoEvent("c_nodeStartMaster.blockLcp = %d, c_nodeStartMaster.blockGcp = %d, c_nodeStartMaster.wait = %d",
 	      c_nodeStartMaster.blockLcp, c_nodeStartMaster.blockGcp, c_nodeStartMaster.wait);
     infoEvent("cstartGcpNow = %d, cgcpStatus = %d",
@@ -13110,7 +13157,7 @@
     infoEvent("cgcpOrderBlocked = %d, cgcpStartCounter = %d",
               cgcpOrderBlocked, cgcpStartCounter);
   }//if  
-  if (dumpState->args[0] == DumpStateOrd::DihDumpNodeStatusInfo) {
+  if (arg == DumpStateOrd::DihDumpNodeStatusInfo) {
     NodeRecordPtr localNodePtr;
     infoEvent("Printing nodeStatus of all nodes");
     for (localNodePtr.i = 1; localNodePtr.i < MAX_NDB_NODES; localNodePtr.i++) {
@@ -13122,7 +13169,7 @@
     }//for
   }//if
   
-  if (dumpState->args[0] == DumpStateOrd::DihPrintFragmentation){
+  if (arg == DumpStateOrd::DihPrintFragmentation){
     infoEvent("Printing fragmentation of all tables --");
     for(Uint32 i = 0; i<ctabFileSize; i++){
       TabRecordPtr tabPtr;
@@ -13297,7 +13344,7 @@
     }
   }
 
-  if(dumpState->args[0] == 7019 && signal->getLength() == 2)
+  if(arg == 7019 && signal->getLength() == 2)
   {
     char buf2[8+1];
     NodeRecordPtr nodePtr;
@@ -13315,7 +13362,7 @@
 	      nodePtr.p->m_nodefailSteps.getText(buf2));
   }
   
-  if(dumpState->args[0] == 7020 && signal->getLength() > 3)
+  if(arg == 7020 && signal->getLength() > 3)
   {
     Uint32 gsn= signal->theData[1];
     Uint32 block= signal->theData[2];
@@ -13339,7 +13386,7 @@
 			  gsn, getBlockName(block, "UNKNOWN"), length, buf);
   }
   
-  if(dumpState->args[0] == DumpStateOrd::DihDumpLCPState){
+  if(arg == DumpStateOrd::DihDumpLCPState){
     infoEvent("-- Node %d LCP STATE --", getOwnNodeId());
     infoEvent("lcpStatus = %d (update place = %d) ",
 	      c_lcpState.lcpStatus, c_lcpState.lcpStatusUpdatedPlace);
@@ -13355,7 +13402,7 @@
     infoEvent("-- Node %d LCP STATE --", getOwnNodeId());
   }
 
-  if(dumpState->args[0] == DumpStateOrd::DihDumpLCPMasterTakeOver){
+  if(arg == DumpStateOrd::DihDumpLCPMasterTakeOver){
     infoEvent("-- Node %d LCP MASTER TAKE OVER STATE --", getOwnNodeId());
     infoEvent
       ("c_lcpMasterTakeOverState.state = %d updatePlace = %d failedNodeId = %d",
@@ -13370,52 +13417,25 @@
     infoEvent("-- Node %d LCP MASTER TAKE OVER STATE --", getOwnNodeId());
   }
 
-  if (signal->theData[0] == 7015){
-    for(Uint32 i = 0; i<ctabFileSize; i++){
-      TabRecordPtr tabPtr;
-      tabPtr.i = i;
-      ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
-      
-      if(tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
-	continue;
-      
-      infoEvent
-	("Table %d: TabCopyStatus: %d TabUpdateStatus: %d TabLcpStatus: %d",
-	 tabPtr.i, 
-	 tabPtr.p->tabCopyStatus, 
-	 tabPtr.p->tabUpdateState,
-	 tabPtr.p->tabLcpStatus);
+  if (signal->theData[0] == 7015)
+  {
+    if (signal->getLength() == 1)
+    {
+      signal->theData[1] = 0;
+    }
 
-      FragmentstorePtr fragPtr;
-      for (Uint32 fid = 0; fid < tabPtr.p->totalfragments; fid++) {
-	jam();
-	getFragstore(tabPtr.p, fid, fragPtr);
-	
-	char buf[100], buf2[100];
-	BaseString::snprintf(buf, sizeof(buf), " Fragment %d: noLcpReplicas==%d ", 
-		 fid, fragPtr.p->noLcpReplicas);
-	
-	Uint32 num=0;
-	ReplicaRecordPtr replicaPtr;
-	replicaPtr.i = fragPtr.p->storedReplicas;
-	do {
-	  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
-	  BaseString::snprintf(buf2, sizeof(buf2), "%s %d(on %d)=%d(%s)",
-		   buf, num, 
-		   replicaPtr.p->procNode, 
-		   replicaPtr.p->lcpIdStarted,
-		   replicaPtr.p->lcpOngoingFlag ? "Ongoing" : "Idle");
-	  BaseString::snprintf(buf, sizeof(buf), "%s", buf2);
-	  
-	  num++;
-	  replicaPtr.i = replicaPtr.p->nextReplica;
-	} while (replicaPtr.i != RNIL);
-	infoEvent(buf);
-      }
+    Uint32 tableId = signal->theData[1];
+    if (tableId < ctabFileSize)
+    {
+      signal->theData[0] = 7021;
+      execDUMP_STATE_ORD(signal);
+      signal->theData[0] = 7015;
+      signal->theData[1] = tableId + 1;
+      sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 2, JBB);
     }
   }
 
-  if(dumpState->args[0] == DumpStateOrd::EnableUndoDelayDataWrite){
+  if(arg == DumpStateOrd::EnableUndoDelayDataWrite){
     ndbout << "Dbdih:: delay write of datapages for table = " 
 	   << dumpState->args[1]<< endl;
     // Send this dump to ACC and TUP
@@ -13445,7 +13465,7 @@
     return;
   }
   
-  if(dumpState->args[0] == 7098){
+  if(arg == 7098){
     if(signal->length() == 3){
       jam();
       infoEvent("startLcpRoundLoopLab(tabel=%d, fragment=%d)",
@@ -13458,9 +13478,72 @@
     }
   }
 
-  if(dumpState->args[0] == DumpStateOrd::DihStartLcpImmediately){
+  if(arg == DumpStateOrd::DihStartLcpImmediately){
     c_lcpState.ctimer += (1 << c_lcpState.clcpDelay);
     return;
+  }
+
+  if (arg == DumpStateOrd::DihSetTimeBetweenGcp)
+  {
+    if (signal->getLength() == 1)
+    {
+      const ndb_mgm_configuration_iterator * p = 
+	theConfiguration.getOwnConfigIterator();
+      ndbrequire(p != 0);
+      ndb_mgm_get_int_parameter(p, CFG_DB_GCP_INTERVAL, &cgcpDelay);
+    }
+    else
+    {
+      cgcpDelay = signal->theData[1];
+    }
+    ndbout_c("Setting time between gcp : %d", cgcpDelay);
+  }
+
+  if (arg == 7021 && signal->getLength() == 2)
+  {
+    TabRecordPtr tabPtr;
+    tabPtr.i = signal->theData[1];
+    if (tabPtr.i >= ctabFileSize)
+      return;
+
+    ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
+    
+    if(tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
+      return;
+    
+    infoEvent
+      ("Table %d: TabCopyStatus: %d TabUpdateStatus: %d TabLcpStatus: %d",
+       tabPtr.i, 
+       tabPtr.p->tabCopyStatus, 
+       tabPtr.p->tabUpdateState,
+       tabPtr.p->tabLcpStatus);
+    
+    FragmentstorePtr fragPtr;
+    for (Uint32 fid = 0; fid < tabPtr.p->totalfragments; fid++) {
+      jam();
+      getFragstore(tabPtr.p, fid, fragPtr);
+      
+      char buf[100], buf2[100];
+      BaseString::snprintf(buf, sizeof(buf), " Fragment %d: noLcpReplicas==%d ", 
+			   fid, fragPtr.p->noLcpReplicas);
+      
+      Uint32 num=0;
+      ReplicaRecordPtr replicaPtr;
+      replicaPtr.i = fragPtr.p->storedReplicas;
+      do {
+	ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
+	BaseString::snprintf(buf2, sizeof(buf2), "%s %d(on %d)=%d(%s)",
+			     buf, num, 
+			     replicaPtr.p->procNode, 
+			     replicaPtr.p->lcpIdStarted,
+			     replicaPtr.p->lcpOngoingFlag ? "Ongoing" : "Idle");
+	BaseString::snprintf(buf, sizeof(buf), "%s", buf2);
+	
+	num++;
+	replicaPtr.i = replicaPtr.p->nextReplica;
+      } while (replicaPtr.i != RNIL);
+      infoEvent(buf);
+    }
   }
 }//Dbdih::execDUMP_STATE_ORD()
 

--- 1.83/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2006-02-10 19:25:41 +01:00
+++ 1.84/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2006-03-22 15:24:29 +01:00
@@ -18569,6 +18569,173 @@
     c_error_insert_table_id = dumpState->args[1];
     SET_ERROR_INSERT_VALUE(5042);
   }
+
+  TcConnectionrec *regTcConnectionrec = tcConnectionrec;
+  Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
+  Uint32 arg = dumpState->args[0];
+  if(arg == 2306)
+  {
+    for(Uint32 i = 0; i<1024; i++)
+    {
+      TcConnectionrecPtr tcRec;
+      tcRec.i = ctransidHash[i];
+      while(tcRec.i != RNIL)
+      {
+	ptrCheckGuard(tcRec, ttcConnectrecFileSize, regTcConnectionrec);
+	ndbout << "TcConnectionrec " << tcRec.i;
+	signal->theData[0] = 2307;
+	signal->theData[1] = tcRec.i;
+	execDUMP_STATE_ORD(signal);
+	tcRec.i = tcRec.p->nextHashRec;
+      }
+    }
+  }
+
+  if(arg == 2307 || arg == 2308)
+  {
+    TcConnectionrecPtr tcRec;
+    tcRec.i = signal->theData[1];
+    ptrCheckGuard(tcRec, ttcConnectrecFileSize, regTcConnectionrec);
+    
+    ndbout << " transactionState = " << tcRec.p->transactionState<<endl;
+    ndbout << " operation = " << tcRec.p->operation<<endl;
+    ndbout << " tcNodeFailrec = " << tcRec.p->tcNodeFailrec
+	   << " seqNoReplica = " << tcRec.p->seqNoReplica
+	   << " simpleRead = " << tcRec.p->simpleRead
+	   << endl;
+    ndbout << " replicaType = " << tcRec.p->replicaType
+	   << " reclenAiLqhkey = " << tcRec.p->reclenAiLqhkey
+	   << " opExec = " << tcRec.p->opExec
+	   << endl;
+    ndbout << " opSimple = " << tcRec.p->opSimple
+	   << " nextSeqNoReplica = " << tcRec.p->nextSeqNoReplica
+	   << " lockType = " << tcRec.p->lockType
+	   << endl;
+    ndbout << " lastReplicaNo = " << tcRec.p->lastReplicaNo
+	   << " indTakeOver = " << tcRec.p->indTakeOver
+	   << " dirtyOp = " << tcRec.p->dirtyOp
+	   << endl;
+    ndbout << " activeCreat = " << tcRec.p->activeCreat
+	   << " tcBlockref = " << hex << tcRec.p->tcBlockref
+	   << " reqBlockref = " << hex << tcRec.p->reqBlockref
+	   << " primKeyLen = " << tcRec.p->primKeyLen
+	   << endl;
+    ndbout << " nextReplica = " << tcRec.p->nextReplica
+	   << " tcBlockref = " << hex << tcRec.p->tcBlockref
+	   << " reqBlockref = " << hex << tcRec.p->reqBlockref
+	   << " primKeyLen = " << tcRec.p->primKeyLen
+	   << endl;
+    ndbout << " logStopPageNo = " << tcRec.p->logStopPageNo
+	   << " logStartPageNo = " << tcRec.p->logStartPageNo
+	   << " logStartPageIndex = " << tcRec.p->logStartPageIndex
+	   << endl;
+    ndbout << " errorCode = " << tcRec.p->errorCode
+	   << " clientBlockref = " << hex << tcRec.p->clientBlockref
+	   << " applRef = " << hex << tcRec.p->applRef
+	   << " totSendlenAi = " << tcRec.p->totSendlenAi
+	   << endl;
+    ndbout << " totReclenAi = " << tcRec.p->totReclenAi
+	   << " tcScanRec = " << tcRec.p->tcScanRec
+	   << " tcScanInfo = " << tcRec.p->tcScanInfo
+	   << " tcOprec = " << hex << tcRec.p->tcOprec
+	   << endl;
+    ndbout << " tableref = " << tcRec.p->tableref
+	   << " simpleTcConnect = " << tcRec.p->simpleTcConnect
+	   << " storedProcId = " << tcRec.p->storedProcId
+	   << " schemaVersion = " << tcRec.p->schemaVersion
+	   << endl;
+    ndbout << " reqinfo = " << tcRec.p->reqinfo
+	   << " reqRef = " << tcRec.p->reqRef
+	   << " readlenAi = " << tcRec.p->readlenAi
+	   << " prevTc = " << tcRec.p->prevTc
+	   << endl;
+    ndbout << " prevLogTcrec = " << tcRec.p->prevLogTcrec
+	   << " prevHashRec = " << tcRec.p->prevHashRec
+	   << " nodeAfterNext0 = " << tcRec.p->nodeAfterNext[0]
+	   << " nodeAfterNext1 = " << tcRec.p->nodeAfterNext[1]
+	   << endl;
+    ndbout << " nextTcConnectrec = " << tcRec.p->nextTcConnectrec
+	   << " nextTc = " << tcRec.p->nextTc
+	   << " nextTcLogQueue = " << tcRec.p->nextTcLogQueue
+	   << " nextLogTcrec = " << tcRec.p->nextLogTcrec
+	   << endl;
+    ndbout << " nextHashRec = " << tcRec.p->nextHashRec
+	   << " logWriteState = " << tcRec.p->logWriteState
+	   << " logStartFileNo = " << tcRec.p->logStartFileNo
+	   << " listState = " << tcRec.p->listState
+	   << endl;
+    ndbout << " lastAttrinbuf = " << tcRec.p->lastAttrinbuf
+	   << " lastTupkeybuf = " << tcRec.p->lastTupkeybuf
+	   << " hashValue = " << tcRec.p->hashValue
+	   << endl;
+    ndbout << " gci = " << tcRec.p->gci
+	   << " fragmentptr = " << tcRec.p->fragmentptr
+	   << " fragmentid = " << tcRec.p->fragmentid
+	   << " firstTupkeybuf = " << tcRec.p->firstTupkeybuf
+	   << endl;
+    ndbout << " firstAttrinbuf = " << tcRec.p->firstAttrinbuf
+	   << " currTupAiLen = " << tcRec.p->currTupAiLen
+	   << " currReclenAi = " << tcRec.p->currReclenAi
+	   << endl;
+    ndbout << " tcTimer = " << tcRec.p->tcTimer
+	   << " clientConnectrec = " << tcRec.p->clientConnectrec
+	   << " applOprec = " << hex << tcRec.p->applOprec
+	   << " abortState = " << tcRec.p->abortState
+	   << endl;
+    ndbout << " transid0 = " << hex << tcRec.p->transid[0]
+	   << " transid1 = " << hex << tcRec.p->transid[1]
+	   << " tupkeyData0 = " << tcRec.p->tupkeyData[0]
+	   << " tupkeyData1 = " << tcRec.p->tupkeyData[1]
+	   << endl;
+    ndbout << " tupkeyData2 = " << tcRec.p->tupkeyData[2]
+	   << " tupkeyData3 = " << tcRec.p->tupkeyData[3]
+	   << endl;
+    switch (tcRec.p->transactionState) {
+	
+    case TcConnectionrec::SCAN_STATE_USED:
+      if (tcRec.p->tcScanRec < cscanrecFileSize){
+	ScanRecordPtr TscanPtr;
+	c_scanRecordPool.getPtr(TscanPtr, tcRec.p->tcScanRec);
+	ndbout << " scanState = " << TscanPtr.p->scanState << endl;
+	//TscanPtr.p->scanLocalref[2];
+	ndbout << " copyPtr="<<TscanPtr.p->copyPtr
+	       << " scanAccPtr="<<TscanPtr.p->scanAccPtr
+	       << " scanAiLength="<<TscanPtr.p->scanAiLength
+	       << endl;
+	ndbout << " m_curr_batch_size_rows="<<
+	  TscanPtr.p->m_curr_batch_size_rows
+	       << " m_max_batch_size_rows="<<
+	  TscanPtr.p->m_max_batch_size_rows
+	       << " scanErrorCounter="<<TscanPtr.p->scanErrorCounter
+	       << endl;
+	ndbout << " scanSchemaVersion="<<TscanPtr.p->scanSchemaVersion
+	       << "  scanStoredProcId="<<TscanPtr.p->scanStoredProcId
+	       << "  scanTcrec="<<TscanPtr.p->scanTcrec
+	       << endl;
+	ndbout << "  scanType="<<TscanPtr.p->scanType
+	       << "  scanApiBlockref="<<TscanPtr.p->scanApiBlockref
+	       << "  scanNodeId="<<TscanPtr.p->scanNodeId
+	       << "  scanCompletedStatus="<<TscanPtr.p->scanCompletedStatus
+	       << endl;
+	ndbout << "  scanFlag="<<TscanPtr.p->scanFlag
+	       << "  scanLockHold="<<TscanPtr.p->scanLockHold
+	       << "  scanLockMode="<<TscanPtr.p->scanLockMode
+	       << "  scanNumber="<<TscanPtr.p->scanNumber
+	       << endl;
+	ndbout << "  scanReleaseCounter="<<TscanPtr.p->scanReleaseCounter
+	       << "  scanTcWaiting="<<TscanPtr.p->scanTcWaiting
+	       << "  scanKeyinfoFlag="<<TscanPtr.p->scanKeyinfoFlag
+	       << endl;
+      } else{
+	ndbout << "No connected scan record found" << endl;
+      }
+      break;
+    default:
+      break;
+    }
+    ndbrequire(arg != 2308);
+  }
+  
 }//Dblqh::execDUMP_STATE_ORD()
 
 void Dblqh::execSET_VAR_REQ(Signal* signal) 

--- 1.32/ndb/src/kernel/blocks/dbtc/Dbtc.hpp	2005-12-14 10:57:06 +01:00
+++ 1.33/ndb/src/kernel/blocks/dbtc/Dbtc.hpp	2006-03-22 15:10:34 +01:00
@@ -213,14 +213,6 @@
     LTS_ACTIVE = 1
   };
 
-  enum TakeOverState {
-    TOS_NOT_DEFINED = 0,
-    TOS_IDLE = 1,
-    TOS_ACTIVE = 2,
-    TOS_COMPLETED = 3,
-    TOS_NODE_FAILED = 4
-  };
-
   enum FailState {
     FS_IDLE = 0,
     FS_LISTENING = 1,
@@ -638,6 +630,7 @@
     ConnectionState apiConnectstate;
     UintR transid[2];
     UintR firstTcConnect;
+    NdbNodeBitmask m_transaction_nodes; 
     
     //---------------------------------------------------
     // Second 16 byte cache line. Hot variables.
@@ -934,7 +927,6 @@
   struct HostRecord {
     HostState hostStatus;
     LqhTransState lqhTransStatus;
-    TakeOverState takeOverStatus;
     bool  inPackedList;
     UintR noOfPackedWordsLqh;
     UintR packedWordsLqh[26];
@@ -943,6 +935,17 @@
     UintR noOfWordsTCINDXCONF;
     UintR packedWordsTCINDXCONF[30];
     BlockReference hostLqhBlockRef;
+
+    enum NodeFailBits
+    {
+      NF_TAKEOVER          = 0x1,
+      NF_CHECK_SCAN        = 0x2,
+      NF_CHECK_TRANSACTION = 0x4,
+      NF_CHECK_DROP_TAB    = 0x8,
+      NF_NODE_FAIL_BITS    = 0xF // All bits...
+    };
+    Uint32 m_nf_bits;
+    NdbNodeBitmask m_lqh_trans_conf;
   }; /* p2c: size = 128 bytes */
   
   typedef Ptr<HostRecord> HostRecordPtr;
@@ -1589,7 +1592,7 @@
   void wrongSchemaVersionErrorLab(Signal* signal);
   void noFreeConnectionErrorLab(Signal* signal);
   void tckeyreq050Lab(Signal* signal);
-  void timeOutFoundLab(Signal* signal, UintR anAdd);
+  void timeOutFoundLab(Signal* signal, UintR anAdd, Uint32 errCode);
   void completeTransAtTakeOverLab(Signal* signal, UintR TtakeOverInd);
   void completeTransAtTakeOverDoLast(Signal* signal, UintR TtakeOverInd);
   void completeTransAtTakeOverDoOne(Signal* signal, UintR TtakeOverInd);
@@ -1611,6 +1614,9 @@
   void checkScanFragList(Signal*, Uint32 failedNodeId, ScanRecord * scanP, 
 			 LocalDLList<ScanFragRec>::Head&);
 
+  void nodeFailCheckTransactions(Signal*,Uint32 transPtrI,Uint32 failedNodeId);
+  void checkNodeFailComplete(Signal* signal, Uint32 failedNodeId, Uint32 bit);
+  
   // Initialisation
   void initData();
   void initRecords();
@@ -1637,6 +1643,7 @@
   HostRecord *hostRecord;
   HostRecordPtr hostptr;
   UintR chostFilesize;
+  NdbNodeBitmask c_alive_nodes;
 
   GcpRecord *gcpRecord;
   GcpRecordPtr gcpPtr;

--- 1.89/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2005-12-14 11:30:21 +01:00
+++ 1.90/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2006-03-22 15:24:29 +01:00
@@ -266,6 +266,10 @@
     jam();
     checkScanActiveInFailedLqh(signal, Tdata0, Tdata1);
     return;
+  case TcContinueB::ZNF_CHECK_TRANSACTIONS:
+    jam();
+    nodeFailCheckTransactions(signal, Tdata0, Tdata1);
+    return;
   case TcContinueB::CHECK_WAIT_DROP_TAB_FAILED_LQH:
     jam();
     checkWaitDropTabFailedLqh(signal, Tdata0, Tdata1);
@@ -303,8 +307,8 @@
   hostptr.i = signal->theData[1];
   ptrCheckGuard(hostptr, chostFilesize, hostRecord);
   hostptr.p->hostStatus = HS_ALIVE;
-  hostptr.p->takeOverStatus = TOS_IDLE;
   signal->theData[0] = cownref;
+  c_alive_nodes.set(hostptr.i);
   sendSignal(tblockref, GSN_INCL_NODECONF, signal, 1, JBB);
 }
 
@@ -503,6 +507,7 @@
      * Finished
      */
     jam();
+    checkNodeFailComplete(signal, nodeId, HostRecord::NF_CHECK_DROP_TAB);
     return;
   }
   
@@ -868,8 +873,6 @@
       hostptr.i = i;
       ptrCheckGuard(hostptr, chostFilesize, hostRecord);
 
-      hostptr.p->takeOverStatus = TOS_IDLE;
-      
       if (NodeBitmask::get(readNodes->inactiveNodes, i)) {
         jam();
         hostptr.p->hostStatus = HS_DEAD;
@@ -877,6 +880,7 @@
         jam();
         con_lineNodes++;
         hostptr.p->hostStatus = HS_ALIVE;
+	c_alive_nodes.set(i);
       }//if
     }//if
   }//for
@@ -2378,6 +2382,7 @@
   regApiPtr->commitAckMarker = RNIL;
   regApiPtr->buddyPtr = RNIL;
   regApiPtr->currSavePointId = 0;
+  regApiPtr->m_transaction_nodes.clear();
   // Trigger data
   releaseFiredTriggerData(&regApiPtr->theFiredTriggers),
   // Index data
@@ -2986,6 +2991,10 @@
   signal->theData[0] = TdihConnectptr;
   signal->theData[1] = Ttableref;
   signal->theData[2] = TdistrHashValue;
+  signal->theData[3] = 0;
+  signal->theData[4] = 0;
+  signal->theData[5] = 0;
+  signal->theData[6] = 0;
 
   /*-------------------------------------------------------------*/
   /* FOR EFFICIENCY REASONS WE AVOID THE SIGNAL SENDING HERE AND */
@@ -3165,6 +3174,7 @@
   TcConnectRecord * const regTcPtr = tcConnectptr.p;
   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
   CacheRecord * const regCachePtr = cachePtr.p;
+  UintR sig0, sig1, sig2, sig3, sig4, sig5, sig6;
 #ifdef ERROR_INSERT
   if (ERROR_INSERTED(8002)) {
     systemErrorLab(signal, __LINE__);
@@ -3202,6 +3212,9 @@
   LqhKeyReq::setScanTakeOverFlag(tslrAttrLen, regCachePtr->scanTakeOverInd);
 
   Tdata10 = 0;
+  sig0 = regCachePtr->opSimple;
+  sig1 = regTcPtr->operation;
+  bool simpleRead = (sig1 == ZREAD && sig0 == ZTRUE);
   LqhKeyReq::setKeyLen(Tdata10, regCachePtr->keylen);
   LqhKeyReq::setLastReplicaNo(Tdata10, regTcPtr->lastReplicaNo);
   LqhKeyReq::setLockType(Tdata10, regCachePtr->opLock);
@@ -3211,8 +3224,8 @@
   LqhKeyReq::setApplicationAddressFlag(Tdata10, 1);
   LqhKeyReq::setDirtyFlag(Tdata10, regTcPtr->dirtyOp);
   LqhKeyReq::setInterpretedFlag(Tdata10, regCachePtr->opExec);
-  LqhKeyReq::setSimpleFlag(Tdata10, regCachePtr->opSimple);
-  LqhKeyReq::setOperation(Tdata10, regTcPtr->operation);
+  LqhKeyReq::setSimpleFlag(Tdata10, sig0);
+  LqhKeyReq::setOperation(Tdata10, sig1);
   /* ----------------------------------------------------------------------- 
    * Sequential Number of first LQH = 0, bit 22-23                           
    * IF ATTRIBUTE INFORMATION IS SENT IN TCKEYREQ,
@@ -3225,18 +3238,16 @@
    * ----------------------------------------------------------------------- */
   //LqhKeyReq::setAPIVersion(Tdata10, regCachePtr->apiVersionNo);
   Uint32 commitAckMarker = regTcPtr->commitAckMarker;
+  const Uint32 noOfLqhs = regTcPtr->noOfNodes;
   if(commitAckMarker != RNIL){
     jam();
-    
     LqhKeyReq::setMarkerFlag(Tdata10, 1);
 
-    CommitAckMarker * tmp;
-    tmp = m_commitAckMarkerHash.getPtr(commitAckMarker);
+    CommitAckMarker * tmp = m_commitAckMarkerHash.getPtr(commitAckMarker);
     
     /**
      * Populate LQH array
      */
-    const Uint32 noOfLqhs = regTcPtr->noOfNodes;
     tmp->noOfLqhs = noOfLqhs;
     for(Uint32 i = 0; i<noOfLqhs; i++){
       tmp->lqhNodeId[i] = regTcPtr->tcNodedata[i];
@@ -3247,7 +3258,6 @@
   /* NO READ LENGTH SENT FROM TC. SEQUENTIAL NUMBER IS 1 AND IT    */
   /* IS SENT TO A PRIMARY NODE.                                    */
   /* ************************************************************> */
-  UintR sig0, sig1, sig2, sig3, sig4, sig5, sig6;
 
   LqhKeyReq * const lqhKeyReq = (LqhKeyReq *)signal->getDataPtrSend();
 
@@ -3271,6 +3281,14 @@
   sig5 = regTcPtr->clientData;
   sig6 = regCachePtr->scanInfo;
 
+  if (! simpleRead)
+  {
+    regApiPtr->m_transaction_nodes.set(regTcPtr->tcNodedata[0]);
+    regApiPtr->m_transaction_nodes.set(regTcPtr->tcNodedata[1]);
+    regApiPtr->m_transaction_nodes.set(regTcPtr->tcNodedata[2]);
+    regApiPtr->m_transaction_nodes.set(regTcPtr->tcNodedata[3]);  
+  }
+  
   lqhKeyReq->tableSchemaVersion = sig0;
   lqhKeyReq->fragmentData = sig1;
   lqhKeyReq->transId1 = sig2;
@@ -4655,6 +4673,7 @@
   UintR TgcpPointer = regTmpApiPtr->gcpPointer;
   UintR TgcpFilesize = cgcpFilesize;
   UintR TcommitAckMarker = regTmpApiPtr->commitAckMarker;
+  NdbNodeBitmask Tnodes = regTmpApiPtr->m_transaction_nodes;
   GcpRecord *localGcpRecord = gcpRecord;
 
   regApiPtr->ndbapiBlockref = regTmpApiPtr->ndbapiBlockref;
@@ -4665,6 +4684,7 @@
   regApiPtr->transid[1] = Ttransid2;
   regApiPtr->lqhkeyconfrec = Tlqhkeyconfrec;
   regApiPtr->commitAckMarker = TcommitAckMarker;
+  regApiPtr->m_transaction_nodes = Tnodes;
 
   gcpPtr.i = TgcpPointer;
   ptrCheckGuard(gcpPtr, TgcpFilesize, localGcpRecord);
@@ -4675,6 +4695,7 @@
   regTmpApiPtr->commitAckMarker = RNIL;
   regTmpApiPtr->firstTcConnect = RNIL;
   regTmpApiPtr->lastTcConnect = RNIL;
+  regTmpApiPtr->m_transaction_nodes.clear();
   releaseAllSeizedIndexOperations(regTmpApiPtr);
 }//Dbtc::copyApi()
 
@@ -4933,7 +4954,7 @@
   TcConnectRecordPtr localTcConnectptr;
   UintR TtcConnectFilesize = ctcConnectFilesize;
   TcConnectRecord *localTcConnectRecord = tcConnectRecord;
-
+  apiConnectptr.p->m_transaction_nodes.clear();
   localTcConnectptr.i = apiConnectptr.p->firstTcConnect;
   do {
     jam();
@@ -5338,7 +5359,8 @@
       break;
     case CS_ABORTING:
       jam();
-      errorCode = ZABORTINPROGRESS;
+      errorCode = regApiPtr->returncode ? 
+	regApiPtr->returncode : ZABORTINPROGRESS;
       break;
     case CS_START_SCAN:
       jam();
@@ -5877,9 +5899,9 @@
 
   if (transP->firstTcConnect == RNIL) {
     jam();
-    /*-----------------------------------------------------------------------*/
-    /*    WE HAVE NO PARTICIPANTS IN THE TRANSACTION.                        */
-    /*-----------------------------------------------------------------------*/
+    /*--------------------------------------------------------------------*/
+    /* WE HAVE NO PARTICIPANTS IN THE TRANSACTION.                        */
+    /*--------------------------------------------------------------------*/
     releaseAbortResources(signal);
     return;
   }//if
@@ -6156,10 +6178,12 @@
     if (api_timer != 0) {
       time_out_value= time_out_param + (api_con_ptr & mask_value);
       time_passed= tc_timer - api_timer;
-      if (time_passed > time_out_value) {
+      if (time_passed > time_out_value) 
+      {
         jam();
-        timeOutFoundLab(signal, api_con_ptr);
-        return;
+        timeOutFoundLab(signal, api_con_ptr, ZTIME_OUT_ERROR);
+	api_con_ptr++;
+	break;
       }
     }
   }
@@ -6179,10 +6203,8 @@
   return;
 }//Dbtc::timeOutLoopStartLab()
 
-void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr) 
+void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr, Uint32 errCode) 
 {
-  sendContinueTimeOutControl(signal, TapiConPtr + 1);
-  
   apiConnectptr.i = TapiConPtr;
   ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
   /*------------------------------------------------------------------*/
@@ -6195,7 +6217,8 @@
 	<< "Time-out in state = " << apiConnectptr.p->apiConnectstate
 	<< " apiConnectptr.i = " << apiConnectptr.i 
 	<< " - exec: " << apiConnectptr.p->m_exec_flag
-	<< " - place: " << c_apiConTimer_line[apiConnectptr.i]);
+	<< " - place: " << c_apiConTimer_line[apiConnectptr.i]
+	<< " code: " << errCode);
   switch (apiConnectptr.p->apiConnectstate) {
   case CS_STARTED:
     if(apiConnectptr.p->lqhkeyreqrec == apiConnectptr.p->lqhkeyconfrec){
@@ -6212,7 +6235,7 @@
       }//if
     }
     apiConnectptr.p->returnsignal = RS_TCROLLBACKREP;      
-    apiConnectptr.p->returncode = ZTIME_OUT_ERROR;
+    apiConnectptr.p->returncode = errCode;
     abort010Lab(signal);
     return;
   case CS_RECEIVING:
@@ -6225,7 +6248,7 @@
     /*       START ABORTING THE TRANSACTION. ALSO START CHECKING THE    */
     /*       REMAINING TRANSACTIONS.                                    */
     /*------------------------------------------------------------------*/
-    terrorCode = ZTIME_OUT_ERROR;
+    terrorCode = errCode;
     abortErrorLab(signal);
     return;
   case CS_COMMITTING:
@@ -6432,6 +6455,7 @@
     return;
   }
   
+  bool found = false;
   OperationState tmp[16];
   
   Uint32 TloopCount = 0;
@@ -6439,7 +6463,31 @@
     jam();
     if (tcConnectptr.i == RNIL) {
       jam();
-      if (Tcheck == 0) {
+
+#ifdef VM_TRACE
+      ndbout_c("found: %d Tcheck: %d apiConnectptr.p->counter: %d",
+	       found, Tcheck, apiConnectptr.p->counter);
+#endif
+      if (found || apiConnectptr.p->counter)
+      {
+	jam();
+	/**
+	 * We sent atleast one ABORT/ABORTED
+	 *   or ZABORT_TIMEOUT_BREAK is in job buffer
+	 *   wait for reception...
+	 */
+	return;
+      }
+      
+      if (Tcheck == 1)
+      {
+	jam();
+	releaseAbortResources(signal);
+	return;
+      }
+      
+      if (Tcheck == 0)
+      {
         jam();
 	/*------------------------------------------------------------------
 	 * All nodes had already reported ABORTED for all tcConnect records.
@@ -6448,9 +6496,11 @@
 	 *------------------------------------------------------------------*/
 	char buf[96]; buf[0] = 0;
 	char buf2[96];
-	BaseString::snprintf(buf, sizeof(buf), "TC %d: %d ops:",
-		 __LINE__, apiConnectptr.i);
-	for(Uint32 i = 0; i<TloopCount; i++){
+	BaseString::snprintf(buf, sizeof(buf), "TC %d: %d counter: %d ops:",
+			     __LINE__, apiConnectptr.i,
+			     apiConnectptr.p->counter);
+	for(Uint32 i = 0; i<TloopCount; i++)
+	{
 	  BaseString::snprintf(buf2, sizeof(buf2), "%s %d", buf, tmp[i]);
 	  BaseString::snprintf(buf, sizeof(buf), buf2);
 	}
@@ -6458,7 +6508,9 @@
 	ndbout_c(buf);
 	ndbrequire(false);
 	releaseAbortResources(signal);
+	return;
       }
+      
       return;
     }//if
     TloopCount++;
@@ -6473,7 +6525,16 @@
       signal->theData[0] = TcContinueB::ZABORT_TIMEOUT_BREAK;
       signal->theData[1] = tcConnectptr.i;
       signal->theData[2] = apiConnectptr.i;      
-      sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
+      if (ERROR_INSERTED(8050))
+      {
+	ndbout_c("sending ZABORT_TIMEOUT_BREAK delayed (%d %d)", 
+		 Tcheck, apiConnectptr.p->counter);
+	sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 2000, 3);
+      }
+      else
+      {
+	sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
+      }
       return;
     }//if
     ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
@@ -6496,7 +6557,7 @@
         jam();
         if (tcConnectptr.p->tcNodedata[Ti] != 0) {
           TloopCount += 31;
-          Tcheck = 1;
+	  found = true;
           hostptr.i = tcConnectptr.p->tcNodedata[Ti];
           ptrCheckGuard(hostptr, chostFilesize, hostRecord);
           if (hostptr.p->hostStatus == HS_ALIVE) {
@@ -6869,58 +6930,44 @@
   const Uint32 tnewMasterId = nodeFail->masterNodeId;
   
   arrGuard(tnoOfNodes, MAX_NDB_NODES);
+  Uint32 i;
   int index = 0;
-  for (unsigned i = 1; i< MAX_NDB_NODES; i++) {
-    if(NodeBitmask::get(nodeFail->theNodes, i)){
+  for (i = 1; i< MAX_NDB_NODES; i++) 
+  {
+    if(NodeBitmask::get(nodeFail->theNodes, i))
+    {
       cdata[index] = i;
       index++;
     }//if
   }//for
 
+  cmasterNodeId = tnewMasterId;
+  
   tcNodeFailptr.i = 0;
   ptrAss(tcNodeFailptr, tcFailRecord);
-  Uint32 tindex;
-  for (tindex = 0; tindex < tnoOfNodes; tindex++) {
+  for (i = 0; i < tnoOfNodes; i++) 
+  {
     jam();
-    hostptr.i = cdata[tindex];
+    hostptr.i = cdata[i];
     ptrCheckGuard(hostptr, chostFilesize, hostRecord);
+    
     /*------------------------------------------------------------*/
     /*       SET STATUS OF THE FAILED NODE TO DEAD SINCE IT HAS   */
     /*       FAILED.                                              */
     /*------------------------------------------------------------*/
     hostptr.p->hostStatus = HS_DEAD;
+    hostptr.p->m_nf_bits = HostRecord::NF_NODE_FAIL_BITS;
+    c_alive_nodes.clear(hostptr.i);
 
-    if (hostptr.p->takeOverStatus == TOS_COMPLETED) {
-      jam();
-      /*------------------------------------------------------------*/
-      /*       A VERY UNUSUAL SITUATION. THE TAKE OVER WAS COMPLETED*/
-      /*       EVEN BEFORE WE HEARD ABOUT THE NODE FAILURE REPORT.  */
-      /*       HOWEVER UNUSUAL THIS SITUATION IS POSSIBLE.          */
-      /*------------------------------------------------------------*/
-      /*       RELEASE THE CURRENTLY UNUSED LQH CONNECTIONS. THE    */
-      /*       REMAINING WILL BE RELEASED WHEN THE TRANSACTION THAT */
-      /*       USED THEM IS COMPLETED.                              */
-      /*------------------------------------------------------------*/
-      {
-	NFCompleteRep * const nfRep = (NFCompleteRep *)&signal->theData[0];
-	nfRep->blockNo      = DBTC;
-	nfRep->nodeId       = cownNodeid;
-	nfRep->failedNodeId = hostptr.i;
-      }
-      sendSignal(cdihblockref, GSN_NF_COMPLETEREP, signal, 
-		 NFCompleteRep::SignalLength, JBB);
-    } else {
-      ndbrequire(hostptr.p->takeOverStatus == TOS_IDLE);
-      hostptr.p->takeOverStatus = TOS_NODE_FAILED;
-    }//if
-    
-    if (tcNodeFailptr.p->failStatus == FS_LISTENING) {
+    if (tcNodeFailptr.p->failStatus == FS_LISTENING) 
+    {
       jam();
       /*------------------------------------------------------------*/
       /*       THE CURRENT TAKE OVER CAN BE AFFECTED BY THIS NODE   */
       /*       FAILURE.                                             */
       /*------------------------------------------------------------*/
-      if (hostptr.p->lqhTransStatus == LTS_ACTIVE) {
+      if (hostptr.p->lqhTransStatus == LTS_ACTIVE) 
+      {
 	jam();
 	/*------------------------------------------------------------*/
 	/*       WE WERE WAITING FOR THE FAILED NODE IN THE TAKE OVER */
@@ -6932,86 +6979,46 @@
       }//if
     }//if
     
-  }//for
-
-  const bool masterFailed = (cmasterNodeId != tnewMasterId);
-  cmasterNodeId = tnewMasterId;
-
-  if(getOwnNodeId() == cmasterNodeId && masterFailed){
-    /**
-     * Master has failed and I'm the new master
-     */
-    jam();
-    
-    for (hostptr.i = 1; hostptr.i < MAX_NDB_NODES; hostptr.i++) {
+    if (getOwnNodeId() != tnewMasterId)
+    {
       jam();
-      ptrAss(hostptr, hostRecord);
-      if (hostptr.p->hostStatus != HS_ALIVE) {
-	jam();
-	if (hostptr.p->takeOverStatus == TOS_COMPLETED) {
-	  jam();
-	  /*------------------------------------------------------------*/
-	  /*       SEND TAKE OVER CONFIRMATION TO ALL ALIVE NODES IF    */
-	  /*       TAKE OVER IS COMPLETED. THIS IS PERFORMED TO ENSURE  */
-	  /*       THAT ALL NODES AGREE ON THE IDLE STATE OF THE TAKE   */
-	  /*       OVER. THIS MIGHT BE MISSED IN AN ERROR SITUATION IF  */
-	  /*       MASTER FAILS AFTER SENDING CONFIRMATION TO NEW       */
-	  /*       MASTER BUT FAILING BEFORE SENDING TO ANOTHER NODE    */
-	  /*       WHICH WAS NOT MASTER. IF THIS NODE LATER BECOMES     */
-	  /*       MASTER IT MIGHT START A NEW TAKE OVER EVEN AFTER THE */
-	  /*       CRASHED NODE HAVE ALREADY RECOVERED.                 */
-	  /*------------------------------------------------------------*/
-	  for(tmpHostptr.i = 1; tmpHostptr.i < MAX_NDB_NODES;tmpHostptr.i++) {
-	    jam();
-	    ptrAss(tmpHostptr, hostRecord);
-	    if (tmpHostptr.p->hostStatus == HS_ALIVE) {
-	      jam();
-	      tblockref = calcTcBlockRef(tmpHostptr.i);
-	      signal->theData[0] = hostptr.i;
-	      sendSignal(tblockref, GSN_TAKE_OVERTCCONF, signal, 1, JBB);
-	    }//if
-	  }//for
-	}//if
-      }//if
-    }//for
-  }
-
-  if(getOwnNodeId() == cmasterNodeId){
-    jam();
-    for (hostptr.i = 1; hostptr.i < MAX_NDB_NODES; hostptr.i++) {
+      /**
+       * Only master does takeover currently
+       */
+      hostptr.p->m_nf_bits &= ~HostRecord::NF_TAKEOVER;
+    }
+    else
+    {
       jam();
-      ptrAss(hostptr, hostRecord);
-      if (hostptr.p->hostStatus != HS_ALIVE) {
-        jam();
-        if (hostptr.p->takeOverStatus == TOS_NODE_FAILED) {
-          jam();
-	  /*------------------------------------------------------------*/
-	  /*       CONCLUDE ALL ACTIVITIES THE FAILED TC DID CONTROL    */
-	  /*       SINCE WE ARE THE MASTER. THIS COULD HAVE BEEN STARTED*/
-	  /*       BY A PREVIOUS MASTER BUT HAVE NOT BEEN CONCLUDED YET.*/
-	  /*------------------------------------------------------------*/
-          hostptr.p->takeOverStatus = TOS_ACTIVE;
-          signal->theData[0] = hostptr.i;
-          sendSignal(cownref, GSN_TAKE_OVERTCREQ, signal, 1, JBB);
-        }//if
-      }//if
-    }//for
-  }//if
-  for (tindex = 0; tindex < tnoOfNodes; tindex++) {
-    jam();
-    hostptr.i = cdata[tindex];
-    ptrCheckGuard(hostptr, chostFilesize, hostRecord);
-    /*------------------------------------------------------------*/
-    /*       LOOP THROUGH AND ABORT ALL SCANS THAT WHERE          */
-    /*       CONTROLLED BY THIS TC AND ACTIVE IN THE FAILED       */
-    /*       NODE'S LQH                                           */
-    /*------------------------------------------------------------*/
+      signal->theData[0] = hostptr.i;
+      sendSignal(cownref, GSN_TAKE_OVERTCREQ, signal, 1, JBB);
+    }
+
     checkScanActiveInFailedLqh(signal, 0, hostptr.i);
     checkWaitDropTabFailedLqh(signal, hostptr.i, 0); // nodeid, tableid
-  }//for
-
+    nodeFailCheckTransactions(signal, 0, hostptr.i);
+  }
 }//Dbtc::execNODE_FAILREP()
 
+void
+Dbtc::checkNodeFailComplete(Signal* signal, 
+			    Uint32 failedNodeId,
+			    Uint32 bit)
+{
+  hostptr.i = failedNodeId;
+  ptrCheckGuard(hostptr, chostFilesize, hostRecord);
+  hostptr.p->m_nf_bits &= ~bit;
+  if (hostptr.p->m_nf_bits == 0)
+  {
+    NFCompleteRep * const nfRep = (NFCompleteRep *)&signal->theData[0];
+    nfRep->blockNo      = DBTC;
+    nfRep->nodeId       = cownNodeid;
+    nfRep->failedNodeId = hostptr.i;
+    sendSignal(cdihblockref, GSN_NF_COMPLETEREP, signal, 
+	       NFCompleteRep::SignalLength, JBB);
+  }
+}
+
 void Dbtc::checkScanActiveInFailedLqh(Signal* signal, 
 				      Uint32 scanPtrI, 
 				      Uint32 failedNodeId){
@@ -7053,8 +7060,44 @@
     sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
     return;
   }//for
+
+  checkNodeFailComplete(signal, failedNodeId, HostRecord::NF_CHECK_SCAN);
+}
+
+void
+Dbtc::nodeFailCheckTransactions(Signal* signal, 
+				Uint32 transPtrI, 
+				Uint32 failedNodeId)
+{
+  jam();
+  Ptr<ApiConnectRecord> transPtr;
+  for (transPtr.i = transPtrI; transPtr.i < capiConnectFilesize; transPtr.i++)
+  {
+    ptrCheckGuard(transPtr, capiConnectFilesize, apiConnectRecord); 
+    if (transPtr.p->m_transaction_nodes.get(failedNodeId))
+    {
+      jam();
+      // Force timeout regardless of state      
+      Uint32 save = c_appl_timeout_value;
+      c_appl_timeout_value = 1;
+      setApiConTimer(transPtr.i, 0, __LINE__);
+      timeOutFoundLab(signal, transPtr.i, ZNODEFAIL_BEFORE_COMMIT);
+      c_appl_timeout_value = save;
+    }
+    
+    // Send CONTINUEB to continue later
+    signal->theData[0] = TcContinueB::ZNF_CHECK_TRANSACTIONS;
+    signal->theData[1] = transPtr.i + 1; // Check next
+    signal->theData[2] = failedNodeId;
+    sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
+    return;
+  }
+
+  checkNodeFailComplete(signal, failedNodeId, 
+			HostRecord::NF_CHECK_TRANSACTION);
 }
 
+
 void
 Dbtc::checkScanFragList(Signal* signal,
 			Uint32 failedNodeId,
@@ -7070,54 +7113,14 @@
   tfailedNodeId = signal->theData[0];
   hostptr.i = tfailedNodeId;
   ptrCheckGuard(hostptr, chostFilesize, hostRecord);
-  switch (hostptr.p->takeOverStatus) {
-  case TOS_IDLE:
-    jam();
-    /*------------------------------------------------------------*/
-    /*       THIS MESSAGE ARRIVED EVEN BEFORE THE NODE_FAILREP    */
-    /*       MESSAGE. THIS IS POSSIBLE IN EXTREME SITUATIONS.     */
-    /*       WE SET THE STATE TO TAKE_OVER_COMPLETED AND WAIT     */
-    /*       FOR THE NODE_FAILREP MESSAGE.                        */
-    /*------------------------------------------------------------*/
-    hostptr.p->takeOverStatus = TOS_COMPLETED;
-    break;
-  case TOS_NODE_FAILED:
-  case TOS_ACTIVE:
-    jam();
-    /*------------------------------------------------------------*/
-    /*       WE ARE NOT MASTER AND THE TAKE OVER IS ACTIVE OR WE  */
-    /*       ARE MASTER AND THE TAKE OVER IS ACTIVE. IN BOTH      */
-    /*       WE SET THE STATE TO TAKE_OVER_COMPLETED.             */
-    /*------------------------------------------------------------*/
-    /*       RELEASE THE CURRENTLY UNUSED LQH CONNECTIONS. THE    */
-    /*       REMAINING WILL BE RELEASED WHEN THE TRANSACTION THAT */
-    /*       USED THEM IS COMPLETED.                              */
-    /*------------------------------------------------------------*/
-    hostptr.p->takeOverStatus = TOS_COMPLETED;
-    {
-      NFCompleteRep * const nfRep = (NFCompleteRep *)&signal->theData[0];
-      nfRep->blockNo      = DBTC;
-      nfRep->nodeId       = cownNodeid;
-      nfRep->failedNodeId = hostptr.i;
-    }
-    sendSignal(cdihblockref, GSN_NF_COMPLETEREP, signal, 
-               NFCompleteRep::SignalLength, JBB);
-    break;
-  case TOS_COMPLETED:
-    jam();
-    /*------------------------------------------------------------*/
-    /*       WE HAVE ALREADY RECEIVED THE CONF SIGNAL. IT IS MOST */
-    /*       LIKELY SENT FROM A NEW MASTER WHICH WASN'T SURE IF   */
-    /*       THIS NODE HEARD THE CONF SIGNAL FROM THE OLD MASTER. */
-    /*       WE SIMPLY IGNORE THE MESSAGE.                        */
-    /*------------------------------------------------------------*/
-    /*empty*/;
-    break;
-  default:
+
+  if (signal->getSendersBlockRef() != reference())
+  {
     jam();
-    systemErrorLab(signal, __LINE__);
     return;
-  }//switch
+  }
+  
+  checkNodeFailComplete(signal, hostptr.i, HostRecord::NF_TAKEOVER);
 }//Dbtc::execTAKE_OVERTCCONF()
 
 void Dbtc::execTAKE_OVERTCREQ(Signal* signal) 
@@ -7357,16 +7360,10 @@
     /*       TO REPORT THE COMPLETION OF THE TAKE OVER TO ALL     */
     /*       NODES THAT ARE ALIVE.                                */
     /*------------------------------------------------------------*/
-    for (hostptr.i = 1; hostptr.i < MAX_NDB_NODES; hostptr.i++) {
-      jam();
-      ptrAss(hostptr, hostRecord);
-      if (hostptr.p->hostStatus == HS_ALIVE) {
-        jam();
-        tblockref = calcTcBlockRef(hostptr.i);
-        signal->theData[0] = tcNodeFailptr.p->takeOverNode;
-        sendSignal(tblockref, GSN_TAKE_OVERTCCONF, signal, 1, JBB);
-      }//if
-    }//for
+    NodeReceiverGroup rg(DBTC, c_alive_nodes);
+    signal->theData[0] = tcNodeFailptr.p->takeOverNode;
+    sendSignal(rg, GSN_TAKE_OVERTCCONF, signal, 1, JBB);
+    
     if (tcNodeFailptr.p->queueIndex > 0) {
       jam();
       /*------------------------------------------------------------*/
@@ -8048,6 +8045,7 @@
   apiConnectptr.p->ndbapiBlockref = 0;
   apiConnectptr.p->ndbapiConnect = 0;
   apiConnectptr.p->buddyPtr = RNIL;
+  apiConnectptr.p->m_transaction_nodes.clear();
   setApiConTimer(apiConnectptr.i, 0, __LINE__);
   switch(ttransStatus){
   case LqhTransConf::Committed:
@@ -9875,6 +9873,7 @@
     apiConnectptr.p->executingIndexOp = RNIL;
     apiConnectptr.p->buddyPtr = RNIL;
     apiConnectptr.p->currSavePointId = 0;
+    apiConnectptr.p->m_transaction_nodes.clear();
   }//for
   apiConnectptr.i = tiacTmp - 1;
   ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
@@ -9902,6 +9901,7 @@
       apiConnectptr.p->executingIndexOp = RNIL;
       apiConnectptr.p->buddyPtr = RNIL;
       apiConnectptr.p->currSavePointId = 0;
+      apiConnectptr.p->m_transaction_nodes.clear();
     }//for
   apiConnectptr.i = (2 * tiacTmp) - 1;
   ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
@@ -9929,6 +9929,7 @@
     apiConnectptr.p->executingIndexOp = RNIL;
     apiConnectptr.p->buddyPtr = RNIL;
     apiConnectptr.p->currSavePointId = 0;
+    apiConnectptr.p->m_transaction_nodes.clear();
   }//for
   apiConnectptr.i = (3 * tiacTmp) - 1;
   ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
@@ -9989,13 +9990,13 @@
     ptrAss(hostptr, hostRecord);
     hostptr.p->hostStatus = HS_DEAD;
     hostptr.p->inPackedList = false;
-    hostptr.p->takeOverStatus = TOS_NOT_DEFINED;
     hostptr.p->lqhTransStatus = LTS_IDLE;
     hostptr.p->noOfWordsTCKEYCONF = 0;
     hostptr.p->noOfWordsTCINDXCONF = 0;
     hostptr.p->noOfPackedWordsLqh = 0;
     hostptr.p->hostLqhBlockRef = calcLqhBlockRef(hostptr.i);
   }//for
+  c_alive_nodes.clear();
 }//Dbtc::inithost()
 
 void Dbtc::initialiseRecordsLab(Signal* signal, UintR Tdata0, 
@@ -10248,6 +10249,7 @@
   }//while
   apiConnectptr.p->firstTcConnect = RNIL;
   apiConnectptr.p->lastTcConnect = RNIL;
+  apiConnectptr.p->m_transaction_nodes.clear();
 
   // MASV let state be CS_ABORTING until all 
   // signals in the "air" have been received. Reset to CS_CONNECTED
@@ -10321,6 +10323,7 @@
   cfirstfreeApiConnect = TlocalApiConnectptr.i;
   setApiConTimer(TlocalApiConnectptr.i, 0, __LINE__);
   TlocalApiConnectptr.p->apiConnectstate = CS_DISCONNECTED;
+  ndbassert(TlocalApiConnectptr.p->m_transaction_nodes.isclear());
   ndbassert(TlocalApiConnectptr.p->apiScanRec == RNIL);
   TlocalApiConnectptr.p->ndbapiBlockref = 0;
 }//Dbtc::releaseApiCon()
@@ -10855,6 +10858,34 @@
     infoEvent("IndexOpCount: pool: %d free: %d", 
 	      c_theIndexOperationPool.getSize(),
 	      c_theIndexOperationPool.getNoOfFree());
+  }
+
+  if (dumpState->args[0] == 2514)
+  {
+    if (signal->getLength() == 2)
+    {
+      dumpState->args[0] = DumpStateOrd::TcDumpOneApiConnectRec;
+      execDUMP_STATE_ORD(signal);
+    }
+
+    NodeReceiverGroup rg(CMVMI, c_alive_nodes);
+    dumpState->args[0] = 15;
+    sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBB);
+
+    signal->theData[0] = 2515;
+    sendSignalWithDelay(cownref, GSN_DUMP_STATE_ORD, signal, 1000, 1);    
+    return;
+  }
+
+  if (dumpState->args[0] == 2515)
+  {
+    NdbNodeBitmask mask = c_alive_nodes;
+    mask.clear(getOwnNodeId());
+    NodeReceiverGroup rg(NDBCNTR, mask);
+    
+    sendSignal(rg, GSN_SYSTEM_ERROR, signal, 1, JBB);
+    sendSignalWithDelay(cownref, GSN_SYSTEM_ERROR, signal, 300, 1);    
+    return;
   }
 }//Dbtc::execDUMP_STATE_ORD()
 

--- 1.23/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp	2005-12-06 11:25:49 +01:00
+++ 1.24/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp	2006-03-22 15:10:35 +01:00
@@ -278,6 +278,7 @@
 
 void Qmgr::execCONNECT_REP(Signal* signal)
 {
+  jamEntry();
   const Uint32 nodeId = signal->theData[0];
   c_connectedNodes.set(nodeId);
   NodeRecPtr nodePtr;
@@ -285,9 +286,13 @@
   ptrCheckGuard(nodePtr, MAX_NODES, nodeRec);
   switch(nodePtr.p->phase){
   case ZSTARTING:
+  case ZRUNNING:
     jam();
+    if(!c_start.m_nodes.isWaitingFor(nodeId)){
+      jam();
+      return;
+    }
     break;
-  case ZRUNNING:
   case ZPREPARE_FAIL:
   case ZFAIL_CLOSING:
     jam();
@@ -298,21 +303,28 @@
   case ZAPI_INACTIVE:
     return;
   }
-
-  if(!c_start.m_nodes.isWaitingFor(nodeId)){
-    jam();
-    return;
-  }
-
+  
   switch(c_start.m_gsn){
   case GSN_CM_REGREQ:
     jam();
     sendCmRegReq(signal, nodeId);
     return;
-  case GSN_CM_NODEINFOREQ:{
+  case GSN_CM_NODEINFOREQ:
     jam();
     sendCmNodeInfoReq(signal, nodeId, nodePtr.p);
     return;
+  case GSN_CM_ADD:{
+    jam();
+
+    ndbrequire(getOwnNodeId() != cpresident);
+    c_start.m_nodes.clearWaitingFor(nodeId);
+    c_start.m_gsn = RNIL;
+    
+    NodeRecPtr addNodePtr;
+    addNodePtr.i = nodeId;
+    ptrCheckGuard(addNodePtr, MAX_NDB_NODES, nodeRec);
+    cmAddPrepare(signal, addNodePtr, nodePtr.p);
+    return;
   }
   default:
     return;
@@ -945,15 +957,27 @@
     return;
   case ZFAIL_CLOSING:
     jam();
-#ifdef VM_TRACE
-    ndbout_c("Enabling communication to CM_ADD node state=%d", 
-	     nodePtr.p->phase);
-#endif
+    
+#if 1
+    warningEvent("Recieved request to incorperate node %u, "
+		 "while error handling has not yet completed",
+		 nodePtr.i);
+    
+    ndbrequire(getOwnNodeId() != cpresident);
+    ndbrequire(signal->header.theVerId_signalNumber == GSN_CM_ADD);
+    c_start.m_nodes.clearWaitingFor();
+    c_start.m_nodes.setWaitingFor(nodePtr.i);
+    c_start.m_gsn = GSN_CM_ADD;
+#else
+    warningEvent("Enabling communication to CM_ADD node %u state=%d", 
+		 nodePtr.i,
+		 nodePtr.p->phase);
     nodePtr.p->phase = ZSTARTING;
     nodePtr.p->failState = NORMAL;
     signal->theData[0] = 0;
     signal->theData[1] = nodePtr.i;
     sendSignal(CMVMI_REF, GSN_OPEN_COMREQ, signal, 2, JBA);
+#endif
     return;
   case ZSTARTING:
     break;
@@ -1788,11 +1812,27 @@
 
   jamEntry();
   failedNodePtr.i = signal->theData[0];  
+
+  if (ERROR_INSERTED(930))
+  {
+    CLEAR_ERROR_INSERT_VALUE;
+    infoEvent("Discarding NDB_FAILCONF for %u", failedNodePtr.i);
+    return;
+  }
+  
   ptrCheckGuard(failedNodePtr, MAX_NODES, nodeRec);
   if (failedNodePtr.p->failState == WAITING_FOR_NDB_FAILCONF){
     failedNodePtr.p->failState = NORMAL;
   } else {
     jam();
+
+    char buf[100];
+    BaseString::snprintf(buf, 100, 
+			 "Received NDB_FAILCONF for node %u with state: %d %d",
+			 failedNodePtr.i,
+			 failedNodePtr.p->phase,
+			 failedNodePtr.p->failState);
+    progError(__LINE__, 0, buf);
     systemErrorLab(signal, __LINE__);
   }//if
   if (cpresident == getOwnNodeId()) {
@@ -2112,10 +2152,42 @@
   ptrCheckGuard(failedNodePtr, MAX_NODES, nodeRec);
   if (failedNodePtr.i == getOwnNodeId()) {
     jam();
-    systemErrorLab(signal, __LINE__);
+
+    const char * msg = 0;
+    switch(aFailCause){
+    case FailRep::ZOWN_FAILURE: 
+      msg = "Own failure"; 
+      break;
+    case FailRep::ZOTHER_NODE_WHEN_WE_START: 
+    case FailRep::ZOTHERNODE_FAILED_DURING_START:
+      msg = "Other node died during start"; 
+      break;
+    case FailRep::ZIN_PREP_FAIL_REQ:
+      msg = "Prep fail";
+      break;
+    case FailRep::ZSTART_IN_REGREQ:
+      msg = "Start timeout";
+      break;
+    case FailRep::ZHEARTBEAT_FAILURE:
+      msg = "Hearbeat failure";
+      break;
+    case FailRep::ZLINK_FAILURE:
+      msg = "Connection failure";
+      break;
+    }
+    
+    char buf[100];
+    BaseString::snprintf(buf, 100, 
+			 "We(%u) have been declared dead by %u reason: %s(%u)",
+			 getOwnNodeId(),
+			 refToNode(signal->getSendersBlockRef()),
+			 aFailCause,
+			 msg ? msg : "<Unknown>");
+
+    progError(__LINE__, 0, buf);
     return;
   }//if
-
+  
   myNodePtr.i = getOwnNodeId();
   ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec);
   if (myNodePtr.p->phase != ZRUNNING) {
@@ -2826,6 +2898,7 @@
         cfailureNr = cprepareFailureNr;
         ctoFailureNr = 0;
         ctoStatus = Q_ACTIVE;
+	c_start.reset(); // Don't take over nodes being started
         if (cnoCommitFailedNodes > 0) {
           jam();
 	  /**-----------------------------------------------------------------

--- 1.30.6.1/ndb/src/ndbapi/NdbConnection.cpp	2006-03-20 14:49:44 +01:00
+++ 1.47/ndb/src/ndbapi/NdbTransaction.cpp	2006-03-22 15:10:35 +01:00
@@ -16,7 +16,7 @@
 
 #include <ndb_global.h>
 #include <NdbOut.hpp>
-#include <NdbConnection.hpp>
+#include <NdbTransaction.hpp>
 #include <NdbOperation.hpp>
 #include <NdbScanOperation.hpp>
 #include <NdbIndexScanOperation.hpp>
@@ -25,7 +25,6 @@
 #include "TransporterFacade.hpp"
 #include "API.hpp"
 #include "NdbBlob.hpp"
-#include <ndb_limits.h>
 
 #include <signaldata/TcKeyConf.hpp>
 #include <signaldata/TcIndx.hpp>
@@ -34,13 +33,13 @@
 #include <signaldata/TcHbRep.hpp>
 
 /*****************************************************************************
-NdbConnection( Ndb* aNdb );
+NdbTransaction( Ndb* aNdb );
 
 Return Value:  None
 Parameters:    aNdb: Pointers to the Ndb object 
 Remark:        Creates a connection object. 
 *****************************************************************************/
-NdbConnection::NdbConnection( Ndb* aNdb ) :
+NdbTransaction::NdbTransaction( Ndb* aNdb ) :
   theSendStatus(NotInit),
   theCallbackFunction(NULL),
   theCallbackObject(NULL),
@@ -89,19 +88,19 @@
 
   CHECK_SZ(m_db_nodes, NdbNodeBitmask::Size);
   CHECK_SZ(m_failed_db_nodes, NdbNodeBitmask::Size);
-}//NdbConnection::NdbConnection()
+}//NdbTransaction::NdbTransaction()
 
 /*****************************************************************************
-~NdbConnection();
+~NdbTransaction();
 
 Remark:        Deletes the connection object. 
 *****************************************************************************/
-NdbConnection::~NdbConnection()
+NdbTransaction::~NdbTransaction()
 {
-  DBUG_ENTER("NdbConnection::~NdbConnection");
+  DBUG_ENTER("NdbTransaction::~NdbTransaction");
   theNdb->theImpl->theNdbObjectIdMap.unmap(theId, this);
   DBUG_VOID_RETURN;
-}//NdbConnection::~NdbConnection()
+}//NdbTransaction::~NdbTransaction()
 
 /*****************************************************************************
 void init();
@@ -109,7 +108,7 @@
 Remark:         Initialise connection object for new transaction. 
 *****************************************************************************/
 void	
-NdbConnection::init()
+NdbTransaction::init()
 {
   theListState            = NotInList;
   theInUseState           = true;
@@ -149,7 +148,7 @@
   //
   theBlobFlag = false;
   thePendingBlobOps = 0;
-}//NdbConnection::init()
+}//NdbTransaction::init()
 
 /*****************************************************************************
 setOperationErrorCode(int error);
@@ -158,9 +157,9 @@
                operation object. 
 *****************************************************************************/
 void
-NdbConnection::setOperationErrorCode(int error)
+NdbTransaction::setOperationErrorCode(int error)
 {
-  DBUG_ENTER("NdbConnection::setOperationErrorCode");
+  DBUG_ENTER("NdbTransaction::setOperationErrorCode");
   setErrorCode(error);
   DBUG_VOID_RETURN;
 }
@@ -172,9 +171,9 @@
                operation object. 
 *****************************************************************************/
 void
-NdbConnection::setOperationErrorCodeAbort(int error, int abortOption)
+NdbTransaction::setOperationErrorCodeAbort(int error, int abortOption)
 {
-  DBUG_ENTER("NdbConnection::setOperationErrorCodeAbort");
+  DBUG_ENTER("NdbTransaction::setOperationErrorCodeAbort");
   if (abortOption == -1)
     abortOption = m_abortOption;
   if (theTransactionIsStarted == false) {
@@ -194,20 +193,20 @@
 Remark:        Sets an error indication on the connection object. 
 *****************************************************************************/
 void
-NdbConnection::setErrorCode(int error)
+NdbTransaction::setErrorCode(int error)
 {
-  DBUG_ENTER("NdbConnection::setErrorCode");
+  DBUG_ENTER("NdbTransaction::setErrorCode");
   DBUG_PRINT("enter", ("error: %d, theError.code: %d", error, theError.code));
 
   if (theError.code == 0)
     theError.code = error;
 
   DBUG_VOID_RETURN;
-}//NdbConnection::setErrorCode()
+}//NdbTransaction::setErrorCode()
 
 int
-NdbConnection::restart(){
-  DBUG_ENTER("NdbConnection::restart");
+NdbTransaction::restart(){
+  DBUG_ENTER("NdbTransaction::restart");
   if(theCompletionStatus == CompletedSuccess){
     releaseCompletedOperations();
     Uint64 tTransid = theNdb->theFirstTransId;
@@ -232,23 +231,8 @@
 Remark:        Handle time-out on a transaction object. 
 *****************************************************************************/
 void
-NdbConnection::handleExecuteCompletion()
+NdbTransaction::handleExecuteCompletion()
 {
-  
-  if (theCompletionStatus == CompletedFailure) {
-    NdbOperation* tOpTemp = theFirstExecOpInList;
-    while (tOpTemp != NULL) {
-/*****************************************************************************
- *	Ensure that all executing operations report failed for each 
- *      read attribute when failure occurs. 
- *      We do not want any operations to report both failure and 
- *      success on different read attributes.
- ****************************************************************************/
-      tOpTemp->handleFailedAI_ElemLen();
-      tOpTemp = tOpTemp->next();
-    }//while
-    theReturnStatus = ReturnFailure;
-  }//if
   /***************************************************************************
    *	  Move the NdbOperation objects from the list of executing 
    *      operations to list of completed
@@ -265,7 +249,7 @@
   }//if
   theSendStatus = InitState;
   return;
-}//NdbConnection::handleExecuteCompletion()
+}//NdbTransaction::handleExecuteCompletion()
 
 /*****************************************************************************
 int execute(ExecType aTypeOfExec, CommitType aTypeOfCommit, int forceSend);
@@ -276,12 +260,12 @@
 Remark:        Initialise connection object for new transaction. 
 *****************************************************************************/
 int 
-NdbConnection::execute(ExecType aTypeOfExec, 
+NdbTransaction::execute(ExecType aTypeOfExec, 
 		       AbortOption abortOption,
 		       int forceSend)
 {
   NdbError savedError= theError;
-  DBUG_ENTER("NdbConnection::execute");
+  DBUG_ENTER("NdbTransaction::execute");
   DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d", 
 		       aTypeOfExec, abortOption));
 
@@ -432,11 +416,11 @@
 }
 
 int 
-NdbConnection::executeNoBlobs(ExecType aTypeOfExec, 
+NdbTransaction::executeNoBlobs(ExecType aTypeOfExec, 
                               AbortOption abortOption,
                               int forceSend)
 {
-  DBUG_ENTER("NdbConnection::executeNoBlobs");
+  DBUG_ENTER("NdbTransaction::executeNoBlobs");
   DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d", 
 		       aTypeOfExec, abortOption));
 
@@ -445,7 +429,7 @@
 // since last execute or since beginning. If this works ok we will continue
 // by calling the poll with wait method. This method will return when
 // the NDB kernel has completed its task or when 10 seconds have passed.
-// The NdbConnectionCallBack-method will receive the return code of the
+// The NdbTransactionCallBack-method will receive the return code of the
 // transaction. The normal methods of reading error codes still apply.
 //------------------------------------------------------------------------
   Ndb* tNdb = theNdb;
@@ -493,7 +477,7 @@
   }
   thePendingBlobOps = 0;
   DBUG_RETURN(0);
-}//NdbConnection::execute()
+}//NdbTransaction::execute()
 
 /*****************************************************************************
 void executeAsynchPrepare(ExecType           aTypeOfExec,
@@ -511,12 +495,12 @@
 Remark:        Prepare a part of a transaction in an asynchronous manner. 
 *****************************************************************************/
 void 
-NdbConnection::executeAsynchPrepare( ExecType           aTypeOfExec,
+NdbTransaction::executeAsynchPrepare( ExecType           aTypeOfExec,
                                      NdbAsynchCallback  aCallback,
                                      void*              anyObject,
                                      AbortOption abortOption)
 {
-  DBUG_ENTER("NdbConnection::executeAsynchPrepare");
+  DBUG_ENTER("NdbTransaction::executeAsynchPrepare");
   DBUG_PRINT("enter", ("aTypeOfExec: %d, aCallback: %x, anyObject: %x", 
 		       aTypeOfExec, aCallback, anyObject));
 
@@ -679,14 +663,14 @@
   NdbNodeBitmask::clear(m_db_nodes);
   NdbNodeBitmask::clear(m_failed_db_nodes);
   DBUG_VOID_RETURN;
-}//NdbConnection::executeAsynchPrepare()
+}//NdbTransaction::executeAsynchPrepare()
 
-void NdbConnection::close()
+void NdbTransaction::close()
 {
   theNdb->closeTransaction(this);
 }
 
-int NdbConnection::refresh(){
+int NdbTransaction::refresh(){
   return sendTC_HBREP();
 }
 
@@ -698,7 +682,7 @@
 Remark:        Order NDB to refresh the timeout counter of the transaction. 
 ******************************************************************************/
 int 	
-NdbConnection::sendTC_HBREP()		// Send a TC_HBREP signal;
+NdbTransaction::sendTC_HBREP()		// Send a TC_HBREP signal;
 {
   NdbApiSignal* tSignal;
   Ndb* tNdb = theNdb;
@@ -733,7 +717,7 @@
   }    
   
   return 0;
-}//NdbConnection::sendTC_HBREP()
+}//NdbTransaction::sendTC_HBREP()
 
 /*****************************************************************************
 int doSend();
@@ -745,9 +729,9 @@
                object from the prepared transactions array on the Ndb-object.
 *****************************************************************************/
 int
-NdbConnection::doSend()
+NdbTransaction::doSend()
 {
-  DBUG_ENTER("NdbConnection::doSend");
+  DBUG_ENTER("NdbTransaction::doSend");
 
   /*
   This method assumes that at least one operation have been defined. This
@@ -806,7 +790,7 @@
   theTransactionIsStarted = false;
   theCommitStatus = Aborted;
   DBUG_RETURN(-1);
-}//NdbConnection::doSend()
+}//NdbTransaction::doSend()
 
 /**************************************************************************
 int sendROLLBACK();
@@ -816,7 +800,7 @@
 Remark:        Order NDB to rollback the transaction. 
 **************************************************************************/
 int 	
-NdbConnection::sendROLLBACK()      // Send a TCROLLBACKREQ signal;
+NdbTransaction::sendROLLBACK()      // Send a TCROLLBACKREQ signal;
 {
   Ndb* tNdb = theNdb;
   if ((theTransactionIsStarted == true) &&
@@ -860,7 +844,7 @@
     return 0;
     ;
   }//if
-}//NdbConnection::sendROLLBACK()
+}//NdbTransaction::sendROLLBACK()
 
 /***************************************************************************
 int sendCOMMIT();
@@ -871,7 +855,7 @@
 Remark:        Order NDB to commit the transaction. 
 ***************************************************************************/
 int 	
-NdbConnection::sendCOMMIT()    // Send a TC_COMMITREQ signal;
+NdbTransaction::sendCOMMIT()    // Send a TC_COMMITREQ signal;
 {
   NdbApiSignal tSignal(theNdb->theMyRef);
   Uint32 tTransId1, tTransId2;
@@ -893,7 +877,7 @@
   } else {
     return -1;
   }//if
-}//NdbConnection::sendCOMMIT()
+}//NdbTransaction::sendCOMMIT()
 
 /******************************************************************************
 void release();
@@ -901,7 +885,7 @@
 Remark:         Release all operations.
 ******************************************************************************/
 void 
-NdbConnection::release(){
+NdbTransaction::release(){
   releaseOperations();
   if ( (theTransactionIsStarted == true) &&
        ((theCommitStatus != Committed) &&
@@ -920,10 +904,10 @@
     abort();
   }
 #endif
-}//NdbConnection::release()
+}//NdbTransaction::release()
 
 void
-NdbConnection::releaseOps(NdbOperation* tOp){
+NdbTransaction::releaseOps(NdbOperation* tOp){
   while (tOp != NULL) {
     NdbOperation* tmp = tOp;
     tOp->release();
@@ -938,7 +922,7 @@
 Remark:         Release all operations.
 ******************************************************************************/
 void 
-NdbConnection::releaseOperations()
+NdbTransaction::releaseOperations()
 {
   // Release any open scans
   releaseScanOperations(m_theFirstScanOperation);
@@ -958,15 +942,15 @@
   m_theFirstScanOperation = NULL;
   m_theLastScanOperation = NULL;
   m_firstExecutedScanOp = NULL;
-}//NdbConnection::releaseOperations()
+}//NdbTransaction::releaseOperations()
 
 void 
-NdbConnection::releaseCompletedOperations()
+NdbTransaction::releaseCompletedOperations()
 {
   releaseOps(theCompletedFirstOp);
   theCompletedFirstOp = NULL;
   theCompletedLastOp = NULL;
-}//NdbConnection::releaseOperations()
+}//NdbTransaction::releaseOperations()
 
 /******************************************************************************
 void releaseScanOperations();
@@ -975,7 +959,7 @@
                 (NdbScanOperation and NdbIndexOperation)
 ******************************************************************************/
 void 
-NdbConnection::releaseScanOperations(NdbIndexScanOperation* cursorOp)
+NdbTransaction::releaseScanOperations(NdbIndexScanOperation* cursorOp)
 {
   while(cursorOp != 0){
     NdbIndexScanOperation* next = (NdbIndexScanOperation*)cursorOp->next();
@@ -983,7 +967,7 @@
     theNdb->releaseScanOperation(cursorOp);
     cursorOp = next;
   }
-}//NdbConnection::releaseScanOperations()
+}//NdbTransaction::releaseScanOperations()
 
 /*****************************************************************************
 void releaseExecutedScanOperation();
@@ -991,9 +975,9 @@
 Remark:         Release scan op when hupp'ed trans closed (save memory)
 ******************************************************************************/
 void 
-NdbConnection::releaseExecutedScanOperation(NdbIndexScanOperation* cursorOp)
+NdbTransaction::releaseExecutedScanOperation(NdbIndexScanOperation* cursorOp)
 {
-  DBUG_ENTER("NdbConnection::releaseExecutedScanOperation");
+  DBUG_ENTER("NdbTransaction::releaseExecutedScanOperation");
   DBUG_PRINT("enter", ("this=0x%x op=0x%x", (UintPtr)this, (UintPtr)cursorOp))
 
   // here is one reason to make op lists doubly linked
@@ -1014,7 +998,7 @@
     }
   }
   DBUG_VOID_RETURN;
-}//NdbConnection::releaseExecutedScanOperation()
+}//NdbTransaction::releaseExecutedScanOperation()
 
 /*****************************************************************************
 NdbOperation* getNdbOperation(const char* aTableName);
@@ -1024,13 +1008,13 @@
                 Return NULL : In all other case. 	
 Parameters:     aTableName : Name of the database table. 	
 Remark:         Get an operation from NdbOperation idlelist and get the 
-                NdbConnection object 
+                NdbTransaction object 
 		who was fetch by startTransaction pointing to this  operation  
 		getOperation will set the theTableId in the NdbOperation object.
                 synchronous
 ******************************************************************************/
 NdbOperation*
-NdbConnection::getNdbOperation(const char* aTableName)
+NdbTransaction::getNdbOperation(const char* aTableName)
 {
   if (theCommitStatus == Started){
     NdbTableImpl* table = theNdb->theDictionary->getTable(aTableName);
@@ -1045,7 +1029,7 @@
   setOperationErrorCodeAbort(4114);
   
   return NULL;
-}//NdbConnection::getNdbOperation()
+}//NdbTransaction::getNdbOperation()
 
 /*****************************************************************************
 NdbOperation* getNdbOperation(int aTableId);
@@ -1055,13 +1039,13 @@
                 Return NULL: In all other case. 	
 Parameters:     tableId : Id of the database table beeing deleted.
 Remark:         Get an operation from NdbOperation object idlelist and 
-                get the NdbConnection object who was fetch by 
+                get the NdbTransaction object who was fetch by 
                 startTransaction pointing to this operation 
   	        getOperation will set the theTableId in the NdbOperation 
                 object, synchronous.
 *****************************************************************************/
 NdbOperation*
-NdbConnection::getNdbOperation(const NdbTableImpl * tab, NdbOperation* aNextOp)
+NdbTransaction::getNdbOperation(const NdbTableImpl * tab, NdbOperation* aNextOp)
 { 
   NdbOperation* tOp;
 
@@ -1105,15 +1089,15 @@
  getNdbOp_error1:
   setOperationErrorCodeAbort(4000);
   return NULL;
-}//NdbConnection::getNdbOperation()
+}//NdbTransaction::getNdbOperation()
 
-NdbOperation* NdbConnection::getNdbOperation(const NdbDictionary::Table * table)
+NdbOperation* NdbTransaction::getNdbOperation(const NdbDictionary::Table * table)
 {
   if (table)
     return getNdbOperation(& NdbTableImpl::getImpl(*table));
   else
     return NULL;
-}//NdbConnection::getNdbOperation()
+}//NdbTransaction::getNdbOperation()
 
 // NdbScanOperation
 /*****************************************************************************
@@ -1122,12 +1106,12 @@
 Return Value    Return a pointer to a NdbScanOperation object if getNdbScanOperation was succesful.
                 Return NULL : In all other case. 	
 Parameters:     aTableName : Name of the database table. 	
-Remark:         Get an operation from NdbScanOperation idlelist and get the NdbConnection object 
+Remark:         Get an operation from NdbScanOperation idlelist and get the NdbTransaction object 
 		who was fetch by startTransaction pointing to this  operation  
 		getOperation will set the theTableId in the NdbOperation object.synchronous
 ******************************************************************************/
 NdbScanOperation*
-NdbConnection::getNdbScanOperation(const char* aTableName)
+NdbTransaction::getNdbScanOperation(const char* aTableName)
 {
   if (theCommitStatus == Started){
     NdbTableImpl* tab = theNdb->theDictionary->getTable(aTableName);
@@ -1141,78 +1125,104 @@
   
   setOperationErrorCodeAbort(4114);
   return NULL;
-}//NdbConnection::getNdbScanOperation()
+}//NdbTransaction::getNdbScanOperation()
 
 /*****************************************************************************
-NdbScanOperation* getNdbScanOperation(const char* anIndexName, const char* aTableName);
+NdbScanOperation* getNdbIndexScanOperation(const char* anIndexName, const char* aTableName);
 
-Return Value    Return a pointer to a NdbScanOperation object if getNdbScanOperation was succesful.
+Return Value    Return a pointer to a NdbIndexScanOperation object if getNdbIndexScanOperation was succesful.
                 Return NULL : In all other case. 	
 Parameters:     anIndexName : Name of the index to use. 	
                 aTableName : Name of the database table. 	
-Remark:         Get an operation from NdbScanOperation idlelist and get the NdbConnection object 
+Remark:         Get an operation from NdbIndexScanOperation idlelist and get the NdbTransaction object 
 		who was fetch by startTransaction pointing to this  operation  
-		getOperation will set the theTableId in the NdbOperation object.synchronous
+		getOperation will set the theTableId in the NdbIndexScanOperation object.synchronous
 ******************************************************************************/
 NdbIndexScanOperation*
-NdbConnection::getNdbIndexScanOperation(const char* anIndexName, 
+NdbTransaction::getNdbIndexScanOperation(const char* anIndexName, 
 					const char* aTableName)
 {
   NdbIndexImpl* index = 
     theNdb->theDictionary->getIndex(anIndexName, aTableName);
+  if (index == 0)
+  {
+    setOperationErrorCodeAbort(theNdb->theDictionary->getNdbError().code);
+    return 0;
+  }
   NdbTableImpl* table = theNdb->theDictionary->getTable(aTableName);
+  if (table == 0)
+  {
+    setOperationErrorCodeAbort(theNdb->theDictionary->getNdbError().code);
+    return 0;
+  }
 
   return getNdbIndexScanOperation(index, table);
 }
 
 NdbIndexScanOperation*
-NdbConnection::getNdbIndexScanOperation(const NdbIndexImpl* index,
+NdbTransaction::getNdbIndexScanOperation(const NdbIndexImpl* index,
 					const NdbTableImpl* table)
 {
   if (theCommitStatus == Started){
     const NdbTableImpl * indexTable = index->getIndexTable();
     if (indexTable != 0){
-      NdbIndexScanOperation* tOp = 
-	getNdbScanOperation((NdbTableImpl *) indexTable);
+      NdbIndexScanOperation* tOp = getNdbScanOperation(indexTable);
       if(tOp)
       {
 	tOp->m_currentTable = table;
-	tOp->m_cursor_type = NdbScanOperation::IndexCursor;
       }
       return tOp;
     } else {
-      setOperationErrorCodeAbort(theNdb->theError.code);
+      setOperationErrorCodeAbort(4271);
       return NULL;
     }//if
   } 
   
   setOperationErrorCodeAbort(4114);
   return NULL;
-}//NdbConnection::getNdbIndexScanOperation()
+}//NdbTransaction::getNdbIndexScanOperation()
 
 NdbIndexScanOperation* 
-NdbConnection::getNdbIndexScanOperation(const NdbDictionary::Index * index,
+NdbTransaction::getNdbIndexScanOperation(const NdbDictionary::Index * index)
+{ 
+  if (index)
+  {
+    const NdbDictionary::Table *table=
+      theNdb->theDictionary->getTable(index->getTable());
+
+    if (table)
+      return getNdbIndexScanOperation(index, table);
+
+    setOperationErrorCodeAbort(theNdb->theDictionary->getNdbError().code);
+    return NULL;
+  }
+  setOperationErrorCodeAbort(4271);
+  return NULL;
+}
+
+NdbIndexScanOperation* 
+NdbTransaction::getNdbIndexScanOperation(const NdbDictionary::Index * index,
 					const NdbDictionary::Table * table)
 {
   if (index && table)
     return getNdbIndexScanOperation(& NdbIndexImpl::getImpl(*index),
 				    & NdbTableImpl::getImpl(*table));
-  else
-    return NULL;
-}//NdbConnection::getNdbIndexScanOperation()
+  setOperationErrorCodeAbort(4271);
+  return NULL;
+}//NdbTransaction::getNdbIndexScanOperation()
 
 /*****************************************************************************
 NdbScanOperation* getNdbScanOperation(int aTableId);
 
-Return Value    Return a pointer to a NdbOperation object if getNdbOperation was succesful.
+Return Value    Return a pointer to a NdbScanOperation object if getNdbScanOperation was succesful.
                 Return NULL: In all other case. 	
 Parameters:     tableId : Id of the database table beeing deleted.
-Remark:         Get an operation from NdbScanOperation object idlelist and get the NdbConnection 
+Remark:         Get an operation from NdbScanOperation object idlelist and get the NdbTransaction 
                 object who was fetch by startTransaction pointing to this  operation 
-  	        getOperation will set the theTableId in the NdbOperation object, synchronous.
+  	        getOperation will set the theTableId in the NdbScanOperation object, synchronous.
 *****************************************************************************/
 NdbIndexScanOperation*
-NdbConnection::getNdbScanOperation(const NdbTableImpl * tab)
+NdbTransaction::getNdbScanOperation(const NdbTableImpl * tab)
 { 
   NdbIndexScanOperation* tOp;
   
@@ -1231,10 +1241,10 @@
 getNdbOp_error1:
   setOperationErrorCodeAbort(4000);
   return NULL;
-}//NdbConnection::getNdbScanOperation()
+}//NdbTransaction::getNdbScanOperation()
 
 void
-NdbConnection::remove_list(NdbOperation*& list, NdbOperation* op){
+NdbTransaction::remove_list(NdbOperation*& list, NdbOperation* op){
   NdbOperation* tmp= list;
   if(tmp == op)
     list = op->next();
@@ -1247,7 +1257,7 @@
 }
 
 void
-NdbConnection::define_scan_op(NdbIndexScanOperation * tOp){
+NdbTransaction::define_scan_op(NdbIndexScanOperation * tOp){
   // Link scan operation into list of cursor operations
   if (m_theLastScanOperation == NULL)
     m_theFirstScanOperation = m_theLastScanOperation = tOp;
@@ -1259,13 +1269,13 @@
 }
 
 NdbScanOperation* 
-NdbConnection::getNdbScanOperation(const NdbDictionary::Table * table)
+NdbTransaction::getNdbScanOperation(const NdbDictionary::Table * table)
 {
   if (table)
     return getNdbScanOperation(& NdbTableImpl::getImpl(*table));
   else
     return NULL;
-}//NdbConnection::getNdbScanOperation()
+}//NdbTransaction::getNdbScanOperation()
 
 
 // IndexOperation
@@ -1273,21 +1283,39 @@
 NdbIndexOperation* getNdbIndexOperation(const char* anIndexName,
 					const char* aTableName);
 
-Return Value    Return a pointer to a NdbOperation object if getNdbScanOperation was succesful.
+Return Value    Return a pointer to a NdbOperation object if getNdbIndexOperation was succesful.
                 Return NULL : In all other case. 	
 Parameters:     aTableName : Name of the database table. 	
-Remark:         Get an operation from NdbScanOperation idlelist and get the NdbConnection object 
-		who was fetch by startTransaction pointing to this  operation  
-		getOperation will set the theTableId in the NdbScanOperation object.synchronous
+Remark:         Get an operation from NdbIndexOperation idlelist and get the NdbTransaction object 
+		who was fetch by startTransaction pointing to this operation  
+		getOperation will set the theTableId in the NdbIndexOperation object.synchronous
 ******************************************************************************/
 NdbIndexOperation*
-NdbConnection::getNdbIndexOperation(const char* anIndexName, 
+NdbTransaction::getNdbIndexOperation(const char* anIndexName, 
                                     const char* aTableName)
 {
   if (theCommitStatus == Started) {
     NdbTableImpl * table = theNdb->theDictionary->getTable(aTableName);
-    NdbIndexImpl * index = theNdb->theDictionary->getIndex(anIndexName,
-							   aTableName);
+    NdbIndexImpl * index;
+
+    if (table == 0)
+    {
+      setOperationErrorCodeAbort(theNdb->theDictionary->getNdbError().code);
+      return NULL;
+    }
+
+    if (table->m_frm.get_data())
+    {
+      // This unique index is defined from SQL level
+      static const char* uniqueSuffix= "$unique";
+      BaseString uniqueIndexName(anIndexName);
+      uniqueIndexName.append(uniqueSuffix);
+      index = theNdb->theDictionary->getIndex(uniqueIndexName.c_str(),
+					      aTableName);      
+    }
+    else
+      index = theNdb->theDictionary->getIndex(anIndexName,
+					      aTableName);
     if(table != 0 && index != 0){
       return getNdbIndexOperation(index, table);
     }
@@ -1297,14 +1325,13 @@
       return NULL;
     }
 
-    // table == 0
-    setOperationErrorCodeAbort(theNdb->theError.code);
+    setOperationErrorCodeAbort(4243);
     return NULL;
   } 
   
   setOperationErrorCodeAbort(4114);
   return 0;
-}//NdbConnection::getNdbIndexOperation()
+}//NdbTransaction::getNdbIndexOperation()
 
 /*****************************************************************************
 NdbIndexOperation* getNdbIndexOperation(int anIndexId, int aTableId);
@@ -1312,12 +1339,12 @@
 Return Value    Return a pointer to a NdbIndexOperation object if getNdbIndexOperation was succesful.
                 Return NULL: In all other case. 	
 Parameters:     tableId : Id of the database table beeing deleted.
-Remark:         Get an operation from NdbIndexOperation object idlelist and get the NdbConnection 
+Remark:         Get an operation from NdbIndexOperation object idlelist and get the NdbTransaction 
                 object who was fetch by startTransaction pointing to this  operation 
   	        getOperation will set the theTableId in the NdbIndexOperation object, synchronous.
 *****************************************************************************/
 NdbIndexOperation*
-NdbConnection::getNdbIndexOperation(const NdbIndexImpl * anIndex, 
+NdbTransaction::getNdbIndexOperation(const NdbIndexImpl * anIndex, 
 				    const NdbTableImpl * aTable,
                                     NdbOperation* aNextOp)
 { 
@@ -1358,18 +1385,37 @@
  getNdbOp_error1:
   setOperationErrorCodeAbort(4000);
   return NULL;
-}//NdbConnection::getNdbIndexOperation()
+}//NdbTransaction::getNdbIndexOperation()
+
+NdbIndexOperation* 
+NdbTransaction::getNdbIndexOperation(const NdbDictionary::Index * index)
+{ 
+  if (index)
+  {
+    const NdbDictionary::Table *table=
+      theNdb->theDictionary->getTable(index->getTable());
+
+    if (table)
+      return getNdbIndexOperation(index, table);
+
+    setOperationErrorCodeAbort(theNdb->theDictionary->getNdbError().code);
+    return NULL;
+  }
+  setOperationErrorCodeAbort(4271);
+  return NULL;
+}
 
 NdbIndexOperation* 
-NdbConnection::getNdbIndexOperation(const NdbDictionary::Index * index,
+NdbTransaction::getNdbIndexOperation(const NdbDictionary::Index * index,
 				    const NdbDictionary::Table * table)
 {
   if (index && table)
     return getNdbIndexOperation(& NdbIndexImpl::getImpl(*index),
 				& NdbTableImpl::getImpl(*table));
-  else
-    return NULL;
-}//NdbConnection::getNdbIndexOperation()
+  
+  setOperationErrorCodeAbort(4271);
+  return NULL;
+}//NdbTransaction::getNdbIndexOperation()
 
 
 /*******************************************************************************
@@ -1381,7 +1427,7 @@
 Remark:        Sets theRestartGCI in the NDB object. 
 *******************************************************************************/
 int			
-NdbConnection::receiveDIHNDBTAMPER(NdbApiSignal* aSignal)
+NdbTransaction::receiveDIHNDBTAMPER(NdbApiSignal* aSignal)
 {
   if (theStatus != Connecting) {
     return -1;
@@ -1390,7 +1436,7 @@
     theStatus = Connected;
   }//if
   return 0;  
-}//NdbConnection::receiveDIHNDBTAMPER()
+}//NdbTransaction::receiveDIHNDBTAMPER()
 
 /*******************************************************************************
 int  receiveTCSEIZECONF(NdbApiSignal* aSignal);
@@ -1401,7 +1447,7 @@
 Remark:        Sets TC Connect pointer at reception of TCSEIZECONF. 
 *******************************************************************************/
 int			
-NdbConnection::receiveTCSEIZECONF(NdbApiSignal* aSignal)
+NdbTransaction::receiveTCSEIZECONF(NdbApiSignal* aSignal)
 {
   if (theStatus != Connecting)
   {
@@ -1412,7 +1458,7 @@
     theStatus = Connected;
   }
   return 0;
-}//NdbConnection::receiveTCSEIZECONF()
+}//NdbTransaction::receiveTCSEIZECONF()
 
 /*******************************************************************************
 int  receiveTCSEIZEREF(NdbApiSignal* aSignal);
@@ -1423,18 +1469,22 @@
 Remark:        Sets TC Connect pointer. 
 *******************************************************************************/
 int			
-NdbConnection::receiveTCSEIZEREF(NdbApiSignal* aSignal)
+NdbTransaction::receiveTCSEIZEREF(NdbApiSignal* aSignal)
 {
+  DBUG_ENTER("NdbTransaction::receiveTCSEIZEREF");
   if (theStatus != Connecting)
   {
-    return -1;
+    DBUG_RETURN(-1);
   } else
   {
     theStatus = ConnectFailure;
     theNdb->theError.code = aSignal->readData(2);
-    return 0;
+    DBUG_PRINT("info",("error code %d, %s",
+		       theNdb->getNdbError().code,
+		       theNdb->getNdbError().message));
+    DBUG_RETURN(0);
   }
-}//NdbConnection::receiveTCSEIZEREF()
+}//NdbTransaction::receiveTCSEIZEREF()
 
 /*******************************************************************************
 int  receiveTCRELEASECONF(NdbApiSignal* aSignal);
@@ -1445,7 +1495,7 @@
 Remark:         DisConnect TC Connect pointer to NDBAPI. 
 *******************************************************************************/
 int			
-NdbConnection::receiveTCRELEASECONF(NdbApiSignal* aSignal)
+NdbTransaction::receiveTCRELEASECONF(NdbApiSignal* aSignal)
 {
   if (theStatus != DisConnecting)
   {
@@ -1455,7 +1505,7 @@
     theStatus = NotConnected;
   }
   return 0;
-}//NdbConnection::receiveTCRELEASECONF()
+}//NdbTransaction::receiveTCRELEASECONF()
 
 /*******************************************************************************
 int  receiveTCRELEASEREF(NdbApiSignal* aSignal);
@@ -1466,7 +1516,7 @@
 Remark:        DisConnect TC Connect pointer to NDBAPI Failure. 
 *******************************************************************************/
 int			
-NdbConnection::receiveTCRELEASEREF(NdbApiSignal* aSignal)
+NdbTransaction::receiveTCRELEASEREF(NdbApiSignal* aSignal)
 {
   if (theStatus != DisConnecting) {
     return -1;
@@ -1475,7 +1525,7 @@
     theNdb->theError.code = aSignal->readData(2);
     return 0;
   }//if
-}//NdbConnection::receiveTCRELEASEREF()
+}//NdbTransaction::receiveTCRELEASEREF()
 
 /******************************************************************************
 int  receiveTC_COMMITCONF(NdbApiSignal* aSignal);
@@ -1486,11 +1536,12 @@
 Remark:        
 ******************************************************************************/
 int			
-NdbConnection::receiveTC_COMMITCONF(const TcCommitConf * commitConf)
+NdbTransaction::receiveTC_COMMITCONF(const TcCommitConf * commitConf)
 { 
   if(checkState_TransId(&commitConf->transId1)){
     theCommitStatus = Committed;
     theCompletionStatus = CompletedSuccess;
+    theGlobalCheckpointId = commitConf->gci;
     return 0;
   } else {
 #ifdef NDB_NO_DROPPED_SIGNAL
@@ -1498,7 +1549,7 @@
 #endif
   }
   return -1;
-}//NdbConnection::receiveTC_COMMITCONF()
+}//NdbTransaction::receiveTC_COMMITCONF()
 
 /******************************************************************************
 int  receiveTC_COMMITREF(NdbApiSignal* aSignal);
@@ -1509,13 +1560,14 @@
 Remark:        
 ******************************************************************************/
 int			
-NdbConnection::receiveTC_COMMITREF(NdbApiSignal* aSignal)
+NdbTransaction::receiveTC_COMMITREF(NdbApiSignal* aSignal)
 {
   const TcCommitRef * ref = CAST_CONSTPTR(TcCommitRef, aSignal->getDataPtr());
   if(checkState_TransId(&ref->transId1)){
     setOperationErrorCodeAbort(ref->errorCode);
     theCommitStatus = Aborted;
     theCompletionStatus = CompletedFailure;
+    theReturnStatus = ReturnFailure;
     return 0;
   } else {
 #ifdef NDB_NO_DROPPED_SIGNAL
@@ -1524,7 +1576,7 @@
   }
 
   return -1;
-}//NdbConnection::receiveTC_COMMITREF()
+}//NdbTransaction::receiveTC_COMMITREF()
 
 /******************************************************************************
 int  receiveTCROLLBACKCONF(NdbApiSignal* aSignal);
@@ -1535,7 +1587,7 @@
 Remark:        
 ******************************************************************************/
 int			
-NdbConnection::receiveTCROLLBACKCONF(NdbApiSignal* aSignal)
+NdbTransaction::receiveTCROLLBACKCONF(NdbApiSignal* aSignal)
 {
   if(checkState_TransId(aSignal->getDataPtr() + 1)){
     theCommitStatus = Aborted;
@@ -1548,7 +1600,7 @@
   }
 
   return -1;
-}//NdbConnection::receiveTCROLLBACKCONF()
+}//NdbTransaction::receiveTCROLLBACKCONF()
 
 /*******************************************************************************
 int  receiveTCROLLBACKREF(NdbApiSignal* aSignal);
@@ -1559,12 +1611,13 @@
 Remark:        
 *******************************************************************************/
 int			
-NdbConnection::receiveTCROLLBACKREF(NdbApiSignal* aSignal)
+NdbTransaction::receiveTCROLLBACKREF(NdbApiSignal* aSignal)
 {
   if(checkState_TransId(aSignal->getDataPtr() + 1)){
     setOperationErrorCodeAbort(aSignal->readData(4));
     theCommitStatus = Aborted;
     theCompletionStatus = CompletedFailure;
+    theReturnStatus = ReturnFailure;
     return 0;
   } else {
 #ifdef NDB_NO_DROPPED_SIGNAL
@@ -1573,7 +1626,7 @@
   }
 
   return -1;
-}//NdbConnection::receiveTCROLLBACKREF()
+}//NdbTransaction::receiveTCROLLBACKREF()
 
 /*****************************************************************************
 int receiveTCROLLBACKREP( NdbApiSignal* aSignal)
@@ -1585,7 +1638,7 @@
 Remark:         Handles the reception of the ROLLBACKREP signal.
 *****************************************************************************/
 int
-NdbConnection::receiveTCROLLBACKREP( NdbApiSignal* aSignal)
+NdbTransaction::receiveTCROLLBACKREP( NdbApiSignal* aSignal)
 {
   /****************************************************************************
 Check that we are expecting signals from this transaction and that it doesn't
@@ -1604,6 +1657,7 @@
     /**********************************************************************/
     theCompletionStatus = CompletedFailure;
     theCommitStatus = Aborted;
+    theReturnStatus = ReturnFailure;
     return 0;
   } else {
 #ifdef NDB_NO_DROPPED_SIGNAL
@@ -1612,7 +1666,7 @@
   }
 
   return -1;
-}//NdbConnection::receiveTCROLLBACKREP()
+}//NdbTransaction::receiveTCROLLBACKREP()
 
 /*******************************************************************************
 int  receiveTCKEYCONF(NdbApiSignal* aSignal, Uint32 long_short_ind);
@@ -1623,7 +1677,7 @@
 Remark:        
 *******************************************************************************/
 int			
-NdbConnection::receiveTCKEYCONF(const TcKeyConf * keyConf, Uint32 aDataLength)
+NdbTransaction::receiveTCKEYCONF(const TcKeyConf * keyConf, Uint32 aDataLength)
 {
   NdbReceiver* tOp;
   const Uint32 tTemp = keyConf->confInfo;
@@ -1652,6 +1706,7 @@
 	    done = 1;
 	    tOp->setErrorCode(4119);
 	    theCompletionStatus = CompletedFailure;
+	    theReturnStatus = NdbTransaction::ReturnFailure;
 	  }	    
 	}
 	tNoComp += done;
@@ -1681,6 +1736,7 @@
 /**********************************************************************/
       theError.code = 4011;
       theCompletionStatus = CompletedFailure;
+      theReturnStatus = NdbTransaction::ReturnFailure;
       theCommitStatus = Aborted;
       return 0;
     }//if
@@ -1695,7 +1751,7 @@
   }
   
   return -1;
-}//NdbConnection::receiveTCKEYCONF()
+}//NdbTransaction::receiveTCKEYCONF()
 
 /*****************************************************************************
 int receiveTCKEY_FAILCONF( NdbApiSignal* aSignal)
@@ -1707,7 +1763,7 @@
 Remark:         Handles the reception of the TCKEY_FAILCONF signal.
 *****************************************************************************/
 int
-NdbConnection::receiveTCKEY_FAILCONF(const TcKeyFailConf * failConf)
+NdbTransaction::receiveTCKEY_FAILCONF(const TcKeyFailConf * failConf)
 {
   NdbOperation*	tOp;
   /*
@@ -1740,6 +1796,7 @@
       case NdbOperation::OpenScanRequest:
       case NdbOperation::OpenRangeScanRequest:
 	theCompletionStatus = CompletedFailure;
+	theReturnStatus = NdbTransaction::ReturnFailure;
 	setOperationErrorCodeAbort(4115);
 	tOp = NULL;
 	break;
@@ -1757,7 +1814,7 @@
 #endif
   }
   return -1;
-}//NdbConnection::receiveTCKEY_FAILCONF()
+}//NdbTransaction::receiveTCKEY_FAILCONF()
 
 /*************************************************************************
 int receiveTCKEY_FAILREF( NdbApiSignal* aSignal)
@@ -1769,7 +1826,7 @@
 Remark:         Handles the reception of the TCKEY_FAILREF signal.
 **************************************************************************/
 int
-NdbConnection::receiveTCKEY_FAILREF(NdbApiSignal* aSignal)
+NdbTransaction::receiveTCKEY_FAILREF(NdbApiSignal* aSignal)
 {
   /*
     Check that we are expecting signals from this transaction and
@@ -1781,18 +1838,19 @@
       We received an indication of that this transaction was aborted due to a
       node failure.
     */
-    if (theSendStatus == NdbConnection::sendTC_ROLLBACK) {
+    if (theSendStatus == NdbTransaction::sendTC_ROLLBACK) {
       /*
 	We were in the process of sending a rollback anyways. We will
 	report it as a success.
       */
-      theCompletionStatus = NdbConnection::CompletedSuccess;
+      theCompletionStatus = NdbTransaction::CompletedSuccess;
     } else {
-      theCompletionStatus = NdbConnection::CompletedFailure;
+      theReturnStatus = NdbTransaction::ReturnFailure;
+      theCompletionStatus = NdbTransaction::CompletedFailure;
       theError.code = 4031;
     }//if
     theReleaseOnClose = true;
-    theCommitStatus = NdbConnection::Aborted;
+    theCommitStatus = NdbTransaction::Aborted;
     return 0;
   } else {
 #ifdef VM_TRACE
@@ -1800,7 +1858,7 @@
 #endif
   }
   return -1;
-}//NdbConnection::receiveTCKEY_FAILREF()
+}//NdbTransaction::receiveTCKEY_FAILREF()
 
 /******************************************************************************
 int  receiveTCINDXCONF(NdbApiSignal* aSignal, Uint32 long_short_ind);
@@ -1811,7 +1869,7 @@
 Remark:        
 ******************************************************************************/
 int			
-NdbConnection::receiveTCINDXCONF(const TcIndxConf * indxConf, 
+NdbTransaction::receiveTCINDXCONF(const TcIndxConf * indxConf, 
 				 Uint32 aDataLength)
 {
   if(checkState_TransId(&indxConf->transId1)){
@@ -1845,8 +1903,9 @@
       // no Commit flag set. This is clearly an anomaly.
       /**********************************************************************/
       theError.code = 4011;
-      theCompletionStatus = NdbConnection::CompletedFailure;
-      theCommitStatus = NdbConnection::Aborted;
+      theCompletionStatus = NdbTransaction::CompletedFailure;
+      theCommitStatus = NdbTransaction::Aborted;
+      theReturnStatus = NdbTransaction::ReturnFailure;
       return 0;
     }//if
     if (tNoComp >= tNoSent) {
@@ -1860,7 +1919,7 @@
   }
 
   return -1;
-}//NdbConnection::receiveTCINDXCONF()
+}//NdbTransaction::receiveTCINDXCONF()
 
 /*****************************************************************************
 int receiveTCINDXREF( NdbApiSignal* aSignal)
@@ -1872,7 +1931,7 @@
 Remark:         Handles the reception of the TCINDXREF signal.
 *****************************************************************************/
 int
-NdbConnection::receiveTCINDXREF( NdbApiSignal* aSignal)
+NdbTransaction::receiveTCINDXREF( NdbApiSignal* aSignal)
 {
   if(checkState_TransId(aSignal->getDataPtr()+1)){
     theError.code = aSignal->readData(4);	// Override any previous errors
@@ -1884,8 +1943,9 @@
     /*	and we only need to report completion and return with the     */
     /*	error code to the application.				      */
     /**********************************************************************/
-    theCompletionStatus = NdbConnection::CompletedFailure;
-    theCommitStatus = NdbConnection::Aborted;
+    theCompletionStatus = NdbTransaction::CompletedFailure;
+    theCommitStatus = NdbTransaction::Aborted;
+    theReturnStatus = NdbTransaction::ReturnFailure;
     return 0;
   } else {
 #ifdef NDB_NO_DROPPED_SIGNAL
@@ -1894,7 +1954,7 @@
   }
 
   return -1;
-}//NdbConnection::receiveTCINDXREF()
+}//NdbTransaction::receiveTCINDXREF()
 
 /*******************************************************************************
 int OpCompletedFailure();
@@ -1905,12 +1965,12 @@
 Remark:        An operation was completed with failure.
 *******************************************************************************/
 int 
-NdbConnection::OpCompleteFailure(Uint8 abortOption, bool setFailure)
+NdbTransaction::OpCompleteFailure(Uint8 abortOption, bool setFailure)
 {
   Uint32 tNoComp = theNoOfOpCompleted;
   Uint32 tNoSent = theNoOfOpSent;
   if (setFailure)
-    theCompletionStatus = NdbConnection::CompletedFailure;
+    theCompletionStatus = NdbTransaction::CompletedFailure;
   tNoComp++;
   theNoOfOpCompleted = tNoComp;
   if (tNoComp == tNoSent) {
@@ -1935,7 +1995,7 @@
   } else {
     return -1;	// Continue waiting for more signals
   }//if
-}//NdbConnection::OpCompleteFailure()
+}//NdbTransaction::OpCompleteFailure()
 
 /******************************************************************************
 int OpCompleteSuccess();
@@ -1945,7 +2005,7 @@
 Remark:        An operation was completed with success.
 *******************************************************************************/
 int 
-NdbConnection::OpCompleteSuccess()
+NdbTransaction::OpCompleteSuccess()
 {
   Uint32 tNoComp = theNoOfOpCompleted;
   Uint32 tNoSent = theNoOfOpSent;
@@ -1958,10 +2018,11 @@
   } else {
     setOperationErrorCodeAbort(4113);	// Too many operations, 
                                         // stop waiting for more
-    theCompletionStatus = NdbConnection::CompletedFailure;
+    theCompletionStatus = NdbTransaction::CompletedFailure;
+    theReturnStatus = NdbTransaction::ReturnFailure;
     return 0;
   }//if
-}//NdbConnection::OpCompleteSuccess()
+}//NdbTransaction::OpCompleteSuccess()
 
 /******************************************************************************
  int            getGCI();
@@ -1969,13 +2030,13 @@
 Remark:		Get global checkpoint identity of the transaction
 *******************************************************************************/
 int
-NdbConnection::getGCI()
+NdbTransaction::getGCI()
 {
-  if (theCommitStatus == NdbConnection::Committed) {
+  if (theCommitStatus == NdbTransaction::Committed) {
     return theGlobalCheckpointId;
   }//if
   return 0;
-}//NdbConnection::getGCI()
+}//NdbTransaction::getGCI()
 
 /*******************************************************************************
 Uint64 getTransactionId(void);
@@ -1983,31 +2044,31 @@
 Remark:        Get the transaction identity. 
 *******************************************************************************/
 Uint64
-NdbConnection::getTransactionId()
+NdbTransaction::getTransactionId()
 {
   return theTransactionId;
-}//NdbConnection::getTransactionId()
+}//NdbTransaction::getTransactionId()
 
-NdbConnection::CommitStatusType
-NdbConnection::commitStatus()
+NdbTransaction::CommitStatusType
+NdbTransaction::commitStatus()
 {
   return theCommitStatus;
-}//NdbConnection::commitStatus()
+}//NdbTransaction::commitStatus()
 
 int 
-NdbConnection::getNdbErrorLine()
+NdbTransaction::getNdbErrorLine()
 {
   return theErrorLine;
 }
 
 NdbOperation*
-NdbConnection::getNdbErrorOperation()
+NdbTransaction::getNdbErrorOperation()
 {
   return theErrorOperation;
-}//NdbConnection::getNdbErrorOperation()
+}//NdbTransaction::getNdbErrorOperation()
 
 const NdbOperation * 
-NdbConnection::getNextCompletedOperation(const NdbOperation * current) const {
+NdbTransaction::getNextCompletedOperation(const NdbOperation * current) const {
   if(current == 0)
     return theCompletedFirstOp;
   return current->theNext;
@@ -2016,7 +2077,7 @@
 #ifdef VM_TRACE
 #define CASE(x) case x: ndbout << " " << #x; break
 void
-NdbConnection::printState()
+NdbTransaction::printState()
 {
   ndbout << "con=" << hex << this << dec;
   ndbout << " node=" << getConnectedNodeId();
@@ -2069,7 +2130,7 @@
 #endif
 
 int
-NdbConnection::report_node_failure(Uint32 id){
+NdbTransaction::report_node_failure(Uint32 id){
   NdbNodeBitmask::set(m_failed_db_nodes, id);
   if(!NdbNodeBitmask::get(m_db_nodes, id))
   {
@@ -2088,22 +2149,28 @@
   const Uint32 len = TcKeyConf::SimpleReadBit | id;
   Uint32 tNoComp = theNoOfOpCompleted;
   Uint32 tNoSent = theNoOfOpSent;
+  Uint32 count = 0;
   while(tmp != 0)
   {
     if(tmp->theReceiver.m_expected_result_length == len && 
        tmp->theReceiver.m_received_result_length == 0)
     {
-      tNoComp++;
+      count++;
       tmp->theError.code = 4119;
     }
     tmp = tmp->next();
   }
+  tNoComp += count;
   theNoOfOpCompleted = tNoComp;
-  if(tNoComp == tNoSent)
+  if(count)
   {
-    theError.code = 4119;
-    theCompletionStatus = NdbConnection::CompletedFailure;    
-    return 1;
+    theReturnStatus = NdbTransaction::ReturnFailure;
+    if(tNoComp == tNoSent)
+    {
+      theError.code = 4119;
+      theCompletionStatus = NdbTransaction::CompletedFailure;    
+      return 1;
+    }
   }
   return 0;
 }

--- 1.30/ndb/src/ndbapi/Ndbif.cpp	2005-09-20 10:25:25 +02:00
+++ 1.31/ndb/src/ndbapi/Ndbif.cpp	2006-03-22 15:24:29 +01:00
@@ -953,23 +953,25 @@
 void
 Ndb::check_send_timeout()
 {
+  Uint32 timeout = TransporterFacade::instance()->m_waitfor_timeout;
   NDB_TICKS current_time = NdbTick_CurrentMillisecond();
   if (current_time - the_last_check_time > 1000) {
     the_last_check_time = current_time;
     Uint32 no_of_sent = theNoOfSentTransactions;
     for (Uint32 i = 0; i < no_of_sent; i++) {
       NdbTransaction* a_con = theSentTransactionsArray[i];
-      if ((current_time - a_con->theStartTransTime) >
-          WAITFOR_RESPONSE_TIMEOUT) {
+      if ((current_time - a_con->theStartTransTime) > timeout)
+      {
 #ifdef VM_TRACE
         a_con->printState();
 	Uint32 t1 = a_con->theTransactionId;
 	Uint32 t2 = a_con->theTransactionId >> 32;
-	ndbout_c("[%.8x %.8x]", t1, t2);
-	abort();
+	ndbout_c("4012 [%.8x %.8x]", t1, t2);
+	//abort();
 #endif
+        a_con->theReleaseOnClose = true;
         a_con->setOperationErrorCodeAbort(4012);
-        a_con->theCommitStatus = NdbTransaction::Aborted;
+	a_con->theCommitStatus = NdbTransaction::NeedAbort;
         a_con->theCompletionStatus = NdbTransaction::CompletedFailure;
         a_con->handleExecuteCompletion();
         remove_sent_list(i);

--- 1.41/ndb/src/ndbapi/TransporterFacade.cpp	2005-10-11 15:47:58 +02:00
+++ 1.42/ndb/src/ndbapi/TransporterFacade.cpp	2006-03-22 15:24:29 +01:00
@@ -563,6 +563,19 @@
     m_batch_size= batch_size;
   }
   
+  Uint32 timeout = 120000;
+  iter.first();
+  for (iter.first(); iter.valid(); iter.next())
+  {
+    Uint32 tmp1 = 0, tmp2 = 0;
+    iter.get(CFG_DB_TRANSACTION_CHECK_INTERVAL, &tmp1);
+    iter.get(CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT, &tmp2);
+    tmp1 += tmp2;
+    if (tmp1 > timeout)
+      timeout = tmp1;
+  }
+  m_waitfor_timeout = timeout;
+  
   if (!theTransporterRegistry->start_service(m_socket_server)){
     ndbout_c("Unable to start theTransporterRegistry->start_service");
     DBUG_RETURN(false);

--- 1.24/ndb/src/ndbapi/TransporterFacade.hpp	2005-07-22 12:29:16 +02:00
+++ 1.25/ndb/src/ndbapi/TransporterFacade.hpp	2006-03-22 15:10:35 +01:00
@@ -178,6 +178,7 @@
    * (Ndb objects should not be shared by different threads.)
    */
   STATIC_CONST( MAX_NO_THREADS = 4711 );
+  Uint32 m_waitfor_timeout; // in milli seconds...
 private:
 
   struct ThreadData {

--- 1.17/ndb/test/ndbapi/testNodeRestart.cpp	2005-12-13 11:51:01 +01:00
+++ 1.18/ndb/test/ndbapi/testNodeRestart.cpp	2006-03-22 15:10:35 +01:00
@@ -535,6 +535,119 @@
   return NDBT_FAILED;
 }
 
+int 
+runBug16772(NDBT_Context* ctx, NDBT_Step* step){
+
+  NdbRestarter restarter;
+  if (restarter.getNumDbNodes() < 2)
+  {
+    ctx->stopTest();
+    return NDBT_OK;
+  }
+
+  int aliveNodeId = restarter.getRandomNotMasterNodeId(rand());
+  int deadNodeId = aliveNodeId;
+  while (deadNodeId == aliveNodeId)
+    deadNodeId = restarter.getDbNodeId(rand() % restarter.getNumDbNodes());
+  
+  if (restarter.insertErrorInNode(aliveNodeId, 930))
+    return NDBT_FAILED;
+
+  if (restarter.restartOneDbNode(deadNodeId,
+				 /** initial */ false, 
+				 /** nostart */ true,
+				 /** abort   */ true))
+    return NDBT_FAILED;
+  
+  if (restarter.waitNodesNoStart(&deadNodeId, 1))
+    return NDBT_FAILED;
+
+  if (restarter.startNodes(&deadNodeId, 1))
+    return NDBT_FAILED;
+
+  // It should now be hanging since we throw away NDB_FAILCONF
+  int ret = restarter.waitNodesStartPhase(&deadNodeId, 1, 3, 10);
+  // So this should fail...i.e it should not reach startphase 3
+
+  // Now send a NDB_FAILCONF for deadNo
+  int dump[] = { 7020, 323, 252, 0 };
+  dump[3] = deadNodeId;
+  if (restarter.dumpStateOneNode(aliveNodeId, dump, 4))
+    return NDBT_FAILED;
+  
+  if (restarter.waitNodesStarted(&deadNodeId, 1))
+    return NDBT_FAILED;
+
+  return ret ? NDBT_OK : NDBT_FAILED;
+}
+
+int 
+runBug18414(NDBT_Context* ctx, NDBT_Step* step){
+
+  NdbRestarter restarter;
+  if (restarter.getNumDbNodes() < 2)
+  {
+    ctx->stopTest();
+    return NDBT_OK;
+  }
+
+  Ndb* pNdb = GETNDB(step);
+  HugoOperations hugoOps(*ctx->getTab());
+  HugoTransactions hugoTrans(*ctx->getTab());
+  int loop = 0;
+  do 
+  {
+    if(hugoOps.startTransaction(pNdb) != 0)
+      goto err;
+    
+    if(hugoOps.pkUpdateRecord(pNdb, 0, 128, rand()) != 0)
+      goto err;
+    
+    if(hugoOps.execute_NoCommit(pNdb) != 0)
+      goto err;
+
+    int node1 = hugoOps.getTransaction()->getConnectedNodeId();
+    int node2 = restarter.getRandomNodeSameNodeGroup(node1, rand());
+    
+    if (node1 == -1 || node2 == -1)
+      break;
+    
+    if (loop & 1)
+    {
+      if (restarter.insertErrorInNode(node1, 8050))
+	goto err;
+    }
+    
+    if (restarter.insertErrorInNode(node2, 5003))
+      goto err;
+    
+    int res= hugoOps.execute_Rollback(pNdb);
+  
+    if (restarter.waitNodesNoStart(&node2, 1) != 0)
+      goto err;
+    
+    if (restarter.insertErrorInAllNodes(0))
+      goto err;
+    
+    if (restarter.startNodes(&node2, 1) != 0)
+      goto err;
+    
+    if (restarter.waitClusterStarted() != 0)
+      goto err;
+    
+    if (hugoTrans.scanUpdateRecords(pNdb, 128) != 0)
+      goto err;
+
+    hugoOps.closeTransaction(pNdb);
+    
+  } while(++loop < 5);
+  
+  return NDBT_OK;
+  
+err:
+  hugoOps.closeTransaction(pNdb);
+  return NDBT_FAILED;    
+}
 
 NDBT_TESTSUITE(testNodeRestart);
 TESTCASE("NoLoad", 
@@ -818,6 +931,16 @@
 TESTCASE("Bug15685",
 	 "Test bug with NF during abort"){
   STEP(runBug15685);
+  FINALIZER(runClearTable);
+}
+TESTCASE("Bug16772",
+	 "Test bug with restarting before NF handling is complete"){
+  STEP(runBug16772);
+}
+TESTCASE("Bug18414",
+	 "Test bug with NF during NR"){
+  INITIALIZER(runLoadTable);
+  STEP(runBug18414);
   FINALIZER(runClearTable);
 }
 NDBT_TESTSUITE_END(testNodeRestart);

--- 1.12/ndb/test/ndbapi/testTimeout.cpp	2005-06-14 00:05:24 +02:00
+++ 1.13/ndb/test/ndbapi/testTimeout.cpp	2006-03-22 15:24:29 +01:00
@@ -24,6 +24,7 @@
 
 #define TIMEOUT (Uint32)3000
 Uint32 g_org_timeout = 3000;
+Uint32 g_org_deadlock = 3000;
 
 int
 setTransactionTimeout(NDBT_Context* ctx, NDBT_Step* step){
@@ -59,6 +60,60 @@
   return NDBT_OK;
 }
 
+int
+setDeadlockTimeout(NDBT_Context* ctx, NDBT_Step* step){
+  NdbRestarter restarter;
+  int timeout = ctx->getProperty("TransactionDeadlockTimeout", TIMEOUT);
+  
+  NdbConfig conf(GETNDB(step)->getNodeId()+1);
+  unsigned int nodeId = conf.getMasterNodeId();
+  if (!conf.getProperty(nodeId,
+			NODE_TYPE_DB, 
+			CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT,
+			&g_org_deadlock))
+    return NDBT_FAILED;
+  
+  g_err << "Setting timeout: " << timeout << endl;
+  int val[] = { DumpStateOrd::TcSetTransactionTimeout, timeout };
+  if(restarter.dumpStateAllNodes(val, 2) != 0){
+    return NDBT_FAILED;
+  }
+  
+  return NDBT_OK;
+}
+
+int
+getDeadlockTimeout(NDBT_Context* ctx, NDBT_Step* step){
+  NdbRestarter restarter;
+  
+  Uint32 val = 0;
+  NdbConfig conf(GETNDB(step)->getNodeId()+1);
+  unsigned int nodeId = conf.getMasterNodeId();
+  if (!conf.getProperty(nodeId,
+			NODE_TYPE_DB, 
+			CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT,
+			&val))
+    return NDBT_FAILED;
+
+  if (val < 120000)
+    val = 120000;
+  ctx->setProperty("TransactionDeadlockTimeout", 4*val);
+  
+  return NDBT_OK;
+}
+
+int
+resetDeadlockTimeout(NDBT_Context* ctx, NDBT_Step* step){
+  NdbRestarter restarter;
+  
+  int val[] = { DumpStateOrd::TcSetTransactionTimeout, g_org_deadlock };
+  if(restarter.dumpStateAllNodes(val, 2) != 0){
+    return NDBT_FAILED;
+  }
+  
+  return NDBT_OK;
+}
+
 
 int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){
 
@@ -333,6 +388,43 @@
   return result;
 }
 
+int 
+runError4012(NDBT_Context* ctx, NDBT_Step* step){
+  int result = NDBT_OK;
+  int loops = ctx->getNumLoops();
+  int stepNo = step->getStepNo();
+  
+  int timeout = ctx->getProperty("TransactionDeadlockTimeout", TIMEOUT);
+
+  HugoOperations hugoOps(*ctx->getTab());
+  Ndb* pNdb = GETNDB(step);
+
+  do{
+    // Commit transaction
+    CHECK(hugoOps.startTransaction(pNdb) == 0);
+    CHECK(hugoOps.pkUpdateRecord(pNdb, 0) == 0);
+    int ret = hugoOps.execute_NoCommit(pNdb);
+    if (ret == 0)
+    {
+      int sleep = timeout;
+      ndbout << "Sleeping for " << sleep << " milliseconds" << endl;
+      NdbSleep_MilliSleep(sleep);
+      
+      // Expect that transaction has NOT timed-out
+      CHECK(hugoOps.execute_Commit(pNdb) == 0);
+    }
+    else
+    {
+      CHECK(ret == 4012);
+    }
+  } while(false);
+  
+  hugoOps.closeTransaction(pNdb);
+  
+  return result;
+}
+
+
 NDBT_TESTSUITE(testTimeout);
 TESTCASE("DontTimeoutTransaction", 
 	 "Test that the transaction does not timeout "\
@@ -403,6 +495,15 @@
   FINALIZER(resetTransactionTimeout);
   FINALIZER(runClearTable);
 }
+TESTCASE("Error4012", ""){
+  TC_PROPERTY("TransactionDeadlockTimeout", 120000);
+  INITIALIZER(runLoadTable);
+  INITIALIZER(getDeadlockTimeout);
+  INITIALIZER(setDeadlockTimeout);
+  STEPS(runError4012, 2);
+  FINALIZER(runClearTable);
+}
+
 NDBT_TESTSUITE_END(testTimeout);
 
 int main(int argc, const char** argv){

--- 1.11/ndb/test/src/NdbRestarter.cpp	2004-12-31 06:19:26 +01:00
+++ 1.12/ndb/test/src/NdbRestarter.cpp	2006-03-22 15:10:35 +01:00
@@ -174,6 +174,39 @@
   return -1;
 }
 
+int
+NdbRestarter::getRandomNodeSameNodeGroup(int nodeId, int rand){
+  if (!isConnected())
+    return -1;
+  
+  if (getStatus() != 0)
+    return -1;
+  
+  int node_group = -1;
+  for(size_t i = 0; i < ndbNodes.size(); i++){
+    if(ndbNodes[i].node_id == nodeId){
+      node_group = ndbNodes[i].node_group;
+      break;
+    }
+  }
+  if(node_group == -1){
+    return -1;
+  }
+
+  Uint32 counter = 0;
+  rand = rand % ndbNodes.size();
+  while(counter++ < ndbNodes.size() && 
+	(ndbNodes[rand].node_id == nodeId || 
+	 ndbNodes[rand].node_group != node_group))
+    rand = (rand + 1) % ndbNodes.size();
+  
+  if(ndbNodes[rand].node_group == node_group &&
+     ndbNodes[rand].node_id != nodeId)
+    return ndbNodes[rand].node_id;
+  
+  return -1;
+}
+
 int 
 NdbRestarter::waitClusterStarted(unsigned int _timeout){
   return waitClusterState(NDB_MGM_NODE_STATUS_STARTED, _timeout);

--- 1.18/ndb/tools/desc.cpp	2005-04-06 20:29:12 +02:00
+++ 1.19/ndb/tools/desc.cpp	2006-03-22 15:24:29 +01:00
@@ -23,6 +23,7 @@
 
 static const char* _dbname = "TEST_DB";
 static int _unqualified = 0;
+static int _partinfo = 0;
 static struct my_option my_long_options[] =
 {
   NDB_STD_OPTS("ndb_desc"),
@@ -32,6 +33,9 @@
   { "unqualified", 'u', "Use unqualified table names",
     (gptr*) &_unqualified, (gptr*) &_unqualified, 0,
     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, 
+  { "extra-partition-info", 'p', "Print more info per partition",
+    (gptr*) &_partinfo, (gptr*) &_partinfo, 0,
+    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, 
   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };
 static void usage()
@@ -45,6 +49,8 @@
   my_print_variables(my_long_options);
 }
 
+static void print_part_info(Ndb* pNdb, NDBT_Table* pTab);
+
 int main(int argc, char** argv){
   NDB_INIT(argv[0]);
   const char *load_default_groups[]= { "mysql_cluster",0 };
@@ -109,11 +115,83 @@
 	  
 	ndbout << (*pIdx) << endl;
       }
+
       ndbout << endl;
+      
+      if (_partinfo)
+	print_part_info(pMyNdb, pTab);
     }
     else
       ndbout << argv[i] << ": " << dict->getNdbError() << endl;
   }
   
   return NDBT_ProgramExit(NDBT_OK);
+}
+
+struct InfoInfo
+{
+  const char * m_title;
+  NdbRecAttr* m_rec_attr;
+  const NdbDictionary::Column* m_column;
+};
+
+
+static 
+void print_part_info(Ndb* pNdb, NDBT_Table* pTab)
+{
+  InfoInfo g_part_info[] = {
+    { "Partition", 0, NdbDictionary::Column::FRAGMENT },
+    { "Row count", 0, NdbDictionary::Column::ROW_COUNT },
+    { "Commit count", 0, NdbDictionary::Column::COMMIT_COUNT },
+    { "Frag memory", 0, NdbDictionary::Column::FRAGMENT_MEMORY },
+    { 0, 0, 0 }
+  };
+
+  ndbout << "-- Per partition info -- " << endl;
+  
+  NdbConnection* pTrans = pNdb->startTransaction();
+  if (pTrans == 0)
+    return;
+  
+  do
+  {
+    NdbScanOperation* pOp= pTrans->getNdbScanOperation(pTab->getName());
+    if (pOp == NULL)
+      break;
+    
+    NdbResultSet* rs= pOp->readTuples(NdbOperation::LM_CommittedRead); 
+    if (rs == 0)
+      break;
+    
+    if (pOp->interpret_exit_last_row() != 0)
+      break;
+    
+    Uint32 i = 0;
+    for(i = 0; g_part_info[i].m_title != 0; i++)
+    {
+      if ((g_part_info[i].m_rec_attr = pOp->getValue(g_part_info[i].m_column)) == 0)
+	break;
+    }
+
+    if (g_part_info[i].m_title != 0)
+      break;
+
+    if (pTrans->execute(NoCommit) != 0)
+      break;
+	
+    for (i = 0; g_part_info[i].m_title != 0; i++)
+      ndbout << g_part_info[i].m_title << "\t";
+    ndbout << endl;
+    
+    while(rs->nextResult() == 0)
+    {
+      for(i = 0; g_part_info[i].m_title != 0; i++)
+      {
+	ndbout << *g_part_info[i].m_rec_attr << "\t";
+      }
+      ndbout << endl;
+    }
+  } while(0);
+  
+  pTrans->close();
 }

--- 1.286/sql/ha_innodb.cc	2006-01-31 19:41:42 +01:00
+++ 1.287/sql/ha_innodb.cc	2006-03-22 15:10:35 +01:00
@@ -513,6 +513,13 @@
 
     		return(HA_ERR_NO_SAVEPOINT);
   	} else if (error == (int) DB_LOCK_TABLE_FULL) {
+          /* Since we rolled back the whole transaction, we must
+          tell it also to MySQL so that MySQL knows to empty the
+          cached binlog for this transaction */
+
+          if (thd) {
+                  ha_rollback(thd);
+          }
 
     		return(HA_ERR_LOCK_TABLE_FULL);
     	} else {

--- 1.22/ndb/test/run-test/Makefile.am	2005-05-10 12:33:41 +02:00
+++ 1.23/ndb/test/run-test/Makefile.am	2006-03-22 15:10:35 +01:00
@@ -7,11 +7,10 @@
 
 test_PROGRAMS = atrt
 test_DATA=daily-basic-tests.txt daily-devel-tests.txt 16node-tests.txt \
-          conf-daily-basic-ndbmaster.txt \
-          conf-daily-basic-shark.txt \
-          conf-daily-devel-ndbmaster.txt \
-          conf-daily-sql-ndbmaster.txt \
-          conf-daily-basic-dl145a.txt
+          conf-ndbmaster.txt \
+          conf-shark.txt \
+          conf-dl145a.txt
+
 test_SCRIPTS=atrt-analyze-result.sh atrt-gather-result.sh atrt-setup.sh \
           atrt-clear-result.sh make-config.sh make-index.sh make-html-reports.sh
 
Thread
bk commit into 5.0 tree (jonas:1.2089)jonas22 Mar