diff options
Diffstat (limited to 'ndb')
30 files changed, 386 insertions, 98 deletions
diff --git a/ndb/include/ndbapi/ndberror.h b/ndb/include/ndbapi/ndberror.h index 2225f68f08d..4d4eddfe617 100644 --- a/ndb/include/ndbapi/ndberror.h +++ b/ndb/include/ndbapi/ndberror.h @@ -93,7 +93,7 @@ typedef ndberror_classification_enum ndberror_classification; const char *ndberror_status_message(ndberror_status); const char *ndberror_classification_message(ndberror_classification); void ndberror_update(ndberror_struct *); -int ndb_error_string(int err_no, char *str, unsigned int size); +int ndb_error_string(int err_no, char *str, int size); #endif /* doxygen skip internal*/ diff --git a/ndb/src/common/util/File.cpp b/ndb/src/common/util/File.cpp index 056b7ff199b..33d6ca1d535 100644 --- a/ndb/src/common/util/File.cpp +++ b/ndb/src/common/util/File.cpp @@ -123,13 +123,25 @@ bool File_class::close() { bool rc = true; + int retval = 0; + if (m_file != NULL) { ::fflush(m_file); - rc = (::fclose(m_file) == 0 ? true : false); - m_file = NULL; // Try again? + retval = ::fclose(m_file); + while ( (retval != 0) && (errno == EINTR) ){ + retval = ::fclose(m_file); + } + if( retval == 0){ + rc = true; + } + else { + rc = false; + ndbout_c("ERROR: Close file error in File.cpp for %s",strerror(errno)); + } } - + m_file = NULL; + return rc; } diff --git a/ndb/src/common/util/InputStream.cpp b/ndb/src/common/util/InputStream.cpp index 1b0e809a047..adeca127eb5 100644 --- a/ndb/src/common/util/InputStream.cpp +++ b/ndb/src/common/util/InputStream.cpp @@ -65,6 +65,5 @@ SocketInputStream::gets(char * buf, int bufLen) { if(res == -1) return 0; - return buf; } diff --git a/ndb/src/common/util/NdbSqlUtil.cpp b/ndb/src/common/util/NdbSqlUtil.cpp index f3d70a5734a..ba451c4dd8b 100644 --- a/ndb/src/common/util/NdbSqlUtil.cpp +++ b/ndb/src/common/util/NdbSqlUtil.cpp @@ -136,7 +136,7 @@ NdbSqlUtil::m_typeList[] = { }, { // 22 Type::Bit, - NULL, + cmpBit, NULL }, { // 23 @@ -679,6 +679,17 @@ NdbSqlUtil::cmpText(const void* info, const void* p1, unsigned n1, const void* p } int +NdbSqlUtil::cmpBit(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) +{ + Uint32 n = (n1 < n2) ? n1 : n2; + char* c1 = (char*)p1; + char* c2 = (char*)p2; + int ret = memcmp(p1, p2, n); + return ret; +} + + +int NdbSqlUtil::cmpTime(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { if (n2 >= 3) { @@ -698,12 +709,6 @@ NdbSqlUtil::cmpTime(const void* info, const void* p1, unsigned n1, const void* p } // not yet -int -NdbSqlUtil::cmpBit(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) -{ - assert(false); - return 0; -} int NdbSqlUtil::cmpLongvarchar(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) diff --git a/ndb/src/common/util/socket_io.cpp b/ndb/src/common/util/socket_io.cpp index ba2794e4374..9401d1cd6d0 100644 --- a/ndb/src/common/util/socket_io.cpp +++ b/ndb/src/common/util/socket_io.cpp @@ -53,10 +53,6 @@ readln_socket(NDB_SOCKET_TYPE socket, int timeout_millis, if(buflen <= 1) return 0; - int sock_flags= fcntl(socket, F_GETFL); - if(fcntl(socket, F_SETFL, sock_flags | O_NONBLOCK) == -1) - return -1; - fd_set readset; FD_ZERO(&readset); FD_SET(socket, &readset); @@ -71,43 +67,70 @@ readln_socket(NDB_SOCKET_TYPE socket, int timeout_millis, } if(selectRes == -1){ - fcntl(socket, F_SETFL, sock_flags); return -1; } - const int t = recv(socket, buf, buflen, MSG_PEEK); - - if(t < 1) + char* ptr = buf; + int len = buflen; + do { - fcntl(socket, F_SETFL, sock_flags); - return -1; - } + int t; + while((t = recv(socket, ptr, len, MSG_PEEK)) == -1 && errno == EINTR); + + if(t < 1) + { + return -1; + } - for(int i=0; i< t;i++) - { - if(buf[i] == '\n'){ - int r= recv(socket, buf, i+1, 0); - buf[i+1]= 0; - if(r < 1) { - fcntl(socket, F_SETFL, sock_flags); - return -1; + + for(int i = 0; i<t; i++) + { + if(ptr[i] == '\n') + { + /** + * Now consume + */ + for (len = 1 + i; len; ) + { + while ((t = recv(socket, ptr, len, 0)) == -1 && errno == EINTR); + if (t < 1) + return -1; + ptr += t; + len -= t; + } + if (i > 0 && buf[i-1] == '\r') + { + buf[i-1] = '\n'; + ptr--; + } + ptr[0]= 0; + return ptr - buf; } - - if(i > 0 && buf[i-1] == '\r'){ - buf[i-1] = '\n'; - buf[i]= '\0'; + } + + for (int tmp = t; tmp; ) + { + while ((t = recv(socket, ptr, tmp, 0)) == -1 && errno == EINTR); + if (t < 1) + { + return -1; } - - fcntl(socket, F_SETFL, sock_flags); - return r; + ptr += t; + len -= t; + tmp -= t; } - } - int r= recv(socket, buf, t, 0); - if(r>=0) - buf[r] = 0; - fcntl(socket, F_SETFL, sock_flags); - return r; + FD_ZERO(&readset); + FD_SET(socket, &readset); + timeout.tv_sec = (timeout_millis / 1000); + timeout.tv_usec = (timeout_millis % 1000) * 1000; + const int selectRes = select(socket + 1, &readset, 0, 0, &timeout); + if(selectRes != 1){ + return -1; + } + } while (len > 0); + + return -1; } extern "C" diff --git a/ndb/src/kernel/blocks/ERROR_codes.txt b/ndb/src/kernel/blocks/ERROR_codes.txt index 74d5df2c1e6..16f5da8a553 100644 --- a/ndb/src/kernel/blocks/ERROR_codes.txt +++ b/ndb/src/kernel/blocks/ERROR_codes.txt @@ -6,7 +6,7 @@ Next DBTUP 4014 Next DBLQH 5043 Next DBDICT 6007 Next DBDIH 7178 -Next DBTC 8038 +Next DBTC 8039 Next CMVMI 9000 Next BACKUP 10022 Next DBUTIL 11002 @@ -287,6 +287,11 @@ ABORT OF TCKEYREQ 8037 : Invalid schema version in TCINDXREQ +------ + +8038 : Simulate API disconnect just after SCAN_TAB_REQ + + CMVMI ----- 9000 Set RestartOnErrorInsert to restart -n diff --git a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp index 44f9917438f..042021bc6e0 100644 --- a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp +++ b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp @@ -91,6 +91,7 @@ Cmvmi::Cmvmi(const Configuration & conf) : addRecSignal(GSN_DUMP_STATE_ORD, &Cmvmi::execDUMP_STATE_ORD); addRecSignal(GSN_TESTSIG, &Cmvmi::execTESTSIG); + addRecSignal(GSN_NODE_START_REP, &Cmvmi::execNODE_START_REP, true); subscriberPool.setSize(5); @@ -340,6 +341,16 @@ void Cmvmi::execSTTOR(Signal* signal) jamEntry(); if (theStartPhase == 1){ 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); return; } else if (theStartPhase == 3) { @@ -360,18 +371,6 @@ void Cmvmi::execSTTOR(Signal* signal) execOPEN_COMREQ(signal); globalData.theStartLevel = NodeState::SL_STARTED; sendSTTORRY(signal); - } 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); } } @@ -425,7 +424,8 @@ void Cmvmi::execOPEN_COMREQ(Signal* signal) if(len == 2){ #ifdef ERROR_INSERT - if (! (ERROR_INSERTED(9000) && c_error_9000_nodes_mask.get(tStartingNode))) + if (! ((ERROR_INSERTED(9000) || ERROR_INSERTED(9002)) + && c_error_9000_nodes_mask.get(tStartingNode))) #endif { globalTransporterRegistry.do_connect(tStartingNode); @@ -446,7 +446,8 @@ void Cmvmi::execOPEN_COMREQ(Signal* signal) jam(); #ifdef ERROR_INSERT - if (ERROR_INSERTED(9000) && c_error_9000_nodes_mask.get(i)) + if ((ERROR_INSERTED(9000) || ERROR_INSERTED(9002)) + && c_error_9000_nodes_mask.get(i)) continue; #endif @@ -697,6 +698,7 @@ Cmvmi::execTEST_ORD(Signal * signal){ // Do nothing break; } + globalSignalLoggers.flushSignalLog(); } #endif @@ -1144,9 +1146,9 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal) } #ifdef ERROR_INSERT - if (arg == 9000) + if (arg == 9000 || arg == 9002) { - SET_ERROR_INSERT_VALUE(9000); + SET_ERROR_INSERT_VALUE(arg); for (Uint32 i = 1; i<signal->getLength(); i++) c_error_9000_nodes_mask.set(signal->theData[i]); } @@ -1193,6 +1195,17 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal) #endif }//Cmvmi::execDUMP_STATE_ORD() +void +Cmvmi::execNODE_START_REP(Signal* signal) +{ +#ifdef ERROR_INSERT + if (ERROR_INSERTED(9002) && signal->theData[0] == getOwnNodeId()) + { + signal->theData[0] = 9001; + execDUMP_STATE_ORD(signal); + } +#endif +} BLOCK_FUNCTIONS(Cmvmi) diff --git a/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp b/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp index f89c8f15e86..d050587e91d 100644 --- a/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp +++ b/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp @@ -72,7 +72,8 @@ private: void handleSET_VAR_REQ(Signal* signal); void execTESTSIG(Signal* signal); - + void execNODE_START_REP(Signal* signal); + char theErrorMessage[256]; void sendSTTORRY(Signal* signal); diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 2eca2a76c45..f922bfdf561 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -10184,6 +10184,15 @@ Dbdict::checkDictLockQueue(Signal* signal, bool poll) break; } + if (c_blockState != BS_IDLE) + { + /** + * If state is BS_NODE_FAILURE, it might be that no op is running + */ + jam(); + break; + } + ndbrequire(c_blockState == BS_IDLE); lockPtr.p->locked = true; c_blockState = lockPtr.p->lt->blockState; diff --git a/ndb/src/kernel/blocks/dbdih/Dbdih.hpp b/ndb/src/kernel/blocks/dbdih/Dbdih.hpp index 53e54e96d2b..f1b3897c76f 100644 --- a/ndb/src/kernel/blocks/dbdih/Dbdih.hpp +++ b/ndb/src/kernel/blocks/dbdih/Dbdih.hpp @@ -1602,7 +1602,7 @@ private: void startInfoReply(Signal *, Uint32 nodeId); // DIH specifics for execNODE_START_REP (sendDictUnlockOrd) - void exec_node_start_rep(Signal* signal); + void execNODE_START_REP(Signal* signal); /* * Lock master DICT. Only current use is by starting node diff --git a/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp b/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp index 2b878034258..bb96c4b8831 100644 --- a/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp +++ b/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp @@ -269,7 +269,8 @@ Dbdih::Dbdih(const class Configuration & config): addRecSignal(GSN_DICT_LOCK_CONF, &Dbdih::execDICT_LOCK_CONF); addRecSignal(GSN_DICT_LOCK_REF, &Dbdih::execDICT_LOCK_REF); - + addRecSignal(GSN_NODE_START_REP, &Dbdih::execNODE_START_REP, true); + apiConnectRecord = 0; connectRecord = 0; fileRecord = 0; diff --git a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp index 4aeb8136650..28384d7cb86 100644 --- a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp +++ b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp @@ -1390,7 +1390,7 @@ void Dbdih::execNDB_STTOR(Signal* signal) }//Dbdih::execNDB_STTOR() void -Dbdih::exec_node_start_rep(Signal* signal) +Dbdih::execNODE_START_REP(Signal* signal) { /* * Send DICT_UNLOCK_ORD when this node is SL_STARTED. diff --git a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp index 299cad16ec1..0691e52d0ee 100644 --- a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp +++ b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp @@ -236,6 +236,7 @@ #define ZOPERATION_EVENT_REP 19 #define ZPREP_DROP_TABLE 20 #define ZENABLE_EXPAND_CHECK 21 +#define ZRETRY_TCKEYREF 22 /* ------------------------------------------------------------------------- */ /* NODE STATE DURING SYSTEM RESTART, VARIABLES CNODES_SR_STATE */ @@ -2276,6 +2277,7 @@ private: void releaseScanrec(Signal* signal); void seizeScanrec(Signal* signal); Uint32 sendKeyinfo20(Signal* signal, ScanRecord *, TcConnectionrec *); + void sendTCKEYREF(Signal*, Uint32 dst, Uint32 route, Uint32 cnt); void sendScanFragConf(Signal* signal, Uint32 scanCompleted); void initCopyrec(Signal* signal); void initCopyTc(Signal* signal); diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 4739450884c..3d93ce3fc31 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -464,6 +464,22 @@ void Dblqh::execCONTINUEB(Signal* signal) return; } } + case ZRETRY_TCKEYREF: + { + jam(); + Uint32 cnt = signal->theData[1]; + Uint32 ref = signal->theData[2]; + if (cnt < (10 * 60 * 5)) + { + jam(); + /** + * Only retry for 5 minutes...then hope that API has handled it..somehow + */ + memmove(signal->theData, signal->theData+3, 4*TcKeyRef::SignalLength); + sendTCKEYREF(signal, ref, 0, cnt); + } + return; + } default: ndbrequire(false); break; @@ -2370,7 +2386,7 @@ void Dblqh::noFreeRecordLab(Signal* signal, tcKeyRef->transId[0] = transid1; tcKeyRef->transId[1] = transid2; tcKeyRef->errorCode = errCode; - sendSignal(apiRef, GSN_TCKEYREF, signal, TcKeyRef::SignalLength, JBB); + sendTCKEYREF(signal, apiRef, signal->getSendersBlockRef(), 0); } else { jam(); @@ -6576,8 +6592,7 @@ void Dblqh::continueAfterLogAbortWriteLab(Signal* signal) tcKeyRef->transId[0] = regTcPtr->transid[0]; tcKeyRef->transId[1] = regTcPtr->transid[1]; tcKeyRef->errorCode = regTcPtr->errorCode; - sendSignal(regTcPtr->applRef, - GSN_TCKEYREF, signal, TcKeyRef::SignalLength, JBB); + sendTCKEYREF(signal, regTcPtr->applRef, regTcPtr->clientBlockref, 0); cleanUp(signal); return; }//if @@ -6612,6 +6627,29 @@ void Dblqh::continueAfterLogAbortWriteLab(Signal* signal) cleanUp(signal); }//Dblqh::continueAfterLogAbortWriteLab() +void +Dblqh::sendTCKEYREF(Signal* signal, Uint32 ref, Uint32 routeRef, Uint32 cnt) +{ + const Uint32 nodeId = refToNode(ref); + const bool connectedToNode = getNodeInfo(nodeId).m_connected; + + if (likely(connectedToNode)) + { + jam(); + sendSignal(ref, GSN_TCKEYREF, signal, TcKeyRef::SignalLength, JBB); + } + else + { + jam(); + memmove(signal->theData + 3, signal->theData, 4*TcKeyRef::SignalLength); + signal->theData[0] = ZRETRY_TCKEYREF; + signal->theData[1] = cnt + 1; + signal->theData[2] = ref; + sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, + TcKeyRef::SignalLength + 3); + } +} + /* ########################################################################## * ####### MODULE TO HANDLE TC FAILURE ####### * diff --git a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp index bf6ce7129ba..792586d7baf 100644 --- a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp +++ b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp @@ -942,7 +942,8 @@ public: NF_CHECK_SCAN = 0x2, NF_CHECK_TRANSACTION = 0x4, NF_CHECK_DROP_TAB = 0x8, - NF_NODE_FAIL_BITS = 0xF // All bits... + NF_NODE_FAIL_BITS = 0xF, // All bits... + NF_STARTED = 0x10 }; Uint32 m_nf_bits; NdbNodeBitmask m_lqh_trans_conf; @@ -1319,6 +1320,7 @@ private: void execCOMMITCONF(Signal* signal); void execABORTCONF(Signal* signal); void execNODE_FAILREP(Signal* signal); + void execNODE_START_REP(Signal* signal); void execINCL_NODEREQ(Signal* signal); void execTIME_SIGNAL(Signal* signal); void execAPI_FAILREQ(Signal* signal); diff --git a/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp b/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp index 7bd308119fc..098373fb3de 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp @@ -290,7 +290,8 @@ Dbtc::Dbtc(const class Configuration & conf): addRecSignal(GSN_WAIT_DROP_TAB_CONF, &Dbtc::execWAIT_DROP_TAB_CONF); addRecSignal(GSN_ALTER_TAB_REQ, &Dbtc::execALTER_TAB_REQ); - + addRecSignal(GSN_NODE_START_REP, &Dbtc::execNODE_START_REP, true); + cacheRecord = 0; apiConnectRecord = 0; tcConnectRecord = 0; diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index cc39219590f..a436316f7c9 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -3068,7 +3068,28 @@ void Dbtc::tckeyreq050Lab(Signal* signal) }//if }//for } - }//if + + if (regTcPtr->tcNodedata[0] != getOwnNodeId()) + { + jam(); + for (Uint32 i = 0; i < tnoOfBackup + 1; i++) + { + HostRecordPtr hostPtr; + hostPtr.i = regTcPtr->tcNodedata[i]; + ptrCheckGuard(hostPtr, chostFilesize, hostRecord); + if (hostPtr.p->m_nf_bits & HostRecord::NF_STARTED) + { + jam(); + if (i != 0) + { + jam(); + regTcPtr->tcNodedata[0] = hostPtr.i; + } + break; + } + } + }//if + } jam(); regTcPtr->lastReplicaNo = 0; regTcPtr->noOfNodes = 1; @@ -7003,6 +7024,19 @@ void Dbtc::execNODE_FAILREP(Signal* signal) }//Dbtc::execNODE_FAILREP() void +Dbtc::execNODE_START_REP(Signal* signal) +{ + Uint32 nodeId = signal->theData[0]; + hostptr.i = nodeId; + ptrCheckGuard(hostptr, chostFilesize, hostRecord); + if (hostptr.p->m_nf_bits == 0) + { + jam(); + hostptr.p->m_nf_bits |= HostRecord::NF_STARTED; + } +} + +void Dbtc::checkNodeFailComplete(Signal* signal, Uint32 failedNodeId, Uint32 bit) @@ -8701,6 +8735,20 @@ void Dbtc::execSCAN_TABREQ(Signal* signal) * IF ANY TO RECEIVE. **********************************************************/ scanptr.p->scanState = ScanRecord::WAIT_AI; + + if (ERROR_INSERTED(8038)) + { + /** + * Force API_FAILREQ + */ + DisconnectRep * const rep = (DisconnectRep *)signal->getDataPtrSend(); + rep->nodeId = refToNode(apiConnectptr.p->ndbapiBlockref); + rep->err = 8038; + + EXECUTE_DIRECT(CMVMI, GSN_DISCONNECT_REP, signal, 2); + CLEAR_ERROR_INSERT_VALUE; + } + return; SCAN_error_check: @@ -8790,6 +8838,7 @@ void Dbtc::initScanrec(ScanRecordPtr scanptr, jam(); ScanFragRecPtr ptr; ndbrequire(list.seize(ptr)); + ptr.p->scanFragState = ScanFragRec::IDLE; ptr.p->scanRec = scanptr.i; ptr.p->scanFragId = 0; ptr.p->m_apiPtr = cdata[i]; @@ -9582,9 +9631,17 @@ Dbtc::close_scan_req(Signal* signal, ScanRecordPtr scanPtr, bool req_received){ ScanRecord* scanP = scanPtr.p; ndbrequire(scanPtr.p->scanState != ScanRecord::IDLE); + ScanRecord::ScanState old = scanPtr.p->scanState; scanPtr.p->scanState = ScanRecord::CLOSING_SCAN; scanPtr.p->m_close_scan_req = req_received; + if (old == ScanRecord::WAIT_FRAGMENT_COUNT) + { + jam(); + scanPtr.p->scanState = old; + return; // Will continue on execDI_FCOUNTCONF + } + /** * Queue : Action * ============= : ================= @@ -9612,11 +9669,22 @@ Dbtc::close_scan_req(Signal* signal, ScanRecordPtr scanPtr, bool req_received){ ScanFragRecPtr curr = ptr; // Remove while iterating... running.next(ptr); - if(curr.p->scanFragState == ScanFragRec::WAIT_GET_PRIMCONF){ + switch(curr.p->scanFragState){ + case ScanFragRec::IDLE: + jam(); // real early abort + ndbrequire(old == ScanRecord::WAIT_AI); + running.release(curr); + continue; + case ScanFragRec::WAIT_GET_PRIMCONF: jam(); continue; + case ScanFragRec::LQH_ACTIVE: + jam(); + break; + default: + jamLine(curr.p->scanFragState); + ndbrequire(false); } - ndbrequire(curr.p->scanFragState == ScanFragRec::LQH_ACTIVE); curr.p->startFragTimer(ctcTimer); curr.p->scanFragState = ScanFragRec::LQH_ACTIVE; diff --git a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp index 0b66d9a45bb..c068a993792 100644 --- a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp +++ b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp @@ -196,6 +196,7 @@ #define ZTRY_TO_UPDATE_ERROR 888 #define ZCALL_ERROR 890 #define ZTEMPORARY_RESOURCE_FAILURE 891 +#define ZUNSUPPORTED_BRANCH 892 #define ZSTORED_SEIZE_ATTRINBUFREC_ERROR 873 // Part of Scan diff --git a/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp b/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp index e9043a8b52d..07babd72ce1 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp @@ -444,6 +444,11 @@ int Dbtup::TUPKEY_abort(Signal* signal, int error_type) }//if break; + case 40: + ljam(); + terrorCode = ZUNSUPPORTED_BRANCH; + break; + default: ndbrequire(false); break; diff --git a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp index 13c0bad9c7a..9917ac4e340 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp @@ -1876,6 +1876,11 @@ int Dbtup::interpreterNextLab(Signal* signal, // NULL==NULL and NULL<not-NULL res1 = r1_null && r2_null ? 0 : r1_null ? -1 : 1; } else { + jam(); + if (unlikely(sqlType.m_cmp == 0)) + { + return TUPKEY_abort(signal, 40); + } res1 = (*sqlType.m_cmp)(cs, s1, attrLen, s2, argLen, true); } } else { @@ -1883,6 +1888,11 @@ int Dbtup::interpreterNextLab(Signal* signal, // NULL like NULL is true (has no practical use) res1 = r1_null && r2_null ? 0 : -1; } else { + jam(); + if (unlikely(sqlType.m_like == 0)) + { + return TUPKEY_abort(signal, 40); + } res1 = (*sqlType.m_like)(cs, s1, attrLen, s2, argLen); } } diff --git a/ndb/src/kernel/vm/SimulatedBlock.cpp b/ndb/src/kernel/vm/SimulatedBlock.cpp index b4787209d55..d5bf2a911b8 100644 --- a/ndb/src/kernel/vm/SimulatedBlock.cpp +++ b/ndb/src/kernel/vm/SimulatedBlock.cpp @@ -658,24 +658,26 @@ SimulatedBlock::allocRecord(const char * type, size_t s, size_t n, bool clear) void * p = NULL; size_t size = n*s; + Uint64 real_size = (Uint64)((Uint64)n)*((Uint64)s); refresh_watch_dog(); - if (size > 0){ + if (real_size > 0){ #ifdef VM_TRACE_MEM - ndbout_c("%s::allocRecord(%s, %u, %u) = %u bytes", + ndbout_c("%s::allocRecord(%s, %u, %u) = %llu bytes", getBlockName(number()), type, s, n, - size); + real_size); #endif - p = ndbd_malloc(size); + if( real_size == (Uint64)size ) + p = ndbd_malloc(size); if (p == NULL){ char buf1[255]; char buf2[255]; BaseString::snprintf(buf1, sizeof(buf1), "%s could not allocate memory for %s", getBlockName(number()), type); - BaseString::snprintf(buf2, sizeof(buf2), "Requested: %ux%u = %u bytes", - (Uint32)s, (Uint32)n, (Uint32)size); + BaseString::snprintf(buf2, sizeof(buf2), "Requested: %ux%u = %llu bytes", + (Uint32)s, (Uint32)n, (Uint64)real_size); ERROR_SET(fatal, NDBD_EXIT_MEMALLOC, buf1, buf2); } @@ -917,15 +919,6 @@ SimulatedBlock::execCONTINUE_FRAGMENTED(Signal * signal){ void SimulatedBlock::execNODE_START_REP(Signal* signal) { - // common stuff for all blocks - - // block specific stuff by virtual method override (default empty) - exec_node_start_rep(signal); -} - -void -SimulatedBlock::exec_node_start_rep(Signal* signal) -{ } #ifdef VM_TRACE_TIME diff --git a/ndb/src/kernel/vm/SimulatedBlock.hpp b/ndb/src/kernel/vm/SimulatedBlock.hpp index 4a3620a00ab..f7ca4ecbf38 100644 --- a/ndb/src/kernel/vm/SimulatedBlock.hpp +++ b/ndb/src/kernel/vm/SimulatedBlock.hpp @@ -424,7 +424,6 @@ private: void execSIGNAL_DROPPED_REP(Signal* signal); void execCONTINUE_FRAGMENTED(Signal* signal); void execNODE_START_REP(Signal* signal); - virtual void exec_node_start_rep(Signal* signal); Uint32 c_fragmentIdCounter; ArrayPool<FragmentInfo> c_fragmentInfoPool; diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index bf16aa03d04..a6dcc13a894 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -1337,7 +1337,7 @@ Ndb_mgmd_event_service::log(int eventType, const Uint32* theData, NodeId nodeId) if (EventLoggerBase::event_lookup(eventType,cat,threshold,severity,textF)) DBUG_VOID_RETURN; - char m_text[256]; + char m_text[512]; EventLogger::getText(m_text, sizeof(m_text), textF, theData, nodeId); @@ -1353,6 +1353,15 @@ Ndb_mgmd_event_service::log(int eventType, const Uint32* theData, NodeId nodeId) if (ndb_logevent_body[i].index_fn) val= (*(ndb_logevent_body[i].index_fn))(val); str.appfmt("%s=%d\n",ndb_logevent_body[i].token, val); + if(strcmp(ndb_logevent_body[i].token,"error") == 0) + { + int m_text_len= strlen(m_text); + if(sizeof(m_text)-m_text_len-3 > 0) + { + BaseString::snprintf(m_text+m_text_len, 4 , " - "); + ndb_error_string(val, m_text+(m_text_len+3), sizeof(m_text)-m_text_len-3); + } + } } Vector<NDB_SOCKET_TYPE> copy; diff --git a/ndb/src/ndbapi/NdbTransaction.cpp b/ndb/src/ndbapi/NdbTransaction.cpp index 36b1217c101..483ef933caa 100644 --- a/ndb/src/ndbapi/NdbTransaction.cpp +++ b/ndb/src/ndbapi/NdbTransaction.cpp @@ -923,7 +923,10 @@ NdbTransaction::release(){ * The user did not perform any rollback but simply closed the * transaction. We must rollback Ndb since Ndb have been contacted. ************************************************************************/ - execute(Rollback); + if (!theSimpleState) + { + execute(Rollback); + } }//if theMagicNumber = 0xFE11DC; theInUseState = false; diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c index 6173292261d..660117ed4c2 100644 --- a/ndb/src/ndbapi/ndberror.c +++ b/ndb/src/ndbapi/ndberror.c @@ -278,6 +278,7 @@ ErrorBundle ErrorCodes[] = { { 885, AE, "Stack underflow in interpreter" }, { 886, AE, "More than 65535 instructions executed in interpreter" }, { 897, AE, "Update attempt of primary key via ndbcluster internal api (if this occurs via the MySQL server it is a bug, please report)" }, + { 892, AE, "Unsupported type in scan filter" }, { 4256, AE, "Must call Ndb::init() before this function" }, { 4257, AE, "Tried to read too much - too many getValue calls" }, @@ -680,11 +681,14 @@ const char *ndberror_classification_message(ndberror_classification classificati return empty_string; } -int ndb_error_string(int err_no, char *str, unsigned int size) +int ndb_error_string(int err_no, char *str, int size) { ndberror_struct error; - unsigned int len; + int len; + assert(size > 1); + if(size <= 1) + return 0; error.code = err_no; ndberror_update(&error); diff --git a/ndb/test/ndbapi/testDict.cpp b/ndb/test/ndbapi/testDict.cpp index ba05bbad7bb..a8e28742757 100644 --- a/ndb/test/ndbapi/testDict.cpp +++ b/ndb/test/ndbapi/testDict.cpp @@ -1893,7 +1893,7 @@ runDictOps(NDBT_Context* ctx, NDBT_Step* step) // create indexes const char** indlist = NDBT_Tables::getIndexes(tabName); uint indnum = 0; - while (*indlist != 0) { + while (indlist != 0 && *indlist != 0) { uint count = 0; try_create_index: count++; diff --git a/ndb/test/ndbapi/testNodeRestart.cpp b/ndb/test/ndbapi/testNodeRestart.cpp index c1502940655..082013f07cc 100644 --- a/ndb/test/ndbapi/testNodeRestart.cpp +++ b/ndb/test/ndbapi/testNodeRestart.cpp @@ -23,6 +23,7 @@ #include <Vector.hpp> #include <signaldata/DumpStateOrd.hpp> #include <Bitmask.hpp> +#include <RefConvert.hpp> int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ @@ -919,6 +920,41 @@ int runBug20185(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_OK; } +int runBug24717(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + NdbRestarter restarter; + Ndb* pNdb = GETNDB(step); + + HugoTransactions hugoTrans(*ctx->getTab()); + + int dump[] = { 9002, 0 } ; + Uint32 ownNode = refToNode(pNdb->getReference()); + dump[1] = ownNode; + + for (; loops; loops --) + { + int nodeId = restarter.getRandomNotMasterNodeId(rand()); + restarter.restartOneDbNode(nodeId, false, true, true); + restarter.waitNodesNoStart(&nodeId, 1); + + if (restarter.dumpStateOneNode(nodeId, dump, 2)) + return NDBT_FAILED; + + restarter.startNodes(&nodeId, 1); + + for (Uint32 i = 0; i < 100; i++) + { + hugoTrans.pkReadRecords(pNdb, 100, 1, NdbOperation::LM_CommittedRead); + } + + restarter.waitClusterStarted(); + } + + return NDBT_OK; +} + NDBT_TESTSUITE(testNodeRestart); TESTCASE("NoLoad", @@ -1232,6 +1268,9 @@ TESTCASE("Bug20185", STEP(runBug20185); FINALIZER(runClearTable); } +TESTCASE("Bug24717", ""){ + INITIALIZER(runBug24717); +} NDBT_TESTSUITE_END(testNodeRestart); int main(int argc, const char** argv){ diff --git a/ndb/test/ndbapi/testScan.cpp b/ndb/test/ndbapi/testScan.cpp index 2802f1c950e..882ed649b9a 100644 --- a/ndb/test/ndbapi/testScan.cpp +++ b/ndb/test/ndbapi/testScan.cpp @@ -630,7 +630,7 @@ int runRestarter(NDBT_Context* ctx, NDBT_Step* step){ int nodeId = restarter.getDbNodeId(lastId); lastId = (lastId + 1) % restarter.getNumDbNodes(); - if(restarter.restartOneDbNode(nodeId) != 0){ + if(restarter.restartOneDbNode(nodeId, false, false, true) != 0){ g_err << "Failed to restartNextDbNode" << endl; result = NDBT_FAILED; break; @@ -1125,6 +1125,39 @@ runScanParallelism(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_OK; } +int +runBug24447(NDBT_Context* ctx, NDBT_Step* step){ + int loops = 1; //ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int abort = ctx->getProperty("AbortProb", 15); + NdbRestarter restarter; + HugoTransactions hugoTrans(*ctx->getTab()); + int i = 0; + while (i<loops && !ctx->isTestStopped()) + { + g_info << i++ << ": "; + + int nodeId = restarter.getRandomNotMasterNodeId(rand()); + if (nodeId == -1) + nodeId = restarter.getMasterNodeId(); + if (restarter.insertErrorInNode(nodeId, 8038) != 0) + { + ndbout << "Could not insert error in node="<<nodeId<<endl; + return NDBT_FAILED; + } + + for (Uint32 j = 0; i<10; i++) + { + hugoTrans.scanReadRecords(GETNDB(step), records, abort, 0, + NdbOperation::LM_CommittedRead); + } + + } + restarter.insertErrorInAllNodes(0); + + return NDBT_OK; +} + NDBT_TESTSUITE(testScan); TESTCASE("ScanRead", "Verify scan requirement: It should be possible "\ @@ -1603,6 +1636,12 @@ TESTCASE("ScanParallelism", STEP(runScanParallelism); FINALIZER(runClearTable); } +TESTCASE("Bug24447", + ""){ + INITIALIZER(runLoadTable); + STEP(runBug24447); + FINALIZER(runClearTable); +} NDBT_TESTSUITE_END(testScan); int main(int argc, const char** argv){ diff --git a/ndb/test/run-test/daily-basic-tests.txt b/ndb/test/run-test/daily-basic-tests.txt index a544355abd6..bbfc2f630b9 100644 --- a/ndb/test/run-test/daily-basic-tests.txt +++ b/ndb/test/run-test/daily-basic-tests.txt @@ -414,6 +414,10 @@ cmd: testScan args: -n ScanParallelism max-time: 500 +cmd: testScan +args: -n Bug24447 T1 + +max-time: 500 cmd: testNodeRestart args: -n Bug15587 T1 @@ -453,6 +457,10 @@ max-time: 1000 cmd: testIndex args: -n Bug21384 +max-time: 1000 +cmd: testNodeRestart +args: -n Bug24717 T1 + # OLD FLEX max-time: 500 cmd: flexBench @@ -510,7 +518,7 @@ args: -n TemporaryTables T1 T6 T7 T8 max-time: 1500 cmd: testDict -args: -n Restart_NR2 T1 +args: -n Restart_NR2 T1 I3 # # TEST NDBAPI diff --git a/ndb/tools/ndb_config.cpp b/ndb/tools/ndb_config.cpp index 049e4599447..c65f7157c15 100644 --- a/ndb/tools/ndb_config.cpp +++ b/ndb/tools/ndb_config.cpp @@ -37,7 +37,6 @@ static int g_verbose = 0; static int try_reconnect = 3; static int g_nodes, g_connections, g_section; -static const char * g_connectstring = 0; static const char * g_query = 0; static int g_nodeid = 0; @@ -486,7 +485,7 @@ fetch_configuration() ndb_mgm_set_error_stream(mgm, stderr); - if (ndb_mgm_set_connectstring(mgm, g_connectstring)) + if (ndb_mgm_set_connectstring(mgm, opt_connect_str)) { fprintf(stderr, "* %5d: %s\n", ndb_mgm_get_latest_error(mgm), |