mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 03:47:17 +02:00
bug#10142 - ndb unhandle resource shortage in unique index code
ndb/src/kernel/blocks/dbtc/Dbtc.hpp: remove unneccessary TcSeizedIndexOperation object ndb/src/kernel/blocks/dbtc/DbtcInit.cpp: remove unneccessary TcSeizedIndexOperation object ndb/src/kernel/blocks/dbtc/DbtcMain.cpp: 1) Set transid on starting TCINDXREQ 2) New error code for out of index operation records 3) Check accumulating index op for RNIL before dereferencing it ndb/src/kernel/error/ErrorReporter.cpp: Include NDB version in ndb_X_error.log ndb/src/ndbapi/NdbIndexOperation.cpp: Let failed tcindxreq abort ndb/src/ndbapi/ndberror.c: New error code for out of index operation records
This commit is contained in:
parent
7ecca388af
commit
e46360bad6
6 changed files with 47 additions and 77 deletions
|
|
@ -585,34 +585,8 @@ public:
|
||||||
*/
|
*/
|
||||||
ArrayPool<TcIndexOperation> c_theIndexOperationPool;
|
ArrayPool<TcIndexOperation> c_theIndexOperationPool;
|
||||||
|
|
||||||
/**
|
|
||||||
* The list of index operations
|
|
||||||
*/
|
|
||||||
ArrayList<TcIndexOperation> c_theIndexOperations;
|
|
||||||
|
|
||||||
UintR c_maxNumberOfIndexOperations;
|
UintR c_maxNumberOfIndexOperations;
|
||||||
|
|
||||||
struct TcSeizedIndexOperation {
|
|
||||||
/**
|
|
||||||
* Next ptr (used in pool/list)
|
|
||||||
*/
|
|
||||||
union {
|
|
||||||
Uint32 nextPool;
|
|
||||||
Uint32 nextList;
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Prev pointer (used in list)
|
|
||||||
*/
|
|
||||||
Uint32 prevList;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pool of seized index operations
|
|
||||||
*/
|
|
||||||
ArrayPool<TcSeizedIndexOperation> c_theSeizedIndexOperationPool;
|
|
||||||
|
|
||||||
typedef Ptr<TcSeizedIndexOperation> TcSeizedIndexOperationPtr;
|
|
||||||
|
|
||||||
/************************** API CONNECT RECORD ***********************
|
/************************** API CONNECT RECORD ***********************
|
||||||
* The API connect record contains the connection record to which the
|
* The API connect record contains the connection record to which the
|
||||||
* application connects.
|
* application connects.
|
||||||
|
|
@ -650,7 +624,7 @@ public:
|
||||||
|
|
||||||
struct ApiConnectRecord {
|
struct ApiConnectRecord {
|
||||||
ApiConnectRecord(ArrayPool<TcFiredTriggerData> & firedTriggerPool,
|
ApiConnectRecord(ArrayPool<TcFiredTriggerData> & firedTriggerPool,
|
||||||
ArrayPool<TcSeizedIndexOperation> & seizedIndexOpPool):
|
ArrayPool<TcIndexOperation> & seizedIndexOpPool):
|
||||||
theFiredTriggers(firedTriggerPool),
|
theFiredTriggers(firedTriggerPool),
|
||||||
isIndexOp(false),
|
isIndexOp(false),
|
||||||
theSeizedIndexOperations(seizedIndexOpPool)
|
theSeizedIndexOperations(seizedIndexOpPool)
|
||||||
|
|
@ -763,7 +737,7 @@ public:
|
||||||
UintR accumulatingIndexOp;
|
UintR accumulatingIndexOp;
|
||||||
UintR executingIndexOp;
|
UintR executingIndexOp;
|
||||||
UintR tcIndxSendArray[6];
|
UintR tcIndxSendArray[6];
|
||||||
ArrayList<TcSeizedIndexOperation> theSeizedIndexOperations;
|
ArrayList<TcIndexOperation> theSeizedIndexOperations;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Ptr<ApiConnectRecord> ApiConnectRecordPtr;
|
typedef Ptr<ApiConnectRecord> ApiConnectRecordPtr;
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,6 @@ void Dbtc::initData()
|
||||||
c_theFiredTriggerPool.setSize(c_maxNumberOfFiredTriggers);
|
c_theFiredTriggerPool.setSize(c_maxNumberOfFiredTriggers);
|
||||||
c_theIndexPool.setSize(c_maxNumberOfIndexes);
|
c_theIndexPool.setSize(c_maxNumberOfIndexes);
|
||||||
c_theIndexOperationPool.setSize(c_maxNumberOfIndexOperations);
|
c_theIndexOperationPool.setSize(c_maxNumberOfIndexOperations);
|
||||||
c_theSeizedIndexOperationPool.setSize(c_maxNumberOfIndexOperations);
|
|
||||||
c_theAttributeBufferPool.setSize(c_transactionBufferSpace);
|
c_theAttributeBufferPool.setSize(c_transactionBufferSpace);
|
||||||
c_firedTriggerHash.setSize((c_maxNumberOfFiredTriggers+10)/10);
|
c_firedTriggerHash.setSize((c_maxNumberOfFiredTriggers+10)/10);
|
||||||
}//Dbtc::initData()
|
}//Dbtc::initData()
|
||||||
|
|
@ -85,7 +84,7 @@ void Dbtc::initRecords()
|
||||||
for(unsigned i = 0; i<capiConnectFilesize; i++) {
|
for(unsigned i = 0; i<capiConnectFilesize; i++) {
|
||||||
p = &apiConnectRecord[i];
|
p = &apiConnectRecord[i];
|
||||||
new (p) ApiConnectRecord(c_theFiredTriggerPool,
|
new (p) ApiConnectRecord(c_theFiredTriggerPool,
|
||||||
c_theSeizedIndexOperationPool);
|
c_theIndexOperationPool);
|
||||||
}
|
}
|
||||||
// Init all fired triggers
|
// Init all fired triggers
|
||||||
DLFifoList<TcFiredTriggerData> triggers(c_theFiredTriggerPool);
|
DLFifoList<TcFiredTriggerData> triggers(c_theFiredTriggerPool);
|
||||||
|
|
@ -177,7 +176,6 @@ Dbtc::Dbtc(const class Configuration & conf):
|
||||||
c_maxNumberOfFiredTriggers(0),
|
c_maxNumberOfFiredTriggers(0),
|
||||||
c_theIndexes(c_theIndexPool),
|
c_theIndexes(c_theIndexPool),
|
||||||
c_maxNumberOfIndexes(0),
|
c_maxNumberOfIndexes(0),
|
||||||
c_theIndexOperations(c_theIndexOperationPool),
|
|
||||||
c_maxNumberOfIndexOperations(0),
|
c_maxNumberOfIndexOperations(0),
|
||||||
m_commitAckMarkerHash(m_commitAckMarkerPool)
|
m_commitAckMarkerHash(m_commitAckMarkerPool)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -11161,16 +11161,21 @@ void Dbtc::execTCINDXREQ(Signal* signal)
|
||||||
jam();
|
jam();
|
||||||
// This is a newly started transaction, clean-up
|
// This is a newly started transaction, clean-up
|
||||||
releaseAllSeizedIndexOperations(regApiPtr);
|
releaseAllSeizedIndexOperations(regApiPtr);
|
||||||
|
|
||||||
|
regApiPtr->transid[0] = tcIndxReq->transId1;
|
||||||
|
regApiPtr->transid[1] = tcIndxReq->transId2;
|
||||||
}//if
|
}//if
|
||||||
if (!seizeIndexOperation(regApiPtr, indexOpPtr)) {
|
ndbout_c("here");
|
||||||
|
|
||||||
|
if (ERROR_INSERTED(8036) || !seizeIndexOperation(regApiPtr, indexOpPtr)) {
|
||||||
jam();
|
jam();
|
||||||
// Failed to allocate index operation
|
// Failed to allocate index operation
|
||||||
TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend();
|
TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend();
|
||||||
|
|
||||||
tcIndxRef->connectPtr = tcIndxReq->senderData;
|
tcIndxRef->connectPtr = tcIndxReq->senderData;
|
||||||
tcIndxRef->transId[0] = regApiPtr->transid[0];
|
tcIndxRef->transId[0] = regApiPtr->transid[0];
|
||||||
tcIndxRef->transId[1] = regApiPtr->transid[1];
|
tcIndxRef->transId[1] = regApiPtr->transid[1];
|
||||||
tcIndxRef->errorCode = 4000;
|
tcIndxRef->errorCode = 288;
|
||||||
sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
|
sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
|
||||||
TcIndxRef::SignalLength, JBB);
|
TcIndxRef::SignalLength, JBB);
|
||||||
return;
|
return;
|
||||||
|
|
@ -11307,15 +11312,17 @@ void Dbtc::execINDXKEYINFO(Signal* signal)
|
||||||
TcIndexOperationPtr indexOpPtr;
|
TcIndexOperationPtr indexOpPtr;
|
||||||
TcIndexOperation* indexOp;
|
TcIndexOperation* indexOp;
|
||||||
|
|
||||||
indexOpPtr.i = regApiPtr->accumulatingIndexOp;
|
if((indexOpPtr.i = regApiPtr->accumulatingIndexOp) != RNIL)
|
||||||
indexOp = c_theIndexOperations.getPtr(indexOpPtr.i);
|
{
|
||||||
if (saveINDXKEYINFO(signal,
|
indexOp = c_theIndexOperationPool.getPtr(indexOpPtr.i);
|
||||||
indexOp,
|
if (saveINDXKEYINFO(signal,
|
||||||
src,
|
indexOp,
|
||||||
keyInfoLength)) {
|
src,
|
||||||
jam();
|
keyInfoLength)) {
|
||||||
// We have received all we need
|
jam();
|
||||||
readIndexTable(signal, regApiPtr, indexOp);
|
// We have received all we need
|
||||||
|
readIndexTable(signal, regApiPtr, indexOp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -11338,15 +11345,17 @@ void Dbtc::execINDXATTRINFO(Signal* signal)
|
||||||
TcIndexOperationPtr indexOpPtr;
|
TcIndexOperationPtr indexOpPtr;
|
||||||
TcIndexOperation* indexOp;
|
TcIndexOperation* indexOp;
|
||||||
|
|
||||||
indexOpPtr.i = regApiPtr->accumulatingIndexOp;
|
if((indexOpPtr.i = regApiPtr->accumulatingIndexOp) != RNIL)
|
||||||
indexOp = c_theIndexOperations.getPtr(indexOpPtr.i);
|
{
|
||||||
if (saveINDXATTRINFO(signal,
|
indexOp = c_theIndexOperationPool.getPtr(indexOpPtr.i);
|
||||||
indexOp,
|
if (saveINDXATTRINFO(signal,
|
||||||
src,
|
indexOp,
|
||||||
attrInfoLength)) {
|
src,
|
||||||
jam();
|
attrInfoLength)) {
|
||||||
// We have received all we need
|
jam();
|
||||||
readIndexTable(signal, regApiPtr, indexOp);
|
// We have received all we need
|
||||||
|
readIndexTable(signal, regApiPtr, indexOp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -11371,7 +11380,7 @@ bool Dbtc::saveINDXKEYINFO(Signal* signal,
|
||||||
releaseIndexOperation(apiConnectptr.p, indexOp);
|
releaseIndexOperation(apiConnectptr.p, indexOp);
|
||||||
terrorCode = 4000;
|
terrorCode = 4000;
|
||||||
abortErrorLab(signal);
|
abortErrorLab(signal);
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
if (receivedAllINDXKEYINFO(indexOp) && receivedAllINDXATTRINFO(indexOp)) {
|
if (receivedAllINDXKEYINFO(indexOp) && receivedAllINDXATTRINFO(indexOp)) {
|
||||||
jam();
|
jam();
|
||||||
|
|
@ -11404,7 +11413,7 @@ bool Dbtc::saveINDXATTRINFO(Signal* signal,
|
||||||
releaseIndexOperation(apiConnectptr.p, indexOp);
|
releaseIndexOperation(apiConnectptr.p, indexOp);
|
||||||
terrorCode = 4000;
|
terrorCode = 4000;
|
||||||
abortErrorLab(signal);
|
abortErrorLab(signal);
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
if (receivedAllINDXKEYINFO(indexOp) && receivedAllINDXATTRINFO(indexOp)) {
|
if (receivedAllINDXKEYINFO(indexOp) && receivedAllINDXATTRINFO(indexOp)) {
|
||||||
jam();
|
jam();
|
||||||
|
|
@ -11464,7 +11473,7 @@ void Dbtc::execTCKEYCONF(Signal* signal)
|
||||||
|
|
||||||
jamEntry();
|
jamEntry();
|
||||||
indexOpPtr.i = tcKeyConf->apiConnectPtr;
|
indexOpPtr.i = tcKeyConf->apiConnectPtr;
|
||||||
TcIndexOperation* indexOp = c_theIndexOperations.getPtr(indexOpPtr.i);
|
TcIndexOperation* indexOp = c_theIndexOperationPool.getPtr(indexOpPtr.i);
|
||||||
Uint32 confInfo = tcKeyConf->confInfo;
|
Uint32 confInfo = tcKeyConf->confInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -11553,7 +11562,7 @@ void Dbtc::execTCKEYREF(Signal* signal)
|
||||||
|
|
||||||
jamEntry();
|
jamEntry();
|
||||||
indexOpPtr.i = tcKeyRef->connectPtr;
|
indexOpPtr.i = tcKeyRef->connectPtr;
|
||||||
TcIndexOperation* indexOp = c_theIndexOperations.getPtr(indexOpPtr.i);
|
TcIndexOperation* indexOp = c_theIndexOperationPool.getPtr(indexOpPtr.i);
|
||||||
indexOpPtr.p = indexOp;
|
indexOpPtr.p = indexOp;
|
||||||
if (!indexOp) {
|
if (!indexOp) {
|
||||||
jam();
|
jam();
|
||||||
|
|
@ -11654,7 +11663,7 @@ void Dbtc::execTRANSID_AI(Signal* signal)
|
||||||
jamEntry();
|
jamEntry();
|
||||||
TcIndexOperationPtr indexOpPtr;
|
TcIndexOperationPtr indexOpPtr;
|
||||||
indexOpPtr.i = transIdAI->connectPtr;
|
indexOpPtr.i = transIdAI->connectPtr;
|
||||||
TcIndexOperation* indexOp = c_theIndexOperations.getPtr(indexOpPtr.i);
|
TcIndexOperation* indexOp = c_theIndexOperationPool.getPtr(indexOpPtr.i);
|
||||||
indexOpPtr.p = indexOp;
|
indexOpPtr.p = indexOp;
|
||||||
if (!indexOp) {
|
if (!indexOp) {
|
||||||
jam();
|
jam();
|
||||||
|
|
@ -11762,7 +11771,7 @@ void Dbtc::execTCROLLBACKREP(Signal* signal)
|
||||||
jamEntry();
|
jamEntry();
|
||||||
TcIndexOperationPtr indexOpPtr;
|
TcIndexOperationPtr indexOpPtr;
|
||||||
indexOpPtr.i = tcRollbackRep->connectPtr;
|
indexOpPtr.i = tcRollbackRep->connectPtr;
|
||||||
TcIndexOperation* indexOp = c_theIndexOperations.getPtr(indexOpPtr.i);
|
TcIndexOperation* indexOp = c_theIndexOperationPool.getPtr(indexOpPtr.i);
|
||||||
indexOpPtr.p = indexOp;
|
indexOpPtr.p = indexOp;
|
||||||
tcRollbackRep = (TcRollbackRep *)signal->getDataPtrSend();
|
tcRollbackRep = (TcRollbackRep *)signal->getDataPtrSend();
|
||||||
tcRollbackRep->connectPtr = indexOp->tcIndxReq.senderData;
|
tcRollbackRep->connectPtr = indexOp->tcIndxReq.senderData;
|
||||||
|
|
@ -12090,16 +12099,7 @@ void Dbtc::executeIndexOperation(Signal* signal,
|
||||||
bool Dbtc::seizeIndexOperation(ApiConnectRecord* regApiPtr,
|
bool Dbtc::seizeIndexOperation(ApiConnectRecord* regApiPtr,
|
||||||
TcIndexOperationPtr& indexOpPtr)
|
TcIndexOperationPtr& indexOpPtr)
|
||||||
{
|
{
|
||||||
bool seizeOk;
|
return regApiPtr->theSeizedIndexOperations.seize(indexOpPtr);
|
||||||
|
|
||||||
seizeOk = c_theIndexOperations.seize(indexOpPtr);
|
|
||||||
if (seizeOk) {
|
|
||||||
jam();
|
|
||||||
TcSeizedIndexOperationPtr seizedIndexOpPtr;
|
|
||||||
seizeOk &= regApiPtr->theSeizedIndexOperations.seizeId(seizedIndexOpPtr,
|
|
||||||
indexOpPtr.i);
|
|
||||||
}
|
|
||||||
return seizeOk;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dbtc::releaseIndexOperation(ApiConnectRecord* regApiPtr,
|
void Dbtc::releaseIndexOperation(ApiConnectRecord* regApiPtr,
|
||||||
|
|
@ -12113,18 +12113,16 @@ void Dbtc::releaseIndexOperation(ApiConnectRecord* regApiPtr,
|
||||||
indexOp->expectedTransIdAI = 0;
|
indexOp->expectedTransIdAI = 0;
|
||||||
indexOp->transIdAI.release();
|
indexOp->transIdAI.release();
|
||||||
regApiPtr->theSeizedIndexOperations.release(indexOp->indexOpId);
|
regApiPtr->theSeizedIndexOperations.release(indexOp->indexOpId);
|
||||||
c_theIndexOperations.release(indexOp->indexOpId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dbtc::releaseAllSeizedIndexOperations(ApiConnectRecord* regApiPtr)
|
void Dbtc::releaseAllSeizedIndexOperations(ApiConnectRecord* regApiPtr)
|
||||||
{
|
{
|
||||||
TcSeizedIndexOperationPtr seizedIndexOpPtr;
|
TcIndexOperationPtr seizedIndexOpPtr;
|
||||||
|
|
||||||
regApiPtr->theSeizedIndexOperations.first(seizedIndexOpPtr);
|
regApiPtr->theSeizedIndexOperations.first(seizedIndexOpPtr);
|
||||||
while(seizedIndexOpPtr.i != RNIL) {
|
while(seizedIndexOpPtr.i != RNIL) {
|
||||||
jam();
|
jam();
|
||||||
TcIndexOperation* indexOp =
|
TcIndexOperation* indexOp = seizedIndexOpPtr.p;
|
||||||
c_theIndexOperations.getPtr(seizedIndexOpPtr.i);
|
|
||||||
|
|
||||||
indexOp->indexOpState = IOS_NOOP;
|
indexOp->indexOpState = IOS_NOOP;
|
||||||
indexOp->expectedKeyInfo = 0;
|
indexOp->expectedKeyInfo = 0;
|
||||||
|
|
@ -12133,7 +12131,6 @@ void Dbtc::releaseAllSeizedIndexOperations(ApiConnectRecord* regApiPtr)
|
||||||
indexOp->attrInfo.release();
|
indexOp->attrInfo.release();
|
||||||
indexOp->expectedTransIdAI = 0;
|
indexOp->expectedTransIdAI = 0;
|
||||||
indexOp->transIdAI.release();
|
indexOp->transIdAI.release();
|
||||||
c_theIndexOperations.release(seizedIndexOpPtr.i);
|
|
||||||
regApiPtr->theSeizedIndexOperations.next(seizedIndexOpPtr);
|
regApiPtr->theSeizedIndexOperations.next(seizedIndexOpPtr);
|
||||||
}
|
}
|
||||||
regApiPtr->theSeizedIndexOperations.release();
|
regApiPtr->theSeizedIndexOperations.release();
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ ErrorReporter::formatMessage(ErrorCategory type,
|
||||||
"Date/Time: %s\nType of error: %s\n"
|
"Date/Time: %s\nType of error: %s\n"
|
||||||
"Message: %s\nFault ID: %d\nProblem data: %s"
|
"Message: %s\nFault ID: %d\nProblem data: %s"
|
||||||
"\nObject of reference: %s\nProgramName: %s\n"
|
"\nObject of reference: %s\nProgramName: %s\n"
|
||||||
"ProcessID: %d\nTraceFile: %s\n***EOM***\n",
|
"ProcessID: %d\nTraceFile: %s\n%s\n***EOM***\n",
|
||||||
formatTimeStampString() ,
|
formatTimeStampString() ,
|
||||||
errorType[type],
|
errorType[type],
|
||||||
lookupErrorMessage(faultID),
|
lookupErrorMessage(faultID),
|
||||||
|
|
@ -139,7 +139,8 @@ ErrorReporter::formatMessage(ErrorCategory type,
|
||||||
objRef,
|
objRef,
|
||||||
my_progname,
|
my_progname,
|
||||||
processId,
|
processId,
|
||||||
theNameOfTheTraceFile ? theNameOfTheTraceFile : "<no tracefile>");
|
theNameOfTheTraceFile ? theNameOfTheTraceFile : "<no tracefile>",
|
||||||
|
NDB_VERSION_STRING);
|
||||||
|
|
||||||
// Add trailing blanks to get a fixed lenght of the message
|
// Add trailing blanks to get a fixed lenght of the message
|
||||||
while (strlen(messptr) <= MESSAGE_LENGTH-3){
|
while (strlen(messptr) <= MESSAGE_LENGTH-3){
|
||||||
|
|
|
||||||
|
|
@ -752,5 +752,5 @@ NdbIndexOperation::receiveTCINDXREF( NdbApiSignal* aSignal)
|
||||||
Uint32 errorCode = tcIndxRef->errorCode;
|
Uint32 errorCode = tcIndxRef->errorCode;
|
||||||
theError.code = errorCode;
|
theError.code = errorCode;
|
||||||
theNdbCon->setOperationErrorCodeAbort(errorCode);
|
theNdbCon->setOperationErrorCodeAbort(errorCode);
|
||||||
return theNdbCon->OpCompleteFailure(theNdbCon->m_abortOption);
|
return theNdbCon->OpCompleteFailure(AbortOnError);
|
||||||
}//NdbIndexOperation::receiveTCINDXREF()
|
}//NdbIndexOperation::receiveTCINDXREF()
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,7 @@ ErrorBundle ErrorCodes[] = {
|
||||||
{ 4021, TR, "Out of Send Buffer space in NDB API" },
|
{ 4021, TR, "Out of Send Buffer space in NDB API" },
|
||||||
{ 4022, TR, "Out of Send Buffer space in NDB API" },
|
{ 4022, TR, "Out of Send Buffer space in NDB API" },
|
||||||
{ 4032, TR, "Out of Send Buffer space in NDB API" },
|
{ 4032, TR, "Out of Send Buffer space in NDB API" },
|
||||||
|
{ 288, TR, "Out of index operations in transaction coordinator (increase MaxNoOfConcurrentIndexOperations)" },
|
||||||
/**
|
/**
|
||||||
* InsufficientSpace
|
* InsufficientSpace
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue