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@stripped, 2006-12-15 16:57:43+01:00, jonas@stripped +6 -0
Merge perch.ndb.mysql.com:/home/jonas/src/50-work
into perch.ndb.mysql.com:/home/jonas/src/51-work
MERGE: 1.1810.2124.36
storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp@stripped, 2006-12-15 16:56:26+01:00, jonas@stripped +0 -0
Auto merged
MERGE: 1.73.32.3
storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp@stripped, 2006-12-15 16:56:26+01:00, jonas@stripped +0 -0
Merge rename: ndb/src/kernel/blocks/dbtc/DbtcMain.cpp -> storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
storage/ndb/src/ndbapi/NdbTransaction.cpp@stripped, 2006-12-15 16:56:26+01:00, jonas@stripped +0 -0
Auto merged
MERGE: 1.43.22.2
storage/ndb/src/ndbapi/NdbTransaction.cpp@stripped, 2006-12-15 16:56:26+01:00, jonas@stripped +0 -0
Merge rename: ndb/src/ndbapi/NdbTransaction.cpp -> storage/ndb/src/ndbapi/NdbTransaction.cpp
storage/ndb/src/ndbapi/Ndbif.cpp@stripped, 2006-12-15 16:56:26+01:00, jonas@stripped +0 -0
Auto merged
MERGE: 1.27.8.2
storage/ndb/src/ndbapi/Ndbif.cpp@stripped, 2006-12-15 16:56:26+01:00, jonas@stripped +0 -0
Merge rename: ndb/src/ndbapi/Ndbif.cpp -> storage/ndb/src/ndbapi/Ndbif.cpp
storage/ndb/test/ndbapi/testBasic.cpp@stripped, 2006-12-15 16:57:41+01:00, jonas@stripped +33 -26
merge
MERGE: 1.8.1.2
storage/ndb/test/ndbapi/testBasic.cpp@stripped, 2006-12-15 16:56:26+01:00, jonas@stripped +0 -0
Merge rename: ndb/test/ndbapi/testBasic.cpp -> storage/ndb/test/ndbapi/testBasic.cpp
storage/ndb/test/ndbapi/testIndex.cpp@stripped, 2006-12-15 16:56:26+01:00, jonas@stripped +0 -0
Auto merged
MERGE: 1.14.3.2
storage/ndb/test/ndbapi/testIndex.cpp@stripped, 2006-12-15 16:56:26+01:00, jonas@stripped +0 -0
Merge rename: ndb/test/ndbapi/testIndex.cpp -> storage/ndb/test/ndbapi/testIndex.cpp
storage/ndb/test/run-test/daily-basic-tests.txt@stripped, 2006-12-15 16:56:26+01:00, jonas@stripped +0 -0
Auto merged
MERGE: 1.27.22.3
storage/ndb/test/run-test/daily-basic-tests.txt@stripped, 2006-12-15 16:56:26+01:00, jonas@stripped +0 -0
Merge rename: ndb/test/run-test/daily-basic-tests.txt -> storage/ndb/test/run-test/daily-basic-tests.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.27.22.2/ndb/test/run-test/daily-basic-tests.txt 2006-12-15 16:57:49 +01:00
+++ 1.59/storage/ndb/test/run-test/daily-basic-tests.txt 2006-12-15 16:57:49 +01:00
@@ -81,23 +81,23 @@
max-time: 500
cmd: testBasic
-args: -n PkReadAndLocker T6
+args: -n PkReadAndLocker T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n PkReadAndLocker2 T6
+args: -n PkReadAndLocker2 T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n PkReadUpdateAndLocker T6
+args: -n PkReadUpdateAndLocker T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n ReadWithLocksAndInserts T6
+args: -n ReadWithLocksAndInserts T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n PkInsertTwice T1 T6 T10
+args: -n PkInsertTwice T1 T6 T10 D1 D2
max-time: 1500
cmd: testBasic
@@ -109,79 +109,79 @@
max-time: 500
cmd: testBasic
-args: -n NoCommitSleep T6
+args: -n NoCommitSleep T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n NoCommit626 T6
+args: -n NoCommit626 T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n NoCommitAndClose T6
+args: -n NoCommitAndClose T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n Commit626 T6
+args: -n Commit626 T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n CommitTry626 T6
+args: -n CommitTry626 T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n CommitAsMuch626 T6
+args: -n CommitAsMuch626 T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n NoCommit626 T6
+args: -n NoCommit626 T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n NoCommitRollback626 T1 T6
+args: -n NoCommitRollback626 T1 T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n Commit630 T1 T6
+args: -n Commit630 T1 T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n CommitTry630 T1 T6
+args: -n CommitTry630 T1 T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n CommitAsMuch630 T1 T6
+args: -n CommitAsMuch630 T1 T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n NoCommit630 T1 T6
+args: -n NoCommit630 T1 T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n NoCommitRollback630 T1 T6
+args: -n NoCommitRollback630 T1 T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n NoCommitAndClose T1 T6
+args: -n NoCommitAndClose T1 T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n RollbackUpdate T1 T6
+args: -n RollbackUpdate T1 T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n RollbackDeleteMultiple T1 T6
+args: -n RollbackDeleteMultiple T1 T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n ImplicitRollbackDelete T1 T6
+args: -n ImplicitRollbackDelete T1 T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n CommitDelete T1 T6
+args: -n CommitDelete T1 T6 D1 D2
max-time: 500
cmd: testBasic
-args: -n RollbackNothing T1 T6
+args: -n RollbackNothing T1 T6 D1 D2
max-time: 500
cmd: testBasicAsynch
@@ -199,13 +199,33 @@
cmd: testBasicAsynch
args: -n PkDeleteAsynch
+max-time: 1000
+cmd: testBasic
+args: -n MassiveRollback T1 T7 D1 D2
+
+max-time: 500
+cmd: testBasic
+args: -n MassiveRollback2 T1 T7 D1 D2
+
+max-time: 500
+cmd: testBasic
+args: -n MassiveRollback3 T1 T7 D1 D2
+
max-time: 500
cmd: testBasic
-args: -n MassiveRollback T1 T6 T13
+args: -n MassiveRollback4 T1 T7 D1 D2
max-time: 500
cmd: testBasic
-args: -n MassiveRollback2 T1 T6 T13
+args: -n TupError
+
+max-time: 500
+cmd: testBasic
+args: -n InsertError T1
+
+max-time: 500
+cmd: testBasic
+args: -n InsertError2 T1
max-time: 500
cmd: testTimeout
@@ -239,7 +259,7 @@
max-time: 500
cmd: testScan
-args: -n ScanUpdate2 T6
+args: -n ScanUpdate2 T6 D1 D2
max-time: 500
cmd: testScan
@@ -247,47 +267,51 @@
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 ScanRead488T -l 10 T6 D1 D2
max-time: 1000
cmd: testScan
-args: -n ScanRead488_Mixed -l 10 T6
+args: -n ScanRead488_Mixed -l 10 T6 D1 D2
max-time: 500
cmd: testScan
-args: -n ScanRead488Timeout -l 10 T6
+args: -n ScanRead488Timeout -l 10 T6 D1 D2
max-time: 600
cmd: testScan
-args: -n ScanRead40 -l 100 T2
+args: -n ScanRead40 -l 100 T2 D1 D2
max-time: 1800
cmd: testScan
-args: -n ScanRead100 -l 100 T1
+args: -n ScanRead100 -l 100 T1 D1 D2
max-time: 600
cmd: testScan
-args: -n ScanRead40 -l 100 T1
+args: -n ScanRead40 -l 100 T1 D1 D2
max-time: 1800
cmd: testScan
@@ -299,123 +323,135 @@
max-time: 500
cmd: testScan
-args: -n ScanWithLocksAndInserts T6
+args: -n ScanWithLocksAndInserts T6 D1 D2
max-time: 500
cmd: testScan
-args: -n ScanReadAbort T6
+args: -n ScanReadAbort T6 D1 D2
max-time: 500
cmd: testScan
-args: -n ScanReadAbort15 T6
+args: -n ScanReadAbort15 T6 D1 D2
max-time: 500
cmd: testScan
-args: -n ScanReadAbort240 T6
+args: -n ScanReadAbort240 T6 D1 D2
max-time: 500
cmd: testScan
-args: -n ScanUpdateAbort16 T6
+args: -n ScanUpdateAbort16 T6 D1 D2
max-time: 3600
cmd: testScan
-args: -n ScanReadRestart T1 T6 T13
+args: -n ScanReadRestart T1 T6 T13
-max-time: 500
+max-time: 3600
cmd: testScan
-args: -n ScanUpdateRestart T6
+args: -n ScanReadRestart D1 D2
-max-time: 500
+max-time: 1200
+cmd: testScan
+args: -n ScanUpdateRestart T6
+
+max-time: 1200
cmd: testScan
-args: -n CheckGetValue T6
+args: -n ScanUpdateRestart D1 D2
max-time: 500
cmd: testScan
-args: -n CloseWithoutStop T6
+args: -n CheckGetValue T6 D1 D2
max-time: 500
cmd: testScan
-args: -n NextScanWhenNoMore T6
+args: -n CloseWithoutStop T6 D1 D2
max-time: 500
cmd: testScan
-args: -n ExecuteScanWithoutOpenScan T6
+args: -n NextScanWhenNoMore T6 D1 D2
max-time: 500
cmd: testScan
-args: -n OnlyOpenScanOnce T6
+args: -n ExecuteScanWithoutOpenScan T6 D1 D2
max-time: 500
cmd: testScan
-args: -n OnlyOneOpInScanTrans T6
+args: -n OnlyOpenScanOnce T6 D1 D2
max-time: 500
cmd: testScan
-args: -n OnlyOneOpBeforeOpenScan T6
+args: -n OnlyOneOpInScanTrans T6 D1 D2
max-time: 500
cmd: testScan
-args: -n OnlyOneScanPerTrans T6
+args: -n OnlyOneOpBeforeOpenScan T6 D1 D2
max-time: 500
cmd: testScan
-args: -n NoCloseTransaction T6
+args: -n OnlyOneScanPerTrans T6 D1 D2
max-time: 500
cmd: testScan
-args: -n CheckInactivityTimeOut T6
+args: -n NoCloseTransaction T6 D1 D2
max-time: 500
cmd: testScan
-args: -n CheckInactivityBeforeClose T6
+args: -n CheckInactivityTimeOut T6 D1 D2
max-time: 500
cmd: testScan
-args: -n CheckAfterTerror T6
+args: -n CheckInactivityBeforeClose T6 D1 D2
max-time: 500
cmd: testScan
-args: -n ScanReadError5021 T1
+args: -n CheckAfterTerror T6 D1 D2
max-time: 500
cmd: testScan
-args: -n ScanReaderror5022 T1
+args: -n ScanReadError5021 T1 D1 D2
max-time: 500
cmd: testScan
-args: -n ScanReadError5023 T1
+args: -n ScanReaderror5022 T1 D1 D2
max-time: 500
cmd: testScan
-args: -n ScanReadError5024 T1
+args: -n ScanReadError5023 T1 D1 D2
max-time: 500
cmd: testScan
-args: -n ScanReadError5025 T1
+args: -n ScanReadError5024 T1 D1 D2
max-time: 500
cmd: testScan
-args: -n ScanReadError5030 T1
+args: -n ScanReadError5025 T1 D1 D2
max-time: 500
cmd: testScan
-args: -n InsertDelete T1 T6
+args: -n ScanReadError5030 T1 D1 D2
max-time: 500
cmd: testScan
-args: -n CheckAfterTerror T1
+args: -n InsertDelete T1 T6 D1 D2
max-time: 500
cmd: testScan
+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 ScanRestart T1
+args: -n ScanRestart T1 D1 D2
max-time: 500
cmd: testScan
-args: -l 100 -n Scan-bug8262 T7
+args: -l 100 -n Scan-bug8262 T7 D1 D2
max-time: 500
cmd: testScan
@@ -426,6 +462,10 @@
args: -n Bug24447 T1
max-time: 500
+cmd: testScan
+args: -n ScanVariants
+
+max-time: 500
cmd: testNodeRestart
args: -n Bug15587 T1
@@ -462,6 +502,10 @@
args: -n Bug20185 T1
max-time: 1000
+cmd: testNodeRestart
+args: -n Bug21271 T6
+
+max-time: 1000
cmd: testIndex
args: -n Bug21384
@@ -469,15 +513,6 @@
cmd: testNodeRestart
args: -n Bug24717 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
@@ -494,7 +529,7 @@
max-time: 1500
cmd: testDict
-args: -n CreateAndDropDuring T6 T10
+args: -n CreateAndDropDuring T6 T10 D1 D2
max-time: 1500
cmd: testDict
@@ -526,7 +561,7 @@
max-time: 1500
cmd: testDict
-args: -n Restart_NR2 T1
+args: -n Restart_NR2 T1 I3
#
# TEST NDBAPI
@@ -583,23 +618,27 @@
max-time: 500
cmd: testNdbApi
-args: -n UpdateWithoutKeys T6
+args: -n UpdateWithoutKeys T6 D1 D2
+
+max-time: 500
+cmd: testNdbApi
+args: -n UpdateWithoutValues T6 D1 D2
max-time: 500
cmd: testNdbApi
-args: -n UpdateWithoutValues T6
+args: -n ReadWithoutGetValue D1 D2
max-time: 500
cmd: testNdbApi
-args: -n ReadWithoutGetValue
+args: -n Bug_11133 T1 D1 D2
max-time: 500
cmd: testNdbApi
-args: -n Bug_11133 T1
+args: -n Scan_4006 T1 D1 D2
max-time: 500
cmd: testNdbApi
-args: -n Scan_4006 T1
+args: -n Bug_WritePartialIgnoreError T1
#max-time: 500
#cmd: testInterpreter
@@ -617,13 +656,21 @@
cmd: testRestartGci
args: T6
-max-time: 600
+max-time: 1500
cmd: testBlobs
args:
max-time: 5000
cmd: testOIBasic
-args:
+args: -case abcdefz
+
+max-time: 2000
+cmd: testOIBasic
+args: -case gz
+
+max-time: 2000
+cmd: testOIBasic
+args: -case hz
max-time: 2500
cmd: testBitfield
@@ -655,6 +702,14 @@
max-time: 1500
cmd: testSystemRestart
+args: -n SR1 D1
+
+max-time: 1500
+cmd: testSystemRestart
+args: -n SR1 D2
+
+max-time: 1500
+cmd: testSystemRestart
args: -n SR2 T1
max-time: 1500
@@ -667,6 +722,14 @@
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
@@ -680,6 +743,26 @@
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
+
+max-time: 300
+cmd: testNodeRestart
+args: -n Bug24543 T1
+
+max-time: 1500
+cmd: testSystemRestart
+args: -n Bug24664
# OLD FLEX
max-time: 500
--- 1.73.32.2/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp 2006-12-15 16:57:49 +01:00
+++ 1.129/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp 2006-12-15 16:57:49 +01:00
@@ -38,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>
@@ -71,6 +72,8 @@
#include <NdbOut.hpp>
#include <DebuggerNames.hpp>
+#include <signaldata/RouteOrd.hpp>
+
// Use DEBUG to print messages that should be
// seen only when we debug the product
#ifdef VM_TRACE
@@ -344,7 +347,7 @@
tabptr.p->noOfKeyAttr = desc->noOfKeyAttr;
tabptr.p->hasCharAttr = desc->hasCharAttr;
tabptr.p->noOfDistrKeys = desc->noOfDistrKeys;
-
+ tabptr.p->hasVarKeys = desc->noOfVarKeys > 0;
signal->theData[0] = tabptr.i;
signal->theData[1] = retPtr;
sendSignal(retRef, GSN_TC_SCHVERCONF, signal, 2, JBB);
@@ -610,7 +613,7 @@
jamEntry();
const ndb_mgm_configuration_iterator * p =
- theConfiguration.getOwnConfigIterator();
+ m_ctx.m_config.getOwnConfigIterator();
ndbrequire(p != 0);
initData();
@@ -1294,6 +1297,7 @@
apiConnectptr.p->firstTcConnect == RNIL))
{
jam(); /* JUST REPLY OK */
+ apiConnectptr.p->m_transaction_nodes.clear();
releaseApiCon(signal, apiConnectptr.i);
signal->theData[0] = tuserpointer;
sendSignal(tapiBlockref,
@@ -2296,14 +2300,15 @@
{
Uint64 Tmp[MAX_KEY_SIZE_IN_WORDS * MAX_XFRM_MULTIPLY];
const TableRecord* tabPtrP = &tableRecord[tabPtrI];
+ const bool hasVarKeys = tabPtrP->hasVarKeys;
const bool hasCharAttr = tabPtrP->hasCharAttr;
- const bool hasDistKeys = tabPtrP->noOfDistrKeys > 0;
+ const bool compute_distkey = distr && (tabPtrP->noOfDistrKeys > 0);
Uint32 *dst = (Uint32*)Tmp;
Uint32 dstPos = 0;
Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX];
Uint32 * keyPartLenPtr;
- if(hasCharAttr)
+ if(hasCharAttr || (compute_distkey && hasVarKeys))
{
keyPartLenPtr = keyPartLen;
dstPos = xfrm_key(tabPtrI, src, dst, sizeof(Tmp) >> 2, keyPartLenPtr);
@@ -2321,7 +2326,7 @@
md5_hash(dstHash, (Uint64*)dst, dstPos);
- if(distr && hasDistKeys)
+ if(compute_distkey)
{
jam();
@@ -2730,12 +2735,14 @@
Uint8 TDirtyFlag = tcKeyReq->getDirtyFlag(Treqinfo);
Uint8 TInterpretedFlag = tcKeyReq->getInterpretedFlag(Treqinfo);
Uint8 TDistrKeyFlag = tcKeyReq->getDistributionKeyFlag(Treqinfo);
+ Uint8 TNoDiskFlag = TcKeyReq::getNoDiskFlag(Treqinfo);
Uint8 TexecuteFlag = TexecFlag;
regCachePtr->opSimple = TSimpleFlag;
regCachePtr->opExec = TInterpretedFlag;
regTcPtr->dirtyOp = TDirtyFlag;
regCachePtr->distributionKeyIndicator = TDistrKeyFlag;
+ regCachePtr->m_no_disk_flag = TNoDiskFlag;
//-------------------------------------------------------------
// The next step is to read the upto three conditional words.
@@ -2799,17 +2806,9 @@
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){
@@ -2843,24 +2842,10 @@
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);
@@ -3035,7 +3020,7 @@
tnoOfStandby = (tnodeinfo >> 8) & 3;
regCachePtr->fragmentDistributionKey = (tnodeinfo >> 16) & 255;
- if (Toperation == ZREAD) {
+ if (Toperation == ZREAD || Toperation == ZREAD_EX) {
if (Tdirty == 1) {
jam();
/*-------------------------------------------------------------*/
@@ -3068,28 +3053,7 @@
}//if
}//for
}
-
- if (regTcPtr->tcNodedata[0] != getOwnNodeId())
- {
- jam();
- for (Uint32 i = 0; i < tnoOfBackup + 1; i++)
- {
- HostRecordPtr hostPtr;
- hostPtr.i = regTcPtr->tcNodedata[i];
- ptrCheckGuard(hostPtr, chostFilesize, hostRecord);
- if (hostPtr.p->m_nf_bits & HostRecord::NF_STARTED)
- {
- jam();
- if (i != 0)
- {
- jam();
- regTcPtr->tcNodedata[0] = hostPtr.i;
- }
- break;
- }
- }
- }//if
- }
+ }//if
jam();
regTcPtr->lastReplicaNo = 0;
regTcPtr->noOfNodes = 1;
@@ -3185,6 +3149,7 @@
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)) {
@@ -3228,7 +3193,12 @@
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 = (Operation_t) op == ZREAD_EX ? ZUPDATE : (Operation_t) op == ZWRITE ? ZINSERT : (Operation_t) op;
+ LqhKeyReq::setLockType(Tdata10, lock);
+ }
/* ---------------------------------------------------------------------- */
// Indicate Application Reference is present in bit 15
/* ---------------------------------------------------------------------- */
@@ -3237,6 +3207,8 @@
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,
@@ -3954,7 +3926,7 @@
const UintR TopWords = (UintR)regApiPtr->tckeyrec;
localHostptr.i = refToNode(regApiPtr->ndbapiBlockref);
const Uint32 type = getNodeInfo(localHostptr.i).m_type;
- const bool is_api = (type >= NodeInfo::API && type <= NodeInfo::REP);
+ const bool is_api = (type >= NodeInfo::API && type <= NodeInfo::MGM);
const BlockNumber TblockNum = refToBlock(regApiPtr->ndbapiBlockref);
const Uint32 Tmarker = (regApiPtr->commitAckMarker == RNIL) ? 0 : 1;
ptrAss(localHostptr, hostRecord);
@@ -4636,7 +4608,8 @@
commitConf->transId1 = regApiPtr->transid[0];
commitConf->transId2 = regApiPtr->transid[1];
commitConf->gci = regApiPtr->globalcheckpointid;
- sendSignal(regApiPtr->ndbapiBlockref, GSN_TC_COMMITCONF, signal,
+
+ sendSignal(regApiPtr->ndbapiBlockref, GSN_TC_COMMITCONF, signal,
TcCommitConf::SignalLength, JBB);
} else if (regApiPtr->returnsignal == RS_NO_RETURN) {
jam();
@@ -4826,13 +4799,14 @@
key.transid2 = signal->theData[1];
CommitAckMarkerPtr removedMarker;
- m_commitAckMarkerHash.release(removedMarker, key);
+ m_commitAckMarkerHash.remove(removedMarker, key);
if (removedMarker.i == RNIL) {
jam();
warningHandlerLab(signal, __LINE__);
return;
}//if
sendRemoveMarkers(signal, removedMarker.p);
+ m_commitAckMarkerPool.release(removedMarker);
}
void
@@ -5177,6 +5151,19 @@
return;
}
+ /* Only ref in certain situations */
+ {
+ const Uint32 opType = regTcPtr->operation;
+ if ( (opType == ZDELETE && errCode != ZNOT_FOUND)
+ || (opType == ZINSERT && errCode != ZALREADYEXIST)
+ || (opType == ZUPDATE && errCode != ZNOT_FOUND)
+ || (opType == ZWRITE && errCode != 839 && errCode != 840))
+ {
+ TCKEY_abort(signal, 49);
+ return;
+ }
+ }
+
/* *************** */
/* TCKEYREF < */
/* *************** */
@@ -7026,19 +7013,6 @@
}//Dbtc::execNODE_FAILREP()
void
-Dbtc::execNODE_START_REP(Signal* signal)
-{
- Uint32 nodeId = signal->theData[0];
- hostptr.i = nodeId;
- ptrCheckGuard(hostptr, chostFilesize, hostRecord);
- if (hostptr.p->m_nf_bits == 0)
- {
- jam();
- hostptr.p->m_nf_bits |= HostRecord::NF_STARTED;
- }
-}
-
-void
Dbtc::checkNodeFailComplete(Signal* signal,
Uint32 failedNodeId,
Uint32 bit)
@@ -7126,15 +7100,20 @@
for (transPtr.i = transPtrI; transPtr.i < capiConnectFilesize; transPtr.i++)
{
ptrCheckGuard(transPtr, capiConnectFilesize, apiConnectRecord);
+ Uint32 state = transPtr.p->apiConnectstate;
if (transPtr.p->m_transaction_nodes.get(failedNodeId))
{
jam();
-
- // Force timeout regardless of state
- c_appl_timeout_value = 1;
- setApiConTimer(transPtr.i, TtcTimer - 2, __LINE__);
- timeOutFoundLab(signal, transPtr.i, ZNODEFAIL_BEFORE_COMMIT);
- c_appl_timeout_value = TapplTimeout;
+
+ // avoid assertion in timeoutfoundlab
+ if (state != CS_PREPARE_TO_COMMIT)
+ {
+ // Force timeout regardless of state
+ c_appl_timeout_value = 1;
+ setApiConTimer(transPtr.i, TtcTimer - 2, __LINE__);
+ timeOutFoundLab(signal, transPtr.i, ZNODEFAIL_BEFORE_COMMIT);
+ c_appl_timeout_value = TapplTimeout;
+ }
}
// Send CONTINUEB to continue later
@@ -8828,6 +8807,7 @@
ScanFragReq::setDescendingFlag(tmp, ScanTabReq::getDescendingFlag(ri));
ScanFragReq::setTupScanFlag(tmp, ScanTabReq::getTupScanFlag(ri));
ScanFragReq::setAttrLen(tmp, scanTabReq->attrLenKeyLen & 0xFFFF);
+ ScanFragReq::setNoDiskFlag(tmp, ScanTabReq::getNoDiskFlag(ri));
scanptr.p->scanRequestInfo = tmp;
scanptr.p->scanStoredProcId = scanTabReq->storedProcId;
@@ -8949,9 +8929,11 @@
* 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);
+ 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
{
@@ -8962,17 +8944,18 @@
UintR TerrorIndicator = signal->theData[0];
jamEntry();
if (TerrorIndicator != 0) {
- signal->theData[0] = tcConnectptr.i;
- //signal->theData[1] Contains error
+ 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;
-
- signal->theData[0] = tcConnectptr.i;
- signal->theData[1] = 1; // Frag count
+ DihFragCountConf * const conf = (DihFragCountConf*)signal->getDataPtr();
+ conf->m_connectionData = tcConnectptr.i;
+ conf->m_fragmentCount = 1; // Frag count
execDI_FCOUNTCONF(signal);
}
return;
@@ -8990,8 +8973,9 @@
void Dbtc::execDI_FCOUNTCONF(Signal* signal)
{
jamEntry();
- tcConnectptr.i = signal->theData[0];
- Uint32 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);
@@ -9075,9 +9059,10 @@
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;
@@ -10232,6 +10217,7 @@
tabptr.p->noOfKeyAttr = 0;
tabptr.p->hasCharAttr = 0;
tabptr.p->noOfDistrKeys = 0;
+ tabptr.p->hasVarKeys = 0;
}//for
}//Dbtc::initTable()
@@ -11296,7 +11282,6 @@
ApiConnectRecordPtr transPtr;
TcConnectRecord *localTcConnectRecord = tcConnectRecord;
TcConnectRecordPtr opPtr;
-
/**
* TODO
* Check transid,
@@ -11310,6 +11295,7 @@
c_firedTriggerHash.remove(trigPtr);
+ trigPtr.p->fragId= fireOrd->fragId;
bool ok = trigPtr.p->keyValues.getSize() == fireOrd->m_noPrimKeyWords;
ok &= trigPtr.p->afterValues.getSize() == fireOrd->m_noAfterValueWords;
ok &= trigPtr.p->beforeValues.getSize() == fireOrd->m_noBeforeValueWords;
@@ -11521,7 +11507,7 @@
const UintR TopWords = (UintR)regApiPtr->tcindxrec;
localHostptr.i = refToNode(regApiPtr->ndbapiBlockref);
const Uint32 type = getNodeInfo(localHostptr.i).m_type;
- const bool is_api = (type >= NodeInfo::API && type <= NodeInfo::REP);
+ const bool is_api = (type >= NodeInfo::API && type <= NodeInfo::MGM);
const BlockNumber TblockNum = refToBlock(regApiPtr->ndbapiBlockref);
const Uint32 Tmarker = (regApiPtr->commitAckMarker == RNIL ? 0 : 1);
ptrAss(localHostptr, hostRecord);
@@ -12220,7 +12206,11 @@
Uint32 dataPos = 0;
TcKeyReq * const tcIndxReq = &indexOp->tcIndxReq;
TcKeyReq * const tcKeyReq = (TcKeyReq *)signal->getDataPtrSend();
- Uint32 * dataPtr = &tcKeyReq->scanInfo;
+ /*
+ Data points to distrGroupHashValue since scanInfo is used to send
+ fragment id of receiving fragment
+ */
+ Uint32 * dataPtr = &tcKeyReq->distrGroupHashValue;
Uint32 tcKeyLength = TcKeyReq::StaticLength;
Uint32 tcKeyRequestInfo = tcIndxReq->requestInfo;
TcIndexData* indexData;
@@ -12259,11 +12249,16 @@
regApiPtr->executingIndexOp = indexOp->indexOpId;;
regApiPtr->noIndexOp++; // Increase count
- // Filter out AttributeHeader:s since this should not be in key
+ /*
+ Filter out AttributeHeader:s since this should not be in key.
+ Also filter out fragment id from primary key and handle that
+ separately by setting it as Distribution Key and set indicator.
+ */
+
AttributeHeader* attrHeader = (AttributeHeader *) aiIter.data;
Uint32 headerSize = attrHeader->getHeaderSize();
- Uint32 keySize = attrHeader->getDataSize();
+ Uint32 keySize = attrHeader->getDataSize() - 1;
TcKeyReq::setKeyLength(tcKeyRequestInfo, keySize);
// Skip header
if (headerSize == 1) {
@@ -12273,6 +12268,9 @@
jam();
moreKeyData = indexOp->transIdAI.next(aiIter, headerSize - 1);
}//if
+ tcKeyReq->scanInfo = *aiIter.data; //Fragment Id
+ moreKeyData = indexOp->transIdAI.next(aiIter);
+ TcKeyReq::setDistributionKeyFlag(tcKeyRequestInfo, 1U);
while(// If we have not read complete key
(keySize != 0) &&
(dataPos < keyBufSize)) {
@@ -12538,7 +12536,7 @@
tmp2.release();
LocalDataBuffer<11> tmp3(pool, trigPtr.p->afterValues);
tmp3.release();
- regApiPtr->theFiredTriggers.release(trigPtr.i);
+ regApiPtr->theFiredTriggers.release(trigPtr);
}
trigPtr = nextTrigPtr;
}
@@ -12655,7 +12653,7 @@
AttributeBuffer::DataBufferIterator iter;
Uint32 attrId = 0;
Uint32 keyLength = 0;
- Uint32 totalPrimaryKeyLength = 0;
+ Uint32 totalPrimaryKeyLength = 1; // fragment length
Uint32 hops;
indexTabPtr.i = indexData->indexId;
@@ -12708,11 +12706,12 @@
hops = attrHeader->getHeaderSize() + attrHeader->getDataSize();
moreAttrData = keyValues.next(iter, hops);
}
- AttributeHeader pkAttrHeader(attrId, totalPrimaryKeyLength);
+ AttributeHeader pkAttrHeader(attrId, totalPrimaryKeyLength << 2);
+ Uint32 attributesLength = afterValues.getSize() +
+ pkAttrHeader.getHeaderSize() + pkAttrHeader.getDataSize();
TcKeyReq::setKeyLength(tcKeyRequestInfo, keyLength);
- tcKeyReq->attrLen = afterValues.getSize() +
- pkAttrHeader.getHeaderSize() + pkAttrHeader.getDataSize();
+ tcKeyReq->attrLen = attributesLength;
tcKeyReq->tableId = indexData->indexId;
TcKeyReq::setOperationType(tcKeyRequestInfo, ZINSERT);
TcKeyReq::setExecutingTrigger(tcKeyRequestInfo, true);
@@ -12762,8 +12761,11 @@
}
tcKeyLength += dataPos;
- Uint32 attributesLength = afterValues.getSize() +
- pkAttrHeader.getHeaderSize() + pkAttrHeader.getDataSize();
+ /*
+ Size of attrinfo is unique index attributes one by one, header for each
+ of them (all contained in the afterValues data structure), plus a header,
+ the primary key (compacted) and the fragment id before the primary key
+ */
if (attributesLength <= attrBufSize) {
jam();
// ATTRINFO fits in TCKEYREQ
@@ -12780,6 +12782,10 @@
// as one attribute
pkAttrHeader.insertHeader(dataPtr);
dataPtr += pkAttrHeader.getHeaderSize();
+ /*
+ Insert fragment id before primary key as part of reference to tuple
+ */
+ *dataPtr++ = firedTriggerData->fragId;
moreAttrData = keyValues.first(iter);
while(moreAttrData) {
jam();
@@ -12975,6 +12981,29 @@
pkAttrHeader.insertHeader(dataPtr);
dataPtr += pkAttrHeader.getHeaderSize();
attrInfoPos += pkAttrHeader.getHeaderSize();
+ /*
+ Add fragment id before primary key
+ TODO: This code really needs to be made into a long signal
+ to remove this messy code.
+ */
+ if (attrInfoPos == AttrInfo::DataLength)
+ {
+ jam();
+ // Flush ATTRINFO
+#if INTERNAL_TRIGGER_TCKEYREQ_JBA
+ sendSignal(reference(), GSN_ATTRINFO, signal,
+ AttrInfo::HeaderLength + AttrInfo::DataLength, JBA);
+#else
+ EXECUTE_DIRECT(DBTC, GSN_ATTRINFO, signal,
+ AttrInfo::HeaderLength + AttrInfo::DataLength);
+ jamEntry();
+#endif
+ dataPtr = (Uint32 *) &attrInfo->attrData;
+ attrInfoPos = 0;
+ }
+ attrInfoPos++;
+ *dataPtr++ = firedTriggerData->fragId;
+
moreAttrData = keyValues.first(iter);
while(moreAttrData) {
jam();
@@ -13275,3 +13304,56 @@
return 0;
}
+void
+Dbtc::execROUTE_ORD(Signal* signal)
+{
+ jamEntry();
+ if(!assembleFragments(signal)){
+ jam();
+ return;
+ }
+
+ RouteOrd* ord = (RouteOrd*)signal->getDataPtr();
+ Uint32 dstRef = ord->dstRef;
+ Uint32 srcRef = ord->srcRef;
+ Uint32 gsn = ord->gsn;
+ Uint32 cnt = ord->cnt;
+
+ if (likely(getNodeInfo(refToNode(dstRef)).m_connected))
+ {
+ jam();
+ Uint32 secCount = signal->getNoOfSections();
+ SegmentedSectionPtr ptr[3];
+ ndbrequire(secCount >= 1 && secCount <= 3);
+
+ jamLine(secCount);
+ for (Uint32 i = 0; i<secCount; i++)
+ signal->getSection(ptr[i], i);
+
+ /**
+ * Put section 0 in signal->theData
+ */
+ ndbrequire(ptr[0].sz <= 25);
+ copy(signal->theData, ptr[0]);
+
+ signal->header.m_noOfSections = 0;
+
+ /**
+ * Shift rest of sections
+ */
+ for(Uint32 i = 1; i<secCount; i++)
+ {
+ signal->setSection(ptr[i], i - 1);
+ }
+
+ sendSignal(dstRef, gsn, signal, ptr[0].sz, JBB);
+
+ signal->header.m_noOfSections = 0;
+ signal->setSection(ptr[0], 0);
+ releaseSections(signal);
+ return ;
+ }
+
+ warningEvent("Unable to route GSN: %d from %x to %x",
+ gsn, srcRef, dstRef);
+}
--- 1.43.22.1/ndb/src/ndbapi/NdbTransaction.cpp 2006-12-15 16:57:49 +01:00
+++ 1.71/storage/ndb/src/ndbapi/NdbTransaction.cpp 2006-12-15 16:57:49 +01:00
@@ -62,6 +62,7 @@
theTCConPtr(0),
theTransactionId(0),
theGlobalCheckpointId(0),
+ p_latest_trans_gci(0),
theStatus(NotConnected),
theCompletionStatus(NotCompleted),
theCommitStatus(NotStarted),
@@ -127,6 +128,8 @@
theCompletedLastOp = NULL;
theGlobalCheckpointId = 0;
+ p_latest_trans_gci =
+ theNdb->theImpl->m_ndb_cluster_connection.get_latest_trans_gci();
theCommitStatus = Started;
theCompletionStatus = NotCompleted;
m_abortOption = AbortOnError;
@@ -463,7 +466,7 @@
//------------------------------------------------------------------------
Ndb* tNdb = theNdb;
- Uint32 timeout = TransporterFacade::instance()->m_waitfor_timeout;
+ Uint32 timeout = theNdb->theImpl->m_transporter_facade->m_waitfor_timeout;
m_waitForReply = false;
executeAsynchPrepare(aTypeOfExec, NULL, NULL, abortOption);
if (m_waitForReply){
@@ -531,8 +534,8 @@
AbortOption abortOption)
{
DBUG_ENTER("NdbTransaction::executeAsynchPrepare");
- DBUG_PRINT("enter", ("aTypeOfExec: %d, aCallback: %x, anyObject: %x",
- aTypeOfExec, aCallback, anyObject));
+ DBUG_PRINT("enter", ("aTypeOfExec: %d, aCallback: 0x%lx, anyObject: Ox%lx",
+ aTypeOfExec, (long) aCallback, (long) anyObject));
/**
* Reset error.code on execute
@@ -736,7 +739,7 @@
tcHbRep->transId1 = tTransId1;
tcHbRep->transId2 = tTransId2;
- TransporterFacade *tp = TransporterFacade::instance();
+ TransporterFacade *tp = theNdb->theImpl->m_transporter_facade;
tp->lock_mutex();
const int res = tp->sendSignal(tSignal,theDBnode);
tp->unlock_mutex();
@@ -842,7 +845,7 @@
*************************************************************************/
NdbApiSignal tSignal(tNdb->theMyRef);
Uint32 tTransId1, tTransId2;
- TransporterFacade *tp = TransporterFacade::instance();
+ TransporterFacade *tp = theNdb->theImpl->m_transporter_facade;
int tReturnCode;
tTransId1 = (Uint32) theTransactionId;
@@ -889,7 +892,7 @@
{
NdbApiSignal tSignal(theNdb->theMyRef);
Uint32 tTransId1, tTransId2;
- TransporterFacade *tp = TransporterFacade::instance();
+ TransporterFacade *tp = theNdb->theImpl->m_transporter_facade;
int tReturnCode;
tTransId1 = (Uint32) theTransactionId;
@@ -1003,7 +1006,7 @@
}//NdbTransaction::releaseScanOperations()
/*****************************************************************************
-void releaseExecutedScanOperation();
+void releaseScanOperation();
Remark: Release scan op when hupp'ed trans closed (save memory)
******************************************************************************/
@@ -1011,7 +1014,7 @@
NdbTransaction::releaseExecutedScanOperation(NdbIndexScanOperation* cursorOp)
{
DBUG_ENTER("NdbTransaction::releaseExecutedScanOperation");
- DBUG_PRINT("enter", ("this=0x%x op=0x%x", (UintPtr)this, (UintPtr)cursorOp));
+ DBUG_PRINT("enter", ("this: 0x%lx op: 0x%lx", (long) this, (long) cursorOp));
releaseScanOperation(&m_firstExecutedScanOp, 0, cursorOp);
@@ -1234,9 +1237,9 @@
if(tOp)
{
tOp->m_currentTable = table;
+ // Mark that this really an NdbIndexScanOperation
+ tOp->m_type = NdbOperation::OrderedIndexScan;
}
- // Mark that this really an NdbIndexScanOperation
- tOp->m_type = NdbOperation::OrderedIndexScan;
return tOp;
} else {
setOperationErrorCodeAbort(4271);
@@ -1610,6 +1613,9 @@
theCommitStatus = Committed;
theCompletionStatus = CompletedSuccess;
theGlobalCheckpointId = commitConf->gci;
+ // theGlobalCheckpointId == 0 if NoOp transaction
+ if (theGlobalCheckpointId)
+ *p_latest_trans_gci = theGlobalCheckpointId;
return 0;
} else {
#ifdef NDB_NO_DROPPED_SIGNAL
@@ -1788,6 +1794,10 @@
if (tCommitFlag == 1) {
theCommitStatus = Committed;
theGlobalCheckpointId = tGCI;
+ if (tGCI) // Read(dirty) only transaction doesnt get GCI
+ {
+ *p_latest_trans_gci = tGCI;
+ }
} else if ((tNoComp >= tNoSent) &&
(theLastExecOpInList->theCommitIndicator == 1)){
@@ -1964,6 +1974,10 @@
if (tCommitFlag == 1) {
theCommitStatus = Committed;
theGlobalCheckpointId = tGCI;
+ if (tGCI) // Read(dirty) only transaction doesnt get GCI
+ {
+ *p_latest_trans_gci = tGCI;
+ }
} else if ((tNoComp >= tNoSent) &&
(theLastExecOpInList->theCommitIndicator == 1)){
--- 1.27.8.1/ndb/src/ndbapi/Ndbif.cpp 2006-12-15 16:57:49 +01:00
+++ 1.48/storage/ndb/src/ndbapi/Ndbif.cpp 2006-12-15 16:57:49 +01:00
@@ -26,6 +26,7 @@
#include <NdbRecAttr.hpp>
#include <NdbReceiver.hpp>
#include "API.hpp"
+#include "NdbEventOperationImpl.hpp"
#include <signaldata/TcCommit.hpp>
#include <signaldata/TcKeyFailConf.hpp>
@@ -37,11 +38,14 @@
#include <signaldata/TransIdAI.hpp>
#include <signaldata/ScanFrag.hpp>
#include <signaldata/ScanTab.hpp>
+#include <signaldata/SumaImpl.hpp>
#include <ndb_limits.h>
#include <NdbOut.hpp>
#include <NdbTick.h>
+#include <EventLogger.hpp>
+extern EventLogger g_eventLogger;
/******************************************************************************
* int init( int aNrOfCon, int aNrOfOp );
@@ -74,7 +78,7 @@
DBUG_RETURN(-1);
}//if
theInitState = StartingInit;
- TransporterFacade * theFacade = TransporterFacade::instance();
+ TransporterFacade * theFacade = theImpl->m_transporter_facade;
theFacade->lock_mutex();
const int tBlockNo = theFacade->open(this,
@@ -142,7 +146,7 @@
ndbout << "error_handler" << endl;
releaseTransactionArrays();
delete theDictionary;
- TransporterFacade::instance()->close(theNdbBlockNumber, 0);
+ theImpl->m_transporter_facade->close(theNdbBlockNumber, 0);
DBUG_RETURN(-1);
}
@@ -173,6 +177,7 @@
void Ndb::connected(Uint32 ref)
{
+// cluster connect, a_node == own reference
theMyRef= ref;
Uint32 tmpTheNode= refToNode(ref);
Uint64 tBlockNo= refToBlock(ref);
@@ -180,7 +185,7 @@
assert(theMyRef == numberToRef(theNdbBlockNumber, tmpTheNode));
}
- TransporterFacade * theFacade = TransporterFacade::instance();
+ TransporterFacade * theFacade = theImpl->m_transporter_facade;
int i, n= 0;
for (i = 1; i < MAX_NDB_NODES; i++){
if (theFacade->getIsDbNode(i)){
@@ -188,32 +193,47 @@
n++;
}
}
- theImpl->theNoOfDBnodes= n;
+ theImpl->theNoOfDBnodes = n;
+
theFirstTransId = ((Uint64)tBlockNo << 52)+
((Uint64)tmpTheNode << 40);
theFirstTransId += theFacade->m_max_trans_id;
// assert(0);
- DBUG_PRINT("info",("connected with ref=%x, id=%d, no_db_nodes=%d, first_trans_id=%lx",
+ DBUG_PRINT("info",("connected with ref=%x, id=%d, no_db_nodes=%d, first_trans_id: 0x%lx",
theMyRef,
tmpTheNode,
theImpl->theNoOfDBnodes,
- theFirstTransId));
+ (long) theFirstTransId));
theCommitAckSignal = new NdbApiSignal(theMyRef);
theDictionary->m_receiver.m_reference= theMyRef;
theNode= tmpTheNode; // flag that Ndb object is initialized
}
+void Ndb::report_node_connected(Uint32 nodeId)
+{
+ if (theEventBuffer)
+ {
+ // node connected
+ // eventOperations in the ndb object should be notified
+ theEventBuffer->report_node_connected(nodeId);
+ }
+}
+
void
Ndb::statusMessage(void* NdbObject, Uint32 a_node, bool alive, bool nfComplete)
{
DBUG_ENTER("Ndb::statusMessage");
+ DBUG_PRINT("info", ("a_node: %u alive: %u nfComplete: %u",
+ a_node, alive, nfComplete));
Ndb* tNdb = (Ndb*)NdbObject;
if (alive) {
if (nfComplete) {
+ // cluster connect, a_node == own reference
tNdb->connected(a_node);
DBUG_VOID_RETURN;
}//if
+ tNdb->report_node_connected(a_node);
} else {
if (nfComplete) {
tNdb->report_node_failure_completed(a_node);
@@ -235,6 +255,7 @@
*
* This method is only called by ClusterMgr (via lots of methods)
*/
+
theImpl->the_release_ind[node_id] = 1;
// must come after
theImpl->the_release_ind[0] = 1;
@@ -246,6 +267,19 @@
void
Ndb::report_node_failure_completed(Uint32 node_id)
{
+ if (theEventBuffer)
+ {
+ // node failed
+ // eventOperations in the ndb object should be notified
+ theEventBuffer->report_node_failure(node_id);
+ if(!theImpl->m_transporter_facade->theClusterMgr->isClusterAlive())
+ {
+ // cluster is unavailable,
+ // eventOperations in the ndb object should be notified
+ theEventBuffer->completeClusterFailed();
+ }
+ }
+
abortTransactionsAfterNodeFailure(node_id);
}//Ndb::report_node_failure_completed()
@@ -323,6 +357,7 @@
const Uint32 tFirstData = *tDataPtr;
const Uint32 tLen = aSignal->getLength();
void * tFirstDataPtr;
+ NdbWaiter *t_waiter;
/*
In order to support 64 bit processes in the application we need to use
@@ -352,10 +387,11 @@
}//if
if(TcKeyConf::getMarkerFlag(keyConf->confInfo)){
- NdbTransaction::sendTC_COMMIT_ACK(theCommitAckSignal,
- keyConf->transId1,
- keyConf->transId2,
- aTCRef);
+ NdbTransaction::sendTC_COMMIT_ACK(theImpl->m_transporter_facade,
+ theCommitAckSignal,
+ keyConf->transId1,
+ keyConf->transId2,
+ aTCRef);
}
return;
@@ -431,10 +467,11 @@
#endif
}
if(tFirstData & 1){
- NdbTransaction::sendTC_COMMIT_ACK(theCommitAckSignal,
- failConf->transId1,
- failConf->transId2,
- aTCRef);
+ NdbTransaction::sendTC_COMMIT_ACK(theImpl->m_transporter_facade,
+ theCommitAckSignal,
+ failConf->transId1,
+ failConf->transId2,
+ aTCRef);
}
return;
}
@@ -461,7 +498,7 @@
ndbout_c("Recevied TCKEY_FAILREF wo/ operation");
#endif
return;
- break;
+ return;
}
case GSN_TCKEYREF:
{
@@ -502,10 +539,11 @@
}//if
if(tFirstData & 1){
- NdbTransaction::sendTC_COMMIT_ACK(theCommitAckSignal,
- commitConf->transId1,
- commitConf->transId2,
- aTCRef);
+ NdbTransaction::sendTC_COMMIT_ACK(theImpl->m_transporter_facade,
+ theCommitAckSignal,
+ commitConf->transId1,
+ commitConf->transId2,
+ aTCRef);
}
return;
}
@@ -661,11 +699,75 @@
case GSN_CREATE_INDX_REF:
case GSN_DROP_INDX_CONF:
case GSN_DROP_INDX_REF:
+ case GSN_CREATE_EVNT_CONF:
+ case GSN_CREATE_EVNT_REF:
+ case GSN_DROP_EVNT_CONF:
+ case GSN_DROP_EVNT_REF:
case GSN_LIST_TABLES_CONF:
+ case GSN_CREATE_FILE_REF:
+ case GSN_CREATE_FILE_CONF:
+ case GSN_CREATE_FILEGROUP_REF:
+ case GSN_CREATE_FILEGROUP_CONF:
+ case GSN_DROP_FILE_REF:
+ case GSN_DROP_FILE_CONF:
+ case GSN_DROP_FILEGROUP_REF:
+ case GSN_DROP_FILEGROUP_CONF:
+ case GSN_WAIT_GCP_CONF:
+ case GSN_WAIT_GCP_REF:
NdbDictInterface::execSignal(&theDictionary->m_receiver,
aSignal, ptr);
- break;
+ return;
+
+ case GSN_SUB_REMOVE_CONF:
+ case GSN_SUB_REMOVE_REF:
+ return; // ignore these signals
+ case GSN_SUB_START_CONF:
+ case GSN_SUB_START_REF:
+ case GSN_SUB_STOP_CONF:
+ case GSN_SUB_STOP_REF:
+ NdbDictInterface::execSignal(&theDictionary->m_receiver,
+ aSignal, ptr);
+ return;
+ case GSN_SUB_GCP_COMPLETE_REP:
+ {
+ const SubGcpCompleteRep * const rep=
+ CAST_CONSTPTR(SubGcpCompleteRep, aSignal->getDataPtr());
+ theEventBuffer->execSUB_GCP_COMPLETE_REP(rep);
+ return;
+ }
+ case GSN_SUB_TABLE_DATA:
+ {
+ const SubTableData * const sdata=
+ CAST_CONSTPTR(SubTableData, aSignal->getDataPtr());
+ const Uint32 oid = sdata->senderData;
+ NdbEventOperationImpl *op= (NdbEventOperationImpl*)int2void(oid);
+
+ if (unlikely(op == 0 || op->m_magic_number != NDB_EVENT_OP_MAGIC_NUMBER))
+ {
+ g_eventLogger.error("dropped GSN_SUB_TABLE_DATA due to wrong magic "
+ "number");
+ return ;
+ }
+
+ // Accumulate DIC_TAB_INFO for TE_ALTER events
+ if (SubTableData::getOperation(sdata->requestInfo) ==
+ NdbDictionary::Event::_TE_ALTER &&
+ !op->execSUB_TABLE_DATA(aSignal, ptr))
+ return;
+ for (int i= aSignal->m_noOfSections;i < 3; i++) {
+ ptr[i].p = NULL;
+ ptr[i].sz = 0;
+ }
+ DBUG_PRINT("info",("oid=senderData: %d, gci: %d, operation: %d, "
+ "tableId: %d",
+ sdata->senderData, sdata->gci,
+ SubTableData::getOperation(sdata->requestInfo),
+ sdata->tableId));
+
+ theEventBuffer->insertDataL(op,sdata, ptr);
+ return;
+ }
case GSN_DIHNDBTAMPER:
{
tFirstDataPtr = int2void(tFirstData);
@@ -777,10 +879,11 @@
}//if
if(TcIndxConf::getMarkerFlag(indxConf->confInfo)){
- NdbTransaction::sendTC_COMMIT_ACK(theCommitAckSignal,
- indxConf->transId1,
- indxConf->transId2,
- aTCRef);
+ NdbTransaction::sendTC_COMMIT_ACK(theImpl->m_transporter_facade,
+ theCommitAckSignal,
+ indxConf->transId1,
+ indxConf->transId2,
+ aTCRef);
}
return;
}
@@ -806,11 +909,32 @@
}
default:
goto InvalidSignal;
- }//switch
-
- if (theImpl->theWaiter.m_state == NO_WAIT) {
- // Wake up the thread waiting for response
- NdbCondition_Signal(theImpl->theWaiter.m_condition);
+ }//swich
+
+ t_waiter= &theImpl->theWaiter;
+ if (t_waiter->get_state() == NO_WAIT && tWaitState != NO_WAIT)
+ {
+ /*
+ If our waiter object is the owner of the "poll rights", then we
+ can simply return, we will return from this routine to the
+ place where external_poll was called. From there it will move
+ the "poll ownership" to a new thread if available.
+
+ If our waiter object doesn't own the "poll rights", then we must
+ signal the thread from where this waiter object called
+ its conditional wait. This will wake up this thread so that it
+ can continue its work.
+ */
+ TransporterFacade *tp= theImpl->m_transporter_facade;
+ if (tp->get_poll_owner() != t_waiter)
+ {
+ /*
+ Wake up the thread waiting for response and remove it from queue
+ of objects waiting for receive completion
+ */
+ tp->remove_from_cond_wait_queue(t_waiter);
+ t_waiter->cond_signal();
+ }
}//if
return;
@@ -865,7 +989,19 @@
if ((theMinNoOfEventsToWakeUp != 0) &&
(theNoOfCompletedTransactions >= theMinNoOfEventsToWakeUp)) {
theMinNoOfEventsToWakeUp = 0;
- NdbCondition_Signal(theImpl->theWaiter.m_condition);
+ TransporterFacade *tp = theImpl->m_transporter_facade;
+ NdbWaiter *t_waiter= &theImpl->theWaiter;
+ if (tp->get_poll_owner() != t_waiter) {
+ /*
+ When we come here, this is executed by the thread owning the "poll
+ rights". This thread is not where our waiter object belongs.
+ Thus we wake up the thread owning this waiter object but first
+ we must remove it from the conditional wait queue so that we
+ don't assign it as poll owner later on.
+ */
+ tp->remove_from_cond_wait_queue(t_waiter);
+ t_waiter->cond_signal();
+ }
return;
}//if
} else {
@@ -935,8 +1071,9 @@
void
Ndb::check_send_timeout()
{
- Uint32 timeout = TransporterFacade::instance()->m_waitfor_timeout;
+ Uint32 timeout = theImpl->m_transporter_facade->m_waitfor_timeout;
NDB_TICKS current_time = NdbTick_CurrentMillisecond();
+ assert(current_time >= the_last_check_time);
if (current_time - the_last_check_time > 1000) {
the_last_check_time = current_time;
Uint32 no_of_sent = theNoOfSentTransactions;
@@ -1024,7 +1161,7 @@
and we keep a small space for messages like that.
*/
Uint32 i;
- TransporterFacade* tp = TransporterFacade::instance();
+ TransporterFacade* tp = theImpl->m_transporter_facade;
Uint32 no_of_prep_trans = theNoOfPreparedTransactions;
for (i = 0; i < no_of_prep_trans; i++) {
NdbTransaction * a_con = thePreparedTransactionsArray[i];
@@ -1127,7 +1264,8 @@
******************************************************************************/
void
Ndb::waitCompletedTransactions(int aMilliSecondsToWait,
- int noOfEventsToWaitFor)
+ int noOfEventsToWaitFor,
+ PollGuard *poll_guard)
{
theImpl->theWaiter.m_state = NO_WAIT;
/**
@@ -1136,22 +1274,24 @@
* (see ReportFailure)
*/
int waitTime = aMilliSecondsToWait;
- NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + (NDB_TICKS)waitTime;
+ NDB_TICKS currTime = NdbTick_CurrentMillisecond();
+ NDB_TICKS maxTime = currTime + (NDB_TICKS)waitTime;
theMinNoOfEventsToWakeUp = noOfEventsToWaitFor;
+ const int maxsleep = aMilliSecondsToWait > 10 ? 10 : aMilliSecondsToWait;
do {
- if (waitTime < 1000) waitTime = 1000;
- NdbCondition_WaitTimeout(theImpl->theWaiter.m_condition,
- (NdbMutex*)theImpl->theWaiter.m_mutex,
- waitTime);
+ poll_guard->wait_for_input(maxsleep);
if (theNoOfCompletedTransactions >= (Uint32)noOfEventsToWaitFor) {
break;
}//if
theMinNoOfEventsToWakeUp = noOfEventsToWaitFor;
waitTime = (int)(maxTime - NdbTick_CurrentMillisecond());
} while (waitTime > 0);
- return;
}//Ndb::waitCompletedTransactions()
+void Ndb::cond_signal()
+{
+ NdbCondition_Signal(theImpl->theWaiter.m_condition);
+}
/*****************************************************************************
void sendPreparedTransactions(int forceSend = 0);
@@ -1162,9 +1302,9 @@
void
Ndb::sendPreparedTransactions(int forceSend)
{
- TransporterFacade::instance()->lock_mutex();
+ theImpl->m_transporter_facade->lock_mutex();
sendPrepTrans(forceSend);
- TransporterFacade::instance()->unlock_mutex();
+ theImpl->m_transporter_facade->unlock_mutex();
return;
}//Ndb::sendPreparedTransactions()
@@ -1179,28 +1319,39 @@
int
Ndb::sendPollNdb(int aMillisecondNumber, int minNoOfEventsToWakeup, int forceSend)
{
+ /*
+ The PollGuard has an implicit call of unlock_and_signal through the
+ ~PollGuard method. This method is called implicitly by the compiler
+ in all places where the object is out of context due to a return,
+ break, continue or simply end of statement block
+ */
+ PollGuard pg(theImpl->m_transporter_facade, &theImpl->theWaiter,
+ theNdbBlockNumber);
+ sendPrepTrans(forceSend);
+ return poll_trans(aMillisecondNumber, minNoOfEventsToWakeup, &pg);
+}
+
+int
+Ndb::poll_trans(int aMillisecondNumber, int minNoOfEventsToWakeup,
+ PollGuard *pg)
+{
NdbTransaction* tConArray[1024];
Uint32 tNoCompletedTransactions;
-
- //theCurrentConnectCounter = 0;
- //theCurrentConnectIndex++;
- TransporterFacade::instance()->lock_mutex();
- sendPrepTrans(forceSend);
if ((minNoOfEventsToWakeup <= 0) ||
((Uint32)minNoOfEventsToWakeup > theNoOfSentTransactions)) {
minNoOfEventsToWakeup = theNoOfSentTransactions;
}//if
if ((theNoOfCompletedTransactions < (Uint32)minNoOfEventsToWakeup) &&
(aMillisecondNumber > 0)) {
- waitCompletedTransactions(aMillisecondNumber, minNoOfEventsToWakeup);
+ waitCompletedTransactions(aMillisecondNumber, minNoOfEventsToWakeup, pg);
tNoCompletedTransactions = pollCompleted(tConArray);
} else {
tNoCompletedTransactions = pollCompleted(tConArray);
}//if
- TransporterFacade::instance()->unlock_mutex();
+ pg->unlock_and_signal();
reportCallback(tConArray, tNoCompletedTransactions);
return tNoCompletedTransactions;
-}//Ndb::sendPollNdb()
+}
/*****************************************************************************
int pollNdb(int aMillisecondNumber, int minNoOfEventsToWakeup);
@@ -1212,67 +1363,23 @@
int
Ndb::pollNdb(int aMillisecondNumber, int minNoOfEventsToWakeup)
{
- NdbTransaction* tConArray[1024];
- Uint32 tNoCompletedTransactions;
-
- //theCurrentConnectCounter = 0;
- //theCurrentConnectIndex++;
- TransporterFacade::instance()->lock_mutex();
- if ((minNoOfEventsToWakeup == 0) ||
- ((Uint32)minNoOfEventsToWakeup > theNoOfSentTransactions)) {
- minNoOfEventsToWakeup = theNoOfSentTransactions;
- }//if
- if ((theNoOfCompletedTransactions < (Uint32)minNoOfEventsToWakeup) &&
- (aMillisecondNumber > 0)) {
- waitCompletedTransactions(aMillisecondNumber, minNoOfEventsToWakeup);
- tNoCompletedTransactions = pollCompleted(tConArray);
- } else {
- tNoCompletedTransactions = pollCompleted(tConArray);
- }//if
- TransporterFacade::instance()->unlock_mutex();
- reportCallback(tConArray, tNoCompletedTransactions);
- return tNoCompletedTransactions;
-}//Ndb::sendPollNdbWithoutWait()
-
-/*****************************************************************************
-int receiveOptimisedResponse();
-
-Return: 0 - Response received
- -1 - Timeout occured waiting for response
- -2 - Node failure interupted wait for response
-
-******************************************************************************/
-int
-Ndb::receiveResponse(int waitTime){
- int tResultCode;
- TransporterFacade::instance()->checkForceSend(theNdbBlockNumber);
-
- theImpl->theWaiter.wait(waitTime);
-
- if(theImpl->theWaiter.m_state == NO_WAIT) {
- tResultCode = 0;
- } else {
-
-#ifdef VM_TRACE
- ndbout << "ERR: receiveResponse - theImpl->theWaiter.m_state = ";
- ndbout << theImpl->theWaiter.m_state << endl;
-#endif
-
- if (theImpl->theWaiter.m_state == WAIT_NODE_FAILURE){
- tResultCode = -2;
- } else {
- tResultCode = -1;
- }
- theImpl->theWaiter.m_state = NO_WAIT;
- }
- return tResultCode;
-}//Ndb::receiveResponse()
+ /*
+ The PollGuard has an implicit call of unlock_and_signal through the
+ ~PollGuard method. This method is called implicitly by the compiler
+ in all places where the object is out of context due to a return,
+ break, continue or simply end of statement block
+ */
+ PollGuard pg(theImpl->m_transporter_facade, &theImpl->theWaiter,
+ theNdbBlockNumber);
+ return poll_trans(aMillisecondNumber, minNoOfEventsToWakeup, &pg);
+}
int
Ndb::sendRecSignal(Uint16 node_id,
Uint32 aWaitState,
NdbApiSignal* aSignal,
- Uint32 conn_seq)
+ Uint32 conn_seq,
+ Uint32 *ret_conn_seq)
{
/*
In most situations 0 is returned.
@@ -1285,19 +1392,28 @@
*/
int return_code;
- TransporterFacade* tp = TransporterFacade::instance();
- Uint32 send_size = 1; // Always sends one signal only
- tp->lock_mutex();
+ Uint32 read_conn_seq;
+ TransporterFacade* tp = theImpl->m_transporter_facade;
+ Uint32 send_size = 1; // Always sends one signal only
// Protected area
+ /*
+ The PollGuard has an implicit call of unlock_and_signal through the
+ ~PollGuard method. This method is called implicitly by the compiler
+ in all places where the object is out of context due to a return,
+ break, continue or simply end of statement block
+ */
+ PollGuard poll_guard(tp,&theImpl->theWaiter,theNdbBlockNumber);
+ read_conn_seq= tp->getNodeSequence(node_id);
+ if (ret_conn_seq)
+ *ret_conn_seq= read_conn_seq;
if ((tp->get_node_alive(node_id)) &&
- ((tp->getNodeSequence(node_id) == conn_seq) ||
+ ((read_conn_seq == conn_seq) ||
(conn_seq == 0))) {
if (tp->check_send_size(node_id, send_size)) {
return_code = tp->sendSignal(aSignal, node_id);
if (return_code != -1) {
- theImpl->theWaiter.m_node = node_id;
- theImpl->theWaiter.m_state = aWaitState;
- return_code = receiveResponse();
+ return poll_guard.wait_n_unlock(WAITFOR_RESPONSE_TIMEOUT,node_id,
+ aWaitState, false);
} else {
return_code = -3;
}
@@ -1306,29 +1422,28 @@
}//if
} else {
if ((tp->get_node_stopping(node_id)) &&
- ((tp->getNodeSequence(node_id) == conn_seq) ||
+ ((read_conn_seq == conn_seq) ||
(conn_seq == 0))) {
return_code = -5;
} else {
return_code = -2;
}//if
}//if
- tp->unlock_mutex();
- // End of protected area
return return_code;
+ // End of protected area
}//Ndb::sendRecSignal()
void
-NdbTransaction::sendTC_COMMIT_ACK(NdbApiSignal * aSignal,
- Uint32 transId1, Uint32 transId2,
- Uint32 aTCRef){
+NdbTransaction::sendTC_COMMIT_ACK(TransporterFacade *tp,
+ NdbApiSignal * aSignal,
+ Uint32 transId1, Uint32 transId2,
+ Uint32 aTCRef){
#ifdef MARKER_TRACE
ndbout_c("Sending TC_COMMIT_ACK(0x%.8x, 0x%.8x) to -> %d",
transId1,
transId2,
refToNode(aTCRef));
#endif
- TransporterFacade *tp = TransporterFacade::instance();
aSignal->theTrace = TestOrd::TraceAPI;
aSignal->theReceiversBlockNumber = DBTC;
aSignal->theVerId_signalNumber = GSN_TC_COMMIT_ACK;
@@ -1337,6 +1452,29 @@
Uint32 * dataPtr = aSignal->getDataPtrSend();
dataPtr[0] = transId1;
dataPtr[1] = transId2;
-
tp->sendSignalUnCond(aSignal, refToNode(aTCRef));
+}
+
+int
+NdbImpl::send_event_report(Uint32 *data, Uint32 length)
+{
+ NdbApiSignal aSignal(m_ndb.theMyRef);
+ TransporterFacade *tp = m_transporter_facade;
+ aSignal.theTrace = TestOrd::TraceAPI;
+ aSignal.theReceiversBlockNumber = CMVMI;
+ aSignal.theVerId_signalNumber = GSN_EVENT_REP;
+ aSignal.theLength = length;
+ memcpy((char *)aSignal.getDataPtrSend(), (char *)data, length*4);
+
+ Uint32 tNode;
+ Ndb_cluster_connection_node_iter node_iter;
+ m_ndb_cluster_connection.init_get_next_node(node_iter);
+ while ((tNode= m_ndb_cluster_connection.get_next_node(node_iter)))
+ {
+ if(tp->get_node_alive(tNode)){
+ tp->sendSignal(&aSignal, tNode);
+ return 0;
+ }
+ }
+ return 1;
}
--- 1.8.1.1/ndb/test/ndbapi/testBasic.cpp 2006-12-15 16:57:49 +01:00
+++ 1.15/storage/ndb/test/ndbapi/testBasic.cpp 2006-12-15 16:57:49 +01:00
@@ -1035,6 +1035,222 @@
}
int
+runMassiveRollback3(NDBT_Context* ctx, NDBT_Step* step){
+
+ int result = NDBT_OK;
+ HugoOperations hugoOps(*ctx->getTab());
+ Ndb* pNdb = GETNDB(step);
+
+ const Uint32 BATCH = 10;
+ const Uint32 OPS_TOTAL = 50;
+ const Uint32 LOOPS = 100;
+
+ for(Uint32 loop = 0; loop<LOOPS; loop++)
+ {
+ CHECK(hugoOps.startTransaction(pNdb) == 0);
+ bool ok = true;
+ for (Uint32 i = 0; i<OPS_TOTAL; i+= BATCH)
+ {
+ CHECK(hugoOps.pkInsertRecord(pNdb, i, BATCH, 0) == 0);
+ if (hugoOps.execute_NoCommit(pNdb) != 0)
+ {
+ ok = false;
+ break;
+ }
+ }
+ hugoOps.execute_Rollback(pNdb);
+ CHECK(hugoOps.closeTransaction(pNdb) == 0);
+ }
+
+ hugoOps.closeTransaction(pNdb);
+ return result;
+}
+
+int
+runMassiveRollback4(NDBT_Context* ctx, NDBT_Step* step){
+
+ int result = NDBT_OK;
+ HugoOperations hugoOps(*ctx->getTab());
+ Ndb* pNdb = GETNDB(step);
+
+ const Uint32 BATCH = 10;
+ const Uint32 OPS_TOTAL = 20;
+ const Uint32 LOOPS = 100;
+
+ for(Uint32 loop = 0; loop<LOOPS; loop++)
+ {
+ CHECK(hugoOps.startTransaction(pNdb) == 0);
+ bool ok = true;
+ for (Uint32 i = 0; i<OPS_TOTAL; i+= BATCH)
+ {
+ CHECK(hugoOps.pkInsertRecord(pNdb, i, BATCH, 0) == 0);
+ CHECK(hugoOps.pkDeleteRecord(pNdb, i, BATCH) == 0);
+ if (hugoOps.execute_NoCommit(pNdb) != 0)
+ {
+ ok = false;
+ break;
+ }
+ }
+ hugoOps.execute_Rollback(pNdb);
+ CHECK(hugoOps.closeTransaction(pNdb) == 0);
+ }
+
+ hugoOps.closeTransaction(pNdb);
+ return result;
+}
+
+/**
+ * TUP errors
+ */
+struct TupError
+{
+ enum Bits {
+ TE_VARSIZE = 0x1,
+ TE_MULTI_OP = 0x2,
+ TE_DISK = 0x4,
+ TE_REPLICA = 0x8
+ };
+ int op;
+ int error;
+ int bits;
+};
+
+static
+TupError
+f_tup_errors[] =
+{
+ { NdbOperation::InsertRequest, 4014, 0 }, // Out of undo buffer
+ { NdbOperation::InsertRequest, 4015, TupError::TE_DISK }, // Out of log space
+ { NdbOperation::InsertRequest, 4016, 0 }, // AI Inconsistency
+ { NdbOperation::InsertRequest, 4017, 0 }, // Out of memory
+ { NdbOperation::InsertRequest, 4018, 0 }, // Null check error
+ { NdbOperation::InsertRequest, 4019, TupError::TE_REPLICA }, //Alloc rowid error
+ { NdbOperation::InsertRequest, 4020, TupError::TE_MULTI_OP }, // Size change error
+ { NdbOperation::InsertRequest, 4021, TupError::TE_DISK }, // Out of disk space
+ { -1, 0, 0 }
+};
+
+int
+runTupErrors(NDBT_Context* ctx, NDBT_Step* step){
+
+ NdbRestarter restarter;
+ HugoTransactions hugoTrans(*ctx->getTab());
+ HugoOperations hugoOps(*ctx->getTab());
+ Ndb* pNdb = GETNDB(step);
+
+ const NdbDictionary::Table * tab = ctx->getTab();
+ Uint32 i;
+ int bits = TupError::TE_MULTI_OP;
+ for(i = 0; i<tab->getNoOfColumns(); i++)
+ {
+ if (tab->getColumn(i)->getArrayType() != NdbDictionary::Column::ArrayTypeFixed)
+ bits |= TupError::TE_VARSIZE;
+ if (tab->getColumn(i)->getStorageType()!= NdbDictionary::Column::StorageTypeMemory)
+ bits |= TupError::TE_DISK;
+ }
+
+ if (restarter.getNumDbNodes() >= 2)
+ {
+ bits |= TupError::TE_REPLICA;
+ }
+
+ /**
+ * Insert
+ */
+ for(i = 0; f_tup_errors[i].op != -1; i++)
+ {
+ if (f_tup_errors[i].op != NdbOperation::InsertRequest)
+ {
+ g_info << "Skipping " << f_tup_errors[i].error
+ << " - not insert" << endl;
+ continue;
+ }
+
+ if ((f_tup_errors[i].bits & bits) != f_tup_errors[i].bits)
+ {
+ g_info << "Skipping " << f_tup_errors[i].error
+ << " - req bits: " << hex << f_tup_errors[i].bits
+ << " bits: " << hex << bits << endl;
+ continue;
+ }
+
+ g_info << "Testing error insert: " << f_tup_errors[i].error << endl;
+ restarter.insertErrorInAllNodes(f_tup_errors[i].error);
+ if (f_tup_errors[i].bits & TupError::TE_MULTI_OP)
+ {
+
+ }
+ else
+ {
+ hugoTrans.loadTable(pNdb, 5);
+ }
+ restarter.insertErrorInAllNodes(0);
+ if (hugoTrans.clearTable(pNdb, 5) != 0)
+ {
+ return NDBT_FAILED;
+ }
+ }
+
+ return NDBT_OK;
+}
+
+int
+runInsertError(NDBT_Context* ctx, NDBT_Step* step){
+
+ int result = NDBT_OK;
+ HugoOperations hugoOp1(*ctx->getTab());
+ HugoOperations hugoOp2(*ctx->getTab());
+ Ndb* pNdb = GETNDB(step);
+
+ NdbRestarter restarter;
+ restarter.insertErrorInAllNodes(4017);
+ const Uint32 LOOPS = 10;
+ for (Uint32 i = 0; i<LOOPS; i++)
+ {
+ CHECK(hugoOp1.startTransaction(pNdb) == 0);
+ CHECK(hugoOp1.pkInsertRecord(pNdb, 1) == 0);
+
+ CHECK(hugoOp2.startTransaction(pNdb) == 0);
+ CHECK(hugoOp2.pkReadRecord(pNdb, 1, 1) == 0);
+
+ CHECK(hugoOp1.execute_async_prepare(pNdb, NdbTransaction::Commit) == 0);
+ CHECK(hugoOp2.execute_async_prepare(pNdb, NdbTransaction::Commit) == 0);
+ hugoOp1.wait_async(pNdb);
+ hugoOp2.wait_async(pNdb);
+ CHECK(hugoOp1.closeTransaction(pNdb) == 0);
+ CHECK(hugoOp2.closeTransaction(pNdb) == 0);
+ }
+
+ restarter.insertErrorInAllNodes(0);
+
+ return result;
+}
+
+int
+runInsertError2(NDBT_Context* ctx, NDBT_Step* step){
+ int result = NDBT_OK;
+ HugoOperations hugoOp1(*ctx->getTab());
+ Ndb* pNdb = GETNDB(step);
+
+ NdbRestarter restarter;
+ restarter.insertErrorInAllNodes(4017);
+
+ const Uint32 LOOPS = 1;
+ for (Uint32 i = 0; i<LOOPS; i++)
+ {
+ CHECK(hugoOp1.startTransaction(pNdb) == 0);
+ CHECK(hugoOp1.pkInsertRecord(pNdb, 1) == 0);
+ CHECK(hugoOp1.pkDeleteRecord(pNdb, 1) == 0);
+
+ hugoOp1.execute_NoCommit(pNdb);
+ CHECK(hugoOp1.closeTransaction(pNdb) == 0);
+ }
+
+ restarter.insertErrorInAllNodes(0);
+ return NDBT_OK;
+}
+
+int
runBug25090(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = GETNDB(step);
@@ -1288,11 +1504,35 @@
INITIALIZER(runMassiveRollback2);
FINALIZER(runClearTable2);
}
+TESTCASE("MassiveRollback3",
+ "Test rollback of 4096 operations"){
+ INITIALIZER(runClearTable2);
+ STEP(runMassiveRollback3);
+ STEP(runMassiveRollback3);
+ FINALIZER(runClearTable2);
+}
+TESTCASE("MassiveRollback4",
+ "Test rollback of 4096 operations"){
+ INITIALIZER(runClearTable2);
+ STEP(runMassiveRollback4);
+ STEP(runMassiveRollback4);
+ FINALIZER(runClearTable2);
+}
TESTCASE("MassiveTransaction",
"Test very large insert transaction"){
INITIALIZER(runLoadTable2);
FINALIZER(runClearTable2);
}
+TESTCASE("TupError",
+ "Verify what happens when we fill the db" ){
+ INITIALIZER(runTupErrors);
+}
+TESTCASE("InsertError", "" ){
+ INITIALIZER(runInsertError);
+}
+TESTCASE("InsertError2", "" ){
+ INITIALIZER(runInsertError2);
+}
TESTCASE("Fill",
"Verify what happens when we fill the db" ){
INITIALIZER(runFillTable);
@@ -1311,6 +1551,12 @@
"same result no matter"){
STEP(runInsertOne);
STEP(runReadOne);
+ FINALIZER(runClearTable2);
+}
+TESTCASE("Fill",
+ "Verify what happens when we fill the db" ){
+ INITIALIZER(runFillTable);
+ INITIALIZER(runPkRead);
FINALIZER(runClearTable2);
}
#endif
| Thread |
|---|
| • bk commit into 5.1 tree (jonas:1.2356) | jonas | 15 Dec |