diff options
55 files changed, 1024 insertions, 883 deletions
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 52165ee5b7a..339b31543b8 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -31,6 +31,7 @@ dlenev@brandersnatch.localdomain dlenev@build.mysql.com dlenev@jabberwock.localdomain dlenev@mysql.com +ejonore@mc03.ndb.mysql.com gerberb@ou800.zenez.com gluh@gluh.(none) gluh@gluh.mysql.r18.ru @@ -71,6 +72,7 @@ jcole@mugatu.jcole.us jcole@mugatu.spaceapes.com jcole@sarvik.tfr.cafe.ee jcole@tetra.spaceapes.com +joreland@mysql.com jorge@linux.jorge.mysql.com kaj@work.mysql.com konstantin@mysql.com diff --git a/ndb/config/Defs.LINUX.x86.GCC.mk b/ndb/config/Defs.LINUX.x86.GCC.mk index a1cc3c52a7e..e1bed3a8ca9 100644 --- a/ndb/config/Defs.LINUX.x86.GCC.mk +++ b/ndb/config/Defs.LINUX.x86.GCC.mk @@ -3,12 +3,12 @@ # Defines SHELL := /bin/sh -C++ := g++$(GCC_VERSION) +C++ := gcc$(GCC_VERSION) CC := gcc$(GCC_VERSION) AR_RCS := $(PURE) ar rcs SO := gcc$(GCC_VERSION) -shared -lpthread -o -MAKEDEPEND := g++$(GCC_VERSION) -M +MAKEDEPEND := gcc$(GCC_VERSION) -M PIC := -fPIC RPCGENFLAGS := -M -C -N @@ -53,4 +53,4 @@ LINK.cc = $(PURE) $(CC) $(CCFLAGS) $(LDFLAGS) LINK.c = $(PURE) $(CC) $(CFLAGS) $(LDFLAGS) -LDFLAGS_LAST = -lpthread -lrt -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic +LDFLAGS_LAST = -lpthread -lrt diff --git a/ndb/examples/ndbapi_async_example/Makefile b/ndb/examples/ndbapi_async_example/Makefile index 7910a4a1d12..f30398f9587 100644 --- a/ndb/examples/ndbapi_async_example/Makefile +++ b/ndb/examples/ndbapi_async_example/Makefile @@ -1,4 +1,4 @@ --include ../../Defs.mk +-include .defs.mk #NDB_OS = OS_YOU_ARE_RUNNING_ON #NDB_OS = LINUX #You need to set the NDB_OS variable here (LINUX, SOLARIS, MACOSX) diff --git a/ndb/examples/ndbapi_async_example/ndbapi_async.cpp b/ndb/examples/ndbapi_async_example/ndbapi_async.cpp index 078ac0c5cbf..685c853c5d5 100644 --- a/ndb/examples/ndbapi_async_example/ndbapi_async.cpp +++ b/ndb/examples/ndbapi_async_example/ndbapi_async.cpp @@ -349,7 +349,7 @@ int populate(Ndb * myNdb, int data, async_callback_t * cbData) NdbOperation* myNdbOperation; // For operations async_callback_t * cb; - int retries; + int retries = 0; int current = 0; for(int i=0; i<1024; i++) { diff --git a/ndb/examples/ndbapi_scan_example/Makefile b/ndb/examples/ndbapi_scan_example/Makefile index 6e53317f8bf..d7f08af4647 100644 --- a/ndb/examples/ndbapi_scan_example/Makefile +++ b/ndb/examples/ndbapi_scan_example/Makefile @@ -1,4 +1,4 @@ --include ../../Defs.mk +-include .defs.mk #NDB_OS = OS_YOU_ARE_RUNNING_ON #You need to set the NDB_OS variable here (LINUX, SOLARIS, MACOSX) #NDB_OS = LINUX diff --git a/ndb/include/debugger/SignalLoggerManager.hpp b/ndb/include/debugger/SignalLoggerManager.hpp index cf777505399..3d89b399f3b 100644 --- a/ndb/include/debugger/SignalLoggerManager.hpp +++ b/ndb/include/debugger/SignalLoggerManager.hpp @@ -111,6 +111,9 @@ public: void setTrace(unsigned long trace); unsigned long getTrace() const; + void setOwnNodeId(int nodeId); + void setLogDistributed(bool val); + /** * Print header */ @@ -149,6 +152,9 @@ public: static void printDataWord(FILE * output, Uint32 & pos, const Uint32 data); private: + bool m_logDistributed; + int m_ownNodeId; + FILE * outputStream; int log(int cmd, BlockNumber bno, LogMode logMode); diff --git a/ndb/include/kernel/signaldata/ScanFrag.hpp b/ndb/include/kernel/signaldata/ScanFrag.hpp index 65ab6f7e411..2b37e544e1f 100644 --- a/ndb/include/kernel/signaldata/ScanFrag.hpp +++ b/ndb/include/kernel/signaldata/ScanFrag.hpp @@ -54,6 +54,7 @@ public: static Uint32 getReadCommittedFlag(const Uint32 & requestInfo); static Uint32 getRangeScanFlag(const Uint32 & requestInfo); static Uint32 getAttrLen(const Uint32 & requestInfo); + static Uint32 getScanPrio(const Uint32 & requestInfo); static void setConcurrency(Uint32 & requestInfo, Uint32 concurrency); static void setLockMode(Uint32 & requestInfo, Uint32 lockMode); @@ -62,6 +63,7 @@ public: static void setReadCommittedFlag(Uint32 & requestInfo, Uint32 readCommitted); static void setRangeScanFlag(Uint32 & requestInfo, Uint32 rangeScan); static void setAttrLen(Uint32 & requestInfo, Uint32 attrLen); + static void setScanPrio(Uint32& requestInfo, Uint32 prio); }; class KeyInfo20 { @@ -192,10 +194,11 @@ public: * k = Keyinfo - 1 Bit 8 * r = read committed - 1 Bit 9 * x = range scan - 1 Bit 6 + * p = Scan prio - 4 Bits (12-15) -> max 15 * * 1111111111222222222233 * 01234567890123456789012345678901 - * ccccclxhkr aaaaaaaaaaaaaaaa + * ccccclxhkr ppppaaaaaaaaaaaaaaaa */ #define SF_CONCURRENCY_SHIFT (0) #define SF_CONCURRENCY_MASK (31) @@ -211,6 +214,9 @@ public: #define SF_ATTR_LEN_SHIFT (16) #define SF_ATTR_LEN_MASK (65535) +#define SF_PRIO_SHIFT 12 +#define SF_PRIO_MASK 15 + inline Uint32 ScanFragReq::getConcurrency(const Uint32 & requestInfo){ @@ -237,14 +243,14 @@ ScanFragReq::getKeyinfoFlag(const Uint32 & requestInfo){ inline Uint32 -ScanFragReq::getReadCommittedFlag(const Uint32 & requestInfo){ - return (requestInfo >> SF_READ_COMMITTED_SHIFT) & 1; +ScanFragReq::getRangeScanFlag(const Uint32 & requestInfo){ + return (requestInfo >> SF_RANGE_SCAN_SHIFT) & 1; } inline Uint32 -ScanFragReq::getRangeScanFlag(const Uint32 & requestInfo){ - return (requestInfo >> SF_RANGE_SCAN_SHIFT) & 1; +ScanFragReq::getReadCommittedFlag(const Uint32 & requestInfo){ + return (requestInfo >> SF_READ_COMMITTED_SHIFT) & 1; } inline @@ -254,6 +260,19 @@ ScanFragReq::getAttrLen(const Uint32 & requestInfo){ } inline +Uint32 +ScanFragReq::getScanPrio(const Uint32 & requestInfo){ + return (requestInfo >> SF_PRIO_SHIFT) & SF_PRIO_MASK; +} + +inline +void +ScanFragReq::setScanPrio(UintR & requestInfo, UintR val){ + ASSERT_MAX(val, SF_PRIO_MASK, "ScanFragReq::setScanPrio"); + requestInfo |= (val << SF_PRIO_SHIFT); +} + +inline void ScanFragReq::setConcurrency(UintR & requestInfo, UintR val){ ASSERT_MAX(val, SF_CONCURRENCY_MASK, "ScanFragReq::setConcurrency"); diff --git a/ndb/include/ndb_version.h b/ndb/include/ndb_version.h index 4fb6ec18fce..958dd339f74 100644 --- a/ndb/include/ndb_version.h +++ b/ndb/include/ndb_version.h @@ -29,8 +29,8 @@ */ #define NDB_VERSION_MAJOR 3 -#define NDB_VERSION_MINOR 4 -#define NDB_VERSION_BUILD 5 +#define NDB_VERSION_MINOR 5 +#define NDB_VERSION_BUILD 0 #define NDB_VERSION_STATUS "alpha" #define NDB_VERSION_D MAKE_VERSION(NDB_VERSION_MAJOR, NDB_VERSION_MINOR, NDB_VERSION_BUILD) diff --git a/ndb/include/ndbapi/NdbScanOperation.hpp b/ndb/include/ndbapi/NdbScanOperation.hpp index 2a27d8b34a1..e041c79d96f 100644 --- a/ndb/include/ndbapi/NdbScanOperation.hpp +++ b/ndb/include/ndbapi/NdbScanOperation.hpp @@ -149,7 +149,7 @@ public: char* anAttrName; Uint32 anAttrId; }; - typedef struct String { + struct String { char* aStringValue; Uint32 len; }; diff --git a/ndb/include/util/SocketServer.hpp b/ndb/include/util/SocketServer.hpp index f1ce5182183..334fa575e47 100644 --- a/ndb/include/util/SocketServer.hpp +++ b/ndb/include/util/SocketServer.hpp @@ -62,8 +62,7 @@ public: * To manage threads self, just return NULL */ virtual Session * newSession(NDB_SOCKET_TYPE theSock) = 0; - - virtual void stopSessions() {} + virtual void stopSessions(){} }; /** diff --git a/ndb/src/common/debugger/SignalLoggerManager.cpp b/ndb/src/common/debugger/SignalLoggerManager.cpp index e51edbba169..ae6edd5ed71 100644 --- a/ndb/src/common/debugger/SignalLoggerManager.cpp +++ b/ndb/src/common/debugger/SignalLoggerManager.cpp @@ -31,6 +31,8 @@ SignalLoggerManager::SignalLoggerManager() logModes[i] = 0; } outputStream = 0; + m_ownNodeId = 0; + m_logDistributed = false; } SignalLoggerManager::~SignalLoggerManager() @@ -78,7 +80,17 @@ SignalLoggerManager::getTrace() const { return traceId; } + +void +SignalLoggerManager::setOwnNodeId(int nodeId){ + m_ownNodeId = nodeId; +} +void +SignalLoggerManager::setLogDistributed(bool val){ + m_logDistributed = val; +} + int getParameter(char *blocks[NO_OF_BLOCKS], const char * par, const char * line) { @@ -236,10 +248,12 @@ SignalLoggerManager::executeSignal(const SignalHeader& sh, Uint8 prio, Uint32 trace = sh.theTrace; //Uint32 senderBlockNo = refToBlock(sh.theSendersBlockRef); Uint32 receiverBlockNo = sh.theReceiversBlockNumber; + Uint32 senderNode = refToNode(sh.theSendersBlockRef); if(outputStream != 0 && (traceId == 0 || traceId == trace) && - logMatch(receiverBlockNo, LogIn)){ + (logMatch(receiverBlockNo, LogOut) || + (m_logDistributed && m_ownNodeId != senderNode))){ #ifdef VM_TRACE_TIME fprintf(outputStream, "---- Received - Signal - %d ----\n", time(0)); #else @@ -261,10 +275,12 @@ SignalLoggerManager::executeSignal(const SignalHeader& sh, Uint8 prio, Uint32 trace = sh.theTrace; //Uint32 senderBlockNo = refToBlock(sh.theSendersBlockRef); Uint32 receiverBlockNo = sh.theReceiversBlockNumber; + Uint32 senderNode = refToNode(sh.theSendersBlockRef); if(outputStream != 0 && (traceId == 0 || traceId == trace) && - logMatch(receiverBlockNo, LogIn)){ + (logMatch(receiverBlockNo, LogOut) || + (m_logDistributed && m_ownNodeId != senderNode))){ #ifdef VM_TRACE_TIME fprintf(outputStream, "---- Received - Signal - %d ----\n", time(0)); #else @@ -293,7 +309,8 @@ SignalLoggerManager::sendSignal(const SignalHeader& sh, if(outputStream != 0 && (traceId == 0 || traceId == trace) && - logMatch(senderBlockNo, LogOut)){ + (logMatch(senderBlockNo, LogOut) || + (m_logDistributed && m_ownNodeId != node))){ #ifdef VM_TRACE_TIME fprintf(outputStream, "---- Send ----- Signal - %d ----\n", time(0)); #else @@ -321,7 +338,8 @@ SignalLoggerManager::sendSignal(const SignalHeader& sh, Uint8 prio, if(outputStream != 0 && (traceId == 0 || traceId == trace) && - logMatch(senderBlockNo, LogOut)){ + (logMatch(senderBlockNo, LogOut) || + (m_logDistributed && m_ownNodeId != node))){ #ifdef VM_TRACE_TIME fprintf(outputStream, "---- Send ----- Signal - %d ----\n", time(0)); #else diff --git a/ndb/src/common/logger/ConsoleLogHandler.cpp b/ndb/src/common/logger/ConsoleLogHandler.cpp index 8f6a45fe5dd..94367d2fc45 100644 --- a/ndb/src/common/logger/ConsoleLogHandler.cpp +++ b/ndb/src/common/logger/ConsoleLogHandler.cpp @@ -58,7 +58,7 @@ ConsoleLogHandler::writeMessage(const char* pMsg) void ConsoleLogHandler::writeFooter() { - ndbout << getDefaultFooter(); + ndbout << getDefaultFooter() << flush; } diff --git a/ndb/src/common/portlib/unix/NdbMem.c b/ndb/src/common/portlib/unix/NdbMem.c index a18cf30cc8a..3b47494967f 100644 --- a/ndb/src/common/portlib/unix/NdbMem.c +++ b/ndb/src/common/portlib/unix/NdbMem.c @@ -62,7 +62,8 @@ int NdbMem_MemLockAll(){ #if defined NDB_MACOSX return 0; #else - return mlockall(MCL_CURRENT | MCL_FUTURE); + //return mlockall(MCL_CURRENT | MCL_FUTURE); + return mlockall(MCL_CURRENT); #endif } diff --git a/ndb/src/common/util/Makefile b/ndb/src/common/util/Makefile index e400bb12d29..b3e33704266 100644 --- a/ndb/src/common/util/Makefile +++ b/ndb/src/common/util/Makefile @@ -8,7 +8,7 @@ ARCHIVE_TARGET := general SOURCES = File.cpp md5_hash.cpp Properties.cpp socket_io.cpp \ SimpleProperties.cpp Parser.cpp InputStream.cpp SocketServer.cpp \ OutputStream.cpp NdbOut.cpp BaseString.cpp Base64.cpp \ - NdbSqlUtil.cpp + NdbSqlUtil.cpp new.cpp SOURCES.c = uucode.c random.c getarg.c version.c diff --git a/ndb/src/common/util/new.cpp b/ndb/src/common/util/new.cpp new file mode 100644 index 00000000000..aff7a0e3986 --- /dev/null +++ b/ndb/src/common/util/new.cpp @@ -0,0 +1,46 @@ + +#include <malloc.h> +#include <stdlib.h> + +extern "C" { + void (* ndb_new_handler)() = 0; +} + +void *operator new (size_t sz) +{ + void * p = malloc (sz ? sz : 1); + if(p) + return p; + if(ndb_new_handler) + (* ndb_new_handler)(); + abort(); +} + +void *operator new[] (size_t sz) +{ + void * p = (void *) malloc (sz ? sz : 1); + if(p) + return p; + if(ndb_new_handler) + (* ndb_new_handler)(); + abort(); +} + +void operator delete (void *ptr) +{ + if (ptr) + free(ptr); +} + +void operator delete[] (void *ptr) throw () +{ + if (ptr) + free(ptr); +} + +/** + * GCC linking problem... + */ +#if ( __GNUC__ == 3 ) +extern "C" { int __cxa_pure_virtual() {return 0;} } +#endif diff --git a/ndb/src/common/util/version.c b/ndb/src/common/util/version.c index d220a06850a..2ff10f51932 100644 --- a/ndb/src/common/util/version.c +++ b/ndb/src/common/util/version.c @@ -65,7 +65,6 @@ struct NdbUpGradeCompatible { #ifndef TEST_VERSION struct NdbUpGradeCompatible ndbCompatibleTable_full[] = { - { NDB_VERSION_D , MAKE_VERSION(NDB_VERSION_MAJOR,NDB_VERSION_MINOR,2), UG_Range }, { 0, 0, UG_Null } }; diff --git a/ndb/src/cw/cpcd/Process.cpp b/ndb/src/cw/cpcd/Process.cpp index 01a63a5c653..a54c6b8e475 100644 --- a/ndb/src/cw/cpcd/Process.cpp +++ b/ndb/src/cw/cpcd/Process.cpp @@ -361,8 +361,8 @@ CPCD::Process::start() { switch(pid = fork()) { case 0: /* Child */ + writePid(getpid()); if(runas(m_runas.c_str()) == 0){ - writePid(getpid()); do_exec(); } _exit(1); @@ -385,15 +385,14 @@ CPCD::Process::start() { */ switch(fork()) { case 0: /* Child */ - if(runas(m_runas.c_str()) != 0){ - writePid(-1); - _exit(1); - } signal(SIGCHLD, SIG_IGN); pid_t pid; switch(pid = fork()) { case 0: /* Child */ writePid(getpid()); + if(runas(m_runas.c_str()) != 0){ + _exit(1); + } setsid(); do_exec(); _exit(1); diff --git a/ndb/src/kernel/blocks/ERROR_codes.txt b/ndb/src/kernel/blocks/ERROR_codes.txt index 595afe9650e..331333c101e 100644 --- a/ndb/src/kernel/blocks/ERROR_codes.txt +++ b/ndb/src/kernel/blocks/ERROR_codes.txt @@ -3,7 +3,7 @@ Next NDBCNTR 1000 Next NDBFS 2000 Next DBACC 3001 Next DBTUP 4007 -Next DBLQH 5031 +Next DBLQH 5036 Next DBDICT 6003 Next DBDIH 7173 Next DBTC 8035 @@ -187,6 +187,10 @@ Delay execution of ABORTREQ signal 2 seconds to generate time-out. 5032: lqhKeyRef, ZTEMPORARY_REDO_LOG_FAILURE 5033: lqhKeyRef, ZTAIL_PROBLEM_IN_LOG_ERROR +5034: Don't pop scan queue + +5035: Delay ACC_CONTOPCONT + ERROR CODES FOR TESTING TIME-OUT HANDLING IN DBTC ------------------------------------------------- 8040: @@ -262,6 +266,7 @@ ABORT OF TCKEYREQ CMVMI ----- 9000 Set RestartOnErrorInsert to restart -n +9998 Enter endless loop (trigger watchdog) 9999 Crash system immediatly Test Crashes in handling node restarts diff --git a/ndb/src/kernel/blocks/backup/restore/Restore.cpp b/ndb/src/kernel/blocks/backup/restore/Restore.cpp index f91651d9720..50eb0df7c56 100644 --- a/ndb/src/kernel/blocks/backup/restore/Restore.cpp +++ b/ndb/src/kernel/blocks/backup/restore/Restore.cpp @@ -938,6 +938,7 @@ void TableS::createAttr(const char* name, ndbout_c("Restore: Failed to allocate memory"); abort(); } + d->m_table = this; allAttributesDesc.push_back(d); if(desc.key != NoKey /* && not variable */){ diff --git a/ndb/src/kernel/blocks/backup/restore/Restore.hpp b/ndb/src/kernel/blocks/backup/restore/Restore.hpp index f214bcb1380..f1a73bb18b9 100644 --- a/ndb/src/kernel/blocks/backup/restore/Restore.hpp +++ b/ndb/src/kernel/blocks/backup/restore/Restore.hpp @@ -89,9 +89,10 @@ struct AttributeDesc { public: AttributeDesc() { - name[0] = 0; + name[0] = 0; } + const TableS * m_table; Uint32 getSizeInWords() const { return (size * arraySize + 31)/ 32;} }; // AttributeDesc diff --git a/ndb/src/kernel/blocks/backup/restore/main.cpp b/ndb/src/kernel/blocks/backup/restore/main.cpp index 52857aa2c42..b38f6ab751b 100644 --- a/ndb/src/kernel/blocks/backup/restore/main.cpp +++ b/ndb/src/kernel/blocks/backup/restore/main.cpp @@ -20,6 +20,7 @@ #include <NdbSleep.h> #include <Vector.hpp> #include <ndb_limits.h> +#include <NdbTCP.h> #ifdef USE_MYSQL #include <mysql.h> #endif @@ -607,15 +608,20 @@ operator<<(NdbOut& ndbout, const AttributeS& attr){ } // switch size break; case (String): - if (desc.size == 8) - { - ndbout << data.string_value; - j = desc.arraySize; + if (desc.size == 8){ + NdbDictionary::Column::Type type = desc.m_table->m_dictTable->getColumn(desc.attrId)->getType(); + if(type == NdbDictionary::Column::Varchar){ + short len = ntohs(data.u_int16_value[0]); + ndbout.print("%.*s", len, (data.string_value+2)); + } else { + ndbout << data.string_value; + } } // if else { ndbout << "String sz != 8 - this is something wrong??" << endl; } + j = desc.arraySize; break; case (Float): // Not yet supported to print float @@ -642,7 +648,6 @@ operator<<(NdbOut& ndbout, const TupleS& tuple) { const AttributeS * attr = tuple[i]; debug << i << " " << attr->Desc->name; - ndbout << (* attr); if (i != (tuple.getNoOfAttributes() - 1)) @@ -795,7 +800,6 @@ static void restoreCallback(int result, // Result for transaction - bool BackupPrinter::table(const TableS & tab) { diff --git a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp index 2735cac0c8e..cd6198eff23 100644 --- a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp +++ b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp @@ -46,10 +46,11 @@ #include <TimeQueue.hpp> #include <new> +#include <NdbSleep.h> #include <SafeCounter.hpp> // Used here only to print event reports on stdout/console. -static EventLogger eventLogger; +EventLogger g_eventLogger; Cmvmi::Cmvmi(const Configuration & conf) : SimulatedBlock(CMVMI, conf) @@ -92,11 +93,6 @@ Cmvmi::Cmvmi(const Configuration & conf) : subscriberPool.setSize(5); - // Print to stdout/console - eventLogger.createConsoleHandler(); - eventLogger.setCategory("NDB"); - eventLogger.enable(Logger::LL_INFO, Logger::LL_ALERT); // Log INFO to ALERT - const ClusterConfiguration::ClusterData & clData = theConfig.clusterConfigurationData() ; @@ -130,6 +126,10 @@ void Cmvmi::execNDB_TAMPER(Signal* signal) if(ERROR_INSERTED(9999)){ CRASH_INSERTION(9999); } + + if(ERROR_INSERTED(9998)){ + while(true) NdbSleep_SecSleep(1); + } }//execNDB_TAMPER() void Cmvmi::execSET_LOGLEVELORD(Signal* signal) @@ -194,7 +194,7 @@ void Cmvmi::execEVENT_REP(Signal* signal) } // Print the event info - eventLogger.log(eventReport->getEventType(), signal->theData); + g_eventLogger.log(eventReport->getEventType(), signal->theData); }//execEVENT_REP() @@ -395,6 +395,15 @@ void Cmvmi::execSIZEALT_ACK(Signal* signal) sendSignal(numberToRef(blockNo, 0), GSN_SIZEALT_REP, signal,21, JBB); } else { jam(); + + if(theConfig.lockPagesInMainMemory()){ + int res = NdbMem_MemLockAll(); + if(res != 0){ + g_eventLogger.warning("Failed to memlock pages"); + warningEvent("Failed to memlock pages"); + } + } + sendSTTORRY(signal); } } @@ -404,7 +413,7 @@ void Cmvmi::execCM_INFOREQ(Signal* signal) int id = signal->theData[1]; const BlockReference userRef = signal->theData[0]; const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData(); + theConfig.clusterConfigurationData(); const int myNodeId = globalData.ownId; jamEntry(); @@ -1116,6 +1125,24 @@ public: }; #endif + +static int iii; + +static +int +recurse(char * buf, int loops, int arg){ + char * tmp = (char*)alloca(arg); + printf("tmp = %p\n", tmp); + for(iii = 0; iii<arg; iii += 1024){ + tmp[iii] = (iii % 23 + (arg & iii)); + } + + if(loops == 0) + return tmp[345]; + else + return tmp[arg/loops] + recurse(tmp, loops - 1, arg); +} + void Cmvmi::execDUMP_STATE_ORD(Signal* signal) { @@ -1141,7 +1168,18 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal) * Here I can dump CMVMI state if needed */ if(signal->theData[0] == 13){ - infoEvent("Cmvmi: signalCount = %d", signalCount); +#if 0 + int loop = 100; + int len = (10*1024*1024); + if(signal->getLength() > 1) + loop = signal->theData[1]; + if(signal->getLength() > 2) + len = signal->theData[2]; + + ndbout_c("recurse(%d loop, %dkb per recurse)", loop, len/1024); + int a = recurse(0, loop, len); + ndbout_c("after...%d", a); +#endif } DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0]; diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 9a72d9deb50..790c29737e9 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -2635,7 +2635,7 @@ void Dbdict::execINCL_NODEREQ(Signal* signal) c_noNodesFailed--; c_nodes.getPtr(nodePtr); - ndbrequire(nodePtr.p->nodeState = NodeRecord::NDB_NODE_DEAD); + ndbrequire(nodePtr.p->nodeState == NodeRecord::NDB_NODE_DEAD); nodePtr.p->nodeState = NodeRecord::NDB_NODE_ALIVE; signal->theData[0] = reference(); sendSignal(retRef, GSN_INCL_NODECONF, signal, 1, JBB); diff --git a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp index 6b85ca11b27..3d7980f0e73 100644 --- a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp +++ b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp @@ -20,6 +20,8 @@ #include <pc.hpp> #include <ndb_limits.h> #include <SimulatedBlock.hpp> +#include <DLList.hpp> +#include <DLFifoList.hpp> #include <DLHashTable.hpp> #include <NodeBitmask.hpp> @@ -505,6 +507,79 @@ public: }; // size 20 bytes typedef Ptr<Databuf> DatabufPtr; + struct ScanRecord { + enum ScanState { + SCAN_FREE = 0, + WAIT_STORED_PROC_COPY = 1, + WAIT_STORED_PROC_SCAN = 2, + WAIT_NEXT_SCAN_COPY = 3, + WAIT_NEXT_SCAN = 4, + WAIT_DELETE_STORED_PROC_ID_SCAN = 5, + WAIT_DELETE_STORED_PROC_ID_COPY = 6, + WAIT_ACC_COPY = 7, + WAIT_ACC_SCAN = 8, + WAIT_SCAN_KEYINFO = 9, + WAIT_SCAN_NEXTREQ = 10, + WAIT_COPY_KEYINFO = 11, + WAIT_CLOSE_SCAN = 12, + WAIT_CLOSE_COPY = 13, + WAIT_RELEASE_LOCK = 14, + WAIT_TUPKEY_COPY = 15, + WAIT_LQHKEY_COPY = 16, + IN_QUEUE = 17 + }; + enum ScanType { + ST_IDLE = 0, + SCAN = 1, + COPY = 2 + }; + UintR scanAccOpPtr[MAX_PARALLEL_OP_PER_SCAN]; + UintR scanApiOpPtr[MAX_PARALLEL_OP_PER_SCAN]; + UintR scanOpLength[MAX_PARALLEL_OP_PER_SCAN]; + UintR scanLocalref[2]; + UintR copyPtr; + union { + Uint32 nextPool; + Uint32 nextList; + }; + Uint32 prevList; + Uint32 nextHash; + Uint32 prevHash; + bool equal(const ScanRecord & key) const { + return scanNumber == key.scanNumber && fragPtrI == key.fragPtrI; + } + Uint32 hashValue() const { + return fragPtrI ^ scanNumber; + } + + UintR scanAccPtr; + UintR scanAiLength; + UintR scanCompletedOperations; + UintR scanConcurrentOperations; + UintR scanErrorCounter; + UintR scanLocalFragid; + UintR scanSchemaVersion; + Uint32 fragPtrI; + UintR scanSearchCondFalseCount; + UintR scanStoredProcId; + ScanState scanState; + UintR scanTcrec; + ScanType scanType; + BlockReference scanApiBlockref; + NodeId scanNodeId; + Uint8 scanCompletedStatus; + Uint8 scanFlag; + Uint8 scanLockHold; + Uint8 scanLockMode; + Uint8 readCommitted; + Uint8 rangeScan; + Uint8 scanNumber; + Uint8 scanReleaseCounter; + Uint8 scanTcWaiting; + Uint8 scanKeyinfoFlag; + }; // Size 272 bytes + typedef Ptr<ScanRecord> ScanRecordPtr; + struct Fragrecord { enum ExecSrStatus { IDLE = 0, @@ -627,7 +702,11 @@ public: * fragment operations on the fragment. * A maximum of four concurrently active is allowed. */ - Uint16 fragScanRec[MAX_PARALLEL_SCANS_PER_FRAG + MAX_PARALLEL_INDEX_SCANS_PER_FRAG]; + typedef Bitmask<4> ScanNumberMask; + ScanNumberMask m_scanNumberMask; + DLList<ScanRecord>::Head m_activeScans; + DLFifoList<ScanRecord>::Head m_queuedScans; + Uint16 srLqhLognode[4]; /** * The fragment pointers in TUP and TUX @@ -799,12 +878,7 @@ public: * should perform. */ Uint8 nextLcp; - /** - * The number of active scans currently in the fragment - * replica. - */ - Uint8 noActiveScan; - /** + /** * How many local checkpoints does the fragment contain */ Uint8 srChkpnr; @@ -1774,64 +1848,6 @@ public: }; // size 44 bytes typedef Ptr<PageRefRecord> PageRefRecordPtr; - struct ScanRecord { - enum ScanState { - SCAN_FREE = 0, - WAIT_STORED_PROC_COPY = 1, - WAIT_STORED_PROC_SCAN = 2, - WAIT_NEXT_SCAN_COPY = 3, - WAIT_NEXT_SCAN = 4, - WAIT_DELETE_STORED_PROC_ID_SCAN = 5, - WAIT_DELETE_STORED_PROC_ID_COPY = 6, - WAIT_ACC_COPY = 7, - WAIT_ACC_SCAN = 8, - WAIT_SCAN_KEYINFO = 9, - WAIT_SCAN_NEXTREQ = 10, - WAIT_COPY_KEYINFO = 11, - WAIT_CLOSE_SCAN = 12, - WAIT_CLOSE_COPY = 13, - WAIT_RELEASE_LOCK = 14, - WAIT_TUPKEY_COPY = 15, - WAIT_LQHKEY_COPY = 16 - }; - enum ScanType { - ST_IDLE = 0, - SCAN = 1, - COPY = 2 - }; - UintR scanAccOpPtr[MAX_PARALLEL_OP_PER_SCAN]; - UintR scanApiOpPtr[MAX_PARALLEL_OP_PER_SCAN]; - UintR scanOpLength[MAX_PARALLEL_OP_PER_SCAN]; - UintR scanLocalref[2]; - UintR copyPtr; - UintR nextScanrec; - UintR scanAccPtr; - UintR scanAiLength; - UintR scanCompletedOperations; - UintR scanConcurrentOperations; - UintR scanErrorCounter; - UintR scanLocalFragid; - UintR scanSchemaVersion; - UintR scanSearchCondFalseCount; - UintR scanStoredProcId; - ScanState scanState; - UintR scanTcrec; - ScanType scanType; - BlockReference scanApiBlockref; - NodeId scanNodeId; - Uint8 scanCompletedStatus; - Uint8 scanFlag; - Uint8 scanLockHold; - Uint8 scanLockMode; - Uint8 readCommitted; - Uint8 rangeScan; - Uint8 scanNumber; - Uint8 scanReleaseCounter; - Uint8 scanTcWaiting; - Uint8 scanKeyinfoFlag; - }; // Size 272 bytes - typedef Ptr<ScanRecord> ScanRecordPtr; - struct Tablerec { enum TableStatus { TABLE_DEFINED = 0, @@ -2644,11 +2660,10 @@ private: UintR cpageRefFileSize; #define ZSCANREC_FILE_SIZE 100 - ScanRecord *scanRecord; + ArrayPool<ScanRecord> c_scanRecordPool; ScanRecordPtr scanptr; - UintR cfirstfreeScanrec; - UintR cscanrecFileSize; UintR cscanNoFreeRec; + Uint32 cscanrecFileSize; // Configurable Tablerec *tablerec; @@ -2893,7 +2908,7 @@ public: return getNodeState().startLevel < NodeState::SL_STOPPING_3; } - + DLHashTable<ScanRecord> c_scanTakeOverHash; }; #endif diff --git a/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp b/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp index 615cfa4ea0b..cb1698ec8c0 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp @@ -56,7 +56,6 @@ void Dblqh::initData() logFileOperationRecord = 0; logPageRecord = 0; pageRefRecord = 0; - scanRecord = 0; tablerec = 0; tcConnectionrec = 0; tcNodeFailRecord = 0; @@ -127,9 +126,9 @@ void Dblqh::initRecords() sizeof(PageRefRecord), cpageRefFileSize); - scanRecord = (ScanRecord*)allocRecord("ScanRecord", - sizeof(ScanRecord), - cscanrecFileSize); + cscanNoFreeRec = cscanrecFileSize; + c_scanRecordPool.setSize(cscanrecFileSize); + c_scanTakeOverHash.setSize(64); tablerec = (Tablerec*)allocRecord("Tablerec", sizeof(Tablerec), @@ -172,7 +171,8 @@ void Dblqh::initRecords() Dblqh::Dblqh(const class Configuration & conf): SimulatedBlock(DBLQH, conf), - m_commitAckMarkerHash(m_commitAckMarkerPool) + m_commitAckMarkerHash(m_commitAckMarkerPool), + c_scanTakeOverHash(c_scanRecordPool) { BLOCK_CONSTRUCTOR(Dblqh); @@ -391,10 +391,6 @@ Dblqh::~Dblqh() sizeof(PageRefRecord), cpageRefFileSize); - deallocRecord((void**)&scanRecord, - "ScanRecord", - sizeof(ScanRecord), - cscanrecFileSize); deallocRecord((void**)&tablerec, "Tablerec", diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 2596be468bc..debea883cfc 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -66,9 +66,7 @@ #define DEBUG(x) #endif -const Uint32 NR_ScanNo = MAX_PARALLEL_SCANS_PER_FRAG - 1; -const Uint32 NR_MinRangeScanNo = MAX_PARALLEL_SCANS_PER_FRAG; -const Uint32 NR_MaxRangeScanNo = NR_MinRangeScanNo + MAX_PARALLEL_INDEX_SCANS_PER_FRAG; +const Uint32 NR_ScanNo = 0; void Dblqh::execACC_COM_BLOCK(Signal* signal) { @@ -360,8 +358,7 @@ void Dblqh::execCONTINUEB(Signal* signal) break; case ZCHECK_LCP_STOP_BLOCKED: jam(); - scanptr.i = data0; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr, data0); tcConnectptr.i = scanptr.p->scanTcrec; ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec); fragptr.i = tcConnectptr.p->fragmentptr; @@ -964,8 +961,10 @@ void Dblqh::execLQHFRAGREQ(Signal* signal) ndbrequire(tFragPtr.i != RNIL); // store it fragptr.p->tableFragptr = tFragPtr.i; + } else { + fragptr.p->tableFragptr = fragptr.i; } - + if (tempTable) { //-------------------------------------------- // reqinfo bit 3-4 = 2 means temporary table @@ -2047,15 +2046,13 @@ void Dblqh::execTIME_SIGNAL(Signal* signal) case TcConnectionrec::SCAN_STATE_USED: if (tTcConptr.p->tcScanRec < cscanrecFileSize){ ScanRecordPtr TscanPtr; - TscanPtr.i = tTcConptr.p->tcScanRec; - ptrCheckGuard(TscanPtr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(TscanPtr, tTcConptr.p->tcScanRec); ndbout << " scanState = " << TscanPtr.p->scanState << endl; //TscanPtr.p->scanAccOpPtr[16]; //TscanPtr.p->scanApiOpPtr[16]; //TscanPtr.p->scanOpLength[16]; //TscanPtr.p->scanLocalref[2]; ndbout << " copyPtr="<<TscanPtr.p->copyPtr - << " nextScanrec="<<TscanPtr.p->nextScanrec << " scanAccPtr="<<TscanPtr.p->scanAccPtr << " scanAiLength="<<TscanPtr.p->scanAiLength << endl; @@ -3499,7 +3496,6 @@ void Dblqh::endgettupkeyLab(Signal* signal) void Dblqh::prepareContinueAfterBlockedLab(Signal* signal) { UintR ttcScanOp; - UintR ttcScanNumber; UintR taccreq; /* -------------------------------------------------------------------------- */ @@ -3515,20 +3511,20 @@ void Dblqh::prepareContinueAfterBlockedLab(Signal* signal) if (regTcPtr->indTakeOver == ZTRUE) { jam(); ttcScanOp = KeyInfo20::getScanOp(regTcPtr->tcScanInfo); - ttcScanNumber = KeyInfo20::getScanNo(regTcPtr->tcScanInfo); - scanptr.i = ZNIL; - if (ttcScanNumber < NR_MaxRangeScanNo && ttcScanNumber != NR_ScanNo) { - jam(); - // table fragment also when index scan - scanptr.i = fragptr.p->fragScanRec[ttcScanNumber]; + scanptr.i = RNIL; + { + ScanRecord key; + key.scanNumber = KeyInfo20::getScanNo(regTcPtr->tcScanInfo); + key.fragPtrI = fragptr.i; + c_scanTakeOverHash.find(scanptr, key); + ndbassert(scanptr.i != RNIL); } - if (scanptr.i == ZNIL) { + if (scanptr.i == RNIL) { jam(); releaseActiveFrag(signal); takeOverErrorLab(signal); return; }//if - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); Uint32 accOpPtr = scanptr.p->scanAccOpPtr[ttcScanOp]; if (accOpPtr == RNIL) { jam(); @@ -6455,7 +6451,7 @@ void Dblqh::lqhTransNextLab(Signal* signal) }//if } else { scanptr.i = tcConnectptr.p->tcScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); if (scanptr.p->scanType == ScanRecord::COPY) { jam(); if (scanptr.p->scanNodeId == tcNodeFailptr.p->oldNodeId) { @@ -6593,7 +6589,7 @@ void Dblqh::execACC_SCAN_INFO(Signal* signal) { jamEntry(); scanptr.i = signal->theData[0]; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); Uint32 length = signal->theData[3]; ndbrequire(length <= 4); accScanInfoEnterLab(signal, &signal->theData[4], length); @@ -6604,7 +6600,7 @@ void Dblqh::execACC_SCAN_INFO24(Signal* signal) { jamEntry(); scanptr.i = signal->theData[0]; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); Uint32 length = signal->theData[3]; ndbrequire(length <= 20); accScanInfoEnterLab(signal, &signal->theData[4], length); @@ -6639,7 +6635,7 @@ void Dblqh::execACC_SCANCONF(Signal* signal) AccScanConf * const accScanConf = (AccScanConf *)&signal->theData[0]; jamEntry(); scanptr.i = accScanConf->scanPtr; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); if (scanptr.p->scanState == ScanRecord::WAIT_ACC_SCAN) { accScanConfScanLab(signal); } else { @@ -6665,7 +6661,7 @@ void Dblqh::execNEXT_SCANCONF(Signal* signal) NextScanConf * const nextScanConf = (NextScanConf *)&signal->theData[0]; jamEntry(); scanptr.i = nextScanConf->scanPtr; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); if (nextScanConf->localKeyLength == 1) { jam(); nextScanConf->localKey[1] = @@ -6719,7 +6715,7 @@ void Dblqh::execSTORED_PROCCONF(Signal* signal) Uint32 storedProcId = signal->theData[1]; ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec); scanptr.i = tcConnectptr.p->tcScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); switch (scanptr.p->scanState) { case ScanRecord::WAIT_STORED_PROC_SCAN: jam(); @@ -6756,7 +6752,7 @@ void Dblqh::execSTORED_PROCREF(Signal* signal) Uint32 errorCode = signal->theData[1]; ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec); scanptr.i = tcConnectptr.p->tcScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); switch (scanptr.p->scanState) { case ScanRecord::WAIT_STORED_PROC_SCAN: jam(); @@ -6829,13 +6825,14 @@ void Dblqh::execSCAN_NEXTREQ(Signal* signal) }//if if (ERROR_INSERTED(5030)){ ndbout << "ERROR 5030" << endl; + CLEAR_ERROR_INSERT_VALUE; // Drop signal return; }//if scanptr.i = tcConnectptr.p->tcScanRec; ndbrequire(scanptr.i != RNIL); - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); scanptr.p->scanTcWaiting = ZTRUE; /* ------------------------------------------------------------------ @@ -6846,6 +6843,9 @@ void Dblqh::execSCAN_NEXTREQ(Signal* signal) * ------------------------------------------------------------------ */ if (nextReq->closeFlag == ZTRUE){ jam(); + if(ERROR_INSERTED(5034)){ + CLEAR_ERROR_INSERT_VALUE; + } closeScanRequestLab(signal); return; }//if @@ -6929,7 +6929,7 @@ void Dblqh::scanReleaseLocksLab(Signal* signal) void Dblqh::continueScanReleaseAfterBlockedLab(Signal* signal) { scanptr.i = tcConnectptr.p->tcScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); scanptr.p->scanState = ScanRecord::WAIT_RELEASE_LOCK; signal->theData[0] = scanptr.p->scanAccPtr; ndbrequire((scanptr.p->scanReleaseCounter -1) < MAX_PARALLEL_OP_PER_SCAN); @@ -6963,6 +6963,10 @@ void Dblqh::closeScanRequestLab(Signal* signal) case TcConnectionrec::SCAN_STATE_USED: DEBUG("scanState = " << scanptr.p->scanState); switch (scanptr.p->scanState) { + case ScanRecord::IN_QUEUE: + jam(); + tupScanCloseConfLab(signal); + break; case ScanRecord::WAIT_SCAN_KEYINFO: case ScanRecord::WAIT_NEXT_SCAN: jam(); @@ -7167,30 +7171,21 @@ void Dblqh::execSCAN_FRAGREQ(Signal* signal) goto error_handler; }//if - // 1 table scan is reserved for node recovery - if (! rangeScan && fragptr.p->noActiveScan >= NR_ScanNo){ - jam(); - errorCode = ScanFragRef::ZTOO_MANY_ACTIVE_SCAN_ERROR; - goto error_handler; - } - // count is actually not used in range scans - fragptr.p->noActiveScan++; - // 1 scan record is reserved for node recovery if (cscanNoFreeRec < 2) { jam(); errorCode = ScanFragRef::ZNO_FREE_SCANREC_ERROR; - goto error_handler1; + goto error_handler; } // XXX adjust cmaxAccOps for range scans and remove this comment if ((cbookedAccOps + scanConcurrentOperations) > cmaxAccOps) { jam(); errorCode = ScanFragRef::ZSCAN_BOOK_ACC_OP_ERROR; - goto error_handler1; + goto error_handler; }//if - seizeScanrec(signal); + ndbrequire(c_scanRecordPool.seize(scanptr)); initScanTc(signal, transid1, transid2, @@ -7201,6 +7196,7 @@ void Dblqh::execSCAN_FRAGREQ(Signal* signal) jam(); goto error_handler2; }//if + cscanNoFreeRec--; cbookedAccOps += scanConcurrentOperations; hashIndex = (tcConnectptr.p->transid[0] ^ tcConnectptr.p->tcOprec) & 1023; @@ -7227,9 +7223,7 @@ void Dblqh::execSCAN_FRAGREQ(Signal* signal) error_handler2: // no scan number allocated - releaseScanrec(signal); -error_handler1: - fragptr.p->noActiveScan--; + c_scanRecordPool.release(scanptr); error_handler: ref = (ScanFragRef*)&signal->theData[0]; tcConnectptr.p->abortState = TcConnectionrec::ABORT_ACTIVE; @@ -7267,6 +7261,12 @@ error_handler: void Dblqh::continueAfterReceivingAllAiLab(Signal* signal) { tcConnectptr.p->transactionState = TcConnectionrec::SCAN_STATE_USED; + + if(scanptr.p->scanState == ScanRecord::IN_QUEUE){ + jam(); + return; + } + scanptr.p->scanState = ScanRecord::WAIT_ACC_SCAN; AccScanReq * req = (AccScanReq*)&signal->theData[0]; req->senderData = scanptr.i; @@ -7293,7 +7293,7 @@ void Dblqh::scanAttrinfoLab(Signal* signal, Uint32* dataPtr, Uint32 length) { if (saveTupattrbuf(signal, dataPtr, length) == ZOK) { scanptr.i = tcConnectptr.p->tcScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); if (tcConnectptr.p->currTupAiLen < scanptr.p->scanAiLength) { jam(); } else { @@ -7304,13 +7304,21 @@ void Dblqh::scanAttrinfoLab(Signal* signal, Uint32* dataPtr, Uint32 length) return; }//if terrorCode = ZGET_ATTRINBUF_ERROR; - fragptr.i = tcConnectptr.p->fragmentptr; - ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord); finishScanrec(signal); releaseScanrec(signal); - fragptr.p->noActiveScan--; tcConnectptr.p->transactionState = TcConnectionrec::IDLE; - sendScanFragRefLateLab(signal); + tcConnectptr.p->abortState = TcConnectionrec::ABORT_ACTIVE; + + ScanFragRef * ref = (ScanFragRef*)&signal->theData[0]; + ref->senderData = tcConnectptr.p->clientConnectrec; + ref->transId1 = tcConnectptr.p->transid[0]; + ref->transId2 = tcConnectptr.p->transid[1]; + ref->errorCode = terrorCode; + sendSignal(tcConnectptr.p->clientBlockref, GSN_SCAN_FRAGREF, signal, + ScanFragRef::SignalLength, JBB); + deleteTransidHash(signal); + releaseOprec(signal); + releaseTcrec(signal, tcConnectptr); }//Dblqh::scanAttrinfoLab() /*---------------------------------------------------------------------*/ @@ -7322,7 +7330,7 @@ void Dblqh::execSCAN_HBREP(Signal* signal) { jamEntry(); scanptr.i = signal->theData[0]; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); switch(scanptr.p->scanType){ case ScanRecord::SCAN: if (scanptr.p->scanTcWaiting == ZTRUE) { @@ -7361,17 +7369,6 @@ void Dblqh::execSCAN_HBREP(Signal* signal) void Dblqh::sendScanFragRefLateLab(Signal* signal) { - tcConnectptr.p->abortState = TcConnectionrec::ABORT_ACTIVE; - ScanFragRef * ref = (ScanFragRef*)&signal->theData[0]; - ref->senderData = tcConnectptr.p->clientConnectrec; - ref->transId1 = tcConnectptr.p->transid[0]; - ref->transId2 = tcConnectptr.p->transid[1]; - ref->errorCode = terrorCode; - sendSignal(tcConnectptr.p->clientBlockref, GSN_SCAN_FRAGREF, signal, - ScanFragRef::SignalLength, JBB); - deleteTransidHash(signal); - releaseOprec(signal); - releaseTcrec(signal, tcConnectptr); }//Dblqh::sendScanFragRefLateLab() @@ -7506,7 +7503,7 @@ void Dblqh::storedProcConfScanLab(Signal* signal) void Dblqh::continueFirstScanAfterBlockedLab(Signal* signal) { scanptr.i = tcConnectptr.p->tcScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); scanptr.p->scanState = ScanRecord::WAIT_NEXT_SCAN; initScanAccOp(signal); signal->theData[0] = scanptr.p->scanAccPtr; @@ -7527,7 +7524,7 @@ void Dblqh::execCHECK_LCP_STOP(Signal* signal) { jamEntry(); scanptr.i = signal->theData[0]; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); tcConnectptr.i = scanptr.p->scanTcrec; ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec); fragptr.i = tcConnectptr.p->fragmentptr; @@ -7582,7 +7579,7 @@ void Dblqh::checkLcpStopBlockedLab(Signal* signal) void Dblqh::continueAfterCheckLcpStopBlocked(Signal* signal) { scanptr.i = tcConnectptr.p->tcScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); signal->theData[0] = scanptr.p->scanAccPtr; signal->theData[1] = AccCheckScan::ZNOT_CHECK_LCP_STOP; if (! scanptr.p->rangeScan) @@ -7831,7 +7828,7 @@ void Dblqh::scanTupkeyConfLab(Signal* signal) tcConnectptr.p->transactionState = TcConnectionrec::SCAN_STATE_USED; scanptr.i = tcConnectptr.p->tcScanRec; releaseActiveFrag(signal); - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); if (scanptr.p->scanCompletedStatus == ZTRUE) { /* --------------------------------------------------------------------- * STOP THE SCAN PROCESS IF THIS HAS BEEN REQUESTED. @@ -7930,7 +7927,7 @@ void Dblqh::scanNextLoopLab(Signal* signal) void Dblqh::continueScanAfterBlockedLab(Signal* signal) { scanptr.i = tcConnectptr.p->tcScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); Uint32 accOpPtr; if (scanptr.p->scanFlag == NextScanReq::ZSCAN_NEXT_ABORT) { jam(); @@ -7966,7 +7963,7 @@ void Dblqh::scanTupkeyRefLab(Signal* signal) scanptr.i = tcConnectptr.p->tcScanRec; releaseActiveFrag(signal); releaseOprec(signal); - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); if (scanptr.p->scanCompletedStatus == ZTRUE) { /* --------------------------------------------------------------------- * STOP THE SCAN PROCESS IF THIS HAS BEEN REQUESTED. @@ -8068,7 +8065,7 @@ void Dblqh::continueCloseScanAfterBlockedLab(Signal* signal) { tcConnectptr.p->transactionState = TcConnectionrec::SCAN_STATE_USED; scanptr.i = tcConnectptr.p->tcScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); scanptr.p->scanState = ScanRecord::WAIT_CLOSE_SCAN; signal->theData[0] = scanptr.p->scanAccPtr; signal->theData[1] = RNIL; @@ -8132,7 +8129,6 @@ void Dblqh::tupScanCloseConfLab(Signal* signal) finishScanrec(signal); releaseScanrec(signal); tcConnectptr.p->tcScanRec = RNIL; - fragptr.p->noActiveScan = fragptr.p->noActiveScan - 1; deleteTransidHash(signal); releaseOprec(signal); releaseTcrec(signal, tcConnectptr); @@ -8165,8 +8161,9 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq) const Uint32 scanLockHold = ScanFragReq::getHoldLockFlag(reqinfo); const Uint32 keyinfo = ScanFragReq::getKeyinfoFlag(reqinfo); const Uint32 readCommitted = ScanFragReq::getReadCommittedFlag(reqinfo); - const Uint32 rangeScan = ScanFragReq::getRangeScanFlag(reqinfo); + const Uint32 idx = ScanFragReq::getRangeScanFlag(reqinfo); const Uint32 attrLen = ScanFragReq::getAttrLen(reqinfo); + const Uint32 scanPrio = ScanFragReq::getScanPrio(reqinfo); scanptr.p->scanKeyinfoFlag = keyinfo; scanptr.p->scanLockHold = scanLockHold; @@ -8181,7 +8178,7 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq) scanptr.p->scanErrorCounter = 0; scanptr.p->scanLockMode = scanLockMode; scanptr.p->readCommitted = readCommitted; - scanptr.p->rangeScan = rangeScan; + scanptr.p->rangeScan = idx; scanptr.p->scanSearchCondFalseCount = 0; scanptr.p->scanState = ScanRecord::SCAN_FREE; scanptr.p->scanFlag = ZFALSE; @@ -8189,6 +8186,7 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq) scanptr.p->scanLocalref[1] = 0; scanptr.p->scanLocalFragid = 0; scanptr.p->scanTcWaiting = ZTRUE; + scanptr.p->scanNumber = ZNIL; for (Uint32 i = 0; i < scanConcurrentOperations; i++) { jam(); @@ -8196,6 +8194,59 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq) scanptr.p->scanOpLength[i] = 0; scanptr.p->scanAccOpPtr[i] = 0; }//for + + /** + * Used for scan take over + */ + FragrecordPtr tFragPtr; + tFragPtr.i = fragptr.p->tableFragptr; + ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord); + scanptr.p->fragPtrI = fragptr.p->tableFragptr; + + /** + * !idx uses 1 - (MAX_PARALLEL_SCANS_PER_FRAG - 1) = 1-11 + * idx uses from MAX_PARALLEL_SCANS_PER_FRAG - MAX = 12-42) + */ + Uint32 start = (idx ? MAX_PARALLEL_SCANS_PER_FRAG : 1 ); + Uint32 stop = (idx ? MAX_PARALLEL_INDEX_SCANS_PER_FRAG : MAX_PARALLEL_SCANS_PER_FRAG - 1); + stop += start; + Uint32 free = tFragPtr.p->m_scanNumberMask.find(start); + + if(free == Fragrecord::ScanNumberMask::NotFound || free >= stop){ + jam(); + + if(scanPrio == 0){ + jam(); + return ScanFragRef::ZTOO_MANY_ACTIVE_SCAN_ERROR; + } + + /** + * Put on queue + */ + scanptr.p->scanState = ScanRecord::IN_QUEUE; + LocalDLFifoList<ScanRecord> queue(c_scanRecordPool, + tFragPtr.p->m_queuedScans); + queue.add(scanptr); + return ZOK; + } + + + scanptr.p->scanNumber = free; + tFragPtr.p->m_scanNumberMask.clear(free);// Update mask + + LocalDLList<ScanRecord> active(c_scanRecordPool, tFragPtr.p->m_activeScans); + active.add(scanptr); + if(scanptr.p->scanKeyinfoFlag){ + jam(); +#ifdef VM_TRACE + ScanRecordPtr tmp; + ndbrequire(!c_scanTakeOverHash.find(tmp, * scanptr.p)); +#endif + c_scanTakeOverHash.add(scanptr); + } + return ZOK; + +#if 0 if (! rangeScan) { jam(); for (Int32 i = NR_ScanNo - 1; i >= 0; i--) { @@ -8223,6 +8274,7 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq) } } return ZNO_FREE_FRAG_SCAN_REC_ERROR; +#endif }//Dblqh::initScanrec() /* ========================================================================= @@ -8263,17 +8315,72 @@ void Dblqh::initScanTc(Signal* signal, * ========================================================================= */ void Dblqh::finishScanrec(Signal* signal) { - if (! scanptr.p->rangeScan) { - ndbrequire(scanptr.p->scanNumber < NR_ScanNo); - fragptr.p->fragScanRec[scanptr.p->scanNumber] = ZNIL; - } else { + FragrecordPtr tFragPtr; + tFragPtr.i = scanptr.p->fragPtrI; + ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord); + + LocalDLFifoList<ScanRecord> queue(c_scanRecordPool, + tFragPtr.p->m_queuedScans); + + if(scanptr.p->scanState == ScanRecord::IN_QUEUE){ jam(); - ndbrequire(NR_MinRangeScanNo <= scanptr.p->scanNumber && scanptr.p->scanNumber < NR_MaxRangeScanNo); - FragrecordPtr tFragPtr; - tFragPtr.i = fragptr.p->tableFragptr; - ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord); - tFragPtr.p->fragScanRec[scanptr.p->scanNumber] = ZNIL; + queue.release(scanptr); + return; } + + if(scanptr.p->scanKeyinfoFlag){ + jam(); + ScanRecordPtr tmp; + c_scanTakeOverHash.remove(tmp, * scanptr.p); + ndbrequire(tmp.p == scanptr.p); + } + + LocalDLList<ScanRecord> scans(c_scanRecordPool, tFragPtr.p->m_activeScans); + scans.release(scanptr); + + const Uint32 scanNumber = scanptr.p->scanNumber; + ndbrequire(!tFragPtr.p->m_scanNumberMask.get(scanNumber)); + ScanRecordPtr restart; + + /** + * Start on of queued scans + */ + if(scanNumber == NR_ScanNo || !queue.first(restart)){ + jam(); + tFragPtr.p->m_scanNumberMask.set(scanNumber); + return; + } + + if(ERROR_INSERTED(5034)){ + jam(); + tFragPtr.p->m_scanNumberMask.set(scanNumber); + return; + } + + ScanRecordPtr tmpScan = scanptr; + TcConnectionrecPtr tmpTc = tcConnectptr; + + tcConnectptr.i = restart.p->scanTcrec; + ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec); + restart.p->scanNumber = scanNumber; + restart.p->scanState = ScanRecord::WAIT_ACC_SCAN; + + queue.remove(restart); + scans.add(restart); + if(restart.p->scanKeyinfoFlag){ + jam(); +#ifdef VM_TRACE + ScanRecordPtr tmp; + ndbrequire(!c_scanTakeOverHash.find(tmp, * restart.p)); +#endif + c_scanTakeOverHash.add(restart); + } + + scanptr = restart; + continueAfterReceivingAllAiLab(signal); + + scanptr = tmpScan; + tcConnectptr = tmpTc; }//Dblqh::finishScanrec() /* ========================================================================= @@ -8283,8 +8390,6 @@ void Dblqh::finishScanrec(Signal* signal) * ========================================================================= */ void Dblqh::releaseScanrec(Signal* signal) { - scanptr.p->nextScanrec = cfirstfreeScanrec; - cfirstfreeScanrec = scanptr.i; scanptr.p->scanState = ScanRecord::SCAN_FREE; scanptr.p->scanType = ScanRecord::ST_IDLE; scanptr.p->scanTcWaiting = ZFALSE; @@ -8292,20 +8397,6 @@ void Dblqh::releaseScanrec(Signal* signal) cscanNoFreeRec++; }//Dblqh::releaseScanrec() -/* ========================================================================= - * ======= SEIZE SCAN RECORD ======= - * - * GETS A NEW SCAN RECORD FROM FREELIST. - * ========================================================================= */ -void Dblqh::seizeScanrec(Signal* signal) -{ - scanptr.i = cfirstfreeScanrec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); - cfirstfreeScanrec = scanptr.p->nextScanrec; - scanptr.p->nextScanrec = RNIL; - cscanNoFreeRec--; -}//Dblqh::seizeScanrec() - /* ------------------------------------------------------------------------ * ------- SEND KEYINFO20 TO API ------- * @@ -8471,10 +8562,8 @@ void Dblqh::execCOPY_FRAGREQ(Signal* signal) ndbrequire(cnoActiveCopy < 3); ndbrequire(getFragmentrec(signal, fragId)); ndbrequire(fragptr.p->copyFragState == ZIDLE); - ndbrequire(fragptr.p->noActiveScan < MAX_PARALLEL_SCANS_PER_FRAG); - ndbrequire(cfirstfreeScanrec != RNIL); ndbrequire(cfirstfreeTcConrec != RNIL); - ndbrequire(fragptr.p->fragScanRec[NR_ScanNo] == ZNIL); + ndbrequire(fragptr.p->m_scanNumberMask.get(NR_ScanNo)); fragptr.p->fragDistributionKey = copyFragReq->distributionKey; @@ -8494,7 +8583,8 @@ void Dblqh::execCOPY_FRAGREQ(Signal* signal) return; }//if - seizeScanrec(signal); + LocalDLList<ScanRecord> scans(c_scanRecordPool, fragptr.p->m_activeScans); + ndbrequire(scans.seize(scanptr)); /* ------------------------------------------------------------------------- */ // We keep track of how many operation records in ACC that has been booked. // Copy fragment has records always booked and thus need not book any. The @@ -8519,8 +8609,9 @@ void Dblqh::execCOPY_FRAGREQ(Signal* signal) scanptr.p->scanCompletedStatus = ZFALSE; scanptr.p->scanErrorCounter = 0; scanptr.p->scanNumber = NR_ScanNo; - fragptr.p->fragScanRec[NR_ScanNo] = scanptr.i; - fragptr.p->noActiveScan++; + scanptr.p->scanKeyinfoFlag = 0; // Don't put into hash + scanptr.p->fragPtrI = fragptr.i; + fragptr.p->m_scanNumberMask.clear(NR_ScanNo); initScanTc(signal, 0, @@ -8600,7 +8691,7 @@ void Dblqh::storedProcConfCopyLab(Signal* signal) return; }//if scanptr.i = tcConnectptr.p->tcScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); scanptr.p->scanState = ScanRecord::WAIT_NEXT_SCAN_COPY; switch (fragptr.p->fragStatus) { case Fragrecord::FSACTIVE: @@ -8636,7 +8727,7 @@ void Dblqh::storedProcConfCopyLab(Signal* signal) void Dblqh::continueFirstCopyAfterBlockedLab(Signal* signal) { scanptr.i = tcConnectptr.p->tcScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); signal->theData[0] = scanptr.p->scanAccPtr; signal->theData[1] = RNIL; signal->theData[2] = NextScanReq::ZSCAN_NEXT; @@ -8798,7 +8889,7 @@ void Dblqh::copyTupkeyConfLab(Signal* signal) UintR readLength = tupKeyConf->readLength; scanptr.i = tcConnectptr.p->tcScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); releaseActiveFrag(signal); if (tcConnectptr.p->errorCode != 0) { jam(); @@ -8867,7 +8958,7 @@ void Dblqh::copyCompletedLab(Signal* signal) ndbrequire(tcConnectptr.p->transid[1] == lqhKeyConf->transId2); scanptr.i = tcConnectptr.p->tcScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); if (tcConnectptr.p->copyCountWords >= cmaxWordsAtNodeRec) { tcConnectptr.p->copyCountWords -= lqhKeyConf->transId1; // Data overload, see note! if (scanptr.p->scanCompletedStatus == ZTRUE) { @@ -8918,7 +9009,7 @@ void Dblqh::nextRecordCopy(Signal* signal) fragptr.i = tcConnectptr.p->fragmentptr; ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord); scanptr.i = tcConnectptr.p->tcScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); if (scanptr.p->scanState != ScanRecord::WAIT_LQHKEY_COPY) { jam(); /*---------------------------------------------------------------------------*/ @@ -8964,7 +9055,7 @@ void Dblqh::nextRecordCopy(Signal* signal) void Dblqh::continueCopyAfterBlockedLab(Signal* signal) { scanptr.i = tcConnectptr.p->tcScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); tcConnectptr.p->errorCode = 0; signal->theData[0] = scanptr.p->scanAccPtr; signal->theData[1] = scanptr.p->scanAccOpPtr[0]; @@ -8978,7 +9069,7 @@ void Dblqh::copyLqhKeyRefLab(Signal* signal) ndbrequire(tcConnectptr.p->transid[1] == signal->theData[4]); tcConnectptr.p->copyCountWords -= signal->theData[3]; scanptr.i = tcConnectptr.p->tcScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); scanptr.p->scanErrorCounter++; tcConnectptr.p->errorCode = terrorCode; closeCopyLab(signal); @@ -9001,7 +9092,7 @@ void Dblqh::closeCopyLab(Signal* signal) fragptr.i = tcConnectptr.p->fragmentptr; ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord); scanptr.i = tcConnectptr.p->tcScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); scanptr.p->scanState = ScanRecord::WAIT_CLOSE_COPY; switch (fragptr.p->fragStatus) { case Fragrecord::FSACTIVE: @@ -9037,7 +9128,7 @@ void Dblqh::closeCopyLab(Signal* signal) void Dblqh::continueCloseCopyAfterBlockedLab(Signal* signal) { scanptr.i = tcConnectptr.p->tcScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); signal->theData[0] = scanptr.p->scanAccPtr; signal->theData[1] = RNIL; signal->theData[2] = ZCOPY_CLOSE; @@ -9085,6 +9176,8 @@ void Dblqh::tupCopyCloseConfLab(Signal* signal) { fragptr.i = tcConnectptr.p->fragmentptr; ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord); + fragptr.p->copyFragState = ZIDLE; + if (tcConnectptr.p->abortState == TcConnectionrec::NEW_FROM_TC) { jam(); tcNodeFailptr.i = tcConnectptr.p->tcNodeFailrec; @@ -9129,11 +9222,7 @@ void Dblqh::tupCopyCloseConfLab(Signal* signal) }//if releaseActiveCopy(signal); tcConnectptr.p->tcScanRec = RNIL; - ndbrequire(scanptr.p->scanNumber < MAX_PARALLEL_SCANS_PER_FRAG); - fragptr.p->fragScanRec[scanptr.p->scanNumber] = ZNIL; - ndbrequire(fragptr.p->noActiveScan > 0); - fragptr.p->noActiveScan--; - fragptr.p->copyFragState = ZIDLE; + finishScanrec(signal); releaseOprec(signal); releaseTcrec(signal, tcConnectptr); releaseScanrec(signal); @@ -9321,8 +9410,10 @@ void Dblqh::scanTcConnectLab(Signal* signal, Uint32 tstartTcConnect, Uint32 frag /* ***************>> */ void Dblqh::execCOPY_STATEREQ(Signal* signal) { - Uint32* dataPtr = &signal->theData[2]; jamEntry(); + ndbrequire(0) +#if 0 + Uint32* dataPtr = &signal->theData[2]; BlockReference tmasterBlockref = signal->theData[0]; Uint32 tnoCopy = 0; do { @@ -9340,7 +9431,7 @@ void Dblqh::execCOPY_STATEREQ(Signal* signal) /* THIS FRAGMENT IS CURRENTLY ACTIVE IN COPYING THE FRAGMENT. */ /*---------------------------------------------------------------------------*/ scanptr.i = fragptr.p->fragScanRec[NR_ScanNo]; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + c_scanRecordPool.getPtr(scanptr); if (scanptr.p->scanCompletedStatus == ZTRUE) { jam(); dataPtr[3 + (tnoCopy << 2)] = ZCOPY_CLOSING; @@ -9366,6 +9457,7 @@ void Dblqh::execCOPY_STATEREQ(Signal* signal) signal->theData[0] = cownNodeid; signal->theData[1] = tnoCopy; sendSignal(tmasterBlockref, GSN_COPY_STATECONF, signal, 18, JBB); +#endif return; }//Dblqh::execCOPY_STATEREQ() @@ -9857,6 +9949,12 @@ void Dblqh::lcpStartedLab(Signal* signal) *-------------------------------------------------------------------------- */ void Dblqh::execACC_CONTOPCONF(Signal* signal) { + if(ERROR_INSERTED(5035) && signal->getSendersBlockRef() != reference()){ + sendSignalWithDelay(reference(), GSN_ACC_CONTOPCONF, signal, 1000, + signal->length()); + return; + } + jamEntry(); lcpLocptr.i = signal->theData[0]; ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord); @@ -10142,8 +10240,6 @@ void Dblqh::lcpCompletedLab(Signal* signal) * WE START BY SENDING LCP_REPORT TO DIH TO REPORT THE COMPLETED LCP. * TO CATER FOR NODE CRASHES WE SEND IT IN PARALLEL TO ALL NODES. * ----------------------------------------------------------------------- */ - sendLCP_FRAG_REP(signal, lcpPtr.p->currentFragment); - fragptr.i = lcpPtr.p->currentFragment.fragPtrI; ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord); fragptr.p->fragActiveStatus = ZFALSE; @@ -10194,6 +10290,12 @@ void Dblqh::contChkpNextFragLab(Signal* signal) lcpPtr.p->lcpState = LcpRecord::LCP_BLOCKED_COMP; return; }//if + + /** + * Send rep when fragment is done + unblocked + */ + sendLCP_FRAG_REP(signal, lcpPtr.p->currentFragment); + /* ------------------------------------------------------------------------ * WE ALSO RELEASE THE LOCAL LCP RECORDS. * ----------------------------------------------------------------------- */ @@ -11782,6 +11884,12 @@ void Dblqh::writeLogfileLab(Signal* signal) /* WRITE. */ /*---------------------------------------------------------------------------*/ switch (logFilePtr.p->fileChangeState) { +#if 0 + case LogFileRecord::BOTH_WRITES_ONGOING: + jam(); + ndbout_c("not crashing!!"); + // Fall-through +#endif case LogFileRecord::NOT_ONGOING: jam(); checkGcpCompleted(signal, @@ -16046,18 +16154,16 @@ void Dblqh::sendInitialiseRecords(Signal* signal, Uint32 data) void Dblqh::initialiseScanrec(Signal* signal) { ndbrequire(cscanrecFileSize > 1); - for (scanptr.i = 0; scanptr.i < cscanrecFileSize; scanptr.i++) { - ptrAss(scanptr, scanRecord); - scanptr.p->nextScanrec = scanptr.i + 1; + DLList<ScanRecord> tmp(c_scanRecordPool); + while (tmp.seize(scanptr)){ + //new (scanptr.p) ScanRecord(); scanptr.p->scanType = ScanRecord::ST_IDLE; scanptr.p->scanState = ScanRecord::SCAN_FREE; scanptr.p->scanTcWaiting = ZFALSE; - }//for - scanptr.i = cscanrecFileSize - 1; - ptrAss(scanptr, scanRecord); - scanptr.p->nextScanrec = RNIL; - cfirstfreeScanrec = 0; - cscanNoFreeRec = cscanrecFileSize; + scanptr.p->nextHash = RNIL; + scanptr.p->prevHash = RNIL; + } + tmp.release(); }//Dblqh::initialiseScanrec() /* ========================================================================== @@ -16136,6 +16242,8 @@ void Dblqh::initFragrec(Signal* signal, Uint32 fragId, Uint32 copyType) { + new (fragptr.p) Fragrecord(); + fragptr.p->m_scanNumberMask.set(); // All is free fragptr.p->accBlockref = caccBlockref; fragptr.p->accBlockedList = RNIL; fragptr.p->activeList = RNIL; @@ -16151,12 +16259,8 @@ void Dblqh::initFragrec(Signal* signal, for (Uint32 i = 0; i < MAX_LCP_STORED; i++) { fragptr.p->lcpId[i] = 0; }//for - for (Uint32 i = 0; i < NR_MaxRangeScanNo; i++) { - fragptr.p->fragScanRec[i] = ZNIL; - }//for fragptr.p->maxGciCompletedInLcp = 0; fragptr.p->maxGciInLcp = 0; - fragptr.p->noActiveScan = 0; fragptr.p->copyFragState = ZIDLE; fragptr.p->nextFrag = RNIL; fragptr.p->newestGci = cnewestGci; @@ -17809,7 +17913,7 @@ Dblqh::execDUMP_STATE_ORD(Signal* signal) ScanRecordPtr sp; sp.i = recordNo; - ptrAss(sp, scanRecord); + c_scanRecordPool.getPtr(scanptr); if (sp.p->scanState != ScanRecord::SCAN_FREE){ dumpState->args[0] = DumpStateOrd::LqhDumpOneScanRec; dumpState->args[1] = recordNo; @@ -17836,7 +17940,7 @@ Dblqh::execDUMP_STATE_ORD(Signal* signal) ScanRecordPtr sp; sp.i = recordNo; - ptrAss(sp, scanRecord); + c_scanRecordPool.getPtr(sp); infoEvent("Dblqh::ScanRecord[%d]: state=%d, type=%d, " "complStatus=%d, scanNodeId=%d", sp.i, @@ -17868,8 +17972,6 @@ Dblqh::execDUMP_STATE_ORD(Signal* signal) sp.p->scanTcWaiting, sp.p->scanTcrec, sp.p->scanKeyinfoFlag); - infoEvent(" next=%d", - sp.p->nextScanrec); return; } if(dumpState->args[0] == DumpStateOrd::LqhDumpLcpState){ diff --git a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp index a3a01065429..3fc79120942 100644 --- a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp +++ b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp @@ -380,11 +380,8 @@ public: /* WHEN THE TRIGGER IS DEACTIVATED. */ /* **************************************** */ struct TcFiredTriggerData { - TcFiredTriggerData(AttributeBuffer::DataBufferPool & abp): - keyValues(abp), - beforeValues(abp), - afterValues(abp) - {} + TcFiredTriggerData() {} + /** * Trigger id, used to identify the trigger **/ @@ -396,19 +393,24 @@ public: Uint32 fireingOperation; /** + * Used for scrapping in case of node failure + */ + Uint32 nodeId; + + /** * Trigger attribute info, primary key value(s) */ - AttributeBuffer keyValues; + AttributeBuffer::Head keyValues; /** * Trigger attribute info, attribute value(s) before operation */ - AttributeBuffer beforeValues; + AttributeBuffer::Head beforeValues; /** * Trigger attribute info, attribute value(s) after operation */ - AttributeBuffer afterValues; + AttributeBuffer::Head afterValues; /** * Next ptr (used in pool/list) @@ -416,16 +418,28 @@ public: union { Uint32 nextPool; Uint32 nextList; + Uint32 nextHash; }; /** * Prev pointer (used in list) */ - Uint32 prevList; - + union { + Uint32 prevList; + Uint32 prevHash; + }; + inline void print(NdbOut & s) const { s << "[FiredTriggerData = " << triggerId << "]"; } + + inline Uint32 hashValue() const { + return fireingOperation ^ nodeId; + } + + inline bool equal(const TcFiredTriggerData & rec) const { + return fireingOperation == rec.fireingOperation && nodeId == rec.nodeId; + } }; typedef Ptr<TcFiredTriggerData> FiredTriggerPtr; @@ -433,6 +447,7 @@ public: * Pool of trigger data record */ ArrayPool<TcFiredTriggerData> c_theFiredTriggerPool; + DLHashTable<TcFiredTriggerData> c_firedTriggerHash; AttributeBuffer::DataBufferPool c_theTriggerAttrInfoPool; Uint32 c_maxNumberOfDefinedTriggers; @@ -822,7 +837,6 @@ public: UintR triggerExecutionCount; UintR triggeringOperation; UintR savedState[LqhKeyConf::SignalLength]; - UintR triggerError; // Index data bool isIndexOp; // Used to mark on-going TcKeyReq as index table access diff --git a/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp b/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp index 1ac5273188c..0982ae5bff5 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp @@ -71,6 +71,7 @@ void Dbtc::initData() c_theIndexOperationPool.setSize(c_maxNumberOfIndexOperations); c_theSeizedIndexOperationPool.setSize(c_maxNumberOfIndexOperations); c_theAttributeBufferPool.setSize(c_transactionBufferSpace); + c_firedTriggerHash.setSize((c_maxNumberOfFiredTriggers+10)/10); }//Dbtc::initData() void Dbtc::initRecords() @@ -93,7 +94,7 @@ void Dbtc::initRecords() DLFifoList<TcFiredTriggerData> triggers(c_theFiredTriggerPool); FiredTriggerPtr tptr; while(triggers.seize(tptr) == true) { - new (tptr.p) TcFiredTriggerData(c_theAttributeBufferPool); + new (tptr.p) TcFiredTriggerData(); } triggers.release(); @@ -169,6 +170,7 @@ void Dbtc::initRecords() Dbtc::Dbtc(const class Configuration & conf): SimulatedBlock(DBTC, conf), c_theDefinedTriggers(c_theDefinedTriggerPool), + c_firedTriggerHash(c_theFiredTriggerPool), c_maxNumberOfDefinedTriggers(0), c_maxNumberOfFiredTriggers(0), c_theIndexes(c_theIndexPool), diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index ac8a130eb83..feb5712d9d3 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -2314,7 +2314,6 @@ Dbtc::seizeTcRecord(Signal* signal) regTcPtr->noReceivedTriggers = 0; regTcPtr->triggerExecutionCount = 0; regTcPtr->triggeringOperation = RNIL; - regTcPtr->triggerError = 0; regTcPtr->isIndexOp = false; regTcPtr->indexOp = RNIL; regTcPtr->currentIndexId = RNIL; @@ -3500,7 +3499,7 @@ void Dbtc::execLQHKEYCONF(Signal* signal) UintR TapiConnectFilesize = capiConnectFilesize; UintR Ttrans1 = lqhKeyConf->transId1; UintR Ttrans2 = lqhKeyConf->transId2; - regTcPtr->noFiredTriggers = lqhKeyConf->noFiredTriggers; + Uint32 noFired = lqhKeyConf->noFiredTriggers; if (TapiConnectptrIndex >= TapiConnectFilesize) { TCKEY_abort(signal, 29); @@ -3554,6 +3553,7 @@ void Dbtc::execLQHKEYCONF(Signal* signal) UintR TtcTimer = ctcTimer; regTcPtr->lastLqhCon = tlastLqhConnect; regTcPtr->lastLqhNodeId = refToNode(tlastLqhBlockref); + regTcPtr->noFiredTriggers = noFired; UintR Ttckeyrec = (UintR)regApiPtr->tckeyrec; UintR TclientData = regTcPtr->clientData; @@ -3576,18 +3576,16 @@ void Dbtc::execLQHKEYCONF(Signal* signal) // will be returned unpacked regTcPtr->attrInfoLen = treadlenAi; } else { - jam(); - regApiPtr->tcSendArray[Ttckeyrec] = TclientData; - regApiPtr->tcSendArray[Ttckeyrec + 1] = treadlenAi; - if ((regTcPtr->noFiredTriggers == 0) && - (regTcPtr->triggeringOperation == RNIL)) { + if (noFired == 0 && regTcPtr->triggeringOperation == RNIL) { jam(); /* - Skip counting triggering operations the first round - since they will enter execLQHKEYCONF a second time - Skip counting internally generated TcKeyReq - */ - regApiPtr->tckeyrec += 2; + * Skip counting triggering operations the first round + * since they will enter execLQHKEYCONF a second time + * Skip counting internally generated TcKeyReq + */ + regApiPtr->tcSendArray[Ttckeyrec] = TclientData; + regApiPtr->tcSendArray[Ttckeyrec + 1] = treadlenAi; + regApiPtr->tckeyrec = Ttckeyrec + 2; }//if }//if if (TdirtyOp == ZTRUE) { @@ -3597,7 +3595,7 @@ void Dbtc::execLQHKEYCONF(Signal* signal) regApiPtr->lqhkeyreqrec = Tlqhkeyreqrec - 1; } else { jam(); - if (regTcPtr->noFiredTriggers == 0) { + if (noFired == 0) { jam(); // No triggers to execute UintR Tlqhkeyconfrec = regApiPtr->lqhkeyconfrec; @@ -3624,10 +3622,9 @@ void Dbtc::execLQHKEYCONF(Signal* signal) Continue triggering operation */ jam(); - regTcPtr->triggeringOperation = RNIL; continueTriggeringOp(signal, opPtr.p); } - } else if (regTcPtr->noFiredTriggers == 0) { + } else if (noFired == 0) { // This operation did not fire any triggers, finish operation jam(); if (regTcPtr->isIndexOp) { @@ -3639,20 +3636,19 @@ void Dbtc::execLQHKEYCONF(Signal* signal) // We have fired triggers jam(); saveTriggeringOpState(signal, regTcPtr); - if (regTcPtr->noReceivedTriggers == regTcPtr->noFiredTriggers) { + if (regTcPtr->noReceivedTriggers == noFired) { ApiConnectRecordPtr transPtr; - + // We have received all data jam(); transPtr.i = TapiConnectptrIndex; transPtr.p = regApiPtr; executeTriggers(signal, &transPtr); } - // else wait for more trigger data + // else wait for more trigger data } }//Dbtc::execLQHKEYCONF() - - + void Dbtc::setupIndexOpReturn(ApiConnectRecord* regApiPtr, TcConnectRecord* regTcPtr) { @@ -4863,16 +4859,8 @@ void Dbtc::execLQHKEYREF(Signal* signal) { const LqhKeyRef * const lqhKeyRef = (LqhKeyRef *)signal->getDataPtr(); jamEntry(); - - handleFailedOperation(signal, lqhKeyRef, true); -} - -void Dbtc::handleFailedOperation(Signal* signal, - const LqhKeyRef * const lqhKeyRef, - bool gotLqhKeyRef) -{ + UintR compare_transid1, compare_transid2; - UintR TtcConnectFilesize = ctcConnectFilesize; /*------------------------------------------------------------------------- * @@ -4891,7 +4879,7 @@ void Dbtc::handleFailedOperation(Signal* signal, * ALREADY COMPLETED (ABORTED). *-----------------------------------------------------------------------*/ tcConnectptr.i = lqhKeyRef->connectPtr; - terrorCode = lqhKeyRef->errorCode; + Uint32 errCode = terrorCode = lqhKeyRef->errorCode; ptrAss(tcConnectptr, tcConnectRecord); TcConnectRecord * const regTcPtr = tcConnectptr.p; if (regTcPtr->tcConnectstate == OS_OPERATING) { @@ -4906,98 +4894,58 @@ void Dbtc::handleFailedOperation(Signal* signal, return; }//if - if (regTcPtr->triggeringOperation != RNIL) { + const ConnectionState state = regApiPtr->apiConnectstate; + const Uint32 triggeringOp = regTcPtr->triggeringOperation; + if (triggeringOp != RNIL) { jam(); // This operation was created by a trigger execting operation TcConnectRecordPtr opPtr; TcConnectRecord *localTcConnectRecord = tcConnectRecord; const Uint32 currentIndexId = regTcPtr->currentIndexId; + ndbassert(currentIndexId != 0); // Only index triggers so far - opPtr.i = regTcPtr->triggeringOperation; + opPtr.i = triggeringOp; ptrCheckGuard(opPtr, ctcConnectFilesize, localTcConnectRecord); - if (currentIndexId != RNIL) - { - jam(); - // The operation executed an index trigger - TcIndexData* indexData = NULL; - indexData = c_theIndexes.getPtr(currentIndexId); - if (regTcPtr->operation == ZDELETE) { - if (lqhKeyRef->errorCode == ZNOT_FOUND) { - if (indexData->indexState == IS_BUILDING) { - jam(); - /* - If an index trigger fail with delete during index - build phase it just means that the index build has not - yet inserted that tuple - Check if operation was a delete and part of trigger execution - */ - } else { - jam(); - ndbassert(false); - terrorCode = ZINDEX_CORRUPT_ERROR; - abortErrorLab(signal); - return; - }//if - } else { - terrorCode = lqhKeyRef->errorCode; - abortErrorLab(signal); - return; - } - } else if (regTcPtr->operation == ZINSERT) { - if (lqhKeyRef->errorCode == ZALREADYEXIST) { - terrorCode = 893; //Constraint violation - abortErrorLab(signal); - return; - } else { - terrorCode = lqhKeyRef->errorCode; - abortErrorLab(signal); - } - } else { - ndbrequire(false); - return; - } - markOperationAborted(regApiPtr, regTcPtr); - if (regApiPtr->apiConnectstate == CS_ABORTING) { - jam(); - return; - } - unlinkReadyTcCon(signal); - releaseTcCon(signal); - // Decrease counter as if NOOP - regApiPtr->lqhkeyreqrec--; - opPtr.p->triggerExecutionCount--; - if (opPtr.p->triggerExecutionCount == 0) { - jam(); - /* - We have completed current trigger execution - continue triggering operation - */ - continueTriggeringOp(signal, opPtr.p); - }//if - if (!regApiPtr->theFiredTriggers.isEmpty()) { - jam(); - /* - There are more triggers - Continue with next trigger - */ - executeTriggers(signal, &apiConnectptr); - }//if - return; + + // The operation executed an index trigger + const Uint32 opType = regTcPtr->operation; + if (!(opType == ZDELETE && errCode == ZNOT_FOUND)) { + jam(); + /** + * "Normal path" + */ + // fall-through } else { - /** - * Currently the index id is always set for triggering operations - since we only support them for unique hash indexes at the moment. - */ - ndbrequire(false); - return; - } + jam(); + /** ZDELETE && NOT_FOUND */ + TcIndexData* indexData = c_theIndexes.getPtr(currentIndexId); + if(indexData->indexState == IS_BUILDING && state != CS_ABORTING){ + jam(); + /** + * Ignore error + */ + regApiPtr->lqhkeyconfrec++; + + unlinkReadyTcCon(signal); + releaseTcCon(signal); + + opPtr.p->triggerExecutionCount--; + if (opPtr.p->triggerExecutionCount == 0) { + /** + * We have completed current trigger execution + * Continue triggering operation + */ + jam(); + continueTriggeringOp(signal, opPtr.p); + } + return; + } + } } - if (gotLqhKeyRef) { - jam(); - markOperationAborted(regApiPtr, regTcPtr); - }//if - + + markOperationAborted(regApiPtr, regTcPtr); + if(regApiPtr->apiConnectstate == CS_ABORTING){ /** * We're already aborting' so don't send an "extra" TCKEYREF @@ -5006,8 +4954,8 @@ void Dbtc::handleFailedOperation(Signal* signal, return; } - const Uint32 abortOption = regTcPtr->m_execAbortOption; - if (abortOption == TcKeyReq::AbortOnError) { + const Uint32 abort = regTcPtr->m_execAbortOption; + if (abort == TcKeyReq::AbortOnError || triggeringOp != RNIL) { /** * No error is allowed on this operation */ @@ -5035,10 +4983,8 @@ void Dbtc::handleFailedOperation(Signal* signal, bool isIndexOp = regTcPtr->isIndexOp; Uint32 indexOp = tcConnectptr.p->indexOp; Uint32 clientData = regTcPtr->clientData; - if (gotLqhKeyRef) { - unlinkReadyTcCon(signal); /* LINK TC CONNECT RECORD OUT OF */ - releaseTcCon(signal); /* RELEASE THE TC CONNECT RECORD */ - } + unlinkReadyTcCon(signal); /* LINK TC CONNECT RECORD OUT OF */ + releaseTcCon(signal); /* RELEASE THE TC CONNECT RECORD */ setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__); if (isIndexOp) { jam(); @@ -5057,18 +5003,12 @@ void Dbtc::handleFailedOperation(Signal* signal, * IF NO MORE OUTSTANDING LQHKEYREQ'S THEN WE NEED TO * TCKEYCONF (IF THERE IS ANYTHING TO SEND). *---------------------------------------------------------------------*/ - if (gotLqhKeyRef) { - jam(); - regApiPtr->lqhkeyreqrec = regApiPtr->lqhkeyreqrec - 1; - } else { - jam(); - regApiPtr->lqhkeyconfrec = regApiPtr->lqhkeyconfrec + 1; - }//if + regApiPtr->lqhkeyreqrec--; if (regApiPtr->lqhkeyconfrec == regApiPtr->lqhkeyreqrec) { if ((regApiPtr->lqhkeyconfrec == 0) && (regApiPtr->apiConnectstate == CS_START_COMMITTING)) { - - if(abortOption == TcKeyReq::IgnoreError){ + + if(abort == TcKeyReq::IgnoreError){ jam(); regApiPtr->returnsignal = RS_NO_RETURN; abort010Lab(signal); @@ -6289,12 +6229,21 @@ void Dbtc::sendAbortedAfterTimeout(Signal* signal, int Tcheck) transP->firstTcConnect, c_apiConTimer[apiConnectptr.i] ); + ndbout_c("TC: %d: %d state=%d abort==IDLE place: %d fop=%d t: %d", + __LINE__, + apiConnectptr.i, + transP->apiConnectstate, + c_apiConTimer_line[apiConnectptr.i], + transP->firstTcConnect, + c_apiConTimer[apiConnectptr.i] + ); + ndbrequire(false); setApiConTimer(apiConnectptr.i, 0, __LINE__); return; } OperationState tmp[16]; - + Uint32 TloopCount = 0; do { jam(); @@ -6316,6 +6265,8 @@ void Dbtc::sendAbortedAfterTimeout(Signal* signal, int Tcheck) snprintf(buf, sizeof(buf), buf2); } warningEvent(buf); + ndbout_c(buf); + ndbrequire(false); releaseAbortResources(signal); return; }//if @@ -7919,8 +7870,8 @@ void Dbtc::initApiConnectFail(Signal* signal) tblockref = calcTcBlockRef(tcNodeFailptr.p->takeOverNode); apiConnectptr.p->tcBlockref = tblockref; - apiConnectptr.p->ndbapiBlockref = tapplRef; - apiConnectptr.p->ndbapiConnect = tapplOprec; + apiConnectptr.p->ndbapiBlockref = 0; + apiConnectptr.p->ndbapiConnect = 0; apiConnectptr.p->buddyPtr = RNIL; setApiConTimer(apiConnectptr.i, 0, __LINE__); switch(ttransStatus){ @@ -9821,6 +9772,7 @@ void Dbtc::sendScanFragReq(Signal* signal) { ScanFragReq::setReadCommittedFlag(requestInfo, scanptr.p->readCommitted); ScanFragReq::setRangeScanFlag(requestInfo, scanptr.p->rangeScan); ScanFragReq::setAttrLen(requestInfo, scanptr.p->scanAiLength); + ScanFragReq::setScanPrio(requestInfo, 1); apiConnectptr.i = scanptr.p->scanApiRec; ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); ScanFragReq * const req = (ScanFragReq *)&signal->theData[0]; @@ -11195,34 +11147,52 @@ void Dbtc::execALTER_INDX_REQ(Signal* signal) void Dbtc::execFIRE_TRIG_ORD(Signal* signal) { jamEntry(); - FireTrigOrd * const fireTrigOrd = (FireTrigOrd *)signal->getDataPtr(); + FireTrigOrd * const fireOrd = (FireTrigOrd *)signal->getDataPtr(); ApiConnectRecord *localApiConnectRecord = apiConnectRecord; ApiConnectRecordPtr transPtr; TcConnectRecord *localTcConnectRecord = tcConnectRecord; TcConnectRecordPtr opPtr; - - opPtr.i = fireTrigOrd->getConnectionPtr(); - ptrCheckGuard(opPtr, ctcConnectFilesize, localTcConnectRecord); - transPtr.i = opPtr.p->apiConnect; - transPtr.p = &localApiConnectRecord[transPtr.i]; - if(opPtr.p->triggerError == 0){ - scheduleFiredTrigger(&transPtr, &opPtr); - } - - // If we have received complete info of all fired triggers - // then execute the triggers - if (++(opPtr.p->noReceivedTriggers) == opPtr.p->noFiredTriggers) { + + /** + * TODO + * Check transid, + * Fix overload i.e invalid word count + */ + TcFiredTriggerData key; + key.fireingOperation = fireOrd->getConnectionPtr(); + key.nodeId = refToNode(signal->getSendersBlockRef()); + FiredTriggerPtr trigPtr; + if(c_firedTriggerHash.find(trigPtr, key)){ + + c_firedTriggerHash.remove(trigPtr); + + bool ok = trigPtr.p->keyValues.getSize() == fireOrd->m_noPrimKeyWords; + ok &= trigPtr.p->afterValues.getSize() == fireOrd->m_noAfterValueWords; + ok &= trigPtr.p->beforeValues.getSize() == fireOrd->m_noBeforeValueWords; + if(ok){ + opPtr.i = key.fireingOperation; + ptrCheckGuard(opPtr, ctcConnectFilesize, localTcConnectRecord); + transPtr.i = opPtr.p->apiConnect; + transPtr.p = &localApiConnectRecord[transPtr.i]; + + opPtr.p->noReceivedTriggers++; + opPtr.p->triggerExecutionCount++; + + // Insert fired trigger in execution queue + transPtr.p->theFiredTriggers.add(trigPtr); + if (opPtr.p->noReceivedTriggers == opPtr.p->noFiredTriggers) { + executeTriggers(signal, &transPtr); + } + return; + } jam(); - if (opPtr.p->triggerError != 0) { - jam(); - // Abort transaction - apiConnectptr.i = transPtr.i; - terrorCode = opPtr.p->triggerError; - abortErrorLab(signal); - return; - }//if - executeTriggers(signal, &transPtr); - }//if + c_theFiredTriggerPool.release(trigPtr); + } + jam(); + /** + * Failed to find record or invalid word counts + */ + ndbrequire(false); } void Dbtc::execTRIG_ATTRINFO(Signal* signal) @@ -11231,91 +11201,57 @@ void Dbtc::execTRIG_ATTRINFO(Signal* signal) TrigAttrInfo * const trigAttrInfo = (TrigAttrInfo *)signal->getDataPtr(); Uint32 attrInfoLength = signal->getLength() - TrigAttrInfo::StaticLength; const Uint32 *src = trigAttrInfo->getData(); - TcFiredTriggerData* currentTrigger; FiredTriggerPtr firedTrigPtr; - TcConnectRecord *localTcConnectRecord = tcConnectRecord; - TcConnectRecordPtr opPtr; - opPtr.i = trigAttrInfo->getConnectionPtr(); - ptrCheckGuard(opPtr, ctcConnectFilesize, localTcConnectRecord); - - if (opPtr.p->accumulatingTriggerData.p) { - jam(); - // We are already accumulating - } else { + TcFiredTriggerData key; + key.fireingOperation = trigAttrInfo->getConnectionPtr(); + key.nodeId = refToNode(signal->getSendersBlockRef()); + if(!c_firedTriggerHash.find(firedTrigPtr, key)){ jam(); - // Allocate new trigger record - ApiConnectRecord *localApiConnectRecord = apiConnectRecord; - ApiConnectRecordPtr transPtr; - - transPtr.i = opPtr.p->apiConnect; - //transPtr.p = &localApiConnectRecord[transPtr.i]; - ptrCheckGuard(transPtr, capiConnectFilesize, localApiConnectRecord); - if (!c_theFiredTriggerPool.seize(firedTrigPtr)) { + if(!c_firedTriggerHash.seize(firedTrigPtr)){ jam(); - // Resource shortage, abort transaction - // Mark transaction for abortion -#ifdef VM_TRACE - ndbout_c("Dbtc::execTRIG_ATTRINFO: Failed to seize fired triggers\n"); - ndbout_c("%u: Trigger error = %u\n", __LINE__, 4000); -#endif - opPtr.p->triggerError = 4000; - return; - }//if - ndbrequire(firedTrigPtr.p->keyValues.isEmpty() && - firedTrigPtr.p->beforeValues.isEmpty() && - firedTrigPtr.p->afterValues.isEmpty()); + /** + * Will be handled when FIRE_TRIG_ORD arrives + */ + ndbout_c("op: %d node: %d failed to seize", + key.fireingOperation, key.nodeId); + return; + } + ndbrequire(firedTrigPtr.p->keyValues.getSize() == 0 && + firedTrigPtr.p->beforeValues.getSize() == 0 && + firedTrigPtr.p->afterValues.getSize() == 0); + + firedTrigPtr.p->nodeId = refToNode(signal->getSendersBlockRef()); + firedTrigPtr.p->fireingOperation = key.fireingOperation; firedTrigPtr.p->triggerId = trigAttrInfo->getTriggerId(); - opPtr.p->accumulatingTriggerData = firedTrigPtr; - firedTrigPtr.p->fireingOperation = opPtr.i; - }//if - currentTrigger = opPtr.p->accumulatingTriggerData.p; + c_firedTriggerHash.add(firedTrigPtr); + } + + AttributeBuffer::DataBufferPool & pool = c_theAttributeBufferPool; switch (trigAttrInfo->getAttrInfoType()) { case(TrigAttrInfo::PRIMARY_KEY): jam(); - if (currentTrigger->keyValues.append(src, attrInfoLength) == false) { - jam(); - // Mark transaction for abortion -#ifdef VM_TRACE - ndbout_c("Dbtc::execTRIG_ATTRINFO: Failed to seize keyValues\n"); - ndbout_c("%u: Trigger error = %u\n", __LINE__, 4000); -#endif - opPtr.p->triggerError = 4000; - // Return trigger to pool - c_theFiredTriggerPool.release(opPtr.p->accumulatingTriggerData.i); - return; + { + LocalDataBuffer<11> buf(pool, firedTrigPtr.p->keyValues); + buf.append(src, attrInfoLength); } break; case(TrigAttrInfo::BEFORE_VALUES): jam(); - if (currentTrigger->beforeValues.append(src, attrInfoLength) == false) { - jam(); - // Mark transaction for abortion -#ifdef VM_TRACE - ndbout_c("Dbtc::execTRIG_ATTRINFO: Failed to seize beforeValues\n"); - ndbout_c("%u: Trigger error = %u\n", __LINE__, 4000); -#endif - opPtr.p->triggerError = 4000; - // Return trigger to pool - c_theFiredTriggerPool.release(opPtr.p->accumulatingTriggerData.i); - return; + { + LocalDataBuffer<11> buf(pool, firedTrigPtr.p->beforeValues); + buf.append(src, attrInfoLength); } break; case(TrigAttrInfo::AFTER_VALUES): jam(); - if (currentTrigger->afterValues.append(src, attrInfoLength) == false) { - jam(); - // Mark transaction for abortion -#ifdef VM_TRACE - ndbout_c("Dbtc::execTRIG_ATTRINFO: Failed to seize afterValues\n"); - ndbout_c("%u: Trigger error = %u\n", __LINE__, 4000); -#endif - opPtr.p->triggerError = 4000; - // Return trigger to pool - c_theFiredTriggerPool.release(opPtr.p->accumulatingTriggerData.i); - return; + { + LocalDataBuffer<11> buf(pool, firedTrigPtr.p->afterValues); + buf.append(src, attrInfoLength); } break; + default: + ndbrequire(false); } } @@ -12342,46 +12278,18 @@ void Dbtc::saveTriggeringOpState(Signal* signal, TcConnectRecord* trigOp) LqhKeyConf::SignalLength); } -void Dbtc::restoreTriggeringOpState(Signal* signal, TcConnectRecord* trigOp) +void Dbtc::continueTriggeringOp(Signal* signal, TcConnectRecord* trigOp) { LqhKeyConf * lqhKeyConf = (LqhKeyConf *)signal->getDataPtr(); copyFromToLen(&trigOp->savedState[0], (UintR*)lqhKeyConf, LqhKeyConf::SignalLength); - lqhKeyConf->noFiredTriggers = 0; -} -void Dbtc::continueTriggeringOp(Signal* signal, TcConnectRecord* trigOp) -{ - restoreTriggeringOpState(signal, trigOp); + lqhKeyConf->noFiredTriggers = 0; trigOp->noReceivedTriggers = 0; - if (trigOp->triggerError != 0) { - // A trigger operation has failed - LqhKeyConf * lqhKeyConf = (LqhKeyConf *)signal->getDataPtr(); - LqhKeyRef * lqhKeyRef = (LqhKeyRef *)signal->getDataPtrSend(); - // Copy fields to avoid overwrite - Uint32 opPtr = lqhKeyConf->opPtr; - Uint32 userRef = lqhKeyConf->userRef; - Uint32 transId1 = lqhKeyConf->transId1; - Uint32 transId2 = lqhKeyConf->transId2; - - lqhKeyRef->connectPtr = opPtr; - lqhKeyRef->userRef = userRef; - if (trigOp->triggerError == 630) { // Tuple already existed - jam(); - lqhKeyRef->errorCode = 893; // Constraint violation - } else { - jam(); - lqhKeyRef->errorCode = trigOp->triggerError; - }//if - lqhKeyRef->transId1 = transId1; - lqhKeyRef->transId2 = transId2; - handleFailedOperation(signal, lqhKeyRef, false); - } else { - jam(); - // All triggers executed successfully, continue operation - execLQHKEYCONF(signal); - }//if + + // All triggers executed successfully, continue operation + execLQHKEYCONF(signal); } void Dbtc::scheduleFiredTrigger(ApiConnectRecordPtr* transPtr, @@ -12389,7 +12297,7 @@ void Dbtc::scheduleFiredTrigger(ApiConnectRecordPtr* transPtr, { // Set initial values for trigger fireing operation opPtr->p->triggerExecutionCount++; - opPtr->p->triggerError = 0; + // Insert fired trigger in execution queue transPtr->p->theFiredTriggers.add(opPtr->p->accumulatingTriggerData); opPtr->p->accumulatingTriggerData.i = RNIL; @@ -12414,9 +12322,7 @@ void Dbtc::executeTriggers(Signal* signal, ApiConnectRecordPtr* transPtr) // Execute all ready triggers in parallel opPtr.i = trigPtr.p->fireingOperation; ptrCheckGuard(opPtr, ctcConnectFilesize, localTcConnectRecord); - FiredTriggerPtr nextTrigPtr; - nextTrigPtr.i = trigPtr.i; - nextTrigPtr.p = trigPtr.p; + FiredTriggerPtr nextTrigPtr = trigPtr; regApiPtr->theFiredTriggers.next(nextTrigPtr); if (opPtr.p->noReceivedTriggers == opPtr.p->noFiredTriggers) { jam(); @@ -12425,9 +12331,13 @@ void Dbtc::executeTriggers(Signal* signal, ApiConnectRecordPtr* transPtr) // Should allow for interleaving here by sending a CONTINUEB and // return // Release trigger records - trigPtr.p->keyValues.release(); - trigPtr.p->beforeValues.release(); - trigPtr.p->afterValues.release(); + AttributeBuffer::DataBufferPool & pool = c_theAttributeBufferPool; + LocalDataBuffer<11> tmp1(pool, trigPtr.p->keyValues); + tmp1.release(); + LocalDataBuffer<11> tmp2(pool, trigPtr.p->beforeValues); + tmp2.release(); + LocalDataBuffer<11> tmp3(pool, trigPtr.p->afterValues); + tmp3.release(); regApiPtr->theFiredTriggers.release(trigPtr.i); } trigPtr = nextTrigPtr; @@ -12515,9 +12425,15 @@ void Dbtc::releaseFiredTriggerData(DLFifoList<TcFiredTriggerData>* triggers) while (trigPtr.i != RNIL) { jam(); // Release trigger records - trigPtr.p->keyValues.release(); - trigPtr.p->beforeValues.release(); - trigPtr.p->afterValues.release(); + + AttributeBuffer::DataBufferPool & pool = c_theAttributeBufferPool; + LocalDataBuffer<11> tmp1(pool, trigPtr.p->keyValues); + tmp1.release(); + LocalDataBuffer<11> tmp2(pool, trigPtr.p->beforeValues); + tmp2.release(); + LocalDataBuffer<11> tmp3(pool, trigPtr.p->afterValues); + tmp3.release(); + triggers->next(trigPtr); } triggers->release(); @@ -12551,30 +12467,30 @@ void Dbtc::insertIntoIndexTable(Signal* signal, opRecord->triggerExecutionCount++; }//if // Calculate key length and renumber attribute id:s - for(bool moreKeyAttrs = firedTriggerData->afterValues.first(iter); - moreKeyAttrs; - attrId++) { + AttributeBuffer::DataBufferPool & pool = c_theAttributeBufferPool; + LocalDataBuffer<11> afterValues(pool, firedTriggerData->afterValues); + for(bool moreKeyAttrs = afterValues.first(iter); moreKeyAttrs; attrId++) { jam(); AttributeHeader* attrHeader = (AttributeHeader *) iter.data; attrHeader->setAttributeId(attrId); keyLength += attrHeader->getDataSize(); hops = attrHeader->getHeaderSize() + attrHeader->getDataSize(); - moreKeyAttrs = firedTriggerData->afterValues.next(iter, hops); + moreKeyAttrs = afterValues.next(iter, hops); } // Filter out single NULL attributes if (attrId == 1) { jam(); - firedTriggerData->afterValues.first(iter); + afterValues.first(iter); AttributeHeader* attrHeader = (AttributeHeader *) iter.data; - if (attrHeader->isNULL() && !firedTriggerData->afterValues.next(iter)) { + if (attrHeader->isNULL() && !afterValues.next(iter)) { jam(); opRecord->triggerExecutionCount--; if (opRecord->triggerExecutionCount == 0) { /* - We have completed current trigger execution - Continue triggering operation + We have completed current trigger execution + Continue triggering operation */ jam(); continueTriggeringOp(signal, opRecord); @@ -12584,20 +12500,19 @@ void Dbtc::insertIntoIndexTable(Signal* signal, }//if // Calculate total length of primary key to be stored in index table - for(bool moreAttrData = firedTriggerData->keyValues.first(iter); - (moreAttrData); - moreAttrData = firedTriggerData->keyValues.next(iter, hops)) { + LocalDataBuffer<11> keyValues(pool, firedTriggerData->keyValues); + for(bool moreAttrData = keyValues.first(iter); moreAttrData; ) { jam(); AttributeHeader* attrHeader = (AttributeHeader *) iter.data; totalPrimaryKeyLength += attrHeader->getDataSize(); hops = attrHeader->getHeaderSize() + attrHeader->getDataSize(); + moreAttrData = keyValues.next(iter, hops); } AttributeHeader pkAttrHeader(attrId, totalPrimaryKeyLength); - + TcKeyReq::setKeyLength(tcKeyRequestInfo, keyLength); - tcKeyReq->attrLen = - firedTriggerData->afterValues.getSize() + + tcKeyReq->attrLen = afterValues.getSize() + pkAttrHeader.getHeaderSize() + pkAttrHeader.getDataSize(); tcKeyReq->tableId = indexData->indexId; TcKeyReq::setOperationType(tcKeyRequestInfo, ZINSERT); @@ -12611,15 +12526,14 @@ void Dbtc::insertIntoIndexTable(Signal* signal, Uint32 attrBufSize = 5; // Maximum for key in TCKEYREQ Uint32 dataPos = 0; // Filter out AttributeHeader:s since this should no be in key - bool moreKeyData = firedTriggerData->afterValues.first(iter); + bool moreKeyData = afterValues.first(iter); Uint32 headerSize = 0, keyAttrSize = 0, dataSize = 0, headAndData = 0; - while (moreKeyData && - (dataPos < keyBufSize)) { + while (moreKeyData && (dataPos < keyBufSize)) { /* - If we have not read complete key - and it fits in the signal - */ + * If we have not read complete key + * and it fits in the signal + */ jam(); AttributeHeader* attrHeader = (AttributeHeader *) iter.data; @@ -12629,19 +12543,18 @@ void Dbtc::insertIntoIndexTable(Signal* signal, // Skip header if (headerSize == 1) { jam(); - moreKeyData = firedTriggerData->afterValues.next(iter); + moreKeyData = afterValues.next(iter); } else { jam(); - moreKeyData = firedTriggerData->afterValues.next(iter, headerSize - 1); + moreKeyData = afterValues.next(iter, headerSize - 1); }//if - while((keyAttrSize != 0) && - (dataPos < keyBufSize)) { + while((keyAttrSize != 0) && (dataPos < keyBufSize)) { // If we have not read complete key jam(); *dataPtr++ = *iter.data; dataPos++; keyAttrSize--; - moreKeyData = firedTriggerData->afterValues.next(iter); + moreKeyData = afterValues.next(iter); } if (keyAttrSize != 0) { jam(); @@ -12650,8 +12563,7 @@ void Dbtc::insertIntoIndexTable(Signal* signal, } tcKeyLength += dataPos; - Uint32 attributesLength = - firedTriggerData->afterValues.getSize() + + Uint32 attributesLength = afterValues.getSize() + pkAttrHeader.getHeaderSize() + pkAttrHeader.getDataSize(); if (attributesLength <= attrBufSize) { jam(); @@ -12660,16 +12572,16 @@ void Dbtc::insertIntoIndexTable(Signal* signal, TcKeyReq::setAIInTcKeyReq(tcKeyRequestInfo, attributesLength); bool moreAttrData; // Insert primary key attributes (insert after values of primary table) - for(moreAttrData = firedTriggerData->afterValues.first(iter); + for(moreAttrData = afterValues.first(iter); moreAttrData; - moreAttrData = firedTriggerData->afterValues.next(iter)) { + moreAttrData = afterValues.next(iter)) { *dataPtr++ = *iter.data; } // Insert attribute values (insert key values of primary table) // as one attribute pkAttrHeader.insertHeader(dataPtr); dataPtr += pkAttrHeader.getHeaderSize(); - moreAttrData = firedTriggerData->keyValues.first(iter); + moreAttrData = keyValues.first(iter); while(moreAttrData) { jam(); AttributeHeader* attrHeader = (AttributeHeader *) iter.data; @@ -12679,15 +12591,15 @@ void Dbtc::insertIntoIndexTable(Signal* signal, // Skip header if (headerSize == 1) { jam(); - moreAttrData = firedTriggerData->keyValues.next(iter); + moreAttrData = keyValues.next(iter); } else { jam(); - moreAttrData = firedTriggerData->keyValues.next(iter, headerSize - 1); + moreAttrData = keyValues.next(iter, headerSize - 1); }//if // Copy attribute data while(dataSize-- != 0) { *dataPtr++ = *iter.data; - moreAttrData = firedTriggerData->keyValues.next(iter); + moreAttrData = keyValues.next(iter); } } tcKeyLength += attributesLength; @@ -12721,8 +12633,7 @@ void Dbtc::insertIntoIndexTable(Signal* signal, dataPtr = (Uint32 *) &keyInfo->keyData; dataPos = 0; // Pack any part of a key attribute that did no fit TCKEYREQ - while((keyAttrSize != 0) && - (dataPos < KeyInfo::DataLength)) { + while((keyAttrSize != 0) && (dataPos < KeyInfo::DataLength)) { // If we have not read complete key *dataPtr++ = *iter.data; dataPos++; @@ -12741,7 +12652,7 @@ void Dbtc::insertIntoIndexTable(Signal* signal, dataPtr = (Uint32 *) &keyInfo->keyData; dataPos = 0; } - moreKeyData = firedTriggerData->afterValues.next(iter); + moreKeyData = afterValues.next(iter); } while(moreKeyData) { @@ -12754,11 +12665,10 @@ void Dbtc::insertIntoIndexTable(Signal* signal, // Skip header if (headerSize == 1) { jam(); - moreKeyData = firedTriggerData->afterValues.next(iter); + moreKeyData = afterValues.next(iter); } else { jam(); - moreKeyData = firedTriggerData->afterValues.next(iter, - headerSize - 1); + moreKeyData = afterValues.next(iter, headerSize - 1); }//if while (keyAttrSize-- != 0) { *dataPtr++ = *iter.data; @@ -12777,7 +12687,7 @@ void Dbtc::insertIntoIndexTable(Signal* signal, dataPtr = (Uint32 *) &keyInfo->keyData; dataPos = 0; } - moreKeyData = firedTriggerData->afterValues.next(iter); + moreKeyData = afterValues.next(iter); } } if (dataPos != 0) { @@ -12810,9 +12720,9 @@ void Dbtc::insertIntoIndexTable(Signal* signal, bool moreAttrData; // Insert primary key attributes (insert after values of primary table) - for(moreAttrData = firedTriggerData->afterValues.first(iter); + for(moreAttrData = afterValues.first(iter); moreAttrData; - moreAttrData = firedTriggerData->afterValues.next(iter)) { + moreAttrData = afterValues.next(iter)) { *dataPtr++ = *iter.data; attrInfoPos++; if (attrInfoPos == AttrInfo::DataLength) { @@ -12835,7 +12745,7 @@ void Dbtc::insertIntoIndexTable(Signal* signal, pkAttrHeader.insertHeader(dataPtr); dataPtr += pkAttrHeader.getHeaderSize(); attrInfoPos += pkAttrHeader.getHeaderSize(); - moreAttrData = firedTriggerData->keyValues.first(iter); + moreAttrData = keyValues.first(iter); while(moreAttrData) { jam(); AttributeHeader* attrHeader = (AttributeHeader *) iter.data; @@ -12845,11 +12755,10 @@ void Dbtc::insertIntoIndexTable(Signal* signal, // Skip header if (headerSize == 1) { jam(); - moreAttrData = firedTriggerData->keyValues.next(iter); + moreAttrData = keyValues.next(iter); } else { jam(); - moreAttrData = firedTriggerData->keyValues.next(iter, - headerSize - 1); + moreAttrData = keyValues.next(iter, headerSize - 1); }//if while(dataSize-- != 0) { // If we have not read complete key if (attrInfoPos == AttrInfo::DataLength) { @@ -12868,7 +12777,7 @@ void Dbtc::insertIntoIndexTable(Signal* signal, } *dataPtr++ = *iter.data; attrInfoPos++; - moreAttrData = firedTriggerData->keyValues.next(iter); + moreAttrData = keyValues.next(iter); } } if (attrInfoPos != 0) { @@ -12913,7 +12822,9 @@ void Dbtc::deleteFromIndexTable(Signal* signal, opRecord->triggerExecutionCount++; }//if // Calculate key length and renumber attribute id:s - for(bool moreKeyAttrs = firedTriggerData->beforeValues.first(iter); + AttributeBuffer::DataBufferPool & pool = c_theAttributeBufferPool; + LocalDataBuffer<11> beforeValues(pool, firedTriggerData->beforeValues); + for(bool moreKeyAttrs = beforeValues.first(iter); (moreKeyAttrs); attrId++) { jam(); @@ -12922,15 +12833,15 @@ void Dbtc::deleteFromIndexTable(Signal* signal, attrHeader->setAttributeId(attrId); keyLength += attrHeader->getDataSize(); hops = attrHeader->getHeaderSize() + attrHeader->getDataSize(); - moreKeyAttrs = firedTriggerData->beforeValues.next(iter, hops); + moreKeyAttrs = beforeValues.next(iter, hops); } // Filter out single NULL attributes if (attrId == 1) { jam(); - firedTriggerData->beforeValues.first(iter); + beforeValues.first(iter); AttributeHeader* attrHeader = (AttributeHeader *) iter.data; - if (attrHeader->isNULL() && !firedTriggerData->beforeValues.next(iter)) { + if (attrHeader->isNULL() && !beforeValues.next(iter)) { jam(); opRecord->triggerExecutionCount--; if (opRecord->triggerExecutionCount == 0) { @@ -12958,7 +12869,7 @@ void Dbtc::deleteFromIndexTable(Signal* signal, Uint32 keyBufSize = 8; // Maximum for key in TCKEYREQ Uint32 dataPos = 0; // Filter out AttributeHeader:s since this should no be in key - bool moreKeyData = firedTriggerData->beforeValues.first(iter); + bool moreKeyData = beforeValues.first(iter); Uint32 headerSize = 0, keyAttrSize = 0, headAndData = 0; while (moreKeyData && @@ -12976,10 +12887,10 @@ void Dbtc::deleteFromIndexTable(Signal* signal, // Skip header if (headerSize == 1) { jam(); - moreKeyData = firedTriggerData->beforeValues.next(iter); + moreKeyData = beforeValues.next(iter); } else { jam(); - moreKeyData = firedTriggerData->beforeValues.next(iter, headerSize - 1); + moreKeyData = beforeValues.next(iter, headerSize - 1); }//if while((keyAttrSize != 0) && (dataPos < keyBufSize)) { @@ -12988,7 +12899,7 @@ void Dbtc::deleteFromIndexTable(Signal* signal, *dataPtr++ = *iter.data; dataPos++; keyAttrSize--; - moreKeyData = firedTriggerData->beforeValues.next(iter); + moreKeyData = beforeValues.next(iter); } if (keyAttrSize != 0) { jam(); @@ -13042,7 +12953,7 @@ void Dbtc::deleteFromIndexTable(Signal* signal, dataPtr = (Uint32 *) &keyInfo->keyData; dataPos = 0; } - moreKeyData = firedTriggerData->beforeValues.next(iter); + moreKeyData = beforeValues.next(iter); } while(moreKeyData) { @@ -13055,10 +12966,10 @@ void Dbtc::deleteFromIndexTable(Signal* signal, // Skip header if (headerSize == 1) { jam(); - moreKeyData = firedTriggerData->beforeValues.next(iter); + moreKeyData = beforeValues.next(iter); } else { jam(); - moreKeyData = firedTriggerData->beforeValues.next(iter, + moreKeyData = beforeValues.next(iter, headerSize - 1); }//if while (keyAttrSize-- != 0) { @@ -13078,7 +12989,7 @@ void Dbtc::deleteFromIndexTable(Signal* signal, dataPtr = (Uint32 *) &keyInfo->keyData; dataPos = 0; } - moreKeyData = firedTriggerData->beforeValues.next(iter); + moreKeyData = beforeValues.next(iter); } } if (dataPos != 0) { diff --git a/ndb/src/kernel/blocks/dbutil/DbUtil.cpp b/ndb/src/kernel/blocks/dbutil/DbUtil.cpp index 3936a211d4b..2cb129bc591 100644 --- a/ndb/src/kernel/blocks/dbutil/DbUtil.cpp +++ b/ndb/src/kernel/blocks/dbutil/DbUtil.cpp @@ -1870,6 +1870,7 @@ DbUtil::execUTIL_EXECUTE_REQ(Signal* signal) } releaseSections(signal); + transPtr.p->noOfRetries = 3; runTransaction(signal, transPtr); } @@ -2287,6 +2288,21 @@ DbUtil::execTCROLLBACKREP(Signal* signal){ ndbout << "Transaction error (code: " << errCode << ")" << endl; #endif + if(transPtr.p->noOfRetries > 0){ + transPtr.p->noOfRetries--; + switch(errCode){ + case 266: + case 410: + case 1204: +#if 0 + ndbout_c("errCode: %d noOfRetries: %d -> retry", + errCode, transPtr.p->noOfRetries); +#endif + runTransaction(signal, transPtr); + return; + } + } + transPtr.p->errorCode = errCode; finishTransaction(signal, transPtr); } diff --git a/ndb/src/kernel/blocks/dbutil/DbUtil.hpp b/ndb/src/kernel/blocks/dbutil/DbUtil.hpp index 8ab2fe8d8d0..c6e15a3c539 100644 --- a/ndb/src/kernel/blocks/dbutil/DbUtil.hpp +++ b/ndb/src/kernel/blocks/dbutil/DbUtil.hpp @@ -341,6 +341,7 @@ public: SLList<Operation> operations; Uint32 errorCode; + Uint32 noOfRetries; Uint32 sent; // No of operations sent Uint32 recv; // No of completed operations received inline bool complete() const { return sent == recv; }; @@ -401,7 +402,7 @@ public: KeyInfoIterator & kit); void sendAttrInfo(Signal*, AttrInfo* attrInfo, - const AttrInfoBuffer & attrInfo, + const AttrInfoBuffer &, AttrInfoIterator & ait); int getResultSet(Signal* signal, const Transaction * transP, struct LinearSectionPtr sectionsPtr[]); diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp index 6f30ff2c511..4211645ace6 100644 --- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp +++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp @@ -2933,6 +2933,11 @@ Ndbcntr::execSTOP_REQ(Signal* signal){ return; } } + + signal->theData[0] = EventReport::NDBStopStarted; + signal->theData[1] = StopReq::getSystemStop(c_stopRec.stopReq.requestInfo) ? 1 : 0; + sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); + NodeState newState(NodeState::SL_STOPPING_1, StopReq::getSystemStop(c_stopRec.stopReq.requestInfo)); @@ -3022,6 +3027,10 @@ Ndbcntr::StopRecord::checkNodeFail(Signal* signal){ NodeState newState(NodeState::SL_STARTED); cntr.updateNodeState(signal, newState); + + signal->theData[0] = EventReport::NDBStopAborted; + cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB); + return false; } diff --git a/ndb/src/kernel/blocks/ndbfs/Filename.cpp b/ndb/src/kernel/blocks/ndbfs/Filename.cpp index 98ff7c7e4e4..c0bc52b4501 100644 --- a/ndb/src/kernel/blocks/ndbfs/Filename.cpp +++ b/ndb/src/kernel/blocks/ndbfs/Filename.cpp @@ -184,7 +184,7 @@ Filename::set(BlockReference blockReference, strcat(theName, fileExtension[type]); if(dir == true){ - for(Uint32 l = strlen(theName) - 1; l >= 0; l--){ + for(int l = strlen(theName) - 1; l >= 0; l--){ if(theName[l] == DIR_SEPARATOR[0]){ theName[l] = 0; break; diff --git a/ndb/src/kernel/blocks/suma/Suma.cpp b/ndb/src/kernel/blocks/suma/Suma.cpp index 236333f58e4..9718845de43 100644 --- a/ndb/src/kernel/blocks/suma/Suma.cpp +++ b/ndb/src/kernel/blocks/suma/Suma.cpp @@ -1906,7 +1906,8 @@ SumaParticipant::execSCAN_FRAGCONF(Signal* signal){ const Uint32 completed = conf->fragmentCompleted; const Uint32 senderData = conf->senderData; - + const Uint32 completedOps = conf->completedOps; + SubscriptionPtr subPtr; c_subscriptions.getPtr(subPtr, senderData); @@ -1922,12 +1923,14 @@ SumaParticipant::execSCAN_FRAGCONF(Signal* signal){ #else SubSyncContinueReq * const req = (SubSyncContinueReq*)signal->getDataPtrSend(); req->subscriberData = subPtr.p->m_subscriberData; - req->noOfRowsSent = 0; //rowCount; + req->noOfRowsSent = completedOps; sendSignal(subPtr.p->m_subscriberRef, GSN_SUB_SYNC_CONTINUE_REQ, signal, SubSyncContinueReq::SignalLength, JBB); #endif return; } + + ndbrequire(completedOps == 0); SyncRecord* tmp = c_syncPool.getPtr(subPtr.p->m_syncPtrI); diff --git a/ndb/src/kernel/error/Error.hpp b/ndb/src/kernel/error/Error.hpp index d10c69b327a..e19d6782793 100644 --- a/ndb/src/kernel/error/Error.hpp +++ b/ndb/src/kernel/error/Error.hpp @@ -34,7 +34,7 @@ * */ -typedef enum ErrorCategory +enum ErrorCategory { warning, ecError, diff --git a/ndb/src/kernel/ndb-main/Main.cpp b/ndb/src/kernel/ndb-main/Main.cpp index ca3bfa32a59..88fd9d177de 100644 --- a/ndb/src/kernel/ndb-main/Main.cpp +++ b/ndb/src/kernel/ndb-main/Main.cpp @@ -28,6 +28,7 @@ #include <WatchDog.hpp> #include <LogLevel.hpp> +#include <EventLogger.hpp> #include <NodeState.hpp> #if defined NDB_SOLARIS @@ -37,16 +38,17 @@ #if !defined NDB_SOFTOSE && !defined NDB_OSE #include <signal.h> // For process signals +#endif -extern "C" { - void ndbSignal(int signo, void (*func) (int)); - void handler(int signo); // for process signal handling -}; - -void catchsigs(); // for process signal handling - +extern EventLogger g_eventLogger; +#if defined (NDB_LINUX) || defined (NDB_SOLARIS) +#include <sys/types.h> +#include <sys/wait.h> #endif +void catchsigs(bool ignore); // for process signal handling +extern "C" void handler(int signo); // for process signal handling + // Shows system information void systemInfo(const Configuration & conf, const LogLevel & ll); @@ -55,11 +57,16 @@ const char programName[] = "NDB Kernel"; extern int global_ndb_check; NDB_MAIN(ndb_kernel){ - + global_ndb_check = 1; + // Print to stdout/console + g_eventLogger.createConsoleHandler(); + g_eventLogger.setCategory("NDB"); + g_eventLogger.enable(Logger::LL_INFO, Logger::LL_ALERT); // Log INFO to ALERT + globalEmulatorData.create(); - + // Parse command line options Configuration* theConfig = globalEmulatorData.theConfiguration; if(!theConfig->init(argc, argv)){ @@ -75,6 +82,9 @@ NDB_MAIN(ndb_kernel){ NdbConfig_HomePath(homePath, 255); #if defined (NDB_LINUX) || defined (NDB_SOLARIS) + /** + * This has only been tested with linux & solaris + */ if (theConfig->getDaemonMode()) { // Become a daemon char lockfile[255], logfile[255]; @@ -85,12 +95,54 @@ NDB_MAIN(ndb_kernel){ return 1; } } -#endif + + for(pid_t child = fork(); child != 0; child = fork()){ + /** + * Parent + */ + catchsigs(true); + int status = 0; + while(waitpid(child, &status, 0) != child); + if(WIFEXITED(status) || !theConfig->stopOnError()){ + switch(WEXITSTATUS(status)){ + case NRT_Default: + g_eventLogger.info("Angel shutting down"); + exit(0); + break; + case NRT_NoStart_Restart: + theConfig->setInitialStart(false); + globalData.theRestartFlag = initial_state; + break; + case NRT_NoStart_InitialStart: + theConfig->setInitialStart(true); + globalData.theRestartFlag = initial_state; + break; + case NRT_DoStart_InitialStart: + theConfig->setInitialStart(true); + globalData.theRestartFlag = perform_start; + break; + default: + case NRT_DoStart_Restart: + theConfig->setInitialStart(false); + globalData.theRestartFlag = perform_start; + break; + } + g_eventLogger.info("Ndb has terminated (pid %d) restarting", child); + } else { + /** + * Error shutdown && stopOnError() + */ + exit(0); + } + } + g_eventLogger.info("Angel pid: %d ndb pid: %d", getppid(), getpid()); +#endif + systemInfo(* theConfig, theConfig->clusterConfigurationData().SizeAltData.logLevel); - - // Load blocks + + // Load blocks globalEmulatorData.theSimBlockList->load(* theConfig); // Set thread concurrency for Solaris' light weight processes @@ -106,9 +158,7 @@ NDB_MAIN(ndb_kernel){ globalSignalLoggers.setOutputStream(signalLog); #endif -#if !defined NDB_SOFTOSE && !defined NDB_OSE - catchsigs(); -#endif + catchsigs(false); /** * Do startup @@ -132,7 +182,7 @@ NDB_MAIN(ndb_kernel){ globalEmulatorData.theThreadConfig->ipControlLoop(); NdbShutdown(NST_Normal); - return 0; + return NRT_Default; } @@ -169,131 +219,39 @@ systemInfo(const Configuration & config, const LogLevel & logLevel){ #endif if(logLevel.getLogLevel(LogLevel::llStartUp) > 0){ - ndbout << "-- NDB Cluster -- DB node " << globalData.ownId - << " -- " << NDB_VERSION_STRING << " -- " << endl; + g_eventLogger.info("NDB Cluster -- DB node %d", globalData.ownId); + g_eventLogger.info("%s --", NDB_VERSION_STRING); #ifdef NDB_SOLARIS - ndbout << "NDB is running " - << " on a machine with " << processors - << " processor(s) at " << speed <<" MHz" - << endl; + g_eventLogger.info("NDB is running on a machine with %d processor(s) at %d MHz", + processor, speed); #endif } if(logLevel.getLogLevel(LogLevel::llStartUp) > 3){ Uint32 t = config.timeBetweenWatchDogCheck(); - ndbout << "WatchDog timer is set to " << t << " ms" << endl; + g_eventLogger.info("WatchDog timer is set to %d ms", t); } } -#if !defined NDB_SOFTOSE && !defined NDB_OSE - -#ifdef NDB_WIN32 - -void -catchsigs() -{ - ndbSignal(SIGINT, handler); // 2 - ndbSignal(SIGILL, handler); // 4 - ndbSignal(SIGFPE, handler); // 8 -#ifndef VM_TRACE - ndbSignal(SIGSEGV, handler); // 11 -#endif - ndbSignal(SIGTERM, handler); // 15 - ndbSignal(SIGBREAK, handler); // 21 - ndbSignal(SIGABRT, handler); // 22 -} - -#else - void -catchsigs(){ +catchsigs(bool ignore){ +#if ! defined NDB_SOFTOSE && !defined NDB_OSE // Makes the main process catch process signals, eg installs a // handler named "handler". "handler" will then be called is instead // of the defualt process signal handler) - ndbSignal(SIGHUP, handler); // 1 - ndbSignal(SIGINT, handler); // 2 - ndbSignal(SIGQUIT, handler); // 3 - ndbSignal(SIGILL, handler); // 4 - ndbSignal(SIGTRAP, handler); // 5 -#ifdef NDB_LINUX - ndbSignal(7, handler); -#elif NDB_SOLARIS - ndbSignal(SIGEMT, handler); // 7 -#elif NDB_MACOSX - ndbSignal(SIGEMT, handler); // 7 -#endif - ndbSignal(SIGFPE, handler); // 8 - // SIGKILL cannot be caught, 9 - ndbSignal(SIGBUS, handler); // 10 - ndbSignal(SIGSEGV, handler); // 11 - ndbSignal(SIGSYS, handler); // 12 - ndbSignal(SIGPIPE, handler); // 13 - ndbSignal(SIGALRM, handler); // 14 - ndbSignal(SIGTERM, handler); // 15 - ndbSignal(SIGUSR1, handler); // 16 - ndbSignal(SIGUSR2, handler); // 17 -#ifndef NDB_MACOSX - ndbSignal(SIGPWR, handler); // 19 - ndbSignal(SIGPOLL, handler); // 22 -#endif - // SIGSTOP cannot be caught 23 - ndbSignal(SIGTSTP, handler); // 24 - ndbSignal(SIGTTIN, handler); // 26 - ndbSignal(SIGTTOU, handler); // 27 - ndbSignal(SIGVTALRM, handler); // 28 - ndbSignal(SIGPROF, handler); // 29 - ndbSignal(SIGXCPU, handler); // 30 - ndbSignal(SIGXFSZ, handler); // 31 -} -#endif - -extern "C" -void ndbSignal(int signo, void (*func) (int)) { -#ifdef NDB_WIN32 - signal(signo, func); -#else - struct sigaction act, oact; - act.sa_handler = func; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - if(signo == SIGALRM) { -#ifdef SA_INTERRUPT - act.sa_flags |= SA_INTERRUPT; -#endif + if(ignore){ + for(int i = 1; i<100; i++){ + if(i != SIGCHLD) + signal(i, SIG_IGN); + } } else { -#ifdef SA_RESTART - act.sa_flags |= SA_RESTART; -#endif + for(int i = 1; i<100; i++){ + signal(i, handler); + } } - sigaction(signo, &act, &oact); #endif } - -#ifdef NDB_WIN32 - -extern "C" -void -handler(int sig) -{ - switch(sig){ - case SIGINT: /* 2 - Interrupt */ - case SIGTERM: /* 15 - Terminate */ - case SIGBREAK: /* 21 - Ctrl-Break sequence */ - case SIGABRT: /* 22 - abnormal termination triggered by abort call */ - globalData.theRestartFlag = perform_stop; - break; - default: - // restart the system - char errorData[40]; - snprintf(errorData, 40, "Signal %d received", sig); - ERROR_SET(fatal, 0, errorData, __FILE__); - break; - } -} - -#else - extern "C" void handler(int sig){ @@ -328,9 +286,6 @@ handler(int sig){ } } -#endif -#endif - diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp index 0b680940105..03495449787 100644 --- a/ndb/src/kernel/vm/Configuration.cpp +++ b/ndb/src/kernel/vm/Configuration.cpp @@ -32,6 +32,9 @@ extern "C" { void ndbSetOwnVersion(); } +#include <EventLogger.hpp> +extern EventLogger g_eventLogger; + bool Configuration::init(int argc, const char** argv){ @@ -259,10 +262,6 @@ Configuration::setupConfiguration(){ delete p; - if (_lockPagesInMainMemory) { - NdbMem_MemLockAll(); - } - /** * Create the watch dog thread */ @@ -336,3 +335,8 @@ Configuration::getConnectStringCopy() const { return strdup(_connectString); return 0; } + +void +Configuration::setInitialStart(bool val){ + _initialStart = val; +} diff --git a/ndb/src/kernel/vm/Configuration.hpp b/ndb/src/kernel/vm/Configuration.hpp index e7e3a125394..3f96bb454c5 100644 --- a/ndb/src/kernel/vm/Configuration.hpp +++ b/ndb/src/kernel/vm/Configuration.hpp @@ -62,6 +62,7 @@ public: * */ bool getInitialStart() const; + void setInitialStart(bool val); bool getDaemonMode() const; private: diff --git a/ndb/src/kernel/vm/DLFifoList.hpp b/ndb/src/kernel/vm/DLFifoList.hpp index 0b40d00f56e..91b5b421b0c 100644 --- a/ndb/src/kernel/vm/DLFifoList.hpp +++ b/ndb/src/kernel/vm/DLFifoList.hpp @@ -60,6 +60,11 @@ public: void add(Ptr<T> &); /** + * Remove from list + */ + void remove(Ptr<T> &); + + /** * Return an object to pool */ void release(Uint32 i); @@ -241,14 +246,11 @@ DLFifoList<T>::release(Uint32 i){ p.p = thePool.getPtr(i); release(p); } - -/** - * Return an object to pool - */ + template <class T> inline void -DLFifoList<T>::release(Ptr<T> & p){ +DLFifoList<T>::remove(Ptr<T> & p){ T * t = p.p; Uint32 ni = t->nextList; Uint32 pi = t->prevList; @@ -268,6 +270,16 @@ DLFifoList<T>::release(Ptr<T> & p){ // We are releasing first head.firstItem = ni; } +} + +/** + * Return an object to pool + */ +template <class T> +inline +void +DLFifoList<T>::release(Ptr<T> & p){ + remove(p); thePool.release(p.i); } diff --git a/ndb/src/kernel/vm/Emulator.cpp b/ndb/src/kernel/vm/Emulator.cpp index 43b5619d202..a852e045c6e 100644 --- a/ndb/src/kernel/vm/Emulator.cpp +++ b/ndb/src/kernel/vm/Emulator.cpp @@ -34,11 +34,14 @@ #include <stdlib.h> #include <new> -#ifdef NDB_WIN32 -#include <new.h> -#include <process.h> -#define execvp _execvp -#define set_new_handler _set_new_handler +extern "C" { + extern void (* ndb_new_handler)(); +} + + +#if defined (NDB_LINUX) || defined (NDB_SOLARIS) +#include <sys/types.h> +#include <sys/wait.h> #endif /** @@ -73,7 +76,7 @@ EmulatorData::EmulatorData(){ } void -ndb_new_handler(){ +ndb_new_handler_impl(){ ERROR_SET(fatal, ERR_MEMALLOC, "New handler", ""); } @@ -88,11 +91,7 @@ EmulatorData::create(){ theShutdownMutex = NdbMutex_Create(); -#ifdef NDB_WIN32 - set_new_handler((_PNH)ndb_new_handler); -#else - std::set_new_handler(ndb_new_handler); -#endif + ndb_new_handler = ndb_new_handler_impl; } void @@ -110,60 +109,6 @@ EmulatorData::destroy(){ } void -NdbRestart(char * programName, - NdbRestartType type, char * connString){ -#if ! ( defined NDB_OSE || defined NDB_SOFTOSE) - int argc = 2; - switch(type){ - case NRT_NoStart_Restart: - case NRT_DoStart_InitialStart: - argc = 3; - break; - case NRT_NoStart_InitialStart: - argc = 4; - break; - case NRT_DoStart_Restart: - case NRT_Default: - default: - argc = 2; - break; - } - - if(connString != 0){ - argc += 2; - } - - char ** argv = new char * [argc]; - argv[0] = programName; - argv[argc - 1] = 0; - - switch(type){ - case NRT_NoStart_Restart: - argv[1] = "-n"; - break; - case NRT_DoStart_InitialStart: - argv[1] = "-i"; - break; - case NRT_NoStart_InitialStart: - argv[1] = "-n"; - argv[2] = "-i"; - break; - case NRT_DoStart_Restart: - case NRT_Default: - default: - break; - } - - if(connString != 0){ - argv[argc-3] = "-c"; - argv[argc-2] = connString; - } - - execvp(programName, argv); -#endif -} - -void NdbShutdown(NdbShutdownType type, NdbRestartType restartType){ @@ -181,27 +126,12 @@ NdbShutdown(NdbShutdownType type, globalData.theRestartFlag = perform_stop; bool restart = false; - char * progName = 0; - char * connString = 0; #if ! ( defined NDB_OSE || defined NDB_SOFTOSE) if((type != NST_Normal && globalEmulatorData.theConfiguration->stopOnError() == false) || type == NST_Restart) { restart = true; - progName = strdup(globalEmulatorData.theConfiguration->programName()); - connString = globalEmulatorData.theConfiguration->getConnectStringCopy(); - if(type != NST_Restart){ - /** - * If we crash before we started - * - * Do restart -n - */ - if(globalData.theStartLevel == NodeState::SL_STARTED) - restartType = NRT_Default; - else - restartType = NRT_NoStart_Restart; - } } #endif @@ -238,21 +168,18 @@ NdbShutdown(NdbShutdownType type, #endif if(type == NST_Watchdog){ - if(restart){ - NdbRestart(progName, restartType, connString); - } - /** - * Very serious + * Very serious, don't attempt to free, just die!! */ ndbout << "Watchdog shutdown completed - " << exitAbort << endl; #if defined VM_TRACE && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) ) + signal(6, SIG_DFL); abort(); #else - exit(1); + exit(-1); #endif } - + globalEmulatorData.theWatchDog->doStop(); #ifdef VM_TRACE @@ -265,7 +192,7 @@ NdbShutdown(NdbShutdownType type, globalTransporterRegistry.stopReceiving(); globalTransporterRegistry.removeAll(); - + #ifdef VM_TRACE #define UNLOAD (type != NST_ErrorHandler && type != NST_Watchdog) #else @@ -274,61 +201,44 @@ NdbShutdown(NdbShutdownType type, if(UNLOAD){ globalEmulatorData.theSimBlockList->unload(); globalEmulatorData.destroy(); - } - - if(type != NST_Normal && - type != NST_Restart){ - if(restart){ - NdbRestart(progName, restartType, connString); - } - + + if(type != NST_Normal && type != NST_Restart){ ndbout << "Error handler shutdown completed - " << exitAbort << endl; #if defined VM_TRACE && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) ) + signal(6, SIG_DFL); abort(); #else - exit(1); + exit(-1); #endif } /** - * This is a normal restart + * This is a normal restart, depend on angel */ if(type == NST_Restart){ - if(restart){ - NdbRestart(progName, restartType, connString); - } - /** - * What to do if in restart mode, but being unable to do it... - */ -#if defined VM_TRACE && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) ) - abort(); -#else - exit(1); -#endif + exit(restartType); } - - /** - * This is normal shutdown - */ + ndbout << "Shutdown completed - exiting" << endl; } else { /** * Shutdown is already in progress */ - + /** * If this is the watchdog, kill system the hard way */ if (type== NST_Watchdog){ ndbout << "Watchdog is killing system the hard way" << endl; #if defined VM_TRACE && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) ) + signal(6, SIG_DFL); abort(); #else - exit(1); + exit(-1); #endif } - + while(true) NdbSleep_MilliSleep(10); } diff --git a/ndb/src/kernel/vm/SignalCounter.hpp b/ndb/src/kernel/vm/SignalCounter.hpp index b05d0858867..d572551ea92 100644 --- a/ndb/src/kernel/vm/SignalCounter.hpp +++ b/ndb/src/kernel/vm/SignalCounter.hpp @@ -148,7 +148,7 @@ inline const char * SignalCounter::getText() const { static char buf[255]; - static char nodes[m_nodes.TextLength+1]; + static char nodes[NodeBitmask::TextLength+1]; snprintf(buf, sizeof(buf), "[SignalCounter: m_count=%d %s]", m_count, m_nodes.getText(nodes)); return buf; } diff --git a/ndb/src/kernel/vm/SimulatedBlock.cpp b/ndb/src/kernel/vm/SimulatedBlock.cpp index b9bfcfebc7d..f36b3e43d42 100644 --- a/ndb/src/kernel/vm/SimulatedBlock.cpp +++ b/ndb/src/kernel/vm/SimulatedBlock.cpp @@ -948,7 +948,6 @@ SimulatedBlock::FragmentInfo::FragmentInfo(Uint32 fragId, Uint32 sender){ m_sectionPtrI[0] = RNIL; m_sectionPtrI[1] = RNIL; m_sectionPtrI[2] = RNIL; - m_sectionPtrI[3] = RNIL; } SimulatedBlock::FragmentSendInfo::FragmentSendInfo() diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 45b32169e57..23ceeb15947 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -450,6 +450,8 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId, nodeTypes[nodeId] = NDB_MGM_NODE_TYPE_API; if(type == "DB") nodeTypes[nodeId] = NDB_MGM_NODE_TYPE_NDB; + if(type == "REP") + nodeTypes[nodeId] = NDB_MGM_NODE_TYPE_API; } } diff --git a/ndb/src/mgmsrv/NodeLogLevel.cpp b/ndb/src/mgmsrv/NodeLogLevel.cpp index 67791ca02bf..5271cdb0f2b 100644 --- a/ndb/src/mgmsrv/NodeLogLevel.cpp +++ b/ndb/src/mgmsrv/NodeLogLevel.cpp @@ -40,6 +40,7 @@ NodeLogLevel::getCategory() const { return m_logLevel.theCategories[i]; } + return 0; } int @@ -49,6 +50,7 @@ NodeLogLevel::getLevel() const { return m_logLevel.theLevels[i]; } + return 0; } void diff --git a/ndb/src/ndbapi/ClusterMgr.cpp b/ndb/src/ndbapi/ClusterMgr.cpp index f9c553ab63b..93fb0109669 100644 --- a/ndb/src/ndbapi/ClusterMgr.cpp +++ b/ndb/src/ndbapi/ClusterMgr.cpp @@ -409,9 +409,10 @@ ClusterMgr::reportNodeFailed(NodeId nodeId){ const bool report = (theNode.m_state.startLevel != NodeState::SL_NOTHING); theNode.m_state.startLevel = NodeState::SL_NOTHING; - if(report) + if(report){ theFacade.ReportNodeDead(nodeId); - + } + theNode.nfCompleteRep = false; if(noOfConnectedNodes == 0){ diff --git a/ndb/src/ndbapi/Ndberror.cpp b/ndb/src/ndbapi/Ndberror.cpp index 2aa890b0918..ee668605f0d 100644 --- a/ndb/src/ndbapi/Ndberror.cpp +++ b/ndb/src/ndbapi/Ndberror.cpp @@ -266,7 +266,6 @@ ErrorBundle ErrorCodes[] = { { 707, SE, "No more table metadata records" }, { 708, SE, "No more attribute metadata records" }, { 709, SE, "No such table existed" }, - { 720, SE, "Attribute name reused in table definition" }, { 721, SE, "Table or index with given name already exists" }, { 723, SE, "No such table existed" }, { 736, SE, "Wrong attribute size" }, @@ -293,6 +292,7 @@ ErrorBundle ErrorCodes[] = { /** * Still uncategorized */ + { 720, AE, "Attribute name reused in table definition" }, { 4004, AE, "Attribute name not found in the Table" }, { 4100, AE, "Status Error in NDB" }, diff --git a/ndb/src/rep/rep_version.hpp b/ndb/src/rep/rep_version.hpp index a6af131f4ef..0182f080730 100644 --- a/ndb/src/rep/rep_version.hpp +++ b/ndb/src/rep/rep_version.hpp @@ -25,6 +25,8 @@ #define DBUG +#include <ndb_version.h> + extern "C" void DBUG_PRINT(const char * fmt, ...); @@ -52,7 +54,7 @@ extern int replogEnabled; /** * Used for config id */ -#define REP_VERSION_ID 0 +#define REP_VERSION_ID NDB_VERSION #define MAX_NODE_GROUPS 6 diff --git a/ndb/test/ndbapi/testDict/testDict.cpp b/ndb/test/ndbapi/testDict/testDict.cpp index 40c508efddd..06614690b8d 100644 --- a/ndb/test/ndbapi/testDict/testDict.cpp +++ b/ndb/test/ndbapi/testDict/testDict.cpp @@ -564,7 +564,7 @@ int runTestFragmentTypes(NDBT_Context* ctx, NDBT_Step* step){ goto drop_the_tab; } - if (pTab->equal(*pTab3) == false){ + if (newTab.equal(*pTab3) == false){ ndbout << "It was not equal" << endl; result = NDBT_FAILED; goto drop_the_tab; diff --git a/ndb/test/ndbapi/testIndex/testIndex.cpp b/ndb/test/ndbapi/testIndex/testIndex.cpp index a39c4ac49d5..47db0b3cff7 100644 --- a/ndb/test/ndbapi/testIndex/testIndex.cpp +++ b/ndb/test/ndbapi/testIndex/testIndex.cpp @@ -256,17 +256,18 @@ int createRandomIndex(NDBT_Context* ctx, NDBT_Step* step){ AttribList attrList; attrList.buildAttribList(pTab); - int retries = 10; + int retries = 100; while(retries > 0){ const Uint32 i = rand() % attrList.attriblist.size(); int res = create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], logged); - if (res == SKIP_INDEX) + if (res == SKIP_INDEX){ + retries--; continue; + } if (res == NDBT_FAILED){ - retries--; - continue; + return NDBT_FAILED; } ctx->setProperty("createRandomIndex", i); @@ -1452,22 +1453,22 @@ TESTCASE("BuildDuring", "Test that index build when running transactions work"){ TC_PROPERTY("OrderedIndex", (unsigned)0); TC_PROPERTY("LoggedIndexes", (unsigned)0); - TC_PROPERTY("Threads", 2); // # runTransactions4 + TC_PROPERTY("Threads", 1); // # runTransactions4 INITIALIZER(runClearTable); STEP(runBuildDuring); STEP(runTransactions4); - STEP(runTransactions4); + //STEP(runTransactions4); FINALIZER(runClearTable); } TESTCASE("BuildDuring_O", "Test that index build when running transactions work"){ TC_PROPERTY("OrderedIndex", (unsigned)1); TC_PROPERTY("LoggedIndexes", (unsigned)0); - TC_PROPERTY("Threads", 2); // # runTransactions4 + TC_PROPERTY("Threads", 1); // # runTransactions4 INITIALIZER(runClearTable); STEP(runBuildDuring); STEP(runTransactions4); - STEP(runTransactions4); + //STEP(runTransactions4); FINALIZER(runClearTable); } TESTCASE("UniqueNull", diff --git a/ndb/test/ndbapi/testMgm/testMgm.cpp b/ndb/test/ndbapi/testMgm/testMgm.cpp index 54ca64c6e81..d5b9372cc9b 100644 --- a/ndb/test/ndbapi/testMgm/testMgm.cpp +++ b/ndb/test/ndbapi/testMgm/testMgm.cpp @@ -69,7 +69,6 @@ int create_index_on_pk(Ndb* pNdb, const char* tabName){ } else { ndbout << "OK!" << endl; } - delete tab; return result; } diff --git a/ndb/test/ndbapi/testScan/testScan.cpp b/ndb/test/ndbapi/testScan/testScan.cpp index c48b41ee0b9..dbf91f016d8 100644 --- a/ndb/test/ndbapi/testScan/testScan.cpp +++ b/ndb/test/ndbapi/testScan/testScan.cpp @@ -23,9 +23,18 @@ #include "ScanFunctions.hpp" #include <random.h> +const NdbDictionary::Table * +getTable(Ndb* pNdb, int i){ + const NdbDictionary::Table* t = NDBT_Tables::getTable(i); + if (t == NULL){ + return 0; + } + return pNdb->getDictionary()->getTable(t->getName()); +} -int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ +int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); HugoTransactions hugoTrans(*ctx->getTab()); if (hugoTrans.loadTable(GETNDB(step), records) != 0){ @@ -37,7 +46,8 @@ int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ int runCreateAllTables(NDBT_Context* ctx, NDBT_Step* step){ - return NDBT_Tables::createAllTables(GETNDB(step), false, true); + int a = NDBT_Tables::createAllTables(GETNDB(step), false, true); + return a; } int runDropAllTablesExceptTestTable(NDBT_Context* ctx, NDBT_Step* step){ @@ -64,12 +74,12 @@ int runDropAllTablesExceptTestTable(NDBT_Context* ctx, NDBT_Step* step){ int runLoadAllTables(NDBT_Context* ctx, NDBT_Step* step){ - + int records = ctx->getNumRecords(); for (int i=0; i < NDBT_Tables::getNumTables(); i++){ - const NdbDictionary::Table* tab = NDBT_Tables::getTable(i); - if (tab == NULL){ + const NdbDictionary::Table* tab = getTable(GETNDB(step), i); + if (tab == NULL){ return NDBT_FAILED; } HugoTransactions hugoTrans(*tab); @@ -85,20 +95,20 @@ int runScanReadRandomTable(NDBT_Context* ctx, NDBT_Step* step){ int records = ctx->getNumRecords(); int parallelism = ctx->getProperty("Parallelism", 240); int abort = ctx->getProperty("AbortProb"); - + int i = 0; while (i<loops) { int tabNum = myRandom48(NDBT_Tables::getNumTables()); - const NdbDictionary::Table* tab = NDBT_Tables::getTable(tabNum); + const NdbDictionary::Table* tab = getTable(GETNDB(step), tabNum); if (tab == NULL){ g_info << "tab == NULL" << endl; return NDBT_FAILED; } - + g_info << "Scan reading from table " << tab->getName() << endl; HugoTransactions hugoTrans(*tab); - + g_info << i << ": "; if (hugoTrans.scanReadRecords(GETNDB(step), records, abort, parallelism) != 0){ return NDBT_FAILED; @@ -212,7 +222,7 @@ int runScanRead(NDBT_Context* ctx, NDBT_Step* step){ int i = 0; HugoTransactions hugoTrans(*ctx->getTab()); - while (i<loops) { + while (i<loops && !ctx->isTestStopped()) { g_info << i << ": "; if (hugoTrans.scanReadRecords(GETNDB(step), records, abort, parallelism) != 0){ return NDBT_FAILED; @@ -230,10 +240,10 @@ int runScanReadCommitted(NDBT_Context* ctx, NDBT_Step* step){ int i = 0; HugoTransactions hugoTrans(*ctx->getTab()); - while (i<loops) { + while (i<loops && !ctx->isTestStopped()) { g_info << i << ": "; if (hugoTrans.scanReadCommittedRecords(GETNDB(step), records, - abort, parallelism) != 0){ + abort, parallelism) != 0){ return NDBT_FAILED; } i++; @@ -251,7 +261,7 @@ int runScanReadError(NDBT_Context* ctx, NDBT_Step* step){ int i = 0; HugoTransactions hugoTrans(*ctx->getTab()); - while (i<loops) { + while (i<loops && !ctx->isTestStopped()) { g_info << i << ": "; ndbout << "insertErrorInAllNodes("<<error<<")"<<endl; @@ -988,7 +998,15 @@ TESTCASE("ScanRead488", "When this limit is exceeded the scan will be aborted with errorcode "\ "488."){ INITIALIZER(runLoadTable); - STEPS(runScanRead, 15); + STEPS(runScanRead, 70); + FINALIZER(runClearTable); +} +TESTCASE("ScanRead488Timeout", + ""){ + INITIALIZER(runLoadTable); + TC_PROPERTY("ErrorCode", 5034); + STEPS(runScanRead, 30); + STEP(runScanReadError); FINALIZER(runClearTable); } TESTCASE("ScanRead40", diff --git a/ndb/test/src/HugoTransactions.cpp b/ndb/test/src/HugoTransactions.cpp index b1c55fcc780..1293d395974 100644 --- a/ndb/test/src/HugoTransactions.cpp +++ b/ndb/test/src/HugoTransactions.cpp @@ -794,6 +794,18 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb, return NDBT_FAILED; } } + + const NdbError err = pTrans->getNdbError(); + if( check == -1 ) { + pNdb->closeTransaction(pTrans); + ERR(err); + if (err.status == NdbError::TemporaryError){ + NdbSleep_MilliSleep(50); + goto restart; + } + return NDBT_FAILED; + } + pNdb->closeTransaction(pTrans); g_info << rows << " rows have been updated" << endl; diff --git a/ndb/test/src/NDBT_Tables.cpp b/ndb/test/src/NDBT_Tables.cpp index c7d4f458165..41a38e4fe44 100644 --- a/ndb/test/src/NDBT_Tables.cpp +++ b/ndb/test/src/NDBT_Tables.cpp @@ -760,8 +760,9 @@ NDBT_Tables::createAllTables(Ndb* pNdb, bool _temp, bool existsOk){ tmpTab.setStoredTable(_temp? 0 : 1); int r = pNdb->getDictionary()->createTable(tmpTab); + int err = pNdb->getDictionary()->getNdbError().code; if(r == -1){ - if (existsOk && pNdb->getNdbError().code == 721) + if (existsOk && err == 721) ; else { return NDBT_FAILED; diff --git a/ndb/test/src/NDBT_Test.cpp b/ndb/test/src/NDBT_Test.cpp index e56e699af76..4cd2c96486b 100644 --- a/ndb/test/src/NDBT_Test.cpp +++ b/ndb/test/src/NDBT_Test.cpp @@ -824,6 +824,8 @@ void NDBT_TestSuite::execute(Ndb* ndb, const NdbDictionary::Table* pTab, continue; } pTab2 = pDict->getTable(pTab->getName()); + } else { + pTab2 = pTab; } ctx = new NDBT_Context(); diff --git a/ndb/test/src/UtilTransactions.cpp b/ndb/test/src/UtilTransactions.cpp index 927c0b99bc3..2e6ff360123 100644 --- a/ndb/test/src/UtilTransactions.cpp +++ b/ndb/test/src/UtilTransactions.cpp @@ -352,6 +352,7 @@ UtilTransactions::clearTable3(Ndb* pNdb, NdbScanOperation *pOp; NdbError err; + int par = parallelism; while (true){ restart: if (retryAttempt++ >= retryMax){ @@ -376,7 +377,7 @@ UtilTransactions::clearTable3(Ndb* pNdb, goto failed; } - NdbResultSet * rs = pOp->readTuplesExclusive(parallelism); + NdbResultSet * rs = pOp->readTuplesExclusive(par); if( rs == 0 ) { goto failed; } @@ -411,16 +412,28 @@ UtilTransactions::clearTable3(Ndb* pNdb, ERR(err); pNdb->closeTransaction(pTrans); NdbSleep_MilliSleep(50); + par = 1; goto restart; } goto failed; } } + if(check == -1){ + err = pTrans->getNdbError(); + if(err.status == NdbError::TemporaryError){ + ERR(err); + pNdb->closeTransaction(pTrans); + NdbSleep_MilliSleep(50); + par = 1; + goto restart; + } + goto failed; + } pNdb->closeTransaction(pTrans); return NDBT_OK; } return NDBT_FAILED; - + failed: if(pTrans != 0) pNdb->closeTransaction(pTrans); ERR(err); |