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

MySQL数据库

开发平台:

Visual C++

  1.       break;
  2.     }//switch
  3.   }//if
  4.   return;
  5. }//Dblqh::execATTRINFO()
  6. /* ************************************************************************>> */
  7. /*  TUP_ATTRINFO: Interpreted execution in DBTUP generates redo-log info      */
  8. /*  which is sent back to DBLQH for logging. This is because the decision     */
  9. /*  to execute or not is made in DBTUP and thus we cannot start logging until */
  10. /*  DBTUP part has been run.                                                  */
  11. /* ************************************************************************>> */
  12. void Dblqh::execTUP_ATTRINFO(Signal* signal) 
  13. {
  14.   TcConnectionrec *regTcConnectionrec = tcConnectionrec;
  15.   Uint32 length = signal->length() - 3;
  16.   Uint32 tcIndex = signal->theData[0];
  17.   Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
  18.   jamEntry();
  19.   tcConnectptr.i = tcIndex;
  20.   ptrCheckGuard(tcConnectptr, ttcConnectrecFileSize, regTcConnectionrec);
  21.   ndbrequire(tcConnectptr.p->transactionState == TcConnectionrec::WAIT_TUP);
  22.   if (saveTupattrbuf(signal, &signal->theData[3], length) == ZOK) {
  23.     return;
  24.   } else {
  25.     jam();
  26. /* ------------------------------------------------------------------------- */
  27. /* WE ARE WAITING FOR RESPONSE FROM TUP HERE. THUS WE NEED TO                */
  28. /* GO THROUGH THE STATE MACHINE FOR THE OPERATION.                           */
  29. /* ------------------------------------------------------------------------- */
  30.     localAbortStateHandlerLab(signal);
  31.   }//if
  32. }//Dblqh::execTUP_ATTRINFO()
  33. /* ------------------------------------------------------------------------- */
  34. /* -------                HANDLE ATTRINFO FROM LQH                   ------- */
  35. /*                                                                           */
  36. /* ------------------------------------------------------------------------- */
  37. void Dblqh::lqhAttrinfoLab(Signal* signal, Uint32* dataPtr, Uint32 length) 
  38. {
  39.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  40.   if (regTcPtr->operation != ZREAD) {
  41.     if (regTcPtr->opExec != 1) {
  42.       if (saveTupattrbuf(signal, dataPtr, length) == ZOK) {
  43.         ;
  44.       } else {
  45.         jam();
  46. /* ------------------------------------------------------------------------- */
  47. /* WE MIGHT BE WAITING FOR RESPONSE FROM SOME BLOCK HERE. THUS WE NEED TO    */
  48. /* GO THROUGH THE STATE MACHINE FOR THE OPERATION.                           */
  49. /* ------------------------------------------------------------------------- */
  50.         localAbortStateHandlerLab(signal);
  51.         return;
  52.       }//if
  53.     }//if
  54.   }//if
  55.   Uint32 sig0 = regTcPtr->tupConnectrec;
  56.   Uint32 blockNo = refToBlock(regTcPtr->tcTupBlockref);
  57.   signal->theData[0] = sig0;
  58.   EXECUTE_DIRECT(blockNo, GSN_ATTRINFO, signal, length + 3);
  59.   jamEntry();
  60. }//Dblqh::lqhAttrinfoLab()
  61. /* ------------------------------------------------------------------------- */
  62. /* ------         FIND TRANSACTION BY USING HASH TABLE               ------- */
  63. /*                                                                           */
  64. /* ------------------------------------------------------------------------- */
  65. int Dblqh::findTransaction(UintR Transid1, UintR Transid2, UintR TcOprec) 
  66. {
  67.   TcConnectionrec *regTcConnectionrec = tcConnectionrec;
  68.   Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
  69.   TcConnectionrecPtr locTcConnectptr;
  70.   Uint32 ThashIndex = (Transid1 ^ TcOprec) & 1023;
  71.   locTcConnectptr.i = ctransidHash[ThashIndex];
  72.   while (locTcConnectptr.i != RNIL) {
  73.     ptrCheckGuard(locTcConnectptr, ttcConnectrecFileSize, regTcConnectionrec);
  74.     if ((locTcConnectptr.p->transid[0] == Transid1) &&
  75.         (locTcConnectptr.p->transid[1] == Transid2) &&
  76.         (locTcConnectptr.p->tcOprec == TcOprec)) {
  77. /* FIRST PART OF TRANSACTION CORRECT */
  78. /* SECOND PART ALSO CORRECT */
  79. /* THE OPERATION RECORD POINTER IN TC WAS ALSO CORRECT */
  80.       jam();
  81.       tcConnectptr.i = locTcConnectptr.i;
  82.       tcConnectptr.p = locTcConnectptr.p;
  83.       return (int)ZOK;
  84.     }//if
  85.     jam();
  86. /* THIS WAS NOT THE TRANSACTION WHICH WAS SOUGHT */
  87.     locTcConnectptr.i = locTcConnectptr.p->nextHashRec;
  88.   }//while
  89. /* WE DID NOT FIND THE TRANSACTION, REPORT NOT FOUND */
  90.   return (int)ZNOT_FOUND;
  91. }//Dblqh::findTransaction()
  92. /* ------------------------------------------------------------------------- */
  93. /* -------       SAVE ATTRINFO FROM TUP IN ATTRINBUF                 ------- */
  94. /*                                                                           */
  95. /* ------------------------------------------------------------------------- */
  96. int Dblqh::saveTupattrbuf(Signal* signal, Uint32* dataPtr, Uint32 length) 
  97. {
  98.   Uint32 tfirstfreeAttrinbuf = cfirstfreeAttrinbuf;
  99.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  100.   Uint32 currTupAiLen = regTcPtr->currTupAiLen;
  101.   if (tfirstfreeAttrinbuf == RNIL) {
  102.     jam();
  103.     terrorCode = ZGET_ATTRINBUF_ERROR;
  104.     return ZGET_ATTRINBUF_ERROR;
  105.   }//if
  106.   seizeAttrinbuf(signal);
  107.   Attrbuf * const regAttrPtr = attrinbufptr.p;
  108.   MEMCOPY_NO_WORDS(&regAttrPtr->attrbuf[0], dataPtr, length);
  109.   regTcPtr->currTupAiLen = currTupAiLen + length;
  110.   regAttrPtr->attrbuf[ZINBUF_DATA_LEN] = length;
  111.   return ZOK;
  112. }//Dblqh::saveTupattrbuf()
  113. /* ==========================================================================
  114.  * =======                       SEIZE ATTRIBUTE IN BUFFER            ======= 
  115.  *
  116.  *       GET A NEW ATTRINBUF AND SETS ATTRINBUFPTR.
  117.  * ========================================================================= */
  118. void Dblqh::seizeAttrinbuf(Signal* signal) 
  119. {
  120.   AttrbufPtr tmpAttrinbufptr;
  121.   AttrbufPtr regAttrinbufptr;
  122.   Attrbuf *regAttrbuf = attrbuf;
  123.   Uint32 tattrinbufFileSize = cattrinbufFileSize;
  124.   regAttrinbufptr.i = seize_attrinbuf();
  125.   tmpAttrinbufptr.i = tcConnectptr.p->lastAttrinbuf;
  126.   ptrCheckGuard(regAttrinbufptr, tattrinbufFileSize, regAttrbuf);
  127.   tcConnectptr.p->lastAttrinbuf = regAttrinbufptr.i;
  128.   regAttrinbufptr.p->attrbuf[ZINBUF_DATA_LEN] = 0;
  129.   if (tmpAttrinbufptr.i == RNIL) {
  130.     jam();
  131.     tcConnectptr.p->firstAttrinbuf = regAttrinbufptr.i;
  132.   } else {
  133.     jam();
  134.     ptrCheckGuard(tmpAttrinbufptr, tattrinbufFileSize, regAttrbuf);
  135.     tmpAttrinbufptr.p->attrbuf[ZINBUF_NEXT] = regAttrinbufptr.i;
  136.   }//if
  137.   regAttrinbufptr.p->attrbuf[ZINBUF_NEXT] = RNIL;
  138.   attrinbufptr = regAttrinbufptr;
  139. }//Dblqh::seizeAttrinbuf()
  140. /* ==========================================================================
  141.  * =======                        SEIZE TC CONNECT RECORD             ======= 
  142.  * 
  143.  *       GETS A NEW TC CONNECT RECORD FROM FREELIST.
  144.  * ========================================================================= */
  145. void Dblqh::seizeTcrec() 
  146. {
  147.   TcConnectionrecPtr locTcConnectptr;
  148.   locTcConnectptr.i = cfirstfreeTcConrec;
  149.   ptrCheckGuard(locTcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  150.   Uint32 nextTc = locTcConnectptr.p->nextTcConnectrec;
  151.   locTcConnectptr.p->nextTcConnectrec = RNIL;
  152.   locTcConnectptr.p->clientConnectrec = RNIL;
  153.   locTcConnectptr.p->clientBlockref = RNIL;
  154.   locTcConnectptr.p->abortState = TcConnectionrec::ABORT_IDLE;
  155.   locTcConnectptr.p->tcTimer = cLqhTimeOutCount;
  156.   locTcConnectptr.p->tableref = RNIL;
  157.   locTcConnectptr.p->savePointId = 0;
  158.   cfirstfreeTcConrec = nextTc;
  159.   tcConnectptr = locTcConnectptr;
  160.   locTcConnectptr.p->connectState = TcConnectionrec::CONNECTED;
  161. }//Dblqh::seizeTcrec()
  162. /* ==========================================================================
  163.  * =======                          SEIZE DATA BUFFER                 ======= 
  164.  * ========================================================================= */
  165. void Dblqh::seizeTupkeybuf(Signal* signal) 
  166. {
  167.   Databuf *regDatabuf = databuf;
  168.   DatabufPtr tmpDatabufptr;
  169.   DatabufPtr regDatabufptr;
  170.   Uint32 tdatabufFileSize = cdatabufFileSize;
  171. /* ------- GET A DATABUF. ------- */
  172.   regDatabufptr.i = cfirstfreeDatabuf;
  173.   tmpDatabufptr.i = tcConnectptr.p->lastTupkeybuf;
  174.   ptrCheckGuard(regDatabufptr, tdatabufFileSize, regDatabuf);
  175.   Uint32 nextFirst = regDatabufptr.p->nextDatabuf;
  176.   tcConnectptr.p->lastTupkeybuf = regDatabufptr.i;
  177.   if (tmpDatabufptr.i == RNIL) {
  178.     jam();
  179.     tcConnectptr.p->firstTupkeybuf = regDatabufptr.i;
  180.   } else {
  181.     jam();
  182.     ptrCheckGuard(tmpDatabufptr, tdatabufFileSize, regDatabuf);
  183.     tmpDatabufptr.p->nextDatabuf = regDatabufptr.i;
  184.   }//if
  185.   cfirstfreeDatabuf = nextFirst;
  186.   regDatabufptr.p->nextDatabuf = RNIL;
  187.   databufptr = regDatabufptr;
  188. }//Dblqh::seizeTupkeybuf()
  189. /* ------------------------------------------------------------------------- */
  190. /* -------                TAKE CARE OF LQHKEYREQ                     ------- */
  191. /* LQHKEYREQ IS THE SIGNAL THAT STARTS ALL OPERATIONS IN THE LQH BLOCK       */
  192. /* THIS SIGNAL CONTAINS A LOT OF INFORMATION ABOUT WHAT TYPE OF OPERATION,   */
  193. /* KEY INFORMATION, ATTRIBUTE INFORMATION, NODE INFORMATION AND A LOT MORE   */
  194. /* ------------------------------------------------------------------------- */
  195. void Dblqh::execLQHKEYREQ(Signal* signal) 
  196. {
  197.   UintR sig0, sig1, sig2, sig3, sig4, sig5;
  198.   Uint8 tfragDistKey;
  199.   const LqhKeyReq * const lqhKeyReq = (LqhKeyReq *)signal->getDataPtr();
  200.   sig0 = lqhKeyReq->clientConnectPtr;
  201.   if (cfirstfreeTcConrec != RNIL && !ERROR_INSERTED(5031)) {
  202.     jamEntry();
  203.     seizeTcrec();
  204.   } else {
  205. /* ------------------------------------------------------------------------- */
  206. /* NO FREE TC RECORD AVAILABLE, THUS WE CANNOT HANDLE THE REQUEST.           */
  207. /* ------------------------------------------------------------------------- */
  208.     if (ERROR_INSERTED(5031)) {
  209.       CLEAR_ERROR_INSERT_VALUE;
  210.     }
  211.     noFreeRecordLab(signal, lqhKeyReq, ZNO_TC_CONNECT_ERROR);
  212.     return;
  213.   }//if
  214.   if(ERROR_INSERTED(5038) && 
  215.      refToNode(signal->getSendersBlockRef()) != getOwnNodeId()){
  216.     jam();
  217.     SET_ERROR_INSERT_VALUE(5039);
  218.     return;
  219.   }
  220.   
  221.   c_Counters.operations++;
  222.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  223.   regTcPtr->clientBlockref = signal->senderBlockRef();
  224.   regTcPtr->clientConnectrec = sig0;
  225.   regTcPtr->tcOprec = sig0;
  226.   regTcPtr->storedProcId = ZNIL;
  227.   UintR TtotReclenAi = lqhKeyReq->attrLen;
  228.   sig1 = lqhKeyReq->savePointId;
  229.   sig2 = lqhKeyReq->hashValue;
  230.   UintR Treqinfo = lqhKeyReq->requestInfo;
  231.   sig4 = lqhKeyReq->tableSchemaVersion;
  232.   sig5 = lqhKeyReq->tcBlockref;
  233.   regTcPtr->savePointId = sig1;
  234.   regTcPtr->hashValue = sig2;
  235.   const Uint32 schemaVersion = regTcPtr->schemaVersion = LqhKeyReq::getSchemaVersion(sig4);
  236.   tabptr.i = LqhKeyReq::getTableId(sig4);
  237.   regTcPtr->tcBlockref = sig5;
  238.   const Uint8 op = LqhKeyReq::getOperation(Treqinfo);
  239.   if (op == ZREAD && !getAllowRead()){
  240.     noFreeRecordLab(signal, lqhKeyReq, ZNODE_SHUTDOWN_IN_PROGESS);
  241.     return;
  242.   }
  243.   regTcPtr->totReclenAi = LqhKeyReq::getAttrLen(TtotReclenAi);
  244.   regTcPtr->tcScanInfo  = lqhKeyReq->scanInfo;
  245.   regTcPtr->indTakeOver = LqhKeyReq::getScanTakeOverFlag(TtotReclenAi);
  246.   regTcPtr->readlenAi = 0;
  247.   regTcPtr->currTupAiLen = 0;
  248.   regTcPtr->listState = TcConnectionrec::NOT_IN_LIST;
  249.   regTcPtr->logWriteState = TcConnectionrec::NOT_STARTED;
  250.   regTcPtr->fragmentptr = RNIL;
  251.   sig0 = lqhKeyReq->fragmentData;
  252.   sig1 = lqhKeyReq->transId1;
  253.   sig2 = lqhKeyReq->transId2;
  254.   sig3 = lqhKeyReq->variableData[0];
  255.   sig4 = lqhKeyReq->variableData[1];
  256.   regTcPtr->fragmentid = LqhKeyReq::getFragmentId(sig0);
  257.   regTcPtr->nextReplica = LqhKeyReq::getNextReplicaNodeId(sig0);
  258.   regTcPtr->transid[0] = sig1;
  259.   regTcPtr->transid[1] = sig2;
  260.   regTcPtr->applRef = sig3;
  261.   regTcPtr->applOprec = sig4;
  262.   regTcPtr->commitAckMarker = RNIL;
  263.   if(LqhKeyReq::getMarkerFlag(Treqinfo)){
  264.     jam();
  265.     
  266.     CommitAckMarkerPtr markerPtr;
  267.     m_commitAckMarkerHash.seize(markerPtr);
  268.     if(markerPtr.i == RNIL){
  269.       noFreeRecordLab(signal, lqhKeyReq, ZNO_FREE_MARKER_RECORDS_ERROR);
  270.       return;
  271.     }
  272.     markerPtr.p->transid1 = sig1;
  273.     markerPtr.p->transid2 = sig2;
  274.     markerPtr.p->apiRef   = sig3;
  275.     markerPtr.p->apiOprec = sig4;
  276.     const NodeId tcNodeId  = refToNode(sig5);
  277.     markerPtr.p->tcNodeId = tcNodeId;
  278.     
  279.     CommitAckMarkerPtr tmp;
  280. #ifdef VM_TRACE
  281. #ifdef MARKER_TRACE
  282.     ndbout_c("Add marker[%.8x %.8x]", markerPtr.p->transid1, markerPtr.p->transid2);
  283. #endif
  284.     ndbrequire(!m_commitAckMarkerHash.find(tmp, * markerPtr.p));
  285. #endif
  286.     m_commitAckMarkerHash.add(markerPtr);
  287.     regTcPtr->commitAckMarker = markerPtr.i;
  288.   } 
  289.   
  290.   regTcPtr->reqinfo = Treqinfo;
  291.   regTcPtr->lastReplicaNo = LqhKeyReq::getLastReplicaNo(Treqinfo);
  292.   regTcPtr->lockType      = LqhKeyReq::getLockType(Treqinfo);
  293.   regTcPtr->dirtyOp       = LqhKeyReq::getDirtyFlag(Treqinfo);
  294.   regTcPtr->opExec        = LqhKeyReq::getInterpretedFlag(Treqinfo);
  295.   regTcPtr->opSimple      = LqhKeyReq::getSimpleFlag(Treqinfo);
  296.   regTcPtr->operation     = LqhKeyReq::getOperation(Treqinfo);
  297.   regTcPtr->simpleRead    = regTcPtr->operation == ZREAD && regTcPtr->opSimple;
  298.   regTcPtr->seqNoReplica  = LqhKeyReq::getSeqNoReplica(Treqinfo);
  299.   UintR TreclenAiLqhkey   = LqhKeyReq::getAIInLqhKeyReq(Treqinfo);
  300.   regTcPtr->apiVersionNo  = 0; 
  301.   
  302.   CRASH_INSERTION2(5041, regTcPtr->simpleRead && 
  303.    refToNode(signal->senderBlockRef()) != cownNodeid);
  304.   
  305.   regTcPtr->reclenAiLqhkey = TreclenAiLqhkey;
  306.   regTcPtr->currReclenAi = TreclenAiLqhkey;
  307.   UintR TitcKeyLen = LqhKeyReq::getKeyLen(Treqinfo);
  308.   regTcPtr->primKeyLen = TitcKeyLen;
  309.   regTcPtr->noFiredTriggers = lqhKeyReq->noFiredTriggers;
  310.   UintR TapplAddressInd = LqhKeyReq::getApplicationAddressFlag(Treqinfo);
  311.   UintR nextPos = (TapplAddressInd << 1);
  312.   UintR TsameClientAndTcOprec = LqhKeyReq::getSameClientAndTcFlag(Treqinfo);
  313.   if (TsameClientAndTcOprec == 1) {
  314.     regTcPtr->tcOprec = lqhKeyReq->variableData[nextPos];
  315.     nextPos++;
  316.   }//if
  317.   UintR TnextReplicasIndicator = regTcPtr->lastReplicaNo - 
  318.                                  regTcPtr->seqNoReplica;
  319.   if (TnextReplicasIndicator > 1) {
  320.     regTcPtr->nodeAfterNext[0] = lqhKeyReq->variableData[nextPos] & 0xFFFF;
  321.     regTcPtr->nodeAfterNext[1] = lqhKeyReq->variableData[nextPos] >> 16;
  322.     nextPos++;
  323.   }//if
  324.   UintR TstoredProcIndicator = LqhKeyReq::getStoredProcFlag(TtotReclenAi);
  325.   if (TstoredProcIndicator == 1) {
  326.     regTcPtr->storedProcId = lqhKeyReq->variableData[nextPos] & ZNIL;
  327.     nextPos++;
  328.   }//if
  329.   UintR TreadLenAiIndicator = LqhKeyReq::getReturnedReadLenAIFlag(Treqinfo);
  330.   if (TreadLenAiIndicator == 1) {
  331.     regTcPtr->readlenAi = lqhKeyReq->variableData[nextPos] & ZNIL;
  332.     nextPos++;
  333.   }//if
  334.   sig0 = lqhKeyReq->variableData[nextPos + 0];
  335.   sig1 = lqhKeyReq->variableData[nextPos + 1];
  336.   sig2 = lqhKeyReq->variableData[nextPos + 2];
  337.   sig3 = lqhKeyReq->variableData[nextPos + 3];
  338.   regTcPtr->tupkeyData[0] = sig0;
  339.   regTcPtr->tupkeyData[1] = sig1;
  340.   regTcPtr->tupkeyData[2] = sig2;
  341.   regTcPtr->tupkeyData[3] = sig3;
  342.   if (TitcKeyLen > 0) {
  343.     if (TitcKeyLen < 4) {
  344.       nextPos += TitcKeyLen;
  345.     } else {
  346.       nextPos += 4;
  347.     }//if
  348.   } else {
  349.     LQHKEY_error(signal, 3);
  350.     return;
  351.   }//if
  352.   if ((LqhKeyReq::FixedSignalLength + nextPos + TreclenAiLqhkey) != 
  353.       signal->length()) {
  354.     LQHKEY_error(signal, 2);
  355.     return;
  356.   }//if
  357.   UintR TseqNoReplica = regTcPtr->seqNoReplica;
  358.   UintR TlastReplicaNo = regTcPtr->lastReplicaNo;
  359.   if (TseqNoReplica == TlastReplicaNo) {
  360.     jam();
  361.     regTcPtr->nextReplica = ZNIL;
  362.   } else {
  363.     if (TseqNoReplica < TlastReplicaNo) {
  364.       jam();
  365.       regTcPtr->nextSeqNoReplica = TseqNoReplica + 1;
  366.       if ((regTcPtr->nextReplica == 0) ||
  367.           (regTcPtr->nextReplica == cownNodeid)) {
  368.         LQHKEY_error(signal, 0);
  369.       }//if
  370.     } else {
  371.       LQHKEY_error(signal, 4);
  372.       return;
  373.     }//if
  374.   }//if
  375.   TcConnectionrecPtr localNextTcConnectptr;
  376.   Uint32 hashIndex = (regTcPtr->transid[0] ^ regTcPtr->tcOprec) & 1023;
  377.   localNextTcConnectptr.i = ctransidHash[hashIndex];
  378.   ctransidHash[hashIndex] = tcConnectptr.i;
  379.   regTcPtr->prevHashRec = RNIL;
  380.   regTcPtr->nextHashRec = localNextTcConnectptr.i;
  381.   if (localNextTcConnectptr.i != RNIL) {
  382. /* -------------------------------------------------------------------------- */
  383. /* ENSURE THAT THE NEXT RECORD HAS SET PREVIOUS TO OUR RECORD IF IT EXISTS    */
  384. /* -------------------------------------------------------------------------- */
  385.     ptrCheckGuard(localNextTcConnectptr, 
  386.                   ctcConnectrecFileSize, tcConnectionrec);
  387.     jam();
  388.     localNextTcConnectptr.p->prevHashRec = tcConnectptr.i;
  389.   }//if
  390.   if (tabptr.i >= ctabrecFileSize) {
  391.     LQHKEY_error(signal, 5);
  392.     return;
  393.   }//if
  394.   ptrAss(tabptr, tablerec);
  395.   if(tabptr.p->tableStatus != Tablerec::TABLE_DEFINED){
  396.     LQHKEY_abort(signal, 4);
  397.     return;
  398.   }
  399.   if(table_version_major(tabptr.p->schemaVersion) != 
  400.      table_version_major(schemaVersion)){
  401.     LQHKEY_abort(signal, 5);
  402.     return;
  403.   }
  404.   regTcPtr->tableref = tabptr.i;
  405.   tabptr.p->usageCount++;
  406.   
  407.   if (!getFragmentrec(signal, regTcPtr->fragmentid)) {
  408.     LQHKEY_error(signal, 6);
  409.     return;
  410.   }//if
  411.   regTcPtr->localFragptr = (regTcPtr->hashValue >> fragptr.p->hashCheckBit) & 1;
  412.   Uint8 TcopyType = fragptr.p->fragCopy;
  413.   tfragDistKey = fragptr.p->fragDistributionKey;
  414.   if (fragptr.p->fragStatus == Fragrecord::ACTIVE_CREATION) {
  415.     jam();
  416.     regTcPtr->activeCreat = ZTRUE;
  417.     CRASH_INSERTION(5002);
  418.   } else {
  419.     regTcPtr->activeCreat = ZFALSE;
  420.   }//if
  421.   regTcPtr->replicaType = TcopyType;
  422.   regTcPtr->fragmentptr = fragptr.i;
  423.   Uint8 TdistKey = LqhKeyReq::getDistributionKey(TtotReclenAi);
  424.   if ((tfragDistKey != TdistKey) &&
  425.       (regTcPtr->seqNoReplica == 0) &&
  426.       (regTcPtr->dirtyOp == ZFALSE) &&
  427.       (regTcPtr->simpleRead == ZFALSE)) {
  428.     /* ----------------------------------------------------------------------
  429.      * WE HAVE DIFFERENT OPINION THAN THE DIH THAT STARTED THE TRANSACTION. 
  430.      * THE REASON COULD BE THAT THIS IS AN OLD DISTRIBUTION WHICH IS NO LONGER
  431.      * VALID TO USE. THIS MUST BE CHECKED.
  432.      * ONE IS ADDED TO THE DISTRIBUTION KEY EVERY TIME WE ADD A NEW REPLICA.
  433.      * FAILED REPLICAS DO NOT AFFECT THE DISTRIBUTION KEY. THIS MEANS THAT THE 
  434.      * MAXIMUM DEVIATION CAN BE ONE BETWEEN THOSE TWO VALUES.              
  435.      * --------------------------------------------------------------------- */
  436.     Int32 tmp = TdistKey - tfragDistKey;
  437.     tmp = (tmp < 0 ? - tmp : tmp);
  438.     if ((tmp <= 1) || (tfragDistKey == 0)) {
  439.       LQHKEY_abort(signal, 0);
  440.       return;
  441.     }//if
  442.     LQHKEY_error(signal, 1);
  443.   }//if
  444.   if (TreclenAiLqhkey != 0) {
  445.     if (regTcPtr->operation != ZREAD) {
  446.       if (regTcPtr->operation != ZDELETE) {
  447.         if (regTcPtr->opExec != 1) {
  448.           jam();
  449. /*---------------------------------------------------------------------------*/
  450. /*                                                                           */
  451. /* UPDATES, WRITES AND INSERTS THAT ARE NOT INTERPRETED WILL USE THE         */
  452. /* SAME ATTRINFO IN ALL REPLICAS. THUS WE SAVE THE ATTRINFO ALREADY          */
  453. /* TO SAVE A SIGNAL FROM TUP TO LQH. INTERPRETED EXECUTION IN TUP            */
  454. /* WILL CREATE NEW ATTRINFO FOR THE OTHER REPLICAS AND IT IS THUS NOT        */
  455. /* A GOOD IDEA TO SAVE THE INFORMATION HERE. READS WILL ALSO BE              */
  456. /* UNNECESSARY TO SAVE SINCE THAT ATTRINFO WILL NEVER BE SENT TO ANY         */
  457. /* MORE REPLICAS.                                                            */
  458. /*---------------------------------------------------------------------------*/
  459. /* READS AND DELETES CAN ONLY HAVE INFORMATION ABOUT WHAT IS TO BE READ.     */
  460. /* NO INFORMATION THAT NEEDS LOGGING.                                        */
  461. /*---------------------------------------------------------------------------*/
  462.           sig0 = lqhKeyReq->variableData[nextPos + 0];
  463.           sig1 = lqhKeyReq->variableData[nextPos + 1];
  464.           sig2 = lqhKeyReq->variableData[nextPos + 2];
  465.           sig3 = lqhKeyReq->variableData[nextPos + 3];
  466.           sig4 = lqhKeyReq->variableData[nextPos + 4];
  467.           regTcPtr->firstAttrinfo[0] = sig0;
  468.           regTcPtr->firstAttrinfo[1] = sig1;
  469.           regTcPtr->firstAttrinfo[2] = sig2;
  470.           regTcPtr->firstAttrinfo[3] = sig3;
  471.           regTcPtr->firstAttrinfo[4] = sig4;
  472.           regTcPtr->currTupAiLen = TreclenAiLqhkey;
  473.         } else {
  474.           jam();
  475.           regTcPtr->reclenAiLqhkey = 0;
  476.         }//if
  477.       } else {
  478.         jam();
  479.         regTcPtr->reclenAiLqhkey = 0;
  480.       }//if
  481.     }//if
  482.     sig0 = lqhKeyReq->variableData[nextPos + 0];
  483.     sig1 = lqhKeyReq->variableData[nextPos + 1];
  484.     sig2 = lqhKeyReq->variableData[nextPos + 2];
  485.     sig3 = lqhKeyReq->variableData[nextPos + 3];
  486.     sig4 = lqhKeyReq->variableData[nextPos + 4];
  487.     signal->theData[0] = regTcPtr->tupConnectrec;
  488.     signal->theData[3] = sig0;
  489.     signal->theData[4] = sig1;
  490.     signal->theData[5] = sig2;
  491.     signal->theData[6] = sig3;
  492.     signal->theData[7] = sig4;
  493.     EXECUTE_DIRECT(refToBlock(regTcPtr->tcTupBlockref), GSN_ATTRINFO, 
  494.    signal, TreclenAiLqhkey + 3);
  495.     jamEntry();
  496.     if (signal->theData[0] == (UintR)-1) {
  497.       LQHKEY_abort(signal, 2);
  498.       return;
  499.     }//if
  500.   }//if
  501. /* ------- TAKE CARE OF PRIM KEY DATA ------- */
  502.   if (regTcPtr->primKeyLen <= 4) {
  503.     endgettupkeyLab(signal);
  504.     return;
  505.   } else {
  506.     jam();
  507. /*--------------------------------------------------------------------*/
  508. /*       KEY LENGTH WAS MORE THAN 4 WORDS (WORD = 4 BYTE). THUS WE    */
  509. /*       HAVE TO ALLOCATE A DATA BUFFER TO STORE THE KEY DATA AND     */
  510. /*       WAIT FOR THE KEYINFO SIGNAL.                                 */
  511. /*--------------------------------------------------------------------*/
  512.     regTcPtr->save1 = 4;
  513.     regTcPtr->transactionState = TcConnectionrec::WAIT_TUPKEYINFO;
  514.     return;
  515.   }//if
  516.   return;
  517. }//Dblqh::execLQHKEYREQ()
  518. void Dblqh::endgettupkeyLab(Signal* signal) 
  519. {
  520.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  521.   if (regTcPtr->totReclenAi == regTcPtr->currReclenAi) {
  522.     ;
  523.   } else {
  524.     jam();
  525.     ndbrequire(regTcPtr->currReclenAi < regTcPtr->totReclenAi);
  526.     regTcPtr->transactionState = TcConnectionrec::WAIT_ATTR;
  527.     return;
  528.   }//if
  529. /* ---------------------------------------------------------------------- */
  530. /*       NOW RECEPTION OF LQHKEYREQ IS COMPLETED THE NEXT STEP IS TO START*/
  531. /*       PROCESSING THE MESSAGE. IF THE MESSAGE IS TO A STAND-BY NODE     */
  532. /*       WITHOUT NETWORK REDUNDANCY OR PREPARE-TO-COMMIT ACTIVATED THE    */
  533. /*       PREPARATION TO SEND TO THE NEXT NODE WILL START IMMEDIATELY.     */
  534. /*                                                                        */
  535. /*       OTHERWISE THE PROCESSING WILL START AFTER SETTING THE PROPER     */
  536. /*       STATE. HOWEVER BEFORE PROCESSING THE MESSAGE                     */
  537. /*       IT IS NECESSARY TO CHECK THAT THE FRAGMENT IS NOT PERFORMING     */
  538. /*       A CHECKPOINT. THE OPERATION SHALL ALSO BE LINKED INTO THE        */
  539. /*       FRAGMENT QUEUE OR LIST OF ACTIVE OPERATIONS.                     */
  540. /*                                                                        */
  541. /*       THE FIRST STEP IN PROCESSING THE MESSAGE IS TO CONTACT DBACC.    */
  542. /*------------------------------------------------------------------------*/
  543.   switch (fragptr.p->fragStatus) {
  544.   case Fragrecord::FSACTIVE:
  545.   case Fragrecord::CRASH_RECOVERING:
  546.   case Fragrecord::ACTIVE_CREATION:
  547.     linkActiveFrag(signal);
  548.     prepareContinueAfterBlockedLab(signal);
  549.     return;
  550.     break;
  551.   case Fragrecord::BLOCKED:
  552.     jam();
  553.     linkFragQueue(signal);
  554.     regTcPtr->transactionState = TcConnectionrec::STOPPED;
  555.     return;
  556.     break;
  557.   case Fragrecord::FREE:
  558.     jam();
  559.   case Fragrecord::DEFINED:
  560.     jam();
  561.   case Fragrecord::REMOVING:
  562.     jam();
  563.   default:
  564.     ndbrequire(false);
  565.     break;
  566.   }//switch
  567.   return;
  568. }//Dblqh::endgettupkeyLab()
  569. void Dblqh::prepareContinueAfterBlockedLab(Signal* signal) 
  570. {
  571.   UintR ttcScanOp;
  572.   UintR taccreq;
  573. /* -------------------------------------------------------------------------- */
  574. /*       INPUT:          TC_CONNECTPTR           ACTIVE CONNECTION RECORD     */
  575. /*                       FRAGPTR                 FRAGMENT RECORD              */
  576. /* -------------------------------------------------------------------------- */
  577. /* -------------------------------------------------------------------------- */
  578. /*  CONTINUE HERE AFTER BEING BLOCKED FOR A WHILE DURING LOCAL CHECKPOINT.    */
  579. /* -------------------------------------------------------------------------- */
  580. /*       ALSO AFTER NORMAL PROCEDURE WE CONTINUE HERE                         */
  581. /* -------------------------------------------------------------------------- */
  582.   Uint32 tc_ptr_i = tcConnectptr.i;
  583.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  584.   if (regTcPtr->indTakeOver == ZTRUE) {
  585.     jam();
  586.     ttcScanOp = KeyInfo20::getScanOp(regTcPtr->tcScanInfo);
  587.     scanptr.i = RNIL;
  588.     {
  589.       ScanRecord key;
  590.       key.scanNumber = KeyInfo20::getScanNo(regTcPtr->tcScanInfo);
  591.       key.fragPtrI = fragptr.i;
  592.       c_scanTakeOverHash.find(scanptr, key);
  593. #ifdef TRACE_SCAN_TAKEOVER
  594.       if(scanptr.i == RNIL)
  595. ndbout_c("not finding (%d %d)", key.scanNumber, key.fragPtrI);
  596. #endif
  597.     }
  598.     if (scanptr.i == RNIL) {
  599.       jam();
  600.       releaseActiveFrag(signal);
  601.       takeOverErrorLab(signal);
  602.       return;
  603.     }//if
  604.     Uint32 accOpPtr= get_acc_ptr_from_scan_record(scanptr.p,
  605.                                                   ttcScanOp,
  606.                                                   true);
  607.     if (accOpPtr == RNIL) {
  608.       jam();
  609.       releaseActiveFrag(signal);
  610.       takeOverErrorLab(signal);
  611.       return;
  612.     }//if
  613.     signal->theData[1] = accOpPtr;
  614.     signal->theData[2] = regTcPtr->transid[0];
  615.     signal->theData[3] = regTcPtr->transid[1];
  616.     EXECUTE_DIRECT(refToBlock(regTcPtr->tcAccBlockref), GSN_ACC_TO_REQ, 
  617.    signal, 4);
  618.     if (signal->theData[0] == (UintR)-1) {
  619.       execACC_TO_REF(signal);
  620.       return;
  621.     }//if
  622.     jamEntry();
  623.   }//if
  624. /*-------------------------------------------------------------------*/
  625. /*       IT IS NOW TIME TO CONTACT ACC. THE TUPLE KEY WILL BE SENT   */
  626. /*       AND THIS WILL BE TRANSLATED INTO A LOCAL KEY BY USING THE   */
  627. /*       LOCAL PART OF THE LH3-ALGORITHM. ALSO PROPER LOCKS ON THE   */
  628. /*       TUPLE WILL BE SET. FOR INSERTS AND DELETES THE MESSAGE WILL */
  629. /*       START AN INSERT/DELETE INTO THE HASH TABLE.                 */
  630. /*                                                                   */
  631. /*       BEFORE SENDING THE MESSAGE THE REQUEST INFORMATION IS SET   */
  632. /*       PROPERLY.                                                   */
  633. /* ----------------------------------------------------------------- */
  634. #if 0
  635.   if (regTcPtr->tableref != 0) {
  636.     switch (regTcPtr->operation) {
  637.     case ZREAD: ndbout << "Läsning "; break;
  638.     case ZUPDATE: ndbout << " Uppdatering "; break;
  639.     case ZWRITE: ndbout << "Write "; break;
  640.     case ZINSERT: ndbout << "Inläggning "; break;
  641.     case ZDELETE: ndbout << "Borttagning "; break;
  642.     default: ndbout << "????"; break;
  643.     }
  644.     ndbout << "med nyckel = " << regTcPtr->tupkeyData[0] << endl;
  645.   }
  646. #endif
  647.   
  648.   regTcPtr->transactionState = TcConnectionrec::WAIT_ACC;
  649.   taccreq = regTcPtr->operation;
  650.   taccreq = taccreq + (regTcPtr->opSimple << 3);
  651.   taccreq = taccreq + (regTcPtr->lockType << 4);
  652.   taccreq = taccreq + (regTcPtr->dirtyOp << 6);
  653.   taccreq = taccreq + (regTcPtr->replicaType << 7);
  654.   taccreq = taccreq + (regTcPtr->apiVersionNo << 9);
  655. /* ************ */
  656. /*  ACCKEYREQ < */
  657. /* ************ */
  658.   ndbrequire(regTcPtr->localFragptr < 2);
  659.   Uint32 sig0, sig1, sig2, sig3, sig4;
  660.   sig0 = regTcPtr->accConnectrec;
  661.   sig1 = fragptr.p->accFragptr[regTcPtr->localFragptr];
  662.   sig2 = regTcPtr->hashValue;
  663.   sig3 = regTcPtr->primKeyLen;
  664.   sig4 = regTcPtr->transid[0];
  665.   signal->theData[0] = sig0;
  666.   signal->theData[1] = sig1;
  667.   signal->theData[2] = taccreq;
  668.   signal->theData[3] = sig2;
  669.   signal->theData[4] = sig3;
  670.   signal->theData[5] = sig4;
  671.   sig0 = regTcPtr->transid[1];
  672.   sig1 = regTcPtr->tupkeyData[0];
  673.   sig2 = regTcPtr->tupkeyData[1];
  674.   sig3 = regTcPtr->tupkeyData[2];
  675.   sig4 = regTcPtr->tupkeyData[3];
  676.   signal->theData[6] = sig0;
  677.   signal->theData[7] = sig1;
  678.   signal->theData[8] = sig2;
  679.   signal->theData[9] = sig3;
  680.   signal->theData[10] = sig4;
  681.   if (regTcPtr->primKeyLen > 4) {
  682.     sendKeyinfoAcc(signal, 11);
  683.   }//if
  684.   EXECUTE_DIRECT(refToBlock(regTcPtr->tcAccBlockref), GSN_ACCKEYREQ, 
  685.  signal, 7 + regTcPtr->primKeyLen);
  686.   if (signal->theData[0] < RNIL) {
  687.     signal->theData[0] = tc_ptr_i;
  688.     execACCKEYCONF(signal);
  689.     return;
  690.   } else if (signal->theData[0] == RNIL) {
  691.     ;
  692.   } else {
  693.     ndbrequire(signal->theData[0] == (UintR)-1);
  694.     signal->theData[0] = tc_ptr_i;
  695.     execACCKEYREF(signal);
  696.   }//if
  697.   return;
  698. }//Dblqh::prepareContinueAfterBlockedLab()
  699. /* ========================================================================== */
  700. /* =======                  SEND KEYINFO TO ACC                       ======= */
  701. /*                                                                            */
  702. /* ========================================================================== */
  703. void Dblqh::sendKeyinfoAcc(Signal* signal, Uint32 Ti) 
  704. {
  705.   DatabufPtr regDatabufptr;
  706.   regDatabufptr.i = tcConnectptr.p->firstTupkeybuf;
  707.   
  708.   do {
  709.     jam();
  710.     ptrCheckGuard(regDatabufptr, cdatabufFileSize, databuf);
  711.     Uint32 sig0 = regDatabufptr.p->data[0];
  712.     Uint32 sig1 = regDatabufptr.p->data[1];
  713.     Uint32 sig2 = regDatabufptr.p->data[2];
  714.     Uint32 sig3 = regDatabufptr.p->data[3];
  715.     signal->theData[Ti] = sig0;
  716.     signal->theData[Ti + 1] = sig1;
  717.     signal->theData[Ti + 2] = sig2;
  718.     signal->theData[Ti + 3] = sig3;
  719.     regDatabufptr.i = regDatabufptr.p->nextDatabuf;
  720.     Ti += 4;
  721.   } while (regDatabufptr.i != RNIL);
  722. }//Dblqh::sendKeyinfoAcc()
  723. void Dblqh::execLQH_ALLOCREQ(Signal* signal)
  724. {
  725.   TcConnectionrecPtr regTcPtr;  
  726.   FragrecordPtr regFragptr;
  727.   jamEntry();
  728.   regTcPtr.i = signal->theData[0];
  729.   ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec);
  730.   regFragptr.i = regTcPtr.p->fragmentptr;
  731.   ptrCheckGuard(regFragptr, cfragrecFileSize, fragrecord);
  732.   ndbrequire(regTcPtr.p->localFragptr < 2);
  733.   signal->theData[0] = regTcPtr.p->tupConnectrec;
  734.   signal->theData[1] = regFragptr.p->tupFragptr[regTcPtr.p->localFragptr];
  735.   signal->theData[2] = regTcPtr.p->tableref;
  736.   Uint32 tup = refToBlock(regTcPtr.p->tcTupBlockref);
  737.   EXECUTE_DIRECT(tup, GSN_TUP_ALLOCREQ, signal, 3);
  738. }//Dblqh::execTUP_ALLOCREQ()
  739. /* ************>> */
  740. /*  ACCKEYCONF  > */
  741. /* ************>> */
  742. void Dblqh::execACCKEYCONF(Signal* signal) 
  743. {
  744.   TcConnectionrec *regTcConnectionrec = tcConnectionrec;
  745.   Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
  746.   Uint32 tcIndex = signal->theData[0];
  747.   Uint32 Tfragid = signal->theData[2];
  748.   Uint32 localKey1 = signal->theData[3];
  749.   Uint32 localKey2 = signal->theData[4];
  750.   Uint32 localKeyFlag = signal->theData[5];
  751.   jamEntry();
  752.   tcConnectptr.i = tcIndex;
  753.   ptrCheckGuard(tcConnectptr, ttcConnectrecFileSize, regTcConnectionrec);
  754.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  755.   if (regTcPtr->transactionState != TcConnectionrec::WAIT_ACC) {
  756.     LQHKEY_abort(signal, 3);
  757.     return;
  758.   }//if
  759.   /* ------------------------------------------------------------------------ 
  760.    * Set transaction state and also reset the activeCreat since that is only 
  761.    * valid in cases where the record was not present.
  762.    * ------------------------------------------------------------------------ */
  763.   regTcPtr->transactionState = TcConnectionrec::WAIT_TUP;
  764.   regTcPtr->activeCreat = ZFALSE;
  765.   /* ------------------------------------------------------------------------
  766.    * IT IS NOW TIME TO CONTACT THE TUPLE MANAGER. THE TUPLE MANAGER NEEDS THE
  767.    * INFORMATION ON WHICH TABLE AND FRAGMENT, THE LOCAL KEY AND IT NEEDS TO
  768.    * KNOW THE TYPE OF OPERATION TO PERFORM. TUP CAN SEND THE ATTRINFO DATA 
  769.    * EITHER TO THE TC BLOCK OR DIRECTLY TO THE APPLICATION. THE SCHEMA VERSION
  770.    * IS NEEDED SINCE TWO SCHEMA VERSIONS CAN BE ACTIVE SIMULTANEOUSLY ON A 
  771.    * TABLE.
  772.    * ----------------------------------------------------------------------- */
  773.   if (regTcPtr->operation == ZWRITE) 
  774.   {
  775.     Uint32 op= signal->theData[1];
  776.     if(likely(op == ZINSERT || op == ZUPDATE))
  777.     {
  778.       regTcPtr->operation = op;
  779.     }
  780.     else
  781.     {
  782.       warningEvent("Convering %d to ZUPDATE", op);
  783.       regTcPtr->operation = ZUPDATE;
  784.     }
  785.   }//if
  786.   
  787.   ndbrequire(localKeyFlag == 1);
  788.   localKey2 = localKey1 & MAX_TUPLES_PER_PAGE;
  789.   localKey1 = localKey1 >> MAX_TUPLES_BITS;
  790.   Uint32 Ttupreq = regTcPtr->dirtyOp;
  791.   Ttupreq = Ttupreq + (regTcPtr->opSimple << 1);
  792.   Ttupreq = Ttupreq + (regTcPtr->operation << 6);
  793.   Ttupreq = Ttupreq + (regTcPtr->opExec << 10);
  794.   Ttupreq = Ttupreq + (regTcPtr->apiVersionNo << 11);
  795.   /* --------------------------------------------------------------------- 
  796.    * Clear interpreted mode bit since we do not want the next replica to
  797.    * use interpreted mode. The next replica will receive a normal write.
  798.    * --------------------------------------------------------------------- */
  799.   regTcPtr->opExec = 0;
  800.   /* ************< */
  801.   /*  TUPKEYREQ  < */
  802.   /* ************< */
  803.   TupKeyReq * const tupKeyReq = (TupKeyReq *)signal->getDataPtrSend();
  804.   Uint32 sig0, sig1, sig2, sig3;
  805.   sig0 = regTcPtr->tupConnectrec;
  806.   sig1 = regTcPtr->tableref;
  807.   tupKeyReq->connectPtr = sig0;
  808.   tupKeyReq->request = Ttupreq;
  809.   tupKeyReq->tableRef = sig1;
  810.   tupKeyReq->fragId = Tfragid;
  811.   tupKeyReq->keyRef1 = localKey1;
  812.   tupKeyReq->keyRef2 = localKey2;
  813.   sig0 = regTcPtr->totReclenAi;
  814.   sig1 = regTcPtr->applOprec;
  815.   sig2 = regTcPtr->applRef;
  816.   sig3 = regTcPtr->schemaVersion;
  817.   FragrecordPtr regFragptr;
  818.   regFragptr.i = regTcPtr->fragmentptr;
  819.   ptrCheckGuard(regFragptr, cfragrecFileSize, fragrecord);
  820.   tupKeyReq->attrBufLen = sig0;
  821.   tupKeyReq->opRef = sig1;
  822.   tupKeyReq->applRef = sig2;
  823.   tupKeyReq->schemaVersion = sig3;
  824.   ndbrequire(regTcPtr->localFragptr < 2);
  825.   sig0 = regTcPtr->storedProcId;
  826.   sig1 = regTcPtr->transid[0];
  827.   sig2 = regTcPtr->transid[1];
  828.   sig3 = regFragptr.p->tupFragptr[regTcPtr->localFragptr];
  829.   Uint32 tup = refToBlock(regTcPtr->tcTupBlockref);
  830.   tupKeyReq->storedProcedure = sig0;
  831.   tupKeyReq->transId1 = sig1;
  832.   tupKeyReq->transId2 = sig2;
  833.   tupKeyReq->fragPtr = sig3;
  834.   tupKeyReq->primaryReplica = (tcConnectptr.p->seqNoReplica == 0)?true:false;
  835.   tupKeyReq->coordinatorTC = tcConnectptr.p->tcBlockref;
  836.   tupKeyReq->tcOpIndex = tcConnectptr.p->tcOprec;
  837.   tupKeyReq->savePointId = tcConnectptr.p->savePointId;
  838.   EXECUTE_DIRECT(tup, GSN_TUPKEYREQ, signal, TupKeyReq::SignalLength);
  839. }//Dblqh::execACCKEYCONF()
  840. /* --------------------------------------------------------------------------
  841.  * -------                       ENTER TUP...                         ------- 
  842.  * ENTER TUPKEYCONF WITH
  843.  *           TC_CONNECTPTR,
  844.  *           TDATA2,     LOCAL KEY REFERENCE 1, ONLY INTERESTING AFTER INSERT
  845.  *           TDATA3,     LOCAL KEY REFERENCE 1, ONLY INTERESTING AFTER INSERT
  846.  *           TDATA4,     TOTAL LENGTH OF READ DATA SENT TO TC/APPLICATION
  847.  *           TDATA5      TOTAL LENGTH OF UPDATE DATA SENT TO/FROM TUP
  848.  *        GOTO TUPKEY_CONF
  849.  *
  850.  *  TAKE CARE OF RESPONSES FROM TUPLE MANAGER.
  851.  * -------------------------------------------------------------------------- */
  852. void Dblqh::tupkeyConfLab(Signal* signal) 
  853. {
  854. /* ---- GET OPERATION TYPE AND CHECK WHAT KIND OF OPERATION IS REQUESTED ---- */
  855.   const TupKeyConf * const tupKeyConf = (TupKeyConf *)&signal->theData[0];
  856.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  857.   if (regTcPtr->simpleRead) {
  858.     jam();
  859.     /* ----------------------------------------------------------------------
  860.      * THE OPERATION IS A SIMPLE READ. WE WILL IMMEDIATELY COMMIT THE OPERATION.
  861.      * SINCE WE HAVE NOT RELEASED THE FRAGMENT LOCK (FOR LOCAL CHECKPOINTS) YET 
  862.      * WE CAN GO IMMEDIATELY TO COMMIT_CONTINUE_AFTER_BLOCKED.
  863.      * WE HAVE ALREADY SENT THE RESPONSE SO WE ARE NOT INTERESTED IN READ LENGTH
  864.      * ---------------------------------------------------------------------- */
  865.     regTcPtr->gci = cnewestGci;
  866.     releaseActiveFrag(signal);
  867.     commitContinueAfterBlockedLab(signal);
  868.     return;
  869.   }//if
  870.   if (tupKeyConf->readLength != 0) {
  871.     jam();
  872.     /* SET BIT 15 IN REQINFO */
  873.     LqhKeyReq::setApplicationAddressFlag(regTcPtr->reqinfo, 1);
  874.     regTcPtr->readlenAi = tupKeyConf->readLength;
  875.   }//if
  876.   regTcPtr->totSendlenAi = tupKeyConf->writeLength;
  877.   ndbrequire(regTcPtr->totSendlenAi == regTcPtr->currTupAiLen);
  878.   rwConcludedLab(signal);
  879.   return;
  880. }//Dblqh::tupkeyConfLab()
  881. /* --------------------------------------------------------------------------
  882.  *     THE CODE IS FOUND IN THE SIGNAL RECEPTION PART OF LQH                 
  883.  * -------------------------------------------------------------------------- */
  884. void Dblqh::rwConcludedLab(Signal* signal) 
  885. {
  886.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  887.   /* ------------------------------------------------------------------------
  888.    *  WE HAVE NOW CONCLUDED READING/WRITING IN ACC AND TUP FOR THIS OPERATION. 
  889.    *  IT IS NOW TIME TO LOG THE OPERATION, SEND REQUEST TO NEXT NODE OR TC AND 
  890.    *  FOR SOME TYPES OF OPERATIONS IT IS EVEN TIME TO COMMIT THE OPERATION.
  891.    * ------------------------------------------------------------------------ */
  892.   if (regTcPtr->operation == ZREAD) {
  893.     jam();
  894.     /* ---------------------------------------------------------------------- 
  895.      * A NORMAL READ OPERATION IS NOT LOGGED BUT IS NOT COMMITTED UNTIL THE 
  896.      * COMMIT SIGNAL ARRIVES. THUS WE CONTINUE PACKING THE RESPONSE.   
  897.      * ---------------------------------------------------------------------- */
  898.     releaseActiveFrag(signal);
  899.     packLqhkeyreqLab(signal);
  900.     return;
  901.   } else {
  902.     FragrecordPtr regFragptr;
  903.     regFragptr.i = regTcPtr->fragmentptr;
  904.     ptrCheckGuard(regFragptr, cfragrecFileSize, fragrecord);
  905.     if (regFragptr.p->logFlag == Fragrecord::STATE_FALSE){
  906.       if (regTcPtr->dirtyOp == ZTRUE) {
  907.         jam();
  908. /* ------------------------------------------------------------------
  909.  * THIS OPERATION WAS A WRITE OPERATION THAT DO NOT NEED LOGGING AND 
  910.  * THAT CAN CAN  BE COMMITTED IMMEDIATELY.                     
  911.  * ------------------------------------------------------------------ */
  912.         regTcPtr->gci = cnewestGci;
  913.         releaseActiveFrag(signal);
  914.         commitContinueAfterBlockedLab(signal);
  915.         return;
  916.       } else {
  917.         jam();
  918. /* ------------------------------------------------------------------
  919.  * A NORMAL WRITE OPERATION ON A FRAGMENT WHICH DO NOT NEED LOGGING.
  920.  * WE WILL PACK THE REQUEST/RESPONSE TO THE NEXT NODE/TO TC.   
  921.  * ------------------------------------------------------------------ */
  922.         regTcPtr->logWriteState = TcConnectionrec::NOT_WRITTEN;
  923.         releaseActiveFrag(signal);
  924.         packLqhkeyreqLab(signal);
  925.         return;
  926.       }//if
  927.     } else {
  928.       jam();
  929.       /* --------------------------------------------------------------------
  930.        * A DIRTY OPERATION WHICH NEEDS LOGGING. WE START BY LOGGING THE 
  931.        * REQUEST. IN THIS CASE WE WILL RELEASE THE FRAGMENT LOCK FIRST.
  932.        * -------------------------------------------------------------------- 
  933.        * A NORMAL WRITE OPERATION THAT NEEDS LOGGING AND WILL NOT BE 
  934.        * PREMATURELY COMMITTED.                                   
  935.        * -------------------------------------------------------------------- */
  936.       releaseActiveFrag(signal);
  937.       logLqhkeyreqLab(signal);
  938.       return;
  939.     }//if
  940.   }//if
  941. }//Dblqh::rwConcludedLab()
  942. void Dblqh::rwConcludedAiLab(Signal* signal) 
  943. {
  944.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  945.   fragptr.i = regTcPtr->fragmentptr;
  946.   /* ------------------------------------------------------------------------
  947.    * WE HAVE NOW CONCLUDED READING/WRITING IN ACC AND TUP FOR THIS OPERATION. 
  948.    * IT IS NOW TIME TO LOG THE OPERATION, SEND REQUEST TO NEXT NODE OR TC AND 
  949.    * FOR SOME TYPES OF OPERATIONS IT IS EVEN TIME TO COMMIT THE OPERATION.
  950.    * IN THIS CASE WE HAVE ALREADY RELEASED THE FRAGMENT LOCK.
  951.    * ERROR CASES AT FRAGMENT CREATION AND STAND-BY NODES ARE THE REASONS FOR
  952.    * COMING HERE.
  953.    * ------------------------------------------------------------------------ */
  954.   if (regTcPtr->operation == ZREAD) {
  955.     if (regTcPtr->opSimple == 1) {
  956.       jam();
  957.       /* --------------------------------------------------------------------
  958.        * THE OPERATION IS A SIMPLE READ. WE WILL IMMEDIATELY COMMIT THE 
  959.        * OPERATION.   
  960.        * -------------------------------------------------------------------- */
  961.       regTcPtr->gci = cnewestGci;
  962.       localCommitLab(signal);
  963.       return;
  964.     } else {
  965.       jam();
  966.       /* --------------------------------------------------------------------
  967.        * A NORMAL READ OPERATION IS NOT LOGGED BUT IS NOT COMMITTED UNTIL 
  968.        * THE COMMIT SIGNAL ARRIVES. THUS WE CONTINUE PACKING THE RESPONSE.
  969.        * -------------------------------------------------------------------- */
  970.       ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  971.       packLqhkeyreqLab(signal);
  972.       return;
  973.     }//if
  974.   } else {
  975.     jam();
  976.     ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  977.     if (fragptr.p->logFlag == Fragrecord::STATE_FALSE) {
  978.       if (regTcPtr->dirtyOp == ZTRUE) {
  979. /* ------------------------------------------------------------------
  980.  * THIS OPERATION WAS A WRITE OPERATION THAT DO NOT NEED LOGGING AND 
  981.  * THAT CAN CAN  BE COMMITTED IMMEDIATELY. 
  982.  * ------------------------------------------------------------------ */
  983.         jam();
  984.   /* ----------------------------------------------------------------
  985.    * IT MUST BE ACTIVE CREATION OF A FRAGMENT.
  986.    * ---------------------------------------------------------------- */
  987.         regTcPtr->gci = cnewestGci;
  988.         localCommitLab(signal);
  989.         return;
  990.       } else {
  991. /* ------------------------------------------------------------------
  992.  * A NORMAL WRITE OPERATION ON A FRAGMENT WHICH DO NOT NEED LOGGING. 
  993.  * WE WILL PACK THE REQUEST/RESPONSE TO THE NEXT NODE/TO TC. 
  994.  * ------------------------------------------------------------------ */
  995.         jam();
  996.   /* ---------------------------------------------------------------
  997.    * IT MUST BE ACTIVE CREATION OF A FRAGMENT.          
  998.    * NOT A DIRTY OPERATION THUS PACK REQUEST/RESPONSE.
  999.    * ---------------------------------------------------------------- */
  1000.         regTcPtr->logWriteState = TcConnectionrec::NOT_WRITTEN;
  1001.         packLqhkeyreqLab(signal);
  1002.         return;
  1003.       }//if
  1004.     } else {
  1005.       jam();
  1006.       /* -------------------------------------------------------------------- 
  1007.        * A DIRTY OPERATION WHICH NEEDS LOGGING. WE START BY LOGGING THE 
  1008.        * REQUEST. IN THIS CASE WE WILL RELEASE THE FRAGMENT LOCK FIRST.
  1009.        * -------------------------------------------------------------------- */
  1010.       /* A NORMAL WRITE OPERATION THAT NEEDS LOGGING AND WILL NOT BE 
  1011.        * PREMATURELY COMMITTED.
  1012.        * -------------------------------------------------------------------- */
  1013.       logLqhkeyreqLab(signal);
  1014.       return;
  1015.     }//if
  1016.   }//if
  1017. }//Dblqh::rwConcludedAiLab()
  1018. /* ########################################################################## 
  1019.  * #######                            LOG MODULE                      ####### 
  1020.  *
  1021.  * ########################################################################## 
  1022.  * -------------------------------------------------------------------------- 
  1023.  *       THE LOG MODULE HANDLES THE READING AND WRITING OF THE LOG
  1024.  *       IT IS ALSO RESPONSIBLE FOR HANDLING THE SYSTEM RESTART. 
  1025.  *       IT CONTROLS THE SYSTEM RESTART IN TUP AND ACC AS WELL.
  1026.  * -------------------------------------------------------------------------- */
  1027. void Dblqh::logLqhkeyreqLab(Signal* signal) 
  1028. {
  1029.   UintR tcurrentFilepage;
  1030.   TcConnectionrecPtr tmpTcConnectptr;
  1031.   if (cnoOfLogPages < ZMIN_LOG_PAGES_OPERATION || ERROR_INSERTED(5032)) {
  1032.     jam();
  1033.     if(ERROR_INSERTED(5032)){
  1034.       CLEAR_ERROR_INSERT_VALUE;
  1035.     }
  1036. /*---------------------------------------------------------------------------*/
  1037. // The log disk is having problems in catching up with the speed of execution. 
  1038. // We must wait with writing the log of this operation to ensure we do not 
  1039. // overload the log.
  1040. /*---------------------------------------------------------------------------*/
  1041.     terrorCode = ZTEMPORARY_REDO_LOG_FAILURE;
  1042.     abortErrorLab(signal);
  1043.     return;
  1044.   }//if
  1045.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  1046.   logPartPtr.i = regTcPtr->hashValue & 3;
  1047.   ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
  1048. /* -------------------------------------------------- */
  1049. /*       THIS PART IS USED TO WRITE THE LOG           */
  1050. /* -------------------------------------------------- */
  1051. /* -------------------------------------------------- */
  1052. /*       CHECK IF A LOG OPERATION IS ONGOING ALREADY. */
  1053. /*       IF SO THEN QUEUE THE OPERATION FOR LATER     */
  1054. /*       RESTART WHEN THE LOG PART IS FREE AGAIN.     */
  1055. /* -------------------------------------------------- */
  1056.   LogPartRecord * const regLogPartPtr = logPartPtr.p;
  1057.   if(ERROR_INSERTED(5033)){
  1058.     jam();
  1059.     CLEAR_ERROR_INSERT_VALUE;
  1060.     if ((regLogPartPtr->firstLogQueue != RNIL) &&
  1061.         (regLogPartPtr->LogLqhKeyReqSent == ZFALSE)) {
  1062.       /* -------------------------------------------------- */
  1063.       /*       WE HAVE A PROBLEM IN THAT THE LOG HAS NO     */
  1064.       /*       ROOM FOR ADDITIONAL OPERATIONS AT THE MOMENT.*/
  1065.       /* -------------------------------------------------- */
  1066.       /* -------------------------------------------------- */
  1067.       /*       WE MUST STILL RESTART QUEUED OPERATIONS SO   */
  1068.       /*       THEY ALSO CAN BE ABORTED.                    */
  1069.       /* -------------------------------------------------- */
  1070.       regLogPartPtr->LogLqhKeyReqSent = ZTRUE;
  1071.       signal->theData[0] = ZLOG_LQHKEYREQ;
  1072.       signal->theData[1] = logPartPtr.i;
  1073.       sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  1074.     }//if
  1075.     
  1076.     terrorCode = ZTAIL_PROBLEM_IN_LOG_ERROR;
  1077.     abortErrorLab(signal);
  1078.     return;
  1079.   }
  1080.   
  1081.   if (regLogPartPtr->logPartState == LogPartRecord::IDLE) {
  1082.     ;
  1083.   } else if (regLogPartPtr->logPartState == LogPartRecord::ACTIVE) {
  1084.     jam();
  1085.     linkWaitLog(signal, logPartPtr);
  1086.     regTcPtr->transactionState = TcConnectionrec::LOG_QUEUED;
  1087.     return;
  1088.   } else {
  1089.     if ((regLogPartPtr->firstLogQueue != RNIL) &&
  1090.         (regLogPartPtr->LogLqhKeyReqSent == ZFALSE)) {
  1091. /* -------------------------------------------------- */
  1092. /*       WE HAVE A PROBLEM IN THAT THE LOG HAS NO     */
  1093. /*       ROOM FOR ADDITIONAL OPERATIONS AT THE MOMENT.*/
  1094. /* -------------------------------------------------- */
  1095. /* -------------------------------------------------- */
  1096. /*       WE MUST STILL RESTART QUEUED OPERATIONS SO   */
  1097. /*       THEY ALSO CAN BE ABORTED.                    */
  1098. /* -------------------------------------------------- */
  1099.       regLogPartPtr->LogLqhKeyReqSent = ZTRUE;
  1100.       signal->theData[0] = ZLOG_LQHKEYREQ;
  1101.       signal->theData[1] = logPartPtr.i;
  1102.       sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  1103.     }//if
  1104.     if (regLogPartPtr->logPartState == LogPartRecord::TAIL_PROBLEM) {
  1105.       jam();
  1106.       terrorCode = ZTAIL_PROBLEM_IN_LOG_ERROR;
  1107.     } else {
  1108.       ndbrequire(regLogPartPtr->logPartState == LogPartRecord::FILE_CHANGE_PROBLEM);
  1109.       jam();
  1110.       terrorCode = ZFILE_CHANGE_PROBLEM_IN_LOG_ERROR;
  1111.     }//if
  1112.     abortErrorLab(signal);
  1113.     return;
  1114.   }//if
  1115.   regLogPartPtr->logPartState = LogPartRecord::ACTIVE;
  1116.   logFilePtr.i = regLogPartPtr->currentLogfile;
  1117.   ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  1118. /* -------------------------------------------------- */
  1119. /*       CHECK IF A NEW MBYTE IS TO BE STARTED. IF    */
  1120. /*       SO INSERT A NEXT LOG RECORD, WRITE THE LOG   */
  1121. /*       AND PLACE THE LOG POINTER ON THE NEW POSITION*/
  1122. /*       IF A NEW FILE IS TO BE USED, CHANGE FILE AND */
  1123. /*       ALSO START OPENING THE NEXT LOG FILE. IF A   */
  1124. /*       LAP HAS BEEN COMPLETED THEN ADD ONE TO LAP   */
  1125. /*       COUNTER.                                     */
  1126. /* -------------------------------------------------- */
  1127.   checkNewMbyte(signal);
  1128. /* -------------------------------------------------- */
  1129. /*       INSERT THE OPERATION RECORD LAST IN THE LIST */
  1130. /*       OF NOT COMPLETED OPERATIONS. ALSO RECORD THE */
  1131. /*       FILE NO, PAGE NO AND PAGE INDEX OF THE START */
  1132. /*       OF THIS LOG RECORD.                          */
  1133. /*       IT IS NOT ALLOWED TO INSERT IT INTO THE LIST */
  1134. /*       BEFORE CHECKING THE NEW MBYTE SINCE THAT WILL*/
  1135. /*       CAUSE THE OLD VALUES OF TC_CONNECTPTR TO BE  */
  1136. /*       USED IN WRITE_FILE_DESCRIPTOR.               */
  1137. /* -------------------------------------------------- */
  1138.   Uint32 tcIndex = tcConnectptr.i;
  1139.   tmpTcConnectptr.i = regLogPartPtr->lastLogTcrec;
  1140.   regLogPartPtr->lastLogTcrec = tcIndex;
  1141.   if (tmpTcConnectptr.i == RNIL) {
  1142.     jam();
  1143.     regLogPartPtr->firstLogTcrec = tcIndex;
  1144.   } else {
  1145.     ptrCheckGuard(tmpTcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  1146.     tmpTcConnectptr.p->nextLogTcrec = tcIndex;
  1147.   }//if
  1148.   Uint32 fileNo = logFilePtr.p->fileNo;
  1149.   tcurrentFilepage = logFilePtr.p->currentFilepage;
  1150.   logPagePtr.i = logFilePtr.p->currentLogpage;
  1151.   regTcPtr->nextLogTcrec = RNIL;
  1152.   regTcPtr->prevLogTcrec = tmpTcConnectptr.i;
  1153.   ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
  1154.   Uint32 pageIndex = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
  1155.   regTcPtr->logStartFileNo = fileNo;
  1156.   regTcPtr->logStartPageNo = tcurrentFilepage;
  1157.   regTcPtr->logStartPageIndex = pageIndex;
  1158. /* -------------------------------------------------- */
  1159. /*       WRITE THE LOG HEADER OF THIS OPERATION.      */
  1160. /* -------------------------------------------------- */
  1161.   writeLogHeader(signal);
  1162. /* -------------------------------------------------- */
  1163. /*       WRITE THE TUPLE KEY OF THIS OPERATION.       */
  1164. /* -------------------------------------------------- */
  1165.   writeKey(signal);
  1166. /* -------------------------------------------------- */
  1167. /*       WRITE THE ATTRIBUTE INFO OF THIS OPERATION.  */
  1168. /* -------------------------------------------------- */
  1169.   writeAttrinfoLab(signal);
  1170.   logNextStart(signal);
  1171. /* -------------------------------------------------- */
  1172. /*       RESET THE STATE OF THE LOG PART. IF ANY      */
  1173. /*       OPERATIONS HAVE QUEUED THEN START THE FIRST  */
  1174. /*       OF THESE.                                    */
  1175. /* -------------------------------------------------- */
  1176. /* -------------------------------------------------- */
  1177. /*       CONTINUE WITH PACKING OF LQHKEYREQ           */
  1178. /* -------------------------------------------------- */
  1179.   tcurrentFilepage = logFilePtr.p->currentFilepage;
  1180.   if (logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] == ZPAGE_HEADER_SIZE) {
  1181.     jam();
  1182.     tcurrentFilepage--;
  1183.   }//if
  1184.   regTcPtr->logStopPageNo = tcurrentFilepage;
  1185.   regTcPtr->logWriteState = TcConnectionrec::WRITTEN;
  1186.   if (regTcPtr->abortState != TcConnectionrec::ABORT_IDLE) {
  1187. /* -------------------------------------------------- */
  1188. /*       AN ABORT HAVE BEEN ORDERED. THE ABORT WAITED */
  1189. /*       FOR THE LOG WRITE TO BE COMPLETED. NOW WE    */
  1190. /*       CAN PROCEED WITH THE NORMAL ABORT HANDLING.  */
  1191. /* -------------------------------------------------- */
  1192.     abortCommonLab(signal);
  1193.     return;
  1194.   }//if
  1195.   if (regTcPtr->dirtyOp != ZTRUE) {
  1196.     packLqhkeyreqLab(signal);
  1197.   } else {
  1198.     /* ----------------------------------------------------------------------
  1199.      * I NEED TO INSERT A COMMIT LOG RECORD SINCE WE ARE WRITING LOG IN THIS
  1200.      * TRANSACTION. SINCE WE RELEASED THE LOG LOCK JUST NOW NO ONE ELSE CAN BE
  1201.      * ACTIVE IN WRITING THE LOG. WE THUS WRITE THE LOG WITHOUT GETTING A LOCK
  1202.      * SINCE WE ARE ONLY WRITING A COMMIT LOG RECORD.
  1203.      * ---------------------------------------------------------------------- */
  1204.     writeCommitLog(signal, logPartPtr);
  1205.     /* ----------------------------------------------------------------------
  1206.      * DIRTY OPERATIONS SHOULD COMMIT BEFORE THEY PACK THE REQUEST/RESPONSE.
  1207.      * ---------------------------------------------------------------------- */
  1208.     regTcPtr->gci = cnewestGci;
  1209.     localCommitLab(signal);
  1210.   }//if
  1211. }//Dblqh::logLqhkeyreqLab()
  1212. /* ------------------------------------------------------------------------- */
  1213. /* -------                        SEND LQHKEYREQ                             */
  1214. /*                                                                           */
  1215. /* NO STATE CHECKING SINCE THE SIGNAL IS A LOCAL SIGNAL. THE EXECUTION OF    */
  1216. /* THE OPERATION IS COMPLETED. IT IS NOW TIME TO SEND THE OPERATION TO THE   */
  1217. /* NEXT REPLICA OR TO TC.                                                    */
  1218. /* ------------------------------------------------------------------------- */
  1219. void Dblqh::packLqhkeyreqLab(Signal* signal) 
  1220. {
  1221.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  1222.   if (regTcPtr->nextReplica == ZNIL) {
  1223. /* ------------------------------------------------------------------------- */
  1224. /* -------               SEND LQHKEYCONF                             ------- */
  1225. /*                                                                           */
  1226. /* ------------------------------------------------------------------------- */
  1227.     sendLqhkeyconfTc(signal, regTcPtr->tcBlockref);
  1228.     if (regTcPtr->dirtyOp != ZTRUE) {
  1229.       jam();
  1230.       regTcPtr->transactionState = TcConnectionrec::PREPARED;
  1231.       releaseOprec(signal);
  1232.     } else {
  1233.       jam();
  1234. /*************************************************************>*/
  1235. /*       DIRTY WRITES ARE USED IN TWO SITUATIONS. THE FIRST    */
  1236. /*       SITUATION IS WHEN THEY ARE USED TO UPDATE COUNTERS AND*/
  1237. /*       OTHER ATTRIBUTES WHICH ARE NOT SENSITIVE TO CONSISTE- */
  1238. /*       NCY. THE SECOND SITUATION IS BY OPERATIONS THAT ARE   */
  1239. /*       SENT AS PART OF A COPY FRAGMENT PROCESS.              */
  1240. /*                                                             */
  1241. /*       DURING A COPY FRAGMENT PROCESS THERE IS NO LOGGING    */
  1242. /*       ONGOING SINCE THE FRAGMENT IS NOT COMPLETE YET. THE   */
  1243. /*       LOGGING STARTS AFTER COMPLETING THE LAST COPY TUPLE   */
  1244. /*       OPERATION. THE EXECUTION OF THE LAST COPY TUPLE DOES  */
  1245. /*       ALSO START A LOCAL CHECKPOINT SO THAT THE FRAGMENT    */
  1246. /*       REPLICA IS RECOVERABLE. THUS GLOBAL CHECKPOINT ID FOR */
  1247. /*       THOSE OPERATIONS ARE NOT INTERESTING.                 */
  1248. /*                                                             */
  1249. /*       A DIRTY WRITE IS BY DEFINITION NOT CONSISTENT. THUS   */
  1250. /*       IT CAN USE ANY GLOBAL CHECKPOINT. THE IDEA HERE IS TO */
  1251. /*       ALWAYS USE THE LATEST DEFINED GLOBAL CHECKPOINT ID IN */
  1252. /*       THIS NODE.                                            */
  1253. /*************************************************************>*/
  1254.       cleanUp(signal);
  1255.     }//if
  1256.     return;
  1257.   }//if
  1258. /* ------------------------------------------------------------------------- */
  1259. /* -------            SEND LQHKEYREQ                                 ------- */
  1260. /*                                                                           */
  1261. /* ------------------------------------------------------------------------- */
  1262. /* ------------------------------------------------------------------------- */
  1263. /* THERE ARE MORE REPLICAS TO SEND THE OPERATION TO. A NEW LQHKEYREQ WILL BE */
  1264. /* PREPARED FOR THE NEXT REPLICA.                                            */
  1265. /* ------------------------------------------------------------------------- */
  1266. /* CLEAR REPLICA TYPE, ATTRINFO INDICATOR (IN LQHKEYREQ),                    */
  1267. /* INTERPRETED EXECUTION, SEQUENTIAL NUMBER OF REPLICA.                      */
  1268. // Set bit indicating Client and TC record not the same.
  1269. // Set readlenAi indicator if readlenAi != 0
  1270. // Stored Procedure Indicator not set.
  1271. /* ------------------------------------------------------------------------- */
  1272.   LqhKeyReq * const lqhKeyReq = (LqhKeyReq *)&signal->theData[0];
  1273.   UintR Treqinfo;
  1274.   UintR sig0, sig1, sig2, sig3, sig4, sig5, sig6;
  1275.   Treqinfo = preComputedRequestInfoMask & regTcPtr->reqinfo;
  1276.   UintR TapplAddressIndicator = (regTcPtr->nextSeqNoReplica == 0 ? 0 : 1);
  1277.   LqhKeyReq::setApplicationAddressFlag(Treqinfo, TapplAddressIndicator);
  1278.   LqhKeyReq::setInterpretedFlag(Treqinfo, regTcPtr->opExec);
  1279.   LqhKeyReq::setSeqNoReplica(Treqinfo, regTcPtr->nextSeqNoReplica);
  1280.   LqhKeyReq::setAIInLqhKeyReq(Treqinfo, regTcPtr->reclenAiLqhkey);
  1281.   UintR TreadLenAiInd = (regTcPtr->readlenAi == 0 ? 0 : 1);
  1282.   UintR TsameLqhAndClient = (tcConnectptr.i == 
  1283.                              regTcPtr->tcOprec ? 0 : 1);
  1284.   LqhKeyReq::setSameClientAndTcFlag(Treqinfo, TsameLqhAndClient);
  1285.   LqhKeyReq::setReturnedReadLenAIFlag(Treqinfo, TreadLenAiInd);
  1286.   UintR TotReclenAi = regTcPtr->totSendlenAi;
  1287. /* ------------------------------------------------------------------------- */
  1288. /* WE ARE NOW PREPARED TO SEND THE LQHKEYREQ. WE HAVE TO DECIDE IF ATTRINFO  */
  1289. /* IS INCLUDED IN THE LQHKEYREQ SIGNAL AND THEN SEND IT.                     */
  1290. /* TAKE OVER SCAN OPERATION IS NEVER USED ON BACKUPS, LOG RECORDS AND START-UP*/
  1291. /* OF NEW REPLICA AND THUS ONLY TOT_SENDLEN_AI IS USED THE UPPER 16 BITS ARE */
  1292. /* ZERO.                                                                     */
  1293. /* ------------------------------------------------------------------------- */
  1294.   sig0 = tcConnectptr.i;
  1295.   sig1 = regTcPtr->savePointId;
  1296.   sig2 = regTcPtr->hashValue;
  1297.   sig4 = regTcPtr->tcBlockref;
  1298.   lqhKeyReq->clientConnectPtr = sig0;
  1299.   lqhKeyReq->attrLen = TotReclenAi;
  1300.   lqhKeyReq->savePointId = sig1;
  1301.   lqhKeyReq->hashValue = sig2;
  1302.   lqhKeyReq->requestInfo = Treqinfo;
  1303.   lqhKeyReq->tcBlockref = sig4;
  1304.   sig0 = regTcPtr->tableref + ((regTcPtr->schemaVersion << 16) & 0xFFFF0000);
  1305.   sig1 = regTcPtr->fragmentid + (regTcPtr->nodeAfterNext[0] << 16);
  1306.   sig2 = regTcPtr->transid[0];
  1307.   sig3 = regTcPtr->transid[1];
  1308.   sig4 = regTcPtr->applRef;
  1309.   sig5 = regTcPtr->applOprec;
  1310.   sig6 = regTcPtr->tcOprec;
  1311.   UintR nextPos = (TapplAddressIndicator << 1);
  1312.   lqhKeyReq->tableSchemaVersion = sig0;
  1313.   lqhKeyReq->fragmentData = sig1;
  1314.   lqhKeyReq->transId1 = sig2;
  1315.   lqhKeyReq->transId2 = sig3;
  1316.   lqhKeyReq->noFiredTriggers = regTcPtr->noFiredTriggers;
  1317.   lqhKeyReq->variableData[0] = sig4;
  1318.   lqhKeyReq->variableData[1] = sig5;
  1319.   lqhKeyReq->variableData[2] = sig6;
  1320.   nextPos += TsameLqhAndClient;
  1321.   if ((regTcPtr->lastReplicaNo - regTcPtr->nextSeqNoReplica) > 1) {
  1322.     sig0 = (UintR)regTcPtr->nodeAfterNext[1] +
  1323.            (UintR)(regTcPtr->nodeAfterNext[2] << 16);
  1324.     lqhKeyReq->variableData[nextPos] = sig0;
  1325.     nextPos++;
  1326.   }//if
  1327.   sig0 = regTcPtr->readlenAi;
  1328.   sig1 = regTcPtr->tupkeyData[0];
  1329.   sig2 = regTcPtr->tupkeyData[1];
  1330.   sig3 = regTcPtr->tupkeyData[2];
  1331.   sig4 = regTcPtr->tupkeyData[3];
  1332.   lqhKeyReq->variableData[nextPos] = sig0;
  1333.   nextPos += TreadLenAiInd;
  1334.   lqhKeyReq->variableData[nextPos] = sig1;
  1335.   lqhKeyReq->variableData[nextPos + 1] = sig2;
  1336.   lqhKeyReq->variableData[nextPos + 2] = sig3;
  1337.   lqhKeyReq->variableData[nextPos + 3] = sig4;
  1338.   UintR TkeyLen = LqhKeyReq::getKeyLen(Treqinfo);
  1339.   if (TkeyLen < 4) {
  1340.     nextPos += TkeyLen;
  1341.   } else {
  1342.     nextPos += 4;
  1343.   }//if
  1344.   sig0 = regTcPtr->firstAttrinfo[0];
  1345.   sig1 = regTcPtr->firstAttrinfo[1];
  1346.   sig2 = regTcPtr->firstAttrinfo[2];
  1347.   sig3 = regTcPtr->firstAttrinfo[3];
  1348.   sig4 = regTcPtr->firstAttrinfo[4];
  1349.   UintR TAiLen = regTcPtr->reclenAiLqhkey;
  1350.   BlockReference lqhRef = calcLqhBlockRef(regTcPtr->nextReplica);
  1351.   lqhKeyReq->variableData[nextPos] = sig0;
  1352.   lqhKeyReq->variableData[nextPos + 1] = sig1;
  1353.   lqhKeyReq->variableData[nextPos + 2] = sig2;
  1354.   lqhKeyReq->variableData[nextPos + 3] = sig3;
  1355.   lqhKeyReq->variableData[nextPos + 4] = sig4;
  1356.   nextPos += TAiLen;
  1357.   sendSignal(lqhRef, GSN_LQHKEYREQ, signal, 
  1358.              nextPos + LqhKeyReq::FixedSignalLength, JBB);
  1359.   if (regTcPtr->primKeyLen > 4) {
  1360.     jam();
  1361. /* ------------------------------------------------------------------------- */
  1362. /* MORE THAN 4 WORDS OF KEY DATA IS IN THE OPERATION. THEREFORE WE NEED TO   */
  1363. /* PREPARE A KEYINFO SIGNAL. MORE THAN ONE KEYINFO SIGNAL CAN BE SENT.       */
  1364. /* ------------------------------------------------------------------------- */
  1365.     sendTupkey(signal);
  1366.   }//if
  1367. /* ------------------------------------------------------------------------- */
  1368. /* NOW I AM PREPARED TO SEND ALL THE ATTRINFO SIGNALS. AT THE MOMENT A LOOP  */
  1369. /* SENDS ALL AT ONCE. LATER WE HAVE TO ADDRESS THE PROBLEM THAT THESE COULD  */
  1370. /* LEAD TO BUFFER EXPLOSION => NODE CRASH.                                   */
  1371. /* ------------------------------------------------------------------------- */
  1372. /*       NEW CODE TO SEND ATTRINFO IN PACK_LQHKEYREQ  */
  1373. /*       THIS CODE USES A REAL-TIME BREAK AFTER       */
  1374. /*       SENDING 16 SIGNALS.                          */
  1375. /* -------------------------------------------------- */
  1376.   sig0 = regTcPtr->tcOprec;
  1377.   sig1 = regTcPtr->transid[0];
  1378.   sig2 = regTcPtr->transid[1];
  1379.   signal->theData[0] = sig0;
  1380.   signal->theData[1] = sig1;
  1381.   signal->theData[2] = sig2;
  1382.   AttrbufPtr regAttrinbufptr;
  1383.   regAttrinbufptr.i = regTcPtr->firstAttrinbuf;
  1384.   while (regAttrinbufptr.i != RNIL) {
  1385.     ptrCheckGuard(regAttrinbufptr, cattrinbufFileSize, attrbuf);
  1386.     jam();
  1387.     Uint32 dataLen = regAttrinbufptr.p->attrbuf[ZINBUF_DATA_LEN];
  1388.     ndbrequire(dataLen != 0);
  1389.     MEMCOPY_NO_WORDS(&signal->theData[3], &regAttrinbufptr.p->attrbuf[0], dataLen);
  1390.     regAttrinbufptr.i = regAttrinbufptr.p->attrbuf[ZINBUF_NEXT];
  1391.     sendSignal(lqhRef, GSN_ATTRINFO, signal, dataLen + 3, JBB);
  1392.   }//while
  1393.   regTcPtr->transactionState = TcConnectionrec::PREPARED;
  1394.   if (regTcPtr->dirtyOp == ZTRUE) {
  1395.     jam();
  1396. /*************************************************************>*/
  1397. /*       DIRTY WRITES ARE USED IN TWO SITUATIONS. THE FIRST    */
  1398. /*       SITUATION IS WHEN THEY ARE USED TO UPDATE COUNTERS AND*/
  1399. /*       OTHER ATTRIBUTES WHICH ARE NOT SENSITIVE TO CONSISTE- */
  1400. /*       NCY. THE SECOND SITUATION IS BY OPERATIONS THAT ARE   */
  1401. /*       SENT AS PART OF A COPY FRAGMENT PROCESS.              */
  1402. /*                                                             */
  1403. /*       DURING A COPY FRAGMENT PROCESS THERE IS NO LOGGING    */
  1404. /*       ONGOING SINCE THE FRAGMENT IS NOT COMPLETE YET. THE   */
  1405. /*       LOGGING STARTS AFTER COMPLETING THE LAST COPY TUPLE   */
  1406. /*       OPERATION. THE EXECUTION OF THE LAST COPY TUPLE DOES  */
  1407. /*       ALSO START A LOCAL CHECKPOINT SO THAT THE FRAGMENT    */
  1408. /*       REPLICA IS RECOVERABLE. THUS GLOBAL CHECKPOINT ID FOR */
  1409. /*       THOSE OPERATIONS ARE NOT INTERESTING.                 */
  1410. /*                                                             */
  1411. /*       A DIRTY WRITE IS BY DEFINITION NOT CONSISTENT. THUS   */
  1412. /*       IT CAN USE ANY GLOBAL CHECKPOINT. THE IDEA HERE IS TO */
  1413. /*       ALWAYS USE THE LATEST DEFINED GLOBAL CHECKPOINT ID IN */
  1414. /*       THIS NODE.                                            */
  1415. /*************************************************************>*/
  1416.     cleanUp(signal);
  1417.     return;
  1418.   }//if
  1419.   /* ------------------------------------------------------------------------ 
  1420.    *   ALL INFORMATION NEEDED BY THE COMMIT PHASE AND COMPLETE PHASE IS 
  1421.    *   KEPT IN THE TC_CONNECT RECORD. TO ENSURE PROPER USE OF MEMORY 
  1422.    *   RESOURCES WE DEALLOCATE THE ATTRINFO RECORD AND KEY RECORDS 
  1423.    *   AS SOON AS POSSIBLE.
  1424.    * ------------------------------------------------------------------------ */
  1425.   releaseOprec(signal);
  1426. }//Dblqh::packLqhkeyreqLab()
  1427. /* ========================================================================= */
  1428. /* ==== CHECK IF THE LOG RECORD FITS INTO THE CURRENT MBYTE,         ======= */
  1429. /*      OTHERWISE SWITCH TO NEXT MBYTE.                                      */
  1430. /*                                                                           */
  1431. /* ========================================================================= */
  1432. void Dblqh::checkNewMbyte(Signal* signal) 
  1433. {
  1434.   UintR tcnmTmp;
  1435.   UintR ttotalLogSize;
  1436. /* -------------------------------------------------- */
  1437. /*       CHECK IF A NEW MBYTE OF LOG RECORD IS TO BE  */
  1438. /*       OPENED BEFORE WRITING THE LOG RECORD. NO LOG */
  1439. /*       RECORDS ARE ALLOWED TO SPAN A MBYTE BOUNDARY */
  1440. /*                                                    */
  1441. /*       INPUT:  TC_CONNECTPTR   THE OPERATION        */
  1442. /*               LOG_FILE_PTR    THE LOG FILE         */
  1443. /*       OUTPUT: LOG_FILE_PTR    THE NEW LOG FILE     */
  1444. /* -------------------------------------------------- */
  1445.   ttotalLogSize = ZLOG_HEAD_SIZE + tcConnectptr.p->currTupAiLen;
  1446.   ttotalLogSize = ttotalLogSize + tcConnectptr.p->primKeyLen;
  1447.   tcnmTmp = logFilePtr.p->remainingWordsInMbyte;
  1448.   if ((ttotalLogSize + ZNEXT_LOG_SIZE) <= tcnmTmp) {
  1449.     ndbrequire(tcnmTmp >= ttotalLogSize);
  1450.     logFilePtr.p->remainingWordsInMbyte = tcnmTmp - ttotalLogSize;
  1451.     return;
  1452.   } else {
  1453.     jam();
  1454. /* -------------------------------------------------- */
  1455. /*       IT WAS NOT ENOUGH SPACE IN THIS MBYTE FOR    */
  1456. /*       THIS LOG RECORD. MOVE TO NEXT MBYTE          */
  1457. /*       THIS MIGHT INCLUDE CHANGING LOG FILE         */
  1458. /* -------------------------------------------------- */
  1459. /*       WE HAVE TO INSERT A NEXT LOG RECORD FIRST    */
  1460. /* -------------------------------------------------- */
  1461. /*       THEN CONTINUE BY WRITING THE FILE DESCRIPTORS*/
  1462. /* -------------------------------------------------- */
  1463.     logPagePtr.i = logFilePtr.p->currentLogpage;
  1464.     ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
  1465.     changeMbyte(signal);
  1466.     tcnmTmp = logFilePtr.p->remainingWordsInMbyte;
  1467.   }//if
  1468.   ndbrequire(tcnmTmp >= ttotalLogSize);
  1469.   logFilePtr.p->remainingWordsInMbyte = tcnmTmp - ttotalLogSize;
  1470. }//Dblqh::checkNewMbyte()
  1471. /* --------------------------------------------------------------------------
  1472.  * -------               WRITE OPERATION HEADER TO LOG                ------- 
  1473.  * 
  1474.  *       SUBROUTINE SHORT NAME: WLH
  1475.  * ------------------------------------------------------------------------- */
  1476. void Dblqh::writeLogHeader(Signal* signal) 
  1477. {
  1478.   Uint32 logPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
  1479.   Uint32 hashValue = tcConnectptr.p->hashValue;
  1480.   Uint32 operation = tcConnectptr.p->operation;
  1481.   Uint32 keyLen = tcConnectptr.p->primKeyLen;
  1482.   Uint32 aiLen = tcConnectptr.p->currTupAiLen;
  1483.   Uint32 totLogLen = aiLen + keyLen + ZLOG_HEAD_SIZE;
  1484.   if ((logPos + ZLOG_HEAD_SIZE) < ZPAGE_SIZE) {
  1485.     Uint32* dataPtr = &logPagePtr.p->logPageWord[logPos];
  1486.     logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = logPos + ZLOG_HEAD_SIZE;
  1487.     dataPtr[0] = ZPREP_OP_TYPE;
  1488.     dataPtr[1] = totLogLen;
  1489.     dataPtr[2] = hashValue;
  1490.     dataPtr[3] = operation;
  1491.     dataPtr[4] = aiLen;
  1492.     dataPtr[5] = keyLen;
  1493.   } else {
  1494.     writeLogWord(signal, ZPREP_OP_TYPE);
  1495.     writeLogWord(signal, totLogLen);
  1496.     writeLogWord(signal, hashValue);
  1497.     writeLogWord(signal, operation);
  1498.     writeLogWord(signal, aiLen);
  1499.     writeLogWord(signal, keyLen);
  1500.   }//if
  1501. }//Dblqh::writeLogHeader()
  1502. /* --------------------------------------------------------------------------
  1503.  * -------               WRITE TUPLE KEY TO LOG                       ------- 
  1504.  *
  1505.  *       SUBROUTINE SHORT NAME: WK
  1506.  * ------------------------------------------------------------------------- */
  1507. void Dblqh::writeKey(Signal* signal) 
  1508. {
  1509.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  1510.   Uint32 logPos, endPos, dataLen;
  1511.   Int32 remainingLen;
  1512.   logPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
  1513.   remainingLen = regTcPtr->primKeyLen;
  1514.   dataLen = remainingLen;
  1515.   if (remainingLen > 4)
  1516.     dataLen = 4;
  1517.   remainingLen -= dataLen;
  1518.   endPos = logPos + dataLen;
  1519.   if (endPos < ZPAGE_SIZE) {
  1520.     MEMCOPY_NO_WORDS(&logPagePtr.p->logPageWord[logPos],
  1521.                      &regTcPtr->tupkeyData[0],
  1522.                      dataLen);
  1523.   } else {
  1524.     jam();
  1525.     for (Uint32 i = 0; i < dataLen; i++)
  1526.       writeLogWord(signal, regTcPtr->tupkeyData[i]);
  1527.     endPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
  1528.   }//if
  1529.   DatabufPtr regDatabufptr;
  1530.   regDatabufptr.i = regTcPtr->firstTupkeybuf;
  1531.   while (remainingLen > 0) {
  1532.     logPos = endPos;
  1533.     ptrCheckGuard(regDatabufptr, cdatabufFileSize, databuf);
  1534.     dataLen = remainingLen;
  1535.     if (remainingLen > 4)
  1536.       dataLen = 4;
  1537.     remainingLen -= dataLen;
  1538.     endPos += dataLen;
  1539.     if (endPos < ZPAGE_SIZE) {
  1540.       MEMCOPY_NO_WORDS(&logPagePtr.p->logPageWord[logPos],
  1541.                        &regDatabufptr.p->data[0],
  1542.                        dataLen);
  1543.     } else {
  1544.       logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = logPos;
  1545.       for (Uint32 i = 0; i < dataLen; i++)
  1546.         writeLogWord(signal, regDatabufptr.p->data[i]);
  1547.       endPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
  1548.     }//if
  1549.     regDatabufptr.i = regDatabufptr.p->nextDatabuf;
  1550.   }//while
  1551.   logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = endPos;
  1552.   ndbrequire(regDatabufptr.i == RNIL);
  1553. }//Dblqh::writeKey()
  1554. /* --------------------------------------------------------------------------
  1555.  * -------               WRITE ATTRINFO TO LOG                        ------- 
  1556.  *
  1557.  *       SUBROUTINE SHORT NAME: WA
  1558.  * ------------------------------------------------------------------------- */
  1559. void Dblqh::writeAttrinfoLab(Signal* signal) 
  1560. {
  1561.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  1562.   Uint32 totLen = regTcPtr->currTupAiLen;
  1563.   if (totLen == 0)
  1564.     return;
  1565.   Uint32 logPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
  1566.   Uint32 lqhLen = regTcPtr->reclenAiLqhkey;
  1567.   ndbrequire(totLen >= lqhLen);
  1568.   Uint32 endPos = logPos + lqhLen;
  1569.   totLen -= lqhLen;
  1570.   if (endPos < ZPAGE_SIZE) {
  1571.     MEMCOPY_NO_WORDS(&logPagePtr.p->logPageWord[logPos],
  1572.                      &regTcPtr->firstAttrinfo[0],
  1573.                      lqhLen);
  1574.   } else {
  1575.     for (Uint32 i = 0; i < lqhLen; i++)
  1576.       writeLogWord(signal, regTcPtr->firstAttrinfo[i]);
  1577.     endPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
  1578.   }//if
  1579.   AttrbufPtr regAttrinbufptr;
  1580.   regAttrinbufptr.i = regTcPtr->firstAttrinbuf;
  1581.   while (totLen > 0) {
  1582.     logPos = endPos;
  1583.     ptrCheckGuard(regAttrinbufptr, cattrinbufFileSize, attrbuf);
  1584.     Uint32 dataLen = regAttrinbufptr.p->attrbuf[ZINBUF_DATA_LEN];
  1585.     ndbrequire(totLen >= dataLen);
  1586.     ndbrequire(dataLen > 0);
  1587.     totLen -= dataLen;
  1588.     endPos += dataLen;
  1589.     if (endPos < ZPAGE_SIZE) {
  1590.       MEMCOPY_NO_WORDS(&logPagePtr.p->logPageWord[logPos],
  1591.                       &regAttrinbufptr.p->attrbuf[0],
  1592.                       dataLen);
  1593.     } else {
  1594.       logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = logPos;
  1595.       for (Uint32 i = 0; i < dataLen; i++)
  1596.         writeLogWord(signal, regAttrinbufptr.p->attrbuf[i]);
  1597.       endPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
  1598.     }//if
  1599.     regAttrinbufptr.i = regAttrinbufptr.p->attrbuf[ZINBUF_NEXT];
  1600.   }//while
  1601.   logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = endPos;
  1602.   ndbrequire(regAttrinbufptr.i == RNIL);
  1603. }//Dblqh::writeAttrinfoLab()
  1604. /* ------------------------------------------------------------------------- */
  1605. /* -------          SEND TUPLE KEY IN KEYINFO SIGNAL(S)              ------- */
  1606. /*                                                                           */
  1607. /*       SUBROUTINE SHORT NAME: STU                                          */
  1608. /* ------------------------------------------------------------------------- */
  1609. void Dblqh::sendTupkey(Signal* signal) 
  1610. {
  1611.   UintR TdataPos = 3;
  1612.   BlockReference lqhRef = calcLqhBlockRef(tcConnectptr.p->nextReplica);
  1613.   signal->theData[0] = tcConnectptr.p->tcOprec;
  1614.   signal->theData[1] = tcConnectptr.p->transid[0];
  1615.   signal->theData[2] = tcConnectptr.p->transid[1];
  1616.   databufptr.i = tcConnectptr.p->firstTupkeybuf;
  1617.   do {
  1618.     ptrCheckGuard(databufptr, cdatabufFileSize, databuf);
  1619.     signal->theData[TdataPos] = databufptr.p->data[0];
  1620.     signal->theData[TdataPos + 1] = databufptr.p->data[1];
  1621.     signal->theData[TdataPos + 2] = databufptr.p->data[2];
  1622.     signal->theData[TdataPos + 3] = databufptr.p->data[3];
  1623.     databufptr.i = databufptr.p->nextDatabuf;
  1624.     TdataPos += 4;
  1625.     if (databufptr.i == RNIL) {
  1626.       jam();
  1627.       sendSignal(lqhRef, GSN_KEYINFO, signal, TdataPos, JBB);
  1628.       return;
  1629.     } else if (TdataPos == 23) {
  1630.       jam();
  1631.       sendSignal(lqhRef, GSN_KEYINFO, signal, 23, JBB);
  1632.       TdataPos = 3;
  1633.     }
  1634.   } while (1);
  1635. }//Dblqh::sendTupkey()
  1636. void Dblqh::cleanUp(Signal* signal) 
  1637. {
  1638.   releaseOprec(signal);
  1639.   deleteTransidHash(signal);
  1640.   releaseTcrec(signal, tcConnectptr);
  1641. }//Dblqh::cleanUp()
  1642. /* --------------------------------------------------------------------------
  1643.  * ---- RELEASE ALL RECORDS CONNECTED TO THE OPERATION RECORD AND THE    ---- 
  1644.  *      OPERATION RECORD ITSELF
  1645.  * ------------------------------------------------------------------------- */
  1646. void Dblqh::releaseOprec(Signal* signal) 
  1647. {
  1648.   UintR Tmpbuf;
  1649.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  1650. /* ---- RELEASE DATA BUFFERS ------------------- */
  1651.   DatabufPtr regDatabufptr;
  1652.   regDatabufptr.i = regTcPtr->firstTupkeybuf;
  1653. /* --------------------------------------------------------------------------
  1654.  * -------       RELEASE DATA BUFFERS                                 ------- 
  1655.  * 
  1656.  * ------------------------------------------------------------------------- */
  1657.   while (regDatabufptr.i != RNIL) {
  1658.     jam();
  1659.     ptrCheckGuard(regDatabufptr, cdatabufFileSize, databuf);
  1660.     Tmpbuf = regDatabufptr.p->nextDatabuf;
  1661.     regDatabufptr.p->nextDatabuf = cfirstfreeDatabuf;
  1662.     cfirstfreeDatabuf = regDatabufptr.i;
  1663.     regDatabufptr.i = Tmpbuf;
  1664.   }//while
  1665. /* ---- RELEASE ATTRINFO BUFFERS ------------------- */
  1666.   AttrbufPtr regAttrinbufptr;
  1667.   regAttrinbufptr.i = regTcPtr->firstAttrinbuf;
  1668.   /* ########################################################################
  1669.    * #######                            RELEASE_ATTRINBUF             #######
  1670.    *
  1671.    * ####################################################################### */
  1672.   while (regAttrinbufptr.i != RNIL) {
  1673.     jam();
  1674.     regAttrinbufptr.i= release_attrinbuf(regAttrinbufptr.i);
  1675.   }//while
  1676.   regTcPtr->firstAttrinbuf = RNIL;
  1677.   regTcPtr->lastAttrinbuf = RNIL;
  1678.   regTcPtr->firstTupkeybuf = RNIL;
  1679.   regTcPtr->lastTupkeybuf = RNIL;
  1680. }//Dblqh::releaseOprec()
  1681. /* ------------------------------------------------------------------------- */
  1682. /* ------         DELETE TRANSACTION ID FROM HASH TABLE              ------- */
  1683. /*                                                                           */
  1684. /* ------------------------------------------------------------------------- */
  1685. void Dblqh::deleteTransidHash(Signal* signal) 
  1686. {
  1687.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  1688.   TcConnectionrecPtr prevHashptr;
  1689.   TcConnectionrecPtr nextHashptr;
  1690.   prevHashptr.i = regTcPtr->prevHashRec;
  1691.   nextHashptr.i = regTcPtr->nextHashRec;
  1692.   if (prevHashptr.i != RNIL) {
  1693.     jam();
  1694.     ptrCheckGuard(prevHashptr, ctcConnectrecFileSize, tcConnectionrec);
  1695.     prevHashptr.p->nextHashRec = nextHashptr.i;
  1696.   } else {
  1697.     jam();
  1698. /* ------------------------------------------------------------------------- */
  1699. /* THE OPERATION WAS PLACED FIRST IN THE LIST OF THE HASH TABLE. NEED TO SET */
  1700. /* A NEW LEADER OF THE LIST.                                                 */
  1701. /* ------------------------------------------------------------------------- */
  1702.     Uint32 hashIndex = (regTcPtr->transid[0] ^ regTcPtr->tcOprec) & 1023;
  1703.     ctransidHash[hashIndex] = nextHashptr.i;
  1704.   }//if
  1705.   if (nextHashptr.i != RNIL) {
  1706.     jam();
  1707.     ptrCheckGuard(nextHashptr, ctcConnectrecFileSize, tcConnectionrec);
  1708.     nextHashptr.p->prevHashRec = prevHashptr.i;
  1709.   }//if
  1710. }//Dblqh::deleteTransidHash()
  1711. /* --------------------------------------------------------------------------
  1712.  * -------               LINK OPERATION IN ACTIVE LIST ON FRAGMENT    -------
  1713.  *
  1714.  *       SUBROUTINE SHORT NAME: LAF
  1715. // Input Pointers:
  1716. // tcConnectptr
  1717. // fragptr
  1718.  * ------------------------------------------------------------------------- */
  1719. void Dblqh::linkActiveFrag(Signal* signal) 
  1720. {
  1721.   TcConnectionrecPtr lafTcConnectptr;
  1722.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  1723.   Fragrecord * const regFragPtr = fragptr.p;
  1724.   Uint32 tcIndex = tcConnectptr.i;
  1725.   lafTcConnectptr.i = regFragPtr->activeList;
  1726.   regTcPtr->prevTc = RNIL;
  1727.   regFragPtr->activeList = tcIndex;
  1728.   ndbrequire(regTcPtr->listState == TcConnectionrec::NOT_IN_LIST);
  1729.   regTcPtr->nextTc = lafTcConnectptr.i;
  1730.   regTcPtr->listState = TcConnectionrec::IN_ACTIVE_LIST;
  1731.   if (lafTcConnectptr.i == RNIL) {
  1732.     return;
  1733.   } else {
  1734.     jam();
  1735.     ptrCheckGuard(lafTcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  1736.     lafTcConnectptr.p->prevTc = tcIndex;
  1737.   }//if
  1738.   return;
  1739. }//Dblqh::linkActiveFrag()
  1740. /* -------------------------------------------------------------------------
  1741.  * -------       RELEASE OPERATION FROM ACTIVE LIST ON FRAGMENT      ------- 
  1742.  * 
  1743.  *       SUBROUTINE SHORT NAME = RAF
  1744.  * ------------------------------------------------------------------------- */
  1745. void Dblqh::releaseActiveFrag(Signal* signal) 
  1746. {
  1747.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  1748.   TcConnectionrecPtr ralTcNextConnectptr;
  1749.   TcConnectionrecPtr ralTcPrevConnectptr;
  1750.   fragptr.i = regTcPtr->fragmentptr;
  1751.   ralTcPrevConnectptr.i = regTcPtr->prevTc;
  1752.   ralTcNextConnectptr.i = regTcPtr->nextTc;
  1753.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1754.   Fragrecord * const regFragPtr = fragptr.p;
  1755.   ndbrequire(regTcPtr->listState == TcConnectionrec::IN_ACTIVE_LIST);
  1756.   regTcPtr->listState = TcConnectionrec::NOT_IN_LIST;
  1757.   if (ralTcNextConnectptr.i != RNIL) {
  1758.     jam();
  1759.     ptrCheckGuard(ralTcNextConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  1760.     ralTcNextConnectptr.p->prevTc = ralTcPrevConnectptr.i;
  1761.   }//if
  1762.   if (ralTcPrevConnectptr.i != RNIL) {
  1763.     jam();
  1764.     ptrCheckGuard(ralTcPrevConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  1765.     ralTcPrevConnectptr.p->nextTc = regTcPtr->nextTc;
  1766.   } else {
  1767.     jam();
  1768.     /* ----------------------------------------------------------------------
  1769.      *   OPERATION RECORD IS FIRST IN ACTIVE LIST    
  1770.      *   THIS MEANS THAT THERE EXISTS NO PREVIOUS TC THAT NEEDS TO BE UPDATED.
  1771.      * --------------------------------------------------------------------- */
  1772.     regFragPtr->activeList = ralTcNextConnectptr.i;
  1773.   }//if
  1774.   if (regFragPtr->lcpRef != RNIL) {
  1775.     jam();
  1776.     lcpPtr.i = regFragPtr->lcpRef;
  1777.     ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
  1778.     ndbrequire(lcpPtr.p->lcpState == LcpRecord::LCP_WAIT_ACTIVE_FINISH);
  1779.     /* --------------------------------------------------------------------
  1780.      *   IF A FRAGMENT IS CURRENTLY STARTING A LOCAL CHECKPOINT AND IT 
  1781.      *   IS WAITING FOR ACTIVE OPERATIONS TO BE COMPLETED WITH THE 
  1782.      *   CURRENT PHASE, THEN IT IS CHECKED WHETHER THE 
  1783.      *   LAST ACTIVE OPERATION WAS NOW COMPLETED.
  1784.      * ------------------------------------------------------------------- */
  1785.     if (regFragPtr->activeList == RNIL) {
  1786.       jam();
  1787.       /* ------------------------------------------------------------------
  1788.        *       ACTIVE LIST ON FRAGMENT IS EMPTY AND WE ARE WAITING FOR 
  1789.        *       THIS TO HAPPEN.    
  1790.        *       WE WILL NOW START THE CHECKPOINT IN TUP AND ACC.
  1791.        * ----------------------------------------------------------------- */
  1792.       /*      SEND START LOCAL CHECKPOINT TO ACC AND TUP                   */
  1793.       /* ----------------------------------------------------------------- */
  1794.       fragptr.p->lcpRef = RNIL;
  1795.       lcpPtr.p->lcpState = LcpRecord::LCP_START_CHKP;
  1796.       sendStartLcp(signal);
  1797.     }//if
  1798.   }//if
  1799. }//Dblqh::releaseActiveFrag()
  1800. /* ######################################################################### */
  1801. /* #######                   TRANSACTION MODULE                      ####### */
  1802. /*      THIS MODULE HANDLES THE COMMIT AND THE COMPLETE PHASE.               */
  1803. /* ######################################################################### */
  1804. void Dblqh::warningReport(Signal* signal, int place)
  1805. {
  1806.   switch (place) {
  1807.   case 0:
  1808.     jam();
  1809. #ifdef ABORT_TRACE
  1810.     ndbout << "W: Received COMMIT in wrong state in Dblqh" << endl;
  1811. #endif
  1812.     break;
  1813.   case 1:
  1814.     jam();
  1815. #ifdef ABORT_TRACE
  1816.     ndbout << "W: Received COMMIT with wrong transid in Dblqh" << endl;
  1817. #endif
  1818.     break;
  1819.   case 2:
  1820.     jam();
  1821. #ifdef ABORT_TRACE
  1822.     ndbout << "W: Received COMPLETE in wrong state in Dblqh" << endl;
  1823. #endif
  1824.     break;
  1825.   case 3:
  1826.     jam();
  1827. #ifdef ABORT_TRACE
  1828.     ndbout << "W: Received COMPLETE with wrong transid in Dblqh" << endl;
  1829. #endif
  1830.     break;
  1831.   case 4:
  1832.     jam();
  1833. #ifdef ABORT_TRACE
  1834.     ndbout << "W: Received COMMITREQ in wrong state in Dblqh" << endl;
  1835. #endif
  1836.     break;
  1837.   case 5:
  1838.     jam();
  1839. #ifdef ABORT_TRACE
  1840.     ndbout << "W: Received COMMITREQ with wrong transid in Dblqh" << endl;
  1841. #endif
  1842.     break;
  1843.   case 6:
  1844.     jam();
  1845. #ifdef ABORT_TRACE
  1846.     ndbout << "W: Received COMPLETEREQ in wrong state in Dblqh" << endl;
  1847. #endif
  1848.     break;
  1849.   case 7:
  1850.     jam();
  1851. #ifdef ABORT_TRACE
  1852.     ndbout << "W: Received COMPLETEREQ with wrong transid in Dblqh" << endl;
  1853. #endif
  1854.     break;
  1855.   case 8:
  1856.     jam();
  1857. #ifdef ABORT_TRACE
  1858.     ndbout << "W: Received ABORT with non-existing transid in Dblqh" << endl;
  1859. #endif
  1860.     break;
  1861.   case 9:
  1862.     jam();
  1863. #ifdef ABORT_TRACE
  1864.     ndbout << "W: Received ABORTREQ with non-existing transid in Dblqh" << endl;
  1865. #endif
  1866.     break;
  1867.   case 10:
  1868.     jam();
  1869. #ifdef ABORT_TRACE
  1870.     ndbout << "W: Received ABORTREQ in wrong state in Dblqh" << endl;
  1871. #endif
  1872.     break;
  1873.   case 11:
  1874.     jam();
  1875. #ifdef ABORT_TRACE
  1876.     ndbout << "W: Received COMMIT when tc-rec released in Dblqh" << endl;
  1877. #endif
  1878.     break;
  1879.   case 12:
  1880.     jam();
  1881. #ifdef ABORT_TRACE
  1882.     ndbout << "W: Received COMPLETE when tc-rec released in Dblqh" << endl;
  1883. #endif
  1884.     break;
  1885.   case 13:
  1886.     jam();
  1887. #ifdef ABORT_TRACE
  1888.     ndbout << "W: Received LQHKEYREF when tc-rec released in Dblqh" << endl;
  1889. #endif
  1890.     break;
  1891.   case 14:
  1892.     jam();
  1893. #ifdef ABORT_TRACE
  1894.     ndbout << "W: Received LQHKEYREF with wrong transid in Dblqh" << endl;
  1895. #endif
  1896.     break;
  1897.   case 15:
  1898.     jam();
  1899. #ifdef ABORT_TRACE
  1900.     ndbout << "W: Received LQHKEYREF when already aborting in Dblqh" << endl;
  1901. #endif
  1902.     break;
  1903.   case 16:
  1904.     jam();
  1905.     ndbrequire(cstartPhase == ZNIL);
  1906. #ifdef ABORT_TRACE
  1907.     ndbout << "W: Received LQHKEYREF in wrong state in Dblqh" << endl;
  1908. #endif
  1909.     break;
  1910.   default:
  1911.     jam();
  1912.     break;
  1913.   }//switch
  1914.   return;
  1915. }//Dblqh::warningReport()
  1916. void Dblqh::errorReport(Signal* signal, int place)
  1917. {
  1918.   switch (place) {
  1919.   case 0:
  1920.     jam();
  1921.     break;
  1922.   case 1:
  1923.     jam();
  1924.     break;
  1925.   case 2:
  1926.     jam();
  1927.     break;
  1928.   case 3:
  1929.     jam();
  1930.     break;
  1931.   default:
  1932.     jam();
  1933.     break;
  1934.   }//switch
  1935.   systemErrorLab(signal);
  1936.   return;
  1937. }//Dblqh::errorReport()
  1938. /* ************************************************************************>>
  1939.  *  COMMIT: Start commit request from TC. This signal is originally sent as a
  1940.  *  packed signal and this function is called from execPACKED_SIGNAL.
  1941.  *  This is the normal commit protocol where TC first send this signal to the
  1942.  *  backup node which then will send COMMIT to the primary node. If 
  1943.  *  everything is ok the primary node send COMMITTED back to TC.
  1944.  * ************************************************************************>> */
  1945. void Dblqh::execCOMMIT(Signal* signal) 
  1946. {
  1947.   TcConnectionrec *regTcConnectionrec = tcConnectionrec;
  1948.   Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
  1949.   Uint32 tcIndex = signal->theData[0];
  1950.   Uint32 gci = signal->theData[1];
  1951.   Uint32 transid1 = signal->theData[2];
  1952.   Uint32 transid2 = signal->theData[3];
  1953.   jamEntry();
  1954.   if (tcIndex >= ttcConnectrecFileSize) {
  1955.     errorReport(signal, 0);
  1956.     return;
  1957.   }//if
  1958.   if (ERROR_INSERTED(5011)) {
  1959.     CLEAR_ERROR_INSERT_VALUE;
  1960.     sendSignalWithDelay(cownref, GSN_COMMIT, signal, 2000, 4);
  1961.     return;
  1962.   }//if
  1963.   if (ERROR_INSERTED(5012)) {
  1964.     SET_ERROR_INSERT_VALUE(5017);
  1965.     sendSignalWithDelay(cownref, GSN_COMMIT, signal, 2000, 4);
  1966.     return;
  1967.   }//if
  1968.   tcConnectptr.i = tcIndex;
  1969.   ptrAss(tcConnectptr, regTcConnectionrec);
  1970.   if ((tcConnectptr.p->transid[0] == transid1) &&
  1971.       (tcConnectptr.p->transid[1] == transid2)) {
  1972.     commitReqLab(signal, gci);
  1973.     return;
  1974.   }//if
  1975.   warningReport(signal, 1);
  1976.   return;
  1977. }//Dblqh::execCOMMIT()
  1978. /* ************************************************************************>> 
  1979.  *  COMMITREQ: Commit request from TC. This is the commit protocol used if
  1980.  *  one of the nodes is not behaving correctly. TC explicitly sends COMMITREQ 
  1981.  *  to both the backup and primary node and gets a COMMITCONF back if the 
  1982.  *  COMMIT was ok. 
  1983.  * ************************************************************************>> */
  1984. void Dblqh::execCOMMITREQ(Signal* signal) 
  1985. {
  1986.   jamEntry();
  1987.   Uint32 reqPtr = signal->theData[0];
  1988.   BlockReference reqBlockref = signal->theData[1];
  1989.   Uint32 gci = signal->theData[2];
  1990.   Uint32 transid1 = signal->theData[3];
  1991.   Uint32 transid2 = signal->theData[4];
  1992.   Uint32 tcOprec = signal->theData[6];
  1993.   if (ERROR_INSERTED(5004)) {
  1994.     systemErrorLab(signal);
  1995.   }
  1996.   if (ERROR_INSERTED(5017)) {
  1997.     CLEAR_ERROR_INSERT_VALUE;
  1998.     sendSignalWithDelay(cownref, GSN_COMMITREQ, signal, 2000, 7);
  1999.     return;
  2000.   }//if
  2001.   if (findTransaction(transid1,
  2002.                       transid2,
  2003.                       tcOprec) != ZOK) {
  2004.     warningReport(signal, 5);
  2005.     return;
  2006.   }//if
  2007.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  2008.   switch (regTcPtr->transactionState) {
  2009.   case TcConnectionrec::PREPARED:
  2010.   case TcConnectionrec::LOG_COMMIT_QUEUED_WAIT_SIGNAL:
  2011.   case TcConnectionrec::LOG_COMMIT_WRITTEN_WAIT_SIGNAL:
  2012.     jam();
  2013. /*-------------------------------------------------------*/
  2014. /*       THE NORMAL CASE.                                */
  2015. /*-------------------------------------------------------*/
  2016.     regTcPtr->reqBlockref = reqBlockref;
  2017.     regTcPtr->reqRef = reqPtr;
  2018.     regTcPtr->abortState = TcConnectionrec::REQ_FROM_TC;
  2019.     commitReqLab(signal, gci);
  2020.     return;
  2021.     break;
  2022.   case TcConnectionrec::COMMITTED:
  2023.     jam();
  2024. /*---------------------------------------------------------*/
  2025. /*       FOR SOME REASON THE COMMIT PHASE HAVE BEEN        */
  2026. /*       FINISHED AFTER A TIME OUT. WE NEED ONLY SEND A    */
  2027. /*       COMMITCONF SIGNAL.                                */
  2028. /*---------------------------------------------------------*/
  2029.     regTcPtr->reqBlockref = reqBlockref;
  2030.     regTcPtr->reqRef = reqPtr;
  2031.     regTcPtr->abortState = TcConnectionrec::REQ_FROM_TC;
  2032.     signal->theData[0] = regTcPtr->reqRef;
  2033.     signal->theData[1] = cownNodeid;
  2034.     signal->theData[2] = regTcPtr->transid[0];
  2035.     signal->theData[3] = regTcPtr->transid[1];
  2036.     sendSignal(regTcPtr->reqBlockref, GSN_COMMITCONF, signal, 4, JBB);
  2037.     break;
  2038.   case TcConnectionrec::COMMIT_STOPPED:
  2039.     jam();
  2040.     regTcPtr->reqBlockref = reqBlockref;
  2041.     regTcPtr->reqRef = reqPtr;
  2042.     regTcPtr->abortState = TcConnectionrec::REQ_FROM_TC;
  2043.     /*empty*/;
  2044.     break;
  2045.   default:
  2046.     jam();
  2047.     warningReport(signal, 4);
  2048.     return;
  2049.     break;
  2050.   }//switch
  2051.   return;
  2052. }//Dblqh::execCOMMITREQ()
  2053. /* ************************************************************************>>
  2054.  *  COMPLETE : Complete the transaction. Sent as a packed signal from TC.
  2055.  *  Works the same way as COMMIT protocol. This is the normal case with both 
  2056.  *  primary and backup working (See COMMIT).
  2057.  * ************************************************************************>> */
  2058. void Dblqh::execCOMPLETE(Signal* signal) 
  2059. {
  2060.   TcConnectionrec *regTcConnectionrec = tcConnectionrec;
  2061.   Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
  2062.   Uint32 tcIndex = signal->theData[0];
  2063.   Uint32 transid1 = signal->theData[1];
  2064.   Uint32 transid2 = signal->theData[2];
  2065.   jamEntry();
  2066.   if (tcIndex >= ttcConnectrecFileSize) {
  2067.     errorReport(signal, 1);
  2068.     return;
  2069.   }//if
  2070.   if (ERROR_INSERTED(5013)) {
  2071.     CLEAR_ERROR_INSERT_VALUE;
  2072.     sendSignalWithDelay(cownref, GSN_COMPLETE, signal, 2000, 3);
  2073.     return;
  2074.   }//if
  2075.   if (ERROR_INSERTED(5014)) {
  2076.     SET_ERROR_INSERT_VALUE(5018);
  2077.     sendSignalWithDelay(cownref, GSN_COMPLETE, signal, 2000, 3);
  2078.     return;
  2079.   }//if
  2080.   tcConnectptr.i = tcIndex;
  2081.   ptrAss(tcConnectptr, regTcConnectionrec);
  2082.   if ((tcConnectptr.p->transactionState == TcConnectionrec::COMMITTED) &&
  2083.       (tcConnectptr.p->transid[0] == transid1) &&
  2084.       (tcConnectptr.p->transid[1] == transid2)) {
  2085.     if (tcConnectptr.p->seqNoReplica != 0) {
  2086.       jam();
  2087.       localCommitLab(signal);
  2088.       return;
  2089.     } else {
  2090.       jam();
  2091.       completeTransLastLab(signal);
  2092.       return;
  2093.     }//if
  2094.   }//if
  2095.   if (tcConnectptr.p->transactionState != TcConnectionrec::COMMITTED) {
  2096.     warningReport(signal, 2);
  2097.   } else {
  2098.     warningReport(signal, 3);
  2099.   }//if
  2100. }//Dblqh::execCOMPLETE()
  2101. /* ************************************************************************>>
  2102.  * COMPLETEREQ: Complete request from TC. Same as COMPLETE but used if one 
  2103.  * node is not working ok (See COMMIT).
  2104.  * ************************************************************************>> */
  2105. void Dblqh::execCOMPLETEREQ(Signal* signal) 
  2106. {
  2107.   jamEntry();
  2108.   Uint32 reqPtr = signal->theData[0];
  2109.   BlockReference reqBlockref = signal->theData[1];
  2110.   Uint32 transid1 = signal->theData[2];
  2111.   Uint32 transid2 = signal->theData[3];
  2112.   Uint32 tcOprec = signal->theData[5];
  2113.   if (ERROR_INSERTED(5005)) {
  2114.     systemErrorLab(signal);
  2115.   }
  2116.   if (ERROR_INSERTED(5018)) {
  2117.     CLEAR_ERROR_INSERT_VALUE;
  2118.     sendSignalWithDelay(cownref, GSN_COMPLETEREQ, signal, 2000, 6);
  2119.     return;
  2120.   }//if
  2121.   if (findTransaction(transid1,
  2122.                       transid2,
  2123.                       tcOprec) != ZOK) {
  2124.     jam();
  2125. /*---------------------------------------------------------*/
  2126. /*       FOR SOME REASON THE COMPLETE PHASE STARTED AFTER  */
  2127. /*       A TIME OUT. THE TRANSACTION IS GONE. WE NEED TO   */
  2128. /*       REPORT COMPLETION ANYWAY.                         */
  2129. /*---------------------------------------------------------*/
  2130.     signal->theData[0] = reqPtr;
  2131.     signal->theData[1] = cownNodeid;
  2132.     signal->theData[2] = transid1;
  2133.     signal->theData[3] = transid2;
  2134.     sendSignal(reqBlockref, GSN_COMPLETECONF, signal, 4, JBB);
  2135.     warningReport(signal, 7);
  2136.     return;
  2137.   }//if
  2138.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  2139.   switch (regTcPtr->transactionState) {
  2140.   case TcConnectionrec::COMMITTED:
  2141.     jam();
  2142.     regTcPtr->reqBlockref = reqBlockref;
  2143.     regTcPtr->reqRef = reqPtr;
  2144.     regTcPtr->abortState = TcConnectionrec::REQ_FROM_TC;
  2145.     /*empty*/;
  2146.     break;
  2147. /*---------------------------------------------------------*/
  2148. /*       THE NORMAL CASE.                                  */
  2149. /*---------------------------------------------------------*/
  2150.   case TcConnectionrec::COMMIT_STOPPED:
  2151.     jam();
  2152. /*---------------------------------------------------------*/
  2153. /*       FOR SOME REASON THE COMPLETE PHASE STARTED AFTER  */
  2154. /*       A TIME OUT. WE HAVE SET THE PROPER VARIABLES SUCH */
  2155. /*       THAT A COMPLETECONF WILL BE SENT WHEN COMPLETE IS */
  2156. /*       FINISHED.                                         */
  2157. /*---------------------------------------------------------*/
  2158.     regTcPtr->reqBlockref = reqBlockref;
  2159.     regTcPtr->reqRef = reqPtr;
  2160.     regTcPtr->abortState = TcConnectionrec::REQ_FROM_TC;
  2161.     return;
  2162.     break;
  2163.   default:
  2164.     jam();
  2165.     warningReport(signal, 6);
  2166.     return;
  2167.     break;
  2168.   }//switch
  2169.   if (regTcPtr->seqNoReplica != 0) {
  2170.     jam();
  2171.     localCommitLab(signal);
  2172.     return;
  2173.   } else {
  2174.     jam();
  2175.     completeTransLastLab(signal);
  2176.     return;
  2177.   }//if
  2178. }//Dblqh::execCOMPLETEREQ()
  2179. /* ************> */
  2180. /*  COMPLETED  > */
  2181. /* ************> */
  2182. void Dblqh::execLQHKEYCONF(Signal* signal) 
  2183. {
  2184.   LqhKeyConf * const lqhKeyConf = (LqhKeyConf *)signal->getDataPtr();
  2185.   Uint32 tcIndex = lqhKeyConf->opPtr;
  2186.   Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
  2187.   TcConnectionrec *regTcConnectionrec = tcConnectionrec;
  2188.   jamEntry();
  2189.   if (tcIndex >= ttcConnectrecFileSize) {
  2190.     errorReport(signal, 2);
  2191.     return;
  2192.   }//if
  2193.   tcConnectptr.i = tcIndex;  
  2194.   ptrAss(tcConnectptr, regTcConnectionrec);
  2195.   switch (tcConnectptr.p->connectState) {
  2196.   case TcConnectionrec::LOG_CONNECTED:
  2197.     jam();
  2198.     completedLab(signal);
  2199.     return;
  2200.     break;
  2201.   case TcConnectionrec::COPY_CONNECTED:
  2202.     jam();
  2203.     copyCompletedLab(signal);
  2204.     return;
  2205.     break;
  2206.   default:
  2207.     jam();
  2208.     ndbrequire(false);
  2209.     break;
  2210.   }//switch
  2211.   return;
  2212. }//Dblqh::execLQHKEYCONF()
  2213. /* ------------------------------------------------------------------------- */
  2214. /* -------                       COMMIT PHASE                        ------- */
  2215. /*                                                                           */
  2216. /* ------------------------------------------------------------------------- */
  2217. void Dblqh::commitReqLab(Signal* signal, Uint32 gci) 
  2218. {
  2219.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  2220.   TcConnectionrec::LogWriteState logWriteState = regTcPtr->logWriteState;
  2221.   TcConnectionrec::TransactionState transState = regTcPtr->transactionState;
  2222.   regTcPtr->gci = gci; 
  2223.   if (transState == TcConnectionrec::PREPARED) {
  2224.     if (logWriteState == TcConnectionrec::WRITTEN) {
  2225.       jam();
  2226.       regTcPtr->transactionState = TcConnectionrec::PREPARED_RECEIVED_COMMIT;
  2227.       TcConnectionrecPtr saveTcPtr = tcConnectptr;
  2228.       Uint32 blockNo = refToBlock(regTcPtr->tcTupBlockref);
  2229.       signal->theData[0] = regTcPtr->tupConnectrec;
  2230.       signal->theData[1] = gci;
  2231.       EXECUTE_DIRECT(blockNo, GSN_TUP_WRITELOG_REQ, signal, 2);
  2232.       jamEntry();
  2233.       if (regTcPtr->transactionState == TcConnectionrec::LOG_COMMIT_QUEUED) {
  2234.         jam();
  2235.         return;
  2236.       }//if
  2237.       ndbrequire(regTcPtr->transactionState == TcConnectionrec::LOG_COMMIT_WRITTEN);
  2238.       tcConnectptr = saveTcPtr;
  2239.     } else if (logWriteState == TcConnectionrec::NOT_STARTED) {
  2240.       jam();
  2241.     } else if (logWriteState == TcConnectionrec::NOT_WRITTEN) {
  2242.       jam();
  2243. /*---------------------------------------------------------------------------*/
  2244. /* IT IS A READ OPERATION OR OTHER OPERATION THAT DO NOT USE THE LOG.        */
  2245. /*---------------------------------------------------------------------------*/
  2246. /*---------------------------------------------------------------------------*/
  2247. /* THE LOG HAS NOT BEEN WRITTEN SINCE THE LOG FLAG WAS FALSE. THIS CAN OCCUR */
  2248. /* WHEN WE ARE STARTING A NEW FRAGMENT.                                      */
  2249. /*---------------------------------------------------------------------------*/
  2250.       regTcPtr->logWriteState = TcConnectionrec::NOT_STARTED;
  2251.     } else {
  2252.       ndbrequire(logWriteState == TcConnectionrec::NOT_WRITTEN_WAIT);
  2253.       jam();
  2254. /*---------------------------------------------------------------------------*/
  2255. /* THE STATE WAS SET TO NOT_WRITTEN BY THE OPERATION BUT LATER A SCAN OF ALL */
  2256. /* OPERATION RECORD CHANGED IT INTO NOT_WRITTEN_WAIT. THIS INDICATES THAT WE */
  2257. /* ARE WAITING FOR THIS OPERATION TO COMMIT OR ABORT SO THAT WE CAN FIND THE */
  2258. /* STARTING GLOBAL CHECKPOINT OF THIS NEW FRAGMENT.                          */
  2259. /*---------------------------------------------------------------------------*/
  2260.       checkScanTcCompleted(signal);
  2261.     }//if
  2262.   } else if (transState == TcConnectionrec::LOG_COMMIT_QUEUED_WAIT_SIGNAL) {
  2263.     jam();
  2264.     regTcPtr->transactionState = TcConnectionrec::LOG_COMMIT_QUEUED;
  2265.     return;
  2266.   } else if (transState == TcConnectionrec::LOG_COMMIT_WRITTEN_WAIT_SIGNAL) {
  2267.     jam();
  2268.   } else {
  2269.     warningReport(signal, 0);
  2270.     return;
  2271.   }//if
  2272.   if (regTcPtr->seqNoReplica != 0) {
  2273.     jam();
  2274.     commitReplyLab(signal);
  2275.     return;
  2276.   }//if
  2277.   localCommitLab(signal);
  2278.   return;
  2279. }//Dblqh::commitReqLab()
  2280. void Dblqh::execLQH_WRITELOG_REQ(Signal* signal)
  2281. {
  2282.   jamEntry();
  2283.   tcConnectptr.i = signal->theData[0];
  2284.   ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  2285.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  2286.   Uint32 gci = signal->theData[1];
  2287.   Uint32 newestGci = cnewestGci;
  2288.   TcConnectionrec::LogWriteState logWriteState = regTcPtr->logWriteState;
  2289.   TcConnectionrec::TransactionState transState = regTcPtr->transactionState;
  2290.   regTcPtr->gci = gci;
  2291.   if (gci > newestGci) {
  2292.     jam();
  2293. /* ------------------------------------------------------------------------- */
  2294. /*       KEEP TRACK OF NEWEST GLOBAL CHECKPOINT THAT LQH HAS HEARD OF.       */
  2295. /* ------------------------------------------------------------------------- */
  2296.     cnewestGci = gci;
  2297.   }//if
  2298.   if (logWriteState == TcConnectionrec::WRITTEN) {
  2299. /*---------------------------------------------------------------------------*/
  2300. /* I NEED TO INSERT A COMMIT LOG RECORD SINCE WE ARE WRITING LOG IN THIS     */
  2301. /* TRANSACTION.                                                              */
  2302. /*---------------------------------------------------------------------------*/
  2303.     jam();
  2304.     LogPartRecordPtr regLogPartPtr;
  2305.     Uint32 noOfLogPages = cnoOfLogPages;
  2306.     jam();
  2307.     regLogPartPtr.i = regTcPtr->hashValue & 3;
  2308.     ptrCheckGuard(regLogPartPtr, clogPartFileSize, logPartRecord);
  2309.     if ((regLogPartPtr.p->logPartState == LogPartRecord::ACTIVE) ||
  2310.         (noOfLogPages == 0)) {
  2311.       jam();
  2312. /*---------------------------------------------------------------------------*/
  2313. /* THIS LOG PART WAS CURRENTLY ACTIVE WRITING ANOTHER LOG RECORD. WE MUST    */
  2314. /* WAIT UNTIL THIS PART HAS COMPLETED ITS OPERATION.                         */
  2315. /*---------------------------------------------------------------------------*/
  2316. // We must delay the write of commit info to the log to safe-guard against
  2317. // a crash due to lack of log pages. We temporary stop all log writes to this
  2318. // log part to ensure that we don't get a buffer explosion in the delayed
  2319. // signal buffer instead.
  2320. /*---------------------------------------------------------------------------*/
  2321.       linkWaitLog(signal, regLogPartPtr);
  2322.       if (transState == TcConnectionrec::PREPARED) {
  2323.         jam();
  2324.         regTcPtr->transactionState = TcConnectionrec::LOG_COMMIT_QUEUED_WAIT_SIGNAL;
  2325.       } else {
  2326.         jam();
  2327.         ndbrequire(transState == TcConnectionrec::PREPARED_RECEIVED_COMMIT);
  2328.         regTcPtr->transactionState = TcConnectionrec::LOG_COMMIT_QUEUED;
  2329.       }//if
  2330.       if (regLogPartPtr.p->logPartState == LogPartRecord::IDLE) {
  2331.         jam();
  2332.         regLogPartPtr.p->logPartState = LogPartRecord::ACTIVE;
  2333.       }//if
  2334.       return;
  2335.     }//if
  2336.     writeCommitLog(signal, regLogPartPtr);
  2337.     if (transState == TcConnectionrec::PREPARED) {
  2338.       jam();
  2339.       regTcPtr->transactionState = TcConnectionrec::LOG_COMMIT_WRITTEN_WAIT_SIGNAL;
  2340.     } else {
  2341.       jam();
  2342.       ndbrequire(transState == TcConnectionrec::PREPARED_RECEIVED_COMMIT);
  2343.       regTcPtr->transactionState = TcConnectionrec::LOG_COMMIT_WRITTEN;
  2344.     }//if
  2345.   }//if
  2346. }//Dblqh::execLQH_WRITELOG_REQ()
  2347. void Dblqh::localCommitLab(Signal* signal) 
  2348. {
  2349.   FragrecordPtr regFragptr;
  2350.   regFragptr.i = tcConnectptr.p->fragmentptr;
  2351.   ptrCheckGuard(regFragptr, cfragrecFileSize, fragrecord);
  2352.   Fragrecord::FragStatus status = regFragptr.p->fragStatus;
  2353.   fragptr = regFragptr;
  2354.   switch (status) {
  2355.   case Fragrecord::FSACTIVE:
  2356.   case Fragrecord::CRASH_RECOVERING:
  2357.   case Fragrecord::ACTIVE_CREATION:
  2358.     jam();
  2359.     commitContinueAfterBlockedLab(signal);
  2360.     return;
  2361.     break;
  2362.   case Fragrecord::BLOCKED:
  2363.     jam();
  2364.     linkFragQueue(signal);
  2365.     tcConnectptr.p->transactionState = TcConnectionrec::COMMIT_STOPPED;
  2366.     break;
  2367.   case Fragrecord::FREE:
  2368.     jam();
  2369.   case Fragrecord::DEFINED:
  2370.     jam();
  2371.   case Fragrecord::REMOVING:
  2372.     jam();
  2373.   default:
  2374.     ndbrequire(false);
  2375.     break;
  2376.   }//switch
  2377. }//Dblqh::localCommitLab()
  2378. void Dblqh::commitContinueAfterBlockedLab(Signal* signal) 
  2379. {
  2380. /* ------------------------------------------------------------------------- */
  2381. /*INPUT:          TC_CONNECTPTR           ACTIVE OPERATION RECORD            */
  2382. /* ------------------------------------------------------------------------- */
  2383. /* ------------------------------------------------------------------------- */
  2384. /*CONTINUE HERE AFTER BEING BLOCKED FOR A WHILE DURING LOCAL CHECKPOINT.     */
  2385. /*The operation is already removed from the active list since there is no    */
  2386. /*chance for any real-time breaks before we need to release it.              */
  2387. /* ------------------------------------------------------------------------- */
  2388. /*ALSO AFTER NORMAL PROCEDURE WE CONTINUE                                    */
  2389. /*WE MUST COMMIT TUP BEFORE ACC TO ENSURE THAT NO ONE RACES IN AND SEES A    */
  2390. /*DIRTY STATE IN TUP.                                                        */
  2391. /* ------------------------------------------------------------------------- */
  2392.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  2393.   Fragrecord * const regFragptr = fragptr.p;
  2394.   Uint32 operation = regTcPtr->operation;
  2395.   Uint32 simpleRead = regTcPtr->simpleRead;
  2396.   Uint32 dirtyOp = regTcPtr->dirtyOp;
  2397.   if (regTcPtr->activeCreat == ZFALSE) {
  2398.     if ((cCommitBlocked == true) &&
  2399.         (regFragptr->fragActiveStatus == ZTRUE)) {
  2400.       jam();
  2401. /* ------------------------------------------------------------------------- */
  2402. // TUP and/or ACC have problems in writing the undo log to disk fast enough.
  2403. // We must avoid the commit at this time and try later instead. The fragment
  2404. // is also active with a local checkpoint and this commit can generate UNDO
  2405. // log records that overflow the UNDO log buffer.
  2406. /* ------------------------------------------------------------------------- */
  2407. /*---------------------------------------------------------------------------*/
  2408. // We must delay the write of commit info to the log to safe-guard against
  2409. // a crash due to lack of log pages. We temporary stop all log writes to this
  2410. // log part to ensure that we don't get a buffer explosion in the delayed
  2411. // signal buffer instead.
  2412. /*---------------------------------------------------------------------------*/
  2413.       logPartPtr.i = regTcPtr->hashValue & 3;
  2414.       ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
  2415.       linkWaitLog(signal, logPartPtr);
  2416.       regTcPtr->transactionState = TcConnectionrec::COMMIT_QUEUED;
  2417.       if (logPartPtr.p->logPartState == LogPartRecord::IDLE) {
  2418.         jam();
  2419.         logPartPtr.p->logPartState = LogPartRecord::ACTIVE;
  2420.       }//if
  2421.       return;
  2422.     }//if
  2423.     if (operation != ZREAD) {
  2424.       TupCommitReq * const tupCommitReq = 
  2425.         (TupCommitReq *)signal->getDataPtrSend();
  2426.       Uint32 sig0 = regTcPtr->tupConnectrec;
  2427.       Uint32 tup = refToBlock(regTcPtr->tcTupBlockref);
  2428.       jam();
  2429.       tupCommitReq->opPtr = sig0;
  2430.       tupCommitReq->gci = regTcPtr->gci;
  2431.       tupCommitReq->hashValue = regTcPtr->hashValue;
  2432.       EXECUTE_DIRECT(tup, GSN_TUP_COMMITREQ, signal, 
  2433.      TupCommitReq::SignalLength);
  2434.       Uint32 acc = refToBlock(regTcPtr->tcAccBlockref);
  2435.       signal->theData[0] = regTcPtr->accConnectrec;
  2436.       EXECUTE_DIRECT(acc, GSN_ACC_COMMITREQ, signal, 1);
  2437.     } else {
  2438.       if(!dirtyOp){
  2439. Uint32 acc = refToBlock(regTcPtr->tcAccBlockref);
  2440. signal->theData[0] = regTcPtr->accConnectrec;
  2441. EXECUTE_DIRECT(acc, GSN_ACC_COMMITREQ, signal, 1);
  2442.       }
  2443.     }
  2444.     jamEntry();
  2445.     if (simpleRead) {
  2446.       jam();
  2447. /* ------------------------------------------------------------------------- */
  2448. /*THE OPERATION WAS A SIMPLE READ THUS THE COMMIT PHASE IS ONLY NEEDED TO    */
  2449. /*RELEASE THE LOCKS. AT THIS POINT IN THE CODE THE LOCKS ARE RELEASED AND WE */
  2450. /*ARE IN A POSITION TO SEND LQHKEYCONF TO TC. WE WILL ALSO RELEASE ALL       */
  2451. /*RESOURCES BELONGING TO THIS OPERATION SINCE NO MORE WORK WILL BE           */
  2452. /*PERFORMED.                                                                 */
  2453. /* ------------------------------------------------------------------------- */
  2454.       cleanUp(signal);
  2455.       return;
  2456.     }//if
  2457.   }//if
  2458.   Uint32 seqNoReplica = regTcPtr->seqNoReplica;
  2459.   if (regTcPtr->gci > regFragptr->newestGci) {
  2460.     jam();
  2461. /* ------------------------------------------------------------------------- */
  2462. /*IT IS THE FIRST TIME THIS GLOBAL CHECKPOINT IS INVOLVED IN UPDATING THIS   */
  2463. /*FRAGMENT. UPDATE THE VARIABLE THAT KEEPS TRACK OF NEWEST GCI IN FRAGMENT   */
  2464. /* ------------------------------------------------------------------------- */
  2465.     regFragptr->newestGci = regTcPtr->gci;
  2466.   }//if
  2467.   if (dirtyOp != ZTRUE) {
  2468.     if (seqNoReplica != 0) {
  2469.       jam();
  2470.       completeTransNotLastLab(signal);
  2471.       return;
  2472.     }//if
  2473.     commitReplyLab(signal);
  2474.     return;
  2475.   } else {
  2476. /* ------------------------------------------------------------------------- */
  2477. /*WE MUST HANDLE DIRTY WRITES IN A SPECIAL WAY. THESE OPERATIONS WILL NOT    */
  2478. /*SEND ANY COMMIT OR COMPLETE MESSAGES TO OTHER NODES. THEY WILL MERELY SEND */
  2479. /*THOSE SIGNALS INTERNALLY.                                                  */
  2480. /* ------------------------------------------------------------------------- */
  2481.     if (regTcPtr->abortState == TcConnectionrec::ABORT_IDLE) {
  2482.       jam();
  2483.       packLqhkeyreqLab(signal);
  2484.     } else {
  2485.       ndbrequire(regTcPtr->abortState != TcConnectionrec::NEW_FROM_TC);
  2486.       jam();
  2487.       sendLqhTransconf(signal, LqhTransConf::Committed);
  2488.       cleanUp(signal);
  2489.     }//if
  2490.   }//if
  2491. }//Dblqh::commitContinueAfterBlockedLab()
  2492. void Dblqh::commitReplyLab(Signal* signal) 
  2493. {
  2494. /* -------------------------------------------------------------- */
  2495. /* BACKUP AND STAND-BY REPLICAS ONLY UPDATE THE TRANSACTION STATE */
  2496. /* -------------------------------------------------------------- */
  2497.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  2498.   TcConnectionrec::AbortState abortState = regTcPtr->abortState;
  2499.   regTcPtr->transactionState = TcConnectionrec::COMMITTED;
  2500.   if (abortState == TcConnectionrec::ABORT_IDLE) {
  2501.     Uint32 clientBlockref = regTcPtr->clientBlockref;
  2502.     if (regTcPtr->seqNoReplica == 0) {
  2503.       jam();
  2504.       sendCommittedTc(signal, clientBlockref);
  2505.       return;
  2506.     } else {
  2507.       jam();
  2508.       sendCommitLqh(signal, clientBlockref);
  2509.       return;
  2510.     }//if
  2511.   } else if (regTcPtr->abortState == TcConnectionrec::REQ_FROM_TC) {
  2512.     jam();
  2513.     signal->theData[0] = regTcPtr->reqRef;
  2514.     signal->theData[1] = cownNodeid;
  2515.     signal->theData[2] = regTcPtr->transid[0];
  2516.     signal->theData[3] = regTcPtr->transid[1];
  2517.     sendSignal(tcConnectptr.p->reqBlockref, GSN_COMMITCONF, signal, 4, JBB);
  2518.   } else {
  2519.     ndbrequire(regTcPtr->abortState == TcConnectionrec::NEW_FROM_TC);
  2520.     jam();
  2521.     sendLqhTransconf(signal, LqhTransConf::Committed);
  2522.   }//if
  2523.   return;
  2524. }//Dblqh::commitReplyLab()
  2525. /* ------------------------------------------------------------------------- */
  2526. /* -------                COMPLETE PHASE                             ------- */
  2527. /*                                                                           */
  2528. /* ------------------------------------------------------------------------- */
  2529. void Dblqh::completeTransNotLastLab(Signal* signal) 
  2530. {
  2531.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  2532.   if (regTcPtr->abortState == TcConnectionrec::ABORT_IDLE) {
  2533.     Uint32 clientBlockref = regTcPtr->clientBlockref;
  2534.     jam();
  2535.     sendCompleteLqh(signal, clientBlockref);
  2536.     cleanUp(signal);
  2537.     return;
  2538.   } else {
  2539.     jam();
  2540.     completeUnusualLab(signal);
  2541.     return;
  2542.   }//if
  2543. }//Dblqh::completeTransNotLastLab()
  2544. void Dblqh::completeTransLastLab(Signal* signal) 
  2545. {
  2546.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  2547.   if (regTcPtr->abortState == TcConnectionrec::ABORT_IDLE) {
  2548.     Uint32 clientBlockref = regTcPtr->clientBlockref;
  2549.     jam();
  2550. /* ------------------------------------------------------------------------- */
  2551. /*DIRTY WRITES WHICH ARE LAST IN THE CHAIN OF REPLICAS WILL SEND COMPLETED   */
  2552. /*INSTEAD OF SENDING PREPARED TO THE TC (OR OTHER INITIATOR OF OPERATION).   */
  2553. /* ------------------------------------------------------------------------- */
  2554.     sendCompletedTc(signal, clientBlockref);
  2555.     cleanUp(signal);
  2556.     return;
  2557.   } else {
  2558.     jam();
  2559.     completeUnusualLab(signal);
  2560.     return;
  2561.   }//if
  2562. }//Dblqh::completeTransLastLab()
  2563. void Dblqh::completeUnusualLab(Signal* signal) 
  2564. {
  2565.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  2566.   if (regTcPtr->abortState == TcConnectionrec::ABORT_FROM_TC) {
  2567.     jam();
  2568.     sendAborted(signal);
  2569.   } else if (regTcPtr->abortState == TcConnectionrec::NEW_FROM_TC) {
  2570.     jam();
  2571.     sendLqhTransconf(signal, LqhTransConf::Committed);
  2572.   } else {
  2573.     ndbrequire(regTcPtr->abortState == TcConnectionrec::REQ_FROM_TC);
  2574.     jam();
  2575.     signal->theData[0] = regTcPtr->reqRef;
  2576.     signal->theData[1] = cownNodeid;
  2577.     signal->theData[2] = regTcPtr->transid[0];
  2578.     signal->theData[3] = regTcPtr->transid[1];
  2579.     sendSignal(regTcPtr->reqBlockref,
  2580.                GSN_COMPLETECONF, signal, 4, JBB);
  2581.   }//if
  2582.   cleanUp(signal);
  2583.   return;
  2584. }//Dblqh::completeUnusualLab()
  2585. /* ========================================================================= */
  2586. /* =======                        RELEASE TC CONNECT RECORD          ======= */
  2587. /*                                                                           */
  2588. /*       RELEASE A TC CONNECT RECORD TO THE FREELIST.                        */
  2589. /* ========================================================================= */
  2590. void Dblqh::releaseTcrec(Signal* signal, TcConnectionrecPtr locTcConnectptr) 
  2591. {
  2592.   jam();
  2593.   locTcConnectptr.p->tcTimer = 0;
  2594.   locTcConnectptr.p->transactionState = TcConnectionrec::TC_NOT_CONNECTED;
  2595.   locTcConnectptr.p->nextTcConnectrec = cfirstfreeTcConrec;
  2596.   cfirstfreeTcConrec = locTcConnectptr.i;
  2597.   TablerecPtr tabPtr;
  2598.   tabPtr.i = locTcConnectptr.p->tableref;
  2599.   if(tabPtr.i == RNIL)
  2600.     return;
  2601.   ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
  2602.   
  2603.   /**
  2604.    * Normal case
  2605.    */
  2606.   ndbrequire(tabPtr.p->usageCount > 0);
  2607.   tabPtr.p->usageCount--;
  2608. }//Dblqh::releaseTcrec()
  2609. void Dblqh::releaseTcrecLog(Signal* signal, TcConnectionrecPtr locTcConnectptr) 
  2610. {
  2611.   jam();
  2612.   locTcConnectptr.p->tcTimer = 0;
  2613.   locTcConnectptr.p->transactionState = TcConnectionrec::TC_NOT_CONNECTED;
  2614.   locTcConnectptr.p->nextTcConnectrec = cfirstfreeTcConrec;
  2615.   cfirstfreeTcConrec = locTcConnectptr.i;
  2616.   TablerecPtr tabPtr;
  2617.   tabPtr.i = locTcConnectptr.p->tableref;
  2618.   if(tabPtr.i == RNIL)
  2619.     return;
  2620. }//Dblqh::releaseTcrecLog()
  2621. /* ------------------------------------------------------------------------- */
  2622. /* -------                       ABORT PHASE                         ------- */
  2623. /*                                                                           */
  2624. /*THIS PART IS USED AT ERRORS THAT CAUSE ABORT OF TRANSACTION.               */
  2625. /* ------------------------------------------------------------------------- */
  2626. /* ***************************************************>> */
  2627. /*  ABORT: Abort transaction in connection. Sender TC.   */
  2628. /*  This is the normal protocol (See COMMIT)             */
  2629. /* ***************************************************>> */
  2630. void Dblqh::execABORT(Signal* signal) 
  2631. {
  2632.   jamEntry();
  2633.   Uint32 tcOprec = signal->theData[0];
  2634.   BlockReference tcBlockref = signal->theData[1];
  2635.   Uint32 transid1 = signal->theData[2];
  2636.   Uint32 transid2 = signal->theData[3];
  2637.   CRASH_INSERTION(5003);
  2638.   if (ERROR_INSERTED(5015)) {
  2639.     CLEAR_ERROR_INSERT_VALUE;
  2640.     sendSignalWithDelay(cownref, GSN_ABORT, signal, 2000, 4);
  2641.     return;
  2642.   }//if
  2643.   if (findTransaction(transid1,
  2644.                       transid2,
  2645.                       tcOprec) != ZOK) {
  2646.     jam();
  2647.     if(ERROR_INSERTED(5039) && 
  2648.        refToNode(signal->getSendersBlockRef()) != getOwnNodeId()){
  2649.       jam();
  2650.       SET_ERROR_INSERT_VALUE(5040);
  2651.       return;
  2652.     }
  2653.     if(ERROR_INSERTED(5040) && 
  2654.        refToNode(signal->getSendersBlockRef()) != getOwnNodeId()){
  2655.       jam();
  2656.       SET_ERROR_INSERT_VALUE(5003);
  2657.       return;
  2658.     }
  2659.     
  2660. /* ------------------------------------------------------------------------- */
  2661. // SEND ABORTED EVEN IF NOT FOUND.
  2662. //THE TRANSACTION MIGHT NEVER HAVE ARRIVED HERE.
  2663. /* ------------------------------------------------------------------------- */
  2664.     signal->theData[0] = tcOprec;
  2665.     signal->theData[1] = transid1;
  2666.     signal->theData[2] = transid2;
  2667.     signal->theData[3] = cownNodeid;
  2668.     signal->theData[4] = ZTRUE;
  2669.     sendSignal(tcBlockref, GSN_ABORTED, signal, 5, JBB);
  2670.     warningReport(signal, 8);
  2671.     return;
  2672.   }//if
  2673. /* ------------------------------------------------------------------------- */
  2674. /*A GUIDING DESIGN PRINCIPLE IN HANDLING THESE ERROR SITUATIONS HAVE BEEN    */
  2675. /*KEEP IT SIMPLE. THUS WE RATHER INSERT A WAIT AND SET THE ABORT_STATE TO    */
  2676. /*ACTIVE RATHER THAN WRITE NEW CODE TO HANDLE EVERY SPECIAL SITUATION.       */
  2677. /* ------------------------------------------------------------------------- */
  2678.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  2679.   if (regTcPtr->nextReplica != ZNIL) {
  2680. /* ------------------------------------------------------------------------- */
  2681. // We will immediately send the ABORT message also to the next LQH node in line.
  2682. /* ------------------------------------------------------------------------- */
  2683.     BlockReference TLqhRef = calcLqhBlockRef(regTcPtr->nextReplica);
  2684.     signal->theData[0] = regTcPtr->tcOprec;
  2685.     signal->theData[1] = regTcPtr->tcBlockref;
  2686.     signal->theData[2] = regTcPtr->transid[0];
  2687.     signal->theData[3] = regTcPtr->transid[1];
  2688.     sendSignal(TLqhRef, GSN_ABORT, signal, 4, JBB);
  2689.   }//if
  2690.   regTcPtr->abortState = TcConnectionrec::ABORT_FROM_TC;
  2691.   regTcPtr->activeCreat = ZFALSE;
  2692.   const Uint32 commitAckMarker = regTcPtr->commitAckMarker;
  2693.   if(commitAckMarker != RNIL){
  2694.     jam();
  2695. #ifdef MARKER_TRACE
  2696.     {
  2697.       CommitAckMarkerPtr tmp;
  2698.       m_commitAckMarkerHash.getPtr(tmp, commitAckMarker);
  2699.       ndbout_c("Ab2 marker[%.8x %.8x]", tmp.p->transid1, tmp.p->transid2);
  2700.     }
  2701. #endif
  2702.     m_commitAckMarkerHash.release(commitAckMarker);
  2703.     regTcPtr->commitAckMarker = RNIL;
  2704.   }
  2705.   abortStateHandlerLab(signal);
  2706.   return;
  2707. }//Dblqh::execABORT()
  2708. /* ************************************************************************>> 
  2709.  *  ABORTREQ: Same as ABORT but used in case one node isn't working ok. 
  2710.  *  (See COMMITREQ) 
  2711.  * ************************************************************************>> */
  2712. void Dblqh::execABORTREQ(Signal* signal) 
  2713. {
  2714.   jamEntry();
  2715.   Uint32 reqPtr = signal->theData[0];
  2716.   BlockReference reqBlockref = signal->theData[1];
  2717.   Uint32 transid1 = signal->theData[2];
  2718.   Uint32 transid2 = signal->theData[3];
  2719.   Uint32 tcOprec = signal->theData[5];
  2720.   if (ERROR_INSERTED(5006)) {
  2721.     systemErrorLab(signal);
  2722.   }
  2723.   if (ERROR_INSERTED(5016)) {
  2724.     CLEAR_ERROR_INSERT_VALUE;
  2725.     sendSignalWithDelay(cownref, GSN_ABORTREQ, signal, 2000, 6);
  2726.     return;
  2727.   }//if
  2728.   if (findTransaction(transid1,
  2729.                       transid2,
  2730.                       tcOprec) != ZOK) {
  2731.     signal->theData[0] = reqPtr;
  2732.     signal->theData[2] = cownNodeid;
  2733.     signal->theData[3] = transid1;
  2734.     signal->theData[4] = transid2;
  2735.     sendSignal(reqBlockref, GSN_ABORTCONF, signal, 5, JBB);
  2736.     warningReport(signal, 9);
  2737.     return;
  2738.   }//if
  2739.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  2740.   if (regTcPtr->transactionState != TcConnectionrec::PREPARED) {
  2741.     warningReport(signal, 10);
  2742.     return;
  2743.   }//if
  2744.   regTcPtr->reqBlockref = reqBlockref;
  2745.   regTcPtr->reqRef = reqPtr;
  2746.   regTcPtr->abortState = TcConnectionrec::REQ_FROM_TC;
  2747.   regTcPtr->activeCreat = ZFALSE;
  2748.   abortCommonLab(signal);
  2749.   return;
  2750. }//Dblqh::execABORTREQ()
  2751. /* ************>> */
  2752. /*  ACC_TO_REF  > */
  2753. /* ************>> */
  2754. void Dblqh::execACC_TO_REF(Signal* signal) 
  2755. {
  2756.   jamEntry();
  2757.   terrorCode = signal->theData[1];
  2758.   releaseActiveFrag(signal);
  2759.   abortErrorLab(signal);
  2760.   return;
  2761. }//Dblqh::execACC_TO_REF()
  2762. /* ************> */
  2763. /*  ACCKEYREF  > */
  2764. /* ************> */
  2765. void Dblqh::execACCKEYREF(Signal* signal) 
  2766. {
  2767.   jamEntry();
  2768.   tcConnectptr.i = signal->theData[0];
  2769.   terrorCode = signal->theData[1];
  2770.   ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  2771.   TcConnectionrec * const tcPtr = tcConnectptr.p;
  2772.   switch (tcPtr->transactionState) {
  2773.   case TcConnectionrec::WAIT_ACC:
  2774.     jam();
  2775.     releaseActiveFrag(signal);
  2776.     break;
  2777.   case TcConnectionrec::WAIT_ACC_ABORT:
  2778.   case TcConnectionrec::ABORT_STOPPED:
  2779.   case TcConnectionrec::ABORT_QUEUED:
  2780.     jam();
  2781. /* ------------------------------------------------------------------------- */
  2782. /*IGNORE SINCE ABORT OF THIS OPERATION IS ONGOING ALREADY.                   */
  2783. /* ------------------------------------------------------------------------- */
  2784.     return;
  2785.     break;
  2786.   default:
  2787.     ndbrequire(false);
  2788.     break;
  2789.   }//switch
  2790.   const Uint32 errCode = terrorCode; 
  2791.   tcPtr->errorCode = errCode;
  2792. /* ------------------------------------------------------------------------- */
  2793. /*WHEN AN ABORT FROM TC ARRIVES IT COULD ACTUALLY BE A CORRECT BEHAVIOUR     */
  2794. /*SINCE THE TUPLE MIGHT NOT HAVE ARRIVED YET OR ALREADY HAVE BEEN INSERTED.  */
  2795. /* ------------------------------------------------------------------------- */
  2796.   if (tcPtr->activeCreat == ZTRUE) {
  2797.     jam();
  2798. /* ------------------------------------------------------------------------- */
  2799. /*THIS IS A NORMAL EVENT DURING CREATION OF A FRAGMENT. PERFORM ABORT IN     */
  2800. /*TUP AND ACC AND THEN CONTINUE WITH NORMAL COMMIT PROCESSING. IF THE ERROR  */
  2801. /*HAPPENS TO BE A SERIOUS ERROR THEN PERFORM ABORT PROCESSING AS NORMAL.     */
  2802. /* ------------------------------------------------------------------------- */
  2803.     switch (tcPtr->operation) {
  2804.     case ZUPDATE:
  2805.     case ZDELETE:
  2806.       jam();
  2807.       if (errCode != ZNO_TUPLE_FOUND) {
  2808.         jam();
  2809. /* ------------------------------------------------------------------------- */
  2810. /*A NORMAL ERROR WILL BE TREATED AS A NORMAL ABORT AND WILL ABORT THE        */
  2811. /*TRANSACTION. NO SPECIAL HANDLING IS NEEDED.                                */
  2812. /* ------------------------------------------------------------------------- */
  2813.         tcPtr->activeCreat = ZFALSE;
  2814.       }//if
  2815.       break;
  2816.     case ZINSERT:
  2817.       jam();
  2818.       if (errCode != ZTUPLE_ALREADY_EXIST) {
  2819.         jam();
  2820. /* ------------------------------------------------------------------------- */
  2821. /*A NORMAL ERROR WILL BE TREATED AS A NORMAL ABORT AND WILL ABORT THE        */
  2822. /*TRANSACTION. NO SPECIAL HANDLING IS NEEDED.                                */
  2823. /* ------------------------------------------------------------------------- */
  2824.         tcPtr->activeCreat = ZFALSE;
  2825.       }//if
  2826.       break;
  2827.     default:
  2828.       jam();
  2829. /* ------------------------------------------------------------------------- */
  2830. /*A NORMAL ERROR WILL BE TREATED AS A NORMAL ABORT AND WILL ABORT THE        */
  2831. /*TRANSACTION. NO SPECIAL HANDLING IS NEEDED.                                */
  2832. /* ------------------------------------------------------------------------- */
  2833.       tcPtr->activeCreat = ZFALSE;
  2834.       break;
  2835.     }//switch
  2836.   } else {
  2837.     /**
  2838.      * Only primary replica can get ZTUPLE_ALREADY_EXIST || ZNO_TUPLE_FOUND
  2839.      *
  2840.      * Unless it's a simple or dirty read
  2841.      *
  2842.      * NOT TRUE!
  2843.      * 1) op1 - primary insert ok
  2844.      * 2) op1 - backup insert fail (log full or what ever)
  2845.      * 3) op1 - delete ok @ primary
  2846.      * 4) op1 - delete fail @ backup
  2847.      *
  2848.      * -> ZNO_TUPLE_FOUND is possible
  2849.      */
  2850.     ndbrequire
  2851.       (tcPtr->seqNoReplica == 0 ||
  2852.        errCode != ZTUPLE_ALREADY_EXIST ||
  2853.        (tcPtr->operation == ZREAD && (tcPtr->dirtyOp || tcPtr->opSimple)));
  2854.   }
  2855.   tcPtr->abortState = TcConnectionrec::ABORT_FROM_LQH;
  2856.   abortCommonLab(signal);
  2857.   return;
  2858. }//Dblqh::execACCKEYREF()
  2859. void Dblqh::localAbortStateHandlerLab(Signal* signal) 
  2860. {
  2861.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  2862.   if (regTcPtr->abortState != TcConnectionrec::ABORT_IDLE) {
  2863.     jam();
  2864.     return;
  2865.   }//if
  2866.   regTcPtr->activeCreat = ZFALSE;
  2867.   regTcPtr->abortState = TcConnectionrec::ABORT_FROM_LQH;
  2868.   regTcPtr->errorCode = terrorCode;
  2869.   abortStateHandlerLab(signal);
  2870.   return;
  2871. }//Dblqh::localAbortStateHandlerLab()
  2872. void Dblqh::abortStateHandlerLab(Signal* signal) 
  2873. {
  2874.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  2875.   switch (regTcPtr->transactionState) {
  2876.   case TcConnectionrec::PREPARED:
  2877.     jam();
  2878. /* ------------------------------------------------------------------------- */
  2879. /*THE OPERATION IS ALREADY PREPARED AND SENT TO THE NEXT LQH OR BACK TO TC.  */
  2880. /*WE CAN SIMPLY CONTINUE WITH THE ABORT PROCESS.                             */
  2881. /*IF IT WAS A CHECK FOR TRANSACTION STATUS THEN WE REPORT THE STATUS TO THE  */
  2882. /*NEW TC AND CONTINUE WITH THE NEXT OPERATION IN LQH.                        */
  2883. /* ------------------------------------------------------------------------- */
  2884.     if (regTcPtr->abortState == TcConnectionrec::NEW_FROM_TC) {
  2885.       jam();
  2886.       sendLqhTransconf(signal, LqhTransConf::Prepared);
  2887.       return;
  2888.     }//if
  2889.     break;
  2890.   case TcConnectionrec::LOG_COMMIT_WRITTEN_WAIT_SIGNAL:
  2891.   case TcConnectionrec::LOG_COMMIT_QUEUED_WAIT_SIGNAL:
  2892.     jam();
  2893. /* ------------------------------------------------------------------------- */
  2894. // We can only reach these states for multi-updates on a record in a transaction.
  2895. // We know that at least one of those has received the COMMIT signal, thus we
  2896. // declare us only prepared since we then receive the expected COMMIT signal.
  2897. /* ------------------------------------------------------------------------- */
  2898.     ndbrequire(regTcPtr->abortState == TcConnectionrec::NEW_FROM_TC);
  2899.     sendLqhTransconf(signal, LqhTransConf::Prepared);
  2900.     break;
  2901.   case TcConnectionrec::WAIT_TUPKEYINFO:
  2902.   case TcConnectionrec::WAIT_ATTR:
  2903.     jam();
  2904. /* ------------------------------------------------------------------------- */
  2905. /* WE ARE CURRENTLY WAITING FOR MORE INFORMATION. WE CAN START THE ABORT     */
  2906. /* PROCESS IMMEDIATELY. THE KEYINFO AND ATTRINFO SIGNALS WILL BE DROPPED     */
  2907. /* SINCE THE ABORT STATE WILL BE SET.                                        */
  2908. /* ------------------------------------------------------------------------- */
  2909.     break;
  2910.   case TcConnectionrec::WAIT_TUP:
  2911.     jam();
  2912. /* ------------------------------------------------------------------------- */
  2913. // TUP is currently active. We have to wait for the TUPKEYREF or TUPKEYCONF
  2914. // to arrive since we might otherwise jeopardise the local checkpoint
  2915. // consistency in overload situations.
  2916. /* ------------------------------------------------------------------------- */
  2917.     regTcPtr->transactionState = TcConnectionrec::WAIT_TUP_TO_ABORT;
  2918.     return;
  2919.   case TcConnectionrec::WAIT_ACC:
  2920.     jam();
  2921.     if (regTcPtr->listState == TcConnectionrec::ACC_BLOCK_LIST) {
  2922.       jam();
  2923. /* ------------------------------------------------------------------------- */
  2924. // If the operation is in the ACC Blocked list the operation is not allowed
  2925. // to start yet. We release it from the ACC Blocked list and will go through
  2926. // the gate in abortCommonLab(..) where it will be blocked.
  2927. /* ------------------------------------------------------------------------- */
  2928.       fragptr.i = regTcPtr->fragmentptr;
  2929.       ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  2930.       releaseAccList(signal);
  2931.     } else {
  2932.       jam();
  2933. /* ------------------------------------------------------------------------- */
  2934. // We start the abort immediately since the operation is still in the active
  2935. // list and the fragment cannot have been frozen yet. By sending LCP_HOLDOPCONF
  2936. // as direct signals we avoid the problem that we might find the operation
  2937. // in an unexpected list in ACC.
  2938. // We cannot accept being blocked before aborting ACC here since that would
  2939. // lead to seriously complex issues.
  2940. /* ------------------------------------------------------------------------- */
  2941.       abortContinueAfterBlockedLab(signal, false);
  2942.       return;
  2943.     }//if
  2944.     break;
  2945.   case TcConnectionrec::LOG_QUEUED:
  2946.     jam();
  2947. /* ------------------------------------------------------------------------- */
  2948. /*CURRENTLY QUEUED FOR LOGGING. WAIT UNTIL THE LOG RECORD HAVE BEEN INSERTED */
  2949. /*AND THEN CONTINUE THE ABORT PROCESS.                                       */
  2950. //Could also be waiting for an overloaded log disk. In this case it is easy
  2951. //to abort when CONTINUEB arrives.
  2952. /* ------------------------------------------------------------------------- */
  2953.     return;
  2954.     break;
  2955.   case TcConnectionrec::STOPPED:
  2956.     jam();
  2957.     /* ---------------------------------------------------------------------
  2958.      * WE ARE CURRENTLY QUEUED FOR ACCESS TO THE FRAGMENT BY A LCP
  2959.      * Since nothing has been done, just release operation
  2960.      * i.e. no prepare log record has been written 
  2961.      *      so no abort log records needs to be written
  2962.      */
  2963.     releaseWaitQueue(signal);
  2964.     continueAfterLogAbortWriteLab(signal);
  2965.     return;
  2966.     break;
  2967.   case TcConnectionrec::WAIT_AI_AFTER_ABORT:
  2968.     jam();
  2969. /* ------------------------------------------------------------------------- */