List:Commits« Previous MessageNext Message »
From:jonas Date:June 1 2006 6:35am
Subject:bk commit into 5.1 tree (jonas:1.2377)
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.2377 06/06/01 08:34:57 jonas@stripped +5 -0
  Merge perch.ndb.mysql.com:/home/jonas/src/41-work
  into  perch.ndb.mysql.com:/home/jonas/src/51-work

  storage/ndb/test/run-test/daily-basic-tests.txt
    1.46 06/06/01 08:34:55 jonas@stripped +1 -1
    merge

  storage/ndb/test/ndbapi/testNodeRestart.cpp
    1.26 06/06/01 08:33:46 jonas@stripped +0 -0
    Auto merged

  storage/ndb/test/run-test/daily-basic-tests.txt
    1.13.2.13 06/06/01 08:33:46 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.8.1.15 06/06/01 08:33:46 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.114 06/06/01 08:33:46 jonas@stripped +0 -0
    Auto merged

  storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
    1.62 06/06/01 08:33:46 jonas@stripped +0 -0
    Auto merged

  storage/ndb/src/kernel/blocks/ERROR_codes.txt
    1.19 06/06/01 08:33:46 jonas@stripped +0 -0
    Auto merged

  storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
    1.42.1.25 06/06/01 08:33:45 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/dbdih/DbdihMain.cpp
    1.14.1.24 06/06/01 08:33:45 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.8.1.10 06/06/01 08:33:45 jonas@stripped +0 -0
    Merge rename: ndb/src/kernel/blocks/ERROR_codes.txt -> storage/ndb/src/kernel/blocks/ERROR_codes.txt

# 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/51-work/RESYNC

--- 1.13.2.12/ndb/test/run-test/daily-basic-tests.txt	2006-06-01 08:24:03 +02:00
+++ 1.46/storage/ndb/test/run-test/daily-basic-tests.txt	2006-06-01 08:34:55 +02:00
@@ -75,29 +75,29 @@ max-time: 500
 cmd: testBasic
 args: -n PkInsert 
 
-max-time: 600
+max-time: 660
 cmd: testBasic
 args: -n UpdateAndRead 
 
 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 @@ args: -n Fill T6 
 
 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
@@ -199,46 +199,37 @@ max-time: 500
 cmd: testBasicAsynch
 args: -n PkDeleteAsynch 
 
-max-time: 500
+max-time: 1000
 cmd: testBasic
-args: -n MassiveRollback T1 T6 T13 
+args: -n MassiveRollback T1 T7 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n MassiveRollback2 T1 T6 T13 
-
-#-m 500 1: testBasic -n ReadConsistency T6
-max-time: 500
-cmd: testTimeout
-args: -n DontTimeoutTransaction T1 
+args: -n MassiveRollback2 T1 T7 D1 D2
 
 max-time: 500
-cmd: testTimeout 
-args: -n DontTimeoutTransaction5 T1 
+cmd: testBasic
+args: -n MassiveRollback3 T1 T7 D1 D2
 
 max-time: 500
-cmd: testTimeout
-args: -n TimeoutTransaction T1 
+cmd: testBasic
+args: -n MassiveRollback4 T1 T7 D1 D2
 
 max-time: 500
-cmd: testTimeout 
-args: -n TimeoutTransaction5 T1 
+cmd: testBasic
+args: -n TupError
 
 max-time: 500
-cmd: testTimeout
-args: -n BuddyTransNoTimeout T1 
+cmd: testBasic
+args: -n InsertError T1
 
 max-time: 500
-cmd: testTimeout
-args: -n BuddyTransNoTimeout5 T1 
+cmd: testBasic
+args: -n InsertError2 T1
 
 max-time: 500
 cmd: testTimeout
-args: -n TimeoutRandTransaction T1
-
-max-time: 600
-cmd: testTimeout
-args: -n Error4012 T1
+args: T1 
 
 # SCAN TESTS
 #
@@ -260,7 +251,7 @@ args: -n ScanUpdate 
 
 max-time: 500
 cmd: testScan
-args: -n ScanUpdate2 T6 
+args: -n ScanUpdate2 T6 D1 D2
 
 max-time: 500
 cmd: testScan
@@ -268,47 +259,51 @@ args: -n ScanDelete 
 
 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 ScanRead488T -l 10 T6 D1 D2 
+
+max-time: 1000
+cmd: testScan
+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
@@ -320,123 +315,143 @@ args: -n ScanRead40RandomTable -l 1000 T
 
 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
 
 max-time: 3600
 cmd: testScan
-args: -n ScanReadRestart T1 T6 T13 
+args: -n ScanReadRestart D1 D2
+
+max-time: 1200
+cmd: testScan
+args: -n ScanUpdateRestart T6
+
+max-time: 1200
+cmd: testScan
+args: -n ScanUpdateRestart D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanUpdateRestart T6 
+args: -n CheckGetValue T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n CheckGetValue T6 
+args: -n CloseWithoutStop T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n CloseWithoutStop T6 
+args: -n NextScanWhenNoMore T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n NextScanWhenNoMore T6 
+args: -n ExecuteScanWithoutOpenScan T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ExecuteScanWithoutOpenScan T6 
+args: -n OnlyOpenScanOnce T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n OnlyOpenScanOnce T6 
+args: -n OnlyOneOpInScanTrans T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n OnlyOneOpInScanTrans T6 
+args: -n OnlyOneOpBeforeOpenScan T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n OnlyOneOpBeforeOpenScan T6 
+args: -n OnlyOneScanPerTrans T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n OnlyOneScanPerTrans T6 
+args: -n NoCloseTransaction T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n NoCloseTransaction T6 
+args: -n CheckInactivityTimeOut T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n CheckInactivityTimeOut T6 
+args: -n CheckInactivityBeforeClose T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n CheckInactivityBeforeClose T6 
+args: -n CheckAfterTerror T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n CheckAfterTerror T6 
+args: -n ScanReadError5021 T1 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanReadError5021 T1 
+args: -n ScanReaderror5022 T1 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanReaderror5022 T1 
+args: -n ScanReadError5023 T1 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanReadError5023 T1 
+args: -n ScanReadError5024 T1 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanReadError5024 T1 
+args: -n ScanReadError5025 T1 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanReadError5025 T1 
+args: -n ScanReadError5030 T1 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanReadError5030 T1 
+args: -n InsertDelete T1 T6 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n InsertDelete T1 T6
+args: -n CheckAfterTerror T1 D1 D2 
+
+max-time: 1200
+cmd: testScan
+args: -n ScanReadWhileNodeIsDown T1
+
+max-time: 1200
+cmd: testScan
+args: -n ScanReadWhileNodeIsDown D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n CheckAfterTerror T1
+args: -n ScanRestart T1 D1 D2 
 
 max-time: 500
 cmd: testScan
-args: -n ScanReadWhileNodeIsDown T1
+args: -l 100 -n Scan-bug8262 T7 D1 D2
 
 max-time: 500
 cmd: testScan
-args: -n ScanRestart T1
+args: -n ScanParallelism
 
 max-time: 500
 cmd: testScan
-args: -l 100 -n Scan-bug8262 T7
+args: -n ScanVariants
 
 max-time: 500
 cmd: testNodeRestart
@@ -474,15 +489,6 @@ max-time: 1000
 cmd: testNodeRestart
 args: -n Bug20185 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
@@ -495,7 +501,7 @@ args: -n CreateAndDropWithData 
 
 max-time: 1500
 cmd: testDict
-args: -n CreateAndDropDuring T6 T10 
+args: -n CreateAndDropDuring T6 T10 D1 D2
 
 max-time: 1500
 cmd: testDict
@@ -515,7 +521,7 @@ args: -n FragmentTypeSingle T1 
 
 max-time: 1500
 cmd: testDict
-args: -n FragmentTypeAll T1 T6 T7 T8 
+args: -n FragmentTypeAllSmall T1 T6 T7 T8 
 
 max-time: 1500
 cmd: testDict
@@ -580,19 +586,27 @@ args: -n GetValueInUpdate T6 
 
 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 Bug_WritePartialIgnoreError T1 
 
 #max-time: 500
 #cmd: testInterpreter
@@ -602,7 +616,7 @@ max-time: 150000
 cmd: testOperations
 args:
 
-max-time: 150000
+max-time: 15000
 cmd: testTransactions
 args:
 
@@ -610,14 +624,22 @@ max-time: 1500
 cmd: testRestartGci
 args: T6 
 
-max-time: 600
+max-time: 1500
 cmd: testBlobs
 args:
 
-max-time: 2500
+max-time: 5000
 cmd: testOIBasic
 args: 
 
+max-time: 2500
+cmd: testBitfield
+args:
+
+max-time: 2500
+cmd: testPartitioning
+args:
+
 #
 #
 # SYSTEM RESTARTS
@@ -640,6 +662,14 @@ args: -n SR1 T8 
 
 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
@@ -652,6 +682,14 @@ 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
 args: -n SR_UNDO T1 
 
 max-time: 1500
@@ -665,3 +703,54 @@ args: -n SR_UNDO T7 
 max-time: 1500
 cmd: testSystemRestart
 args: -n SR_UNDO T8 
+
+max-time: 1000
+cmd: testSRBank
+args: -n SR -l 300 -r 15 T1
+
+max-time: 1000
+cmd: testSRBank
+args: -n NR -l 300 -r 15 T1
+
+max-time: 1000
+cmd: testSRBank
+args: -n Mix -l 300 -r 15 T1
+
+# OLD FLEX
+max-time: 500
+cmd: flexBench
+args: -c 25 -t 10 
+
+max-time: 500
+cmd: flexHammer
+args: -r 5 -t 32 
+
+max-time: 300
+cmd: DbCreate
+args:
+
+max-time: 180
+cmd: DbAsyncGenerator
+args: -time 60 -p 1
+type: bench
+
+max-time: 180
+cmd: DbAsyncGenerator
+args: -time 60 -p 25
+type: bench
+
+max-time: 180
+cmd: DbAsyncGenerator
+args: -time 60 -p 100
+type: bench
+
+max-time: 180
+cmd: DbAsyncGenerator
+args: -time 60 -p 200
+type: bench
+
+max-time: 180
+cmd: DbAsyncGenerator
+args: -time 60 -p 1 -proc 25
+type: bench
+

--- 1.8.1.9/ndb/src/kernel/blocks/ERROR_codes.txt	2006-06-01 08:24:02 +02:00
+++ 1.19/storage/ndb/src/kernel/blocks/ERROR_codes.txt	2006-06-01 08:33:46 +02:00
@@ -4,13 +4,13 @@ Next NDBFS 2000
 Next DBACC 3002
 Next DBTUP 4013
 Next DBLQH 5043
-Next DBDICT 6006
+Next DBDICT 6007
 Next DBDIH 7174
 Next DBTC 8037
 Next CMVMI 9000
 Next BACKUP 10022
 Next DBUTIL 11002
-Next DBTUX 12007
+Next DBTUX 12008
 Next SUMA 13001
 
 TESTING NODE FAILURE, ARBITRATION
@@ -205,6 +205,8 @@ Delay execution of ABORTREQ signal 2 sec
 8048: Make TC not choose own node for simple/dirty read
 5041: Crash is receiving simple read from other TC on different node
 
+8050: Send TCKEYREF is operation is non local
+
 5100,5101: Drop ABORT req in primary replica
            Crash on "next" ABORT
 
@@ -429,6 +431,7 @@ Drop Table/Index:
 8034: Fail next index create in TC
 8035: Fail next trigger drop in TC
 8036: Fail next index drop in TC
+6006: Crash participant in create index
 
 System Restart:
 ---------------
@@ -460,9 +463,20 @@ Test routing of signals:
 
 Ordered index:
 --------------
+12007: Make next alloc node fail with no memory error
 
 Dbdict:
 -------
 6003 Crash in participant @ CreateTabReq::Prepare
 6004 Crash in participant @ CreateTabReq::Commit
 6005 Crash in participant @ CreateTabReq::CreateDrop
+
+Dbtup:
+4014 - handleInsert - Out of undo buffer
+4015 - handleInsert - Out of log space
+4016 - handleInsert - AI Inconsistency
+4017 - handleInsert - Out of memory
+4018 - handleInsert - Null check error
+4019 - handleInsert - Alloc rowid error
+4020 - handleInsert - Size change error
+4021 - handleInsert - Out of disk space

--- 1.14.1.23/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2006-06-01 08:24:02 +02:00
+++ 1.62/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2006-06-01 08:33:46 +02:00
@@ -67,6 +67,7 @@
 #include <signaldata/CreateFragmentation.hpp>
 #include <signaldata/LqhFrag.hpp>
 #include <signaldata/FsOpenReq.hpp>
+#include <signaldata/DihFragCount.hpp>
 #include <DebuggerNames.hpp>
 
 #include <EventLogger.hpp>
@@ -247,7 +248,7 @@ void Dbdih::sendSTART_RECREQ(Signal* sig
   req->newestGci = SYSFILE->newestRestorableGCI;
   sendSignal(ref, GSN_START_RECREQ, signal, StartRecReq::SignalLength, JBB);
 
-  signal->theData[0] = EventReport::StartREDOLog;
+  signal->theData[0] = NDB_LE_StartREDOLog;
   signal->theData[1] = nodeId;
   signal->theData[2] = SYSFILE->keepGCI;
   signal->theData[3] = SYSFILE->lastCompletedGCI[nodeId];
@@ -609,6 +610,14 @@ void Dbdih::execCONTINUEB(Signal* signal
     checkWaitDropTabFailedLqh(signal, nodeId, tableId);
     return;
   }
+  case DihContinueB::ZTO_START_FRAGMENTS:
+  {
+    TakeOverRecordPtr takeOverPtr;
+    takeOverPtr.i = signal->theData[1];
+    ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
+    nr_start_fragments(signal, takeOverPtr);
+    return;
+  }
   }//switch
   
   ndbrequire(false);
@@ -639,9 +648,11 @@ void Dbdih::execCOPY_GCIREQ(Signal* sign
     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;
@@ -1052,18 +1063,26 @@ void Dbdih::execREAD_CONFIG_REQ(Signal* 
   jamEntry();
 
   const ndb_mgm_configuration_iterator * p = 
-    theConfiguration.getOwnConfigIterator();
-  ndbrequire(p != 0);
+    m_ctx.m_config.getOwnConfigIterator();
+  ndbrequireErr(p != 0, NDBD_EXIT_INVALID_CONFIG);
+
+  initData();
 
-  ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_API_CONNECT, 
-				       &capiConnectFileSize));
-  ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_CONNECT,&cconnectFileSize));
-  ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_FRAG_CONNECT, 
-					&cfragstoreFileSize));
-  ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_REPLICAS, 
-					&creplicaFileSize));
-  ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_TABLE, &ctabFileSize))
-    cfileFileSize = (2 * ctabFileSize) + 2;
+  ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_API_CONNECT, 
+					   &capiConnectFileSize),
+		NDBD_EXIT_INVALID_CONFIG);
+  ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_CONNECT,
+					   &cconnectFileSize),
+		NDBD_EXIT_INVALID_CONFIG);
+  ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_FRAG_CONNECT, 
+					   &cfragstoreFileSize),
+		NDBD_EXIT_INVALID_CONFIG);
+  ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_REPLICAS, 
+					   &creplicaFileSize),
+		NDBD_EXIT_INVALID_CONFIG);
+  ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_TABLE, &ctabFileSize),
+		NDBD_EXIT_INVALID_CONFIG);
+  cfileFileSize = (2 * ctabFileSize) + 2;
   initRecords();
   initialiseRecordsLab(signal, 0, ref, senderData);
   return;
@@ -1130,7 +1149,7 @@ void Dbdih::execDIH_RESTARTREQ(Signal* s
 {
   jamEntry();
   cntrlblockref = signal->theData[0];
-  if(theConfiguration.getInitialStart()){
+  if(m_ctx.m_config.getInitialStart()){
     sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
   } else {
     readGciFileLab(signal);
@@ -1494,9 +1513,7 @@ void Dbdih::execREAD_NODESCONF(Signal* s
 	       "Illegal configuration change."
 	       " Initial start needs to be performed "
 	       " when changing no of storage nodes (node %d)", i);
-      progError(__LINE__, 
-		ERR_INVALID_CONFIG,
-		buf);
+      progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
     }
   }
   
@@ -1604,7 +1621,7 @@ void Dbdih::execSTART_PERMREF(Signal* si
 			 " with --initial as partial start has been performed"
 			 " and this filesystem is unusable");
     progError(__LINE__, 
-	      ERR_SR_RESTARTCONFLICT,
+	      NDBD_EXIT_SR_RESTARTCONFLICT,
 	      buf);
     ndbrequire(false);
   }
@@ -1650,12 +1667,15 @@ void Dbdih::execSTART_MECONF(Signal* sig
    *
    * 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];
 
@@ -1813,11 +1833,6 @@ void Dbdih::execSTART_MEREQ(Signal* sign
   ndbrequire(c_nodeStartMaster.startNode == Tnodeid);
   ndbrequire(getNodeStatus(Tnodeid) == NodeRecord::STARTING);
   
-  sendSTART_RECREQ(signal, Tnodeid);
-}//Dbdih::execSTART_MEREQ()
-
-void Dbdih::nodeRestartStartRecConfLab(Signal* signal) 
-{
   c_nodeStartMaster.blockLcp = true;
   if ((c_lcpState.lcpStatus != LCP_STATUS_IDLE) &&
       (c_lcpState.lcpStatus != LCP_TCGET)) {
@@ -1868,7 +1883,7 @@ void Dbdih::nodeDictStartConfLab(Signal*
   /*-----------------------------------------------------------------*/
   // Report that node restart has completed copy of dictionary.
   /*-----------------------------------------------------------------*/
-  signal->theData[0] = EventReport::NR_CopyDict;
+  signal->theData[0] = NDB_LE_NR_CopyDict;
   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
 }//Dbdih::nodeDictStartConfLab()
 
@@ -1889,7 +1904,7 @@ void Dbdih::gcpBlockedLab(Signal* signal
   /*-----------------------------------------------------------------*/
   // Report that node restart has completed copy of distribution info.
   /*-----------------------------------------------------------------*/
-  signal->theData[0] = EventReport::NR_CopyDistr;
+  signal->theData[0] = NDB_LE_NR_CopyDistr;
   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
 
   /**
@@ -2050,7 +2065,7 @@ void Dbdih::execSTART_COPYREQ(Signal* si
   /*-------------------------------------------------------------------------*/
   // REPORT Copy process of node restart is now about to start up.
   /*-------------------------------------------------------------------------*/
-  signal->theData[0] = EventReport::NR_CopyFragsStarted;
+  signal->theData[0] = NDB_LE_NR_CopyFragsStarted;
   signal->theData[1] = startNodeId;
   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
 
@@ -2628,13 +2643,14 @@ void Dbdih::sendStartTo(Signal* signal, 
     return;
   }//if
   c_startToLock = takeOverPtrI;
+
+  takeOverPtr.p->toMasterStatus = TakeOverRecord::STARTING;
   StartToReq * const req = (StartToReq *)&signal->theData[0];
   req->userPtr = takeOverPtr.i;
   req->userRef = reference();
   req->startingNodeId = takeOverPtr.p->toStartingNode;
   req->nodeTakenOver = takeOverPtr.p->toFailedNode;
   req->nodeRestart = takeOverPtr.p->toNodeRestart;
-  takeOverPtr.p->toMasterStatus = TakeOverRecord::STARTING;
   sendLoopMacro(START_TOREQ, sendSTART_TOREQ);
 }//Dbdih::sendStartTo()
 
@@ -2678,9 +2694,153 @@ void Dbdih::execSTART_TOCONF(Signal* sig
   CRASH_INSERTION(7134);
   c_startToLock = RNIL;
 
+  if (takeOverPtr.p->toNodeRestart)
+  {
+    jam();
+    takeOverPtr.p->toMasterStatus = TakeOverRecord::STARTING_LOCAL_FRAGMENTS;
+    nr_start_fragments(signal, takeOverPtr);
+    return;
+  }
+
   startNextCopyFragment(signal, takeOverPtr.i);
 }//Dbdih::execSTART_TOCONF()
 
+void
+Dbdih::nr_start_fragments(Signal* signal, 
+			  TakeOverRecordPtr takeOverPtr)
+{
+  Uint32 loopCount = 0 ;
+  TabRecordPtr tabPtr;
+  while (loopCount++ < 100) {
+    tabPtr.i = takeOverPtr.p->toCurrentTabref;
+    if (tabPtr.i >= ctabFileSize) {
+      jam();
+      nr_run_redo(signal, takeOverPtr);
+      return;
+    }//if
+    ptrAss(tabPtr, tabRecord);
+    if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE){
+      jam();
+      takeOverPtr.p->toCurrentFragid = 0;
+      takeOverPtr.p->toCurrentTabref++;
+      continue;
+    }//if
+    Uint32 fragId = takeOverPtr.p->toCurrentFragid;
+    if (fragId >= tabPtr.p->totalfragments) {
+      jam();
+      takeOverPtr.p->toCurrentFragid = 0;
+      takeOverPtr.p->toCurrentTabref++;
+      continue;
+    }//if
+    FragmentstorePtr fragPtr;
+    getFragstore(tabPtr.p, fragId, fragPtr);
+    ReplicaRecordPtr loopReplicaPtr;
+    loopReplicaPtr.i = fragPtr.p->oldStoredReplicas;
+    while (loopReplicaPtr.i != RNIL) {
+      ptrCheckGuard(loopReplicaPtr, creplicaFileSize, replicaRecord);
+      if (loopReplicaPtr.p->procNode == takeOverPtr.p->toStartingNode) {
+        jam();
+	nr_start_fragment(signal, takeOverPtr, loopReplicaPtr);
+	break;
+      } else {
+        jam();
+        loopReplicaPtr.i = loopReplicaPtr.p->nextReplica;
+      }//if
+    }//while
+    takeOverPtr.p->toCurrentFragid++;
+  }//while
+  signal->theData[0] = DihContinueB::ZTO_START_FRAGMENTS;
+  signal->theData[1] = takeOverPtr.i;
+  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
+}
+
+void
+Dbdih::nr_start_fragment(Signal* signal, 
+			 TakeOverRecordPtr takeOverPtr,
+			 ReplicaRecordPtr replicaPtr)
+{
+  Uint32 i, j = 0;
+  Uint32 maxLcpId = 0;
+  Uint32 maxLcpIndex = ~0;
+  
+  Uint32 restorableGCI = 0;
+  
+  ndbout_c("tab: %d frag: %d replicaP->nextLcp: %d",
+	   takeOverPtr.p->toCurrentTabref,
+	   takeOverPtr.p->toCurrentFragid,
+	   replicaPtr.p->nextLcp);
+  
+  Uint32 idx = replicaPtr.p->nextLcp;
+  for(i = 0; i<MAX_LCP_STORED; i++, idx = nextLcpNo(idx))
+  {
+    ndbout_c("scanning idx: %d lcpId: %d", idx, replicaPtr.p->lcpId[idx]);
+    if (replicaPtr.p->lcpStatus[idx] == ZVALID) 
+    {
+      ndbrequire(replicaPtr.p->lcpId[idx] > maxLcpId);
+      Uint32 startGci = replicaPtr.p->maxGciCompleted[idx];
+      Uint32 stopGci = replicaPtr.p->maxGciStarted[idx];
+      for (;j < replicaPtr.p->noCrashedReplicas; j++)
+      {
+	ndbout_c("crashed replica: %d(%d) replicaLastGci: %d",
+		 j, 
+		 replicaPtr.p->noCrashedReplicas,
+		 replicaPtr.p->replicaLastGci[j]);
+	if (replicaPtr.p->replicaLastGci[j] > stopGci)
+	{
+	  maxLcpId = replicaPtr.p->lcpId[idx];
+	  maxLcpIndex = idx;
+	  restorableGCI = replicaPtr.p->replicaLastGci[j];
+	  break;
+	}
+      }
+    }
+  }
+  
+  if (maxLcpIndex == ~0)
+  {
+    ndbout_c("Didnt find any LCP for node: %d tab: %d frag: %d",
+	     takeOverPtr.p->toStartingNode,
+	     takeOverPtr.p->toCurrentTabref,
+	     takeOverPtr.p->toCurrentFragid);
+    replicaPtr.p->lcpIdStarted = 0;
+  }
+  else
+  {
+    ndbout_c("Found LCP: %d(%d) maxGciStarted: %d maxGciCompleted: %d restorable: %d(%d) newestRestorableGCI: %d",
+	     maxLcpId,
+	     maxLcpIndex,
+	     replicaPtr.p->maxGciStarted[maxLcpIndex],
+	     replicaPtr.p->maxGciCompleted[maxLcpIndex],	     
+	     restorableGCI,
+	     SYSFILE->lastCompletedGCI[takeOverPtr.p->toStartingNode],
+	     SYSFILE->newestRestorableGCI);
+
+    replicaPtr.p->lcpIdStarted = restorableGCI;
+    BlockReference ref = calcLqhBlockRef(takeOverPtr.p->toStartingNode);
+    StartFragReq *req = (StartFragReq *)signal->getDataPtrSend();
+    req->userPtr = 0;
+    req->userRef = reference();
+    req->lcpNo = maxLcpIndex;
+    req->lcpId = maxLcpId;
+    req->tableId = takeOverPtr.p->toCurrentTabref;
+    req->fragId = takeOverPtr.p->toCurrentFragid;
+    req->noOfLogNodes = 1;
+    req->lqhLogNode[0] = takeOverPtr.p->toStartingNode;
+    req->startGci[0] = replicaPtr.p->maxGciCompleted[maxLcpIndex];
+    req->lastGci[0] = restorableGCI;
+    sendSignal(ref, GSN_START_FRAGREQ, signal, 
+	       StartFragReq::SignalLength, JBB);
+  }
+}
+
+void
+Dbdih::nr_run_redo(Signal* signal, TakeOverRecordPtr takeOverPtr)
+{
+  takeOverPtr.p->toCurrentTabref = 0;
+  takeOverPtr.p->toCurrentFragid = 0;
+  sendSTART_RECREQ(signal, takeOverPtr.p->toStartingNode);
+}
+
 void Dbdih::initStartTakeOver(const StartToReq * req, 
 			      TakeOverRecordPtr takeOverPtr)
 {
@@ -3013,6 +3173,14 @@ void Dbdih::execCREATE_FRAGCONF(Signal* 
     /*---------------------------------------------------------------------- */
     FragmentstorePtr fragPtr;
     getFragstore(tabPtr.p, fragId, fragPtr);
+    Uint32 gci = 0;
+    if (takeOverPtr.p->toNodeRestart)
+    {
+      ReplicaRecordPtr replicaPtr;
+      findReplica(replicaPtr, fragPtr.p, takeOverPtr.p->toStartingNode, true);
+      gci = replicaPtr.p->lcpIdStarted;
+      replicaPtr.p->lcpIdStarted = 0;
+    }
     takeOverPtr.p->toMasterStatus = TakeOverRecord::COPY_FRAG;
     BlockReference ref = calcLqhBlockRef(takeOverPtr.p->toCopyNode);
     CopyFragReq * const copyFragReq = (CopyFragReq *)&signal->theData[0];
@@ -3023,6 +3191,7 @@ void Dbdih::execCREATE_FRAGCONF(Signal* 
     copyFragReq->nodeId = takeOverPtr.p->toStartingNode;
     copyFragReq->schemaVersion = tabPtr.p->schemaVersion;
     copyFragReq->distributionKey = fragPtr.p->distributionKey;
+    copyFragReq->gci = gci;
     sendSignal(ref, GSN_COPY_FRAGREQ, signal, CopyFragReq::SignalLength, JBB);
   } else {
     ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COMMIT_CREATE);
@@ -3031,7 +3200,7 @@ void Dbdih::execCREATE_FRAGCONF(Signal* 
     /* --------------------------------------------------------------------- */
     // REPORT that copy of fragment has been completed.
     /* --------------------------------------------------------------------- */
-    signal->theData[0] = EventReport::NR_CopyFragDone;
+    signal->theData[0] = NDB_LE_NR_CopyFragDone;
     signal->theData[1] = takeOverPtr.p->toStartingNode;
     signal->theData[2] = tabPtr.i;
     signal->theData[3] = takeOverPtr.p->toCurrentFragid;
@@ -3269,7 +3438,7 @@ Dbdih::switchPrimaryMutex_locked(Signal*
 
 void Dbdih::toCopyCompletedLab(Signal * signal, TakeOverRecordPtr takeOverPtr)
 {
-  signal->theData[0] = EventReport::NR_CopyFragsCompleted;
+  signal->theData[0] = NDB_LE_NR_CopyFragsCompleted;
   signal->theData[1] = takeOverPtr.p->toStartingNode;
   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
 
@@ -3544,6 +3713,7 @@ void Dbdih::readingGcpLab(Signal* signal
   /*     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()
@@ -3593,9 +3763,7 @@ void Dbdih::selectMasterCandidateAndSend
 			   " Initial start needs to be performed "
 			   " when changing no of replicas (%d != %d)", 
 			   node_groups[nodePtr.i], cnoReplicas);
-      progError(__LINE__, 
-		ERR_INVALID_CONFIG,
-		buf);
+      progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
     }
   }
 }//Dbdih::selectMasterCandidate()
@@ -3802,6 +3970,11 @@ void Dbdih::execNODE_FAILREP(Signal* sig
   /*------------------------------------------------------------------------*/
   // Verify that a starting node has also crashed. Reset the node start record.
   /*-------------------------------------------------------------------------*/
+#if 0
+  /**
+   * Node will crash by itself...
+   *   nodeRestart is run then...
+   */
   if (false && c_nodeStartMaster.startNode != RNIL && getNodeStatus(c_nodeStartMaster.startNode) == NodeRecord::ALIVE)
   {
     BlockReference cntrRef = calcNdbCntrBlockRef(c_nodeStartMaster.startNode);
@@ -3813,6 +3986,7 @@ void Dbdih::execNODE_FAILREP(Signal* sig
     sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal,  SystemError::SignalLength, JBA);
     nodeResetStart();  
   }//if
+#endif
 
   /*--------------------------------------------------*/
   /*                                                  */
@@ -3884,9 +4058,7 @@ void Dbdih::execNODE_FAILREP(Signal* sig
 
     if(getNodeState().getNodeRestartInProgress()){
       jam();
-      progError(__LINE__, 
-		ERR_SYSTEM_ERROR,
-		"Unhandle master failure during node restart");
+      progError(__LINE__, NDBD_EXIT_MASTER_FAILURE_DURING_NR);
     }
   }
 
@@ -4060,6 +4232,8 @@ void Dbdih::checkTakeOverInMasterStartNo
 						  Uint32 takeOverPtrI)
 {
   jam();
+  ndbout_c("checkTakeOverInMasterStartNodeFailure %x",
+	   takeOverPtrI);
   if (takeOverPtrI == RNIL) {
     jam();
     return;
@@ -4073,6 +4247,9 @@ void Dbdih::checkTakeOverInMasterStartNo
   takeOverPtr.i = takeOverPtrI;
   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
 
+  ndbout_c("takeOverPtr.p->toMasterStatus: %x", 
+	   takeOverPtr.p->toMasterStatus);
+  
   bool ok = false;
   switch (takeOverPtr.p->toMasterStatus) {
   case TakeOverRecord::IDLE:
@@ -4181,6 +4358,13 @@ void Dbdih::checkTakeOverInMasterStartNo
     //-----------------------------------------------------------------------
     endTakeOver(takeOverPtr.i);
     break;
+
+  case TakeOverRecord::STARTING_LOCAL_FRAGMENTS:
+    ok = true;
+    jam();
+    endTakeOver(takeOverPtr.i);
+    break;
+    
     /**
      * The following are states that it should not be possible to "be" in
      */
@@ -4550,7 +4734,7 @@ void Dbdih::startGcpMasterTakeOver(Signa
   sendLoopMacro(MASTER_GCPREQ, sendMASTER_GCPREQ);
   cgcpMasterTakeOverState = GMTOS_INITIAL;
   
-  signal->theData[0] = EventReport::GCP_TakeoverStarted;
+  signal->theData[0] = NDB_LE_GCP_TakeoverStarted;
   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
 
   setLocalNodefailHandling(signal, oldMasterId, NF_GCP_TAKE_OVER);
@@ -5059,7 +5243,7 @@ void Dbdih::MASTER_GCPhandling(Signal* s
     break;
   }//switch
 
-  signal->theData[0] = EventReport::GCP_TakeoverCompleted;
+  signal->theData[0] = NDB_LE_GCP_TakeoverCompleted;
   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
 
   /*--------------------------------------------------*/
@@ -5509,7 +5693,7 @@ Dbdih::checkEmptyLcpComplete(Signal *sig
   if(isMaster()){
     jam();
 
-    signal->theData[0] = EventReport::LCP_TakeoverStarted;
+    signal->theData[0] = NDB_LE_LCP_TakeoverStarted;
     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
     
     signal->theData[0] = 7012;
@@ -5599,11 +5783,9 @@ Dbdih::sendMASTER_LCPCONF(Signal * signa
 #endif
   }
 
-  bool ok = false;
   MasterLCPConf::State lcpState;
   switch (c_lcpState.lcpStatus) {
   case LCP_STATUS_IDLE:
-    ok = true;
     jam();
     /*------------------------------------------------*/
     /*       LOCAL CHECKPOINT IS CURRENTLY NOT ACTIVE */
@@ -5614,7 +5796,6 @@ Dbdih::sendMASTER_LCPCONF(Signal * signa
     lcpState = MasterLCPConf::LCP_STATUS_IDLE;
     break;
   case LCP_STATUS_ACTIVE:
-    ok = true;
     jam();
     /*--------------------------------------------------*/
     /*       COPY OF RESTART INFORMATION HAS BEEN       */
@@ -5623,7 +5804,6 @@ Dbdih::sendMASTER_LCPCONF(Signal * signa
     lcpState = MasterLCPConf::LCP_STATUS_ACTIVE;
     break;
   case LCP_TAB_COMPLETED:
-    ok = true;
     jam();
     /*--------------------------------------------------------*/
     /*       ALL LCP_REPORT'S HAVE BEEN COMPLETED FOR         */
@@ -5633,7 +5813,6 @@ Dbdih::sendMASTER_LCPCONF(Signal * signa
     lcpState = MasterLCPConf::LCP_TAB_COMPLETED;
     break;
   case LCP_TAB_SAVED:
-    ok = true;
     jam();
     /*--------------------------------------------------------*/
     /*       ALL LCP_REPORT'S HAVE BEEN COMPLETED FOR         */
@@ -5657,15 +5836,15 @@ Dbdih::sendMASTER_LCPCONF(Signal * signa
     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];
@@ -5981,7 +6160,7 @@ void Dbdih::MASTER_LCPhandling(Signal* s
     ndbrequire(false);
     break;
   }//switch
-  signal->theData[0] = EventReport::LCP_TakeoverCompleted;
+  signal->theData[0] = NDB_LE_LCP_TakeoverCompleted;
   signal->theData[1] = c_lcpMasterTakeOverState.state;
   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
   
@@ -6013,7 +6192,7 @@ void Dbdih::execNF_COMPLETEREP(Signal* s
     /* -------------------------------------------------------------------- */
     // Report the event that DBTC completed node failure handling.
     /* -------------------------------------------------------------------- */
-    signal->theData[0] = EventReport::NodeFailCompleted;
+    signal->theData[0] = NDB_LE_NodeFailCompleted;
     signal->theData[1] = DBTC;
     signal->theData[2] = failedNodePtr.i;
     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
@@ -6026,7 +6205,7 @@ void Dbdih::execNF_COMPLETEREP(Signal* s
     /* --------------------------------------------------------------------- */
     // Report the event that DBDICT completed node failure handling.
     /* --------------------------------------------------------------------- */
-    signal->theData[0] = EventReport::NodeFailCompleted;
+    signal->theData[0] = NDB_LE_NodeFailCompleted;
     signal->theData[1] = DBDICT;
     signal->theData[2] = failedNodePtr.i;
     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
@@ -6039,7 +6218,7 @@ void Dbdih::execNF_COMPLETEREP(Signal* s
     /* --------------------------------------------------------------------- */
     // Report the event that DBDIH completed node failure handling.
     /* --------------------------------------------------------------------- */
-    signal->theData[0] = EventReport::NodeFailCompleted;
+    signal->theData[0] = NDB_LE_NodeFailCompleted;
     signal->theData[1] = DBDIH;
     signal->theData[2] = failedNodePtr.i;
     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
@@ -6052,7 +6231,7 @@ void Dbdih::execNF_COMPLETEREP(Signal* s
     /* --------------------------------------------------------------------- */
     // Report the event that DBDIH completed node failure handling.
     /* --------------------------------------------------------------------- */
-    signal->theData[0] = EventReport::NodeFailCompleted;
+    signal->theData[0] = NDB_LE_NodeFailCompleted;
     signal->theData[1] = DBLQH;
     signal->theData[2] = failedNodePtr.i;
     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
@@ -6087,7 +6266,7 @@ void Dbdih::execNF_COMPLETEREP(Signal* s
     /* -------------------------------------------------------------------- */
     // Report the event that nodeId has completed node failure handling.
     /* -------------------------------------------------------------------- */
-    signal->theData[0] = EventReport::NodeFailCompleted;
+    signal->theData[0] = NDB_LE_NodeFailCompleted;
     signal->theData[1] = 0;
     signal->theData[2] = failedNodePtr.i;
     signal->theData[3] = nodeId;
@@ -6160,7 +6339,7 @@ void Dbdih::nodeFailCompletedCheckLab(Si
   /* ---------------------------------------------------------------------- */
   // Report the event that all nodes completed node failure handling.
   /* ---------------------------------------------------------------------- */
-  signal->theData[0] = EventReport::NodeFailCompleted;
+  signal->theData[0] = NDB_LE_NodeFailCompleted;
   signal->theData[1] = 0;
   signal->theData[2] = failedNodePtr.i;
   signal->theData[3] = 0;
@@ -6263,93 +6442,146 @@ void Dbdih::execDIRELEASEREQ(Signal* sig
   3.7.1   A D D   T A B L E   M A I N L Y
   ***************************************
   */
-void Dbdih::execCREATE_FRAGMENTATION_REQ(Signal * signal){
+
+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();
-	// needs to be fixed for single fragment tables
-        NGPtr.i = 0; //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 Sysfile::NS_NotActive_NotTakenOver:
+        case DictTabInfo::AllNodesMediumTable:
           jam();
+          noOfFragments = 2 * csystemnodes;
+          set_default_node_groups(signal, noOfFragments);
           break;
-        case Sysfile::NS_HotSpare:
+        case DictTabInfo::AllNodesLargeTable:
           jam();
-        case Sysfile::NS_NotDefined:
+          noOfFragments = 4 * csystemnodes;
+          set_default_node_groups(signal, noOfFragments);
+          break;
+        case DictTabInfo::SingleFragment:
+          jam();
+          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();
@@ -6363,54 +6595,14 @@ void Dbdih::execCREATE_FRAGMENTATION_REQ
         err = CreateFragmentationRef::InvalidPrimaryTable;
         break;
       }
-      if (noOfFragments != primTabPtr.p->totalfragments) {
-        jam();
-        err = CreateFragmentationRef::InvalidFragmentationType;
-        break;
-      }
-    }
-    
-    //@todo use section writer
-    Uint32 count = 2;
-    Uint32 fragments[2 + 8*MAX_REPLICAS*MAX_NDB_NODES];
-    Uint32 next_replica_node[MAX_NDB_NODES];
-    memset(next_replica_node,0,sizeof(next_replica_node));
-    if (primaryTableId == RNIL) {
-      jam();
-      for(Uint32 fragNo = 0; fragNo<noOfFragments; fragNo++){
-        jam();
-        ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);      
-
-        Uint32 ind = next_replica_node[NGPtr.i];
-        const Uint32 max = NGPtr.p->nodeCount;
-
-        //-------------------------------------------------------------------
-        // We make an extra step to ensure that the primary replicas are
-        // spread among the nodes.
-        //-------------------------------------------------------------------
-        next_replica_node[NGPtr.i] = (ind + 1 >= max ? 0 : ind + 1);
-        
-        for(Uint32 replicaNo = 0; replicaNo<noOfReplicas; replicaNo++){
-          jam();
-          const Uint32 nodeId = NGPtr.p->nodesInGroup[ind++];
-          fragments[count++] = nodeId;
-          ind = (ind == max ? 0 : ind);
-        }
-        
-        /**
-         * 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) {
@@ -6418,9 +6610,9 @@ void Dbdih::execCREATE_FRAGMENTATION_REQ
           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) {
@@ -6428,47 +6620,48 @@ void Dbdih::execCREATE_FRAGMENTATION_REQ
           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;
     
-    LinearSectionPtr ptr[3];
-    ptr[0].p = &fragments[0];
-    ptr[0].sz = count;
-    sendSignal(senderRef,
-	       GSN_CREATE_FRAGMENTATION_CONF,
-	       signal, 
-	       CreateFragmentationConf::SignalLength,
-	       JBB,
-	       ptr,
-	       1);
+    if(senderRef != 0)
+    {
+      jam();
+      LinearSectionPtr ptr[3];
+      ptr[0].p = (Uint32*)&fragments[0];
+      ptr[0].sz = (count + 1) / 2;
+      sendSignal(senderRef,
+		 GSN_CREATE_FRAGMENTATION_CONF,
+		 signal, 
+		 CreateFragmentationConf::SignalLength,
+		 JBB,
+		 ptr,
+		 1);
+    }
+    // Always ACK/NACK (here ACK)
+    signal->theData[0] = 0;
     return;
   } while(false);
-  
-  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);
+  // Always ACK/NACK (here NACK)
+  signal->theData[0] = err;
 }
 
 void Dbdih::execDIADDTABREQ(Signal* signal) 
 {
+  Uint32 fragType;
   jamEntry();
 
   DiAddTabReq * const req = (DiAddTabReq*)signal->getDataPtr();
@@ -6493,6 +6686,7 @@ void Dbdih::execDIADDTABREQ(Signal* sign
   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;
 
@@ -6529,15 +6723,42 @@ void Dbdih::execDIADDTABREQ(Signal* sign
   /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
   tabPtr.p->tabStatus = TabRecord::TS_CREATING;
   tabPtr.p->storedTable = req->storedTable;
-  tabPtr.p->method = TabRecord::HASH;
   tabPtr.p->kvalue = req->kValue;
 
-  Uint32 fragments[2 + 8*MAX_REPLICAS*MAX_NDB_NODES];
+  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;
+  };
   SegmentedSectionPtr fragDataPtr;
   signal->getSection(fragDataPtr, DiAddTabReq::FRAGMENTATION);
-  copy(fragments, fragDataPtr);
+  copy((Uint32*)fragments, fragDataPtr);
   releaseSections(signal);
-
+  
   const Uint32 noReplicas = fragments[0];
   const Uint32 noFragments = fragments[1];
 
@@ -6546,6 +6767,7 @@ void Dbdih::execDIADDTABREQ(Signal* sign
   ndbrequire(noReplicas == cnoReplicas); // Only allowed
 
   if (ERROR_INSERTED(7173)) {
+    CLEAR_ERROR_INSERT_VALUE;
     addtabrefuseLab(signal, connectPtr, ZREPLERROR1);
     return;
   }
@@ -6577,6 +6799,8 @@ void Dbdih::execDIADDTABREQ(Signal* sign
     Uint32 activeIndex = 0;
     getFragstore(tabPtr.p, fragId, fragPtr);
     fragPtr.p->preferredPrimary = fragments[index];
+    fragPtr.p->m_log_part_id = c_nextLogPart++;
+    
     for (Uint32 i = 0; i<noReplicas; i++) {
       const Uint32 nodeId = fragments[index++];
       ReplicaRecordPtr replicaPtr;
@@ -6621,9 +6845,9 @@ Dbdih::sendAddFragreq(Signal* signal, Co
   jam();
   const Uint32 fragCount = tabPtr.p->totalfragments;
   ReplicaRecordPtr replicaPtr; replicaPtr.i = RNIL;
+  FragmentstorePtr fragPtr;
   for(; fragId<fragCount; fragId++){
     jam();
-    FragmentstorePtr fragPtr;
     getFragstore(tabPtr.p, fragId, fragPtr);    
     
     replicaPtr.i = fragPtr.p->storedReplicas;
@@ -6681,6 +6905,7 @@ Dbdih::sendAddFragreq(Signal* signal, Co
     req->nodeId = getOwnNodeId();
     req->totalFragments = fragCount;
     req->startGci = SYSFILE->newestRestorableGCI;
+    req->logPartId = fragPtr.p->m_log_part_id;
     sendSignal(DBDICT_REF, GSN_ADD_FRAGREQ, signal, 
 	       AddFragReq::SignalLength, JBB);
     return;
@@ -6962,18 +7187,40 @@ void Dbdih::execDIGETNODESREQ(Signal* si
   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);
-  hashValue = hashValue >> tabPtr.p->kvalue;
-  Uint32 fragId = tabPtr.p->mask & hashValue;
-  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);
@@ -7140,39 +7387,66 @@ void Dbdih::execDIVERIFYREQ(Signal* sign
 
 void Dbdih::execDI_FCOUNTREQ(Signal* signal) 
 {
+  DihFragCountReq * const req = (DihFragCountReq*)signal->getDataPtr();
   ConnectRecordPtr connectPtr;
   TabRecordPtr tabPtr;
+  const BlockReference senderRef = signal->senderBlockRef();
+  const Uint32 senderData = req->m_senderData;
   jamEntry();
-  connectPtr.i = signal->theData[0];
-  tabPtr.i = signal->theData[1];
+  connectPtr.i = req->m_connectionData;
+  tabPtr.i = req->m_tableRef;
   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
 
-  ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
+  if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
+  {
+    DihFragCountRef* ref = (DihFragCountRef*)signal->getDataPtrSend();
+    //connectPtr.i == RNIL -> question without connect record
+    if(connectPtr.i == RNIL)
+      ref->m_connectionData = RNIL;
+    else
+      ref->m_connectionData = connectPtr.p->userpointer;
+    ref->m_tableRef = tabPtr.i;
+    ref->m_senderData = senderData;
+    ref->m_error = DihFragCountRef::ErroneousTableState;
+    ref->m_tableStatus = tabPtr.p->tabStatus;
+    sendSignal(senderRef, GSN_DI_FCOUNTREF, signal, 
+               DihFragCountRef::SignalLength, JBB);
+    return;
+  }
 
   if(connectPtr.i != RNIL){
     ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
     if (connectPtr.p->connectState == ConnectRecord::INUSE) {
       jam();
-      signal->theData[0] = connectPtr.p->userpointer;
-      signal->theData[1] = tabPtr.p->totalfragments;
-      sendSignal(connectPtr.p->userblockref, GSN_DI_FCOUNTCONF, signal,2, JBB);
-      return;
-    }//if
-    signal->theData[0] = connectPtr.p->userpointer;
-    signal->theData[1] = ZERRONOUSSTATE;
-    sendSignal(connectPtr.p->userblockref, GSN_DI_FCOUNTREF, signal, 2, JBB);
+      DihFragCountConf* conf = (DihFragCountConf*)signal->getDataPtrSend();
+      conf->m_connectionData = connectPtr.p->userpointer;
+      conf->m_tableRef = tabPtr.i;
+      conf->m_senderData = senderData;
+      conf->m_fragmentCount = tabPtr.p->totalfragments;
+      conf->m_noOfBackups = tabPtr.p->noOfBackups;
+      sendSignal(connectPtr.p->userblockref, GSN_DI_FCOUNTCONF, signal,
+                 DihFragCountConf::SignalLength, JBB);
+      return;
+    }//if
+    DihFragCountRef* ref = (DihFragCountRef*)signal->getDataPtrSend();
+    ref->m_connectionData = connectPtr.p->userpointer;
+    ref->m_tableRef = tabPtr.i;
+    ref->m_senderData = senderData;
+    ref->m_error = DihFragCountRef::ErroneousTableState;
+    ref->m_tableStatus = tabPtr.p->tabStatus;
+    sendSignal(connectPtr.p->userblockref, GSN_DI_FCOUNTREF, signal, 
+               DihFragCountRef::SignalLength, JBB);
     return;
   }//if
-
+  DihFragCountConf* conf = (DihFragCountConf*)signal->getDataPtrSend();
   //connectPtr.i == RNIL -> question without connect record
-  const Uint32 senderData = signal->theData[2];
-  const BlockReference senderRef = signal->senderBlockRef();
-  signal->theData[0] = RNIL;
-  signal->theData[1] = tabPtr.p->totalfragments;
-  signal->theData[2] = tabPtr.i;
-  signal->theData[3] = senderData;
-  signal->theData[4] = tabPtr.p->noOfBackups;
-  sendSignal(senderRef, GSN_DI_FCOUNTCONF, signal, 5, JBB);
+  conf->m_connectionData = RNIL;
+  conf->m_tableRef = tabPtr.i;
+  conf->m_senderData = senderData;
+  conf->m_fragmentCount = tabPtr.p->totalfragments;
+  conf->m_noOfBackups = tabPtr.p->noOfBackups;
+  sendSignal(senderRef, GSN_DI_FCOUNTCONF, signal, 
+             DihFragCountConf::SignalLength, JBB);
 }//Dbdih::execDI_FCOUNTREQ()
 
 void Dbdih::execDIGETPRIMREQ(Signal* signal) 
@@ -7327,7 +7601,7 @@ void Dbdih::startGcpLab(Signal* signal, 
   /***************************************************************************/
   // Report the event that a global checkpoint has started.
   /***************************************************************************/
-  signal->theData[0] = EventReport::GlobalCheckpointStarted; //Event type
+  signal->theData[0] = NDB_LE_GlobalCheckpointStarted; //Event type
   signal->theData[1] = cnewgcp;
   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
 
@@ -7590,6 +7864,22 @@ void Dbdih::execDIHNDBTAMPER(Signal* sig
 #ifdef ERROR_INSERT
   case 5:
     jam();
+    if(tuserpointer == 0)
+    {
+      jam();
+      signal->theData[0] = 0;
+      sendSignal(QMGR_REF, GSN_NDB_TAMPER, signal, 1, JBB);
+      sendSignal(NDBCNTR_REF, GSN_NDB_TAMPER, signal, 1, JBB);
+      sendSignal(NDBFS_REF, GSN_NDB_TAMPER, signal, 1, JBB);
+      sendSignal(DBACC_REF, GSN_NDB_TAMPER, signal, 1, JBB);
+      sendSignal(DBTUP_REF, GSN_NDB_TAMPER, signal, 1, JBB);
+      sendSignal(DBLQH_REF, GSN_NDB_TAMPER, signal, 1, JBB);
+      sendSignal(DBDICT_REF, GSN_NDB_TAMPER, signal, 1, JBB);
+      sendSignal(DBDIH_REF, GSN_NDB_TAMPER, signal, 1, JBB);
+      sendSignal(DBTC_REF, GSN_NDB_TAMPER, signal, 1, JBB);
+      sendSignal(CMVMI_REF, GSN_NDB_TAMPER, signal, 1, JBB);
+      return;
+    }
     /*----------------------------------------------------------------------*/
     // Insert errors.
     /*----------------------------------------------------------------------*/
@@ -7808,7 +8098,7 @@ void Dbdih::execCOPY_GCICONF(Signal* sig
     // Report the event that a global checkpoint has completed.
     /************************************************************************/
     signal->setTrace(0);
-    signal->theData[0] = EventReport::GlobalCheckpointCompleted; //Event type
+    signal->theData[0] = NDB_LE_GlobalCheckpointCompleted; //Event type
     signal->theData[1] = coldgcp;
     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);    
 
@@ -7933,9 +8223,12 @@ void Dbdih::writingCopyGciLab(Signal* si
     
     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();
@@ -8294,7 +8587,7 @@ Dbdih::resetReplicaSr(TabRecordPtr tabPt
 	  /* --------------------------------------------------------------- */
 	  /* THE NODE IS ALIVE AND KICKING AND ACTIVE, LET'S USE IT.         */
 	  /* --------------------------------------------------------------- */
-	  arrGuard(noCrashedReplicas, 8);
+	  arrGuardErr(noCrashedReplicas, 8, NDBD_EXIT_MAX_CRASHED_REPLICAS);
 	  Uint32 lastGci = replicaPtr.p->replicaLastGci[noCrashedReplicas];
 	  if(lastGci >= newestRestorableGCI){
 	    jam();
@@ -8502,8 +8795,7 @@ void Dbdih::readPagesIntoTableLab(Signal
   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 */
   /* ---------------------------------- */
@@ -8597,7 +8889,7 @@ void Dbdih::packTableIntoPagesLab(Signal
   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;
@@ -8698,6 +8990,80 @@ void Dbdih::packFragIntoPagesLab(Signal*
 /*****************************************************************************/
 /* **********     START FRAGMENT MODULE                          *************/
 /*****************************************************************************/
+void
+Dbdih::dump_replica_info()
+{
+  TabRecordPtr tabPtr;
+  FragmentstorePtr fragPtr;
+
+  for(tabPtr.i = 0; tabPtr.i < ctabFileSize; tabPtr.i++)
+  {
+    ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
+    if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
+      continue;
+    
+    for(Uint32 fid = 0; fid<tabPtr.p->totalfragments; fid++)
+    {
+      getFragstore(tabPtr.p, fid, fragPtr);
+      ndbout_c("tab: %d frag: %d gci: %d\n  -- storedReplicas:", 
+	       tabPtr.i, fid, SYSFILE->newestRestorableGCI);
+      
+      Uint32 i;
+      ReplicaRecordPtr replicaPtr;
+      replicaPtr.i = fragPtr.p->storedReplicas;
+      for(; replicaPtr.i != RNIL; replicaPtr.i = replicaPtr.p->nextReplica)
+      {
+	ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
+	ndbout_c("  node: %d initialGci: %d nextLcp: %d noCrashedReplicas: %d",
+		 replicaPtr.p->procNode,
+		 replicaPtr.p->initialGci,
+		 replicaPtr.p->nextLcp,
+		 replicaPtr.p->noCrashedReplicas);
+	for(i = 0; i<MAX_LCP_STORED; i++)
+	{
+	  ndbout_c("    i: %d %s : lcpId: %d maxGci Completed: %d Started: %d",
+		   i, 
+		   (replicaPtr.p->lcpStatus[i] == ZVALID ?"VALID":"INVALID"),
+		   replicaPtr.p->lcpId[i],
+		   replicaPtr.p->maxGciCompleted[i],
+		   replicaPtr.p->maxGciStarted[i]);
+	}
+	
+	for (i = 0; i < 8; i++)
+	{
+	  ndbout_c("    crashed replica: %d replicaLastGci: %d createGci: %d",
+		   i, 
+		   replicaPtr.p->replicaLastGci[i],
+		   replicaPtr.p->createGci[i]);
+	}
+      }
+      ndbout_c("  -- oldStoredReplicas");
+      replicaPtr.i = fragPtr.p->oldStoredReplicas;
+      for(; replicaPtr.i != RNIL; replicaPtr.i = replicaPtr.p->nextReplica)
+      {
+	ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
+	for(i = 0; i<MAX_LCP_STORED; i++)
+	{
+	  ndbout_c("    i: %d %s : lcpId: %d maxGci Completed: %d Started: %d",
+		   i, 
+		   (replicaPtr.p->lcpStatus[i] == ZVALID ?"VALID":"INVALID"),
+		   replicaPtr.p->lcpId[i],
+		   replicaPtr.p->maxGciCompleted[i],
+		   replicaPtr.p->maxGciStarted[i]);
+	}
+	
+	for (i = 0; i < 8; i++)
+	{
+	  ndbout_c("    crashed replica: %d replicaLastGci: %d createGci: %d",
+		   i, 
+		   replicaPtr.p->replicaLastGci[i],
+		   replicaPtr.p->createGci[i]);
+	}
+      }
+    }
+  }
+}
+
 void Dbdih::startFragment(Signal* signal, Uint32 tableId, Uint32 fragId) 
 {
   Uint32 TloopCount = 0;
@@ -8759,6 +9125,7 @@ void Dbdih::startFragment(Signal* signal
   /*     SEARCH FOR STORED REPLICAS THAT CAN BE USED TO RESTART THE SYSTEM.  */
   /* ----------------------------------------------------------------------- */
   searchStoredReplicas(fragPtr);
+
   if (cnoOfCreateReplicas == 0) {
     /* --------------------------------------------------------------------- */
     /*   THERE WERE NO STORED REPLICAS AVAILABLE THAT CAN SERVE AS REPLICA TO*/
@@ -8768,14 +9135,14 @@ void Dbdih::startFragment(Signal* signal
     /*   THIS WILL DECREASE THE GCI TO RESTORE WHICH HOPEFULLY WILL MAKE IT  */
     /*   POSSIBLE TO RESTORE THE SYSTEM.                                     */
     /* --------------------------------------------------------------------- */
-    char buf[100];
-    BaseString::snprintf(buf, sizeof(buf), 
-	     "Unable to find restorable replica for "
-	     "table: %d fragment: %d gci: %d",
-	     tableId, fragId, SYSFILE->newestRestorableGCI);
-    progError(__LINE__, 
-	      ERR_SYSTEM_ERROR,
-	      buf);
+    char buf[64];
+    BaseString::snprintf(buf, sizeof(buf), "table: %d fragment: %d gci: %d",
+			 tableId, fragId, SYSFILE->newestRestorableGCI);
+
+    ndbout_c(buf);
+    dump_replica_info();
+    
+    progError(__LINE__, NDBD_EXIT_NO_RESTORABLE_REPLICA, buf);
     ndbrequire(false);
     return;
   }//if
@@ -8851,8 +9218,8 @@ void Dbdih::execSTART_RECCONF(Signal* si
     // otherwise we have a problem.
     /* --------------------------------------------------------------------- */
     jam();
-    ndbrequire(senderNodeId == c_nodeStartMaster.startNode);
-    nodeRestartStartRecConfLab(signal);
+    ndbout_c("startNextCopyFragment");
+    startNextCopyFragment(signal, findTakeOver(senderNodeId));
     return;
   } else {
     /* --------------------------------------------------------------------- */
@@ -9312,7 +9679,7 @@ void Dbdih::execTCGETOPSIZECONF(Signal* 
   ndbrequire(((int)c_lcpState.oldestRestorableGci) > 0);
 
   if (ERROR_INSERTED(7011)) {
-    signal->theData[0] = EventReport::LCPStoppedInCalcKeepGci;
+    signal->theData[0] = NDB_LE_LCPStoppedInCalcKeepGci;
     signal->theData[1] = 0;
     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
     return;
@@ -9398,7 +9765,7 @@ void Dbdih::storeNewLcpIdLab(Signal* sig
   /***************************************************************************/
   // Report the event that a local checkpoint has started.
   /***************************************************************************/
-  signal->theData[0] = EventReport::LocalCheckpointStarted; //Event type
+  signal->theData[0] = NDB_LE_LocalCheckpointStarted; //Event type
   signal->theData[1] = SYSFILE->latestLCP_ID + 1;
   signal->theData[2] = c_lcpState.keepGci;
   signal->theData[3] = c_lcpState.oldestRestorableGci;
@@ -9778,7 +10145,7 @@ void Dbdih::execLCP_FRAG_REP(Signal* sig
   /* --------------------------------------------------------------------- */
   // REPORT that local checkpoint have completed this fragment.
   /* --------------------------------------------------------------------- */
-  signal->theData[0] = EventReport::LCPFragmentCompleted;
+  signal->theData[0] = NDB_LE_LCPFragmentCompleted;
   signal->theData[1] = nodeId;
   signal->theData[2] = tableId;
   signal->theData[3] = fragId;
@@ -9870,9 +10237,11 @@ Dbdih::checkLcpAllTablesDoneInLqh(){
 }
 
 void Dbdih::findReplica(ReplicaRecordPtr& replicaPtr, 
-			Fragmentstore* fragPtrP, Uint32 nodeId)
+			Fragmentstore* fragPtrP, 
+			Uint32 nodeId,
+			bool old)
 {
-  replicaPtr.i = fragPtrP->storedReplicas;
+  replicaPtr.i = old ? fragPtrP->oldStoredReplicas : fragPtrP->storedReplicas;
   while(replicaPtr.i != RNIL){
     ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
     if (replicaPtr.p->procNode == nodeId) {
@@ -10229,7 +10598,7 @@ void Dbdih::allNodesLcpCompletedLab(Sign
   /***************************************************************************/
   // Report the event that a local checkpoint has completed.
   /***************************************************************************/
-  signal->theData[0] = EventReport::LocalCheckpointCompleted; //Event type
+  signal->theData[0] = NDB_LE_LocalCheckpointCompleted; //Event type
   signal->theData[1] = SYSFILE->latestLCP_ID;
   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
   c_lcpState.lcpStopGcp = c_newest_restorable_gci;
@@ -10387,7 +10756,87 @@ void Dbdih::tableCloseLab(Signal* signal
  * GCP stop detected, 
  * send SYSTEM_ERROR to all other alive nodes
  */
-void Dbdih::crashSystemAtGcpStop(Signal* signal){
+void Dbdih::crashSystemAtGcpStop(Signal* signal)
+{
+  switch(cgcpStatus){
+  case GCP_NODE_FINISHED:
+  {
+    /**
+     * We're waiting for a GCP save conf
+     */
+    ndbrequire(!c_GCP_SAVEREQ_Counter.done());
+    NodeReceiverGroup rg(DBLQH, c_GCP_SAVEREQ_Counter);
+    signal->theData[0] = 2305;
+    sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBB);
+    
+    infoEvent("Detected GCP stop...sending kill to %s", 
+	      c_GCP_SAVEREQ_Counter.getText());
+    ndbout_c("Detected GCP stop...sending kill to %s", 
+	     c_GCP_SAVEREQ_Counter.getText());
+    return;
+  }
+  case GCP_SAVE_LQH_FINISHED:
+    ndbout_c("m_copyReason: %d m_waiting: %d",
+	     c_copyGCIMaster.m_copyReason,
+	     c_copyGCIMaster.m_waiting);
+    break;
+  }
+  
+  ndbout_c("c_copyGCISlave: sender{Data, Ref} %d %x reason: %d nextWord: %d",
+	   c_copyGCISlave.m_senderData,
+	   c_copyGCISlave.m_senderRef,
+	   c_copyGCISlave.m_copyReason,
+	   c_copyGCISlave.m_expectedNextWord);
+
+  FileRecordPtr file0Ptr;
+  file0Ptr.i = crestartInfoFile[0];
+  ptrCheckGuard(file0Ptr, cfileFileSize, fileRecord);
+  FileRecordPtr file1Ptr;
+  file1Ptr.i = crestartInfoFile[1];
+  ptrCheckGuard(file1Ptr, cfileFileSize, fileRecord);
+
+  ndbout_c("file[0] status: %d type: %d reqStatus: %d file1: %d %d %d",
+	   file0Ptr.p->fileStatus, file0Ptr.p->fileType, file0Ptr.p->reqStatus,
+	   file1Ptr.p->fileStatus, file1Ptr.p->fileType, file1Ptr.p->reqStatus
+	   );
+
+  signal->theData[0] = 404;
+  signal->theData[1] = file0Ptr.p->fileRef;
+  EXECUTE_DIRECT(NDBFS, GSN_DUMP_STATE_ORD, signal, 2);
+
+  signal->theData[0] = 404;
+  signal->theData[1] = file1Ptr.p->fileRef;
+  EXECUTE_DIRECT(NDBFS, GSN_DUMP_STATE_ORD, signal, 2);
+
+  ndbout_c("c_COPY_GCIREQ_Counter = %s", 
+	   c_COPY_GCIREQ_Counter.getText());
+  ndbout_c("c_COPY_TABREQ_Counter = %s", 
+	   c_COPY_TABREQ_Counter.getText());
+  ndbout_c("c_CREATE_FRAGREQ_Counter = %s", 
+	   c_CREATE_FRAGREQ_Counter.getText());
+  ndbout_c("c_DIH_SWITCH_REPLICA_REQ_Counter = %s", 
+	   c_DIH_SWITCH_REPLICA_REQ_Counter.getText());
+  ndbout_c("c_EMPTY_LCP_REQ_Counter = %s",c_EMPTY_LCP_REQ_Counter.getText());
+  ndbout_c("c_END_TOREQ_Counter = %s", c_END_TOREQ_Counter.getText());
+  ndbout_c("c_GCP_COMMIT_Counter = %s", c_GCP_COMMIT_Counter.getText());
+  ndbout_c("c_GCP_PREPARE_Counter = %s", c_GCP_PREPARE_Counter.getText());
+  ndbout_c("c_GCP_SAVEREQ_Counter = %s", c_GCP_SAVEREQ_Counter.getText());
+  ndbout_c("c_INCL_NODEREQ_Counter = %s", c_INCL_NODEREQ_Counter.getText());
+  ndbout_c("c_MASTER_GCPREQ_Counter = %s", 
+	   c_MASTER_GCPREQ_Counter.getText());
+  ndbout_c("c_MASTER_LCPREQ_Counter = %s", 
+	   c_MASTER_LCPREQ_Counter.getText());
+  ndbout_c("c_START_INFOREQ_Counter = %s", 
+	   c_START_INFOREQ_Counter.getText());
+  ndbout_c("c_START_RECREQ_Counter = %s", c_START_RECREQ_Counter.getText());
+  ndbout_c("c_START_TOREQ_Counter = %s", c_START_TOREQ_Counter.getText());
+  ndbout_c("c_STOP_ME_REQ_Counter = %s", c_STOP_ME_REQ_Counter.getText());
+  ndbout_c("c_TC_CLOPSIZEREQ_Counter = %s", 
+	   c_TC_CLOPSIZEREQ_Counter.getText());
+  ndbout_c("c_TCGETOPSIZEREQ_Counter = %s", 
+	   c_TCGETOPSIZEREQ_Counter.getText());
+  ndbout_c("c_UPDATE_TOREQ_Counter = %s", c_UPDATE_TOREQ_Counter.getText());
+
   NodeRecordPtr nodePtr;
   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
     jam();
@@ -10543,7 +10992,7 @@ void Dbdih::calculateHotSpare() 
     break;
   default:
     jam();
-    progError(0, 0);
+    ndbrequire(false);
     break;
   }//switch
 }//Dbdih::calculateHotSpare()
@@ -10576,7 +11025,7 @@ void Dbdih::checkEscalation() 
     jam();
     if (TnodeGroup[i] == ZFALSE) {
       jam();
-      progError(__LINE__, ERR_SYSTEM_ERROR, "Lost node group");
+      progError(__LINE__, NDBD_EXIT_LOST_NODE_GROUP, "Lost node group");
     }//if
   }//for
 }//Dbdih::checkEscalation()
@@ -11045,6 +11494,7 @@ void Dbdih::initCommonData()
   cnoHotSpare = 0;
   cnoOfActiveTables = 0;
   cnoOfNodeGroups = 0;
+  c_nextNodeGroup = 0;
   cnoReplicas = 0;
   coldgcp = 0;
   coldGcpId = 0;
@@ -11064,6 +11514,7 @@ void Dbdih::initCommonData()
   c_newest_restorable_gci = 0;
   cverifyQueueCounter = 0;
   cwaitLcpSr = false;
+  c_nextLogPart = 0;
 
   nodeResetStart();
   c_nodeStartMaster.wait = ZFALSE;
@@ -11071,7 +11522,7 @@ void Dbdih::initCommonData()
   memset(&sysfileData[0], 0, sizeof(sysfileData));
 
   const ndb_mgm_configuration_iterator * p = 
-    theConfiguration.getOwnConfigIterator();
+    m_ctx.m_config.getOwnConfigIterator();
   ndbrequire(p != 0);
   
   c_lcpState.clcpDelay = 20;
@@ -11086,7 +11537,7 @@ void Dbdih::initCommonData()
   ndb_mgm_get_int_parameter(p, CFG_DB_NO_REPLICAS, &cnoReplicas);
   if (cnoReplicas > 4)
   {
-    progError(__LINE__, ERR_INVALID_CONFIG,
+    progError(__LINE__, NDBD_EXIT_INVALID_CONFIG,
 	      "Only up to four replicas are supported. Check NoOfReplicas.");
   }
 
@@ -11150,6 +11601,8 @@ void Dbdih::initRestartInfo() 
     SYSFILE->takeOver[i] = 0;
   }//for
   Sysfile::setInitialStartOngoing(SYSFILE->systemRestartBits);
+  srand(time(0));
+  globalData.m_restart_seq = SYSFILE->m_restart_seq = 0;
 }//Dbdih::initRestartInfo()
 
 /*--------------------------------------------------------------------*/
@@ -11565,16 +12018,14 @@ void Dbdih::makeNodeGroups(Uint32 nodeAr
   NodeRecordPtr mngNodeptr;
   Uint32 tmngNode;
   Uint32 tmngNodeGroup;
-  Uint32 tmngReplica;
   Uint32 tmngLimit;
-  Uint32 i;
+  Uint32 i, j;
 
   /**-----------------------------------------------------------------------
    * ASSIGN ALL ACTIVE NODES INTO NODE GROUPS. HOT SPARE NODES ARE ASSIGNED 
    * TO NODE GROUP ZNIL
    *-----------------------------------------------------------------------*/
   tmngNodeGroup = 0;
-  tmngReplica = 0;
   tmngLimit = csystemnodes - cnoHotSpare;
   ndbrequire(tmngLimit < MAX_NDB_NODES);
   for (i = 0; i < tmngLimit; i++) {
@@ -11586,13 +12037,11 @@ void Dbdih::makeNodeGroups(Uint32 nodeAr
     mngNodeptr.p->nodeGroup = tmngNodeGroup;
     NGPtr.i = tmngNodeGroup;
     ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
-    arrGuard(tmngReplica, MAX_REPLICAS);
-    NGPtr.p->nodesInGroup[tmngReplica] = mngNodeptr.i;
-    tmngReplica++;
-    if (tmngReplica == cnoReplicas) {
+    arrGuard(NGPtr.p->nodeCount, MAX_REPLICAS);
+    NGPtr.p->nodesInGroup[NGPtr.p->nodeCount++] = mngNodeptr.i;
+    if (NGPtr.p->nodeCount == cnoReplicas) {
       jam();
       tmngNodeGroup++;
-      tmngReplica = 0;
     }//if
   }//for
   cnoOfNodeGroups = tmngNodeGroup;
@@ -11616,6 +12065,38 @@ void Dbdih::makeNodeGroups(Uint32 nodeAr
       Sysfile::setNodeGroup(mngNodeptr.i, SYSFILE->nodeGroups, mngNodeptr.p->nodeGroup);
     }//if
   }//for
+
+  for (i = 0; i<cnoOfNodeGroups; i++)
+  {
+    jam();
+    bool alive = false;
+    NodeGroupRecordPtr NGPtr;
+    NGPtr.i = i;
+    ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
+    for (j = 0; j<NGPtr.p->nodeCount; j++)
+    {
+      jam();
+      mngNodeptr.i = NGPtr.p->nodesInGroup[j];
+      ptrCheckGuard(mngNodeptr, MAX_NDB_NODES, nodeRecord);
+      if (checkNodeAlive(NGPtr.p->nodesInGroup[j]))
+      {
+	alive = true;
+	break;
+      }
+    }
+
+    if (!alive)
+    {
+      char buf[255];
+      BaseString::snprintf
+	(buf, sizeof(buf), 
+	 "Illegal initial start, no alive node in nodegroup %u", i);
+      progError(__LINE__, 
+		NDBD_EXIT_SR_RESTARTCONFLICT,
+		buf);
+      
+    }
+  }
 }//Dbdih::makeNodeGroups()
 
 /**
@@ -11751,7 +12232,8 @@ void Dbdih::newCrashedReplica(Uint32 nod
   /*       THAT THE NEW REPLICA IS NOT STARTED YET AND REPLICA_LAST_GCI IS*/
   /*       SET TO -1 TO INDICATE THAT IT IS NOT DEAD YET.                 */
   /*----------------------------------------------------------------------*/
-  arrGuard(ncrReplicaPtr.p->noCrashedReplicas + 1, 8);
+  arrGuardErr(ncrReplicaPtr.p->noCrashedReplicas + 1, 8,
+              NDBD_EXIT_MAX_CRASHED_REPLICAS);
   ncrReplicaPtr.p->replicaLastGci[ncrReplicaPtr.p->noCrashedReplicas] = 
     SYSFILE->lastCompletedGCI[nodeId];
   ncrReplicaPtr.p->noCrashedReplicas = ncrReplicaPtr.p->noCrashedReplicas + 1;
@@ -11871,6 +12353,8 @@ void Dbdih::readFragment(RWFragment* rf,
     jam();
     fragPtr.p->distributionKey = TdistKey;
   }//if
+
+  fragPtr.p->m_log_part_id = readPageWord(rf);
 }//Dbdih::readFragment()
 
 Uint32 Dbdih::readPageWord(RWFragment* rf) 
@@ -12423,7 +12907,6 @@ void Dbdih::sendStartFragreq(Signal* sig
 void Dbdih::setInitialActiveStatus()
 {
   NodeRecordPtr siaNodeptr;
-  Uint32 tsiaNodeActiveStatus;
   Uint32 tsiaNoActiveNodes;
 
   tsiaNoActiveNodes = csystemnodes - cnoHotSpare;
@@ -12431,39 +12914,34 @@ void Dbdih::setInitialActiveStatus()
     SYSFILE->nodeStatus[i] = 0;
   for (siaNodeptr.i = 1; siaNodeptr.i < MAX_NDB_NODES; siaNodeptr.i++) {
     ptrAss(siaNodeptr, nodeRecord);
-    if (siaNodeptr.p->nodeStatus == NodeRecord::ALIVE) {
+    switch(siaNodeptr.p->nodeStatus){
+    case NodeRecord::ALIVE:
+    case NodeRecord::DEAD:
       if (tsiaNoActiveNodes == 0) {
         jam();
         siaNodeptr.p->activeStatus = Sysfile::NS_HotSpare;
       } else {
         jam();
         tsiaNoActiveNodes = tsiaNoActiveNodes - 1;
-        siaNodeptr.p->activeStatus = Sysfile::NS_Active;
-      }//if
-    } else {
-      jam();
-      siaNodeptr.p->activeStatus = Sysfile::NS_NotDefined;
-    }//if
-    switch (siaNodeptr.p->activeStatus) {
-    case Sysfile::NS_Active:
-      jam();
-      tsiaNodeActiveStatus = Sysfile::NS_Active;
-      break;
-    case Sysfile::NS_HotSpare:
-      jam();
-      tsiaNodeActiveStatus = Sysfile::NS_HotSpare;
-      break;
-    case Sysfile::NS_NotDefined:
-      jam();
-      tsiaNodeActiveStatus = Sysfile::NS_NotDefined;
+        if (siaNodeptr.p->nodeStatus == NodeRecord::ALIVE)
+	{
+	  jam();
+	  siaNodeptr.p->activeStatus = Sysfile::NS_Active;
+	} 
+	else
+	{
+	  siaNodeptr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
+	}
+      }
       break;
     default:
-      ndbrequire(false);
-      return;
+      jam();
+      siaNodeptr.p->activeStatus = Sysfile::NS_NotDefined;
       break;
-    }//switch
-    Sysfile::setNodeStatus(siaNodeptr.i, SYSFILE->nodeStatus,
-                           tsiaNodeActiveStatus);
+    }//if
+    Sysfile::setNodeStatus(siaNodeptr.i, 
+			   SYSFILE->nodeStatus,
+                           siaNodeptr.p->activeStatus);
   }//for
 }//Dbdih::setInitialActiveStatus()
 
@@ -12970,6 +13448,7 @@ void Dbdih::writeFragment(RWFragment* wf
   writePageWord(wf, fragPtr.p->noStoredReplicas);
   writePageWord(wf, fragPtr.p->noOldStoredReplicas);
   writePageWord(wf, fragPtr.p->distributionKey);
+  writePageWord(wf, fragPtr.p->m_log_part_id);
 }//Dbdih::writeFragment()
 
 void Dbdih::writePageWord(RWFragment* wf, Uint32 dataWord)
@@ -13036,7 +13515,7 @@ void Dbdih::writeTabfile(Signal* signal,
   signal->theData[0] = filePtr.p->fileRef;
   signal->theData[1] = reference();
   signal->theData[2] = filePtr.i;
-  signal->theData[3] = ZLIST_OF_PAIRS;
+  signal->theData[3] = ZLIST_OF_PAIRS_SYNCH;
   signal->theData[4] = ZVAR_NO_WORD;
   signal->theData[5] = tab->noPages;
   for (Uint32 i = 0; i < tab->noPages; i++) {
@@ -13399,7 +13878,7 @@ Dbdih::execDUMP_STATE_ORD(Signal* signal
     if (signal->getLength() == 1)
     {
       const ndb_mgm_configuration_iterator * p = 
-	theConfiguration.getOwnConfigIterator();
+	m_ctx.m_config.getOwnConfigIterator();
       ndbrequire(p != 0);
       ndb_mgm_get_int_parameter(p, CFG_DB_GCP_INTERVAL, &cgcpDelay);
     }

--- 1.42.1.24/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2006-06-01 08:24:02 +02:00
+++ 1.114/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2006-06-01 08:33:46 +02:00
@@ -20,6 +20,7 @@
 #include "md5_hash.hpp"
 #include <RefConvert.hpp>
 #include <ndb_limits.h>
+#include <my_sys.h>
 
 #include <signaldata/EventReport.hpp>
 #include <signaldata/TcKeyReq.hpp>
@@ -37,6 +38,7 @@
 #include <signaldata/TcContinueB.hpp>
 #include <signaldata/TcKeyFailConf.hpp>
 #include <signaldata/AbortAll.hpp>
+#include <signaldata/DihFragCount.hpp>
 #include <signaldata/ScanFrag.hpp>
 #include <signaldata/ScanTab.hpp>
 #include <signaldata/PrepDropTab.hpp>
@@ -63,6 +65,9 @@
 #include <signaldata/PackedSignal.hpp>
 #include <AttributeHeader.hpp>
 #include <signaldata/DictTabInfo.hpp>
+#include <AttributeDescriptor.hpp>
+#include <SectionReader.hpp>
+#include <KeyDescriptor.hpp>
 
 #include <NdbOut.hpp>
 #include <DebuggerNames.hpp>
@@ -317,6 +322,10 @@ void Dbtc::execREAD_NODESREF(Signal* sig
 void Dbtc::execTC_SCHVERREQ(Signal* signal) 
 {
   jamEntry();
+  if (! assembleFragments(signal)) {
+    jam();
+    return;
+  }
   tabptr.i = signal->theData[0];
   ptrCheckGuard(tabptr, ctabrecFilesize, tableRecord);
   tabptr.p->currentSchemaVersion = signal->theData[1];
@@ -324,11 +333,19 @@ void Dbtc::execTC_SCHVERREQ(Signal* sign
   BlockReference retRef = signal->theData[3];
   tabptr.p->tableType = (Uint8)signal->theData[4];
   BlockReference retPtr = signal->theData[5];
+  Uint32 noOfKeyAttr = signal->theData[6];
+  ndbrequire(noOfKeyAttr <= MAX_ATTRIBUTES_IN_INDEX);
+
+  const KeyDescriptor* desc = g_key_descriptor_pool.getPtr(tabptr.i);
+  ndbrequire(noOfKeyAttr == desc->noOfKeyAttr);
 
   ndbrequire(tabptr.p->enabled == false);
   tabptr.p->enabled = true;
   tabptr.p->dropping = false;
-  
+  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);
@@ -594,9 +611,11 @@ void Dbtc::execREAD_CONFIG_REQ(Signal* s
   jamEntry();
   
   const ndb_mgm_configuration_iterator * p = 
-    theConfiguration.getOwnConfigIterator();
+    m_ctx.m_config.getOwnConfigIterator();
   ndbrequire(p != 0);
   
+  initData();
+  
   UintR apiConnect;
   UintR tcConnect;
   UintR tables;
@@ -1017,7 +1036,7 @@ Dbtc::handleFailedApiNode(Signal* signal
         /*********************************************************************/
         // Not implemented yet.
         /*********************************************************************/
-        systemErrorLab(signal);
+        systemErrorLab(signal, __LINE__);
         break;
       case CS_RESTART:
         jam();
@@ -1041,7 +1060,7 @@ Dbtc::handleFailedApiNode(Signal* signal
         /*********************************************************************/
       default:
         jam();
-        systemErrorLab(signal);
+        systemErrorLab(signal, __LINE__);
         break;
       }//switch
     } else {
@@ -1380,7 +1399,7 @@ void Dbtc::printState(Signal* signal, in
 	     << " keylen = " << regCachePtr->keylen << endl;
     } else {
       jam();
-      systemErrorLab(signal);
+      systemErrorLab(signal, __LINE__);
     }//if
   }//if
 #endif
@@ -1434,7 +1453,7 @@ Dbtc::TCKEY_abort(Signal* signal, int pl
     return;
   case 6:
     jam();
-    warningHandlerLab(signal);
+    warningHandlerLab(signal, __LINE__);
     return;
 
   case 7:
@@ -1455,7 +1474,7 @@ Dbtc::TCKEY_abort(Signal* signal, int pl
 
   case 10:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 11:
@@ -1486,7 +1505,7 @@ Dbtc::TCKEY_abort(Signal* signal, int pl
       /*       PARTICULAR TC CONNECT RECORD. THIS MUST BE CAUSED BY NDB   */
       /*       INTERNAL ERROR.                                            */
       /********************************************************************/
-      systemErrorLab(signal);
+      systemErrorLab(signal, __LINE__);
       return;
     }//switch
     return;
@@ -1499,17 +1518,17 @@ Dbtc::TCKEY_abort(Signal* signal, int pl
 
   case 16:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 17:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 18:
     jam();
-    warningHandlerLab(signal);
+    warningHandlerLab(signal, __LINE__);
     return;
 
   case 19:
@@ -1518,22 +1537,22 @@ Dbtc::TCKEY_abort(Signal* signal, int pl
 
   case 20:
     jam();
-    warningHandlerLab(signal);
+    warningHandlerLab(signal, __LINE__);
     return;
 
   case 21:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 22:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 23:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 24:
@@ -1543,7 +1562,7 @@ Dbtc::TCKEY_abort(Signal* signal, int pl
 
   case 25:
     jam();
-    warningHandlerLab(signal);
+    warningHandlerLab(signal, __LINE__);
     return;
 
   case 26:
@@ -1551,7 +1570,7 @@ Dbtc::TCKEY_abort(Signal* signal, int pl
     return;
 
   case 27:
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     jam();
     return;
 
@@ -1562,92 +1581,92 @@ Dbtc::TCKEY_abort(Signal* signal, int pl
 
   case 29:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 30:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 31:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 32:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 33:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 34:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 35:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 36:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 37:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 38:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 39:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 40:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 41:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 42:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 43:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 44:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 45:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 46:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 47:
@@ -1669,7 +1688,7 @@ Dbtc::TCKEY_abort(Signal* signal, int pl
 
   case 50:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
 
   case 51:
@@ -1745,7 +1764,7 @@ Dbtc::TCKEY_abort(Signal* signal, int pl
     
   default:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
   }//switch
 }
@@ -1758,7 +1777,7 @@ void Dbtc::execKEYINFO(Signal* signal) 
   tmaxData = 20;
   if (apiConnectptr.i >= capiConnectFilesize) {
     jam();
-    warningHandlerLab(signal);
+    warningHandlerLab(signal, __LINE__);
     return;
   }//if
   ptrAss(apiConnectptr, apiConnectRecord);
@@ -1805,7 +1824,7 @@ void Dbtc::execKEYINFO(Signal* signal) 
     return;
   default:
     jam();
-    warningHandlerLab(signal);
+    warningHandlerLab(signal, __LINE__);
     return;
   }//switch
 
@@ -2228,11 +2247,10 @@ void Dbtc::hash(Signal* signal) 
   UintR  Tdata2;
   UintR  Tdata3;
   UintR*  Tdata32;
-  Uint64 Tdata[512];
-
+  
   CacheRecord * const regCachePtr = cachePtr.p;
-  Tdata32 = (UintR*)&Tdata[0];
-
+  Tdata32 = signal->theData;
+  
   Tdata0 = regCachePtr->keydata[0];
   Tdata1 = regCachePtr->keydata[1];
   Tdata2 = regCachePtr->keydata[2];
@@ -2258,31 +2276,79 @@ void Dbtc::hash(Signal* signal) 
       ti += 4;
     }//while
   }//if
-  UintR ThashValue;
-  UintR TdistrHashValue;
-  ThashValue = md5_hash((Uint64*)&Tdata32[0], (UintR)regCachePtr->keylen);
 
-  if (regCachePtr->distributionGroupIndicator == 1) {
-    if (regCachePtr->distributionGroupType == 1) {
-      jam();
-      TdistrHashValue = (regCachePtr->distributionGroup << 6);
-    } else {
-      jam();
-      Tdata32[0] = regCachePtr->distributionGroup;
-      TdistrHashValue = md5_hash((Uint64*)&Tdata32[0], (UintR)1);
-    }//if
-  } else if (regCachePtr->distributionKeyIndicator == 1) {
+  UintR keylen = (UintR)regCachePtr->keylen;
+  Uint32 distKey = regCachePtr->distributionKeyIndicator;
+  
+  Uint32 tmp[4];
+  if(!regCachePtr->m_special_hash)
+  {
+    md5_hash(tmp, (Uint64*)&Tdata32[0], keylen);
+  }
+  else
+  {
+    handle_special_hash(tmp, Tdata32, keylen, regCachePtr->tableref, !distKey);
+  }
+  
+  thashValue = tmp[0];
+  if (distKey){
     jam();
-    TdistrHashValue = md5_hash((Uint64*)&Tdata32[0], 
-                               (UintR)regCachePtr->distributionKeySize);
+    tdistrHashValue = regCachePtr->distributionKey;
   } else {
     jam();
-    TdistrHashValue = ThashValue;
+    tdistrHashValue = tmp[1];
   }//if
-  thashValue = ThashValue;
-  tdistrHashValue = TdistrHashValue;
 }//Dbtc::hash()
 
+bool
+Dbtc::handle_special_hash(Uint32 dstHash[4], Uint32* src, Uint32 srcLen, 
+			  Uint32 tabPtrI,
+			  bool distr)
+{
+  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 compute_distkey = distr && (tabPtrP->noOfDistrKeys > 0);
+  
+  Uint32 *dst = (Uint32*)Tmp;
+  Uint32 dstPos = 0;
+  Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX];
+  Uint32 * keyPartLenPtr;
+  if(hasCharAttr || (compute_distkey && hasVarKeys))
+  {
+    keyPartLenPtr = keyPartLen;
+    dstPos = xfrm_key(tabPtrI, src, dst, sizeof(Tmp) >> 2, keyPartLenPtr);
+    if (unlikely(dstPos == 0))
+    {
+      goto error;
+    }
+  } 
+  else 
+  {
+    dst = src;
+    dstPos = srcLen;
+    keyPartLenPtr = 0;
+  }
+  
+  md5_hash(dstHash, (Uint64*)dst, dstPos);
+  
+  if(compute_distkey)
+  {
+    jam();
+    
+    Uint32 tmp[4];
+    Uint32 len = create_distr_key(tabPtrI, dst, keyPartLenPtr);
+    md5_hash(tmp, (Uint64*)dst, len);
+    dstHash[1] = tmp[1];
+  }
+  return true;  // success
+
+error:
+  terrorCode = ZINVALID_KEY;
+  return false;
+}
+
 /*
 INIT_API_CONNECT_REC
 ---------------------------
@@ -2675,18 +2741,15 @@ void Dbtc::execTCKEYREQ(Signal* signal) 
   Uint8 TSimpleFlag         = tcKeyReq->getSimpleFlag(Treqinfo);
   Uint8 TDirtyFlag          = tcKeyReq->getDirtyFlag(Treqinfo);
   Uint8 TInterpretedFlag    = tcKeyReq->getInterpretedFlag(Treqinfo);
-  Uint8 TDistrGroupFlag     = tcKeyReq->getDistributionGroupFlag(Treqinfo);
-  Uint8 TDistrGroupTypeFlag = tcKeyReq->getDistributionGroupTypeFlag(Treqinfo);
   Uint8 TDistrKeyFlag       = tcKeyReq->getDistributionKeyFlag(Treqinfo);
+  Uint8 TNoDiskFlag         = TcKeyReq::getNoDiskFlag(Treqinfo);
   Uint8 TexecuteFlag        = TexecFlag;
   
   regCachePtr->opSimple = TSimpleFlag;
   regCachePtr->opExec   = TInterpretedFlag;
   regTcPtr->dirtyOp  = TDirtyFlag;
-
-  regCachePtr->distributionGroupIndicator = TDistrGroupFlag;
-  regCachePtr->distributionGroupType      = TDistrGroupTypeFlag;
-  regCachePtr->distributionKeyIndicator   = TDistrKeyFlag;
+  regCachePtr->distributionKeyIndicator = TDistrKeyFlag;
+  regCachePtr->m_no_disk_flag = TNoDiskFlag;
 
   //-------------------------------------------------------------
   // The next step is to read the upto three conditional words.
@@ -2695,17 +2758,14 @@ void Dbtc::execTCKEYREQ(Signal* signal) 
   Uint32* TOptionalDataPtr = (Uint32*)&tcKeyReq->scanInfo;
   {
     Uint32  TDistrGHIndex    = tcKeyReq->getScanIndFlag(Treqinfo);
-    Uint32  TDistrKeyIndex   = TDistrGHIndex + TDistrGroupFlag;
+    Uint32  TDistrKeyIndex   = TDistrGHIndex;
 
-    Uint32 TscanNode = tcKeyReq->getTakeOverScanNode(TOptionalDataPtr[0]);
     Uint32 TscanInfo = tcKeyReq->getTakeOverScanInfo(TOptionalDataPtr[0]);
 
     regCachePtr->scanTakeOverInd = TDistrGHIndex;
-    regCachePtr->scanNode = TscanNode;
     regCachePtr->scanInfo = TscanInfo;
 
-    regCachePtr->distributionGroup   = TOptionalDataPtr[TDistrGHIndex];
-    regCachePtr->distributionKeySize = TOptionalDataPtr[TDistrKeyIndex];
+    regCachePtr->distributionKey = TOptionalDataPtr[TDistrKeyIndex];
 
     TkeyIndex = TDistrKeyIndex + TDistrKeyFlag;
   }
@@ -2739,7 +2799,8 @@ void Dbtc::execTCKEYREQ(Signal* signal) 
   regCachePtr->keylen = TkeyLength;
   regCachePtr->lenAiInTckeyreq = titcLenAiInTckeyreq;
   regCachePtr->currReclenAi = titcLenAiInTckeyreq;
-
+  regCachePtr->m_special_hash = 
+    localTabptr.p->hasCharAttr | (localTabptr.p->noOfDistrKeys > 0);
   Tdata1 = TAIDataPtr[0];
   Tdata2 = TAIDataPtr[1];
   Tdata3 = TAIDataPtr[2];
@@ -2752,17 +2813,9 @@ void Dbtc::execTCKEYREQ(Signal* signal) 
   regCachePtr->attrinfo15[2] = Tdata4;
   regCachePtr->attrinfo15[3] = Tdata5;
 
-  if (TOperationType == ZREAD) {
+  if (TOperationType == ZREAD || TOperationType == ZREAD_EX) {
     Uint32 TreadCount = c_counters.creadCount;
     jam();
-    regCachePtr->opLock = 0;
-    c_counters.creadCount = TreadCount + 1;
-  } else if(TOperationType == ZREAD_EX){
-    Uint32 TreadCount = c_counters.creadCount;
-    jam();
-    TOperationType = ZREAD;
-    regTcPtr->operation = ZREAD;
-    regCachePtr->opLock = ZUPDATE;
     c_counters.creadCount = TreadCount + 1;
   } else {
     if(regApiPtr->commitAckMarker == RNIL){
@@ -2796,24 +2849,10 @@ void Dbtc::execTCKEYREQ(Signal* signal) 
     c_counters.cwriteCount = TwriteCount + 1;
     switch (TOperationType) {
     case ZUPDATE:
-      jam();
-      if (TattrLen == 0) {
-        //TCKEY_abort(signal, 5);
-        //return;
-      }//if
-      /*---------------------------------------------------------------------*/
-      // The missing break is intentional since we also want to set the opLock 
-      // variable also for updates
-      /*---------------------------------------------------------------------*/
     case ZINSERT:
     case ZDELETE:
-      jam();      
-      regCachePtr->opLock = TOperationType;
-      break;
     case ZWRITE:
       jam();
-      // A write operation is originally an insert operation.
-      regCachePtr->opLock = ZINSERT;  
       break;
     default:
       TCKEY_abort(signal, 9);
@@ -2896,7 +2935,15 @@ void Dbtc::tckeyreq050Lab(Signal* signal
   UintR tnoOfStandby;
   UintR tnodeinfo;
 
+  terrorCode = 0;
+
   hash(signal); /* NOW IT IS TIME TO CALCULATE THE HASH VALUE*/
+  
+  if (unlikely(terrorCode))
+  {
+    releaseAtErrorLab(signal);
+    return;
+  }
 
   CacheRecord * const regCachePtr = cachePtr.p;
   TcConnectRecord * const regTcPtr = tcConnectptr.p;
@@ -2946,6 +2993,15 @@ void Dbtc::tckeyreq050Lab(Signal* signal
     execDIGETNODESREF(signal);
     return;
   }
+  
+  if(ERROR_INSERTED(8050) && signal->theData[3] != getOwnNodeId())
+  {
+    ndbassert(false);
+    signal->theData[1] = 626;
+    execDIGETNODESREF(signal);
+    return;
+  }
+  
   /****************>>*/
   /* DIGETNODESCONF >*/
   /* ***************>*/
@@ -2970,8 +3026,8 @@ void Dbtc::tckeyreq050Lab(Signal* signal
   tnoOfBackup = tnodeinfo & 3;
   tnoOfStandby = (tnodeinfo >> 8) & 3;
  
-  regCachePtr->distributionKey = (tnodeinfo >> 16) & 255;
-  if (Toperation == ZREAD) {
+  regCachePtr->fragmentDistributionKey = (tnodeinfo >> 16) & 255;
+  if (Toperation == ZREAD || Toperation == ZREAD_EX) {
     if (Tdirty == 1) {
       jam();
       /*-------------------------------------------------------------*/
@@ -2980,7 +3036,7 @@ void Dbtc::tckeyreq050Lab(Signal* signal
       /*       NODE IF POSSIBLE TO AVOID UNNECESSARY COMMUNICATION   */
       /*       WITH SIMPLE READS.                                    */
       /*-------------------------------------------------------------*/
-      arrGuard(tnoOfBackup, 4);
+      arrGuard(tnoOfBackup, MAX_REPLICAS);
       UintR Tindex;
       UintR TownNode = cownNodeid;
       for (Tindex = 1; Tindex <= tnoOfBackup; Tindex++) {
@@ -3035,7 +3091,7 @@ void Dbtc::tckeyreq050Lab(Signal* signal
       break;
     default:
       jam();
-      systemErrorLab(signal);
+      systemErrorLab(signal, __LINE__);
       return;
     }//switch
     attrinfoDihReceivedLab(signal);
@@ -3060,8 +3116,6 @@ void Dbtc::attrinfoDihReceivedLab(Signal
   CacheRecord * const regCachePtr = cachePtr.p;
   TcConnectRecord * const regTcPtr = tcConnectptr.p;
   Uint16 Tnode = regTcPtr->tcNodedata[0];
-  Uint16 TscanTakeOverInd = regCachePtr->scanTakeOverInd;
-  Uint16 TscanNode = regCachePtr->scanNode;
 
   TableRecordPtr localTabptr;
   localTabptr.i = regCachePtr->tableref;
@@ -3074,11 +3128,6 @@ void Dbtc::attrinfoDihReceivedLab(Signal
     TCKEY_abort(signal, 58);
     return;
   }
-  if ((TscanTakeOverInd == 1) &&
-      (Tnode != TscanNode)) {
-    TCKEY_abort(signal, 15);
-    return;
-  }//if
   arrGuard(Tnode, MAX_NDB_NODES);
   packLqhkeyreq(signal, calcLqhBlockRef(Tnode));
 }//Dbtc::attrinfoDihReceivedLab()
@@ -3107,10 +3156,11 @@ void Dbtc::sendlqhkeyreq(Signal* signal,
   TcConnectRecord * const regTcPtr = tcConnectptr.p;
   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
   CacheRecord * const regCachePtr = cachePtr.p;
+  Uint32 version = getNodeInfo(refToNode(TBRef)).m_version;
   UintR sig0, sig1, sig2, sig3, sig4, sig5, sig6;
 #ifdef ERROR_INSERT
   if (ERROR_INSERTED(8002)) {
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
   }//if
   if (ERROR_INSERTED(8007)) {
     if (apiConnectptr.p->apiConnectstate == CS_STARTED) {
@@ -3141,7 +3191,7 @@ void Dbtc::sendlqhkeyreq(Signal* signal,
   /* ---------------------------------------------------------------------- */
   // Bit16 == 0 since StoredProcedures are not yet supported.
   /* ---------------------------------------------------------------------- */
-  LqhKeyReq::setDistributionKey(tslrAttrLen, regCachePtr->distributionKey);
+  LqhKeyReq::setDistributionKey(tslrAttrLen, regCachePtr->fragmentDistributionKey);
   LqhKeyReq::setScanTakeOverFlag(tslrAttrLen, regCachePtr->scanTakeOverInd);
 
   Tdata10 = 0;
@@ -3150,7 +3200,12 @@ void Dbtc::sendlqhkeyreq(Signal* signal,
   bool simpleRead = (sig1 == ZREAD && sig0 == ZTRUE);
   LqhKeyReq::setKeyLen(Tdata10, regCachePtr->keylen);
   LqhKeyReq::setLastReplicaNo(Tdata10, regTcPtr->lastReplicaNo);
-  LqhKeyReq::setLockType(Tdata10, regCachePtr->opLock);
+  if (unlikely(version < NDBD_ROWID_VERSION))
+  {
+    Uint32 op = regTcPtr->operation;
+    Uint32 lock = op == ZREAD_EX ? ZUPDATE : op == ZWRITE ? ZINSERT : op;
+    LqhKeyReq::setLockType(Tdata10, lock);
+  }
   /* ---------------------------------------------------------------------- */
   // Indicate Application Reference is present in bit 15
   /* ---------------------------------------------------------------------- */
@@ -3159,6 +3214,8 @@ void Dbtc::sendlqhkeyreq(Signal* signal,
   LqhKeyReq::setInterpretedFlag(Tdata10, regCachePtr->opExec);
   LqhKeyReq::setSimpleFlag(Tdata10, sig0);
   LqhKeyReq::setOperation(Tdata10, sig1);
+  LqhKeyReq::setNoDiskFlag(Tdata10, regCachePtr->m_no_disk_flag);
+
   /* ----------------------------------------------------------------------- 
    * Sequential Number of first LQH = 0, bit 22-23                           
    * IF ATTRIBUTE INFORMATION IS SENT IN TCKEYREQ,
@@ -3377,7 +3434,7 @@ void Dbtc::releaseAttrinfo() 
     regApiPtr->cachePtr = RNIL;
     return;
   }//if
-  systemErrorLab(0);
+  systemErrorLab(0, __LINE__);
   return;
 }//Dbtc::releaseAttrinfo()
 
@@ -3490,7 +3547,7 @@ void Dbtc::execPACKED_SIGNAL(Signal* sig
   Tlength = signal->length();
   if (Tlength > 25) {
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
   }//if
   Uint32* TpackDataPtr;
@@ -3545,7 +3602,7 @@ void Dbtc::execPACKED_SIGNAL(Signal* sig
       Tstep += LqhKeyConf::SignalLength;
       break;
     default:
-      systemErrorLab(signal);
+      systemErrorLab(signal, __LINE__);
       return;
     }//switch
   }//while
@@ -3623,7 +3680,7 @@ void Dbtc::execLQHKEYCONF(Signal* signal
 
 #ifdef ERROR_INSERT
   if (ERROR_INSERTED(8029)) {
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
   }//if
   if (ERROR_INSERTED(8003)) {
     if (regApiPtr->apiConnectstate == CS_STARTED) {
@@ -3876,7 +3933,7 @@ void Dbtc::sendtckeyconf(Signal* signal,
   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);
@@ -4108,7 +4165,7 @@ void Dbtc::diverify010Lab(Signal* signal
   signal->theData[0] = apiConnectptr.i;
   if (ERROR_INSERTED(8022)) {
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
   }//if
   if (TfirstfreeApiConnectCopy != RNIL) {
     seizeApiConnectCopy(signal);
@@ -4456,7 +4513,7 @@ void Dbtc::execCOMMITTED(Signal* signal)
     return;
   }//if
   if (ERROR_INSERTED(8030)) {
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
   }//if
   if (ERROR_INSERTED(8025)) {
     SET_ERROR_INSERT_VALUE(8026);
@@ -4510,7 +4567,7 @@ void Dbtc::execCOMMITTED(Signal* signal)
   }//if
   if (ERROR_INSERTED(8020)) {
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
   }//if
   /*-------------------------------------------------------*/
   /* THE ENTIRE TRANSACTION IS NOW COMMITED                */
@@ -4557,8 +4614,10 @@ void Dbtc::sendApiCommit(Signal* signal)
     }
     commitConf->transId1 = regApiPtr->transid[0];
     commitConf->transId2 = regApiPtr->transid[1];
-    
-    sendSignal(regApiPtr->ndbapiBlockref, GSN_TC_COMMITCONF, signal, 3, JBB);
+    commitConf->gci = regApiPtr->globalcheckpointid;
+
+    sendSignal(regApiPtr->ndbapiBlockref, GSN_TC_COMMITCONF, signal,
+	       TcCommitConf::SignalLength, JBB);
   } else if (regApiPtr->returnsignal == RS_NO_RETURN) {
     jam();
   } else {
@@ -4747,13 +4806,14 @@ Dbtc::execTC_COMMIT_ACK(Signal* signal){
   key.transid2 = signal->theData[1];
 
   CommitAckMarkerPtr removedMarker;
-  m_commitAckMarkerHash.release(removedMarker, key);
+  m_commitAckMarkerHash.remove(removedMarker, key);
   if (removedMarker.i == RNIL) {
     jam();
-    warningHandlerLab(signal);
+    warningHandlerLab(signal, __LINE__);
     return;
   }//if
   sendRemoveMarkers(signal, removedMarker.p);
+  m_commitAckMarkerPool.release(removedMarker);
 }
 
 void
@@ -4812,7 +4872,7 @@ void Dbtc::execCOMPLETED(Signal* signal)
 
 #ifdef ERROR_INSERT
   if (ERROR_INSERTED(8031)) {
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
   }//if
   if (ERROR_INSERTED(8019)) {
     CLEAR_ERROR_INSERT_VALUE;
@@ -4871,7 +4931,7 @@ void Dbtc::execCOMPLETED(Signal* signal)
   }//if
   if (ERROR_INSERTED(8021)) {
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
   }//if
   apiConnectptr = localApiConnectptr;
   releaseTransResources(signal);
@@ -5098,6 +5158,19 @@ void Dbtc::execLQHKEYREF(Signal* signal)
 	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   < */
       /* *************** */
@@ -5255,8 +5328,9 @@ void Dbtc::execTC_COMMITREQ(Signal* sign
         commitConf->apiConnectPtr = apiConnectPtr;
         commitConf->transId1 = transId1;
         commitConf->transId2 = transId2;
-        
-        sendSignal(apiBlockRef, GSN_TC_COMMITCONF, signal, 3, JBB);
+        commitConf->gci = 0;
+        sendSignal(apiBlockRef, GSN_TC_COMMITCONF, signal, 
+		   TcCommitConf::SignalLength, JBB);
         
         regApiPtr->returnsignal = RS_NO_RETURN;
         releaseAbortResources(signal);
@@ -5311,7 +5385,7 @@ void Dbtc::execTC_COMMITREQ(Signal* sign
       return;
       break;
     default:
-      warningHandlerLab(signal);
+      warningHandlerLab(signal, __LINE__);
       return;
     }//switch
     TcCommitRef * const commitRef = (TcCommitRef*)&signal->theData[0];
@@ -5324,7 +5398,7 @@ void Dbtc::execTC_COMMITREQ(Signal* sign
     return;
   } else /** apiConnectptr.i < capiConnectFilesize */ {
     jam();
-    warningHandlerLab(signal);
+    warningHandlerLab(signal, __LINE__);
     return;
   }
 }//Dbtc::execTC_COMMITREQ()
@@ -5420,12 +5494,12 @@ void Dbtc::execTCROLLBACKREQ(Signal* sig
 
 TC_ROLL_warning:
   jam();
-  warningHandlerLab(signal);
+  warningHandlerLab(signal, __LINE__);
   return;
 
 TC_ROLL_system_error:
   jam();
-  systemErrorLab(signal);
+  systemErrorLab(signal, __LINE__);
   return;
 }//Dbtc::execTCROLLBACKREQ()
 
@@ -5666,7 +5740,7 @@ void Dbtc::errorReport(Signal* signal, i
     jam();
     break;
   }//switch
-  systemErrorLab(signal);
+  systemErrorLab(signal, __LINE__);
   return;
 }//Dbtc::errorReport()
 
@@ -5723,7 +5797,7 @@ void Dbtc::execABORTED(Signal* signal) 
   }//if
   if (ERROR_INSERTED(8024)) {
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
   }//if
 
   /**
@@ -5896,12 +5970,12 @@ ABORT020:
   case OS_ABORT_SENT:
     jam();
     DEBUG("ABORT_SENT state in abort015Lab(), not expected");
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
   default:
     jam();
     DEBUG("tcConnectstate = " << tcConnectptr.p->tcConnectstate);
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
   }//switch
 
@@ -6017,7 +6091,7 @@ void Dbtc::checkStartTimeout(Signal* sig
       ctimeOutMissedHeartbeats++;
       if (ctimeOutMissedHeartbeats > 100){
 	jam();
-	systemErrorLab(signal);
+	systemErrorLab(signal, __LINE__);
       }
     }
     ctimeOutCheckLastHeartbeat = ctimeOutCheckHeartbeat;
@@ -6206,7 +6280,7 @@ void Dbtc::timeOutFoundLab(Signal* signa
     if (((ctcTimer - getApiConTimer(apiConnectptr.i)) > (10 * ctimeOutValue)) &&
         ((ctcTimer - getApiConTimer(apiConnectptr.i)) > 500)) {
         jam();
-        systemErrorLab(signal);
+        systemErrorLab(signal, __LINE__);
     }//if
     break;
   case CS_COMMIT_SENT:
@@ -6256,7 +6330,7 @@ void Dbtc::timeOutFoundLab(Signal* signa
     jam();
     tcConnectptr.i = apiConnectptr.p->currentTcConnect;
     ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
-    arrGuard(apiConnectptr.p->currentReplicaNo, 4);
+    arrGuard(apiConnectptr.p->currentReplicaNo, MAX_REPLICAS);
     hostptr.i = tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo];
     ptrCheckGuard(hostptr, chostFilesize, hostRecord);
     if (hostptr.p->hostStatus == HS_ALIVE) {
@@ -6282,7 +6356,7 @@ void Dbtc::timeOutFoundLab(Signal* signa
     jam();
     tcConnectptr.i = apiConnectptr.p->currentTcConnect;
     ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
-    arrGuard(apiConnectptr.p->currentReplicaNo, 4);
+    arrGuard(apiConnectptr.p->currentReplicaNo, MAX_REPLICAS);
     hostptr.i = tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo];
     ptrCheckGuard(hostptr, chostFilesize, hostRecord);
     if (hostptr.p->hostStatus == HS_ALIVE) {
@@ -6308,7 +6382,7 @@ void Dbtc::timeOutFoundLab(Signal* signa
     jam();
     tcConnectptr.i = apiConnectptr.p->currentTcConnect;
     ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
-    arrGuard(apiConnectptr.p->currentReplicaNo, 4);
+    arrGuard(apiConnectptr.p->currentReplicaNo, MAX_REPLICAS);
     hostptr.i = tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo];
     ptrCheckGuard(hostptr, chostFilesize, hostRecord);
     if (hostptr.p->hostStatus == HS_ALIVE) {
@@ -6354,7 +6428,7 @@ void Dbtc::timeOutFoundLab(Signal* signa
     /*       AN IMPOSSIBLE STATE IS SET. CRASH THE SYSTEM.              */
     /*------------------------------------------------------------------*/
     DEBUG("State = " << apiConnectptr.p->apiConnectstate);
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
   }//switch
   return;
@@ -6483,7 +6557,7 @@ void Dbtc::sendAbortedAfterTimeout(Signa
       // in time to the ABORT signal we will declare it as dead.
       /*------------------------------------------------------------------*/
       UintR Ti = 0;
-      arrGuard(tcConnectptr.p->noOfNodes, 4);
+      arrGuard(tcConnectptr.p->noOfNodes, MAX_REPLICAS+1);
       for (Ti = 0; Ti < tcConnectptr.p->noOfNodes; Ti++) {
         jam();
         if (tcConnectptr.p->tcNodedata[Ti] != 0) {
@@ -6662,7 +6736,7 @@ void Dbtc::execSCAN_HBREP(Signal* signal
     break;
   default:
     DEBUG("execSCAN_HBREP: scanFragState="<<scanFragptr.p->scanFragState);
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     break;
   }
 
@@ -6760,7 +6834,7 @@ void Dbtc::timeOutFoundFragLab(Signal* s
      * version. In a release version we will simply set the time-out to zero.
      *-----------------------------------------------------------------------*/
 #ifdef VM_TRACE
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
 #endif
     scanFragptr.p->stopFragTimer();
     break;
@@ -6769,7 +6843,7 @@ void Dbtc::timeOutFoundFragLab(Signal* s
     /*-----------------------------------------------------------------------
      * Non-existent state. Crash.
      *-----------------------------------------------------------------------*/
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     break;
   }//switch
   
@@ -7053,7 +7127,6 @@ void Dbtc::execTAKE_OVERTCCONF(Signal* s
     return;
   }
   
-  
   checkNodeFailComplete(signal, hostptr.i, HostRecord::NF_TAKEOVER);
 }//Dbtc::execTAKE_OVERTCCONF()
 
@@ -7281,7 +7354,7 @@ void Dbtc::completeTransAtTakeOverDoLast
   arrGuard(TtakeOverInd, MAX_NDB_NODES);
   if (tcNodeFailptr.p->takeOverProcState[TtakeOverInd] != ZTAKE_OVER_ACTIVE) {
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
   }//if
   tcNodeFailptr.p->takeOverProcState[TtakeOverInd] = ZTAKE_OVER_IDLE;
@@ -7402,7 +7475,7 @@ void Dbtc::completeTransAtTakeOverDoOne(
     break;
   default:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
   }//switch
 }//Dbtc::completeTransAtTakeOverDoOne()
@@ -7479,7 +7552,7 @@ void Dbtc::execABORTCONF(Signal* signal)
     warningReport(signal, 18);
     return;
   }//if
-  arrGuard(apiConnectptr.p->currentReplicaNo, 4);
+  arrGuard(apiConnectptr.p->currentReplicaNo, MAX_REPLICAS);
   if (tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo] !=
       tnodeid) {
     warningReport(signal, 19);
@@ -7495,7 +7568,7 @@ void Dbtc::toAbortHandlingLab(Signal* si
   do {
     if (tcurrentReplicaNo != (Uint8)Z8NIL) {
       jam();
-      arrGuard(tcurrentReplicaNo, 4);
+      arrGuard(tcurrentReplicaNo, MAX_REPLICAS);
       const LqhTransConf::OperationStatus stat = 
 	(LqhTransConf::OperationStatus)
 	tcConnectptr.p->failData[tcurrentReplicaNo];
@@ -7528,7 +7601,7 @@ void Dbtc::toAbortHandlingLab(Signal* si
         break;
       default:
         jam();
-        systemErrorLab(signal);
+        systemErrorLab(signal, __LINE__);
         return;
       }//switch
     }//if
@@ -7629,7 +7702,7 @@ void Dbtc::execCOMMITCONF(Signal* signal
     warningReport(signal, 10);
     return;
   }//if
-  arrGuard(apiConnectptr.p->currentReplicaNo, 4);
+  arrGuard(apiConnectptr.p->currentReplicaNo, MAX_REPLICAS);
   if (tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo] !=
       tnodeid) {
     warningReport(signal, 11);
@@ -7637,7 +7710,7 @@ void Dbtc::execCOMMITCONF(Signal* signal
   }//if
   if (ERROR_INSERTED(8026)) {
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
   }//if
   tcurrentReplicaNo = (Uint8)Z8NIL;
   tcConnectptr.p->tcConnectstate = OS_COMMITTED;
@@ -7649,7 +7722,7 @@ void Dbtc::toCommitHandlingLab(Signal* s
   do {
     if (tcurrentReplicaNo != (Uint8)Z8NIL) {
       jam();
-      arrGuard(tcurrentReplicaNo, 4);
+      arrGuard(tcurrentReplicaNo, MAX_REPLICAS);
       switch (tcConnectptr.p->failData[tcurrentReplicaNo]) {
       case LqhTransConf::InvalidStatus:
         jam();
@@ -7687,7 +7760,7 @@ void Dbtc::toCommitHandlingLab(Signal* s
         break;
       default:
         jam();
-        systemErrorLab(signal);
+        systemErrorLab(signal, __LINE__);
         return;
         break;
       }//switch
@@ -7774,7 +7847,7 @@ void Dbtc::execCOMPLETECONF(Signal* sign
     warningReport(signal, 14);
     return;
   }//if
-  arrGuard(apiConnectptr.p->currentReplicaNo, 4);
+  arrGuard(apiConnectptr.p->currentReplicaNo, MAX_REPLICAS);
   if (tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo] !=
       tnodeid) {
     warningReport(signal, 15);
@@ -7782,7 +7855,7 @@ void Dbtc::execCOMPLETECONF(Signal* sign
   }//if
   if (ERROR_INSERTED(8028)) {
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
   }//if
   tcConnectptr.p->tcConnectstate = OS_COMPLETED;
   tcurrentReplicaNo = (Uint8)Z8NIL;
@@ -7794,7 +7867,7 @@ void Dbtc::toCompleteHandlingLab(Signal*
   do {
     if (tcurrentReplicaNo != (Uint8)Z8NIL) {
       jam();
-      arrGuard(tcurrentReplicaNo, 4);
+      arrGuard(tcurrentReplicaNo, MAX_REPLICAS);
       switch (tcConnectptr.p->failData[tcurrentReplicaNo]) {
       case LqhTransConf::InvalidStatus:
         jam();
@@ -7897,7 +7970,7 @@ FAF_LOOP:
     jam();
     if (cfirstfreeApiConnectFail == RNIL) {
       jam();
-      systemErrorLab(signal);
+      systemErrorLab(signal, __LINE__);
       return;
     }//if
     seizeApiConnectFail(signal);
@@ -7941,7 +8014,7 @@ void Dbtc::findTcConnectFail(Signal* sig
       jam();
       if (cfirstfreeTcConnectFail == RNIL) {
         jam();
-        systemErrorLab(signal);
+        systemErrorLab(signal, __LINE__);
         return;
       }//if
       seizeTcConnectFail(signal);
@@ -8001,7 +8074,7 @@ void Dbtc::initApiConnectFail(Signal* si
     break;
   default:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
   }//if
   apiConnectptr.p->commitAckMarker = RNIL;
   if(LqhTransConf::getMarkerFlag(treqinfo)){
@@ -8084,6 +8157,7 @@ void Dbtc::setupFailData(Signal* signal)
     case OS_PREPARED:
     case OS_COMMITTING:
       jam();
+      arrGuard(tcConnectptr.p->lastReplicaNo, MAX_REPLICAS);
       for (tindex = 0; tindex <= tcConnectptr.p->lastReplicaNo; tindex++) {
 	jam();
 	/*-------------------------------------------------------------------
@@ -8091,13 +8165,13 @@ void Dbtc::setupFailData(Signal* signal)
 	 * IN THIS CASE ALL LQH'S ARE PREPARED AND WAITING FOR 
 	 * COMMIT/ABORT DECISION.                 
 	 *------------------------------------------------------------------*/
-	arrGuard(tindex, 4);
 	tcConnectptr.p->failData[tindex] = LqhTransConf::Prepared;
       }//for
       break;
     case OS_COMMITTED:
     case OS_COMPLETING:
       jam();
+      arrGuard(tcConnectptr.p->lastReplicaNo, MAX_REPLICAS);
       for (tindex = 0; tindex <= tcConnectptr.p->lastReplicaNo; tindex++) {
 	jam();
 	/*-------------------------------------------------------------------
@@ -8105,25 +8179,24 @@ void Dbtc::setupFailData(Signal* signal)
 	 * IN THIS CASE ALL LQH'S ARE COMMITTED AND WAITING FOR 
 	 * COMPLETE MESSAGE.                     
 	 *------------------------------------------------------------------*/
-	arrGuard(tindex, 4);
 	tcConnectptr.p->failData[tindex] = LqhTransConf::Committed;
       }//for
       break;
     case OS_COMPLETED:
       jam();
+      arrGuard(tcConnectptr.p->lastReplicaNo, MAX_REPLICAS);
       for (tindex = 0; tindex <= tcConnectptr.p->lastReplicaNo; tindex++) {
 	jam();
 	/*-------------------------------------------------------------------
 	 * KEYDATA IS USED TO KEEP AN INDICATION OF STATE IN LQH. 
 	 * IN THIS CASE ALL LQH'S ARE COMPLETED.
 	 *-------------------------------------------------------------------*/
-	arrGuard(tindex, 4);
 	tcConnectptr.p->failData[tindex] = LqhTransConf::InvalidStatus;
       }//for
       break;
     default:
       jam();
-      sendSystemError(signal);
+      sendSystemError(signal, __LINE__);
       break;
     }//switch
     if (tabortInd != ZCOMMIT_SETUP) {
@@ -8210,7 +8283,7 @@ void Dbtc::updateApiStateFail(Signal* si
       break;
     default:
       jam();
-      systemErrorLab(signal);
+      systemErrorLab(signal, __LINE__);
       break;
     }//switch
     break;
@@ -8233,7 +8306,7 @@ void Dbtc::updateApiStateFail(Signal* si
       break;
     default:
       jam();
-      systemErrorLab(signal);
+      systemErrorLab(signal, __LINE__);
       break;
     }//switch
     break;
@@ -8243,7 +8316,7 @@ void Dbtc::updateApiStateFail(Signal* si
     case CS_FAIL_COMMITTING:
     case CS_FAIL_COMMITTED:
       jam();
-      systemErrorLab(signal);
+      systemErrorLab(signal, __LINE__);
       break;
     case CS_FAIL_PREPARED:
       jam();
@@ -8256,7 +8329,7 @@ void Dbtc::updateApiStateFail(Signal* si
       break;
     default:
       jam();
-      systemErrorLab(signal);
+      systemErrorLab(signal, __LINE__);
       break;
     }//switch
     break;
@@ -8265,7 +8338,7 @@ void Dbtc::updateApiStateFail(Signal* si
     break;
   default:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     break;
   }//switch
 }//Dbtc::updateApiStateFail()
@@ -8383,14 +8456,14 @@ void Dbtc::releaseAtErrorLab(Signal* sig
   abortErrorLab(signal);
 }//Dbtc::releaseAtErrorLab()
 
-void Dbtc::warningHandlerLab(Signal* signal) 
+void Dbtc::warningHandlerLab(Signal* signal, int line) 
 {
   ndbassert(false);
 }//Dbtc::warningHandlerLab()
 
-void Dbtc::systemErrorLab(Signal* signal) 
+void Dbtc::systemErrorLab(Signal* signal, int line) 
 {
-  progError(0, 0);
+  progError(line, NDBD_EXIT_NDBREQUIRE);
 }//Dbtc::systemErrorLab()
 
 
@@ -8491,7 +8564,7 @@ void Dbtc::systemErrorLab(Signal* signal
 void Dbtc::execSCAN_TABREQ(Signal* signal) 
 {
   const ScanTabReq * const scanTabReq = (ScanTabReq *)&signal->theData[0];
-  const Uint32 reqinfo = scanTabReq->requestInfo;
+  const Uint32 ri = scanTabReq->requestInfo;
   const Uint32 aiLength = (scanTabReq->attrLenKeyLen & 0xFFFF);
   const Uint32 keyLen = scanTabReq->attrLenKeyLen >> 16;
   const Uint32 schemaVersion = scanTabReq->tableSchemaVersion;
@@ -8501,8 +8574,8 @@ void Dbtc::execSCAN_TABREQ(Signal* signa
   const Uint32 buddyPtr = (tmpXX == 0xFFFFFFFF ? RNIL : tmpXX);
   Uint32 currSavePointId = 0;
   
-  Uint32 scanConcurrency = scanTabReq->getParallelism(reqinfo);
-  Uint32 noOprecPerFrag = ScanTabReq::getScanBatch(reqinfo);
+  Uint32 scanConcurrency = scanTabReq->getParallelism(ri);
+  Uint32 noOprecPerFrag = ScanTabReq::getScanBatch(ri);
   Uint32 scanParallel = scanConcurrency;
   Uint32 errCode;
   ScanRecordPtr scanptr;
@@ -8520,7 +8593,7 @@ void Dbtc::execSCAN_TABREQ(Signal* signa
   if (apiConnectptr.i >= capiConnectFilesize)
   {
     jam();
-    warningHandlerLab(signal);
+    warningHandlerLab(signal, __LINE__);
     return;
   }//if
 
@@ -8586,6 +8659,8 @@ void Dbtc::execSCAN_TABREQ(Signal* signa
   seizeCacheRecord(signal);
   cachePtr.p->keylen = keyLen;
   cachePtr.p->save1 = 0;
+  cachePtr.p->distributionKey = scanTabReq->distributionKey;
+  cachePtr.p->distributionKeyIndicator= ScanTabReq::getDistributionKeyFlag(ri);
   scanptr = seizeScanrec(signal);
 
   ndbrequire(transP->apiScanRec == RNIL);
@@ -8672,6 +8747,7 @@ void Dbtc::initScanrec(ScanRecordPtr sca
 		       UintR scanParallel,
 		       UintR noOprecPerFrag) 
 {
+  const UintR ri = scanTabReq->requestInfo;
   scanptr.p->scanTcrec = tcConnectptr.i;
   scanptr.p->scanApiRec = apiConnectptr.i;
   scanptr.p->scanAiLength = scanTabReq->attrLenKeyLen & 0xFFFF;
@@ -8684,13 +8760,15 @@ void Dbtc::initScanrec(ScanRecordPtr sca
   scanptr.p->batch_size_rows = noOprecPerFrag;
 
   Uint32 tmp = 0;
-  const UintR ri = scanTabReq->requestInfo;
   ScanFragReq::setLockMode(tmp, ScanTabReq::getLockMode(ri));
   ScanFragReq::setHoldLockFlag(tmp, ScanTabReq::getHoldLockFlag(ri));
   ScanFragReq::setKeyinfoFlag(tmp, ScanTabReq::getKeyinfoFlag(ri));
   ScanFragReq::setReadCommittedFlag(tmp,ScanTabReq::getReadCommittedFlag(ri));
   ScanFragReq::setRangeScanFlag(tmp, ScanTabReq::getRangeScanFlag(ri));
+  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;
@@ -8800,14 +8878,46 @@ void Dbtc::diFcountReqLab(Signal* signal
     return;
   }
 
+  scanptr.p->scanNextFragId = 0;
+  scanptr.p->m_booked_fragments_count= 0;
   scanptr.p->scanState = ScanRecord::WAIT_FRAGMENT_COUNT;
-  /*************************************************
-   * THE FIRST STEP TO RECEIVE IS SUCCESSFULLY COMPLETED. 
-   * WE MUST FIRST GET THE NUMBER OF  FRAGMENTS IN THE TABLE.
-   ***************************************************/
-  signal->theData[0] = tcConnectptr.p->dihConnectptr;
-  signal->theData[1] = scanptr.p->scanTableref;
-  sendSignal(cdihblockref, GSN_DI_FCOUNTREQ, signal, 2, JBB);
+  
+  if(!cachePtr.p->distributionKeyIndicator)
+  {
+    jam();
+    /*************************************************
+     * THE FIRST STEP TO RECEIVE IS SUCCESSFULLY COMPLETED. 
+     * WE MUST FIRST GET THE NUMBER OF  FRAGMENTS IN THE TABLE.
+     ***************************************************/
+    DihFragCountReq * const req = (DihFragCountReq*)signal->getDataPtrSend();
+    req->m_connectionData = tcConnectptr.p->dihConnectptr;
+    req->m_tableRef = scanptr.p->scanTableref;
+    sendSignal(cdihblockref, GSN_DI_FCOUNTREQ, signal, 
+               DihFragCountReq::SignalLength, JBB);
+  }
+  else 
+  {
+    signal->theData[0] = tcConnectptr.p->dihConnectptr;
+    signal->theData[1] = tabPtr.i;
+    signal->theData[2] = cachePtr.p->distributionKey;
+    EXECUTE_DIRECT(DBDIH, GSN_DIGETNODESREQ, signal, 3);
+    UintR TerrorIndicator = signal->theData[0];
+    jamEntry();
+    if (TerrorIndicator != 0) {
+      DihFragCountRef * const ref = (DihFragCountRef*)signal->getDataPtr();
+      ref->m_connectionData = tcConnectptr.i;
+      ref->m_error = signal->theData[1];
+      execDI_FCOUNTREF(signal);
+      return;
+    }
+    
+    UintR Tdata1 = signal->theData[1];
+    scanptr.p->scanNextFragId = Tdata1;
+    DihFragCountConf * const conf = (DihFragCountConf*)signal->getDataPtr();
+    conf->m_connectionData = tcConnectptr.i;
+    conf->m_fragmentCount = 1; // Frag count
+    execDI_FCOUNTCONF(signal);
+  }
   return;
 }//Dbtc::diFcountReqLab()
 
@@ -8823,8 +8933,9 @@ void Dbtc::diFcountReqLab(Signal* signal
 void Dbtc::execDI_FCOUNTCONF(Signal* signal) 
 {
   jamEntry();
-  tcConnectptr.i = signal->theData[0];
-  const UintR tfragCount = signal->theData[1];
+  DihFragCountConf * const conf = (DihFragCountConf*)signal->getDataPtr();
+  tcConnectptr.i = conf->m_connectionData;
+  Uint32 tfragCount = conf->m_fragmentCount;
   ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
   apiConnectptr.i = tcConnectptr.p->apiConnect;
   ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
@@ -8859,24 +8970,17 @@ void Dbtc::execDI_FCOUNTCONF(Signal* sig
     return;
   }
 
-  if(scanptr.p->scanParallel > tfragCount){
-    jam();
-    abortScanLab(signal, scanptr, ZTOO_HIGH_CONCURRENCY_ERROR);
-    return;
-  }
-  
   scanptr.p->scanParallel = tfragCount;
   scanptr.p->scanNoFrag = tfragCount;
-  scanptr.p->scanNextFragId = 0;
   scanptr.p->scanState = ScanRecord::RUNNING;
 
   setApiConTimer(apiConnectptr.i, 0, __LINE__);
   updateBuddyTimer(apiConnectptr);
   
   ScanFragRecPtr ptr;
-  ScanFragList list(c_scan_frag_pool, 
-		    scanptr.p->m_running_scan_frags);
-  for (list.first(ptr); !ptr.isNull(); list.next(ptr)){
+  ScanFragList list(c_scan_frag_pool, scanptr.p->m_running_scan_frags);
+  for (list.first(ptr); !ptr.isNull() && tfragCount; 
+       list.next(ptr), tfragCount--){
     jam();
 
     ptr.p->lqhBlockref = 0;
@@ -8891,6 +8995,22 @@ void Dbtc::execDI_FCOUNTCONF(Signal* sig
     signal->theData[3] = ptr.p->scanFragId;
     sendSignal(cdihblockref, GSN_DIGETPRIMREQ, signal, 4, JBB);
   }//for
+
+  ScanFragList queued(c_scan_frag_pool, scanptr.p->m_queued_scan_frags);
+  for (; !ptr.isNull();)
+  {
+    ptr.p->m_ops = 0;
+    ptr.p->m_totalLen = 0;
+    ptr.p->m_scan_frag_conf_status = 1;
+    ptr.p->scanFragState = ScanFragRec::QUEUED_FOR_DELIVERY;
+    ptr.p->stopFragTimer();
+
+    ScanFragRecPtr tmp = ptr;
+    list.next(ptr);
+    list.remove(tmp);
+    queued.add(tmp);
+    scanptr.p->m_queued_count++;
+  }
 }//Dbtc::execDI_FCOUNTCONF()
 
 /******************************************************
@@ -8899,9 +9019,10 @@ void Dbtc::execDI_FCOUNTCONF(Signal* sig
 void Dbtc::execDI_FCOUNTREF(Signal* signal) 
 {
   jamEntry();
-  tcConnectptr.i = signal->theData[0];
+  DihFragCountRef * const ref = (DihFragCountRef*)signal->getDataPtr();
+  tcConnectptr.i = ref->m_connectionData;
   ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
-  const Uint32 errCode = signal->theData[1];
+  const Uint32 errCode = ref->m_error;
   apiConnectptr.i = tcConnectptr.p->apiConnect;
   ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
   ScanRecordPtr scanptr;
@@ -9131,7 +9252,7 @@ void Dbtc::execSCAN_FRAGREF(Signal* sign
   transid1 = transid1 | transid2;
   if (transid1 != 0) {
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
   }//if
 
   /**
@@ -9227,7 +9348,7 @@ void Dbtc::execSCAN_FRAGCONF(Signal* sig
   transid1 = transid1 | transid2;
   if (transid1 != 0) {
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
   }//if
   
   ndbrequire(scanFragptr.p->scanFragState == ScanFragRec::LQH_ACTIVE);
@@ -9252,7 +9373,7 @@ void Dbtc::execSCAN_FRAGCONF(Signal* sig
   }
 
   if(noCompletedOps == 0 && status != 0 && 
-     scanptr.p->scanNextFragId < scanptr.p->scanNoFrag){
+     scanptr.p->scanNextFragId+scanptr.p->m_booked_fragments_count < scanptr.p->scanNoFrag){
     /**
      * Start on next fragment
      */
@@ -9315,7 +9436,7 @@ void Dbtc::execSCAN_NEXTREQ(Signal* sign
   apiConnectptr.i = req->apiConnectPtr;
   if (apiConnectptr.i >= capiConnectFilesize) {
     jam();
-    warningHandlerLab(signal);
+    warningHandlerLab(signal, __LINE__);
     return;
   }//if
   ptrAss(apiConnectptr, apiConnectRecord);
@@ -9422,6 +9543,9 @@ void Dbtc::execSCAN_NEXTREQ(Signal* sign
        */
       jam();
       ndbrequire(scanptr.p->scanNextFragId < scanptr.p->scanNoFrag);
+      jam();
+      ndbassert(scanptr.p->m_booked_fragments_count);
+      scanptr.p->m_booked_fragments_count--;
       scanFragptr.p->scanFragState = ScanFragRec::WAIT_GET_PRIMCONF; 
       
       tcConnectptr.i = scanptr.p->scanTcrec;
@@ -9663,8 +9787,9 @@ void Dbtc::sendScanTabConf(Signal* signa
     jam();
     ops += 21;
   }
-
-  Uint32 left = scanPtr.p->scanNoFrag - scanPtr.p->scanNextFragId;
+  
+  int left = scanPtr.p->scanNoFrag - scanPtr.p->scanNextFragId;
+  Uint32 booked = scanPtr.p->m_booked_fragments_count;
   
   ScanTabConf * conf = (ScanTabConf*)&signal->theData[0];
   conf->apiConnectPtr = apiConnectptr.p->ndbapiConnect;
@@ -9680,8 +9805,10 @@ void Dbtc::sendScanTabConf(Signal* signa
       ScanFragRecPtr curr = ptr; // Remove while iterating...
       queued.next(ptr);
       
-      bool done = curr.p->m_scan_frag_conf_status && --left;
-
+      bool done = curr.p->m_scan_frag_conf_status && (left <= (int)booked);
+      if(curr.p->m_scan_frag_conf_status)
+	booked++;
+      
       * ops++ = curr.p->m_apiPtr;
       * ops++ = done ? RNIL : curr.i;
       * ops++ = (curr.p->m_totalLen << 10) + curr.p->m_ops;
@@ -9699,8 +9826,10 @@ void Dbtc::sendScanTabConf(Signal* signa
     }
   }
   
+  scanPtr.p->m_booked_fragments_count = booked;
   if(scanPtr.p->m_delivered_scan_frags.isEmpty() && 
-     scanPtr.p->m_running_scan_frags.isEmpty()){
+     scanPtr.p->m_running_scan_frags.isEmpty())
+  {
     conf->requestInfo = op_count | ScanTabConf::EndOfData;    
     releaseScanResources(scanPtr);
   }
@@ -9959,7 +10088,7 @@ void Dbtc::initialiseRecordsLab(Signal* 
     break;
   default:
     jam();
-    systemErrorLab(signal);
+    systemErrorLab(signal, __LINE__);
     return;
     break;
   }//switch
@@ -10015,6 +10144,10 @@ void Dbtc::initTable(Signal* signal) 
     tabptr.p->tableType = 0;
     tabptr.p->enabled = false;
     tabptr.p->dropping = false;
+    tabptr.p->noOfKeyAttr = 0;
+    tabptr.p->hasCharAttr = 0;
+    tabptr.p->noOfDistrKeys = 0;
+    tabptr.p->hasVarKeys = 0;
   }//for
 }//Dbtc::initTable()
 
@@ -10194,7 +10327,7 @@ void Dbtc::releaseAbortResources(Signal*
     if(!ok){
       jam();
       ndbout_c("returnsignal = %d", apiConnectptr.p->returnsignal);
-      sendSystemError(signal);
+      sendSystemError(signal, __LINE__);
     }//if
 
   }
@@ -10422,9 +10555,9 @@ void Dbtc::sendKeyinfo(Signal* signal, B
   sendSignal(TBRef, GSN_KEYINFO, signal, 3 + len, JBB);
 }//Dbtc::sendKeyinfo()
 
-void Dbtc::sendSystemError(Signal* signal) 
+void Dbtc::sendSystemError(Signal* signal, int line) 
 {
-  progError(0, 0);
+  progError(line, NDBD_EXIT_NDBREQUIRE);
 }//Dbtc::sendSystemError()
 
 /* ========================================================================= */
@@ -10445,7 +10578,7 @@ void Dbtc::unlinkGcp(Signal* signal) 
      * WE ARE TRYING TO REMOVE A GLOBAL CHECKPOINT WHICH WAS NOT THE OLDEST. 
      * THIS IS A SYSTEM ERROR.                                              
      * ------------------------------------------------------------------- */
-    sendSystemError(signal);
+    sendSystemError(signal, __LINE__);
   }//if
   gcpPtr.p->nextGcp = cfirstfreeGcp;
   cfirstfreeGcp = gcpPtr.i;
@@ -11079,7 +11212,6 @@ void Dbtc::execFIRE_TRIG_ORD(Signal* sig
   ApiConnectRecordPtr transPtr;
   TcConnectRecord *localTcConnectRecord = tcConnectRecord;
   TcConnectRecordPtr opPtr;
-
   /**
    * TODO
    * Check transid,
@@ -11093,6 +11225,7 @@ void Dbtc::execFIRE_TRIG_ORD(Signal* sig
     
     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;
@@ -11218,7 +11351,7 @@ void Dbtc::execTCINDXREQ(Signal* signal)
 {
   jamEntry();
 
-  TcIndxReq * const tcIndxReq =  (TcIndxReq *)signal->getDataPtr();
+  TcKeyReq * const tcIndxReq =  (TcKeyReq *)signal->getDataPtr();
   const UintR TapiIndex = tcIndxReq->apiConnectPtr;
   Uint32 tcIndxRequestInfo = tcIndxReq->requestInfo;
   Uint32 startFlag = tcIndxReq->getStartFlag(tcIndxRequestInfo);
@@ -11229,7 +11362,7 @@ void Dbtc::execTCINDXREQ(Signal* signal)
   transPtr.i = TapiIndex;
   if (transPtr.i >= capiConnectFilesize) {
     jam();
-    warningHandlerLab(signal);
+    warningHandlerLab(signal, __LINE__);
     return;
   }//if
   ptrAss(transPtr, apiConnectRecord);
@@ -11269,7 +11402,7 @@ void Dbtc::execTCINDXREQ(Signal* signal)
 
   // If operation is readTupleExclusive or updateTuple then read index 
   // table with exclusive lock
-  Uint32 indexLength = TcIndxReq::getIndexLength(tcIndxRequestInfo);
+  Uint32 indexLength = TcKeyReq::getKeyLength(tcIndxRequestInfo);
   Uint32 attrLength = tcIndxReq->attrLen;
   indexOp->expectedKeyInfo = indexLength;
   Uint32 includedIndexLength = MIN(indexLength, indexBufSize);
@@ -11304,7 +11437,7 @@ void Dbtc::sendTcIndxConf(Signal* signal
   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);
@@ -11383,7 +11516,7 @@ void Dbtc::execINDXKEYINFO(Signal* signa
   transPtr.i = TconnectIndex;
   if (transPtr.i >= capiConnectFilesize) {
     jam();
-    warningHandlerLab(signal);
+    warningHandlerLab(signal, __LINE__);
     return;
   }//if
   ptrAss(transPtr, apiConnectRecord);
@@ -11416,7 +11549,7 @@ void Dbtc::execINDXATTRINFO(Signal* sign
   transPtr.i = TconnectIndex;
   if (transPtr.i >= capiConnectFilesize) {
     jam();
-    warningHandlerLab(signal);
+    warningHandlerLab(signal, __LINE__);
     return;
   }//if
   ptrAss(transPtr, apiConnectRecord);
@@ -11574,14 +11707,14 @@ void Dbtc::execTCKEYCONF(Signal* signal)
   case(IOS_NOOP): {
     jam();
     // Should never happen, abort
-    TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend();
+    TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
 
     tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData;
     tcIndxRef->transId[0] = regApiPtr->transid[0];
     tcIndxRef->transId[1] = regApiPtr->transid[1];
     tcIndxRef->errorCode = 4349;    
     sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, 
-	       TcIndxRef::SignalLength, JBB);
+	       TcKeyRef::SignalLength, JBB);
     return;
   }
   case(IOS_INDEX_ACCESS): {
@@ -11593,14 +11726,14 @@ void Dbtc::execTCKEYCONF(Signal* signal)
   case(IOS_INDEX_ACCESS_WAIT_FOR_TRANSID_AI): {
     jam();
     // Double TCKEYCONF, should never happen, abort
-    TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend();
+    TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
 
     tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData;
     tcIndxRef->transId[0] = regApiPtr->transid[0];
     tcIndxRef->transId[1] = regApiPtr->transid[1];
     tcIndxRef->errorCode = 4349;    
     sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, 
-	       TcIndxRef::SignalLength, JBB);
+	       TcKeyRef::SignalLength, JBB);
     return;
   }
   case(IOS_INDEX_ACCESS_WAIT_FOR_TCKEYCONF): {  
@@ -11686,8 +11819,8 @@ void Dbtc::execTCKEYREF(Signal* signal)
     // Send TCINDXREF 
     
     jam();
-    TcIndxReq * const tcIndxReq = &indexOp->tcIndxReq;
-    TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend();
+    TcKeyReq * const tcIndxReq = &indexOp->tcIndxReq;
+    TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
     
     ndbassert(regApiPtr->noIndexOp);
     regApiPtr->noIndexOp--; // Decrease count
@@ -11696,7 +11829,7 @@ void Dbtc::execTCKEYREF(Signal* signal)
     tcIndxRef->transId[1] = tcKeyRef->transId[1];
     tcIndxRef->errorCode = tcKeyRef->errorCode;
     sendSignal(regApiPtr->ndbapiBlockref, 
-               GSN_TCINDXREF, signal, TcIndxRef::SignalLength, JBB);
+               GSN_TCINDXREF, signal, TcKeyRef::SignalLength, JBB);
     return;
   }
   }
@@ -11763,14 +11896,14 @@ void Dbtc::execTRANSID_AI(Signal* signal
                       signal->getLength() - TransIdAI::HeaderLength)) {
     jam();
     // Failed to allocate space for TransIdAI
-    TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend();
+    TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
     
     tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData;
     tcIndxRef->transId[0] = regApiPtr->transid[0];
     tcIndxRef->transId[1] = regApiPtr->transid[1];
     tcIndxRef->errorCode = 4000;
     sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, 
-	       TcIndxRef::SignalLength, JBB);
+	       TcKeyRef::SignalLength, JBB);
     return;
   }
 
@@ -11778,14 +11911,14 @@ void Dbtc::execTRANSID_AI(Signal* signal
   case(IOS_NOOP): {
     jam();
     // Should never happen, abort
-    TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend();
+    TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
     
     tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData;
     tcIndxRef->transId[0] = regApiPtr->transid[0];
     tcIndxRef->transId[1] = regApiPtr->transid[1];
     tcIndxRef->errorCode = 4349;
     sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, 
-	       TcIndxRef::SignalLength, JBB);
+	       TcKeyRef::SignalLength, JBB);
     return;
     break;
   }
@@ -11806,14 +11939,14 @@ void Dbtc::execTRANSID_AI(Signal* signal
 #endif
     /*
     // Too many TRANSID_AI
-    TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend();
+    TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
     
     tcIndexRef->connectPtr = indexOp->tcIndxReq.senderData;
     tcIndxRef->transId[0] = regApiPtr->transid[0];
     tcIndxRef->transId[1] = regApiPtr->transid[1];
     tcIndxRef->errorCode = 4349;
     sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, 
-               TcIndxRef::SignalLength, JBB);
+               TcKeyRef::SignalLength, JBB);
     */
     break;
   }
@@ -11831,14 +11964,14 @@ void Dbtc::execTRANSID_AI(Signal* signal
   case(IOS_INDEX_OPERATION): {
     // Should never receive TRANSID_AI in this state!!
     jam();    
-    TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend();
+    TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
 
     tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData;
     tcIndxRef->transId[0] = regApiPtr->transid[0];
     tcIndxRef->transId[1] = regApiPtr->transid[1];
     tcIndxRef->errorCode = 4349;
     sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, 
-	       TcIndxRef::SignalLength, JBB);
+	       TcKeyRef::SignalLength, JBB);
     return;
   }
   }
@@ -11881,24 +12014,24 @@ void Dbtc::readIndexTable(Signal* signal
     (Operation_t)TcKeyReq::getOperationType(tcKeyRequestInfo);
 
   // Find index table
-  if ((indexData = c_theIndexes.getPtr(indexOp->tcIndxReq.indexId)) == NULL) {
+  if ((indexData = c_theIndexes.getPtr(indexOp->tcIndxReq.tableId)) == NULL) {
     jam();
     // Failed to find index record
-    TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend();
+    TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
 
     tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData;
     tcIndxRef->transId[0] = regApiPtr->transid[0];
     tcIndxRef->transId[1] = regApiPtr->transid[1];
     tcIndxRef->errorCode = 4000;    
     sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, 
-	       TcIndxRef::SignalLength, JBB);
+	       TcKeyRef::SignalLength, JBB);
     return;
   }
   tcKeyReq->transId1 = transId1;
   tcKeyReq->transId2 = transId2;
   tcKeyReq->tableId = indexData->indexId;
   tcKeyLength += MIN(keyLength, keyBufSize);
-  tcKeyReq->tableSchemaVersion = indexOp->tcIndxReq.indexSchemaVersion;
+  tcKeyReq->tableSchemaVersion = indexOp->tcIndxReq.tableSchemaVersion;
   TcKeyReq::setOperationType(tcKeyRequestInfo, 
 			     opType == ZREAD ? ZREAD : ZREAD_EX);
   TcKeyReq::setAIInTcKeyReq(tcKeyRequestInfo, 1); // Allways send one AttrInfo
@@ -11990,9 +12123,13 @@ void Dbtc::executeIndexOperation(Signal*
   Uint32 keyBufSize = 8; // Maximum for key in TCKEYREQ
   Uint32 attrBufSize = 5;
   Uint32 dataPos = 0;
-  TcIndxReq * const tcIndxReq = &indexOp->tcIndxReq;
+  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;
@@ -12001,17 +12138,17 @@ void Dbtc::executeIndexOperation(Signal*
   bool moreKeyData = indexOp->transIdAI.first(aiIter);
       
   // Find index table
-  if ((indexData = c_theIndexes.getPtr(tcIndxReq->indexId)) == NULL) {
+  if ((indexData = c_theIndexes.getPtr(tcIndxReq->tableId)) == NULL) {
     jam();
     // Failed to find index record 
-    TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend();
+    TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
 
     tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData;
     tcIndxRef->transId[0] = regApiPtr->transid[0];
     tcIndxRef->transId[1] = regApiPtr->transid[1];
     tcIndxRef->errorCode = 4349;    
     sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, 
-	       TcIndxRef::SignalLength, JBB);
+	       TcKeyRef::SignalLength, JBB);
     return;
   }    
   // Find schema version of primary table
@@ -12031,11 +12168,16 @@ void Dbtc::executeIndexOperation(Signal*
   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) {
@@ -12045,6 +12187,9 @@ void Dbtc::executeIndexOperation(Signal*
     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)) {
@@ -12283,7 +12428,7 @@ void Dbtc::executeTriggers(Signal* signa
 	  tmp2.release();
 	  LocalDataBuffer<11> tmp3(pool, trigPtr.p->afterValues);
 	  tmp3.release();
-          regApiPtr->theFiredTriggers.release(trigPtr.i);
+          regApiPtr->theFiredTriggers.release(trigPtr);
         }
 	trigPtr = nextTrigPtr;
       }
@@ -12400,7 +12545,7 @@ void Dbtc::insertIntoIndexTable(Signal* 
   AttributeBuffer::DataBufferIterator iter;
   Uint32 attrId = 0;
   Uint32 keyLength = 0;
-  Uint32 totalPrimaryKeyLength = 0;
+  Uint32 totalPrimaryKeyLength = 1; // fragment length
   Uint32 hops;
 
   indexTabPtr.i = indexData->indexId;
@@ -12453,11 +12598,12 @@ void Dbtc::insertIntoIndexTable(Signal* 
     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);
@@ -12507,8 +12653,11 @@ void Dbtc::insertIntoIndexTable(Signal* 
   }
 
   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
@@ -12525,6 +12674,10 @@ void Dbtc::insertIntoIndexTable(Signal* 
     // 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();
@@ -12689,6 +12842,29 @@ void Dbtc::insertIntoIndexTable(Signal* 
     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();

--- 1.8.1.14/ndb/test/ndbapi/testNodeRestart.cpp	2006-06-01 08:24:03 +02:00
+++ 1.26/storage/ndb/test/ndbapi/testNodeRestart.cpp	2006-06-01 08:33:46 +02:00
@@ -312,7 +312,7 @@ int runDirtyRead(NDBT_Context* ctx, NDBT
     int id = i % restarter.getNumDbNodes();
     int nodeId = restarter.getDbNodeId(id);
     ndbout << "Restart node " << nodeId << endl; 
-    restarter.insertErrorInAllNodes(5041);
+    restarter.insertErrorInNode(nodeId, 5041);
     restarter.insertErrorInAllNodes(8048 + (i & 1));
     
     for(int j = 0; j<records; j++){
Thread
bk commit into 5.1 tree (jonas:1.2377)jonas1 Jun