summaryrefslogtreecommitdiff
path: root/ndb
diff options
context:
space:
mode:
Diffstat (limited to 'ndb')
-rw-r--r--ndb/include/ndbapi/Ndb.hpp28
-rw-r--r--ndb/include/ndbapi/NdbBlob.hpp6
-rw-r--r--ndb/include/ndbapi/NdbConnection.hpp12
-rw-r--r--ndb/include/ndbapi/NdbIndexOperation.hpp1
-rw-r--r--ndb/include/ndbapi/NdbIndexScanOperation.hpp2
-rw-r--r--ndb/include/ndbapi/NdbOperation.hpp8
-rw-r--r--ndb/include/ndbapi/NdbRecAttr.hpp7
-rw-r--r--ndb/include/util/Parser.hpp2
-rw-r--r--ndb/src/common/portlib/NdbThread.c10
-rw-r--r--ndb/src/kernel/blocks/ERROR_codes.txt5
-rw-r--r--ndb/src/kernel/blocks/backup/Backup.cpp1
-rw-r--r--ndb/src/kernel/blocks/dbdict/Dbdict.cpp156
-rw-r--r--ndb/src/kernel/blocks/dbdict/Dbdict.hpp329
-rw-r--r--ndb/src/kernel/blocks/dbdict/Makefile.am12
-rw-r--r--ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp11
-rw-r--r--ndb/src/kernel/blocks/dbtc/DbtcMain.cpp10
-rw-r--r--ndb/src/kernel/blocks/dbtup/Dbtup.hpp3
-rw-r--r--ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp16
-rw-r--r--ndb/src/mgmapi/mgmapi.cpp3
-rw-r--r--ndb/src/mgmsrv/MgmtSrvr.cpp5
-rw-r--r--ndb/src/ndbapi/NdbApiSignal.cpp19
-rw-r--r--ndb/src/ndbapi/NdbApiSignal.hpp3
-rw-r--r--ndb/src/ndbapi/NdbBlob.cpp2
-rw-r--r--ndb/src/ndbapi/NdbImpl.hpp119
-rw-r--r--ndb/src/ndbapi/NdbRecAttr.cpp4
-rw-r--r--ndb/src/ndbapi/NdbUtil.cpp16
-rw-r--r--ndb/src/ndbapi/NdbUtil.hpp41
-rw-r--r--ndb/src/ndbapi/Ndbif.cpp9
-rw-r--r--ndb/src/ndbapi/Ndbinit.cpp46
-rw-r--r--ndb/src/ndbapi/Ndblist.cpp519
-rw-r--r--ndb/src/ndbapi/ObjectMap.hpp33
-rw-r--r--ndb/src/ndbapi/SignalSender.cpp12
-rw-r--r--ndb/test/include/NDBT_Test.hpp5
-rw-r--r--ndb/test/ndbapi/Makefile.am5
-rw-r--r--ndb/test/ndbapi/bank/Bank.cpp168
-rw-r--r--ndb/test/ndbapi/bank/Bank.hpp2
-rw-r--r--ndb/test/ndbapi/bank/BankLoad.cpp4
-rw-r--r--ndb/test/ndbapi/testOIBasic.cpp6
-rw-r--r--ndb/test/ndbapi/testSRBank.cpp246
-rw-r--r--ndb/test/src/HugoCalculator.cpp6
-rw-r--r--ndb/test/src/NDBT_Test.cpp11
-rw-r--r--ndb/test/src/NdbBackup.cpp2
-rw-r--r--ndb/test/src/NdbRestarts.cpp30
-rw-r--r--ndb/test/src/UtilTransactions.cpp22
-rw-r--r--ndb/tools/restore/Restore.cpp2
45 files changed, 1154 insertions, 805 deletions
diff --git a/ndb/include/ndbapi/Ndb.hpp b/ndb/include/ndbapi/Ndb.hpp
index 766409d64e2..e905a304c97 100644
--- a/ndb/include/ndbapi/Ndb.hpp
+++ b/ndb/include/ndbapi/Ndb.hpp
@@ -882,10 +882,10 @@ class BaseString;
class NdbEventOperation;
class NdbBlob;
class NdbReceiver;
+template <class T> struct Ndb_free_list_t;
typedef void (* NdbEventCallback)(NdbEventOperation*, Ndb*, void*);
-
#if defined NDB_OSE
/**
* Default time to wait for response after request has been sent to
@@ -1386,8 +1386,20 @@ public:
*/
NdbConnection* hupp( NdbConnection* );
Uint32 getReference() const { return theMyRef;}
+
+ struct Free_list_usage
+ {
+ const char * m_name;
+ Uint32 m_created;
+ Uint32 m_free;
+ Uint32 m_sizeof;
+ };
+
+ Free_list_usage * get_free_list_usage(Free_list_usage*);
#endif
+
+
/*****************************************************************************
* These are service routines used by the other classes in the NDBAPI.
****************************************************************************/
@@ -1562,22 +1574,8 @@ private:
class NdbDictionaryImpl* theDictionary;
class NdbGlobalEventBufferHandle* theGlobalEventBufferHandle;
- NdbConnection* theConIdleList; // First connection in idle list.
-
- NdbOperation* theOpIdleList; // First operation in the idle list.
-
- NdbIndexScanOperation* theScanOpIdleList; // First scan operation in the idle list.
- NdbIndexOperation* theIndexOpIdleList; // First index operation in the idle list.
NdbConnection* theTransactionList;
NdbConnection** theConnectionArray;
- NdbRecAttr* theRecAttrIdleList;
- NdbApiSignal* theSignalIdleList; // First signal in idlelist.
- NdbLabel* theLabelList; // First label descriptor in list
- NdbBranch* theBranchList; // First branch descriptor in list
- NdbSubroutine* theSubroutineList; // First subroutine descriptor in
- NdbCall* theCallList; // First call descriptor in list
- NdbReceiver* theScanList;
- NdbBlob* theNdbBlobIdleList;
Uint32 theMyRef; // My block reference
Uint32 theNode; // The node number of our node
diff --git a/ndb/include/ndbapi/NdbBlob.hpp b/ndb/include/ndbapi/NdbBlob.hpp
index b145c69b04b..a04f4f72bc9 100644
--- a/ndb/include/ndbapi/NdbBlob.hpp
+++ b/ndb/include/ndbapi/NdbBlob.hpp
@@ -262,7 +262,7 @@ private:
// for keeping in lists
NdbBlob* theNext;
// initialization
- NdbBlob();
+ NdbBlob(Ndb*);
void init();
void release();
// classify operations
@@ -314,6 +314,10 @@ private:
int getOperationType() const;
friend class NdbOut& operator<<(NdbOut&, const NdbBlob&);
#endif
+
+ void next(NdbBlob* obj) { theNext= obj;}
+ NdbBlob* next() { return theNext;}
+ friend struct Ndb_free_list_t<NdbBlob>;
};
#endif
diff --git a/ndb/include/ndbapi/NdbConnection.hpp b/ndb/include/ndbapi/NdbConnection.hpp
index 2ab6f7d6f64..75c3f80121d 100644
--- a/ndb/include/ndbapi/NdbConnection.hpp
+++ b/ndb/include/ndbapi/NdbConnection.hpp
@@ -18,8 +18,9 @@
#define NdbConnection_H
#include <ndb_types.h>
-#include <NdbError.hpp>
-#include <NdbDictionary.hpp>
+#include "NdbError.hpp"
+#include "NdbDictionary.hpp"
+#include "Ndb.hpp"
class NdbConnection;
class NdbOperation;
@@ -465,10 +466,10 @@ private:
/**************************************************************************
* These are the create and delete methods of this class. *
**************************************************************************/
-
NdbConnection(Ndb* aNdb);
-
~NdbConnection();
+ NdbConnection* next(); // Returns the next pointer
+ void next(NdbConnection*); // Sets the next pointer
void init(); // Initialize connection object for new transaction
@@ -487,8 +488,6 @@ private:
int getTC_ConnectPtr(); // Gets TC Connect pointer
void setBuddyConPtr(Uint32); // Sets Buddy Con Ptr
Uint32 getBuddyConPtr(); // Gets Buddy Con Ptr
- NdbConnection* next(); // Returns the next pointer
- void next(NdbConnection*); // Sets the next pointer
enum ConStatusType {
NotConnected,
@@ -691,6 +690,7 @@ private:
void define_scan_op(NdbIndexScanOperation*);
friend class HugoOperations;
+ friend struct Ndb_free_list_t<NdbConnection>;
};
inline
diff --git a/ndb/include/ndbapi/NdbIndexOperation.hpp b/ndb/include/ndbapi/NdbIndexOperation.hpp
index 1472f1b249e..2ab63cfc4f9 100644
--- a/ndb/include/ndbapi/NdbIndexOperation.hpp
+++ b/ndb/include/ndbapi/NdbIndexOperation.hpp
@@ -200,6 +200,7 @@ private:
Uint32 m_theIndexDefined[NDB_MAX_ATTRIBUTES_IN_INDEX][3];
Uint32 m_theIndexLen; // Length of the index in words
Uint32 m_theNoOfIndexDefined; // The number of index attributes
+ friend struct Ndb_free_list_t<NdbIndexOperation>;
};
#endif
diff --git a/ndb/include/ndbapi/NdbIndexScanOperation.hpp b/ndb/include/ndbapi/NdbIndexScanOperation.hpp
index a3388f62f58..7cd2daea6a6 100644
--- a/ndb/include/ndbapi/NdbIndexScanOperation.hpp
+++ b/ndb/include/ndbapi/NdbIndexScanOperation.hpp
@@ -132,6 +132,8 @@ private:
int compare(Uint32 key, Uint32 cols, const NdbReceiver*, const NdbReceiver*);
Uint32 m_sort_columns;
+
+ friend struct Ndb_free_list_t<NdbIndexScanOperation>;
};
#endif
diff --git a/ndb/include/ndbapi/NdbOperation.hpp b/ndb/include/ndbapi/NdbOperation.hpp
index 46d4ddab0f5..46e44226e18 100644
--- a/ndb/include/ndbapi/NdbOperation.hpp
+++ b/ndb/include/ndbapi/NdbOperation.hpp
@@ -22,6 +22,7 @@
#include "NdbError.hpp"
#include "NdbReceiver.hpp"
#include "NdbDictionary.hpp"
+#include "Ndb.hpp"
class Ndb;
class NdbApiSignal;
@@ -723,8 +724,6 @@ protected:
/******************************************************************************
* These are the methods used to create and delete the NdbOperation objects.
*****************************************************************************/
- NdbOperation(Ndb* aNdb);
- virtual ~NdbOperation();
bool needReply();
/******************************************************************************
@@ -736,8 +735,9 @@ protected:
int init(const class NdbTableImpl*, NdbConnection* aCon);
void initInterpreter();
+ NdbOperation(Ndb* aNdb);
+ virtual ~NdbOperation();
void next(NdbOperation*); // Set next pointer
-
NdbOperation* next(); // Get next pointer
enum OperationStatus{
@@ -925,6 +925,8 @@ protected:
* IgnoreError on connection level.
*/
Int8 m_abortOption;
+
+ friend struct Ndb_free_list_t<NdbOperation>;
};
#ifdef NDB_NO_DROPPED_SIGNAL
diff --git a/ndb/include/ndbapi/NdbRecAttr.hpp b/ndb/include/ndbapi/NdbRecAttr.hpp
index 05635a99385..741ea3d52e2 100644
--- a/ndb/include/ndbapi/NdbRecAttr.hpp
+++ b/ndb/include/ndbapi/NdbRecAttr.hpp
@@ -17,7 +17,8 @@
#ifndef NdbRecAttr_H
#define NdbRecAttr_H
-#include <NdbDictionary.hpp>
+#include "NdbDictionary.hpp"
+#include "Ndb.hpp"
class NdbOperation;
@@ -242,7 +243,6 @@ public:
*/
~NdbRecAttr();
private:
- NdbRecAttr();
Uint32 attrId() const; /* Get attribute id */
bool setNULL(); /* Set NULL indicator */
@@ -251,6 +251,7 @@ private:
void release(); /* Release memory if allocated */
void init(); /* Initialise object when allocated */
+ NdbRecAttr(Ndb*);
void next(NdbRecAttr* aRecAttr);
NdbRecAttr* next() const;
@@ -273,6 +274,8 @@ private:
Uint32 theAttrSize;
Uint32 theArraySize;
const NdbDictionary::Column* m_column;
+
+ friend struct Ndb_free_list_t<NdbRecAttr>;
};
inline
diff --git a/ndb/include/util/Parser.hpp b/ndb/include/util/Parser.hpp
index c117498e1ba..3baf7601a6c 100644
--- a/ndb/include/util/Parser.hpp
+++ b/ndb/include/util/Parser.hpp
@@ -285,7 +285,7 @@ template<class T>
inline
void
Parser<T>::setBreakOnInvalidArg(bool v){
- impl->m_breakOnInvalidArg;
+ impl->m_breakOnInvalidArg = v;
}
#endif
diff --git a/ndb/src/common/portlib/NdbThread.c b/ndb/src/common/portlib/NdbThread.c
index 55ebc4c8111..48d00956ec2 100644
--- a/ndb/src/common/portlib/NdbThread.c
+++ b/ndb/src/common/portlib/NdbThread.c
@@ -53,6 +53,16 @@ ndb_thread_wrapper(void* _ss){
}
#endif
{
+ /**
+ * Block all signals to thread by default
+ * let them go to main process instead
+ */
+ sigset_t mask;
+ sigfillset(&mask);
+ pthread_sigmask(SIG_BLOCK, &mask, 0);
+ }
+
+ {
void *ret;
struct NdbThread * ss = (struct NdbThread *)_ss;
ret= (* ss->func)(ss->object);
diff --git a/ndb/src/kernel/blocks/ERROR_codes.txt b/ndb/src/kernel/blocks/ERROR_codes.txt
index 5193d3eae9d..791df915d66 100644
--- a/ndb/src/kernel/blocks/ERROR_codes.txt
+++ b/ndb/src/kernel/blocks/ERROR_codes.txt
@@ -6,7 +6,7 @@ Next DBTUP 4013
Next DBLQH 5042
Next DBDICT 6006
Next DBDIH 7174
-Next DBTC 8035
+Next DBTC 8037
Next CMVMI 9000
Next BACKUP 10022
Next DBUTIL 11002
@@ -406,8 +406,11 @@ Drop Table/Index:
4001: Crash on REL_TABMEMREQ in TUP
4002: Crash on DROP_TABFILEREQ in TUP
4003: Fail next trigger create in TUP
+4004: Fail next trigger drop in TUP
8033: Fail next trigger create in TC
8034: Fail next index create in TC
+8035: Fail next trigger drop in TC
+8036: Fail next index drop in TC
System Restart:
---------------
diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp
index ec5c7a5d588..56af24c5cf0 100644
--- a/ndb/src/kernel/blocks/backup/Backup.cpp
+++ b/ndb/src/kernel/blocks/backup/Backup.cpp
@@ -3265,6 +3265,7 @@ Backup::execBACKUP_FRAGMENT_REQ(Signal* signal)
req->requestInfo = 0;
req->savePointId = 0;
req->tableId = table.tableId;
+ ScanFragReq::setReadCommittedFlag(req->requestInfo, 1);
ScanFragReq::setLockMode(req->requestInfo, 0);
ScanFragReq::setHoldLockFlag(req->requestInfo, 0);
ScanFragReq::setKeyinfoFlag(req->requestInfo, 0);
diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
index 3d5eb0c52aa..5bd35812b47 100644
--- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
+++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
@@ -3036,8 +3036,8 @@ Dbdict::alterTable_backup_mutex_locked(Signal* signal,
lreq->gci = tablePtr.p->gciTableCreated;
lreq->requestType = AlterTabReq::AlterTablePrepare;
- sendSignal(rg, GSN_ALTER_TAB_REQ, signal,
- AlterTabReq::SignalLength, JBB);
+ sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal,
+ AlterTabReq::SignalLength, JBB);
}
void Dbdict::alterTableRef(Signal * signal,
@@ -3521,8 +3521,8 @@ Dbdict::execALTER_TAB_CONF(Signal * signal){
lreq->gci = gci;
lreq->requestType = AlterTabReq::AlterTableCommit;
- sendSignal(rg, GSN_ALTER_TAB_REQ, signal,
- AlterTabReq::SignalLength, JBB);
+ sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal,
+ AlterTabReq::SignalLength, JBB);
}
}
else {
@@ -6740,14 +6740,16 @@ Dbdict::createIndex_sendReply(Signal* signal, OpCreateIndexPtr opPtr,
CreateIndxRef* rep = (CreateIndxRef*)signal->getDataPtrSend();
Uint32 gsn = GSN_CREATE_INDX_CONF;
Uint32 length = CreateIndxConf::InternalLength;
- bool sendRef = opPtr.p->hasError();
+ bool sendRef;
if (! toUser) {
+ sendRef = opPtr.p->hasLastError();
rep->setUserRef(opPtr.p->m_coordinatorRef);
rep->setConnectionPtr(opPtr.p->key);
rep->setRequestType(opPtr.p->m_requestType);
if (opPtr.p->m_requestType == CreateIndxReq::RT_DICT_ABORT)
sendRef = false;
} else {
+ sendRef = opPtr.p->hasError();
rep->setUserRef(opPtr.p->m_request.getUserRef());
rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
rep->setRequestType(opPtr.p->m_request.getRequestType());
@@ -6816,11 +6818,8 @@ Dbdict::execDROP_INDX_REQ(Signal* signal)
goto error;
}
- if (tmp.p->indexState == TableRecord::IS_DROPPING){
- jam();
- err = DropIndxRef::IndexNotFound;
- goto error;
- }
+ if (tmp.p->indexState != TableRecord::IS_ONLINE)
+ req->addRequestFlag(RequestFlag::RF_FORCE);
tmp.p->indexState = TableRecord::IS_DROPPING;
@@ -7083,14 +7082,16 @@ Dbdict::dropIndex_sendReply(Signal* signal, OpDropIndexPtr opPtr,
DropIndxRef* rep = (DropIndxRef*)signal->getDataPtrSend();
Uint32 gsn = GSN_DROP_INDX_CONF;
Uint32 length = DropIndxConf::InternalLength;
- bool sendRef = opPtr.p->hasError();
+ bool sendRef;
if (! toUser) {
+ sendRef = opPtr.p->hasLastError();
rep->setUserRef(opPtr.p->m_coordinatorRef);
rep->setConnectionPtr(opPtr.p->key);
rep->setRequestType(opPtr.p->m_requestType);
if (opPtr.p->m_requestType == DropIndxReq::RT_DICT_ABORT)
sendRef = false;
} else {
+ sendRef = opPtr.p->hasError();
rep->setUserRef(opPtr.p->m_request.getUserRef());
rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
rep->setRequestType(opPtr.p->m_request.getRequestType());
@@ -9607,7 +9608,7 @@ Dbdict::alterIndex_fromCreateTc(Signal* signal, OpAlterIndexPtr opPtr)
{
jam();
// mark created in local TC
- if (! opPtr.p->hasError()) {
+ if (! opPtr.p->hasLastError()) {
TableRecordPtr indexPtr;
c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
indexPtr.p->indexLocal |= TableRecord::IL_CREATED_TC;
@@ -9623,9 +9624,10 @@ Dbdict::alterIndex_toDropTc(Signal* signal, OpAlterIndexPtr opPtr)
jam();
TableRecordPtr indexPtr;
c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
- // broken index
+ // broken index allowed if force
if (! (indexPtr.p->indexLocal & TableRecord::IL_CREATED_TC)) {
jam();
+ ndbrequire(opPtr.p->m_requestFlag & RequestFlag::RF_FORCE);
alterIndex_sendReply(signal, opPtr, false);
return;
}
@@ -9647,8 +9649,8 @@ Dbdict::alterIndex_fromDropTc(Signal* signal, OpAlterIndexPtr opPtr)
{
jam();
ndbrequire(opPtr.p->m_requestType == AlterIndxReq::RT_DICT_TC);
- if (! opPtr.p->hasError()) {
- // mark dropped in local TC
+ // mark dropped locally
+ if (! opPtr.p->hasLastError()) {
TableRecordPtr indexPtr;
c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
indexPtr.p->indexLocal &= ~TableRecord::IL_CREATED_TC;
@@ -9786,51 +9788,46 @@ Dbdict::alterIndex_toDropTrigger(Signal* signal, OpAlterIndexPtr opPtr)
req->setUserRef(reference());
req->setConnectionPtr(opPtr.p->key);
req->setRequestType(DropTrigReq::RT_ALTER_INDEX);
+ req->addRequestFlag(opPtr.p->m_requestFlag);
req->setTableId(opPtr.p->m_request.getTableId());
req->setIndexId(opPtr.p->m_request.getIndexId());
req->setTriggerInfo(0); // not used
opPtr.p->m_triggerCounter = 0;
- // insert
- if (indexPtr.p->insertTriggerId != RNIL) {
+ if (indexPtr.p->isHashIndex()) {
+ // insert
req->setTriggerId(indexPtr.p->insertTriggerId);
sendSignal(reference(), GSN_DROP_TRIG_REQ,
signal, DropTrigReq::SignalLength, JBB);
opPtr.p->m_triggerCounter++;
- }
- // update
- if (indexPtr.p->updateTriggerId != RNIL) {
+ // update
req->setTriggerId(indexPtr.p->updateTriggerId);
sendSignal(reference(), GSN_DROP_TRIG_REQ,
signal, DropTrigReq::SignalLength, JBB);
opPtr.p->m_triggerCounter++;
- }
- // delete
- if (indexPtr.p->deleteTriggerId != RNIL) {
+ // delete
req->setTriggerId(indexPtr.p->deleteTriggerId);
sendSignal(reference(), GSN_DROP_TRIG_REQ,
signal, DropTrigReq::SignalLength, JBB);
opPtr.p->m_triggerCounter++;
+ // build
+ if (indexPtr.p->buildTriggerId != RNIL) {
+ req->setTriggerId(indexPtr.p->buildTriggerId);
+ sendSignal(reference(), GSN_DROP_TRIG_REQ,
+ signal, DropTrigReq::SignalLength, JBB);
+ opPtr.p->m_triggerCounter++;
+ }
+ return;
}
- // custom
- if (indexPtr.p->customTriggerId != RNIL) {
+ if (indexPtr.p->isOrderedIndex()) {
+ // custom
+ req->addRequestFlag(RequestFlag::RF_NOTCTRIGGER);
req->setTriggerId(indexPtr.p->customTriggerId);
sendSignal(reference(), GSN_DROP_TRIG_REQ,
signal, DropTrigReq::SignalLength, JBB);
opPtr.p->m_triggerCounter++;
+ return;
}
- // build
- if (indexPtr.p->buildTriggerId != RNIL) {
- req->setTriggerId(indexPtr.p->buildTriggerId);
- sendSignal(reference(), GSN_DROP_TRIG_REQ,
- signal, DropTrigReq::SignalLength, JBB);
- opPtr.p->m_triggerCounter++;
- }
- if (opPtr.p->m_triggerCounter == 0) {
- // drop in each TC
- jam();
- opPtr.p->m_requestType = AlterIndxReq::RT_DICT_TC;
- alterIndex_sendSlaveReq(signal, opPtr);
- }
+ ndbrequire(false);
}
void
@@ -9948,14 +9945,16 @@ Dbdict::alterIndex_sendReply(Signal* signal, OpAlterIndexPtr opPtr,
AlterIndxRef* rep = (AlterIndxRef*)signal->getDataPtrSend();
Uint32 gsn = GSN_ALTER_INDX_CONF;
Uint32 length = AlterIndxConf::InternalLength;
- bool sendRef = opPtr.p->hasError();
+ bool sendRef;
if (! toUser) {
+ sendRef = opPtr.p->hasLastError();
rep->setUserRef(opPtr.p->m_coordinatorRef);
rep->setConnectionPtr(opPtr.p->key);
rep->setRequestType(opPtr.p->m_requestType);
if (opPtr.p->m_requestType == AlterIndxReq::RT_DICT_ABORT)
sendRef = false;
} else {
+ sendRef = opPtr.p->hasError();
rep->setUserRef(opPtr.p->m_request.getUserRef());
rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
rep->setRequestType(opPtr.p->m_request.getRequestType());
@@ -10368,8 +10367,10 @@ Dbdict::buildIndex_toOnline(Signal* signal, OpBuildIndexPtr opPtr)
req->setUserRef(reference());
req->setConnectionPtr(opPtr.p->key);
if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TC) {
+ jam();
req->setRequestType(AlterIndxReq::RT_TC);
} else if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TUX) {
+ jam();
req->setRequestType(AlterIndxReq::RT_TUX);
} else {
ndbrequire(false);
@@ -10380,8 +10381,10 @@ Dbdict::buildIndex_toOnline(Signal* signal, OpBuildIndexPtr opPtr)
req->setOnline(true);
BlockReference blockRef = 0;
if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TC) {
+ jam();
blockRef = calcTcBlockRef(getOwnNodeId());
} else if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TUX) {
+ jam();
blockRef = calcTuxBlockRef(getOwnNodeId());
} else {
ndbrequire(false);
@@ -10408,15 +10411,14 @@ Dbdict::buildIndex_sendSlaveReq(Signal* signal, OpBuildIndexPtr opPtr)
req->setConnectionPtr(opPtr.p->key);
req->setRequestType(opPtr.p->m_requestType);
req->addRequestFlag(opPtr.p->m_requestFlag);
- if(opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
- {
+ if(opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
+ jam();
opPtr.p->m_signalCounter.clearWaitingFor();
opPtr.p->m_signalCounter.setWaitingFor(getOwnNodeId());
sendSignal(reference(), GSN_BUILDINDXREQ,
signal, BuildIndxReq::SignalLength, JBB);
- }
- else
- {
+ } else {
+ jam();
opPtr.p->m_signalCounter = c_aliveNodes;
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
sendSignal(rg, GSN_BUILDINDXREQ,
@@ -10431,14 +10433,16 @@ Dbdict::buildIndex_sendReply(Signal* signal, OpBuildIndexPtr opPtr,
BuildIndxRef* rep = (BuildIndxRef*)signal->getDataPtrSend();
Uint32 gsn = GSN_BUILDINDXCONF;
Uint32 length = BuildIndxConf::InternalLength;
- bool sendRef = opPtr.p->hasError();
+ bool sendRef;
if (! toUser) {
+ sendRef = opPtr.p->hasLastError();
rep->setUserRef(opPtr.p->m_coordinatorRef);
rep->setConnectionPtr(opPtr.p->key);
rep->setRequestType(opPtr.p->m_requestType);
if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_ABORT)
sendRef = false;
} else {
+ sendRef = opPtr.p->hasError();
rep->setUserRef(opPtr.p->m_request.getUserRef());
rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
rep->setRequestType(opPtr.p->m_request.getRequestType());
@@ -10925,14 +10929,16 @@ Dbdict::createTrigger_sendReply(Signal* signal, OpCreateTriggerPtr opPtr,
CreateTrigRef* rep = (CreateTrigRef*)signal->getDataPtrSend();
Uint32 gsn = GSN_CREATE_TRIG_CONF;
Uint32 length = CreateTrigConf::InternalLength;
- bool sendRef = opPtr.p->hasError();
+ bool sendRef;
if (! toUser) {
+ sendRef = opPtr.p->hasLastError();
rep->setUserRef(opPtr.p->m_coordinatorRef);
rep->setConnectionPtr(opPtr.p->key);
rep->setRequestType(opPtr.p->m_requestType);
if (opPtr.p->m_requestType == CreateTrigReq::RT_DICT_ABORT)
sendRef = false;
} else {
+ sendRef = opPtr.p->hasError();
rep->setUserRef(opPtr.p->m_request.getUserRef());
rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
rep->setRequestType(opPtr.p->m_request.getRequestType());
@@ -11020,8 +11026,10 @@ Dbdict::execDROP_TRIG_REQ(Signal* signal)
OpDropTrigger opBad;
opPtr.p = &opBad;
opPtr.p->save(req);
- opPtr.p->m_errorCode = DropTrigRef::TriggerNotFound;
- opPtr.p->m_errorLine = __LINE__;
+ if (! (req->getRequestFlag() & RequestFlag::RF_FORCE)) {
+ opPtr.p->m_errorCode = DropTrigRef::TriggerNotFound;
+ opPtr.p->m_errorLine = __LINE__;
+ }
dropTrigger_sendReply(signal, opPtr, true);
return;
}
@@ -11188,6 +11196,7 @@ Dbdict::dropTrigger_toAlterTrigger(Signal* signal, OpDropTriggerPtr opPtr)
req->setUserRef(reference());
req->setConnectionPtr(opPtr.p->key);
req->setRequestType(AlterTrigReq::RT_DROP_TRIGGER);
+ req->addRequestFlag(opPtr.p->m_requestFlag);
req->setTableId(opPtr.p->m_request.getTableId());
req->setTriggerId(opPtr.p->m_request.getTriggerId());
req->setTriggerInfo(0); // not used
@@ -11283,14 +11292,16 @@ Dbdict::dropTrigger_sendReply(Signal* signal, OpDropTriggerPtr opPtr,
DropTrigRef* rep = (DropTrigRef*)signal->getDataPtrSend();
Uint32 gsn = GSN_DROP_TRIG_CONF;
Uint32 length = DropTrigConf::InternalLength;
- bool sendRef = opPtr.p->hasError();
+ bool sendRef;
if (! toUser) {
+ sendRef = opPtr.p->hasLastError();
rep->setUserRef(opPtr.p->m_coordinatorRef);
rep->setConnectionPtr(opPtr.p->key);
rep->setRequestType(opPtr.p->m_requestType);
if (opPtr.p->m_requestType == DropTrigReq::RT_DICT_ABORT)
sendRef = false;
} else {
+ sendRef = opPtr.p->hasError();
rep->setUserRef(opPtr.p->m_request.getUserRef());
rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
rep->setRequestType(opPtr.p->m_request.getRequestType());
@@ -11514,28 +11525,37 @@ Dbdict::alterTrigger_recvReply(Signal* signal, const AlterTrigConf* conf,
if (! (opPtr.p->m_request.getRequestFlag() & RequestFlag::RF_NOTCTRIGGER)) {
if (requestType == AlterTrigReq::RT_DICT_PREPARE) {
jam();
- if (opPtr.p->m_request.getOnline())
+ if (opPtr.p->m_request.getOnline()) {
+ jam();
opPtr.p->m_requestType = AlterTrigReq::RT_DICT_TC;
- else
+ } else {
+ jam();
opPtr.p->m_requestType = AlterTrigReq::RT_DICT_LQH;
+ }
alterTrigger_sendSlaveReq(signal, opPtr);
return;
}
if (requestType == AlterTrigReq::RT_DICT_TC) {
jam();
- if (opPtr.p->m_request.getOnline())
+ if (opPtr.p->m_request.getOnline()) {
+ jam();
opPtr.p->m_requestType = AlterTrigReq::RT_DICT_LQH;
- else
+ } else {
+ jam();
opPtr.p->m_requestType = AlterTrigReq::RT_DICT_COMMIT;
+ }
alterTrigger_sendSlaveReq(signal, opPtr);
return;
}
if (requestType == AlterTrigReq::RT_DICT_LQH) {
jam();
- if (opPtr.p->m_request.getOnline())
+ if (opPtr.p->m_request.getOnline()) {
+ jam();
opPtr.p->m_requestType = AlterTrigReq::RT_DICT_COMMIT;
- else
+ } else {
+ jam();
opPtr.p->m_requestType = AlterTrigReq::RT_DICT_TC;
+ }
alterTrigger_sendSlaveReq(signal, opPtr);
return;
}
@@ -11595,8 +11615,10 @@ Dbdict::alterTrigger_toCreateLocal(Signal* signal, OpAlterTriggerPtr opPtr)
req->setUserRef(reference());
req->setConnectionPtr(opPtr.p->key);
if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
+ jam();
req->setRequestType(CreateTrigReq::RT_TC);
} else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
+ jam();
req->setRequestType(CreateTrigReq::RT_LQH);
} else {
ndbassert(false);
@@ -11613,8 +11635,10 @@ Dbdict::alterTrigger_toCreateLocal(Signal* signal, OpAlterTriggerPtr opPtr)
req->setReceiverRef(opPtr.p->m_request.getReceiverRef());
BlockReference blockRef = 0;
if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
+ jam();
blockRef = calcTcBlockRef(getOwnNodeId());
} else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
+ jam();
blockRef = calcLqhBlockRef(getOwnNodeId());
} else {
ndbassert(false);
@@ -11628,13 +11652,15 @@ void
Dbdict::alterTrigger_fromCreateLocal(Signal* signal, OpAlterTriggerPtr opPtr)
{
jam();
- if (! opPtr.p->hasError()) {
+ if (! opPtr.p->hasLastError()) {
// mark created locally
TriggerRecordPtr triggerPtr;
c_triggerRecordPool.getPtr(triggerPtr, opPtr.p->m_request.getTriggerId());
if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
+ jam();
triggerPtr.p->triggerLocal |= TriggerRecord::TL_CREATED_TC;
} else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
+ jam();
triggerPtr.p->triggerLocal |= TriggerRecord::TL_CREATED_LQH;
} else {
ndbrequire(false);
@@ -11654,17 +11680,21 @@ Dbdict::alterTrigger_toDropLocal(Signal* signal, OpAlterTriggerPtr opPtr)
req->setUserRef(reference());
req->setConnectionPtr(opPtr.p->key);
if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
- // broken trigger
+ jam();
+ // broken trigger allowed if force
if (! (triggerPtr.p->triggerLocal & TriggerRecord::TL_CREATED_TC)) {
jam();
+ ndbrequire(opPtr.p->m_requestFlag & RequestFlag::RF_FORCE);
alterTrigger_sendReply(signal, opPtr, false);
return;
}
req->setRequestType(DropTrigReq::RT_TC);
} else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
- // broken trigger
+ jam();
+ // broken trigger allowed if force
if (! (triggerPtr.p->triggerLocal & TriggerRecord::TL_CREATED_LQH)) {
jam();
+ ndbrequire(opPtr.p->m_requestFlag & RequestFlag::RF_FORCE);
alterTrigger_sendReply(signal, opPtr, false);
return;
}
@@ -11682,8 +11712,10 @@ Dbdict::alterTrigger_toDropLocal(Signal* signal, OpAlterTriggerPtr opPtr)
req->setMonitorAllAttributes(triggerPtr.p->monitorAllAttributes);
BlockReference blockRef = 0;
if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
+ jam();
blockRef = calcTcBlockRef(getOwnNodeId());
} else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
+ jam();
blockRef = calcLqhBlockRef(getOwnNodeId());
} else {
ndbassert(false);
@@ -11696,13 +11728,15 @@ void
Dbdict::alterTrigger_fromDropLocal(Signal* signal, OpAlterTriggerPtr opPtr)
{
jam();
- if (! opPtr.p->hasError()) {
+ if (! opPtr.p->hasLastError()) {
// mark dropped locally
TriggerRecordPtr triggerPtr;
c_triggerRecordPool.getPtr(triggerPtr, opPtr.p->m_request.getTriggerId());
if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
+ jam();
triggerPtr.p->triggerLocal &= ~TriggerRecord::TL_CREATED_TC;
} else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
+ jam();
triggerPtr.p->triggerLocal &= ~TriggerRecord::TL_CREATED_LQH;
} else {
ndbrequire(false);
@@ -11759,8 +11793,9 @@ Dbdict::alterTrigger_sendReply(Signal* signal, OpAlterTriggerPtr opPtr,
AlterTrigRef* rep = (AlterTrigRef*)signal->getDataPtrSend();
Uint32 gsn = GSN_ALTER_TRIG_CONF;
Uint32 length = AlterTrigConf::InternalLength;
- bool sendRef = opPtr.p->hasError();
+ bool sendRef;
if (! toUser) {
+ sendRef = opPtr.p->hasLastError();
rep->setUserRef(opPtr.p->m_coordinatorRef);
rep->setConnectionPtr(opPtr.p->key);
rep->setRequestType(opPtr.p->m_requestType);
@@ -11771,6 +11806,7 @@ Dbdict::alterTrigger_sendReply(Signal* signal, OpAlterTriggerPtr opPtr,
jam();
}
} else {
+ sendRef = opPtr.p->hasError();
jam();
rep->setUserRef(opPtr.p->m_request.getUserRef());
rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
index abe253bcaa7..bcee4a52b6a 100644
--- a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
+++ b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
@@ -924,7 +924,8 @@ private:
enum {
RF_LOCAL = 1 << 0, // create on local node only
RF_NOBUILD = 1 << 1, // no need to build index
- RF_NOTCTRIGGER = 1 << 2 // alter trigger: no trigger in TC
+ RF_NOTCTRIGGER = 1 << 2, // alter trigger: no trigger in TC
+ RF_FORCE = 1 << 4 // force drop
};
};
@@ -944,6 +945,7 @@ private:
CreateIndxReq::RequestType m_requestType;
Uint32 m_requestFlag;
// error info
+ CreateIndxRef::ErrorCode m_lastError;
CreateIndxRef::ErrorCode m_errorCode;
Uint32 m_errorLine;
Uint32 m_errorNode;
@@ -955,6 +957,7 @@ private:
m_coordinatorRef = 0;
m_requestType = CreateIndxReq::RT_UNDEFINED;
m_requestFlag = 0;
+ m_lastError = CreateIndxRef::NoError;
m_errorCode = CreateIndxRef::NoError;
m_errorLine = 0;
m_errorNode = 0;
@@ -964,34 +967,49 @@ private:
m_requestType = req->getRequestType();
m_requestFlag = req->getRequestFlag();
}
+ bool hasLastError() {
+ return m_lastError != CreateIndxRef::NoError;
+ }
bool hasError() {
return m_errorCode != CreateIndxRef::NoError;
}
void setError(const CreateIndxRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = CreateIndxRef::NoError;
+ if (ref != 0) {
+ m_lastError = ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
void setError(const CreateTableRef* ref) {
- if (ref != 0 && ! hasError()) {
+ m_lastError = CreateIndxRef::NoError;
+ if (ref != 0) {
switch (ref->getErrorCode()) {
case CreateTableRef::TableAlreadyExist:
- m_errorCode = CreateIndxRef::IndexExists;
+ m_lastError = CreateIndxRef::IndexExists;
break;
default:
- m_errorCode = (CreateIndxRef::ErrorCode)ref->getErrorCode();
+ m_lastError = (CreateIndxRef::ErrorCode)ref->getErrorCode();
break;
}
- m_errorLine = ref->getErrorLine();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ }
}
}
void setError(const AlterIndxRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = (CreateIndxRef::ErrorCode)ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = CreateIndxRef::NoError;
+ if (ref != 0) {
+ m_lastError = (CreateIndxRef::ErrorCode)ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
};
@@ -1010,6 +1028,7 @@ private:
DropIndxReq::RequestType m_requestType;
Uint32 m_requestFlag;
// error info
+ DropIndxRef::ErrorCode m_lastError;
DropIndxRef::ErrorCode m_errorCode;
Uint32 m_errorLine;
Uint32 m_errorNode;
@@ -1021,6 +1040,7 @@ private:
m_coordinatorRef = 0;
m_requestType = DropIndxReq::RT_UNDEFINED;
m_requestFlag = 0;
+ m_lastError = DropIndxRef::NoError;
m_errorCode = DropIndxRef::NoError;
m_errorLine = 0;
m_errorNode = 0;
@@ -1030,44 +1050,59 @@ private:
m_requestType = req->getRequestType();
m_requestFlag = req->getRequestFlag();
}
+ bool hasLastError() {
+ return m_lastError != DropIndxRef::NoError;
+ }
bool hasError() {
return m_errorCode != DropIndxRef::NoError;
}
void setError(const DropIndxRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = DropIndxRef::NoError;
+ if (ref != 0) {
+ m_lastError = ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = ref->getErrorCode();
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
void setError(const AlterIndxRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = (DropIndxRef::ErrorCode)ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = DropIndxRef::NoError;
+ if (ref != 0) {
+ m_lastError = (DropIndxRef::ErrorCode)ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
void setError(const DropTableRef* ref) {
- if (ref != 0 && ! hasError()) {
- switch(ref->errorCode) {
- case(DropTableRef::Busy):
- m_errorCode = DropIndxRef::Busy;
+ m_lastError = DropIndxRef::NoError;
+ if (ref != 0) {
+ switch (ref->errorCode) {
+ case DropTableRef::Busy:
+ m_lastError = DropIndxRef::Busy;
break;
- case(DropTableRef::NoSuchTable):
- m_errorCode = DropIndxRef::IndexNotFound;
+ case DropTableRef::NoSuchTable:
+ m_lastError = DropIndxRef::IndexNotFound;
break;
- case(DropTableRef::DropInProgress):
- m_errorCode = DropIndxRef::Busy;
+ case DropTableRef::DropInProgress:
+ m_lastError = DropIndxRef::Busy;
break;
- case(DropTableRef::NoDropTableRecordAvailable):
- m_errorCode = DropIndxRef::Busy;
+ case DropTableRef::NoDropTableRecordAvailable:
+ m_lastError = DropIndxRef::Busy;
break;
default:
- m_errorCode = (DropIndxRef::ErrorCode)ref->errorCode;
+ m_lastError = (DropIndxRef::ErrorCode)ref->errorCode;
break;
}
- //m_errorLine = ref->getErrorLine();
- //m_errorNode = ref->getErrorNode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = 0;
+ m_errorNode = 0;
+ }
}
}
};
@@ -1088,6 +1123,7 @@ private:
AlterIndxReq::RequestType m_requestType;
Uint32 m_requestFlag;
// error info
+ AlterIndxRef::ErrorCode m_lastError;
AlterIndxRef::ErrorCode m_errorCode;
Uint32 m_errorLine;
Uint32 m_errorNode;
@@ -1100,6 +1136,7 @@ private:
m_coordinatorRef = 0;
m_requestType = AlterIndxReq::RT_UNDEFINED;
m_requestFlag = 0;
+ m_lastError = AlterIndxRef::NoError;
m_errorCode = AlterIndxRef::NoError;
m_errorLine = 0;
m_errorNode = 0;
@@ -1110,47 +1147,76 @@ private:
m_requestType = req->getRequestType();
m_requestFlag = req->getRequestFlag();
}
+ bool hasLastError() {
+ return m_lastError != AlterIndxRef::NoError;
+ }
bool hasError() {
return m_errorCode != AlterIndxRef::NoError;
}
void setError(const AlterIndxRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = AlterIndxRef::NoError;
+ if (ref != 0) {
+ m_lastError = ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
void setError(const CreateIndxRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = (AlterIndxRef::ErrorCode)ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = AlterIndxRef::NoError;
+ if (ref != 0) {
+ m_lastError = (AlterIndxRef::ErrorCode)ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
void setError(const DropIndxRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = (AlterIndxRef::ErrorCode)ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = AlterIndxRef::NoError;
+ if (ref != 0) {
+ m_lastError = (AlterIndxRef::ErrorCode)ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
void setError(const BuildIndxRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = (AlterIndxRef::ErrorCode)ref->getErrorCode();
+ m_lastError = AlterIndxRef::NoError;
+ if (ref != 0) {
+ m_lastError = (AlterIndxRef::ErrorCode)ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = 0;
+ m_errorNode = 0;
+ }
}
}
void setError(const CreateTrigRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = (AlterIndxRef::ErrorCode)ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = AlterIndxRef::NoError;
+ if (ref != 0) {
+ m_lastError = (AlterIndxRef::ErrorCode)ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
void setError(const DropTrigRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = (AlterIndxRef::ErrorCode)ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = AlterIndxRef::NoError;
+ if (ref != 0) {
+ m_lastError = (AlterIndxRef::ErrorCode)ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
};
@@ -1172,6 +1238,7 @@ private:
Uint32 m_requestFlag;
Uint32 m_constrTriggerId;
// error info
+ BuildIndxRef::ErrorCode m_lastError;
BuildIndxRef::ErrorCode m_errorCode;
Uint32 m_errorLine;
Uint32 m_errorNode;
@@ -1183,7 +1250,7 @@ private:
m_coordinatorRef = 0;
m_requestType = BuildIndxReq::RT_UNDEFINED;
m_requestFlag = 0;
-// Uint32 m_constrTriggerId = RNIL;
+ m_lastError = BuildIndxRef::NoError;
m_errorCode = BuildIndxRef::NoError;
m_errorLine = 0;
m_errorNode = 0;
@@ -1193,33 +1260,54 @@ private:
m_requestType = req->getRequestType();
m_requestFlag = req->getRequestFlag();
}
+ bool hasLastError() {
+ return m_lastError != BuildIndxRef::NoError;
+ }
bool hasError() {
return m_errorCode != BuildIndxRef::NoError;
}
void setError(const BuildIndxRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = ref->getErrorCode();
+ m_lastError = BuildIndxRef::NoError;
+ if (ref != 0) {
+ m_lastError = ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = 0;
+ m_errorNode = 0;
+ }
}
}
void setError(const AlterIndxRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = (BuildIndxRef::ErrorCode)ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = BuildIndxRef::NoError;
+ if (ref != 0) {
+ m_lastError = (BuildIndxRef::ErrorCode)ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
void setError(const CreateTrigRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = (BuildIndxRef::ErrorCode)ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = BuildIndxRef::NoError;
+ if (ref != 0) {
+ m_lastError = (BuildIndxRef::ErrorCode)ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
void setError(const DropTrigRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = (BuildIndxRef::ErrorCode)ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = BuildIndxRef::NoError;
+ if (ref != 0) {
+ m_lastError = (BuildIndxRef::ErrorCode)ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
};
@@ -1352,6 +1440,7 @@ private:
CreateTrigReq::RequestType m_requestType;
Uint32 m_requestFlag;
// error info
+ CreateTrigRef::ErrorCode m_lastError;
CreateTrigRef::ErrorCode m_errorCode;
Uint32 m_errorLine;
Uint32 m_errorNode;
@@ -1363,6 +1452,7 @@ private:
m_coordinatorRef = 0;
m_requestType = CreateTrigReq::RT_UNDEFINED;
m_requestFlag = 0;
+ m_lastError = CreateTrigRef::NoError;
m_errorCode = CreateTrigRef::NoError;
m_errorLine = 0;
m_errorNode = 0;
@@ -1372,21 +1462,32 @@ private:
m_requestType = req->getRequestType();
m_requestFlag = req->getRequestFlag();
}
+ bool hasLastError() {
+ return m_lastError != CreateTrigRef::NoError;
+ }
bool hasError() {
return m_errorCode != CreateTrigRef::NoError;
}
void setError(const CreateTrigRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = CreateTrigRef::NoError;
+ if (ref != 0) {
+ m_lastError = ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
void setError(const AlterTrigRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = (CreateTrigRef::ErrorCode)ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = CreateTrigRef::NoError;
+ if (ref != 0) {
+ m_lastError = (CreateTrigRef::ErrorCode)ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
};
@@ -1405,6 +1506,7 @@ private:
DropTrigReq::RequestType m_requestType;
Uint32 m_requestFlag;
// error info
+ DropTrigRef::ErrorCode m_lastError;
DropTrigRef::ErrorCode m_errorCode;
Uint32 m_errorLine;
Uint32 m_errorNode;
@@ -1416,6 +1518,7 @@ private:
m_coordinatorRef = 0;
m_requestType = DropTrigReq::RT_UNDEFINED;
m_requestFlag = 0;
+ m_lastError = DropTrigRef::NoError;
m_errorCode = DropTrigRef::NoError;
m_errorLine = 0;
m_errorNode = 0;
@@ -1425,21 +1528,32 @@ private:
m_requestType = req->getRequestType();
m_requestFlag = req->getRequestFlag();
}
+ bool hasLastError() {
+ return m_lastError != DropTrigRef::NoError;
+ }
bool hasError() {
return m_errorCode != DropTrigRef::NoError;
}
void setError(const DropTrigRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = DropTrigRef::NoError;
+ if (ref != 0) {
+ m_lastError = ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
void setError(const AlterTrigRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = (DropTrigRef::ErrorCode)ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = DropTrigRef::NoError;
+ if (ref != 0) {
+ m_lastError = (DropTrigRef::ErrorCode)ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
};
@@ -1460,6 +1574,7 @@ private:
AlterTrigReq::RequestType m_requestType;
Uint32 m_requestFlag;
// error info
+ AlterTrigRef::ErrorCode m_lastError;
AlterTrigRef::ErrorCode m_errorCode;
Uint32 m_errorLine;
Uint32 m_errorNode;
@@ -1471,6 +1586,7 @@ private:
m_coordinatorRef = 0;
m_requestType = AlterTrigReq::RT_UNDEFINED;
m_requestFlag = 0;
+ m_lastError = AlterTrigRef::NoError;
m_errorCode = AlterTrigRef::NoError;
m_errorLine = 0;
m_errorNode = 0;
@@ -1480,28 +1596,43 @@ private:
m_requestType = req->getRequestType();
m_requestFlag = req->getRequestFlag();
}
+ bool hasLastError() {
+ return m_lastError != AlterTrigRef::NoError;
+ }
bool hasError() {
return m_errorCode != AlterTrigRef::NoError;
}
void setError(const AlterTrigRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = (AlterTrigRef::ErrorCode)ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = AlterTrigRef::NoError;
+ if (ref != 0) {
+ m_lastError = (AlterTrigRef::ErrorCode)ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
void setError(const CreateTrigRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = (AlterTrigRef::ErrorCode)ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = AlterTrigRef::NoError;
+ if (ref != 0) {
+ m_lastError = (AlterTrigRef::ErrorCode)ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
void setError(const DropTrigRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = (AlterTrigRef::ErrorCode)ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
+ m_lastError = AlterTrigRef::NoError;
+ if (ref != 0) {
+ m_lastError = (AlterTrigRef::ErrorCode)ref->getErrorCode();
+ if (! hasError()) {
+ m_errorCode = m_lastError;
+ m_errorLine = ref->getErrorLine();
+ m_errorNode = ref->getErrorNode();
+ }
}
}
};
diff --git a/ndb/src/kernel/blocks/dbdict/Makefile.am b/ndb/src/kernel/blocks/dbdict/Makefile.am
index 9a0d68f8148..3c1cf6735d9 100644
--- a/ndb/src/kernel/blocks/dbdict/Makefile.am
+++ b/ndb/src/kernel/blocks/dbdict/Makefile.am
@@ -1,12 +1,20 @@
-#SUBDIRS = printSchemafile
-
noinst_LIBRARIES = libdbdict.a
+EXTRA_PROGRAMS = printSchemaFile
libdbdict_a_SOURCES = Dbdict.cpp
+printSchemaFile_SOURCES = printSchemaFile.cpp
+
include $(top_srcdir)/ndb/config/common.mk.am
include $(top_srcdir)/ndb/config/type_kernel.mk.am
+LDADD += \
+ $(top_builddir)/ndb/src/common/util/libgeneral.la \
+ $(top_builddir)/ndb/src/common/portlib/libportlib.la \
+ $(top_builddir)/dbug/libdbug.a \
+ $(top_builddir)/mysys/libmysys.a \
+ $(top_builddir)/strings/libmystrings.a
+
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp b/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp
index 3e944485e1c..a8b84298ebe 100644
--- a/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp
+++ b/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp
@@ -1,11 +1,3 @@
-#if 0
-make -f Makefile -f - printSchemaFile <<'_eof_'
-printSchemaFile: printSchemaFile.cpp
- $(CXXCOMPILE) -o $@ $@.cpp -L../../../common/util/.libs -lgeneral
-_eof_
-exit $?
-#endif
-
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -58,8 +50,7 @@ print(const char * filename, const SchemaFile * file){
SchemaFile::TableEntry te = file->TableEntries[i];
if(te.m_tableState != SchemaFile::INIT){
ndbout << "Table " << i << ": State = " << te.m_tableState
- << " version = " << table_version_major(te.m_tableVersion) <<
- << "(" << table_version_minor(te.m_tableVersion) << ")"
+ << " version = " << te.m_tableVersion
<< " type = " << te.m_tableType
<< " noOfPages = " << te.m_noOfPages
<< " gcp: " << te.m_gcp << endl;
diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
index f0861d1f0cc..04b40dafcb5 100644
--- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
+++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
@@ -10833,6 +10833,7 @@ void Dbtc::execCREATE_TRIG_REQ(Signal* signal)
if (ERROR_INSERTED(8033) ||
!c_theDefinedTriggers.seizeId(triggerPtr,
createTrigReq->getTriggerId())) {
+ jam();
CLEAR_ERROR_INSERT_VALUE;
// Failed to allocate trigger record
CreateTrigRef * const createTrigRef =
@@ -10867,8 +10868,10 @@ void Dbtc::execDROP_TRIG_REQ(Signal* signal)
DropTrigReq * const dropTrigReq = (DropTrigReq *)&signal->theData[0];
BlockReference sender = signal->senderBlockRef();
- if ((c_theDefinedTriggers.getPtr(dropTrigReq->getTriggerId())) == NULL) {
+ if (ERROR_INSERTED(8035) ||
+ (c_theDefinedTriggers.getPtr(dropTrigReq->getTriggerId())) == NULL) {
jam();
+ CLEAR_ERROR_INSERT_VALUE;
// Failed to find find trigger record
DropTrigRef * const dropTrigRef = (DropTrigRef *)&signal->theData[0];
@@ -10900,6 +10903,7 @@ void Dbtc::execCREATE_INDX_REQ(Signal* signal)
if (ERROR_INSERTED(8034) ||
!c_theIndexes.seizeId(indexPtr, createIndxReq->getIndexId())) {
+ jam();
CLEAR_ERROR_INSERT_VALUE;
// Failed to allocate index record
CreateIndxRef * const createIndxRef =
@@ -11111,8 +11115,10 @@ void Dbtc::execDROP_INDX_REQ(Signal* signal)
TcIndexData* indexData;
BlockReference sender = signal->senderBlockRef();
- if ((indexData = c_theIndexes.getPtr(dropIndxReq->getIndexId())) == NULL) {
+ if (ERROR_INSERTED(8036) ||
+ (indexData = c_theIndexes.getPtr(dropIndxReq->getIndexId())) == NULL) {
jam();
+ CLEAR_ERROR_INSERT_VALUE;
// Failed to find index record
DropIndxRef * const dropIndxRef =
(DropIndxRef *)signal->getDataPtrSend();
diff --git a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
index dffafc1ab66..1cb3bd89997 100644
--- a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
+++ b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
@@ -1737,7 +1737,8 @@ private:
Uint32* const mainBuffer,
Uint32& noMainWords,
Uint32* const copyBuffer,
- Uint32& noCopyWords);
+ Uint32& noCopyWords,
+ bool xfrm);
void sendTrigAttrInfo(Signal* signal,
Uint32* data,
diff --git a/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp b/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp
index 575d08efffc..59a31475617 100644
--- a/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp
+++ b/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp
@@ -305,6 +305,10 @@ Dbtup::primaryKey(Tablerec* const regTabPtr, Uint32 attrId)
Uint32
Dbtup::dropTrigger(Tablerec* table, const DropTrigReq* req)
{
+ if (ERROR_INSERTED(4004)) {
+ CLEAR_ERROR_INSERT_VALUE;
+ return 9999;
+ }
Uint32 triggerId = req->getTriggerId();
TriggerType::Value ttype = req->getTriggerType();
@@ -618,7 +622,8 @@ void Dbtup::executeTrigger(Signal* signal,
mainBuffer,
noMainWords,
copyBuffer,
- noCopyWords)) {
+ noCopyWords,
+ (ref == BACKUP ? false : true))) {
ljam();
return;
}//if
@@ -723,7 +728,8 @@ bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr,
Uint32* const mainBuffer,
Uint32& noMainWords,
Uint32* const copyBuffer,
- Uint32& noCopyWords)
+ Uint32& noCopyWords,
+ bool xfrm)
{
noCopyWords = 0;
noMainWords = 0;
@@ -753,7 +759,7 @@ bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr,
regTabPtr->noOfKeyAttr,
keyBuffer,
ZATTR_BUFFER_SIZE,
- true);
+ xfrm);
ndbrequire(ret != -1);
noPrimKey= ret;
@@ -796,7 +802,7 @@ bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr,
numAttrsToRead,
mainBuffer,
ZATTR_BUFFER_SIZE,
- true);
+ xfrm);
ndbrequire(ret != -1);
noMainWords= ret;
} else {
@@ -822,7 +828,7 @@ bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr,
numAttrsToRead,
copyBuffer,
ZATTR_BUFFER_SIZE,
- true);
+ xfrm);
ndbrequire(ret != -1);
noCopyWords = ret;
diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp
index bf78adec970..06b534ac0ca 100644
--- a/ndb/src/mgmapi/mgmapi.cpp
+++ b/ndb/src/mgmapi/mgmapi.cpp
@@ -638,12 +638,10 @@ ndb_mgm_get_status(NdbMgmHandle handle)
Vector<BaseString> split;
tmp.split(split, ":");
if(split.size() != 2){
- abort();
return NULL;
}
if(!(split[0].trim() == "nodes")){
- abort();
return NULL;
}
@@ -692,7 +690,6 @@ ndb_mgm_get_status(NdbMgmHandle handle)
if(i+1 != noOfNodes){
free(state);
- abort();
return NULL;
}
diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp
index 011643237f8..56c24e5f862 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -2501,10 +2501,7 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
case GSN_NODE_FAILREP:{
const NodeFailRep * const rep =
CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
-#ifdef VM_TRACE
- ndbout_c("Node %d failed", rep->failNo);
-#endif
- if (rep->failNo == nodeId ||
+ if (NodeBitmask::get(rep->theNodes,nodeId) ||
waitCompleted == 1)
return 1326;
// wait for next signal
diff --git a/ndb/src/ndbapi/NdbApiSignal.cpp b/ndb/src/ndbapi/NdbApiSignal.cpp
index a1d34896968..953d87ac7b0 100644
--- a/ndb/src/ndbapi/NdbApiSignal.cpp
+++ b/ndb/src/ndbapi/NdbApiSignal.cpp
@@ -62,6 +62,25 @@ NdbApiSignal::NdbApiSignal(BlockReference ref)
theNextSignal = 0;
}
+NdbApiSignal::NdbApiSignal(Ndb* ndb)
+{
+ BlockReference ref = ndb->theMyRef;
+ theVerId_signalNumber = 0; // 4 bit ver id - 16 bit gsn
+ theReceiversBlockNumber = 0; // Only 16 bit blocknum
+ theSendersBlockRef = refToBlock(ref);
+ theLength = 0;
+ theSendersSignalId = 0;
+ theSignalId = 0;
+ theTrace = 0;
+ m_noOfSections = 0;
+ m_fragmentInfo = 0;
+ for (int i = 0; i < 25; i++)
+ theData[i] = 0x13579753;
+
+ setDataPtr(&theData[0]);
+ theNextSignal = 0;
+}
+
/**
* Copy constructor
*/
diff --git a/ndb/src/ndbapi/NdbApiSignal.hpp b/ndb/src/ndbapi/NdbApiSignal.hpp
index 52c3be2256c..9a8326bd666 100644
--- a/ndb/src/ndbapi/NdbApiSignal.hpp
+++ b/ndb/src/ndbapi/NdbApiSignal.hpp
@@ -46,7 +46,8 @@
class NdbApiSignal : public SignalHeader
{
public:
- NdbApiSignal(BlockReference myRef);
+ NdbApiSignal(Ndb* ndb);
+ NdbApiSignal(BlockReference ref);
NdbApiSignal(const NdbApiSignal &);
NdbApiSignal(const SignalHeader &header)
: SignalHeader(header), theNextSignal(0), theRealData(0) {};
diff --git a/ndb/src/ndbapi/NdbBlob.cpp b/ndb/src/ndbapi/NdbBlob.cpp
index f72361b86ac..c5692d79e83 100644
--- a/ndb/src/ndbapi/NdbBlob.cpp
+++ b/ndb/src/ndbapi/NdbBlob.cpp
@@ -137,7 +137,7 @@ NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnIm
// initialization
-NdbBlob::NdbBlob()
+NdbBlob::NdbBlob(Ndb*)
{
init();
}
diff --git a/ndb/src/ndbapi/NdbImpl.hpp b/ndb/src/ndbapi/NdbImpl.hpp
index 00a8ef19f3a..33aaca8de96 100644
--- a/ndb/src/ndbapi/NdbImpl.hpp
+++ b/ndb/src/ndbapi/NdbImpl.hpp
@@ -32,6 +32,21 @@
#include "NdbDictionaryImpl.hpp"
#include "ObjectMap.hpp"
+template <class T>
+struct Ndb_free_list_t
+{
+ Ndb_free_list_t();
+ ~Ndb_free_list_t();
+
+ void fill(Ndb*, Uint32 cnt);
+ T* seize(Ndb*);
+ void release(T*);
+ void clear();
+ Uint32 get_sizeof() const { return sizeof(T); }
+ T * m_free_list;
+ Uint32 m_alloc_cnt, m_free_cnt;
+};
+
/**
* Private parts of the Ndb object (corresponding to Ndb.hpp in public API)
*/
@@ -59,6 +74,23 @@ public:
NdbWaiter theWaiter;
int m_optimized_node_selection;
+
+ /**
+ * NOTE free lists must be _after_ theNdbObjectIdMap take
+ * assure that destructors are run in correct order
+ */
+ Ndb_free_list_t<NdbConnection> theConIdleList;
+ Ndb_free_list_t<NdbOperation> theOpIdleList;
+ Ndb_free_list_t<NdbIndexScanOperation> theScanOpIdleList;
+ Ndb_free_list_t<NdbIndexOperation> theIndexOpIdleList;
+ Ndb_free_list_t<NdbRecAttr> theRecAttrIdleList;
+ Ndb_free_list_t<NdbApiSignal> theSignalIdleList;
+ Ndb_free_list_t<NdbLabel> theLabelList;
+ Ndb_free_list_t<NdbBranch> theBranchList;
+ Ndb_free_list_t<NdbSubroutine> theSubroutineList;
+ Ndb_free_list_t<NdbCall> theCallList;
+ Ndb_free_list_t<NdbBlob> theNdbBlobIdleList;
+ Ndb_free_list_t<NdbReceiver> theScanList;
};
#ifdef VM_TRACE
@@ -133,4 +165,91 @@ enum LockMode {
Delete
};
+template<class T>
+inline
+Ndb_free_list_t<T>::Ndb_free_list_t()
+{
+ m_free_list= 0;
+ m_alloc_cnt= m_free_cnt= 0;
+}
+
+template<class T>
+inline
+Ndb_free_list_t<T>::~Ndb_free_list_t()
+{
+ clear();
+}
+
+template<class T>
+inline
+void
+Ndb_free_list_t<T>::fill(Ndb* ndb, Uint32 cnt)
+{
+ if (m_free_list == 0)
+ {
+ m_free_cnt++;
+ m_alloc_cnt++;
+ m_free_list = new T(ndb);
+ }
+ while(m_alloc_cnt < cnt)
+ {
+ T* obj= new T(ndb);
+ if(obj == 0)
+ return;
+
+ obj->next(m_free_list);
+ m_free_cnt++;
+ m_alloc_cnt++;
+ m_free_list = obj;
+ }
+}
+
+template<class T>
+inline
+T*
+Ndb_free_list_t<T>::seize(Ndb* ndb)
+{
+ T* tmp = m_free_list;
+ if (tmp)
+ {
+ m_free_list = (T*)tmp->next();
+ tmp->next(NULL);
+ m_free_cnt--;
+ return tmp;
+ }
+
+ if((tmp = new T(ndb)))
+ {
+ m_alloc_cnt++;
+ }
+
+ return tmp;
+}
+
+template<class T>
+inline
+void
+Ndb_free_list_t<T>::release(T* obj)
+{
+ obj->next(m_free_list);
+ m_free_list = obj;
+ m_free_cnt++;
+}
+
+
+template<class T>
+inline
+void
+Ndb_free_list_t<T>::clear()
+{
+ T* obj = m_free_list;
+ while(obj)
+ {
+ T* curr = obj;
+ obj = (T*)obj->next();
+ delete curr;
+ m_alloc_cnt--;
+ }
+}
+
#endif
diff --git a/ndb/src/ndbapi/NdbRecAttr.cpp b/ndb/src/ndbapi/NdbRecAttr.cpp
index db83e9c5fcf..f993c652bf9 100644
--- a/ndb/src/ndbapi/NdbRecAttr.cpp
+++ b/ndb/src/ndbapi/NdbRecAttr.cpp
@@ -33,7 +33,7 @@ Adjust: 971206 UABRONM First version
#include "NdbDictionaryImpl.hpp"
#include <NdbTCP.h>
-NdbRecAttr::NdbRecAttr()
+NdbRecAttr::NdbRecAttr(Ndb*)
{
init();
}
@@ -109,7 +109,7 @@ NdbRecAttr::copyout()
NdbRecAttr *
NdbRecAttr::clone() const {
- NdbRecAttr * ret = new NdbRecAttr();
+ NdbRecAttr * ret = new NdbRecAttr(0);
ret->theAttrId = theAttrId;
ret->theNULLind = theNULLind;
diff --git a/ndb/src/ndbapi/NdbUtil.cpp b/ndb/src/ndbapi/NdbUtil.cpp
index 5c74d251ff9..6019ea675a1 100644
--- a/ndb/src/ndbapi/NdbUtil.cpp
+++ b/ndb/src/ndbapi/NdbUtil.cpp
@@ -30,8 +30,7 @@ Comment:
#include "NdbUtil.hpp"
-NdbLabel::NdbLabel() :
- theNext(NULL)
+NdbLabel::NdbLabel(Ndb*)
{
}
@@ -39,8 +38,7 @@ NdbLabel::~NdbLabel()
{
}
-NdbSubroutine::NdbSubroutine() :
- theNext(NULL)
+NdbSubroutine::NdbSubroutine(Ndb*)
{
}
@@ -48,9 +46,8 @@ NdbSubroutine::~NdbSubroutine()
{
}
-NdbBranch::NdbBranch() :
- theSignal(NULL),
- theNext(NULL)
+NdbBranch::NdbBranch(Ndb*) :
+ theSignal(NULL)
{
}
@@ -58,9 +55,8 @@ NdbBranch::~NdbBranch()
{
}
-NdbCall::NdbCall() :
- theSignal(NULL),
- theNext(NULL)
+NdbCall::NdbCall(Ndb*) :
+ theSignal(NULL)
{
}
diff --git a/ndb/src/ndbapi/NdbUtil.hpp b/ndb/src/ndbapi/NdbUtil.hpp
index 80fc15ddd8c..268f6c69e6f 100644
--- a/ndb/src/ndbapi/NdbUtil.hpp
+++ b/ndb/src/ndbapi/NdbUtil.hpp
@@ -31,44 +31,53 @@ Comment:
#include <ndb_global.h>
+class Ndb;
class NdbApiSignal;
class NdbOperation;
-class NdbLabel
+template<class T>
+struct Free_list_element
+{
+ Free_list_element() { theNext = 0;}
+ void next(T* obj) { theNext = obj;}
+ T* next() { return theNext;}
+
+ T* theNext;
+};
+
+class NdbLabel : public Free_list_element<NdbLabel>
{
friend class NdbOperation;
friend class Ndb;
-
-private:
- NdbLabel();
+public:
+ NdbLabel(Ndb*);
~NdbLabel();
- NdbLabel* theNext;
+private:
Uint32 theSubroutine[16];
Uint32 theLabelAddress[16];
Uint32 theLabelNo[16];
};
-class NdbSubroutine
+class NdbSubroutine : public Free_list_element<NdbSubroutine>
{
friend class NdbOperation;
friend class Ndb;
-private:
- NdbSubroutine();
+public:
+ NdbSubroutine(Ndb*);
~NdbSubroutine();
- NdbSubroutine* theNext;
Uint32 theSubroutineAddress[16];
};
-class NdbBranch
+class NdbBranch : public Free_list_element<NdbBranch>
{
friend class NdbOperation;
friend class Ndb;
-private:
- NdbBranch();
+public:
+ NdbBranch(Ndb*);
~NdbBranch();
NdbApiSignal* theSignal;
@@ -76,22 +85,20 @@ private:
Uint32 theBranchAddress;
Uint32 theBranchLabel;
Uint32 theSubroutine;
- NdbBranch* theNext;
};
-class NdbCall
+class NdbCall : public Free_list_element<NdbCall>
{
friend class NdbOperation;
friend class Ndb;
-private:
- NdbCall();
+public:
+ NdbCall(Ndb*);
~NdbCall();
NdbApiSignal* theSignal;
Uint32 theSignalAddress;
Uint32 theSubroutine;
- NdbCall* theNext;
};
#endif
diff --git a/ndb/src/ndbapi/Ndbif.cpp b/ndb/src/ndbapi/Ndbif.cpp
index 1caebe436ef..3ebba7e1c4a 100644
--- a/ndb/src/ndbapi/Ndbif.cpp
+++ b/ndb/src/ndbapi/Ndbif.cpp
@@ -143,15 +143,6 @@ Ndb::init(int aMaxNoOfTransactions)
error_handler:
ndbout << "error_handler" << endl;
releaseTransactionArrays();
- while ( theConIdleList != NULL )
- freeNdbCon();
- while ( theSignalIdleList != NULL )
- freeSignal();
- while (theRecAttrIdleList != NULL)
- freeRecAttr();
- while (theOpIdleList != NULL)
- freeOperation();
-
delete theDictionary;
TransporterFacade::instance()->close(theNdbBlockNumber, 0);
DBUG_RETURN(-1);
diff --git a/ndb/src/ndbapi/Ndbinit.cpp b/ndb/src/ndbapi/Ndbinit.cpp
index a11dd842495..59a6a825be4 100644
--- a/ndb/src/ndbapi/Ndbinit.cpp
+++ b/ndb/src/ndbapi/Ndbinit.cpp
@@ -29,6 +29,10 @@
#include <NdbOut.hpp>
#include <NdbSleep.h>
#include "ObjectMap.hpp"
+#include <NdbIndexScanOperation.hpp>
+#include <NdbIndexOperation.hpp>
+#include "NdbUtil.hpp"
+#include <NdbBlob.hpp>
class NdbGlobalEventBufferHandle;
NdbGlobalEventBufferHandle *NdbGlobalEventBuffer_init(int);
@@ -99,20 +103,8 @@ void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection,
theMaxNoOfTransactions= 0;
theMinNoOfEventsToWakeUp= 0;
prefixEnd= NULL;
- theConIdleList= NULL;
- theOpIdleList= NULL;
- theScanOpIdleList= NULL;
- theIndexOpIdleList= NULL;
theTransactionList= NULL;
theConnectionArray= NULL;
- theRecAttrIdleList= NULL;
- theSignalIdleList= NULL;
- theLabelList= NULL;
- theBranchList= NULL;
- theSubroutineList= NULL;
- theCallList= NULL;
- theScanList= NULL;
- theNdbBlobIdleList= NULL;
the_last_check_time= 0;
theFirstTransId= 0;
theRestartGCI= 0;
@@ -204,33 +196,6 @@ Ndb::~Ndb()
TransporterFacade::instance()->close(theNdbBlockNumber, theFirstTransId);
}
-// if (theSchemaConToNdbList != NULL)
-// closeSchemaTransaction(theSchemaConToNdbList);
- while ( theConIdleList != NULL )
- freeNdbCon();
- while (theOpIdleList != NULL)
- freeOperation();
- while (theScanOpIdleList != NULL)
- freeScanOperation();
- while (theIndexOpIdleList != NULL)
- freeIndexOperation();
- while (theLabelList != NULL)
- freeNdbLabel();
- while (theBranchList != NULL)
- freeNdbBranch();
- while (theSubroutineList != NULL)
- freeNdbSubroutine();
- while (theCallList != NULL)
- freeNdbCall();
- while (theScanList != NULL)
- freeNdbScanRec();
- while (theNdbBlobIdleList != NULL)
- freeNdbBlob();
- while (theRecAttrIdleList != NULL)
- freeRecAttr();
- while ( theSignalIdleList != NULL )
- freeSignal();
-
releaseTransactionArrays();
delete []theConnectionArray;
@@ -296,7 +261,8 @@ NdbImpl::NdbImpl(Ndb_cluster_connection *ndb_cluster_connection,
: m_ndb_cluster_connection(ndb_cluster_connection->m_impl),
m_dictionary(ndb),
theCurrentConnectIndex(0),
- theNdbObjectIdMap(1024,1024),
+ theNdbObjectIdMap(ndb_cluster_connection->m_impl.m_transporter_facade->theMutexPtr,
+ 1024,1024),
theNoOfDBnodes(0)
{
int i;
diff --git a/ndb/src/ndbapi/Ndblist.cpp b/ndb/src/ndbapi/Ndblist.cpp
index 5902aa413dc..3001561a73a 100644
--- a/ndb/src/ndbapi/Ndblist.cpp
+++ b/ndb/src/ndbapi/Ndblist.cpp
@@ -76,25 +76,7 @@ Ndb::checkFailedNode()
int
Ndb::createConIdleList(int aNrOfCon)
{
- for (int i = 0; i < aNrOfCon; i++)
- {
- NdbConnection* tNdbCon = new NdbConnection(this);
- if (tNdbCon == NULL)
- {
- return -1;
- }
- if (theConIdleList == NULL)
- {
- theConIdleList = tNdbCon;
- theConIdleList->next(NULL);
- } else
- {
- tNdbCon->next(theConIdleList);
- theConIdleList = tNdbCon;
- }
- tNdbCon->Status(NdbConnection::NotConnected);
- }
- theNoOfAllocatedTransactions = aNrOfCon;
+ theImpl->theConIdleList.fill(this, aNrOfCon);
return aNrOfCon;
}
@@ -110,19 +92,7 @@ Ndb::createConIdleList(int aNrOfCon)
int
Ndb::createOpIdleList(int aNrOfOp)
{
- for (int i = 0; i < aNrOfOp; i++){
- NdbOperation* tOp = new NdbOperation(this);
- if ( tOp == NULL ){
- return -1;
- }
- if (theOpIdleList == NULL){
- theOpIdleList = tOp;
- theOpIdleList->next(NULL);
- } else{
- tOp->next(theOpIdleList);
- theOpIdleList = tOp;
- }
- }
+ theImpl->theOpIdleList.fill(this, aNrOfOp);
return aNrOfOp;
}
@@ -136,22 +106,7 @@ Ndb::createOpIdleList(int aNrOfOp)
NdbBranch*
Ndb::getNdbBranch()
{
- NdbBranch* tNdbBranch;
- if ( theBranchList == NULL )
- {
- tNdbBranch = new NdbBranch;
- if (tNdbBranch == NULL)
- {
- return NULL;
- }
- tNdbBranch->theNext = NULL;
- } else
- {
- tNdbBranch = theBranchList;
- theBranchList = tNdbBranch->theNext;
- tNdbBranch->theNext = NULL;
- }
- return tNdbBranch;
+ return theImpl->theBranchList.seize(this);
}
/***************************************************************************
@@ -164,22 +119,7 @@ Ndb::getNdbBranch()
NdbCall*
Ndb::getNdbCall()
{
- NdbCall* tNdbCall;
- if ( theCallList == NULL )
- {
- tNdbCall = new NdbCall;
- if (tNdbCall == NULL)
- {
- return NULL;
- }
- tNdbCall->theNext = NULL;
- } else
- {
- tNdbCall = theCallList;
- theCallList = tNdbCall->theNext;
- tNdbCall->theNext = NULL;
- }
- return tNdbCall;
+ return theImpl->theCallList.seize(this);
}
/***************************************************************************
@@ -192,25 +132,14 @@ Ndb::getNdbCall()
NdbConnection*
Ndb::getNdbCon()
{
- NdbConnection* tNdbCon;
- if ( theConIdleList == NULL ) {
- if (theNoOfAllocatedTransactions < theMaxNoOfTransactions) {
- tNdbCon = new NdbConnection(this);
- if (tNdbCon == NULL) {
- return NULL;
- }//if
- theNoOfAllocatedTransactions++;
- } else {
- ndbout << "theNoOfAllocatedTransactions = " << theNoOfAllocatedTransactions << " theMaxNoOfTransactions = " << theMaxNoOfTransactions << endl;
- return NULL;
- }//if
- tNdbCon->next(NULL);
- } else
+ NdbConnection* tNdbCon = theImpl->theConIdleList.seize(this);
+ if (unlikely(theImpl->theConIdleList.m_alloc_cnt > theMaxNoOfTransactions))
{
- tNdbCon = theConIdleList;
- theConIdleList = tNdbCon->next();
- tNdbCon->next(NULL);
- }
+ theImpl->theConIdleList.release(tNdbCon);
+ ndbout << "theNoOfAllocatedTransactions = " << theNoOfAllocatedTransactions << " theMaxNoOfTransactions = " << theMaxNoOfTransactions << endl;
+ return NULL;
+ }//if
+
tNdbCon->theMagicNumber = 0x37412619;
return tNdbCon;
}
@@ -225,22 +154,7 @@ Ndb::getNdbCon()
NdbLabel*
Ndb::getNdbLabel()
{
- NdbLabel* tNdbLabel;
- if ( theLabelList == NULL )
- {
- tNdbLabel = new NdbLabel;
- if (tNdbLabel == NULL)
- {
- return NULL;
- }
- tNdbLabel->theNext = NULL;
- } else
- {
- tNdbLabel = theLabelList;
- theLabelList = tNdbLabel->theNext;
- tNdbLabel->theNext = NULL;
- }
- return tNdbLabel;
+ return theImpl->theLabelList.seize(this);
}
/***************************************************************************
@@ -254,23 +168,7 @@ Ndb::getNdbLabel()
NdbReceiver*
Ndb::getNdbScanRec()
{
- NdbReceiver* tNdbScanRec;
- if ( theScanList == NULL )
- {
- tNdbScanRec = new NdbReceiver(this);
- if (tNdbScanRec == NULL)
- {
- return NULL;
- }
- tNdbScanRec->next(NULL);
- } else
- {
- tNdbScanRec = theScanList;
- theScanList = tNdbScanRec->next();
- tNdbScanRec->next(NULL);
- }
-
- return tNdbScanRec;
+ return theImpl->theScanList.seize(this);
}
/***************************************************************************
@@ -283,22 +181,7 @@ Ndb::getNdbScanRec()
NdbSubroutine*
Ndb::getNdbSubroutine()
{
- NdbSubroutine* tNdbSubroutine;
- if ( theSubroutineList == NULL )
- {
- tNdbSubroutine = new NdbSubroutine;
- if (tNdbSubroutine == NULL)
- {
- return NULL;
- }
- tNdbSubroutine->theNext = NULL;
- } else
- {
- tNdbSubroutine = theSubroutineList;
- theSubroutineList = tNdbSubroutine->theNext;
- tNdbSubroutine->theNext = NULL;
- }
- return tNdbSubroutine;
+ return theImpl->theSubroutineList.seize(this);
}
/***************************************************************************
@@ -311,18 +194,7 @@ Remark: Get an operation from theOpIdleList and return the object .
NdbOperation*
Ndb::getOperation()
{
- NdbOperation* tOp = theOpIdleList;
- if (tOp != NULL ) {
- NdbOperation* tOpNext = tOp->next();
- tOp->next(NULL);
- theOpIdleList = tOpNext;
- return tOp;
- } else {
- tOp = new NdbOperation(this);
- if (tOp != NULL)
- tOp->next(NULL);
- }
- return tOp;
+ return theImpl->theOpIdleList.seize(this);
}
/***************************************************************************
@@ -335,18 +207,7 @@ Remark: Get an operation from theScanOpIdleList and return the object .
NdbIndexScanOperation*
Ndb::getScanOperation()
{
- NdbIndexScanOperation* tOp = theScanOpIdleList;
- if (tOp != NULL ) {
- NdbIndexScanOperation* tOpNext = (NdbIndexScanOperation*)tOp->next();
- tOp->next(NULL);
- theScanOpIdleList = tOpNext;
- return tOp;
- } else {
- tOp = new NdbIndexScanOperation(this);
- if (tOp != NULL)
- tOp->next(NULL);
- }
- return tOp;
+ return theImpl->theScanOpIdleList.seize(this);
}
/***************************************************************************
@@ -359,18 +220,7 @@ Remark: Get an operation from theIndexOpIdleList and return the object .
NdbIndexOperation*
Ndb::getIndexOperation()
{
- NdbIndexOperation* tOp = theIndexOpIdleList;
- if (tOp != NULL ) {
- NdbIndexOperation* tOpNext = (NdbIndexOperation*) tOp->next();
- tOp->next(NULL);
- theIndexOpIdleList = tOpNext;
- return tOp;
- } else {
- tOp = new NdbIndexOperation(this);
- if (tOp != NULL)
- tOp->next(NULL);
- }
- return tOp;
+ return theImpl->theIndexOpIdleList.seize(this);
}
/***************************************************************************
@@ -382,21 +232,14 @@ Return Value: Return a reference to a receive attribute object.
NdbRecAttr*
Ndb::getRecAttr()
{
- NdbRecAttr* tRecAttr;
- tRecAttr = theRecAttrIdleList;
- if (tRecAttr != NULL) {
- NdbRecAttr* tRecAttrNext = tRecAttr->next();
+ NdbRecAttr* tRecAttr = theImpl->theRecAttrIdleList.seize(this);
+ if (tRecAttr != NULL)
+ {
tRecAttr->init();
- theRecAttrIdleList = tRecAttrNext;
return tRecAttr;
- } else {
- tRecAttr = new NdbRecAttr;
- if (tRecAttr == NULL)
- return NULL;
- tRecAttr->next(NULL);
- }//if
- tRecAttr->init();
- return tRecAttr;
+ }
+
+ return NULL;
}
/***************************************************************************
@@ -408,34 +251,16 @@ Return Value: Return a reference to a signal object.
NdbApiSignal*
Ndb::getSignal()
{
- NdbApiSignal* tSignal = theSignalIdleList;
- if (tSignal != NULL){
- NdbApiSignal* tSignalNext = tSignal->next();
- tSignal->next(NULL);
- theSignalIdleList = tSignalNext;
- } else {
- tSignal = new NdbApiSignal(theMyRef);
-#ifdef POORMANSPURIFY
- cnewSignals++;
-#endif
- if (tSignal != NULL)
- tSignal->next(NULL);
- }
-#ifdef POORMANSPURIFY
- cgetSignals++;
-#endif
- return tSignal;
+ return theImpl->theSignalIdleList.seize(this);
}
NdbBlob*
Ndb::getNdbBlob()
{
- NdbBlob* tBlob = theNdbBlobIdleList;
- if (tBlob != NULL) {
- theNdbBlobIdleList = tBlob->theNext;
+ NdbBlob* tBlob = theImpl->theNdbBlobIdleList.seize(this);
+ if(tBlob)
+ {
tBlob->init();
- } else {
- tBlob = new NdbBlob;
}
return tBlob;
}
@@ -449,8 +274,7 @@ Remark: Add a NdbBranch object into the Branch idlelist.
void
Ndb::releaseNdbBranch(NdbBranch* aNdbBranch)
{
- aNdbBranch->theNext = theBranchList;
- theBranchList = aNdbBranch;
+ theImpl->theBranchList.release(aNdbBranch);
}
/***************************************************************************
@@ -462,8 +286,7 @@ Remark: Add a NdbBranch object into the Branch idlelist.
void
Ndb::releaseNdbCall(NdbCall* aNdbCall)
{
- aNdbCall->theNext = theCallList;
- theCallList = aNdbCall;
+ theImpl->theCallList.release(aNdbCall);
}
/***************************************************************************
@@ -475,9 +298,8 @@ Remark: Add a Connection object into the signal idlelist.
void
Ndb::releaseNdbCon(NdbConnection* aNdbCon)
{
- aNdbCon->next(theConIdleList);
aNdbCon->theMagicNumber = 0xFE11DD;
- theConIdleList = aNdbCon;
+ theImpl->theConIdleList.release(aNdbCon);
}
/***************************************************************************
@@ -489,8 +311,7 @@ Remark: Add a NdbLabel object into the Label idlelist.
void
Ndb::releaseNdbLabel(NdbLabel* aNdbLabel)
{
- aNdbLabel->theNext = theLabelList;
- theLabelList = aNdbLabel;
+ theImpl->theLabelList.release(aNdbLabel);
}
/***************************************************************************
@@ -502,8 +323,7 @@ Remark: Add a NdbScanReceiver object into the Scan idlelist.
void
Ndb::releaseNdbScanRec(NdbReceiver* aNdbScanRec)
{
- aNdbScanRec->next(theScanList);
- theScanList = aNdbScanRec;
+ theImpl->theScanList.release(aNdbScanRec);
}
/***************************************************************************
@@ -515,8 +335,7 @@ Remark: Add a NdbSubroutine object into theSubroutine idlelist.
void
Ndb::releaseNdbSubroutine(NdbSubroutine* aNdbSubroutine)
{
- aNdbSubroutine->theNext = theSubroutineList;
- theSubroutineList = aNdbSubroutine;
+ theImpl->theSubroutineList.release(aNdbSubroutine);
}
/***************************************************************************
@@ -529,16 +348,14 @@ void
Ndb::releaseOperation(NdbOperation* anOperation)
{
if(anOperation->m_tcReqGSN == GSN_TCKEYREQ){
- anOperation->next(theOpIdleList);
anOperation->theNdbCon = NULL;
anOperation->theMagicNumber = 0xFE11D0;
- theOpIdleList = anOperation;
+ theImpl->theOpIdleList.release(anOperation);
} else {
assert(anOperation->m_tcReqGSN == GSN_TCINDXREQ);
- anOperation->next(theIndexOpIdleList);
anOperation->theNdbCon = NULL;
anOperation->theMagicNumber = 0xFE11D1;
- theIndexOpIdleList = (NdbIndexOperation*)anOperation;
+ theImpl->theIndexOpIdleList.release((NdbIndexOperation*)anOperation);
}
}
@@ -551,10 +368,9 @@ Remark: Add a NdbScanOperation object into the signal idlelist.
void
Ndb::releaseScanOperation(NdbIndexScanOperation* aScanOperation)
{
- aScanOperation->next(theScanOpIdleList);
aScanOperation->theNdbCon = NULL;
aScanOperation->theMagicNumber = 0xFE11D2;
- theScanOpIdleList = aScanOperation;
+ theImpl->theScanOpIdleList.release(aScanOperation);
}
/***************************************************************************
@@ -567,8 +383,7 @@ void
Ndb::releaseRecAttr(NdbRecAttr* aRecAttr)
{
aRecAttr->release();
- aRecAttr->next(theRecAttrIdleList);
- theRecAttrIdleList = aRecAttr;
+ theImpl->theRecAttrIdleList.release(aRecAttr);
}
/***************************************************************************
@@ -595,8 +410,7 @@ Ndb::releaseSignal(NdbApiSignal* aSignal)
#ifdef POORMANSPURIFY
creleaseSignals++;
#endif
- aSignal->next(theSignalIdleList);
- theSignalIdleList = aSignal;
+ theImpl->theSignalIdleList.release(aSignal);
}
void
@@ -612,163 +426,7 @@ Ndb::releaseSignalsInList(NdbApiSignal** pList){
void
Ndb::releaseNdbBlob(NdbBlob* aBlob)
{
- aBlob->release();
- aBlob->theNext = theNdbBlobIdleList;
- theNdbBlobIdleList = aBlob;
-}
-
-/***************************************************************************
-void freeOperation();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeOperation()
-{
- NdbOperation* tOp = theOpIdleList;
- theOpIdleList = theOpIdleList->next();
- delete tOp;
-}
-
-/***************************************************************************
-void freeScanOperation();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeScanOperation()
-{
- NdbIndexScanOperation* tOp = theScanOpIdleList;
- theScanOpIdleList = (NdbIndexScanOperation *)tOp->next();
- delete tOp;
-}
-
-/***************************************************************************
-void freeIndexOperation();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeIndexOperation()
-{
- NdbIndexOperation* tOp = theIndexOpIdleList;
- theIndexOpIdleList = (NdbIndexOperation *) theIndexOpIdleList->next();
- delete tOp;
-}
-
-/***************************************************************************
-void freeNdbBranch();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbBranch()
-{
- NdbBranch* tNdbBranch = theBranchList;
- theBranchList = theBranchList->theNext;
- delete tNdbBranch;
-}
-
-/***************************************************************************
-void freeNdbCall();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbCall()
-{
- NdbCall* tNdbCall = theCallList;
- theCallList = theCallList->theNext;
- delete tNdbCall;
-}
-
-/***************************************************************************
-void freeNdbScanRec();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbScanRec()
-{
- NdbReceiver* tNdbScanRec = theScanList;
- theScanList = theScanList->next();
- delete tNdbScanRec;
-}
-
-/***************************************************************************
-void freeNdbCon();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbCon()
-{
- NdbConnection* tNdbCon = theConIdleList;
- theConIdleList = theConIdleList->next();
- delete tNdbCon;
-}
-
-/***************************************************************************
-void freeNdbLabel();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbLabel()
-{
- NdbLabel* tNdbLabel = theLabelList;
- theLabelList = theLabelList->theNext;
- delete tNdbLabel;
-}
-
-/***************************************************************************
-void freeNdbSubroutine();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbSubroutine()
-{
- NdbSubroutine* tNdbSubroutine = theSubroutineList;
- theSubroutineList = theSubroutineList->theNext;
- delete tNdbSubroutine;
-}
-
-/***************************************************************************
-void freeRecAttr();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeRecAttr()
-{
- NdbRecAttr* tRecAttr = theRecAttrIdleList;
- theRecAttrIdleList = theRecAttrIdleList->next();
- delete tRecAttr;
-}
-
-/***************************************************************************
-void freeSignal();
-
-Remark: Delete a signal object from the signal idlelist.
-***************************************************************************/
-void
-Ndb::freeSignal()
-{
- NdbApiSignal* tSignal = theSignalIdleList;
- theSignalIdleList = tSignal->next();
- delete tSignal;
-#ifdef POORMANSPURIFY
- cfreeSignals++;
-#endif
-}
-
-void
-Ndb::freeNdbBlob()
-{
- NdbBlob* tBlob = theNdbBlobIdleList;
- theNdbBlobIdleList = tBlob->theNext;
- delete tBlob;
+ theImpl->theNdbBlobIdleList.release(aBlob);
}
/****************************************************************************
@@ -823,3 +481,102 @@ Ndb::releaseConnectToNdb(NdbConnection* a_con)
DBUG_VOID_RETURN;
}
+template<class T>
+static
+Ndb::Free_list_usage*
+update(Ndb::Free_list_usage* curr,
+ Ndb_free_list_t<T> & list,
+ const char * name)
+{
+ curr->m_name = name;
+ curr->m_created = list.m_alloc_cnt;
+ curr->m_free = list.m_free_cnt;
+ curr->m_sizeof = sizeof(T);
+ return curr;
+}
+
+Ndb::Free_list_usage*
+Ndb::get_free_list_usage(Ndb::Free_list_usage* curr)
+{
+ if (curr == 0)
+ {
+ return 0;
+ }
+
+ if(curr->m_name == 0)
+ {
+ update(curr, theImpl->theConIdleList, "NdbTransaction");
+ }
+ else if(!strcmp(curr->m_name, "NdbTransaction"))
+ {
+ update(curr, theImpl->theOpIdleList, "NdbOperation");
+ }
+ else if(!strcmp(curr->m_name, "NdbOperation"))
+ {
+ update(curr, theImpl->theScanOpIdleList, "NdbIndexScanOperation");
+ }
+ else if(!strcmp(curr->m_name, "NdbIndexScanOperation"))
+ {
+ update(curr, theImpl->theIndexOpIdleList, "NdbIndexOperation");
+ }
+ else if(!strcmp(curr->m_name, "NdbIndexOperation"))
+ {
+ update(curr, theImpl->theRecAttrIdleList, "NdbRecAttr");
+ }
+ else if(!strcmp(curr->m_name, "NdbRecAttr"))
+ {
+ update(curr, theImpl->theSignalIdleList, "NdbApiSignal");
+ }
+ else if(!strcmp(curr->m_name, "NdbApiSignal"))
+ {
+ update(curr, theImpl->theLabelList, "NdbLabel");
+ }
+ else if(!strcmp(curr->m_name, "NdbLabel"))
+ {
+ update(curr, theImpl->theBranchList, "NdbBranch");
+ }
+ else if(!strcmp(curr->m_name, "NdbBranch"))
+ {
+ update(curr, theImpl->theSubroutineList, "NdbSubroutine");
+ }
+ else if(!strcmp(curr->m_name, "NdbSubroutine"))
+ {
+ update(curr, theImpl->theCallList, "NdbCall");
+ }
+ else if(!strcmp(curr->m_name, "NdbCall"))
+ {
+ update(curr, theImpl->theNdbBlobIdleList, "NdbBlob");
+ }
+ else if(!strcmp(curr->m_name, "NdbBlob"))
+ {
+ update(curr, theImpl->theScanList, "NdbReceiver");
+ }
+ else if(!strcmp(curr->m_name, "NdbReceiver"))
+ {
+ return 0;
+ }
+ else
+ {
+ update(curr, theImpl->theConIdleList, "NdbTransaction");
+ }
+
+ return curr;
+}
+
+#define TI(T) \
+ template Ndb::Free_list_usage* \
+ update(Ndb::Free_list_usage*, Ndb_free_list_t<T> &, const char * name);\
+ template struct Ndb_free_list_t<T>
+
+TI(NdbBlob);
+TI(NdbCall);
+TI(NdbLabel);
+TI(NdbBranch);
+TI(NdbSubroutine);
+TI(NdbApiSignal);
+TI(NdbRecAttr);
+TI(NdbOperation);
+TI(NdbReceiver);
+TI(NdbConnection);
+TI(NdbIndexOperation);
+TI(NdbIndexScanOperation);
diff --git a/ndb/src/ndbapi/ObjectMap.hpp b/ndb/src/ndbapi/ObjectMap.hpp
index 21407279f0b..c730d1ce6b1 100644
--- a/ndb/src/ndbapi/ObjectMap.hpp
+++ b/ndb/src/ndbapi/ObjectMap.hpp
@@ -30,7 +30,7 @@ class NdbObjectIdMap //: NdbLockable
{
public:
STATIC_CONST( InvalidId = ~(Uint32)0 );
- NdbObjectIdMap(Uint32 initalSize = 128, Uint32 expandSize = 10);
+ NdbObjectIdMap(NdbMutex*, Uint32 initalSize = 128, Uint32 expandSize = 10);
~NdbObjectIdMap();
Uint32 map(void * object);
@@ -46,14 +46,16 @@ private:
void * m_obj;
} * m_map;
+ NdbMutex * m_mutex;
void expand(Uint32 newSize);
};
inline
-NdbObjectIdMap::NdbObjectIdMap(Uint32 sz, Uint32 eSz) {
+NdbObjectIdMap::NdbObjectIdMap(NdbMutex* mutex, Uint32 sz, Uint32 eSz) {
m_size = 0;
m_firstFree = InvalidId;
m_map = 0;
+ m_mutex = mutex;
m_expandSize = eSz;
expand(sz);
#ifdef DEBUG_OBJECTMAP
@@ -131,21 +133,26 @@ NdbObjectIdMap::getObject(Uint32 id){
inline void
NdbObjectIdMap::expand(Uint32 incSize){
+ NdbMutex_Lock(m_mutex);
Uint32 newSize = m_size + incSize;
- MapEntry * tmp = (MapEntry*)malloc(newSize * sizeof(MapEntry));
+ MapEntry * tmp = (MapEntry*)realloc(m_map, newSize * sizeof(MapEntry));
- if (m_map) {
- memcpy(tmp, m_map, m_size * sizeof(MapEntry));
- free((void*)m_map);
+ if (likely(tmp != 0))
+ {
+ m_map = tmp;
+
+ for(Uint32 i = m_size; i<newSize; i++){
+ m_map[i].m_next = i + 1;
+ }
+ m_firstFree = m_size;
+ m_map[newSize-1].m_next = InvalidId;
+ m_size = newSize;
}
- m_map = tmp;
-
- for(Uint32 i = m_size; i<newSize; i++){
- m_map[i].m_next = i + 1;
+ else
+ {
+ ndbout_c("NdbObjectIdMap::expand unable to expand!!");
}
- m_firstFree = m_size;
- m_map[newSize-1].m_next = InvalidId;
- m_size = newSize;
+ NdbMutex_Unlock(m_mutex);
}
#endif
diff --git a/ndb/src/ndbapi/SignalSender.cpp b/ndb/src/ndbapi/SignalSender.cpp
index a1c80f22041..a29fe68937b 100644
--- a/ndb/src/ndbapi/SignalSender.cpp
+++ b/ndb/src/ndbapi/SignalSender.cpp
@@ -250,21 +250,31 @@ SignalSender::execNodeStatus(void* signalSender,
// node shutdown complete
s->header.theVerId_signalNumber = GSN_NF_COMPLETEREP;
NFCompleteRep *rep = (NFCompleteRep *)s->getDataPtrSend();
+ rep->blockNo = 0;
+ rep->nodeId = 0;
rep->failedNodeId = nodeId;
+ rep->unused = 0;
+ rep->from = 0;
}
else
{
// node failure
s->header.theVerId_signalNumber = GSN_NODE_FAILREP;
NodeFailRep *rep = (NodeFailRep *)s->getDataPtrSend();
- rep->failNo = nodeId;
+ rep->failNo = 0;
+ rep->masterNodeId = 0;
+ rep->noOfNodes = 1;
+ NodeBitmask::clear(rep->theNodes);
+ NodeBitmask::set(rep->theNodes,nodeId);
}
ss->m_jobBuffer.push_back(s);
NdbCondition_Signal(ss->m_cond);
}
+#if __SUNPRO_CC != 0x560
template SimpleSignal* SignalSender::waitFor<WaitForNode>(unsigned, WaitForNode&);
template SimpleSignal* SignalSender::waitFor<WaitForAny>(unsigned, WaitForAny&);
+#endif
template class Vector<SimpleSignal*>;
diff --git a/ndb/test/include/NDBT_Test.hpp b/ndb/test/include/NDBT_Test.hpp
index a60228c1a5d..44eb24cd87e 100644
--- a/ndb/test/include/NDBT_Test.hpp
+++ b/ndb/test/include/NDBT_Test.hpp
@@ -64,7 +64,8 @@ public:
const char* getPropertyWait(const char*, const char* );
void decProperty(const char *);
-
+ void incProperty(const char *);
+
// Communicate with other tests
void stopTest();
bool isTestStopped();
@@ -425,7 +426,7 @@ C##suitname():NDBT_TestSuite(#suitname){ \
pt->addTable(tableName, false);
#define NDBT_TESTSUITE_END(suitname) \
- } } ; C##suitname suitname;
+ } } ; C##suitname suitname
// Helper functions for retrieving variables from NDBT_Step
#define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb()
diff --git a/ndb/test/ndbapi/Makefile.am b/ndb/test/ndbapi/Makefile.am
index 6f04ac3fce2..7b4a96f5890 100644
--- a/ndb/test/ndbapi/Makefile.am
+++ b/ndb/test/ndbapi/Makefile.am
@@ -31,7 +31,8 @@ testTimeout \
testTransactions \
testDeadlock \
test_event ndbapi_slow_select testReadPerf testLcp \
-DbCreate DbAsyncGenerator
+DbCreate DbAsyncGenerator \
+testSRBank
#flexTimedAsynch
#testBlobs
@@ -72,6 +73,7 @@ testReadPerf_SOURCES = testReadPerf.cpp
testLcp_SOURCES = testLcp.cpp
DbCreate_SOURCES= bench/mainPopulate.cpp bench/dbPopulate.cpp bench/userInterface.cpp bench/dbPopulate.h bench/userInterface.h bench/testData.h bench/testDefinitions.h bench/ndb_schema.hpp bench/ndb_error.hpp
DbAsyncGenerator_SOURCES= bench/mainAsyncGenerator.cpp bench/asyncGenerator.cpp bench/ndb_async2.cpp bench/dbGenerator.h bench/macros.h bench/userInterface.h bench/testData.h bench/testDefinitions.h bench/ndb_schema.hpp bench/ndb_error.hpp
+testSRBank_SOURCES = testSRBank.cpp
INCLUDES_LOC = -I$(top_srcdir)/ndb/include/kernel
@@ -83,6 +85,7 @@ include $(top_srcdir)/ndb/config/type_ndbapitest.mk.am
##testSystemRestart_INCLUDES = $(INCLUDES) -I$(top_srcdir)/ndb/include/kernel
##testTransactions_INCLUDES = $(INCLUDES) -I$(top_srcdir)/ndb/include/kernel
testBackup_LDADD = $(LDADD) bank/libbank.a
+testSRBank_LDADD = bank/libbank.a $(LDADD)
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/ndb/test/ndbapi/bank/Bank.cpp b/ndb/test/ndbapi/bank/Bank.cpp
index c6029259357..346442367fc 100644
--- a/ndb/test/ndbapi/bank/Bank.cpp
+++ b/ndb/test/ndbapi/bank/Bank.cpp
@@ -19,12 +19,13 @@
#include <NdbSleep.h>
#include <UtilTransactions.hpp>
-Bank::Bank():
+Bank::Bank(bool _init):
m_ndb("BANK"),
m_maxAccount(-1),
m_initialized(false)
{
-
+ if(_init)
+ init();
}
int Bank::init(){
@@ -34,40 +35,39 @@ int Bank::init(){
myRandom48Init(NdbTick_CurrentMillisecond());
m_ndb.init();
- while (m_ndb.waitUntilReady(10) != 0)
- ndbout << "Waiting for ndb to be ready" << endl;
-
+ if (m_ndb.waitUntilReady(30) != 0)
+ {
+ ndbout << "Ndb not ready" << endl;
+ return NDBT_FAILED;
+ }
+
if (getNumAccounts() != NDBT_OK)
return NDBT_FAILED;
+
+ m_initialized = true;
return NDBT_OK;
}
int Bank::performTransactions(int maxSleepBetweenTrans, int yield){
- if (init() != NDBT_OK)
- return NDBT_FAILED;
int transactions = 0;
- while(1){
-
- while(m_ndb.waitUntilReady(10) != 0)
- ndbout << "Waiting for ndb to be ready" << endl;
-
- while(performTransaction() != NDBT_FAILED){
- transactions++;
-
- if (maxSleepBetweenTrans > 0){
- int val = myRandom48(maxSleepBetweenTrans);
- NdbSleep_MilliSleep(val);
- }
-
- if((transactions % 100) == 0)
- g_info << transactions << endl;
-
- if (yield != 0 && transactions >= yield)
- return NDBT_OK;
+ while(performTransaction() == NDBT_OK)
+ {
+ transactions++;
+
+ if (maxSleepBetweenTrans > 0){
+ int val = myRandom48(maxSleepBetweenTrans);
+ NdbSleep_MilliSleep(val);
}
+
+ if((transactions % 100) == 0)
+ g_info << transactions << endl;
+
+ if (yield != 0 && transactions >= yield)
+ return NDBT_OK;
}
+
return NDBT_FAILED;
}
@@ -92,7 +92,7 @@ int Bank::performTransaction(){
int amount = myRandom48(maxAmount);
- retry_transaction:
+retry_transaction:
int res = performTransaction(fromAccount, toAccount, amount);
if (res != 0){
switch (res){
@@ -158,8 +158,9 @@ int Bank::performTransactionImpl1(int fromAccountId,
// Ok, all clear to do the transaction
Uint64 transId;
- if (getNextTransactionId(transId) != NDBT_OK){
- return NDBT_FAILED;
+ int result = NDBT_OK;
+ if ((result= getNextTransactionId(transId)) != NDBT_OK){
+ return result;
}
NdbConnection* pTrans = m_ndb.startTransaction();
@@ -500,8 +501,6 @@ int Bank::performTransactionImpl1(int fromAccountId,
int Bank::performMakeGLs(int yield){
int result;
- if (init() != NDBT_OK)
- return NDBT_FAILED;
int counter, maxCounter;
int yieldCounter = 0;
@@ -512,9 +511,6 @@ int Bank::performMakeGLs(int yield){
counter = 0;
maxCounter = 50 + myRandom48(100);
- while(m_ndb.waitUntilReady(10) != 0)
- ndbout << "Waiting for ndb to be ready" << endl;
-
/**
* Validate GLs and Transactions for previous days
*
@@ -526,6 +522,7 @@ int Bank::performMakeGLs(int yield){
return NDBT_FAILED;
}
g_info << "performValidateGLs failed" << endl;
+ return NDBT_FAILED;
continue;
}
@@ -536,7 +533,7 @@ int Bank::performMakeGLs(int yield){
return NDBT_FAILED;
}
g_info << "performValidatePurged failed" << endl;
- continue;
+ return NDBT_FAILED;
}
while (1){
@@ -607,14 +604,9 @@ int Bank::performMakeGLs(int yield){
int Bank::performValidateAllGLs(){
int result;
- if (init() != NDBT_OK)
- return NDBT_FAILED;
while (1){
- while(m_ndb.waitUntilReady(10) != 0)
- ndbout << "Waiting for ndb to be ready" << endl;
-
/**
* Validate GLs and Transactions for previous days
* Set age so that ALL GL's are validated
@@ -1937,39 +1929,29 @@ int Bank::findTransactionsToPurge(const Uint64 glTime,
}
- int Bank::performIncreaseTime(int maxSleepBetweenDays, int yield){
- if (init() != NDBT_OK)
- return NDBT_FAILED;
-
+int Bank::performIncreaseTime(int maxSleepBetweenDays, int yield)
+{
int yieldCounter = 0;
-
- while(1){
-
- while(m_ndb.waitUntilReady(10) != 0)
- ndbout << "Waiting for ndb to be ready" << endl;
-
- while(1){
-
- Uint64 currTime;
- if (incCurrTime(currTime) != NDBT_OK)
- break;
-
- g_info << "Current time is " << currTime << endl;
- if (maxSleepBetweenDays > 0){
- int val = myRandom48(maxSleepBetweenDays);
- NdbSleep_SecSleep(val);
- }
-
- yieldCounter++;
- if (yield != 0 && yieldCounter >= yield)
- return NDBT_OK;
-
- }
- }
- return NDBT_FAILED;
- }
-
-
+
+ while(1){
+
+ Uint64 currTime;
+ if (incCurrTime(currTime) != NDBT_OK)
+ break;
+
+ g_info << "Current time is " << currTime << endl;
+ if (maxSleepBetweenDays > 0){
+ int val = myRandom48(maxSleepBetweenDays);
+ NdbSleep_SecSleep(val);
+ }
+
+ yieldCounter++;
+ if (yield != 0 && yieldCounter >= yield)
+ return NDBT_OK;
+
+ }
+ return NDBT_FAILED;
+}
int Bank::readSystemValue(SystemValueId sysValId, Uint64 & value){
@@ -1978,22 +1960,30 @@ int Bank::readSystemValue(SystemValueId sysValId, Uint64 & value){
NdbConnection* pTrans = m_ndb.startTransaction();
if (pTrans == NULL){
ERR(m_ndb.getNdbError());
+ if(m_ndb.getNdbError().status == NdbError::TemporaryError)
+ return NDBT_TEMPORARY;
return NDBT_FAILED;
}
- if (prepareReadSystemValueOp(pTrans, sysValId, value) != NDBT_OK) {
+ int result;
+ if ((result= prepareReadSystemValueOp(pTrans, sysValId, value)) != NDBT_OK) {
ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans);
- return NDBT_FAILED;
+ return result;
}
check = pTrans->execute(Commit);
if( check == -1 ) {
ERR(pTrans->getNdbError());
+ if(pTrans->getNdbError().status == NdbError::TemporaryError)
+ {
+ m_ndb.closeTransaction(pTrans);
+ return NDBT_TEMPORARY;
+ }
m_ndb.closeTransaction(pTrans);
return NDBT_FAILED;
}
-
+
m_ndb.closeTransaction(pTrans);
return NDBT_OK;
@@ -2099,6 +2089,8 @@ int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){
NdbConnection* pTrans = m_ndb.startTransaction();
if (pTrans == NULL){
ERR(m_ndb.getNdbError());
+ if (m_ndb.getNdbError().status == NdbError::TemporaryError)
+ DBUG_RETURN(NDBT_TEMPORARY);
DBUG_RETURN(NDBT_FAILED);
}
@@ -2134,6 +2126,11 @@ int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){
check = pTrans->execute(NoCommit);
if( check == -1 ) {
ERR(pTrans->getNdbError());
+ if (pTrans->getNdbError().status == NdbError::TemporaryError)
+ {
+ m_ndb.closeTransaction(pTrans);
+ DBUG_RETURN(NDBT_TEMPORARY);
+ }
m_ndb.closeTransaction(pTrans);
DBUG_RETURN(NDBT_FAILED);
}
@@ -2208,16 +2205,21 @@ int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){
check = pTrans->execute(Commit);
if( check == -1 ) {
ERR(pTrans->getNdbError());
+ if (pTrans->getNdbError().status == NdbError::TemporaryError)
+ {
+ m_ndb.closeTransaction(pTrans);
+ DBUG_RETURN(NDBT_TEMPORARY);
+ }
m_ndb.closeTransaction(pTrans);
DBUG_RETURN(NDBT_FAILED);
}
// Check that value updated equals the value we read after the update
if (valueNewRec->u_64_value() != value){
-
+
printf("value actual=%lld\n", valueNewRec->u_64_value());
printf("value expected=%lld actual=%lld\n", value, valueNewRec->u_64_value());
-
+
DBUG_PRINT("info", ("value expected=%ld actual=%ld", value, valueNewRec->u_64_value()));
g_err << "getNextTransactionId: value was not updated" << endl;
m_ndb.closeTransaction(pTrans);
@@ -2225,7 +2227,7 @@ int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){
}
m_ndb.closeTransaction(pTrans);
-
+
DBUG_RETURN(0);
}
@@ -2242,6 +2244,8 @@ int Bank::increaseSystemValue2(SystemValueId sysValId, Uint64 &value){
NdbConnection* pTrans = m_ndb.startTransaction();
if (pTrans == NULL){
ERR(m_ndb.getNdbError());
+ if(m_ndb.getNdbError().status == NdbError::TemporaryError)
+ return NDBT_TEMPORARY;
return NDBT_FAILED;
}
@@ -2284,6 +2288,11 @@ int Bank::increaseSystemValue2(SystemValueId sysValId, Uint64 &value){
check = pTrans->execute(Commit);
if( check == -1 ) {
ERR(pTrans->getNdbError());
+ if(pTrans->getNdbError().status == NdbError::TemporaryError)
+ {
+ m_ndb.closeTransaction(pTrans);
+ return NDBT_TEMPORARY;
+ }
m_ndb.closeTransaction(pTrans);
return NDBT_FAILED;
}
@@ -2308,16 +2317,11 @@ int Bank::prepareGetCurrTimeOp(NdbConnection *pTrans, Uint64 &time){
int Bank::performSumAccounts(int maxSleepBetweenSums, int yield){
- if (init() != NDBT_OK)
- return NDBT_FAILED;
int yieldCounter = 0;
while (1){
- while (m_ndb.waitUntilReady(10) != 0)
- ndbout << "Waiting for ndb to be ready" << endl;
-
Uint32 sumAccounts = 0;
Uint32 numAccounts = 0;
if (getSumAccounts(sumAccounts, numAccounts) != NDBT_OK){
diff --git a/ndb/test/ndbapi/bank/Bank.hpp b/ndb/test/ndbapi/bank/Bank.hpp
index 34c5ff51cc2..14e01df29d5 100644
--- a/ndb/test/ndbapi/bank/Bank.hpp
+++ b/ndb/test/ndbapi/bank/Bank.hpp
@@ -27,7 +27,7 @@
class Bank {
public:
- Bank();
+ Bank(bool init = true);
int createAndLoadBank(bool overWrite, int num_accounts=10);
int dropBank();
diff --git a/ndb/test/ndbapi/bank/BankLoad.cpp b/ndb/test/ndbapi/bank/BankLoad.cpp
index 39dc8097115..2cc42240234 100644
--- a/ndb/test/ndbapi/bank/BankLoad.cpp
+++ b/ndb/test/ndbapi/bank/BankLoad.cpp
@@ -321,7 +321,7 @@ int Bank::loadGl(){
m_ndb.closeTransaction(pTrans);
return NDBT_OK;
-};
+}
int Bank::getBalanceForAccountType(const Uint32 accountType,
@@ -460,7 +460,7 @@ int Bank::loadAccountType(){
m_ndb.closeTransaction(pTrans);
return NDBT_OK;
-};
+}
/**
* Load ACCOUNT table
diff --git a/ndb/test/ndbapi/testOIBasic.cpp b/ndb/test/ndbapi/testOIBasic.cpp
index 9f8da850ff4..30a76da306a 100644
--- a/ndb/test/ndbapi/testOIBasic.cpp
+++ b/ndb/test/ndbapi/testOIBasic.cpp
@@ -2187,7 +2187,7 @@ pkinsert(Par par)
}
con.closeTransaction();
return 0;
-};
+}
static int
pkupdate(Par par)
@@ -2250,7 +2250,7 @@ pkupdate(Par par)
}
con.closeTransaction();
return 0;
-};
+}
static int
pkdelete(Par par)
@@ -2306,7 +2306,7 @@ pkdelete(Par par)
}
con.closeTransaction();
return 0;
-};
+}
static int
pkread(Par par)
diff --git a/ndb/test/ndbapi/testSRBank.cpp b/ndb/test/ndbapi/testSRBank.cpp
new file mode 100644
index 00000000000..5677f551da6
--- /dev/null
+++ b/ndb/test/ndbapi/testSRBank.cpp
@@ -0,0 +1,246 @@
+/* Copyright (C) 2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <NDBT.hpp>
+#include <NDBT_Test.hpp>
+#include <HugoTransactions.hpp>
+#include <UtilTransactions.hpp>
+#include <NdbBackup.hpp>
+
+#include "bank/Bank.hpp"
+
+int runCreateBank(NDBT_Context* ctx, NDBT_Step* step){
+ Bank bank;
+ int overWriteExisting = true;
+ if (bank.createAndLoadBank(overWriteExisting, 10) != NDBT_OK)
+ return NDBT_FAILED;
+ return NDBT_OK;
+}
+
+/**
+ *
+ * SR 0 - normal
+ * SR 1 - shutdown in progress
+ * SR 2 - restart in progress
+ */
+int runBankTimer(NDBT_Context* ctx, NDBT_Step* step){
+ int wait = 5; // Max seconds between each "day"
+ int yield = 1; // Loops before bank returns
+
+ ctx->incProperty("ThreadCount");
+ while (!ctx->isTestStopped())
+ {
+ Bank bank;
+ while(!ctx->isTestStopped() && ctx->getProperty("SR") <= 1)
+ if(bank.performIncreaseTime(wait, yield) == NDBT_FAILED)
+ break;
+
+ ndbout_c("runBankTimer is stopped");
+ ctx->incProperty("ThreadStopped");
+ if(ctx->getPropertyWait("SR", (Uint32)0))
+ break;
+ }
+ return NDBT_OK;
+}
+
+int runBankTransactions(NDBT_Context* ctx, NDBT_Step* step){
+ int wait = 0; // Max ms between each transaction
+ int yield = 1; // Loops before bank returns
+
+ ctx->incProperty("ThreadCount");
+ while (!ctx->isTestStopped())
+ {
+ Bank bank;
+ while(!ctx->isTestStopped() && ctx->getProperty("SR") <= 1)
+ if(bank.performTransactions(0, 1) == NDBT_FAILED)
+ break;
+
+ ndbout_c("runBankTransactions is stopped");
+ ctx->incProperty("ThreadStopped");
+ if(ctx->getPropertyWait("SR", (Uint32)0))
+ break;
+ }
+ return NDBT_OK;
+}
+
+int runBankGL(NDBT_Context* ctx, NDBT_Step* step){
+ int yield = 1; // Loops before bank returns
+ int result = NDBT_OK;
+
+ ctx->incProperty("ThreadCount");
+ while (ctx->isTestStopped() == false)
+ {
+ Bank bank;
+ while(!ctx->isTestStopped() && ctx->getProperty("SR") <= 1)
+ if (bank.performMakeGLs(yield) != NDBT_OK)
+ {
+ if(ctx->getProperty("SR") != 0)
+ break;
+ ndbout << "bank.performMakeGLs FAILED" << endl;
+ return NDBT_FAILED;
+ }
+
+ ndbout_c("runBankGL is stopped");
+ ctx->incProperty("ThreadStopped");
+ if(ctx->getPropertyWait("SR", (Uint32)0))
+ break;
+ }
+ return NDBT_OK;
+}
+
+int runBankSum(NDBT_Context* ctx, NDBT_Step* step){
+ Bank bank;
+ int wait = 2000; // Max ms between each sum of accounts
+ int yield = 1; // Loops before bank returns
+ int result = NDBT_OK;
+
+ while (ctx->isTestStopped() == false) {
+ if (bank.performSumAccounts(wait, yield) != NDBT_OK){
+ ndbout << "bank.performSumAccounts FAILED" << endl;
+ result = NDBT_FAILED;
+ }
+ }
+ return result ;
+}
+
+#define CHECK(b) if (!(b)) { \
+ g_err << "ERR: "<< step->getName() \
+ << " failed on line " << __LINE__ << endl; \
+ result = NDBT_FAILED; \
+ continue; }
+
+int runSR(NDBT_Context* ctx, NDBT_Step* step)
+{
+ int result = NDBT_OK;
+ int runtime = ctx->getNumLoops();
+ int sleeptime = ctx->getNumRecords();
+ NdbRestarter restarter;
+ bool abort = true;
+ int timeout = 180;
+
+ Uint32 now;
+ const Uint32 stop = time(0)+ runtime;
+ while(!ctx->isTestStopped() && ((now= time(0)) < stop) && result == NDBT_OK)
+ {
+ ndbout << " -- Sleep " << sleeptime << "s " << endl;
+ NdbSleep_SecSleep(sleeptime);
+ ndbout << " -- Shutting down " << endl;
+ ctx->setProperty("SR", 1);
+ CHECK(restarter.restartAll(false, true, abort) == 0);
+ ctx->setProperty("SR", 2);
+ CHECK(restarter.waitClusterNoStart(timeout) == 0);
+
+ Uint32 cnt = ctx->getProperty("ThreadCount");
+ Uint32 curr= ctx->getProperty("ThreadStopped");
+ while(curr != cnt)
+ {
+ ndbout_c("%d %d", curr, cnt);
+ NdbSleep_MilliSleep(100);
+ curr= ctx->getProperty("ThreadStopped");
+ }
+
+ ctx->setProperty("ThreadStopped", (Uint32)0);
+ CHECK(restarter.startAll() == 0);
+ CHECK(restarter.waitClusterStarted(timeout) == 0);
+
+ ndbout << " -- Validating starts " << endl;
+ {
+ int wait = 0;
+ int yield = 1;
+ Bank bank;
+ if (bank.performSumAccounts(wait, yield) != 0)
+ {
+ ndbout << "bank.performSumAccounts FAILED" << endl;
+ return NDBT_FAILED;
+ }
+
+ if (bank.performValidateAllGLs() != 0)
+ {
+ ndbout << "bank.performValidateAllGLs FAILED" << endl;
+ return NDBT_FAILED;
+ }
+ }
+
+ ndbout << " -- Validating complete " << endl;
+ ctx->setProperty("SR", (Uint32)0);
+ ctx->broadcast();
+ }
+ ctx->stopTest();
+ return NDBT_OK;
+}
+
+int runDropBank(NDBT_Context* ctx, NDBT_Step* step){
+ Bank bank;
+ if (bank.dropBank() != NDBT_OK)
+ return NDBT_FAILED;
+ return NDBT_OK;
+}
+
+
+NDBT_TESTSUITE(testSRBank);
+TESTCASE("Graceful",
+ " Test that a consistent bank is restored after graceful shutdown\n"
+ "1. Create bank\n"
+ "2. Start bank and let it run\n"
+ "3. Restart ndb and verify consistency\n"
+ "4. Drop bank\n")
+{
+ INITIALIZER(runCreateBank);
+ STEP(runBankTimer);
+ STEP(runBankTransactions);
+ STEP(runBankTransactions);
+ STEP(runBankTransactions);
+ STEP(runBankTransactions);
+ STEP(runBankTransactions);
+ STEP(runBankTransactions);
+ STEP(runBankTransactions);
+ STEP(runBankTransactions);
+ STEP(runBankTransactions);
+ STEP(runBankTransactions);
+ STEP(runBankGL);
+ STEP(runSR);
+}
+TESTCASE("Abort",
+ " Test that a consistent bank is restored after graceful shutdown\n"
+ "1. Create bank\n"
+ "2. Start bank and let it run\n"
+ "3. Restart ndb and verify consistency\n"
+ "4. Drop bank\n")
+{
+ INITIALIZER(runCreateBank);
+ STEP(runBankTimer);
+ STEP(runBankTransactions);
+ STEP(runBankTransactions);
+ STEP(runBankTransactions);
+ STEP(runBankTransactions);
+ STEP(runBankTransactions);
+ STEP(runBankTransactions);
+ STEP(runBankTransactions);
+ STEP(runBankTransactions);
+ STEP(runBankTransactions);
+ STEP(runBankTransactions);
+ STEP(runBankGL);
+ STEP(runSR);
+ FINALIZER(runDropBank);
+}
+NDBT_TESTSUITE_END(testSRBank);
+
+int main(int argc, const char** argv){
+ ndb_init();
+ return testSRBank.execute(argc, argv);
+}
+
+
diff --git a/ndb/test/src/HugoCalculator.cpp b/ndb/test/src/HugoCalculator.cpp
index 62c35c54a7a..86ff76831d7 100644
--- a/ndb/test/src/HugoCalculator.cpp
+++ b/ndb/test/src/HugoCalculator.cpp
@@ -51,7 +51,7 @@ HugoCalculator::HugoCalculator(const NdbDictionary::Table& tab) : m_tab(tab) {
#endif
// Check that idCol is not conflicting with updatesCol
assert(m_idCol != m_updatesCol && m_idCol != -1 && m_updatesCol != -1);
-};
+}
Int32
HugoCalculator::calcValue(int record,
@@ -73,7 +73,7 @@ HugoCalculator::calcValue(int record,
else
val = record + attrib + updates;
return val;
-};
+}
#if 0
HugoCalculator::U_Int32 calcValue(int record, int attrib, int updates) const;
HugoCalculator::U_Int64 calcValue(int record, int attrib, int updates) const;
@@ -123,7 +123,7 @@ HugoCalculator::calcValue(int record,
buf[len] = 0;
}
return buf;
-};
+}
int
HugoCalculator::verifyRowValues(NDBT_ResultRow* const pRow) const{
diff --git a/ndb/test/src/NDBT_Test.cpp b/ndb/test/src/NDBT_Test.cpp
index 600a5443f40..42bae193b35 100644
--- a/ndb/test/src/NDBT_Test.cpp
+++ b/ndb/test/src/NDBT_Test.cpp
@@ -145,6 +145,15 @@ NDBT_Context::decProperty(const char * name){
NdbCondition_Broadcast(propertyCondPtr);
NdbMutex_Unlock(propertyMutexPtr);
}
+void
+NDBT_Context::incProperty(const char * name){
+ NdbMutex_Lock(propertyMutexPtr);
+ Uint32 val = 0;
+ props.get(name, &val);
+ props.put(name, (val + 1), true);
+ NdbCondition_Broadcast(propertyCondPtr);
+ NdbMutex_Unlock(propertyMutexPtr);
+}
void NDBT_Context::setProperty(const char* _name, const char* _val){
NdbMutex_Lock(propertyMutexPtr);
@@ -615,7 +624,7 @@ int NDBT_TestCase::execute(NDBT_Context* ctx){
<< endl;
}
return res;
-};
+}
void NDBT_TestCase::startTimer(NDBT_Context* ctx){
diff --git a/ndb/test/src/NdbBackup.cpp b/ndb/test/src/NdbBackup.cpp
index 1e56db83c11..9f65fe6b3bc 100644
--- a/ndb/test/src/NdbBackup.cpp
+++ b/ndb/test/src/NdbBackup.cpp
@@ -345,7 +345,7 @@ NdbBackup::NF(NdbRestarter& _restarter, int *NFDuringBackup_codes, const int sz,
}
return NDBT_OK;
-};
+}
int
FailS_codes[] = {
diff --git a/ndb/test/src/NdbRestarts.cpp b/ndb/test/src/NdbRestarts.cpp
index 607e48c4126..c0f31af84ce 100644
--- a/ndb/test/src/NdbRestarts.cpp
+++ b/ndb/test/src/NdbRestarts.cpp
@@ -213,7 +213,7 @@ NdbRestarts::NdbRestart::NdbRestart(const char* _name,
m_restartFunc = _func;
m_numRequiredNodes = _requiredNodes;
// m_arg1 = arg1;
-};
+}
int NdbRestarts::getNumRestarts(){
@@ -367,7 +367,7 @@ int restartRandomNodeGraceful(NdbRestarter& _restarter,
"Could not restart node "<<nodeId);
return NDBT_OK;
-};
+}
int restartRandomNodeAbort(NdbRestarter& _restarter,
const NdbRestarts::NdbRestart* _restart){
@@ -382,7 +382,7 @@ int restartRandomNodeAbort(NdbRestarter& _restarter,
"Could not restart node "<<nodeId);
return NDBT_OK;
-};
+}
int restartRandomNodeError(NdbRestarter& _restarter,
const NdbRestarts::NdbRestart* _restart){
@@ -397,7 +397,7 @@ int restartRandomNodeError(NdbRestarter& _restarter,
"Could not restart node "<<nodeId);
return NDBT_OK;
-};
+}
int restartMasterNodeError(NdbRestarter& _restarter,
const NdbRestarts::NdbRestart* _restart){
@@ -410,7 +410,7 @@ int restartMasterNodeError(NdbRestarter& _restarter,
"Could not restart node "<<nodeId);
return NDBT_OK;
-};
+}
int restartRandomNodeInitial(NdbRestarter& _restarter,
const NdbRestarts::NdbRestart* _restart){
@@ -425,7 +425,7 @@ int restartRandomNodeInitial(NdbRestarter& _restarter,
"Could not restart node "<<nodeId);
return NDBT_OK;
-};
+}
int twoNodeFailure(NdbRestarter& _restarter,
const NdbRestarts::NdbRestart* _restart){
@@ -453,7 +453,7 @@ int twoNodeFailure(NdbRestarter& _restarter,
"Could not restart node "<< nodeId);
return NDBT_OK;
-};
+}
int twoMasterNodeFailure(NdbRestarter& _restarter,
const NdbRestarts::NdbRestart* _restart){
@@ -478,7 +478,7 @@ int twoMasterNodeFailure(NdbRestarter& _restarter,
"Could not restart node "<< nodeId);
return NDBT_OK;
-};
+}
int get50PercentOfNodes(NdbRestarter& restarter,
int * _nodes){
@@ -519,7 +519,7 @@ int fiftyPercentFail(NdbRestarter& _restarter,
"Could not start all nodes");
return NDBT_OK;
-};
+}
int restartAllNodesGracfeul(NdbRestarter& _restarter,
@@ -533,7 +533,7 @@ int restartAllNodesGracfeul(NdbRestarter& _restarter,
return NDBT_OK;
-};
+}
int restartAllNodesAbort(NdbRestarter& _restarter,
const NdbRestarts::NdbRestart* _restart){
@@ -545,7 +545,7 @@ int restartAllNodesAbort(NdbRestarter& _restarter,
"Could not restart all nodes");
return NDBT_OK;
-};
+}
int restartAllNodesError9999(NdbRestarter& _restarter,
const NdbRestarts::NdbRestart* _restart){
@@ -557,7 +557,7 @@ int restartAllNodesError9999(NdbRestarter& _restarter,
"Could not restart all nodes ");
return NDBT_OK;
-};
+}
int fiftyPercentStopAndWait(NdbRestarter& _restarter,
const NdbRestarts::NdbRestart* _restart){
@@ -590,7 +590,7 @@ int fiftyPercentStopAndWait(NdbRestarter& _restarter,
g_info << _restart->m_name << endl;
return NDBT_OK;
-};
+}
int
NFDuringNR_codes[] = {
@@ -713,7 +713,7 @@ int restartNFDuringNR(NdbRestarter& _restarter,
}
return NDBT_OK;
-};
+}
int
NRDuringLCP_Master_codes[] = {
@@ -864,7 +864,7 @@ int stopOnError(NdbRestarter& _restarter,
} while (false);
return NDBT_OK;
-};
+}
int getRandomNodeId(NdbRestarter& _restarter) {
myRandom48Init(NdbTick_CurrentMillisecond());
diff --git a/ndb/test/src/UtilTransactions.cpp b/ndb/test/src/UtilTransactions.cpp
index 869f7fc76cb..92073143d34 100644
--- a/ndb/test/src/UtilTransactions.cpp
+++ b/ndb/test/src/UtilTransactions.cpp
@@ -766,19 +766,29 @@ UtilTransactions::selectCount(Ndb* pNdb,
int check;
NdbScanOperation *pOp;
- if(!pTrans)
- pTrans = pNdb->startTransaction();
while (true){
-
if (retryAttempt >= retryMax){
g_info << "ERROR: has retried this operation " << retryAttempt
<< " times, failing!" << endl;
return NDBT_FAILED;
}
+ if(!pTrans)
+ pTrans = pNdb->startTransaction();
+
+ if(!pTrans)
+ {
+ const NdbError err = pNdb->getNdbError();
+
+ if (err.status == NdbError::TemporaryError)
+ continue;
+ return NDBT_FAILED;
+ }
+
pOp = pTrans->getNdbScanOperation(tab.getName());
if (pOp == NULL) {
ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans);
+ pTrans = 0;
return NDBT_FAILED;
}
@@ -786,6 +796,7 @@ UtilTransactions::selectCount(Ndb* pNdb,
if( rs == 0) {
ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans);
+ pTrans = 0;
return NDBT_FAILED;
}
@@ -799,6 +810,7 @@ UtilTransactions::selectCount(Ndb* pNdb,
if( check == -1 ) {
ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans);
+ pTrans = 0;
return NDBT_FAILED;
}
}
@@ -808,6 +820,7 @@ UtilTransactions::selectCount(Ndb* pNdb,
if( check == -1 ) {
ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans);
+ pTrans = 0;
return NDBT_FAILED;
}
@@ -823,16 +836,19 @@ UtilTransactions::selectCount(Ndb* pNdb,
if (err.status == NdbError::TemporaryError){
pNdb->closeTransaction(pTrans);
+ pTrans = 0;
NdbSleep_MilliSleep(50);
retryAttempt++;
continue;
}
ERR(err);
pNdb->closeTransaction(pTrans);
+ pTrans = 0;
return NDBT_FAILED;
}
pNdb->closeTransaction(pTrans);
+ pTrans = 0;
if (count_rows != NULL){
*count_rows = rows;
diff --git a/ndb/tools/restore/Restore.cpp b/ndb/tools/restore/Restore.cpp
index 26bc08c63a9..79df49c6f26 100644
--- a/ndb/tools/restore/Restore.cpp
+++ b/ndb/tools/restore/Restore.cpp
@@ -869,7 +869,7 @@ operator<<(NdbOut& ndbout, const AttributeS& attr){
return ndbout;
}
- NdbRecAttr tmprec;
+ NdbRecAttr tmprec(0);
tmprec.setup(desc.m_column, (char *)data.void_value);
ndbout << tmprec;