DbtupSystemRestart.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:39k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #define DBTUP_C
  14. #include "Dbtup.hpp"
  15. #include <RefConvert.hpp>
  16. #include <ndb_limits.h>
  17. #include <pc.hpp>
  18. #include <signaldata/EventReport.hpp>
  19. #include <signaldata/FsConf.hpp>
  20. #include <signaldata/FsRef.hpp>
  21. #define ljam() { jamLine(26000 + __LINE__); }
  22. #define ljamEntry() { jamEntryLine(26000 + __LINE__); }
  23. /* **************************************************************** */
  24. /* ********************* SYSTEM RESTART MANAGER ******************* */
  25. /* **************************************************************** */
  26. /***************************************************************/
  27. /* CHECK RESTART STATE AND SET NEW STATE CALLED IN OPEN,       */
  28. /* READ AND COPY STATES                                        */
  29. /***************************************************************/
  30. void Dbtup::execTUP_SRREQ(Signal* signal) 
  31. {
  32.   RestartInfoRecordPtr riPtr;
  33.   PendingFileOpenInfoPtr pfoiPtr;
  34.   ljamEntry();
  35.   Uint32 userPtr = signal->theData[0];
  36.   Uint32 userBlockref = signal->theData[1];
  37.   Uint32 tableId = signal->theData[2];
  38.   Uint32 fragId = signal->theData[3];
  39.   Uint32 checkpointNumber = signal->theData[4];
  40.   seizeRestartInfoRecord(riPtr);
  41.   riPtr.p->sriUserptr = userPtr;
  42.   riPtr.p->sriBlockref = userBlockref;
  43.   riPtr.p->sriState = OPENING_DATA_FILE;
  44.   riPtr.p->sriCheckpointVersion = checkpointNumber;
  45.   riPtr.p->sriFragid = fragId;
  46.   riPtr.p->sriTableId = tableId;
  47.    /* OPEN THE DATA FILE IN THE FOLLOWING FORM              */
  48.    /* D5/DBTUP/T<TABID>/F<FRAGID>/S<CHECKPOINT_NUMBER>.DATA */
  49.   Uint32 fileType = 1;                 /* VERSION                       */
  50.   fileType = (fileType << 8) | 0; /* .DATA                         */
  51.   fileType = (fileType << 8) | 5; /* D5                            */
  52.   fileType = (fileType << 8) | 0xff; /* DON'T USE P DIRECTORY LEVEL   */
  53.   Uint32 fileFlag = 0;                 /* READ ONLY                     */
  54.   seizePendingFileOpenInfoRecord(pfoiPtr);
  55.   pfoiPtr.p->pfoOpenType = LCP_DATA_FILE_READ;
  56.   pfoiPtr.p->pfoRestartInfoP = riPtr.i;
  57.   signal->theData[0] = cownref;
  58.   signal->theData[1] = pfoiPtr.i;
  59.   signal->theData[2] = tableId;
  60.   signal->theData[3] = fragId;
  61.   signal->theData[4] = checkpointNumber;
  62.   signal->theData[5] = fileType;
  63.   signal->theData[6] = fileFlag;
  64.   sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
  65.   return;
  66. }//Dbtup::execTUP_SRREQ()
  67. void Dbtup::seizeRestartInfoRecord(RestartInfoRecordPtr& riPtr) 
  68. {
  69.   riPtr.i = cfirstfreeSri;
  70.   ptrCheckGuard(riPtr, cnoOfRestartInfoRec, restartInfoRecord);
  71.   cfirstfreeSri = riPtr.p->sriNextRec;
  72.   riPtr.p->sriNextRec = RNIL;
  73. }//Dbtup::seizeRestartInfoRecord()
  74. void Dbtup::rfrReadRestartInfoLab(Signal* signal, RestartInfoRecordPtr riPtr) 
  75. {
  76.   DiskBufferSegmentInfoPtr dbsiPtr;
  77.   seizeDiskBufferSegmentRecord(dbsiPtr);
  78.   riPtr.p->sriDataBufferSegmentP = dbsiPtr.i;
  79.   Uint32 retPageRef = RNIL;
  80.   Uint32 noAllocPages = 1;
  81.   Uint32 noOfPagesAllocated;
  82.   {
  83.     /**
  84.      * Use low pages for 0-pages during SR
  85.      *   bitmask of free pages is kept in c_sr_free_page_0
  86.      */
  87.     Uint32 tmp = c_sr_free_page_0;
  88.     for(Uint32 i = 1; i<(1+MAX_PARALLELL_TUP_SRREQ); i++){
  89.       if(tmp & (1 << i)){
  90. retPageRef = i;
  91. c_sr_free_page_0 = tmp & (~(1 << i));
  92. break;
  93.       }
  94.     }
  95.     ndbrequire(retPageRef != RNIL);
  96.   }
  97.   
  98.   dbsiPtr.p->pdxDataPage[0] = retPageRef;
  99.   dbsiPtr.p->pdxNumDataPages = 1;
  100.   dbsiPtr.p->pdxFilePage = 0;
  101.   rfrReadNextDataSegment(signal, riPtr, dbsiPtr);
  102.   dbsiPtr.p->pdxOperation = CHECKPOINT_DATA_READ_PAGE_ZERO;
  103. }//Dbtup::rfrReadRestartInfoLab()
  104. /***************************************************************/
  105. /* THE RESTART INFORMATION IS NOW READ INTO THE DATA BUFFER    */
  106. /* USE THE RESTART INFORMATION TO INITIATE THE RESTART RECORD  */
  107. /***************************************************************/
  108. void 
  109. Dbtup::rfrInitRestartInfoLab(Signal* signal, DiskBufferSegmentInfoPtr dbsiPtr) 
  110. {
  111.   Uint32 TzeroDataPage[64];
  112.   Uint32 Ti;
  113.   FragrecordPtr regFragPtr;
  114.   LocalLogInfoPtr lliPtr;
  115.   PagePtr pagePtr;
  116.   RestartInfoRecordPtr riPtr;
  117.   TablerecPtr regTabPtr;
  118.   riPtr.i = dbsiPtr.p->pdxRestartInfoP;
  119.   ptrCheckGuard(riPtr, cnoOfRestartInfoRec, restartInfoRecord);
  120.   
  121.   regTabPtr.i = riPtr.p->sriTableId;
  122.   ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);
  123.   Uint32 fragId = riPtr.p->sriFragid;
  124.   getFragmentrec(regFragPtr, fragId, regTabPtr.p);
  125.   riPtr.p->sriFragP = regFragPtr.i;
  126.   
  127.   /* ----- PAGE ALLOCATION --- */
  128.   /* ALLOCATE PAGES TO FRAGMENT, INSERT THEM INTO PAGE RANGE TABLE AND       */
  129.   /* ALSO CONVERT THEM INTO EMPTY PAGES AND INSERT THEM INTO THE EMPTY LIST  */
  130.   /* OF THE FRAGMENT. SET ALL LISTS OF FREE PAGES TO RNIL                    */
  131.   ndbrequire(cfirstfreerange != RNIL);
  132.   pagePtr.i = dbsiPtr.p->pdxDataPage[0];
  133.   ptrCheckGuard(pagePtr, cnoOfPage, page);
  134.   for (Ti = 0; Ti < 63; Ti++) {
  135.     /***************************************************************/
  136.     // Save Important content from Page zero in stack variable so
  137.     // that we can immediately release page zero.
  138.     /***************************************************************/
  139.     TzeroDataPage[Ti] = pagePtr.p->pageWord[Ti];
  140.   }//for
  141.   /************************************************************************/
  142.   /* NOW WE DON'T NEED THE RESTART INFO BUFFER PAGE ANYMORE               */
  143.   /* LETS REMOVE IT AND REUSE THE SEGMENT FOR REAL DATA PAGES             */
  144.   /* REMOVE ONE PAGE ONLY, PAGEP IS ALREADY SET TO THE RESTART INFO PAGE */
  145.   /************************************************************************/
  146.   {
  147.     ndbrequire(pagePtr.i > 0 && pagePtr.i <= MAX_PARALLELL_TUP_SRREQ);
  148.     c_sr_free_page_0 |= (1 << pagePtr.i);
  149.   }
  150.   Uint32 undoFileVersion = TzeroDataPage[ZSRI_UNDO_FILE_VER];
  151.   lliPtr.i = (undoFileVersion << 2) + (regTabPtr.i & 0x3);
  152.   ptrCheckGuard(lliPtr, cnoOfParallellUndoFiles, localLogInfo);
  153.   riPtr.p->sriLocalLogInfoP = lliPtr.i;
  154.   ndbrequire(regFragPtr.p->fragTableId == regTabPtr.i);
  155.   ndbrequire(regFragPtr.p->fragmentId == fragId);
  156.   
  157.   regFragPtr.p->fragStatus = SYSTEM_RESTART;
  158.   regFragPtr.p->noCopyPagesAlloc = TzeroDataPage[ZSRI_NO_COPY_PAGES_ALLOC];
  159.   riPtr.p->sriCurDataPageFromBuffer = 0;
  160.   riPtr.p->sriNumDataPages = TzeroDataPage[ZSRI_NO_OF_FRAG_PAGES_POS];
  161.   ndbrequire(riPtr.p->sriNumDataPages >= regFragPtr.p->noOfPages);
  162.   const Uint32 pageCount = riPtr.p->sriNumDataPages - regFragPtr.p->noOfPages;
  163.   if(pageCount > 0){
  164.     Uint32 noAllocPages = allocFragPages(regFragPtr.p, pageCount);
  165.     ndbrequire(noAllocPages == pageCount);
  166.   }//if
  167.   ndbrequire(getNoOfPages(regFragPtr.p) == riPtr.p->sriNumDataPages);
  168. /***************************************************************/
  169. // Set the variables on fragment record which might have been
  170. // affected by allocFragPages.
  171. /***************************************************************/
  172.   regFragPtr.p->emptyPrimPage = TzeroDataPage[ZSRI_EMPTY_PRIM_PAGE];
  173.   regFragPtr.p->thFreeFirst = TzeroDataPage[ZSRI_TH_FREE_FIRST];
  174.   regFragPtr.p->thFreeCopyFirst = TzeroDataPage[ZSRI_TH_FREE_COPY_FIRST];
  175. /***************************************************************/
  176. /* THE RESTART INFORMATION IS NOW READ INTO THE DATA BUFFER    */
  177. /* USE THE RESTART INFORMATION TO INITIATE THE FRAGMENT        */
  178. /***************************************************************/
  179.   /**
  180.    * IF THIS UNDO FILE IS NOT OPEN, IT WILL BE OPENED HERE AND THE EXECUTION 
  181.    * WILL CONTINUE WHEN THE FSOPENCONF IS ENTERED.
  182.    * IF IT'S ALREADY IN USE THE EXECUTION WILL CONTINUE BY A 
  183.    * CONTINUE B SIGNAL
  184.    */
  185.   if (lliPtr.p->lliActiveLcp == 0) {
  186.     PendingFileOpenInfoPtr pfoiPtr;
  187.     ljam();
  188. /***************************************************************/
  189. /* OPEN THE UNDO FILE FOR READ                                 */
  190. /* THE FILE HANDLE WILL BE SET IN THE LOCAL_LOG_INFO_REC       */
  191. /* UPON FSOPENCONF                                             */
  192. /***************************************************************/
  193.     cnoOfLocalLogInfo++;
  194.                                                 /* F_LEVEL NOT USED              */
  195.     Uint32 fileType = 1;                        /* VERSION                       */
  196.     fileType = (fileType << 8) | 2;         /* .LOCLOG                       */
  197.     fileType = (fileType << 8) | 6;         /* D6                            */
  198.     fileType = (fileType << 8) | 0xff;         /* DON'T USE P DIRECTORY LEVEL   */
  199.     Uint32 fileFlag = 0;                 /* READ ONLY                     */
  200.     seizePendingFileOpenInfoRecord(pfoiPtr);
  201.     pfoiPtr.p->pfoOpenType = LCP_UNDO_FILE_READ;
  202.     pfoiPtr.p->pfoRestartInfoP = riPtr.i;
  203.     signal->theData[0] = cownref;
  204.     signal->theData[1] = pfoiPtr.i;
  205.     signal->theData[2] = lliPtr.i;
  206.     signal->theData[3] = 0xFFFFFFFF;
  207.     signal->theData[4] = undoFileVersion;
  208.     signal->theData[5] = fileType;
  209.     signal->theData[6] = fileFlag;
  210.     sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
  211.     lliPtr.p->lliPrevRecordId = 0;
  212.     lliPtr.p->lliActiveLcp = 1;
  213.     lliPtr.p->lliNumFragments = 1;
  214.   } else {
  215.     ljam();
  216.     signal->theData[0] = ZCONT_LOAD_DP;
  217.     signal->theData[1] = riPtr.i;
  218.     sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  219.     lliPtr.p->lliNumFragments++;
  220.   }//if
  221.    /* RETAIN THE HIGH- AND LOWSCORE ID:S OF THE LOGRECORD POSITIONS. WE HAVE TO EXECUTE THE  */
  222.    /* UNDO LOG BETWEEN THE END AND START RECORDS FOR ALL RECORDS THAT INCLUDE FRAGMENTS OF   */
  223.    /* THE RIGHT CHECKPOINT VERSION TO COMPLETE THE OPERATION WE HAVE TO RUN ALL LOGS THAT    */
  224.    /* HAS THE NUMBER OF LCP ELEMENT GREATER THAN 0, I.E. IS INCLUDED.                        */
  225.   if (TzeroDataPage[ZSRI_UNDO_LOG_END_REC_ID] > lliPtr.p->lliPrevRecordId) {
  226.     ljam();
  227.     lliPtr.p->lliPrevRecordId = TzeroDataPage[ZSRI_UNDO_LOG_END_REC_ID];
  228.     lliPtr.p->lliEndPageId = TzeroDataPage[ZSRI_UNDO_LOG_END_PAGE_ID];
  229.   }//if
  230.   return;
  231. }//Dbtup::rfrInitRestartInfoLab()
  232. /***************************************************************/
  233. /* LOAD THE NEXT DATA PAGE SEGMENT INTO MEMORY                 */
  234. /***************************************************************/
  235. void Dbtup::rfrLoadDataPagesLab(Signal* signal, RestartInfoRecordPtr riPtr, DiskBufferSegmentInfoPtr dbsiPtr) 
  236. {
  237.   FragrecordPtr regFragPtr;
  238.   if (riPtr.p->sriCurDataPageFromBuffer >= riPtr.p->sriNumDataPages) {
  239.     ljam();
  240.     rfrCompletedLab(signal, riPtr);
  241.     return;
  242.   }//if
  243.   Uint32 startPage = riPtr.p->sriCurDataPageFromBuffer;
  244.   Uint32 endPage;
  245.   if ((startPage + ZDB_SEGMENT_SIZE) < riPtr.p->sriNumDataPages) {
  246.     ljam();
  247.     endPage = startPage + ZDB_SEGMENT_SIZE;
  248.   } else {
  249.     ljam();
  250.     endPage = riPtr.p->sriNumDataPages;
  251.   }//if
  252.   regFragPtr.i = riPtr.p->sriFragP;
  253.   ptrCheckGuard(regFragPtr, cnoOfFragrec, fragrecord);
  254.   ndbrequire((endPage - startPage) <= 16);
  255.   Uint32 i = 0;
  256.   for (Uint32 pageId = startPage; pageId < endPage; pageId++) {
  257.     ljam();
  258.     dbsiPtr.p->pdxDataPage[i] = getRealpid(regFragPtr.p, pageId);
  259.     i++;
  260.   }//for
  261.   dbsiPtr.p->pdxNumDataPages = endPage - startPage; /* SET THE NUMBER OF DATA PAGES */
  262.   riPtr.p->sriCurDataPageFromBuffer = endPage;
  263.   dbsiPtr.p->pdxFilePage = startPage + 1;
  264.   rfrReadNextDataSegment(signal, riPtr, dbsiPtr);
  265.   return;
  266. }//Dbtup::rfrLoadDataPagesLab()
  267. void Dbtup::rfrCompletedLab(Signal* signal, RestartInfoRecordPtr riPtr) 
  268. {
  269.   PendingFileOpenInfoPtr pfoPtr;
  270. /* ---------------------------------------------------------------------- */
  271. /*       CLOSE THE DATA FILE BEFORE SENDING TUP_SRCONF                    */
  272. /* ---------------------------------------------------------------------- */
  273.   seizePendingFileOpenInfoRecord(pfoPtr);
  274.   pfoPtr.p->pfoOpenType = LCP_DATA_FILE_READ;
  275.   pfoPtr.p->pfoCheckpointInfoP = riPtr.i;
  276.   signal->theData[0] = riPtr.p->sriDataFileHandle;
  277.   signal->theData[1] = cownref;
  278.   signal->theData[2] = pfoPtr.i;
  279.   signal->theData[3] = 0;
  280.   sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, 4, JBA);
  281. }//Dbtup::rfrCompletedLab()
  282. void Dbtup::rfrClosedDataFileLab(Signal* signal, Uint32 restartIndex) 
  283. {
  284.   RestartInfoRecordPtr riPtr;
  285.   DiskBufferSegmentInfoPtr dbsiPtr;
  286.   riPtr.i = restartIndex;
  287.   ptrCheckGuard(riPtr, cnoOfRestartInfoRec, restartInfoRecord);
  288.   riPtr.p->sriDataFileHandle = RNIL;
  289.   dbsiPtr.i = riPtr.p->sriDataBufferSegmentP;
  290.   ptrCheckGuard(dbsiPtr, cnoOfConcurrentWriteOp, diskBufferSegmentInfo);
  291.   releaseDiskBufferSegmentRecord(dbsiPtr);
  292.   signal->theData[0] = riPtr.p->sriUserptr;
  293.   signal->theData[1] = riPtr.p->sriFragP;
  294.   sendSignal(riPtr.p->sriBlockref, GSN_TUP_SRCONF, signal, 2, JBB);
  295.   releaseRestartInfoRecord(riPtr);
  296. }//Dbtup::rfrClosedDataFileLab()
  297. /* ---------------------------------------------------------------- */
  298. /* ---------------------- EXECUTE LOCAL LOG  ---------------------- */
  299. /* ---------------------------------------------------------------- */
  300. void Dbtup::execSTART_RECREQ(Signal* signal) 
  301. {
  302.   ljamEntry();
  303.   clqhUserpointer = signal->theData[0];
  304.   clqhBlockref = signal->theData[1];
  305.   for (int i = 0; i < ZNO_CHECKPOINT_RECORDS; i++){
  306.     cSrUndoRecords[i] = 0;
  307.   }//for
  308.   if (cnoOfLocalLogInfo == 0) {
  309.     ljam();
  310. /* ---------------------------------------------------------------- */
  311. /*       THERE WERE NO LOCAL LOGS TO EXECUTE IN THIS SYSTEM RESTART */
  312. /* ---------------------------------------------------------------- */
  313.     xlcRestartCompletedLab(signal);
  314.     return;
  315.   }//if
  316.   LocalLogInfoPtr lliPtr;
  317.   for (lliPtr.i = 0; lliPtr.i < 16; lliPtr.i++) {
  318.     ljam();
  319.     ptrAss(lliPtr, localLogInfo);
  320.     if (lliPtr.p->lliActiveLcp == 1) {
  321.       ljam();
  322.       signal->theData[0] = ZSTART_EXEC_UNDO_LOG;
  323.       signal->theData[1] = lliPtr.i;
  324.       sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  325.     }//if
  326.   }//for
  327.   return;
  328. }//Dbtup::execSTART_RECREQ()
  329. void Dbtup::closeExecUndoLogLab(Signal* signal, LocalLogInfoPtr lliPtr) 
  330. {
  331.   PendingFileOpenInfoPtr pfoPtr;
  332. /* ---------------------------------------------------------------------- */
  333. /*       CLOSE THE UNDO LOG BEFORE COMPLETION OF THE SYSTEM RESTART       */
  334. /* ---------------------------------------------------------------------- */
  335.   seizePendingFileOpenInfoRecord(pfoPtr);
  336.   pfoPtr.p->pfoOpenType = LCP_UNDO_FILE_READ;
  337.   pfoPtr.p->pfoCheckpointInfoP = lliPtr.i;
  338.   signal->theData[0] = lliPtr.p->lliUndoFileHandle;
  339.   signal->theData[1] = cownref;
  340.   signal->theData[2] = pfoPtr.i;
  341.   signal->theData[3] = 0;
  342.   sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, 4, JBA);
  343.   return;
  344. }//Dbtup::closeExecUndoLogLab()
  345. void Dbtup::endExecUndoLogLab(Signal* signal, Uint32 lliIndex) 
  346. {
  347.   DiskBufferSegmentInfoPtr dbsiPtr;
  348.   LocalLogInfoPtr lliPtr;
  349.   lliPtr.i = lliIndex;
  350.   ptrCheckGuard(lliPtr, cnoOfParallellUndoFiles, localLogInfo);
  351.   lliPtr.p->lliUndoFileHandle = RNIL;
  352.   lliPtr.p->lliActiveLcp = 0;
  353. /* ---------------------------------------------------------------------- */
  354. /*       WE HAVE NOW CLOSED THE LOG. WE WAIT FOR ALL LOCAL LOGS TO        */
  355. /*       COMPLETE LOG EXECUTION BEFORE SENDING THE RESPONSE TO LQH.       */
  356. /* ---------------------------------------------------------------------- */
  357.   dbsiPtr.i = lliPtr.p->lliUndoBufferSegmentP;
  358.   ptrCheckGuard(dbsiPtr, cnoOfConcurrentWriteOp, diskBufferSegmentInfo);
  359.   freeDiskBufferSegmentRecord(signal, dbsiPtr);
  360.   lliPtr.p->lliUndoBufferSegmentP = RNIL;
  361.   for (lliPtr.i = 0; lliPtr.i < 16; lliPtr.i++) {
  362.     ljam();
  363.     ptrAss(lliPtr, localLogInfo);
  364.     if (lliPtr.p->lliActiveLcp == 1) {
  365.       ljam();
  366.       return;
  367.     }//if
  368.   }//for
  369.   xlcRestartCompletedLab(signal);
  370.   return;
  371. }//Dbtup::endExecUndoLogLab()
  372. void Dbtup::xlcRestartCompletedLab(Signal* signal) 
  373. {
  374.   cnoOfLocalLogInfo = 0;
  375.   signal->theData[0] = EventReport::UNDORecordsExecuted;
  376.   signal->theData[1] = DBTUP; // From block
  377.   signal->theData[2] = 0;     // Total records executed
  378.   for (int i = 0; i < 10; i++) {
  379.     if (i < ZNO_CHECKPOINT_RECORDS){
  380.       signal->theData[i+3] = cSrUndoRecords[i];
  381.       signal->theData[2] += cSrUndoRecords[i]; 
  382.     } else {
  383.       signal->theData[i+3] = 0; // Unsused data
  384.     }//if
  385.   }//for
  386.   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 12, JBB);
  387. /* ---------------------------------------------------------------------- */
  388. /*       ALL LOCAL LOGS HAVE COMPLETED. WE HAVE COMPLETED OUR PART OF THE */
  389. /*       SYSTEM RESTART.                                                  */
  390. /* ---------------------------------------------------------------------- */
  391.   signal->theData[0] = clqhUserpointer;
  392.   sendSignal(clqhBlockref, GSN_START_RECCONF, signal, 1, JBB);
  393.   return;
  394. }//Dbtup::xlcRestartCompletedLab()
  395. void Dbtup::startExecUndoLogLab(Signal* signal, Uint32 lliIndex) 
  396. {
  397.   DiskBufferSegmentInfoPtr dbsiPtr;
  398.   LocalLogInfoPtr lliPtr;
  399. /* ---------------------------------------------------------------------- */
  400. /*       START EXECUTING THE LOG FOR THIS PART. WE BEGIN BY READING THE   */
  401. /*       LAST 16 PAGES.                                                   */
  402. /* ---------------------------------------------------------------------- */
  403.    /* SET THE PREVIOS RECORD TO THE LAST ONE BECAUSE THAT'S WHERE TO START */
  404.   lliPtr.i = lliIndex;
  405.   ptrCheckGuard(lliPtr, cnoOfParallellUndoFiles, localLogInfo);
  406.   allocRestartUndoBufferSegment(signal, dbsiPtr, lliPtr);
  407.   lliPtr.p->lliUndoBufferSegmentP = dbsiPtr.i;
  408.   dbsiPtr.p->pdxCheckpointInfoP = lliPtr.i;
  409.   if (lliPtr.p->lliEndPageId > ((2 * ZUB_SEGMENT_SIZE) - 1)) {
  410.     ljam();
  411.     dbsiPtr.p->pdxNumDataPages = ZUB_SEGMENT_SIZE;
  412.     dbsiPtr.p->pdxFilePage = lliPtr.p->lliEndPageId - (ZUB_SEGMENT_SIZE - 1);
  413.   } else if (lliPtr.p->lliEndPageId > (ZUB_SEGMENT_SIZE - 1)) {
  414.     ljam();
  415.     dbsiPtr.p->pdxNumDataPages = lliPtr.p->lliEndPageId - (ZUB_SEGMENT_SIZE - 1);
  416.     dbsiPtr.p->pdxFilePage = ZUB_SEGMENT_SIZE;
  417.   } else {
  418.     ljam();
  419.     dbsiPtr.p->pdxNumDataPages = lliPtr.p->lliEndPageId + 1;
  420.     dbsiPtr.p->pdxFilePage = 0;
  421.     rfrReadNextUndoSegment(signal, dbsiPtr, lliPtr);
  422.     return;
  423.   }//if
  424.   rfrReadFirstUndoSegment(signal, dbsiPtr, lliPtr);
  425.   return;
  426. }//Dbtup::startExecUndoLogLab()
  427. void Dbtup::rfrReadSecondUndoLogLab(Signal* signal, DiskBufferSegmentInfoPtr dbsiPtr) 
  428. {
  429.   LocalLogInfoPtr lliPtr;
  430.   lliPtr.i = dbsiPtr.p->pdxCheckpointInfoP;
  431.   ptrCheckGuard(lliPtr, cnoOfParallellUndoFiles, localLogInfo);
  432.   dbsiPtr.p->pdxNumDataPages = ZUB_SEGMENT_SIZE;
  433.   dbsiPtr.p->pdxFilePage -= ZUB_SEGMENT_SIZE;
  434.   rfrReadNextUndoSegment(signal, dbsiPtr, lliPtr);
  435.   return;
  436. }//Dbtup::rfrReadSecondUndoLogLab()
  437. void Dbtup::readExecUndoLogLab(Signal* signal, DiskBufferSegmentInfoPtr dbsiPtr, LocalLogInfoPtr lliPtr) 
  438. {
  439. /* ---------------------------------------------------------------------- */
  440. /*       THE NEXT UNDO LOG RECORD HAS NOT BEEN READ FROM DISK YET. WE WILL*/
  441. /*       READ UPTO 8 PAGES BACKWARDS OF THE UNDO LOG FILE. WE WILL KEEP   */
  442. /*       THE LAST 8 PAGES TO ENSURE THAT WE WILL BE ABLE TO READ THE NEXT */
  443. /*       LOG RECORD EVEN IF IT SPANS UPTO 8 PAGES.                        */
  444. /* ---------------------------------------------------------------------- */
  445.   if (dbsiPtr.p->pdxFilePage >= ZUB_SEGMENT_SIZE) {
  446.     ljam();
  447.     for (Uint32 i = 0; i < ZUB_SEGMENT_SIZE; i++) {
  448.       ljam();
  449.       Uint32 savePageId = dbsiPtr.p->pdxDataPage[i + ZUB_SEGMENT_SIZE];
  450.       dbsiPtr.p->pdxDataPage[i + ZUB_SEGMENT_SIZE] = dbsiPtr.p->pdxDataPage[i];
  451.       dbsiPtr.p->pdxDataPage[i] = savePageId;
  452.     }//for
  453.     dbsiPtr.p->pdxNumDataPages = ZUB_SEGMENT_SIZE;
  454.     dbsiPtr.p->pdxFilePage = dbsiPtr.p->pdxFilePage - ZUB_SEGMENT_SIZE;
  455.   } else {
  456.     ljam();
  457.     Uint32 dataPages[16];
  458.     ndbrequire(dbsiPtr.p->pdxFilePage > 0);
  459.     ndbrequire(dbsiPtr.p->pdxFilePage <= ZUB_SEGMENT_SIZE);
  460.     Uint32 i;
  461.     for (i = 0; i < dbsiPtr.p->pdxFilePage; i++) {
  462.       ljam();
  463.       dataPages[i] = dbsiPtr.p->pdxDataPage[i + ZUB_SEGMENT_SIZE];
  464.     }//for
  465.     for (i = 0; i < ZUB_SEGMENT_SIZE; i++) {
  466.       ljam();
  467.       dataPages[i + dbsiPtr.p->pdxFilePage] = dbsiPtr.p->pdxDataPage[i];
  468.     }//for
  469.     Uint32 limitLoop = ZUB_SEGMENT_SIZE + dbsiPtr.p->pdxFilePage;
  470.     for (i = 0; i < limitLoop; i++) {
  471.       ljam();
  472.       dbsiPtr.p->pdxDataPage[i] = dataPages[i];
  473.     }//for
  474.     dbsiPtr.p->pdxNumDataPages = dbsiPtr.p->pdxFilePage;
  475.     dbsiPtr.p->pdxFilePage = 0;
  476.   }//if
  477.   rfrReadNextUndoSegment(signal, dbsiPtr, lliPtr);
  478.   return;
  479. }//Dbtup::readExecUndoLogLab()
  480. void Dbtup::rfrReadNextDataSegment(Signal* signal, RestartInfoRecordPtr riPtr, DiskBufferSegmentInfoPtr dbsiPtr) 
  481. {
  482.   dbsiPtr.p->pdxRestartInfoP = riPtr.i;
  483.   dbsiPtr.p->pdxOperation = CHECKPOINT_DATA_READ;
  484.   ndbrequire(dbsiPtr.p->pdxNumDataPages <= 8);
  485.   signal->theData[0] = riPtr.p->sriDataFileHandle;
  486.   signal->theData[1] = cownref;
  487.   signal->theData[2] = dbsiPtr.i;
  488.   signal->theData[3] = 2;
  489.   signal->theData[4] = ZBASE_ADDR_PAGE_WORD;
  490.   signal->theData[5] = dbsiPtr.p->pdxNumDataPages;
  491.   for (Uint32 i = 0; i < dbsiPtr.p->pdxNumDataPages; i++) {
  492.     ljam();
  493.     signal->theData[6 + i] = dbsiPtr.p->pdxDataPage[i];
  494.   }//for
  495.   signal->theData[6 + dbsiPtr.p->pdxNumDataPages] = dbsiPtr.p->pdxFilePage;
  496.   sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 15, JBA);
  497. }//Dbtup::rfrReadNextDataSegment()
  498. /* ---------------------------------------------------------------- */
  499. /* ------------------- RFR_READ_FIRST_UNDO_SEGMENT ---------------- */
  500. /* ---------------------------------------------------------------- */
  501. /* THIS ROUTINE READS IN THE FIRST UNDO SEGMENT INTO THE CURRENTLY  */
  502. /* ACTIVE UNDO BUFFER SEGMENT                                       */
  503. /* -----------------------------------------------------------------*/
  504. void Dbtup::rfrReadFirstUndoSegment(Signal* signal, DiskBufferSegmentInfoPtr dbsiPtr, LocalLogInfoPtr lliPtr) 
  505. {
  506.   dbsiPtr.p->pdxOperation = CHECKPOINT_UNDO_READ_FIRST;
  507.   signal->theData[0] = lliPtr.p->lliUndoFileHandle;
  508.   signal->theData[1] = cownref;
  509.   signal->theData[2] = dbsiPtr.i;
  510.   signal->theData[3] = 1;
  511.   signal->theData[4] = ZBASE_ADDR_UNDO_WORD;
  512.   signal->theData[5] = dbsiPtr.p->pdxNumDataPages;
  513.   signal->theData[6] = dbsiPtr.p->pdxDataPage[ZUB_SEGMENT_SIZE];
  514.   signal->theData[7] = dbsiPtr.p->pdxFilePage;
  515.   sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
  516. }//Dbtup::rfrReadFirstUndoSegment()
  517. /* ---------------------------------------------------------------- */
  518. /* ------------------- RFR_READ_NEXT_UNDO_SEGMENT ----------------- */
  519. /* ---------------------------------------------------------------- */
  520. /* THIS ROUTINE READS IN THE NEXT UNDO SEGMENT INTO THE CURRENTLY   */
  521. /* ACTIVE UNDO BUFFER SEGMENT AND SWITCH TO THE UNACTIVE, READY ONE */
  522. /* -----------------------------------------------------------------*/
  523. void Dbtup::rfrReadNextUndoSegment(Signal* signal, DiskBufferSegmentInfoPtr dbsiPtr, LocalLogInfoPtr lliPtr) 
  524. {
  525.   dbsiPtr.p->pdxOperation = CHECKPOINT_UNDO_READ;
  526.   signal->theData[0] = lliPtr.p->lliUndoFileHandle;
  527.   signal->theData[1] = cownref;
  528.   signal->theData[2] = dbsiPtr.i;
  529.   signal->theData[3] = 1;
  530.   signal->theData[4] = ZBASE_ADDR_UNDO_WORD;
  531.   signal->theData[5] = dbsiPtr.p->pdxNumDataPages;
  532.   signal->theData[6] = dbsiPtr.p->pdxDataPage[0];
  533.   signal->theData[7] = dbsiPtr.p->pdxFilePage;
  534.   sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
  535. }//Dbtup::rfrReadNextUndoSegment()
  536. void Dbtup::xlcGetNextRecordLab(Signal* signal, DiskBufferSegmentInfoPtr dbsiPtr, LocalLogInfoPtr lliPtr) 
  537. {
  538.   Uint32 loopCount = 0;
  539. /* ---------------------------------------------------------------------- */
  540. /*       EXECUTE A NEW SET OF UNDO LOG RECORDS.                           */
  541. /* ---------------------------------------------------------------------- */
  542.   XlcStruct xlcStruct;
  543.   xlcStruct.LliPtr = lliPtr;
  544.   xlcStruct.DbsiPtr = dbsiPtr;
  545.   do {
  546.     ljam();
  547.     loopCount++;
  548.     if (loopCount == 20) {
  549.       ljam();
  550.       signal->theData[0] = ZCONT_EXECUTE_LC;
  551.       signal->theData[1] = xlcStruct.LliPtr.i;
  552.       sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  553.       return;
  554.     }//if
  555.     if (xlcStruct.LliPtr.p->lliPrevRecordId == 0) {
  556.       ljam();
  557.       closeExecUndoLogLab(signal, xlcStruct.LliPtr);
  558.       return;
  559.     }//if
  560.     xlcStruct.PageId = xlcStruct.LliPtr.p->lliPrevRecordId >> ZUNDO_RECORD_ID_PAGE_INDEX;
  561.     xlcStruct.PageIndex = xlcStruct.LliPtr.p->lliPrevRecordId & ZUNDO_RECORD_ID_PAGE_INDEX_MASK;
  562.     if (xlcStruct.PageId < xlcStruct.DbsiPtr.p->pdxFilePage) {
  563.       ljam();
  564.       readExecUndoLogLab(signal, xlcStruct.DbsiPtr, xlcStruct.LliPtr);
  565.       return;
  566.     }//if
  567.     ndbrequire((xlcStruct.PageId - xlcStruct.DbsiPtr.p->pdxFilePage) < 16);
  568.     xlcStruct.UPPtr.i = xlcStruct.DbsiPtr.p->pdxDataPage[xlcStruct.PageId - xlcStruct.DbsiPtr.p->pdxFilePage];
  569.     ptrCheckGuard(xlcStruct.UPPtr, cnoOfUndoPage, undoPage);
  570.     xlcGetLogHeader(xlcStruct);
  571.     getFragmentrec(xlcStruct.FragPtr, xlcStruct.FragId, xlcStruct.TabPtr.p);
  572.     if (xlcStruct.FragPtr.i == RNIL) {
  573.       ljam();
  574.       continue;
  575.     }//if
  576.     if (xlcStruct.FragPtr.p->fragStatus != SYSTEM_RESTART) {
  577.       ljam();
  578.       continue;
  579.     }//if
  580.     ndbrequire(xlcStruct.LogRecordType < ZNO_CHECKPOINT_RECORDS);
  581.     cSrUndoRecords[xlcStruct.LogRecordType]++;
  582.     switch (xlcStruct.LogRecordType) {
  583.     case ZLCPR_TYPE_INSERT_TH:
  584.       ljam();
  585.       xlcInsertTh(xlcStruct);
  586.       break;
  587.     case ZLCPR_TYPE_DELETE_TH:
  588.       ljam();
  589.       xlcDeleteTh(xlcStruct);
  590.       break;
  591.     case ZLCPR_TYPE_UPDATE_TH:
  592.       ljam();
  593.       xlcUpdateTh(xlcStruct);
  594.       break;
  595.     case ZLCPR_TYPE_INSERT_TH_NO_DATA:
  596.       ljam();
  597.       xlcInsertTh(xlcStruct);
  598.       break;
  599.     case ZLCPR_ABORT_UPDATE:
  600.       ljam();
  601.       xlcAbortUpdate(signal, xlcStruct);
  602.       break;
  603.     case ZLCPR_ABORT_INSERT:
  604.       ljam();
  605.       xlcAbortInsert(signal, xlcStruct);
  606.       break;
  607.     case ZTABLE_DESCRIPTOR:
  608.       ljam();
  609.       xlcTableDescriptor(xlcStruct);
  610.       if (xlcStruct.LliPtr.p->lliNumFragments == 0) {
  611.         ljam();
  612.         closeExecUndoLogLab(signal, xlcStruct.LliPtr);
  613.         return;
  614.       }//if
  615.       break;
  616.     case ZLCPR_UNDO_LOG_PAGE_HEADER:
  617.       ljam();
  618.       xlcUndoLogPageHeader(xlcStruct);
  619.       break;
  620.     case ZINDICATE_NO_OP_ACTIVE:
  621.       ljam();
  622.       xlcIndicateNoOpActive(xlcStruct);
  623.       break;
  624.     case ZLCPR_TYPE_UPDATE_GCI:
  625.       ljam();
  626.       xlcUpdateGCI(xlcStruct);
  627.       break;
  628.     default:
  629.       ndbrequire(false);
  630.       break;
  631.     }//switch
  632.   } while (1);
  633. }//Dbtup::xlcGetNextRecordLab()
  634. /* ---------------------------------------------------------------- */
  635. /* -----------------   XLC_GET_LOG_HEADER    ---------------------- */
  636. /* ---------------------------------------------------------------- */
  637. void Dbtup::xlcGetLogHeader(XlcStruct& xlcStruct) 
  638. {
  639.   Uint32 pIndex = xlcStruct.PageIndex;
  640.   Uint32 fragId;
  641.   Uint32 tableId;
  642.   Uint32 prevId;
  643.   if ((pIndex + 4) < ZWORDS_ON_PAGE) {
  644.     UndoPage* const regUndoPagePtr = xlcStruct.UPPtr.p;
  645.     ljam();
  646.     xlcStruct.LogRecordType = regUndoPagePtr->undoPageWord[pIndex];
  647.     prevId = regUndoPagePtr->undoPageWord[pIndex + 1];
  648.     tableId = regUndoPagePtr->undoPageWord[pIndex + 2];
  649.     fragId = regUndoPagePtr->undoPageWord[pIndex + 3];
  650.     xlcStruct.PageIndex = pIndex + 4;
  651.   } else {
  652.     ljam();
  653.     xlcStruct.LogRecordType = xlcGetLogWord(xlcStruct);
  654.     prevId = xlcGetLogWord(xlcStruct);
  655.     tableId = xlcGetLogWord(xlcStruct);
  656.     fragId = xlcGetLogWord(xlcStruct);
  657.   }//if
  658.   xlcStruct.LliPtr.p->lliPrevRecordId = prevId;
  659.   xlcStruct.FragId = fragId;
  660.   xlcStruct.TabPtr.i = tableId;
  661.   ptrCheckGuard(xlcStruct.TabPtr, cnoOfTablerec, tablerec);
  662. }//Dbtup::xlcGetLogHeader()
  663. /* ------------------------------------------------------------------- */
  664. /* ---------------------- XLC_GET_LOG_WORD --------------------------- */
  665. /* ------------------------------------------------------------------- */
  666. Uint32 Dbtup::xlcGetLogWord(XlcStruct& xlcStruct) 
  667. {
  668.   Uint32 pIndex = xlcStruct.PageIndex;
  669.   ndbrequire(xlcStruct.UPPtr.p != NULL);
  670.   ndbrequire(pIndex < ZWORDS_ON_PAGE);
  671.   Uint32 logWord = xlcStruct.UPPtr.p->undoPageWord[pIndex];
  672.   pIndex++;
  673.   xlcStruct.PageIndex = pIndex;
  674.   if (pIndex == ZWORDS_ON_PAGE) {
  675.     ljam();
  676.     xlcStruct.PageIndex = ZUNDO_PAGE_HEADER_SIZE;
  677.     xlcStruct.PageId++;
  678.     if ((xlcStruct.PageId - xlcStruct.DbsiPtr.p->pdxFilePage) >= (2 * ZUB_SEGMENT_SIZE)) {
  679.       ljam();
  680.       xlcStruct.UPPtr.i = RNIL;
  681.       ptrNull(xlcStruct.UPPtr);
  682.     } else {
  683.       ljam();
  684.       Uint32 index = xlcStruct.PageId - xlcStruct.DbsiPtr.p->pdxFilePage;
  685.       ndbrequire(index < 16);
  686.       xlcStruct.UPPtr.i = xlcStruct.DbsiPtr.p->pdxDataPage[index];
  687.       ptrCheckGuard(xlcStruct.UPPtr, cnoOfUndoPage, undoPage);
  688.     }//if
  689.   }//if
  690.   return logWord;
  691. }//Dbtup::xlcGetLogWord()
  692.    /****************************************************/
  693.    /* INSERT A TUPLE HEADER THE DATA IS THE TUPLE DATA */
  694.    /****************************************************/
  695. void Dbtup::xlcInsertTh(XlcStruct& xlcStruct) 
  696. {
  697.   PagePtr pagePtr;
  698.   Fragrecord* const regFragPtr = xlcStruct.FragPtr.p;
  699.   Tablerec* const regTabPtr = xlcStruct.TabPtr.p;
  700.   Uint32 fragPageId = xlcGetLogWord(xlcStruct);
  701.   Uint32 pageIndex = xlcGetLogWord(xlcStruct);
  702.   ndbrequire((pageIndex & 1) == 0);
  703.   pagePtr.i = getRealpid(regFragPtr, fragPageId);
  704.   ptrCheckGuard(pagePtr, cnoOfPage, page);
  705.   Uint32 pageOffset;
  706.   getThAtPageSr(pagePtr.p, pageOffset);
  707.   ndbrequire(pageOffset == (ZPAGE_HEADER_SIZE + (regTabPtr->tupheadsize * (pageIndex >> 1))));
  708.   if (xlcStruct.LogRecordType == ZLCPR_TYPE_INSERT_TH) {
  709.     ljam();
  710.     xlcCopyData(xlcStruct, pageOffset, regTabPtr->tupheadsize, pagePtr);
  711.   } else {
  712.     ndbrequire(xlcStruct.LogRecordType == ZLCPR_TYPE_INSERT_TH_NO_DATA);
  713.     ljam();
  714.   }//if
  715. /* ----------------------------------------*/
  716. /* INDICATE THAT NO OPERATIONS ACTIVE      */
  717. /* ----------------------------------------*/
  718.   ndbrequire(pageOffset < ZWORDS_ON_PAGE);
  719.   pagePtr.p->pageWord[pageOffset] = RNIL;
  720. }//Dbtup::xlcInsertTh()
  721.    /**********************************************/
  722.    /* DELETE A TUPLE HEADER - NO ADDITIONAL DATA */
  723.    /**********************************************/
  724. void Dbtup::xlcDeleteTh(XlcStruct& xlcStruct) 
  725. {
  726.   PagePtr pagePtr;
  727.   Fragrecord* const regFragPtr = xlcStruct.FragPtr.p;
  728.   Tablerec* const regTabPtr = xlcStruct.TabPtr.p;
  729.   Uint32 fragPageId = xlcGetLogWord(xlcStruct);
  730.   Uint32 pageIndex = xlcGetLogWord(xlcStruct);
  731.   ndbrequire((pageIndex & 1) == 0);
  732.   pagePtr.i = getRealpid(regFragPtr, fragPageId);
  733.   ptrCheckGuard(pagePtr, cnoOfPage, page);
  734.   Uint32 pageOffset = ZPAGE_HEADER_SIZE + (regTabPtr->tupheadsize * (pageIndex >> 1));
  735.   freeThSr(regTabPtr, pagePtr.p, pageOffset);
  736. }//Dbtup::xlcDeleteTh()
  737.    /*****************************************************/
  738.    /* UPDATE A TUPLE HEADER, THE DATA IS THE TUPLE DATA */
  739.    /*****************************************************/
  740. void Dbtup::xlcUpdateTh(XlcStruct& xlcStruct) 
  741. {
  742.   PagePtr pagePtr;
  743.   Fragrecord* const regFragPtr = xlcStruct.FragPtr.p;
  744.   Tablerec* const regTabPtr = xlcStruct.TabPtr.p;
  745.   Uint32 fragPageId = xlcGetLogWord(xlcStruct);
  746.   Uint32 pageIndex = xlcGetLogWord(xlcStruct);
  747.   ndbrequire((pageIndex & 1) == 0);
  748.   pagePtr.i = getRealpid(regFragPtr, fragPageId);
  749.   ptrCheckGuard(pagePtr, cnoOfPage, page);
  750.   Uint32 pageOffset = ZPAGE_HEADER_SIZE + (regTabPtr->tupheadsize * (pageIndex >> 1));
  751.   xlcCopyData(xlcStruct, pageOffset, regTabPtr->tupheadsize, pagePtr);
  752. /* ----------------------------------------*/
  753. /* INDICATE THAT NO OPERATIONS ACTIVE      */
  754. /* ----------------------------------------*/
  755.   ndbrequire(pageOffset < ZWORDS_ON_PAGE);
  756.   pagePtr.p->pageWord[pageOffset] = RNIL;
  757. }//Dbtup::xlcUpdateTh()
  758.    /**************************************************/
  759.    /* ABORT AN INSERT OPERATION - NO ADDITIONAL DATA */
  760.    /**************************************************/
  761. void Dbtup::xlcAbortInsert(Signal* signal, XlcStruct& xlcStruct) 
  762. {
  763.   PagePtr pagePtr;
  764.   Fragrecord* const regFragPtr = xlcStruct.FragPtr.p;
  765.   Tablerec* const regTabPtr = xlcStruct.TabPtr.p;
  766.   Uint32 fragPageId = xlcGetLogWord(xlcStruct);
  767.   Uint32 pageIndex = xlcGetLogWord(xlcStruct);
  768.   ndbrequire((pageIndex & 1) == 0);
  769.   pagePtr.i = getRealpid(regFragPtr, fragPageId);
  770.   ptrCheckGuard(pagePtr, cnoOfPage, page);
  771.   Uint32 pageOffset = ZPAGE_HEADER_SIZE + (regTabPtr->tupheadsize * (pageIndex >> 1));
  772.   freeTh(regFragPtr, regTabPtr, signal, pagePtr.p, pageOffset);
  773. }//Dbtup::xlcAbortInsert()
  774.    /*****************************************************/
  775.    /* COPY DATA FROM COPY TUPLE TO ORIGINAL TUPLE       */
  776.    /*****************************************************/
  777. void Dbtup::xlcAbortUpdate(Signal* signal, XlcStruct& xlcStruct) 
  778. {
  779.   PagePtr pagePtr;
  780.   Fragrecord* const regFragPtr = xlcStruct.FragPtr.p;
  781.   Tablerec* const regTabPtr = xlcStruct.TabPtr.p;
  782.   Uint32 tuple_size = regTabPtr->tupheadsize;
  783.   Uint32 fragPageIdC = xlcGetLogWord(xlcStruct);
  784.   Uint32 pageIndexC = xlcGetLogWord(xlcStruct);
  785.   ndbrequire((pageIndexC & 1) == 0);
  786.   Uint32 TdestPageId = getRealpid(regFragPtr, fragPageIdC);
  787.   Uint32 TcmDestIndex = ZPAGE_HEADER_SIZE +
  788.                        (tuple_size * (pageIndexC >> 1));
  789.   Uint32 fragPageId = xlcGetLogWord(xlcStruct);
  790.   Uint32 pageIndex = xlcGetLogWord(xlcStruct);
  791.   ndbrequire((pageIndex & 1) == 0);
  792.   Uint32 TsourcePageId = getRealpid(regFragPtr, fragPageId);
  793.   Uint32 TcmSourceIndex = ZPAGE_HEADER_SIZE +
  794.                          (tuple_size * (pageIndex >> 1));
  795.   Uint32 end_source = tuple_size + TcmSourceIndex;
  796.   Uint32 end_dest = tuple_size + TcmDestIndex;
  797.   void* Tdestination = (void*)&page[TdestPageId].pageWord[TcmDestIndex + 1]; 
  798.   const void* Tsource = 
  799.     (void*)&page[TsourcePageId].pageWord[TcmSourceIndex + 1];
  800.   ndbrequire(TsourcePageId < cnoOfPage &&
  801.              TdestPageId < cnoOfPage &&
  802.              end_source <= ZWORDS_ON_PAGE &&
  803.              end_dest <= ZWORDS_ON_PAGE);
  804.   MEMCOPY_NO_WORDS(Tdestination, Tsource, (tuple_size - 1));
  805.   pagePtr.i = TsourcePageId;
  806.   ptrAss(pagePtr, page);
  807.   freeTh(regFragPtr, regTabPtr, signal, pagePtr.p, TcmSourceIndex);
  808.   pagePtr.i = TdestPageId;
  809.   ptrAss(pagePtr, page);
  810.   pagePtr.p->pageWord[TcmDestIndex] = RNIL;
  811. }//Dbtup::xlcAbortUpdate()
  812.    /*****************************/
  813.    /* RESTORE UPDATED GCI VALUE */
  814.    /*****************************/
  815. void Dbtup::xlcUpdateGCI(XlcStruct& xlcStruct) 
  816. {
  817.   PagePtr pagePtr;
  818.   Fragrecord* const regFragPtr = xlcStruct.FragPtr.p;
  819.   Tablerec* const regTabPtr = xlcStruct.TabPtr.p;
  820.   Uint32 fragPageId = xlcGetLogWord(xlcStruct);
  821.   Uint32 pageIndex = xlcGetLogWord(xlcStruct);
  822.   Uint32 restoredGCI = xlcGetLogWord(xlcStruct);
  823.   ndbrequire((pageIndex & 1) == 0);
  824.   pagePtr.i = getRealpid(regFragPtr, fragPageId);
  825.   ptrCheckGuard(pagePtr, cnoOfPage, page);
  826.   Uint32 pageOffset = ZPAGE_HEADER_SIZE + (regTabPtr->tupheadsize * (pageIndex >> 1));
  827.   Uint32 gciOffset = pageOffset + regTabPtr->tupGCPIndex;
  828.   ndbrequire((gciOffset < ZWORDS_ON_PAGE) &&
  829.              (regTabPtr->tupGCPIndex < regTabPtr->tupheadsize));
  830.   pagePtr.p->pageWord[gciOffset] = restoredGCI;
  831. }//Dbtup::xlcUpdateGCI()
  832.    /*****************************************************/
  833.    /* READ TABLE DESCRIPTOR FROM UNDO LOG               */
  834.    /*****************************************************/
  835. void Dbtup::xlcTableDescriptor(XlcStruct& xlcStruct) 
  836. {
  837.   xlcStruct.LliPtr.p->lliNumFragments--;
  838.   xlcStruct.FragPtr.p->fragStatus = ACTIVE;
  839. }//Dbtup::xlcTableDescriptor()
  840.    /********************************************************/
  841.    /* UPDATE PAGE STATE AND NEXT POINTER IN PAGE           */
  842.    /********************************************************/
  843. void Dbtup::xlcUndoLogPageHeader(XlcStruct& xlcStruct) 
  844. {
  845.   Fragrecord* const regFragPtr = xlcStruct.FragPtr.p;
  846.   PagePtr xlcPagep;
  847.   Uint32 fragPageId = xlcGetLogWord(xlcStruct);
  848.   xlcPagep.i = getRealpid(regFragPtr, fragPageId);
  849.   ptrCheckGuard(xlcPagep, cnoOfPage, page);
  850.   Uint32 logWord = xlcGetLogWord(xlcStruct);
  851.   ndbrequire(logWord != 0);
  852.   ndbrequire(logWord <= ZAC_MM_FREE_COPY);
  853.   xlcPagep.p->pageWord[ZPAGE_STATE_POS] = logWord;
  854.   xlcPagep.p->pageWord[ZPAGE_NEXT_POS] = xlcGetLogWord(xlcStruct);
  855. }//Dbtup::xlcUndoLogPageHeader()
  856.    /********************************************************/
  857.    /* INDICATE THAT NO OPERATIONS ACTIVE                   */
  858.    /********************************************************/
  859. void Dbtup::xlcIndicateNoOpActive(XlcStruct& xlcStruct) 
  860. {
  861.   PagePtr pagePtr;
  862.   Fragrecord* const regFragPtr = xlcStruct.FragPtr.p;
  863.   Tablerec* const regTabPtr = xlcStruct.TabPtr.p;
  864.   Uint32 fragPageId = xlcGetLogWord(xlcStruct);
  865.   Uint32 pageIndex = xlcGetLogWord(xlcStruct);
  866.   ndbrequire((pageIndex & 1) == 0);
  867.   pagePtr.i = getRealpid(regFragPtr, fragPageId);
  868.   ptrCheckGuard(pagePtr, cnoOfPage, page);
  869.   Uint32 pageOffset = ZPAGE_HEADER_SIZE + (regTabPtr->tupheadsize * (pageIndex >> 1));
  870. /* ----------------------------------------*/
  871. /* INDICATE THAT NO OPERATIONS ACTIVE      */
  872. /* ----------------------------------------*/
  873.   ndbrequire(pageOffset < ZWORDS_ON_PAGE);
  874.   pagePtr.p->pageWord[pageOffset] = RNIL;
  875. }//Dbtup::xlcIndicateNoOpActive()
  876.    /********************************************************/
  877.    /* THIS IS THE COMMON ROUTINE TO COPY DATA FROM THE     */
  878.    /* UNDO BUFFER TO THE DATA PAGES. IT USES THE           */
  879.    /* XLC_REQUEST_SEGMENT SUB TO GET MORE DATA WHEN NEEDED */
  880.    /********************************************************/
  881. void Dbtup::xlcCopyData(XlcStruct& xlcStruct, Uint32 pageOffset, Uint32 noOfWords, PagePtr pagePtr) 
  882. {
  883.   ndbrequire((pageOffset + noOfWords - 1) < ZWORDS_ON_PAGE);
  884.   for (Uint32 i = 1; i < noOfWords; i++) {
  885.     ljam();
  886.     pagePtr.p->pageWord[pageOffset + i] = xlcGetLogWord(xlcStruct);
  887.   }//for
  888. }//Dbtup::xlcCopyData()
  889. void Dbtup::allocRestartUndoBufferSegment(Signal* signal, DiskBufferSegmentInfoPtr& dbsiPtr, LocalLogInfoPtr lliPtr) 
  890. {
  891.   UndoPagePtr undoPagePtr;
  892.   ndbrequire(cfirstfreeUndoSeg != RNIL);
  893.   if (cnoFreeUndoSeg == ZMIN_PAGE_LIMIT_TUP_COMMITREQ) {
  894.     EXECUTE_DIRECT(DBLQH, GSN_TUP_COM_BLOCK, signal, 1);
  895.     ljamEntry();
  896.   }//if
  897.   cnoFreeUndoSeg--;
  898.   ndbrequire(cnoFreeUndoSeg >= 0);
  899.   undoPagePtr.i = cfirstfreeUndoSeg;
  900.   ptrCheckGuard(undoPagePtr, cnoOfUndoPage, undoPage);
  901.   cfirstfreeUndoSeg = undoPagePtr.p->undoPageWord[ZPAGE_NEXT_POS];
  902.   undoPagePtr.p->undoPageWord[ZPAGE_NEXT_POS] = RNIL;
  903.   seizeDiskBufferSegmentRecord(dbsiPtr);
  904.   dbsiPtr.p->pdxBuffertype = UNDO_RESTART_PAGES;
  905.   dbsiPtr.p->pdxUndoBufferSet[0] = undoPagePtr.i;
  906.   Uint32 i;
  907.   for (i = 0; i < ZUB_SEGMENT_SIZE; i++) {
  908.     dbsiPtr.p->pdxDataPage[i] = undoPagePtr.i + i;
  909.   }//for
  910.   ndbrequire(cfirstfreeUndoSeg != RNIL);
  911.   if (cnoFreeUndoSeg == ZMIN_PAGE_LIMIT_TUP_COMMITREQ) {
  912.     EXECUTE_DIRECT(DBLQH, GSN_TUP_COM_BLOCK, signal, 1);
  913.     ljamEntry();
  914.   }//if
  915.   cnoFreeUndoSeg--;
  916.   ndbrequire(cnoFreeUndoSeg >= 0);
  917.   undoPagePtr.i = cfirstfreeUndoSeg;
  918.   ptrCheckGuard(undoPagePtr, cnoOfUndoPage, undoPage);
  919.   cfirstfreeUndoSeg = undoPagePtr.p->undoPageWord[ZPAGE_NEXT_POS];
  920.   undoPagePtr.p->undoPageWord[ZPAGE_NEXT_POS] = RNIL;
  921.   dbsiPtr.p->pdxUndoBufferSet[1] = undoPagePtr.i;
  922. //  lliPtr.p->lliUndoPage = undoPagePtr.i;
  923.   for (i = ZUB_SEGMENT_SIZE; i < (2 * ZUB_SEGMENT_SIZE); i++) {
  924.     dbsiPtr.p->pdxDataPage[i] = undoPagePtr.i + (i - ZUB_SEGMENT_SIZE);
  925.   }//for
  926.   return;
  927. }//Dbtup::allocRestartUndoBufferSegment()