diff --git a/storage/ndb/include/ndbapi/NdbTransaction.hpp b/storage/ndb/include/ndbapi/NdbTransaction.hpp index 59816b94545..e29752efb7b 100644 --- a/storage/ndb/include/ndbapi/NdbTransaction.hpp +++ b/storage/ndb/include/ndbapi/NdbTransaction.hpp @@ -658,8 +658,11 @@ private: // Release all cursor operations in connection void releaseOps(NdbOperation*); void releaseScanOperations(NdbIndexScanOperation*); - void releaseScanOperation(NdbIndexScanOperation*); - + bool releaseScanOperation(NdbIndexScanOperation** listhead, + NdbIndexScanOperation** listtail, + NdbIndexScanOperation* op); + void releaseExecutedScanOperation(NdbIndexScanOperation*); + // Set the transaction identity of the transaction void setTransactionId(Uint64 aTransactionId); diff --git a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp index 6dce44b0792..d950bc6d167 100644 --- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp +++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp @@ -10015,73 +10015,84 @@ void Dbdih::startNextChkpt(Signal* signal) nodePtr.i = replicaPtr.p->procNode; ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord); - if (replicaPtr.p->lcpOngoingFlag && - replicaPtr.p->lcpIdStarted < lcpId) { - jam(); - //------------------------------------------------------------------- - // We have found a replica on a node that performs local checkpoint - // that is alive and that have not yet been started. - //------------------------------------------------------------------- - - if (nodePtr.p->noOfStartedChkpt < 2) { - jam(); - /** - * Send LCP_FRAG_ORD to LQH - */ + if (c_lcpState.m_participatingLQH.get(nodePtr.i)) + { + if (replicaPtr.p->lcpOngoingFlag && + replicaPtr.p->lcpIdStarted < lcpId) + { + jam(); + //------------------------------------------------------------------- + // We have found a replica on a node that performs local checkpoint + // that is alive and that have not yet been started. + //------------------------------------------------------------------- - /** - * Mark the replica so with lcpIdStarted == true - */ - replicaPtr.p->lcpIdStarted = lcpId; - - Uint32 i = nodePtr.p->noOfStartedChkpt; - nodePtr.p->startedChkpt[i].tableId = tabPtr.i; - nodePtr.p->startedChkpt[i].fragId = curr.fragmentId; - nodePtr.p->startedChkpt[i].replicaPtr = replicaPtr.i; - nodePtr.p->noOfStartedChkpt = i + 1; - - sendLCP_FRAG_ORD(signal, nodePtr.p->startedChkpt[i]); - } else if (nodePtr.p->noOfQueuedChkpt < 2) { - jam(); - /** - * Put LCP_FRAG_ORD "in queue" - */ - - /** - * Mark the replica so with lcpIdStarted == true - */ - replicaPtr.p->lcpIdStarted = lcpId; - - Uint32 i = nodePtr.p->noOfQueuedChkpt; - nodePtr.p->queuedChkpt[i].tableId = tabPtr.i; - nodePtr.p->queuedChkpt[i].fragId = curr.fragmentId; - nodePtr.p->queuedChkpt[i].replicaPtr = replicaPtr.i; - nodePtr.p->noOfQueuedChkpt = i + 1; - } else { - jam(); - - if(save){ + if (nodePtr.p->noOfStartedChkpt < 2) + { + jam(); /** - * Stop increasing value on first that was "full" + * Send LCP_FRAG_ORD to LQH */ - c_lcpState.currentFragment = curr; - save = false; - } - - busyNodes.set(nodePtr.i); - if(busyNodes.count() == lcpNodes){ + /** - * There were no possibility to start the local checkpoint - * and it was not possible to queue it up. In this case we - * stop the start of local checkpoints until the nodes with a - * backlog have performed more checkpoints. We will return and - * will not continue the process of starting any more checkpoints. + * Mark the replica so with lcpIdStarted == true */ - return; + replicaPtr.p->lcpIdStarted = lcpId; + + Uint32 i = nodePtr.p->noOfStartedChkpt; + nodePtr.p->startedChkpt[i].tableId = tabPtr.i; + nodePtr.p->startedChkpt[i].fragId = curr.fragmentId; + nodePtr.p->startedChkpt[i].replicaPtr = replicaPtr.i; + nodePtr.p->noOfStartedChkpt = i + 1; + + sendLCP_FRAG_ORD(signal, nodePtr.p->startedChkpt[i]); + } + else if (nodePtr.p->noOfQueuedChkpt < 2) + { + jam(); + /** + * Put LCP_FRAG_ORD "in queue" + */ + + /** + * Mark the replica so with lcpIdStarted == true + */ + replicaPtr.p->lcpIdStarted = lcpId; + + Uint32 i = nodePtr.p->noOfQueuedChkpt; + nodePtr.p->queuedChkpt[i].tableId = tabPtr.i; + nodePtr.p->queuedChkpt[i].fragId = curr.fragmentId; + nodePtr.p->queuedChkpt[i].replicaPtr = replicaPtr.i; + nodePtr.p->noOfQueuedChkpt = i + 1; + } + else + { + jam(); + + if(save) + { + /** + * Stop increasing value on first that was "full" + */ + c_lcpState.currentFragment = curr; + save = false; + } + + busyNodes.set(nodePtr.i); + if(busyNodes.count() == lcpNodes) + { + /** + * There were no possibility to start the local checkpoint + * and it was not possible to queue it up. In this case we + * stop the start of local checkpoints until the nodes with a + * backlog have performed more checkpoints. We will return and + * will not continue the process of starting any more checkpoints. + */ + return; + }//if }//if - }//if - } - }//while + } + }//while + } curr.fragmentId++; if (curr.fragmentId >= tabPtr.p->totalfragments) { jam(); diff --git a/storage/ndb/src/ndbapi/NdbScanOperation.cpp b/storage/ndb/src/ndbapi/NdbScanOperation.cpp index 21e4f215c65..31461235fe5 100644 --- a/storage/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/storage/ndb/src/ndbapi/NdbScanOperation.cpp @@ -694,9 +694,27 @@ void NdbScanOperation::close(bool forceSend, bool releaseOp) theNdbCon = NULL; m_transConnection = NULL; - if (releaseOp && tTransCon) { + if (tTransCon) + { NdbIndexScanOperation* tOp = (NdbIndexScanOperation*)this; - tTransCon->releaseScanOperation(tOp); + + bool ret = true; + if (theStatus != WaitResponse) + { + /** + * Not executed yet + */ + ret = + tTransCon->releaseScanOperation(&tTransCon->m_theFirstScanOperation, + &tTransCon->m_theLastScanOperation, + tOp); + } + else if (releaseOp) + { + ret = tTransCon->releaseScanOperation(&tTransCon->m_firstExecutedScanOp, + 0, tOp); + } + assert(ret); } tCon->theScanningOp = 0; diff --git a/storage/ndb/src/ndbapi/NdbTransaction.cpp b/storage/ndb/src/ndbapi/NdbTransaction.cpp index 916135b12d5..31c7f43727d 100644 --- a/storage/ndb/src/ndbapi/NdbTransaction.cpp +++ b/storage/ndb/src/ndbapi/NdbTransaction.cpp @@ -979,50 +979,59 @@ Remark: Release scan op when hupp'ed trans closed (save memory) void NdbTransaction::releaseScanOperation(NdbIndexScanOperation* cursorOp) { - DBUG_ENTER("NdbTransaction::releaseScanOperation"); + DBUG_ENTER("NdbTransaction::releaseExecutedScanOperation"); DBUG_PRINT("enter", ("this=0x%x op=0x%x", (UintPtr)this, (UintPtr)cursorOp)); + + releaseScanOperation(&m_firstExecutedScanOp, 0, cursorOp); + + DBUG_VOID_RETURN; +}//NdbTransaction::releaseExecutedScanOperation() - // here is one reason to make op lists doubly linked - if (cursorOp->m_executed) +bool +NdbTransaction::releaseScanOperation(NdbIndexScanOperation** listhead, + NdbIndexScanOperation** listtail, + NdbIndexScanOperation* op) +{ + if (* listhead == op) { - if (m_firstExecutedScanOp == cursorOp) { - m_firstExecutedScanOp = (NdbIndexScanOperation*)cursorOp->theNext; - cursorOp->release(); - theNdb->releaseScanOperation(cursorOp); - } else if (m_firstExecutedScanOp != NULL) { - NdbIndexScanOperation* tOp = m_firstExecutedScanOp; - while (tOp->theNext != NULL) { - if (tOp->theNext == cursorOp) { - tOp->theNext = cursorOp->theNext; - cursorOp->release(); - theNdb->releaseScanOperation(cursorOp); - break; - } - tOp = (NdbIndexScanOperation*)tOp->theNext; - } + * listhead = (NdbIndexScanOperation*)op->theNext; + if (listtail && *listtail == op) + { + assert(* listhead == 0); + * listtail = 0; } + } else { - if (m_theFirstScanOperation == cursorOp) { - m_theFirstScanOperation = (NdbIndexScanOperation*)cursorOp->theNext; - cursorOp->release(); - theNdb->releaseScanOperation(cursorOp); - } else if (m_theFirstScanOperation != NULL) { - NdbIndexScanOperation* tOp = m_theFirstScanOperation; - while (tOp->theNext != NULL) { - if (tOp->theNext == cursorOp) { - tOp->theNext = cursorOp->theNext; - cursorOp->release(); - theNdb->releaseScanOperation(cursorOp); - break; - } - tOp = (NdbIndexScanOperation*)tOp->theNext; + NdbIndexScanOperation* tmp = * listhead; + while (tmp != NULL) + { + if (tmp->theNext == op) + { + tmp->theNext = (NdbIndexScanOperation*)op->theNext; + if (listtail && *listtail == op) + { + assert(op->theNext == 0); + *listtail = tmp; + } + break; } + tmp = (NdbIndexScanOperation*)tmp->theNext; } + if (tmp == NULL) + op = NULL; } - DBUG_VOID_RETURN; -}//NdbTransaction::releaseScanOperation() + + if (op != NULL) + { + op->release(); + theNdb->releaseScanOperation(op); + return true; + } + + return false; +} /***************************************************************************** NdbOperation* getNdbOperation(const char* aTableName);