Commit 05ba11bf authored by unknown's avatar unknown

Merge perch.ndb.mysql.com:/home/jonas/src/50-work

into  perch.ndb.mysql.com:/home/jonas/src/51-work


storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp:
  Auto merged
storage/ndb/include/ndbapi/NdbTransaction.hpp:
  merge
storage/ndb/src/ndbapi/NdbScanOperation.cpp:
  merge
storage/ndb/src/ndbapi/NdbTransaction.cpp:
  merge
parents fe4672d7 6806ca7d
...@@ -658,8 +658,11 @@ private: ...@@ -658,8 +658,11 @@ private:
// Release all cursor operations in connection // Release all cursor operations in connection
void releaseOps(NdbOperation*); void releaseOps(NdbOperation*);
void releaseScanOperations(NdbIndexScanOperation*); void releaseScanOperations(NdbIndexScanOperation*);
void releaseScanOperation(NdbIndexScanOperation*); bool releaseScanOperation(NdbIndexScanOperation** listhead,
NdbIndexScanOperation** listtail,
NdbIndexScanOperation* op);
void releaseExecutedScanOperation(NdbIndexScanOperation*);
// Set the transaction identity of the transaction // Set the transaction identity of the transaction
void setTransactionId(Uint64 aTransactionId); void setTransactionId(Uint64 aTransactionId);
......
...@@ -10015,73 +10015,84 @@ void Dbdih::startNextChkpt(Signal* signal) ...@@ -10015,73 +10015,84 @@ void Dbdih::startNextChkpt(Signal* signal)
nodePtr.i = replicaPtr.p->procNode; nodePtr.i = replicaPtr.p->procNode;
ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord); ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
if (replicaPtr.p->lcpOngoingFlag && if (c_lcpState.m_participatingLQH.get(nodePtr.i))
replicaPtr.p->lcpIdStarted < lcpId) { {
jam(); if (replicaPtr.p->lcpOngoingFlag &&
//------------------------------------------------------------------- replicaPtr.p->lcpIdStarted < lcpId)
// We have found a replica on a node that performs local checkpoint {
// that is alive and that have not yet been started. jam();
//------------------------------------------------------------------- //-------------------------------------------------------------------
// We have found a replica on a node that performs local checkpoint
if (nodePtr.p->noOfStartedChkpt < 2) { // that is alive and that have not yet been started.
jam(); //-------------------------------------------------------------------
/**
* Send LCP_FRAG_ORD to LQH
*/
/**
* 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; if (nodePtr.p->noOfStartedChkpt < 2)
nodePtr.p->queuedChkpt[i].tableId = tabPtr.i; {
nodePtr.p->queuedChkpt[i].fragId = curr.fragmentId; jam();
nodePtr.p->queuedChkpt[i].replicaPtr = replicaPtr.i; /**
nodePtr.p->noOfQueuedChkpt = i + 1; * Send LCP_FRAG_ORD to LQH
} else { */
jam();
/**
* Mark the replica so with lcpIdStarted == true
*/
replicaPtr.p->lcpIdStarted = lcpId;
if(save){ 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();
/** /**
* Stop increasing value on first that was "full" * Put LCP_FRAG_ORD "in queue"
*/ */
c_lcpState.currentFragment = curr;
save = false;
}
busyNodes.set(nodePtr.i);
if(busyNodes.count() == lcpNodes){
/** /**
* There were no possibility to start the local checkpoint * Mark the replica so with lcpIdStarted == true
* 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; 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
}//if }
} }//while
}//while }
curr.fragmentId++; curr.fragmentId++;
if (curr.fragmentId >= tabPtr.p->totalfragments) { if (curr.fragmentId >= tabPtr.p->totalfragments) {
jam(); jam();
......
...@@ -694,9 +694,27 @@ void NdbScanOperation::close(bool forceSend, bool releaseOp) ...@@ -694,9 +694,27 @@ void NdbScanOperation::close(bool forceSend, bool releaseOp)
theNdbCon = NULL; theNdbCon = NULL;
m_transConnection = NULL; m_transConnection = NULL;
if (releaseOp && tTransCon) { if (tTransCon)
{
NdbIndexScanOperation* tOp = (NdbIndexScanOperation*)this; 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; tCon->theScanningOp = 0;
......
...@@ -979,50 +979,59 @@ Remark: Release scan op when hupp'ed trans closed (save memory) ...@@ -979,50 +979,59 @@ Remark: Release scan op when hupp'ed trans closed (save memory)
void void
NdbTransaction::releaseScanOperation(NdbIndexScanOperation* cursorOp) 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)); 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 bool
if (cursorOp->m_executed) NdbTransaction::releaseScanOperation(NdbIndexScanOperation** listhead,
NdbIndexScanOperation** listtail,
NdbIndexScanOperation* op)
{
if (* listhead == op)
{ {
if (m_firstExecutedScanOp == cursorOp) { * listhead = (NdbIndexScanOperation*)op->theNext;
m_firstExecutedScanOp = (NdbIndexScanOperation*)cursorOp->theNext; if (listtail && *listtail == op)
cursorOp->release(); {
theNdb->releaseScanOperation(cursorOp); assert(* listhead == 0);
} else if (m_firstExecutedScanOp != NULL) { * listtail = 0;
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;
}
} }
} }
else else
{ {
if (m_theFirstScanOperation == cursorOp) { NdbIndexScanOperation* tmp = * listhead;
m_theFirstScanOperation = (NdbIndexScanOperation*)cursorOp->theNext; while (tmp != NULL)
cursorOp->release(); {
theNdb->releaseScanOperation(cursorOp); if (tmp->theNext == op)
} else if (m_theFirstScanOperation != NULL) { {
NdbIndexScanOperation* tOp = m_theFirstScanOperation; tmp->theNext = (NdbIndexScanOperation*)op->theNext;
while (tOp->theNext != NULL) { if (listtail && *listtail == op)
if (tOp->theNext == cursorOp) { {
tOp->theNext = cursorOp->theNext; assert(op->theNext == 0);
cursorOp->release(); *listtail = tmp;
theNdb->releaseScanOperation(cursorOp); }
break; break;
}
tOp = (NdbIndexScanOperation*)tOp->theNext;
} }
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); NdbOperation* getNdbOperation(const char* aTableName);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment