summaryrefslogtreecommitdiff
path: root/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp')
-rw-r--r--storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp1974
1 files changed, 1974 insertions, 0 deletions
diff --git a/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
new file mode 100644
index 00000000000..2baa4400409
--- /dev/null
+++ b/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
@@ -0,0 +1,1974 @@
+/* Copyright (C) 2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef DBTC_H
+#define DBTC_H
+
+#include <ndb_limits.h>
+#include <pc.hpp>
+#include <SimulatedBlock.hpp>
+#include <DLHashTable.hpp>
+#include <SLList.hpp>
+#include <DLList.hpp>
+#include <DLFifoList.hpp>
+#include <DataBuffer.hpp>
+#include <Bitmask.hpp>
+#include <AttributeList.hpp>
+#include <signaldata/AttrInfo.hpp>
+#include <signaldata/LqhTransConf.hpp>
+#include <signaldata/LqhKey.hpp>
+#include <signaldata/TrigAttrInfo.hpp>
+#include <signaldata/TcIndx.hpp>
+#include <signaldata/TransIdAI.hpp>
+#include <signaldata/EventReport.hpp>
+#include <trigger_definitions.h>
+#include <SignalCounter.hpp>
+
+#ifdef DBTC_C
+/*
+ * 2.2 LOCAL SYMBOLS
+ * -----------------
+ */
+#define Z8NIL 255
+#define ZAPI_CONNECT_FILESIZE 20
+#define ZATTRBUF_FILESIZE 4000
+#define ZCLOSED 2
+#define ZCOMMITING 0 /* VALUE FOR TRANSTATUS */
+#define ZCOMMIT_SETUP 2
+#define ZCONTINUE_ABORT_080 4
+#define ZDATABUF_FILESIZE 4000
+#define ZGCP_FILESIZE 10
+#define ZINBUF_DATA_LEN 24 /* POSITION OF 'DATA LENGHT'-VARIABLE. */
+#define ZINBUF_NEXT 27 /* POSITION OF 'NEXT'-VARIABLE. */
+#define ZINBUF_PREV 26 /* POSITION OF 'PREVIOUS'-VARIABLE. */
+#define ZINTSPH1 1
+#define ZINTSPH2 2
+#define ZINTSPH3 3
+#define ZINTSPH6 6
+#define ZLASTPHASE 255
+#define ZMAX_DATA_IN_LQHKEYREQ 12
+#define ZNODEBUF_FILESIZE 2000
+#define ZNR_OF_SEIZE 10
+#define ZSCANREC_FILE_SIZE 100
+#define ZSCAN_FRAGREC_FILE_SIZE 400
+#define ZSCAN_OPREC_FILE_SIZE 400
+#define ZSEND_ATTRINFO 0
+#define ZSPH1 1
+#define ZTABREC_FILESIZE 16
+#define ZTAKE_OVER_ACTIVE 1
+#define ZTAKE_OVER_IDLE 0
+#define ZTC_CONNECT_FILESIZE 200
+#define ZTCOPCONF_SIZE 6
+
+// ----------------------------------------
+// Error Codes for Scan
+// ----------------------------------------
+#define ZNO_CONCURRENCY_ERROR 242
+#define ZTOO_HIGH_CONCURRENCY_ERROR 244
+#define ZNO_SCANREC_ERROR 245
+#define ZNO_FRAGMENT_ERROR 246
+#define ZSCAN_AI_LEN_ERROR 269
+#define ZSCAN_LQH_ERROR 270
+#define ZSCAN_FRAG_LQH_ERROR 274
+
+#define ZSCANTIME_OUT_ERROR 296
+#define ZSCANTIME_OUT_ERROR2 297
+
+// ----------------------------------------
+// Error Codes for transactions
+// ----------------------------------------
+#define ZSTATE_ERROR 202
+#define ZLENGTH_ERROR 207 // Also Scan
+#define ZERO_KEYLEN_ERROR 208
+#define ZSIGNAL_ERROR 209
+#define ZGET_ATTRBUF_ERROR 217 // Also Scan
+#define ZGET_DATAREC_ERROR 218
+#define ZMORE_AI_IN_TCKEYREQ_ERROR 220
+#define ZCOMMITINPROGRESS 230
+#define ZROLLBACKNOTALLOWED 232
+#define ZNO_FREE_TC_CONNECTION 233 // Also Scan
+#define ZABORTINPROGRESS 237
+#define ZPREPAREINPROGRESS 238
+#define ZWRONG_SCHEMA_VERSION_ERROR 241 // Also Scan
+#define ZSCAN_NODE_ERROR 250
+#define ZTRANS_STATUS_ERROR 253
+#define ZTIME_OUT_ERROR 266
+#define ZSIMPLE_READ_WITHOUT_AI 271
+#define ZNO_AI_WITH_UPDATE 272
+#define ZSEIZE_API_COPY_ERROR 275
+#define ZSCANINPROGRESS 276
+#define ZABORT_ERROR 277
+#define ZCOMMIT_TYPE_ERROR 278
+
+#define ZNO_FREE_TC_MARKER 279
+#define ZNODE_SHUTDOWN_IN_PROGRESS 280
+#define ZCLUSTER_SHUTDOWN_IN_PROGRESS 281
+#define ZWRONG_STATE 282
+#define ZCLUSTER_IN_SINGLEUSER_MODE 299
+
+#define ZDROP_TABLE_IN_PROGRESS 283
+#define ZNO_SUCH_TABLE 284
+#define ZUNKNOWN_TABLE_ERROR 285
+#define ZNODEFAIL_BEFORE_COMMIT 286
+#define ZINDEX_CORRUPT_ERROR 287
+
+// ----------------------------------------
+// Seize error
+// ----------------------------------------
+#define ZNO_FREE_API_CONNECTION 219
+#define ZSYSTEM_NOT_STARTED_ERROR 203
+
+// ----------------------------------------
+// Release errors
+// ----------------------------------------
+#define ZINVALID_CONNECTION 229
+
+
+#define ZNOT_FOUND 626
+#define ZALREADYEXIST 630
+#define ZINCONSISTENTHASHINDEX 892
+#define ZNOTUNIQUE 893
+#endif
+
+class Dbtc: public SimulatedBlock {
+public:
+ enum ConnectionState {
+ CS_CONNECTED = 0,
+ CS_DISCONNECTED = 1,
+ CS_STARTED = 2,
+ CS_RECEIVING = 3,
+ CS_PREPARED = 4,
+ CS_START_PREPARING = 5,
+ CS_REC_PREPARING = 6,
+ CS_RESTART = 7,
+ CS_ABORTING = 8,
+ CS_COMPLETING = 9,
+ CS_COMPLETE_SENT = 10,
+ CS_PREPARE_TO_COMMIT = 11,
+ CS_COMMIT_SENT = 12,
+ CS_START_COMMITTING = 13,
+ CS_COMMITTING = 14,
+ CS_REC_COMMITTING = 15,
+ CS_WAIT_ABORT_CONF = 16,
+ CS_WAIT_COMPLETE_CONF = 17,
+ CS_WAIT_COMMIT_CONF = 18,
+ CS_FAIL_ABORTING = 19,
+ CS_FAIL_ABORTED = 20,
+ CS_FAIL_PREPARED = 21,
+ CS_FAIL_COMMITTING = 22,
+ CS_FAIL_COMMITTED = 23,
+ CS_FAIL_COMPLETED = 24,
+ CS_START_SCAN = 25
+ };
+
+ enum OperationState {
+ OS_CONNECTING_DICT = 0,
+ OS_CONNECTED = 1,
+ OS_OPERATING = 2,
+ OS_PREPARED = 3,
+ OS_COMMITTING = 4,
+ OS_COMMITTED = 5,
+ OS_COMPLETING = 6,
+ OS_COMPLETED = 7,
+ OS_RESTART = 8,
+ OS_ABORTING = 9,
+ OS_ABORT_SENT = 10,
+ OS_TAKE_OVER = 11,
+ OS_WAIT_DIH = 12,
+ OS_WAIT_KEYINFO = 13,
+ OS_WAIT_ATTR = 14,
+ OS_WAIT_COMMIT_CONF = 15,
+ OS_WAIT_ABORT_CONF = 16,
+ OS_WAIT_COMPLETE_CONF = 17,
+ OS_WAIT_SCAN = 18
+ };
+
+ enum AbortState {
+ AS_IDLE = 0,
+ AS_ACTIVE = 1
+ };
+
+ enum HostState {
+ HS_ALIVE = 0,
+ HS_DEAD = 1
+ };
+
+ enum LqhTransState {
+ LTS_IDLE = 0,
+ LTS_ACTIVE = 1
+ };
+
+ enum TakeOverState {
+ TOS_NOT_DEFINED = 0,
+ TOS_IDLE = 1,
+ TOS_ACTIVE = 2,
+ TOS_COMPLETED = 3,
+ TOS_NODE_FAILED = 4
+ };
+
+ enum FailState {
+ FS_IDLE = 0,
+ FS_LISTENING = 1,
+ FS_COMPLETING = 2
+ };
+
+ enum SystemStartState {
+ SSS_TRUE = 0,
+ SSS_FALSE = 1
+ };
+
+ enum TimeOutCheckState {
+ TOCS_TRUE = 0,
+ TOCS_FALSE = 1
+ };
+
+ enum ReturnSignal {
+ RS_NO_RETURN = 0,
+ RS_TCKEYCONF = 1,
+ RS_TC_COMMITCONF = 3,
+ RS_TCROLLBACKCONF = 4,
+ RS_TCROLLBACKREP = 5
+ };
+
+ enum IndexOperationState {
+ IOS_NOOP = 0,
+ IOS_INDEX_ACCESS = 1,
+ IOS_INDEX_ACCESS_WAIT_FOR_TCKEYCONF = 2,
+ IOS_INDEX_ACCESS_WAIT_FOR_TRANSID_AI = 3,
+ IOS_INDEX_OPERATION = 4
+ };
+
+ enum IndexState {
+ IS_BUILDING = 0, // build in progress, start state at create
+ IS_ONLINE = 1 // ready to use
+ };
+
+
+ /**--------------------------------------------------------------------------
+ * LOCAL SYMBOLS PER 'SYMBOL-VALUED' VARIABLE
+ *
+ *
+ * NSYMB ZAPI_CONNECT_FILESIZE = 20
+ * NSYMB ZTC_CONNECT_FILESIZE = 200
+ * NSYMB ZHOST_FILESIZE = 16
+ * NSYMB ZDATABUF_FILESIZE = 4000
+ * NSYMB ZATTRBUF_FILESIZE = 4000
+ * NSYMB ZGCP_FILESIZE = 10
+ *
+ *
+ * ABORTED CODES
+ * TPHASE NSYMB ZSPH1 = 1
+ * NSYMB ZLASTPHASE = 255
+ *
+ *
+ * LQH_TRANS
+ * NSYMB ZTRANS_ABORTED = 1
+ * NSYMB ZTRANS_PREPARED = 2
+ * NSYMB ZTRANS_COMMITTED = 3
+ * NSYMB ZCOMPLETED_LQH_TRANS = 4
+ * NSYMB ZTRANS_COMPLETED = 5
+ *
+ *
+ * TAKE OVER
+ * NSYMB ZTAKE_OVER_IDLE = 0
+ * NSYMB ZTAKE_OVER_ACTIVE = 1
+ *
+ * ATTRBUF (ATTRBUF_RECORD)
+ * NSYMB ZINBUF_DATA_LEN = 24
+ * NSYMB ZINBUF_NEXTFREE = 25 (NOT USED )
+ * NSYMB ZINBUF_PREV = 26
+ * NSYMB ZINBUF_NEXT = 27
+ -------------------------------------------------------------------------*/
+ /*
+ 2.3 RECORDS AND FILESIZES
+ -------------------------
+ */
+ /* **************************************************************** */
+ /* ---------------------------------------------------------------- */
+ /* ------------------- TRIGGER AND INDEX DATA --------------------- */
+ /* ---------------------------------------------------------------- */
+ /* **************************************************************** */
+ /* ********* DEFINED TRIGGER DATA ********* */
+ /* THIS RECORD FORMS LISTS OF ACTIVE */
+ /* TRIGGERS FOR EACH TABLE. */
+ /* THE RECORDS ARE MANAGED BY A TRIGGER */
+ /* POOL WHERE A TRIGGER RECORD IS SEIZED */
+ /* WHEN A TRIGGER IS ACTIVATED AND RELEASED */
+ /* WHEN THE TRIGGER IS DEACTIVATED. */
+ /* **************************************** */
+ struct TcDefinedTriggerData {
+ /**
+ * Trigger id, used to identify the trigger
+ */
+ UintR triggerId;
+
+ /**
+ * Trigger type, defines what the trigger is used for
+ */
+ TriggerType::Value triggerType;
+
+ /**
+ * Trigger type, defines what the trigger is used for
+ */
+ TriggerEvent::Value triggerEvent;
+
+ /**
+ * Attribute mask, defines what attributes are to be monitored
+ * Can be seen as a compact representation of SQL column name list
+ */
+ Bitmask<MAXNROFATTRIBUTESINWORDS> attributeMask;
+
+ /**
+ * Next ptr (used in pool/list)
+ */
+ union {
+ Uint32 nextPool;
+ Uint32 nextList;
+ };
+
+ /**
+ * Index id, only used by secondary_index triggers. This is same as
+ * index table id in DICT.
+ **/
+ Uint32 indexId;
+
+ /**
+ * Prev pointer (used in list)
+ */
+ Uint32 prevList;
+
+ inline void print(NdbOut & s) const {
+ s << "[DefinedTriggerData = " << triggerId << "]";
+ }
+ };
+ typedef Ptr<TcDefinedTriggerData> DefinedTriggerPtr;
+
+ /**
+ * Pool of trigger data record
+ */
+ ArrayPool<TcDefinedTriggerData> c_theDefinedTriggerPool;
+
+ /**
+ * The list of active triggers
+ */
+ DLList<TcDefinedTriggerData> c_theDefinedTriggers;
+
+ typedef DataBuffer<11> AttributeBuffer;
+
+ AttributeBuffer::DataBufferPool c_theAttributeBufferPool;
+
+ UintR c_transactionBufferSpace;
+
+
+ /* ********** FIRED TRIGGER DATA ********** */
+ /* THIS RECORD FORMS LISTS OF FIRED */
+ /* TRIGGERS FOR A TRANSACTION. */
+ /* THE RECORDS ARE MANAGED BY A TRIGGER */
+ /* POOL WHERE A TRIGGER RECORD IS SEIZED */
+ /* WHEN A TRIGGER IS ACTIVATED AND RELEASED */
+ /* WHEN THE TRIGGER IS DEACTIVATED. */
+ /* **************************************** */
+ struct TcFiredTriggerData {
+ TcFiredTriggerData() {}
+
+ /**
+ * Trigger id, used to identify the trigger
+ **/
+ Uint32 triggerId;
+
+ /**
+ * The operation that fired the trigger
+ */
+ Uint32 fireingOperation;
+
+ /**
+ * Used for scrapping in case of node failure
+ */
+ Uint32 nodeId;
+
+ /**
+ * Trigger attribute info, primary key value(s)
+ */
+ AttributeBuffer::Head keyValues;
+
+ /**
+ * Trigger attribute info, attribute value(s) before operation
+ */
+ AttributeBuffer::Head beforeValues;
+
+ /**
+ * Trigger attribute info, attribute value(s) after operation
+ */
+ AttributeBuffer::Head afterValues;
+
+ /**
+ * Next ptr (used in pool/list)
+ */
+ union {
+ Uint32 nextPool;
+ Uint32 nextList;
+ Uint32 nextHash;
+ };
+
+ /**
+ * Prev pointer (used in list)
+ */
+ union {
+ Uint32 prevList;
+ Uint32 prevHash;
+ };
+
+ inline void print(NdbOut & s) const {
+ s << "[FiredTriggerData = " << triggerId << "]";
+ }
+
+ inline Uint32 hashValue() const {
+ return fireingOperation ^ nodeId;
+ }
+
+ inline bool equal(const TcFiredTriggerData & rec) const {
+ return fireingOperation == rec.fireingOperation && nodeId == rec.nodeId;
+ }
+ };
+ typedef Ptr<TcFiredTriggerData> FiredTriggerPtr;
+
+ /**
+ * Pool of trigger data record
+ */
+ ArrayPool<TcFiredTriggerData> c_theFiredTriggerPool;
+ DLHashTable<TcFiredTriggerData> c_firedTriggerHash;
+ AttributeBuffer::DataBufferPool c_theTriggerAttrInfoPool;
+
+ Uint32 c_maxNumberOfDefinedTriggers;
+ Uint32 c_maxNumberOfFiredTriggers;
+
+ struct AttrInfoRecord {
+ /**
+ * Pre-allocated AttrInfo signal
+ */
+ AttrInfo attrInfo;
+
+ /**
+ * Next ptr (used in pool/list)
+ */
+ union {
+ Uint32 nextPool;
+ Uint32 nextList;
+ };
+ /**
+ * Prev pointer (used in list)
+ */
+ Uint32 prevList;
+ };
+
+
+ /* ************* INDEX DATA *************** */
+ /* THIS RECORD FORMS LISTS OF ACTIVE */
+ /* INDEX FOR EACH TABLE. */
+ /* THE RECORDS ARE MANAGED BY A INDEX */
+ /* POOL WHERE AN INDEX RECORD IS SEIZED */
+ /* WHEN AN INDEX IS CREATED AND RELEASED */
+ /* WHEN THE INDEX IS DROPPED. */
+ /* **************************************** */
+ struct TcIndexData {
+ /**
+ * IndexState
+ */
+ IndexState indexState;
+
+ /**
+ * Index id, same as index table id in DICT
+ */
+ Uint32 indexId;
+
+ /**
+ * Index attribute list. Only the length is used in v21x.
+ */
+ AttributeList attributeList;
+
+ /**
+ * Primary table id, the primary table to be indexed
+ */
+ Uint32 primaryTableId;
+
+ /**
+ * Primary key position in secondary table
+ */
+ Uint32 primaryKeyPos;
+
+ /**
+ * Next ptr (used in pool/list)
+ */
+ union {
+ Uint32 nextPool;
+ Uint32 nextList;
+ };
+ /**
+ * Prev pointer (used in list)
+ */
+ Uint32 prevList;
+ };
+
+ typedef Ptr<TcIndexData> TcIndexDataPtr;
+
+ /**
+ * Pool of index data record
+ */
+ ArrayPool<TcIndexData> c_theIndexPool;
+
+ /**
+ * The list of defined indexes
+ */
+ ArrayList<TcIndexData> c_theIndexes;
+ UintR c_maxNumberOfIndexes;
+
+ struct TcIndexOperation {
+ TcIndexOperation(AttributeBuffer::DataBufferPool & abp) :
+ indexOpState(IOS_NOOP),
+ expectedKeyInfo(0),
+ keyInfo(abp),
+ expectedAttrInfo(0),
+ attrInfo(abp),
+ expectedTransIdAI(0),
+ transIdAI(abp),
+ indexReadTcConnect(RNIL)
+ {}
+
+ ~TcIndexOperation()
+ {
+ }
+
+ // Index data
+ Uint32 indexOpId;
+ IndexOperationState indexOpState; // Used to mark on-going TcKeyReq
+ Uint32 expectedKeyInfo;
+ AttributeBuffer keyInfo; // For accumulating IndxKeyInfo
+ Uint32 expectedAttrInfo;
+ AttributeBuffer attrInfo; // For accumulating IndxAttrInfo
+ Uint32 expectedTransIdAI;
+ AttributeBuffer transIdAI; // For accumulating TransId_AI
+
+ TcKeyReq tcIndxReq;
+ UintR connectionIndex;
+ UintR indexReadTcConnect; //
+
+ /**
+ * Next ptr (used in pool/list)
+ */
+ union {
+ Uint32 nextPool;
+ Uint32 nextList;
+ };
+ /**
+ * Prev pointer (used in list)
+ */
+ Uint32 prevList;
+ };
+
+ typedef Ptr<TcIndexOperation> TcIndexOperationPtr;
+
+ /**
+ * Pool of index data record
+ */
+ ArrayPool<TcIndexOperation> c_theIndexOperationPool;
+
+ /**
+ * The list of index operations
+ */
+ ArrayList<TcIndexOperation> c_theIndexOperations;
+
+ UintR c_maxNumberOfIndexOperations;
+
+ struct TcSeizedIndexOperation {
+ /**
+ * Next ptr (used in pool/list)
+ */
+ union {
+ Uint32 nextPool;
+ Uint32 nextList;
+ };
+ /**
+ * Prev pointer (used in list)
+ */
+ Uint32 prevList;
+ };
+
+ /**
+ * Pool of seized index operations
+ */
+ ArrayPool<TcSeizedIndexOperation> c_theSeizedIndexOperationPool;
+
+ typedef Ptr<TcSeizedIndexOperation> TcSeizedIndexOperationPtr;
+
+ /************************** API CONNECT RECORD ***********************
+ * The API connect record contains the connection record to which the
+ * application connects.
+ *
+ * The application can send one operation at a time. It can send a
+ * new operation immediately after sending the previous operation.
+ * Thereby several operations can be active in one transaction within TC.
+ * This is achieved by using the API connect record.
+ * Each active operation is handled by the TC connect record.
+ * As soon as the TC connect record has sent the
+ * request to the LQH it is ready to receive new operations.
+ * The LQH connect record takes care of waiting for an operation to
+ * complete.
+ * When an operation has completed on the LQH connect record,
+ * a new operation can be started on this LQH connect record.
+ *******************************************************************
+ *
+ * API CONNECT RECORD ALIGNED TO BE 256 BYTES
+ ********************************************************************/
+
+ /*******************************************************************>*/
+ // We break out the API Timer for optimisation on scanning rather than
+ // on fast access.
+ /*******************************************************************>*/
+ inline void setApiConTimer(Uint32 apiConPtrI, Uint32 value, Uint32 line){
+ c_apiConTimer[apiConPtrI] = value;
+ c_apiConTimer_line[apiConPtrI] = line;
+ }
+
+ inline Uint32 getApiConTimer(Uint32 apiConPtrI) const {
+ return c_apiConTimer[apiConPtrI];
+ }
+ UintR* c_apiConTimer;
+ UintR* c_apiConTimer_line;
+
+ struct ApiConnectRecord {
+ ApiConnectRecord(ArrayPool<TcFiredTriggerData> & firedTriggerPool,
+ ArrayPool<TcSeizedIndexOperation> & seizedIndexOpPool):
+ theFiredTriggers(firedTriggerPool),
+ isIndexOp(false),
+ theSeizedIndexOperations(seizedIndexOpPool)
+ {}
+
+ //---------------------------------------------------
+ // First 16 byte cache line. Hot variables.
+ //---------------------------------------------------
+ ConnectionState apiConnectstate;
+ UintR transid[2];
+ UintR firstTcConnect;
+
+ //---------------------------------------------------
+ // Second 16 byte cache line. Hot variables.
+ //---------------------------------------------------
+ UintR lqhkeyconfrec;
+ UintR cachePtr;
+ UintR currSavePointId;
+ UintR counter;
+
+ //---------------------------------------------------
+ // Third 16 byte cache line. First and second cache
+ // line plus this will be enough for copy API records.
+ // Variables used in late phases.
+ //---------------------------------------------------
+ UintR nextGcpConnect;
+ UintR prevGcpConnect;
+ UintR gcpPointer;
+ UintR ndbapiConnect;
+
+ //---------------------------------------------------
+ // Fourth 16 byte cache line. Only used in late phases.
+ // Plus 4 bytes of error handling.
+ //---------------------------------------------------
+ UintR nextApiConnect;
+ BlockReference ndbapiBlockref;
+ UintR apiCopyRecord;
+ UintR globalcheckpointid;
+
+ //---------------------------------------------------
+ // Second 64 byte cache line starts. First 16 byte
+ // cache line in this one. Variables primarily used
+ // in early phase.
+ //---------------------------------------------------
+ UintR lastTcConnect;
+ UintR lqhkeyreqrec;
+ AbortState abortState;
+ Uint32 buddyPtr;
+ Uint8 m_exec_flag;
+ Uint8 unused2;
+ Uint8 takeOverRec;
+ Uint8 currentReplicaNo;
+
+ //---------------------------------------------------
+ // Error Handling variables. If cache line 32 bytes
+ // ensures that cache line is still only read in
+ // early phases.
+ //---------------------------------------------------
+ union {
+ UintR apiScanRec;
+ UintR commitAckMarker;
+ };
+ UintR currentTcConnect;
+ BlockReference tcBlockref;
+ Uint16 returncode;
+ Uint16 takeOverInd;
+
+ //---------------------------------------------------
+ // Second 64 byte cache line. Third 16 byte cache line
+ // in this one. Variables primarily used in early phase
+ // and checked in late phase.
+ // Fourth cache line is the tcSendArray that is used
+ // when two and three operations are responded to in
+ // parallel. The first two entries in tcSendArray is
+ // part of the third cache line.
+ //---------------------------------------------------
+ //---------------------------------------------------
+ // timeOutCounter is used waiting for ABORTCONF, COMMITCONF
+ // and COMPLETECONF
+ //---------------------------------------------------
+ UintR failureNr;
+ Uint8 tckeyrec; // Ändrad från R
+ Uint8 tcindxrec;
+ Uint8 apiFailState; // Ändrad från R
+ ReturnSignal returnsignal;
+ Uint8 timeOutCounter;
+
+ UintR tcSendArray[6];
+
+ // Trigger data
+
+ /**
+ * The list of fired triggers
+ */
+ DLFifoList<TcFiredTriggerData> theFiredTriggers;
+
+ bool triggerPending; // Used to mark waiting for a CONTINUEB
+
+ // Index data
+
+ bool isIndexOp; // Used to mark on-going TcKeyReq as indx table access
+ bool indexOpReturn;
+ UintR noIndexOp; // No outstanding index ops
+
+ // Index op return context
+ UintR indexOp;
+ UintR clientData;
+ UintR attrInfoLen;
+
+ UintR accumulatingIndexOp;
+ UintR executingIndexOp;
+ UintR tcIndxSendArray[6];
+ ArrayList<TcSeizedIndexOperation> theSeizedIndexOperations;
+ };
+
+ typedef Ptr<ApiConnectRecord> ApiConnectRecordPtr;
+
+
+ /************************** TC CONNECT RECORD ************************/
+ /* *******************************************************************/
+ /* TC CONNECT RECORD KEEPS ALL INFORMATION TO CARRY OUT A TRANSACTION*/
+ /* THE TRANSACTION CONTROLLER ESTABLISHES CONNECTIONS TO DIFFERENT */
+ /* BLOCKS TO CARRY OUT THE TRANSACTION. THERE CAN BE SEVERAL RECORDS */
+ /* PER ACTIVE TRANSACTION. THE TC CONNECT RECORD COOPERATES WITH THE */
+ /* API CONNECT RECORD FOR COMMUNICATION WITH THE API AND WITH THE */
+ /* LQH CONNECT RECORD FOR COMMUNICATION WITH THE LQH'S INVOLVED IN */
+ /* THE TRANSACTION. TC CONNECT RECORD IS PERMANENTLY CONNECTED TO A */
+ /* RECORD IN DICT AND ONE IN DIH. IT CONTAINS A LIST OF ACTIVE LQH */
+ /* CONNECT RECORDS AND A LIST OF STARTED BUT NOT ACTIVE LQH CONNECT */
+ /* RECORDS. IT DOES ALSO CONTAIN A LIST OF ALL OPERATIONS THAT ARE */
+ /* EXECUTED WITH THE TC CONNECT RECORD. */
+ /*******************************************************************>*/
+ /* TC_CONNECT RECORD ALIGNED TO BE 128 BYTES */
+ /*******************************************************************>*/
+ struct TcConnectRecord {
+ //---------------------------------------------------
+ // First 16 byte cache line. Those variables are only
+ // used in error cases.
+ //---------------------------------------------------
+ UintR tcOprec; /* TC OPREC of operation being taken over */
+ Uint16 failData[4]; /* Failed nodes when taking over an operation */
+ UintR nextTcFailHash;
+
+ //---------------------------------------------------
+ // Second 16 byte cache line. Those variables are used
+ // from LQHKEYCONF to sending COMMIT and COMPLETED.
+ //---------------------------------------------------
+ UintR lastLqhCon; /* Connect record in last replicas Lqh record */
+ Uint16 lastLqhNodeId; /* Node id of last replicas Lqh */
+ Uint16 m_execAbortOption;/* TcKeyReq::ExecuteAbortOption */
+ UintR commitAckMarker; /* CommitMarker I value */
+
+ //---------------------------------------------------
+ // Third 16 byte cache line. The hottest variables.
+ //---------------------------------------------------
+ OperationState tcConnectstate; /* THE STATE OF THE CONNECT*/
+ UintR apiConnect; /* POINTER TO API CONNECT RECORD */
+ UintR nextTcConnect; /* NEXT TC RECORD*/
+ Uint8 dirtyOp;
+ Uint8 lastReplicaNo; /* NUMBER OF THE LAST REPLICA IN THE OPERATION */
+ Uint8 noOfNodes; /* TOTAL NUMBER OF NODES IN OPERATION */
+ Uint8 operation; /* OPERATION TYPE */
+ /* 0 = READ REQUEST */
+ /* 1 = UPDATE REQUEST */
+ /* 2 = INSERT REQUEST */
+ /* 3 = DELETE REQUEST */
+
+ //---------------------------------------------------
+ // Fourth 16 byte cache line. The mildly hot variables.
+ // tcNodedata expands 4 Bytes into the next cache line
+ // with indexes almost never used.
+ //---------------------------------------------------
+ UintR clientData; /* SENDERS OPERATION POINTER */
+ UintR dihConnectptr; /* CONNECTION TO DIH BLOCK ON THIS NODE */
+ UintR prevTcConnect; /* DOUBLY LINKED LIST OF TC CONNECT RECORDS*/
+ UintR savePointId;
+
+ Uint16 tcNodedata[4];
+
+ // Trigger data
+ FiredTriggerPtr accumulatingTriggerData;
+ UintR noFiredTriggers;
+ UintR noReceivedTriggers;
+ UintR triggerExecutionCount;
+ UintR triggeringOperation;
+ UintR savedState[LqhKeyConf::SignalLength];
+
+ // Index data
+ bool isIndexOp; // Used to mark on-going TcKeyReq as index table access
+ UintR indexOp;
+ UintR currentIndexId;
+ UintR attrInfoLen;
+ };
+
+ friend struct TcConnectRecord;
+
+ typedef Ptr<TcConnectRecord> TcConnectRecordPtr;
+
+ // ********************** CACHE RECORD **************************************
+ //---------------------------------------------------------------------------
+ // This record is used between reception of TCKEYREQ and sending of LQHKEYREQ
+ // It is separatedso as to improve the cache hit rate and also to minimise
+ // the necessary memory storage in NDB Cluster.
+ //---------------------------------------------------------------------------
+
+ struct CacheRecord {
+ //---------------------------------------------------
+ // First 16 byte cache line. Variables used by
+ // ATTRINFO processing.
+ //---------------------------------------------------
+ UintR firstAttrbuf; /* POINTER TO LINKED LIST OF ATTRIBUTE BUFFERS */
+ UintR lastAttrbuf; /* POINTER TO LINKED LIST OF ATTRIBUTE BUFFERS */
+ UintR currReclenAi;
+ Uint16 attrlength; /* ATTRIBUTE INFORMATION LENGTH */
+ Uint16 save1;
+
+ //---------------------------------------------------
+ // Second 16 byte cache line. Variables initiated by
+ // TCKEYREQ and used in LQHKEYREQ.
+ //---------------------------------------------------
+ UintR attrinfo15[4];
+
+ //---------------------------------------------------
+ // Third 16 byte cache line. Variables initiated by
+ // TCKEYREQ and used in LQHKEYREQ.
+ //---------------------------------------------------
+ UintR attrinfo0;
+ UintR schemaVersion;/* SCHEMA VERSION USED IN TRANSACTION */
+ UintR tableref; /* POINTER TO THE TABLE IN WHICH THE FRAGMENT EXISTS*/
+ Uint16 apiVersionNo;
+ Uint16 keylen; /* KEY LENGTH SENT BY REQUEST SIGNAL */
+
+ //---------------------------------------------------
+ // Fourth 16 byte cache line. Variables initiated by
+ // TCKEYREQ and used in LQHKEYREQ.
+ //---------------------------------------------------
+ UintR keydata[4]; /* RECEIVES FIRST 16 BYTES OF TUPLE KEY */
+
+ //---------------------------------------------------
+ // First 16 byte cache line in second 64 byte cache
+ // line. Diverse use.
+ //---------------------------------------------------
+ UintR fragmentid; /* THE COMPUTED FRAGMENT ID */
+ UintR hashValue; /* THE HASH VALUE USED TO LOCATE FRAGMENT */
+
+ Uint8 distributionKeyIndicator;
+ Uint8 m_special_hash; // collation or distribution key
+ Uint8 unused2;
+ Uint8 lenAiInTckeyreq; /* LENGTH OF ATTRIBUTE INFORMATION IN TCKEYREQ */
+
+ Uint8 fragmentDistributionKey; /* DIH generation no */
+
+ /**
+ * EXECUTION MODE OF OPERATION
+ * 0 = NORMAL EXECUTION, 1 = INTERPRETED EXECUTION
+ */
+ Uint8 opExec;
+
+ /**
+ * LOCK TYPE OF OPERATION IF READ OPERATION
+ * 0 = READ LOCK, 1 = WRITE LOCK
+ */
+ Uint8 opLock;
+
+ /**
+ * IS THE OPERATION A SIMPLE TRANSACTION
+ * 0 = NO, 1 = YES
+ */
+ Uint8 opSimple;
+
+ //---------------------------------------------------
+ // Second 16 byte cache line in second 64 byte cache
+ // line. Diverse use.
+ //---------------------------------------------------
+ UintR distributionKey;
+ UintR nextCacheRec;
+ UintR unused3;
+ Uint32 scanInfo;
+
+ //---------------------------------------------------
+ // Third 16 byte cache line in second 64
+ // byte cache line. Diverse use.
+ //---------------------------------------------------
+ Uint32 unused4;
+ Uint32 scanTakeOverInd;
+ UintR firstKeybuf; /* POINTER THE LINKED LIST OF KEY BUFFERS */
+ UintR lastKeybuf; /* VARIABLE POINTING TO THE LAST KEY BUFFER */
+
+ //---------------------------------------------------
+ // Fourth 16 byte cache line in second 64
+ // byte cache line. Not used currently.
+ //---------------------------------------------------
+ UintR packedCacheVar[4];
+ };
+
+ typedef Ptr<CacheRecord> CacheRecordPtr;
+
+ /* ************************ HOST RECORD ********************************** */
+ /********************************************************/
+ /* THIS RECORD CONTAINS ALIVE-STATUS ON ALL NODES IN THE*/
+ /* SYSTEM */
+ /********************************************************/
+ /* THIS RECORD IS ALIGNED TO BE 128 BYTES. */
+ /********************************************************/
+ struct HostRecord {
+ HostState hostStatus;
+ LqhTransState lqhTransStatus;
+ TakeOverState takeOverStatus;
+ bool inPackedList;
+ UintR noOfPackedWordsLqh;
+ UintR packedWordsLqh[26];
+ UintR noOfWordsTCKEYCONF;
+ UintR packedWordsTCKEYCONF[30];
+ UintR noOfWordsTCINDXCONF;
+ UintR packedWordsTCINDXCONF[30];
+ BlockReference hostLqhBlockRef;
+ }; /* p2c: size = 128 bytes */
+
+ typedef Ptr<HostRecord> HostRecordPtr;
+
+ /* *********** TABLE RECORD ********************************************* */
+
+ /********************************************************/
+ /* THIS RECORD CONTAINS THE CURRENT SCHEMA VERSION OF */
+ /* ALL TABLES IN THE SYSTEM. */
+ /********************************************************/
+ struct TableRecord {
+ Uint32 currentSchemaVersion;
+ Uint8 enabled;
+ Uint8 dropping;
+ Uint8 tableType;
+ Uint8 storedTable;
+
+ Uint8 noOfKeyAttr;
+ Uint8 hasCharAttr;
+ Uint8 noOfDistrKeys;
+
+ struct KeyAttr {
+ Uint32 attributeDescriptor;
+ CHARSET_INFO* charsetInfo;
+ } keyAttr[MAX_ATTRIBUTES_IN_INDEX];
+
+ bool checkTable(Uint32 schemaVersion) const {
+ return enabled && !dropping && (schemaVersion == currentSchemaVersion);
+ }
+
+ Uint32 getErrorCode(Uint32 schemaVersion) const;
+
+ struct DropTable {
+ Uint32 senderRef;
+ Uint32 senderData;
+ SignalCounter waitDropTabCount;
+ } dropTable;
+ };
+ typedef Ptr<TableRecord> TableRecordPtr;
+
+ /**
+ * There is max 16 ScanFragRec's for
+ * each scan started in TC. Each ScanFragRec is used by
+ * a scan fragment "process" that scans one fragment at a time.
+ * It will receive max 16 tuples in each request
+ */
+ struct ScanFragRec {
+ ScanFragRec(){
+ stopFragTimer();
+ lqhBlockref = 0;
+ scanFragState = IDLE;
+ scanRec = RNIL;
+ }
+ /**
+ * ScanFragState
+ * WAIT_GET_PRIMCONF : Waiting for DIGETPRIMCONF when starting a new
+ * fragment scan
+ * LQH_ACTIVE : The scan process has sent a command to LQH and is
+ * waiting for the response
+ * LQH_ACTIVE_CLOSE : The scan process has sent close to LQH and is
+ * waiting for the response
+ * DELIVERED : The result have been delivered, this scan frag process
+ * are waiting for a SCAN_NEXTREQ to tell us to continue scanning
+ * RETURNING_FROM_DELIVERY : SCAN_NEXTREQ received and continuing scan
+ * soon
+ * QUEUED_FOR_DELIVERY : Result queued in TC and waiting for delivery
+ * to API
+ * COMPLETED : The fragment scan processes has completed and finally
+ * sent a SCAN_PROCCONF
+ */
+ enum ScanFragState {
+ IDLE = 0,
+ WAIT_GET_PRIMCONF = 1,
+ LQH_ACTIVE = 2,
+ DELIVERED = 4,
+ QUEUED_FOR_DELIVERY = 6,
+ COMPLETED = 7
+ };
+ // Timer for checking timeout of this fragment scan
+ Uint32 scanFragTimer;
+
+ // Id of the current scanned fragment
+ Uint32 scanFragId;
+
+ // Blockreference of LQH
+ BlockReference lqhBlockref;
+
+ // getNodeInfo.m_connectCount, set at seize used so that
+ // I don't accidently kill a starting node
+ Uint32 m_connectCount;
+
+ // State of this fragment scan
+ ScanFragState scanFragState;
+
+ // Id of the ScanRecord this fragment scan belongs to
+ Uint32 scanRec;
+
+ // The value of fragmentCompleted in the last received SCAN_FRAGCONF
+ Uint8 m_scan_frag_conf_status;
+
+ inline void startFragTimer(Uint32 timeVal){
+ scanFragTimer = timeVal;
+ }
+ inline void stopFragTimer(void){
+ scanFragTimer = 0;
+ }
+
+ Uint32 m_ops;
+ Uint32 m_chksum;
+ Uint32 m_apiPtr;
+ Uint32 m_totalLen;
+ union {
+ Uint32 nextPool;
+ Uint32 nextList;
+ };
+ Uint32 prevList;
+ };
+
+ typedef Ptr<ScanFragRec> ScanFragRecPtr;
+ typedef LocalDLList<ScanFragRec> ScanFragList;
+
+ /**
+ * Each scan allocates one ScanRecord to store information
+ * about the current scan
+ *
+ */
+ struct ScanRecord {
+ ScanRecord() {}
+ /** NOTE! This is the old comment for ScanState. - MASV
+ * STATE TRANSITIONS OF SCAN_STATE. SCAN_STATE IS THE STATE
+ * VARIABLE OF THE RECEIVE AND DELIVERY PROCESS.
+ * THE PROCESS HAS THREE STEPS IT GOES THROUGH.
+ * 1) THE INITIAL STATES WHEN RECEIVING DATA FOR THE SCAN.
+ * - WAIT_SCAN_TAB_INFO
+ * - WAIT_AI
+ * - WAIT_FRAGMENT_COUNT
+ * 2) THE EXECUTION STATES WHEN THE SCAN IS PERFORMED.
+ * - SCAN_NEXT_ORDERED
+ * - DELIVERED
+ * - QUEUED_DELIVERED
+ * 3) THE CLOSING STATE WHEN THE SCAN PROCESS IS CLOSING UP
+ * EVERYTHING.
+ * - CLOSING_SCAN
+ * INITIAL START WHEN SCAN_TABREQ RECEIVED
+ * -> WAIT_SCAN_TAB_INFO (IF ANY SCAN_TABINFO TO BE RECEIVED)
+ * -> WAIT_AI (IF NO SCAN_TAB_INFO BUT ATTRINFO IS RECEIVED)
+ * -> WAIT_FRAGMENT_COUNT (IF NEITHER SCAN_TABINFO OR ATTRINFO
+ * RECEIVED)
+ *
+ * WAIT_SCAN_TAB_INFO TRANSITIONS:
+ * -> WAIT_SCAN_TABINFO (WHEN MORE SCAN_TABINFO RECEIVED)
+ * -> WAIT_AI (WHEN ATTRINFO RECEIVED AFTER RECEIVING ALL
+ * SCAN_TABINFO)
+ * -> WAIT_FRAGMENT_COUNT (WHEN NO ATTRINFO RECEIVED AFTER
+ * RECEIVING ALL SCAN_TABINFO )
+ * WAIT_AI TRANSITIONS:
+ * -> WAIT_AI (WHEN MORE ATTRINFO RECEIVED)
+ * -> WAIT_FRAGMENT_COUNT (WHEN ALL ATTRINFO RECEIVED)
+ *
+ * WAIT_FRAGMENT_COUNT TRANSITIONS:
+ * -> SCAN_NEXT_ORDERED
+ *
+ * SCAN_NEXT_ORDERED TRANSITIONS:
+ * -> DELIVERED (WHEN FIRST SCAN_FRAGCONF ARRIVES WITH OPERATIONS
+ * TO REPORT IN IT)
+ * -> CLOSING_SCAN (WHEN SCAN IS CLOSED BY SCAN_NEXTREQ OR BY SOME
+ * ERROR)
+ *
+ * DELIVERED TRANSITIONS:
+ * -> SCAN_NEXT_ORDERED (IF SCAN_NEXTREQ ARRIVES BEFORE ANY NEW
+ * OPERATIONS TO REPORT ARRIVES)
+ * -> QUEUED_DELIVERED (IF NEW OPERATION TO REPORT ARRIVES BEFORE
+ * SCAN_NEXTREQ)
+ * -> CLOSING_SCAN (WHEN SCAN IS CLOSED BY SCAN_NEXTREQ OR BY SOME
+ * ERROR)
+ *
+ * QUEUED_DELIVERED TRANSITIONS:
+ * -> DELIVERED (WHEN SCAN_NEXTREQ ARRIVES AND QUEUED OPERATIONS
+ * TO REPORT ARE SENT TO THE APPLICATION)
+ * -> CLOSING_SCAN (WHEN SCAN IS CLOSED BY SCAN_NEXTREQ OR BY
+ * SOME ERROR)
+ */
+ enum ScanState {
+ IDLE = 0,
+ WAIT_SCAN_TAB_INFO = 1,
+ WAIT_AI = 2,
+ WAIT_FRAGMENT_COUNT = 3,
+ RUNNING = 4,
+ CLOSING_SCAN = 5
+ };
+
+ // State of this scan
+ ScanState scanState;
+
+ DLList<ScanFragRec>::Head m_running_scan_frags; // Currently in LQH
+ union { Uint32 m_queued_count; Uint32 scanReceivedOperations; };
+ DLList<ScanFragRec>::Head m_queued_scan_frags; // In TC !sent to API
+ DLList<ScanFragRec>::Head m_delivered_scan_frags;// Delivered to API
+
+ // Id of the next fragment to be scanned. Used by scan fragment
+ // processes when they are ready for the next fragment
+ Uint32 scanNextFragId;
+
+ // Total number of fragments in the table we are scanning
+ Uint32 scanNoFrag;
+
+ // Index of next ScanRecords when in free list
+ Uint32 nextScan;
+
+ // Length of expected attribute information
+ union { Uint32 scanAiLength; Uint32 m_booked_fragments_count; };
+
+ Uint32 scanKeyLen;
+
+ // Reference to ApiConnectRecord
+ Uint32 scanApiRec;
+
+ // Reference to TcConnectRecord
+ Uint32 scanTcrec;
+
+ // Number of scan frag processes that belong to this scan
+ Uint32 scanParallel;
+
+ // Schema version used by this scan
+ Uint32 scanSchemaVersion;
+
+ // Index of stored procedure belonging to this scan
+ Uint32 scanStoredProcId;
+
+ // The index of table that is scanned
+ Uint32 scanTableref;
+
+ // Number of operation records per scanned fragment
+ // Number of operations in first batch
+ // Max number of bytes per batch
+ union {
+ Uint16 first_batch_size_rows;
+ Uint16 batch_size_rows;
+ };
+ Uint32 batch_byte_size;
+
+ Uint32 scanRequestInfo; // ScanFrag format
+
+ // Close is ordered
+ bool m_close_scan_req;
+ };
+ typedef Ptr<ScanRecord> ScanRecordPtr;
+
+ /* **********************************************************************$ */
+ /* ******$ DATA BUFFER ******$ */
+ /* */
+ /* THIS BUFFER IS USED AS A GENERAL DATA STORAGE. */
+ /* **********************************************************************$ */
+ struct DatabufRecord {
+ UintR data[4];
+ /* 4 * 1 WORD = 4 WORD */
+ UintR nextDatabuf;
+ }; /* p2c: size = 20 bytes */
+
+ typedef Ptr<DatabufRecord> DatabufRecordPtr;
+
+ /* **********************************************************************$ */
+ /* ******$ ATTRIBUTE INFORMATION RECORD ******$ */
+ /*
+ * CAN CONTAIN ONE (1) ATTRINFO SIGNAL. ONE SIGNAL CONTAINS 24 ATTR.
+ * INFO WORDS. BUT 32 ELEMENTS ARE USED TO MAKE PLEX HAPPY.
+ * SOME OF THE ELEMENTS ARE USED TO THE FOLLOWING THINGS:
+ * DATA LENGHT IN THIS RECORD IS STORED IN THE ELEMENT INDEXED BY
+ * ZINBUF_DATA_LEN.
+ * NEXT FREE ATTRBUF IS POINTED OUT BY THE ELEMENT INDEXED BY
+ * PREVIOUS ATTRBUF IS POINTED OUT BY THE ELEMENT INDEXED BY ZINBUF_PREV
+ * (NOT USED YET).
+ * NEXT ATTRBUF IS POINTED OUT BY THE ELEMENT INDEXED BY ZINBUF_NEXT. */
+ /* ******************************************************************** */
+ struct AttrbufRecord {
+ UintR attrbuf[32];
+ }; /* p2c: size = 128 bytes */
+
+ typedef Ptr<AttrbufRecord> AttrbufRecordPtr;
+
+ /*************************************************************************>*/
+ /* GLOBAL CHECKPOINT INFORMATION RECORD */
+ /* */
+ /* THIS RECORD IS USED TO STORE THE GLOBALCHECKPOINT NUMBER AND A
+ * COUNTER DURING THE COMPLETION PHASE OF THE TRANSACTION */
+ /*************************************************************************>*/
+ /* */
+ /* GCP RECORD ALIGNED TO BE 32 BYTES */
+ /*************************************************************************>*/
+ struct GcpRecord {
+ UintR gcpUnused1[2]; /* p2c: Not used */
+ UintR firstApiConnect;
+ UintR lastApiConnect;
+ UintR gcpId;
+ UintR nextGcp;
+ UintR gcpUnused2; /* p2c: Not used */
+ Uint16 gcpNomoretransRec;
+ }; /* p2c: size = 32 bytes */
+
+ typedef Ptr<GcpRecord> GcpRecordPtr;
+
+ /*************************************************************************>*/
+ /* TC_FAIL_RECORD */
+ /* THIS RECORD IS USED WHEN HANDLING TAKE OVER OF ANOTHER FAILED
+ * TC NODE. */
+ /*************************************************************************>*/
+ struct TcFailRecord {
+ Uint16 queueList[MAX_NDB_NODES];
+ Uint8 takeOverProcState[MAX_NDB_NODES];
+ UintR completedTakeOver;
+ UintR currentHashIndexTakeOver;
+ FailState failStatus;
+ Uint16 queueIndex;
+ Uint16 takeOverNode;
+ }; /* p2c: size = 64 bytes */
+
+ typedef Ptr<TcFailRecord> TcFailRecordPtr;
+
+public:
+ Dbtc(const class Configuration &);
+ virtual ~Dbtc();
+
+private:
+ BLOCK_DEFINES(Dbtc);
+
+ // Transit signals
+ void execPACKED_SIGNAL(Signal* signal);
+ void execABORTED(Signal* signal);
+ void execATTRINFO(Signal* signal);
+ void execCONTINUEB(Signal* signal);
+ void execKEYINFO(Signal* signal);
+ void execSCAN_NEXTREQ(Signal* signal);
+ void execSCAN_PROCREQ(Signal* signal);
+ void execSCAN_PROCCONF(Signal* signal);
+ void execTAKE_OVERTCREQ(Signal* signal);
+ void execTAKE_OVERTCCONF(Signal* signal);
+ void execLQHKEYREF(Signal* signal);
+ void execTRANSID_AI_R(Signal* signal);
+ void execKEYINFO20_R(Signal* signal);
+
+ // Received signals
+ void execDUMP_STATE_ORD(Signal* signal);
+ void execSEND_PACKED(Signal* signal);
+ void execCOMPLETED(Signal* signal);
+ void execCOMMITTED(Signal* signal);
+ void execDIGETNODESREF(Signal* signal);
+ void execDIGETPRIMCONF(Signal* signal);
+ void execDIGETPRIMREF(Signal* signal);
+ void execDISEIZECONF(Signal* signal);
+ void execDIVERIFYCONF(Signal* signal);
+ void execDI_FCOUNTCONF(Signal* signal);
+ void execDI_FCOUNTREF(Signal* signal);
+ void execGCP_NOMORETRANS(Signal* signal);
+ void execLQHKEYCONF(Signal* signal);
+ void execNDB_STTOR(Signal* signal);
+ void execREAD_NODESCONF(Signal* signal);
+ void execREAD_NODESREF(Signal* signal);
+ void execSTTOR(Signal* signal);
+ void execTC_COMMITREQ(Signal* signal);
+ void execTC_CLOPSIZEREQ(Signal* signal);
+ void execTCGETOPSIZEREQ(Signal* signal);
+ void execTCKEYREQ(Signal* signal);
+ void execTCRELEASEREQ(Signal* signal);
+ void execTCSEIZEREQ(Signal* signal);
+ void execTCROLLBACKREQ(Signal* signal);
+ void execTC_HBREP(Signal* signal);
+ void execTC_SCHVERREQ(Signal* signal);
+ void execSCAN_TABREQ(Signal* signal);
+ void execSCAN_TABINFO(Signal* signal);
+ void execSCAN_FRAGCONF(Signal* signal);
+ void execSCAN_FRAGREF(Signal* signal);
+ void execREAD_CONFIG_REQ(Signal* signal);
+ void execLQH_TRANSCONF(Signal* signal);
+ void execCOMPLETECONF(Signal* signal);
+ void execCOMMITCONF(Signal* signal);
+ void execABORTCONF(Signal* signal);
+ void execNODE_FAILREP(Signal* signal);
+ void execINCL_NODEREQ(Signal* signal);
+ void execTIME_SIGNAL(Signal* signal);
+ void execAPI_FAILREQ(Signal* signal);
+ void execSCAN_HBREP(Signal* signal);
+ void execSET_VAR_REQ(Signal* signal);
+
+ void execABORT_ALL_REQ(Signal* signal);
+
+ void execCREATE_TRIG_REQ(Signal* signal);
+ void execDROP_TRIG_REQ(Signal* signal);
+ void execFIRE_TRIG_ORD(Signal* signal);
+ void execTRIG_ATTRINFO(Signal* signal);
+ void execCREATE_INDX_REQ(Signal* signal);
+ void execDROP_INDX_REQ(Signal* signal);
+ void execTCINDXREQ(Signal* signal);
+ void execINDXKEYINFO(Signal* signal);
+ void execINDXATTRINFO(Signal* signal);
+ void execALTER_INDX_REQ(Signal* signal);
+
+ // Index table lookup
+ void execTCKEYCONF(Signal* signal);
+ void execTCKEYREF(Signal* signal);
+ void execTRANSID_AI(Signal* signal);
+ void execTCROLLBACKREP(Signal* signal);
+
+ void execCREATE_TAB_REQ(Signal* signal);
+ void execPREP_DROP_TAB_REQ(Signal* signal);
+ void execDROP_TAB_REQ(Signal* signal);
+ void execWAIT_DROP_TAB_REF(Signal* signal);
+ void execWAIT_DROP_TAB_CONF(Signal* signal);
+ void checkWaitDropTabFailedLqh(Signal*, Uint32 nodeId, Uint32 tableId);
+ void execALTER_TAB_REQ(Signal* signal);
+ void set_timeout_value(Uint32 timeOut);
+ void set_appl_timeout_value(Uint32 timeOut);
+ void set_no_parallel_takeover(Uint32);
+ void updateBuddyTimer(ApiConnectRecordPtr);
+
+ // Statement blocks
+ void updatePackedList(Signal* signal, HostRecord* ahostptr,
+ Uint16 ahostIndex);
+ void clearTcNodeData(Signal* signal,
+ UintR TLastLqhIndicator,
+ UintR Tstart);
+ void errorReport(Signal* signal, int place);
+ void warningReport(Signal* signal, int place);
+ void printState(Signal* signal, int place);
+ int seizeTcRecord(Signal* signal);
+ int seizeCacheRecord(Signal* signal);
+ void TCKEY_abort(Signal* signal, int place);
+ void copyFromToLen(UintR* sourceBuffer, UintR* destBuffer, UintR copyLen);
+ void reportNodeFailed(Signal* signal, Uint32 nodeId);
+ void sendPackedTCKEYCONF(Signal* signal,
+ HostRecord * ahostptr,
+ UintR hostId);
+ void sendPackedTCINDXCONF(Signal* signal,
+ HostRecord * ahostptr,
+ UintR hostId);
+ void sendPackedSignalLqh(Signal* signal, HostRecord * ahostptr);
+ void sendCommitLqh(Signal* signal,
+ TcConnectRecord * const regTcPtr);
+ void sendCompleteLqh(Signal* signal,
+ TcConnectRecord * const regTcPtr);
+ void sendTCKEY_FAILREF(Signal* signal, const ApiConnectRecord *);
+ void sendTCKEY_FAILCONF(Signal* signal, ApiConnectRecord *);
+ void checkStartTimeout(Signal* signal);
+ void checkStartFragTimeout(Signal* signal);
+ void timeOutFoundFragLab(Signal* signal, Uint32 TscanConPtr);
+ void timeOutLoopStartFragLab(Signal* signal, Uint32 TscanConPtr);
+ int releaseAndAbort(Signal* signal);
+ void findApiConnectFail(Signal* signal);
+ void findTcConnectFail(Signal* signal);
+ void initApiConnectFail(Signal* signal);
+ void initTcConnectFail(Signal* signal);
+ void initTcFail(Signal* signal);
+ void releaseTakeOver(Signal* signal);
+ void setupFailData(Signal* signal);
+ void updateApiStateFail(Signal* signal);
+ void updateTcStateFail(Signal* signal);
+ void handleApiFailState(Signal* signal, UintR anApiConnectptr);
+ void handleFailedApiNode(Signal* signal,
+ UintR aFailedNode,
+ UintR anApiConnectPtr);
+ void handleScanStop(Signal* signal, UintR aFailedNode);
+ void initScanTcrec(Signal* signal);
+ void initScanrec(ScanRecordPtr, const class ScanTabReq*,
+ const UintR scanParallel,
+ const UintR noOprecPerFrag);
+ void initScanfragrec(Signal* signal);
+ void releaseScanResources(ScanRecordPtr);
+ ScanRecordPtr seizeScanrec(Signal* signal);
+ void sendScanFragReq(Signal*, ScanRecord*, ScanFragRec*);
+ void sendScanTabConf(Signal* signal, ScanRecordPtr);
+ void close_scan_req(Signal*, ScanRecordPtr, bool received_req);
+ void close_scan_req_send_conf(Signal*, ScanRecordPtr);
+
+ void checkGcp(Signal* signal);
+ void commitGciHandling(Signal* signal, UintR Tgci);
+ void copyApi(Signal* signal);
+ void DIVER_node_fail_handling(Signal* signal, UintR Tgci);
+ void gcpTcfinished(Signal* signal);
+ void handleGcp(Signal* signal);
+ void hash(Signal* signal);
+ bool handle_special_hash(Uint32 dstHash[4],
+ Uint32* src, Uint32 srcLen,
+ Uint32 tabPtrI, bool distr);
+
+ void initApiConnect(Signal* signal);
+ void initApiConnectRec(Signal* signal,
+ ApiConnectRecord * const regApiPtr,
+ bool releaseIndexOperations = false);
+ void initattrbuf(Signal* signal);
+ void initdatabuf(Signal* signal);
+ void initgcp(Signal* signal);
+ void inithost(Signal* signal);
+ void initialiseScanrec(Signal* signal);
+ void initialiseScanFragrec(Signal* signal);
+ void initialiseScanOprec(Signal* signal);
+ void initTable(Signal* signal);
+ void initialiseTcConnect(Signal* signal);
+ void linkApiToGcp(Signal* signal);
+ void linkGciInGcilist(Signal* signal);
+ void linkKeybuf(Signal* signal);
+ void linkTcInConnectionlist(Signal* signal);
+ void releaseAbortResources(Signal* signal);
+ void releaseApiCon(Signal* signal, UintR aApiConnectPtr);
+ void releaseApiConCopy(Signal* signal);
+ void releaseApiConnectFail(Signal* signal);
+ void releaseAttrinfo();
+ void releaseGcp(Signal* signal);
+ void releaseKeys();
+ void releaseSimpleRead(Signal*, ApiConnectRecordPtr, TcConnectRecord*);
+ void releaseDirtyWrite(Signal* signal);
+ void releaseTcCon();
+ void releaseTcConnectFail(Signal* signal);
+ void releaseTransResources(Signal* signal);
+ void saveAttrbuf(Signal* signal);
+ void seizeApiConnect(Signal* signal);
+ void seizeApiConnectCopy(Signal* signal);
+ void seizeApiConnectFail(Signal* signal);
+ void seizeDatabuf(Signal* signal);
+ void seizeGcp(Signal* signal);
+ void seizeTcConnect(Signal* signal);
+ void seizeTcConnectFail(Signal* signal);
+ void sendApiCommit(Signal* signal);
+ void sendAttrinfo(Signal* signal,
+ UintR TattrinfoPtr,
+ AttrbufRecord * const regAttrPtr,
+ UintR TBref);
+ void sendContinueTimeOutControl(Signal* signal, Uint32 TapiConPtr);
+ void sendKeyinfo(Signal* signal, BlockReference TBRef, Uint32 len);
+ void sendlqhkeyreq(Signal* signal, BlockReference TBRef);
+ void sendSystemError(Signal* signal);
+ void sendtckeyconf(Signal* signal, UintR TcommitFlag);
+ void sendTcIndxConf(Signal* signal, UintR TcommitFlag);
+ void unlinkApiConnect(Signal* signal);
+ void unlinkGcp(Signal* signal);
+ void unlinkReadyTcCon(Signal* signal);
+ void handleFailedOperation(Signal* signal,
+ const LqhKeyRef * const lqhKeyRef,
+ bool gotLqhKeyRef);
+ void markOperationAborted(ApiConnectRecord * const regApiPtr,
+ TcConnectRecord * const regTcPtr);
+ void clearCommitAckMarker(ApiConnectRecord * const regApiPtr,
+ TcConnectRecord * const regTcPtr);
+ // Trigger and index handling
+ bool saveINDXKEYINFO(Signal* signal,
+ TcIndexOperation* indexOp,
+ const Uint32 *src,
+ Uint32 len);
+ bool receivedAllINDXKEYINFO(TcIndexOperation* indexOp);
+ bool saveINDXATTRINFO(Signal* signal,
+ TcIndexOperation* indexOp,
+ const Uint32 *src,
+ Uint32 len);
+ bool receivedAllINDXATTRINFO(TcIndexOperation* indexOp);
+ bool saveTRANSID_AI(Signal* signal,
+ TcIndexOperation* indexOp,
+ const Uint32 *src,
+ Uint32 len);
+ bool receivedAllTRANSID_AI(TcIndexOperation* indexOp);
+ void readIndexTable(Signal* signal,
+ ApiConnectRecord* regApiPtr,
+ TcIndexOperation* indexOp);
+ void executeIndexOperation(Signal* signal,
+ ApiConnectRecord* regApiPtr,
+ TcIndexOperation* indexOp);
+ bool seizeIndexOperation(ApiConnectRecord* regApiPtr,
+ TcIndexOperationPtr& indexOpPtr);
+ void releaseIndexOperation(ApiConnectRecord* regApiPtr,
+ TcIndexOperation* indexOp);
+ void releaseAllSeizedIndexOperations(ApiConnectRecord* regApiPtr);
+ void setupIndexOpReturn(ApiConnectRecord* regApiPtr,
+ TcConnectRecord* regTcPtr);
+
+ void saveTriggeringOpState(Signal* signal,
+ TcConnectRecord* trigOp);
+ void restoreTriggeringOpState(Signal* signal,
+ TcConnectRecord* trigOp);
+ void continueTriggeringOp(Signal* signal,
+ TcConnectRecord* trigOp);
+
+ void scheduleFiredTrigger(ApiConnectRecordPtr* transPtr,
+ TcConnectRecordPtr* opPtr);
+ void executeTriggers(Signal* signal, ApiConnectRecordPtr* transPtr);
+ void executeTrigger(Signal* signal,
+ TcFiredTriggerData* firedTriggerData,
+ ApiConnectRecordPtr* transPtr,
+ TcConnectRecordPtr* opPtr);
+ void executeIndexTrigger(Signal* signal,
+ TcDefinedTriggerData* definedTriggerData,
+ TcFiredTriggerData* firedTriggerData,
+ ApiConnectRecordPtr* transPtr,
+ TcConnectRecordPtr* opPtr);
+ void insertIntoIndexTable(Signal* signal,
+ TcFiredTriggerData* firedTriggerData,
+ ApiConnectRecordPtr* transPtr,
+ TcConnectRecordPtr* opPtr,
+ TcIndexData* indexData,
+ bool holdOperation = false);
+ void deleteFromIndexTable(Signal* signal,
+ TcFiredTriggerData* firedTriggerData,
+ ApiConnectRecordPtr* transPtr,
+ TcConnectRecordPtr* opPtr,
+ TcIndexData* indexData,
+ bool holdOperation = false);
+ void releaseFiredTriggerData(DLFifoList<TcFiredTriggerData>* triggers);
+ // Generated statement blocks
+ void warningHandlerLab(Signal* signal);
+ void systemErrorLab(Signal* signal);
+ void sendSignalErrorRefuseLab(Signal* signal);
+ void scanTabRefLab(Signal* signal, Uint32 errCode);
+ void diFcountReqLab(Signal* signal, ScanRecordPtr);
+ void signalErrorRefuseLab(Signal* signal);
+ void abort080Lab(Signal* signal);
+ void packKeyData000Lab(Signal* signal, BlockReference TBRef, Uint32 len);
+ void abortScanLab(Signal* signal, ScanRecordPtr, Uint32 errCode);
+ void sendAbortedAfterTimeout(Signal* signal, int Tcheck);
+ void abort010Lab(Signal* signal);
+ void abort015Lab(Signal* signal);
+ void packLqhkeyreq(Signal* signal, BlockReference TBRef);
+ void packLqhkeyreq040Lab(Signal* signal,
+ UintR anAttrBufIndex,
+ BlockReference TBRef);
+ void packLqhkeyreq040Lab(Signal* signal);
+ void returnFromQueuedDeliveryLab(Signal* signal);
+ void startTakeOverLab(Signal* signal);
+ void toCompleteHandlingLab(Signal* signal);
+ void toCommitHandlingLab(Signal* signal);
+ void toAbortHandlingLab(Signal* signal);
+ void abortErrorLab(Signal* signal);
+ void nodeTakeOverCompletedLab(Signal* signal);
+ void ndbsttorry010Lab(Signal* signal);
+ void commit020Lab(Signal* signal);
+ void complete010Lab(Signal* signal);
+ void releaseAtErrorLab(Signal* signal);
+ void seizeDatabuferrorLab(Signal* signal);
+ void scanAttrinfoLab(Signal* signal, UintR Tlen);
+ void seizeAttrbuferrorLab(Signal* signal);
+ void attrinfoDihReceivedLab(Signal* signal);
+ void aiErrorLab(Signal* signal);
+ void attrinfo020Lab(Signal* signal);
+ void scanReleaseResourcesLab(Signal* signal);
+ void scanCompletedLab(Signal* signal);
+ void scanError(Signal* signal, ScanRecordPtr, Uint32 errorCode);
+ void diverify010Lab(Signal* signal);
+ void intstartphase2x010Lab(Signal* signal);
+ void intstartphase3x010Lab(Signal* signal);
+ void sttorryLab(Signal* signal);
+ void abortBeginErrorLab(Signal* signal);
+ void tabStateErrorLab(Signal* signal);
+ void wrongSchemaVersionErrorLab(Signal* signal);
+ void noFreeConnectionErrorLab(Signal* signal);
+ void tckeyreq050Lab(Signal* signal);
+ void timeOutFoundLab(Signal* signal, UintR anAdd);
+ void completeTransAtTakeOverLab(Signal* signal, UintR TtakeOverInd);
+ void completeTransAtTakeOverDoLast(Signal* signal, UintR TtakeOverInd);
+ void completeTransAtTakeOverDoOne(Signal* signal, UintR TtakeOverInd);
+ void timeOutLoopStartLab(Signal* signal, Uint32 apiConnectPtr);
+ void initialiseRecordsLab(Signal* signal, UintR Tdata0, Uint32, Uint32);
+ void tckeyreq020Lab(Signal* signal);
+ void intstartphase2x020Lab(Signal* signal);
+ void intstartphase1x010Lab(Signal* signal);
+ void startphase1x010Lab(Signal* signal);
+
+ void lqhKeyConf_checkTransactionState(Signal * signal,
+ ApiConnectRecord * const regApiPtr);
+
+ void checkDropTab(Signal* signal);
+
+ void checkScanActiveInFailedLqh(Signal* signal,
+ Uint32 scanPtrI,
+ Uint32 failedNodeId);
+ void checkScanFragList(Signal*, Uint32 failedNodeId, ScanRecord * scanP,
+ LocalDLList<ScanFragRec>::Head&);
+
+ // Initialisation
+ void initData();
+ void initRecords();
+
+ // Transit signals
+
+
+ ApiConnectRecord *apiConnectRecord;
+ ApiConnectRecordPtr apiConnectptr;
+ UintR capiConnectFilesize;
+
+ TcConnectRecord *tcConnectRecord;
+ TcConnectRecordPtr tcConnectptr;
+ UintR ctcConnectFilesize;
+
+ CacheRecord *cacheRecord;
+ CacheRecordPtr cachePtr;
+ UintR ccacheFilesize;
+
+ AttrbufRecord *attrbufRecord;
+ AttrbufRecordPtr attrbufptr;
+ UintR cattrbufFilesize;
+
+ HostRecord *hostRecord;
+ HostRecordPtr hostptr;
+ UintR chostFilesize;
+
+ GcpRecord *gcpRecord;
+ GcpRecordPtr gcpPtr;
+ UintR cgcpFilesize;
+
+ TableRecord *tableRecord;
+ UintR ctabrecFilesize;
+
+ UintR thashValue;
+ UintR tdistrHashValue;
+
+ UintR ttransid_ptr;
+ UintR cfailure_nr;
+ UintR coperationsize;
+ UintR ctcTimer;
+
+ ApiConnectRecordPtr tmpApiConnectptr;
+ UintR tcheckGcpId;
+
+ struct TransCounters {
+ enum { Off, Timer, Started } c_trans_status;
+ UintR cattrinfoCount;
+ UintR ctransCount;
+ UintR ccommitCount;
+ UintR creadCount;
+ UintR csimpleReadCount;
+ UintR cwriteCount;
+ UintR cabortCount;
+ UintR cconcurrentOp;
+ Uint32 c_scan_count;
+ Uint32 c_range_scan_count;
+ void reset () {
+ cattrinfoCount = ctransCount = ccommitCount = creadCount =
+ csimpleReadCount = cwriteCount = cabortCount =
+ c_scan_count = c_range_scan_count = 0;
+ }
+ Uint32 report(Signal* signal){
+ signal->theData[0] = NDB_LE_TransReportCounters;
+ signal->theData[1] = ctransCount;
+ signal->theData[2] = ccommitCount;
+ signal->theData[3] = creadCount;
+ signal->theData[4] = csimpleReadCount;
+ signal->theData[5] = cwriteCount;
+ signal->theData[6] = cattrinfoCount;
+ signal->theData[7] = cconcurrentOp;
+ signal->theData[8] = cabortCount;
+ signal->theData[9] = c_scan_count;
+ signal->theData[10] = c_range_scan_count;
+ return 11;
+ }
+ } c_counters;
+
+ Uint16 cownNodeid;
+ Uint16 terrorCode;
+
+ UintR cfirstfreeAttrbuf;
+ UintR cfirstfreeTcConnect;
+ UintR cfirstfreeApiConnectCopy;
+ UintR cfirstfreeCacheRec;
+
+ UintR cfirstgcp;
+ UintR clastgcp;
+ UintR cfirstfreeGcp;
+ UintR cfirstfreeScanrec;
+
+ TableRecordPtr tabptr;
+ UintR cfirstfreeApiConnectFail;
+ UintR cfirstfreeApiConnect;
+
+ UintR cfirstfreeDatabuf;
+ BlockReference cdihblockref;
+ BlockReference cownref; /* OWN BLOCK REFERENCE */
+
+ ApiConnectRecordPtr timeOutptr;
+
+ ScanRecord *scanRecord;
+ UintR cscanrecFileSize;
+
+ UnsafeArrayPool<ScanFragRec> c_scan_frag_pool;
+ ScanFragRecPtr scanFragptr;
+
+ UintR cscanFragrecFileSize;
+ UintR cdatabufFilesize;
+
+ BlockReference cdictblockref;
+ BlockReference cerrorBlockref;
+ BlockReference clqhblockref;
+ BlockReference cndbcntrblockref;
+
+ Uint16 csignalKey;
+ Uint16 csystemnodes;
+ Uint16 cnodes[4];
+ NodeId cmasterNodeId;
+ UintR cnoParallelTakeOver;
+ TimeOutCheckState ctimeOutCheckFragActive;
+
+ UintR ctimeOutCheckFragCounter;
+ UintR ctimeOutCheckCounter;
+ UintR ctimeOutValue;
+ UintR ctimeOutCheckDelay;
+ Uint32 ctimeOutCheckHeartbeat;
+ Uint32 ctimeOutCheckLastHeartbeat;
+ Uint32 ctimeOutMissedHeartbeats;
+ Uint32 c_appl_timeout_value;
+
+ SystemStartState csystemStart;
+ TimeOutCheckState ctimeOutCheckActive;
+
+ BlockReference capiFailRef;
+ UintR cpackedListIndex;
+ Uint16 cpackedList[MAX_NODES];
+ UintR capiConnectClosing[MAX_NODES];
+ UintR con_lineNodes;
+
+ DatabufRecord *databufRecord;
+ DatabufRecordPtr databufptr;
+ DatabufRecordPtr tmpDatabufptr;
+
+ UintR treqinfo;
+ UintR ttransid1;
+ UintR ttransid2;
+
+ UintR tabortInd;
+
+ NodeId tnodeid;
+ BlockReference tblockref;
+
+ LqhTransConf::OperationStatus ttransStatus;
+ UintR ttcOprec;
+ NodeId tfailedNodeId;
+ Uint8 tcurrentReplicaNo;
+ Uint8 tpad1;
+
+ UintR tgci;
+ UintR tapplRef;
+ UintR tapplOprec;
+
+ UintR tindex;
+ UintR tmaxData;
+ UintR tmp;
+
+ UintR tnodes;
+ BlockReference tusersblkref;
+ UintR tuserpointer;
+ UintR tloadCode;
+
+ UintR tconfig1;
+ UintR tconfig2;
+
+ UintR cdata[32];
+ UintR ctransidFailHash[512];
+ UintR ctcConnectFailHash[1024];
+
+ /**
+ * Commit Ack handling
+ */
+public:
+ struct CommitAckMarker {
+ Uint32 transid1;
+ Uint32 transid2;
+ union { Uint32 nextPool; Uint32 nextHash; };
+ Uint32 prevHash;
+ Uint32 apiConnectPtr;
+ Uint16 apiNodeId;
+ Uint16 noOfLqhs;
+ Uint16 lqhNodeId[MAX_REPLICAS];
+
+ inline bool equal(const CommitAckMarker & p) const {
+ return ((p.transid1 == transid1) && (p.transid2 == transid2));
+ }
+
+ inline Uint32 hashValue() const {
+ return transid1;
+ }
+ };
+private:
+ typedef Ptr<CommitAckMarker> CommitAckMarkerPtr;
+ typedef DLHashTable<CommitAckMarker>::Iterator CommitAckMarkerIterator;
+
+ ArrayPool<CommitAckMarker> m_commitAckMarkerPool;
+ DLHashTable<CommitAckMarker> m_commitAckMarkerHash;
+
+ void execTC_COMMIT_ACK(Signal* signal);
+ void sendRemoveMarkers(Signal*, const CommitAckMarker *);
+ void sendRemoveMarker(Signal* signal,
+ NodeId nodeId,
+ Uint32 transid1,
+ Uint32 transid2);
+ void removeMarkerForFailedAPI(Signal* signal, Uint32 nodeId, Uint32 bucket);
+
+ bool getAllowStartTransaction() const {
+ if(getNodeState().getSingleUserMode())
+ return true;
+ return getNodeState().startLevel < NodeState::SL_STOPPING_2;
+ }
+
+ void checkAbortAllTimeout(Signal* signal, Uint32 sleepTime);
+ struct AbortAllRecord {
+ AbortAllRecord(){ clientRef = 0; }
+ Uint32 clientData;
+ BlockReference clientRef;
+
+ Uint32 oldTimeOutValue;
+ };
+ AbortAllRecord c_abortRec;
+
+ /************************** API CONNECT RECORD ***********************/
+ /* *******************************************************************/
+ /* THE API CONNECT RECORD CONTAINS THE CONNECTION RECORD TO WHICH THE*/
+ /* APPLICATION CONNECTS. THE APPLICATION CAN SEND ONE OPERATION AT A */
+ /* TIME. IT CAN SEND A NEW OPERATION IMMEDIATELY AFTER SENDING THE */
+ /* PREVIOUS OPERATION. THEREBY SEVERAL OPERATIONS CAN BE ACTIVE IN */
+ /* ONE TRANSACTION WITHIN TC. THIS IS ACHIEVED BY USING THE API */
+ /* CONNECT RECORD. EACH ACTIVE OPERATION IS HANDLED BY THE TC */
+ /* CONNECT RECORD. AS SOON AS THE TC CONNECT RECORD HAS SENT THE */
+ /* REQUEST TO THE LQH IT IS READY TO RECEIVE NEW OPERATIONS. THE */
+ /* LQH CONNECT RECORD TAKES CARE OF WAITING FOR AN OPERATION TO */
+ /* COMPLETE. WHEN AN OPERATION HAS COMPLETED ON THE LQH CONNECT */
+ /* RECORD A NEW OPERATION CAN BE STARTED ON THIS LQH CONNECT RECORD. */
+ /*******************************************************************>*/
+ /* */
+ /* API CONNECT RECORD ALIGNED TO BE 256 BYTES */
+ /*******************************************************************>*/
+ /************************** TC CONNECT RECORD ************************/
+ /* *******************************************************************/
+ /* TC CONNECT RECORD KEEPS ALL INFORMATION TO CARRY OUT A TRANSACTION*/
+ /* THE TRANSACTION CONTROLLER ESTABLISHES CONNECTIONS TO DIFFERENT */
+ /* BLOCKS TO CARRY OUT THE TRANSACTION. THERE CAN BE SEVERAL RECORDS */
+ /* PER ACTIVE TRANSACTION. THE TC CONNECT RECORD COOPERATES WITH THE */
+ /* API CONNECT RECORD FOR COMMUNICATION WITH THE API AND WITH THE */
+ /* LQH CONNECT RECORD FOR COMMUNICATION WITH THE LQH'S INVOLVED IN */
+ /* THE TRANSACTION. TC CONNECT RECORD IS PERMANENTLY CONNECTED TO A */
+ /* RECORD IN DICT AND ONE IN DIH. IT CONTAINS A LIST OF ACTIVE LQH */
+ /* CONNECT RECORDS AND A LIST OF STARTED BUT NOT ACTIVE LQH CONNECT */
+ /* RECORDS. IT DOES ALSO CONTAIN A LIST OF ALL OPERATIONS THAT ARE */
+ /* EXECUTED WITH THE TC CONNECT RECORD. */
+ /*******************************************************************>*/
+ /* TC_CONNECT RECORD ALIGNED TO BE 128 BYTES */
+ /*******************************************************************>*/
+ UintR cfirstfreeTcConnectFail;
+
+ /* POINTER FOR THE LQH RECORD*/
+ /* ************************ HOST RECORD ********************************* */
+ /********************************************************/
+ /* THIS RECORD CONTAINS ALIVE-STATUS ON ALL NODES IN THE*/
+ /* SYSTEM */
+ /********************************************************/
+ /* THIS RECORD IS ALIGNED TO BE 8 BYTES. */
+ /********************************************************/
+ /* ************************ TABLE RECORD ******************************** */
+ /********************************************************/
+ /* THIS RECORD CONTAINS THE CURRENT SCHEMA VERSION OF */
+ /* ALL TABLES IN THE SYSTEM. */
+ /********************************************************/
+ /*-------------------------------------------------------------------------*/
+ /* THE TC CONNECTION USED BY THIS SCAN. */
+ /*-------------------------------------------------------------------------*/
+ /*-------------------------------------------------------------------------*/
+ /* LENGTH READ FOR A PARTICULAR SCANNED OPERATION. */
+ /*-------------------------------------------------------------------------*/
+ /*-------------------------------------------------------------------------*/
+ /* REFERENCE TO THE SCAN RECORD FOR THIS SCAN PROCESS. */
+ /*-------------------------------------------------------------------------*/
+ /* *********************************************************************** */
+ /* ******$ DATA BUFFER ******$ */
+ /* */
+ /* THIS BUFFER IS USED AS A GENERAL DATA STORAGE. */
+ /* *********************************************************************** */
+ /* *********************************************************************** */
+ /* ******$ ATTRIBUTE INFORMATION RECORD ******$ */
+ /*
+ CAN CONTAIN ONE (1) ATTRINFO SIGNAL. ONE SIGNAL CONTAINS 24 ATTR.
+ INFO WORDS. BUT 32 ELEMENTS ARE USED TO MAKE PLEX HAPPY.
+ SOME OF THE ELEMENTS ARE USED TO THE FOLLOWING THINGS:
+ DATA LENGHT IN THIS RECORD IS STORED IN THE ELEMENT INDEXED BY
+ ZINBUF_DATA_LEN.
+ NEXT FREE ATTRBUF IS POINTED OUT BY THE ELEMENT INDEXED BY
+ PREVIOUS ATTRBUF IS POINTED OUT BY THE ELEMENT INDEXED BY ZINBUF_PREV
+ (NOT USED YET).
+ NEXT ATTRBUF IS POINTED OUT BY THE ELEMENT INDEXED BY ZINBUF_NEXT.
+ */
+ /* ********************************************************************** */
+ /**************************************************************************/
+ /* GLOBAL CHECKPOINT INFORMATION RECORD */
+ /* */
+ /* THIS RECORD IS USED TO STORE THE GCP NUMBER AND A COUNTER */
+ /* DURING THE COMPLETION PHASE OF THE TRANSACTION */
+ /**************************************************************************/
+ /* */
+ /* GCP RECORD ALIGNED TO BE 32 BYTES */
+ /**************************************************************************/
+ /**************************************************************************/
+ /* TC_FAIL_RECORD */
+ /* THIS RECORD IS USED WHEN HANDLING TAKE OVER OF ANOTHER FAILED TC NODE.*/
+ /**************************************************************************/
+ TcFailRecord *tcFailRecord;
+ TcFailRecordPtr tcNodeFailptr;
+ /**************************************************************************/
+ // Temporary variables that are not allowed to use for storage between
+ // signals. They
+ // can only be used in a signal to transfer values between subroutines.
+ // In the long run
+ // those variables should be removed and exchanged for stack
+ // variable communication.
+ /**************************************************************************/
+};
+#endif