Commit f3d86403 authored by joreland@mysql.com's avatar joreland@mysql.com

bug-4586

parent e8e4772b
......@@ -1192,6 +1192,7 @@ private:
void reportMemoryUsage(Signal* signal, int gth);
void lcp_write_op_to_undolog(Signal* signal);
void reenable_expand_after_redo_log_exection_complete(Signal*);
// Initialisation
......@@ -1561,11 +1562,9 @@ private:
Uint32 cexcPrevforward;
Uint32 clocalkey[32];
Uint32 ckeys[2048];
Uint32 c_errorInsert3000_TableId;
Uint32 cSrUndoRecords[5];
Uint32 c_no_fragment_allocated;
};
#endif
......@@ -599,7 +599,6 @@ void Dbacc::ndbrestart1Lab(Signal* signal)
for (Uint32 tmp = 0; tmp < ZMAX_UNDO_VERSION; tmp++) {
csrVersList[tmp] = RNIL;
}//for
c_no_fragment_allocated = 0;
return;
}//Dbacc::ndbrestart1Lab()
......@@ -1361,8 +1360,6 @@ void Dbacc::releaseDirIndexResources(Signal* signal, FragmentrecPtr regFragPtr)
void Dbacc::releaseFragRecord(Signal* signal, FragmentrecPtr regFragPtr)
{
ndbrequire(c_no_fragment_allocated > 0);
c_no_fragment_allocated--;
regFragPtr.p->nextfreefrag = cfirstfreefrag;
cfirstfreefrag = regFragPtr.i;
initFragGeneral(regFragPtr);
......@@ -2342,13 +2339,14 @@ void Dbacc::execACC_COMMITREQ(Signal* signal)
fragrecptr.p->slack += operationRecPtr.p->insertDeleteLen;
if (fragrecptr.p->slack > fragrecptr.p->slackCheck) { /* TIME FOR JOIN BUCKETS PROCESS */
if (fragrecptr.p->expandCounter > 0) {
if (fragrecptr.p->expandFlag == 0) {
if (fragrecptr.p->expandFlag < 2) {
jam();
fragrecptr.p->expandFlag = 1;
signal->theData[0] = fragrecptr.i;
signal->theData[1] = fragrecptr.p->p;
signal->theData[2] = fragrecptr.p->maxp;
sendSignal(cownBlockref, GSN_SHRINKCHECK2, signal, 3, JBB);
signal->theData[3] = fragrecptr.p->expandFlag;
fragrecptr.p->expandFlag = 2;
sendSignal(cownBlockref, GSN_SHRINKCHECK2, signal, 4, JBB);
}//if
}//if
}//if
......@@ -2362,7 +2360,7 @@ void Dbacc::execACC_COMMITREQ(Signal* signal)
if (fragrecptr.p->slack >= (Uint32)(1 << 31)) { /* IT MEANS THAT IF SLACK < ZERO */
if (fragrecptr.p->expandFlag == 0) {
jam();
fragrecptr.p->expandFlag = 1;
fragrecptr.p->expandFlag = 2;
signal->theData[0] = fragrecptr.i;
signal->theData[1] = fragrecptr.p->p;
signal->theData[2] = fragrecptr.p->maxp;
......@@ -6334,9 +6332,16 @@ Uint32 Dbacc::checkScanExpand(Signal* signal)
void Dbacc::execEXPANDCHECK2(Signal* signal)
{
jamEntry();
if(refToBlock(signal->getSendersBlockRef()) == DBLQH){
jam();
reenable_expand_after_redo_log_exection_complete(signal);
return;
}
DirectoryarrayPtr newDirptr;
jamEntry();
fragrecptr.i = signal->theData[0];
tresult = 0; /* 0= FALSE,1= TRUE,> ZLIMIT_OF_ERROR =ERRORCODE */
Uint32 tmp = 1;
......@@ -6353,7 +6358,7 @@ void Dbacc::execEXPANDCHECK2(Signal* signal)
return;
}//if
if (cfirstfreepage == RNIL) {
if ((cfreepage + c_no_fragment_allocated) >= cpagesize) {
if (cfreepage + 10 >= cpagesize) {
jam();
/*--------------------------------------------------------------*/
/* WE HAVE TO STOP THE EXPAND PROCESS SINCE THERE ARE NO FREE */
......@@ -6394,6 +6399,10 @@ void Dbacc::execEXPANDCHECK2(Signal* signal)
return;
}//if
}//if
ndbout_c("Expanding tab: %d frag: %d",
fragrecptr.p->myTableId, fragrecptr.p->myfid);
/*--------------------------------------------------------------------------*/
/* WE START BY FINDING THE PAGE, THE PAGE INDEX AND THE PAGE DIRECTORY*/
/* OF THE NEW BUCKET WHICH SHALL RECEIVE THE ELEMENT WHICH HAVE A 1 IN*/
......@@ -6447,6 +6456,7 @@ void Dbacc::execEXPANDCHECK2(Signal* signal)
} else {
ptrCheckGuard(expPageptr, cpagesize, page8);
}//if
fragrecptr.p->expReceivePageptr = expPageptr.i;
fragrecptr.p->expReceiveIndex = texpReceivedBucket & ((1 << fragrecptr.p->k) - 1);
/*--------------------------------------------------------------------------*/
......@@ -6497,7 +6507,7 @@ void Dbacc::endofexpLab(Signal* signal)
/* IT IS STILL NECESSARY TO EXPAND THE FRAGMENT EVEN MORE. START IT FROM HERE */
/* WITHOUT WAITING FOR NEXT COMMIT ON THE FRAGMENT. */
/* --------------------------------------------------------------------------------- */
fragrecptr.p->expandFlag = 1;
fragrecptr.p->expandFlag = 2;
signal->theData[0] = fragrecptr.i;
signal->theData[1] = fragrecptr.p->p;
signal->theData[2] = fragrecptr.p->maxp;
......@@ -6506,6 +6516,46 @@ void Dbacc::endofexpLab(Signal* signal)
return;
}//Dbacc::endofexpLab()
void Dbacc::reenable_expand_after_redo_log_exection_complete(Signal* signal){
tabptr.i = signal->theData[0];
Uint32 fragId = signal->theData[1];
ptrCheckGuard(tabptr, ctablesize, tabrec);
ndbrequire(getrootfragmentrec(signal, rootfragrecptr, fragId));
ndbout_c("reenable expand check for table %d fragment: %d",
tabptr.i, fragId);
for (Uint32 i = 0; i < 2; i++) {
fragrecptr.i = rootfragrecptr.p->fragmentptr[i];
ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
switch(fragrecptr.p->expandFlag){
case 0:
/**
* Hmm... this means that it's alreay has been reenabled...
*/
//ndbassert(false);
continue;
case 1:
/**
* Nothing is going on start expand check
*/
case 2:
/**
* A shrink is running, do expand check anyway
* (to reset expandFlag)
*/
fragrecptr.p->expandFlag = 2;
signal->theData[0] = fragrecptr.i;
signal->theData[1] = fragrecptr.p->p;
signal->theData[2] = fragrecptr.p->maxp;
sendSignal(cownBlockref, GSN_EXPANDCHECK2, signal, 3, JBB);
break;
}
}
}
void Dbacc::execDEBUG_SIG(Signal* signal)
{
jamEntry();
......@@ -6901,9 +6951,10 @@ void Dbacc::execSHRINKCHECK2(Signal* signal)
jamEntry();
fragrecptr.i = signal->theData[0];
Uint32 oldFlag = signal->theData[3];
fragrecptr.p->expandFlag = oldFlag;
tresult = 0; /* 0= FALSE,1= TRUE,> ZLIMIT_OF_ERROR =ERRORCODE */
ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
fragrecptr.p->expandFlag = 0;
if (fragrecptr.p->slack <= fragrecptr.p->slackCheck) {
jam();
/* TIME FOR JOIN BUCKETS PROCESS */
......@@ -6938,7 +6989,7 @@ void Dbacc::execSHRINKCHECK2(Signal* signal)
}//if
}//if
if (cfirstfreepage == RNIL) {
if (cfreepage + c_no_fragment_allocated >= cpagesize) {
if (cfreepage >= cpagesize) {
jam();
/*--------------------------------------------------------------*/
/* WE HAVE TO STOP THE SHRINK PROCESS SINCE THERE ARE NO FREE */
......@@ -6984,6 +7035,10 @@ void Dbacc::execSHRINKCHECK2(Signal* signal)
jam();
fragrecptr.p->p--;
}//if
ndbout_c("Shrinking tab: %d frag: %d",
fragrecptr.p->myTableId, fragrecptr.p->myfid);
/*--------------------------------------------------------------------------*/
/* WE START BY FINDING THE NECESSARY INFORMATION OF THE BUCKET TO BE */
/* REMOVED WHICH WILL SEND ITS ELEMENTS TO THE RECEIVING BUCKET. */
......@@ -7176,10 +7231,11 @@ void Dbacc::endofshrinkbucketLab(Signal* signal)
/* SHRINKING BELOW 2^K - 1 (NOW 63). THIS WAS A BUG THAT */
/* WAS REMOVED 2000-05-12. */
/*--------------------------------------------------------------*/
fragrecptr.p->expandFlag = 1;
signal->theData[0] = fragrecptr.i;
signal->theData[1] = fragrecptr.p->p;
signal->theData[2] = fragrecptr.p->maxp;
signal->theData[3] = fragrecptr.p->expandFlag;
fragrecptr.p->expandFlag = 2;
sendSignal(cownBlockref, GSN_SHRINKCHECK2, signal, 3, JBB);
}//if
}//if
......@@ -9196,7 +9252,15 @@ void Dbacc::initFragAdd(Signal* signal,
ndbrequire(req->kValue == 6);
regFragPtr.p->k = req->kValue; /* TK_SIZE = 6 IN THIS VERSION */
regFragPtr.p->expandCounter = 0;
regFragPtr.p->expandFlag = 0;
/**
* Only allow shrink during SR
* - to make sure we don't run out of pages during REDO log execution
*
* Is later restored to 0 by LQH at end of REDO log execution
*/
regFragPtr.p->expandFlag = (getNodeState().getSystemRestartInProgress()?1:0);
regFragPtr.p->p = 0;
regFragPtr.p->maxp = (1 << req->kValue) - 1;
regFragPtr.p->minloadfactor = minLoadFactor;
......@@ -12775,7 +12839,6 @@ void Dbacc::seizeDirrange(Signal* signal)
/* --------------------------------------------------------------------------------- */
void Dbacc::seizeFragrec(Signal* signal)
{
c_no_fragment_allocated++;
fragrecptr.i = cfirstfreefrag;
ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
cfirstfreefrag = fragrecptr.p->nextfreefrag;
......
......@@ -2764,6 +2764,11 @@ private:
/* ------------------------------------------------------------------------- */
UintR cfirstCompletedFragSr;
/**
* List of fragment that the log execution is completed for
*/
Uint32 c_redo_log_complete_frags;
/* ------------------------------------------------------------------------- */
/*USED DURING SYSTEM RESTART, INDICATES THE OLDEST GCI THAT CAN BE RESTARTED */
/*FROM AFTER THIS SYSTEM RESTART. USED TO FIND THE LOG TAIL. */
......
......@@ -65,6 +65,7 @@ void Dblqh::initData()
cLqhTimeOutCount = 0;
cLqhTimeOutCheckCount = 0;
cbookedAccOps = 0;
c_redo_log_complete_frags = RNIL;
}//Dblqh::initData()
void Dblqh::initRecords()
......
......@@ -13642,14 +13642,22 @@ void Dblqh::execSTART_EXEC_SR(Signal* signal)
* ALSO SEND START_FRAGCONF TO DIH AND SET THE STATE TO ACTIVE ON THE
* FRAGMENT.
* ------------------------------------------------------------------- */
Uint32 next = fragptr.p->nextFrag;
if (prevFragptr.i != RNIL) {
jam();
ptrCheckGuard(prevFragptr, cfragrecFileSize, fragrecord);
prevFragptr.p->nextFrag = fragptr.p->nextFrag;
prevFragptr.p->nextFrag = next;
} else {
jam();
cfirstCompletedFragSr = fragptr.p->nextFrag;
cfirstCompletedFragSr = next;
}//if
/**
* Put fragment on list which has completed REDO log
*/
fragptr.p->nextFrag = c_redo_log_complete_frags;
c_redo_log_complete_frags = fragptr.i;
fragptr.p->fragStatus = Fragrecord::FSACTIVE;
fragptr.p->logFlag = Fragrecord::STATE_TRUE;
signal->theData[0] = fragptr.p->srUserptr;
......@@ -13661,7 +13669,7 @@ void Dblqh::execSTART_EXEC_SR(Signal* signal)
* THIS IS PERFORMED BY KEEPING PREV_FRAGPTR AS PREV_FRAGPTR BUT MOVING
* FRAGPTR TO THE NEXT FRAGMENT IN THE LIST.
* ------------------------------------------------------------------- */
fragptr.i = fragptr.p->nextFrag;
fragptr.i = next;
}//if
signal->theData[0] = fragptr.i;
signal->theData[1] = prevFragptr.i;
......@@ -15267,6 +15275,20 @@ void Dblqh::srFourthComp(Signal* signal)
conf->startingNodeId = getOwnNodeId();
sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal,
StartRecConf::SignalLength, JBB);
if(cstartType == NodeState::ST_SYSTEM_RESTART){
fragptr.i = c_redo_log_complete_frags;
ndbout_c("All fragment complete - ");
while(fragptr.i != RNIL){
ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
signal->theData[0] = fragptr.p->tabRef;
signal->theData[1] = fragptr.p->fragId;
sendSignal(DBACC_REF, GSN_EXPANDCHECK2, signal, 2, JBB);
ndbout_c("table: %d fragment: %d",
fragptr.p->tabRef, fragptr.p->fragId);
fragptr.i = fragptr.p->nextFrag;
}
}
} else {
ndbrequire(false);
}//if
......
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