DblqhMain.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:703k
- /* WRITE PAGE ZERO IN FILE ZERO. LOG_FILE_REC WILL REFER TO THE LOG FILE WE */
- /* HAVE JUST WRITTEN PAGE ZERO IN TO GET HOLD OF LOG_FILE_PTR FOR THIS */
- /* RECORD QUICKLY. THIS IS NEEDED TO GET HOLD OF THE FILE_CHANGE_STATE. */
- /* THE ONLY INFORMATION WE WANT TO CHANGE IS THE LAST FILE NUMBER IN THE */
- /* FILE DESCRIPTOR. THIS IS USED AT SYSTEM RESTART TO FIND THE END OF THE */
- /* LOG PART. */
- /*---------------------------------------------------------------------------*/
- Uint32 currLogFile = logFilePtr.i;
- logFilePtr.i = logPartPtr.p->firstLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPagePtr.i = logFilePtr.p->logPageZero;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_FILE_NO] = fileNo;
- writeSinglePage(signal, 0, ZPAGE_SIZE - 1, __LINE__);
- lfoPtr.p->logFileRec = currLogFile;
- lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_PAGE_ZERO;
- return;
- }//if
- }//if
- }//Dblqh::firstPageWriteLab()
- void Dblqh::lastWriteInFileLab(Signal* signal)
- {
- LogFileRecordPtr locLogFilePtr;
- /*---------------------------------------------------------------------------*/
- /* CHECK IF ANY GLOBAL CHECKPOINTS ARE COMPLETED DUE TO THIS COMPLETED DISK */
- /* WRITE. */
- /*---------------------------------------------------------------------------*/
- checkGcpCompleted(signal,
- ((lfoPtr.p->lfoPageNo + lfoPtr.p->noPagesRw) - 1),
- (ZPAGE_SIZE - 1));
- releaseLfoPages(signal);
- releaseLfo(signal);
- /*---------------------------------------------------------------------------*/
- /* IF THE FILE IS NOT IN USE OR THE NEXT FILE TO BE USED WE WILL CLOSE IT. */
- /*---------------------------------------------------------------------------*/
- locLogFilePtr.i = logPartPtr.p->currentLogfile;
- ptrCheckGuard(locLogFilePtr, clogFileFileSize, logFileRecord);
- if (logFilePtr.i != locLogFilePtr.i) {
- if (logFilePtr.i != locLogFilePtr.p->nextLogFile) {
- if (logFilePtr.p->fileNo != 0) {
- jam();
- /*---------------------------------------------------------------------------*/
- /* THE FILE IS NOT FILE ZERO EITHER. WE WILL NOT CLOSE FILE ZERO SINCE WE */
- /* USE IT TO KEEP TRACK OF THE CURRENT LOG FILE BY WRITING PAGE ZERO IN */
- /* FILE ZERO. */
- /*---------------------------------------------------------------------------*/
- /* WE WILL CLOSE THE FILE. */
- /*---------------------------------------------------------------------------*/
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_WRITE_LOG;
- closeFile(signal, logFilePtr);
- }//if
- }//if
- }//if
- /*---------------------------------------------------------------------------*/
- /* IF A NEW FILE HAS BEEN OPENED WE SHALL ALWAYS ALSO WRITE TO PAGE O IN */
- /* FILE 0. THE AIM IS TO MAKE RESTARTS EASIER BY SPECIFYING WHICH IS THE */
- /* LAST FILE WHERE LOGGING HAS STARTED. */
- /*---------------------------------------------------------------------------*/
- /* FIRST CHECK WHETHER THE FIRST WRITE IN THE NEW FILE HAVE COMPLETED */
- /* THIS STATE INFORMATION IS IN THE NEW LOG FILE AND THUS WE HAVE TO MOVE */
- /* THE LOG FILE POINTER TO THIS LOG FILE. */
- /*---------------------------------------------------------------------------*/
- logFilePtr.i = logFilePtr.p->nextLogFile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- if (logFilePtr.p->fileChangeState == LogFileRecord::BOTH_WRITES_ONGOING) {
- jam();
- /*---------------------------------------------------------------------------*/
- /* THE FIRST WRITE WAS STILL ONGOING. */
- /*---------------------------------------------------------------------------*/
- logFilePtr.p->fileChangeState = LogFileRecord::FIRST_WRITE_ONGOING;
- return;
- } else {
- ndbrequire(logFilePtr.p->fileChangeState == LogFileRecord::LAST_WRITE_ONGOING);
- /*---------------------------------------------------------------------------*/
- /* WRITE TO PAGE 0 IN IN FILE 0 NOW. */
- /*---------------------------------------------------------------------------*/
- logFilePtr.p->fileChangeState = LogFileRecord::WRITE_PAGE_ZERO_ONGOING;
- Uint32 fileNo = logFilePtr.p->fileNo;
- if (fileNo == 0) {
- jam();
- /*---------------------------------------------------------------------------*/
- /* IF THE NEW FILE WAS 0 THEN WE HAVE ALREADY WRITTEN PAGE ZERO IN FILE 0. */
- /*---------------------------------------------------------------------------*/
- logFilePtr.p->fileChangeState = LogFileRecord::NOT_ONGOING;
- return;
- } else {
- jam();
- /*---------------------------------------------------------------------------*/
- /* WRITE PAGE ZERO IN FILE ZERO. LOG_FILE_REC WILL REFER TO THE LOG FILE WE */
- /* HAVE JUST WRITTEN PAGE ZERO IN TO GET HOLD OF LOG_FILE_PTR FOR THIS */
- /* RECORD QUICKLY. THIS IS NEEDED TO GET HOLD OF THE FILE_CHANGE_STATE. */
- /* THE ONLY INFORMATION WE WANT TO CHANGE IS THE LAST FILE NUMBER IN THE */
- /* FILE DESCRIPTOR. THIS IS USED AT SYSTEM RESTART TO FIND THE END OF THE */
- /* LOG PART. */
- /*---------------------------------------------------------------------------*/
- Uint32 currLogFile = logFilePtr.i;
- logFilePtr.i = logPartPtr.p->firstLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPagePtr.i = logFilePtr.p->logPageZero;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_FILE_NO] = fileNo;
- writeSinglePage(signal, 0, ZPAGE_SIZE - 1, __LINE__);
- lfoPtr.p->logFileRec = currLogFile;
- lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_PAGE_ZERO;
- return;
- }//if
- }//if
- }//Dblqh::lastWriteInFileLab()
- void Dblqh::writePageZeroLab(Signal* signal)
- {
- logFilePtr.p->fileChangeState = LogFileRecord::NOT_ONGOING;
- /*---------------------------------------------------------------------------*/
- /* IT COULD HAVE ARRIVED PAGE WRITES TO THE CURRENT FILE WHILE WE WERE */
- /* WAITING FOR THIS DISK WRITE TO COMPLETE. THEY COULD NOT CHECK FOR */
- /* COMPLETED GLOBAL CHECKPOINTS. THUS WE SHOULD DO THAT NOW INSTEAD. */
- /*---------------------------------------------------------------------------*/
- checkGcpCompleted(signal,
- logFilePtr.p->lastPageWritten,
- logFilePtr.p->lastWordWritten);
- releaseLfo(signal);
- return;
- }//Dblqh::writePageZeroLab()
- /* ######################################################################### */
- /* INITIAL START MODULE */
- /* THIS MODULE IS A SUB-MODULE OF THE FILE SYSTEM HANDLING. */
- /* */
- /*THIS MODULE INITIALISES ALL THE LOG FILES THAT ARE NEEDED AT A SYSTEM */
- /*RESTART AND WHICH ARE USED DURING NORMAL OPERATIONS. IT CREATES THE FILES */
- /*AND SETS A PROPER SIZE OF THEM AND INITIALISES THE FIRST PAGE IN EACH FILE */
- /* ######################################################################### */
- void Dblqh::openFileInitLab(Signal* signal)
- {
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN_INIT;
- seizeLogpage(signal);
- writeSinglePage(signal, (ZNO_MBYTES_IN_FILE * ZPAGES_IN_MBYTE) - 1,
- ZPAGE_SIZE - 1, __LINE__);
- lfoPtr.p->lfoState = LogFileOperationRecord::INIT_WRITE_AT_END;
- return;
- }//Dblqh::openFileInitLab()
- void Dblqh::initWriteEndLab(Signal* signal)
- {
- releaseLfo(signal);
- initLogpage(signal);
- if (logFilePtr.p->fileNo == 0) {
- jam();
- /*---------------------------------------------------------------------------*/
- /* PAGE ZERO IN FILE ZERO MUST SET LOG LAP TO ONE SINCE IT HAS STARTED */
- /* WRITING TO THE LOG, ALSO GLOBAL CHECKPOINTS ARE SET TO ZERO. */
- /*---------------------------------------------------------------------------*/
- logPagePtr.p->logPageWord[ZPOS_LOG_LAP] = 1;
- logPagePtr.p->logPageWord[ZPOS_MAX_GCI_STARTED] = 0;
- logPagePtr.p->logPageWord[ZPOS_MAX_GCI_COMPLETED] = 0;
- logFilePtr.p->logMaxGciStarted[0] = 0;
- logFilePtr.p->logMaxGciCompleted[0] = 0;
- }//if
- /*---------------------------------------------------------------------------*/
- /* REUSE CODE FOR INITIALISATION OF FIRST PAGE IN ALL LOG FILES. */
- /*---------------------------------------------------------------------------*/
- writeFileHeaderOpen(signal, ZINIT);
- return;
- }//Dblqh::initWriteEndLab()
- void Dblqh::initFirstPageLab(Signal* signal)
- {
- releaseLfo(signal);
- if (logFilePtr.p->fileNo == 0) {
- jam();
- /*---------------------------------------------------------------------------*/
- /* IN FILE ZERO WE WILL INSERT A PAGE ONE WHERE WE WILL INSERT A COMPLETED */
- /* GCI RECORD FOR GCI = 0. */
- /*---------------------------------------------------------------------------*/
- initLogpage(signal);
- logPagePtr.p->logPageWord[ZPOS_LOG_LAP] = 1;
- logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE] = ZCOMPLETED_GCI_TYPE;
- logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + 1] = 1;
- writeSinglePage(signal, 1, ZPAGE_SIZE - 1, __LINE__);
- lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_GCI_ZERO;
- return;
- }//if
- logFilePtr.p->currentMbyte = 1;
- writeInitMbyte(signal);
- return;
- }//Dblqh::initFirstPageLab()
- void Dblqh::writeGciZeroLab(Signal* signal)
- {
- releaseLfo(signal);
- logFilePtr.p->currentMbyte = 1;
- writeInitMbyte(signal);
- return;
- }//Dblqh::writeGciZeroLab()
- void Dblqh::writeInitMbyteLab(Signal* signal)
- {
- releaseLfo(signal);
- logFilePtr.p->currentMbyte = logFilePtr.p->currentMbyte + 1;
- if (logFilePtr.p->currentMbyte == ZNO_MBYTES_IN_FILE) {
- jam();
- releaseLogpage(signal);
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_INIT;
- closeFile(signal, logFilePtr);
- return;
- }//if
- writeInitMbyte(signal);
- return;
- }//Dblqh::writeInitMbyteLab()
- void Dblqh::closingInitLab(Signal* signal)
- {
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
- logPartPtr.i = logFilePtr.p->logPartRec;
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- if (logFilePtr.p->nextLogFile == logPartPtr.p->firstLogfile) {
- jam();
- checkInitCompletedLab(signal);
- return;
- } else {
- jam();
- logFilePtr.i = logFilePtr.p->nextLogFile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- openLogfileInit(signal);
- }//if
- return;
- }//Dblqh::closingInitLab()
- void Dblqh::checkInitCompletedLab(Signal* signal)
- {
- logPartPtr.p->logPartState = LogPartRecord::SR_FIRST_PHASE_COMPLETED;
- /*---------------------------------------------------------------------------*/
- /* WE HAVE NOW INITIALISED ALL FILES IN THIS LOG PART. WE CAN NOW SET THE */
- /* THE LOG LAP TO ONE SINCE WE WILL START WITH LOG LAP ONE. LOG LAP = ZERO */
- /* MEANS THIS PART OF THE LOG IS NOT WRITTEN YET. */
- /*---------------------------------------------------------------------------*/
- logPartPtr.p->logLap = 1;
- logPartPtr.i = 0;
- CHECK_LOG_PARTS_LOOP:
- ptrAss(logPartPtr, logPartRecord);
- if (logPartPtr.p->logPartState != LogPartRecord::SR_FIRST_PHASE_COMPLETED) {
- jam();
- /*---------------------------------------------------------------------------*/
- /* THIS PART HAS STILL NOT COMPLETED. WAIT FOR THIS TO OCCUR. */
- /*---------------------------------------------------------------------------*/
- return;
- }//if
- if (logPartPtr.i == 3) {
- jam();
- /*---------------------------------------------------------------------------*/
- /* ALL LOG PARTS ARE COMPLETED. NOW WE CAN CONTINUE WITH THE RESTART */
- /* PROCESSING. THE NEXT STEP IS TO PREPARE FOR EXECUTING OPERATIONS. THUS WE */
- /* NEED TO INITIALISE ALL NEEDED DATA AND TO OPEN FILE ZERO AND THE NEXT AND */
- /* TO SET THE CURRENT LOG PAGE TO BE PAGE 1 IN FILE ZERO. */
- /*---------------------------------------------------------------------------*/
- for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
- ptrAss(logPartPtr, logPartRecord);
- signal->theData[0] = ZINIT_FOURTH;
- signal->theData[1] = logPartPtr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- }//for
- return;
- } else {
- jam();
- logPartPtr.i = logPartPtr.i + 1;
- goto CHECK_LOG_PARTS_LOOP;
- }//if
- }//Dblqh::checkInitCompletedLab()
- /* ========================================================================= */
- /* ======= INITIATE LOG FILE OPERATION RECORD WHEN ALLOCATED ======= */
- /* */
- /* ========================================================================= */
- void Dblqh::initLfo(Signal* signal)
- {
- lfoPtr.p->firstLfoPage = RNIL;
- lfoPtr.p->lfoState = LogFileOperationRecord::IDLE;
- lfoPtr.p->logFileRec = logFilePtr.i;
- lfoPtr.p->noPagesRw = 0;
- lfoPtr.p->lfoPageNo = ZNIL;
- }//Dblqh::initLfo()
- /* ========================================================================= */
- /* ======= INITIATE LOG FILE WHEN ALLOCATED ======= */
- /* */
- /* INPUT: TFILE_NO NUMBER OF THE FILE INITIATED */
- /* LOG_PART_PTR NUMBER OF LOG PART */
- /* SUBROUTINE SHORT NAME = IL */
- /* ========================================================================= */
- void Dblqh::initLogfile(Signal* signal, Uint32 fileNo)
- {
- UintR tilTmp;
- UintR tilIndex;
- logFilePtr.p->currentFilepage = 0;
- logFilePtr.p->currentLogpage = RNIL;
- logFilePtr.p->fileName[0] = (UintR)-1;
- logFilePtr.p->fileName[1] = (UintR)-1; /* = H'FFFFFFFF = -1 */
- logFilePtr.p->fileName[2] = fileNo; /* Sfile_no */
- tilTmp = 1; /* VERSION 1 OF FILE NAME */
- tilTmp = (tilTmp << 8) + 1; /* FRAGMENT LOG => .FRAGLOG AS EXTENSION */
- tilTmp = (tilTmp << 8) + (8 + logPartPtr.i); /* DIRECTORY = D(8+Part)/DBLQH */
- tilTmp = (tilTmp << 8) + 255; /* IGNORE Pxx PART OF FILE NAME */
- logFilePtr.p->fileName[3] = tilTmp;
- /* ========================================================================= */
- /* FILE NAME BECOMES /D2/DBLQH/Tpart_no/Sfile_no.FRAGLOG */
- /* ========================================================================= */
- logFilePtr.p->fileNo = fileNo;
- logFilePtr.p->filePosition = 0;
- logFilePtr.p->firstLfo = RNIL;
- logFilePtr.p->lastLfo = RNIL;
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
- logFilePtr.p->logPartRec = logPartPtr.i;
- logFilePtr.p->noLogpagesInBuffer = 0;
- logFilePtr.p->firstFilledPage = RNIL;
- logFilePtr.p->lastFilledPage = RNIL;
- logFilePtr.p->lastPageWritten = 0;
- logFilePtr.p->logPageZero = RNIL;
- logFilePtr.p->currentMbyte = 0;
- for (tilIndex = 0; tilIndex <= 15; tilIndex++) {
- logFilePtr.p->logMaxGciCompleted[tilIndex] = (UintR)-1;
- logFilePtr.p->logMaxGciStarted[tilIndex] = (UintR)-1;
- logFilePtr.p->logLastPrepRef[tilIndex] = 0;
- }//for
- }//Dblqh::initLogfile()
- /* ========================================================================= */
- /* ======= INITIATE LOG PAGE WHEN ALLOCATED ======= */
- /* */
- /* ========================================================================= */
- void Dblqh::initLogpage(Signal* signal)
- {
- TcConnectionrecPtr ilpTcConnectptr;
- logPagePtr.p->logPageWord[ZPOS_LOG_LAP] = logPartPtr.p->logLap;
- logPagePtr.p->logPageWord[ZPOS_MAX_GCI_COMPLETED] =
- logPartPtr.p->logPartNewestCompletedGCI;
- logPagePtr.p->logPageWord[ZPOS_MAX_GCI_STARTED] = cnewestGci;
- logPagePtr.p->logPageWord[ZPOS_VERSION] = NDB_VERSION;
- logPagePtr.p->logPageWord[ZPOS_NO_LOG_FILES] = logPartPtr.p->noLogFiles;
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = ZPAGE_HEADER_SIZE;
- ilpTcConnectptr.i = logPartPtr.p->firstLogTcrec;
- if (ilpTcConnectptr.i != RNIL) {
- jam();
- ptrCheckGuard(ilpTcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- logPagePtr.p->logPageWord[ZLAST_LOG_PREP_REF] =
- (ilpTcConnectptr.p->logStartFileNo << 16) +
- (ilpTcConnectptr.p->logStartPageNo >> ZTWOLOG_NO_PAGES_IN_MBYTE);
- } else {
- jam();
- logPagePtr.p->logPageWord[ZLAST_LOG_PREP_REF] =
- (logFilePtr.p->fileNo << 16) +
- (logFilePtr.p->currentFilepage >> ZTWOLOG_NO_PAGES_IN_MBYTE);
- }//if
- }//Dblqh::initLogpage()
- /* ------------------------------------------------------------------------- */
- /* ------- OPEN LOG FILE FOR READ AND WRITE ------- */
- /* */
- /* SUBROUTINE SHORT NAME = OFR */
- /* ------------------------------------------------------------------------- */
- void Dblqh::openFileRw(Signal* signal, LogFileRecordPtr olfLogFilePtr)
- {
- signal->theData[0] = cownref;
- signal->theData[1] = olfLogFilePtr.i;
- signal->theData[2] = olfLogFilePtr.p->fileName[0];
- signal->theData[3] = olfLogFilePtr.p->fileName[1];
- signal->theData[4] = olfLogFilePtr.p->fileName[2];
- signal->theData[5] = olfLogFilePtr.p->fileName[3];
- signal->theData[6] = ZOPEN_READ_WRITE;
- sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
- }//Dblqh::openFileRw()
- /* ------------------------------------------------------------------------- */
- /* ------- OPEN LOG FILE DURING INITIAL START ------- */
- /* */
- /* SUBROUTINE SHORT NAME = OLI */
- /* ------------------------------------------------------------------------- */
- void Dblqh::openLogfileInit(Signal* signal)
- {
- logFilePtr.p->logFileStatus = LogFileRecord::OPENING_INIT;
- signal->theData[0] = cownref;
- signal->theData[1] = logFilePtr.i;
- signal->theData[2] = logFilePtr.p->fileName[0];
- signal->theData[3] = logFilePtr.p->fileName[1];
- signal->theData[4] = logFilePtr.p->fileName[2];
- signal->theData[5] = logFilePtr.p->fileName[3];
- signal->theData[6] = 0x302;
- sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
- }//Dblqh::openLogfileInit()
- /* OPEN FOR READ/WRITE, DO CREATE AND DO TRUNCATE FILE */
- /* ------------------------------------------------------------------------- */
- /* ------- OPEN NEXT LOG FILE ------- */
- /* */
- /* SUBROUTINE SHORT NAME = ONL */
- /* ------------------------------------------------------------------------- */
- void Dblqh::openNextLogfile(Signal* signal)
- {
- LogFileRecordPtr onlLogFilePtr;
- if (logPartPtr.p->noLogFiles > 2) {
- jam();
- /* -------------------------------------------------- */
- /* IF ONLY 1 OR 2 LOG FILES EXIST THEN THEY ARE */
- /* ALWAYS OPEN AND THUS IT IS NOT NECESSARY TO */
- /* OPEN THEM NOW. */
- /* -------------------------------------------------- */
- onlLogFilePtr.i = logFilePtr.p->nextLogFile;
- ptrCheckGuard(onlLogFilePtr, clogFileFileSize, logFileRecord);
- if (onlLogFilePtr.p->logFileStatus != LogFileRecord::CLOSED) {
- ndbrequire(onlLogFilePtr.p->fileNo == 0);
- return;
- }//if
- onlLogFilePtr.p->logFileStatus = LogFileRecord::OPENING_WRITE_LOG;
- signal->theData[0] = cownref;
- signal->theData[1] = onlLogFilePtr.i;
- signal->theData[2] = onlLogFilePtr.p->fileName[0];
- signal->theData[3] = onlLogFilePtr.p->fileName[1];
- signal->theData[4] = onlLogFilePtr.p->fileName[2];
- signal->theData[5] = onlLogFilePtr.p->fileName[3];
- signal->theData[6] = 2;
- sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
- }//if
- }//Dblqh::openNextLogfile()
- /* OPEN FOR READ/WRITE, DON'T CREATE AND DON'T TRUNCATE FILE */
- /* ------------------------------------------------------------------------- */
- /* ------- RELEASE LFO RECORD ------- */
- /* */
- /* ------------------------------------------------------------------------- */
- void Dblqh::releaseLfo(Signal* signal)
- {
- #ifdef VM_TRACE
- // Check that lfo record isn't already in free list
- LogFileOperationRecordPtr TlfoPtr;
- TlfoPtr.i = cfirstfreeLfo;
- while (TlfoPtr.i != RNIL){
- ptrCheckGuard(TlfoPtr, clfoFileSize, logFileOperationRecord);
- ndbrequire(TlfoPtr.i != lfoPtr.i);
- TlfoPtr.i = TlfoPtr.p->nextLfo;
- }
- #endif
- lfoPtr.p->nextLfo = cfirstfreeLfo;
- lfoPtr.p->lfoTimer = 0;
- cfirstfreeLfo = lfoPtr.i;
- lfoPtr.p->lfoState = LogFileOperationRecord::IDLE;
- }//Dblqh::releaseLfo()
- /* ------------------------------------------------------------------------- */
- /* ------- RELEASE ALL LOG PAGES CONNECTED TO A LFO RECORD ------- */
- /* */
- /* SUBROUTINE SHORT NAME = RLP */
- /* ------------------------------------------------------------------------- */
- void Dblqh::releaseLfoPages(Signal* signal)
- {
- LogPageRecordPtr rlpLogPagePtr;
- logPagePtr.i = lfoPtr.p->firstLfoPage;
- RLP_LOOP:
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- rlpLogPagePtr.i = logPagePtr.p->logPageWord[ZNEXT_PAGE];
- releaseLogpage(signal);
- if (rlpLogPagePtr.i != RNIL) {
- jam();
- logPagePtr.i = rlpLogPagePtr.i;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- goto RLP_LOOP;
- }//if
- lfoPtr.p->firstLfoPage = RNIL;
- }//Dblqh::releaseLfoPages()
- /* ------------------------------------------------------------------------- */
- /* ------- RELEASE LOG PAGE ------- */
- /* */
- /* ------------------------------------------------------------------------- */
- void Dblqh::releaseLogpage(Signal* signal)
- {
- #ifdef VM_TRACE
- // Check that log page isn't already in free list
- ndbrequire(logPagePtr.p->logPageWord[ZPOS_IN_FREE_LIST] == 0);
- #endif
- cnoOfLogPages++;
- logPagePtr.p->logPageWord[ZNEXT_PAGE] = cfirstfreeLogPage;
- logPagePtr.p->logPageWord[ZPOS_IN_WRITING]= 0;
- logPagePtr.p->logPageWord[ZPOS_IN_FREE_LIST]= 1;
- cfirstfreeLogPage = logPagePtr.i;
- }//Dblqh::releaseLogpage()
- /* ------------------------------------------------------------------------- */
- /* ------- SEIZE LFO RECORD ------- */
- /* */
- /* ------------------------------------------------------------------------- */
- void Dblqh::seizeLfo(Signal* signal)
- {
- lfoPtr.i = cfirstfreeLfo;
- ptrCheckGuard(lfoPtr, clfoFileSize, logFileOperationRecord);
- cfirstfreeLfo = lfoPtr.p->nextLfo;
- lfoPtr.p->nextLfo = RNIL;
- lfoPtr.p->lfoTimer = cLqhTimeOutCount;
- }//Dblqh::seizeLfo()
- /* ------------------------------------------------------------------------- */
- /* ------- SEIZE LOG FILE RECORD ------- */
- /* */
- /* ------------------------------------------------------------------------- */
- void Dblqh::seizeLogfile(Signal* signal)
- {
- logFilePtr.i = cfirstfreeLogFile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- /* ------------------------------------------------------------------------- */
- /*IF LIST IS EMPTY THEN A SYSTEM CRASH IS INVOKED SINCE LOG_FILE_PTR = RNIL */
- /* ------------------------------------------------------------------------- */
- cfirstfreeLogFile = logFilePtr.p->nextLogFile;
- logFilePtr.p->nextLogFile = RNIL;
- }//Dblqh::seizeLogfile()
- /* ------------------------------------------------------------------------- */
- /* ------- SEIZE LOG PAGE RECORD ------- */
- /* */
- /* ------------------------------------------------------------------------- */
- void Dblqh::seizeLogpage(Signal* signal)
- {
- cnoOfLogPages--;
- logPagePtr.i = cfirstfreeLogPage;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- /* ------------------------------------------------------------------------- */
- /*IF LIST IS EMPTY THEN A SYSTEM CRASH IS INVOKED SINCE LOG_PAGE_PTR = RNIL */
- /* ------------------------------------------------------------------------- */
- cfirstfreeLogPage = logPagePtr.p->logPageWord[ZNEXT_PAGE];
- logPagePtr.p->logPageWord[ZNEXT_PAGE] = RNIL;
- logPagePtr.p->logPageWord[ZPOS_IN_FREE_LIST] = 0;
- }//Dblqh::seizeLogpage()
- /* ------------------------------------------------------------------------- */
- /* ------- WRITE FILE DESCRIPTOR INFORMATION ------- */
- /* */
- /* SUBROUTINE SHORT NAME: WFD */
- // Pointer handling:
- // logFilePtr in
- // logPartPtr in
- /* ------------------------------------------------------------------------- */
- void Dblqh::writeFileDescriptor(Signal* signal)
- {
- TcConnectionrecPtr wfdTcConnectptr;
- UintR twfdFileNo;
- UintR twfdMbyte;
- /* -------------------------------------------------- */
- /* START BY WRITING TO LOG FILE RECORD */
- /* -------------------------------------------------- */
- arrGuard(logFilePtr.p->currentMbyte, 16);
- logFilePtr.p->logMaxGciCompleted[logFilePtr.p->currentMbyte] =
- logPartPtr.p->logPartNewestCompletedGCI;
- logFilePtr.p->logMaxGciStarted[logFilePtr.p->currentMbyte] = cnewestGci;
- wfdTcConnectptr.i = logPartPtr.p->firstLogTcrec;
- if (wfdTcConnectptr.i != RNIL) {
- jam();
- ptrCheckGuard(wfdTcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- twfdFileNo = wfdTcConnectptr.p->logStartFileNo;
- twfdMbyte = wfdTcConnectptr.p->logStartPageNo >> ZTWOLOG_NO_PAGES_IN_MBYTE;
- logFilePtr.p->logLastPrepRef[logFilePtr.p->currentMbyte] =
- (twfdFileNo << 16) + twfdMbyte;
- } else {
- jam();
- logFilePtr.p->logLastPrepRef[logFilePtr.p->currentMbyte] =
- (logFilePtr.p->fileNo << 16) + logFilePtr.p->currentMbyte;
- }//if
- }//Dblqh::writeFileDescriptor()
- /* ------------------------------------------------------------------------- */
- /* ------- WRITE THE HEADER PAGE OF A NEW FILE ------- */
- /* */
- /* SUBROUTINE SHORT NAME: WMO */
- /* ------------------------------------------------------------------------- */
- void Dblqh::writeFileHeaderOpen(Signal* signal, Uint32 wmoType)
- {
- LogFileRecordPtr wmoLogFilePtr;
- UintR twmoNoLogDescriptors;
- UintR twmoLoop;
- UintR twmoIndex;
- /* -------------------------------------------------- */
- /* WRITE HEADER INFORMATION IN THE NEW FILE. */
- /* -------------------------------------------------- */
- logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_LOG_TYPE] = ZFD_TYPE;
- logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_FILE_NO] =
- logFilePtr.p->fileNo;
- if (logPartPtr.p->noLogFiles > ZMAX_LOG_FILES_IN_PAGE_ZERO) {
- jam();
- twmoNoLogDescriptors = ZMAX_LOG_FILES_IN_PAGE_ZERO;
- } else {
- jam();
- twmoNoLogDescriptors = logPartPtr.p->noLogFiles;
- }//if
- logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_NO_FD] =
- twmoNoLogDescriptors;
- wmoLogFilePtr.i = logFilePtr.i;
- twmoLoop = 0;
- WMO_LOOP:
- jam();
- if (twmoLoop < twmoNoLogDescriptors) {
- jam();
- ptrCheckGuard(wmoLogFilePtr, clogFileFileSize, logFileRecord);
- for (twmoIndex = 0; twmoIndex <= ZNO_MBYTES_IN_FILE - 1; twmoIndex++) {
- jam();
- arrGuard(((ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE) +
- (twmoLoop * ZFD_PART_SIZE)) + twmoIndex, ZPAGE_SIZE);
- logPagePtr.p->logPageWord[((ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE) +
- (twmoLoop * ZFD_PART_SIZE)) + twmoIndex] =
- wmoLogFilePtr.p->logMaxGciCompleted[twmoIndex];
- arrGuard((((ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE) +
- (twmoLoop * ZFD_PART_SIZE)) + ZNO_MBYTES_IN_FILE) +
- twmoIndex, ZPAGE_SIZE);
- logPagePtr.p->logPageWord[(((ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE) +
- (twmoLoop * ZFD_PART_SIZE)) + ZNO_MBYTES_IN_FILE) + twmoIndex] =
- wmoLogFilePtr.p->logMaxGciStarted[twmoIndex];
- arrGuard((((ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE) +
- (twmoLoop * ZFD_PART_SIZE)) + (2 * ZNO_MBYTES_IN_FILE)) +
- twmoIndex, ZPAGE_SIZE);
- logPagePtr.p->logPageWord[(((ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE) +
- (twmoLoop * ZFD_PART_SIZE)) + (2 * ZNO_MBYTES_IN_FILE)) + twmoIndex] =
- wmoLogFilePtr.p->logLastPrepRef[twmoIndex];
- }//for
- wmoLogFilePtr.i = wmoLogFilePtr.p->prevLogFile;
- twmoLoop = twmoLoop + 1;
- goto WMO_LOOP;
- }//if
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] =
- (ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE) +
- (ZFD_PART_SIZE * twmoNoLogDescriptors);
- arrGuard(logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX], ZPAGE_SIZE);
- logPagePtr.p->logPageWord[logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX]] =
- ZNEXT_LOG_RECORD_TYPE;
- /* ------------------------------------------------------- */
- /* THIS IS A SPECIAL WRITE OF THE FIRST PAGE IN THE */
- /* LOG FILE. THIS HAS SPECIAL SIGNIFANCE TO FIND */
- /* THE END OF THE LOG AT SYSTEM RESTART. */
- /* ------------------------------------------------------- */
- writeSinglePage(signal, 0, ZPAGE_SIZE - 1, __LINE__);
- if (wmoType == ZINIT) {
- jam();
- lfoPtr.p->lfoState = LogFileOperationRecord::INIT_FIRST_PAGE;
- } else {
- jam();
- lfoPtr.p->lfoState = LogFileOperationRecord::FIRST_PAGE_WRITE_IN_LOGFILE;
- }//if
- logFilePtr.p->filePosition = 1;
- if (wmoType == ZNORMAL) {
- jam();
- /* -------------------------------------------------- */
- /* ALLOCATE A NEW PAGE SINCE THE CURRENT IS */
- /* WRITTEN. */
- /* -------------------------------------------------- */
- seizeLogpage(signal);
- initLogpage(signal);
- logFilePtr.p->currentLogpage = logPagePtr.i;
- logFilePtr.p->currentFilepage = logFilePtr.p->currentFilepage + 1;
- }//if
- }//Dblqh::writeFileHeaderOpen()
- /* -------------------------------------------------- */
- /* THE NEW FILE POSITION WILL ALWAYS BE 1 SINCE */
- /* WE JUST WROTE THE FIRST PAGE IN THE LOG FILE */
- /* -------------------------------------------------- */
- /* ------------------------------------------------------------------------- */
- /* ------- WRITE A MBYTE HEADER DURING INITIAL START ------- */
- /* */
- /* SUBROUTINE SHORT NAME: WIM */
- /* ------------------------------------------------------------------------- */
- void Dblqh::writeInitMbyte(Signal* signal)
- {
- initLogpage(signal);
- writeSinglePage(signal, logFilePtr.p->currentMbyte * ZPAGES_IN_MBYTE,
- ZPAGE_SIZE - 1, __LINE__);
- lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_INIT_MBYTE;
- }//Dblqh::writeInitMbyte()
- /* ------------------------------------------------------------------------- */
- /* ------- WRITE A SINGLE PAGE INTO A FILE ------- */
- /* */
- /* INPUT: TWSP_PAGE_NO THE PAGE NUMBER WRITTEN */
- /* SUBROUTINE SHORT NAME: WSP */
- /* ------------------------------------------------------------------------- */
- void Dblqh::writeSinglePage(Signal* signal, Uint32 pageNo,
- Uint32 wordWritten, Uint32 place)
- {
- seizeLfo(signal);
- initLfo(signal);
- lfoPtr.p->firstLfoPage = logPagePtr.i;
- logPagePtr.p->logPageWord[ZNEXT_PAGE] = RNIL;
- writeDbgInfoPageHeader(logPagePtr, place, pageNo, wordWritten);
- // Calculate checksum for page
- logPagePtr.p->logPageWord[ZPOS_CHECKSUM] = calcPageCheckSum(logPagePtr);
- lfoPtr.p->lfoPageNo = pageNo;
- lfoPtr.p->lfoWordWritten = wordWritten;
- lfoPtr.p->noPagesRw = 1;
- /* -------------------------------------------------- */
- /* SET TIMER ON THIS LOG PART TO SIGNIFY THAT A */
- /* LOG RECORD HAS BEEN SENT AT THIS TIME. */
- /* -------------------------------------------------- */
- logPartPtr.p->logPartTimer = logPartPtr.p->logTimer;
- signal->theData[0] = logFilePtr.p->fileRef;
- signal->theData[1] = cownref;
- signal->theData[2] = lfoPtr.i;
- signal->theData[3] = ZLIST_OF_PAIRS_SYNCH;
- signal->theData[4] = ZVAR_NO_LOG_PAGE_WORD;
- signal->theData[5] = 1; /* ONE PAGE WRITTEN */
- signal->theData[6] = logPagePtr.i;
- signal->theData[7] = pageNo;
- sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
- }//Dblqh::writeSinglePage()
- /* ##########################################################################
- * SYSTEM RESTART PHASE ONE MODULE
- * THIS MODULE IS A SUB-MODULE OF THE FILE SYSTEM HANDLING.
- *
- * THIS MODULE CONTAINS THE CODE FOR THE FIRST PHASE OF THE SYSTEM RESTART.
- * THE AIM OF THIS PHASE IS TO FIND THE END OF THE LOG AND TO FIND
- * INFORMATION ABOUT WHERE GLOBAL CHECKPOINTS ARE COMPLETED AND STARTED
- * IN THE LOG. THIS INFORMATION IS NEEDED TO START PHASE THREE OF
- * THE SYSTEM RESTART.
- * ########################################################################## */
- /* --------------------------------------------------------------------------
- * A SYSTEM RESTART OR NODE RESTART IS ONGOING. WE HAVE NOW OPENED FILE 0
- * NOW WE NEED TO READ PAGE 0 TO FIND WHICH LOG FILE THAT WAS OPEN AT
- * CRASH TIME.
- * -------------------------------------------------------------------------- */
- void Dblqh::openSrFrontpageLab(Signal* signal)
- {
- readSinglePage(signal, 0);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_FRONTPAGE;
- return;
- }//Dblqh::openSrFrontpageLab()
- /* -------------------------------------------------------------------------
- * WE HAVE NOW READ PAGE 0 IN FILE 0. CHECK THE LAST OPEN FILE. ACTUALLY THE
- * LAST OPEN FILE COULD BE THE NEXT AFTER THAT. CHECK THAT FIRST. WHEN THE
- * LAST WAS FOUND WE CAN FIND ALL THE NEEDED INFORMATION WHERE TO START AND
- * STOP READING THE LOG.
- * -------------------------------------------------------------------------- */
- void Dblqh::readSrFrontpageLab(Signal* signal)
- {
- Uint32 fileNo = logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_FILE_NO];
- if (fileNo == 0) {
- jam();
- /* ----------------------------------------------------------------------
- * FILE 0 WAS ALSO LAST FILE SO WE DO NOT NEED TO READ IT AGAIN.
- * ---------------------------------------------------------------------- */
- readSrLastFileLab(signal);
- return;
- }//if
- /* ------------------------------------------------------------------------
- * CLOSE FILE 0 SO THAT WE HAVE CLOSED ALL FILES WHEN STARTING TO READ
- * THE FRAGMENT LOG. ALSO RELEASE PAGE ZERO.
- * ------------------------------------------------------------------------ */
- releaseLogpage(signal);
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_SR;
- closeFile(signal, logFilePtr);
- LogFileRecordPtr locLogFilePtr;
- findLogfile(signal, fileNo, logPartPtr, &locLogFilePtr);
- locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_LAST_FILE;
- openFileRw(signal, locLogFilePtr);
- return;
- }//Dblqh::readSrFrontpageLab()
- void Dblqh::openSrLastFileLab(Signal* signal)
- {
- readSinglePage(signal, 0);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_LAST_FILE;
- return;
- }//Dblqh::openSrLastFileLab()
- void Dblqh::readSrLastFileLab(Signal* signal)
- {
- logPartPtr.p->logLap = logPagePtr.p->logPageWord[ZPOS_LOG_LAP];
- if (logPartPtr.p->noLogFiles > ZMAX_LOG_FILES_IN_PAGE_ZERO) {
- jam();
- initGciInLogFileRec(signal, ZMAX_LOG_FILES_IN_PAGE_ZERO);
- } else {
- jam();
- initGciInLogFileRec(signal, logPartPtr.p->noLogFiles);
- }//if
- releaseLogpage(signal);
- /* ------------------------------------------------------------------------
- * NOW WE HAVE FOUND THE LAST LOG FILE. WE ALSO NEED TO FIND THE LAST
- * MBYTE THAT WAS LAST WRITTEN BEFORE THE SYSTEM CRASH.
- * ------------------------------------------------------------------------ */
- logPartPtr.p->lastLogfile = logFilePtr.i;
- readSinglePage(signal, 0);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_LAST_MBYTE;
- logFilePtr.p->currentMbyte = 0;
- return;
- }//Dblqh::readSrLastFileLab()
- void Dblqh::readSrLastMbyteLab(Signal* signal)
- {
- if (logPartPtr.p->lastMbyte == ZNIL) {
- if (logPagePtr.p->logPageWord[ZPOS_LOG_LAP] < logPartPtr.p->logLap) {
- jam();
- logPartPtr.p->lastMbyte = logFilePtr.p->currentMbyte - 1;
- }//if
- }//if
- arrGuard(logFilePtr.p->currentMbyte, 16);
- logFilePtr.p->logMaxGciCompleted[logFilePtr.p->currentMbyte] =
- logPagePtr.p->logPageWord[ZPOS_MAX_GCI_COMPLETED];
- logFilePtr.p->logMaxGciStarted[logFilePtr.p->currentMbyte] =
- logPagePtr.p->logPageWord[ZPOS_MAX_GCI_STARTED];
- logFilePtr.p->logLastPrepRef[logFilePtr.p->currentMbyte] =
- logPagePtr.p->logPageWord[ZLAST_LOG_PREP_REF];
- releaseLogpage(signal);
- if (logFilePtr.p->currentMbyte < (ZNO_MBYTES_IN_FILE - 1)) {
- jam();
- logFilePtr.p->currentMbyte++;
- readSinglePage(signal, ZPAGES_IN_MBYTE * logFilePtr.p->currentMbyte);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_LAST_MBYTE;
- return;
- } else {
- jam();
- /* ----------------------------------------------------------------------
- * THE LOG WAS IN THE LAST MBYTE WHEN THE CRASH OCCURRED SINCE ALL
- * LOG LAPS ARE EQUAL TO THE CURRENT LOG LAP.
- * ---------------------------------------------------------------------- */
- if (logPartPtr.p->lastMbyte == ZNIL) {
- jam();
- logPartPtr.p->lastMbyte = ZNO_MBYTES_IN_FILE - 1;
- }//if
- }//if
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_SR;
- closeFile(signal, logFilePtr);
- if (logPartPtr.p->noLogFiles > ZMAX_LOG_FILES_IN_PAGE_ZERO) {
- Uint32 fileNo;
- if (logFilePtr.p->fileNo >= ZMAX_LOG_FILES_IN_PAGE_ZERO) {
- jam();
- fileNo = logFilePtr.p->fileNo - ZMAX_LOG_FILES_IN_PAGE_ZERO;
- } else {
- jam();
- fileNo =
- (logPartPtr.p->noLogFiles + logFilePtr.p->fileNo) -
- ZMAX_LOG_FILES_IN_PAGE_ZERO;
- }//if
- if (fileNo == 0) {
- jam();
- /* --------------------------------------------------------------------
- * AVOID USING FILE 0 AGAIN SINCE THAT IS PROBABLY CLOSING AT THE
- * MOMENT.
- * -------------------------------------------------------------------- */
- fileNo = 1;
- logPartPtr.p->srRemainingFiles =
- logPartPtr.p->noLogFiles - (ZMAX_LOG_FILES_IN_PAGE_ZERO - 1);
- } else {
- jam();
- logPartPtr.p->srRemainingFiles =
- logPartPtr.p->noLogFiles - ZMAX_LOG_FILES_IN_PAGE_ZERO;
- }//if
- LogFileRecordPtr locLogFilePtr;
- findLogfile(signal, fileNo, logPartPtr, &locLogFilePtr);
- locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_NEXT_FILE;
- openFileRw(signal, locLogFilePtr);
- return;
- }//if
- /* ------------------------------------------------------------------------
- * THERE WERE NO NEED TO READ ANY MORE PAGE ZERO IN OTHER FILES.
- * WE NOW HAVE ALL THE NEEDED INFORMATION ABOUT THE GCI'S THAT WE NEED.
- * NOW JUST WAIT FOR CLOSE OPERATIONS TO COMPLETE.
- * ------------------------------------------------------------------------ */
- return;
- }//Dblqh::readSrLastMbyteLab()
- void Dblqh::openSrNextFileLab(Signal* signal)
- {
- readSinglePage(signal, 0);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_NEXT_FILE;
- return;
- }//Dblqh::openSrNextFileLab()
- void Dblqh::readSrNextFileLab(Signal* signal)
- {
- if (logPartPtr.p->srRemainingFiles > ZMAX_LOG_FILES_IN_PAGE_ZERO) {
- jam();
- initGciInLogFileRec(signal, ZMAX_LOG_FILES_IN_PAGE_ZERO);
- } else {
- jam();
- initGciInLogFileRec(signal, logPartPtr.p->srRemainingFiles);
- }//if
- releaseLogpage(signal);
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_SR;
- closeFile(signal, logFilePtr);
- if (logPartPtr.p->srRemainingFiles > ZMAX_LOG_FILES_IN_PAGE_ZERO) {
- Uint32 fileNo;
- if (logFilePtr.p->fileNo >= ZMAX_LOG_FILES_IN_PAGE_ZERO) {
- jam();
- fileNo = logFilePtr.p->fileNo - ZMAX_LOG_FILES_IN_PAGE_ZERO;
- } else {
- jam();
- fileNo =
- (logPartPtr.p->noLogFiles + logFilePtr.p->fileNo) -
- ZMAX_LOG_FILES_IN_PAGE_ZERO;
- }//if
- if (fileNo == 0) {
- jam();
- /* --------------------------------------------------------------------
- * AVOID USING FILE 0 AGAIN SINCE THAT IS PROBABLY CLOSING AT THE MOMENT.
- * -------------------------------------------------------------------- */
- fileNo = 1;
- logPartPtr.p->srRemainingFiles =
- logPartPtr.p->srRemainingFiles - (ZMAX_LOG_FILES_IN_PAGE_ZERO - 1);
- } else {
- jam();
- logPartPtr.p->srRemainingFiles =
- logPartPtr.p->srRemainingFiles - ZMAX_LOG_FILES_IN_PAGE_ZERO;
- }//if
- LogFileRecordPtr locLogFilePtr;
- findLogfile(signal, fileNo, logPartPtr, &locLogFilePtr);
- locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_NEXT_FILE;
- openFileRw(signal, locLogFilePtr);
- }//if
- /* ------------------------------------------------------------------------
- * THERE WERE NO NEED TO READ ANY MORE PAGE ZERO IN OTHER FILES.
- * WE NOW HAVE ALL THE NEEDED INFORMATION ABOUT THE GCI'S THAT WE NEED.
- * NOW JUST WAIT FOR CLOSE OPERATIONS TO COMPLETE.
- * ------------------------------------------------------------------------ */
- return;
- }//Dblqh::readSrNextFileLab()
- void Dblqh::closingSrLab(Signal* signal)
- {
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
- logPartPtr.i = logFilePtr.p->logPartRec;
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- logFilePtr.i = logPartPtr.p->firstLogfile;
- do {
- jam();
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- if (logFilePtr.p->logFileStatus != LogFileRecord::CLOSED) {
- jam();
- /* --------------------------------------------------------------------
- * EXIT AND WAIT FOR REMAINING LOG FILES TO COMPLETE THEIR WORK.
- * -------------------------------------------------------------------- */
- return;
- }//if
- logFilePtr.i = logFilePtr.p->nextLogFile;
- } while (logFilePtr.i != logPartPtr.p->firstLogfile);
- /* ------------------------------------------------------------------------
- * ALL FILES IN THIS PART HAVE BEEN CLOSED. THIS INDICATES THAT THE FIRST
- * PHASE OF THE SYSTEM RESTART HAVE BEEN CONCLUDED FOR THIS LOG PART.
- * CHECK IF ALL OTHER LOG PARTS ARE ALSO COMPLETED.
- * ------------------------------------------------------------------------ */
- logPartPtr.p->logPartState = LogPartRecord::SR_FIRST_PHASE_COMPLETED;
- for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
- jam();
- ptrAss(logPartPtr, logPartRecord);
- if (logPartPtr.p->logPartState != LogPartRecord::SR_FIRST_PHASE_COMPLETED) {
- jam();
- /* --------------------------------------------------------------------
- * EXIT AND WAIT FOR THE REST OF THE LOG PARTS TO COMPLETE.
- * -------------------------------------------------------------------- */
- return;
- }//if
- }//for
- /* ------------------------------------------------------------------------
- * THE FIRST PHASE HAVE BEEN COMPLETED.
- * ------------------------------------------------------------------------ */
- signal->theData[0] = ZSR_PHASE3_START;
- signal->theData[1] = ZSR_PHASE1_COMPLETED;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
- }//Dblqh::closingSrLab()
- /* ##########################################################################
- * ####### SYSTEM RESTART PHASE TWO MODULE #######
- *
- * THIS MODULE HANDLES THE SYSTEM RESTART WHERE LQH CONTROLS TUP AND ACC TO
- * ENSURE THAT THEY HAVE KNOWLEDGE OF ALL FRAGMENTS AND HAVE DONE THE NEEDED
- * READING OF DATA FROM FILE AND EXECUTION OF LOCAL LOGS. THIS PROCESS
- * EXECUTES CONCURRENTLY WITH PHASE ONE OF THE SYSTEM RESTART. THIS PHASE
- * FINDS THE INFORMATION ABOUT THE FRAGMENT LOG NEEDED TO EXECUTE THE FRAGMENT
- * LOG.
- * WHEN TUP AND ACC HAVE PREPARED ALL FRAGMENTS THEN LQH ORDERS THOSE LQH'S
- * THAT ARE RESPONSIBLE TO EXECUTE THE FRAGMENT LOGS TO DO SO. IT IS POSSIBLE
- * THAT ANOTHER NODE EXECUTES THE LOG FOR A FRAGMENT RESIDING AT THIS NODE.
- * ########################################################################## */
- /* ***************>> */
- /* START_FRAGREQ > */
- /* ***************>> */
- void Dblqh::execSTART_FRAGREQ(Signal* signal)
- {
- const StartFragReq * const startFragReq = (StartFragReq *)&signal->theData[0];
- jamEntry();
- tabptr.i = startFragReq->tableId;
- Uint32 fragId = startFragReq->fragId;
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
- if (!getFragmentrec(signal, fragId)) {
- startFragRefLab(signal);
- return;
- }//if
- tabptr.p->tableStatus = Tablerec::TABLE_DEFINED;
-
- initFragrecSr(signal);
- if (startFragReq->lcpNo == ZNIL) {
- jam();
- /* ----------------------------------------------------------------------
- * THERE WAS NO LOCAL CHECKPOINT AVAILABLE FOR THIS FRAGMENT. WE DO
- * NOT NEED TO READ IN THE LOCAL FRAGMENT. WE HAVE ALREADY ADDED THE
- * FRAGMENT AS AN EMPTY FRAGMENT AT THIS POINT. THUS WE CAN SIMPLY
- * EXIT AND THE FRAGMENT WILL PARTICIPATE IN THE EXECUTION OF THE LOG.
- * PUT FRAGMENT ON LIST OF COMPLETED FRAGMENTS FOR EXECUTION OF LOG.
- * ---------------------------------------------------------------------- */
- fragptr.p->nextFrag = cfirstCompletedFragSr;
- cfirstCompletedFragSr = fragptr.i;
- return;
- }//if
- if (cfirstWaitFragSr == RNIL) {
- jam();
- lcpPtr.i = 0;
- ptrAss(lcpPtr, lcpRecord);
- if (lcpPtr.p->lcpState == LcpRecord::LCP_IDLE) {
- jam();
- initLcpSr(signal, startFragReq->lcpNo,
- startFragReq->lcpId, tabptr.i,
- fragId, fragptr.i);
- signal->theData[0] = lcpPtr.i;
- signal->theData[1] = cownref;
- signal->theData[2] = lcpPtr.p->currentFragment.lcpFragOrd.lcpNo;
- signal->theData[3] = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
- signal->theData[4] = lcpPtr.p->currentFragment.lcpFragOrd.fragmentId;
- sendSignal(fragptr.p->accBlockref, GSN_SR_FRAGIDREQ, signal, 5, JBB);
- return;
- }//if
- }//if
- fragptr.p->nextFrag = cfirstWaitFragSr;
- cfirstWaitFragSr = fragptr.i;
- }//Dblqh::execSTART_FRAGREQ()
- void Dblqh::startFragRefLab(Signal* signal)
- {
- const StartFragReq * const startFragReq = (StartFragReq *)&signal->theData[0];
- BlockReference userRef = startFragReq->userRef;
- Uint32 userPtr = startFragReq->userPtr;
- signal->theData[0] = userPtr;
- signal->theData[1] = terrorCode;
- signal->theData[2] = cownNodeid;
- sendSignal(userRef, GSN_START_FRAGREF, signal, 3, JBB);
- return;
- }//Dblqh::startFragRefLab()
- /* ***************>> */
- /* SR_FRAGIDCONF > */
- /* ***************>> */
- /* --------------------------------------------------------------------------
- * PRECONDITION: LCP_PTR:LCP_STATE = SR_WAIT_FRAGID
- * -------------------------------------------------------------------------- */
- void Dblqh::execSR_FRAGIDCONF(Signal* signal)
- {
- SrFragidConf * const srFragidConf = (SrFragidConf *)&signal->theData[0];
- jamEntry();
- lcpPtr.i = srFragidConf->lcpPtr;
- ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
- ndbrequire(lcpPtr.p->lcpState == LcpRecord::LCP_SR_WAIT_FRAGID);
- /* ------------------------------------------------------------------------
- * NO ERROR CHECKING OF TNO_LOCFRAG VALUE. OUT OF BOUND WILL IMPLY THAT AN
- * INDEX OUT OF RANGE WILL CAUSE A SYSTEM RESTART WHICH IS DESIRED.
- * ------------------------------------------------------------------------ */
- lcpPtr.p->lcpAccptr = srFragidConf->accPtr;
- fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
- ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
- fragptr.p->accFragptr[0] = srFragidConf->fragPtr[0];
- fragptr.p->accFragptr[1] = srFragidConf->fragPtr[1];
- fragptr.p->hashCheckBit = srFragidConf->hashCheckBit;
- Uint32 noLocFrag = srFragidConf->noLocFrag;
- ndbrequire(noLocFrag == 2);
- Uint32 fragid[2];
- Uint32 i;
- for (i = 0; i < noLocFrag; i++) {
- fragid[i] = srFragidConf->fragId[i];
- }//for
- for (i = 0; i < noLocFrag; i++) {
- jam();
- Uint32 fragId = fragid[i];
- /* ----------------------------------------------------------------------
- * THERE IS NO ERROR CHECKING ON PURPOSE. IT IS POSSIBLE TO CALCULATE HOW
- * MANY LOCAL LCP RECORDS THERE SHOULD BE. IT SHOULD NEVER HAPPEN THAT
- * THERE IS NO ONE FREE. IF THERE IS NO ONE IT WILL ALSO BE A POINTER
- * OUT OF RANGE WHICH IS AN ERROR CODE IN ITSELF. REUSES ERROR
- * HANDLING IN AXE VM.
- * ---------------------------------------------------------------------- */
- seizeLcpLoc(signal);
- initLcpLocAcc(signal, fragId);
- lcpLocptr.p->lcpLocstate = LcpLocRecord::SR_ACC_STARTED;
- signal->theData[0] = lcpPtr.p->lcpAccptr;
- signal->theData[1] = lcpLocptr.i;
- signal->theData[2] = lcpLocptr.p->locFragid;
- signal->theData[3] = lcpPtr.p->currentFragment.lcpFragOrd.lcpId % MAX_LCP_STORED;
- sendSignal(fragptr.p->accBlockref, GSN_ACC_SRREQ, signal, 4, JBB);
- seizeLcpLoc(signal);
- initLcpLocTup(signal, fragId);
- lcpLocptr.p->lcpLocstate = LcpLocRecord::SR_TUP_STARTED;
- signal->theData[0] = lcpLocptr.i;
- signal->theData[1] = cownref;
- signal->theData[2] = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
- signal->theData[3] = lcpLocptr.p->locFragid;
- signal->theData[4] = lcpPtr.p->currentFragment.lcpFragOrd.lcpNo;
- sendSignal(fragptr.p->tupBlockref, GSN_TUP_SRREQ, signal, 5, JBB);
- }//for
- lcpPtr.p->lcpState = LcpRecord::LCP_SR_STARTED;
- return;
- }//Dblqh::execSR_FRAGIDCONF()
- /* ***************> */
- /* SR_FRAGIDREF > */
- /* ***************> */
- void Dblqh::execSR_FRAGIDREF(Signal* signal)
- {
- jamEntry();
- ndbrequire(false);
- }//Dblqh::execSR_FRAGIDREF()
- /* ************>> */
- /* ACC_SRCONF > */
- /* ************>> */
- /* --------------------------------------------------------------------------
- * PRECONDITION: LCP_LOCPTR:LCP_LOCSTATE = SR_ACC_STARTED
- * -------------------------------------------------------------------------- */
- void Dblqh::execACC_SRCONF(Signal* signal)
- {
- jamEntry();
- lcpLocptr.i = signal->theData[0];
- ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
- if (lcpLocptr.p->lcpLocstate != LcpLocRecord::SR_ACC_STARTED) {
- jam();
- systemErrorLab(signal);
- return;
- }//if
- lcpPtr.i = lcpLocptr.p->masterLcpRec;
- ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
- /* ------------------------------------------------------------------------
- * NO ERROR CHECK ON USING VALUE IN MASTER_LCP_REC. ERROR IN THIS REFERENCE
- * WILL CAUSE POINTER OUT OF RANGE WHICH CAUSES A SYSTEM RESTART.
- * ------------------------------------------------------------------------ */
- lcpLocptr.p->lcpLocstate = LcpLocRecord::SR_ACC_COMPLETED;
- srCompletedLab(signal);
- return;
- }//Dblqh::execACC_SRCONF()
- /* ************> */
- /* ACC_SRREF > */
- /* ************> */
- void Dblqh::execACC_SRREF(Signal* signal)
- {
- jamEntry();
- terrorCode = signal->theData[1];
- systemErrorLab(signal);
- return;
- }//Dblqh::execACC_SRREF()
- /* ************>> */
- /* TUP_SRCONF > */
- /* ************>> */
- /* --------------------------------------------------------------------------
- * PRECONDITION: LCP_LOCPTR:LCP_LOCSTATE = SR_TUP_STARTED
- * -------------------------------------------------------------------------- */
- void Dblqh::execTUP_SRCONF(Signal* signal)
- {
- jamEntry();
- lcpLocptr.i = signal->theData[0];
- ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
- Uint32 tupFragPtr = signal->theData[1];
- ndbrequire(lcpLocptr.p->lcpLocstate == LcpLocRecord::SR_TUP_STARTED);
- lcpPtr.i = lcpLocptr.p->masterLcpRec;
- ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
- /* ------------------------------------------------------------------------
- * NO ERROR CHECK ON USING VALUE IN MASTER_LCP_REC. ERROR IN THIS REFERENCE
- * WILL CAUSE POINTER OUT OF RANGE WHICH CAUSES A SYSTEM RESTART.
- * ------------------------------------------------------------------------ */
- lcpLocptr.p->lcpLocstate = LcpLocRecord::SR_TUP_COMPLETED;
- fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
- ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
- if (lcpLocptr.i == lcpPtr.p->firstLcpLocTup) {
- jam();
- fragptr.p->tupFragptr[1] = tupFragPtr;
- } else {
- jam();
- fragptr.p->tupFragptr[0] = tupFragPtr;
- }//if
- srCompletedLab(signal);
- return;
- }//Dblqh::execTUP_SRCONF()
- void Dblqh::srCompletedLab(Signal* signal)
- {
- checkSrCompleted(signal);
- if (lcpPtr.p->lcpState == LcpRecord::LCP_SR_COMPLETED) {
- jam();
- /* ----------------------------------------------------------------------
- * THE SYSTEM RESTART OF THIS FRAGMENT HAS BEEN COMPLETED. IT IS NOW
- * TIME TO START A SYSTEM RESTART ON THE NEXT FRAGMENT OR CONTINUE
- * WITH THE NEXT STEP OF THE SYSTEM RESTART. THIS STEP IS TO EXECUTE
- * THE FRAGMENT LOGS.
- * ----------------------------------------------------------------------
- * WE RELEASE THE LOCAL LCP RECORDS.
- * --------------------------------------------------------------------- */
- releaseLocalLcps(signal);
- /* ----------------------------------------------------------------------
- * PUT FRAGMENT ON LIST OF FRAGMENTS WHICH HAVE BEEN STARTED AS PART OF
- * THE SYSTEM RESTART. THEY ARE NOW WAITING TO EXECUTE THE FRAGMENT LOG.
- * --------------------------------------------------------------------- */
- fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
- ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
- fragptr.p->nextFrag = cfirstCompletedFragSr;
- cfirstCompletedFragSr = fragptr.i;
- if (cfirstWaitFragSr != RNIL) {
- jam();
- /* --------------------------------------------------------------------
- * ANOTHER FRAGMENT IS WAITING FOR SYSTEM RESTART. RESTART THIS
- * FRAGMENT AS WELL.
- * -------------------------------------------------------------------- */
- fragptr.i = cfirstWaitFragSr;
- ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
- cfirstWaitFragSr = fragptr.p->nextFrag;
- /* --------------------------------------------------------------------
- * RETRIEVE DATA FROM THE FRAGMENT RECORD.
- * -------------------------------------------------------------------- */
- ndbrequire(fragptr.p->srChkpnr < MAX_LCP_STORED);
- initLcpSr(signal,
- fragptr.p->srChkpnr,
- fragptr.p->lcpId[fragptr.p->srChkpnr],
- fragptr.p->tabRef,
- fragptr.p->fragId,
- fragptr.i);
- signal->theData[0] = lcpPtr.i;
- signal->theData[1] = cownref;
- signal->theData[2] = lcpPtr.p->currentFragment.lcpFragOrd.lcpNo;
- signal->theData[3] = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
- signal->theData[4] = lcpPtr.p->currentFragment.lcpFragOrd.fragmentId;
- sendSignal(fragptr.p->accBlockref, GSN_SR_FRAGIDREQ, signal, 5, JBB);
- return;
- } else {
- jam();
- /* --------------------------------------------------------------------
- * NO MORE FRAGMENTS ARE WAITING FOR SYSTEM RESTART.
- * -------------------------------------------------------------------- */
- lcpPtr.p->lcpState = LcpRecord::LCP_IDLE;
- if (cstartRecReq == ZTRUE) {
- jam();
- /* ----------------------------------------------------------------
- * WE HAVE ALSO RECEIVED AN INDICATION THAT NO MORE FRAGMENTS
- * NEEDS RESTART.
- * NOW IT IS TIME TO START EXECUTING THE UNDO LOG.
- * ----------------------------------------------------------------
- * WE ARE NOW IN A POSITION TO ORDER TUP AND ACC TO START
- * EXECUTING THEIR UNDO LOGS. THIS MUST BE DONE BEFORE THE
- * FRAGMENT LOGS CAN BE EXECUTED.
- * ---------------------------------------------------------------- */
- csrExecUndoLogState = EULS_STARTED;
- signal->theData[0] = caccBlockref;
- signal->theData[1] = cownref;
- sendSignal(caccBlockref, GSN_START_RECREQ, signal, 2, JBB);
- signal->theData[0] = ctupBlockref;
- signal->theData[1] = cownref;
- sendSignal(ctupBlockref, GSN_START_RECREQ, signal, 2, JBB);
- return;
- } else {
- jam();
- /* ----------------------------------------------------------------
- * WE HAVE NOT RECEIVED ALL FRAGMENTS YET OR AT LEAST NOT WE
- * HAVE NOT RECEIVED THE START_RECREQ SIGNAL. EXIT AND WAIT
- * FOR MORE.
- * ---------------------------------------------------------------- */
- return;
- }//if
- }//if
- }//if
- /*---------------*/
- /* ELSE */
- /*-------------------------------------------------------------------------
- * THE SYSTEM RESTART ON THIS FRAGMENT HAS NOT BEEN COMPLETED,
- * EXIT AND WAIT FOR MORE SIGNALS
- *-------------------------------------------------------------------------
- * DO NOTHING, EXIT IS EXECUTED BELOW
- *------------------------------------------------------------------------- */
- return;
- }//Dblqh::srCompletedLab()
- /* ************> */
- /* TUP_SRREF > */
- /* ************> */
- void Dblqh::execTUP_SRREF(Signal* signal)
- {
- jamEntry();
- terrorCode = signal->theData[1];
- systemErrorLab(signal);
- return;
- }//Dblqh::execTUP_SRREF()
- /* ***************> */
- /* START_RECREQ > */
- /* ***************> */
- void Dblqh::execSTART_RECREQ(Signal* signal)
- {
- CRASH_INSERTION(5027);
- jamEntry();
- StartRecReq * const req = (StartRecReq*)&signal->theData[0];
- cmasterDihBlockref = req->senderRef;
- crestartOldestGci = req->keepGci;
- crestartNewestGci = req->lastCompletedGci;
- cnewestGci = req->newestGci;
- ndbrequire(req->receivingNodeId == cownNodeid);
- cnewestCompletedGci = cnewestGci;
- cstartRecReq = ZTRUE;
- for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) {
- ptrAss(logPartPtr, logPartRecord);
- logPartPtr.p->logPartNewestCompletedGCI = cnewestCompletedGci;
- }//for
- /* ------------------------------------------------------------------------
- * WE HAVE TO SET THE OLDEST AND THE NEWEST GLOBAL CHECKPOINT IDENTITY
- * THAT WILL SURVIVE THIS SYSTEM RESTART. THIS IS NEEDED SO THAT WE CAN
- * SET THE LOG HEAD AND LOG TAIL PROPERLY BEFORE STARTING THE SYSTEM AGAIN.
- * WE ALSO NEED TO SET CNEWEST_GCI TO ENSURE THAT LOG RECORDS ARE EXECUTED
- * WITH A PROPER GCI.
- *------------------------------------------------------------------------ */
- if (cstartType == NodeState::ST_NODE_RESTART) {
- jam();
- signal->theData[0] = ZSR_PHASE3_START;
- signal->theData[1] = ZSR_PHASE2_COMPLETED;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
- }//if
- if(cstartType == NodeState::ST_INITIAL_NODE_RESTART){
- jam();
- StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend();
- conf->startingNodeId = getOwnNodeId();
- sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal,
- StartRecConf::SignalLength, JBB);
- return;
- }//if
- if (cfirstWaitFragSr == RNIL) {
- /* ----------------------------------------------------------------------
- * THERE ARE NO FRAGMENTS WAITING TO BE RESTARTED.
- * --------------------------------------------------------------------- */
- lcpPtr.i = 0;
- ptrAss(lcpPtr, lcpRecord);
- if (lcpPtr.p->lcpState == LcpRecord::LCP_IDLE) {
- jam();
- /* --------------------------------------------------------------------
- * THERE ARE NO FRAGMENTS THAT ARE CURRENTLY PERFORMING THEIR
- * SYSTEM RESTART.
- * --------------------------------------------------------------------
- * WE ARE NOW IN A POSITION TO ORDER TUP AND ACC TO START EXECUTING
- * THEIR UNDO LOGS. THIS MUST BE DONE BEFORE THE FRAGMENT LOGS
- * CAN BE EXECUTED.
- * ------------------------------------------------------------------- */
- csrExecUndoLogState = EULS_STARTED;
- signal->theData[0] = caccBlockref;
- signal->theData[1] = cownref;
- sendSignal(caccBlockref, GSN_START_RECREQ, signal, 2, JBB);
- signal->theData[0] = ctupBlockref;
- signal->theData[1] = cownref;
- sendSignal(ctupBlockref, GSN_START_RECREQ, signal, 2, JBB);
- }//if
- }//if
- /* -----------------------------------------------------------------------
- * EXIT AND WAIT FOR COMPLETION OF ALL FRAGMENTS.
- * ----------------------------------------------------------------------- */
- return;
- }//Dblqh::execSTART_RECREQ()
- /* ***************>> */
- /* START_RECCONF > */
- /* ***************>> */
- void Dblqh::execSTART_RECCONF(Signal* signal)
- {
- jamEntry();
- BlockReference userRef = signal->theData[0];
- if (userRef == caccBlockref) {
- if (csrExecUndoLogState == EULS_STARTED) {
- jam();
- csrExecUndoLogState = EULS_ACC_COMPLETED;
- } else {
- ndbrequire(csrExecUndoLogState == EULS_TUP_COMPLETED);
- jam();
- csrExecUndoLogState = EULS_COMPLETED;
- /* --------------------------------------------------------------------
- * START THE FIRST PHASE OF EXECUTION OF THE LOG.
- * ------------------------------------------------------------------- */
- startExecSr(signal);
- }//if
- } else {
- ndbrequire(userRef == ctupBlockref);
- if (csrExecUndoLogState == EULS_STARTED) {
- jam();
- csrExecUndoLogState = EULS_TUP_COMPLETED;
- } else {
- ndbrequire(csrExecUndoLogState == EULS_ACC_COMPLETED);
- jam();
- csrExecUndoLogState = EULS_COMPLETED;
- /* --------------------------------------------------------------------
- * START THE FIRST PHASE OF EXECUTION OF THE LOG.
- * ------------------------------------------------------------------- */
- startExecSr(signal);
- }//if
- }//if
- return;
- }//Dblqh::execSTART_RECCONF()
- /* ***************> */
- /* START_RECREF > */
- /* ***************> */
- void Dblqh::execSTART_RECREF(Signal* signal)
- {
- jamEntry();
- ndbrequire(false);
- }//Dblqh::execSTART_RECREF()
- /* ***************>> */
- /* START_EXEC_SR > */
- /* ***************>> */
- void Dblqh::execSTART_EXEC_SR(Signal* signal)
- {
- FragrecordPtr prevFragptr;
- jamEntry();
- fragptr.i = signal->theData[0];
- prevFragptr.i = signal->theData[1];
- if (fragptr.i == RNIL) {
- jam();
- ndbrequire(cnoOfNodes < MAX_NDB_NODES);
- /* ----------------------------------------------------------------------
- * NO MORE FRAGMENTS TO START EXECUTING THE LOG ON.
- * SEND EXEC_SRREQ TO ALL LQH TO INDICATE THAT THIS NODE WILL
- * NOT REQUEST ANY MORE FRAGMENTS TO EXECUTE THE FRAGMENT LOG ON.
- * ----------------------------------------------------------------------
- * WE NEED TO SEND THOSE SIGNALS EVEN IF WE HAVE NOT REQUESTED
- * ANY FRAGMENTS PARTICIPATE IN THIS PHASE.
- * --------------------------------------------------------------------- */
- for (Uint32 i = 0; i < cnoOfNodes; i++) {
- jam();
- if (cnodeStatus[i] == ZNODE_UP) {
- jam();
- ndbrequire(cnodeData[i] < MAX_NDB_NODES);
- BlockReference ref = calcLqhBlockRef(cnodeData[i]);
- signal->theData[0] = cownNodeid;
- sendSignal(ref, GSN_EXEC_SRREQ, signal, 1, JBB);
- }//if
- }//for
- } else {
- jam();
- ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
- if (fragptr.p->srNoLognodes > csrPhasesCompleted) {
- jam();
- Uint32 index = csrPhasesCompleted;
- arrGuard(index, 4);
- BlockReference ref = calcLqhBlockRef(fragptr.p->srLqhLognode[index]);
- fragptr.p->srStatus = Fragrecord::SS_STARTED;
- /* --------------------------------------------------------------------
- * SINCE WE CAN HAVE SEVERAL LQH NODES PER FRAGMENT WE CALCULATE
- * THE LQH POINTER IN SUCH A WAY THAT WE CAN DEDUCE WHICH OF THE
- * LQH NODES THAT HAS RESPONDED WHEN EXEC_FRAGCONF IS RECEIVED.
- * ------------------------------------------------------------------- */
- ExecFragReq * const execFragReq = (ExecFragReq *)&signal->theData[0];
- execFragReq->userPtr = fragptr.i;
- execFragReq->userRef = cownref;
- execFragReq->tableId = fragptr.p->tabRef;
- execFragReq->fragId = fragptr.p->fragId;
- execFragReq->startGci = fragptr.p->srStartGci[index];
- execFragReq->lastGci = fragptr.p->srLastGci[index];
- sendSignal(ref, GSN_EXEC_FRAGREQ, signal, ExecFragReq::SignalLength, JBB);
- prevFragptr.i = fragptr.i;
- fragptr.i = fragptr.p->nextFrag;
- } else {
- jam();
- /* --------------------------------------------------------------------
- * THIS FRAGMENT IS NOW FINISHED WITH THE SYSTEM RESTART. IT DOES
- * NOT NEED TO PARTICIPATE IN ANY MORE PHASES. REMOVE IT FROM THE
- * LIST OF COMPLETED FRAGMENTS TO EXECUTE THE LOG ON.
- * 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 = next;
- } else {
- jam();
- 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;
- signal->theData[1] = cownNodeid;
- sendSignal(fragptr.p->srBlockref, GSN_START_FRAGCONF, signal, 2, JBB);
- /* --------------------------------------------------------------------
- * WE HAVE TO ENSURE THAT THIS FRAGMENT IS NOT PUT BACK ON THE LIST BY
- * MISTAKE. WE DO THIS BY ALSO REMOVING IT AS PREVIOUS IN START_EXEC_SR
- * THIS IS PERFORMED BY KEEPING PREV_FRAGPTR AS PREV_FRAGPTR BUT MOVING
- * FRAGPTR TO THE NEXT FRAGMENT IN THE LIST.
- * ------------------------------------------------------------------- */
- fragptr.i = next;
- }//if
- signal->theData[0] = fragptr.i;
- signal->theData[1] = prevFragptr.i;
- sendSignal(cownref, GSN_START_EXEC_SR, signal, 2, JBB);
- }//if
- return;
- }//Dblqh::execSTART_EXEC_SR()
- /* ***************> */
- /* EXEC_FRAGREQ > */
- /* ***************> */
- /* --------------------------------------------------------------------------
- * THIS SIGNAL IS USED TO REQUEST THAT A FRAGMENT PARTICIPATES IN EXECUTING
- * THE LOG IN THIS NODE.
- * ------------------------------------------------------------------------- */
- void Dblqh::execEXEC_FRAGREQ(Signal* signal)
- {
- ExecFragReq * const execFragReq = (ExecFragReq *)&signal->theData[0];
- jamEntry();
- tabptr.i = execFragReq->tableId;
- Uint32 fragId = execFragReq->fragId;
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
- if (!getFragmentrec(signal, fragId)) {
- jam();
- if (!insertFragrec(signal, fragId)) {
- jam();
- sendExecFragRefLab(signal);
- return;
- }//if
- initFragrec(signal, tabptr.i, fragId, ZLOG_NODE);
- fragptr.p->execSrStatus = Fragrecord::ACTIVE_REMOVE_AFTER;
- } else {
- jam();
- if (fragptr.p->execSrStatus == Fragrecord::ACTIVE_REMOVE_AFTER) {
- jam();
- fragptr.p->execSrStatus = Fragrecord::ACTIVE_REMOVE_AFTER;
- } else {
- jam();
- }//if
- }//if
- ndbrequire(fragptr.p->execSrNoReplicas < 4);
- fragptr.p->execSrBlockref[fragptr.p->execSrNoReplicas] = execFragReq->userRef;
- fragptr.p->execSrUserptr[fragptr.p->execSrNoReplicas] = execFragReq->userPtr;
- fragptr.p->execSrStartGci[fragptr.p->execSrNoReplicas] = execFragReq->startGci;
- fragptr.p->execSrLastGci[fragptr.p->execSrNoReplicas] = execFragReq->lastGci;
- fragptr.p->execSrStatus = Fragrecord::ACTIVE;
- fragptr.p->execSrNoReplicas++;
- cnoFragmentsExecSr++;
- return;
- }//Dblqh::execEXEC_FRAGREQ()
- void Dblqh::sendExecFragRefLab(Signal* signal)
- {
- ExecFragReq * const execFragReq = (ExecFragReq *)&signal->theData[0];
- BlockReference retRef = execFragReq->userRef;
- Uint32 retPtr = execFragReq->userPtr;
- signal->theData[0] = retPtr;
- signal->theData[1] = terrorCode;
- sendSignal(retRef, GSN_EXEC_FRAGREF, signal, 2, JBB);
- return;
- }//Dblqh::sendExecFragRefLab()
- /* ***************>> */
- /* EXEC_FRAGCONF > */
- /* ***************>> */
- void Dblqh::execEXEC_FRAGCONF(Signal* signal)
- {
- jamEntry();
- fragptr.i = signal->theData[0];
- ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
- fragptr.p->srStatus = Fragrecord::SS_COMPLETED;
- return;
- }//Dblqh::execEXEC_FRAGCONF()
- /* ***************> */
- /* EXEC_FRAGREF > */
- /* ***************> */
- void Dblqh::execEXEC_FRAGREF(Signal* signal)
- {
- jamEntry();
- terrorCode = signal->theData[1];
- systemErrorLab(signal);
- return;
- }//Dblqh::execEXEC_FRAGREF()
- /* *************** */
- /* EXEC_SRCONF > */
- /* *************** */
- void Dblqh::execEXEC_SRCONF(Signal* signal)
- {
- jamEntry();
- Uint32 nodeId = signal->theData[0];
- arrGuard(nodeId, MAX_NDB_NODES);
- cnodeExecSrState[nodeId] = ZEXEC_SR_COMPLETED;
- ndbrequire(cnoOfNodes < MAX_NDB_NODES);
- for (Uint32 i = 0; i < cnoOfNodes; i++) {
- jam();
- if (cnodeStatus[i] == ZNODE_UP) {
- jam();
- nodeId = cnodeData[i];
- arrGuard(nodeId, MAX_NDB_NODES);
- if (cnodeExecSrState[nodeId] != ZEXEC_SR_COMPLETED) {
- jam();
- /* ------------------------------------------------------------------
- * ALL NODES HAVE NOT REPORTED COMPLETION OF EXECUTING FRAGMENT
- * LOGS YET.
- * ----------------------------------------------------------------- */
- return;
- }//if
- }//if
- }//for
- /* ------------------------------------------------------------------------
- * CLEAR NODE SYSTEM RESTART EXECUTION STATE TO PREPARE FOR NEXT PHASE OF
- * LOG EXECUTION.
- * ----------------------------------------------------------------------- */
- for (nodeId = 0; nodeId < MAX_NDB_NODES; nodeId++) {
- cnodeExecSrState[nodeId] = ZSTART_SR;
- }//for
- /* ------------------------------------------------------------------------
- * NOW CHECK IF ALL FRAGMENTS IN THIS PHASE HAVE COMPLETED. IF SO START THE
- * NEXT PHASE.
- * ----------------------------------------------------------------------- */
- fragptr.i = cfirstCompletedFragSr;
- if (fragptr.i == RNIL) {
- jam();
- execSrCompletedLab(signal);
- return;
- }//if
- do {
- jam();
- ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
- ndbrequire(fragptr.p->srStatus == Fragrecord::SS_COMPLETED);
- fragptr.i = fragptr.p->nextFrag;
- } while (fragptr.i != RNIL);
- execSrCompletedLab(signal);
- return;
- }//Dblqh::execEXEC_SRCONF()
- void Dblqh::execSrCompletedLab(Signal* signal)
- {
- csrPhasesCompleted++;
- /* ------------------------------------------------------------------------
- * ALL FRAGMENTS WERE COMPLETED. THIS PHASE IS COMPLETED. IT IS NOW TIME TO
- * START THE NEXT PHASE.
- * ----------------------------------------------------------------------- */
- if (csrPhasesCompleted >= 4) {
- jam();
- /* ----------------------------------------------------------------------
- * THIS WAS THE LAST PHASE. WE HAVE NOW COMPLETED THE EXECUTION THE
- * FRAGMENT LOGS IN ALL NODES. BEFORE WE SEND START_RECCONF TO THE
- * MASTER DIH TO INDICATE A COMPLETED SYSTEM RESTART IT IS NECESSARY
- * TO FIND THE HEAD AND THE TAIL OF THE LOG WHEN NEW OPERATIONS START
- * TO COME AGAIN.
- *
- * THE FIRST STEP IS TO FIND THE HEAD AND TAIL MBYTE OF EACH LOG PART.
- * TO DO THIS WE REUSE THE CONTINUEB SIGNAL SR_LOG_LIMITS. THEN WE
- * HAVE TO FIND THE ACTUAL PAGE NUMBER AND PAGE INDEX WHERE TO
- * CONTINUE WRITING THE LOG AFTER THE SYSTEM RESTART.
- * --------------------------------------------------------------------- */
- for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) {
- jam();
- ptrAss(logPartPtr, logPartRecord);
- logPartPtr.p->logPartState = LogPartRecord::SR_FOURTH_PHASE_STARTED;
- logPartPtr.p->logLastGci = crestartNewestGci;
- logPartPtr.p->logStartGci = crestartOldestGci;
- logPartPtr.p->logExecState = LogPartRecord::LES_SEARCH_STOP;
- if (logPartPtr.p->headFileNo == ZNIL) {
- jam();
- /* -----------------------------------------------------------------
- * IF WE HAVEN'T FOUND ANY HEAD OF THE LOG THEN WE ARE IN SERIOUS
- * PROBLEM. THIS SHOULD NOT OCCUR. IF IT OCCURS ANYWAY THEN WE
- * HAVE TO FIND A CURE FOR THIS PROBLEM.
- * ----------------------------------------------------------------- */
- systemErrorLab(signal);
- return;
- }//if
- signal->theData[0] = ZSR_LOG_LIMITS;
- signal->theData[1] = logPartPtr.i;
- signal->theData[2] = logPartPtr.p->lastLogfile;
- signal->theData[3] = logPartPtr.p->lastMbyte;
- sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
- }//for
- return;
- } else {
- jam();
- /* ----------------------------------------------------------------------
- * THERE ARE YET MORE PHASES TO RESTART.
- * WE MUST INITIALISE DATA FOR NEXT PHASE AND SEND START SIGNAL.
- * --------------------------------------------------------------------- */
- startExecSr(signal);
- }//if
- return;
- }//Dblqh::execSrCompletedLab()
- /* ************>> */
- /* EXEC_SRREQ > */
- /* ************>> */
- void Dblqh::execEXEC_SRREQ(Signal* signal)
- {
- jamEntry();
- Uint32 nodeId = signal->theData[0];
- ndbrequire(nodeId < MAX_NDB_NODES);
- cnodeSrState[nodeId] = ZEXEC_SR_COMPLETED;
- ndbrequire(cnoOfNodes < MAX_NDB_NODES);
- for (Uint32 i = 0; i < cnoOfNodes; i++) {
- jam();
- if (cnodeStatus[i] == ZNODE_UP) {
- jam();
- nodeId = cnodeData[i];
- if (cnodeSrState[nodeId] != ZEXEC_SR_COMPLETED) {
- jam();
- /* ------------------------------------------------------------------
- * ALL NODES HAVE NOT REPORTED COMPLETION OF SENDING EXEC_FRAGREQ YET.
- * ----------------------------------------------------------------- */
- return;
- }//if
- }//if
- }//for
- /* ------------------------------------------------------------------------
- * CLEAR NODE SYSTEM RESTART STATE TO PREPARE FOR NEXT PHASE OF LOG
- * EXECUTION
- * ----------------------------------------------------------------------- */
- for (nodeId = 0; nodeId < MAX_NDB_NODES; nodeId++) {
- cnodeSrState[nodeId] = ZSTART_SR;
- }//for
- if (csrPhasesCompleted != 0) {
- /* ----------------------------------------------------------------------
- * THE FIRST PHASE MUST ALWAYS EXECUTE THE LOG.
- * --------------------------------------------------------------------- */
- if (cnoFragmentsExecSr == 0) {
- jam();
- /* --------------------------------------------------------------------
- * THERE WERE NO FRAGMENTS THAT NEEDED TO EXECUTE THE LOG IN THIS PHASE.
- * ------------------------------------------------------------------- */
- srPhase3Comp(signal);
- return;
- }//if
- }//if
- /* ------------------------------------------------------------------------
- * NOW ALL NODES HAVE SENT ALL EXEC_FRAGREQ. NOW WE CAN START EXECUTING THE
- * LOG FROM THE MINIMUM GCI NEEDED UNTIL THE MAXIMUM GCI NEEDED.
- *
- * WE MUST FIRST CHECK IF THE FIRST PHASE OF THE SYSTEM RESTART HAS BEEN
- * COMPLETED. THIS HANDLING IS PERFORMED IN THE FILE SYSTEM MODULE
- * ----------------------------------------------------------------------- */
- signal->theData[0] = ZSR_PHASE3_START;
- signal->theData[1] = ZSR_PHASE2_COMPLETED;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
- }//Dblqh::execEXEC_SRREQ()
- /* ######################################################################### */
- /* SYSTEM RESTART PHASE THREE MODULE */
- /* THIS MODULE IS A SUB-MODULE OF THE FILE SYSTEM HANDLING. */
- /* */
- /* THIS MODULE IS CONCERNED WITH EXECUTING THE FRAGMENT LOG. IT DOES ALSO */
- /* CONTAIN SIGNAL RECEPTIONS LQHKEYCONF AND LQHKEYREF SINCE LQHKEYREQ IS USED*/
- /* TO EXECUTE THE LOG RECORDS. */
- /* */
- /* BEFORE IT STARTS IT HAS BEEN DECIDED WHERE TO START AND WHERE TO STOP */
- /* READING THE FRAGMENT LOG BY USING THE INFORMATION ABOUT GCI DISCOVERED IN */
- /* PHASE ONE OF THE SYSTEM RESTART. */
- /* ######################################################################### */
- /*---------------------------------------------------------------------------*/
- /* PHASE THREE OF THE SYSTEM RESTART CAN NOW START. ONE OF THE PHASES HAVE */
- /* COMPLETED. */
- /*---------------------------------------------------------------------------*/
- void Dblqh::srPhase3Start(Signal* signal)
- {
- UintR tsrPhaseStarted;
-
- jamEntry();
- tsrPhaseStarted = signal->theData[0];
- if (csrPhaseStarted == ZSR_NO_PHASE_STARTED) {
- jam();
- csrPhaseStarted = tsrPhaseStarted;
- if (cstartType == NodeState::ST_NODE_RESTART) {
- ndbrequire(cinitialStartOngoing == ZTRUE);
- cinitialStartOngoing = ZFALSE;
- checkStartCompletedLab(signal);
- }//if
- return;
- }//if
- ndbrequire(csrPhaseStarted != tsrPhaseStarted);
- ndbrequire(csrPhaseStarted != ZSR_BOTH_PHASES_STARTED);
- csrPhaseStarted = ZSR_BOTH_PHASES_STARTED;
- for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) {
- jam();
- ptrAss(logPartPtr, logPartRecord);
- logPartPtr.p->logPartState = LogPartRecord::SR_THIRD_PHASE_STARTED;
- logPartPtr.p->logStartGci = (UintR)-1;
- if (csrPhasesCompleted == 0) {
- jam();
- /* --------------------------------------------------------------------
- * THE FIRST PHASE WE MUST ENSURE THAT IT REACHES THE END OF THE LOG.
- * ------------------------------------------------------------------- */
- logPartPtr.p->logLastGci = crestartNewestGci;
- } else {
- jam();
- logPartPtr.p->logLastGci = 2;
- }//if
- }//for
- if (cstartType == NodeState::ST_NODE_RESTART) {
- jam();
- /* ----------------------------------------------------------------------
- * FOR A NODE RESTART WE HAVE NO FRAGMENTS DEFINED YET.
- * THUS WE CAN SKIP THAT PART
- * --------------------------------------------------------------------- */
- signal->theData[0] = ZSR_GCI_LIMITS;
- signal->theData[1] = RNIL;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- } else {
- jam();
- signal->theData[0] = ZSR_GCI_LIMITS;
- signal->theData[1] = 0;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- }//if
- return;
- }//Dblqh::srPhase3Start()
- /* --------------------------------------------------------------------------
- * WE NOW WE NEED TO FIND THE LIMITS WITHIN WHICH TO EXECUTE
- * THE FRAGMENT LOG
- * ------------------------------------------------------------------------- */
- void Dblqh::srGciLimits(Signal* signal)
- {
- LogPartRecordPtr tmpLogPartPtr;
- jamEntry();
- fragptr.i = signal->theData[0];
- Uint32 loopCount = 0;
- logPartPtr.i = 0;
- ptrAss(logPartPtr, logPartRecord);
- while (fragptr.i < cfragrecFileSize) {
- jam();
- ptrAss(fragptr, fragrecord);
- if (fragptr.p->execSrStatus != Fragrecord::IDLE) {
- jam();
- ndbrequire(fragptr.p->execSrNoReplicas - 1 < 4);
- for (Uint32 i = 0; i < fragptr.p->execSrNoReplicas; i++) {
- jam();
- if (fragptr.p->execSrStartGci[i] < logPartPtr.p->logStartGci) {
- jam();
- logPartPtr.p->logStartGci = fragptr.p->execSrStartGci[i];
- }//if
- if (fragptr.p->execSrLastGci[i] > logPartPtr.p->logLastGci) {
- jam();
- logPartPtr.p->logLastGci = fragptr.p->execSrLastGci[i];
- }//if
- }//for
- }//if
- loopCount++;
- if (loopCount > 20) {
- jam();
- signal->theData[0] = ZSR_GCI_LIMITS;
- signal->theData[1] = fragptr.i + 1;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
- } else {
- jam();
- fragptr.i++;
- }//if
- }//while
- if (logPartPtr.p->logStartGci == (UintR)-1) {
- jam();
- /* --------------------------------------------------------------------
- * THERE WERE NO FRAGMENTS TO INSTALL WE WILL EXECUTE THE LOG AS
- * SHORT AS POSSIBLE TO REACH THE END OF THE LOG. THIS WE DO BY
- * STARTING AT THE STOP GCI.
- * ------------------------------------------------------------------- */
- logPartPtr.p->logStartGci = logPartPtr.p->logLastGci;
- }//if
- for (tmpLogPartPtr.i = 1; tmpLogPartPtr.i < 4; tmpLogPartPtr.i++) {
- ptrAss(tmpLogPartPtr, logPartRecord);
- tmpLogPartPtr.p->logStartGci = logPartPtr.p->logStartGci;
- tmpLogPartPtr.p->logLastGci = logPartPtr.p->logLastGci;
- }//for
- for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) {
- jam();
- ptrAss(logPartPtr, logPartRecord);
- logPartPtr.p->logExecState = LogPartRecord::LES_SEARCH_STOP;
- signal->theData[0] = ZSR_LOG_LIMITS;
- signal->theData[1] = logPartPtr.i;
- signal->theData[2] = logPartPtr.p->lastLogfile;
- signal->theData[3] = logPartPtr.p->lastMbyte;
- sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
- }//for
- }//Dblqh::srGciLimits()
- /* --------------------------------------------------------------------------
- * IT IS NOW TIME TO FIND WHERE TO START EXECUTING THE LOG.
- * THIS SIGNAL IS SENT FOR EACH LOG PART AND STARTS THE EXECUTION
- * OF THE LOG FOR THIS PART.
- *-------------------------------------------------------------------------- */
- void Dblqh::srLogLimits(Signal* signal)
- {
- Uint32 tlastPrepRef;
- Uint32 tmbyte;
- jamEntry();
- logPartPtr.i = signal->theData[0];
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- logFilePtr.i = signal->theData[1];
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- tmbyte = signal->theData[2];
- Uint32 loopCount = 0;
- /* ------------------------------------------------------------------------
- * WE ARE SEARCHING FOR THE START AND STOP MBYTE OF THE LOG THAT IS TO BE
- * EXECUTED.
- * ----------------------------------------------------------------------- */
- while(true) {
- ndbrequire(tmbyte < 16);
- if (logPartPtr.p->logExecState == LogPartRecord::LES_SEARCH_STOP) {
- if (logFilePtr.p->logMaxGciCompleted[tmbyte] < logPartPtr.p->logLastGci) {
- jam();
- /* --------------------------------------------------------------------
- * WE ARE STEPPING BACKWARDS FROM MBYTE TO MBYTE. THIS IS THE FIRST
- * MBYTE WHICH IS TO BE INCLUDED IN THE LOG EXECUTION. THE STOP GCI
- * HAS NOT BEEN COMPLETED BEFORE THIS MBYTE. THUS THIS MBYTE HAVE
- * TO BE EXECUTED.
- * ------------------------------------------------------------------- */
- logPartPtr.p->stopLogfile = logFilePtr.i;
- logPartPtr.p->stopMbyte = tmbyte;
- logPartPtr.p->logExecState = LogPartRecord::LES_SEARCH_START;
- }//if
- }//if
- /* ------------------------------------------------------------------------
- * WHEN WE HAVEN'T FOUND THE STOP MBYTE IT IS NOT NECESSARY TO LOOK FOR THE
- * START MBYTE. THE REASON IS THE FOLLOWING LOGIC CHAIN:
- * MAX_GCI_STARTED >= MAX_GCI_COMPLETED >= LAST_GCI >= START_GCI
- * THUS MAX_GCI_STARTED >= START_GCI. THUS MAX_GCI_STARTED < START_GCI CAN
- * NOT BE TRUE AS WE WILL CHECK OTHERWISE.
- * ----------------------------------------------------------------------- */
- if (logPartPtr.p->logExecState == LogPartRecord::LES_SEARCH_START) {
- if (logFilePtr.p->logMaxGciStarted[tmbyte] < logPartPtr.p->logStartGci) {
- jam();
- /* --------------------------------------------------------------------
- * WE HAVE NOW FOUND THE START OF THE EXECUTION OF THE LOG.
- * WE STILL HAVE TO MOVE IT BACKWARDS TO ALSO INCLUDE THE
- * PREPARE RECORDS WHICH WERE STARTED IN A PREVIOUS MBYTE.
- * ------------------------------------------------------------------- */
- tlastPrepRef = logFilePtr.p->logLastPrepRef[tmbyte];
- logPartPtr.p->startMbyte = tlastPrepRef & 65535;
- LogFileRecordPtr locLogFilePtr;
- findLogfile(signal, tlastPrepRef >> 16, logPartPtr, &locLogFilePtr);
- logPartPtr.p->startLogfile = locLogFilePtr.i;
- logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOG;
- }//if
- }//if
- if (logPartPtr.p->logExecState != LogPartRecord::LES_EXEC_LOG) {
- if (tmbyte == 0) {
- jam();
- tmbyte = ZNO_MBYTES_IN_FILE - 1;
- logFilePtr.i = logFilePtr.p->prevLogFile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- } else {
- jam();
- tmbyte--;
- }//if
- if (logPartPtr.p->lastLogfile == logFilePtr.i) {
- ndbrequire(logPartPtr.p->lastMbyte != tmbyte);
- }//if
- if (loopCount > 20) {
- jam();
- signal->theData[0] = ZSR_LOG_LIMITS;
- signal->theData[1] = logPartPtr.i;
- signal->theData[2] = logFilePtr.i;
- signal->theData[3] = tmbyte;
- sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
- return;
- }//if
- loopCount++;
- } else {
- jam();
- break;
- }//if
- }//while
- /* ------------------------------------------------------------------------
- * WE HAVE NOW FOUND BOTH THE START AND THE STOP OF THE LOG. NOW START
- * EXECUTING THE LOG. THE FIRST ACTION IS TO OPEN THE LOG FILE WHERE TO
- * START EXECUTING THE LOG.
- * ----------------------------------------------------------------------- */
- if (logPartPtr.p->logPartState == LogPartRecord::SR_THIRD_PHASE_STARTED) {
- jam();
- logFilePtr.i = logPartPtr.p->startLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN_EXEC_SR_START;
- openFileRw(signal, logFilePtr);
- } else {
- jam();
- ndbrequire(logPartPtr.p->logPartState == LogPartRecord::SR_FOURTH_PHASE_STARTED);
- /* --------------------------------------------------------------------
- * WE HAVE NOW FOUND THE TAIL MBYTE IN THE TAIL FILE.
- * SET THOSE PARAMETERS IN THE LOG PART.
- * WE HAVE ALSO FOUND THE HEAD MBYTE. WE STILL HAVE TO SEARCH
- * FOR THE PAGE NUMBER AND PAGE INDEX WHERE TO SET THE HEAD.
- * ------------------------------------------------------------------- */
- logFilePtr.i = logPartPtr.p->startLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPartPtr.p->logTailFileNo = logFilePtr.p->fileNo;
- logPartPtr.p->logTailMbyte = logPartPtr.p->startMbyte;
- /* --------------------------------------------------------------------
- * THE HEAD WE ACTUALLY FOUND DURING EXECUTION OF LOG SO WE USE
- * THIS INFO HERE RATHER THAN THE MBYTE WE FOUND TO BE THE HEADER.
- * ------------------------------------------------------------------- */
- LogFileRecordPtr locLogFilePtr;
- findLogfile(signal, logPartPtr.p->headFileNo, logPartPtr, &locLogFilePtr);
- locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_FOURTH_PHASE;
- openFileRw(signal, locLogFilePtr);
- }//if
- return;
- }//Dblqh::srLogLimits()
- void Dblqh::openExecSrStartLab(Signal* signal)
- {
- logPartPtr.p->currentLogfile = logFilePtr.i;
- logFilePtr.p->currentMbyte = logPartPtr.p->startMbyte;
- /* ------------------------------------------------------------------------
- * WE NEED A TC CONNECT RECORD TO HANDLE EXECUTION OF LOG RECORDS.
- * ------------------------------------------------------------------------ */
- seizeTcrec();
- logPartPtr.p->logTcConrec = tcConnectptr.i;
- /* ------------------------------------------------------------------------
- * THE FIRST LOG RECORD TO EXECUTE IS ALWAYS AT A NEW MBYTE.
- * SET THE NUMBER OF PAGES IN THE MAIN MEMORY BUFFER TO ZERO AS AN INITIAL
- * VALUE. THIS VALUE WILL BE UPDATED AND ENSURED THAT IT RELEASES PAGES IN
- * THE SUBROUTINE READ_EXEC_SR.
- * ----------------------------------------------------------------------- */
- logPartPtr.p->mmBufferSize = 0;
- readExecSrNewMbyte(signal);
- return;
- }//Dblqh::openExecSrStartLab()
- /* ---------------------------------------------------------------------------
- * WE WILL ALWAYS ENSURE THAT WE HAVE AT LEAST 16 KBYTE OF LOG PAGES WHEN WE
- * START READING A LOG RECORD. THE ONLY EXCEPTION IS WHEN WE COME CLOSE TO A
- * MBYTE BOUNDARY. SINCE WE KNOW THAT LOG RECORDS ARE NEVER WRITTEN ACROSS A
- * MBYTE BOUNDARY THIS IS NOT A PROBLEM.
- *
- * WE START BY READING 64 KBYTE BEFORE STARTING TO EXECUTE THE LOG RECORDS.
- * WHEN WE COME BELOW 64 KBYTE WE READ ANOTHER SET OF LOG PAGES. WHEN WE
- * GO BELOW 16 KBYTE WE WAIT UNTIL THE READ PAGES HAVE ENTERED THE BLOCK.
- * ------------------------------------------------------------------------- */
- /* --------------------------------------------------------------------------
- * NEW PAGES FROM LOG FILE DURING EXECUTION OF LOG HAS ARRIVED.
- * ------------------------------------------------------------------------- */
- void Dblqh::readExecSrLab(Signal* signal)
- {
- buildLinkedLogPageList(signal);
- /* ------------------------------------------------------------------------
- * WE NEED TO SET THE CURRENT PAGE INDEX OF THE FIRST PAGE SINCE IT CAN BE
- * USED IMMEDIATELY WITHOUT ANY OTHER INITIALISATION. THE REST OF THE PAGES
- * WILL BE INITIALISED BY READ_LOGWORD.
- * ----------------------------------------------------------------------- */
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = ZPAGE_HEADER_SIZE;
- if (logPartPtr.p->logExecState ==
- LogPartRecord::LES_WAIT_READ_EXEC_SR_NEW_MBYTE) {
- jam();
- /* ----------------------------------------------------------------------
- * THIS IS THE FIRST READ DURING THE EXECUTION OF THIS MBYTE. SET THE
- * NEW CURRENT LOG PAGE TO THE FIRST OF THESE PAGES. CHANGE
- * LOG_EXEC_STATE TO ENSURE THAT WE START EXECUTION OF THE LOG.
- * --------------------------------------------------------------------- */
- logFilePtr.p->currentFilepage = logFilePtr.p->currentMbyte *
- ZPAGES_IN_MBYTE;
- logPartPtr.p->prevFilepage = logFilePtr.p->currentFilepage;
- logFilePtr.p->currentLogpage = lfoPtr.p->firstLfoPage;
- logPartPtr.p->prevLogpage = logFilePtr.p->currentLogpage;
- }//if
- moveToPageRef(signal);
- releaseLfo(signal);
- /* ------------------------------------------------------------------------
- * NOW WE HAVE COMPLETED THE RECEPTION OF THESE PAGES.
- * NOW CHECK IF WE NEED TO READ MORE PAGES.
- * ----------------------------------------------------------------------- */
- checkReadExecSr(signal);
- if (logPartPtr.p->logExecState == LogPartRecord::LES_EXEC_LOG) {
- jam();
- signal->theData[0] = ZEXEC_SR;
- signal->theData[1] = logPartPtr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
- }//if
- return;
- }//Dblqh::readExecSrLab()
- void Dblqh::openExecSrNewMbyteLab(Signal* signal)
- {
- readExecSrNewMbyte(signal);
- return;
- }//Dblqh::openExecSrNewMbyteLab()
- void Dblqh::closeExecSrLab(Signal* signal)
- {
- LogFileRecordPtr locLogFilePtr;
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
- logPartPtr.i = logFilePtr.p->logPartRec;
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- locLogFilePtr.i = logPartPtr.p->currentLogfile;
- ptrCheckGuard(locLogFilePtr, clogFileFileSize, logFileRecord);
- locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_EXEC_SR_NEW_MBYTE;
- openFileRw(signal, locLogFilePtr);
- return;
- }//Dblqh::closeExecSrLab()
- void Dblqh::writeDirtyLab(Signal* signal)
- {
- releaseLfo(signal);
- signal->theData[0] = logPartPtr.i;
- execSr(signal);
- return;
- }//Dblqh::writeDirtyLab()
- /* --------------------------------------------------------------------------
- * EXECUTE A LOG RECORD WITHIN THE CURRENT MBYTE.
- * ------------------------------------------------------------------------- */
- void Dblqh::execSr(Signal* signal)
- {
- LogFileRecordPtr nextLogFilePtr;
- LogPageRecordPtr tmpLogPagePtr;
- Uint32 logWord;
- jamEntry();
- logPartPtr.i = signal->theData[0];
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- do {
- jam();
- logFilePtr.i = logPartPtr.p->currentLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPagePtr.i = logPartPtr.p->prevLogpage;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- if (logPagePtr.p->logPageWord[ZPOS_DIRTY] == ZDIRTY) {
- jam();
- switch (logPartPtr.p->logExecState) {
- case LogPartRecord::LES_EXEC_LOG_COMPLETED:
- case LogPartRecord::LES_EXEC_LOG_NEW_FILE:
- case LogPartRecord::LES_EXEC_LOG_NEW_MBYTE:
- jam();
- /* ------------------------------------------------------------------
- * IN THIS WE HAVE COMPLETED EXECUTION OF THE CURRENT LOG PAGE
- * AND CAN WRITE IT TO DISK SINCE IT IS DIRTY.
- * ----------------------------------------------------------------- */
- writeDirty(signal, __LINE__);
- return;
- break;
- case LogPartRecord::LES_EXEC_LOG:
- jam();
- /* --------------------------------------------------------------------
- * IN THIS CASE WE ONLY WRITE THE PAGE TO DISK IF WE HAVE COMPLETED
- * EXECUTION OF LOG RECORDS BELONGING TO THIS LOG PAGE.
- * ------------------------------------------------------------------- */
- if (logFilePtr.p->currentLogpage != logPartPtr.p->prevLogpage) {
- jam();
- writeDirty(signal, __LINE__);
- return;
- }//if
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- }//if
- if (logFilePtr.p->currentLogpage != logPartPtr.p->prevLogpage) {
- jam();
- logPartPtr.p->prevLogpage = logPagePtr.p->logPageWord[ZNEXT_PAGE];
- logPartPtr.p->prevFilepage++;
- continue;
- }//if
- switch (logPartPtr.p->logExecState) {
- case LogPartRecord::LES_EXEC_LOG_COMPLETED:
- jam();
- releaseMmPages(signal);
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_EXEC_SR_COMPLETED;
- closeFile(signal, logFilePtr);
- return;
- break;
- case LogPartRecord::LES_EXEC_LOG_NEW_MBYTE:
- jam();
- logFilePtr.p->currentMbyte++;
- readExecSrNewMbyte(signal);
- return;
- break;
- case LogPartRecord::LES_EXEC_LOG_NEW_FILE:
- jam();
- nextLogFilePtr.i = logFilePtr.p->nextLogFile;
- logPartPtr.p->currentLogfile = nextLogFilePtr.i;
- ptrCheckGuard(nextLogFilePtr, clogFileFileSize, logFileRecord);
- nextLogFilePtr.p->currentMbyte = 0;
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_EXEC_SR;
- closeFile(signal, logFilePtr);
- return;
- break;
- case LogPartRecord::LES_EXEC_LOG:
- jam();
- /*empty*/;
- break;
- default:
- jam();
- systemErrorLab(signal);
- return;
- break;
- }//switch
- logPagePtr.i = logFilePtr.p->currentLogpage;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- logPartPtr.p->savePageIndex = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- if (logPartPtr.p->execSrPagesRead < ZMIN_READ_BUFFER_SIZE) {
- /* --------------------------------------------------------------------
- * THERE WERE LESS THAN 16 KBYTE OF LOG PAGES REMAINING. WE WAIT UNTIL
- * THE NEXT 64 KBYTE ARRIVES UNTIL WE CONTINUE AGAIN.
- * ------------------------------------------------------------------- */
- if ((logPartPtr.p->execSrPagesRead +
- logPartPtr.p->execSrPagesExecuted) < ZPAGES_IN_MBYTE) {
- jam();
- /* ------------------------------------------------------------------
- * WE ONLY STOP AND WAIT IF THERE MORE PAGES TO READ. IF IT IS NOT
- * THEN IT IS THE END OF THE MBYTE AND WE WILL CONTINUE. IT IS NO
- * RISK THAT A LOG RECORD WE FIND WILL NOT BE READ AT THIS TIME
- * SINCE THE LOG RECORDS NEVER SPAN OVER A MBYTE BOUNDARY.
- * ----------------------------------------------------------------- */
- readExecSr(signal);
- logPartPtr.p->logExecState = LogPartRecord::LES_WAIT_READ_EXEC_SR;
- return;
- }//if
- }//if
- logWord = readLogword(signal);
- switch (logWord) {
- /* ========================================================================= */
- /* ========================================================================= */
- case ZPREP_OP_TYPE:
- {
- logWord = readLogword(signal);
- stepAhead(signal, logWord - 2);
- break;
- }
- /* ========================================================================= */
- /* ========================================================================= */
- case ZINVALID_COMMIT_TYPE:
- jam();
- stepAhead(signal, ZCOMMIT_LOG_SIZE - 1);
- break;
- /* ========================================================================= */
- /* ========================================================================= */
- case ZCOMMIT_TYPE:
- {
- CommitLogRecord commitLogRecord;
- jam();
- tcConnectptr.i = logPartPtr.p->logTcConrec;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- readCommitLog(signal, &commitLogRecord);
- if (tcConnectptr.p->gci > crestartNewestGci) {
- jam();
- /*---------------------------------------------------------------------------*/
- /* THIS LOG RECORD MUST BE IGNORED. IT IS PART OF A GLOBAL CHECKPOINT WHICH */
- /* WILL BE INVALIDATED BY THE SYSTEM RESTART. IF NOT INVALIDATED IT MIGHT BE */
- /* EXECUTED IN A FUTURE SYSTEM RESTART. */
- /*---------------------------------------------------------------------------*/
- tmpLogPagePtr.i = logPartPtr.p->prevLogpage;
- ptrCheckGuard(tmpLogPagePtr, clogPageFileSize, logPageRecord);
- arrGuard(logPartPtr.p->savePageIndex, ZPAGE_SIZE);
- tmpLogPagePtr.p->logPageWord[logPartPtr.p->savePageIndex] =
- ZINVALID_COMMIT_TYPE;
- tmpLogPagePtr.p->logPageWord[ZPOS_DIRTY] = ZDIRTY;
- } else {
- jam();
- /*---------------------------------------------------------------------------*/
- /* CHECK IF I AM SUPPOSED TO EXECUTE THIS LOG RECORD. IF I AM THEN SAVE PAGE */
- /* INDEX IN CURRENT LOG PAGE SINCE IT WILL BE OVERWRITTEN WHEN EXECUTING THE */
- /* LOG RECORD. */
- /*---------------------------------------------------------------------------*/
- logPartPtr.p->execSrExecuteIndex = 0;
- Uint32 result = checkIfExecLog(signal);
- if (result == ZOK) {
- jam();
- //*---------------------------------------------------------------------------*/
- /* IN A NODE RESTART WE WILL NEVER END UP HERE SINCE NO FRAGMENTS HAVE BEEN */
- /* DEFINED YET. THUS NO EXTRA CHECKING FOR NODE RESTART IS NECESSARY. */
- /*---------------------------------------------------------------------------*/
- logPartPtr.p->savePageIndex =
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- tcConnectptr.p->fragmentptr = fragptr.i;
- findPageRef(signal, &commitLogRecord);
- logPartPtr.p->execSrLogPageIndex = commitLogRecord.startPageIndex;
- if (logPagePtr.i != RNIL) {
- jam();
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = commitLogRecord.startPageIndex;
- logPartPtr.p->execSrLogPage = logPagePtr.i;
- execLogRecord(signal);
- return;
- }//if
- logPartPtr.p->execSrStartPageNo = commitLogRecord.startPageNo;
- logPartPtr.p->execSrStopPageNo = commitLogRecord.stopPageNo;
- findLogfile(signal, commitLogRecord.fileNo, logPartPtr, &logFilePtr);
- logPartPtr.p->execSrExecLogFile = logFilePtr.i;
- if (logFilePtr.i == logPartPtr.p->currentLogfile) {
- jam();
- readExecLog(signal);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_EXEC_LOG;
- return;
- } else {
- jam();
- /*---------------------------------------------------------------------------*/
- /* THE FILE IS CURRENTLY NOT OPEN. WE MUST OPEN IT BEFORE WE CAN READ FROM */
- /* THE FILE. */
- /*---------------------------------------------------------------------------*/
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN_EXEC_LOG;
- openFileRw(signal, logFilePtr);
- return;
- }//if
- }//if
- }//if
- break;
- }
- /* ========================================================================= */
- /* ========================================================================= */
- case ZABORT_TYPE:
- jam();
- stepAhead(signal, ZABORT_LOG_SIZE - 1);
- break;
- /* ========================================================================= */
- /* ========================================================================= */
- case ZFD_TYPE:
- jam();
- /*---------------------------------------------------------------------------*/
- /* THIS IS THE FIRST ITEM WE ENCOUNTER IN A NEW FILE. AT THIS MOMENT WE SHALL*/
- /* SIMPLY BYPASS IT. IT HAS NO SIGNIFANCE WHEN EXECUTING THE LOG. IT HAS ITS */
- /* SIGNIFANCE WHEN FINDING THE START END THE END OF THE LOG. */
- /* WE HARDCODE THE PAGE INDEX SINCE THIS SHOULD NEVER BE FOUND AT ANY OTHER */
- /* PLACE THAN IN THE FIRST PAGE OF A NEW FILE IN THE FIRST POSITION AFTER THE*/
- /* HEADER. */
- /*---------------------------------------------------------------------------*/
- ndbrequire(logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] ==
- (ZPAGE_HEADER_SIZE + ZPOS_NO_FD));
- {
- Uint32 noFdDescriptors =
- logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_NO_FD];
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] =
- (ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE) +
- (noFdDescriptors * ZFD_PART_SIZE);
- }
- break;
- /* ========================================================================= */
- /* ========================================================================= */
- case ZNEXT_LOG_RECORD_TYPE:
- jam();
- stepAhead(signal, ZPAGE_SIZE - logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX]);
- break;
- /* ========================================================================= */
- /* ========================================================================= */
- case ZNEXT_MBYTE_TYPE:
- /*---------------------------------------------------------------------------*/
- /* WE WILL SKIP A PART OF THE LOG FILE. ACTUALLY THE NEXT POINTER IS TO */
- /* A NEW MBYTE. THEREFORE WE WILL START UP A NEW MBYTE. THIS NEW MBYTE IS */
- /* HOWEVER ONLY STARTED IF IT IS NOT AFTER THE STOP MBYTE. */
- /* IF WE HAVE REACHED THE END OF THE STOP MBYTE THEN THE EXECUTION OF THE LOG*/
- /* IS COMPLETED. */
- /*---------------------------------------------------------------------------*/
- if (logPartPtr.p->currentLogfile == logPartPtr.p->stopLogfile) {
- if (logFilePtr.p->currentMbyte == logPartPtr.p->stopMbyte) {
- jam();
- /*---------------------------------------------------------------------------*/
- /* THIS WAS THE LAST MBYTE TO EXECUTE IN THIS LOG PART. WE SHOULD HAVE FOUND */
- /* A COMPLETED GCI RECORD OF THE LAST GCI BEFORE THIS. FOR SOME REASON THIS */
- /* RECORD WAS NOT AVAILABLE ON THE LOG. CRASH THE SYSTEM, A VERY SERIOUS */
- /* ERROR WHICH WE MUST REALLY WORK HARD TO AVOID. */
- /*---------------------------------------------------------------------------*/
- /*---------------------------------------------------------------------------*/
- /* SEND A SIGNAL TO THE SIGNAL LOG AND THEN CRASH THE SYSTEM. */
- /*---------------------------------------------------------------------------*/
- signal->theData[0] = RNIL;
- signal->theData[1] = logPartPtr.i;
- Uint32 tmp = logFilePtr.p->fileName[3];
- tmp = (tmp >> 8) & 0xff;// To get the Directory, DXX.
- signal->theData[2] = tmp;
- signal->theData[3] = logFilePtr.p->fileNo;
- signal->theData[4] = logFilePtr.p->currentFilepage;
- signal->theData[5] = logFilePtr.p->currentMbyte;
- signal->theData[6] = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- sendSignal(cownref, GSN_DEBUG_SIG, signal, 7, JBA);
- return;
- }//if
- }//if
- /*---------------------------------------------------------------------------*/
- /* START EXECUTION OF A NEW MBYTE IN THE LOG. */
- /*---------------------------------------------------------------------------*/
- if (logFilePtr.p->currentMbyte < (ZNO_MBYTES_IN_FILE - 1)) {
- jam();
- logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOG_NEW_MBYTE;
- } else {
- ndbrequire(logFilePtr.p->currentMbyte == (ZNO_MBYTES_IN_FILE - 1));
- jam();
- /*---------------------------------------------------------------------------*/
- /* WE HAVE TO CHANGE FILE. CLOSE THIS ONE AND THEN OPEN THE NEXT. */
- /*---------------------------------------------------------------------------*/
- logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOG_NEW_FILE;
- }//if
- break;
- /* ========================================================================= */
- /* ========================================================================= */
- case ZCOMPLETED_GCI_TYPE:
- jam();
- logWord = readLogword(signal);
- if (logWord == logPartPtr.p->logLastGci) {
- jam();
- /*---------------------------------------------------------------------------*/
- /* IF IT IS THE LAST GCI TO LIVE AFTER SYSTEM RESTART THEN WE RECORD THE NEXT*/
- /* WORD AS THE NEW HEADER OF THE LOG FILE. OTHERWISE WE SIMPLY IGNORE THIS */
- /* LOG RECORD. */
- /*---------------------------------------------------------------------------*/
- if (csrPhasesCompleted == 0) {
- jam();
- /*---------------------------------------------------------------------------*/
- /*WE ONLY RECORD THE HEAD OF THE LOG IN THE FIRST LOG ROUND OF LOG EXECUTION.*/
- /*---------------------------------------------------------------------------*/
- logPartPtr.p->headFileNo = logFilePtr.p->fileNo;
- logPartPtr.p->headPageNo = logFilePtr.p->currentFilepage;
- logPartPtr.p->headPageIndex =
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- }//if
- /*---------------------------------------------------------------------------*/
- /* THERE IS NO NEED OF EXECUTING PAST THIS LINE SINCE THERE WILL ONLY BE LOG */
- /* RECORDS THAT WILL BE OF NO INTEREST. THUS CLOSE THE FILE AND START THE */
- /* NEXT PHASE OF THE SYSTEM RESTART. */
- /*---------------------------------------------------------------------------*/
- logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOG_COMPLETED;
- }//if
- break;
- default:
- jam();
- /* ========================================================================= */
- /* ========================================================================= */
- /*---------------------------------------------------------------------------*/
- /* SEND A SIGNAL TO THE SIGNAL LOG AND THEN CRASH THE SYSTEM. */
- /*---------------------------------------------------------------------------*/
- signal->theData[0] = RNIL;
- signal->theData[1] = logPartPtr.i;
- Uint32 tmp = logFilePtr.p->fileName[3];
- tmp = (tmp >> 8) & 0xff;// To get the Directory, DXX.
- signal->theData[2] = tmp;
- signal->theData[3] = logFilePtr.p->fileNo;
- signal->theData[4] = logFilePtr.p->currentMbyte;
- signal->theData[5] = logFilePtr.p->currentFilepage;
- signal->theData[6] = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- signal->theData[7] = logWord;
- sendSignal(cownref, GSN_DEBUG_SIG, signal, 8, JBA);
- return;
- break;
- }//switch
- /*---------------------------------------------------------------------------*/
- // We continue to execute log records until we find a proper one to execute or
- // that we reach a new page.
- /*---------------------------------------------------------------------------*/
- } while (1);
- }//Dblqh::execSr()
- /*---------------------------------------------------------------------------*/
- /* THIS SIGNAL IS ONLY RECEIVED TO BE CAPTURED IN THE SIGNAL LOG. IT IS */
- /* ALSO USED TO CRASH THE SYSTEM AFTER SENDING A SIGNAL TO THE LOG. */
- /*---------------------------------------------------------------------------*/
- void Dblqh::execDEBUG_SIG(Signal* signal)
- {
- /*
- 2.5 TEMPORARY VARIABLES
- -----------------------
- */
- UintR tdebug;
- jamEntry();
- logPagePtr.i = signal->theData[0];
- tdebug = logPagePtr.p->logPageWord[0];
- char buf[100];
- BaseString::snprintf(buf, 100,
- "Error while reading REDO log.n"
- "D=%d, F=%d Mb=%d FP=%d W1=%d W2=%d",
- signal->theData[2], signal->theData[3], signal->theData[4],
- signal->theData[5], signal->theData[6], signal->theData[7]);
- progError(__LINE__, ERR_SR_REDOLOG, buf);
- return;
- }//Dblqh::execDEBUG_SIG()
- /*---------------------------------------------------------------------------*/
- /*---------------------------------------------------------------------------*/
- void Dblqh::closeExecLogLab(Signal* signal)
- {
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
- signal->theData[0] = ZEXEC_SR;
- signal->theData[1] = logFilePtr.p->logPartRec;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
- }//Dblqh::closeExecLogLab()
- void Dblqh::openExecLogLab(Signal* signal)
- {
- readExecLog(signal);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_EXEC_LOG;
- return;
- }//Dblqh::openExecLogLab()
- void Dblqh::readExecLogLab(Signal* signal)
- {
- buildLinkedLogPageList(signal);
- logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOGREC_FROM_FILE;
- logPartPtr.p->execSrLfoRec = lfoPtr.i;
- logPartPtr.p->execSrLogPage = logPagePtr.i;
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] =
- logPartPtr.p->execSrLogPageIndex;
- execLogRecord(signal);
- return;
- }//Dblqh::readExecLogLab()
- /*---------------------------------------------------------------------------*/
- /* THIS CODE IS USED TO EXECUTE A LOG RECORD WHEN IT'S DATA HAVE BEEN LOCATED*/
- /* AND TRANSFERRED INTO MEMORY. */
- /*---------------------------------------------------------------------------*/
- void Dblqh::execLogRecord(Signal* signal)
- {
- jamEntry();
- tcConnectptr.i = logPartPtr.p->logTcConrec;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- fragptr.i = tcConnectptr.p->fragmentptr;
- ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
- // Read a log record and prepare it for execution
- readLogHeader(signal);
- readKey(signal);
- readAttrinfo(signal);
- initReqinfoExecSr(signal);
- arrGuard(logPartPtr.p->execSrExecuteIndex, 4);
- BlockReference ref = fragptr.p->execSrBlockref[logPartPtr.p->execSrExecuteIndex];
- tcConnectptr.p->nextReplica = refToNode(ref);
- tcConnectptr.p->connectState = TcConnectionrec::LOG_CONNECTED;
- tcConnectptr.p->tcOprec = tcConnectptr.i;
- packLqhkeyreqLab(signal);
- return;
- }//Dblqh::execLogRecord()
- //----------------------------------------------------------------------------
- // This function invalidates log pages after the last GCI record in a
- // system/node restart. This is to ensure that the end of the log is
- // consistent. This function is executed last in start phase 3.
- // RT 450. EDTJAMO.
- //----------------------------------------------------------------------------
- void Dblqh::invalidateLogAfterLastGCI(Signal* signal) {
-
- jam();
- if (logPartPtr.p->logExecState != LogPartRecord::LES_EXEC_LOG_INVALIDATE) {
- jam();
- systemError(signal);
- }
- if (logFilePtr.p->fileNo != logPartPtr.p->invalidateFileNo) {
- jam();
- systemError(signal);
- }
- switch (lfoPtr.p->lfoState) {
- case LogFileOperationRecord::WRITE_SR_INVALIDATE_PAGES:
- jam();
- releaseLfo(signal);
- releaseLogpage(signal);
- if (logPartPtr.p->invalidatePageNo < (ZNO_MBYTES_IN_FILE * ZPAGES_IN_MBYTE - 1)) {
- // We continue in this file.
- logPartPtr.p->invalidatePageNo++;
- } else {
- // We continue in the next file.
- logFilePtr.i = logFilePtr.p->nextLogFile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPartPtr.p->invalidateFileNo = logFilePtr.p->fileNo;
- // Page 0 is used for file descriptors.
- logPartPtr.p->invalidatePageNo = 1;
- if (logFilePtr.p->logFileStatus != LogFileRecord::OPEN) {
- jam();
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_INVALIDATE_PAGES;
- openFileRw(signal, logFilePtr);
- return;
- break;
- }
- }
- // Read a page from the log file.
- readFileInInvalidate(signal);
- return;
- break;
- case LogFileOperationRecord::READ_SR_INVALIDATE_PAGES:
- jam();
- releaseLfo(signal);
- // Check if this page must be invalidated.
- // If the log lap number on a page after the head of the tail is the same
- // as the actual log lap number we must invalidate this page. Otherwise it
- // could be impossible to find the end of the log in a later system/node
- // restart.
- if (logPagePtr.p->logPageWord[ZPOS_LOG_LAP] == logPartPtr.p->logLap) {
- // This page must be invalidated.
- logPagePtr.p->logPageWord[ZPOS_LOG_LAP] = 0;
- // Contact NDBFS. Real time break.
- writeSinglePage(signal, logPartPtr.p->invalidatePageNo,
- ZPAGE_SIZE - 1, __LINE__);
- lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_SR_INVALIDATE_PAGES;
- } else {
- // We are done with invalidating. Finish start phase 3.4.
- exitFromInvalidate(signal);
- }
- return;
- break;
- default:
- jam();
- systemError(signal);
- return;
- break;
- }
- return;
- }//Dblqh::invalidateLogAfterLastGCI
- void Dblqh::readFileInInvalidate(Signal* signal) {
- jam();
- // Contact NDBFS. Real time break.
- readSinglePage(signal, logPartPtr.p->invalidatePageNo);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_INVALIDATE_PAGES;
- }
- void Dblqh::exitFromInvalidate(Signal* signal) {
- jam();
- // Close files if necessary. Current file and the next file should be
- // left open.
- if (logFilePtr.i != logPartPtr.p->currentLogfile) {
- LogFileRecordPtr currentLogFilePtr;
- LogFileRecordPtr nextAfterCurrentLogFilePtr;
- currentLogFilePtr.i = logPartPtr.p->currentLogfile;
- ptrCheckGuard(currentLogFilePtr, clogFileFileSize, logFileRecord);
- nextAfterCurrentLogFilePtr.i = currentLogFilePtr.p->nextLogFile;
- if (logFilePtr.i != nextAfterCurrentLogFilePtr.i) {
- // This file should be closed.
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSE_SR_INVALIDATE_PAGES;
- closeFile(signal, logFilePtr);
- // Return from this function and wait for close confirm. Then come back
- // and test the previous file for closing.
- return;
- }
- }
- // We are done with closing files, send completed signal and exit this phase.
- signal->theData[0] = ZSR_FOURTH_COMP;
- signal->theData[1] = logPartPtr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
- }
- /*---------------------------------------------------------------------------*/
- /* THE EXECUTION OF A LOG RECORD IS COMPLETED. RELEASE PAGES IF THEY WERE */
- /* READ FROM DISK FOR THIS PARTICULAR OPERATION. */
- /*---------------------------------------------------------------------------*/
- void Dblqh::completedLab(Signal* signal)
- {
- Uint32 result = returnExecLog(signal);
- /*---------------------------------------------------------------------------*/
- /* ENTER COMPLETED WITH */
- /* LQH_CONNECTPTR */
- /*---------------------------------------------------------------------------*/
- if (result == ZOK) {
- jam();
- execLogRecord(signal);
- return;
- } else if (result == ZNOT_OK) {
- jam();
- signal->theData[0] = ZEXEC_SR;
- signal->theData[1] = logPartPtr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- } else {
- jam();
- /*empty*/;
- }//if
- /*---------------------------------------------------------------------------*/
- /* WE HAVE TO WAIT FOR CLOSING OF THE EXECUTED LOG FILE BEFORE PROCEEDING IN */
- /* RARE CASES. */
- /*---------------------------------------------------------------------------*/
- return;
- }//Dblqh::completedLab()
- /*---------------------------------------------------------------------------*/
- /* EXECUTION OF LOG RECORD WAS NOT SUCCESSFUL. CHECK IF IT IS OK ANYWAY, */
- /* THEN EXECUTE THE NEXT LOG RECORD. */
- /*---------------------------------------------------------------------------*/
- void Dblqh::logLqhkeyrefLab(Signal* signal)
- {
- Uint32 result = returnExecLog(signal);
- switch (tcConnectptr.p->operation) {
- case ZUPDATE:
- case ZDELETE:
- jam();
- ndbrequire(terrorCode == ZNO_TUPLE_FOUND);
- break;
- case ZINSERT:
- jam();
- ndbrequire(terrorCode == ZTUPLE_ALREADY_EXIST);
- break;
- default:
- ndbrequire(false);
- return;
- break;
- }//switch
- if (result == ZOK) {
- jam();
- execLogRecord(signal);
- return;
- } else if (result == ZNOT_OK) {
- jam();
- signal->theData[0] = ZEXEC_SR;
- signal->theData[1] = logPartPtr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- } else {
- jam();
- /*empty*/;
- }//if
- /* ------------------------------------------------------------------------
- * WE HAVE TO WAIT FOR CLOSING OF THE EXECUTED LOG FILE BEFORE
- * PROCEEDING IN RARE CASES.
- * ----------------------------------------------------------------------- */
- return;
- }//Dblqh::logLqhkeyrefLab()
- void Dblqh::closeExecSrCompletedLab(Signal* signal)
- {
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
- signal->theData[0] = logFilePtr.p->logPartRec;
- execLogComp(signal);
- return;
- }//Dblqh::closeExecSrCompletedLab()
- /* --------------------------------------------------------------------------
- * ONE OF THE LOG PARTS HAVE COMPLETED EXECUTING THE LOG. CHECK IF ALL LOG
- * PARTS ARE COMPLETED. IF SO START SENDING EXEC_FRAGCONF AND EXEC_SRCONF.
- * ------------------------------------------------------------------------- */
- void Dblqh::execLogComp(Signal* signal)
- {
- logPartPtr.i = signal->theData[0];
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- logPartPtr.p->logPartState = LogPartRecord::SR_THIRD_PHASE_COMPLETED;
- /* ------------------------------------------------------------------------
- * WE MUST RELEASE THE TC CONNECT RECORD HERE SO THAT IT CAN BE REUSED.
- * ----------------------------------------------------------------------- */
- tcConnectptr.i = logPartPtr.p->logTcConrec;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- releaseTcrecLog(signal, tcConnectptr);
- for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
- jam();
- ptrAss(logPartPtr, logPartRecord);
- if (logPartPtr.p->logPartState != LogPartRecord::SR_THIRD_PHASE_COMPLETED) {
- if (logPartPtr.p->logPartState != LogPartRecord::SR_THIRD_PHASE_STARTED) {
- jam();
- systemErrorLab(signal);
- return;
- } else {
- jam();
- /* ------------------------------------------------------------------
- * THIS LOG PART WAS NOT COMPLETED YET. EXIT AND WAIT FOR IT
- * TO COMPLETE
- * ----------------------------------------------------------------- */
- return;
- }//if
- }//if
- }//for
- /* ------------------------------------------------------------------------
- * ALL LOG PARTS HAVE COMPLETED THE EXECUTION OF THE LOG. WE CAN NOW START
- * SENDING THE EXEC_FRAGCONF SIGNALS TO ALL INVOLVED FRAGMENTS.
- * ----------------------------------------------------------------------- */
- if (cstartType != NodeState::ST_NODE_RESTART) {
- jam();
- signal->theData[0] = ZSEND_EXEC_CONF;
- signal->theData[1] = 0;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- } else {
- jam();
- /* ----------------------------------------------------------------------
- * FOR NODE RESTART WE CAN SKIP A NUMBER OF STEPS SINCE WE HAVE NO
- * FRAGMENTS DEFINED AT THIS POINT. OBVIOUSLY WE WILL NOT NEED TO
- * EXECUTE ANY MORE LOG STEPS EITHER AND THUS WE CAN IMMEDIATELY
- * START FINDING THE END AND THE START OF THE LOG.
- * --------------------------------------------------------------------- */
- csrPhasesCompleted = 3;
- execSrCompletedLab(signal);
- return;
- }//if
- return;
- }//Dblqh::execLogComp()
- /* --------------------------------------------------------------------------
- * GO THROUGH THE FRAGMENT RECORDS TO DEDUCE TO WHICH SHALL BE SENT
- * EXEC_FRAGCONF AFTER COMPLETING THE EXECUTION OF THE LOG.
- * ------------------------------------------------------------------------- */
- void Dblqh::sendExecConf(Signal* signal)
- {
- jamEntry();
- fragptr.i = signal->theData[0];
- Uint32 loopCount = 0;
- while (fragptr.i < cfragrecFileSize) {
- ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
- if (fragptr.p->execSrStatus != Fragrecord::IDLE) {
- jam();
- ndbrequire(fragptr.p->execSrNoReplicas - 1 < 4);
- for (Uint32 i = 0; i < fragptr.p->execSrNoReplicas; i++) {
- jam();
- signal->theData[0] = fragptr.p->execSrUserptr[i];
- sendSignal(fragptr.p->execSrBlockref[i], GSN_EXEC_FRAGCONF,
- signal, 1, JBB);
- }//for
- if (fragptr.p->execSrStatus == Fragrecord::ACTIVE) {
- jam();
- fragptr.p->execSrStatus = Fragrecord::IDLE;
- } else {
- ndbrequire(fragptr.p->execSrStatus == Fragrecord::ACTIVE_REMOVE_AFTER);
- jam();
- Uint32 fragId = fragptr.p->fragId;
- tabptr.i = fragptr.p->tabRef;
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
- deleteFragrec(fragId);
- }//if
- fragptr.p->execSrNoReplicas = 0;
- }//if
- loopCount++;
- if (loopCount > 20) {
- jam();
- signal->theData[0] = ZSEND_EXEC_CONF;
- signal->theData[1] = fragptr.i + 1;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
- } else {
- jam();
- fragptr.i++;
- }//if
- }//while
- /* ----------------------------------------------------------------------
- * WE HAVE NOW SENT ALL EXEC_FRAGCONF. NOW IT IS TIME TO SEND
- * EXEC_SRCONF TO ALL NODES.
- * --------------------------------------------------------------------- */
- srPhase3Comp(signal);
- }//Dblqh::sendExecConf()
- /* --------------------------------------------------------------------------
- * PHASE 3 HAS NOW COMPLETED. INFORM ALL OTHER NODES OF THIS EVENT.
- * ------------------------------------------------------------------------- */
- void Dblqh::srPhase3Comp(Signal* signal)
- {
- jamEntry();
- ndbrequire(cnoOfNodes < MAX_NDB_NODES);
- for (Uint32 i = 0; i < cnoOfNodes; i++) {
- jam();
- if (cnodeStatus[i] == ZNODE_UP) {
- jam();
- ndbrequire(cnodeData[i] < MAX_NDB_NODES);
- BlockReference ref = calcLqhBlockRef(cnodeData[i]);
- signal->theData[0] = cownNodeid;
- sendSignal(ref, GSN_EXEC_SRCONF, signal, 1, JBB);
- }//if
- }//for
- return;
- }//Dblqh::srPhase3Comp()
- /* ##########################################################################
- * SYSTEM RESTART PHASE FOUR MODULE
- * THIS MODULE IS A SUB-MODULE OF THE FILE SYSTEM HANDLING.
- *
- * THIS MODULE SETS UP THE HEAD AND TAIL POINTERS OF THE LOG PARTS IN THE
- * FRAGMENT LOG. WHEN IT IS COMPLETED IT REPORTS TO THE MASTER DIH THAT
- * IT HAS COMPLETED THE PART OF THE SYSTEM RESTART WHERE THE DATABASE IS
- * LOADED.
- * IT ALSO OPENS THE CURRENT LOG FILE AND THE NEXT AND SETS UP THE FIRST
- * LOG PAGE WHERE NEW LOG DATA IS TO BE INSERTED WHEN THE SYSTEM STARTS
- * AGAIN.
- *
- * THIS PART IS ACTUALLY EXECUTED FOR ALL RESTART TYPES.
- * ######################################################################### */
- void Dblqh::initFourth(Signal* signal)
- {
- LogFileRecordPtr locLogFilePtr;
- jamEntry();
- logPartPtr.i = signal->theData[0];
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- crestartNewestGci = 1;
- crestartOldestGci = 1;
- /* ------------------------------------------------------------------------
- * INITIALISE LOG PART AND LOG FILES AS NEEDED.
- * ----------------------------------------------------------------------- */
- logPartPtr.p->headFileNo = 0;
- logPartPtr.p->headPageNo = 1;
- logPartPtr.p->headPageIndex = ZPAGE_HEADER_SIZE + 2;
- logPartPtr.p->logPartState = LogPartRecord::SR_FOURTH_PHASE_STARTED;
- logPartPtr.p->logTailFileNo = 0;
- logPartPtr.p->logTailMbyte = 0;
- locLogFilePtr.i = logPartPtr.p->firstLogfile;
- ptrCheckGuard(locLogFilePtr, clogFileFileSize, logFileRecord);
- locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_FOURTH_PHASE;
- openFileRw(signal, locLogFilePtr);
- return;
- }//Dblqh::initFourth()
- void Dblqh::openSrFourthPhaseLab(Signal* signal)
- {
- /* ------------------------------------------------------------------------
- * WE HAVE NOW OPENED THE HEAD LOG FILE WE WILL NOW START READING IT
- * FROM THE HEAD MBYTE TO FIND THE NEW HEAD OF THE LOG.
- * ----------------------------------------------------------------------- */
- readSinglePage(signal, logPartPtr.p->headPageNo);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_FOURTH_PHASE;
- return;
- }//Dblqh::openSrFourthPhaseLab()
- void Dblqh::readSrFourthPhaseLab(Signal* signal)
- {
- if(c_diskless){
- jam();
- logPagePtr.p->logPageWord[ZPOS_LOG_LAP] = 1;
- }
- /* ------------------------------------------------------------------------
- * INITIALISE ALL LOG PART INFO AND LOG FILE INFO THAT IS NEEDED TO
- * START UP THE SYSTEM.
- * ------------------------------------------------------------------------
- * INITIALISE THE NEWEST GLOBAL CHECKPOINT IDENTITY AND THE NEWEST
- * COMPLETED GLOBAL CHECKPOINT IDENITY AS THE NEWEST THAT WAS RESTARTED.
- * ------------------------------------------------------------------------
- * INITIALISE THE HEAD PAGE INDEX IN THIS PAGE.
- * ASSIGN IT AS THE CURRENT LOGPAGE.
- * ASSIGN THE FILE AS THE CURRENT LOG FILE.
- * ASSIGN THE CURRENT FILE NUMBER FROM THE CURRENT LOG FILE AND THE NEXT
- * FILE NUMBER FROM THE NEXT LOG FILE.
- * ASSIGN THE CURRENT FILEPAGE FROM HEAD PAGE NUMBER.
- * ASSIGN THE CURRENT MBYTE BY DIVIDING PAGE NUMBER BY 128.
- * INITIALISE LOG LAP TO BE THE LOG LAP AS FOUND IN THE HEAD PAGE.
- * WE HAVE TO CALCULATE THE NUMBER OF REMAINING WORDS IN THIS MBYTE.
- * ----------------------------------------------------------------------- */
- cnewestGci = crestartNewestGci;
- cnewestCompletedGci = crestartNewestGci;
- logPartPtr.p->logPartNewestCompletedGCI = cnewestCompletedGci;
- logPartPtr.p->currentLogfile = logFilePtr.i;
- logFilePtr.p->filePosition = logPartPtr.p->headPageNo;
- logFilePtr.p->currentMbyte =
- logPartPtr.p->headPageNo >> ZTWOLOG_NO_PAGES_IN_MBYTE;
- logFilePtr.p->fileChangeState = LogFileRecord::NOT_ONGOING;
- logPartPtr.p->logLap = logPagePtr.p->logPageWord[ZPOS_LOG_LAP];
- logFilePtr.p->currentFilepage = logPartPtr.p->headPageNo;
- logFilePtr.p->currentLogpage = logPagePtr.i;
- initLogpage(signal);
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = logPartPtr.p->headPageIndex;
- logFilePtr.p->remainingWordsInMbyte =
- ((
- ((logFilePtr.p->currentMbyte + 1) * ZPAGES_IN_MBYTE) -
- logFilePtr.p->currentFilepage) *
- (ZPAGE_SIZE - ZPAGE_HEADER_SIZE)) -
- (logPartPtr.p->headPageIndex - ZPAGE_HEADER_SIZE);
- /* ------------------------------------------------------------------------
- * THE NEXT STEP IS TO OPEN THE NEXT LOG FILE (IF THERE IS ONE).
- * ----------------------------------------------------------------------- */
- if (logFilePtr.p->nextLogFile != logFilePtr.i) {
- LogFileRecordPtr locLogFilePtr;
- jam();
- locLogFilePtr.i = logFilePtr.p->nextLogFile;
- ptrCheckGuard(locLogFilePtr, clogFileFileSize, logFileRecord);
- locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_FOURTH_NEXT;
- openFileRw(signal, locLogFilePtr);
- } else {
- jam();
- /* ----------------------------------------------------------------------
- * THIS CAN ONLY OCCUR IF WE HAVE ONLY ONE LOG FILE. THIS LOG FILE MUST
- * BE LOG FILE ZERO AND THAT IS THE FILE WE CURRENTLY HAVE READ.
- * THUS WE CAN CONTINUE IMMEDIATELY TO READ PAGE ZERO IN FILE ZERO.
- * --------------------------------------------------------------------- */
- openSrFourthZeroSkipInitLab(signal);
- return;
- }//if
- return;
- }//Dblqh::readSrFourthPhaseLab()
- void Dblqh::openSrFourthNextLab(Signal* signal)
- {
- /* ------------------------------------------------------------------------
- * WE MUST ALSO HAVE FILE 0 OPEN ALL THE TIME.
- * ----------------------------------------------------------------------- */
- logFilePtr.i = logPartPtr.p->firstLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- if (logFilePtr.p->logFileStatus == LogFileRecord::OPEN) {
- jam();
- openSrFourthZeroSkipInitLab(signal);
- return;
- } else {
- jam();
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_FOURTH_ZERO;
- openFileRw(signal, logFilePtr);
- }//if
- return;
- }//Dblqh::openSrFourthNextLab()
- void Dblqh::openSrFourthZeroLab(Signal* signal)
- {
- openSrFourthZeroSkipInitLab(signal);
- return;
- }//Dblqh::openSrFourthZeroLab()
- void Dblqh::openSrFourthZeroSkipInitLab(Signal* signal)
- {
- if (logFilePtr.i == logPartPtr.p->currentLogfile) {
- if (logFilePtr.p->currentFilepage == 0) {
- jam();
- /* -------------------------------------------------------------------
- * THE HEADER PAGE IN THE LOG IS PAGE ZERO IN FILE ZERO.
- * THIS SHOULD NEVER OCCUR.
- * ------------------------------------------------------------------- */
- systemErrorLab(signal);
- return;
- }//if
- }//if
- readSinglePage(signal, 0);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_FOURTH_ZERO;
- return;
- }//Dblqh::openSrFourthZeroSkipInitLab()
- void Dblqh::readSrFourthZeroLab(Signal* signal)
- {
- logFilePtr.p->logPageZero = logPagePtr.i;
- // --------------------------------------------------------------------
- // This is moved to invalidateLogAfterLastGCI(), RT453.
- // signal->theData[0] = ZSR_FOURTH_COMP;
- // signal->theData[1] = logPartPtr.i;
- // sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- // --------------------------------------------------------------------
-
- // Need to invalidate log pages after the head of the log. RT 453. EDTJAMO.
- // Set the start of the invalidation.
- logFilePtr.i = logPartPtr.p->currentLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPartPtr.p->invalidateFileNo = logPartPtr.p->headFileNo;
- logPartPtr.p->invalidatePageNo = logPartPtr.p->headPageNo;
-
- logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOG_INVALIDATE;
- seizeLfo(signal);
- initLfo(signal);
- // The state here is a little confusing, but simulates that we return
- // to invalidateLogAfterLastGCI() from an invalidate write and are ready
- // to read a page from file.
- lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_SR_INVALIDATE_PAGES;
- invalidateLogAfterLastGCI(signal);
- return;
- }//Dblqh::readSrFourthZeroLab()
- /* --------------------------------------------------------------------------
- * ONE OF THE LOG PARTS HAVE COMPLETED PHASE FOUR OF THE SYSTEM RESTART.
- * CHECK IF ALL LOG PARTS ARE COMPLETED. IF SO SEND START_RECCONF
- * ------------------------------------------------------------------------- */
- void Dblqh::srFourthComp(Signal* signal)
- {
- jamEntry();
- logPartPtr.i = signal->theData[0];
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- logPartPtr.p->logPartState = LogPartRecord::SR_FOURTH_PHASE_COMPLETED;
- for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
- jam();
- ptrAss(logPartPtr, logPartRecord);
- if (logPartPtr.p->logPartState != LogPartRecord::SR_FOURTH_PHASE_COMPLETED) {