MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Dbtc.hpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #ifndef DBTC_H
19 #define DBTC_H
20 
21 #include <ndb_limits.h>
22 #include <pc.hpp>
23 #include <SimulatedBlock.hpp>
24 #include <DLHashTable.hpp>
25 #include <SLList.hpp>
26 #include <DLList.hpp>
27 #include <DLFifoList.hpp>
28 #include <DataBuffer.hpp>
29 #include <Bitmask.hpp>
30 #include <AttributeList.hpp>
31 #include <signaldata/AttrInfo.hpp>
32 #include <signaldata/LqhTransConf.hpp>
33 #include <signaldata/LqhKey.hpp>
34 #include <signaldata/TrigAttrInfo.hpp>
35 #include <signaldata/TcIndx.hpp>
36 #include <signaldata/TransIdAI.hpp>
37 #include <signaldata/EventReport.hpp>
38 #include <trigger_definitions.h>
39 #include <SignalCounter.hpp>
40 
41 #ifdef DBTC_C
42 /*
43  * 2.2 LOCAL SYMBOLS
44  * -----------------
45  */
46 #define Z8NIL 255
47 #define ZAPI_CONNECT_FILESIZE 20
48 #define ZCLOSED 2
49 #define ZCOMMITING 0 /* VALUE FOR TRANSTATUS */
50 #define ZCOMMIT_SETUP 2
51 #define ZCONTINUE_ABORT_080 4
52 #define ZGCP_FILESIZE 10
53 #define ZINTSPH1 1
54 #define ZINTSPH2 2
55 #define ZINTSPH3 3
56 #define ZINTSPH6 6
57 #define ZLASTPHASE 255
58 #define ZNODEBUF_FILESIZE 2000
59 #define ZNR_OF_SEIZE 10
60 #define ZSCANREC_FILE_SIZE 100
61 #define ZSCAN_FRAGREC_FILE_SIZE 400
62 #define ZSCAN_OPREC_FILE_SIZE 400
63 #define ZSPH1 1
64 #define ZTABREC_FILESIZE 16
65 #define ZTAKE_OVER_ACTIVE 1
66 #define ZTAKE_OVER_IDLE 0
67 #define ZTC_CONNECT_FILESIZE 200
68 #define ZTCOPCONF_SIZE 6
69 
70 // ----------------------------------------
71 // Error Codes for Scan
72 // ----------------------------------------
73 #define ZNO_CONCURRENCY_ERROR 242
74 #define ZTOO_HIGH_CONCURRENCY_ERROR 244
75 #define ZNO_SCANREC_ERROR 245
76 #define ZNO_FRAGMENT_ERROR 246
77 #define ZSCAN_AI_LEN_ERROR 269
78 #define ZSCAN_LQH_ERROR 270
79 #define ZSCAN_FRAG_LQH_ERROR 274
80 
81 #define ZSCANTIME_OUT_ERROR 296
82 #define ZSCANTIME_OUT_ERROR2 297
83 
84 // ----------------------------------------
85 // Error Codes for transactions
86 // ----------------------------------------
87 #define ZSTATE_ERROR 202
88 #define ZLENGTH_ERROR 207 // Also Scan
89 #define ZERO_KEYLEN_ERROR 208
90 #define ZSIGNAL_ERROR 209
91 #define ZGET_ATTRBUF_ERROR 217 // Also Scan
92 #define ZGET_DATAREC_ERROR 218
93 #define ZMORE_AI_IN_TCKEYREQ_ERROR 220
94 #define ZCOMMITINPROGRESS 230
95 #define ZROLLBACKNOTALLOWED 232
96 #define ZNO_FREE_TC_CONNECTION 233 // Also Scan
97 #define ZABORTINPROGRESS 237
98 #define ZPREPAREINPROGRESS 238
99 #define ZWRONG_SCHEMA_VERSION_ERROR 241 // Also Scan
100 #define ZSCAN_NODE_ERROR 250
101 #define ZTRANS_STATUS_ERROR 253
102 #define ZTIME_OUT_ERROR 266
103 #define ZSIMPLE_READ_WITHOUT_AI 271
104 #define ZNO_AI_WITH_UPDATE 272
105 #define ZSEIZE_API_COPY_ERROR 275
106 #define ZSCANINPROGRESS 276
107 #define ZABORT_ERROR 277
108 #define ZCOMMIT_TYPE_ERROR 278
109 
110 #define ZNO_FREE_TC_MARKER 279
111 #define ZNODE_SHUTDOWN_IN_PROGRESS 280
112 #define ZCLUSTER_SHUTDOWN_IN_PROGRESS 281
113 #define ZWRONG_STATE 282
114 #define ZCLUSTER_IN_SINGLEUSER_MODE 299
115 
116 #define ZDROP_TABLE_IN_PROGRESS 283
117 #define ZNO_SUCH_TABLE 284
118 #define ZUNKNOWN_TABLE_ERROR 285
119 #define ZNODEFAIL_BEFORE_COMMIT 286
120 #define ZINDEX_CORRUPT_ERROR 287
121 #define ZSCAN_FRAGREC_ERROR 291
122 
123 // ----------------------------------------
124 // Seize error
125 // ----------------------------------------
126 #define ZNO_FREE_API_CONNECTION 219
127 #define ZSYSTEM_NOT_STARTED_ERROR 203
128 
129 // ----------------------------------------
130 // Release errors
131 // ----------------------------------------
132 #define ZINVALID_CONNECTION 229
133 
134 
135 #define ZNOT_FOUND 626
136 #define ZALREADYEXIST 630
137 #define ZNOTUNIQUE 893
138 
139 #define ZINVALID_KEY 290
140 #define ZUNLOCKED_IVAL_TOO_HIGH 294
141 #define ZUNLOCKED_OP_HAS_BAD_STATE 295
142 #define ZBAD_DIST_KEY 298
143 #define ZTRANS_TOO_BIG 261
144 #endif
145 
146 class Dbtc: public SimulatedBlock {
147 public:
148 
153  STATIC_CONST( TAKE_OVER_INSTANCE = 1 );
154 
156  CS_CONNECTED = 0,
157  CS_DISCONNECTED = 1,
158  CS_STARTED = 2,
159  CS_RECEIVING = 3,
160  CS_PREPARED = 4,
161  CS_START_PREPARING = 5,
162  CS_REC_PREPARING = 6,
163  CS_RESTART = 7,
164  CS_ABORTING = 8,
165  CS_COMPLETING = 9,
166  CS_COMPLETE_SENT = 10,
167  CS_PREPARE_TO_COMMIT = 11,
168  CS_COMMIT_SENT = 12,
169  CS_START_COMMITTING = 13,
170  CS_COMMITTING = 14,
171  CS_REC_COMMITTING = 15,
172  CS_WAIT_ABORT_CONF = 16,
173  CS_WAIT_COMPLETE_CONF = 17,
174  CS_WAIT_COMMIT_CONF = 18,
175  CS_FAIL_ABORTING = 19,
176  CS_FAIL_ABORTED = 20,
177  CS_FAIL_PREPARED = 21,
178  CS_FAIL_COMMITTING = 22,
179  CS_FAIL_COMMITTED = 23,
180  CS_FAIL_COMPLETED = 24,
181  CS_START_SCAN = 25,
182 
187 
192  };
193 
194  enum OperationState {
195  OS_CONNECTED = 1,
196  OS_OPERATING = 2,
197  OS_PREPARED = 3,
198  OS_COMMITTING = 4,
199  OS_COMMITTED = 5,
200  OS_COMPLETING = 6,
201  OS_COMPLETED = 7,
202  OS_RESTART = 8,
203  OS_ABORTING = 9,
204  OS_ABORT_SENT = 10,
205  OS_TAKE_OVER = 11,
206  OS_WAIT_DIH = 12,
207  OS_WAIT_KEYINFO = 13,
208  OS_WAIT_ATTR = 14,
209  OS_WAIT_COMMIT_CONF = 15,
210  OS_WAIT_ABORT_CONF = 16,
211  OS_WAIT_COMPLETE_CONF = 17,
212  OS_WAIT_SCAN = 18,
213 
214  OS_FIRE_TRIG_REQ = 19,
215  };
216 
217  enum AbortState {
218  AS_IDLE = 0,
219  AS_ACTIVE = 1
220  };
221 
222  enum HostState {
223  HS_ALIVE = 0,
224  HS_DEAD = 1
225  };
226 
227  enum LqhTransState {
228  LTS_IDLE = 0,
229  LTS_ACTIVE = 1
230  };
231 
232  enum FailState {
233  FS_IDLE = 0,
234  FS_LISTENING = 1,
235  FS_COMPLETING = 2
236  };
237 
238  enum SystemStartState {
239  SSS_TRUE = 0,
240  SSS_FALSE = 1
241  };
242 
243  enum TimeOutCheckState {
244  TOCS_TRUE = 0,
245  TOCS_FALSE = 1
246  };
247 
248  enum ReturnSignal {
249  RS_NO_RETURN = 0,
250  RS_TCKEYCONF = 1,
251  RS_TC_COMMITCONF = 3,
252  RS_TCROLLBACKCONF = 4,
253  RS_TCROLLBACKREP = 5
254  };
255 
256  enum IndexOperationState {
257  IOS_NOOP = 0,
258  IOS_INDEX_ACCESS = 1,
259  IOS_INDEX_ACCESS_WAIT_FOR_TCKEYCONF = 2,
260  IOS_INDEX_ACCESS_WAIT_FOR_TRANSID_AI = 3
261  };
262 
263  enum IndexState {
264  IS_BUILDING = 0, // build in progress, start state at create
265  IS_ONLINE = 1 // ready to use
266  };
267 
268  /* Sub states of IndexOperation while waiting for TransId_AI
269  * from index table lookup
270  */
271  enum IndexTransIdAIState {
272  ITAS_WAIT_HEADER = 0, // Initial state
273  ITAS_WAIT_FRAGID = 1, // Waiting for fragment id word
274  ITAS_WAIT_KEY = 2, // Waiting for (more) key information
275  ITAS_ALL_RECEIVED = 3, // All TransIdAI info received
276  ITAS_WAIT_KEY_FAIL = 4 // Failed collecting key
277  };
278 
279 
315  /*
316  2.3 RECORDS AND FILESIZES
317  -------------------------
318  */
319  /* **************************************************************** */
320  /* ---------------------------------------------------------------- */
321  /* ------------------- TRIGGER AND INDEX DATA --------------------- */
322  /* ---------------------------------------------------------------- */
323  /* **************************************************************** */
324  /* ********* DEFINED TRIGGER DATA ********* */
325  /* THIS RECORD FORMS LISTS OF ACTIVE */
326  /* TRIGGERS FOR EACH TABLE. */
327  /* THE RECORDS ARE MANAGED BY A TRIGGER */
328  /* POOL WHERE A TRIGGER RECORD IS SEIZED */
329  /* WHEN A TRIGGER IS ACTIVATED AND RELEASED */
330  /* WHEN THE TRIGGER IS DEACTIVATED. */
331  /* **************************************** */
337  UintR triggerId;
338 
342  TriggerType::Value triggerType;
343 
348 
352  union {
353  Uint32 nextPool;
354  Uint32 nextList;
355  };
356 
361  union {
362  Uint32 indexId; // For unique index trigger
363  Uint32 tableId; // For reorg trigger
364  };
365 
369  Uint32 prevList;
370 
371  Uint32 oldTriggerIds[2]; // For upgrade :(
372 
373  inline void print(NdbOut & s) const {
374  s << "[DefinedTriggerData = " << triggerId << "]";
375  }
376  };
377  typedef Ptr<TcDefinedTriggerData> DefinedTriggerPtr;
378 
383 
388 
390 
391  AttributeBuffer::DataBufferPool c_theAttributeBufferPool;
392 
393  UintR c_transactionBufferSpace;
394 
395 
396  /* ********** FIRED TRIGGER DATA ********** */
397  /* THIS RECORD FORMS LISTS OF FIRED */
398  /* TRIGGERS FOR A TRANSACTION. */
399  /* THE RECORDS ARE MANAGED BY A TRIGGER */
400  /* POOL WHERE A TRIGGER RECORD IS SEIZED */
401  /* WHEN A TRIGGER IS ACTIVATED AND RELEASED */
402  /* WHEN THE TRIGGER IS DEACTIVATED. */
403  /* **************************************** */
405  TcFiredTriggerData() {}
406 
410  Uint32 triggerId;
411 
416 
422  Uint32 fragId;
423 
427  Uint32 nodeId;
428 
432  TriggerType::Value triggerType;
433 
438 
442  AttributeBuffer::Head keyValues;
443 
447  AttributeBuffer::Head beforeValues;
448 
452  AttributeBuffer::Head afterValues;
453 
457  union {
458  Uint32 nextPool;
459  Uint32 nextList;
460  Uint32 nextHash;
461  };
462 
466  union {
467  Uint32 prevList;
468  Uint32 prevHash;
469  };
470 
471  inline void print(NdbOut & s) const {
472  s << "[FiredTriggerData = " << triggerId << "]";
473  }
474 
475  inline Uint32 hashValue() const {
476  return fireingOperation ^ nodeId;
477  }
478 
479  inline bool equal(const TcFiredTriggerData & rec) const {
480  return fireingOperation == rec.fireingOperation && nodeId == rec.nodeId;
481  }
482  };
483  typedef Ptr<TcFiredTriggerData> FiredTriggerPtr;
484 
489  DLHashTable<TcFiredTriggerData> c_firedTriggerHash;
490  AttributeBuffer::DataBufferPool c_theTriggerAttrInfoPool;
491 
492  Uint32 c_maxNumberOfDefinedTriggers;
493  Uint32 c_maxNumberOfFiredTriggers;
494 
495  struct AttrInfoRecord {
500 
504  union {
505  Uint32 nextPool;
506  Uint32 nextList;
507  };
511  Uint32 prevList;
512  };
513 
514 
515  /* ************* INDEX DATA *************** */
516  /* THIS RECORD FORMS LISTS OF ACTIVE */
517  /* INDEX FOR EACH TABLE. */
518  /* THE RECORDS ARE MANAGED BY A INDEX */
519  /* POOL WHERE AN INDEX RECORD IS SEIZED */
520  /* WHEN AN INDEX IS CREATED AND RELEASED */
521  /* WHEN THE INDEX IS DROPPED. */
522  /* **************************************** */
523  struct TcIndexData {
524  TcIndexData() {}
525 
529  IndexState indexState;
530 
534  Uint32 indexId;
535 
540 
545 
550 
554  union {
555  Uint32 nextPool;
556  Uint32 nextList;
557  };
561  Uint32 prevList;
562  };
563 
565 
570 
575  UintR c_maxNumberOfIndexes;
576 
578  TcIndexOperation() :
579  indexOpState(IOS_NOOP),
580  pendingKeyInfo(0),
581  keyInfoSectionIVal(RNIL),
582  pendingAttrInfo(0),
583  attrInfoSectionIVal(RNIL),
584  transIdAIState(ITAS_WAIT_HEADER),
585  pendingTransIdAI(0),
586  transIdAISectionIVal(RNIL),
587  indexReadTcConnect(RNIL)
588  {}
589 
591  {
592  }
593 
594  // Index data
595  Uint32 indexOpId;
596  IndexOperationState indexOpState; // Used to mark on-going TcKeyReq
597  Uint32 pendingKeyInfo;
598  Uint32 keyInfoSectionIVal;
599  Uint32 pendingAttrInfo;
600  Uint32 attrInfoSectionIVal;
601  IndexTransIdAIState transIdAIState;
602  Uint32 pendingTransIdAI;
603  Uint32 transIdAISectionIVal; // For accumulating TransId_AI
604  Uint32 fragmentId;
605 
606  TcKeyReq tcIndxReq;
607  UintR connectionIndex;
608  UintR indexReadTcConnect; //
609 
613  union {
614  Uint32 nextPool;
615  Uint32 nextList;
616  };
620  Uint32 prevList;
621  };
622 
624 
629 
630  UintR c_maxNumberOfIndexOperations;
631 
632  /************************** API CONNECT RECORD ***********************
633  * The API connect record contains the connection record to which the
634  * application connects.
635  *
636  * The application can send one operation at a time. It can send a
637  * new operation immediately after sending the previous operation.
638  * Thereby several operations can be active in one transaction within TC.
639  * This is achieved by using the API connect record.
640  * Each active operation is handled by the TC connect record.
641  * As soon as the TC connect record has sent the
642  * request to the LQH it is ready to receive new operations.
643  * The LQH connect record takes care of waiting for an operation to
644  * complete.
645  * When an operation has completed on the LQH connect record,
646  * a new operation can be started on this LQH connect record.
647  *******************************************************************
648  *
649  * API CONNECT RECORD ALIGNED TO BE 256 BYTES
650  ********************************************************************/
651 
652  /*******************************************************************>*/
653  // We break out the API Timer for optimisation on scanning rather than
654  // on fast access.
655  /*******************************************************************>*/
656  inline void setApiConTimer(Uint32 apiConPtrI, Uint32 value, Uint32 line){
657  c_apiConTimer[apiConPtrI] = value;
658  c_apiConTimer_line[apiConPtrI] = line;
659  }
660 
661  inline Uint32 getApiConTimer(Uint32 apiConPtrI) const {
662  return c_apiConTimer[apiConPtrI];
663  }
664  UintR* c_apiConTimer;
665  UintR* c_apiConTimer_line;
666 
669  ArrayPool<TcIndexOperation> & seizedIndexOpPool):
670  m_special_op_flags(0),
671  theFiredTriggers(firedTriggerPool),
672  theSeizedIndexOperations(seizedIndexOpPool)
673  {}
674 
675  //---------------------------------------------------
676  // First 16 byte cache line. Hot variables.
677  //---------------------------------------------------
678  ConnectionState apiConnectstate;
679  UintR transid[2];
680  UintR firstTcConnect;
681 
682  //---------------------------------------------------
683  // Second 16 byte cache line. Hot variables.
684  //---------------------------------------------------
685  UintR lqhkeyconfrec;
686  UintR cachePtr;
687  UintR currSavePointId;
688  UintR counter;
689 
690  //---------------------------------------------------
691  // Third 16 byte cache line. First and second cache
692  // line plus this will be enough for copy API records.
693  // Variables used in late phases.
694  //---------------------------------------------------
695  UintR nextGcpConnect;
696  UintR prevGcpConnect;
697  UintR gcpPointer;
698  UintR ndbapiConnect;
699 
700  //---------------------------------------------------
701  // Fourth 16 byte cache line. Only used in late phases.
702  // Plus 4 bytes of error handling.
703  //---------------------------------------------------
704  UintR nextApiConnect;
705  BlockReference ndbapiBlockref;
706  UintR apiCopyRecord;
707  Uint64 globalcheckpointid;
708 
709  //---------------------------------------------------
710  // Second 64 byte cache line starts. First 16 byte
711  // cache line in this one. Variables primarily used
712  // in early phase.
713  //---------------------------------------------------
714  UintR lastTcConnect;
715  UintR lqhkeyreqrec;
716  union {
717  Uint32 buddyPtr;
718  Int32 pendingTriggers; // For deferred triggers
719  };
720  union {
721  UintR apiScanRec;
722  UintR commitAckMarker;
723  };
724 
725  Uint32 no_commit_ack_markers;
726  Uint32 m_write_count;
727  ReturnSignal returnsignal;
728  AbortState abortState;
729 
730  enum TransactionFlags
731  {
732  TF_INDEX_OP_RETURN = 1,
733  TF_TRIGGER_PENDING = 2, // Used to mark waiting for a CONTINUEB
734  TF_EXEC_FLAG = 4,
735  TF_COMMIT_ACK_MARKER_RECEIVED = 8,
736  TF_DEFERRED_CONSTRAINTS = 16, // check constraints in deferred fashion
737  TF_DEFERRED_TRIGGERS = 32, // trans has deferred triggers
738  TF_END = 0
739  };
740  Uint32 m_flags;
741 
742  Uint8 m_special_op_flags; // Used to mark on-going TcKeyReq as indx table
743 
744  Uint8 takeOverRec;
745  Uint8 currentReplicaNo;
746 
747  Uint8 tckeyrec; // Changed from R
748 
749  Uint8 tcindxrec;
750  Uint8 apiFailState; // Changed R
751  Uint8 timeOutCounter;
752  Uint8 singleUserMode;
753 
754  Uint16 returncode;
755  Uint16 takeOverInd;
756  //---------------------------------------------------
757  // Error Handling variables. If cache line 32 bytes
758  // ensures that cache line is still only read in
759  // early phases.
760  //---------------------------------------------------
761  UintR currentTcConnect;
762  BlockReference tcBlockref;
763  UintR failureNr;
764 
765  //---------------------------------------------------
766  // Second 64 byte cache line. Third 16 byte cache line
767  // in this one. Variables primarily used in early phase
768  // and checked in late phase.
769  // Fourth cache line is the tcSendArray that is used
770  // when two and three operations are responded to in
771  // parallel. The first two entries in tcSendArray is
772  // part of the third cache line.
773  //---------------------------------------------------
774  //---------------------------------------------------
775  // timeOutCounter is used waiting for ABORTCONF, COMMITCONF
776  // and COMPLETECONF
777  //---------------------------------------------------
778  UintR tcSendArray[6];
779  NdbNodeBitmask m_transaction_nodes;
780 
781  // Trigger data
782 
787 
788 
789  // Index data
790 
791  UintR noIndexOp; // No outstanding index ops
792 
793  // Index op return context
794  UintR indexOp;
795  UintR clientData;
796  Uint32 errorData;
797  UintR attrInfoLen;
798  Uint32 immediateTriggerId; // Id of trigger op being fired NOW
799 
800  UintR accumulatingIndexOp;
801  UintR executingIndexOp;
802  UintR tcIndxSendArray[6];
803  DLList<TcIndexOperation> theSeizedIndexOperations;
804 
805 #ifdef ERROR_INSERT
806  Uint32 continueBCount; // ERROR_INSERT 8082
807 #endif
808  Uint8 m_pre_commit_pass;
809 
810  bool isExecutingDeferredTriggers() const {
811  return apiConnectstate == CS_SEND_FIRE_TRIG_REQ ||
812  apiConnectstate == CS_WAIT_FIRE_TRIG_REQ ;
813  }
814  };
815 
816  typedef Ptr<ApiConnectRecord> ApiConnectRecordPtr;
817 
818 
819  /************************** TC CONNECT RECORD ************************/
820  /* *******************************************************************/
821  /* TC CONNECT RECORD KEEPS ALL INFORMATION TO CARRY OUT A TRANSACTION*/
822  /* THE TRANSACTION CONTROLLER ESTABLISHES CONNECTIONS TO DIFFERENT */
823  /* BLOCKS TO CARRY OUT THE TRANSACTION. THERE CAN BE SEVERAL RECORDS */
824  /* PER ACTIVE TRANSACTION. THE TC CONNECT RECORD COOPERATES WITH THE */
825  /* API CONNECT RECORD FOR COMMUNICATION WITH THE API AND WITH THE */
826  /* LQH CONNECT RECORD FOR COMMUNICATION WITH THE LQH'S INVOLVED IN */
827  /* THE TRANSACTION. TC CONNECT RECORD IS PERMANENTLY CONNECTED TO A */
828  /* RECORD IN DICT AND ONE IN DIH. IT CONTAINS A LIST OF ACTIVE LQH */
829  /* CONNECT RECORDS AND A LIST OF STARTED BUT NOT ACTIVE LQH CONNECT */
830  /* RECORDS. IT DOES ALSO CONTAIN A LIST OF ALL OPERATIONS THAT ARE */
831  /* EXECUTED WITH THE TC CONNECT RECORD. */
832  /*******************************************************************>*/
833  /* TC_CONNECT RECORD ALIGNED TO BE 128 BYTES */
834  /*******************************************************************>*/
836  //---------------------------------------------------
837  // First 16 byte cache line. Those variables are only
838  // used in error cases.
839  //---------------------------------------------------
840  UintR tcOprec; /* TC OPREC of operation being taken over */
841  Uint16 failData[4]; /* Failed nodes when taking over an operation */
842  UintR nextTcFailHash;
843 
844  //---------------------------------------------------
845  // Second 16 byte cache line. Those variables are used
846  // from LQHKEYCONF to sending COMMIT and COMPLETED.
847  //---------------------------------------------------
848  UintR lastLqhCon; /* Connect record in last replicas Lqh record */
849  Uint16 lastLqhNodeId; /* Node id of last replicas Lqh */
850  Uint16 m_execAbortOption;/* TcKeyReq::ExecuteAbortOption */
851  UintR commitAckMarker; /* CommitMarker I value */
852 
853  //---------------------------------------------------
854  // Third 16 byte cache line. The hottest variables.
855  //---------------------------------------------------
856  OperationState tcConnectstate; /* THE STATE OF THE CONNECT*/
857  UintR apiConnect; /* POINTER TO API CONNECT RECORD */
858  UintR nextTcConnect; /* NEXT TC RECORD*/
859  Uint8 dirtyOp;
860  Uint8 opSimple;
861  Uint8 lastReplicaNo; /* NUMBER OF THE LAST REPLICA IN THE OPERATION */
862  Uint8 noOfNodes; /* TOTAL NUMBER OF NODES IN OPERATION */
863  Uint8 operation; /* OPERATION TYPE */
864  /* 0 = READ REQUEST */
865  /* 1 = UPDATE REQUEST */
866  /* 2 = INSERT REQUEST */
867  /* 3 = DELETE REQUEST */
868  Uint8 m_special_op_flags; // See ApiConnectRecord::SpecialOpFlags
869  enum SpecialOpFlags {
870  SOF_NORMAL = 0,
871  SOF_INDEX_TABLE_READ = 1, // Read index table
872  SOF_INDEX_BASE_TABLE_ACCESS = 2,// Execute on "real" table
873  SOF_REORG_TRIGGER_BASE = 4,
874  SOF_REORG_TRIGGER = 4 | 16, // A reorg trigger
875  SOF_REORG_MOVING = 8, // A record that should be moved
876  SOF_TRIGGER = 16, // A trigger
877  SOF_REORG_COPY = 32,
878  SOF_REORG_DELETE = 64,
879  SOF_DEFERRED_TRIGGER = 128 // Op has deferred trigger
880  };
881 
882  static inline bool isIndexOp(Uint8 flags) {
883  return
884  flags == SOF_INDEX_TABLE_READ ||
885  flags == SOF_INDEX_BASE_TABLE_ACCESS;
886  }
887 
888  //---------------------------------------------------
889  // Fourth 16 byte cache line. The mildly hot variables.
890  // tcNodedata expands 4 Bytes into the next cache line
891  // with indexes almost never used.
892  //---------------------------------------------------
893  UintR clientData; /* SENDERS OPERATION POINTER */
894  UintR prevTcConnect; /* DOUBLY LINKED LIST OF TC CONNECT RECORDS*/
895  UintR savePointId;
896 
897  Uint16 tcNodedata[4];
898  /* Instance key to send to LQH. Receiver maps it to actual instance. */
899  Uint16 lqhInstanceKey;
900 
901  // Trigger data
902  UintR noFiredTriggers; // As reported by lqhKeyConf
903  UintR noReceivedTriggers; // FIRE_TRIG_ORD
904  UintR triggerExecutionCount;// No of outstanding op due to triggers
905  UintR savedState[LqhKeyConf::SignalLength];
906 
907  UintR triggeringOperation; // Which operation was "cause" of this op
908 
909  // Index data
910  UintR indexOp;
911  UintR currentTriggerId;
912  UintR attrInfoLen;
913  };
914 
915  friend struct TcConnectRecord;
916 
918 
919  // ********************** CACHE RECORD **************************************
920  //---------------------------------------------------------------------------
921  // This record is used between reception of TCKEYREQ and sending of LQHKEYREQ
922  // It is separatedso as to improve the cache hit rate and also to minimise
923  // the necessary memory storage in NDB Cluster.
924  //---------------------------------------------------------------------------
925 
926  struct CacheRecord {
927  /* Fields used by TCKEYREQ/TCINDXREQ/SCANTABREQ */
928  Uint32 keyInfoSectionI; /* KeyInfo section I-val */
929  Uint32 attrInfoSectionI; /* AttrInfo section I-val */
930 
931  // TODO : Consider using section length + other vars for this
932  UintR currReclenAi; /* AttrInfo words received so far */
933  Uint16 attrlength; /* Total AttrInfo length */
934  Uint16 save1; /* KeyInfo words received so far */
935  Uint16 keylen; /* KEY LENGTH SENT BY REQUEST SIGNAL */
936 
937  /* Distribution information */
938  // TODO : Consider placing this info into other records
939  Uint8 distributionKeyIndicator;
940  Uint8 viaSPJFlag; /* Send request via the SPJ block.*/
941  UintR distributionKey;
942  /* End of fields used by TCKEYREQ/TCINDXREQ/SCANTABREQ */
943 
944 
945  /* TCKEYREQ/TCINDXREQ only fields */
946  UintR schemaVersion;/* SCHEMA VERSION USED IN TRANSACTION */
947  UintR tableref; /* POINTER TO THE TABLE IN WHICH THE FRAGMENT EXISTS*/
948  Uint16 apiVersionNo;
949 
950  UintR fragmentid; /* THE COMPUTED FRAGMENT ID */
951  UintR hashValue; /* THE HASH VALUE USED TO LOCATE FRAGMENT */
952 
953  Uint8 m_special_hash; // collation or distribution key
954  Uint8 m_no_hash; // Hash not required for LQH (special variant)
955  Uint8 m_no_disk_flag;
956  Uint8 m_op_queue;
957  Uint8 lenAiInTckeyreq; /* LENGTH OF ATTRIBUTE INFORMATION IN TCKEYREQ */
958 
959  Uint8 fragmentDistributionKey; /* DIH generation no */
960 
965  Uint8 opExec;
966 
967  /* Use of Long signals */
968  Uint8 isLongTcKeyReq; /* Incoming TcKeyReq used long signal */
969  Uint8 useLongLqhKeyReq; /* Outgoing LqhKeyReq should be long */
970 
971  UintR nextCacheRec;
972  Uint32 scanInfo;
973 
974  Uint32 scanTakeOverInd;
975  Uint32 unlockNodeId; /* NodeId for unlock operation */
976  /* End of TCKEYREQ/TCINDXREQ only fields */
977 
978  };
979 
981 
982  /* ************************ HOST RECORD ********************************** */
983  /********************************************************/
984  /* THIS RECORD CONTAINS ALIVE-STATUS ON ALL NODES IN THE*/
985  /* SYSTEM */
986  /********************************************************/
987  /* THIS RECORD IS ALIGNED TO BE 128 BYTES. */
988  /********************************************************/
989  struct HostRecord {
990  HostState hostStatus;
991  LqhTransState lqhTransStatus;
992  bool inPackedList;
993  UintR noOfPackedWordsLqh;
994  UintR packedWordsLqh[26];
995  UintR noOfWordsTCKEYCONF;
996  UintR packedWordsTCKEYCONF[30];
997  BlockReference hostLqhBlockRef;
998 
999  enum NodeFailBits
1000  {
1001  NF_TAKEOVER = 0x1,
1002  NF_CHECK_SCAN = 0x2,
1003  NF_CHECK_TRANSACTION = 0x4,
1004  NF_BLOCK_HANDLE = 0x8,
1005  NF_NODE_FAIL_BITS = 0xF // All bits...
1006  };
1007  Uint32 m_nf_bits;
1008  NdbNodeBitmask m_lqh_trans_conf;
1009  }; /* p2c: size = 128 bytes */
1010 
1012 
1013  /* *********** TABLE RECORD ********************************************* */
1014 
1015  /********************************************************/
1016  /* THIS RECORD CONTAINS THE CURRENT SCHEMA VERSION OF */
1017  /* ALL TABLES IN THE SYSTEM. */
1018  /********************************************************/
1019  struct TableRecord {
1020  TableRecord() {}
1021  Uint32 currentSchemaVersion;
1022  Uint16 m_flags;
1023  Uint8 tableType;
1024  Uint8 singleUserMode;
1025 
1026  enum {
1027  TR_ENABLED = 1 << 0,
1028  TR_DROPPING = 1 << 1,
1029  TR_STORED_TABLE = 1 << 2,
1030  TR_PREPARED = 1 << 3
1031  ,TR_USER_DEFINED_PARTITIONING = 1 << 4
1032  };
1033  Uint8 get_enabled() const { return (m_flags & TR_ENABLED) != 0; }
1034  Uint8 get_dropping() const { return (m_flags & TR_DROPPING) != 0; }
1035  Uint8 get_storedTable() const { return (m_flags & TR_STORED_TABLE) != 0; }
1036  Uint8 get_prepared() const { return (m_flags & TR_PREPARED) != 0; }
1037  void set_enabled(Uint8 f) { f ? m_flags |= (Uint16)TR_ENABLED : m_flags &= ~(Uint16)TR_ENABLED; }
1038  void set_dropping(Uint8 f) { f ? m_flags |= (Uint16)TR_DROPPING : m_flags &= ~(Uint16)TR_DROPPING; }
1039  void set_storedTable(Uint8 f) { f ? m_flags |= (Uint16)TR_STORED_TABLE : m_flags &= ~(Uint16)TR_STORED_TABLE; }
1040  void set_prepared(Uint8 f) { f ? m_flags |= (Uint16)TR_PREPARED : m_flags &= ~(Uint16)TR_PREPARED; }
1041 
1042  Uint8 get_user_defined_partitioning() const {
1043  return (m_flags & TR_USER_DEFINED_PARTITIONING) != 0;
1044  }
1045 
1046  void set_user_defined_partitioning(Uint8 f) {
1047  f ?
1048  m_flags |= (Uint16)TR_USER_DEFINED_PARTITIONING :
1049  m_flags &= ~(Uint16)TR_USER_DEFINED_PARTITIONING;
1050  }
1051 
1052  Uint8 noOfKeyAttr;
1053  Uint8 hasCharAttr;
1054  Uint8 noOfDistrKeys;
1055  Uint8 hasVarKeys;
1056 
1057  bool checkTable(Uint32 schemaVersion) const {
1058  return !get_dropping() &&
1059  ((
1060  get_enabled() && table_version_major(schemaVersion) == table_version_major(currentSchemaVersion))
1061  ||
1062  (
1066  get_prepared() && schemaVersion == currentSchemaVersion &&
1067  DictTabInfo::isUniqueIndex(tableType)));
1068  }
1069 
1070  Uint32 getErrorCode(Uint32 schemaVersion) const;
1071  };
1072  typedef Ptr<TableRecord> TableRecordPtr;
1073 
1080  struct ScanFragRec {
1081  ScanFragRec(){
1082  stopFragTimer();
1083  lqhBlockref = 0;
1084  scanFragState = IDLE;
1085  scanRec = RNIL;
1086  }
1105  IDLE = 0,
1106  WAIT_GET_PRIMCONF = 1,
1107  LQH_ACTIVE = 2,
1108  DELIVERED = 4,
1109  QUEUED_FOR_DELIVERY = 6,
1110  COMPLETED = 7
1111  };
1112  // Timer for checking timeout of this fragment scan
1113  Uint32 scanFragTimer;
1114 
1115  // Id of the current scanned fragment
1116  Uint32 scanFragId;
1117 
1118  // Blockreference of LQH
1119  BlockReference lqhBlockref;
1120 
1121  // getNodeInfo.m_connectCount, set at seize used so that
1122  // I don't accidently kill a starting node
1123  Uint32 m_connectCount;
1124 
1125  // State of this fragment scan
1126  ScanFragState scanFragState;
1127 
1128  // Id of the ScanRecord this fragment scan belongs to
1129  Uint32 scanRec;
1130 
1131  // The value of fragmentCompleted in the last received SCAN_FRAGCONF
1132  Uint8 m_scan_frag_conf_status;
1133 
1134  inline void startFragTimer(Uint32 timeVal){
1135  scanFragTimer = timeVal;
1136  }
1137  inline void stopFragTimer(void){
1138  scanFragTimer = 0;
1139  }
1140 
1141  Uint32 m_ops;
1142  Uint32 m_chksum;
1143  Uint32 m_apiPtr;
1144  Uint32 m_totalLen;
1145  union {
1146  Uint32 nextPool;
1147  Uint32 nextList;
1148  };
1149  Uint32 prevList;
1150  };
1151 
1152  typedef Ptr<ScanFragRec> ScanFragRecPtr;
1153  typedef LocalDLList<ScanFragRec> ScanFragList;
1154 
1160  struct ScanRecord {
1161  ScanRecord() {}
1216  enum ScanState {
1217  IDLE = 0,
1218  WAIT_SCAN_TAB_INFO = 1,
1219  WAIT_AI = 2,
1220  WAIT_FRAGMENT_COUNT = 3,
1221  RUNNING = 4,
1222  CLOSING_SCAN = 5
1223  };
1224 
1225  // State of this scan
1226  ScanState scanState;
1227 
1228  DLList<ScanFragRec>::Head m_running_scan_frags; // Currently in LQH
1229  union { Uint32 m_queued_count; Uint32 scanReceivedOperations; };
1230  DLList<ScanFragRec>::Head m_queued_scan_frags; // In TC !sent to API
1231  DLList<ScanFragRec>::Head m_delivered_scan_frags;// Delivered to API
1232 
1233  // Id of the next fragment to be scanned. Used by scan fragment
1234  // processes when they are ready for the next fragment
1235  Uint32 scanNextFragId;
1236 
1237  // Total number of fragments in the table we are scanning
1238  Uint32 scanNoFrag;
1239 
1240  // Index of next ScanRecords when in free list
1241  Uint32 nextScan;
1242 
1243  // Length of expected attribute information
1244  union { Uint32 scanAiLength; Uint32 m_booked_fragments_count; };
1245 
1246  Uint32 scanKeyLen;
1247 
1248  // Reference to ApiConnectRecord
1249  Uint32 scanApiRec;
1250 
1251  // Reference to TcConnectRecord
1252  Uint32 scanTcrec;
1253 
1254  // Number of scan frag processes that belong to this scan
1255  Uint32 scanParallel;
1256 
1257  // Schema version used by this scan
1258  Uint32 scanSchemaVersion;
1259 
1260  // Index of stored procedure belonging to this scan
1261  Uint32 scanStoredProcId;
1262 
1263  // The index of table that is scanned
1264  Uint32 scanTableref;
1265  Uint32 m_scan_cookie;
1266 
1267  // Number of operation records per scanned fragment
1268  // Number of operations in first batch
1269  // Max number of bytes per batch
1270  union {
1271  Uint16 first_batch_size_rows;
1272  Uint16 batch_size_rows;
1273  };
1274  Uint32 batch_byte_size;
1275  Uint32 m_scan_block_no;
1276 
1277  Uint32 scanRequestInfo; // ScanFrag format
1278 
1279  // Close is ordered
1280  bool m_close_scan_req;
1281  // All SCAN_FRAGCONS should be passed on to the API as SCAN_TABCONFS.
1282  // This is needed to correctly propagate 'node masks' when scanning via the
1283  // SPJ block.
1284  bool m_pass_all_confs;
1285 
1290  };
1292 
1293  /*************************************************************************>*/
1294  /* GLOBAL CHECKPOINT INFORMATION RECORD */
1295  /* */
1296  /* THIS RECORD IS USED TO STORE THE GLOBALCHECKPOINT NUMBER AND A
1297  * COUNTER DURING THE COMPLETION PHASE OF THE TRANSACTION */
1298  /*************************************************************************>*/
1299  /* */
1300  /* GCP RECORD ALIGNED TO BE 32 BYTES */
1301  /*************************************************************************>*/
1302  struct GcpRecord {
1303  Uint16 gcpUnused0;
1304  Uint16 gcpNomoretransRec;
1305  UintR gcpUnused1[2]; /* p2c: Not used */
1306  UintR firstApiConnect;
1307  UintR lastApiConnect;
1308  UintR nextGcp;
1309  Uint64 gcpId;
1310  }; /* p2c: size = 32 bytes */
1311 
1312  typedef Ptr<GcpRecord> GcpRecordPtr;
1313 
1314  /*************************************************************************>*/
1315  /* TC_FAIL_RECORD */
1316  /* THIS RECORD IS USED WHEN HANDLING TAKE OVER OF ANOTHER FAILED
1317  * TC NODE. */
1318  /*************************************************************************>*/
1319  struct TcFailRecord {
1320  Uint16 queueList[MAX_NDB_NODES];
1321  Uint8 takeOverProcState[MAX_NDB_NODES];
1322  UintR completedTakeOver;
1323  UintR currentHashIndexTakeOver;
1324  FailState failStatus;
1325  Uint16 queueIndex;
1326  Uint16 takeOverNode;
1327  }; /* p2c: size = 64 bytes */
1328 
1330 
1331 public:
1332  Dbtc(Block_context&, Uint32 instanceNumber = 0);
1333  virtual ~Dbtc();
1334 
1335 private:
1336  BLOCK_DEFINES(Dbtc);
1337 
1338  // Transit signals
1339  void execPACKED_SIGNAL(Signal* signal);
1340  void execABORTED(Signal* signal);
1341  void execATTRINFO(Signal* signal);
1342  void execCONTINUEB(Signal* signal);
1343  void execKEYINFO(Signal* signal);
1344  void execSCAN_NEXTREQ(Signal* signal);
1345  void execSCAN_PROCREQ(Signal* signal);
1346  void execSCAN_PROCCONF(Signal* signal);
1347  void execTAKE_OVERTCREQ(Signal* signal);
1348  void execTAKE_OVERTCCONF(Signal* signal);
1349  void execLQHKEYREF(Signal* signal);
1350  void execTRANSID_AI_R(Signal* signal);
1351  void execKEYINFO20_R(Signal* signal);
1352  void execROUTE_ORD(Signal* signal);
1353  // Received signals
1354  void execDUMP_STATE_ORD(Signal* signal);
1355  void execDBINFO_SCANREQ(Signal* signal);
1356  void execSEND_PACKED(Signal* signal);
1357  void execCOMPLETED(Signal* signal);
1358  void execCOMMITTED(Signal* signal);
1359  void execDIGETNODESREF(Signal* signal);
1360  void execDIH_SCAN_GET_NODES_REF(Signal* signal);
1361  void execDIH_SCAN_GET_NODES_CONF(Signal* signal);
1362  void execDIVERIFYCONF(Signal* signal);
1363  void execDIH_SCAN_TAB_REF(Signal* signal);
1364  void execDIH_SCAN_TAB_CONF(Signal* signal);
1365  void execGCP_NOMORETRANS(Signal* signal);
1366  void execLQHKEYCONF(Signal* signal);
1367  void execNDB_STTOR(Signal* signal);
1368  void execREAD_NODESCONF(Signal* signal);
1369  void execREAD_NODESREF(Signal* signal);
1370  void execSTTOR(Signal* signal);
1371  void execTC_COMMITREQ(Signal* signal);
1372  void execTC_CLOPSIZEREQ(Signal* signal);
1373  void execTCGETOPSIZEREQ(Signal* signal);
1374  void execTCKEYREQ(Signal* signal);
1375  void execTCRELEASEREQ(Signal* signal);
1376  void execTCSEIZEREQ(Signal* signal);
1377  void execTCROLLBACKREQ(Signal* signal);
1378  void execTC_HBREP(Signal* signal);
1379  void execTC_SCHVERREQ(Signal* signal);
1380  void execTAB_COMMITREQ(Signal* signal);
1381  void execSCAN_TABREQ(Signal* signal);
1382  void execSCAN_TABINFO(Signal* signal);
1383  void execSCAN_FRAGCONF(Signal* signal);
1384  void execSCAN_FRAGREF(Signal* signal);
1385  void execREAD_CONFIG_REQ(Signal* signal);
1386  void execLQH_TRANSCONF(Signal* signal);
1387  void execCOMPLETECONF(Signal* signal);
1388  void execCOMMITCONF(Signal* signal);
1389  void execABORTCONF(Signal* signal);
1390  void execNODE_FAILREP(Signal* signal);
1391  void execINCL_NODEREQ(Signal* signal);
1392  void execTIME_SIGNAL(Signal* signal);
1393  void execAPI_FAILREQ(Signal* signal);
1394  void execSCAN_HBREP(Signal* signal);
1395 
1396  void execABORT_ALL_REQ(Signal* signal);
1397 
1398  void execCREATE_TRIG_IMPL_REQ(Signal* signal);
1399  void execDROP_TRIG_IMPL_REQ(Signal* signal);
1400  void execFIRE_TRIG_ORD(Signal* signal);
1401  void execTRIG_ATTRINFO(Signal* signal);
1402  void execCREATE_INDX_IMPL_REQ(Signal* signal);
1403  void execDROP_INDX_IMPL_REQ(Signal* signal);
1404  void execTCINDXREQ(Signal* signal);
1405  void execINDXKEYINFO(Signal* signal);
1406  void execINDXATTRINFO(Signal* signal);
1407  void execALTER_INDX_IMPL_REQ(Signal* signal);
1408  void execSIGNAL_DROPPED_REP(Signal* signal);
1409 
1410  void execFIRE_TRIG_REF(Signal*);
1411  void execFIRE_TRIG_CONF(Signal*);
1412 
1413  // Index table lookup
1414  void execTCKEYCONF(Signal* signal);
1415  void execTCKEYREF(Signal* signal);
1416  void execTRANSID_AI(Signal* signal);
1417  void execTCROLLBACKREP(Signal* signal);
1418 
1419  void execCREATE_TAB_REQ(Signal* signal);
1420  void execPREP_DROP_TAB_REQ(Signal* signal);
1421  void execDROP_TAB_REQ(Signal* signal);
1422  void checkWaitDropTabFailedLqh(Signal*, Uint32 nodeId, Uint32 tableId);
1423  void execALTER_TAB_REQ(Signal* signal);
1424  void set_timeout_value(Uint32 timeOut);
1425  void set_appl_timeout_value(Uint32 timeOut);
1426  void set_no_parallel_takeover(Uint32);
1427  void updateBuddyTimer(ApiConnectRecordPtr);
1428 
1429  // Statement blocks
1430  void updatePackedList(Signal* signal, HostRecord* ahostptr,
1431  Uint16 ahostIndex);
1432  void clearTcNodeData(Signal* signal,
1433  UintR TLastLqhIndicator,
1434  UintR Tstart);
1435  void errorReport(Signal* signal, int place);
1436  void warningReport(Signal* signal, int place);
1437  void printState(Signal* signal, int place);
1438  int seizeTcRecord(Signal* signal);
1439  int seizeCacheRecord(Signal* signal);
1440  void TCKEY_abort(Signal* signal, int place);
1441  void copyFromToLen(UintR* sourceBuffer, UintR* destBuffer, UintR copyLen);
1442  void reportNodeFailed(Signal* signal, Uint32 nodeId);
1443  void sendPackedTCKEYCONF(Signal* signal,
1444  HostRecord * ahostptr,
1445  UintR hostId);
1446  void sendPackedSignalLqh(Signal* signal, HostRecord * ahostptr);
1447  Uint32 sendCommitLqh(Signal* signal,
1448  TcConnectRecord * const regTcPtr);
1449  Uint32 sendCompleteLqh(Signal* signal,
1450  TcConnectRecord * const regTcPtr);
1451 
1452  void sendFireTrigReq(Signal*, Ptr<ApiConnectRecord>, Uint32 firstTcConnect);
1453  Uint32 sendFireTrigReqLqh(Signal*, Ptr<TcConnectRecord>, Uint32 pass);
1454 
1455  void sendTCKEY_FAILREF(Signal* signal, ApiConnectRecord *);
1456  void sendTCKEY_FAILCONF(Signal* signal, ApiConnectRecord *);
1457  void routeTCKEY_FAILREFCONF(Signal* signal, const ApiConnectRecord *,
1458  Uint32 gsn, Uint32 len);
1459  void execTCKEY_FAILREFCONF_R(Signal* signal);
1460  void checkStartTimeout(Signal* signal);
1461  void checkStartFragTimeout(Signal* signal);
1462  void timeOutFoundFragLab(Signal* signal, Uint32 TscanConPtr);
1463  void timeOutLoopStartFragLab(Signal* signal, Uint32 TscanConPtr);
1464  int releaseAndAbort(Signal* signal);
1465  void findApiConnectFail(Signal* signal);
1466  void findTcConnectFail(Signal* signal, Uint32 instanceKey);
1467  void initApiConnectFail(Signal* signal);
1468  void initTcConnectFail(Signal* signal, Uint32 instanceKey);
1469  void initTcFail(Signal* signal);
1470  void releaseTakeOver(Signal* signal);
1471  void setupFailData(Signal* signal);
1472  void updateApiStateFail(Signal* signal);
1473  void updateTcStateFail(Signal* signal, Uint32 instanceKey);
1474  void handleApiFailState(Signal* signal, UintR anApiConnectptr);
1475  void handleFailedApiNode(Signal* signal,
1476  UintR aFailedNode,
1477  UintR anApiConnectPtr);
1478  void handleScanStop(Signal* signal, UintR aFailedNode);
1479  void initScanTcrec(Signal* signal);
1480  Uint32 initScanrec(ScanRecordPtr, const class ScanTabReq*,
1481  const UintR scanParallel,
1482  const UintR noOprecPerFrag,
1483  const Uint32 aiLength,
1484  const Uint32 keyLength);
1485  void initScanfragrec(Signal* signal);
1486  void releaseScanResources(Signal*, ScanRecordPtr, bool not_started = false);
1487  ScanRecordPtr seizeScanrec(Signal* signal);
1488  void sendScanFragReq(Signal*, ScanRecord*, ScanFragRec*, bool);
1489  void sendScanTabConf(Signal* signal, ScanRecordPtr);
1490  void close_scan_req(Signal*, ScanRecordPtr, bool received_req);
1491  void close_scan_req_send_conf(Signal*, ScanRecordPtr);
1492 
1493  void checkGcp(Signal* signal);
1494  void commitGciHandling(Signal* signal, Uint64 Tgci);
1495  void copyApi(Ptr<ApiConnectRecord> dst, Ptr<ApiConnectRecord> src);
1496  void DIVER_node_fail_handling(Signal* signal, Uint64 Tgci);
1497  void gcpTcfinished(Signal* signal, Uint64 gci);
1498  void handleGcp(Signal* signal, Ptr<ApiConnectRecord>);
1499  void hash(Signal* signal);
1500  bool handle_special_hash(Uint32 dstHash[4],
1501  const Uint32* src, Uint32 srcLen,
1502  Uint32 tabPtrI, bool distr);
1503 
1504  void initApiConnect(Signal* signal);
1505  void initApiConnectRec(Signal* signal,
1506  ApiConnectRecord * const regApiPtr,
1507  bool releaseIndexOperations = false);
1508  void initgcp(Signal* signal);
1509  void inithost(Signal* signal);
1510  void initialiseScanrec(Signal* signal);
1511  void initialiseScanFragrec(Signal* signal);
1512  void initialiseScanOprec(Signal* signal);
1513  void initTable(Signal* signal);
1514  void initialiseTcConnect(Signal* signal);
1515  void linkApiToGcp(Ptr<GcpRecord>, Ptr<ApiConnectRecord>);
1516  void linkGciInGcilist(Ptr<GcpRecord>);
1517  void linkTcInConnectionlist(Signal* signal);
1518  void releaseAbortResources(Signal* signal);
1519  void releaseApiCon(Signal* signal, UintR aApiConnectPtr);
1520  void releaseApiConCopy(Signal* signal);
1521  void releaseApiConnectFail(Signal* signal);
1522  void releaseAttrinfo();
1523  void releaseKeys();
1524  void releaseDirtyRead(Signal*, ApiConnectRecordPtr, TcConnectRecord*);
1525  void releaseDirtyWrite(Signal* signal);
1526  void releaseTcCon();
1527  void releaseTcConnectFail(Signal* signal);
1528  void releaseTransResources(Signal* signal);
1529  void seizeApiConnect(Signal* signal);
1530  void seizeApiConnectCopy(Signal* signal);
1531  void seizeApiConnectFail(Signal* signal);
1532  void crash_gcp(Uint32 line);
1533  void seizeGcp(Ptr<GcpRecord> & dst, Uint64 gci);
1534  void seizeTcConnect(Signal* signal);
1535  void seizeTcConnectFail(Signal* signal);
1536  Ptr<ApiConnectRecord> sendApiCommit(Signal* signal);
1537  bool sendAttrInfoTrain(Signal* signal,
1538  UintR TBRef,
1539  Uint32 connectPtr,
1540  Uint32 offset,
1541  Uint32 attrInfoIVal);
1542  void sendContinueTimeOutControl(Signal* signal, Uint32 TapiConPtr);
1543  void sendlqhkeyreq(Signal* signal,
1544  BlockReference TBRef);
1545  void sendSystemError(Signal* signal, int line);
1546  void sendtckeyconf(Signal* signal, UintR TcommitFlag);
1547  void unlinkApiConnect(Ptr<GcpRecord>, Ptr<ApiConnectRecord>);
1548  void unlinkGcp(Ptr<GcpRecord>);
1549  void unlinkReadyTcCon(Signal* signal);
1550  void handleFailedOperation(Signal* signal,
1551  const LqhKeyRef * const lqhKeyRef,
1552  bool gotLqhKeyRef);
1553  void markOperationAborted(ApiConnectRecord * const regApiPtr,
1554  TcConnectRecord * const regTcPtr);
1555  void clearCommitAckMarker(ApiConnectRecord * const regApiPtr,
1556  TcConnectRecord * const regTcPtr);
1557  // Trigger and index handling
1558  int saveINDXKEYINFO(Signal* signal,
1559  TcIndexOperation* indexOp,
1560  const Uint32 *src,
1561  Uint32 len);
1562  bool receivedAllINDXKEYINFO(TcIndexOperation* indexOp);
1563  int saveINDXATTRINFO(Signal* signal,
1564  TcIndexOperation* indexOp,
1565  const Uint32 *src,
1566  Uint32 len);
1567  bool receivedAllINDXATTRINFO(TcIndexOperation* indexOp);
1568  bool saveTRANSID_AI(Signal* signal,
1569  TcIndexOperation* indexOp,
1570  const Uint32 *src,
1571  Uint32 len);
1572  bool receivedAllTRANSID_AI(TcIndexOperation* indexOp);
1573  void readIndexTable(Signal* signal,
1574  ApiConnectRecord* regApiPtr,
1575  TcIndexOperation* indexOp);
1576  void executeIndexOperation(Signal* signal,
1577  ApiConnectRecord* regApiPtr,
1578  TcIndexOperation* indexOp);
1579  bool seizeIndexOperation(ApiConnectRecord* regApiPtr,
1580  TcIndexOperationPtr& indexOpPtr);
1581  void releaseIndexOperation(ApiConnectRecord* regApiPtr,
1582  TcIndexOperation* indexOp);
1583  void releaseAllSeizedIndexOperations(ApiConnectRecord* regApiPtr);
1584  void setupIndexOpReturn(ApiConnectRecord* regApiPtr,
1585  TcConnectRecord* regTcPtr);
1586 
1587  void saveTriggeringOpState(Signal* signal,
1588  TcConnectRecord* trigOp);
1589  void restoreTriggeringOpState(Signal* signal,
1590  TcConnectRecord* trigOp);
1591  void trigger_op_finished(Signal* signal, ApiConnectRecordPtr,
1592  TcConnectRecord* triggeringOp);
1593  void continueTriggeringOp(Signal* signal, TcConnectRecord* trigOp);
1594 
1595  void executeTriggers(Signal* signal, ApiConnectRecordPtr* transPtr);
1596  void executeTrigger(Signal* signal,
1597  TcFiredTriggerData* firedTriggerData,
1598  ApiConnectRecordPtr* transPtr,
1599  TcConnectRecordPtr* opPtr);
1600  void executeIndexTrigger(Signal* signal,
1601  TcDefinedTriggerData* definedTriggerData,
1602  TcFiredTriggerData* firedTriggerData,
1603  ApiConnectRecordPtr* transPtr,
1604  TcConnectRecordPtr* opPtr);
1605  bool appendAttrDataToSection(Uint32& sectionIVal,
1606  DataBuffer<11>& values,
1607  bool withHeaders,
1608  Uint32& attrId,
1609  bool& hasNull);
1610  void insertIntoIndexTable(Signal* signal,
1611  TcFiredTriggerData* firedTriggerData,
1612  ApiConnectRecordPtr* transPtr,
1613  TcConnectRecordPtr* opPtr,
1614  TcIndexData* indexData);
1615  void deleteFromIndexTable(Signal* signal,
1616  TcFiredTriggerData* firedTriggerData,
1617  ApiConnectRecordPtr* transPtr,
1618  TcConnectRecordPtr* opPtr,
1619  TcIndexData* indexData);
1620 
1621  void executeReorgTrigger(Signal* signal,
1622  TcDefinedTriggerData* definedTriggerData,
1623  TcFiredTriggerData* firedTriggerData,
1624  ApiConnectRecordPtr* transPtr,
1625  TcConnectRecordPtr* opPtr);
1626 
1627  void releaseFiredTriggerData(DLFifoList<TcFiredTriggerData>* triggers);
1628  void abortTransFromTrigger(Signal* signal, const ApiConnectRecordPtr& transPtr,
1629  Uint32 error);
1630  // Generated statement blocks
1631  void warningHandlerLab(Signal* signal, int line);
1632  void systemErrorLab(Signal* signal, int line);
1633  void sendSignalErrorRefuseLab(Signal* signal);
1634  void scanTabRefLab(Signal* signal, Uint32 errCode);
1635  void diFcountReqLab(Signal* signal, ScanRecordPtr);
1636  void signalErrorRefuseLab(Signal* signal);
1637  void abort080Lab(Signal* signal);
1638  void sendKeyInfoTrain(Signal* signal,
1639  BlockReference TBRef,
1640  Uint32 connectPtr,
1641  Uint32 offset,
1642  Uint32 keyInfoIVal);
1643  void abortScanLab(Signal* signal, ScanRecordPtr, Uint32 errCode,
1644  bool not_started = false);
1645  void sendAbortedAfterTimeout(Signal* signal, int Tcheck);
1646  void abort010Lab(Signal* signal);
1647  void abort015Lab(Signal* signal);
1648  void packLqhkeyreq(Signal* signal,
1649  BlockReference TBRef);
1650  void packLqhkeyreq040Lab(Signal* signal,
1651  BlockReference TBRef);
1652  void returnFromQueuedDeliveryLab(Signal* signal);
1653  void startTakeOverLab(Signal* signal);
1654  void toCompleteHandlingLab(Signal* signal);
1655  void toCommitHandlingLab(Signal* signal);
1656  void toAbortHandlingLab(Signal* signal);
1657  void abortErrorLab(Signal* signal);
1658  void nodeTakeOverCompletedLab(Signal* signal);
1659  void ndbsttorry010Lab(Signal* signal);
1660  void commit020Lab(Signal* signal);
1661  void complete010Lab(Signal* signal);
1662  void releaseAtErrorLab(Signal* signal);
1663  void seizeDatabuferrorLab(Signal* signal);
1664  void appendToSectionErrorLab(Signal* signal);
1665  void scanKeyinfoLab(Signal* signal);
1666  void scanAttrinfoLab(Signal* signal, UintR Tlen);
1667  void attrinfoDihReceivedLab(Signal* signal);
1668  void aiErrorLab(Signal* signal);
1669  void scanReleaseResourcesLab(Signal* signal);
1670  void scanCompletedLab(Signal* signal);
1671  void scanError(Signal* signal, ScanRecordPtr, Uint32 errorCode);
1672  void diverify010Lab(Signal* signal);
1673  void intstartphase3x010Lab(Signal* signal);
1674  void sttorryLab(Signal* signal);
1675  void abortBeginErrorLab(Signal* signal);
1676  void tabStateErrorLab(Signal* signal);
1677  void wrongSchemaVersionErrorLab(Signal* signal);
1678  void noFreeConnectionErrorLab(Signal* signal);
1679  void tckeyreq050Lab(Signal* signal);
1680  void timeOutFoundLab(Signal* signal, UintR anAdd, Uint32 errCode);
1681  void completeTransAtTakeOverLab(Signal* signal, UintR TtakeOverInd);
1682  void completeTransAtTakeOverDoLast(Signal* signal, UintR TtakeOverInd);
1683  void completeTransAtTakeOverDoOne(Signal* signal, UintR TtakeOverInd);
1684  void timeOutLoopStartLab(Signal* signal, Uint32 apiConnectPtr);
1685  void initialiseRecordsLab(Signal* signal, UintR Tdata0, Uint32, Uint32);
1686  void tckeyreq020Lab(Signal* signal);
1687  void intstartphase1x010Lab(Signal* signal);
1688  void startphase1x010Lab(Signal* signal);
1689 
1690  void lqhKeyConf_checkTransactionState(Signal * signal,
1691  Ptr<ApiConnectRecord> regApiPtr);
1692 
1693  void checkDropTab(Signal* signal);
1694 
1695  void checkScanActiveInFailedLqh(Signal* signal,
1696  Uint32 scanPtrI,
1697  Uint32 failedNodeId);
1698  void checkScanFragList(Signal*, Uint32 failedNodeId, ScanRecord * scanP,
1700 
1701  void nodeFailCheckTransactions(Signal*,Uint32 transPtrI,Uint32 failedNodeId);
1702  void ndbdFailBlockCleanupCallback(Signal* signal, Uint32 failedNodeId, Uint32 ignoredRc);
1703  void checkNodeFailComplete(Signal* signal, Uint32 failedNodeId, Uint32 bit);
1704 
1705  void apiFailBlockCleanupCallback(Signal* signal, Uint32 failedNodeId, Uint32 ignoredRc);
1706  bool isRefreshSupported() const;
1707 
1708  // Initialisation
1709  void initData();
1710  void initRecords();
1711 
1712 protected:
1713  virtual bool getParam(const char* name, Uint32* count);
1714 
1715 private:
1716 
1717  // Transit signals
1718 
1719 
1720  ApiConnectRecord *apiConnectRecord;
1721  ApiConnectRecordPtr apiConnectptr;
1722  UintR capiConnectFilesize;
1723 
1724  TcConnectRecord *tcConnectRecord;
1725  TcConnectRecordPtr tcConnectptr;
1726  UintR ctcConnectFilesize;
1727 
1728  CacheRecord *cacheRecord;
1729  CacheRecordPtr cachePtr;
1730  UintR ccacheFilesize;
1731 
1732  HostRecord *hostRecord;
1733  HostRecordPtr hostptr;
1734  UintR chostFilesize;
1735  NdbNodeBitmask c_alive_nodes;
1736 
1737  Uint32 c_ongoing_take_over_cnt;
1738  GcpRecord *gcpRecord;
1739  UintR cgcpFilesize;
1740 
1741  TableRecord *tableRecord;
1742  UintR ctabrecFilesize;
1743 
1744  UintR thashValue;
1745  UintR tdistrHashValue;
1746 
1747  UintR ttransid_ptr;
1748  UintR cfailure_nr;
1749  UintR coperationsize;
1750  UintR ctcTimer;
1751  UintR cDbHbInterval;
1752 
1753  Uint64 tcheckGcpId;
1754 
1755  // Montonically increasing counters
1756  struct MonotonicCounters {
1757  Uint64 cattrinfoCount;
1758  Uint64 ctransCount;
1759  Uint64 ccommitCount;
1760  Uint64 creadCount;
1761  Uint64 csimpleReadCount;
1762  Uint64 cwriteCount;
1763  Uint64 cabortCount;
1764  Uint64 c_scan_count;
1765  Uint64 c_range_scan_count;
1766 
1767  // Resource usage counter(not monotonic)
1768  Uint32 cconcurrentOp;
1769 
1770  MonotonicCounters() :
1771  cattrinfoCount(0),
1772  ctransCount(0),
1773  ccommitCount(0),
1774  creadCount(0),
1775  csimpleReadCount(0),
1776  cwriteCount(0),
1777  cabortCount(0),
1778  c_scan_count(0),
1779  c_range_scan_count(0),
1780  cconcurrentOp(0) {}
1781 
1782  Uint32 build_event_rep(Signal* signal)
1783  {
1784  /*
1785  Read saved value from CONTINUEB, subtract from
1786  counter and write to EVENT_REP
1787  */
1788  const Uint32 attrinfoCount = diff(signal, 1, cattrinfoCount);
1789  const Uint32 transCount = diff(signal, 3, ctransCount);
1790  const Uint32 commitCount = diff(signal, 5, ccommitCount);
1791  const Uint32 readCount = diff(signal, 7, creadCount);
1792  const Uint32 simpleReadCount = diff(signal, 9, csimpleReadCount);
1793  const Uint32 writeCount = diff(signal, 11, cwriteCount);
1794  const Uint32 abortCount = diff(signal, 13, cabortCount);
1795  const Uint32 scan_count = diff(signal, 15, c_scan_count);
1796  const Uint32 range_scan_count = diff(signal, 17, c_range_scan_count);
1797 
1798  signal->theData[0] = NDB_LE_TransReportCounters;
1799  signal->theData[1] = transCount;
1800  signal->theData[2] = commitCount;
1801  signal->theData[3] = readCount;
1802  signal->theData[4] = simpleReadCount;
1803  signal->theData[5] = writeCount;
1804  signal->theData[6] = attrinfoCount;
1805  signal->theData[7] = cconcurrentOp; // Exception that confirms the rule!
1806  signal->theData[8] = abortCount;
1807  signal->theData[9] = scan_count;
1808  signal->theData[10] = range_scan_count;
1809  return 11;
1810  }
1811 
1812  Uint32 build_continueB(Signal* signal) const
1813  {
1814  /* Save current value of counters to CONTINUEB */
1815  const Uint64* vars[] = {
1816  &cattrinfoCount, &ctransCount, &ccommitCount,
1817  &creadCount, &csimpleReadCount, &cwriteCount,
1818  &cabortCount, &c_scan_count, &c_range_scan_count };
1819  const size_t num = sizeof(vars)/sizeof(vars[0]);
1820 
1821  for (size_t i = 0; i < num; i++)
1822  {
1823  signal->theData[1+i*2] = Uint32(*vars[i] >> 32);
1824  signal->theData[1+i*2+1] = Uint32(*vars[i]);
1825  }
1826  return 1 + num * 2;
1827  }
1828  private:
1829  Uint32 diff(Signal* signal, size_t pos, Uint64 curr) const
1830  {
1831  const Uint64 old =
1832  (signal->theData[pos+1] | (Uint64(signal->theData[pos]) << 32));
1833  return (Uint32)(curr - old);
1834  }
1835  } c_counters;
1836 
1837  Uint16 cownNodeid;
1838  Uint16 terrorCode;
1839 
1840  UintR cfirstfreeTcConnect;
1841  UintR cfirstfreeApiConnectCopy;
1842  UintR cfirstfreeCacheRec;
1843 
1844  UintR cfirstgcp;
1845  UintR clastgcp;
1846  UintR cfirstfreeGcp;
1847  UintR cfirstfreeScanrec;
1848 
1849  TableRecordPtr tabptr;
1850  UintR cfirstfreeApiConnectFail;
1851  UintR cfirstfreeApiConnect;
1852 
1853  BlockReference cdihblockref;
1854  BlockReference cownref; /* OWN BLOCK REFERENCE */
1855 
1856  ApiConnectRecordPtr timeOutptr;
1857 
1858  ScanRecord *scanRecord;
1859  UintR cscanrecFileSize;
1860 
1861  UnsafeArrayPool<ScanFragRec> c_scan_frag_pool;
1862  ScanFragRecPtr scanFragptr;
1863 
1864  UintR cscanFragrecFileSize;
1865 
1866  BlockReference cdictblockref;
1867  BlockReference cerrorBlockref;
1868  BlockReference clqhblockref;
1869  BlockReference cndbcntrblockref;
1870 
1871  Uint16 csignalKey;
1872  Uint16 csystemnodes;
1873  Uint16 cnodes[4];
1874  NodeId cmasterNodeId;
1875  UintR cnoParallelTakeOver;
1876  TimeOutCheckState ctimeOutCheckFragActive;
1877 
1878  UintR ctimeOutCheckFragCounter;
1879  UintR ctimeOutCheckCounter;
1880  UintR ctimeOutValue;
1881  UintR ctimeOutCheckDelay;
1882  Uint32 ctimeOutCheckHeartbeat;
1883  Uint32 ctimeOutCheckLastHeartbeat;
1884  Uint32 ctimeOutMissedHeartbeats;
1885  Uint32 c_appl_timeout_value;
1886 
1887  SystemStartState csystemStart;
1888  TimeOutCheckState ctimeOutCheckActive;
1889 
1890  BlockReference capiFailRef;
1891  UintR cpackedListIndex;
1892  Uint16 cpackedList[MAX_NODES];
1893  UintR capiConnectClosing[MAX_NODES];
1894  UintR con_lineNodes;
1895 
1896  UintR treqinfo;
1897  UintR ttransid1;
1898  UintR ttransid2;
1899 
1900  UintR tabortInd;
1901 
1902  NodeId tnodeid;
1903  BlockReference tblockref;
1904 
1905  LqhTransConf::OperationStatus ttransStatus;
1906  UintR ttcOprec;
1907  NodeId tfailedNodeId;
1908  Uint8 tcurrentReplicaNo;
1909  Uint8 tpad1;
1910 
1911  Uint64 tgci;
1912  UintR tapplRef;
1913  UintR tapplOprec;
1914 
1915  UintR tindex;
1916  UintR tmaxData;
1917  UintR tmp;
1918 
1919  UintR tnodes;
1920  BlockReference tusersblkref;
1921  UintR tuserpointer;
1922  UintR tloadCode;
1923 
1924  UintR tconfig1;
1925  UintR tconfig2;
1926 
1927  UintR cdata[32];
1928  UintR ctransidFailHash[512];
1929  UintR ctcConnectFailHash[1024];
1930 
1934 public:
1936  CommitAckMarker() {}
1937  Uint32 transid1;
1938  Uint32 transid2;
1939  union { Uint32 nextPool; Uint32 nextHash; };
1940  Uint32 prevHash;
1941  Uint32 apiConnectPtr;
1942  Uint16 apiNodeId;
1943  NdbNodeBitmask m_commit_ack_marker_nodes;
1944 
1945  inline bool equal(const CommitAckMarker & p) const {
1946  return ((p.transid1 == transid1) && (p.transid2 == transid2));
1947  }
1948 
1949  inline Uint32 hashValue() const {
1950  return transid1;
1951  }
1952  };
1953 
1954 private:
1956  typedef DLHashTable<CommitAckMarker>::Iterator CommitAckMarkerIterator;
1957 
1958  ArrayPool<CommitAckMarker> m_commitAckMarkerPool;
1959  DLHashTable<CommitAckMarker> m_commitAckMarkerHash;
1960 
1961  void execTC_COMMIT_ACK(Signal* signal);
1962  void sendRemoveMarkers(Signal*, const CommitAckMarker *);
1963  void sendRemoveMarker(Signal* signal,
1964  NodeId nodeId,
1965  Uint32 transid1,
1966  Uint32 transid2);
1967  void removeMarkerForFailedAPI(Signal* signal, Uint32 nodeId, Uint32 bucket);
1968 
1969  bool getAllowStartTransaction(Uint32 nodeId, Uint32 table_single_user_mode) const {
1970  if (unlikely(getNodeState().getSingleUserMode()))
1971  {
1972  if (getNodeState().getSingleUserApi() == nodeId || table_single_user_mode)
1973  return true;
1974  else
1975  return false;
1976  }
1978  }
1979 
1980  void checkAbortAllTimeout(Signal* signal, Uint32 sleepTime);
1981  struct AbortAllRecord {
1982  AbortAllRecord(){ clientRef = 0; }
1983  Uint32 clientData;
1984  BlockReference clientRef;
1985 
1986  Uint32 oldTimeOutValue;
1987  };
1988  AbortAllRecord c_abortRec;
1989 
1990  bool validate_filter(Signal*);
1991  bool match_and_print(Signal*, ApiConnectRecordPtr);
1992 
1993 #ifdef ERROR_INSERT
1994  bool testFragmentDrop(Signal* signal);
1995 #endif
1996 
1997  /************************** API CONNECT RECORD ***********************/
1998  /* *******************************************************************/
1999  /* THE API CONNECT RECORD CONTAINS THE CONNECTION RECORD TO WHICH THE*/
2000  /* APPLICATION CONNECTS. THE APPLICATION CAN SEND ONE OPERATION AT A */
2001  /* TIME. IT CAN SEND A NEW OPERATION IMMEDIATELY AFTER SENDING THE */
2002  /* PREVIOUS OPERATION. THEREBY SEVERAL OPERATIONS CAN BE ACTIVE IN */
2003  /* ONE TRANSACTION WITHIN TC. THIS IS ACHIEVED BY USING THE API */
2004  /* CONNECT RECORD. EACH ACTIVE OPERATION IS HANDLED BY THE TC */
2005  /* CONNECT RECORD. AS SOON AS THE TC CONNECT RECORD HAS SENT THE */
2006  /* REQUEST TO THE LQH IT IS READY TO RECEIVE NEW OPERATIONS. THE */
2007  /* LQH CONNECT RECORD TAKES CARE OF WAITING FOR AN OPERATION TO */
2008  /* COMPLETE. WHEN AN OPERATION HAS COMPLETED ON THE LQH CONNECT */
2009  /* RECORD A NEW OPERATION CAN BE STARTED ON THIS LQH CONNECT RECORD. */
2010  /*******************************************************************>*/
2011  /* */
2012  /* API CONNECT RECORD ALIGNED TO BE 256 BYTES */
2013  /*******************************************************************>*/
2014  /************************** TC CONNECT RECORD ************************/
2015  /* *******************************************************************/
2016  /* TC CONNECT RECORD KEEPS ALL INFORMATION TO CARRY OUT A TRANSACTION*/
2017  /* THE TRANSACTION CONTROLLER ESTABLISHES CONNECTIONS TO DIFFERENT */
2018  /* BLOCKS TO CARRY OUT THE TRANSACTION. THERE CAN BE SEVERAL RECORDS */
2019  /* PER ACTIVE TRANSACTION. THE TC CONNECT RECORD COOPERATES WITH THE */
2020  /* API CONNECT RECORD FOR COMMUNICATION WITH THE API AND WITH THE */
2021  /* LQH CONNECT RECORD FOR COMMUNICATION WITH THE LQH'S INVOLVED IN */
2022  /* THE TRANSACTION. TC CONNECT RECORD IS PERMANENTLY CONNECTED TO A */
2023  /* RECORD IN DICT AND ONE IN DIH. IT CONTAINS A LIST OF ACTIVE LQH */
2024  /* CONNECT RECORDS AND A LIST OF STARTED BUT NOT ACTIVE LQH CONNECT */
2025  /* RECORDS. IT DOES ALSO CONTAIN A LIST OF ALL OPERATIONS THAT ARE */
2026  /* EXECUTED WITH THE TC CONNECT RECORD. */
2027  /*******************************************************************>*/
2028  /* TC_CONNECT RECORD ALIGNED TO BE 128 BYTES */
2029  /*******************************************************************>*/
2030  UintR cfirstfreeTcConnectFail;
2031 
2032  /* POINTER FOR THE LQH RECORD*/
2033  /* ************************ HOST RECORD ********************************* */
2034  /********************************************************/
2035  /* THIS RECORD CONTAINS ALIVE-STATUS ON ALL NODES IN THE*/
2036  /* SYSTEM */
2037  /********************************************************/
2038  /* THIS RECORD IS ALIGNED TO BE 8 BYTES. */
2039  /********************************************************/
2040  /* ************************ TABLE RECORD ******************************** */
2041  /********************************************************/
2042  /* THIS RECORD CONTAINS THE CURRENT SCHEMA VERSION OF */
2043  /* ALL TABLES IN THE SYSTEM. */
2044  /********************************************************/
2045  /*-------------------------------------------------------------------------*/
2046  /* THE TC CONNECTION USED BY THIS SCAN. */
2047  /*-------------------------------------------------------------------------*/
2048  /*-------------------------------------------------------------------------*/
2049  /* LENGTH READ FOR A PARTICULAR SCANNED OPERATION. */
2050  /*-------------------------------------------------------------------------*/
2051  /*-------------------------------------------------------------------------*/
2052  /* REFERENCE TO THE SCAN RECORD FOR THIS SCAN PROCESS. */
2053  /*-------------------------------------------------------------------------*/
2054  /* *********************************************************************** */
2055  /* ******$ DATA BUFFER ******$ */
2056  /* */
2057  /* THIS BUFFER IS USED AS A GENERAL DATA STORAGE. */
2058  /* *********************************************************************** */
2059  /* *********************************************************************** */
2060  /* ******$ ATTRIBUTE INFORMATION RECORD ******$ */
2061  /*
2062  CAN CONTAIN ONE (1) ATTRINFO SIGNAL. ONE SIGNAL CONTAINS 24 ATTR.
2063  INFO WORDS. BUT 32 ELEMENTS ARE USED TO MAKE PLEX HAPPY.
2064  SOME OF THE ELEMENTS ARE USED TO THE FOLLOWING THINGS:
2065  DATA LENGHT IN THIS RECORD IS STORED IN THE ELEMENT INDEXED BY
2066  ZINBUF_DATA_LEN.
2067  NEXT FREE ATTRBUF IS POINTED OUT BY THE ELEMENT INDEXED BY
2068  PREVIOUS ATTRBUF IS POINTED OUT BY THE ELEMENT INDEXED BY ZINBUF_PREV
2069  (NOT USED YET).
2070  NEXT ATTRBUF IS POINTED OUT BY THE ELEMENT INDEXED BY ZINBUF_NEXT.
2071  */
2072  /* ********************************************************************** */
2073  /**************************************************************************/
2074  /* GLOBAL CHECKPOINT INFORMATION RECORD */
2075  /* */
2076  /* THIS RECORD IS USED TO STORE THE GCP NUMBER AND A COUNTER */
2077  /* DURING THE COMPLETION PHASE OF THE TRANSACTION */
2078  /**************************************************************************/
2079  /* */
2080  /* GCP RECORD ALIGNED TO BE 32 BYTES */
2081  /**************************************************************************/
2082  /**************************************************************************/
2083  /* TC_FAIL_RECORD */
2084  /* THIS RECORD IS USED WHEN HANDLING TAKE OVER OF ANOTHER FAILED TC NODE.*/
2085  /**************************************************************************/
2086  TcFailRecord *tcFailRecord;
2087  TcFailRecordPtr tcNodeFailptr;
2088  /**************************************************************************/
2089  // Temporary variables that are not allowed to use for storage between
2090  // signals. They
2091  // can only be used in a signal to transfer values between subroutines.
2092  // In the long run
2093  // those variables should be removed and exchanged for stack
2094  // variable communication.
2095  /**************************************************************************/
2096 
2097  Uint32 c_gcp_ref;
2098  Uint32 c_gcp_data;
2099 
2100  Uint32 c_sttor_ref;
2101 
2102 #ifdef ERROR_INSERT
2103  // Used with ERROR_INSERT 8078 + 8079 to check API_FAILREQ handling
2104  Uint32 c_lastFailedApi;
2105 #endif
2106  Uint32 m_deferred_enabled;
2107  Uint32 m_max_writes_per_trans;
2108 };
2109 
2110 #endif