List:Commits« Previous MessageNext Message »
From:jonas Date:December 13 2005 11:07am
Subject:bk commit into 5.1 tree (jonas:1.1960)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 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.1960 05/12/13 12:07:36 jonas@stripped +9 -0
  Merge perch.ndb.mysql.com:/home/jonas/src/mysql-5.0
  into  perch.ndb.mysql.com:/home/jonas/src/mysql-5.1-new

  storage/ndb/test/run-test/daily-basic-tests.txt
    1.37 05/12/13 12:07:34 jonas@stripped +1 -10
    merge

  storage/ndb/test/ndbapi/testNodeRestart.cpp
    1.21 05/12/13 12:05:23 jonas@stripped +0 -0
    Auto merged

  storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
    1.95 05/12/13 12:05:23 jonas@stripped +0 -0
    Auto merged

  storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
    1.81 05/12/13 12:05:23 jonas@stripped +0 -0
    Auto merged

  storage/ndb/test/run-test/daily-basic-tests.txt
    1.27.7.2 05/12/13 12:05:23 jonas@stripped +0 -0
    Merge rename: ndb/test/run-test/daily-basic-tests.txt -> storage/ndb/test/run-test/daily-basic-tests.txt

  storage/ndb/test/ndbapi/testNodeRestart.cpp
    1.13.4.2 05/12/13 12:05:23 jonas@stripped +0 -0
    Merge rename: ndb/test/ndbapi/testNodeRestart.cpp -> storage/ndb/test/ndbapi/testNodeRestart.cpp

  storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
    1.73.13.2 05/12/13 12:05:23 jonas@stripped +0 -0
    Merge rename: ndb/src/kernel/blocks/dbtc/DbtcMain.cpp -> storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp

  storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
    1.66.9.2 05/12/13 12:05:23 jonas@stripped +0 -0
    Merge rename: ndb/src/kernel/blocks/dblqh/DblqhMain.cpp -> storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp

  storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
    1.41 05/12/13 12:05:23 jonas@stripped +0 -0
    Auto merged

  storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
    1.39 05/12/13 12:05:23 jonas@stripped +0 -0
    Auto merged

  storage/ndb/src/kernel/blocks/ERROR_codes.txt
    1.14 05/12/13 12:05:23 jonas@stripped +0 -0
    Auto merged

  storage/ndb/include/ndb_version.h.in
    1.5 05/12/13 12:05:23 jonas@stripped +0 -0
    Auto merged

  storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp
    1.7 05/12/13 12:05:23 jonas@stripped +0 -0
    Auto merged

  storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
    1.32.5.2 05/12/13 12:05:22 jonas@stripped +0 -0
    Merge rename: ndb/src/kernel/blocks/dblqh/Dblqh.hpp -> storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp

  storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
    1.24.11.2 05/12/13 12:05:22 jonas@stripped +0 -0
    Merge rename: ndb/src/kernel/blocks/dbdih/DbdihMain.cpp -> storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp

  storage/ndb/src/kernel/blocks/ERROR_codes.txt
    1.9.4.2 05/12/13 12:05:22 jonas@stripped +0 -0
    Merge rename: ndb/src/kernel/blocks/ERROR_codes.txt -> storage/ndb/src/kernel/blocks/ERROR_codes.txt

  storage/ndb/include/ndb_version.h.in
    1.1.3.2 05/12/13 12:05:22 jonas@stripped +0 -0
    Merge rename: ndb/include/ndb_version.h.in -> storage/ndb/include/ndb_version.h.in

  storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp
    1.3.2.2 05/12/13 12:05:22 jonas@stripped +0 -0
    Merge rename: ndb/include/kernel/signaldata/DumpStateOrd.hpp -> storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp

# 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/mysql-5.1-new/RESYNC

--- 1.27.7.1/ndb/test/run-test/daily-basic-tests.txt	2005-12-13 11:54:40 +01:00
+++ 1.37/storage/ndb/test/run-test/daily-basic-tests.txt	2005-12-13 12:07:34 +01:00
@@ -81,23 +81,23 @@
 
 max-time: 500
 cmd: testBasic
-args: -n PkReadAndLocker T6 
+args: -n PkReadAndLocker T6 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n PkReadAndLocker2 T6 
+args: -n PkReadAndLocker2 T6 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n PkReadUpdateAndLocker T6 
+args: -n PkReadUpdateAndLocker T6 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n ReadWithLocksAndInserts T6 
+args: -n ReadWithLocksAndInserts T6 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n PkInsertTwice T1 T6 T10 
+args: -n PkInsertTwice T1 T6 T10 D1 D2
 
 max-time: 1500
 cmd: testBasic
@@ -109,79 +109,79 @@
 
 max-time: 500
 cmd: testBasic
-args: -n NoCommitSleep T6 
+args: -n NoCommitSleep T6 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n NoCommit626 T6 
+args: -n NoCommit626 T6 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n NoCommitAndClose T6 
+args: -n NoCommitAndClose T6 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n Commit626 T6 
+args: -n Commit626 T6 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n CommitTry626 T6 
+args: -n CommitTry626 T6 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n CommitAsMuch626 T6 
+args: -n CommitAsMuch626 T6 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n NoCommit626 T6 
+args: -n NoCommit626 T6 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n NoCommitRollback626 T1 T6 
+args: -n NoCommitRollback626 T1 T6 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n Commit630 T1 T6 
+args: -n Commit630 T1 T6 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n CommitTry630 T1 T6 
+args: -n CommitTry630 T1 T6 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n CommitAsMuch630 T1 T6 
+args: -n CommitAsMuch630 T1 T6 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n NoCommit630 T1 T6 
+args: -n NoCommit630 T1 T6 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n NoCommitRollback630 T1 T6 
+args: -n NoCommitRollback630 T1 T6 D1 D2 
 
 max-time: 500
 cmd: testBasic
-args: -n NoCommitAndClose T1 T6 
+args: -n NoCommitAndClose T1 T6 D1 D2 
 
 max-time: 500
 cmd: testBasic
-args: -n RollbackUpdate T1 T6 
+args: -n RollbackUpdate T1 T6 D1 D2 
 
 max-time: 500
 cmd: testBasic
-args: -n RollbackDeleteMultiple T1 T6 
+args: -n RollbackDeleteMultiple T1 T6 D1 D2 
 
 max-time: 500
 cmd: testBasic
-args: -n ImplicitRollbackDelete T1 T6 
+args: -n ImplicitRollbackDelete T1 T6 D1 D2 
 
 max-time: 500
 cmd: testBasic
-args: -n CommitDelete T1 T6 
+args: -n CommitDelete T1 T6 D1 D2 
 
 max-time: 500
 cmd: testBasic
-args: -n RollbackNothing T1 T6 
+args: -n RollbackNothing T1 T6 D1 D2 
 
 max-time: 500
 cmd: testBasicAsynch
@@ -201,11 +201,11 @@
 
 max-time: 500
 cmd: testBasic
-args: -n MassiveRollback T1 T6 T13 
+args: -n MassiveRollback T1 T6 T13 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n MassiveRollback2 T1 T6 T13 
+args: -n MassiveRollback2 T1 T6 T13 D1 D2
 
 max-time: 500
 cmd: testTimeout
@@ -231,7 +231,7 @@
 
 max-time: 500
 cmd: testScan
-args: -n ScanUpdate2 T6 
+args: -n ScanUpdate2 T6 D1 D2
 
 max-time: 500
 cmd: testScan
@@ -239,47 +239,47 @@
 
 max-time: 500
 cmd: testScan
-args: -n ScanDelete2 T10 
+args: -n ScanDelete2 T10 D1 D2
 
 max-time: 500
 cmd: testScan
-args: -n ScanUpdateAndScanRead T6 
+args: -n ScanUpdateAndScanRead T6 D1 D2
 
 max-time: 500
 cmd: testScan
-args: -n ScanReadAndLocker T6 
+args: -n ScanReadAndLocker T6 D1 D2
 
 max-time: 500
 cmd: testScan
-args: -n ScanReadAndPkRead T6 
+args: -n ScanReadAndPkRead T6 D1 D2
 
 max-time: 500
 cmd: testScan
-args: -n ScanRead488 -l 10 T6 
+args: -n ScanRead488 -l 10 T6 D1 D2
 
 max-time: 500
 cmd: testScan
-args: -n ScanRead488O -l 10 T6 
+args: -n ScanRead488O -l 10 T6 D1 D2 
 
 max-time: 1000
 cmd: testScan
-args: -n ScanRead488_Mixed -l 10 T6 
+args: -n ScanRead488_Mixed -l 10 T6 D1 D2
 
 max-time: 500
 cmd: testScan
-args: -n ScanRead488Timeout -l 10 T6 
+args: -n ScanRead488Timeout -l 10 T6 D1 D2
 
 max-time: 600
 cmd: testScan
-args: -n ScanRead40 -l 100 T2 
+args: -n ScanRead40 -l 100 T2 D1 D2 
 
 max-time: 1800
 cmd: testScan
-args: -n ScanRead100 -l 100 T1 
+args: -n ScanRead100 -l 100 T1 D1 D2 
 
 max-time: 600
 cmd: testScan
-args: -n ScanRead40 -l 100 T1 
+args: -n ScanRead40 -l 100 T1 D1 D2 
 
 max-time: 1800
 cmd: testScan
@@ -291,123 +291,123 @@
 
 max-time: 500
 cmd: testScan
-args: -n ScanWithLocksAndInserts T6 
+args: -n ScanWithLocksAndInserts T6 D1 D2
 
 max-time: 500
 cmd: testScan
-args: -n ScanReadAbort T6 
+args: -n ScanReadAbort T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanReadAbort15 T6 
+args: -n ScanReadAbort15 T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanReadAbort240 T6 
+args: -n ScanReadAbort240 T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanUpdateAbort16 T6 
+args: -n ScanUpdateAbort16 T6 D1 D2 
 
 max-time: 3600
 cmd: testScan
-args: -n ScanReadRestart T1 T6 T13 
+args: -n ScanReadRestart T1 T6 T13 D1 D2
 
 max-time: 500
 cmd: testScan
-args: -n ScanUpdateRestart T6 
+args: -n ScanUpdateRestart T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n CheckGetValue T6 
+args: -n CheckGetValue T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n CloseWithoutStop T6 
+args: -n CloseWithoutStop T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n NextScanWhenNoMore T6 
+args: -n NextScanWhenNoMore T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ExecuteScanWithoutOpenScan T6 
+args: -n ExecuteScanWithoutOpenScan T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n OnlyOpenScanOnce T6 
+args: -n OnlyOpenScanOnce T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n OnlyOneOpInScanTrans T6 
+args: -n OnlyOneOpInScanTrans T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n OnlyOneOpBeforeOpenScan T6 
+args: -n OnlyOneOpBeforeOpenScan T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n OnlyOneScanPerTrans T6 
+args: -n OnlyOneScanPerTrans T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n NoCloseTransaction T6 
+args: -n NoCloseTransaction T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n CheckInactivityTimeOut T6 
+args: -n CheckInactivityTimeOut T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n CheckInactivityBeforeClose T6 
+args: -n CheckInactivityBeforeClose T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n CheckAfterTerror T6 
+args: -n CheckAfterTerror T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanReadError5021 T1 
+args: -n ScanReadError5021 T1 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanReaderror5022 T1 
+args: -n ScanReaderror5022 T1 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanReadError5023 T1 
+args: -n ScanReadError5023 T1 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanReadError5024 T1 
+args: -n ScanReadError5024 T1 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanReadError5025 T1 
+args: -n ScanReadError5025 T1 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanReadError5030 T1 
+args: -n ScanReadError5030 T1 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n InsertDelete T1 T6
+args: -n InsertDelete T1 T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n CheckAfterTerror T1
+args: -n CheckAfterTerror T1 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanReadWhileNodeIsDown T1
+args: -n ScanReadWhileNodeIsDown T1 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanRestart T1
+args: -n ScanRestart T1 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -l 100 -n Scan-bug8262 T7
+args: -l 100 -n Scan-bug8262 T7 D1 D2
 
 max-time: 500
 cmd: testScan
@@ -425,15 +425,6 @@
 cmd: testNodeRestart
 args: -n Bug15685 T1
 
-# OLD FLEX
-max-time: 500
-cmd: flexBench
-args: -c 25 -t 10
-
-max-time: 500
-cmd: flexHammer
-args: -r 5 -t 32
-
 #
 # DICT TESTS
 max-time: 1500
@@ -446,7 +437,7 @@
 
 max-time: 1500
 cmd: testDict
-args: -n CreateAndDropDuring T6 T10 
+args: -n CreateAndDropDuring T6 T10 D1 D2
 
 max-time: 1500
 cmd: testDict
@@ -531,23 +522,27 @@
 
 max-time: 500
 cmd: testNdbApi
-args: -n UpdateWithoutKeys T6 
+args: -n UpdateWithoutKeys T6 D1 D2 
+
+max-time: 500
+cmd: testNdbApi
+args: -n UpdateWithoutValues T6 D1 D2 
 
 max-time: 500
 cmd: testNdbApi
-args: -n UpdateWithoutValues T6 
+args: -n ReadWithoutGetValue D1 D2 
 
 max-time: 500
 cmd: testNdbApi
-args: -n ReadWithoutGetValue
+args: -n Bug_11133 T1 D1 D2 
 
 max-time: 500
 cmd: testNdbApi
-args: -n Bug_11133 T1 
+args: -n Scan_4006 T1 D1 D2 
 
 max-time: 500
 cmd: testNdbApi
-args: -n Scan_4006 T1
+args: -n Bug_WritePartialIgnoreError T1 
 
 #max-time: 500
 #cmd: testInterpreter
@@ -603,6 +598,14 @@
 
 max-time: 1500
 cmd: testSystemRestart
+args: -n SR1 D1
+
+max-time: 1500
+cmd: testSystemRestart
+args: -n SR1 D2 
+
+max-time: 1500
+cmd: testSystemRestart
 args: -n SR2 T1 
 
 max-time: 1500
@@ -612,6 +615,14 @@
 max-time: 1500
 cmd: testSystemRestart
 args: -n SR2 T7 
+
+max-time: 1500
+cmd: testSystemRestart
+args: -n SR2 D1
+
+max-time: 1500
+cmd: testSystemRestart
+args: -n SR2 D2 
 
 max-time: 1500
 cmd: testSystemRestart

--- 1.3.2.1/ndb/include/kernel/signaldata/DumpStateOrd.hpp	2005-12-08 15:28:13 +01:00
+++ 1.7/storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp	2005-12-13 12:05:23 +01:00
@@ -106,6 +106,8 @@
     CmvmiDumpLongSignalMemory = 2601,
     CmvmiSetRestartOnErrorInsert = 2602,
     CmvmiTestLongSigWithDelay = 2603,
+    
+    LCPContinue = 5900,
     // 7000 DIH
     // 7001 DIH
     // 7002 DIH
@@ -132,7 +134,11 @@
     // 12000 Tux
     TuxLogToFile = 12001,
     TuxSetLogFlags = 12002,
-    TuxMetaDataJunk = 12009
+    TuxMetaDataJunk = 12009,
+    
+    DumpTsman = 9000, 
+    DumpLgman = 10000,
+    DumpPgman = 11000
   };
 public:
   

--- 1.24.11.1/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2005-12-13 11:51:01 +01:00
+++ 1.39/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2005-12-13 12:05:23 +01:00
@@ -639,9 +639,11 @@
     c_copyGCISlave.m_expectedNextWord += CopyGCIReq::DATA_SIZE;
     return;
   }//if
-  
+
+  Uint32 tmp= SYSFILE->m_restart_seq;
   memcpy(sysfileData, cdata, sizeof(sysfileData));
-  
+  SYSFILE->m_restart_seq = tmp;
+
   c_copyGCISlave.m_copyReason = reason;
   c_copyGCISlave.m_senderRef  = signal->senderBlockRef();
   c_copyGCISlave.m_senderData = copyGCI->anyData;
@@ -1613,12 +1615,15 @@
    *
    * But dont copy lastCompletedGCI:s
    */
+  Uint32 key = SYSFILE->m_restart_seq;
   Uint32 tempGCP[MAX_NDB_NODES];
   for(i = 0; i < MAX_NDB_NODES; i++)
     tempGCP[i] = SYSFILE->lastCompletedGCI[i];
 
   for(i = 0; i < Sysfile::SYSFILE_SIZE32; i++)
     sysfileData[i] = cdata[i];
+
+  SYSFILE->m_restart_seq = key;
   for(i = 0; i < MAX_NDB_NODES; i++)
     SYSFILE->lastCompletedGCI[i] = tempGCP[i];
 
@@ -3497,6 +3502,7 @@
   /*     WE ALSO COPY TO OUR OWN NODE. TO ENABLE US TO DO THIS PROPERLY WE   */
   /*     START BY CLOSING THIS FILE.                                         */
   /* ----------------------------------------------------------------------- */
+  globalData.m_restart_seq = ++SYSFILE->m_restart_seq;
   closeFile(signal, filePtr);
   filePtr.p->reqStatus = FileRecord::CLOSING_GCP;
 }//Dbdih::readingGcpLab()
@@ -5553,11 +5559,9 @@
 #endif
   }
 
-  bool ok = false;
   MasterLCPConf::State lcpState;
   switch (c_lcpState.lcpStatus) {
   case LCP_STATUS_IDLE:
-    ok = true;
     jam();
     /*------------------------------------------------*/
     /*       LOCAL CHECKPOINT IS CURRENTLY NOT ACTIVE */
@@ -5568,7 +5572,6 @@
     lcpState = MasterLCPConf::LCP_STATUS_IDLE;
     break;
   case LCP_STATUS_ACTIVE:
-    ok = true;
     jam();
     /*--------------------------------------------------*/
     /*       COPY OF RESTART INFORMATION HAS BEEN       */
@@ -5577,7 +5580,6 @@
     lcpState = MasterLCPConf::LCP_STATUS_ACTIVE;
     break;
   case LCP_TAB_COMPLETED:
-    ok = true;
     jam();
     /*--------------------------------------------------------*/
     /*       ALL LCP_REPORT'S HAVE BEEN COMPLETED FOR         */
@@ -5587,7 +5589,6 @@
     lcpState = MasterLCPConf::LCP_TAB_COMPLETED;
     break;
   case LCP_TAB_SAVED:
-    ok = true;
     jam();
     /*--------------------------------------------------------*/
     /*       ALL LCP_REPORT'S HAVE BEEN COMPLETED FOR         */
@@ -5611,15 +5612,15 @@
     break;
   case LCP_COPY_GCI:
   case LCP_INIT_TABLES:
-    ok = true;
     /**
      * These two states are handled by if statements above
      */
     ndbrequire(false);
     lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning
     break;
+  default:
+    ndbrequire(false);
   }//switch
-  ndbrequire(ok);
 
   Uint32 failedNodeId = c_lcpState.m_MASTER_LCPREQ_FailedNodeId;
   MasterLCPConf * const conf = (MasterLCPConf *)&signal->theData[0];
@@ -6220,96 +6221,147 @@
   3.7.1   A D D   T A B L E   M A I N L Y
   ***************************************
   */
-void Dbdih::execCREATE_FRAGMENTATION_REQ(Signal * signal){
+
+#define UNDEF_NODEGROUP 65535
+static inline void inc_node_or_group(Uint32 &node, Uint32 max_node)
+{
+  Uint32 next = node + 1;
+  node = (next == max_node ? 0 : next);
+}
+
+/*
+  Spread fragments in backwards compatible mode
+*/
+static void set_default_node_groups(Signal *signal, Uint32 noFrags)
+{
+  Uint16 *node_group_array = (Uint16*)&signal->theData[25];
+  Uint32 i;
+  node_group_array[0] = 0;
+  for (i = 1; i < noFrags; i++)
+    node_group_array[i] = UNDEF_NODEGROUP;
+}
+void Dbdih::execCREATE_FRAGMENTATION_REQ(Signal * signal)
+{
+  Uint16 node_group_id[MAX_NDB_PARTITIONS];
   jamEntry();
   CreateFragmentationReq * const req = 
     (CreateFragmentationReq*)signal->getDataPtr();
   
   const Uint32 senderRef = req->senderRef;
   const Uint32 senderData = req->senderData;
-  const Uint32 fragmentNode = req->fragmentNode;
-  const Uint32 fragmentType = req->fragmentationType;
-  //const Uint32 fragmentCount = req->noOfFragments;
+  Uint32 noOfFragments = req->noOfFragments;
+  const Uint32 fragType = req->fragmentationType;
   const Uint32 primaryTableId = req->primaryTableId;
 
   Uint32 err = 0;
   
   do {
-    Uint32 noOfFragments = 0;
-    Uint32 noOfReplicas = cnoReplicas;
-    switch(fragmentType){
-    case DictTabInfo::AllNodesSmallTable:
-      jam();
-      noOfFragments = csystemnodes;
-      break;
-    case DictTabInfo::AllNodesMediumTable:
-      jam();
-      noOfFragments = 2 * csystemnodes;
-      break;
-    case DictTabInfo::AllNodesLargeTable:
-      jam();
-      noOfFragments = 4 * csystemnodes;
-      break;
-    case DictTabInfo::SingleFragment:
-      jam();
-      noOfFragments = 1;
-      break;
-#if 0
-    case DictTabInfo::SpecifiedFragmentCount:
-      noOfFragments = (fragmentCount == 0 ? 1 : (fragmentCount + 1)/ 2);
-      break;
-#endif
-    default:
-      jam();
-      err = CreateFragmentationRef::InvalidFragmentationType;
-      break;
-    }
-    if(err)
-      break;
-   
     NodeGroupRecordPtr NGPtr;
     TabRecordPtr primTabPtr;
+    Uint32 count = 2;
+    Uint16 noOfReplicas = cnoReplicas;
+    Uint16 *fragments = (Uint16*)(signal->theData+25);
     if (primaryTableId == RNIL) {
-      if(fragmentNode == 0){
-        jam();
-        NGPtr.i = 0; 
-	if(noOfFragments < csystemnodes)
-	{
-	  NGPtr.i = c_nextNodeGroup; 
-	  c_nextNodeGroup = (NGPtr.i + 1 == cnoOfNodeGroups ? 0 : NGPtr.i + 1);
-	}
-      } else if(! (fragmentNode < MAX_NDB_NODES)) {
-        jam();
-        err = CreateFragmentationRef::InvalidNodeId;
-      } else {
-        jam();
-        const Uint32 stat = Sysfile::getNodeStatus(fragmentNode,
-                                                   SYSFILE->nodeStatus);
-        switch (stat) {
-        case Sysfile::NS_Active:
-        case Sysfile::NS_ActiveMissed_1:
-        case Sysfile::NS_ActiveMissed_2:
-        case Sysfile::NS_TakeOver:
+      jam();
+      switch ((DictTabInfo::FragmentType)fragType)
+      {
+        /*
+          Backward compatability and for all places in code not changed.
+        */
+        case DictTabInfo::AllNodesSmallTable:
+          jam();
+          noOfFragments = csystemnodes;
+          set_default_node_groups(signal, noOfFragments);
+          break;
+        case DictTabInfo::AllNodesMediumTable:
           jam();
+          noOfFragments = 2 * csystemnodes;
+          set_default_node_groups(signal, noOfFragments);
           break;
-        case Sysfile::NS_NotActive_NotTakenOver:
+        case DictTabInfo::AllNodesLargeTable:
           jam();
+          noOfFragments = 4 * csystemnodes;
+          set_default_node_groups(signal, noOfFragments);
           break;
-        case Sysfile::NS_HotSpare:
+        case DictTabInfo::SingleFragment:
           jam();
-        case Sysfile::NS_NotDefined:
+          noOfFragments = 1;
+          set_default_node_groups(signal, noOfFragments);
+          break;
+        case DictTabInfo::DistrKeyHash:
+          jam();
+        case DictTabInfo::DistrKeyLin:
           jam();
+          if (noOfFragments == 0)
+          {
+            jam();
+            noOfFragments = csystemnodes;
+            set_default_node_groups(signal, noOfFragments);
+          }
+          break;
         default:
           jam();
-          err = CreateFragmentationRef::InvalidNodeType;
+          if (noOfFragments == 0)
+          {
+            jam();
+            err = CreateFragmentationRef::InvalidFragmentationType;
+          }
           break;
+      }
+      if (err)
+        break;
+      /*
+        When we come here the the exact partition is specified
+        and there is an array of node groups sent along as well.
+      */
+      memcpy(&node_group_id[0], &signal->theData[25], 2 * noOfFragments);
+      Uint16 next_replica_node[MAX_NDB_NODES];
+      memset(next_replica_node,0,sizeof(next_replica_node));
+      Uint32 default_node_group= c_nextNodeGroup;
+      for(Uint32 fragNo = 0; fragNo < noOfFragments; fragNo++)
+      {
+        jam();
+        NGPtr.i = node_group_id[fragNo];
+        if (NGPtr.i == UNDEF_NODEGROUP)
+        {
+          jam();
+	  NGPtr.i = default_node_group; 
         }
-        if(err)
+        if (NGPtr.i > cnoOfNodeGroups)
+        {
+          jam();
+          err = CreateFragmentationRef::InvalidNodeGroup;
           break;
-        NGPtr.i = Sysfile::getNodeGroup(fragmentNode,
-                                        SYSFILE->nodeGroups);
+        }
+        ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
+        const Uint32 max = NGPtr.p->nodeCount;
+	
+	Uint32 tmp= next_replica_node[NGPtr.i];
+        for(Uint32 replicaNo = 0; replicaNo < noOfReplicas; replicaNo++)
+        {
+          jam();
+          const Uint16 nodeId = NGPtr.p->nodesInGroup[tmp];
+          fragments[count++]= nodeId;
+          inc_node_or_group(tmp, max);
+        }
+        inc_node_or_group(tmp, max);
+	next_replica_node[NGPtr.i]= tmp;
+	
+        /**
+         * Next node group for next fragment
+         */
+        inc_node_or_group(default_node_group, cnoOfNodeGroups);
+      }
+      if (err)
+      {
+        jam();
         break;
       }
+      else
+      {
+        jam();
+        c_nextNodeGroup = default_node_group;
+      }
     } else {
       if (primaryTableId >= ctabFileSize) {
         jam();
@@ -6323,49 +6375,14 @@
         err = CreateFragmentationRef::InvalidPrimaryTable;
         break;
       }
-      if (noOfFragments != primTabPtr.p->totalfragments) {
-        jam();
-        err = CreateFragmentationRef::InvalidFragmentationType;
-        break;
-      }
-    }
-    
-    Uint32 count = 2;
-    Uint16 *fragments = (Uint16*)(signal->theData+25);
-    if (primaryTableId == RNIL) {
-      jam();
-      Uint8 next_replica_node[MAX_NDB_NODES];
-      memset(next_replica_node,0,sizeof(next_replica_node));
-      for(Uint32 fragNo = 0; fragNo<noOfFragments; fragNo++){
-        jam();
-        ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);      
-        const Uint32 max = NGPtr.p->nodeCount;
-	
-	Uint32 tmp= next_replica_node[NGPtr.i];
-        for(Uint32 replicaNo = 0; replicaNo<noOfReplicas; replicaNo++)
-        {
-          jam();
-          const Uint32 nodeId = NGPtr.p->nodesInGroup[tmp++];
-          fragments[count++] = nodeId;
-          tmp = (tmp >= max ? 0 : tmp);
-        }
-	tmp++;
-	next_replica_node[NGPtr.i]= (tmp >= max ? 0 : tmp);
-	
-        /**
-         * Next node group for next fragment
-         */
-        NGPtr.i++;
-        NGPtr.i = (NGPtr.i == cnoOfNodeGroups ? 0 : NGPtr.i);
-      }
-    } else {
+      noOfFragments= primTabPtr.p->totalfragments;
       for (Uint32 fragNo = 0;
-           fragNo < primTabPtr.p->totalfragments; fragNo++) {
+           fragNo < noOfFragments; fragNo++) {
         jam();
         FragmentstorePtr fragPtr;
         ReplicaRecordPtr replicaPtr;
         getFragstore(primTabPtr.p, fragNo, fragPtr);
-        fragments[count++] = fragPtr.p->preferredPrimary;
+        fragments[count++]= fragPtr.p->preferredPrimary;
         for (replicaPtr.i = fragPtr.p->storedReplicas;
              replicaPtr.i != RNIL;
              replicaPtr.i = replicaPtr.p->nextReplica) {
@@ -6373,9 +6390,9 @@
           ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
           if (replicaPtr.p->procNode != fragPtr.p->preferredPrimary) {
             jam();
-            fragments[count++] = replicaPtr.p->procNode;
-          }//if
-        }//for
+            fragments[count++]= replicaPtr.p->procNode;
+          }
+        }
         for (replicaPtr.i = fragPtr.p->oldStoredReplicas;
              replicaPtr.i != RNIL;
              replicaPtr.i = replicaPtr.p->nextReplica) {
@@ -6383,25 +6400,26 @@
           ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
           if (replicaPtr.p->procNode != fragPtr.p->preferredPrimary) {
             jam();
-            fragments[count++] = replicaPtr.p->procNode;
-          }//if
-        }//for
+            fragments[count++]= replicaPtr.p->procNode;
+          }
+        }
       }
     }
-    ndbrequire(count == (2 + noOfReplicas * noOfFragments)); 
+    ndbrequire(count == (2U + noOfReplicas * noOfFragments)); 
     
     CreateFragmentationConf * const conf = 
       (CreateFragmentationConf*)signal->getDataPtrSend();
     conf->senderRef = reference();
     conf->senderData = senderData;
-    conf->noOfReplicas = noOfReplicas;
-    conf->noOfFragments = noOfFragments;
+    conf->noOfReplicas = (Uint32)noOfReplicas;
+    conf->noOfFragments = (Uint32)noOfFragments;
 
-    fragments[0] = noOfReplicas;
-    fragments[1] = noOfFragments;
+    fragments[0]= noOfReplicas;
+    fragments[1]= noOfFragments;
     
     if(senderRef != 0)
     {
+      jam();
       LinearSectionPtr ptr[3];
       ptr[0].p = (Uint32*)&fragments[0];
       ptr[0].sz = (count + 1) / 2;
@@ -6413,33 +6431,17 @@
 		 ptr,
 		 1);
     }
-    else
-    {
-      // Execute direct
-      signal->theData[0] = 0;
-    }
+    // Always ACK/NACK (here ACK)
+    signal->theData[0] = 0;
     return;
   } while(false);
-
-  if(senderRef != 0)
-  {
-    CreateFragmentationRef * const ref = 
-      (CreateFragmentationRef*)signal->getDataPtrSend();
-    ref->senderRef = reference();
-    ref->senderData = senderData;
-    ref->errorCode = err;
-    sendSignal(senderRef, GSN_CREATE_FRAGMENTATION_REF, signal, 
-	       CreateFragmentationRef::SignalLength, JBB);
-  }
-  else
-  {
-    // Execute direct
-    signal->theData[0] = err;
-  }
+  // Always ACK/NACK (here NACK)
+  signal->theData[0] = err;
 }
 
 void Dbdih::execDIADDTABREQ(Signal* signal) 
 {
+  Uint32 fragType;
   jamEntry();
 
   DiAddTabReq * const req = (DiAddTabReq*)signal->getDataPtr();
@@ -6464,6 +6466,7 @@
   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
   tabPtr.p->connectrec = connectPtr.i;
   tabPtr.p->tableType = req->tableType;
+  fragType= req->fragType;
   tabPtr.p->schemaVersion = req->schemaVersion;
   tabPtr.p->primaryTableId = req->primaryTableId;
 
@@ -6500,9 +6503,33 @@
   /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
   tabPtr.p->tabStatus = TabRecord::TS_CREATING;
   tabPtr.p->storedTable = req->storedTable;
-  tabPtr.p->method = TabRecord::HASH;
   tabPtr.p->kvalue = req->kValue;
 
+  switch ((DictTabInfo::FragmentType)fragType)
+  {
+    case DictTabInfo::AllNodesSmallTable:
+    case DictTabInfo::AllNodesMediumTable:
+    case DictTabInfo::AllNodesLargeTable:
+    case DictTabInfo::SingleFragment:
+      jam();
+    case DictTabInfo::DistrKeyLin:
+      jam();
+      tabPtr.p->method= TabRecord::LINEAR_HASH;
+      break;
+    case DictTabInfo::DistrKeyHash:
+    case DictTabInfo::DistrKeyUniqueHashIndex:
+    case DictTabInfo::DistrKeyOrderedIndex:
+      jam();
+      tabPtr.p->method= TabRecord::NORMAL_HASH;
+      break;
+    case DictTabInfo::UserDefined:
+      jam();
+      tabPtr.p->method= TabRecord::USER_DEFINED;
+      break;
+    default:
+      ndbrequire(false);
+  }
+
   union {
     Uint16 fragments[2 + MAX_FRAG_PER_NODE*MAX_REPLICAS*MAX_NDB_NODES];
     Uint32 align;
@@ -6937,17 +6964,40 @@
   tabPtr.i = req->tableId;
   Uint32 hashValue = req->hashValue;
   Uint32 ttabFileSize = ctabFileSize;
+  Uint32 fragId;
+  DiGetNodesConf * const conf = (DiGetNodesConf *)&signal->theData[0];
   TabRecord* regTabDesc = tabRecord;
   jamEntry();
   ptrCheckGuard(tabPtr, ttabFileSize, regTabDesc);
-  Uint32 fragId = hashValue & tabPtr.p->mask;
-  ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
-  if (fragId < tabPtr.p->hashpointer) {
+  if (tabPtr.p->method == TabRecord::LINEAR_HASH)
+  {
     jam();
-    fragId = hashValue & ((tabPtr.p->mask << 1) + 1);
-  }//if
+    fragId = hashValue & tabPtr.p->mask;
+    ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
+    if (fragId < tabPtr.p->hashpointer) {
+      jam();
+      fragId = hashValue & ((tabPtr.p->mask << 1) + 1);
+    }//if
+  }
+  else if (tabPtr.p->method == TabRecord::NORMAL_HASH)
+  {
+    jam();
+    fragId= hashValue % tabPtr.p->totalfragments;
+  }
+  else
+  {
+    jam();
+    ndbassert(tabPtr.p->method == TabRecord::USER_DEFINED);
+    fragId= hashValue;
+    if (fragId >= tabPtr.p->totalfragments)
+    {
+      jam();
+      conf->zero= 1; //Indicate error;
+      signal->theData[1]= ZUNDEFINED_FRAGMENT_ERROR;
+      return;
+    }
+  }
   getFragstore(tabPtr.p, fragId, fragPtr);
-  DiGetNodesConf * const conf = (DiGetNodesConf *)&signal->theData[0];
   Uint32 nodeCount = extractNodeInfo(fragPtr.p, conf->nodes);
   Uint32 sig2 = (nodeCount - 1) + 
     (fragPtr.p->distributionKey << 16);
@@ -7903,9 +7953,12 @@
     
     SubGcpCompleteRep * const rep = (SubGcpCompleteRep*)signal->getDataPtr();
     rep->gci = coldgcp;
-    rep->senderData = 0;
     sendSignal(SUMA_REF, GSN_SUB_GCP_COMPLETE_REP, signal, 
 	       SubGcpCompleteRep::SignalLength, JBB);
+
+    EXECUTE_DIRECT(LGMAN, GSN_SUB_GCP_COMPLETE_REP, signal, 
+		   SubGcpCompleteRep::SignalLength);
+    jamEntry();
   }
   
   jam();
@@ -8472,8 +8525,7 @@
   rf.rwfTabPtr.p->hashpointer = readPageWord(&rf);
   rf.rwfTabPtr.p->kvalue = readPageWord(&rf);
   rf.rwfTabPtr.p->mask = readPageWord(&rf);
-  ndbrequire(readPageWord(&rf) == TabRecord::HASH);
-  rf.rwfTabPtr.p->method = TabRecord::HASH;
+  rf.rwfTabPtr.p->method = (TabRecord::Method)readPageWord(&rf);
   /* ---------------------------------- */
   /* Type of table, 2 = temporary table */
   /* ---------------------------------- */
@@ -8567,7 +8619,7 @@
   writePageWord(&wf, tabPtr.p->hashpointer);
   writePageWord(&wf, tabPtr.p->kvalue);
   writePageWord(&wf, tabPtr.p->mask);
-  writePageWord(&wf, TabRecord::HASH);
+  writePageWord(&wf, tabPtr.p->method);
   writePageWord(&wf, tabPtr.p->storedTable);
 
   signal->theData[0] = DihContinueB::ZPACK_FRAG_INTO_PAGES;
@@ -11091,6 +11143,7 @@
   cnoHotSpare = 0;
   cnoOfActiveTables = 0;
   cnoOfNodeGroups = 0;
+  c_nextNodeGroup = 0;
   cnoReplicas = 0;
   coldgcp = 0;
   coldGcpId = 0;
@@ -11190,6 +11243,8 @@
     SYSFILE->takeOver[i] = 0;
   }//for
   Sysfile::setInitialStartOngoing(SYSFILE->systemRestartBits);
+  srand(time(0));
+  globalData.m_restart_seq = SYSFILE->m_restart_seq = 0;
 }//Dbdih::initRestartInfo()
 
 /*--------------------------------------------------------------------*/

--- 1.32.5.1/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2005-12-13 11:51:01 +01:00
+++ 1.41/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2005-12-13 12:05:23 +01:00
@@ -20,6 +20,7 @@
 #include <pc.hpp>
 #include <ndb_limits.h>
 #include <SimulatedBlock.hpp>
+#include <SLList.hpp>
 #include <DLList.hpp>
 #include <DLFifoList.hpp>
 #include <DLHashTable.hpp>
@@ -30,7 +31,9 @@
 #include <signaldata/LqhFrag.hpp>
 
 // primary key is stored in TUP
-#include <../dbtup/Dbtup.hpp>
+#include "../dbtup/Dbtup.hpp"
+
+#include "../dbacc/Dbacc.hpp"
 
 #ifdef DBLQH_C
 // Constants
@@ -230,7 +233,6 @@
 #define ZSCAN_TC_CONNECT 13
 #define ZINITIALISE_RECORDS 14
 #define ZINIT_GCP_REC 15
-#define ZRESTART_OPERATIONS_AFTER_STOP 16
 #define ZCHECK_LCP_STOP_BLOCKED 17
 #define ZSCAN_MARKERS 18
 #define ZOPERATION_EVENT_REP 19
@@ -418,24 +420,18 @@
   enum ExecUndoLogState {
     EULS_IDLE = 0,
     EULS_STARTED = 1,
-    EULS_COMPLETED = 2,
-    EULS_ACC_COMPLETED = 3,
-    EULS_TUP_COMPLETED = 4
+    EULS_COMPLETED = 2
   };
 
   struct AddFragRecord {
     enum AddFragStatus {
       FREE = 0,
       ACC_ADDFRAG = 1,
-      WAIT_TWO_TUP = 2,
-      WAIT_ONE_TUP = 3,
-      WAIT_TWO_TUX = 4,
-      WAIT_ONE_TUX = 5,
+      WAIT_TUP = 3,
+      WAIT_TUX = 5,
       WAIT_ADD_ATTR = 6,
-      TUP_ATTR_WAIT1 = 7,
-      TUP_ATTR_WAIT2 = 8,
-      TUX_ATTR_WAIT1 = 9,
-      TUX_ATTR_WAIT2 = 10
+      TUP_ATTR_WAIT = 7,
+      TUX_ATTR_WAIT = 9
     };
     LqhAddAttrReq::Entry attributes[LqhAddAttrReq::MAX_ATTRIBUTES];
     UintR accConnectptr;
@@ -445,10 +441,8 @@
     UintR nextAddfragrec;
     UintR noOfAllocPages;
     UintR schemaVer;
-    UintR tup1Connectptr;
-    UintR tup2Connectptr;
-    UintR tux1Connectptr;
-    UintR tux2Connectptr;
+    UintR tupConnectptr;
+    UintR tuxConnectptr;
     UintR checksumIndicator;
     UintR GCPIndicator;
     BlockReference dictBlockref;
@@ -457,8 +451,6 @@
     Uint16 attrSentToTup;
     Uint16 attrReceived;
     Uint16 addFragid;
-    Uint16 fragid1;
-    Uint16 fragid2;
     Uint16 noOfAttr;
     Uint16 noOfNull;
     Uint16 tabId;
@@ -470,6 +462,7 @@
     Uint16 lh3DistrBits;
     Uint16 tableType;
     Uint16 primaryTableId;
+    Uint32 tablespace_id;
   };// Size 108 bytes
   typedef Ptr<AddFragRecord> AddFragRecordPtr;
   
@@ -595,6 +588,8 @@
   typedef Ptr<ScanRecord> ScanRecordPtr;
 
   struct Fragrecord {
+    Fragrecord() {}
+
     enum ExecSrStatus {
       IDLE = 0,
       ACTIVE_REMOVE_AFTER = 1,
@@ -695,7 +690,7 @@
     /**
      *       The fragment pointers in ACC
      */
-    UintR accFragptr[2];
+    UintR accFragptr;
     /**
      *       The EXEC_SR variables are used to keep track of which fragments  
      *       that are interested in being executed as part of executing the    
@@ -725,54 +720,38 @@
     /**
      *       The fragment pointers in TUP and TUX
      */
-    UintR tupFragptr[2];
-    UintR tuxFragptr[2];
-    /**
-     *       This queue is where operations are put when blocked in ACC
-     *       during start of a local chkp.
-     */
-    UintR accBlockedList;
-    /**
-     *       This is the queue where all operations that are active on the     
-     *       fragment is put. 
-     *       This is used to deduct when the fragment do 
-     *       no longer contain any active operations. 
-     *       This is needed when starting a local checkpoint.
-     */
-    UintR activeList;
+    UintR tupFragptr;
+    UintR tuxFragptr;
+
     /**
      *       This variable keeps track of how many operations that are 
      *       active that have skipped writing the log but not yet committed 
      *       or aborted.  This is used during start of fragment.
      */
     UintR activeTcCounter;
+
     /**
      *       This status specifies whether this fragment is actively 
      *       engaged in executing the fragment log.
      */
     ExecSrStatus execSrStatus;
+
     /**
      *       The fragment id of this fragment.
      */
     UintR fragId;
+
     /**
      *       Status of fragment
      */
     FragStatus fragStatus;
+
     /**
      *       Indicates a local checkpoint is active and thus can generate
      *       UNDO log records.
      */
     UintR fragActiveStatus;
-    /**
-     *       Reference to current LCP record. 
-     *       If no LCP is ongoing on the fragment then the value is RNIL.
-     *       If LCP_REF /= RNIL then a local checkpoint is ongoing in the 
-     *       fragment.
-     *       LCP_STATE in LCP_RECORD specifies the state of the 
-     *       local checkpoint.
-     */
-    UintR lcpRef;
+
     /**
      *       This flag indicates whether logging is currently activated at 
      *       the fragment.  
@@ -789,7 +768,12 @@
      *       Reference to the next fragment record in a free list of fragment 
      *       records.              
      */
-    UintR nextFrag;
+    union {
+      Uint32 nextPool;
+      Uint32 nextList;
+    };
+    Uint32 prevList;
+    
     /**
      *       The newest GCI that has been committed on fragment             
      */
@@ -804,18 +788,21 @@
      *       A reference to the table owning this fragment.
      */
     UintR tabRef;
+
     /**
      *       This is the queue to put operations that have been blocked 
      *       during start of a local chkp.
      */
     UintR firstWaitQueue;
     UintR lastWaitQueue;
+
     /**
      *       The block reference to ACC on the fragment makes it
      *       possible to have different ACC blocks for different
      *       fragments in the future.
      */
     BlockReference accBlockref;
+
     /**
      *       Ordered index block.
      */
@@ -969,6 +956,36 @@
   typedef Ptr<HostRecord> HostRecordPtr;
   
   /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
+  /* $$$$$$               LOCAL CHECKPOINT SUPPORT RECORD            $$$$$$$ */
+  /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
+  /**
+   *      This record contains the information about an outstanding
+   *      request to TUP or ACC. Used for both local checkpoints and
+   *      system restart.
+   */
+  struct LcpLocRecord {
+    enum LcpLocstate {
+      IDLE = 0,
+      WAIT_TUP_PREPLCP = 1,
+      WAIT_LCPHOLDOP = 2,
+      HOLDOP_READY = 3,
+      ACC_WAIT_STARTED = 4,
+      ACC_STARTED = 5,
+      ACC_COMPLETED = 6,
+      TUP_WAIT_STARTED = 7,
+      TUP_STARTED = 8,
+      TUP_COMPLETED = 9,
+      SR_ACC_STARTED = 10,
+      SR_TUP_STARTED = 11,
+      SR_ACC_COMPLETED = 12,
+      SR_TUP_COMPLETED = 13
+    };
+    LcpLocstate lcpLocstate;
+    Uint32 lcpRef;
+  }; // 28 bytes
+  typedef Ptr<LcpLocRecord> LcpLocRecordPtr;
+
+  /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
   /* $$$$$$$              LOCAL CHECKPOINT RECORD                    $$$$$$$ */
   /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
   /** 
@@ -985,18 +1002,17 @@
       LCP_WAIT_FRAGID = 3,
       LCP_WAIT_TUP_PREPLCP = 4,
       LCP_WAIT_HOLDOPS = 5,
-      LCP_WAIT_ACTIVE_FINISH = 6,
       LCP_START_CHKP = 7,
       LCP_BLOCKED_COMP = 8,
       LCP_SR_WAIT_FRAGID = 9,
       LCP_SR_STARTED = 10,
       LCP_SR_COMPLETED = 11
     };
-    Uint32 firstLcpLocAcc;
-    Uint32 firstLcpLocTup;
-    Uint32 lcpAccptr;
+    LcpLocRecord m_acc;
+    LcpLocRecord m_tup;
  
     LcpState lcpState;
+    bool firstFragmentFlag;
     bool lastFragmentFlag;
 
     struct FragOrd {
@@ -1010,50 +1026,11 @@
     
     bool   reportEmpty;
     NdbNodeBitmask m_EMPTY_LCP_REQ;
+
+    Uint32 m_outstanding;
   }; // Size 76 bytes
   typedef Ptr<LcpRecord> LcpRecordPtr;
-  
-  /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
-  /* $$$$$$               LOCAL CHECKPOINT SUPPORT RECORD            $$$$$$$ */
-  /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
-  /**
-   *      This record contains the information about an outstanding
-   *      request to TUP or ACC. Used for both local checkpoints and
-   *      system restart.
-   */
-  struct LcpLocRecord {
-    enum LcpLocstate {
-      IDLE = 0,
-      WAIT_TUP_PREPLCP = 1,
-      WAIT_LCPHOLDOP = 2,
-      HOLDOP_READY = 3,
-      ACC_WAIT_STARTED = 4,
-      ACC_STARTED = 5,
-      ACC_COMPLETED = 6,
-      TUP_WAIT_STARTED = 7,
-      TUP_STARTED = 8,
-      TUP_COMPLETED = 9,
-      SR_ACC_STARTED = 10,
-      SR_TUP_STARTED = 11,
-      SR_ACC_COMPLETED = 12,
-      SR_TUP_COMPLETED = 13
-    };
-    enum WaitingBlock {
-      ACC = 0,
-      TUP = 1,
-      NONE = 2
-    };
     
-    LcpLocstate lcpLocstate;
-    UintR locFragid;
-    UintR masterLcpRec;
-    UintR nextLcpLoc;
-    UintR tupRef;
-    WaitingBlock waitingBlock;
-    Uint32 accContCounter;
-  }; // 28 bytes
-  typedef Ptr<LcpLocRecord> LcpLocRecordPtr;
-  
   /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
   /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
   /*                                                                          */
@@ -1874,6 +1851,7 @@
     Uint16 tableType;
     Uint16 primaryTableId;
     Uint32 schemaVersion;
+    Uint8 m_disk_table;
 
     Uint32 usageCount;
     NdbNodeBitmask waitingTC;
@@ -1884,8 +1862,6 @@
   struct TcConnectionrec {
     enum ListState {
       NOT_IN_LIST = 0,
-      IN_ACTIVE_LIST = 1,
-      ACC_BLOCK_LIST = 2,
       WAIT_QUEUE_LIST = 3
     };
     enum LogWriteState {
@@ -1925,6 +1901,7 @@
       LOG_COMMIT_QUEUED = 11,
       COMMIT_QUEUED = 12,
       COMMITTED = 13,
+      WAIT_TUP_COMMIT= 35,
       
       /* -------------------------------------------------------------------- */
       // Abort in progress states
@@ -2041,7 +2018,6 @@
     Uint8 dirtyOp;
     Uint8 indTakeOver;
     Uint8 lastReplicaNo;
-    Uint8 localFragptr;
     Uint8 lockType;
     Uint8 nextSeqNoReplica;
     Uint8 opSimple;
@@ -2053,6 +2029,8 @@
     Uint8 simpleRead;
     Uint8 seqNoReplica;
     Uint8 tcNodeFailrec;
+    Uint8 m_disk_table;
+    Uint32 m_local_key;
   }; /* p2c: size = 280 bytes */
   
   typedef Ptr<TcConnectionrec> TcConnectionrecPtr;
@@ -2083,6 +2061,9 @@
 public:
   Dblqh(const class Configuration &);
   virtual ~Dblqh();
+
+  void receive_keyinfo(Signal*, Uint32 * data, Uint32 len);
+  void receive_attrinfo(Signal*, Uint32 * data, Uint32 len);
   
 private:
   BLOCK_DEFINES(Dblqh);
@@ -2107,7 +2088,11 @@
   void execSTART_EXEC_SR(Signal* signal);
   void execEXEC_SRREQ(Signal* signal);
   void execEXEC_SRCONF(Signal* signal);
-  void execREAD_PSUEDO_REQ(Signal* signal);
+  void execREAD_PSEUDO_REQ(Signal* signal);
+
+  void build_acc(Signal*, Uint32 fragPtrI);
+  void execBUILDINDXREF(Signal*signal);
+  void execBUILDINDXCONF(Signal*signal);
   
   void execDUMP_STATE_ORD(Signal* signal);
   void execACC_COM_BLOCK(Signal* signal);
@@ -2161,32 +2146,13 @@
   void execLQH_TRANSREQ(Signal* signal);
   void execTRANSID_AI(Signal* signal);
   void execINCL_NODEREQ(Signal* signal);
-  void execACC_LCPCONF(Signal* signal);
-  void execACC_LCPREF(Signal* signal);
-  void execACC_LCPSTARTED(Signal* signal);
-  void execACC_CONTOPCONF(Signal* signal);
-  void execLCP_FRAGIDCONF(Signal* signal);
-  void execLCP_FRAGIDREF(Signal* signal);
-  void execLCP_HOLDOPCONF(Signal* signal);
-  void execLCP_HOLDOPREF(Signal* signal);
-  void execTUP_PREPLCPCONF(Signal* signal);
-  void execTUP_PREPLCPREF(Signal* signal);
-  void execTUP_LCPCONF(Signal* signal);
-  void execTUP_LCPREF(Signal* signal);
-  void execTUP_LCPSTARTED(Signal* signal);
-  void execEND_LCPCONF(Signal* signal);
 
   void execLCP_FRAG_ORD(Signal* signal);
   void execEMPTY_LCP_REQ(Signal* signal);
   
   void execSTART_FRAGREQ(Signal* signal);
   void execSTART_RECREF(Signal* signal);
-  void execSR_FRAGIDCONF(Signal* signal);
-  void execSR_FRAGIDREF(Signal* signal);
-  void execACC_SRCONF(Signal* signal);
-  void execACC_SRREF(Signal* signal);
-  void execTUP_SRCONF(Signal* signal);
-  void execTUP_SRREF(Signal* signal);
+
   void execGCP_SAVEREQ(Signal* signal);
   void execFSOPENCONF(Signal* signal);
   void execFSCLOSECONF(Signal* signal);
@@ -2251,17 +2217,13 @@
   void sendCompleteLqh(Signal* signal, BlockReference alqhBlockref);
   void sendPackedSignalLqh(Signal* signal, HostRecord * ahostptr);
   void sendPackedSignalTc(Signal* signal, HostRecord * ahostptr);
-  Uint32 handleLongTupKey(Signal* signal,
-                          Uint32 lenSofar,
-                          Uint32 primKeyLen,
-                          Uint32* dataPtr);
   void cleanUp(Signal* signal);
   void sendAttrinfoLoop(Signal* signal);
   void sendAttrinfoSignal(Signal* signal);
   void sendLqhAttrinfoSignal(Signal* signal);
   void sendKeyinfoAcc(Signal* signal, Uint32 pos);
   Uint32 initScanrec(const class ScanFragReq *);
-  void initScanTc(Signal* signal,
+  void initScanTc(const class ScanFragReq *,
                   Uint32 transid1,
                   Uint32 transid2,
                   Uint32 fragId,
@@ -2281,8 +2243,6 @@
   void getNextFragForLcp(Signal* signal);
   void initLcpLocAcc(Signal* signal, Uint32 fragId);
   void initLcpLocTup(Signal* signal, Uint32 fragId);
-  void moveAccActiveFrag(Signal* signal);
-  void moveActiveToAcc(Signal* signal);
   void releaseLocalLcps(Signal* signal);
   void seizeLcpLoc(Signal* signal);
   void sendAccContOp(Signal* signal);
@@ -2361,7 +2321,6 @@
   void initLogPointers(Signal* signal);
   void initReqinfoExecSr(Signal* signal);
   bool insertFragrec(Signal* signal, Uint32 fragId);
-  void linkActiveFrag(Signal* signal);
   void linkFragQueue(Signal* signal);
   void linkWaitLog(Signal* signal, LogPartRecordPtr regLogPartPtr);
   void logNextStart(Signal* signal);
@@ -2377,10 +2336,7 @@
   Uint32 readLogword(Signal* signal);
   Uint32 readLogwordExec(Signal* signal);
   void readSinglePage(Signal* signal, Uint32 pageNo);
-  void releaseAccList(Signal* signal);
   void releaseActiveCopy(Signal* signal);
-  void releaseActiveFrag(Signal* signal);
-  void releaseActiveList(Signal* signal);
   void releaseAddfragrec(Signal* signal);
   void releaseFragrec();
   void releaseLcpLoc(Signal* signal);
@@ -2429,6 +2385,7 @@
   void readFileInInvalidate(Signal *signal);
   void exitFromInvalidate(Signal* signal);
   Uint32 calcPageCheckSum(LogPageRecordPtr logP);
+  Uint32 handleLongTupKey(Signal* signal, Uint32* dataPtr, Uint32 len);
 
   // Generated statement blocks
   void systemErrorLab(Signal* signal, int line);
@@ -2469,7 +2426,7 @@
   void completeTransNotLastLab(Signal* signal);
   void completedLab(Signal* signal);
   void copyCompletedLab(Signal* signal);
-  void completeLcpRoundLab(Signal* signal);
+  void completeLcpRoundLab(Signal* signal, Uint32 lcpId);
   void continueAfterLogAbortWriteLab(Signal* signal);
   void sendAttrinfoLab(Signal* signal);
   void sendExecConf(Signal* signal);
@@ -2561,7 +2518,6 @@
   void restartOperationsLab(Signal* signal);
   void lqhTransNextLab(Signal* signal);
   void restartOperationsAfterStopLab(Signal* signal);
-  void sttorStartphase1Lab(Signal* signal);
   void startphase1Lab(Signal* signal, Uint32 config, Uint32 nodeId);
   void tupkeyConfLab(Signal* signal);
   void copyTupkeyConfLab(Signal* signal);
@@ -2584,8 +2540,49 @@
   void initData();
   void initRecords();
 
+  void define_backup(Signal*);
+  void execDEFINE_BACKUP_REF(Signal*);
+  void execDEFINE_BACKUP_CONF(Signal*);
+  void execBACKUP_FRAGMENT_REF(Signal* signal);
+  void execBACKUP_FRAGMENT_CONF(Signal* signal);
+  void execLCP_PREPARE_REF(Signal* signal);
+  void execLCP_PREPARE_CONF(Signal* signal);
+  void execEND_LCPREF(Signal* signal);
+  void execEND_LCPCONF(Signal* signal);
+  Uint32 m_backup_ptr;
+
+  void send_restore_lcp(Signal * signal);
+  void execRESTORE_LCP_REF(Signal* signal);
+  void execRESTORE_LCP_CONF(Signal* signal);
+  
   Dbtup* c_tup;
+  Dbacc* c_acc;
   Uint32 readPrimaryKeys(ScanRecord*, TcConnectionrec*, Uint32 * dst);
+
+  void acckeyconf_tupkeyreq(Signal*, TcConnectionrec*, Fragrecord*, Uint32, Uint32);
+  void acckeyconf_load_diskpage(Signal*,TcConnectionrecPtr,Fragrecord*,Uint32);
+
+public:
+  void acckeyconf_load_diskpage_callback(Signal*, Uint32, Uint32);
+
+private:
+  void next_scanconf_load_diskpage(Signal* signal, 
+				   ScanRecordPtr scanPtr,
+				   Ptr<TcConnectionrec> regTcPtr,
+				   Fragrecord* fragPtrP);
+  
+  void next_scanconf_tupkeyreq(Signal* signal, ScanRecordPtr,
+			       TcConnectionrec * regTcPtr,
+			       Fragrecord* fragPtrP,
+			       Uint32 disk_page);
+
+public:  
+  void next_scanconf_load_diskpage_callback(Signal* signal, Uint32, Uint32);
+
+  void tupcommit_conf_callback(Signal* signal, Uint32 tcPtrI);
+private:
+  void tupcommit_conf(Signal* signal, TcConnectionrec *,Fragrecord *);
+  
 // ----------------------------------------------------------------
 // These are variables handling the records. For most records one
 // pointer to the array of structs, one pointer-struct, a file size
@@ -2622,10 +2619,8 @@
   UintR cdatabufFileSize;
 
 // Configurable
-  Fragrecord *fragrecord;
   FragrecordPtr fragptr;
-  UintR cfirstfreeFragrec;
-  UintR cfragrecFileSize;
+  ArrayPool<Fragrecord> c_fragment_pool;
 
 #define ZGCPREC_FILE_SIZE 1
   GcpRecord *gcpRecord;
@@ -2642,11 +2637,6 @@
   UintR cfirstfreeLcpLoc;
   UintR clcpFileSize;
 
-#define ZLCP_LOCREC_FILE_SIZE 4
-  LcpLocRecord *lcpLocRecord;
-  LcpLocRecordPtr lcpLocptr;
-  UintR clcpLocrecFileSize;
-
 #define ZLOG_PART_FILE_SIZE 4
   LogPartRecord *logPartRecord;
   LogPartRecordPtr logPartPtr;
@@ -2777,17 +2767,10 @@
 /*THIS VARIABLE IS THE HEAD OF A LINKED LIST OF FRAGMENTS WAITING TO BE      */
 /*RESTORED FROM DISK.                                                        */
 /* ------------------------------------------------------------------------- */
-  UintR cfirstWaitFragSr;
-/* ------------------------------------------------------------------------- */
-/*THIS VARIABLE IS THE HEAD OF A LINKED LIST OF FRAGMENTS THAT HAVE BEEN     */
-/*RESTORED FROM DISK THAT AWAITS EXECUTION OF THE FRAGMENT LOG.              */
-/* ------------------------------------------------------------------------- */
-  UintR cfirstCompletedFragSr;
-
-  /**
-   * List of fragment that the log execution is completed for
-   */
-  Uint32 c_redo_log_complete_frags;
+  DLList<Fragrecord> c_lcp_waiting_fragments;  // StartFragReq'ed
+  DLList<Fragrecord> c_lcp_restoring_fragments; // Restoring as we speek
+  DLList<Fragrecord> c_lcp_complete_fragments;  // Restored
+  DLList<Fragrecord> c_redo_complete_fragments; // Redo'ed
   
 /* ------------------------------------------------------------------------- */
 /*USED DURING SYSTEM RESTART, INDICATES THE OLDEST GCI THAT CAN BE RESTARTED */
@@ -2888,6 +2871,10 @@
   Uint32 c_error_insert_table_id;
   
 public:
+  bool is_same_trans(Uint32 opId, Uint32 trid1, Uint32 trid2);
+  void get_op_info(Uint32 opId, Uint32 *hash, Uint32* gci);
+  void accminupdate(Signal*, Uint32 opPtrI, const Local_key*);
+
   /**
    *
    */
@@ -2963,5 +2950,42 @@
     acc_ptr= (Uint32*)&regAttrPtr.p->attrbuf[attr_buf_index];
   }
 }
+
+inline
+bool
+Dblqh::is_same_trans(Uint32 opId, Uint32 trid1, Uint32 trid2)
+{
+  TcConnectionrecPtr regTcPtr;  
+  regTcPtr.i= opId;
+  ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec);
+  return ((regTcPtr.p->transid[0] == trid1) &&
+          (regTcPtr.p->transid[1] == trid2));
+}
+
+inline
+void
+Dblqh::get_op_info(Uint32 opId, Uint32 *hash, Uint32* gci)
+{
+  TcConnectionrecPtr regTcPtr;  
+  regTcPtr.i= opId;
+  ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec);
+  *hash= regTcPtr.p->hashValue;
+  *gci= regTcPtr.p->gci;
+}
+
+#include "../dbacc/Dbacc.hpp"
+
+inline
+void
+Dblqh::accminupdate(Signal* signal, Uint32 opId, const Local_key* key)
+{
+  TcConnectionrecPtr regTcPtr;  
+  regTcPtr.i= opId;
+  ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec);
+  signal->theData[0] = regTcPtr.p->accConnectrec;
+  signal->theData[1] = key->m_page_no << MAX_TUPLES_BITS | key->m_page_idx;
+  c_acc->execACCMINUPDATE(signal);
+}
+
 
 #endif

--- 1.66.9.1/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2005-12-13 11:54:40 +01:00
+++ 1.81/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2005-12-13 12:05:23 +01:00
@@ -53,8 +53,14 @@
 #include <signaldata/DropTab.hpp>
 
 #include <signaldata/AlterTab.hpp>
+#include <signaldata/DictTabInfo.hpp>
 
 #include <signaldata/LCP.hpp>
+#include <DebuggerNames.hpp>
+#include <signaldata/BackupImpl.hpp>
+#include <signaldata/RestoreImpl.hpp>
+#include <signaldata/KeyInfo.hpp>
+#include <signaldata/AttrInfo.hpp>
 #include <KeyDescriptor.hpp>
 
 // Use DEBUG to print messages that should be
@@ -235,7 +241,7 @@
     tcConnectptr.i = logPartPtr.p->firstLogQueue;
     ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
     fragptr.i = tcConnectptr.p->fragmentptr;
-    ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+    c_fragment_pool.getPtr(fragptr);
     if ((cCommitBlocked == true) &&
         (fragptr.p->fragActiveStatus == ZTRUE)) {
       jam();
@@ -389,26 +395,13 @@
     initGcpRecLab(signal);
     return;
     break;
-  case ZRESTART_OPERATIONS_AFTER_STOP:
-    jam();
-    tcConnectptr.i = data0;
-    ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
-    if (tcConnectptr.p->listState != TcConnectionrec::WAIT_QUEUE_LIST) {
-      jam();
-      return;
-    }//if
-    releaseWaitQueue(signal);
-    linkActiveFrag(signal);
-    restartOperationsAfterStopLab(signal);
-    return;
-    break;
   case ZCHECK_LCP_STOP_BLOCKED:
     jam();
     c_scanRecordPool.getPtr(scanptr, data0);
     tcConnectptr.i = scanptr.p->scanTcrec;
     ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
     fragptr.i = tcConnectptr.p->fragmentptr;
-    ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+    c_fragment_pool.getPtr(fragptr);
     checkLcpStopBlockedLab(signal);
     return;
   case ZSCAN_MARKERS:
@@ -492,11 +485,16 @@
   case ZSTART_PHASE1:
     jam();
     cstartPhase = tstartPhase;
-    sttorStartphase1Lab(signal);
     c_tup = (Dbtup*)globalData.getBlock(DBTUP);
-    ndbrequire(c_tup != 0);
+    c_acc = (Dbacc*)globalData.getBlock(DBACC);
+    ndbrequire(c_tup != 0 && c_acc != 0);
+    sendsttorryLab(signal);
     return;
     break;
+  case 4:
+    jam();
+    define_backup(signal);
+    break;
   default:
     jam();
     /*empty*/;
@@ -506,6 +504,42 @@
   }//switch
 }//Dblqh::execSTTOR()
 
+void
+Dblqh::define_backup(Signal* signal)
+{
+  DefineBackupReq * req = (DefineBackupReq*)signal->getDataPtrSend();
+  req->backupId = 0;
+  req->clientRef = 0;
+  req->clientData = 0;
+  req->senderRef = reference();
+  req->backupPtr = 0;
+  req->backupKey[0] = 0;
+  req->backupKey[1] = 0;
+  req->nodes.clear();
+  req->nodes.set(getOwnNodeId());
+  req->backupDataLen = ~0;
+
+  sendSignal(BACKUP_REF, GSN_DEFINE_BACKUP_REQ, signal, 
+	     DefineBackupReq::SignalLength, JBB);
+}
+
+void
+Dblqh::execDEFINE_BACKUP_REF(Signal* signal)
+{
+  jamEntry();
+  m_backup_ptr = RNIL;
+  sendsttorryLab(signal);
+}
+
+void
+Dblqh::execDEFINE_BACKUP_CONF(Signal* signal)
+{
+  jamEntry();
+  DefineBackupConf * conf = (DefineBackupConf*)signal->getDataPtrSend();
+  m_backup_ptr = conf->backupPtr;
+  sendsttorryLab(signal);
+}
+
 /* ***************************************> */
 /*  Restart phases 1 - 6, sender is Ndbcntr */
 /* ***************************************> */
@@ -571,21 +605,11 @@
   }//switch
 }//Dblqh::execNDB_STTOR()
 
-/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
-/* +++++++                     START PHASE 1                          +++++++ */
-/*               LOAD OUR BLOCK REFERENCE AND OUR PROCESSOR ID                */
-/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
-void Dblqh::sttorStartphase1Lab(Signal* signal) 
-{
-  sendsttorryLab(signal);
-  return;
-}//Dblqh::sttorStartphase1Lab()
-
-/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
-/* +++++++                           START PHASE 2                    +++++++ */
-/*                                                                            */
-/*               INITIATE ALL RECORDS WITHIN THE BLOCK                        */
-/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+/* +++++++                         START PHASE 2                    +++++++ */
+/*                                                                          */
+/*             INITIATE ALL RECORDS WITHIN THE BLOCK                        */
+/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
 void Dblqh::startphase1Lab(Signal* signal, Uint32 _dummy, Uint32 ownNodeId) 
 {
   UintR Ti;
@@ -854,8 +878,9 @@
   signal->theData[1] = 3;          /* BLOCK CATEGORY */
   signal->theData[2] = 2;          /* SIGNAL VERSION NUMBER */
   signal->theData[3] = ZSTART_PHASE1;
-  signal->theData[4] = 255;
-  sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 5, JBB);
+  signal->theData[4] = 4;
+  signal->theData[5] = 255;
+  sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 6, JBB);
   return;
 }//Dblqh::sendsttorryLab()
 
@@ -889,7 +914,6 @@
 					&cnoLogFiles));
   ndbrequire(cnoLogFiles > 0);
 
-  ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_LQH_FRAG, &cfragrecFileSize));
   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_LQH_TABLE, &ctabrecFileSize));
   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_LQH_TC_CONNECT, 
 					&ctcConnectrecFileSize));
@@ -899,6 +923,10 @@
 
   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &c_diskless));
   
+  Uint32 tmp= 0;
+  ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_LQH_FRAG, &tmp));
+  c_fragment_pool.setSize(tmp);
+
   initRecords();
   initialiseRecordsLab(signal, 0, ref, senderData);
   
@@ -946,11 +974,11 @@
   Uint32 noOfKeyAttr = req->noOfKeyAttr;
   Uint32 noOfNewAttr = req->noOfNewAttr;
   Uint32 checksumIndicator = req->checksumIndicator;
-  Uint32 noOfAttributeGroups = req->noOfAttributeGroups;
   Uint32 gcpIndicator = req->GCPIndicator;
   Uint32 startGci = req->startGci;
   Uint32 tableType = req->tableType;
   Uint32 primaryTableId = req->primaryTableId;
+  Uint32 tablespace= req->tablespace_id;
 
   ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
   bool tempTable = ((reqinfo & LqhFragReq::TemporaryTable) != 0);
@@ -959,8 +987,10 @@
   if (tabptr.p->tableStatus == Tablerec::NOT_DEFINED){
     tabptr.p->tableStatus = Tablerec::ADD_TABLE_ONGOING;
     tabptr.p->tableType = tableType;
-    tabptr.p->primaryTableId = primaryTableId;
+    tabptr.p->primaryTableId = 
+      (primaryTableId == RNIL ? tabptr.i : primaryTableId);
     tabptr.p->schemaVersion = tschemaVersion;
+    tabptr.p->m_disk_table= 0;
   }//if
   
   if (tabptr.p->tableStatus != Tablerec::ADD_TABLE_ONGOING){
@@ -1053,16 +1083,14 @@
   addfragptr.p->noOfKeyAttr = noOfKeyAttr;
   addfragptr.p->noOfNewAttr = noOfNewAttr;
   addfragptr.p->checksumIndicator = checksumIndicator;
-  addfragptr.p->noOfAttributeGroups = noOfAttributeGroups;
   addfragptr.p->GCPIndicator = gcpIndicator;
   addfragptr.p->lh3DistrBits = tlhstar;
   addfragptr.p->tableType = tableType;
   addfragptr.p->primaryTableId = primaryTableId;
+  addfragptr.p->tablespace_id= tablespace;
   //
-  addfragptr.p->tup1Connectptr = RNIL;
-  addfragptr.p->tup2Connectptr = RNIL;
-  addfragptr.p->tux1Connectptr = RNIL;
-  addfragptr.p->tux2Connectptr = RNIL;
+  addfragptr.p->tupConnectptr = RNIL;
+  addfragptr.p->tuxConnectptr = RNIL;
 
   if (DictTabInfo::isTable(tableType) ||
       DictTabInfo::isHashIndex(tableType)) {
@@ -1080,21 +1108,18 @@
     accreq->lhFragBits = tlhstar;
     accreq->lhDirBits = tlh;
     accreq->keyLength = ttupKeyLength;
-    /* ----------------------------------------------------------------------- */
-    /* Send ACCFRAGREQ, when confirmation is received send 2 * TUPFRAGREQ to   */
-    /* create 2 tuple fragments on this node.                                  */
-    /* ----------------------------------------------------------------------- */
+    /* --------------------------------------------------------------------- */
+    /* Send ACCFRAGREQ, when confirmation is received send 2 * TUPFRAGREQ to */
+    /* create 2 tuple fragments on this node.                                */
+    /* --------------------------------------------------------------------- */
     addfragptr.p->addfragStatus = AddFragRecord::ACC_ADDFRAG;
     sendSignal(fragptr.p->accBlockref, GSN_ACCFRAGREQ,
-        signal, AccFragReq::SignalLength, JBB);
+	       signal, AccFragReq::SignalLength, JBB);
     return;
   }
   if (DictTabInfo::isOrderedIndex(tableType)) {
     jam();
-    // NOTE: next 2 lines stolen from ACC
-    addfragptr.p->fragid1 = (fragId << 1) | 0;
-    addfragptr.p->fragid2 = (fragId << 1) | 1;
-    addfragptr.p->addfragStatus = AddFragRecord::WAIT_TWO_TUP;
+    addfragptr.p->addfragStatus = AddFragRecord::WAIT_TUP;
     sendAddFragReq(signal);
     return;
   }
@@ -1109,22 +1134,17 @@
   jamEntry();
   addfragptr.i = signal->theData[0];
   Uint32 taccConnectptr = signal->theData[1];
-  Uint32 fragId1 = signal->theData[2];
-  Uint32 fragId2 = signal->theData[3];
+  //Uint32 fragId1 = signal->theData[2];
   Uint32 accFragPtr1 = signal->theData[4];
-  Uint32 accFragPtr2 = signal->theData[5];
   ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
   ndbrequire(addfragptr.p->addfragStatus == AddFragRecord::ACC_ADDFRAG);
 
   addfragptr.p->accConnectptr = taccConnectptr;
-  addfragptr.p->fragid1 = fragId1;
-  addfragptr.p->fragid2 = fragId2;
   fragptr.i = addfragptr.p->fragmentPtr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-  fragptr.p->accFragptr[0] = accFragPtr1;
-  fragptr.p->accFragptr[1] = accFragPtr2;
+  c_fragment_pool.getPtr(fragptr);
+  fragptr.p->accFragptr = accFragPtr1;
 
-  addfragptr.p->addfragStatus = AddFragRecord::WAIT_TWO_TUP;
+  addfragptr.p->addfragStatus = AddFragRecord::WAIT_TUP;
   sendAddFragReq(signal);
 }//Dblqh::execACCFRAGCONF()
 
@@ -1137,50 +1157,27 @@
   addfragptr.i = signal->theData[0];
   Uint32 tupConnectptr = signal->theData[1];
   Uint32 tupFragPtr = signal->theData[2];  /* TUP FRAGMENT POINTER */
-  Uint32 localFragId = signal->theData[3];  /* LOCAL FRAGMENT ID    */
+  //Uint32 localFragId = signal->theData[3];  /* LOCAL FRAGMENT ID    */
   ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
   fragptr.i = addfragptr.p->fragmentPtr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-  if (localFragId == addfragptr.p->fragid1) {
-    jam();
-    fragptr.p->tupFragptr[0] = tupFragPtr;
-  } else if (localFragId == addfragptr.p->fragid2) {
-    jam();
-    fragptr.p->tupFragptr[1] = tupFragPtr;
-  } else {
-    ndbrequire(false);
-    return;
-  }//if
+  c_fragment_pool.getPtr(fragptr);
+  fragptr.p->tupFragptr = tupFragPtr;
   switch (addfragptr.p->addfragStatus) {
-  case AddFragRecord::WAIT_TWO_TUP:
+  case AddFragRecord::WAIT_TUP:
     jam();
-    fragptr.p->tupFragptr[0] = tupFragPtr;
-    addfragptr.p->tup1Connectptr = tupConnectptr;
-    addfragptr.p->addfragStatus = AddFragRecord::WAIT_ONE_TUP;
-    sendAddFragReq(signal);
-    break;
-  case AddFragRecord::WAIT_ONE_TUP:
-    jam();
-    fragptr.p->tupFragptr[1] = tupFragPtr;
-    addfragptr.p->tup2Connectptr = tupConnectptr;
+    fragptr.p->tupFragptr = tupFragPtr;
+    addfragptr.p->tupConnectptr = tupConnectptr;
     if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType)) {
-      addfragptr.p->addfragStatus = AddFragRecord::WAIT_TWO_TUX;
+      addfragptr.p->addfragStatus = AddFragRecord::WAIT_TUX;
       sendAddFragReq(signal);
       break;
     }
     goto done_with_frag;
     break;
-  case AddFragRecord::WAIT_TWO_TUX:
+  case AddFragRecord::WAIT_TUX:
     jam();
-    fragptr.p->tuxFragptr[0] = tupFragPtr;
-    addfragptr.p->tux1Connectptr = tupConnectptr;
-    addfragptr.p->addfragStatus = AddFragRecord::WAIT_ONE_TUX;
-    sendAddFragReq(signal);
-    break;
-  case AddFragRecord::WAIT_ONE_TUX:
-    jam();
-    fragptr.p->tuxFragptr[1] = tupFragPtr;
-    addfragptr.p->tux2Connectptr = tupConnectptr;
+    fragptr.p->tuxFragptr = tupFragPtr;
+    addfragptr.p->tuxConnectptr = tupConnectptr;
     goto done_with_frag;
     break;
   done_with_frag:
@@ -1193,7 +1190,7 @@
       conf->senderData = addfragptr.p->dictConnectptr;
       conf->lqhFragPtr = addfragptr.i;
       sendSignal(addfragptr.p->dictBlockref, GSN_LQHFRAGCONF,
-          signal, LqhFragConf::SignalLength, JBB);
+		 signal, LqhFragConf::SignalLength, JBB);
     }
     break;
   default:
@@ -1218,9 +1215,8 @@
 Dblqh::sendAddFragReq(Signal* signal)
 {
   fragptr.i = addfragptr.p->fragmentPtr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-  if (addfragptr.p->addfragStatus == AddFragRecord::WAIT_TWO_TUP ||
-      addfragptr.p->addfragStatus == AddFragRecord::WAIT_ONE_TUP) {
+  c_fragment_pool.getPtr(fragptr);
+  if (addfragptr.p->addfragStatus == AddFragRecord::WAIT_TUP){
     if (DictTabInfo::isTable(addfragptr.p->tableType) ||
         DictTabInfo::isHashIndex(addfragptr.p->tableType)) {
       jam();
@@ -1229,9 +1225,7 @@
       signal->theData[2] = 0; /* ADD TABLE */
       signal->theData[3] = addfragptr.p->tabId;
       signal->theData[4] = addfragptr.p->noOfAttr;
-      signal->theData[5] =
-        addfragptr.p->addfragStatus == AddFragRecord::WAIT_TWO_TUP
-        ? addfragptr.p->fragid1 : addfragptr.p->fragid2;
+      signal->theData[5] = addfragptr.p->addFragid;
       signal->theData[6] = (addfragptr.p->noOfAllocPages >> 1) + 1;
       signal->theData[7] = addfragptr.p->noOfNull;
       signal->theData[8] = addfragptr.p->schemaVer;
@@ -1240,8 +1234,9 @@
       signal->theData[11] = addfragptr.p->checksumIndicator;
       signal->theData[12] = addfragptr.p->noOfAttributeGroups;
       signal->theData[13] = addfragptr.p->GCPIndicator;
+      signal->theData[14] = addfragptr.p->tablespace_id;
       sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ,
-          signal, TupFragReq::SignalLength, JBB);
+		 signal, TupFragReq::SignalLength, JBB);
       return;
     }
     if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType)) {
@@ -1251,9 +1246,7 @@
       signal->theData[2] = 0; /* ADD TABLE */
       signal->theData[3] = addfragptr.p->tabId;
       signal->theData[4] = 1; /* ordered index: one array attr */
-      signal->theData[5] =
-        addfragptr.p->addfragStatus == AddFragRecord::WAIT_TWO_TUP
-        ? addfragptr.p->fragid1 : addfragptr.p->fragid2;
+      signal->theData[5] = addfragptr.p->addFragid;
       signal->theData[6] = (addfragptr.p->noOfAllocPages >> 1) + 1;
       signal->theData[7] = 0; /* ordered index: no nullable */
       signal->theData[8] = addfragptr.p->schemaVer;
@@ -1263,12 +1256,11 @@
       signal->theData[12] = addfragptr.p->noOfAttributeGroups;
       signal->theData[13] = addfragptr.p->GCPIndicator;
       sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ,
-          signal, TupFragReq::SignalLength, JBB);
+		 signal, TupFragReq::SignalLength, JBB);
       return;
     }
   }
-  if (addfragptr.p->addfragStatus == AddFragRecord::WAIT_TWO_TUX ||
-      addfragptr.p->addfragStatus == AddFragRecord::WAIT_ONE_TUX) {
+  if (addfragptr.p->addfragStatus == AddFragRecord::WAIT_TUX) {
     if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType)) {
       jam();
       TuxFragReq* const tuxreq = (TuxFragReq*)signal->getDataPtrSend();
@@ -1278,26 +1270,22 @@
       tuxreq->tableId = addfragptr.p->tabId;
       ndbrequire(addfragptr.p->noOfAttr >= 2);
       tuxreq->noOfAttr = addfragptr.p->noOfAttr - 1; /* skip NDB$TNODE */
-      tuxreq->fragId =
-        addfragptr.p->addfragStatus == AddFragRecord::WAIT_TWO_TUX
-        ? addfragptr.p->fragid1: addfragptr.p->fragid2;
+      tuxreq->fragId = addfragptr.p->addFragid;
       tuxreq->fragOff = addfragptr.p->lh3DistrBits;
       tuxreq->tableType = addfragptr.p->tableType;
       tuxreq->primaryTableId = addfragptr.p->primaryTableId;
       // pointer to index fragment in TUP
-      tuxreq->tupIndexFragPtrI =
-        addfragptr.p->addfragStatus == AddFragRecord::WAIT_TWO_TUX ?
-        fragptr.p->tupFragptr[0] : fragptr.p->tupFragptr[1];
+      tuxreq->tupIndexFragPtrI = fragptr.p->tupFragptr;
       // pointers to table fragments in TUP and ACC
       FragrecordPtr tFragPtr;
       tFragPtr.i = fragptr.p->tableFragptr;
-      ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord);
-      tuxreq->tupTableFragPtrI[0] = tFragPtr.p->tupFragptr[0];
-      tuxreq->tupTableFragPtrI[1] = tFragPtr.p->tupFragptr[1];
-      tuxreq->accTableFragPtrI[0] = tFragPtr.p->accFragptr[0];
-      tuxreq->accTableFragPtrI[1] = tFragPtr.p->accFragptr[1];
+      c_fragment_pool.getPtr(tFragPtr);
+      tuxreq->tupTableFragPtrI[0] = tFragPtr.p->tupFragptr;
+      tuxreq->tupTableFragPtrI[1] = RNIL;
+      tuxreq->accTableFragPtrI[0] = tFragPtr.p->accFragptr;
+      tuxreq->accTableFragPtrI[1] = RNIL;
       sendSignal(fragptr.p->tuxBlockref, GSN_TUXFRAGREQ,
-          signal, TuxFragReq::SignalLength, JBB);
+		 signal, TuxFragReq::SignalLength, JBB);
       return;
     }
   }
@@ -1326,11 +1314,18 @@
   addfragptr.p->attrReceived = tnoOfAttr;
   for (Uint32 i = 0; i < tnoOfAttr; i++) {
     addfragptr.p->attributes[i] = req->attributes[i];
+    if(AttributeDescriptor::getDiskBased(req->attributes[i].attrDescriptor))
+    {
+      TablerecPtr tabPtr;
+      tabPtr.i = addfragptr.p->tabId;
+      ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
+      tabPtr.p->m_disk_table = 1;
+    }
   }//for
   addfragptr.p->attrSentToTup = 0;
   ndbrequire(addfragptr.p->dictConnectptr == senderData);
   addfragptr.p->m_senderAttrPtr = senderAttrPtr;
-  addfragptr.p->addfragStatus = AddFragRecord::TUP_ATTR_WAIT1;
+  addfragptr.p->addfragStatus = AddFragRecord::TUP_ATTR_WAIT;
   sendAddAttrReq(signal);
 }//Dblqh::execLQHADDATTREQ()
 
@@ -1345,35 +1340,18 @@
   const bool lastAttr = signal->theData[1];
   ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
   switch (addfragptr.p->addfragStatus) {
-  case AddFragRecord::TUP_ATTR_WAIT1:
-    jam();
-    if (lastAttr)
-      addfragptr.p->tup1Connectptr = RNIL;
-    addfragptr.p->addfragStatus = AddFragRecord::TUP_ATTR_WAIT2;
-    sendAddAttrReq(signal);
-    break;
-  case AddFragRecord::TUP_ATTR_WAIT2:
-    jam();
-    if (lastAttr)
-      addfragptr.p->tup2Connectptr = RNIL;
+  case AddFragRecord::TUP_ATTR_WAIT:
     if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType)) {
-      addfragptr.p->addfragStatus = AddFragRecord::TUX_ATTR_WAIT1;
+      addfragptr.p->addfragStatus = AddFragRecord::TUX_ATTR_WAIT;
       sendAddAttrReq(signal);
       break;
     }
     goto done_with_attr;
     break;
-  case AddFragRecord::TUX_ATTR_WAIT1:
+  case AddFragRecord::TUX_ATTR_WAIT:
     jam();
     if (lastAttr)
-      addfragptr.p->tux1Connectptr = RNIL;
-    addfragptr.p->addfragStatus = AddFragRecord::TUX_ATTR_WAIT2;
-    sendAddAttrReq(signal);
-    break;
-  case AddFragRecord::TUX_ATTR_WAIT2:
-    jam();
-    if (lastAttr)
-      addfragptr.p->tux2Connectptr = RNIL;
+      addfragptr.p->tuxConnectptr = RNIL;
     goto done_with_attr;
     break;
   done_with_attr:
@@ -1383,7 +1361,7 @@
     if (addfragptr.p->attrSentToTup < addfragptr.p->attrReceived) {
       // more in this batch
       jam();
-      addfragptr.p->addfragStatus = AddFragRecord::TUP_ATTR_WAIT1;
+      addfragptr.p->addfragStatus = AddFragRecord::TUP_ATTR_WAIT;
       sendAddAttrReq(signal);
     } else if (addfragptr.p->totalAttrReceived < addfragptr.p->noOfAttr) {
       // more batches to receive
@@ -1394,10 +1372,10 @@
       conf->senderAttrPtr = addfragptr.p->m_senderAttrPtr;
       conf->fragId = addfragptr.p->addFragid;
       sendSignal(addfragptr.p->dictBlockref, GSN_LQHADDATTCONF,
-          signal, LqhAddAttrConf::SignalLength, JBB);
+		 signal, LqhAddAttrConf::SignalLength, JBB);
     } else {
       fragptr.i = addfragptr.p->fragmentPtr;
-      ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+      c_fragment_pool.getPtr(fragptr);
       /* ------------------------------------------------------------------ 
        * WE HAVE NOW COMPLETED ADDING THIS FRAGMENT. WE NOW NEED TO SET THE 
        * PROPER STATE IN FRAG_STATUS DEPENDENT ON IF WE ARE CREATING A NEW 
@@ -1451,18 +1429,15 @@
   const Uint32 attrId = entry.attrId & 0xffff;
   const Uint32 primaryAttrId = entry.attrId >> 16;
   fragptr.i = addfragptr.p->fragmentPtr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-  if (addfragptr.p->addfragStatus == AddFragRecord::TUP_ATTR_WAIT1 ||
-      addfragptr.p->addfragStatus == AddFragRecord::TUP_ATTR_WAIT2) {
+  c_fragment_pool.getPtr(fragptr);
+  if (addfragptr.p->addfragStatus == AddFragRecord::TUP_ATTR_WAIT) {
     if (DictTabInfo::isTable(addfragptr.p->tableType) ||
         DictTabInfo::isHashIndex(addfragptr.p->tableType) ||
         (DictTabInfo::isOrderedIndex(addfragptr.p->tableType) &&
          primaryAttrId == ZNIL)) {
       jam();
       TupAddAttrReq* const tupreq = (TupAddAttrReq*)signal->getDataPtrSend();
-      tupreq->tupConnectPtr =
-        addfragptr.p->addfragStatus == AddFragRecord::TUP_ATTR_WAIT1
-        ? addfragptr.p->tup1Connectptr : addfragptr.p->tup2Connectptr;
+      tupreq->tupConnectPtr = addfragptr.p->tupConnectptr;
       tupreq->notused1 = 0;
       tupreq->attrId = attrId;
       tupreq->attrDescriptor = entry.attrDescriptor;
@@ -1479,27 +1454,24 @@
       tupconf->userPtr = addfragptr.i;
       tupconf->lastAttr = false;
       sendSignal(reference(), GSN_TUP_ADD_ATTCONF,
-          signal, TupAddAttrConf::SignalLength, JBB);
+		 signal, TupAddAttrConf::SignalLength, JBB);
       return;
     }
   }
-  if (addfragptr.p->addfragStatus == AddFragRecord::TUX_ATTR_WAIT1 ||
-      addfragptr.p->addfragStatus == AddFragRecord::TUX_ATTR_WAIT2) {
+  if (addfragptr.p->addfragStatus == AddFragRecord::TUX_ATTR_WAIT) {
     jam();
     if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType) &&
         primaryAttrId != ZNIL) {
       jam();
       TuxAddAttrReq* const tuxreq = (TuxAddAttrReq*)signal->getDataPtrSend();
-      tuxreq->tuxConnectPtr =
-        addfragptr.p->addfragStatus == AddFragRecord::TUX_ATTR_WAIT1
-        ? addfragptr.p->tux1Connectptr : addfragptr.p->tux2Connectptr;
+      tuxreq->tuxConnectPtr = addfragptr.p->tuxConnectptr;
       tuxreq->notused1 = 0;
       tuxreq->attrId = attrId;
       tuxreq->attrDescriptor = entry.attrDescriptor;
       tuxreq->extTypeInfo = entry.extTypeInfo;
       tuxreq->primaryAttrId = primaryAttrId;
       sendSignal(fragptr.p->tuxBlockref, GSN_TUX_ADD_ATTRREQ,
-          signal, TuxAddAttrReq::SignalLength, JBB);
+		 signal, TuxAddAttrReq::SignalLength, JBB);
       return;
     }
     if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType) &&
@@ -1510,7 +1482,7 @@
       tuxconf->userPtr = addfragptr.i;
       tuxconf->lastAttr = false;
       sendSignal(reference(), GSN_TUX_ADD_ATTRCONF,
-          signal, TuxAddAttrConf::SignalLength, JBB);
+		 signal, TuxAddAttrConf::SignalLength, JBB);
       return;
     }
   }
@@ -1579,31 +1551,19 @@
 void Dblqh::abortAddFragOps(Signal* signal)
 {
   fragptr.i = addfragptr.p->fragmentPtr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(fragptr);
   signal->theData[0] = (Uint32)-1;
-  if (addfragptr.p->tup1Connectptr != RNIL) {
-    jam();
-    signal->theData[1] = addfragptr.p->tup1Connectptr;
-    sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ, signal, 2, JBB);
-    addfragptr.p->tup1Connectptr = RNIL;
-  }
-  if (addfragptr.p->tup2Connectptr != RNIL) {
+  if (addfragptr.p->tupConnectptr != RNIL) {
     jam();
-    signal->theData[1] = addfragptr.p->tup2Connectptr;
+    signal->theData[1] = addfragptr.p->tupConnectptr;
     sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ, signal, 2, JBB);
-    addfragptr.p->tup2Connectptr = RNIL;
+    addfragptr.p->tupConnectptr = RNIL;
   }
-  if (addfragptr.p->tux1Connectptr != RNIL) {
+  if (addfragptr.p->tuxConnectptr != RNIL) {
     jam();
-    signal->theData[1] = addfragptr.p->tux1Connectptr;
+    signal->theData[1] = addfragptr.p->tuxConnectptr;
     sendSignal(fragptr.p->tuxBlockref, GSN_TUXFRAGREQ, signal, 2, JBB);
-    addfragptr.p->tux1Connectptr = RNIL;
-  }
-  if (addfragptr.p->tux2Connectptr != RNIL) {
-    jam();
-    signal->theData[1] = addfragptr.p->tux2Connectptr;
-    sendSignal(fragptr.p->tuxBlockref, GSN_TUXFRAGREQ, signal, 2, JBB);
-    addfragptr.p->tux2Connectptr = RNIL;
+    addfragptr.p->tuxConnectptr = RNIL;
   }
 }
 
@@ -1638,21 +1598,15 @@
   ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
   terrorCode = signal->theData[1];
   fragptr.i = addfragptr.p->fragmentPtr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(fragptr);
   addfragptr.p->addfragErrorCode = terrorCode;
 
   // no operation to release, just add some jams
   switch (addfragptr.p->addfragStatus) {
-  case AddFragRecord::WAIT_TWO_TUP:
-    jam();
-    break;
-  case AddFragRecord::WAIT_ONE_TUP:
+  case AddFragRecord::WAIT_TUP:
     jam();
     break;
-  case AddFragRecord::WAIT_TWO_TUX:
-    jam();
-    break;
-  case AddFragRecord::WAIT_ONE_TUX:
+  case AddFragRecord::WAIT_TUX:
     jam();
     break;
   default:
@@ -1691,25 +1645,15 @@
 
   // operation was released on the other side
   switch (addfragptr.p->addfragStatus) {
-  case AddFragRecord::TUP_ATTR_WAIT1:
-    jam();
-    ndbrequire(addfragptr.p->tup1Connectptr != RNIL);
-    addfragptr.p->tup1Connectptr = RNIL;
-    break;
-  case AddFragRecord::TUP_ATTR_WAIT2:
-    jam();
-    ndbrequire(addfragptr.p->tup2Connectptr != RNIL);
-    addfragptr.p->tup2Connectptr = RNIL;
-    break;
-  case AddFragRecord::TUX_ATTR_WAIT1:
+  case AddFragRecord::TUP_ATTR_WAIT:
     jam();
-    ndbrequire(addfragptr.p->tux1Connectptr != RNIL);
-    addfragptr.p->tux1Connectptr = RNIL;
+    ndbrequire(addfragptr.p->tupConnectptr != RNIL);
+    addfragptr.p->tupConnectptr = RNIL;
     break;
-  case AddFragRecord::TUX_ATTR_WAIT2:
+  case AddFragRecord::TUX_ATTR_WAIT:
     jam();
-    ndbrequire(addfragptr.p->tux2Connectptr != RNIL);
-    addfragptr.p->tux2Connectptr = RNIL;
+    ndbrequire(addfragptr.p->tuxConnectptr != RNIL);
+    addfragptr.p->tuxConnectptr = RNIL;
     break;
   default:
     ndbrequire(false);
@@ -2023,7 +1967,7 @@
   tabptr.i = tableId;
   ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
   
-  for (Uint32 i = (MAX_FRAG_PER_NODE - 1); (Uint32)~i; i--) {
+  for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
     jam();
     if (tabptr.p->fragid[i] != ZNIL) {
       jam();
@@ -2105,146 +2049,11 @@
 	     << " cLqhTimeOutCount = " << cLqhTimeOutCount << endl
 	     << " tcTimer="<<tTcConptr.p->tcTimer<<endl
 	     << " tcTimer+120="<<tTcConptr.p->tcTimer + 120<<endl;
-	  
-      ndbout << " transactionState = " << tTcConptr.p->transactionState<<endl;
-      ndbout << " operation = " << tTcConptr.p->operation<<endl;
-      ndbout << " tcNodeFailrec = " << tTcConptr.p->tcNodeFailrec
-	     << " seqNoReplica = " << tTcConptr.p->seqNoReplica
-	     << " simpleRead = " << tTcConptr.p->simpleRead
-	     << endl;
-      ndbout << " replicaType = " << tTcConptr.p->replicaType
-	     << " reclenAiLqhkey = " << tTcConptr.p->reclenAiLqhkey
-	     << " opExec = " << tTcConptr.p->opExec
-	     << endl;
-      ndbout << " opSimple = " << tTcConptr.p->opSimple
-	     << " nextSeqNoReplica = " << tTcConptr.p->nextSeqNoReplica
-	     << " lockType = " << tTcConptr.p->lockType
-	     << " localFragptr = " << tTcConptr.p->localFragptr
-	     << endl;
-      ndbout << " lastReplicaNo = " << tTcConptr.p->lastReplicaNo
-	     << " indTakeOver = " << tTcConptr.p->indTakeOver
-	     << " dirtyOp = " << tTcConptr.p->dirtyOp
-	     << endl;
-      ndbout << " activeCreat = " << tTcConptr.p->activeCreat
-	     << " tcBlockref = " << hex << tTcConptr.p->tcBlockref
-	     << " reqBlockref = " << hex << tTcConptr.p->reqBlockref
-	     << " primKeyLen = " << tTcConptr.p->primKeyLen
-	     << endl;
-      ndbout << " nextReplica = " << tTcConptr.p->nextReplica
-	     << " tcBlockref = " << hex << tTcConptr.p->tcBlockref
-	     << " reqBlockref = " << hex << tTcConptr.p->reqBlockref
-	     << " primKeyLen = " << tTcConptr.p->primKeyLen
-	     << endl;
-      ndbout << " logStopPageNo = " << tTcConptr.p->logStopPageNo
-	     << " logStartPageNo = " << tTcConptr.p->logStartPageNo
-	     << " logStartPageIndex = " << tTcConptr.p->logStartPageIndex
-	     << endl;
-      ndbout << " errorCode = " << tTcConptr.p->errorCode
-	     << " clientBlockref = " << hex << tTcConptr.p->clientBlockref
-	     << " applRef = " << hex << tTcConptr.p->applRef
-	     << " totSendlenAi = " << tTcConptr.p->totSendlenAi
-	     << endl;
-      ndbout << " totReclenAi = " << tTcConptr.p->totReclenAi
-	     << " tcScanRec = " << tTcConptr.p->tcScanRec
-	     << " tcScanInfo = " << tTcConptr.p->tcScanInfo
-	     << " tcOprec = " << hex << tTcConptr.p->tcOprec
-	     << endl;
-      ndbout << " tableref = " << tTcConptr.p->tableref
-	     << " simpleTcConnect = " << tTcConptr.p->simpleTcConnect
-	     << " storedProcId = " << tTcConptr.p->storedProcId
-	     << " schemaVersion = " << tTcConptr.p->schemaVersion
-	     << endl;
-      ndbout << " reqinfo = " << tTcConptr.p->reqinfo
-	     << " reqRef = " << tTcConptr.p->reqRef
-	     << " readlenAi = " << tTcConptr.p->readlenAi
-	     << " prevTc = " << tTcConptr.p->prevTc
-	     << endl;
-      ndbout << " prevLogTcrec = " << tTcConptr.p->prevLogTcrec
-	     << " prevHashRec = " << tTcConptr.p->prevHashRec
-	     << " nodeAfterNext0 = " << tTcConptr.p->nodeAfterNext[0]
-	     << " nodeAfterNext1 = " << tTcConptr.p->nodeAfterNext[1]
-	     << endl;
-      ndbout << " nextTcConnectrec = " << tTcConptr.p->nextTcConnectrec
-	     << " nextTc = " << tTcConptr.p->nextTc
-	     << " nextTcLogQueue = " << tTcConptr.p->nextTcLogQueue
-	     << " nextLogTcrec = " << tTcConptr.p->nextLogTcrec
-	     << endl;
-      ndbout << " nextHashRec = " << tTcConptr.p->nextHashRec
-	     << " logWriteState = " << tTcConptr.p->logWriteState
-	     << " logStartFileNo = " << tTcConptr.p->logStartFileNo
-	     << " listState = " << tTcConptr.p->listState
-	     << endl;
-      ndbout << " lastAttrinbuf = " << tTcConptr.p->lastAttrinbuf
-	     << " lastTupkeybuf = " << tTcConptr.p->lastTupkeybuf
-	     << " hashValue = " << tTcConptr.p->hashValue
-	     << endl;
-      ndbout << " gci = " << tTcConptr.p->gci
-	     << " fragmentptr = " << tTcConptr.p->fragmentptr
-	     << " fragmentid = " << tTcConptr.p->fragmentid
-	     << " firstTupkeybuf = " << tTcConptr.p->firstTupkeybuf
-	     << endl;
-      ndbout << " firstAttrinbuf = " << tTcConptr.p->firstAttrinbuf
-	     << " currTupAiLen = " << tTcConptr.p->currTupAiLen
-	     << " currReclenAi = " << tTcConptr.p->currReclenAi
-	     << endl;
-      ndbout << " tcTimer = " << tTcConptr.p->tcTimer
-	     << " clientConnectrec = " << tTcConptr.p->clientConnectrec
-	     << " applOprec = " << hex << tTcConptr.p->applOprec
-	     << " abortState = " << tTcConptr.p->abortState
-	     << endl;
-      ndbout << " transid0 = " << hex << tTcConptr.p->transid[0]
-	     << " transid1 = " << hex << tTcConptr.p->transid[1]
-	     << " tupkeyData0 = " << tTcConptr.p->tupkeyData[0]
-	     << " tupkeyData1 = " << tTcConptr.p->tupkeyData[1]
-	     << endl;
-      ndbout << " tupkeyData2 = " << tTcConptr.p->tupkeyData[2]
-	     << " tupkeyData3 = " << tTcConptr.p->tupkeyData[3]
-	     << endl;
-      switch (tTcConptr.p->transactionState) {
-	
-      case TcConnectionrec::SCAN_STATE_USED:
-	if (tTcConptr.p->tcScanRec < cscanrecFileSize){
-	  ScanRecordPtr TscanPtr;
-	  c_scanRecordPool.getPtr(TscanPtr, tTcConptr.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
-		 << " scanLocalFragid="<<TscanPtr.p->scanLocalFragid
-		 << 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;
-      }//switch
 
+      signal->theData[0] = 2307;
+      signal->theData[1] = tTcConptr.i;
+      execDUMP_STATE_ORD(signal);
+      
       // Reset the timer 
       tTcConptr.p->tcTimer = 0;
     }//if
@@ -2616,25 +2425,34 @@
 }//Dblqh::updatePackedList()
 
 void
-Dblqh::execREAD_PSUEDO_REQ(Signal* signal){
+Dblqh::execREAD_PSEUDO_REQ(Signal* signal){
   jamEntry();
   TcConnectionrecPtr regTcPtr;
   regTcPtr.i = signal->theData[0];
   ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec);
   
-  if(signal->theData[1] != AttributeHeader::RANGE_NO)
+  if (signal->theData[1] == AttributeHeader::RANGE_NO) {
+    signal->theData[0] = regTcPtr.p->m_scan_curr_range_no;
+  }
+  else if (signal->theData[1] != AttributeHeader::RECORDS_IN_RANGE)
   {
     jam();
     FragrecordPtr regFragptr;
     regFragptr.i = regTcPtr.p->fragmentptr;
-    ptrCheckGuard(regFragptr, cfragrecFileSize, fragrecord);
+    c_fragment_pool.getPtr(regFragptr);
     
-    signal->theData[0] = regFragptr.p->accFragptr[regTcPtr.p->localFragptr];
-    EXECUTE_DIRECT(DBACC, GSN_READ_PSUEDO_REQ, signal, 2);
+    signal->theData[0] = regFragptr.p->accFragptr;
+    EXECUTE_DIRECT(DBACC, GSN_READ_PSEUDO_REQ, signal, 2);
   }
   else
   {
-    signal->theData[0] = regTcPtr.p->m_scan_curr_range_no;
+    jam();
+    // scanptr gets reset somewhere within the timeslice
+    ScanRecordPtr tmp;
+    tmp.i = regTcPtr.p->tcScanRec;
+    c_scanRecordPool.getPtr(tmp);
+    signal->theData[0] = tmp.p->scanAccPtr;
+    EXECUTE_DIRECT(DBTUX, GSN_READ_PSEUDO_REQ, signal, 2);
   }
 }
 
@@ -2650,6 +2468,12 @@
   jamEntry();
   tcConnectptr.i = tcIndex;
   ptrCheckGuard(tcConnectptr, ttcConnectrecFileSize, regTcConnectionrec);
+
+  FragrecordPtr regFragptr;
+  regFragptr.i = tcConnectptr.p->fragmentptr;
+  c_fragment_pool.getPtr(regFragptr);
+  fragptr = regFragptr;
+  
   switch (tcConnectptr.p->transactionState) {
   case TcConnectionrec::WAIT_TUP:
     jam();
@@ -2671,7 +2495,6 @@
 // Abort was not ready to start until this signal came back. Now we are ready
 // to start the abort.
 /* ------------------------------------------------------------------------- */
-    releaseActiveFrag(signal);
     abortCommonLab(signal);
     break;
   case TcConnectionrec::WAIT_ACC_ABORT:
@@ -2698,10 +2521,15 @@
   tcConnectptr.i = tupKeyRef->userRef;
   terrorCode = tupKeyRef->errorCode;
   ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
+
+  FragrecordPtr regFragptr;
+  regFragptr.i = tcConnectptr.p->fragmentptr;
+  c_fragment_pool.getPtr(regFragptr);
+  fragptr = regFragptr;
+  
   switch (tcConnectptr.p->transactionState) {
   case TcConnectionrec::WAIT_TUP:
     jam();
-    releaseActiveFrag(signal);
     abortErrorLab(signal);
     break;
   case TcConnectionrec::COPY_TUPKEY:
@@ -2717,7 +2545,6 @@
 // Abort was not ready to start until this signal came back. Now we are ready
 // to start the abort.
 /* ------------------------------------------------------------------------- */
-    releaseActiveFrag(signal);
     abortCommonLab(signal);
     break;
   case TcConnectionrec::WAIT_ACC_ABORT:
@@ -2850,6 +2677,7 @@
   LqhKeyConf* lqhKeyConf;
   HostRecordPtr Thostptr;
 
+  bool packed= true;
   Thostptr.i = refToNode(atcBlockref);
   ptrCheckGuard(Thostptr, chostFileSize, hostRecord);
   if (refToBlock(atcBlockref) == DBTC) {
@@ -2868,7 +2696,7 @@
     lqhKeyConf = (LqhKeyConf *)
       &Thostptr.p->packedWordsTc[Thostptr.p->noOfPackedWordsTc];
     Thostptr.p->noOfPackedWordsTc += LqhKeyConf::SignalLength;
-  } else {
+  } else if(refToBlock(atcBlockref) == DBLQH){
     jam();
 /*******************************************************************
 // This signal was intended for DBLQH as part of log execution or
@@ -2884,7 +2712,10 @@
     lqhKeyConf = (LqhKeyConf *)
       &Thostptr.p->packedWordsLqh[Thostptr.p->noOfPackedWordsLqh];
     Thostptr.p->noOfPackedWordsLqh += LqhKeyConf::SignalLength;
-  }//if
+  } else {
+    packed= false;
+    lqhKeyConf = (LqhKeyConf *)signal->getDataPtrSend();
+  }
   Uint32 ptrAndType = tcConnectptr.i | (ZLQHKEYCONF << 28);
   Uint32 tcOprec = tcConnectptr.p->tcOprec;
   Uint32 ownRef = cownref;
@@ -2899,6 +2730,21 @@
   lqhKeyConf->transId1 = transid1;
   lqhKeyConf->transId2 = transid2;
   lqhKeyConf->noFiredTriggers = noFiredTriggers;
+
+  if(!packed)
+  {
+    lqhKeyConf->connectPtr = tcConnectptr.i;
+    if(Thostptr.i == 0 || Thostptr.i == getOwnNodeId())
+    {
+      EXECUTE_DIRECT(refToBlock(atcBlockref), GSN_LQHKEYCONF,
+		     signal, LqhKeyConf::SignalLength);
+    }
+    else
+    {
+      sendSignal(atcBlockref, GSN_LQHKEYCONF,
+		 signal, LqhKeyConf::SignalLength, JBB);
+    }
+  }
 }//Dblqh::sendLqhkeyconfTc()
 
 /* ************************************************************************>>
@@ -2916,6 +2762,16 @@
     jam();
     return;
   }//if
+
+  receive_keyinfo(signal, 
+		  signal->theData+KeyInfo::HeaderLength, 
+		  signal->getLength()-KeyInfo::HeaderLength);
+}
+
+void
+Dblqh::receive_keyinfo(Signal* signal, 
+		       Uint32 * data, Uint32 len)
+{
   TcConnectionrec * const regTcPtr = tcConnectptr.p;
   TcConnectionrec::TransactionState state = regTcPtr->transactionState;
   if (state != TcConnectionrec::WAIT_TUPKEYINFO &&
@@ -2928,10 +2784,10 @@
 /*****************************************************************************/
     return;
   }//if
-  Uint32 errorCode = handleLongTupKey(signal,
-                                      (Uint32)regTcPtr->save1,
-                                      (Uint32)regTcPtr->primKeyLen,
-                                      &signal->theData[3]);
+
+  Uint32 errorCode = 
+    handleLongTupKey(signal, data, len);
+  
   if (errorCode != 0) {
     if (errorCode == 1) {
       jam();
@@ -2949,7 +2805,7 @@
   {
     FragrecordPtr regFragptr;
     regFragptr.i = regTcPtr->fragmentptr;
-    ptrCheckGuard(regFragptr, cfragrecFileSize, fragrecord);
+    c_fragment_pool.getPtr(regFragptr);
     fragptr = regFragptr;
     endgettupkeyLab(signal);
   }
@@ -2960,14 +2816,14 @@
 /* FILL IN KEY DATA INTO DATA BUFFERS.                                       */
 /* ------------------------------------------------------------------------- */
 Uint32 Dblqh::handleLongTupKey(Signal* signal,
-			       Uint32 keyLength,
-			       Uint32 primKeyLength,
-			       Uint32* dataPtr) 
+			       Uint32* dataPtr,
+			       Uint32 len) 
 {
   TcConnectionrec * const regTcPtr = tcConnectptr.p;
   Uint32 dataPos = 0;
-  while (true) {
-    keyLength += 4;
+  Uint32 total = regTcPtr->save1 + len;
+  Uint32 primKeyLen = regTcPtr->primKeyLen;
+  while (dataPos < len) {
     if (cfirstfreeDatabuf == RNIL) {
       jam();
       return ZGET_DATAREC_ERROR;
@@ -2983,18 +2839,10 @@
     regDataPtr->data[2] = data2;
     regDataPtr->data[3] = data3;
     dataPos += 4;
-    if (keyLength < primKeyLength) {
-      if (dataPos > 16) {
-        jam();
-/* SAVE STATE AND WAIT FOR KEYINFO */
-        regTcPtr->save1 = keyLength;
-        return 1;
-      }//if
-    } else {
-      jam();
-      return 0;
-    }//if
-  }//while
+  }
+
+  regTcPtr->save1 = total;
+  return (total >= primKeyLen ? 0 : 1);
 }//Dblqh::handleLongTupKey()
 
 /* ------------------------------------------------------------------------- */
@@ -3018,22 +2866,26 @@
     jam();
     return;
   }//if
+
+  receive_attrinfo(signal, 
+		   signal->getDataPtrSend()+AttrInfo::HeaderLength,
+		   signal->getLength()-AttrInfo::HeaderLength);
+}//Dblqh::execATTRINFO()
+
+void
+Dblqh::receive_attrinfo(Signal* signal, Uint32 * dataPtr, Uint32 length)
+{
   TcConnectionrec * const regTcPtr = tcConnectptr.p;
-  Uint32 length = signal->length() - 3;
   Uint32 totReclenAi = regTcPtr->totReclenAi;
   Uint32 currReclenAi = regTcPtr->currReclenAi + length;
-  Uint32* dataPtr = &signal->theData[3];
   regTcPtr->currReclenAi = currReclenAi;
   if (totReclenAi == currReclenAi) {
     switch (regTcPtr->transactionState) {
     case TcConnectionrec::WAIT_ATTR:
     {
-      Fragrecord *regFragrecord = fragrecord;
-      Uint32 fragIndex = regTcPtr->fragmentptr;
-      Uint32 tfragrecFileSize = cfragrecFileSize;
       jam();
-      fragptr.i = fragIndex;
-      ptrCheckGuard(fragptr, tfragrecFileSize, regFragrecord);
+      fragptr.i = regTcPtr->fragmentptr;
+      c_fragment_pool.getPtr(fragptr);
       lqhAttrinfoLab(signal, dataPtr, length);
       endgettupkeyLab(signal);
       return;
@@ -3101,7 +2953,7 @@
     }//switch
   }//if
   return;
-}//Dblqh::execATTRINFO()
+}
 
 /* ************************************************************************>> */
 /*  TUP_ATTRINFO: Interpreted execution in DBTUP generates redo-log info      */
@@ -3153,11 +3005,7 @@
       }//if
     }//if
   }//if
-  Uint32 sig0 = regTcPtr->tupConnectrec;
-  Uint32 blockNo = refToBlock(regTcPtr->tcTupBlockref);
-  signal->theData[0] = sig0;
-  EXECUTE_DIRECT(blockNo, GSN_ATTRINFO, signal, length + 3);
-  jamEntry();
+  c_tup->receive_attrinfo(signal, regTcPtr->tupConnectrec, dataPtr, length);
 }//Dblqh::lqhAttrinfoLab()
 
 /* ------------------------------------------------------------------------- */
@@ -3197,21 +3045,28 @@
 /* -------       SAVE ATTRINFO FROM TUP IN ATTRINBUF                 ------- */
 /*                                                                           */
 /* ------------------------------------------------------------------------- */
-int Dblqh::saveTupattrbuf(Signal* signal, Uint32* dataPtr, Uint32 length) 
+int Dblqh::saveTupattrbuf(Signal* signal, Uint32* dataPtr, Uint32 len) 
 {
-  Uint32 tfirstfreeAttrinbuf = cfirstfreeAttrinbuf;
   TcConnectionrec * const regTcPtr = tcConnectptr.p;
-  Uint32 currTupAiLen = regTcPtr->currTupAiLen;
-  if (tfirstfreeAttrinbuf == RNIL) {
-    jam();
-    terrorCode = ZGET_ATTRINBUF_ERROR;
-    return ZGET_ATTRINBUF_ERROR;
-  }//if
-  seizeAttrinbuf(signal);
-  Attrbuf * const regAttrPtr = attrinbufptr.p;
-  MEMCOPY_NO_WORDS(&regAttrPtr->attrbuf[0], dataPtr, length);
-  regTcPtr->currTupAiLen = currTupAiLen + length;
-  regAttrPtr->attrbuf[ZINBUF_DATA_LEN] = length;
+  while(len)
+  {
+    Uint32 length = len > AttrInfo::DataLength ? AttrInfo::DataLength : len;
+    Uint32 tfirstfreeAttrinbuf = cfirstfreeAttrinbuf;
+    Uint32 currTupAiLen = regTcPtr->currTupAiLen;
+    if (tfirstfreeAttrinbuf == RNIL) {
+      jam();
+      terrorCode = ZGET_ATTRINBUF_ERROR;
+      return ZGET_ATTRINBUF_ERROR;
+    }//if
+    seizeAttrinbuf(signal);
+    Attrbuf * const regAttrPtr = attrinbufptr.p;
+    MEMCOPY_NO_WORDS(&regAttrPtr->attrbuf[0], dataPtr, length);
+    regTcPtr->currTupAiLen = currTupAiLen + length;
+    regAttrPtr->attrbuf[ZINBUF_DATA_LEN] = length;
+    
+    len -= length;
+    dataPtr += length;
+  }
   return ZOK;
 }//Dblqh::saveTupattrbuf()
 
@@ -3263,6 +3118,7 @@
   locTcConnectptr.p->tcTimer = cLqhTimeOutCount;
   locTcConnectptr.p->tableref = RNIL;
   locTcConnectptr.p->savePointId = 0;
+  locTcConnectptr.p->gci = 0;
   cfirstfreeTcConrec = nextTc;
   tcConnectptr = locTcConnectptr;
   locTcConnectptr.p->connectState = TcConnectionrec::CONNECTED;
@@ -3528,15 +3384,20 @@
     LQHKEY_abort(signal, 5);
     return;
   }
-
+  
   regTcPtr->tableref = tabptr.i;
+  regTcPtr->m_disk_table = tabptr.p->m_disk_table;
+  if(refToBlock(signal->senderBlockRef()) == RESTORE)
+    regTcPtr->m_disk_table &= !LqhKeyReq::getNoDiskFlag(Treqinfo);
+  else if(op == ZREAD || op == ZREAD_EX || op == ZUPDATE)
+    regTcPtr->m_disk_table &= !LqhKeyReq::getNoDiskFlag(Treqinfo);
+  
   tabptr.p->usageCount++;
   
   if (!getFragmentrec(signal, regTcPtr->fragmentid)) {
     LQHKEY_error(signal, 6);
     return;
   }//if
-  regTcPtr->localFragptr = regTcPtr->hashValue & 1;
   Uint8 TcopyType = fragptr.p->fragCopy;
   tfragDistKey = fragptr.p->fragDistributionKey;
   if (fragptr.p->fragStatus == Fragrecord::ACTIVE_CREATION) {
@@ -3614,16 +3475,10 @@
     sig2 = lqhKeyReq->variableData[nextPos + 2];
     sig3 = lqhKeyReq->variableData[nextPos + 3];
     sig4 = lqhKeyReq->variableData[nextPos + 4];
-
-    signal->theData[0] = regTcPtr->tupConnectrec;
-    signal->theData[3] = sig0;
-    signal->theData[4] = sig1;
-    signal->theData[5] = sig2;
-    signal->theData[6] = sig3;
-    signal->theData[7] = sig4;
-    EXECUTE_DIRECT(refToBlock(regTcPtr->tcTupBlockref), GSN_ATTRINFO, 
-		   signal, TreclenAiLqhkey + 3);
-    jamEntry();
+    
+    c_tup->receive_attrinfo(signal, regTcPtr->tupConnectrec, 
+			    lqhKeyReq->variableData+nextPos, TreclenAiLqhkey);
+    
     if (signal->theData[0] == (UintR)-1) {
       LQHKEY_abort(signal, 2);
       return;
@@ -3658,6 +3513,57 @@
     regTcPtr->transactionState = TcConnectionrec::WAIT_ATTR;
     return;
   }//if
+//#define TRACE_LQHKEYREQ
+#ifdef TRACE_LQHKEYREQ
+  {
+    ndbout << (regTcPtr->operation == ZREAD ? "READ" :
+	       regTcPtr->operation == ZUPDATE ? "UPDATE" :
+	       regTcPtr->operation == ZINSERT ? "INSERT" :
+	       regTcPtr->operation == ZDELETE ? "DELETE" : "<Other>")
+	   << "(" << (int)regTcPtr->operation << ")" 
+	   << " from=(" << getBlockName(refToBlock(regTcPtr->clientBlockref))
+	   << ", " << refToNode(regTcPtr->clientBlockref) << ")"
+	   << " table=" << regTcPtr->tableref << " ";
+    
+    ndbout << "hash: " << hex << regTcPtr->hashValue << endl;
+
+    ndbout << "key=[" << hex;
+    Uint32 i;
+    for(i = 0; i<regTcPtr->primKeyLen && i < 4; i++){
+      ndbout << hex << regTcPtr->tupkeyData[i] << " ";
+    }
+
+    DatabufPtr regDatabufptr;
+    regDatabufptr.i = regTcPtr->firstTupkeybuf;
+    while(i < regTcPtr->primKeyLen)
+    {
+      ptrCheckGuard(regDatabufptr, cdatabufFileSize, databuf);
+      for(Uint32 j = 0; j<4 && i<regTcPtr->primKeyLen; j++, i++)
+	ndbout << hex << regDatabufptr.p->data[j] << " ";
+    }
+    ndbout << "]" << endl;
+    
+    ndbout << "attr=[" << hex;
+    for(i = 0; i<regTcPtr->reclenAiLqhkey && i < 5; i++)
+      ndbout << hex << regTcPtr->firstAttrinfo[i] << " ";
+    
+    AttrbufPtr regAttrinbufptr;
+    regAttrinbufptr.i= regTcPtr->firstAttrinbuf;
+    while(i < regTcPtr->totReclenAi)
+    {
+      ptrCheckGuard(regAttrinbufptr, cattrinbufFileSize, attrbuf);
+      Uint32 dataLen = regAttrinbufptr.p->attrbuf[ZINBUF_DATA_LEN];
+      ndbrequire(dataLen != 0);
+      ndbrequire(i + dataLen <= regTcPtr->totReclenAi);
+      for(Uint32 j= 0; j<dataLen; j++, i++)
+	ndbout << hex << regAttrinbufptr.p->attrbuf[j] << " ";
+      
+      regAttrinbufptr.i = regAttrinbufptr.p->attrbuf[ZINBUF_NEXT];
+    }
+    
+    ndbout << "]" << endl;
+  }
+#endif
 /* ---------------------------------------------------------------------- */
 /*       NOW RECEPTION OF LQHKEYREQ IS COMPLETED THE NEXT STEP IS TO START*/
 /*       PROCESSING THE MESSAGE. IF THE MESSAGE IS TO A STAND-BY NODE     */
@@ -3676,7 +3582,6 @@
   case Fragrecord::FSACTIVE:
   case Fragrecord::CRASH_RECOVERING:
   case Fragrecord::ACTIVE_CREATION:
-    linkActiveFrag(signal);
     prepareContinueAfterBlockedLab(signal);
     return;
     break;
@@ -3731,7 +3636,6 @@
     }
     if (scanptr.i == RNIL) {
       jam();
-      releaseActiveFrag(signal);
       takeOverErrorLab(signal);
       return;
     }//if
@@ -3740,7 +3644,6 @@
                                                   true);
     if (accOpPtr == RNIL) {
       jam();
-      releaseActiveFrag(signal);
       takeOverErrorLab(signal);
       return;
     }//if
@@ -3789,10 +3692,9 @@
 /* ************ */
 /*  ACCKEYREQ < */
 /* ************ */
-  ndbrequire(regTcPtr->localFragptr < 2);
   Uint32 sig0, sig1, sig2, sig3, sig4;
   sig0 = regTcPtr->accConnectrec;
-  sig1 = fragptr.p->accFragptr[regTcPtr->localFragptr];
+  sig1 = fragptr.p->accFragptr;
   sig2 = regTcPtr->hashValue;
   sig3 = regTcPtr->primKeyLen;
   sig4 = regTcPtr->transid[0];
@@ -3867,11 +3769,10 @@
   ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec);
 
   regFragptr.i = regTcPtr.p->fragmentptr;
-  ptrCheckGuard(regFragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(regFragptr);
 
-  ndbrequire(regTcPtr.p->localFragptr < 2);
   signal->theData[0] = regTcPtr.p->tupConnectrec;
-  signal->theData[1] = regFragptr.p->tupFragptr[regTcPtr.p->localFragptr];
+  signal->theData[1] = regFragptr.p->tupFragptr;
   signal->theData[2] = regTcPtr.p->tableref;
   Uint32 tup = refToBlock(regTcPtr.p->tcTupBlockref);
   EXECUTE_DIRECT(tup, GSN_TUP_ALLOCREQ, signal, 3);
@@ -3885,9 +3786,8 @@
   TcConnectionrec *regTcConnectionrec = tcConnectionrec;
   Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
   Uint32 tcIndex = signal->theData[0];
-  Uint32 Tfragid = signal->theData[2];
   Uint32 localKey1 = signal->theData[3];
-  Uint32 localKey2 = signal->theData[4];
+  //Uint32 localKey2 = signal->theData[4];
   Uint32 localKeyFlag = signal->theData[5];
   jamEntry();
   tcConnectptr.i = tcIndex;
@@ -3897,11 +3797,8 @@
     LQHKEY_abort(signal, 3);
     return;
   }//if
-  /* ------------------------------------------------------------------------ 
-   * Set transaction state and also reset the activeCreat since that is only 
-   * valid in cases where the record was not present.
-   * ------------------------------------------------------------------------ */
-  regTcPtr->transactionState = TcConnectionrec::WAIT_TUP;
+
+  // reset the activeCreat since that is only valid in cases where the record was not present.
   regTcPtr->activeCreat = ZFALSE;
   /* ------------------------------------------------------------------------
    * IT IS NOW TIME TO CONTACT THE TUPLE MANAGER. THE TUPLE MANAGER NEEDS THE
@@ -3921,13 +3818,50 @@
     else
     {
       warningEvent("Convering %d to ZUPDATE", op);
-      regTcPtr->operation = ZUPDATE;
+      op = regTcPtr->operation = ZUPDATE;
     }
   }//if
-  
+
+  /* ------------------------------------------------------------------------
+   * IT IS NOW TIME TO CONTACT THE TUPLE MANAGER. THE TUPLE MANAGER NEEDS THE
+   * INFORMATION ON WHICH TABLE AND FRAGMENT, THE LOCAL KEY AND IT NEEDS TO
+   * KNOW THE TYPE OF OPERATION TO PERFORM. TUP CAN SEND THE ATTRINFO DATA 
+   * EITHER TO THE TC BLOCK OR DIRECTLY TO THE APPLICATION. THE SCHEMA VERSION
+   * IS NEEDED SINCE TWO SCHEMA VERSIONS CAN BE ACTIVE SIMULTANEOUSLY ON A 
+   * TABLE.
+   * ----------------------------------------------------------------------- */
+  FragrecordPtr regFragptr;
+  regFragptr.i = regTcPtr->fragmentptr;
+  c_fragment_pool.getPtr(regFragptr);
+
   ndbrequire(localKeyFlag == 1);
-  localKey2 = localKey1 & MAX_TUPLES_PER_PAGE;
-  localKey1 = localKey1 >> MAX_TUPLES_BITS;
+  if(!regTcPtr->m_disk_table)
+    acckeyconf_tupkeyreq(signal, regTcPtr, regFragptr.p, localKey1, RNIL);
+  else
+    acckeyconf_load_diskpage(signal, tcConnectptr, regFragptr.p, localKey1);
+}
+
+void
+Dblqh::acckeyconf_tupkeyreq(Signal* signal, TcConnectionrec* regTcPtr,
+			    Fragrecord* regFragptrP, 
+			    Uint32 local_key,
+			    Uint32 disk_page)
+{
+  regTcPtr->transactionState = TcConnectionrec::WAIT_TUP;
+  /* ------------------------------------------------------------------------
+   * IT IS NOW TIME TO CONTACT THE TUPLE MANAGER. THE TUPLE MANAGER NEEDS THE
+   * INFORMATION ON WHICH TABLE AND FRAGMENT, THE LOCAL KEY AND IT NEEDS TO
+   * KNOW THE TYPE OF OPERATION TO PERFORM. TUP CAN SEND THE ATTRINFO DATA 
+   * EITHER TO THE TC BLOCK OR DIRECTLY TO THE APPLICATION. THE SCHEMA VERSION
+   * IS NEEDED SINCE TWO SCHEMA VERSIONS CAN BE ACTIVE SIMULTANEOUSLY ON A 
+   * TABLE.
+   * ----------------------------------------------------------------------- */
+  Uint32 localKey2 = local_key & MAX_TUPLES_PER_PAGE;
+  Uint32 localKey1 = local_key >> MAX_TUPLES_BITS;
+#ifdef TRACE_LQHKEYREQ
+  ndbout << "localkey: [ " << hex << localKey1 << " " << localKey2 << "]" 
+	 << endl;
+#endif
   Uint32 Ttupreq = regTcPtr->dirtyOp;
   Ttupreq = Ttupreq + (regTcPtr->opSimple << 1);
   Ttupreq = Ttupreq + (regTcPtr->operation << 6);
@@ -3942,35 +3876,27 @@
   /* ************< */
   /*  TUPKEYREQ  < */
   /* ************< */
-  TupKeyReq * const tupKeyReq = (TupKeyReq *)signal->getDataPtrSend();
   Uint32 sig0, sig1, sig2, sig3;
-
   sig0 = regTcPtr->tupConnectrec;
-  sig1 = regTcPtr->tableref;
+
+  TupKeyReq * const tupKeyReq = (TupKeyReq *)signal->getDataPtrSend();
   tupKeyReq->connectPtr = sig0;
   tupKeyReq->request = Ttupreq;
-  tupKeyReq->tableRef = sig1;
-  tupKeyReq->fragId = Tfragid;
   tupKeyReq->keyRef1 = localKey1;
   tupKeyReq->keyRef2 = localKey2;
 
   sig0 = regTcPtr->totReclenAi;
   sig1 = regTcPtr->applOprec;
   sig2 = regTcPtr->applRef;
-  sig3 = regTcPtr->schemaVersion;
-  FragrecordPtr regFragptr;
-  regFragptr.i = regTcPtr->fragmentptr;
-  ptrCheckGuard(regFragptr, cfragrecFileSize, fragrecord);
+  
   tupKeyReq->attrBufLen = sig0;
   tupKeyReq->opRef = sig1;
   tupKeyReq->applRef = sig2;
-  tupKeyReq->schemaVersion = sig3;
 
-  ndbrequire(regTcPtr->localFragptr < 2);
   sig0 = regTcPtr->storedProcId;
   sig1 = regTcPtr->transid[0];
   sig2 = regTcPtr->transid[1];
-  sig3 = regFragptr.p->tupFragptr[regTcPtr->localFragptr];
+  sig3 = regFragptrP->tupFragptr;
   Uint32 tup = refToBlock(regTcPtr->tcTupBlockref);
 
   tupKeyReq->storedProcedure = sig0;
@@ -3981,10 +3907,73 @@
   tupKeyReq->coordinatorTC = tcConnectptr.p->tcBlockref;
   tupKeyReq->tcOpIndex = tcConnectptr.p->tcOprec;
   tupKeyReq->savePointId = tcConnectptr.p->savePointId;
+  tupKeyReq->disk_page= disk_page;
 
   EXECUTE_DIRECT(tup, GSN_TUPKEYREQ, signal, TupKeyReq::SignalLength);
 }//Dblqh::execACCKEYCONF()
 
+void
+Dblqh::acckeyconf_load_diskpage(Signal* signal, TcConnectionrecPtr regTcPtr,
+				Fragrecord* regFragptrP, Uint32 local_key)
+{
+  int res;
+  if((res= c_tup->load_diskpage(signal, 
+				regTcPtr.p->tupConnectrec,
+				regFragptrP->tupFragptr, 
+				local_key, 
+				regTcPtr.p->operation)) > 0)
+  {
+    acckeyconf_tupkeyreq(signal, regTcPtr.p, regFragptrP, local_key, res);
+  }
+  else if(res == 0)
+  {
+    regTcPtr.p->transactionState = TcConnectionrec::WAIT_TUP;
+    regTcPtr.p->m_local_key = local_key;
+  }
+  else 
+  {
+    TupKeyRef * ref = (TupKeyRef *)signal->getDataPtr();
+    ref->userRef= regTcPtr.i;
+    ref->errorCode= ~0;
+    execTUPKEYREF(signal);
+  }
+}
+
+void
+Dblqh::acckeyconf_load_diskpage_callback(Signal* signal, 
+					 Uint32 callbackData,
+					 Uint32 disk_page)
+{
+  jamEntry();
+  tcConnectptr.i = callbackData;
+  ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
+  TcConnectionrec * const regTcPtr = tcConnectptr.p;
+
+  TcConnectionrec::TransactionState state = regTcPtr->transactionState;
+  if (likely(disk_page > 0 && state == TcConnectionrec::WAIT_TUP))
+  {
+    FragrecordPtr fragPtr;
+    c_fragment_pool.getPtr(fragPtr, regTcPtr->fragmentptr);
+    
+    acckeyconf_tupkeyreq(signal, regTcPtr, fragPtr.p, 
+			 regTcPtr->m_local_key,
+			 disk_page);
+  }
+  else if (state != TcConnectionrec::WAIT_TUP)
+  {
+    ndbrequire(state == TcConnectionrec::WAIT_TUP_TO_ABORT);
+    abortCommonLab(signal);
+    return;
+  }
+  else
+  {
+    TupKeyRef * ref = (TupKeyRef *)signal->getDataPtr();
+    ref->userRef= callbackData;
+    ref->errorCode= disk_page;
+    execTUPKEYREF(signal);
+  }
+}
+
 /* --------------------------------------------------------------------------
  * -------                       ENTER TUP...                         ------- 
  * ENTER TUPKEYCONF WITH
@@ -4011,7 +4000,6 @@
      * WE HAVE ALREADY SENT THE RESPONSE SO WE ARE NOT INTERESTED IN READ LENGTH
      * ---------------------------------------------------------------------- */
     regTcPtr->gci = cnewestGci;
-    releaseActiveFrag(signal);
     commitContinueAfterBlockedLab(signal);
     return;
   }//if
@@ -4046,22 +4034,18 @@
      * A NORMAL READ OPERATION IS NOT LOGGED BUT IS NOT COMMITTED UNTIL THE 
      * COMMIT SIGNAL ARRIVES. THUS WE CONTINUE PACKING THE RESPONSE.   
      * ---------------------------------------------------------------------- */
-    releaseActiveFrag(signal);
     packLqhkeyreqLab(signal);
     return;
   } else {
-    FragrecordPtr regFragptr;
-    regFragptr.i = regTcPtr->fragmentptr;
-    ptrCheckGuard(regFragptr, cfragrecFileSize, fragrecord);
+    FragrecordPtr regFragptr = fragptr;
     if (regFragptr.p->logFlag == Fragrecord::STATE_FALSE){
       if (regTcPtr->dirtyOp == ZTRUE) {
         jam();
 	/* ------------------------------------------------------------------
 	 * THIS OPERATION WAS A WRITE OPERATION THAT DO NOT NEED LOGGING AND 
 	 * THAT CAN CAN  BE COMMITTED IMMEDIATELY.                     
-	 * ------------------------------------------------------------------ */
+	 * ----------------------------------------------------------------- */
         regTcPtr->gci = cnewestGci;
-        releaseActiveFrag(signal);
         commitContinueAfterBlockedLab(signal);
         return;
       } else {
@@ -4071,7 +4055,6 @@
 	 * WE WILL PACK THE REQUEST/RESPONSE TO THE NEXT NODE/TO TC.   
 	 * ------------------------------------------------------------------ */
         regTcPtr->logWriteState = TcConnectionrec::NOT_WRITTEN;
-        releaseActiveFrag(signal);
         packLqhkeyreqLab(signal);
         return;
       }//if
@@ -4084,7 +4067,6 @@
        * A NORMAL WRITE OPERATION THAT NEEDS LOGGING AND WILL NOT BE 
        * PREMATURELY COMMITTED.                                   
        * -------------------------------------------------------------------- */
-      releaseActiveFrag(signal);
       logLqhkeyreqLab(signal);
       return;
     }//if
@@ -4119,13 +4101,13 @@
        * A NORMAL READ OPERATION IS NOT LOGGED BUT IS NOT COMMITTED UNTIL 
        * THE COMMIT SIGNAL ARRIVES. THUS WE CONTINUE PACKING THE RESPONSE.
        * -------------------------------------------------------------------- */
-      ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+      c_fragment_pool.getPtr(fragptr);
       packLqhkeyreqLab(signal);
       return;
     }//if
   } else {
     jam();
-    ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+    c_fragment_pool.getPtr(fragptr);
     if (fragptr.p->logFlag == Fragrecord::STATE_FALSE) {
       if (regTcPtr->dirtyOp == ZTRUE) {
 	/* ------------------------------------------------------------------
@@ -4892,99 +4874,11 @@
   }//if
 }//Dblqh::deleteTransidHash()
 
-/* --------------------------------------------------------------------------
- * -------               LINK OPERATION IN ACTIVE LIST ON FRAGMENT    -------
- *
- *       SUBROUTINE SHORT NAME: LAF
-// Input Pointers:
-// tcConnectptr
-// fragptr
- * ------------------------------------------------------------------------- */
-void Dblqh::linkActiveFrag(Signal* signal) 
-{
-  TcConnectionrecPtr lafTcConnectptr;
-  TcConnectionrec * const regTcPtr = tcConnectptr.p;
-  Fragrecord * const regFragPtr = fragptr.p;
-  Uint32 tcIndex = tcConnectptr.i;
-  lafTcConnectptr.i = regFragPtr->activeList;
-  regTcPtr->prevTc = RNIL;
-  regFragPtr->activeList = tcIndex;
-  ndbrequire(regTcPtr->listState == TcConnectionrec::NOT_IN_LIST);
-  regTcPtr->nextTc = lafTcConnectptr.i;
-  regTcPtr->listState = TcConnectionrec::IN_ACTIVE_LIST;
-  if (lafTcConnectptr.i == RNIL) {
-    return;
-  } else {
-    jam();
-    ptrCheckGuard(lafTcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
-    lafTcConnectptr.p->prevTc = tcIndex;
-  }//if
-  return;
-}//Dblqh::linkActiveFrag()
-
 /* -------------------------------------------------------------------------
  * -------       RELEASE OPERATION FROM ACTIVE LIST ON FRAGMENT      ------- 
  * 
  *       SUBROUTINE SHORT NAME = RAF
  * ------------------------------------------------------------------------- */
-void Dblqh::releaseActiveFrag(Signal* signal) 
-{
-  TcConnectionrec * const regTcPtr = tcConnectptr.p;
-  TcConnectionrecPtr ralTcNextConnectptr;
-  TcConnectionrecPtr ralTcPrevConnectptr;
-  fragptr.i = regTcPtr->fragmentptr;
-  ralTcPrevConnectptr.i = regTcPtr->prevTc;
-  ralTcNextConnectptr.i = regTcPtr->nextTc;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-  Fragrecord * const regFragPtr = fragptr.p;
-  ndbrequire(regTcPtr->listState == TcConnectionrec::IN_ACTIVE_LIST);
-  regTcPtr->listState = TcConnectionrec::NOT_IN_LIST;
-
-  if (ralTcNextConnectptr.i != RNIL) {
-    jam();
-    ptrCheckGuard(ralTcNextConnectptr, ctcConnectrecFileSize, tcConnectionrec);
-    ralTcNextConnectptr.p->prevTc = ralTcPrevConnectptr.i;
-  }//if
-  if (ralTcPrevConnectptr.i != RNIL) {
-    jam();
-    ptrCheckGuard(ralTcPrevConnectptr, ctcConnectrecFileSize, tcConnectionrec);
-    ralTcPrevConnectptr.p->nextTc = regTcPtr->nextTc;
-  } else {
-    jam();
-    /* ----------------------------------------------------------------------
-     *   OPERATION RECORD IS FIRST IN ACTIVE LIST    
-     *   THIS MEANS THAT THERE EXISTS NO PREVIOUS TC THAT NEEDS TO BE UPDATED.
-     * --------------------------------------------------------------------- */
-    regFragPtr->activeList = ralTcNextConnectptr.i;
-  }//if
-  if (regFragPtr->lcpRef != RNIL) {
-    jam();
-    lcpPtr.i = regFragPtr->lcpRef;
-    ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
-    ndbrequire(lcpPtr.p->lcpState == LcpRecord::LCP_WAIT_ACTIVE_FINISH);
-
-    /* --------------------------------------------------------------------
-     *   IF A FRAGMENT IS CURRENTLY STARTING A LOCAL CHECKPOINT AND IT 
-     *   IS WAITING FOR ACTIVE OPERATIONS TO BE COMPLETED WITH THE 
-     *   CURRENT PHASE, THEN IT IS CHECKED WHETHER THE 
-     *   LAST ACTIVE OPERATION WAS NOW COMPLETED.
-     * ------------------------------------------------------------------- */
-    if (regFragPtr->activeList == RNIL) {
-      jam();
-      /* ------------------------------------------------------------------
-       *       ACTIVE LIST ON FRAGMENT IS EMPTY AND WE ARE WAITING FOR 
-       *       THIS TO HAPPEN.    
-       *       WE WILL NOW START THE CHECKPOINT IN TUP AND ACC.
-       * ----------------------------------------------------------------- */
-      /*      SEND START LOCAL CHECKPOINT TO ACC AND TUP                   */
-      /* ----------------------------------------------------------------- */
-      fragptr.p->lcpRef = RNIL;
-      lcpPtr.p->lcpState = LcpRecord::LCP_START_CHKP;
-      sendStartLcp(signal);
-    }//if
-  }//if
-}//Dblqh::releaseActiveFrag()
-
 /* ######################################################################### */
 /* #######                   TRANSACTION MODULE                      ####### */
 /*      THIS MODULE HANDLES THE COMMIT AND THE COMPLETE PHASE.               */
@@ -5227,6 +5121,7 @@
     sendSignal(regTcPtr->reqBlockref, GSN_COMMITCONF, signal, 4, JBB);
     break;
   case TcConnectionrec::COMMIT_STOPPED:
+  case TcConnectionrec::WAIT_TUP_COMMIT:
     jam();
     regTcPtr->reqBlockref = reqBlockref;
     regTcPtr->reqRef = reqPtr;
@@ -5341,6 +5236,7 @@
 /*       THE NORMAL CASE.                                  */
 /*---------------------------------------------------------*/
   case TcConnectionrec::COMMIT_STOPPED:
+  case TcConnectionrec::WAIT_TUP_COMMIT:
     jam();
 /*---------------------------------------------------------*/
 /*       FOR SOME REASON THE COMPLETE PHASE STARTED AFTER  */
@@ -5414,6 +5310,7 @@
   TcConnectionrec * const regTcPtr = tcConnectptr.p;
   TcConnectionrec::LogWriteState logWriteState = regTcPtr->logWriteState;
   TcConnectionrec::TransactionState transState = regTcPtr->transactionState;
+  ndbrequire(regTcPtr->gci == gci || regTcPtr->gci == 0);
   regTcPtr->gci = gci; 
   if (transState == TcConnectionrec::PREPARED) {
     if (logWriteState == TcConnectionrec::WRITTEN) {
@@ -5483,6 +5380,7 @@
   Uint32 newestGci = cnewestGci;
   TcConnectionrec::LogWriteState logWriteState = regTcPtr->logWriteState;
   TcConnectionrec::TransactionState transState = regTcPtr->transactionState;
+  ndbrequire(regTcPtr->gci == gci || regTcPtr->gci == 0);
   regTcPtr->gci = gci;
   if (gci > newestGci) {
     jam();
@@ -5545,7 +5443,7 @@
 {
   FragrecordPtr regFragptr;
   regFragptr.i = tcConnectptr.p->fragmentptr;
-  ptrCheckGuard(regFragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(regFragptr);
   Fragrecord::FragStatus status = regFragptr.p->fragStatus;
   fragptr = regFragptr;
   switch (status) {
@@ -5629,6 +5527,13 @@
       tupCommitReq->hashValue = regTcPtr->hashValue;
       EXECUTE_DIRECT(tup, GSN_TUP_COMMITREQ, signal, 
 		     TupCommitReq::SignalLength);
+
+      if(signal->theData[0] != 0)
+      {
+	regTcPtr->transactionState = TcConnectionrec::WAIT_TUP_COMMIT;
+	return; // TUP_COMMIT was timesliced
+      }
+      
       Uint32 acc = refToBlock(regTcPtr->tcAccBlockref);
       signal->theData[0] = regTcPtr->accConnectrec;
       EXECUTE_DIRECT(acc, GSN_ACC_COMMITREQ, signal, 1);
@@ -5638,10 +5543,9 @@
 	signal->theData[0] = regTcPtr->accConnectrec;
 	EXECUTE_DIRECT(acc, GSN_ACC_COMMITREQ, signal, 1);
       }
-    }
-    jamEntry();
-    if (simpleRead) {
-      jam();
+      
+      if (simpleRead) {
+	jam();
 /* ------------------------------------------------------------------------- */
 /*THE OPERATION WAS A SIMPLE READ THUS THE COMMIT PHASE IS ONLY NEEDED TO    */
 /*RELEASE THE LOCKS. AT THIS POINT IN THE CODE THE LOCKS ARE RELEASED AND WE */
@@ -5649,10 +5553,45 @@
 /*RESOURCES BELONGING TO THIS OPERATION SINCE NO MORE WORK WILL BE           */
 /*PERFORMED.                                                                 */
 /* ------------------------------------------------------------------------- */
-      cleanUp(signal);
-      return;
-    }//if
+	cleanUp(signal);
+	return;
+      }//if
+    }
   }//if
+  jamEntry();
+  tupcommit_conf(signal, regTcPtr, regFragptr);
+}
+
+void
+Dblqh::tupcommit_conf_callback(Signal* signal, Uint32 tcPtrI)
+{
+  jamEntry();
+
+  tcConnectptr.i = tcPtrI;
+  ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
+  TcConnectionrec * const tcPtr = tcConnectptr.p;
+
+  ndbrequire(tcPtr->transactionState == TcConnectionrec::WAIT_TUP_COMMIT);
+
+  FragrecordPtr regFragptr;
+  regFragptr.i = tcPtr->fragmentptr;
+  c_fragment_pool.getPtr(regFragptr);
+  fragptr = regFragptr;
+
+  Uint32 acc = refToBlock(tcPtr->tcAccBlockref);
+  signal->theData[0] = tcPtr->accConnectrec;
+  EXECUTE_DIRECT(acc, GSN_ACC_COMMITREQ, signal, 1);
+  jamEntry();
+
+  tupcommit_conf(signal, tcPtr, regFragptr.p);
+}
+
+void
+Dblqh::tupcommit_conf(Signal* signal, 
+		      TcConnectionrec * regTcPtr,
+		      Fragrecord * regFragptr)
+{
+  Uint32 dirtyOp = regTcPtr->dirtyOp;
   Uint32 seqNoReplica = regTcPtr->seqNoReplica;
   if (regTcPtr->gci > regFragptr->newestGci) {
     jam();
@@ -5980,7 +5919,6 @@
 {
   jamEntry();
   terrorCode = signal->theData[1];
-  releaseActiveFrag(signal);
   abortErrorLab(signal);
   return;
 }//Dblqh::execACC_TO_REF()
@@ -5998,7 +5936,6 @@
   switch (tcPtr->transactionState) {
   case TcConnectionrec::WAIT_ACC:
     jam();
-    releaseActiveFrag(signal);
     break;
   case TcConnectionrec::WAIT_ACC_ABORT:
   case TcConnectionrec::ABORT_STOPPED:
@@ -6146,18 +6083,6 @@
     return;
   case TcConnectionrec::WAIT_ACC:
     jam();
-    if (regTcPtr->listState == TcConnectionrec::ACC_BLOCK_LIST) {
-      jam();
-/* ------------------------------------------------------------------------- */
-// If the operation is in the ACC Blocked list the operation is not allowed
-// to start yet. We release it from the ACC Blocked list and will go through
-// the gate in abortCommonLab(..) where it will be blocked.
-/* ------------------------------------------------------------------------- */
-      fragptr.i = regTcPtr->fragmentptr;
-      ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-      releaseAccList(signal);
-    } else {
-      jam();
 /* ------------------------------------------------------------------------- */
 // We start the abort immediately since the operation is still in the active
 // list and the fragment cannot have been frozen yet. By sending LCP_HOLDOPCONF
@@ -6166,9 +6091,8 @@
 // We cannot accept being blocked before aborting ACC here since that would
 // lead to seriously complex issues.
 /* ------------------------------------------------------------------------- */
-      abortContinueAfterBlockedLab(signal, false);
-      return;
-    }//if
+    abortContinueAfterBlockedLab(signal, false);
+    return;
     break;
   case TcConnectionrec::LOG_QUEUED:
     jam();
@@ -6214,6 +6138,7 @@
 /* ------------------------------------------------------------------------- */
     return;
     break;
+  case TcConnectionrec::WAIT_TUP_COMMIT:
   case TcConnectionrec::COMMIT_STOPPED:
   case TcConnectionrec::LOG_COMMIT_QUEUED:
   case TcConnectionrec::COMMIT_QUEUED:
@@ -6310,13 +6235,12 @@
   fragptr.i = regTcPtr->fragmentptr;
   if (fragptr.i != RNIL) {
     jam();
-    ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+    c_fragment_pool.getPtr(fragptr);
     switch (fragptr.p->fragStatus) {
     case Fragrecord::FSACTIVE:
     case Fragrecord::CRASH_RECOVERING:
     case Fragrecord::ACTIVE_CREATION:
       jam();
-      linkActiveFrag(signal);
       abortContinueAfterBlockedLab(signal, true);
       return;
       break;
@@ -6356,7 +6280,7 @@
    * ------------------------------------------------------------------------ */
   TcConnectionrec * const regTcPtr = tcConnectptr.p;
   fragptr.i = regTcPtr->fragmentptr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(fragptr);
   if ((cCommitBlocked == true) &&
       (fragptr.p->fragActiveStatus == ZTRUE) &&
       (canBlock == true) &&
@@ -6378,7 +6302,6 @@
 // log part to ensure that we don't get a buffer explosion in the delayed
 // signal buffer instead.
 /*---------------------------------------------------------------------------*/
-    releaseActiveFrag(signal);
     logPartPtr.i = regTcPtr->hashValue & 3;
     ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
     linkWaitLog(signal, logPartPtr);
@@ -6422,17 +6345,17 @@
     if (regTcPtr->currTupAiLen == regTcPtr->totReclenAi) {
       jam();
       regTcPtr->abortState = TcConnectionrec::ABORT_IDLE;
+      fragptr.i = regTcPtr->fragmentptr;
+      c_fragment_pool.getPtr(fragptr);
       rwConcludedLab(signal);
       return;
     } else {
       ndbrequire(regTcPtr->currTupAiLen < regTcPtr->totReclenAi);
       jam();
-      releaseActiveFrag(signal);
       regTcPtr->transactionState = TcConnectionrec::WAIT_AI_AFTER_ABORT;
       return;
     }//if
   }//if
-  releaseActiveFrag(signal);
   continueAbortLab(signal);
   return;
 }//Dblqh::execACC_ABORTCONF()
@@ -6724,39 +6647,39 @@
         } else {
           scanptr.i = tcConnectptr.p->tcScanRec;
 	  c_scanRecordPool.getPtr(scanptr);
-          if (scanptr.p->scanType == ScanRecord::COPY) {
+	  switch(scanptr.p->scanType){
+	  case ScanRecord::COPY: 
+	  {
             jam();
             if (scanptr.p->scanNodeId == tcNodeFailptr.p->oldNodeId) {
               jam();
 	      /* ------------------------------------------------------------
 	       * THE RECEIVER OF THE COPY HAVE FAILED. 
 	       * WE HAVE TO CLOSE THE COPY PROCESS. 
-	       * ------------------------------------------------------------ */
+	       * ----------------------------------------------------------- */
               tcConnectptr.p->tcNodeFailrec = tcNodeFailptr.i;
               tcConnectptr.p->abortState = TcConnectionrec::NEW_FROM_TC;
               closeCopyRequestLab(signal);
               return;
-            }//if
-          } else {
-            if (scanptr.p->scanType == ScanRecord::SCAN) {
-              jam();
-              if (refToNode(tcConnectptr.p->tcBlockref) == 
-		  tcNodeFailptr.p->oldNodeId) {
-                jam();
-                tcConnectptr.p->tcNodeFailrec = tcNodeFailptr.i;
-                tcConnectptr.p->abortState = TcConnectionrec::NEW_FROM_TC;
-                closeScanRequestLab(signal);
-                return;
-              }//if
-            } else {
-              jam();
-	      /* ------------------------------------------------------------
-	       * THIS IS AN ERROR THAT SHOULD NOT OCCUR. WE CRASH THE SYSTEM.
-	       * ------------------------------------------------------------ */
-               systemErrorLab(signal, __LINE__);
-               return;
-            }//if
-          }//if
+            }
+	    break;
+	  }
+	  case ScanRecord::SCAN:
+	  {
+	    jam();
+	    if (refToNode(tcConnectptr.p->tcBlockref) == 
+		tcNodeFailptr.p->oldNodeId) {
+	      jam();
+	      tcConnectptr.p->tcNodeFailrec = tcNodeFailptr.i;
+	      tcConnectptr.p->abortState = TcConnectionrec::NEW_FROM_TC;
+	      closeScanRequestLab(signal);
+	      return;
+	    }//if
+	    break;
+	  }
+	  default:
+	    ndbrequire(false);
+	  }
         }//if
       }//if
     }//if
@@ -6897,6 +6820,9 @@
                   nextScanConf->localKey[0] & MAX_TUPLES_PER_PAGE;
     nextScanConf->localKey[0] = nextScanConf->localKey[0] >> MAX_TUPLES_BITS;
   }//if
+
+  fragptr.i = scanptr.p->fragPtrI;
+  c_fragment_pool.getPtr(fragptr);
   switch (scanptr.p->scanState) {
   case ScanRecord::WAIT_CLOSE_SCAN:
     jam();
@@ -6953,7 +6879,6 @@
     break;
   case ScanRecord::WAIT_DELETE_STORED_PROC_ID_SCAN:
     jam();
-    releaseActiveFrag(signal);
     tupScanCloseConfLab(signal);
     break;
   case ScanRecord::WAIT_STORED_PROC_COPY:
@@ -6963,7 +6888,6 @@
     break;
   case ScanRecord::WAIT_DELETE_STORED_PROC_ID_COPY:
     jam();
-    releaseActiveFrag(signal);
     tupCopyCloseConfLab(signal);
     break;
   default:
@@ -7090,7 +7014,7 @@
   }//if
 
   fragptr.i = tcConnectptr.p->fragmentptr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(fragptr);
 
   /**
    * Change parameters while running
@@ -7156,7 +7080,6 @@
   switch (fragptr.p->fragStatus) {
   case Fragrecord::FSACTIVE:
     jam();
-    linkActiveFrag(signal);
     break;
   case Fragrecord::BLOCKED:
     jam();
@@ -7260,7 +7183,7 @@
       scanptr.p->scanCompletedStatus = ZTRUE;
 
       fragptr.i = tcConnectptr.p->fragmentptr;
-      ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+      c_fragment_pool.getPtr(fragptr);
 
       if (scanptr.p->scanLockHold == ZTRUE) {
 	if (scanptr.p->m_curr_batch_size_rows > 0) {
@@ -7340,7 +7263,6 @@
 {
   tcConnectptr.i = scanptr.p->scanTcrec;
   ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);  
-  releaseActiveFrag(signal);
 
   if (scanptr.p->scanReleaseCounter == scanptr.p->m_curr_batch_size_rows) {
     if ((scanptr.p->scanErrorCounter > 0) ||
@@ -7459,7 +7381,6 @@
                                     bool crash_flag)
 {
   Uint32* acc_ptr;
-  Uint32 attr_buf_rec, attr_buf_index;
   if (!((index < MAX_PARALLEL_OP_PER_SCAN) &&
        index < scanP->scan_acc_index)) {
     ndbrequire(crash_flag);
@@ -7558,7 +7479,7 @@
   }//if
 
   ndbrequire(c_scanRecordPool.seize(scanptr));
-  initScanTc(signal,
+  initScanTc(scanFragReq,
              transid1,
              transid2,
              fragId,
@@ -7681,7 +7602,7 @@
   c_scanRecordPool.getPtr(scanptr);
 
   fragptr.i = tcConnectptr.p->fragmentptr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(fragptr);
   finishScanrec(signal);
   releaseScanrec(signal);
   tcConnectptr.p->transactionState = TcConnectionrec::IDLE;
@@ -7967,7 +7888,7 @@
 void Dblqh::storedProcConfScanLab(Signal* signal) 
 {
   fragptr.i = tcConnectptr.p->fragmentptr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(fragptr);
   if (scanptr.p->scanCompletedStatus == ZTRUE) {
     jam();
     // STOP THE SCAN PROCESS IF THIS HAS BEEN REQUESTED.
@@ -7977,7 +7898,6 @@
   switch (fragptr.p->fragStatus) {
   case Fragrecord::FSACTIVE:
     jam();
-    linkActiveFrag(signal);
     break;
   case Fragrecord::BLOCKED:
     jam();
@@ -8026,10 +7946,9 @@
   tcConnectptr.i = scanptr.p->scanTcrec;
   ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
   fragptr.i = tcConnectptr.p->fragmentptr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(fragptr);
   if (signal->theData[1] == ZTRUE) {
     jam();
-    releaseActiveFrag(signal);
     signal->theData[0] = ZCHECK_LCP_STOP_BLOCKED;
     signal->theData[1] = scanptr.i;
     sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 10, 2);
@@ -8038,7 +7957,6 @@
   }//if
   if (fragptr.p->fragStatus != Fragrecord::FSACTIVE) {
     ndbrequire(fragptr.p->fragStatus == Fragrecord::BLOCKED); 
-    releaseActiveFrag(signal);
     linkFragQueue(signal);
     tcConnectptr.p->transactionState = TcConnectionrec::SCAN_CHECK_STOPPED;
     signal->theData[0] = RNIL;
@@ -8050,7 +7968,6 @@
   switch (fragptr.p->fragStatus) {
   case Fragrecord::FSACTIVE:
     jam();
-    linkActiveFrag(signal);
     continueAfterCheckLcpStopBlocked(signal);
     break;
   case Fragrecord::BLOCKED:
@@ -8103,7 +8020,6 @@
      *       REQUEST IS RECEIVED. IF WE DO NOT HAVE ANY NEED FOR
      *       LOCKS WE CAN CLOSE THE SCAN IMMEDIATELY.
      * --------------------------------------------------------------------- */
-    releaseActiveFrag(signal);
     /*************************************************************
      *       STOP THE SCAN PROCESS IF THIS HAS BEEN REQUESTED.
      ************************************************************ */    
@@ -8148,7 +8064,6 @@
      *       STOP THE SCAN PROCESS IF THIS HAS BEEN REQUESTED.
      ************************************************************ */    
     if (scanptr.p->scanCompletedStatus == ZTRUE) {
-      releaseActiveFrag(signal);
       if ((scanptr.p->scanLockHold == ZTRUE) && 
 	  (scanptr.p->m_curr_batch_size_rows > 0)) {
 	jam();
@@ -8163,7 +8078,6 @@
 
     if (scanptr.p->m_curr_batch_size_rows > 0) {
       jam();
-      releaseActiveFrag(signal);
       scanptr.p->scanState = ScanRecord::WAIT_SCAN_NEXTREQ;
       sendScanFragConf(signal, ZFALSE);
       return;
@@ -8193,7 +8107,6 @@
    * ---------------------------------------------------------------------- */
   if (scanptr.p->scanCompletedStatus == ZTRUE) {
     jam();
-    releaseActiveFrag(signal);
     if ((scanptr.p->scanLockHold == ZTRUE) && 
         (scanptr.p->m_curr_batch_size_rows > 0)) {
       jam();
@@ -8204,53 +8117,125 @@
     closeScanLab(signal);
     return;
   }//if
-  jam();
-  Uint32 tableRef;
-  Uint32 tupFragPtr;
-  Uint32 reqinfo = (scanptr.p->scanLockHold == ZFALSE);
-  reqinfo = reqinfo + (tcConnectptr.p->operation << 6);
-  reqinfo = reqinfo + (tcConnectptr.p->opExec << 10);
-  tcConnectptr.p->transactionState = TcConnectionrec::SCAN_TUPKEY;
-  fragptr.i = tcConnectptr.p->fragmentptr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-  if (! scanptr.p->rangeScan) {
-    tableRef = tcConnectptr.p->tableref;
-    tupFragPtr = fragptr.p->tupFragptr[scanptr.p->scanLocalFragid & 1];
-  } else {
+
+  Fragrecord* fragPtrP= fragptr.p;
+  if (scanptr.p->rangeScan) {
     jam();
     // for ordered index use primary table
-    FragrecordPtr tFragPtr;
-    tFragPtr.i = fragptr.p->tableFragptr;
-    ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord);
-    tableRef = tFragPtr.p->tabRef;
-    tupFragPtr = tFragPtr.p->tupFragptr[scanptr.p->scanLocalFragid & 1];
+    fragPtrP= c_fragment_pool.getPtr(fragPtrP->tableFragptr);
+  }
+
+  tcConnectptr.p->transactionState = TcConnectionrec::SCAN_TUPKEY;
+  if(tcConnectptr.p->m_disk_table)
+  {
+    next_scanconf_load_diskpage(signal, scanptr, tcConnectptr,fragPtrP);
   }
+  else
+  {
+    next_scanconf_tupkeyreq(signal, scanptr, tcConnectptr.p, fragPtrP, RNIL);
+  }
+}
+
+void
+Dblqh::next_scanconf_load_diskpage(Signal* signal, 
+				   ScanRecordPtr scanPtr,
+				   Ptr<TcConnectionrec> regTcPtr,
+				   Fragrecord* fragPtrP)
+{
+  jam();
+  
+  int res;
+  Uint32 local_key;
+  local_key = scanptr.p->scanLocalref[0] << MAX_TUPLES_BITS;
+  local_key += scanptr.p->scanLocalref[1];
+  
+  if((res= c_tup->load_diskpage_scan(signal, 
+				     regTcPtr.p->tupConnectrec,
+				     fragPtrP->tupFragptr, 
+				     local_key, 
+				     0)) > 0)
+  {
+    next_scanconf_tupkeyreq(signal, scanptr, regTcPtr.p, fragPtrP, res);
+  }
+  else if(unlikely(res != 0))
   {
     jam();
-    TupKeyReq * const tupKeyReq = (TupKeyReq *)signal->getDataPtrSend(); 
+    TupKeyRef * ref = (TupKeyRef *)signal->getDataPtr();
+    ref->userRef= regTcPtr.i;
+    ref->errorCode= ~0;
+    execTUPKEYREF(signal);
+  }
+}
 
-    tupKeyReq->connectPtr = tcConnectptr.p->tupConnectrec;
-    tupKeyReq->request = reqinfo;
-    tupKeyReq->tableRef = tableRef;
-    tupKeyReq->fragId = scanptr.p->scanLocalFragid;
-    tupKeyReq->keyRef1 = scanptr.p->scanLocalref[0];
-    tupKeyReq->keyRef2 = scanptr.p->scanLocalref[1];
-    tupKeyReq->attrBufLen = 0;
-    tupKeyReq->opRef = scanptr.p->scanApiOpPtr; 
-    tupKeyReq->applRef = scanptr.p->scanApiBlockref;
-    tupKeyReq->schemaVersion = scanptr.p->scanSchemaVersion;
-    tupKeyReq->storedProcedure = scanptr.p->scanStoredProcId;
-    tupKeyReq->transId1 = tcConnectptr.p->transid[0];
-    tupKeyReq->transId2 = tcConnectptr.p->transid[1];
-    tupKeyReq->fragPtr = tupFragPtr;
-    tupKeyReq->primaryReplica = (tcConnectptr.p->seqNoReplica == 0)?true:false;
-    tupKeyReq->coordinatorTC = tcConnectptr.p->tcBlockref;
-    tupKeyReq->tcOpIndex = tcConnectptr.p->tcOprec;
-    tupKeyReq->savePointId = tcConnectptr.p->savePointId;
-    Uint32 blockNo = refToBlock(tcConnectptr.p->tcTupBlockref);
-    EXECUTE_DIRECT(blockNo, GSN_TUPKEYREQ, signal, 
-               TupKeyReq::SignalLength);
+void
+Dblqh::next_scanconf_load_diskpage_callback(Signal* signal, 
+					    Uint32 callbackData,
+					    Uint32 disk_page)
+{
+  jamEntry();
+
+  Ptr<TcConnectionrec> regTcPtr;
+  regTcPtr.i= callbackData;
+  ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec);
+  
+  ScanRecordPtr scanPtr;
+  c_scanRecordPool.getPtr(scanPtr, regTcPtr.p->tcScanRec);
+
+  if(disk_page > 0)
+  {
+    FragrecordPtr fragPtr;
+    c_fragment_pool.getPtr(fragPtr, regTcPtr.p->fragmentptr);
+
+    if (scanPtr.p->rangeScan) {
+      jam();
+      // for ordered index use primary table
+      fragPtr.p = c_fragment_pool.getPtr(fragPtr.p->tableFragptr);
+    }
+    
+    next_scanconf_tupkeyreq(signal, scanPtr, regTcPtr.p, fragPtr.p, disk_page);
   }
+  else
+  {
+    TupKeyRef * ref = (TupKeyRef *)signal->getDataPtr();
+    ref->userRef= callbackData;
+    ref->errorCode= disk_page;
+    execTUPKEYREF(signal);
+  }
+}
+
+void
+Dblqh::next_scanconf_tupkeyreq(Signal* signal, 
+			       Ptr<ScanRecord> scanPtr,
+			       TcConnectionrec * regTcPtr,
+			       Fragrecord* fragPtrP,
+			       Uint32 disk_page)
+{
+  jam();
+  Uint32 reqinfo = (scanPtr.p->scanLockHold == ZFALSE);
+  reqinfo = reqinfo + (regTcPtr->operation << 6);
+  reqinfo = reqinfo + (regTcPtr->opExec << 10);
+  
+  TupKeyReq * const tupKeyReq = (TupKeyReq *)signal->getDataPtrSend(); 
+  
+  tupKeyReq->connectPtr = regTcPtr->tupConnectrec;
+  tupKeyReq->request = reqinfo;
+  tupKeyReq->keyRef1 = scanPtr.p->scanLocalref[0];
+  tupKeyReq->keyRef2 = scanPtr.p->scanLocalref[1];
+  tupKeyReq->attrBufLen = 0;
+  tupKeyReq->opRef = scanPtr.p->scanApiOpPtr; 
+  tupKeyReq->applRef = scanPtr.p->scanApiBlockref;
+  tupKeyReq->storedProcedure = scanPtr.p->scanStoredProcId;
+  tupKeyReq->transId1 = regTcPtr->transid[0];
+  tupKeyReq->transId2 = regTcPtr->transid[1];
+  tupKeyReq->fragPtr = fragPtrP->tupFragptr;
+  tupKeyReq->primaryReplica = (regTcPtr->seqNoReplica == 0)?true:false;
+  tupKeyReq->coordinatorTC = regTcPtr->tcBlockref;
+  tupKeyReq->tcOpIndex = regTcPtr->tcOprec;
+  tupKeyReq->savePointId = regTcPtr->savePointId;
+  tupKeyReq->disk_page= disk_page;
+  Uint32 blockNo = refToBlock(regTcPtr->tcTupBlockref);
+  EXECUTE_DIRECT(blockNo, GSN_TUPKEYREQ, signal, 
+		 TupKeyReq::SignalLength);
 }
 
 /* -------------------------------------------------------------------------
@@ -8285,7 +8270,7 @@
     // for ordered index use primary table
     FragrecordPtr tFragPtr;
     tFragPtr.i = fragptr.p->tableFragptr;
-    ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord);
+    c_fragment_pool.getPtr(tFragPtr);
     tableId = tFragPtr.p->tabRef;
   }
 
@@ -8311,7 +8296,6 @@
 
   tcConnectptr.p->transactionState = TcConnectionrec::SCAN_STATE_USED;
   scanptr.i = tcConnectptr.p->tcScanRec;
-  releaseActiveFrag(signal);
   c_scanRecordPool.getPtr(scanptr);
   if (scanptr.p->scanCompletedStatus == ZTRUE) {
     /* ---------------------------------------------------------------------
@@ -8366,7 +8350,6 @@
   switch (fragptr.p->fragStatus) {
   case Fragrecord::FSACTIVE:
     jam();
-    linkActiveFrag(signal);
     break;
   case Fragrecord::BLOCKED:
     jam();
@@ -8429,7 +8412,6 @@
 {
   tcConnectptr.p->transactionState = TcConnectionrec::SCAN_STATE_USED;
   scanptr.i = tcConnectptr.p->tcScanRec;
-  releaseActiveFrag(signal);
   c_scanRecordPool.getPtr(scanptr);
   if (scanptr.p->scanCompletedStatus == ZTRUE) {
     /* ---------------------------------------------------------------------
@@ -8500,11 +8482,10 @@
 void Dblqh::closeScanLab(Signal* signal) 
 {
   fragptr.i = tcConnectptr.p->fragmentptr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(fragptr);
   switch (fragptr.p->fragStatus) {
   case Fragrecord::FSACTIVE:
     jam();
-    linkActiveFrag(signal);
     break;
   case Fragrecord::BLOCKED:
     jam();
@@ -8554,7 +8535,6 @@
     scanptr.p->scanCompletedStatus != ZTRUE)
   {
     jam();
-    releaseActiveFrag(signal);
     continueAfterReceivingAllAiLab(signal);
     return;
   }
@@ -8577,7 +8557,7 @@
 void Dblqh::tupScanCloseConfLab(Signal* signal) 
 {
   fragptr.i = tcConnectptr.p->fragmentptr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(fragptr);
   if (tcConnectptr.p->abortState == TcConnectionrec::NEW_FROM_TC) {
     jam();
     tcNodeFailptr.i = tcConnectptr.p->tcNodeFailrec;
@@ -8678,7 +8658,7 @@
    */
   FragrecordPtr tFragPtr;
   tFragPtr.i = fragptr.p->tableFragptr;
-  ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(tFragPtr);
   scanptr.p->fragPtrI = fragptr.p->tableFragptr;
   
   /**
@@ -8736,7 +8716,7 @@
  *
  *       SUBROUTINE SHORT NAME = IST
  * ========================================================================= */
-void Dblqh::initScanTc(Signal* signal,
+void Dblqh::initScanTc(const ScanFragReq* req,
                        Uint32 transid1,
                        Uint32 transid2,
                        Uint32 fragId,
@@ -8761,6 +8741,13 @@
   tcConnectptr.p->commitAckMarker = RNIL;
   tcConnectptr.p->m_offset_current_keybuf = 0;
   tcConnectptr.p->m_scan_curr_range_no = 0;
+  tcConnectptr.p->m_disk_table = tabptr.p->m_disk_table;
+
+  TablerecPtr tTablePtr;
+  tTablePtr.i = tabptr.p->primaryTableId;
+  ptrCheckGuard(tTablePtr, ctabrecFileSize, tablerec);
+  tcConnectptr.p->m_disk_table = tTablePtr.p->m_disk_table &&
+    (!req || !ScanFragReq::getNoDiskFlag(req->requestInfo));  
 
   tabptr.p->usageCount++;
 }//Dblqh::initScanTc()
@@ -8798,7 +8785,7 @@
   
   FragrecordPtr tFragPtr;
   tFragPtr.i = scanptr.p->fragPtrI;
-  ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(tFragPtr);
 
   const Uint32 scanNumber = scanptr.p->scanNumber;
   ndbrequire(!tFragPtr.p->m_scanNumberMask.get(scanNumber));
@@ -8842,10 +8829,12 @@
 #endif
   }
 
-  restart.p->scanState = ScanRecord::SCAN_FREE; // set in initScanRec
+  /**
+   * This state is a bit weird, but that what set in initScanRec
+   */
+  restart.p->scanState = ScanRecord::SCAN_FREE;
   if(tcConnectptr.p->transactionState == TcConnectionrec::SCAN_STATE_USED)
   {
-    jam();
     scanptr = restart;
     continueAfterReceivingAllAiLab(signal);  
   }
@@ -8853,6 +8842,7 @@
   {
     ndbrequire(tcConnectptr.p->transactionState == TcConnectionrec::WAIT_SCAN_AI);
   }
+  
   scanptr = tmpScan;
   tcConnectptr = tmpTc;
 }//Dblqh::finishScanrec()
@@ -8890,9 +8880,9 @@
   const Uint32 scanOp = scanP->m_curr_batch_size_rows;
   const Uint32 nodeId = refToNode(ref);
   const bool connectedToNode = getNodeInfo(nodeId).m_connected;
-  const Uint32 type = getNodeInfo(nodeId).m_type;
-  const bool is_api = (type >= NodeInfo::API && type <= NodeInfo::REP);
-  const bool old_dest = (getNodeInfo(nodeId).m_version < MAKE_VERSION(3,5,0));
+  //const Uint32 type = getNodeInfo(nodeId).m_type;
+  //const bool is_api= (type >= NodeInfo::API && type <= NodeInfo::REP);
+  //const bool old_dest= (getNodeInfo(nodeId).m_version < MAKE_VERSION(3,5,0));
   const bool longable = true; // TODO is_api && !old_dest;
 
   Uint32 * dst = keyInfo->keyData;
@@ -8993,7 +8983,7 @@
     return;
   }
   ScanFragConf * conf = (ScanFragConf*)&signal->theData[0];
-  NodeId tc_node_id= refToNode(tcConnectptr.p->clientBlockref);
+  //NodeId tc_node_id= refToNode(tcConnectptr.p->clientBlockref);
   Uint32 trans_id1= tcConnectptr.p->transid[0];
   Uint32 trans_id2= tcConnectptr.p->transid[1];
 
@@ -9088,6 +9078,7 @@
   scanptr.p->rangeScan = 0;
   scanptr.p->tupScan = 0;
   seizeTcrec();
+  tcConnectptr.p->clientBlockref = userRef;
   
   /**
    * Remove implicit cast/usage of CopyFragReq
@@ -9095,7 +9086,6 @@
   //initCopyrec(signal);
   scanptr.p->copyPtr = copyPtr;
   scanptr.p->scanType = ScanRecord::COPY;
-  scanptr.p->scanApiBlockref = userRef;
   scanptr.p->scanNodeId = nodeId;
   scanptr.p->scanTcrec = tcConnectptr.i;
   scanptr.p->scanSchemaVersion = copyFragReq->schemaVersion;
@@ -9104,10 +9094,13 @@
   scanptr.p->scanNumber = NR_ScanNo;
   scanptr.p->scanKeyinfoFlag = 0; // Don't put into hash
   scanptr.p->fragPtrI = fragptr.i;
+  scanptr.p->scanApiOpPtr = tcConnectptr.i;
+  scanptr.p->scanApiBlockref = reference();
   fragptr.p->m_scanNumberMask.clear(NR_ScanNo);
   scanptr.p->scanBlockref = DBACC_REF;
-
-  initScanTc(signal,
+  scanptr.p->scanLockHold = ZFALSE;
+  
+  initScanTc(0,
              0,
              (DBLQH << 20) + (cownNodeid << 8),
              fragId,
@@ -9174,7 +9167,7 @@
 /*   PRECONDITION: SCAN_STATE = WAIT_STORED_PROC_COPY                        */
 /*---------------------------------------------------------------------------*/
   fragptr.i = tcConnectptr.p->fragmentptr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(fragptr);
   if (scanptr.p->scanCompletedStatus == ZTRUE) {
     jam();
 /*---------------------------------------------------------------------------*/
@@ -9189,7 +9182,6 @@
   switch (fragptr.p->fragStatus) {
   case Fragrecord::FSACTIVE:
     jam();
-    linkActiveFrag(signal);
     break;
   case Fragrecord::BLOCKED:
     jam();
@@ -9254,7 +9246,6 @@
 /*   THERE ARE NO MORE TUPLES TO FETCH. WE NEED TO CLOSE                     */
 /*   THE COPY IN ACC AND DELETE THE STORED PROCEDURE IN TUP                  */
 /*---------------------------------------------------------------------------*/
-    releaseActiveFrag(signal);
     if (tcConnectptr.p->copyCountWords == 0) {
       closeCopyLab(signal);
       return;
@@ -9278,48 +9269,21 @@
 
   set_acc_ptr_in_scan_record(scanptr.p, 0, nextScanConf->accOperationPtr);
   initCopyTc(signal);
-  copySendTupkeyReqLab(signal);
-  return;
-}//Dblqh::nextScanConfCopyLab()
 
-void Dblqh::copySendTupkeyReqLab(Signal* signal) 
-{
-  Uint32 reqinfo = 0;
-  Uint32 tupFragPtr;
-
-  reqinfo = reqinfo + (tcConnectptr.p->operation << 6);
-  reqinfo = reqinfo + (tcConnectptr.p->opExec << 10);
-  tcConnectptr.p->transactionState = TcConnectionrec::COPY_TUPKEY;
+  Fragrecord* fragPtrP= fragptr.p;
   scanptr.p->scanState = ScanRecord::WAIT_TUPKEY_COPY;
-  fragptr.i = tcConnectptr.p->fragmentptr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-  tupFragPtr = fragptr.p->tupFragptr[scanptr.p->scanLocalFragid & 1];
+  tcConnectptr.p->transactionState = TcConnectionrec::COPY_TUPKEY;
+  if(tcConnectptr.p->m_disk_table)
   {
-    TupKeyReq * const tupKeyReq = (TupKeyReq *)signal->getDataPtrSend(); 
-
-    tupKeyReq->connectPtr = tcConnectptr.p->tupConnectrec;
-    tupKeyReq->request = reqinfo;
-    tupKeyReq->tableRef = tcConnectptr.p->tableref;
-    tupKeyReq->fragId = scanptr.p->scanLocalFragid;
-    tupKeyReq->keyRef1 = scanptr.p->scanLocalref[0];
-    tupKeyReq->keyRef2 = scanptr.p->scanLocalref[1];
-    tupKeyReq->attrBufLen = 0;
-    tupKeyReq->opRef = tcConnectptr.i;
-    tupKeyReq->applRef = cownref;
-    tupKeyReq->schemaVersion = scanptr.p->scanSchemaVersion;
-    tupKeyReq->storedProcedure = scanptr.p->scanStoredProcId;
-    tupKeyReq->transId1 = tcConnectptr.p->transid[0];
-    tupKeyReq->transId2 = tcConnectptr.p->transid[1];
-    tupKeyReq->fragPtr = tupFragPtr;
-    tupKeyReq->primaryReplica = (tcConnectptr.p->seqNoReplica == 0)?true:false;
-    tupKeyReq->coordinatorTC = tcConnectptr.p->tcBlockref;
-    tupKeyReq->tcOpIndex = tcConnectptr.p->tcOprec;
-    tupKeyReq->savePointId = tcConnectptr.p->savePointId;
-    Uint32 blockNo = refToBlock(tcConnectptr.p->tcTupBlockref);
-    EXECUTE_DIRECT(blockNo, GSN_TUPKEYREQ, signal, 
-               TupKeyReq::SignalLength);
+    next_scanconf_load_diskpage(signal, scanptr, tcConnectptr,fragPtrP);
+  }
+  else
+  {
+    next_scanconf_tupkeyreq(signal, scanptr, tcConnectptr.p, fragPtrP, RNIL);
   }
-}//Dblqh::copySendTupkeyReqLab()
+  return;
+}//Dblqh::nextScanConfCopyLab()
+
 
 /*---------------------------------------------------------------------------*/
 /*   USED IN COPYING OPERATION TO RECEIVE ATTRINFO FROM TUP.                 */
@@ -9372,7 +9336,6 @@
   scanptr.i = tcConnectptr.p->tcScanRec;
   c_scanRecordPool.getPtr(scanptr);
   ScanRecord* scanP = scanptr.p;
-  releaseActiveFrag(signal);
   if (tcConnectptr.p->errorCode != 0) {
     jam();
     closeCopyLab(signal);
@@ -9510,7 +9473,7 @@
 void Dblqh::nextRecordCopy(Signal* signal)
 {
   fragptr.i = tcConnectptr.p->fragmentptr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(fragptr);
   scanptr.i = tcConnectptr.p->tcScanRec;
   c_scanRecordPool.getPtr(scanptr);
   if (scanptr.p->scanState != ScanRecord::WAIT_LQHKEY_COPY) {
@@ -9527,7 +9490,6 @@
   switch (fragptr.p->fragStatus) {
   case Fragrecord::FSACTIVE:
     jam();
-    linkActiveFrag(signal);
     break;
   case Fragrecord::BLOCKED:
     jam();
@@ -9594,14 +9556,13 @@
   tcConnectptr.p->transid[0] = 0;
   tcConnectptr.p->transid[1] = 0;
   fragptr.i = tcConnectptr.p->fragmentptr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(fragptr);
   scanptr.i = tcConnectptr.p->tcScanRec;
   c_scanRecordPool.getPtr(scanptr);
   scanptr.p->scanState = ScanRecord::WAIT_CLOSE_COPY;
   switch (fragptr.p->fragStatus) {
   case Fragrecord::FSACTIVE:
     jam();
-    linkActiveFrag(signal);
     break;
   case Fragrecord::BLOCKED:
     jam();
@@ -9679,7 +9640,7 @@
 void Dblqh::tupCopyCloseConfLab(Signal* signal) 
 {
   fragptr.i = tcConnectptr.p->fragmentptr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(fragptr);
   fragptr.p->copyFragState = ZIDLE;
 
   if (tcConnectptr.p->abortState == TcConnectionrec::NEW_FROM_TC) {
@@ -9698,7 +9659,7 @@
     ref->tableId = fragptr.p->tabRef;
     ref->fragId = fragptr.p->fragId;
     ref->errorCode = ZNODE_FAILURE_ERROR;
-    sendSignal(scanptr.p->scanApiBlockref, GSN_COPY_FRAGREF, signal,
+    sendSignal(tcConnectptr.p->clientBlockref, GSN_COPY_FRAGREF, signal,
                CopyFragRef::SignalLength, JBB);
   } else {
     if (scanptr.p->scanErrorCounter > 0) {
@@ -9710,7 +9671,7 @@
       ref->tableId = fragptr.p->tabRef;
       ref->fragId = fragptr.p->fragId;
       ref->errorCode = tcConnectptr.p->errorCode;
-      sendSignal(scanptr.p->scanApiBlockref, GSN_COPY_FRAGREF, signal,
+      sendSignal(tcConnectptr.p->clientBlockref, GSN_COPY_FRAGREF, signal,
                  CopyFragRef::SignalLength, JBB);
     } else {
       jam();
@@ -9720,7 +9681,7 @@
       conf->startingNodeId = scanptr.p->scanNodeId;
       conf->tableId = tcConnectptr.p->tableref;
       conf->fragId = tcConnectptr.p->fragmentid;
-      sendSignal(scanptr.p->scanApiBlockref, GSN_COPY_FRAGCONF, signal,
+      sendSignal(tcConnectptr.p->clientBlockref, GSN_COPY_FRAGCONF, signal,
                  CopyFragConf::SignalLength, JBB);
     }//if
   }//if
@@ -9927,7 +9888,7 @@
       jam();
       break;
     }//if
-    ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+    c_fragment_pool.getPtr(fragptr);
     if (fragptr.p->copyFragState != ZIDLE) {
       jam();
 /*---------------------------------------------------------------------------*/
@@ -10071,11 +10032,32 @@
   return;
 }//Dblqh::execEMPTY_LCPREQ()
 
+#ifdef NDB_DEBUG_FULL
+static struct TraceLCP {
+  void sendSignal(Uint32 ref, Uint32 gsn, Signal* signal,
+		  Uint32 len, Uint32 prio);
+  void save(Signal*);
+  void restore(SimulatedBlock&, Signal* sig);
+  struct Sig {
+    enum { 
+      Sig_save = 0,
+      Sig_send = 1
+    } type;
+    SignalHeader header;
+    Uint32 theData[25];
+  };
+  Vector<Sig> m_signals;
+} g_trace_lcp;
+template class Vector<TraceLCP::Sig>;
+#else
+#endif
+
 void Dblqh::execLCP_FRAG_ORD(Signal* signal)
 {
   jamEntry();
   CRASH_INSERTION(5010);
   LcpFragOrd * const lcpFragOrd = (LcpFragOrd *)&signal->theData[0];
+
   Uint32 lcpId = lcpFragOrd->lcpId;
 
   lcpPtr.i = 0;
@@ -10091,7 +10073,7 @@
        * -------------------------------------------------------- */
       if (cnoOfFragsCheckpointed > 0) {
         jam();
-        completeLcpRoundLab(signal);
+        completeLcpRoundLab(signal, lcpId);
       } else {
         jam();
         sendLCP_COMPLETE_REP(signal, lcpId);
@@ -10111,17 +10093,18 @@
   lcpPtr.i = 0;
   ptrAss(lcpPtr, lcpRecord);
   ndbrequire(!lcpPtr.p->lcpQueued);
+
   if (c_lcpId < lcpFragOrd->lcpId) {
     jam();
-    /**
-     * A new LCP
-     */
+
+    lcpPtr.p->firstFragmentFlag= true;
+    
     c_lcpId = lcpFragOrd->lcpId;
     ndbrequire(lcpPtr.p->lcpState == LcpRecord::LCP_IDLE);
     setLogTail(signal, lcpFragOrd->keepGci);
     ndbrequire(clcpCompletedState == LCP_IDLE);
     clcpCompletedState = LCP_RUNNING;
-  }//if
+  }
   cnoOfFragsCheckpointed++;
   
   if(tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_DONE){
@@ -10147,567 +10130,131 @@
   sendLCP_FRAGIDREQ(signal);
 }//Dblqh::execLCP_FRAGORD()
 
-/* --------------------------------------------------------------------------
- *       PRECONDITION: LCP_PTR:LCP_STATE = WAIT_FRAGID
- * -------------------------------------------------------------------------- 
- *       WE NOW HAVE THE LOCAL FRAGMENTS THAT THE LOCAL CHECKPOINT WILL USE.
- * -------------------------------------------------------------------------- */
-void Dblqh::execLCP_FRAGIDCONF(Signal* signal) 
+void Dblqh::execLCP_PREPARE_REF(Signal* signal) 
 {
-  UintR Tfragid[4];
-
   jamEntry();
 
-  lcpPtr.i = signal->theData[0];
+  LcpPrepareRef* ref= (LcpPrepareRef*)signal->getDataPtr();
   
-  Uint32 TaccPtr = signal->theData[1];
-  Uint32 noLocfrag = signal->theData[2];
-  Tfragid[0] = signal->theData[3];
-  Tfragid[1] = signal->theData[4];
-
+  lcpPtr.i = ref->senderData;
   ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
   ndbrequire(lcpPtr.p->lcpState == LcpRecord::LCP_WAIT_FRAGID);
-  /* ------------------------------------------------------------------------
-   * NO ERROR CHECKING OF TNO_LOCFRAG VALUE. OUT OF BOUND WILL IMPLY THAT AN
-   * INDEX OUT OF RANGE WILL CAUSE A SYSTEM RESTART WHICH IS DESIRED.
-   * ------------------------------------------------------------------------ */
-  lcpPtr.p->lcpAccptr = TaccPtr;
-  fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-  ndbrequire(noLocfrag - 1 < 2);
-  for (Uint32 Tindex = 0; Tindex < noLocfrag; Tindex++) {
-    jam();
-    Uint32 fragId = Tfragid[Tindex];
-    /* ----------------------------------------------------------------------
-     *  THERE IS NO ERROR CHECKING ON PURPOSE. IT IS POSSIBLE TO CALCULATE HOW
-     *  MANY LOCAL LCP RECORDS THERE SHOULD BE. IT SHOULD NEVER HAPPEN THAT 
-     *  THERE IS NO ONE FREE. IF THERE IS NO ONE IT WILL ALSO BE A POINTER 
-     *  OUT OF RANGE WHICH IS AN ERROR CODE IN ITSELF. REUSES ERROR HANDLING 
-     *  IN AXE VM.
-     * ---------------------------------------------------------------------- */
-    seizeLcpLoc(signal);
-    initLcpLocAcc(signal, fragId);
-    seizeLcpLoc(signal);
-    initLcpLocTup(signal, fragId);
-    signal->theData[0] = lcpLocptr.i;
-    signal->theData[1] = cownref;
-    signal->theData[2] = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
-    signal->theData[3] = lcpLocptr.p->locFragid;
-    signal->theData[4] = lcpPtr.p->currentFragment.lcpFragOrd.lcpNo;
-    signal->theData[5] = lcpPtr.p->currentFragment.lcpFragOrd.lcpId % MAX_LCP_STORED;
-    sendSignal(fragptr.p->tupBlockref, GSN_TUP_PREPLCPREQ, signal, 6, JBB);
-  }//for
-  lcpPtr.p->lcpState = LcpRecord::LCP_WAIT_TUP_PREPLCP;
-  return;
-}//Dblqh::execLCP_FRAGIDCONF()
-
-/* --------------------------------------------------------------------------
- *       PRECONDITION: LCP_LOCPTR:LCP_STATE = WAIT_TUPPREPLCP
- * --------------------------------------------------------------------------
- *       WE HAVE NOW PREPARED A LOCAL FRAGMENT IN TUP FOR LCP EXECUTION.
- * -------------------------------------------------------------------------- */
-void Dblqh::execTUP_PREPLCPCONF(Signal* signal) 
-{
-  UintR ttupPtr;
-
-  jamEntry();
-  lcpLocptr.i = signal->theData[0];
-  ttupPtr = signal->theData[1];
-  ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-
-  lcpPtr.i = lcpLocptr.p->masterLcpRec;
-  ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
-  ndbrequire(lcpLocptr.p->lcpLocstate == LcpLocRecord::WAIT_TUP_PREPLCP);
-
-  lcpLocptr.p->tupRef = ttupPtr;
-  lcpLocptr.p->lcpLocstate = LcpLocRecord::IDLE;
-  checkLcpTupprep(signal);
-  if (lcpPtr.p->lcpState != LcpRecord::LCP_WAIT_HOLDOPS) {
-    jam();
-    return;
-  }//if
+  
   fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-  lcpLocptr.i = lcpPtr.p->firstLcpLocAcc;
-  do {
-    jam();
-    ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-    lcpLocptr.p->lcpLocstate = LcpLocRecord::WAIT_LCPHOLDOP;
-    signal->theData[0] = lcpPtr.p->lcpAccptr;
-    signal->theData[1] = lcpLocptr.p->locFragid;
-    signal->theData[2] = 0;
-    signal->theData[3] = lcpLocptr.i;
-    sendSignal(fragptr.p->accBlockref, GSN_LCP_HOLDOPREQ, signal, 4, JBA);
-    lcpLocptr.i = lcpLocptr.p->nextLcpLoc;
-  } while (lcpLocptr.i != RNIL);
-  /* ------------------------------------------------------------------------
-   *   SET STATE ON FRAGMENT TO BLOCKED TO ENSURE THAT NO MORE OPERATIONS ARE
-   *   STARTED FROM LQH IN TUP AND ACC UNTIL THE START CHECKPOINT HAS BEEN
-   *   COMPLETED. ALSO SET THE LOCAL CHECKPOINT STATE TO WAIT FOR 
-   *   LCP_HOLDOPCONF
-   * ----------------------------------------------------------------------- */
-  fragptr.p->fragStatus = Fragrecord::BLOCKED;
-  fragptr.p->fragActiveStatus = ZTRUE;
-  lcpPtr.p->lcpState = LcpRecord::LCP_WAIT_HOLDOPS;
-  return;
-}//Dblqh::execTUP_PREPLCPCONF()
-
-void Dblqh::execTUP_PREPLCPREF(Signal* signal) 
-{
-  jamEntry();
-  ndbrequire(false);
-}//Dblqh::execTUP_PREPLCPREF()
+  c_fragment_pool.getPtr(fragptr);
+  
+  ndbrequire(ref->tableId == fragptr.p->tabRef);
+  ndbrequire(ref->fragmentId == fragptr.p->fragId);
 
-void Dblqh::execLCP_FRAGIDREF(Signal* signal) 
-{
-  jamEntry();
-  ndbrequire(false);
-}//Dblqh::execLCP_FRAGIDREF()
+  tabptr.i = ref->tableId;
+  ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
+  
+  lcpPtr.p->lcpState = LcpRecord::LCP_COMPLETED;
+  lcpPtr.p->m_acc.lcpLocstate = LcpLocRecord::ACC_COMPLETED;
+  contChkpNextFragLab(signal);
+}
 
 /* --------------------------------------------------------------------------
- *   A NUMBER OF OPERATIONS THAT HAVE BEEN SET ON HOLD IN ACC. MOVE THOSE TO
- *   LIST OF BLOCKED ACC OPERATIONS. IF MORE OPERATIONS ARE BLOCKED GET THOSE
- *   OTHERWISE CONTINUE THE LOCAL CHECKPOINT BY REQUESTING TUP AND ACC TO
- *   WRITE THEIR START CHECKPOINT.
+ *       PRECONDITION: LCP_PTR:LCP_STATE = WAIT_FRAGID
  * -------------------------------------------------------------------------- 
- *       PRECONDITION: LCP_LOCPTR:LCP_LOCSTATE = WAIT_LCPHOLDOP
- * ------------------------------------------------------------------------- */
-/* ***************>> */
-/*  LCP_HOLDOPCONF > */
-/* ***************>> */
-void Dblqh::execLCP_HOLDOPCONF(Signal* signal) 
+ *       WE NOW HAVE THE LOCAL FRAGMENTS THAT THE LOCAL CHECKPOINT WILL USE.
+ * -------------------------------------------------------------------------- */
+void Dblqh::execLCP_PREPARE_CONF(Signal* signal) 
 {
-  UintR tnoHoldops;
-  Uint32 Tdata[23];
-  Uint32 Tlength;
-
   jamEntry();
-  lcpLocptr.i = signal->theData[0];
-  Tlength = signal->theData[1];
-  for (Uint32 i = 0; i < 23; i++)
-    Tdata[i] = signal->theData[i + 2];
-  ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-  ndbrequire(lcpLocptr.p->lcpLocstate == LcpLocRecord::WAIT_LCPHOLDOP);
 
-  lcpPtr.i = lcpLocptr.p->masterLcpRec;
-  /* ------------------------------------------------------------------------
-   *   NO ERROR CHECK ON USING VALUE IN MASTER_LCP_REC. ERROR IN THIS 
-   *   REFERENCE WILL CAUSE POINTER OUT OF RANGE WHICH CAUSES A SYSTEM RESTART.
-   * ----------------------------------------------------------------------- */
-  tnoHoldops = Tlength & 65535;
+  LcpPrepareConf* conf= (LcpPrepareConf*)signal->getDataPtr();
+  
+  lcpPtr.i = conf->senderData;
   ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
+  ndbrequire(lcpPtr.p->lcpState == LcpRecord::LCP_WAIT_FRAGID);
+  
   fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-  ndbrequire(tnoHoldops <= 23);
-  for (Uint32 Tindex = 0; Tindex < tnoHoldops; Tindex++) {
-    jam();
-    tcConnectptr.i = Tdata[Tindex];
-    ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
-    moveActiveToAcc(signal);
-  }//for
-  if ((Tlength >> 16) == 1) {
-    jam();
-                                        /* MORE HOLDOPS NEEDED */
-    signal->theData[0] = lcpPtr.p->lcpAccptr;
-    signal->theData[1] = lcpLocptr.p->locFragid;
-    signal->theData[2] = 1;
-    signal->theData[3] = lcpLocptr.i;
-    sendSignal(fragptr.p->accBlockref, GSN_LCP_HOLDOPREQ, signal, 4, JBA);
-    return;
-  } else {
-    jam();
-
-                                        /* NO MORE HOLDOPS NEEDED */
-    lcpLocptr.p->lcpLocstate = LcpLocRecord::HOLDOP_READY;
-    checkLcpHoldop(signal);
-
-    if (lcpPtr.p->lcpState == LcpRecord::LCP_WAIT_ACTIVE_FINISH) {
-      if (fragptr.p->activeList == RNIL) {
-        jam();
-	/* ------------------------------------------------------------------ 
-	 *  THERE ARE NO MORE ACTIVE OPERATIONS. IT IS NOW OK TO START THE 
-	 *  LOCAL CHECKPOINT IN BOTH TUP AND ACC.
-	 * ----------------------------------------------------------------- */
-        sendStartLcp(signal);
-        lcpPtr.p->lcpState = LcpRecord::LCP_START_CHKP;
-      } else {
-        jam();
-	// Set this to signal releaseActiveFrag 
-	// that it should check to see if itäs time to call sendStartLcp
-	fragptr.p->lcpRef = lcpPtr.i;
-      }//if
-    }//if
-  }//if
-
-  /* ----------------------- */
-  /*           ELSE          */
-  /* ------------------------------------------------------------------------
-   *   THERE ARE STILL MORE ACTIVE OPERATIONS. WAIT UNTIL THEY ARE FINSIHED.
-   *   THIS IS DISCOVERED WHEN RELEASE_ACTIVE_FRAG IS EXECUTED.
-   * ------------------------------------------------------------------------
-   *       DO NOTHING, EXIT IS EXECUTED BELOW                                  
-   * ----------------------------------------------------------------------- */
-  return;
-}//Dblqh::execLCP_HOLDOPCONF()
-
-/* ***************> */
-/*  LCP_HOLDOPREF > */
-/* ***************> */
-void Dblqh::execLCP_HOLDOPREF(Signal* signal) 
-{
-  jamEntry();
-  ndbrequire(false);
-}//Dblqh::execLCP_HOLDOPREF()
-
-/* ************************************************************************>>
- *  ACC_LCPSTARTED: Confirm that ACC started local checkpoint and undo 
- *  logging is on. 
- * ************************************************************************>> 
- * --------------------------------------------------------------------------
- *       PRECONDITION: LCP_LOCPTR:LCP_LOCSTATE = ACC_WAIT_STARTED 
- * ------------------------------------------------------------------------- */
-void Dblqh::execACC_LCPSTARTED(Signal* signal) 
-{
-  jamEntry();
-  lcpLocptr.i = signal->theData[0];
-  ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-  ndbrequire(lcpLocptr.p->lcpLocstate == LcpLocRecord::ACC_WAIT_STARTED);
-
-  lcpPtr.i = lcpLocptr.p->masterLcpRec;
-  ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
-  /* ------------------------------------------------------------------------ 
-   * NO ERROR CHECK ON USING VALUE IN MASTER_LCP_REC. ERROR IN THIS 
-   * REFERENCE  WILL CAUSE POINTER OUT OF RANGE WHICH CAUSES A SYSTEM RESTART.
-   * ----------------------------------------------------------------------- */
-  lcpLocptr.p->lcpLocstate = LcpLocRecord::ACC_STARTED;
-  lcpStartedLab(signal);
-  return;
-}//Dblqh::execACC_LCPSTARTED()
+  c_fragment_pool.getPtr(fragptr);
+  
+  ndbrequire(conf->tableId == fragptr.p->tabRef);
+  ndbrequire(conf->fragmentId == fragptr.p->fragId);
 
-/* ******************************************> */
-/*  TUP_LCPSTARTED: Same as above but for TUP. */
-/* ******************************************> */
-/* -------------------------------------------------------------------------- 
- *       PRECONDITION: LCP_LOCPTR:LCP_LOCSTATE = TUP_WAIT_STARTED
- * ------------------------------------------------------------------------- */
-void Dblqh::execTUP_LCPSTARTED(Signal* signal) 
-{
-  jamEntry();
-  lcpLocptr.i = signal->theData[0];
-  ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-  ndbrequire(lcpLocptr.p->lcpLocstate == LcpLocRecord::TUP_WAIT_STARTED);
+  lcpPtr.p->lcpState = LcpRecord::LCP_WAIT_HOLDOPS;
+  lcpPtr.p->m_acc.lcpLocstate = LcpLocRecord::WAIT_LCPHOLDOP;
 
-  lcpPtr.i = lcpLocptr.p->masterLcpRec;
-  ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
-  /* ------------------------------------------------------------------------
-   *   NO ERROR CHECK ON USING VALUE IN MASTER_LCP_REC. ERROR IN THIS REFERENCE
-   *   WILL CAUSE POINTER OUT OF RANGE WHICH CAUSES A SYSTEM RESTART.
-   * ----------------------------------------------------------------------- */
-  lcpLocptr.p->lcpLocstate = LcpLocRecord::TUP_STARTED;
-  lcpStartedLab(signal);
-  return;
-}//Dblqh::execTUP_LCPSTARTED()
+  lcpPtr.p->lcpState = LcpRecord::LCP_START_CHKP;
+  lcpPtr.p->m_acc.lcpLocstate = LcpLocRecord::HOLDOP_READY;
+  
+  /* ----------------------------------------------------------------------
+   *    UPDATE THE MAX_GCI_IN_LCP AND MAX_GCI_COMPLETED_IN_LCP NOW BEFORE
+   *    ACTIVATING THE FRAGMENT AGAIN.
+   * --------------------------------------------------------------------- */
+  ndbrequire(lcpPtr.p->currentFragment.lcpFragOrd.lcpNo < MAX_LCP_STORED);
+  fragptr.p->maxGciInLcp = fragptr.p->newestGci;
+  fragptr.p->maxGciCompletedInLcp = cnewestCompletedGci;
 
-void Dblqh::lcpStartedLab(Signal* signal) 
-{
-  if (checkLcpStarted(signal))
   {
-    jam();
-    /* ----------------------------------------------------------------------
-     *  THE LOCAL CHECKPOINT HAS BEEN STARTED. IT IS NOW TIME TO 
-     *  RESTART THE TRANSACTIONS WHICH HAVE BEEN BLOCKED.
-     * --------------------------------------------------------------------- */
-    fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
-    ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-    /* ----------------------------------------------------------------------
-     *    UPDATE THE MAX_GCI_IN_LCP AND MAX_GCI_COMPLETED_IN_LCP NOW BEFORE
-     *    ACTIVATING THE FRAGMENT AGAIN.
-     * --------------------------------------------------------------------- */
-    ndbrequire(lcpPtr.p->currentFragment.lcpFragOrd.lcpNo < MAX_LCP_STORED);
-    fragptr.p->maxGciInLcp = fragptr.p->newestGci;
-    fragptr.p->maxGciCompletedInLcp = cnewestCompletedGci;
-    sendAccContOp(signal);	/* START OPERATIONS IN ACC       */
-    moveAccActiveFrag(signal);	/* MOVE FROM ACC BLOCKED LIST TO ACTIVE LIST 
-				   ON FRAGMENT */
-  }
-  /*---------------*/
-  /*       ELSE    */
-  /*-------------------------------------------------------------------------*/
-  /*    THE LOCAL CHECKPOINT HAS NOT BEEN STARTED. EXIT AND WAIT FOR 
-   *    MORE SIGNALS */
-  /*-------------------------------------------------------------------------*/
-  /*       DO NOTHING, EXIT IS EXECUTED BELOW                                */
-  /*-------------------------------------------------------------------------*/
-  return;
-}//Dblqh::lcpStartedLab()
-
-/*---------------------------------------------------------------------------
- *     ACC HAVE RESTARTED THE BLOCKED OPERATIONS AGAIN IN ONE FRAGMENT PART. 
- *     IT IS NOW OUR TURN TO RESTART ALL OPERATIONS QUEUED IN LQH IF ALL 
- *     FRAGMENT PARTS ARE COMPLETED.
- *-------------------------------------------------------------------------- */
-void Dblqh::execACC_CONTOPCONF(Signal* signal) 
-{
-  if(ERROR_INSERTED(5035) && signal->getSendersBlockRef() != reference()){
-    sendSignalWithDelay(reference(), GSN_ACC_CONTOPCONF, signal, 1000, 
-			signal->length());
-    return;
-  }
+    LcpFragOrd *ord= (LcpFragOrd*)signal->getDataPtrSend();
+    *ord = lcpPtr.p->currentFragment.lcpFragOrd;
+    EXECUTE_DIRECT(LGMAN, GSN_LCP_FRAG_ORD, signal, signal->length());
+    jamEntry();
 
-  jamEntry();
-  lcpLocptr.i = signal->theData[0];
-  ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-  lcpLocptr.p->accContCounter = 1;
+    *ord = lcpPtr.p->currentFragment.lcpFragOrd;
+    EXECUTE_DIRECT(DBTUP, GSN_LCP_FRAG_ORD, signal, signal->length());
+    jamEntry();
 
-  lcpPtr.i = lcpLocptr.p->masterLcpRec;
-  ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
-  lcpLocptr.i = lcpPtr.p->firstLcpLocAcc;
-  do {
-    ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-    if (lcpLocptr.p->accContCounter == 0) {
+    if(lcpPtr.p->firstFragmentFlag)
+    {
       jam();
-      return;
-    }//if
-    lcpLocptr.i = lcpLocptr.p->nextLcpLoc;
-  } while (lcpLocptr.i != RNIL);
-  fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-  restartOperationsLab(signal);
-  return;
-}//Dblqh::execACC_CONTOPCONF()
-
-/* ********************************************************* */
-/*  LQH_RESTART_OP: Restart operations after beeing blocked. */
-/* ********************************************************* */
-/*---------------------------------------------------------------------------*/
-/*       PRECONDITION: FRAG_STATUS = BLOCKED AND LCP_STATE = STARTED         */
-/*---------------------------------------------------------------------------*/
-void Dblqh::execLQH_RESTART_OP(Signal* signal) 
-{
-  jamEntry();
-  fragptr.i = signal->theData[0];
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+      lcpPtr.p->firstFragmentFlag= false;
+      *ord = lcpPtr.p->currentFragment.lcpFragOrd;
+      EXECUTE_DIRECT(PGMAN, GSN_LCP_FRAG_ORD, signal, signal->length());
+      jamEntry();
 
-  lcpPtr.i = signal->theData[1];
-  ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
-  ndbrequire(fragptr.p->fragStatus == Fragrecord::BLOCKED);
-  restartOperationsLab(signal);
-}//Dblqh::execLQH_RESTART_OP()
+      /**
+       * First fragment mean that last LCP is complete :-)
+       */
+      EXECUTE_DIRECT(TSMAN, GSN_END_LCP_REQ, signal, signal->length());
+      jamEntry();
+    }
+  }
 
-void Dblqh::restartOperationsLab(Signal* signal) 
-{
-  Uint32 loopCount = 0;
-  tcConnectptr.i = fragptr.p->firstWaitQueue;
-  do {
-    if (tcConnectptr.i != RNIL) {
-      jam();
-/*---------------------------------------------------------------------------*/
-/*    START UP THE TRANSACTION AGAIN. WE START IT AS A SEPARATE SIGNAL.      */
-/*---------------------------------------------------------------------------*/
-      signal->theData[0] = ZRESTART_OPERATIONS_AFTER_STOP;
-      signal->theData[1] = tcConnectptr.i;
-      signal->theData[2] = fragptr.i;
-      sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
-      ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
-      tcConnectptr.i = tcConnectptr.p->nextTc;
-    } else {
-      jam();
-/*--------------------------------------------------------------------------*/
-/* NO MORE OPERATIONS TO RESTART. WE CAN NOW RESET THE STATE TO ACTIVE AND  */
-/* RESTART NORMAL ACTIVITIES ON THE FRAGMENT WHILE THE FUZZY PART OF THE    */
-/* LOCAL CHECKPOINT IS COMPLETING.                                          */
-/* IF THE CHECKPOINT WAS COMPLETED ALREADY ON THIS FRAGMENT WE PROCEED WITH */
-/* THE NEXT FRAGMENT NOW THAT WE HAVE COMPLETED THIS CHECKPOINT.            */
-/*--------------------------------------------------------------------------*/
-      fragptr.p->fragStatus = Fragrecord::FSACTIVE;
-      if (lcpPtr.p->lcpState == LcpRecord::LCP_BLOCKED_COMP) {
-        jam();
-        contChkpNextFragLab(signal);
-        return;
-      }//if
-      return;
-    }//if
-    loopCount++;
-    if (loopCount > 16) {
-      jam();
-      signal->theData[0] = fragptr.i;
-      signal->theData[1] = lcpPtr.i;
-      sendSignal(cownref, GSN_LQH_RESTART_OP, signal, 2, JBB);
-      return;
-    }//if
-  } while (1);
-}//Dblqh::restartOperationsLab()
+  BackupFragmentReq* req= (BackupFragmentReq*)signal->getDataPtr();
+  req->tableId = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
+  req->fragmentNo = 0; 
+  req->backupPtr = m_backup_ptr;
+  req->backupId = lcpPtr.p->currentFragment.lcpFragOrd.lcpId;
+  req->count = 0;
 
-void Dblqh::restartOperationsAfterStopLab(Signal* signal) 
-{
-  /*-------------------------------------------------------------------------
-   * WHEN ARRIVING HERE THE OPERATION IS ALREADY SET IN THE ACTIVE LIST. 
-   * THUS WE CAN IMMEDIATELY CALL THE METHODS THAT EXECUTE FROM WHERE 
-   * THE OPERATION WAS STOPPED.
-   *------------------------------------------------------------------------ */
-  switch (tcConnectptr.p->transactionState) {
-  case TcConnectionrec::STOPPED:
-    jam();
-    /*-----------------------------------------------------------------------
-     *       STOPPED BEFORE TRYING TO SEND ACCKEYREQ           
-     *---------------------------------------------------------------------- */
-    prepareContinueAfterBlockedLab(signal);
-    return;
-    break;
-  case TcConnectionrec::COMMIT_STOPPED:
-    jam();
-    /* ----------------------------------------------------------------------
-     *       STOPPED BEFORE TRYING TO SEND ACC_COMMITREQ
-     * --------------------------------------------------------------------- */
-    releaseActiveFrag(signal);
-    commitContinueAfterBlockedLab(signal);
-    return;
-    break;
-  case TcConnectionrec::ABORT_STOPPED:
-    jam();
-    /* ----------------------------------------------------------------------
-     *       STOPPED BEFORE TRYING TO SEND ACC_ABORTREQ
-     * --------------------------------------------------------------------- */
-    abortContinueAfterBlockedLab(signal, true);
-    return;
-    break;
-  case TcConnectionrec::COPY_STOPPED:
-    jam();
-    /* ----------------------------------------------------------------------
-     *       STOPPED BEFORE TRYING TO SEND NEXT_SCANREQ DURING COPY FRAGMENT
-     * --------------------------------------------------------------------- */
-    continueCopyAfterBlockedLab(signal);
-    return;
-    break;
-  case TcConnectionrec::COPY_FIRST_STOPPED:
-    jam();
-    /* ----------------------------------------------------------------------
-     *       STOPPED BEFORE TRYING TO SEND NEXT_SCANREQ DURING COPY FRAGMENT
-     * --------------------------------------------------------------------- */
-    continueFirstCopyAfterBlockedLab(signal);
-    return;
-    break;
-  case TcConnectionrec::SCAN_FIRST_STOPPED:
-    jam();
-    /* ----------------------------------------------------------------------
-     *       STOPPED BEFORE TRYING TO SEND NEXT_SCANREQ DURING SCAN
-     * --------------------------------------------------------------------- */
-    tcConnectptr.p->transactionState = TcConnectionrec::SCAN_STATE_USED;
-    continueFirstScanAfterBlockedLab(signal);
-    return;
-    break;
-  case TcConnectionrec::SCAN_CHECK_STOPPED:
-    jam();
-    /* ----------------------------------------------------------------------
-     *       STOPPED BEFORE TRYING TO SEND NEXT_SCANREQ DURING SCAN
-     * --------------------------------------------------------------------- */
-    tcConnectptr.p->transactionState = TcConnectionrec::SCAN_STATE_USED;
-    continueAfterCheckLcpStopBlocked(signal);
-    return;
-    break;
-  case TcConnectionrec::SCAN_STOPPED:
-    jam();
-    /* ----------------------------------------------------------------------
-     *       STOPPED BEFORE TRYING TO SEND NEXT_SCANREQ DURING SCAN
-     * --------------------------------------------------------------------- */
-    tcConnectptr.p->transactionState = TcConnectionrec::SCAN_STATE_USED;
-    continueScanAfterBlockedLab(signal);
-    return;
-    break;
-  case TcConnectionrec::SCAN_RELEASE_STOPPED:
-    jam();
-    /* ----------------------------------------------------------------------
-     *       STOPPED BEFORE TRYING TO SEND NEXT_SCANREQ DURING RELEASE 
-     *       LOCKS IN SCAN  
-     * --------------------------------------------------------------------- */
-    tcConnectptr.p->transactionState = TcConnectionrec::SCAN_STATE_USED;
-    continueScanReleaseAfterBlockedLab(signal);
-    return;
-    break;
-  case TcConnectionrec::SCAN_CLOSE_STOPPED:
-    jam();
-    /* ----------------------------------------------------------------------
-     *       STOPPED BEFORE TRYING TO SEND NEXT_SCANREQ DURING CLOSE OF SCAN
-     * --------------------------------------------------------------------- */
-    continueCloseScanAfterBlockedLab(signal);
-    return;
-    break;
-  case TcConnectionrec::COPY_CLOSE_STOPPED:
-    jam();
-    /* ----------------------------------------------------------------------
-     *       STOPPED BEFORE TRYING TO SEND NEXT_SCANREQ DURING CLOSE OF COPY
-     * --------------------------------------------------------------------- */
-    continueCloseCopyAfterBlockedLab(signal);
-    return;
-    break;
-  default:
-    jam();
-    systemErrorLab(signal, __LINE__);
-    return;
-    break;
-  }//switch
-}//Dblqh::restartOperationsAfterStopLab()
+#ifdef NDB_DEBUG_FULL
+  if(ERROR_INSERTED(5904))
+  {
+    g_trace_lcp.sendSignal(BACKUP_REF, GSN_BACKUP_FRAGMENT_REQ, signal, 
+			   BackupFragmentReq::SignalLength, JBB);
+  }
+  else
+#endif
+  {
+    sendSignal(BACKUP_REF, GSN_BACKUP_FRAGMENT_REQ, signal, 
+	       BackupFragmentReq::SignalLength, JBB);
+  }
+  
+  lcpPtr.p->m_acc.lcpLocstate = LcpLocRecord::ACC_STARTED;
+  lcpPtr.p->m_tup.lcpLocstate = LcpLocRecord::TUP_COMPLETED;
+}
 
-/* *************** */
-/*  ACC_LCPCONF  > */
-/* *************** */
-/*---------------------------------------------------------------------------
- *       PRECONDITION: LCP_LOCPTR:LCP_LOCSTATE = ACC_STARTED 
- *-------------------------------------------------------------------------- */
-void Dblqh::execACC_LCPCONF(Signal* signal) 
+void Dblqh::execBACKUP_FRAGMENT_REF(Signal* signal) 
 {
-  jamEntry();
-  lcpLocptr.i = signal->theData[0];
-  ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-  ndbrequire(lcpLocptr.p->lcpLocstate == LcpLocRecord::ACC_STARTED);
-
-  lcpPtr.i = lcpLocptr.p->masterLcpRec;
-  ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
-  /* ------------------------------------------------------------------------
-   *   NO ERROR CHECK ON USING VALUE IN MASTER_LCP_REC. ERROR IN 
-   *   THIS REFERENCE WILL CAUSE POINTER OUT OF RANGE WHICH CAUSES A 
-   *   SYSTEM RESTART.
-   * ----------------------------------------------------------------------- */
-  lcpLocptr.p->lcpLocstate = LcpLocRecord::ACC_COMPLETED;
-  lcpCompletedLab(signal);
-  return;
-}//Dblqh::execACC_LCPCONF()
+  ndbrequire(false);
+}
 
-/* *************** */
-/*  TUP_LCPCONF  > */
-/* *************** */
-/* --------------------------------------------------------------------------
- *       PRECONDITION: LCP_LOCPTR:LCP_LOCSTATE = TUP_STARTED    
- * ------------------------------------------------------------------------- */
-void Dblqh::execTUP_LCPCONF(Signal* signal) 
+void Dblqh::execBACKUP_FRAGMENT_CONF(Signal* signal) 
 {
   jamEntry();
-  lcpLocptr.i = signal->theData[0];
-  ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-  ndbrequire(lcpLocptr.p->lcpLocstate == LcpLocRecord::TUP_STARTED);
+  //BackupFragmentConf* conf= (BackupFragmentConf*)signal->getDataPtr();
 
-  lcpPtr.i = lcpLocptr.p->masterLcpRec;
+  lcpPtr.i = 0;
   ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
-  /* ------------------------------------------------------------------------
-   *  NO ERROR CHECK ON USING VALUE IN MASTER_LCP_REC. ERROR IN THIS
-   *  REFERENCE WILL CAUSE POINTER OUT OF RANGE WHICH CAUSES A SYSTEM RESTART.
-   * ----------------------------------------------------------------------- */
-  lcpLocptr.p->lcpLocstate = LcpLocRecord::TUP_COMPLETED;
-  lcpCompletedLab(signal);
-  return;
-}//Dblqh::execTUP_LCPCONF()
+  ndbrequire(lcpPtr.p->m_acc.lcpLocstate == LcpLocRecord::ACC_STARTED);
+  lcpPtr.p->m_acc.lcpLocstate = LcpLocRecord::ACC_COMPLETED;
+  lcpPtr.p->lcpState = LcpRecord::LCP_COMPLETED;
 
-void Dblqh::lcpCompletedLab(Signal* signal) 
-{
-  checkLcpCompleted(signal);
-  if (lcpPtr.p->lcpState != LcpRecord::LCP_COMPLETED) {
-    jam();
-    /* ----------------------------------------------------------------------
-     *       THE LOCAL CHECKPOINT HAS NOT BEEN COMPLETED, EXIT & WAIT 
-     *       FOR MORE SIGNALS 
-     * --------------------------------------------------------------------- */
-    return;
-  }//if
   /* ------------------------------------------------------------------------
    *   THE LOCAL CHECKPOINT HAS BEEN COMPLETED. IT IS NOW TIME TO START 
    *   A LOCAL CHECKPOINT ON THE NEXT FRAGMENT OR COMPLETE THIS LCP ROUND.
@@ -10716,9 +10263,9 @@
    *   TO CATER FOR NODE CRASHES WE SEND IT IN PARALLEL TO ALL NODES.
    * ----------------------------------------------------------------------- */
   fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(fragptr);
   fragptr.p->fragActiveStatus = ZFALSE;
-
+  
   contChkpNextFragLab(signal);
   return;
 }//Dblqh::lcpCompletedLab()
@@ -10727,10 +10274,8 @@
 Dblqh::sendLCP_FRAG_REP(Signal * signal, 
 			const LcpRecord::FragOrd & fragOrd) const {
   
-  FragrecordPtr fragPtr;
-  fragPtr.i = fragOrd.fragPtrI;
-  ptrCheckGuard(fragPtr, cfragrecFileSize, fragrecord);
-
+  const Fragrecord* fragPtrP = c_fragment_pool.getConstPtr(fragOrd.fragPtrI);
+  
   ndbrequire(fragOrd.lcpFragOrd.lcpNo < MAX_LCP_STORED);
   LcpFragRep * const lcpReport = (LcpFragRep *)&signal->theData[0];
   lcpReport->nodeId = cownNodeid;
@@ -10738,8 +10283,8 @@
   lcpReport->lcpNo = fragOrd.lcpFragOrd.lcpNo;
   lcpReport->tableId = fragOrd.lcpFragOrd.tableId;
   lcpReport->fragId = fragOrd.lcpFragOrd.fragmentId;
-  lcpReport->maxGciCompleted = fragPtr.p->maxGciCompletedInLcp;
-  lcpReport->maxGciStarted = fragPtr.p->maxGciInLcp;
+  lcpReport->maxGciCompleted = fragPtrP->maxGciCompletedInLcp;
+  lcpReport->maxGciStarted = fragPtrP->maxGciInLcp;
   
   for (Uint32 i = 0; i < cnoOfNodes; i++) {
     jam();
@@ -10767,7 +10312,6 @@
      *   but restarting of operations isn't
      */
     lcpPtr.p->lcpState = LcpRecord::LCP_BLOCKED_COMP;
-    //restartOperationsLab(signal);
     return;
   }//if
 
@@ -10779,7 +10323,6 @@
   /* ------------------------------------------------------------------------
    *       WE ALSO RELEASE THE LOCAL LCP RECORDS.
    * ----------------------------------------------------------------------- */
-  releaseLocalLcps(signal);
   if (lcpPtr.p->lcpQueued) {
     jam();
     /* ----------------------------------------------------------------------
@@ -10801,7 +10344,7 @@
     /* ----------------------------------------------------------------------
      *       NOW THE COMPLETE LOCAL CHECKPOINT ROUND IS COMPLETED.  
      * --------------------------------------------------------------------- */
-    completeLcpRoundLab(signal);
+    completeLcpRoundLab(signal, lcpPtr.p->currentFragment.lcpFragOrd.lcpId);
     return;
   }//if
   
@@ -10814,9 +10357,6 @@
 
 void Dblqh::sendLCP_FRAGIDREQ(Signal* signal)
 {
-  ndbrequire(lcpPtr.p->firstLcpLocTup == RNIL);
-  ndbrequire(lcpPtr.p->firstLcpLocAcc == RNIL);
-  
   TablerecPtr tabPtr;
   tabPtr.i = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
   ptrAss(tabPtr, tablerec);
@@ -10826,20 +10366,24 @@
     /**
      * Fake that the fragment is done
      */
-    lcpCompletedLab(signal);
+    contChkpNextFragLab(signal);
     return;
   }
   
   ndbrequire(tabPtr.p->tableStatus == Tablerec::TABLE_DEFINED);
   
   lcpPtr.p->lcpState = LcpRecord::LCP_WAIT_FRAGID;
-  signal->theData[0] = lcpPtr.i;
-  signal->theData[1] = cownref;
-  signal->theData[2] = lcpPtr.p->currentFragment.lcpFragOrd.lcpNo;
-  signal->theData[3] = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
-  signal->theData[4] = lcpPtr.p->currentFragment.lcpFragOrd.fragmentId;
-  signal->theData[5] = lcpPtr.p->currentFragment.lcpFragOrd.lcpId % MAX_LCP_STORED;
-  sendSignal(fragptr.p->accBlockref, GSN_LCP_FRAGIDREQ, signal, 6, JBB);
+  LcpPrepareReq* req= (LcpPrepareReq*)signal->getDataPtr();
+  req->senderData = lcpPtr.i;
+  req->senderRef = reference();
+  req->lcpNo = lcpPtr.p->currentFragment.lcpFragOrd.lcpNo;
+  req->tableId = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
+  req->fragmentId = lcpPtr.p->currentFragment.lcpFragOrd.fragmentId;
+  req->lcpId = lcpPtr.p->currentFragment.lcpFragOrd.lcpId % MAX_LCP_STORED;
+  req->backupPtr = m_backup_ptr;
+  req->backupId = lcpPtr.p->currentFragment.lcpFragOrd.lcpId;
+  sendSignal(BACKUP_REF, GSN_LCP_PREPARE_REQ, signal, 
+	     LcpPrepareReq::SignalLength, JBB);
 }//Dblqh::sendLCP_FRAGIDREQ()
 
 void Dblqh::sendEMPTY_LCP_CONF(Signal* signal, bool idle)
@@ -10884,63 +10428,50 @@
   lcpPtr.p->m_EMPTY_LCP_REQ.clear();
 }//Dblqh::sendEMPTY_LCPCONF()
 
-void Dblqh::execACC_LCPREF(Signal* signal) 
-{
-  jamEntry();
-  ndbrequire(false);
-}//Dblqh::execACC_LCPREF()
-
-void Dblqh::execTUP_LCPREF(Signal* signal) 
-{
-  jamEntry();
-  ndbrequire(false);
-}//Dblqh::execTUP_LCPREF()
-
 /* --------------------------------------------------------------------------
  *       THE LOCAL CHECKPOINT ROUND IS NOW COMPLETED. SEND COMPLETED MESSAGE
  *       TO THE MASTER DIH.
  * ------------------------------------------------------------------------- */
-void Dblqh::completeLcpRoundLab(Signal* signal)
+void Dblqh::completeLcpRoundLab(Signal* signal, Uint32 lcpId)
 {
   clcpCompletedState = LCP_CLOSE_STARTED;
-  signal->theData[0] = caccBlockref;
-  signal->theData[1] = cownref;
-  sendSignal(caccBlockref, GSN_END_LCPREQ, signal, 2, JBB);
-  signal->theData[0] = ctupBlockref;
-  signal->theData[1] = cownref;
-  sendSignal(ctupBlockref, GSN_END_LCPREQ, signal, 2, JBB);
+
+  EndLcpReq* req= (EndLcpReq*)signal->getDataPtr();
+  req->senderData= lcpPtr.i;
+  req->senderRef= reference();
+  req->backupPtr= m_backup_ptr;
+  req->backupId= lcpId;
+  sendSignal(BACKUP_REF, GSN_END_LCP_REQ, signal, 
+	     EndLcpReq::SignalLength, JBB);
+  
+  sendSignal(PGMAN_REF, GSN_END_LCP_REQ, signal, 
+	     EndLcpReq::SignalLength, JBB);
+
+  sendSignal(LGMAN_REF, GSN_END_LCP_REQ, signal, 
+	     EndLcpReq::SignalLength, JBB);
+  
+  lcpPtr.i = 0;
+  ptrAss(lcpPtr, lcpRecord);
+  lcpPtr.p->m_outstanding = 3;
   return;
 }//Dblqh::completeLcpRoundLab()
 
 void Dblqh::execEND_LCPCONF(Signal* signal) 
 {
   jamEntry();
-  BlockReference userpointer = signal->theData[0];
-  if (userpointer == caccBlockref) {
-    if (clcpCompletedState == LCP_CLOSE_STARTED) {
-      jam();
-      clcpCompletedState = ACC_LCP_CLOSE_COMPLETED;
-      return;
-    } else {
-      jam();
-      ndbrequire(clcpCompletedState == TUP_LCP_CLOSE_COMPLETED);
-      clcpCompletedState = LCP_IDLE;
-    }//if
-  } else {
-    ndbrequire(userpointer == ctupBlockref);
-    if (clcpCompletedState == LCP_CLOSE_STARTED) {
-      jam();
-      clcpCompletedState = TUP_LCP_CLOSE_COMPLETED;
-      return;
-    } else {
-      jam();
-      ndbrequire(clcpCompletedState == ACC_LCP_CLOSE_COMPLETED);
-      clcpCompletedState = LCP_IDLE;
-    }//if
-  }//if
   lcpPtr.i = 0;
   ptrAss(lcpPtr, lcpRecord);
-  sendLCP_COMPLETE_REP(signal, lcpPtr.p->currentFragment.lcpFragOrd.lcpId);
+
+  ndbrequire(clcpCompletedState == LCP_CLOSE_STARTED);
+  ndbrequire(lcpPtr.p->m_outstanding);
+  
+  lcpPtr.p->m_outstanding--;
+  if(lcpPtr.p->m_outstanding == 0)
+  {
+    jam();
+    clcpCompletedState = LCP_IDLE;
+    sendLCP_COMPLETE_REP(signal, lcpPtr.p->currentFragment.lcpFragOrd.lcpId);
+  }
 }//Dblqh::execEND_LCPCONF()
 
 void Dblqh::sendLCP_COMPLETE_REP(Signal* signal, Uint32 lcpId)
@@ -10953,6 +10484,7 @@
   lcpPtr.i = 0;
   ptrAss(lcpPtr, lcpRecord);
   lcpPtr.p->lastFragmentFlag = false;
+  lcpPtr.p->firstFragmentFlag = false;
   
   LcpCompleteRep* rep = (LcpCompleteRep*)signal->getDataPtrSend();
   rep->nodeId = getOwnNodeId();
@@ -10976,269 +10508,9 @@
     sendEMPTY_LCP_CONF(signal, true);
   }
   return;
-}//Dblqh::sendCOMP_LCP_ROUND()
-
-/* ==========================================================================
- * =======  CHECK IF ALL PARTS OF A LOCAL CHECKPOINT ARE COMPLETED    ======= 
- *
- *       SUBROUTINE SHORT NAME = CLC
- * ========================================================================= */
-void Dblqh::checkLcpCompleted(Signal* signal) 
-{
-  LcpLocRecordPtr clcLcpLocptr;
-
-  clcLcpLocptr.i = lcpPtr.p->firstLcpLocAcc;
-  while (clcLcpLocptr.i != RNIL) {
-    ptrCheckGuard(clcLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-    if (clcLcpLocptr.p->lcpLocstate != LcpLocRecord::ACC_COMPLETED) {
-      jam();
-      ndbrequire((clcLcpLocptr.p->lcpLocstate == LcpLocRecord::ACC_WAIT_STARTED) ||
-                 (clcLcpLocptr.p->lcpLocstate == LcpLocRecord::ACC_STARTED));
-      return;
-    }//if
-    clcLcpLocptr.i = clcLcpLocptr.p->nextLcpLoc;
-  }
-
-  clcLcpLocptr.i = lcpPtr.p->firstLcpLocTup;
-  while (clcLcpLocptr.i != RNIL){
-    ptrCheckGuard(clcLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-    if (clcLcpLocptr.p->lcpLocstate != LcpLocRecord::TUP_COMPLETED) {
-      jam();
-      ndbrequire((clcLcpLocptr.p->lcpLocstate==LcpLocRecord::TUP_WAIT_STARTED) 
-		 ||(clcLcpLocptr.p->lcpLocstate == LcpLocRecord::TUP_STARTED));
-      return;
-    }//if
-    clcLcpLocptr.i = clcLcpLocptr.p->nextLcpLoc;
-  }
-  
-  lcpPtr.p->lcpState = LcpRecord::LCP_COMPLETED;
-}//Dblqh::checkLcpCompleted()
-
-/* ========================================================================== 
- * =======              CHECK IF ALL HOLD OPERATIONS ARE COMPLETED    ======= 
- *
- *       SUBROUTINE SHORT NAME = CHO
- * ========================================================================= */
-void Dblqh::checkLcpHoldop(Signal* signal) 
-{
-  LcpLocRecordPtr choLcpLocptr;
-
-  choLcpLocptr.i = lcpPtr.p->firstLcpLocAcc;
-  do {
-    ptrCheckGuard(choLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-    if (choLcpLocptr.p->lcpLocstate != LcpLocRecord::HOLDOP_READY) {
-      ndbrequire(choLcpLocptr.p->lcpLocstate == LcpLocRecord::WAIT_LCPHOLDOP);
-      return;
-    }//if
-    choLcpLocptr.i = choLcpLocptr.p->nextLcpLoc;
-  } while (choLcpLocptr.i != RNIL);
-  lcpPtr.p->lcpState = LcpRecord::LCP_WAIT_ACTIVE_FINISH;
-}//Dblqh::checkLcpHoldop()
-
-/* ========================================================================== 
- * =======  CHECK IF ALL PARTS OF A LOCAL CHECKPOINT ARE STARTED      ======= 
- *
- *       SUBROUTINE SHORT NAME = CLS
- * ========================================================================== */
-bool
-Dblqh::checkLcpStarted(Signal* signal) 
-{
-  LcpLocRecordPtr clsLcpLocptr;
-
-  terrorCode = ZOK;
-  clsLcpLocptr.i = lcpPtr.p->firstLcpLocAcc;
-  int i = 0;
-  do {
-    ptrCheckGuard(clsLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-    if (clsLcpLocptr.p->lcpLocstate == LcpLocRecord::ACC_WAIT_STARTED){
-      return false;
-    }//if
-    clsLcpLocptr.i = clsLcpLocptr.p->nextLcpLoc;
-    i++;
-  } while (clsLcpLocptr.i != RNIL);
-
-  i = 0;
-  clsLcpLocptr.i = lcpPtr.p->firstLcpLocTup;
-  do {
-    ptrCheckGuard(clsLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-    if (clsLcpLocptr.p->lcpLocstate == LcpLocRecord::TUP_WAIT_STARTED){
-      return false;
-    }//if
-    clsLcpLocptr.i = clsLcpLocptr.p->nextLcpLoc;
-    i++;
-  } while (clsLcpLocptr.i != RNIL);
-  
-  return true;
-}//Dblqh::checkLcpStarted()
-
-/* ========================================================================== 
- * =======       CHECK IF ALL PREPARE TUP OPERATIONS ARE COMPLETED    =======
- *
- *       SUBROUTINE SHORT NAME = CLT
- * ========================================================================== */
-void Dblqh::checkLcpTupprep(Signal* signal) 
-{
-  LcpLocRecordPtr cltLcpLocptr;
-  cltLcpLocptr.i = lcpPtr.p->firstLcpLocTup;
-  do {
-    ptrCheckGuard(cltLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-    if (cltLcpLocptr.p->lcpLocstate != LcpLocRecord::IDLE) {
-      ndbrequire(cltLcpLocptr.p->lcpLocstate == LcpLocRecord::WAIT_TUP_PREPLCP);
-      return;
-    }//if
-    cltLcpLocptr.i = cltLcpLocptr.p->nextLcpLoc;
-  } while (cltLcpLocptr.i != RNIL);
-  lcpPtr.p->lcpState = LcpRecord::LCP_WAIT_HOLDOPS;
-}//Dblqh::checkLcpTupprep()
-
-/* ========================================================================== 
- * =======            INITIATE LCP LOCAL RECORD USED TOWARDS ACC      ======= 
- *
- * ========================================================================== */
-void Dblqh::initLcpLocAcc(Signal* signal, Uint32 fragId) 
-{
-  lcpLocptr.p->nextLcpLoc = lcpPtr.p->firstLcpLocAcc;
-  lcpPtr.p->firstLcpLocAcc = lcpLocptr.i;
-  lcpLocptr.p->locFragid = fragId;
-  lcpLocptr.p->waitingBlock = LcpLocRecord::ACC;
-  lcpLocptr.p->lcpLocstate = LcpLocRecord::IDLE;
-  lcpLocptr.p->masterLcpRec = lcpPtr.i;
-  lcpLocptr.p->tupRef = RNIL;
-}//Dblqh::initLcpLocAcc()
-
-/* ========================================================================== 
- * =======           INITIATE LCP LOCAL RECORD USED TOWARDS TUP       ======= 
- *
- * ========================================================================== */
-void Dblqh::initLcpLocTup(Signal* signal, Uint32 fragId) 
-{
-  lcpLocptr.p->nextLcpLoc = lcpPtr.p->firstLcpLocTup;
-  lcpPtr.p->firstLcpLocTup = lcpLocptr.i;
-  lcpLocptr.p->locFragid = fragId;
-  lcpLocptr.p->waitingBlock = LcpLocRecord::TUP;
-  lcpLocptr.p->lcpLocstate = LcpLocRecord::WAIT_TUP_PREPLCP;
-  lcpLocptr.p->masterLcpRec = lcpPtr.i;
-  lcpLocptr.p->tupRef = RNIL;
-}//Dblqh::initLcpLocTup()
-
-/* --------------------------------------------------------------------------
- * -------         MOVE OPERATION FROM ACC WAITING LIST ON FRAGMENT   ------- 
- * -------               TO ACTIVE LIST ON FRAGMENT                   -------
- *
- *       SUBROUTINE SHORT NAME = MAA
- * -------------------------------------------------------------------------- */
-void Dblqh::moveAccActiveFrag(Signal* signal) 
-{
-  UintR maaTcNextConnectptr;
-
-  tcConnectptr.i = fragptr.p->accBlockedList;
-  fragptr.p->accBlockedList = RNIL;
-  /* ------------------------------------------------------------------------
-   *       WE WILL MOVE ALL RECORDS FROM THE ACC BLOCKED LIST AT ONCE.
-   * ------------------------------------------------------------------------ */
-  while (tcConnectptr.i != RNIL) {
-    jam();
-    ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
-    maaTcNextConnectptr = tcConnectptr.p->nextTc;
-    ndbrequire(tcConnectptr.p->listState == TcConnectionrec::ACC_BLOCK_LIST);
-    tcConnectptr.p->listState = TcConnectionrec::NOT_IN_LIST;
-    linkActiveFrag(signal);
-    tcConnectptr.i = maaTcNextConnectptr;
-  }//while
-}//Dblqh::moveAccActiveFrag()
-
-/* -------------------------------------------------------------------------- 
- * -------               MOVE OPERATION FROM ACTIVE LIST ON FRAGMENT  ------- 
- * -------               TO ACC BLOCKED LIST ON FRAGMENT              -------
- *
- *       SUBROUTINE SHORT NAME = MAT
- * -------------------------------------------------------------------------- */
-void Dblqh::moveActiveToAcc(Signal* signal) 
-{
-  TcConnectionrecPtr matTcNextConnectptr;
-
-  releaseActiveList(signal);
-  /* ------------------------------------------------------------------------
-   *       PUT OPERATION RECORD FIRST IN ACC BLOCKED LIST.
-   * ------------------------------------------------------------------------ */
-  matTcNextConnectptr.i = fragptr.p->accBlockedList;
-  tcConnectptr.p->nextTc = matTcNextConnectptr.i;
-  tcConnectptr.p->prevTc = RNIL;
-  tcConnectptr.p->listState = TcConnectionrec::ACC_BLOCK_LIST;
-  fragptr.p->accBlockedList = tcConnectptr.i;
-  if (matTcNextConnectptr.i != RNIL) {
-    jam();
-    ptrCheckGuard(matTcNextConnectptr, ctcConnectrecFileSize, tcConnectionrec);
-    matTcNextConnectptr.p->prevTc = tcConnectptr.i;
-  }//if
-}//Dblqh::moveActiveToAcc()
-
-/* ------------------------------------------------------------------------- */
-/* ---- RELEASE LOCAL LCP RECORDS AFTER COMPLETION OF A LOCAL CHECKPOINT---- */
-/*                                                                           */
-/*       SUBROUTINE SHORT NAME = RLL                                         */
-/* ------------------------------------------------------------------------- */
-void Dblqh::releaseLocalLcps(Signal* signal) 
-{
-  lcpLocptr.i = lcpPtr.p->firstLcpLocAcc;
-  while (lcpLocptr.i != RNIL){
-    ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-    Uint32 tmp = lcpLocptr.p->nextLcpLoc;
-    releaseLcpLoc(signal);
-    lcpLocptr.i = tmp;
-  } 
-  lcpPtr.p->firstLcpLocAcc = RNIL;
   
-  lcpLocptr.i = lcpPtr.p->firstLcpLocTup;
-  while (lcpLocptr.i != RNIL){
-    ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-    Uint32 tmp = lcpLocptr.p->nextLcpLoc;
-    releaseLcpLoc(signal);
-    lcpLocptr.i = tmp;
-  } 
-  lcpPtr.p->firstLcpLocTup = RNIL;
-  
-}//Dblqh::releaseLocalLcps()
-
-/* ------------------------------------------------------------------------- */
-/* -------       SEIZE LCP LOCAL RECORD                              ------- */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-void Dblqh::seizeLcpLoc(Signal* signal) 
-{
-  lcpLocptr.i = cfirstfreeLcpLoc;
-  ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-  cfirstfreeLcpLoc = lcpLocptr.p->nextLcpLoc;
-  lcpLocptr.p->nextLcpLoc = RNIL;
-}//Dblqh::seizeLcpLoc()
-
-/* ------------------------------------------------------------------------- */
-/* -------               SEND ACC_CONT_OP                            ------- */
-/*                                                                           */
-/*       INPUT:          LCP_PTR         LOCAL CHECKPOINT RECORD             */
-/*                       FRAGPTR         FRAGMENT RECORD                     */
-/*                                                                           */
-/*       SUBROUTINE SHORT NAME = SAC                                         */
-/* ------------------------------------------------------------------------- */
-void Dblqh::sendAccContOp(Signal* signal) 
-{
-  LcpLocRecordPtr sacLcpLocptr;
+}//Dblqh::sendCOMP_LCP_ROUND()
 
-  int count = 0;
-  sacLcpLocptr.i = lcpPtr.p->firstLcpLocAcc;
-  do {
-    ptrCheckGuard(sacLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-    sacLcpLocptr.p->accContCounter = 0;
-    /* ------------------------------------------------------------------- */
-    /*SEND START OPERATIONS TO ACC AGAIN                                   */
-    /* ------------------------------------------------------------------- */
-    signal->theData[0] = lcpPtr.p->lcpAccptr;
-    signal->theData[1] = sacLcpLocptr.p->locFragid;
-    sendSignal(fragptr.p->accBlockref, GSN_ACC_CONTOPREQ, signal, 2, JBA);
-    sacLcpLocptr.i = sacLcpLocptr.p->nextLcpLoc;
-  } while (sacLcpLocptr.i != RNIL);
-  
-}//Dblqh::sendAccContOp()
 
 /* ------------------------------------------------------------------------- */
 /* -------               SEND ACC_LCPREQ AND TUP_LCPREQ              ------- */
@@ -11249,39 +10521,6 @@
 /* ------------------------------------------------------------------------- */
 void Dblqh::sendStartLcp(Signal* signal) 
 {
-  LcpLocRecordPtr stlLcpLocptr;
-  stlLcpLocptr.i = lcpPtr.p->firstLcpLocAcc;
-  do {
-    jam();
-    ptrCheckGuard(stlLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-    stlLcpLocptr.p->lcpLocstate = LcpLocRecord::ACC_WAIT_STARTED;
-    signal->theData[0] = lcpPtr.p->lcpAccptr;
-    signal->theData[1] = stlLcpLocptr.i;
-    signal->theData[2] = stlLcpLocptr.p->locFragid;
-    sendSignal(fragptr.p->accBlockref, GSN_ACC_LCPREQ, signal, 3, JBA);
-    stlLcpLocptr.i = stlLcpLocptr.p->nextLcpLoc;
-  } while (stlLcpLocptr.i != RNIL);
-
-  stlLcpLocptr.i = lcpPtr.p->firstLcpLocTup;
-  do {
-    jam();
-    ptrCheckGuard(stlLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-    stlLcpLocptr.p->lcpLocstate = LcpLocRecord::TUP_WAIT_STARTED;
-    signal->theData[0] = stlLcpLocptr.i;
-    signal->theData[1] = cownref;
-    signal->theData[2] = stlLcpLocptr.p->tupRef;
-    if(ERROR_INSERTED(5077))
-      sendSignalWithDelay(fragptr.p->tupBlockref, GSN_TUP_LCPREQ, 
-			  signal, 5000, 3);
-    else
-      sendSignal(fragptr.p->tupBlockref, GSN_TUP_LCPREQ, signal, 3, JBA);
-    stlLcpLocptr.i = stlLcpLocptr.p->nextLcpLoc;
-  } while (stlLcpLocptr.i != RNIL);
-
-  if(ERROR_INSERTED(5077))
-  {
-    ndbout_c("Delayed TUP_LCPREQ with 5 sec");
-  }
 }//Dblqh::sendStartLcp()
 
 /* ------------------------------------------------------------------------- */
@@ -13427,42 +12666,99 @@
   }//if
   tabptr.p->tableStatus = Tablerec::TABLE_DEFINED;
   
-  initFragrecSr(signal);
-  if (startFragReq->lcpNo == ZNIL) {
+  Uint32 lcpNo = startFragReq->lcpNo;
+  Uint32 noOfLogNodes = startFragReq->noOfLogNodes;
+  Uint32 lcpId = startFragReq->lcpId;
+  ndbrequire(noOfLogNodes <= 4);
+  fragptr.p->fragStatus = Fragrecord::CRASH_RECOVERING;
+  fragptr.p->srBlockref = startFragReq->userRef;
+  fragptr.p->srUserptr = startFragReq->userPtr;
+  fragptr.p->srChkpnr = lcpNo;
+  if (lcpNo == (MAX_LCP_STORED - 1)) {
     jam();
-    /* ----------------------------------------------------------------------
-     *  THERE WAS NO LOCAL CHECKPOINT AVAILABLE FOR THIS FRAGMENT. WE DO 
-     *  NOT NEED TO READ IN THE LOCAL FRAGMENT. WE HAVE ALREADY ADDED THE 
-     *  FRAGMENT AS AN EMPTY FRAGMENT AT THIS POINT. THUS WE CAN SIMPLY 
-     *  EXIT AND THE FRAGMENT WILL PARTICIPATE IN THE EXECUTION OF THE LOG.
-     *  PUT FRAGMENT ON LIST OF COMPLETED FRAGMENTS FOR EXECUTION OF LOG.
-     * ---------------------------------------------------------------------- */
-    fragptr.p->nextFrag = cfirstCompletedFragSr;
-    cfirstCompletedFragSr = fragptr.i;
-    return;
+    fragptr.p->lcpId[lcpNo] = lcpId;
+    fragptr.p->nextLcp = 0;
+  } else if (lcpNo < (MAX_LCP_STORED - 1)) {
+    jam();
+    fragptr.p->lcpId[lcpNo] = lcpId;
+    fragptr.p->nextLcp = lcpNo + 1;
+  } else {
+    ndbrequire(lcpNo == ZNIL);
+    jam();
+    fragptr.p->nextLcp = 0;
   }//if
-  if (cfirstWaitFragSr == RNIL) {
+  fragptr.p->srNoLognodes = noOfLogNodes;
+  fragptr.p->logFlag = Fragrecord::STATE_FALSE;
+  fragptr.p->srStatus = Fragrecord::SS_IDLE;
+
+  if (noOfLogNodes > 0) {
     jam();
-      lcpPtr.i = 0;
-    ptrAss(lcpPtr, lcpRecord);
-    if (lcpPtr.p->lcpState == LcpRecord::LCP_IDLE) {
+    for (Uint32 i = 0; i < noOfLogNodes; i++) {
       jam();
-      initLcpSr(signal, startFragReq->lcpNo,
-                startFragReq->lcpId, tabptr.i,
-                fragId, fragptr.i);
-      signal->theData[0] = lcpPtr.i;
-      signal->theData[1] = cownref;
-      signal->theData[2] = lcpPtr.p->currentFragment.lcpFragOrd.lcpNo;
-      signal->theData[3] = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
-      signal->theData[4] = lcpPtr.p->currentFragment.lcpFragOrd.fragmentId;
-      sendSignal(fragptr.p->accBlockref, GSN_SR_FRAGIDREQ, signal, 5, JBB);
-      return;
-    }//if
+      fragptr.p->srStartGci[i] = startFragReq->startGci[i];
+      fragptr.p->srLastGci[i] = startFragReq->lastGci[i];
+      fragptr.p->srLqhLognode[i] = startFragReq->lqhLogNode[i];
+    }//for
+    fragptr.p->newestGci = startFragReq->lastGci[noOfLogNodes - 1];
+  } else {
+    fragptr.p->newestGci = cnewestGci;
+  }//if
+  
+  if (lcpNo == ZNIL || fragptr.i != tabptr.p->fragrec[0])
+  {
+    jam();
+    /**
+     *  THERE WAS NO LOCAL CHECKPOINT AVAILABLE FOR THIS FRAGMENT. WE DO 
+     *  NOT NEED TO READ IN THE LOCAL FRAGMENT. 
+     */
+    /**
+     * Or this is not "first" fragment in table
+     *   RESTORE_LCP_REQ will currently restore all fragments
+     */
+    c_lcp_complete_fragments.add(fragptr);
+
+    if(lcpNo == ZNIL)
+    {
+      for (Uint32 i = 0; i<MAX_FRAG_PER_NODE; i++)
+      {
+	if (tabptr.p->fragrec[i] != RNIL)
+	{
+	  signal->theData[0] = tabptr.i;
+	  signal->theData[1] = tabptr.p->fragid[i];
+	  sendSignal(DBACC_REF, GSN_EXPANDCHECK2, signal, 2, JBB);
+	}
+      }
+    }
+    
+    return;
   }//if
-  fragptr.p->nextFrag = cfirstWaitFragSr;
-  cfirstWaitFragSr = fragptr.i;
+
+  c_lcpId = (c_lcpId == 0 ? lcpId : c_lcpId);
+  c_lcpId = (c_lcpId < lcpId ? c_lcpId : lcpId);
+  c_lcp_waiting_fragments.add(fragptr);
+  if(c_lcp_restoring_fragments.isEmpty())
+    send_restore_lcp(signal);
 }//Dblqh::execSTART_FRAGREQ()
 
+void
+Dblqh::send_restore_lcp(Signal * signal)
+{
+  c_lcp_waiting_fragments.first(fragptr);
+  c_lcp_waiting_fragments.remove(fragptr);
+  c_lcp_restoring_fragments.add(fragptr);
+  
+  RestoreLcpReq* req= (RestoreLcpReq*)signal->getDataPtrSend();
+  req->senderData = fragptr.i;
+  req->senderRef = reference();
+  req->tableId = fragptr.p->tabRef;
+  req->fragmentId = fragptr.p->fragId;
+  req->lcpNo = fragptr.p->srChkpnr;
+  req->lcpId = fragptr.p->lcpId[fragptr.p->srChkpnr];
+  
+  sendSignal(RESTORE_REF, GSN_RESTORE_LCP_REQ, signal, 
+	     RestoreLcpReq::SignalLength, JBB);
+}
+
 void Dblqh::startFragRefLab(Signal* signal) 
 {
   const StartFragReq * const startFragReq = (StartFragReq *)&signal->theData[0];
@@ -13475,256 +12771,66 @@
   return;
 }//Dblqh::startFragRefLab()
 
-/* ***************>> */
-/*  SR_FRAGIDCONF  > */
-/* ***************>> */
-/* --------------------------------------------------------------------------
- *       PRECONDITION: LCP_PTR:LCP_STATE = SR_WAIT_FRAGID 
- * -------------------------------------------------------------------------- */
-void Dblqh::execSR_FRAGIDCONF(Signal* signal) 
-{
-  SrFragidConf * const srFragidConf = (SrFragidConf *)&signal->theData[0];
-  jamEntry();
-
-  lcpPtr.i = srFragidConf->lcpPtr;
-  ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
-  ndbrequire(lcpPtr.p->lcpState == LcpRecord::LCP_SR_WAIT_FRAGID);
-  /* ------------------------------------------------------------------------
-   *  NO ERROR CHECKING OF TNO_LOCFRAG VALUE. OUT OF BOUND WILL IMPLY THAT AN
-   *  INDEX OUT OF RANGE WILL CAUSE A SYSTEM RESTART WHICH IS DESIRED.
-   * ------------------------------------------------------------------------ */
-  lcpPtr.p->lcpAccptr = srFragidConf->accPtr;
-  fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-  fragptr.p->accFragptr[0] = srFragidConf->fragPtr[0];
-  fragptr.p->accFragptr[1] = srFragidConf->fragPtr[1];
-  Uint32 noLocFrag = srFragidConf->noLocFrag;
-  ndbrequire(noLocFrag == 2);
-  Uint32 fragid[2];
-  Uint32 i;
-  for (i = 0; i < noLocFrag; i++) {
-    fragid[i] = srFragidConf->fragId[i];
-  }//for
-
-  for (i = 0; i < noLocFrag; i++) {
-    jam();
-    Uint32 fragId = fragid[i];
-    /* ----------------------------------------------------------------------
-     *  THERE IS NO ERROR CHECKING ON PURPOSE. IT IS POSSIBLE TO CALCULATE HOW
-     *  MANY LOCAL LCP RECORDS THERE SHOULD BE. IT SHOULD NEVER HAPPEN THAT 
-     *  THERE IS NO ONE FREE. IF THERE IS NO ONE IT WILL ALSO BE A POINTER 
-     *  OUT OF RANGE WHICH IS AN ERROR CODE IN ITSELF. REUSES ERROR 
-     *  HANDLING IN AXE VM.
-     * ---------------------------------------------------------------------- */
-    seizeLcpLoc(signal);
-    initLcpLocAcc(signal, fragId);
-    lcpLocptr.p->lcpLocstate = LcpLocRecord::SR_ACC_STARTED;
-    signal->theData[0] = lcpPtr.p->lcpAccptr;
-    signal->theData[1] = lcpLocptr.i;
-    signal->theData[2] = lcpLocptr.p->locFragid;
-    signal->theData[3] = lcpPtr.p->currentFragment.lcpFragOrd.lcpId % MAX_LCP_STORED;
-    sendSignal(fragptr.p->accBlockref, GSN_ACC_SRREQ, signal, 4, JBB);
-    seizeLcpLoc(signal);
-    initLcpLocTup(signal, fragId);
-    lcpLocptr.p->lcpLocstate = LcpLocRecord::SR_TUP_STARTED;
-    signal->theData[0] = lcpLocptr.i;
-    signal->theData[1] = cownref;
-    signal->theData[2] = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
-    signal->theData[3] = lcpLocptr.p->locFragid;
-    signal->theData[4] = lcpPtr.p->currentFragment.lcpFragOrd.lcpNo;
-    sendSignal(fragptr.p->tupBlockref, GSN_TUP_SRREQ, signal, 5, JBB);
-  }//for
-  lcpPtr.p->lcpState = LcpRecord::LCP_SR_STARTED;
-  return;
-}//Dblqh::execSR_FRAGIDCONF()
-
-/* ***************> */
-/*  SR_FRAGIDREF  > */
-/* ***************> */
-void Dblqh::execSR_FRAGIDREF(Signal* signal) 
+void Dblqh::execRESTORE_LCP_REF(Signal* signal) 
 {
   jamEntry();
   ndbrequire(false);
-}//Dblqh::execSR_FRAGIDREF()
-
-/* ************>> */
-/*  ACC_SRCONF  > */
-/* ************>> */
-/* --------------------------------------------------------------------------
- *       PRECONDITION: LCP_LOCPTR:LCP_LOCSTATE = SR_ACC_STARTED
- * -------------------------------------------------------------------------- */
-void Dblqh::execACC_SRCONF(Signal* signal) 
-{
-  jamEntry();
-  lcpLocptr.i = signal->theData[0];
-  ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-  if (lcpLocptr.p->lcpLocstate != LcpLocRecord::SR_ACC_STARTED) {
-    jam();
-    systemErrorLab(signal, __LINE__);
-    return;
-  }//if
-
-  lcpPtr.i = lcpLocptr.p->masterLcpRec;
-  ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
-  /* ------------------------------------------------------------------------
-   *  NO ERROR CHECK ON USING VALUE IN MASTER_LCP_REC. ERROR IN THIS REFERENCE
-   *  WILL CAUSE POINTER OUT OF RANGE WHICH CAUSES A SYSTEM RESTART.
-   * ------------------------------------------------------------------------ */
-  lcpLocptr.p->lcpLocstate = LcpLocRecord::SR_ACC_COMPLETED;
-  srCompletedLab(signal);
   return;
-}//Dblqh::execACC_SRCONF()
-
-/* ************> */
-/*  ACC_SRREF  > */
-/* ************> */
-void Dblqh::execACC_SRREF(Signal* signal) 
-{
-  jamEntry();
-  terrorCode = signal->theData[1];
-  systemErrorLab(signal, __LINE__);
-  return;
-}//Dblqh::execACC_SRREF()
+}
 
-/* ************>> */
-/*  TUP_SRCONF  > */
-/* ************>> */
-/* --------------------------------------------------------------------------
- *       PRECONDITION: LCP_LOCPTR:LCP_LOCSTATE = SR_TUP_STARTED
- * -------------------------------------------------------------------------- */
-void Dblqh::execTUP_SRCONF(Signal* signal) 
+void Dblqh::execRESTORE_LCP_CONF(Signal* signal) 
 {
   jamEntry();
-  lcpLocptr.i = signal->theData[0];
-  ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-  Uint32 tupFragPtr = signal->theData[1];
-  ndbrequire(lcpLocptr.p->lcpLocstate == LcpLocRecord::SR_TUP_STARTED);
+  RestoreLcpConf* conf= (RestoreLcpConf*)signal->getDataPtr();
+  fragptr.i = conf->senderData;
+  c_fragment_pool.getPtr(fragptr);
 
-  lcpPtr.i = lcpLocptr.p->masterLcpRec;
-  ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
-  /* ------------------------------------------------------------------------
-   *  NO ERROR CHECK ON USING VALUE IN MASTER_LCP_REC. ERROR IN THIS REFERENCE
-   *  WILL CAUSE POINTER OUT OF RANGE WHICH CAUSES A SYSTEM RESTART.
-   * ------------------------------------------------------------------------ */
-  lcpLocptr.p->lcpLocstate = LcpLocRecord::SR_TUP_COMPLETED;
-  fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-  if (lcpLocptr.i == lcpPtr.p->firstLcpLocTup) {
-    jam();
-    fragptr.p->tupFragptr[1] = tupFragPtr;
-  } else {
-    jam();
-    fragptr.p->tupFragptr[0] = tupFragPtr;
-  }//if
-  srCompletedLab(signal);
-  return;
-}//Dblqh::execTUP_SRCONF()
+  c_lcp_restoring_fragments.remove(fragptr);
+  c_lcp_complete_fragments.add(fragptr);
 
-void Dblqh::srCompletedLab(Signal* signal) 
-{
-  checkSrCompleted(signal);
-  if (lcpPtr.p->lcpState == LcpRecord::LCP_SR_COMPLETED) {
+  /**
+   * Disable expand check in ACC
+   *   before running REDO
+   */
+  tabptr.i = fragptr.p->tabRef;
+  ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
+  for (Uint32 i = 0; i<MAX_FRAG_PER_NODE; i++)
+  {
+    if (tabptr.p->fragrec[i] != RNIL)
+    {
+      signal->theData[0] = tabptr.i;
+      signal->theData[1] = tabptr.p->fragid[i];
+      sendSignal(DBACC_REF, GSN_EXPANDCHECK2, signal, 2, JBB);
+    }
+  }
+  
+  if (!c_lcp_waiting_fragments.isEmpty())
+  {
+    send_restore_lcp(signal);
+    return;
+  }
+  if (c_lcp_restoring_fragments.isEmpty() && cstartRecReq == ZTRUE)
+  {
     jam();
-    /* ----------------------------------------------------------------------
-     *  THE SYSTEM RESTART OF THIS FRAGMENT HAS BEEN COMPLETED. IT IS NOW
-     *  TIME TO START A SYSTEM RESTART ON THE NEXT FRAGMENT OR CONTINUE 
-     *  WITH THE NEXT STEP OF THE SYSTEM RESTART. THIS STEP IS TO EXECUTE 
-     *  THE FRAGMENT LOGS.
-     * ----------------------------------------------------------------------
-     *  WE RELEASE THE LOCAL LCP RECORDS.
-     * --------------------------------------------------------------------- */
-    releaseLocalLcps(signal);
-    /* ----------------------------------------------------------------------
-     *  PUT FRAGMENT ON LIST OF FRAGMENTS WHICH HAVE BEEN STARTED AS PART OF 
-     *  THE SYSTEM RESTART. THEY ARE NOW WAITING TO EXECUTE THE FRAGMENT LOG.
-     * --------------------------------------------------------------------- */
-    fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
-    ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-    fragptr.p->nextFrag = cfirstCompletedFragSr;
-    cfirstCompletedFragSr = fragptr.i;
-    if (cfirstWaitFragSr != RNIL) {
-      jam();
-      /* --------------------------------------------------------------------
-       *  ANOTHER FRAGMENT IS WAITING FOR SYSTEM RESTART. RESTART THIS 
-       *  FRAGMENT AS WELL.
-       * -------------------------------------------------------------------- */
-      fragptr.i = cfirstWaitFragSr;
-      ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-      cfirstWaitFragSr = fragptr.p->nextFrag;
-      /* --------------------------------------------------------------------
-       *  RETRIEVE DATA FROM THE FRAGMENT RECORD.
-       * -------------------------------------------------------------------- */
-      ndbrequire(fragptr.p->srChkpnr < MAX_LCP_STORED);
-      initLcpSr(signal,
-                fragptr.p->srChkpnr,
-                fragptr.p->lcpId[fragptr.p->srChkpnr],
-                fragptr.p->tabRef,
-                fragptr.p->fragId,
-                fragptr.i);
-      signal->theData[0] = lcpPtr.i;
-      signal->theData[1] = cownref;
-      signal->theData[2] = lcpPtr.p->currentFragment.lcpFragOrd.lcpNo;
-      signal->theData[3] = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
-      signal->theData[4] = lcpPtr.p->currentFragment.lcpFragOrd.fragmentId;
-      sendSignal(fragptr.p->accBlockref, GSN_SR_FRAGIDREQ, signal, 5, JBB);
-      return;
-    } else {
-      jam();
-      /* --------------------------------------------------------------------
-       *  NO MORE FRAGMENTS ARE WAITING FOR SYSTEM RESTART.
-       * -------------------------------------------------------------------- */
-      lcpPtr.p->lcpState = LcpRecord::LCP_IDLE;
-      if (cstartRecReq == ZTRUE) {
-        jam();
-	/* ----------------------------------------------------------------
-         *  WE HAVE ALSO RECEIVED AN INDICATION THAT NO MORE FRAGMENTS 
-	 *  NEEDS RESTART.
-	 *  NOW IT IS TIME TO START EXECUTING THE UNDO LOG.
-	 * ----------------------------------------------------------------
-	 *  WE ARE NOW IN A POSITION TO ORDER TUP AND ACC TO START 
-	 *  EXECUTING THEIR UNDO LOGS. THIS MUST BE DONE BEFORE THE 
-	 *  FRAGMENT LOGS CAN BE EXECUTED.
-	 * ---------------------------------------------------------------- */
-        csrExecUndoLogState = EULS_STARTED;
-        signal->theData[0] = caccBlockref;
-        signal->theData[1] = cownref;
-        sendSignal(caccBlockref, GSN_START_RECREQ, signal, 2, JBB);
-        signal->theData[0] = ctupBlockref;
-        signal->theData[1] = cownref;
-        sendSignal(ctupBlockref, GSN_START_RECREQ, signal, 2, JBB);
-        return;
-      } else {
-        jam();
-	/* ----------------------------------------------------------------
-	 *  WE HAVE NOT RECEIVED ALL FRAGMENTS YET OR AT LEAST NOT WE 
-	 *  HAVE NOT RECEIVED THE START_RECREQ SIGNAL. EXIT AND WAIT 
-	 *  FOR MORE.
-	 * ---------------------------------------------------------------- */
-        return;
-      }//if
-    }//if
-  }//if
-  /*---------------*/
-  /*       ELSE    */
-  /*-------------------------------------------------------------------------
-   *       THE SYSTEM RESTART ON THIS FRAGMENT HAS NOT BEEN COMPLETED, 
-   *       EXIT AND WAIT FOR MORE SIGNALS
-   *-------------------------------------------------------------------------
-   *       DO NOTHING, EXIT IS EXECUTED BELOW
-   *------------------------------------------------------------------------- */
-  return;
-}//Dblqh::srCompletedLab()
-
-/* ************> */
-/*  TUP_SRREF  > */
-/* ************> */
-void Dblqh::execTUP_SRREF(Signal* signal) 
-{
-  jamEntry();
-  terrorCode = signal->theData[1];
-  systemErrorLab(signal, __LINE__);
-  return;
-}//Dblqh::execTUP_SRREF()
+    /* ----------------------------------------------------------------
+     *  WE HAVE ALSO RECEIVED AN INDICATION THAT NO MORE FRAGMENTS 
+     *  NEEDS RESTART.
+     *  NOW IT IS TIME TO START EXECUTING THE UNDO LOG.
+     * ----------------------------------------------------------------
+     *  WE ARE NOW IN A POSITION TO ORDER TUP AND ACC TO START 
+     *  EXECUTING THEIR UNDO LOGS. THIS MUST BE DONE BEFORE THE 
+     *  FRAGMENT LOGS CAN BE EXECUTED.
+     * ---------------------------------------------------------------- */
+    csrExecUndoLogState = EULS_STARTED;
+    lcpPtr.i = 0;
+    ptrAss(lcpPtr, lcpRecord);
+    lcpPtr.p->m_outstanding = 1;
+    
+    signal->theData[0] = c_lcpId;
+    sendSignal(TSMAN_REF, GSN_START_RECREQ, signal, 1, JBB);
+    return;
+  }
+}
 
 /* ***************> */
 /*  START_RECREQ  > */
@@ -13771,35 +12877,19 @@
 	       StartRecConf::SignalLength, JBB);
     return;
   }//if
-  if (cfirstWaitFragSr == RNIL) {
-    /* ----------------------------------------------------------------------
-     *      THERE ARE NO FRAGMENTS WAITING TO BE RESTARTED.
-     * --------------------------------------------------------------------- */
+
+  if (c_lcp_restoring_fragments.isEmpty())
+  {
+    jam();
+    csrExecUndoLogState = EULS_STARTED;
+
     lcpPtr.i = 0;
     ptrAss(lcpPtr, lcpRecord);
-    if (lcpPtr.p->lcpState == LcpRecord::LCP_IDLE) {
-      jam();
-      /* --------------------------------------------------------------------
-       *    THERE ARE NO FRAGMENTS THAT ARE CURRENTLY PERFORMING THEIR 
-       *    SYSTEM RESTART.
-       * --------------------------------------------------------------------
-       *    WE ARE NOW IN A POSITION TO ORDER TUP AND ACC TO START EXECUTING 
-       *    THEIR UNDO LOGS. THIS MUST BE DONE BEFORE THE FRAGMENT LOGS 
-       *    CAN BE EXECUTED.   
-       * ------------------------------------------------------------------- */
-      csrExecUndoLogState = EULS_STARTED;
-      signal->theData[0] = caccBlockref;
-      signal->theData[1] = cownref;
-      sendSignal(caccBlockref, GSN_START_RECREQ, signal, 2, JBB);
-      signal->theData[0] = ctupBlockref;
-      signal->theData[1] = cownref;
-      sendSignal(ctupBlockref, GSN_START_RECREQ, signal, 2, JBB);
-    }//if
+    lcpPtr.p->m_outstanding = 1;
+    
+    signal->theData[0] = c_lcpId;
+    sendSignal(TSMAN_REF, GSN_START_RECREQ, signal, 1, JBB);
   }//if
-  /* -----------------------------------------------------------------------
-   *       EXIT AND WAIT FOR COMPLETION OF ALL FRAGMENTS.
-   * ----------------------------------------------------------------------- */
-  return;
 }//Dblqh::execSTART_RECREQ()
 
 /* ***************>> */
@@ -13808,38 +12898,95 @@
 void Dblqh::execSTART_RECCONF(Signal* signal) 
 {
   jamEntry();
-  BlockReference userRef = signal->theData[0];
-  if (userRef == caccBlockref) {
-    if (csrExecUndoLogState == EULS_STARTED) {
-      jam();
-      csrExecUndoLogState = EULS_ACC_COMPLETED;
-    } else {
-      ndbrequire(csrExecUndoLogState == EULS_TUP_COMPLETED);
-      jam();
-      csrExecUndoLogState = EULS_COMPLETED;
-      /* --------------------------------------------------------------------
-       *       START THE FIRST PHASE OF EXECUTION OF THE LOG.
-       * ------------------------------------------------------------------- */
-      startExecSr(signal);
-    }//if
-  } else {
-    ndbrequire(userRef == ctupBlockref);
-    if (csrExecUndoLogState == EULS_STARTED) {
-      jam();
-      csrExecUndoLogState = EULS_TUP_COMPLETED;
-    } else {
-      ndbrequire(csrExecUndoLogState == EULS_ACC_COMPLETED);
-      jam();
-      csrExecUndoLogState = EULS_COMPLETED;
-      /* --------------------------------------------------------------------
-       *       START THE FIRST PHASE OF EXECUTION OF THE LOG.
-       * ------------------------------------------------------------------- */
-      startExecSr(signal);
-    }//if
-  }//if
+  lcpPtr.i = 0;
+  ptrAss(lcpPtr, lcpRecord);
+  ndbrequire(csrExecUndoLogState == EULS_STARTED);
+  ndbrequire(lcpPtr.p->m_outstanding);
+
+  Uint32 sender= signal->theData[0];
+  
+  lcpPtr.p->m_outstanding--;
+  if(lcpPtr.p->m_outstanding)
+  {
+    jam();
+    return;
+  }
+
+  switch(refToBlock(sender)){
+  case TSMAN:
+    jam();
+    lcpPtr.p->m_outstanding++;
+    signal->theData[0] = c_lcpId;
+    sendSignal(LGMAN_REF, GSN_START_RECREQ, signal, 1, JBB);
+    return;
+  case LGMAN:
+    jam();
+    break;
+  default:
+    ndbrequire(false);
+  }
+
+  jam();
+  csrExecUndoLogState = EULS_COMPLETED;
+  c_lcp_complete_fragments.first(fragptr);
+  build_acc(signal, fragptr.i);
   return;
 }//Dblqh::execSTART_RECCONF()
 
+void
+Dblqh::build_acc(Signal* signal, Uint32 fragPtrI)
+{
+  fragptr.i = fragPtrI;
+  while(fragptr.i != RNIL)
+  {
+    c_lcp_complete_fragments.getPtr(fragptr);
+    tabptr.i = fragptr.p->tabRef;
+    ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
+    
+    if(true || fragptr.i != tabptr.p->fragrec[0])
+    {
+      // Only need to send 1 build per table, TUP will rebuild all
+      fragptr.i = fragptr.p->nextList;
+      continue;
+    }
+
+    BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
+    req->setUserRef(reference());
+    req->setConnectionPtr(fragptr.i);
+    req->setRequestType(BuildIndxReq::RT_SYSTEMRESTART);
+    req->setBuildId(0);   // not used
+    req->setBuildKey(0);  // not used
+    req->setIndexType(RNIL);
+    req->setIndexId(RNIL);
+    req->setTableId(tabptr.i);
+    req->setParallelism(0);
+
+    sendSignal(DBTUP_REF, GSN_BUILDINDXREQ, signal, 
+	       BuildIndxReq::SignalLength, JBB);
+    return;
+  }
+
+  startExecSr(signal);
+}
+
+void
+Dblqh::execBUILDINDXREF(Signal* signal)
+{
+  ndbrequire(false);
+}
+
+void
+Dblqh::execBUILDINDXCONF(Signal* signal)
+{
+  BuildIndxConf* conf = (BuildIndxConf*)signal->getDataPtrSend();    
+  Uint32 fragPtrI = conf->getConnectionPtr();
+
+  fragptr.i = fragPtrI;
+  c_fragment_pool.getPtr(fragptr);
+  infoEvent("LQH: primary key index %u rebuild done", fragptr.p->tabRef);
+  build_acc(signal, fragptr.p->nextList);
+}
+
 /* ***************> */
 /*  START_RECREF  > */
 /* ***************> */
@@ -13854,10 +13001,10 @@
 /* ***************>> */
 void Dblqh::execSTART_EXEC_SR(Signal* signal) 
 {
-  FragrecordPtr prevFragptr;
   jamEntry();
   fragptr.i = signal->theData[0];
-  prevFragptr.i = signal->theData[1];
+  Uint32 next = RNIL;
+  
   if (fragptr.i == RNIL) {
     jam();
     ndbrequire(cnoOfNodes < MAX_NDB_NODES);
@@ -13879,15 +13026,17 @@
         sendSignal(ref, GSN_EXEC_SRREQ, signal, 1, JBB);
       }//if
     }//for
+    return;
   } else {
     jam();
-    ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+    c_lcp_complete_fragments.getPtr(fragptr);
     if (fragptr.p->srNoLognodes > csrPhasesCompleted) {
       jam();
       Uint32 index = csrPhasesCompleted;
       arrGuard(index, 4);
       BlockReference ref = calcLqhBlockRef(fragptr.p->srLqhLognode[index]);
       fragptr.p->srStatus = Fragrecord::SS_STARTED;
+
       /* --------------------------------------------------------------------
        *  SINCE WE CAN HAVE SEVERAL LQH NODES PER FRAGMENT WE CALCULATE 
        *  THE LQH POINTER IN SUCH A WAY THAT WE CAN DEDUCE WHICH OF THE 
@@ -13900,9 +13049,10 @@
       execFragReq->fragId = fragptr.p->fragId;
       execFragReq->startGci = fragptr.p->srStartGci[index];
       execFragReq->lastGci = fragptr.p->srLastGci[index];
-      sendSignal(ref, GSN_EXEC_FRAGREQ, signal, ExecFragReq::SignalLength, JBB);
-      prevFragptr.i = fragptr.i;
-      fragptr.i = fragptr.p->nextFrag;
+      sendSignal(ref, GSN_EXEC_FRAGREQ, signal, 
+		 ExecFragReq::SignalLength, JBB);
+
+      next = fragptr.p->nextList;
     } else {
       jam();
       /* --------------------------------------------------------------------
@@ -13912,38 +13062,19 @@
        *  ALSO SEND START_FRAGCONF TO DIH AND SET THE STATE TO ACTIVE ON THE
        *  FRAGMENT.
        * ------------------------------------------------------------------- */
-      Uint32 next = fragptr.p->nextFrag;
-      if (prevFragptr.i != RNIL) {
-        jam();
-        ptrCheckGuard(prevFragptr, cfragrecFileSize, fragrecord);
-        prevFragptr.p->nextFrag = next;
-      } else {
-        jam();
-        cfirstCompletedFragSr = next;
-      }//if
-
-      /**
-       * Put fragment on list which has completed REDO log
-       */
-      fragptr.p->nextFrag = c_redo_log_complete_frags;
-      c_redo_log_complete_frags = fragptr.i;
+      next = fragptr.p->nextList;
+      c_lcp_complete_fragments.remove(fragptr);
+      c_redo_complete_fragments.add(fragptr);
       
       fragptr.p->fragStatus = Fragrecord::FSACTIVE;
       fragptr.p->logFlag = Fragrecord::STATE_TRUE;
       signal->theData[0] = fragptr.p->srUserptr;
       signal->theData[1] = cownNodeid;
       sendSignal(fragptr.p->srBlockref, GSN_START_FRAGCONF, signal, 2, JBB);
-      /* --------------------------------------------------------------------
-       *  WE HAVE TO ENSURE THAT THIS FRAGMENT IS NOT PUT BACK ON THE LIST BY
-       *  MISTAKE. WE DO THIS BY ALSO REMOVING IT AS PREVIOUS IN START_EXEC_SR
-       *  THIS IS PERFORMED BY KEEPING PREV_FRAGPTR AS PREV_FRAGPTR BUT MOVING
-       *  FRAGPTR TO THE NEXT FRAGMENT IN THE LIST.
-       * ------------------------------------------------------------------- */
-      fragptr.i = next;
-    }//if
-    signal->theData[0] = fragptr.i;
-    signal->theData[1] = prevFragptr.i;
-    sendSignal(cownref, GSN_START_EXEC_SR, signal, 2, JBB);
+      
+    } //if
+    signal->theData[0] = next;
+    sendSignal(cownref, GSN_START_EXEC_SR, signal, 1, JBB);
   }//if
   return;
 }//Dblqh::execSTART_EXEC_SR()
@@ -14010,7 +13141,7 @@
 {
   jamEntry();
   fragptr.i = signal->theData[0];
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(fragptr);
   fragptr.p->srStatus = Fragrecord::SS_COMPLETED;
   return;
 }//Dblqh::execEXEC_FRAGCONF()
@@ -14052,6 +13183,7 @@
       }//if
     }//if
   }//for
+
   /* ------------------------------------------------------------------------
    *  CLEAR NODE SYSTEM RESTART EXECUTION STATE TO PREPARE FOR NEXT PHASE OF
    *  LOG EXECUTION.
@@ -14059,22 +13191,21 @@
   for (nodeId = 0; nodeId < MAX_NDB_NODES; nodeId++) {
     cnodeExecSrState[nodeId] = ZSTART_SR;
   }//for
+
   /* ------------------------------------------------------------------------
    *  NOW CHECK IF ALL FRAGMENTS IN THIS PHASE HAVE COMPLETED. IF SO START THE
    *  NEXT PHASE.
    * ----------------------------------------------------------------------- */
-  fragptr.i = cfirstCompletedFragSr;
-  if (fragptr.i == RNIL) {
-    jam();
-    execSrCompletedLab(signal);
-    return;
-  }//if
-  do {
+  c_lcp_complete_fragments.first(fragptr);
+  while (fragptr.i != RNIL)
+  {
     jam();
-    ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-    ndbrequire(fragptr.p->srStatus == Fragrecord::SS_COMPLETED);
-    fragptr.i = fragptr.p->nextFrag;
-  } while (fragptr.i != RNIL);
+    if(fragptr.p->srStatus != Fragrecord::SS_COMPLETED)
+    {
+      return;
+    }
+    c_lcp_complete_fragments.next(fragptr);
+  } 
   execSrCompletedLab(signal);
   return;
 }//Dblqh::execEXEC_SRCONF()
@@ -14255,8 +13386,9 @@
     sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
   } else {
     jam();
+    c_lcp_complete_fragments.first(fragptr);
     signal->theData[0] = ZSR_GCI_LIMITS;
-    signal->theData[1] = 0;
+    signal->theData[1] = fragptr.i;
     sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
   }//if
   return;
@@ -14268,43 +13400,49 @@
  * ------------------------------------------------------------------------- */
 void Dblqh::srGciLimits(Signal* signal) 
 {
-  LogPartRecordPtr tmpLogPartPtr;
-
   jamEntry();
   fragptr.i = signal->theData[0];
   Uint32 loopCount = 0;
   logPartPtr.i = 0;
   ptrAss(logPartPtr, logPartRecord);
-  while (fragptr.i < cfragrecFileSize) {
+  while (fragptr.i != RNIL){
     jam();
-    ptrAss(fragptr, fragrecord);
-    if (fragptr.p->execSrStatus != Fragrecord::IDLE) {
+    c_lcp_complete_fragments.getPtr(fragptr);
+    ndbrequire(fragptr.p->execSrNoReplicas - 1 < 4);
+    for (Uint32 i = 0; i < fragptr.p->execSrNoReplicas; i++) {
       jam();
-      ndbrequire(fragptr.p->execSrNoReplicas - 1 < 4);
-      for (Uint32 i = 0; i < fragptr.p->execSrNoReplicas; i++) {
-        jam();
-        if (fragptr.p->execSrStartGci[i] < logPartPtr.p->logStartGci) {
-          jam();
-          logPartPtr.p->logStartGci = fragptr.p->execSrStartGci[i];
-        }//if
-        if (fragptr.p->execSrLastGci[i] > logPartPtr.p->logLastGci) {
-          jam();
-          logPartPtr.p->logLastGci = fragptr.p->execSrLastGci[i];
-        }//if
-      }//for
-    }//if
+      if (fragptr.p->execSrStartGci[i] < logPartPtr.p->logStartGci) {
+	jam();
+	logPartPtr.p->logStartGci = fragptr.p->execSrStartGci[i];
+      }//if
+      if (fragptr.p->execSrLastGci[i] > logPartPtr.p->logLastGci) {
+	jam();
+	logPartPtr.p->logLastGci = fragptr.p->execSrLastGci[i];
+      }
+    }
+    
     loopCount++;
     if (loopCount > 20) {
       jam();
       signal->theData[0] = ZSR_GCI_LIMITS;
-      signal->theData[1] = fragptr.i + 1;
+      signal->theData[1] = fragptr.p->nextList;
       sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
       return;
     } else {
       jam();
-      fragptr.i++;
+      fragptr.i = fragptr.p->nextList;
     }//if
-  }//while
+  }
+
+  for(Uint32 i = 1; i<4; i++)
+  {
+    LogPartRecordPtr tmp;
+    tmp.i = i;
+    ptrAss(tmp, logPartRecord);
+    tmp.p->logStartGci = logPartPtr.p->logStartGci;
+    tmp.p->logLastGci = logPartPtr.p->logLastGci;
+  }
+
   if (logPartPtr.p->logStartGci == (UintR)-1) {
     jam();
       /* --------------------------------------------------------------------
@@ -14314,11 +13452,7 @@
        * ------------------------------------------------------------------- */
     logPartPtr.p->logStartGci = logPartPtr.p->logLastGci;
   }//if
-  for (tmpLogPartPtr.i = 1; tmpLogPartPtr.i < 4; tmpLogPartPtr.i++) {
-    ptrAss(tmpLogPartPtr, logPartRecord);
-    tmpLogPartPtr.p->logStartGci = logPartPtr.p->logStartGci;
-    tmpLogPartPtr.p->logLastGci = logPartPtr.p->logLastGci;
-  }//for
+  
   for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) {
     jam();
     ptrAss(logPartPtr, logPartRecord);
@@ -14966,7 +14100,7 @@
   tcConnectptr.i = logPartPtr.p->logTcConrec;
   ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
   fragptr.i = tcConnectptr.p->fragmentptr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(fragptr);
   // Read a log record and prepare it for execution
   readLogHeader(signal);
   readKey(signal);
@@ -15218,8 +14352,9 @@
    * ----------------------------------------------------------------------- */
   if (cstartType != NodeState::ST_NODE_RESTART) {
     jam();
+    c_lcp_complete_fragments.first(fragptr);
     signal->theData[0] = ZSEND_EXEC_CONF;
-    signal->theData[1] = 0;
+    signal->theData[1] = fragptr.i;
     sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
   } else {
     jam();
@@ -15245,8 +14380,9 @@
   jamEntry();
   fragptr.i = signal->theData[0];
   Uint32 loopCount = 0;
-  while (fragptr.i < cfragrecFileSize) {
-    ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  while (fragptr.i != RNIL) {
+    c_lcp_complete_fragments.getPtr(fragptr);
+    Uint32 next = fragptr.p->nextList;
     if (fragptr.p->execSrStatus != Fragrecord::IDLE) {
       jam();
       ndbrequire(fragptr.p->execSrNoReplicas - 1 < 4);
@@ -15265,6 +14401,7 @@
         Uint32 fragId = fragptr.p->fragId;
         tabptr.i = fragptr.p->tabRef;
         ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
+	c_lcp_complete_fragments.remove(fragptr);
         deleteFragrec(fragId);
       }//if
       fragptr.p->execSrNoReplicas = 0;
@@ -15273,18 +14410,18 @@
     if (loopCount > 20) {
       jam();
       signal->theData[0] = ZSEND_EXEC_CONF;
-      signal->theData[1] = fragptr.i + 1;
+      signal->theData[1] = next;
       sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
       return;
     } else {
       jam();
-      fragptr.i++;
+      fragptr.i = next;
     }//if
   }//while
-    /* ----------------------------------------------------------------------
-     *  WE HAVE NOW SENT ALL EXEC_FRAGCONF. NOW IT IS TIME TO SEND 
-     *  EXEC_SRCONF TO ALL NODES.
-     * --------------------------------------------------------------------- */
+  /* ----------------------------------------------------------------------
+   *  WE HAVE NOW SENT ALL EXEC_FRAGCONF. NOW IT IS TIME TO SEND 
+   *  EXEC_SRCONF TO ALL NODES.
+   * --------------------------------------------------------------------- */
   srPhase3Comp(signal);
 }//Dblqh::sendExecConf()
 
@@ -15548,20 +14685,23 @@
   } else if ((cstartType == NodeState::ST_NODE_RESTART) ||
              (cstartType == NodeState::ST_SYSTEM_RESTART)) {
     jam();
+    
+    
+
     StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend();
     conf->startingNodeId = getOwnNodeId();
     sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal, 
 	       StartRecConf::SignalLength, JBB);
 
     if(cstartType == NodeState::ST_SYSTEM_RESTART){
-      fragptr.i = c_redo_log_complete_frags;
+      c_redo_complete_fragments.first(fragptr);
       while(fragptr.i != RNIL){
-	ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
 	signal->theData[0] = fragptr.p->tabRef;
 	signal->theData[1] = fragptr.p->fragId;
 	sendSignal(DBACC_REF, GSN_EXPANDCHECK2, signal, 2, JBB);
-	fragptr.i = fragptr.p->nextFrag;
+	c_redo_complete_fragments.next(fragptr);
       }
+      c_redo_complete_fragments.remove();
     }
   } else {
     ndbrequire(false);
@@ -15749,13 +14889,6 @@
     dataPtr[index]++;
   }//while
   index++;
-  fragptr.i = cfirstfreeFragrec;
-  while (fragptr.i != RNIL) {
-    ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-    fragptr.i = fragptr.p->nextFrag;
-    dataPtr[index]++;
-  }//while
-  index++;
   for (tabptr.i = 0;
        tabptr.i < ctabrecFileSize;
        tabptr.i++) {
@@ -15902,7 +15035,7 @@
 {
   tcConnectptr.p->logWriteState = TcConnectionrec::NOT_STARTED;
   fragptr.i = tcConnectptr.p->fragmentptr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(fragptr);
   fragptr.p->activeTcCounter = fragptr.p->activeTcCounter - 1;
   if (fragptr.p->activeTcCounter == 0) {
     jam();
@@ -15920,44 +15053,19 @@
  * ========================================================================= */
 void Dblqh::checkSrCompleted(Signal* signal) 
 {
-  LcpLocRecordPtr cscLcpLocptr;
-  
   terrorCode = ZOK;
   ptrGuard(lcpPtr);
-  cscLcpLocptr.i = lcpPtr.p->firstLcpLocAcc;
-CSC_ACC_DOWHILE:
-  ptrCheckGuard(cscLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-  if (cscLcpLocptr.p->lcpLocstate != LcpLocRecord::SR_ACC_COMPLETED) {
-    jam();
-    if (cscLcpLocptr.p->lcpLocstate != LcpLocRecord::SR_ACC_STARTED) {
-      jam();
-      systemErrorLab(signal, __LINE__);
-      return;
-    }//if
+  if(lcpPtr.p->m_acc.lcpLocstate != LcpLocRecord::SR_ACC_COMPLETED)
+  {
+    ndbrequire(lcpPtr.p->m_acc.lcpLocstate == LcpLocRecord::SR_ACC_STARTED);
     return;
-  }//if
-  cscLcpLocptr.i = cscLcpLocptr.p->nextLcpLoc;
-  if (cscLcpLocptr.i != RNIL) {
-    jam();
-    goto CSC_ACC_DOWHILE;
-  }//if
-  cscLcpLocptr.i = lcpPtr.p->firstLcpLocTup;
-CSC_TUP_DOWHILE:
-  ptrCheckGuard(cscLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
-  if (cscLcpLocptr.p->lcpLocstate != LcpLocRecord::SR_TUP_COMPLETED) {
-    jam();
-    if (cscLcpLocptr.p->lcpLocstate != LcpLocRecord::SR_TUP_STARTED) {
-      jam();
-      systemErrorLab(signal, __LINE__);
-      return;
-    }//if
+  }
+  
+  if(lcpPtr.p->m_tup.lcpLocstate != LcpLocRecord::SR_TUP_COMPLETED) 
+  {
+    ndbrequire(lcpPtr.p->m_tup.lcpLocstate == LcpLocRecord::SR_TUP_STARTED);
     return;
-  }//if
-  cscLcpLocptr.i = cscLcpLocptr.p->nextLcpLoc;
-  if (cscLcpLocptr.i != RNIL) {
-    jam();
-    goto CSC_TUP_DOWHILE;
-  }//if
+  }
   lcpPtr.p->lcpState = LcpRecord::LCP_SR_COMPLETED;
 }//Dblqh::checkSrCompleted()
 
@@ -16101,7 +15209,7 @@
 {
   Uint32 indexFound= RNIL;
   fragptr.i = RNIL;
-  for (Uint32 i = (MAX_FRAG_PER_NODE - 1); (Uint32)~i; i--) {
+  for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
     jam();
     if (tabptr.p->fragid[i] == fragId) {
       fragptr.i = tabptr.p->fragrec[i];
@@ -16111,10 +15219,11 @@
   }//for
   if (fragptr.i != RNIL) {
     jam();
-    ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+    c_fragment_pool.getPtr(fragptr);
     tabptr.p->fragid[indexFound] = ZNIL;
     tabptr.p->fragrec[indexFound] = RNIL;
-    releaseFragrec();
+    fragptr.p->fragStatus = Fragrecord::FREE;
+    c_fragment_pool.release(fragptr);
   }//if
 }//Dblqh::deleteFragrec()
 
@@ -16209,11 +15318,11 @@
 /* ---------------------------------------------------------------- */
 bool Dblqh::getFragmentrec(Signal* signal, Uint32 fragId) 
 {
-  for (Uint32 i = (MAX_FRAG_PER_NODE - 1); (UintR)~i; i--) {
+  for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
     jam();
     if (tabptr.p->fragid[i] == fragId) {
       fragptr.i = tabptr.p->fragrec[i];
-      ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+      c_fragment_pool.getPtr(fragptr);
       return true;
     }//if
   }//for
@@ -16295,24 +15404,18 @@
 /* ========================================================================= */
 void Dblqh::initialiseFragrec(Signal* signal) 
 {
-  if (cfragrecFileSize != 0) {
-    for (fragptr.i = 0; fragptr.i < cfragrecFileSize; fragptr.i++) {
-      refresh_watch_dog();
-      ptrAss(fragptr, fragrecord);
-      fragptr.p->fragStatus = Fragrecord::FREE;
-      fragptr.p->fragActiveStatus = ZFALSE;
-      fragptr.p->execSrStatus = Fragrecord::IDLE;
-      fragptr.p->srStatus = Fragrecord::SS_IDLE;
-      fragptr.p->nextFrag = fragptr.i + 1;
-    }//for
-    fragptr.i = cfragrecFileSize - 1;
-    ptrAss(fragptr, fragrecord);
-    fragptr.p->nextFrag = RNIL;
-    cfirstfreeFragrec = 0;
-  } else {
-    jam();
-    cfirstfreeFragrec = RNIL;
-  }//if
+  
+  SLList<Fragrecord> tmp(c_fragment_pool);
+  while(tmp.seize(fragptr))
+  {
+    refresh_watch_dog();
+    new (fragptr.p) Fragrecord();
+    fragptr.p->fragStatus = Fragrecord::FREE;
+    fragptr.p->fragActiveStatus = ZFALSE;
+    fragptr.p->execSrStatus = Fragrecord::IDLE;
+    fragptr.p->srStatus = Fragrecord::SS_IDLE;
+  }
+  tmp.release();
 }//Dblqh::initialiseFragrec()
 
 /* ========================================================================= */
@@ -16345,39 +15448,14 @@
       ptrAss(lcpPtr, lcpRecord);
       lcpPtr.p->lcpState = LcpRecord::LCP_IDLE;
       lcpPtr.p->lcpQueued = false;
-      lcpPtr.p->firstLcpLocAcc = RNIL;
-      lcpPtr.p->firstLcpLocTup = RNIL;
       lcpPtr.p->reportEmpty = false;
+      lcpPtr.p->firstFragmentFlag = false;
       lcpPtr.p->lastFragmentFlag = false;
     }//for
   }//if
 }//Dblqh::initialiseLcpRec()
 
 /* ========================================================================= */
-/* ======                INITIATE LCP LOCAL RECORD                   ======= */
-/*                                                                           */
-/* ========================================================================= */
-void Dblqh::initialiseLcpLocrec(Signal* signal) 
-{
-  if (clcpLocrecFileSize != 0) {
-    for (lcpLocptr.i = 0; lcpLocptr.i < clcpLocrecFileSize; lcpLocptr.i++) {
-      ptrAss(lcpLocptr, lcpLocRecord);
-      lcpLocptr.p->nextLcpLoc = lcpLocptr.i + 1;
-      lcpLocptr.p->lcpLocstate = LcpLocRecord::IDLE;
-      lcpLocptr.p->masterLcpRec = RNIL;
-      lcpLocptr.p->waitingBlock = LcpLocRecord::NONE;
-    }//for
-    lcpLocptr.i = clcpLocrecFileSize - 1;
-    ptrAss(lcpLocptr, lcpLocRecord);
-    lcpLocptr.p->nextLcpLoc = RNIL;
-    cfirstfreeLcpLoc = 0;
-  } else {
-    jam();
-    cfirstfreeLcpLoc = RNIL;
-  }//if
-}//Dblqh::initialiseLcpLocrec()
-
-/* ========================================================================= */
 /* ======         INITIATE LOG FILE OPERATION RECORD                 ======= */
 /*                                                                           */
 /* ========================================================================= */
@@ -16515,8 +15593,6 @@
     cnewestCompletedGci = (UintR)-1;
     crestartOldestGci = 0;
     crestartNewestGci = 0;
-    cfirstWaitFragSr = RNIL;
-    cfirstCompletedFragSr = RNIL;
     csrPhaseStarted = ZSR_NO_PHASE_STARTED;
     csrPhasesCompleted = 0;
     cmasterDihBlockref = 0;
@@ -16546,7 +15622,6 @@
     jam();
     initialiseGcprec(signal);
     initialiseLcpRec(signal);
-    initialiseLcpLocrec(signal);
     break;
   case 6:
     jam();
@@ -16635,7 +15710,7 @@
       ptrAss(tabptr, tablerec);
       tabptr.p->tableStatus = Tablerec::NOT_DEFINED;
       tabptr.p->usageCount = 0;
-      for (Uint32 i = 0; i <= (MAX_FRAG_PER_NODE - 1); i++) {
+      for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
         tabptr.p->fragid[i] = ZNIL;
         tabptr.p->fragrec[i] = RNIL;
       }//for
@@ -16704,15 +15779,12 @@
   new (fragptr.p) Fragrecord();
   fragptr.p->m_scanNumberMask.set(); // All is free
   fragptr.p->accBlockref = caccBlockref;
-  fragptr.p->accBlockedList = RNIL;
-  fragptr.p->activeList = RNIL;
   fragptr.p->firstWaitQueue = RNIL;
   fragptr.p->lastWaitQueue = RNIL;
   fragptr.p->fragStatus = Fragrecord::DEFINED;
   fragptr.p->fragCopy = copyType;
   fragptr.p->tupBlockref = ctupBlockref;
   fragptr.p->tuxBlockref = ctuxBlockref;
-  fragptr.p->lcpRef = RNIL;
   fragptr.p->logFlag = Fragrecord::STATE_TRUE;
   fragptr.p->lcpFlag = Fragrecord::LCP_STATE_TRUE;
   for (Uint32 i = 0; i < MAX_LCP_STORED; i++) {
@@ -16721,7 +15793,6 @@
   fragptr.p->maxGciCompletedInLcp = 0;
   fragptr.p->maxGciInLcp = 0;
   fragptr.p->copyFragState = ZIDLE;
-  fragptr.p->nextFrag = RNIL;
   fragptr.p->newestGci = cnewestGci;
   fragptr.p->nextLcp = 0;
   fragptr.p->tabRef = tableId;
@@ -16739,45 +15810,6 @@
  *
  *       SUBROUTINE SHORT NAME = IFS
  * ========================================================================= */
-void Dblqh::initFragrecSr(Signal* signal) 
-{
-  const StartFragReq * const startFragReq = (StartFragReq *)&signal->theData[0];
-  Uint32 lcpNo = startFragReq->lcpNo;
-  Uint32 noOfLogNodes = startFragReq->noOfLogNodes;
-  ndbrequire(noOfLogNodes <= 4);
-  fragptr.p->fragStatus = Fragrecord::CRASH_RECOVERING;
-  fragptr.p->srBlockref = startFragReq->userRef;
-  fragptr.p->srUserptr = startFragReq->userPtr;
-  fragptr.p->srChkpnr = lcpNo;
-  if (lcpNo == (MAX_LCP_STORED - 1)) {
-    jam();
-    fragptr.p->lcpId[lcpNo] = startFragReq->lcpId;
-    fragptr.p->nextLcp = 0;
-  } else if (lcpNo < (MAX_LCP_STORED - 1)) {
-    jam();
-    fragptr.p->lcpId[lcpNo] = startFragReq->lcpId;
-    fragptr.p->nextLcp = lcpNo + 1;
-  } else {
-    ndbrequire(lcpNo == ZNIL);
-    jam();
-    fragptr.p->nextLcp = 0;
-  }//if
-  fragptr.p->srNoLognodes = noOfLogNodes;
-  fragptr.p->logFlag = Fragrecord::STATE_FALSE;
-  fragptr.p->srStatus = Fragrecord::SS_IDLE;
-  if (noOfLogNodes > 0) {
-    jam();
-    for (Uint32 i = 0; i < noOfLogNodes; i++) {
-      jam();
-      fragptr.p->srStartGci[i] = startFragReq->startGci[i];
-      fragptr.p->srLastGci[i] = startFragReq->lastGci[i];
-      fragptr.p->srLqhLognode[i] = startFragReq->lqhLogNode[i];
-    }//for
-    fragptr.p->newestGci = startFragReq->lastGci[noOfLogNodes - 1];
-  } else {
-    fragptr.p->newestGci = cnewestGci;
-  }//if
-}//Dblqh::initFragrecSr()
 
 /* ========================================================================== 
  * =======       INITIATE INFORMATION ABOUT GLOBAL CHECKPOINTS        ======= 
@@ -16847,9 +15879,6 @@
   lcpPtr.p->currentFragment.lcpFragOrd.tableId = tableId;
   lcpPtr.p->currentFragment.lcpFragOrd.fragmentId = fragId;
   lcpPtr.p->lcpState = LcpRecord::LCP_SR_WAIT_FRAGID;
-  lcpPtr.p->firstLcpLocAcc = RNIL;
-  lcpPtr.p->firstLcpLocTup = RNIL;
-  lcpPtr.p->lcpAccptr = RNIL;
 }//Dblqh::initLcpSr()
 
 /* ========================================================================== 
@@ -16951,13 +15980,12 @@
 bool Dblqh::insertFragrec(Signal* signal, Uint32 fragId) 
 {
   terrorCode = ZOK;
-  if (cfirstfreeFragrec == RNIL) {
-    jam();
+  if(c_fragment_pool.seize(fragptr) == false)
+  {
     terrorCode = ZNO_FREE_FRAGMENTREC;
     return false;
-  }//if
-  seizeFragmentrec(signal);
-  for (Uint32 i = (MAX_FRAG_PER_NODE - 1); (Uint32)~i; i--) {
+  }
+  for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
     jam();
     if (tabptr.p->fragid[i] == ZNIL) {
       jam();
@@ -16966,6 +15994,7 @@
       return true;
     }//if
   }//for
+  c_fragment_pool.release(fragptr);
   terrorCode = ZTOO_MANY_FRAGMENTS;
   return false;
 }//Dblqh::insertFragrec()
@@ -17500,44 +16529,6 @@
   sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
 }//Dblqh::readSinglePage()
 
-/* --------------------------------------------------------------------------
- * -------         RELEASE OPERATION FROM ACTIVE LIST ON FRAGMENT     ------- 
- * 
- *       SUBROUTINE SHORT NAME = RAC
- * ------------------------------------------------------------------------- */
-void Dblqh::releaseAccList(Signal* signal) 
-{
-  TcConnectionrecPtr racTcNextConnectptr;
-  TcConnectionrecPtr racTcPrevConnectptr;
-
-  fragptr.i = tcConnectptr.p->fragmentptr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-  racTcPrevConnectptr.i = tcConnectptr.p->prevTc;
-  racTcNextConnectptr.i = tcConnectptr.p->nextTc;
-  if (tcConnectptr.p->listState != TcConnectionrec::ACC_BLOCK_LIST) {
-    jam();
-    systemError(signal, __LINE__);
-  }//if
-  tcConnectptr.p->listState = TcConnectionrec::NOT_IN_LIST;
-  if (racTcNextConnectptr.i != RNIL) {
-    jam();
-    ptrCheckGuard(racTcNextConnectptr, ctcConnectrecFileSize, tcConnectionrec);
-    racTcNextConnectptr.p->prevTc = racTcPrevConnectptr.i;
-  }//if
-  if (racTcPrevConnectptr.i != RNIL) {
-    jam();
-    ptrCheckGuard(racTcPrevConnectptr, ctcConnectrecFileSize, tcConnectionrec);
-    racTcPrevConnectptr.p->nextTc = tcConnectptr.p->nextTc;
-  } else {
-    jam();
-    /* ---------------------------------------------------------------------
-     *    OPERATION RECORD IS FIRST IN ACTIVE LIST
-     *    THIS MEANS THAT THERE EXISTS NO PREVIOUS TC THAT NEEDS TO BE UPDATED.
-     * --------------------------------------------------------------------- */
-    fragptr.p->accBlockedList = racTcNextConnectptr.i;
-  }//if
-}//Dblqh::releaseAccList()
-
 /* -------------------------------------------------------------------------- 
  * -------       REMOVE COPY FRAGMENT FROM ACTIVE COPY LIST           ------- 
  *
@@ -17570,37 +16561,6 @@
   cnoActiveCopy--;
 }//Dblqh::releaseActiveCopy()
 
-/* --------------------------------------------------------------------------
- * -------        RELEASE OPERATION FROM ACTIVE LIST ON FRAGMENT      ------- 
- * 
- *       SUBROUTINE SHORT NAME = RAL
- * ------------------------------------------------------------------------- */
-void Dblqh::releaseActiveList(Signal* signal) 
-{
-  TcConnectionrecPtr ralTcNextConnectptr;
-  TcConnectionrecPtr ralTcPrevConnectptr;
-  ralTcPrevConnectptr.i = tcConnectptr.p->prevTc;
-  ralTcNextConnectptr.i = tcConnectptr.p->nextTc;
-  ndbrequire(tcConnectptr.p->listState == TcConnectionrec::IN_ACTIVE_LIST);
-  tcConnectptr.p->listState = TcConnectionrec::NOT_IN_LIST;
-  if (ralTcNextConnectptr.i != RNIL) {
-    jam();
-    ptrCheckGuard(ralTcNextConnectptr, ctcConnectrecFileSize, tcConnectionrec);
-    ralTcNextConnectptr.p->prevTc = ralTcPrevConnectptr.i;
-  }//if
-  if (ralTcPrevConnectptr.i != RNIL) {
-    jam();
-    ptrCheckGuard(ralTcPrevConnectptr, ctcConnectrecFileSize, tcConnectionrec);
-    ralTcPrevConnectptr.p->nextTc = tcConnectptr.p->nextTc;
-  } else {
-    jam();
-    /* ----------------------------------------------------------------------
-     *   OPERATION RECORD IS FIRST IN ACTIVE LIST
-     *   THIS MEANS THAT THERE EXISTS NO PREVIOUS TC THAT NEEDS TO BE UPDATED.
-     * --------------------------------------------------------------------- */
-    fragptr.p->activeList = ralTcNextConnectptr.i;
-  }//if
-}//Dblqh::releaseActiveList()
 
 /* --------------------------------------------------------------------------
  * -------       RELEASE ADD FRAGMENT RECORD                          ------- 
@@ -17614,28 +16574,6 @@
 }//Dblqh::releaseAddfragrec()
 
 /* --------------------------------------------------------------------------
- * -------       RELEASE FRAGMENT RECORD                              -------
- *
- * ------------------------------------------------------------------------- */
-void Dblqh::releaseFragrec() 
-{
-  fragptr.p->fragStatus = Fragrecord::FREE;
-  fragptr.p->nextFrag = cfirstfreeFragrec;
-  cfirstfreeFragrec = fragptr.i;
-}//Dblqh::releaseFragrec()
-
-/* --------------------------------------------------------------------------
- * -------       RELEASE LCP LOCAL RECORD                             ------- 
- * 
- * ------------------------------------------------------------------------- */
-void Dblqh::releaseLcpLoc(Signal* signal) 
-{
-  lcpLocptr.p->lcpLocstate = LcpLocRecord::IDLE;
-  lcpLocptr.p->nextLcpLoc = cfirstfreeLcpLoc;
-  cfirstfreeLcpLoc = lcpLocptr.i;
-}//Dblqh::releaseLcpLoc()
-
-/* --------------------------------------------------------------------------
  * -------     RELEASE A PAGE REFERENCE RECORD.                       ------- 
  *
  * ------------------------------------------------------------------------- */
@@ -17690,7 +16628,7 @@
   TcConnectionrecPtr rwaTcPrevConnectptr;
 
   fragptr.i = tcConnectptr.p->fragmentptr;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+  c_fragment_pool.getPtr(fragptr);
   rwaTcPrevConnectptr.i = tcConnectptr.p->prevTc;
   rwaTcNextConnectptr.i = tcConnectptr.p->nextTc;
   if (tcConnectptr.p->listState != TcConnectionrec::WAIT_QUEUE_LIST) {
@@ -17844,14 +16782,6 @@
  * -------       SEIZE FRAGMENT RECORD                                ------- 
  *
  * ------------------------------------------------------------------------- */
-void Dblqh::seizeFragmentrec(Signal* signal) 
-{
-  fragptr.i = cfirstfreeFragrec;
-  ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
-  cfirstfreeFragrec = fragptr.p->nextFrag;
-  fragptr.p->nextFrag = RNIL;
-}//Dblqh::seizeFragmentrec()
-
 /* ------------------------------------------------------------------------- */
 /* -------     SEIZE A PAGE REFERENCE RECORD.                        ------- */
 /*                                                                           */
@@ -17934,9 +16864,9 @@
 void Dblqh::startExecSr(Signal* signal) 
 {
   cnoFragmentsExecSr = 0;
-  signal->theData[0] = cfirstCompletedFragSr;
-  signal->theData[1] = RNIL;
-  sendSignal(cownref, GSN_START_EXEC_SR, signal, 2, JBB);
+  c_lcp_complete_fragments.first(fragptr);
+  signal->theData[0] = fragptr.i;
+  sendSignal(cownref, GSN_START_EXEC_SR, signal, 1, JBB);
 }//Dblqh::startExecSr()
 
 /* ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ 
@@ -18295,7 +17225,9 @@
 void
 Dblqh::execDUMP_STATE_ORD(Signal* signal)
 {
+  jamEntry();
   DumpStateOrd * const dumpState = (DumpStateOrd *)&signal->theData[0];
+  Uint32 arg= dumpState->args[0];
   if(dumpState->args[0] == DumpStateOrd::CommitAckMarkersSize){
     infoEvent("LQH: m_commitAckMarkerPool: %d free size: %d",
 	      m_commitAckMarkerPool.getNoOfFree(),
@@ -18449,12 +17381,9 @@
     // Print information about the current local checkpoint
     TlcpPtr.i = 0;
     ptrAss(TlcpPtr, lcpRecord);
-    infoEvent(" lcpState=%d firstLcpLocTup=%d firstLcpLocAcc=%d",
-	      TlcpPtr.p->lcpState,
-	      TlcpPtr.p->firstLcpLocTup,
-	      TlcpPtr.p->firstLcpLocAcc);
+    infoEvent(" lcpState=%d", TlcpPtr.p->lcpState);
     infoEvent(" lcpAccptr=%d lastFragmentFlag=%d",
-	      TlcpPtr.p->lcpAccptr,
+	      TlcpPtr.p->m_acc.lcpRef,
 	      TlcpPtr.p->lastFragmentFlag);
     infoEvent("currentFragment.fragPtrI=%d",
 	        TlcpPtr.p->currentFragment.fragPtrI);
@@ -18470,7 +17399,187 @@
     return;
   }
 
-  Uint32 arg= dumpState->args[0];
+  TcConnectionrec *regTcConnectionrec = tcConnectionrec;
+  Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
+  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
+	       << " scanLocalFragid="<<TscanPtr.p->scanLocalFragid
+	       << 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);
+  }
+  
+#ifdef ERROR_INSERT
+#ifdef NDB_DEBUG_FULL
+  if(dumpState->args[0] == DumpStateOrd::LCPContinue){
+    switch(cerrorInsert){
+    case 5904:
+      CLEAR_ERROR_INSERT_VALUE;
+      g_trace_lcp.restore(*globalData.getBlock(BACKUP), signal);
+      return;
+    default:
+      return;
+    }
+  }
+#endif
+#endif
+
   if(arg == 2304 || arg == 2305)
   {
     jam();
@@ -18642,6 +17751,57 @@
 #endif
     return checkSum;  
   }
+
+#ifdef NDB_DEBUG_FULL
+#ifdef ERROR_INSERT
+void
+TraceLCP::sendSignal(Uint32 ref, Uint32 gsn, Signal* signal,
+		     Uint32 len, Uint32 prio)
+{
+  Sig s;
+  s.type = Sig::Sig_send;
+  s.header = signal->header;
+  s.header.theVerId_signalNumber = gsn;
+  s.header.theReceiversBlockNumber = ref;
+  s.header.theLength = len;
+  memcpy(s.theData, signal->theData, 4 * len);
+  m_signals.push_back(s);
+  assert(signal->getNoOfSections() == 0);
+}
+
+void
+TraceLCP::save(Signal* signal){
+  Sig s;
+  s.type = Sig::Sig_save;
+  s.header = signal->header;
+  memcpy(s.theData, signal->theData, 4 * signal->getLength());
+  m_signals.push_back(s);
+  assert(signal->getNoOfSections() == 0);
+}
+
+void
+TraceLCP::restore(SimulatedBlock& lqh, Signal* sig){
+  Uint32 cnt = m_signals.size();
+  for(Uint32 i = 0; i<cnt; i++){
+    sig->header = m_signals[i].header;
+    memcpy(sig->theData, m_signals[i].theData, 4 * sig->getLength());
+    switch(m_signals[i].type){
+    case Sig::Sig_send:
+      lqh.sendSignal(sig->header.theReceiversBlockNumber,
+		     sig->header.theVerId_signalNumber,
+		     sig,
+		     sig->header.theLength,
+		     JBB);
+      break;
+    case Sig::Sig_save:
+      lqh.executeFunction(sig->header.theVerId_signalNumber, sig);
+      break;
+    }
+  }
+  m_signals.clear();
+}
+#endif
+#endif
 
 void Dblqh::writeDbgInfoPageHeader(LogPageRecordPtr logP, Uint32 place,
                                    Uint32 pageNo, Uint32 wordWritten)

--- 1.73.13.1/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2005-12-13 11:51:01 +01:00
+++ 1.95/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2005-12-13 12:05:23 +01:00
@@ -340,7 +340,7 @@
   tabptr.p->noOfKeyAttr = desc->noOfKeyAttr;
   tabptr.p->hasCharAttr = desc->hasCharAttr;
   tabptr.p->noOfDistrKeys = desc->noOfDistrKeys;
-  
+  tabptr.p->hasVarKeys = desc->noOfVarKeys > 0;
   signal->theData[0] = tabptr.i;
   signal->theData[1] = retPtr;
   sendSignal(retRef, GSN_TC_SCHVERCONF, signal, 2, JBB);
@@ -2302,14 +2302,15 @@
 {
   Uint64 Tmp[MAX_KEY_SIZE_IN_WORDS * MAX_XFRM_MULTIPLY];
   const TableRecord* tabPtrP = &tableRecord[tabPtrI];
+  const bool hasVarKeys = tabPtrP->hasVarKeys;
   const bool hasCharAttr = tabPtrP->hasCharAttr;
-  const bool hasDistKeys = tabPtrP->noOfDistrKeys > 0;
+  const bool compute_distkey = distr && (tabPtrP->noOfDistrKeys > 0);
   
   Uint32 *dst = (Uint32*)Tmp;
   Uint32 dstPos = 0;
   Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX];
   Uint32 * keyPartLenPtr;
-  if(hasCharAttr)
+  if(hasCharAttr || (compute_distkey && hasVarKeys))
   {
     keyPartLenPtr = keyPartLen;
     dstPos = xfrm_key(tabPtrI, src, dst, sizeof(Tmp) >> 2, keyPartLenPtr);
@@ -2324,7 +2325,7 @@
   
   md5_hash(dstHash, (Uint64*)dst, dstPos);
   
-  if(distr && hasDistKeys)
+  if(compute_distkey)
   {
     jam();
     
@@ -2728,12 +2729,14 @@
   Uint8 TDirtyFlag          = tcKeyReq->getDirtyFlag(Treqinfo);
   Uint8 TInterpretedFlag    = tcKeyReq->getInterpretedFlag(Treqinfo);
   Uint8 TDistrKeyFlag       = tcKeyReq->getDistributionKeyFlag(Treqinfo);
+  Uint8 TNoDiskFlag         = TcKeyReq::getNoDiskFlag(Treqinfo);
   Uint8 TexecuteFlag        = TexecFlag;
   
   regCachePtr->opSimple = TSimpleFlag;
   regCachePtr->opExec   = TInterpretedFlag;
   regTcPtr->dirtyOp  = TDirtyFlag;
   regCachePtr->distributionKeyIndicator = TDistrKeyFlag;
+  regCachePtr->m_no_disk_flag = TNoDiskFlag;
 
   //-------------------------------------------------------------
   // The next step is to read the upto three conditional words.
@@ -3198,6 +3201,8 @@
   LqhKeyReq::setInterpretedFlag(Tdata10, regCachePtr->opExec);
   LqhKeyReq::setSimpleFlag(Tdata10, regCachePtr->opSimple);
   LqhKeyReq::setOperation(Tdata10, regTcPtr->operation);
+  LqhKeyReq::setNoDiskFlag(Tdata10, regCachePtr->m_no_disk_flag);
+
   /* ----------------------------------------------------------------------- 
    * Sequential Number of first LQH = 0, bit 22-23                           
    * IF ATTRIBUTE INFORMATION IS SENT IN TCKEYREQ,
@@ -3910,7 +3915,7 @@
   const UintR TopWords = (UintR)regApiPtr->tckeyrec;
   localHostptr.i = refToNode(regApiPtr->ndbapiBlockref);
   const Uint32 type = getNodeInfo(localHostptr.i).m_type;
-  const bool is_api = (type >= NodeInfo::API && type <= NodeInfo::REP);
+  const bool is_api = (type >= NodeInfo::API && type <= NodeInfo::MGM);
   const BlockNumber TblockNum = refToBlock(regApiPtr->ndbapiBlockref);
   const Uint32 Tmarker = (regApiPtr->commitAckMarker == RNIL) ? 0 : 1;
   ptrAss(localHostptr, hostRecord);
@@ -4592,7 +4597,8 @@
     commitConf->transId1 = regApiPtr->transid[0];
     commitConf->transId2 = regApiPtr->transid[1];
     commitConf->gci = regApiPtr->globalcheckpointid;
-    sendSignal(regApiPtr->ndbapiBlockref, GSN_TC_COMMITCONF, signal, 
+
+    sendSignal(regApiPtr->ndbapiBlockref, GSN_TC_COMMITCONF, signal,
 	       TcCommitConf::SignalLength, JBB);
   } else if (regApiPtr->returnsignal == RS_NO_RETURN) {
     jam();
@@ -5130,6 +5136,19 @@
 	return;
       }
       
+      /* Only ref in certain situations */
+      {
+	const Uint32 opType = regTcPtr->operation;
+	if (   (opType == ZDELETE && errCode != ZNOT_FOUND)
+	    || (opType == ZINSERT && errCode != ZALREADYEXIST)
+	    || (opType == ZUPDATE && errCode != ZNOT_FOUND)
+	    || (opType == ZWRITE  && errCode != 839 && errCode != 840))
+	{
+	  TCKEY_abort(signal, 49);
+	  return;
+	}
+      }
+
       /* *************** */
       /*    TCKEYREF   < */
       /* *************** */
@@ -8748,6 +8767,7 @@
   ScanFragReq::setDescendingFlag(tmp, ScanTabReq::getDescendingFlag(ri));
   ScanFragReq::setTupScanFlag(tmp, ScanTabReq::getTupScanFlag(ri));
   ScanFragReq::setAttrLen(tmp, scanTabReq->attrLenKeyLen & 0xFFFF);
+  ScanFragReq::setNoDiskFlag(tmp, ScanTabReq::getNoDiskFlag(ri));
   
   scanptr.p->scanRequestInfo = tmp;
   scanptr.p->scanStoredProcId = scanTabReq->storedProcId;
@@ -10105,6 +10125,7 @@
     tabptr.p->noOfKeyAttr = 0;
     tabptr.p->hasCharAttr = 0;
     tabptr.p->noOfDistrKeys = 0;
+    tabptr.p->hasVarKeys = 0;
   }//for
 }//Dbtc::initTable()
 
@@ -11139,7 +11160,6 @@
   ApiConnectRecordPtr transPtr;
   TcConnectRecord *localTcConnectRecord = tcConnectRecord;
   TcConnectRecordPtr opPtr;
-
   /**
    * TODO
    * Check transid,
@@ -11153,6 +11173,7 @@
     
     c_firedTriggerHash.remove(trigPtr);
 
+    trigPtr.p->fragId= fireOrd->fragId;
     bool ok = trigPtr.p->keyValues.getSize() == fireOrd->m_noPrimKeyWords;
     ok &= trigPtr.p->afterValues.getSize() == fireOrd->m_noAfterValueWords;
     ok &= trigPtr.p->beforeValues.getSize() == fireOrd->m_noBeforeValueWords;
@@ -11364,7 +11385,7 @@
   const UintR TopWords = (UintR)regApiPtr->tcindxrec;
   localHostptr.i = refToNode(regApiPtr->ndbapiBlockref);
   const Uint32 type = getNodeInfo(localHostptr.i).m_type;
-  const bool is_api = (type >= NodeInfo::API && type <= NodeInfo::REP);
+  const bool is_api = (type >= NodeInfo::API && type <= NodeInfo::MGM);
   const BlockNumber TblockNum = refToBlock(regApiPtr->ndbapiBlockref);
   const Uint32 Tmarker = (regApiPtr->commitAckMarker == RNIL ? 0 : 1);
   ptrAss(localHostptr, hostRecord);
@@ -12052,7 +12073,11 @@
   Uint32 dataPos = 0;
   TcKeyReq * const tcIndxReq = &indexOp->tcIndxReq;
   TcKeyReq * const tcKeyReq = (TcKeyReq *)signal->getDataPtrSend();
-  Uint32 * dataPtr = &tcKeyReq->scanInfo;
+  /*
+    Data points to distrGroupHashValue since scanInfo is used to send
+    fragment id of receiving fragment
+  */
+  Uint32 * dataPtr = &tcKeyReq->distrGroupHashValue;
   Uint32 tcKeyLength = TcKeyReq::StaticLength;
   Uint32 tcKeyRequestInfo = tcIndxReq->requestInfo;
   TcIndexData* indexData;
@@ -12091,11 +12116,16 @@
   regApiPtr->executingIndexOp = indexOp->indexOpId;;
   regApiPtr->noIndexOp++; // Increase count
 
-  // Filter out AttributeHeader:s since this should not be in key
+  /*
+    Filter out AttributeHeader:s since this should not be in key.
+    Also filter out fragment id from primary key and handle that
+    separately by setting it as Distribution Key and set indicator.
+  */
+
   AttributeHeader* attrHeader = (AttributeHeader *) aiIter.data;
     
   Uint32 headerSize = attrHeader->getHeaderSize();
-  Uint32 keySize = attrHeader->getDataSize();
+  Uint32 keySize = attrHeader->getDataSize() - 1;
   TcKeyReq::setKeyLength(tcKeyRequestInfo, keySize);
   // Skip header
   if (headerSize == 1) {
@@ -12105,6 +12135,9 @@
     jam();
     moreKeyData = indexOp->transIdAI.next(aiIter, headerSize - 1);
   }//if
+  tcKeyReq->scanInfo = *aiIter.data; //Fragment Id
+  moreKeyData = indexOp->transIdAI.next(aiIter);
+  TcKeyReq::setDistributionKeyFlag(tcKeyRequestInfo, 1U);
   while(// If we have not read complete key
 	(keySize != 0) &&
 	(dataPos < keyBufSize)) {
@@ -12460,7 +12493,7 @@
   AttributeBuffer::DataBufferIterator iter;
   Uint32 attrId = 0;
   Uint32 keyLength = 0;
-  Uint32 totalPrimaryKeyLength = 0;
+  Uint32 totalPrimaryKeyLength = 1; // fragment length
   Uint32 hops;
 
   indexTabPtr.i = indexData->indexId;
@@ -12513,11 +12546,12 @@
     hops = attrHeader->getHeaderSize() + attrHeader->getDataSize();
     moreAttrData = keyValues.next(iter, hops);
   }
-  AttributeHeader pkAttrHeader(attrId, totalPrimaryKeyLength);
+  AttributeHeader pkAttrHeader(attrId, totalPrimaryKeyLength << 2);
+  Uint32 attributesLength = afterValues.getSize() + 
+    pkAttrHeader.getHeaderSize() + pkAttrHeader.getDataSize();
   
   TcKeyReq::setKeyLength(tcKeyRequestInfo, keyLength);
-  tcKeyReq->attrLen = afterValues.getSize() + 
-    pkAttrHeader.getHeaderSize() + pkAttrHeader.getDataSize();
+  tcKeyReq->attrLen = attributesLength;
   tcKeyReq->tableId = indexData->indexId;
   TcKeyReq::setOperationType(tcKeyRequestInfo, ZINSERT);
   TcKeyReq::setExecutingTrigger(tcKeyRequestInfo, true);
@@ -12567,8 +12601,11 @@
   }
 
   tcKeyLength += dataPos;
-  Uint32 attributesLength = afterValues.getSize() + 
-    pkAttrHeader.getHeaderSize() + pkAttrHeader.getDataSize();
+  /*
+    Size of attrinfo is unique index attributes one by one, header for each
+    of them (all contained in the afterValues data structure), plus a header,
+    the primary key (compacted) and the fragment id before the primary key
+  */
   if (attributesLength <= attrBufSize) {
     jam();
     // ATTRINFO fits in TCKEYREQ
@@ -12585,6 +12622,10 @@
     // as one attribute
     pkAttrHeader.insertHeader(dataPtr);
     dataPtr += pkAttrHeader.getHeaderSize();
+    /*
+      Insert fragment id before primary key as part of reference to tuple
+    */
+    *dataPtr++ = firedTriggerData->fragId;
     moreAttrData = keyValues.first(iter);
     while(moreAttrData) {
       jam();
@@ -12749,6 +12790,29 @@
     pkAttrHeader.insertHeader(dataPtr);
     dataPtr += pkAttrHeader.getHeaderSize();
     attrInfoPos += pkAttrHeader.getHeaderSize();
+    /*
+      Add fragment id before primary key
+      TODO: This code really needs to be made into a long signal
+      to remove this messy code.
+    */
+    if (attrInfoPos == AttrInfo::DataLength)
+    {
+      jam();
+      // Flush ATTRINFO
+#if INTERNAL_TRIGGER_TCKEYREQ_JBA
+      sendSignal(reference(), GSN_ATTRINFO, signal, 
+                 AttrInfo::HeaderLength + AttrInfo::DataLength, JBA);
+#else
+      EXECUTE_DIRECT(DBTC, GSN_ATTRINFO, signal,
+                     AttrInfo::HeaderLength + AttrInfo::DataLength);
+      jamEntry();
+#endif
+      dataPtr = (Uint32 *) &attrInfo->attrData;	  
+      attrInfoPos = 0;
+    }
+    attrInfoPos++;
+    *dataPtr++ = firedTriggerData->fragId;
+
     moreAttrData = keyValues.first(iter);
     while(moreAttrData) {
       jam();
Thread
bk commit into 5.1 tree (jonas:1.1960)jonas13 Dec