MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Dbdih.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 DBDIH_H
19 #define DBDIH_H
20 
21 #include <ndb_limits.h>
22 #include <pc.hpp>
23 #include <SimulatedBlock.hpp>
24 #include "Sysfile.hpp"
25 #include <SignalCounter.hpp>
26 
27 #include <signaldata/MasterLCP.hpp>
28 #include <signaldata/CopyGCIReq.hpp>
29 #include <blocks/mutexes.hpp>
30 #include <signaldata/LCP.hpp>
31 #include <NdbSeqLock.hpp>
32 
33 #ifdef DBDIH_C
34 
35 /*###################*/
36 /* FILE SYSTEM FLAGS */
37 /*###################*/
38 #define ZLIST_OF_PAIRS 0
39 #define ZLIST_OF_PAIRS_SYNCH 16
40 #define ZOPEN_READ_WRITE 2
41 #define ZCREATE_READ_WRITE 0x302
42 #define ZCLOSE_NO_DELETE 0
43 #define ZCLOSE_DELETE 1
44 
45 /*###############*/
46 /* NODE STATES */
47 /*###############*/
48 #define ZIDLE 0
49 #define ZACTIVE 1
50 
51 /*#########*/
52 /* GENERAL */
53 /*#########*/
54 #define ZVAR_NO_WORD 1
55 #define ZVAR_NO_CRESTART_INFO 20
56 #define ZVAR_NO_CRESTART_INFO_TO_FILE 21
57 #define ZVALID 1
58 #define ZINVALID 2
59 
60 /*###############*/
61 /* ERROR CODES */
62 /*###############*/
63 // ------------------------------------------
64 // Error Codes for Transactions (None sofar)
65 // ------------------------------------------
66 #define ZUNDEFINED_FRAGMENT_ERROR 311
67 
68 // --------------------------------------
69 // Error Codes for Add Table
70 // --------------------------------------
71 #define ZREPLERROR1 306
72 #define ZREPLERROR2 307
73 
74 // --------------------------------------
75 // Crash Codes
76 // --------------------------------------
77 #define ZCOULD_NOT_OCCUR_ERROR 300
78 #define ZNOT_MASTER_ERROR 301
79 #define ZWRONG_FAILURE_NUMBER_ERROR 302
80 #define ZWRONG_START_NODE_ERROR 303
81 #define ZNO_REPLICA_FOUND_ERROR 304
82 
83 // --------------------------------------
84 // Codes from LQH
85 // --------------------------------------
86 #define ZNODE_FAILURE_ERROR 400
87 
88 
89 /*#########*/
90 /* PHASES */
91 /*#########*/
92 #define ZNDB_SPH1 1
93 #define ZNDB_SPH2 2
94 #define ZNDB_SPH3 3
95 #define ZNDB_SPH4 4
96 #define ZNDB_SPH5 5
97 #define ZNDB_SPH6 6
98 #define ZNDB_SPH7 7
99 #define ZNDB_SPH8 8
100 /*#########*/
101 /* SIZES */
102 /*#########*/
103 #define ZPAGEREC 100
104 #define ZCREATE_REPLICA_FILE_SIZE 4
105 #define ZPROXY_MASTER_FILE_SIZE 10
106 #define ZPROXY_FILE_SIZE 10
107 #endif
108 
109 class Dbdih: public SimulatedBlock {
110 #ifdef ERROR_INSERT
111  typedef void (Dbdih::* SendFunction)(Signal*, Uint32, Uint32);
112 #endif
113 public:
114 
115  // Records
116 
117  /*いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい
118  * THE API CONNECT RECORD IS THE SAME RECORD POINTER AS USED IN THE TC BLOCK
119  *
120  * IT KEEPS TRACK OF ALL THE OPERATIONS CONNECTED TO THIS TRANSACTION.
121  * IT IS LINKED INTO A QUEUE IN CASE THE GLOBAL CHECKPOINT IS CURRENTLY
122  * ONGOING */
124  Uint64 apiGci;
125  Uint32 senderData;
126  };
128 
129  /*############## CONNECT_RECORD ##############*/
130  /*いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい*/
131  /* THE CONNECT RECORD IS CREATED WHEN A TRANSACTION HAS TO START. IT KEEPS
132  ALL INTERMEDIATE INFORMATION NECESSARY FOR THE TRANSACTION FROM THE
133  DISTRIBUTED MANAGER. THE RECORD KEEPS INFORMATION ABOUT THE
134  OPERATIONS THAT HAVE TO BE CARRIED OUT BY THE TRANSACTION AND
135  ALSO THE TRAIL OF NODES FOR EACH OPERATION IN THE THE
136  TRANSACTION.
137  */
138  struct ConnectRecord {
139  enum ConnectState {
140  INUSE = 0,
141  FREE = 1,
142  STARTED = 2,
143  ALTER_TABLE = 3,
144  ALTER_TABLE_ABORT = 4, // "local" abort
145  ALTER_TABLE_REVERT = 5,
146  GET_TABINFO = 6
147  };
148  union {
149  Uint32 nodes[MAX_REPLICAS];
150  struct {
151  Uint32 m_changeMask;
152  Uint32 m_totalfragments;
153  Uint32 m_org_totalfragments;
154  Uint32 m_new_map_ptr_i;
155  } m_alter;
156  struct {
157  Uint32 m_map_ptr_i;
158  } m_create;
159  struct {
160  Uint32 m_requestInfo;
161  } m_get_tabinfo;
162  };
163  ConnectState connectState;
164  Uint32 nextPool;
165  Uint32 table;
166  Uint32 userpointer;
167  BlockReference userblockref;
168  Callback m_callback;
169  };
171 
172  /*いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい*/
173  /* THESE RECORDS ARE USED WHEN CREATING REPLICAS DURING SYSTEM */
174  /* RESTART. I NEED A COMPLEX DATA STRUCTURE DESCRIBING THE REPLICAS */
175  /* I WILL TRY TO CREATE FOR EACH FRAGMENT. */
176  /* */
177  /* I STORE A REFERENCE TO THE FOUR POSSIBLE CREATE REPLICA RECORDS */
178  /* IN A COMMON STORED VARIABLE. I ALLOW A MAXIMUM OF 4 REPLICAS TO */
179  /* BE RESTARTED PER FRAGMENT. */
180  /*いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい*/
182  Uint32 logStartGci[MAX_LOG_EXEC];
183  Uint32 logStopGci[MAX_LOG_EXEC];
184  Uint16 logNodeId[MAX_LOG_EXEC];
185  Uint32 createLcpId;
186 
187  Uint32 replicaRec;
188  Uint16 dataNodeId;
189  Uint16 lcpNo;
190  Uint16 noLogNodes;
191  };
193 
194  /*いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい*/
195  /* THIS RECORD CONTAINS A FILE DESCRIPTION. THERE ARE TWO */
196  /* FILES PER TABLE TO RAISE SECURITY LEVEL AGAINST DISK CRASHES. */
197  /*いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい*/
198  struct FileRecord {
199  enum FileStatus {
200  CLOSED = 0,
201  CRASHED = 1,
202  OPEN = 2
203  };
204  enum FileType {
205  TABLE_FILE = 0,
206  GCP_FILE = 1
207  };
208  enum ReqStatus {
209  IDLE = 0,
210  CREATING_GCP = 1,
211  OPENING_GCP = 2,
212  OPENING_COPY_GCI = 3,
213  WRITING_COPY_GCI = 4,
214  CREATING_COPY_GCI = 5,
215  OPENING_TABLE = 6,
216  READING_GCP = 7,
217  READING_TABLE = 8,
218  WRITE_INIT_GCP = 9,
219  TABLE_CREATE = 10,
220  TABLE_WRITE = 11,
221  TABLE_CLOSE = 12,
222  CLOSING_GCP = 13,
223  CLOSING_TABLE_CRASH = 14,
224  CLOSING_TABLE_SR = 15,
225  CLOSING_GCP_CRASH = 16,
226  TABLE_OPEN_FOR_DELETE = 17,
227  TABLE_CLOSE_DELETE = 18
228  };
229  Uint32 fileName[4];
230  Uint32 fileRef;
231  FileStatus fileStatus;
232  FileType fileType;
233  Uint32 nextFile;
234  ReqStatus reqStatus;
235  Uint32 tabRef;
236  };
238 
239  /*いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい*/
240  /* THIS RECORD KEEPS THE STORAGE AND DECISIONS INFORMATION OF A FRAGMENT */
241  /* AND ITS REPLICAS. IF FRAGMENT HAS MORE THAN ONE BACK UP */
242  /* REPLICA THEN A LIST OF MORE NODES IS ATTACHED TO THIS RECORD. */
243  /* EACH RECORD IN MORE LIST HAS INFORMATION ABOUT ONE BACKUP. THIS RECORD */
244  /* ALSO HAVE THE STATUS OF THE FRAGMENT. */
245  /*いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい*/
246  /* */
247  /* FRAGMENTSTORE RECORD ALIGNED TO BE 64 BYTES */
248  /*いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい*/
249  struct Fragmentstore {
250  Uint16 activeNodes[MAX_REPLICAS];
251  Uint32 preferredPrimary;
252 
253  Uint32 oldStoredReplicas; /* "DEAD" STORED REPLICAS */
254  Uint32 storedReplicas; /* "ALIVE" STORED REPLICAS */
255  Uint32 nextFragmentChunk;
256 
257  Uint32 m_log_part_id;
258 
259  Uint8 distributionKey;
260  Uint8 fragReplicas;
261  Uint8 noOldStoredReplicas; /* NUMBER OF "DEAD" STORED REPLICAS */
262  Uint8 noStoredReplicas; /* NUMBER OF "ALIVE" STORED REPLICAS*/
264  };
266 
267  /*########### PAGE RECORD ############*/
268  /*いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい*/
269  /* THIS RECORD KEEPS INFORMATION ABOUT NODE GROUPS. */
270  /*いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい*/
272  Uint32 nodesInGroup[MAX_REPLICAS + 1];
273  Uint32 nextReplicaNode;
274  Uint32 nodeCount;
275  Uint32 activeTakeOver; // Which node...
276  Uint32 m_next_log_part;
277  Uint32 nodegroupIndex;
278  Uint32 m_ref_count;
279  };
281  /*いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい*/
282  /* THIS RECORD KEEPS INFORMATION ABOUT NODES. */
283  /*いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい*/
284  /* RECORD ALIGNED TO BE 64 BYTES. */
285  /*いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい*/
286  enum NodefailHandlingStep {
287  NF_REMOVE_NODE_FROM_TABLE = 1,
288  NF_GCP_TAKE_OVER = 2,
289  NF_LCP_TAKE_OVER = 4
290  };
291 
292  struct NodeRecord {
293  NodeRecord();
294 
295  enum NodeStatus {
296  NOT_IN_CLUSTER = 0,
297  ALIVE = 1,
298  STARTING = 2,
299  DIED_NOW = 3,
300  DYING = 4,
301  DEAD = 5
302  };
303 
305  Uint32 tableId;
306  Uint32 fragId;
307  Uint32 replicaPtr;
308  };
309 
310  Sysfile::ActiveStatus activeStatus;
311 
312  NodeStatus nodeStatus;
313  bool useInTransactions;
314  bool allowNodeStart;
315  bool m_inclDihLcp;
316  Uint8 copyCompleted; // 0 = NO :-), 1 = YES, 2 = yes, first WAITING
317 
318  FragmentCheckpointInfo startedChkpt[2];
319  FragmentCheckpointInfo queuedChkpt[2];
320 
321  Bitmask<1> m_nodefailSteps;
322  Uint32 activeTabptr;
323  Uint32 nextNode;
324  Uint32 nodeGroup;
325 
326  SignalCounter m_NF_COMPLETE_REP;
327 
328  Uint8 dbtcFailCompleted;
329  Uint8 dblqhFailCompleted;
330  Uint8 dbdihFailCompleted;
331  Uint8 dbdictFailCompleted;
332  Uint8 recNODE_FAILREP;
333 
334  Uint8 noOfQueuedChkpt;
335  Uint8 noOfStartedChkpt;
336 
337  MasterLCPConf::State lcpStateAtTakeOver;
338  Uint32 m_remove_node_from_table_lcp_id;
339  };
341  /**********************************************************************/
342  /* THIS RECORD KEEPS THE INFORMATION ABOUT A TABLE AND ITS FRAGMENTS */
343  /**********************************************************************/
344  struct PageRecord {
345  Uint32 word[2048];
346  /* 8 KBYTE PAGE*/
347  Uint32 nextfreepage;
348  };
350 
351  /************ REPLICA RECORD *************/
352  /**********************************************************************/
353  /* THIS RECORD KEEPS THE INFORMATION ABOUT A REPLICA OF A FRAGMENT */
354  /**********************************************************************/
355  struct ReplicaRecord {
356  /* -------------------------------------------------------------------- */
357  /* THE GLOBAL CHECKPOINT IDENTITY WHEN THIS REPLICA WAS CREATED. */
358  /* THERE IS ONE INDEX PER REPLICA. A REPLICA INDEX IS CREATED WHEN ANODE*/
359  /* CRASH OCCURS. */
360  /* -------------------------------------------------------------------- */
361  Uint32 createGci[8];
362  /* -------------------------------------------------------------------- */
363  /* THE LAST GLOBAL CHECKPOINT IDENTITY WHICH HAS BEEN SAVED ON DISK. */
364  /* THIS VARIABLE IS ONLY VALID FOR REPLICAS WHICH HAVE "DIED". A REPLICA*/
365  /* "DIES" EITHER WHEN THE NODE CRASHES THAT KEPT THE REPLICA OR BY BEING*/
366  /* STOPPED IN A CONTROLLED MANNER. */
367  /* THERE IS ONE INDEX PER REPLICA. A REPLICA INDEX IS CREATED WHEN ANODE*/
368  /* CRASH OCCURS. */
369  /* -------------------------------------------------------------------- */
370  Uint32 replicaLastGci[8];
371  /* -------------------------------------------------------------------- */
372  /* THE LOCAL CHECKPOINT IDENTITY OF A LOCAL CHECKPOINT. */
373  /* -------------------------------------------------------------------- */
374  Uint32 lcpId[MAX_LCP_STORED];
375  /* -------------------------------------------------------------------- */
376  /* THIS VARIABLE KEEPS TRACK OF THE MAXIMUM GLOBAL CHECKPOINT COMPLETED */
377  /* FOR EACH OF THE LOCAL CHECKPOINTS IN THIS FRAGMENT REPLICA. */
378  /* -------------------------------------------------------------------- */
379  Uint32 maxGciCompleted[MAX_LCP_STORED];
380  /* -------------------------------------------------------------------- */
381  /* THIS VARIABLE KEEPS TRACK OF THE MINIMUM GLOBAL CHECKPOINT STARTEDFOR*/
382  /* EACH OF THE LOCAL CHECKPOINTS IN THIS FRAGMENT REPLICA. */
383  /* -------------------------------------------------------------------- */
384  Uint32 maxGciStarted[MAX_LCP_STORED];
385  /* -------------------------------------------------------------------- */
386  /* THE GLOBAL CHECKPOINT IDENTITY WHEN THE TABLE WAS CREATED. */
387  /* -------------------------------------------------------------------- */
388  Uint32 initialGci;
389 
390  /* -------------------------------------------------------------------- */
391  /* THE REFERENCE TO THE NEXT REPLICA. EITHER IT REFERS TO THE NEXT IN */
392  /* THE FREE LIST OR IT REFERS TO THE NEXT IN A LIST OF REPLICAS ON A */
393  /* FRAGMENT. */
394  /* -------------------------------------------------------------------- */
395  Uint32 nextReplica;
396 
397  /* -------------------------------------------------------------------- */
398  /* THE NODE ID WHERE THIS REPLICA IS STORED. */
399  /* -------------------------------------------------------------------- */
400  Uint16 procNode;
401 
402  /* -------------------------------------------------------------------- */
403  /* The last local checkpoint id started or queued on this replica. */
404  /* -------------------------------------------------------------------- */
405  union {
406  Uint32 lcpIdStarted; // Started or queued
407  Uint32 m_restorable_gci;
408  };
409 
410  /* -------------------------------------------------------------------- */
411  /* THIS VARIABLE SPECIFIES WHAT THE STATUS OF THE LOCAL CHECKPOINT IS.IT*/
412  /* CAN EITHER BE VALID OR INVALID. AT CREATION OF A FRAGMENT REPLICA ALL*/
413  /* LCP'S ARE INVALID. ALSO IF IF INDEX >= NO_LCP THEN THELOCALCHECKPOINT*/
414  /* IS ALWAYS INVALID. IF THE LCP BEFORE THE NEXT_LCP HAS LCP_ID THAT */
415  /* DIFFERS FROM THE LATEST LCP_ID STARTED THEN THE NEXT_LCP IS ALSO */
416  /* INVALID */
417  /* -------------------------------------------------------------------- */
418  Uint8 lcpStatus[MAX_LCP_STORED];
419 
420  /* -------------------------------------------------------------------- */
421  /* THE NEXT LOCAL CHECKPOINT TO EXECUTE IN THIS FRAGMENT REPLICA. */
422  /* -------------------------------------------------------------------- */
423  Uint8 nextLcp;
424 
425  /* -------------------------------------------------------------------- */
426  /* THE NUMBER OF CRASHED REPLICAS IN THIS REPLICAS SO FAR. */
427  /* -------------------------------------------------------------------- */
428  Uint8 noCrashedReplicas;
429 
434  };
436 
437  /*************************************************************************
438  * TAB_DESCRIPTOR IS A DESCRIPTOR OF THE LOCATION OF THE FRAGMENTS BELONGING
439  * TO THE TABLE.THE INFORMATION ABOUT FRAGMENTS OF A TABLE ARE STORED IN
440  * CHUNKS OF FRAGMENTSTORE RECORDS.
441  * THIS RECORD ALSO HAS THE NECESSARY INFORMATION TO LOCATE A FRAGMENT AND
442  * TO LOCATE A FRAGMENT AND TO TRANSLATE A KEY OF A TUPLE TO THE FRAGMENT IT
443  * BELONGS
444  */
445  struct TabRecord
446  {
447  TabRecord() { }
448 
455 
459  enum CopyStatus {
460  CS_IDLE,
461  CS_SR_PHASE1_READ_PAGES,
462  CS_SR_PHASE2_READ_TABLE,
463  CS_SR_PHASE3_COPY_TABLE,
464  CS_REMOVE_NODE,
465  CS_LCP_READ_TABLE,
466  CS_COPY_TAB_REQ,
467  CS_COPY_NODE_STATE,
468  CS_ADD_TABLE_MASTER,
469  CS_ADD_TABLE_SLAVE,
470  CS_INVALIDATE_NODE_LCP,
471  CS_ALTER_TABLE,
472  CS_COPY_TO_SAVE
473  ,CS_GET_TABINFO
474  };
478  enum UpdateState {
479  US_IDLE,
480  US_LOCAL_CHECKPOINT,
481  US_REMOVE_NODE,
482  US_COPY_TAB_REQ,
483  US_ADD_TABLE_MASTER,
484  US_ADD_TABLE_SLAVE,
485  US_INVALIDATE_NODE_LCP,
486  US_CALLBACK
487  };
488  enum TabLcpStatus {
489  TLS_ACTIVE = 1,
490  TLS_WRITING_TO_FILE = 2,
491  TLS_COMPLETED = 3
492  };
493  enum TabStatus {
494  TS_IDLE = 0,
495  TS_ACTIVE = 1,
496  TS_CREATING = 2,
497  TS_DROPPING = 3
498  };
499  enum Method {
500  LINEAR_HASH = 0,
501  NOTDEFINED = 1,
502  NORMAL_HASH = 2,
503  USER_DEFINED = 3,
504  HASH_MAP = 4
505  };
506  enum Storage {
507  ST_NOLOGGING = 0, // Table is not logged, but survives SR
508  ST_NORMAL = 1, // Normal table, logged and durable
509  ST_TEMPORARY = 2 // Table is lost after SR, not logged
510  };
511  CopyStatus tabCopyStatus;
512  UpdateState tabUpdateState;
513  TabLcpStatus tabLcpStatus;
514  TabStatus tabStatus;
515  Method method;
516  Storage tabStorage;
517 
518  Uint32 pageRef[32];
519 //-----------------------------------------------------------------------------
520 // Each entry in this array contains a reference to 16 fragment records in a
521 // row. Thus finding the correct record is very quick provided the fragment id.
522 //-----------------------------------------------------------------------------
523  Uint32 startFid[MAX_NDB_NODES * MAX_FRAG_PER_NODE / NO_OF_FRAGS_PER_CHUNK];
524 
525  Uint32 tabFile[2];
526  Uint32 connectrec;
527  union {
528  Uint32 hashpointer;
529  Uint32 m_new_map_ptr_i;
530  };
531  union {
532  Uint32 mask;
533  Uint32 m_map_ptr_i;
534  };
535  Uint32 noOfWords;
536  Uint32 schemaVersion;
537  Uint32 tabRemoveNode;
538  Uint32 totalfragments;
539  Uint32 noOfFragChunks;
540  Uint32 m_scan_count[2];
541  Uint32 m_scan_reorg_flag;
542  Uint32 tabErrorCode;
543  struct {
544  Uint32 tabUserRef;
545  Uint32 tabUserPtr;
546  } m_dropTab;
547 
548  Uint8 kvalue;
549  Uint8 noOfBackups;
550  Uint8 noPages;
551  Uint16 tableType;
552  Uint16 primaryTableId;
553 
554  // set in local protocol during prepare until commit
555  Uint32 schemaTransId;
556  };
557  typedef Ptr<TabRecord> TabRecordPtr;
558 
559  /***************************************************************************/
560  /* THIS RECORD IS USED TO KEEP TRACK OF TAKE OVER AND STARTING A NODE. */
561  /* WE KEEP IT IN A RECORD TO ENABLE IT TO BE PARALLELISED IN THE FUTURE. */
562  /**************************************************************************/
563  struct TakeOverRecord {
564 
569  TO_SLAVE_IDLE = 0
570  ,TO_START_FRAGMENTS = 1 // Finding LCP for each fragment
571  ,TO_RUN_REDO = 2 // Waiting for local LQH to run REDO
572  ,TO_START_TO = 3 // Waiting for master (START_TOREQ)
573  ,TO_SELECTING_NEXT = 4 // Selecting next fragment to copy
574  ,TO_PREPARE_COPY = 5 // Waiting for local LQH (PREPARE_COPYREQ)
575  ,TO_UPDATE_BEFORE_STORED = 6 // Waiting on master (UPDATE_TOREQ)
576  ,TO_CREATE_FRAG_STORED = 7 // Waiting for all (CREATE_FRAGREQ stored)
577  ,TO_UPDATE_AFTER_STORED = 8 // Waiting for master (UPDATE_TOREQ)
578  ,TO_COPY_FRAG = 9 // Waiting for copy node (COPY_FRAGREQ)
579  ,TO_COPY_ACTIVE = 10 // Waiting for local LQH (COPY_ACTIVEREQ)
580  ,TO_UPDATE_BEFORE_COMMIT = 11// Waiting for master (UPDATE_TOREQ)
581  ,TO_CREATE_FRAG_COMMIT = 12 // Waiting for all (CREATE_FRAGREQ commit)
582  ,TO_UPDATE_AFTER_COMMIT = 13 // Waiting for master (UPDATE_TOREQ)
583 
584  ,TO_START_LOGGING = 14 // Enabling logging on all fragments
585  ,TO_SL_COPY_ACTIVE = 15 // Start logging: Copy active (local)
586  ,TO_SL_CREATE_FRAG = 16 // Start logging: Create Frag (dist)
587  ,TO_END_TO = 17 // Waiting for master (EBND_TOREQ)
588  };
589 
594  TO_MASTER_IDLE = 0
595  ,TO_MUTEX_BEFORE_STORED = 1 // Waiting for lock
596  ,TO_MUTEX_BEFORE_LOCKED = 2 // Lock held
597  ,TO_AFTER_STORED = 3 // No lock, but NGPtr reservation
598  ,TO_MUTEX_BEFORE_COMMIT = 4 // Waiting for lock
599  ,TO_MUTEX_BEFORE_SWITCH_REPLICA = 5 // Waiting for switch replica lock
600  ,TO_MUTEX_AFTER_SWITCH_REPLICA = 6
601  ,TO_WAIT_LCP = 7 // No locks, waiting for LCP
602  };
603 
604  Uint32 m_flags; //
605  Uint32 m_senderRef; // Who requested START_COPYREQ
606  Uint32 m_senderData; // Data of sender
607 
608  Uint32 restorableGci; // Which GCI can be restore "locally" by node
609  Uint32 startGci;
610  Uint32 maxPage;
611  Uint32 toCopyNode;
612  Uint32 toCurrentFragid;
613  Uint32 toCurrentReplica;
614  Uint32 toCurrentTabref;
615  Uint32 toFailedNode;
616  Uint32 toStartingNode;
617  Uint64 toStartTime;
618  ToSlaveStatus toSlaveStatus;
619  ToMasterStatus toMasterStatus;
620 
621  MutexHandle2<DIH_SWITCH_PRIMARY_MUTEX> m_switchPrimaryMutexHandle;
622  MutexHandle2<DIH_FRAGMENT_INFO> m_fragmentInfoMutex;
623 
624  Uint32 nextList;
625  union {
626  Uint32 prevList;
627  Uint32 nextPool;
628  };
629  };
630  typedef Ptr<TakeOverRecord> TakeOverRecordPtr;
631 
632  virtual bool getParam(const char * param, Uint32 * retVal) {
633  if (param && strcmp(param, "ActiveMutexes") == 0)
634  {
635  if (retVal)
636  {
637  * retVal = 5 + MAX_NDB_NODES;
638  }
639  return true;
640  }
641  return false;
642  }
643 
644 public:
645  Dbdih(Block_context& ctx);
646  virtual ~Dbdih();
647 
648  struct RWFragment {
649  Uint32 pageIndex;
650  Uint32 wordIndex;
651  Uint32 fragId;
652  TabRecordPtr rwfTabPtr;
653  PageRecordPtr rwfPageptr;
654  Uint32 totalfragments;
655  };
656  struct CopyTableNode {
657  Uint32 pageIndex;
658  Uint32 wordIndex;
659  Uint32 noOfWords;
660  TabRecordPtr ctnTabPtr;
661  PageRecordPtr ctnPageptr;
662  };
663 
664 private:
665  friend class SimulatedBlock;
666  BLOCK_DEFINES(Dbdih);
667 
668  void execDUMP_STATE_ORD(Signal *);
669  void execNDB_TAMPER(Signal *);
670  void execDEBUG_SIG(Signal *);
671  void execEMPTY_LCP_CONF(Signal *);
672  void execEMPTY_LCP_REP(Signal*);
673  void execMASTER_GCPREF(Signal *);
674  void execMASTER_GCPREQ(Signal *);
675  void execMASTER_GCPCONF(Signal *);
676  void execMASTER_LCPREF(Signal *);
677  void execMASTER_LCPREQ(Signal *);
678  void execMASTER_LCPCONF(Signal *);
679  void execNF_COMPLETEREP(Signal *);
680  void execSTART_PERMREQ(Signal *);
681  void execSTART_PERMCONF(Signal *);
682  void execSTART_PERMREF(Signal *);
683  void execINCL_NODEREQ(Signal *);
684  void execINCL_NODECONF(Signal *);
685 
686  void execSTART_TOREQ(Signal *);
687  void execSTART_TOREF(Signal *);
688  void execSTART_TOCONF(Signal*);
689 
690  void execEND_TOREQ(Signal *);
691  void execEND_TOREF(Signal *);
692  void execEND_TOCONF(Signal*);
693 
694  void execUPDATE_TOREQ(Signal* signal);
695  void execUPDATE_TOREF(Signal* signal);
696  void execUPDATE_TOCONF(Signal* signal);
697 
698  void execSTART_MEREQ(Signal *);
699  void execSTART_MECONF(Signal *);
700  void execSTART_MEREF(Signal *);
701  void execSTART_COPYREQ(Signal *);
702  void execSTART_COPYCONF(Signal *);
703  void execSTART_COPYREF(Signal *);
704  void execCREATE_FRAGREQ(Signal *);
705  void execCREATE_FRAGCONF(Signal *);
706  void execDIVERIFYREQ(Signal *);
707  void execGCP_SAVEREQ(Signal *);
708  void execGCP_SAVECONF(Signal *);
709  void execGCP_PREPARECONF(Signal *);
710  void execGCP_PREPARE(Signal *);
711  void execGCP_NODEFINISH(Signal *);
712  void execGCP_COMMIT(Signal *);
713  void execSUB_GCP_COMPLETE_REP(Signal *);
714  void execSUB_GCP_COMPLETE_ACK(Signal *);
715  void execDIHNDBTAMPER(Signal *);
716  void execCONTINUEB(Signal *);
717  void execCOPY_GCIREQ(Signal *);
718  void execCOPY_GCICONF(Signal *);
719  void execCOPY_TABREQ(Signal *);
720  void execCOPY_TABCONF(Signal *);
721  void execTCGETOPSIZECONF(Signal *);
722  void execTC_CLOPSIZECONF(Signal *);
723 
724  void execDIH_GET_TABINFO_REQ(Signal*);
725 
726  int handle_invalid_lcp_no(const struct LcpFragRep*, ReplicaRecordPtr);
727  void execLCP_FRAG_REP(Signal *);
728  void execLCP_COMPLETE_REP(Signal *);
729  void execSTART_LCP_REQ(Signal *);
730  void execSTART_LCP_CONF(Signal *);
731  MutexHandle2<DIH_START_LCP_MUTEX> c_startLcpMutexHandle;
732  void startLcpMutex_locked(Signal* signal, Uint32, Uint32);
733  void startLcpMutex_unlocked(Signal* signal, Uint32, Uint32);
734  void lcpFragmentMutex_locked(Signal* signal, Uint32, Uint32);
735  void master_lcp_fragmentMutex_locked(Signal* signal, Uint32, Uint32);
736 
737  MutexHandle2<DIH_SWITCH_PRIMARY_MUTEX> c_switchPrimaryMutexHandle;
738  void switchPrimaryMutex_locked(Signal* signal, Uint32, Uint32);
739  void switchPrimaryMutex_unlocked(Signal* signal, Uint32, Uint32);
740  void check_force_lcp(Ptr<TakeOverRecord> takeOverPtr);
741 
742  void switch_primary_stop_node(Signal* signal, Uint32, Uint32);
743 
744  void updateToReq_fragmentMutex_locked(Signal*, Uint32, Uint32);
745 
746  MutexHandle2<DIH_FRAGMENT_INFO> c_fragmentInfoMutex_lcp;
747 
748  void execBLOCK_COMMIT_ORD(Signal *);
749  void execUNBLOCK_COMMIT_ORD(Signal *);
750 
751  void execDIH_SWITCH_REPLICA_REQ(Signal *);
752  void execDIH_SWITCH_REPLICA_REF(Signal *);
753  void execDIH_SWITCH_REPLICA_CONF(Signal *);
754 
755  void execSTOP_PERM_REQ(Signal *);
756  void execSTOP_PERM_REF(Signal *);
757  void execSTOP_PERM_CONF(Signal *);
758 
759  void execSTOP_ME_REQ(Signal *);
760  void execSTOP_ME_REF(Signal *);
761  void execSTOP_ME_CONF(Signal *);
762 
763  void execREAD_CONFIG_REQ(Signal *);
764  void execUNBLO_DICTCONF(Signal *);
765  void execCOPY_ACTIVECONF(Signal *);
766  void execTAB_COMMITREQ(Signal *);
767  void execNODE_FAILREP(Signal *);
768  void execCOPY_FRAGCONF(Signal *);
769  void execCOPY_FRAGREF(Signal *);
770  void execPREPARE_COPY_FRAG_REF(Signal*);
771  void execPREPARE_COPY_FRAG_CONF(Signal*);
772  void execDIADDTABREQ(Signal *);
773  void execDIGETNODESREQ(Signal *);
774  void execSTTOR(Signal *);
775  void execDIH_SCAN_TAB_REQ(Signal *);
776  void execDIH_SCAN_GET_NODES_REQ(Signal *);
777  void execDIH_SCAN_TAB_COMPLETE_REP(Signal*);
778  void execGCP_SAVEREF(Signal *);
779  void execGCP_TCFINISHED(Signal *);
780  void execGCP_TCFINISHED_sync_conf(Signal* signal, Uint32 cb, Uint32 err);
781  void execREAD_NODESCONF(Signal *);
782  void execNDB_STTOR(Signal *);
783  void execDICTSTARTCONF(Signal *);
784  void execNDB_STARTREQ(Signal *);
785  void execGETGCIREQ(Signal *);
786  void execDIH_RESTARTREQ(Signal *);
787  void execSTART_RECCONF(Signal *);
788  void execSTART_FRAGREF(Signal *);
789  void execSTART_FRAGCONF(Signal *);
790  void execADD_FRAGCONF(Signal *);
791  void execADD_FRAGREF(Signal *);
792  void execDROP_FRAG_REF(Signal *);
793  void execDROP_FRAG_CONF(Signal *);
794  void execFSOPENCONF(Signal *);
795  void execFSOPENREF(Signal *);
796  void execFSCLOSECONF(Signal *);
797  void execFSCLOSEREF(Signal *);
798  void execFSREADCONF(Signal *);
799  void execFSREADREF(Signal *);
800  void execFSWRITECONF(Signal *);
801  void execFSWRITEREF(Signal *);
802  void execCHECKNODEGROUPSREQ(Signal *);
803  void execSTART_INFOREQ(Signal*);
804  void execSTART_INFOREF(Signal*);
805  void execSTART_INFOCONF(Signal*);
806  void execWAIT_GCP_REQ(Signal* signal);
807  void execWAIT_GCP_REF(Signal* signal);
808  void execWAIT_GCP_CONF(Signal* signal);
809 
810  void execPREP_DROP_TAB_REQ(Signal* signal);
811  void execDROP_TAB_REQ(Signal* signal);
812 
813  void execALTER_TAB_REQ(Signal* signal);
814 
815  void execCREATE_FRAGMENTATION_REQ(Signal*);
816 
817  void waitDropTabWritingToFile(Signal *, TabRecordPtr tabPtr);
818  void checkDropTabComplete(Signal *, TabRecordPtr tabPtr);
819 
820  void execDICT_LOCK_CONF(Signal* signal);
821  void execDICT_LOCK_REF(Signal* signal);
822 
823  void execUPGRADE_PROTOCOL_ORD(Signal* signal);
824 
825  void execCREATE_NODEGROUP_IMPL_REQ(Signal*);
826  void execDROP_NODEGROUP_IMPL_REQ(Signal*);
827 
828  // Statement blocks
829 //------------------------------------
830 // Methods that send signals
831 //------------------------------------
832  void nullRoutine(Signal *, Uint32 nodeId, Uint32);
833  void sendCOPY_GCIREQ(Signal *, Uint32 nodeId, Uint32);
834  void sendDIH_SWITCH_REPLICA_REQ(Signal *, Uint32 nodeId, Uint32);
835  void sendEMPTY_LCP_REQ(Signal *, Uint32 nodeId, Uint32);
836  void sendEND_TOREQ(Signal *, Uint32 nodeId, Uint32);
837  void sendGCP_COMMIT(Signal *, Uint32 nodeId, Uint32);
838  void sendGCP_PREPARE(Signal *, Uint32 nodeId, Uint32);
839  void sendGCP_SAVEREQ(Signal *, Uint32 nodeId, Uint32);
840  void sendSUB_GCP_COMPLETE_REP(Signal*, Uint32 nodeId, Uint32);
841  void sendINCL_NODEREQ(Signal *, Uint32 nodeId, Uint32);
842  void sendMASTER_GCPREQ(Signal *, Uint32 nodeId, Uint32);
843  void sendMASTER_LCPREQ(Signal *, Uint32 nodeId, Uint32);
844  void sendMASTER_LCPCONF(Signal * signal);
845  void sendSTART_RECREQ(Signal *, Uint32 nodeId, Uint32);
846  void sendSTART_INFOREQ(Signal *, Uint32 nodeId, Uint32);
847  void sendSTART_TOREQ(Signal *, Uint32 nodeId, Uint32);
848  void sendSTOP_ME_REQ(Signal *, Uint32 nodeId, Uint32);
849  void sendTC_CLOPSIZEREQ(Signal *, Uint32 nodeId, Uint32);
850  void sendTCGETOPSIZEREQ(Signal *, Uint32 nodeId, Uint32);
851  void sendUPDATE_TOREQ(Signal *, Uint32 nodeId, Uint32);
852  void sendSTART_LCP_REQ(Signal *, Uint32 nodeId, Uint32);
853 
854  void sendLCP_FRAG_ORD(Signal*, NodeRecord::FragmentCheckpointInfo info);
855  void sendLastLCP_FRAG_ORD(Signal *);
856 
857  void sendCopyTable(Signal *, CopyTableNode* ctn,
858  BlockReference ref, Uint32 reqinfo);
859  void sendCreateFragReq(Signal *,
860  Uint32 startGci,
861  Uint32 storedType,
862  Uint32 takeOverPtr);
863  void sendDihfragreq(Signal *,
864  TabRecordPtr regTabPtr,
865  Uint32 fragId);
866 
867  void sendStartTo(Signal* signal, TakeOverRecordPtr);
868  void sendUpdateTo(Signal* signal, TakeOverRecordPtr);
869 
870  void sendStartFragreq(Signal *,
871  TabRecordPtr regTabPtr,
872  Uint32 fragId);
873  void sendAddFragreq(Signal *,
874  TabRecordPtr regTabPtr,
875  Uint32 fragId,
876  Uint32 lcpNo,
877  Uint32 param);
878 
879  void sendAddFragreq(Signal*, ConnectRecordPtr, TabRecordPtr, Uint32 fragId);
880  void addTable_closeConf(Signal* signal, Uint32 tabPtrI);
881  void resetReplicaSr(TabRecordPtr tabPtr);
882  void resetReplicaLcp(ReplicaRecord * replicaP, Uint32 stopGci);
883  void resetReplica(Ptr<ReplicaRecord>);
884 
885 //------------------------------------
886 // Methods for LCP functionality
887 //------------------------------------
888  void checkKeepGci(TabRecordPtr, Uint32, Fragmentstore*, Uint32);
889  void checkLcpStart(Signal *, Uint32 lineNo);
890  void checkStartMoreLcp(Signal *, Uint32 nodeId);
891  bool reportLcpCompletion(const struct LcpFragRep *);
892  void sendLCP_COMPLETE_REP(Signal *);
893 
894 //------------------------------------
895 // Methods for Delete Table Files
896 //------------------------------------
897  void startDeleteFile(Signal* signal, TabRecordPtr tabPtr);
898  void openTableFileForDelete(Signal* signal, Uint32 fileIndex);
899  void tableOpenLab(Signal* signal, FileRecordPtr regFilePtr);
900  void tableDeleteLab(Signal* signal, FileRecordPtr regFilePtr);
901 
902 //------------------------------------
903 // File Record specific methods
904 //------------------------------------
905  void closeFile(Signal *, FileRecordPtr regFilePtr);
906  void closeFileDelete(Signal *, FileRecordPtr regFilePtr);
907  void createFileRw(Signal *, FileRecordPtr regFilePtr);
908  void openFileRw(Signal *, FileRecordPtr regFilePtr);
909  void openFileRo(Signal *, FileRecordPtr regFilePtr);
910  void seizeFile(FileRecordPtr& regFilePtr);
911  void releaseFile(Uint32 fileIndex);
912 
913 //------------------------------------
914 // Methods called when completing file
915 // operation.
916 //------------------------------------
917  void creatingGcpLab(Signal *, FileRecordPtr regFilePtr);
918  void openingGcpLab(Signal *, FileRecordPtr regFilePtr);
919  void openingTableLab(Signal *, FileRecordPtr regFilePtr);
920  void tableCreateLab(Signal *, FileRecordPtr regFilePtr);
921  void creatingGcpErrorLab(Signal *, FileRecordPtr regFilePtr);
922  void openingCopyGciErrorLab(Signal *, FileRecordPtr regFilePtr);
923  void creatingCopyGciErrorLab(Signal *, FileRecordPtr regFilePtr);
924  void openingGcpErrorLab(Signal *, FileRecordPtr regFilePtr);
925  void openingTableErrorLab(Signal *, FileRecordPtr regFilePtr);
926  void tableCreateErrorLab(Signal *, FileRecordPtr regFilePtr);
927  void closingGcpLab(Signal *, FileRecordPtr regFilePtr);
928  void closingGcpCrashLab(Signal *, FileRecordPtr regFilePtr);
929  void closingTableCrashLab(Signal *, FileRecordPtr regFilePtr);
930  void closingTableSrLab(Signal *, FileRecordPtr regFilePtr);
931  void tableCloseLab(Signal *, FileRecordPtr regFilePtr);
932  void tableCloseErrorLab(FileRecordPtr regFilePtr);
933  void readingGcpLab(Signal *, FileRecordPtr regFilePtr);
934  void readingTableLab(Signal *, FileRecordPtr regFilePtr);
935  void readingGcpErrorLab(Signal *, FileRecordPtr regFilePtr);
936  void readingTableErrorLab(Signal *, FileRecordPtr regFilePtr);
937  void writingCopyGciLab(Signal *, FileRecordPtr regFilePtr);
938  void writeInitGcpLab(Signal *, FileRecordPtr regFilePtr);
939  void tableWriteLab(Signal *, FileRecordPtr regFilePtr);
940  void writeInitGcpErrorLab(Signal *, FileRecordPtr regFilePtr);
941 
942 
943  void checkEscalation();
944  void clearRestartInfoBits(Signal *);
945  void invalidateLcpInfoAfterSr(Signal*);
946 
947  bool isMaster();
948  bool isActiveMaster();
949 
950  void handleGcpStateInMaster(Signal *, NodeRecordPtr failedNodeptr);
951  void initRestartInfo(Signal*);
952  void initRestorableGciFiles();
953  void makeNodeGroups(Uint32 nodeArray[]);
954  void add_nodegroup(NodeGroupRecordPtr);
955  void inc_ng_refcount(Uint32 ng);
956  void dec_ng_refcount(Uint32 ng);
957 
958  void makePrnList(class ReadNodesConf * readNodes, Uint32 nodeArray[]);
959  void nodeResetStart(Signal* signal);
960  void releaseTabPages(Uint32 tableId);
961  void replication(Uint32 noOfReplicas,
962  NodeGroupRecordPtr NGPtr,
963  FragmentstorePtr regFragptr);
964  void sendDihRestartRef(Signal*);
965  void selectMasterCandidateAndSend(Signal *);
966  void setLcpActiveStatusEnd(Signal*);
967  void setLcpActiveStatusStart(Signal *);
968  void setNodeActiveStatus();
969  void setNodeGroups();
970  void setNodeInfo(Signal *);
971  void setNodeLcpActiveStatus();
972  void setNodeRestartInfoBits(Signal*);
973  void startGcp(Signal *);
974  void startGcpMonitor(Signal*);
975 
976  void readFragment(RWFragment* rf, FragmentstorePtr regFragptr);
977  Uint32 readPageWord(RWFragment* rf);
978  void readReplica(RWFragment* rf, ReplicaRecordPtr readReplicaPtr);
979  void readReplicas(RWFragment* rf, FragmentstorePtr regFragptr);
980  void readRestorableGci(Signal *, FileRecordPtr regFilePtr);
981  void readTabfile(Signal *, TabRecord* tab, FileRecordPtr regFilePtr);
982  void writeFragment(RWFragment* wf, FragmentstorePtr regFragptr);
983  void writePageWord(RWFragment* wf, Uint32 dataWord);
984  void writeReplicas(RWFragment* wf, Uint32 replicaStartIndex);
985  void writeRestorableGci(Signal *, FileRecordPtr regFilePtr);
986  void writeTabfile(Signal *, TabRecord* tab, FileRecordPtr regFilePtr);
987  void copyTabReq_complete(Signal* signal, TabRecordPtr tabPtr);
988 
989  void gcpcommitreqLab(Signal *);
990  void copyGciLab(Signal *, CopyGCIReq::CopyReason reason);
991  void storeNewLcpIdLab(Signal *);
992  void startLcpRoundLoopLab(Signal *, Uint32 startTableId, Uint32 startFragId);
993 
994  void nodeFailCompletedCheckLab(Signal*, NodeRecordPtr failedNodePtr);
995 
999  void setLocalNodefailHandling(Signal*, Uint32 failedNodeId,
1000  NodefailHandlingStep step);
1001  void checkLocalNodefailComplete(Signal*, Uint32 failedNodeId,
1002  NodefailHandlingStep step);
1003 
1004  Callback m_sendSTTORRY;
1005  void sendSTTORRY(Signal*, Uint32 senderData = 0, Uint32 retVal = 0);
1006  void ndbsttorry10Lab(Signal *, Uint32 _line);
1007  void createMutexes(Signal* signal, Uint32 no);
1008  void createMutex_done(Signal* signal, Uint32 no, Uint32 retVal);
1009  void dumpGcpStop();
1010  void crashSystemAtGcpStop(Signal *, bool);
1011  void sendFirstDictfragsreq(Signal *, TabRecordPtr regTabPtr);
1012  void addtabrefuseLab(Signal *, ConnectRecordPtr regConnectPtr, Uint32 errorCode);
1013  void GCP_SAVEhandling(Signal *, Uint32 nodeId);
1014  void packTableIntoPagesLab(Signal *, Uint32 tableId);
1015  void readPagesIntoTableLab(Signal *, Uint32 tableId);
1016  void readPagesIntoFragLab(Signal *, RWFragment* rf);
1017  void readTabDescriptionLab(Signal *, Uint32 tableId);
1018  void copyTableLab(Signal *, Uint32 tableId);
1019  void breakCopyTableLab(Signal *,
1020  TabRecordPtr regTabPtr,
1021  Uint32 nodeId);
1022  void checkAddfragCompletedLab(Signal *,
1023  TabRecordPtr regTabPtr,
1024  Uint32 fragId);
1025  void completeRestartLab(Signal *);
1026  void readTableFromPagesLab(Signal *, TabRecordPtr regTabPtr);
1027  void srPhase2ReadTableLab(Signal *, TabRecordPtr regTabPtr);
1028  void checkTcCounterLab(Signal *);
1029  void calculateKeepGciLab(Signal *, Uint32 tableId, Uint32 fragId);
1030  void tableUpdateLab(Signal *, TabRecordPtr regTabPtr);
1031  void checkLcpCompletedLab(Signal *);
1032  void initLcpLab(Signal *, Uint32 masterRef, Uint32 tableId);
1033  void startGcpLab(Signal *, Uint32 aWaitTime);
1034  void checkGcpStopLab(Signal *);
1035  void MASTER_GCPhandling(Signal *, Uint32 failedNodeId);
1036  void MASTER_LCPhandling(Signal *, Uint32 failedNodeId);
1037  void rnfTableNotReadyLab(Signal *, TabRecordPtr regTabPtr, Uint32 removeNodeId);
1038  void startLcpTakeOverLab(Signal *, Uint32 failedNodeId);
1039 
1040  void startLcpMasterTakeOver(Signal *, Uint32 failedNodeId);
1041  void startGcpMasterTakeOver(Signal *, Uint32 failedNodeId);
1042  void checkGcpOutstanding(Signal*, Uint32 failedNodeId);
1043 
1044  void checkEmptyLcpComplete(Signal *);
1045  void lcpBlockedLab(Signal *, Uint32, Uint32);
1046  void breakCheckTabCompletedLab(Signal *, TabRecordPtr regTabptr);
1047  void readGciFileLab(Signal *);
1048  void openingCopyGciSkipInitLab(Signal *, FileRecordPtr regFilePtr);
1049  void startLcpRoundLab(Signal *);
1050  void gcpBlockedLab(Signal *);
1051  void initialStartCompletedLab(Signal *);
1052  void allNodesLcpCompletedLab(Signal *);
1053  void nodeRestartPh2Lab(Signal *);
1054  void nodeRestartPh2Lab2(Signal *);
1055  void initGciFilesLab(Signal *);
1056  void dictStartConfLab(Signal *);
1057  void nodeDictStartConfLab(Signal *);
1058  void ndbStartReqLab(Signal *, BlockReference ref);
1059  void nodeRestartStartRecConfLab(Signal *);
1060  void dihCopyCompletedLab(Signal *);
1061  void release_connect(ConnectRecordPtr ptr);
1062  void copyTableNode(Signal *,
1063  CopyTableNode* ctn,
1064  NodeRecordPtr regNodePtr);
1065  void startFragment(Signal *, Uint32 tableId, Uint32 fragId);
1066  bool checkLcpAllTablesDoneInLqh(Uint32 from);
1067 
1068  void lcpStateAtNodeFailureLab(Signal *, Uint32 nodeId);
1069  void copyNodeLab(Signal *, Uint32 tableId);
1070  void copyGciReqLab(Signal *);
1071  void allLab(Signal *,
1072  ConnectRecordPtr regConnectPtr,
1073  TabRecordPtr regTabPtr);
1074  void tableCopyNodeLab(Signal *, TabRecordPtr regTabPtr);
1075 
1076  void removeNodeFromTables(Signal *, Uint32 tableId, Uint32 nodeId);
1077  void removeNodeFromTable(Signal *, Uint32 tableId, TabRecordPtr tabPtr);
1078  void removeNodeFromTablesComplete(Signal* signal, Uint32 nodeId);
1079 
1080  void packFragIntoPagesLab(Signal *, RWFragment* wf);
1081  void startNextChkpt(Signal *);
1082  void failedNodeLcpHandling(Signal*, NodeRecordPtr failedNodePtr);
1083  void failedNodeSynchHandling(Signal *, NodeRecordPtr failedNodePtr);
1084  void checkCopyTab(Signal*, NodeRecordPtr failedNodePtr);
1085 
1086  void initCommonData();
1087  void initialiseRecordsLab(Signal *, Uint32 stepNo, Uint32, Uint32);
1088 
1089  void findReplica(ReplicaRecordPtr& regReplicaPtr,
1090  Fragmentstore* fragPtrP,
1091  Uint32 nodeId,
1092  bool oldStoredReplicas = false);
1093 //------------------------------------
1094 // Node failure handling methods
1095 //------------------------------------
1096  void startRemoveFailedNode(Signal *, NodeRecordPtr failedNodePtr);
1097  void handleGcpTakeOver(Signal *, NodeRecordPtr failedNodePtr);
1098  void handleLcpTakeOver(Signal *, NodeRecordPtr failedNodePtr);
1099  void handleNewMaster(Signal *, NodeRecordPtr failedNodePtr);
1100  void handleTakeOver(Signal*, Ptr<TakeOverRecord>);
1101  void handleLcpMasterTakeOver(Signal *, Uint32 nodeId);
1102 
1103 //------------------------------------
1104 // Replica record specific methods
1105 //------------------------------------
1106  Uint32 findLogInterval(ConstPtr<ReplicaRecord> regReplicaPtr,
1107  Uint32 startGci);
1108  void findMinGci(ReplicaRecordPtr fmgReplicaPtr,
1109  Uint32& keeGci,
1110  Uint32& oldestRestorableGci);
1111  bool findStartGci(ConstPtr<ReplicaRecord> fstReplicaPtr,
1112  Uint32 tfstStopGci,
1113  Uint32& tfstStartGci,
1114  Uint32& tfstLcp);
1115  void newCrashedReplica(ReplicaRecordPtr ncrReplicaPtr);
1116  void packCrashedReplicas(ReplicaRecordPtr pcrReplicaPtr);
1117  void releaseReplicas(Uint32 * replicaPtr);
1118  void removeOldCrashedReplicas(Uint32, Uint32, ReplicaRecordPtr rocReplicaPtr);
1119  void removeTooNewCrashedReplicas(ReplicaRecordPtr rtnReplicaPtr, Uint32 lastCompletedGCI);
1120  void mergeCrashedReplicas(ReplicaRecordPtr pcrReplicaPtr);
1121  void seizeReplicaRec(ReplicaRecordPtr& replicaPtr);
1122 
1123 //------------------------------------
1124 // Methods operating on a fragment and
1125 // its connected replicas and nodes.
1126 //------------------------------------
1127  void allocStoredReplica(FragmentstorePtr regFragptr,
1128  ReplicaRecordPtr& newReplicaPtr,
1129  Uint32 nodeId);
1130  Uint32 extractNodeInfo(const Fragmentstore * fragPtr, Uint32 nodes[]);
1131  bool findBestLogNode(CreateReplicaRecord* createReplica,
1132  FragmentstorePtr regFragptr,
1133  Uint32 startGci,
1134  Uint32 stopGci,
1135  Uint32 logNode,
1136  Uint32& fblStopGci);
1137  bool findLogNodes(CreateReplicaRecord* createReplica,
1138  FragmentstorePtr regFragptr,
1139  Uint32 startGci,
1140  Uint32 stopGci);
1141  void initFragstore(FragmentstorePtr regFragptr);
1142  void insertBackup(FragmentstorePtr regFragptr, Uint32 nodeId);
1143  void insertfraginfo(FragmentstorePtr regFragptr,
1144  Uint32 noOfBackups,
1145  Uint32* nodeArray);
1146  void linkOldStoredReplica(FragmentstorePtr regFragptr,
1147  ReplicaRecordPtr replicaPtr);
1148  void linkStoredReplica(FragmentstorePtr regFragptr,
1149  ReplicaRecordPtr replicaPtr);
1150  void prepareReplicas(FragmentstorePtr regFragptr);
1151  void removeNodeFromStored(Uint32 nodeId,
1152  FragmentstorePtr regFragptr,
1153  ReplicaRecordPtr replicaPtr,
1154  bool temporary);
1155  void removeOldStoredReplica(FragmentstorePtr regFragptr,
1156  ReplicaRecordPtr replicaPtr);
1157  void removeStoredReplica(FragmentstorePtr regFragptr,
1158  ReplicaRecordPtr replicaPtr);
1159  void searchStoredReplicas(FragmentstorePtr regFragptr);
1160  bool setup_create_replica(FragmentstorePtr, CreateReplicaRecord*,
1162  void updateNodeInfo(FragmentstorePtr regFragptr);
1163 
1164 //------------------------------------
1165 // Fragment allocation, deallocation and
1166 // find methods
1167 //------------------------------------
1168  void allocFragments(Uint32 noOfFragments, TabRecordPtr regTabPtr);
1169  void releaseFragments(TabRecordPtr regTabPtr);
1170  void getFragstore(TabRecord *, Uint32 fragNo, FragmentstorePtr & ptr);
1171  void initialiseFragstore();
1172 
1173  void wait_old_scan(Signal*);
1174  Uint32 add_fragments_to_table(Ptr<TabRecord>, const Uint16 buf[]);
1175  Uint32 add_fragment_to_table(Ptr<TabRecord>, Uint32, Ptr<Fragmentstore>&);
1176 
1177  void drop_fragments(Signal*, ConnectRecordPtr, Uint32 last);
1178  void release_fragment_from_table(Ptr<TabRecord>, Uint32 fragId);
1179  void send_alter_tab_ref(Signal*, Ptr<TabRecord>,Ptr<ConnectRecord>, Uint32);
1180  void send_alter_tab_conf(Signal*, Ptr<ConnectRecord>);
1181  void alter_table_writeTable_conf(Signal* signal, Uint32 ptrI, Uint32 err);
1182  void saveTableFile(Signal*, Ptr<ConnectRecord>, Ptr<TabRecord>,
1184 
1185 //------------------------------------
1186 // Page Record specific methods
1187 //------------------------------------
1188  void allocpage(PageRecordPtr& regPagePtr);
1189  void releasePage(Uint32 pageIndex);
1190 
1191 //------------------------------------
1192 // Table Record specific methods
1193 //------------------------------------
1194  void initTable(TabRecordPtr regTabPtr);
1195  void initTableFile(TabRecordPtr regTabPtr);
1196  void releaseTable(TabRecordPtr tabPtr);
1197  bool findTakeOver(Ptr<TakeOverRecord> & ptr, Uint32 failedNodeId);
1198  void handleTakeOverMaster(Signal *, Uint32 takeOverPtr);
1199  void handleTakeOverNewMaster(Signal *, Uint32 takeOverPtr);
1200 
1201 //------------------------------------
1202 // TakeOver Record specific methods
1203 //------------------------------------
1204  void releaseTakeOver(TakeOverRecordPtr);
1205  void abortTakeOver(Signal*, TakeOverRecordPtr);
1206  bool anyActiveTakeOver();
1207  void checkToCopy();
1208  void checkToCopyCompleted(Signal *);
1209  bool checkToInterrupted(TakeOverRecordPtr& regTakeOverptr);
1210  Uint32 getStartNode(Uint32 takeOverPtr);
1211 
1212 //------------------------------------
1213 // Methods for take over functionality
1214 //------------------------------------
1215  void changeNodeGroups(Uint32 startNode, Uint32 nodeTakenOver);
1216  void endTakeOver(Uint32 takeOverPtr);
1217 
1218  void systemRestartTakeOverLab(Signal *);
1219  void startTakeOver(Signal *,
1220  Uint32 startNode,
1221  Uint32 toNode,
1222  const struct StartCopyReq*);
1223  void startNextCopyFragment(Signal *, Uint32 takeOverPtr);
1224  void toCopyFragLab(Signal *, Uint32 takeOverPtr);
1225  void toStartCopyFrag(Signal *, TakeOverRecordPtr);
1226  void startHsAddFragConfLab(Signal *);
1227  void prepareSendCreateFragReq(Signal *, Uint32 takeOverPtr);
1228  void toCopyCompletedLab(Signal *, TakeOverRecordPtr regTakeOverptr);
1229  void takeOverCompleted(Uint32 aNodeId);
1230 
1231 //------------------------------------
1232 // Node Record specific methods
1233 //------------------------------------
1234  void checkStartTakeOver(Signal *);
1235  void insertAlive(NodeRecordPtr newNodePtr);
1236  void insertDeadNode(NodeRecordPtr removeNodePtr);
1237  void removeAlive(NodeRecordPtr removeNodePtr);
1238  void removeDeadNode(NodeRecordPtr removeNodePtr);
1239 
1240  NodeRecord::NodeStatus getNodeStatus(Uint32 nodeId);
1241  void setNodeStatus(Uint32 nodeId, NodeRecord::NodeStatus);
1242  Sysfile::ActiveStatus getNodeActiveStatus(Uint32 nodeId);
1243  void setNodeActiveStatus(Uint32 nodeId, Sysfile::ActiveStatus newStatus);
1244  void setNodeLcpActiveStatus(Uint32 nodeId, bool newState);
1245  bool getNodeLcpActiveStatus(Uint32 nodeId);
1246  bool getAllowNodeStart(Uint32 nodeId);
1247  void setAllowNodeStart(Uint32 nodeId, bool newState);
1248  bool getNodeCopyCompleted(Uint32 nodeId);
1249  void setNodeCopyCompleted(Uint32 nodeId, bool newState);
1250  Uint32 getNodeGroup(Uint32 nodeId) const;
1251  bool checkNodeAlive(Uint32 nodeId);
1252 
1253  void nr_start_fragments(Signal*, TakeOverRecordPtr);
1254  void nr_start_fragment(Signal*, TakeOverRecordPtr, ReplicaRecordPtr);
1255  void nr_run_redo(Signal*, TakeOverRecordPtr);
1256  void nr_start_logging(Signal*, TakeOverRecordPtr);
1257 
1258  void getTabInfo(Signal*);
1259  void getTabInfo_send(Signal*, TabRecordPtr);
1260  void getTabInfo_sendComplete(Signal*, Uint32, Uint32);
1261  int getTabInfo_copyTableToSection(SegmentedSectionPtr & ptr, CopyTableNode);
1262  int getTabInfo_copySectionToPages(TabRecordPtr, SegmentedSectionPtr);
1263 
1264  // Initialisation
1265  void initData();
1266  void initRecords();
1267 
1268  // Variables to support record structures and their free lists
1269 
1270  Uint32 capiConnectFileSize;
1271 
1272  ConnectRecord *connectRecord;
1273  Uint32 cfirstconnect;
1274  Uint32 cconnectFileSize;
1275 
1276  CreateReplicaRecord *createReplicaRecord;
1277  Uint32 cnoOfCreateReplicas;
1278 
1279  FileRecord *fileRecord;
1280  Uint32 cfirstfreeFile;
1281  Uint32 cfileFileSize;
1282 
1283  Fragmentstore *fragmentstore;
1284  Uint32 cfirstfragstore;
1285  Uint32 cfragstoreFileSize;
1286  RSS_OP_SNAPSHOT(cremainingfrags);
1287 
1288  Uint32 c_nextNodeGroup;
1289  NodeGroupRecord *nodeGroupRecord;
1290  RSS_OP_SNAPSHOT(cnghash);
1291 
1292  NodeRecord *nodeRecord;
1293 
1294  PageRecord *pageRecord;
1295  Uint32 cfirstfreepage;
1296  Uint32 cpageFileSize;
1297 
1298  ReplicaRecord *replicaRecord;
1299  Uint32 cfirstfreeReplica;
1300  Uint32 cnoFreeReplicaRec;
1301  Uint32 creplicaFileSize;
1302  RSS_OP_SNAPSHOT(cnoFreeReplicaRec);
1303 
1304  TabRecord *tabRecord;
1305  Uint32 ctabFileSize;
1306 
1307  ArrayPool<TakeOverRecord> c_takeOverPool;
1308  DLList<TakeOverRecord> c_activeTakeOverList;
1309 
1310  /*
1311  2.4 C O M M O N S T O R E D V A R I A B L E S
1312  ----------------------------------------------------
1313  */
1314  struct DIVERIFY_queue
1315  {
1316  DIVERIFY_queue() {
1317  m_ref = 0;
1318  cfirstVerifyQueue = clastVerifyQueue = 0;
1319  apiConnectRecord = 0;
1320  m_empty_done = 1;
1321  }
1322  ApiConnectRecord *apiConnectRecord;
1323  Uint32 cfirstVerifyQueue;
1324  Uint32 clastVerifyQueue;
1325  Uint32 m_empty_done;
1326  Uint32 m_ref;
1327  };
1328 
1329  bool isEmpty(const DIVERIFY_queue&);
1330  void enqueue(DIVERIFY_queue&, Uint32 senderData, Uint64 gci);
1331  void dequeue(DIVERIFY_queue&, ApiConnectRecord &);
1332  void emptyverificbuffer(Signal *, Uint32 q, bool aContintueB);
1333  void emptyverificbuffer_check(Signal*, Uint32, Uint32);
1334 
1335  DIVERIFY_queue c_diverify_queue[MAX_NDBMT_LQH_THREADS];
1336  Uint32 c_diverify_queue_cnt;
1337 
1338  /*------------------------------------------------------------------------*/
1339  /* THIS VARIABLE KEEPS THE REFERENCES TO FILE RECORDS THAT DESCRIBE */
1340  /* THE TWO FILES THAT ARE USED TO STORE THE VARIABLE CRESTART_INFO */
1341  /* ON DISK. */
1342  /*------------------------------------------------------------------------*/
1343  Uint32 crestartInfoFile[2];
1344 
1345  bool cgckptflag; /* A FLAG WHICH IS SET WHILE A NEW GLOBAL CHECK
1346  POINT IS BEING CREATED. NO VERIFICATION IS ALLOWED
1347  IF THE FLAG IS SET*/
1348  Uint32 cgcpOrderBlocked;
1349 
1354  struct GcpSave
1355  {
1356  Uint32 m_gci;
1357  Uint32 m_master_ref;
1358  enum State {
1359  GCP_SAVE_IDLE = 0, // Idle
1360  GCP_SAVE_REQ = 1, // REQ received
1361  GCP_SAVE_CONF = 2, // REF/CONF sent
1362  GCP_SAVE_COPY_GCI = 3
1363  } m_state;
1364 
1365  struct {
1366  State m_state;
1367  Uint32 m_new_gci;
1368  Uint32 m_time_between_gcp; /* Delay between global checkpoints */
1369  Uint64 m_start_time;
1370  } m_master;
1371  } m_gcp_save;
1372 
1376  struct MicroGcp
1377  {
1378  MicroGcp() { }
1379  bool m_enabled;
1380  Uint32 m_master_ref;
1381 
1386  NdbSeqLock m_lock;
1387  Uint64 m_old_gci;
1388  Uint64 m_current_gci; // Currently active
1389  Uint64 m_new_gci; // Currently being prepared...
1390  enum State {
1391  M_GCP_IDLE = 0,
1392  M_GCP_PREPARE = 1,
1393  M_GCP_COMMIT = 2,
1394  M_GCP_COMMITTED = 3,
1395  M_GCP_COMPLETE = 4
1396  } m_state;
1397 
1398  struct {
1399  State m_state;
1400  Uint32 m_time_between_gcp;
1401  Uint64 m_new_gci;
1402  Uint64 m_start_time;
1403  } m_master;
1404  } m_micro_gcp;
1405 
1406  struct GcpMonitor
1407  {
1408  struct
1409  {
1410  Uint32 m_gci;
1411  Uint32 m_counter;
1412  Uint32 m_max_lag;
1413  } m_gcp_save;
1414 
1415  struct
1416  {
1417  Uint64 m_gci;
1418  Uint32 m_counter;
1419  Uint32 m_max_lag;
1420  } m_micro_gcp;
1421  } m_gcp_monitor;
1422 
1423  /*------------------------------------------------------------------------*/
1424  /* THIS VARIABLE KEEPS TRACK OF THE STATE OF THIS NODE AS MASTER. */
1425  /*------------------------------------------------------------------------*/
1426  enum MasterState {
1427  MASTER_IDLE = 0,
1428  MASTER_ACTIVE = 1,
1429  MASTER_TAKE_OVER_GCP = 2
1430  };
1431  MasterState cmasterState;
1432  Uint16 cmasterTakeOverNode;
1433  /* NODE IS NOT MASTER */
1434  /* NODE IS ACTIVE AS MASTER */
1435  /* NODE IS TAKING OVER AS MASTER */
1436 
1437  struct CopyGCIMaster {
1438  CopyGCIMaster(){
1439  m_copyReason = CopyGCIReq::IDLE;
1440  for (Uint32 i = 0; i<WAIT_CNT; i++)
1441  m_waiting[i] = CopyGCIReq::IDLE;
1442  }
1443  /*------------------------------------------------------------------------*/
1444  /* THIS STATE VARIABLE IS USED TO INDICATE IF COPYING OF RESTART */
1445  /* INFO WAS STARTED BY A LOCAL CHECKPOINT OR AS PART OF A SYSTEM */
1446  /* RESTART. */
1447  /*------------------------------------------------------------------------*/
1448  CopyGCIReq::CopyReason m_copyReason;
1449 
1450  /*------------------------------------------------------------------------*/
1451  /* COPYING RESTART INFO CAN BE STARTED BY LOCAL CHECKPOINTS AND BY */
1452  /* GLOBAL CHECKPOINTS. WE CAN HOWEVER ONLY HANDLE TWO SUCH COPY AT */
1453  /* THE TIME. THUS WE HAVE TO KEEP WAIT INFORMATION IN THIS VARIABLE.*/
1454  /*------------------------------------------------------------------------*/
1455  STATIC_CONST( WAIT_CNT = 2 );
1456  CopyGCIReq::CopyReason m_waiting[WAIT_CNT];
1457  } c_copyGCIMaster;
1458 
1459  struct CopyGCISlave {
1460  CopyGCISlave(){ m_copyReason = CopyGCIReq::IDLE; m_expectedNextWord = 0;}
1461  /*------------------------------------------------------------------------*/
1462  /* THIS STATE VARIABLE IS USED TO INDICATE IF COPYING OF RESTART */
1463  /* INFO WAS STARTED BY A LOCAL CHECKPOINT OR AS PART OF A SYSTEM */
1464  /* RESTART. THIS VARIABLE IS USED BY THE NODE THAT RECEIVES */
1465  /* COPY_GCI_REQ. */
1466  /*------------------------------------------------------------------------*/
1467  Uint32 m_senderData;
1468  BlockReference m_senderRef;
1469  CopyGCIReq::CopyReason m_copyReason;
1470 
1471  Uint32 m_expectedNextWord;
1472  } c_copyGCISlave;
1473 
1474  /*------------------------------------------------------------------------*/
1475  /* THIS VARIABLE IS USED TO KEEP TRACK OF THE STATE OF LOCAL */
1476  /* CHECKPOINTS. */
1477  /*------------------------------------------------------------------------*/
1478 public:
1479  enum LcpStatus {
1480  LCP_STATUS_IDLE = 0,
1481  LCP_TCGET = 1, // Only master
1482  LCP_STATUS_ACTIVE = 2,
1483  LCP_CALCULATE_KEEP_GCI = 4, // Only master
1484  LCP_COPY_GCI = 5,
1485  LCP_INIT_TABLES = 6,
1486  LCP_TC_CLOPSIZE = 7, // Only master
1487  LCP_START_LCP_ROUND = 8,
1488  LCP_TAB_COMPLETED = 9,
1489  LCP_TAB_SAVED = 10
1490  };
1491 private:
1492 
1493  struct LcpState {
1494  LcpState() {}
1495  LcpStatus lcpStatus;
1496  Uint32 lcpStatusUpdatedPlace;
1497 
1498  struct Save {
1499  LcpStatus m_status;
1500  Uint32 m_place;
1501  } m_saveState[10];
1502 
1503  void setLcpStatus(LcpStatus status, Uint32 line){
1504  for (Uint32 i = 9; i > 0; i--)
1505  m_saveState[i] = m_saveState[i-1];
1506  m_saveState[0].m_status = lcpStatus;
1507  m_saveState[0].m_place = lcpStatusUpdatedPlace;
1508 
1509  lcpStatus = status;
1510  lcpStatusUpdatedPlace = line;
1511  }
1512 
1513  Uint32 lcpStart;
1514  Uint32 lcpStopGcp;
1515  Uint32 keepGci; /* USED TO CALCULATE THE GCI TO KEEP AFTER A LCP */
1516  Uint32 oldestRestorableGci;
1517 
1518  Uint64 m_start_time; // When last LCP was started
1519  Uint64 m_lcp_time; // How long last LCP took
1520  Uint32 m_lcp_trylock_timeout;
1521 
1523  Uint32 tableId;
1524  Uint32 fragmentId;
1525  } currentFragment;
1526 
1527  Uint32 noOfLcpFragRepOutstanding;
1528 
1529  /*------------------------------------------------------------------------*/
1530  /* USED TO ENSURE THAT LCP'S ARE EXECUTED WITH CERTAIN TIMEINTERVALS*/
1531  /* EVEN WHEN SYSTEM IS NOT DOING ANYTHING. */
1532  /*------------------------------------------------------------------------*/
1533  Uint32 ctimer;
1534  Uint32 ctcCounter;
1535  Uint32 clcpDelay; /* MAX. 2^(CLCP_DELAY - 2) SEC BETWEEN LCP'S */
1536 
1537  /*------------------------------------------------------------------------*/
1538  /* THIS STATE IS USED TO TELL IF THE FIRST LCP AFTER START/RESTART */
1539  /* HAS BEEN RUN. AFTER A NODE RESTART THE NODE DOES NOT ENTER */
1540  /* STARTED STATE BEFORE THIS IS DONE. */
1541  /*------------------------------------------------------------------------*/
1542  bool immediateLcpStart;
1543  bool m_LCP_COMPLETE_REP_From_Master_Received;
1544  SignalCounter m_LCP_COMPLETE_REP_Counter_DIH;
1545  SignalCounter m_LCP_COMPLETE_REP_Counter_LQH;
1546  SignalCounter m_LAST_LCP_FRAG_ORD;
1547  NdbNodeBitmask m_participatingLQH;
1548  NdbNodeBitmask m_participatingDIH;
1549 
1550  Uint32 m_masterLcpDihRef;
1551  bool m_MASTER_LCPREQ_Received;
1552  Uint32 m_MASTER_LCPREQ_FailedNodeId;
1553 
1554  Uint32 m_lastLCP_COMPLETE_REP_id;
1555  Uint32 m_lastLCP_COMPLETE_REP_ref;
1556  } c_lcpState;
1557 
1558  /*------------------------------------------------------------------------*/
1559  /* THIS VARIABLE KEEPS TRACK OF HOW MANY TABLES ARE ACTIVATED WHEN */
1560  /* STARTING A LOCAL CHECKPOINT WE SHOULD AVOID STARTING A CHECKPOINT*/
1561  /* WHEN NO TABLES ARE ACTIVATED. */
1562  /*------------------------------------------------------------------------*/
1563  Uint32 cnoOfActiveTables;
1564 
1565  BlockReference cdictblockref; /* DICTIONARY BLOCK REFERENCE */
1566  Uint32 cfailurenr; /* EVERY TIME WHEN A NODE FAILURE IS REPORTED
1567  THIS NUMBER IS INCREMENTED. AT THE START OF
1568  THE SYSTEM THIS NUMBER MUST BE INITIATED TO
1569  ZERO */
1570 
1571  BlockReference clocallqhblockref;
1572  BlockReference clocaltcblockref;
1573  BlockReference cmasterdihref;
1574  Uint16 cownNodeId;
1575  BlockReference cndbStartReqBlockref;
1576  BlockReference cntrlblockref;
1577  Uint32 con_lineNodes;
1578  Uint32 creceivedfrag;
1579  Uint32 cremainingfrags;
1580  Uint32 cstarttype;
1581  Uint32 csystemnodes;
1582  Uint32 c_newest_restorable_gci;
1583  Uint32 c_set_initial_start_flag;
1584  Uint64 c_current_time; // Updated approx. every 10ms
1585 
1586 public:
1587  enum LcpMasterTakeOverState {
1588  LMTOS_IDLE = 0,
1589  LMTOS_WAIT_EMPTY_LCP = 1, // Currently doing empty LCP
1590  LMTOS_WAIT_LCP_FRAG_REP = 2,// Currently waiting for outst. LCP_FRAG_REP
1591  LMTOS_INITIAL = 3,
1592  LMTOS_ALL_IDLE = 4,
1593  LMTOS_ALL_ACTIVE = 5,
1594  LMTOS_LCP_CONCLUDING = 6,
1595  LMTOS_COPY_ONGOING = 7
1596  };
1597 private:
1598  class MasterTakeOverState {
1599  public:
1600  MasterTakeOverState() {}
1601  void set(LcpMasterTakeOverState s, Uint32 line) {
1602  state = s; updatePlace = line;
1603  }
1604 
1605  LcpMasterTakeOverState state;
1606  Uint32 updatePlace;
1607 
1608  Uint32 minTableId;
1609  Uint32 minFragId;
1610  Uint32 failedNodeId;
1611  } c_lcpMasterTakeOverState;
1612 
1613  Uint16 cmasterNodeId;
1614 
1615  struct NodeStartMasterRecord {
1616  NodeStartMasterRecord() {}
1617  Uint32 startNode;
1618  Uint32 wait;
1619  Uint32 failNr;
1620  bool activeState;
1621  bool blockLcp;
1622  Uint32 blockGcp; // 0, 1=ordered, 2=effective
1623  Uint32 startInfoErrorCode;
1624  Uint32 m_outstandingGsn;
1625  MutexHandle2<DIH_FRAGMENT_INFO> m_fragmentInfoMutex;
1626  };
1627  NodeStartMasterRecord c_nodeStartMaster;
1628 
1629  struct NodeStartSlaveRecord {
1630  NodeStartSlaveRecord() { nodeId = 0;}
1631 
1632  Uint32 nodeId;
1633  };
1634  NodeStartSlaveRecord c_nodeStartSlave;
1635 
1636  Uint32 cfirstAliveNode;
1637  Uint32 cfirstDeadNode;
1638  Uint32 cstartPhase;
1639  Uint32 cnoReplicas;
1640 
1641  bool cwaitLcpSr;
1646  Uint32 c_node_groups[MAX_NDB_NODES];
1647  Uint32 cnoOfNodeGroups;
1648  Uint32 crestartGci; /* VALUE OF GCI WHEN SYSTEM RESTARTED OR STARTED */
1649 
1654  SignalCounter c_COPY_GCIREQ_Counter;
1655  SignalCounter c_COPY_TABREQ_Counter;
1656  SignalCounter c_CREATE_FRAGREQ_Counter;
1657  SignalCounter c_DIH_SWITCH_REPLICA_REQ_Counter;
1658  SignalCounter c_EMPTY_LCP_REQ_Counter;
1659  SignalCounter c_GCP_COMMIT_Counter;
1660  SignalCounter c_GCP_PREPARE_Counter;
1661  SignalCounter c_GCP_SAVEREQ_Counter;
1662  SignalCounter c_SUB_GCP_COMPLETE_REP_Counter;
1663  SignalCounter c_INCL_NODEREQ_Counter;
1664  SignalCounter c_MASTER_GCPREQ_Counter;
1665  SignalCounter c_MASTER_LCPREQ_Counter;
1666  SignalCounter c_START_INFOREQ_Counter;
1667  SignalCounter c_START_RECREQ_Counter;
1668  SignalCounter c_STOP_ME_REQ_Counter;
1669  SignalCounter c_TC_CLOPSIZEREQ_Counter;
1670  SignalCounter c_TCGETOPSIZEREQ_Counter;
1671  SignalCounter c_START_LCP_REQ_Counter;
1672 
1673  bool c_blockCommit;
1674  Uint32 c_blockCommitNo;
1675 
1676  bool getBlockCommit() const {
1677  return c_blockCommit || cgckptflag;
1678  }
1679 
1683  struct SwitchReplicaRecord {
1684  SwitchReplicaRecord() {}
1685  void clear(){}
1686 
1687  Uint32 nodeId;
1688  Uint32 tableId;
1689  Uint32 fragNo;
1690  };
1691  SwitchReplicaRecord c_switchReplicas;
1692 
1693  struct StopPermProxyRecord {
1694  StopPermProxyRecord() { clientRef = 0; }
1695 
1696  Uint32 clientData;
1697  BlockReference clientRef;
1698  BlockReference masterRef;
1699  };
1700 
1701  struct StopPermMasterRecord {
1702  StopPermMasterRecord() { clientRef = 0;}
1703 
1704  Uint32 returnValue;
1705 
1706  Uint32 clientData;
1707  BlockReference clientRef;
1708  };
1709 
1710  StopPermProxyRecord c_stopPermProxy;
1711  StopPermMasterRecord c_stopPermMaster;
1712 
1713  void checkStopPermProxy(Signal*, NodeId failedNodeId);
1714  void checkStopPermMaster(Signal*, NodeRecordPtr failedNodePtr);
1715 
1716  void switchReplica(Signal*,
1717  Uint32 nodeId,
1718  Uint32 tableId,
1719  Uint32 fragNo);
1720 
1721  void switchReplicaReply(Signal*, NodeId nodeId);
1722 
1726  struct WaitGCPProxyRecord {
1727  WaitGCPProxyRecord() { clientRef = 0;}
1728 
1729  Uint32 clientData;
1730  BlockReference clientRef;
1731  BlockReference masterRef;
1732 
1733  union { Uint32 nextPool; Uint32 nextList; };
1734  Uint32 prevList;
1735  };
1736  typedef Ptr<WaitGCPProxyRecord> WaitGCPProxyPtr;
1737 
1741  struct WaitGCPMasterRecord {
1742  WaitGCPMasterRecord() { clientRef = 0;}
1743  Uint32 clientData;
1744  BlockReference clientRef;
1745 
1746  union { Uint32 nextPool; Uint32 nextList; };
1747  Uint32 prevList;
1748  };
1749  typedef Ptr<WaitGCPMasterRecord> WaitGCPMasterPtr;
1750 
1754  ArrayPool<WaitGCPProxyRecord> waitGCPProxyPool;
1755  DLList<WaitGCPProxyRecord> c_waitGCPProxyList;
1756 
1760  ArrayPool<WaitGCPMasterRecord> waitGCPMasterPool;
1761  typedef DLList<WaitGCPMasterRecord> WaitGCPList;
1762  WaitGCPList c_waitGCPMasterList;
1763  WaitGCPList c_waitEpochMasterList;
1764 
1765  void checkWaitGCPProxy(Signal*, NodeId failedNodeId);
1766  void checkWaitGCPMaster(Signal*, NodeId failedNodeId);
1767  void emptyWaitGCPMasterQueue(Signal*, Uint64, WaitGCPList&);
1768 
1772  struct StopMeRecord {
1773  StopMeRecord() { clientRef = 0;}
1774 
1775  BlockReference clientRef;
1776  Uint32 clientData;
1777  };
1778  StopMeRecord c_stopMe;
1779 
1780  void checkStopMe(Signal *, NodeRecordPtr failedNodePtr);
1781 
1782 #define DIH_CDATA_SIZE 128
1783 
1786  Uint32 cdata[DIH_CDATA_SIZE]; /* TEMPORARY ARRAY VARIABLE */
1787 
1791  Uint32 sysfileData[DIH_CDATA_SIZE];
1792  Uint32 sysfileDataToFile[DIH_CDATA_SIZE];
1793 
1798  void invalidateNodeLCP(Signal *, Uint32 nodeId, Uint32 tableId);
1799  void invalidateNodeLCP(Signal *, Uint32 nodeId, TabRecordPtr);
1800 
1804  void startInfoReply(Signal *, Uint32 nodeId);
1805 
1806  void dump_replica_info();
1807  void dump_replica_info(const Fragmentstore*);
1808 
1809  // DIH specifics for execNODE_START_REP (sendDictUnlockOrd)
1810  void execNODE_START_REP(Signal* signal);
1811 
1812  /*
1813  * Lock master DICT. Only current use is by starting node
1814  * during NR. A pool of slave records is convenient anyway.
1815  */
1816  struct DictLockSlaveRecord {
1817  Uint32 lockPtr;
1818  Uint32 lockType;
1819  bool locked;
1820  Callback callback;
1821  Uint32 nextPool;
1822  };
1823 
1824  typedef Ptr<DictLockSlaveRecord> DictLockSlavePtr;
1825  ArrayPool<DictLockSlaveRecord> c_dictLockSlavePool;
1826 
1827  // slave
1828  void sendDictLockReq(Signal* signal, Uint32 lockType, Callback c);
1829  void recvDictLockConf(Signal* signal);
1830  void sendDictUnlockOrd(Signal* signal, Uint32 lockSlavePtrI);
1831 
1832  // NR
1833  Uint32 c_dictLockSlavePtrI_nodeRestart; // userPtr for NR
1834  void recvDictLockConf_nodeRestart(Signal* signal, Uint32 data, Uint32 ret);
1835 
1836  Uint32 c_error_7181_ref;
1837 
1838 #ifdef ERROR_INSERT
1839  void sendToRandomNodes(const char*, Signal*, SignalCounter*,
1840  SendFunction,
1841  Uint32 extra = RNIL,
1842  Uint32 block = 0, Uint32 gsn = 0, Uint32 len = 0,
1843  JobBufferLevel = JBB);
1844 #endif
1845 
1846  bool check_enable_micro_gcp(Signal* signal, bool broadcast);
1847 
1848  bool c_sr_wait_to;
1849  NdbNodeBitmask m_sr_nodes;
1850  NdbNodeBitmask m_to_nodes;
1851 
1852  void startme_copygci_conf(Signal*);
1853 
1863  struct LocalLCPState
1864  {
1865  enum State {
1866  LS_INITIAL = 0,
1867  LS_RUNNING = 1,
1868  LS_COMPLETE = 2
1869  } m_state;
1870 
1871  StartLcpReq m_start_lcp_req;
1872  Uint32 m_keep_gci; // Min GCI is needed to restore LCP
1873  Uint32 m_stop_gci; // This GCI needs to be complete before LCP is restorable
1874 
1875  LocalLCPState() { reset();}
1876 
1877  void reset();
1878  void init(const StartLcpReq*);
1879  void lcp_frag_rep(const LcpFragRep*);
1880  void lcp_complete_rep(Uint32 gci);
1881 
1885  bool check_cut_log_tail(Uint32 gci) const;
1886  } m_local_lcp_state;
1887 
1888  // MT LQH
1889  Uint32 c_fragments_per_node;
1890  Uint32 dihGetInstanceKey(FragmentstorePtr tFragPtr) {
1891  ndbrequire(!tFragPtr.isNull());
1892  Uint32 log_part_id = tFragPtr.p->m_log_part_id;
1893  Uint32 instanceKey = 1 + log_part_id % MAX_NDBMT_LQH_WORKERS;
1894  return instanceKey;
1895  }
1896  Uint32 dihGetInstanceKey(Uint32 tabId, Uint32 fragId);
1897 
1898  bool c_2pass_inr;
1899 };
1900 
1901 #if (DIH_CDATA_SIZE < _SYSFILE_SIZE32)
1902 #error "cdata is to small compared to Sysfile size"
1903 #endif
1904 
1905 #endif
1906