MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DbdihMain.cpp
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 #define DBDIH_C
19 #include <ndb_global.h>
20 #include <ndb_limits.h>
21 #include <ndb_version.h>
22 #include <NdbOut.hpp>
23 
24 #include "Dbdih.hpp"
25 #include "Configuration.hpp"
26 
27 #include <signaldata/BlockCommitOrd.hpp>
28 #include <signaldata/CheckNodeGroups.hpp>
29 #include <signaldata/CopyActive.hpp>
30 #include <signaldata/CopyFrag.hpp>
31 #include <signaldata/CopyGCIReq.hpp>
32 #include <signaldata/DiAddTab.hpp>
33 #include <signaldata/DictStart.hpp>
34 #include <signaldata/DiGetNodes.hpp>
35 #include <signaldata/DihContinueB.hpp>
36 #include <signaldata/DihSwitchReplica.hpp>
37 #include <signaldata/DumpStateOrd.hpp>
38 #include <signaldata/EmptyLcp.hpp>
39 #include <signaldata/EventReport.hpp>
40 #include <signaldata/GCP.hpp>
41 #include <signaldata/HotSpareRep.hpp>
42 #include <signaldata/MasterGCP.hpp>
43 #include <signaldata/MasterLCP.hpp>
44 #include <signaldata/NFCompleteRep.hpp>
45 #include <signaldata/NodeFailRep.hpp>
46 #include <signaldata/ReadNodesConf.hpp>
47 #include <signaldata/StartFragReq.hpp>
48 #include <signaldata/StartInfo.hpp>
49 #include <signaldata/StartMe.hpp>
50 #include <signaldata/StartPerm.hpp>
51 #include <signaldata/StartRec.hpp>
52 #include <signaldata/StopPerm.hpp>
53 #include <signaldata/StopMe.hpp>
54 #include <signaldata/TestOrd.hpp>
55 #include <signaldata/WaitGCP.hpp>
56 #include <signaldata/DihStartTab.hpp>
57 #include <signaldata/LCP.hpp>
58 #include <signaldata/SystemError.hpp>
59 
60 #include <signaldata/TakeOver.hpp>
61 
62 #include <signaldata/DropTab.hpp>
63 #include <signaldata/AlterTab.hpp>
64 #include <signaldata/AlterTable.hpp>
65 #include <signaldata/PrepDropTab.hpp>
66 #include <signaldata/SumaImpl.hpp>
67 #include <signaldata/DictTabInfo.hpp>
68 #include <signaldata/CreateFragmentation.hpp>
69 #include <signaldata/LqhFrag.hpp>
70 #include <signaldata/FsOpenReq.hpp>
71 #include <signaldata/DihScanTab.hpp>
72 #include <signaldata/DictLock.hpp>
73 #include <DebuggerNames.hpp>
74 #include <signaldata/Upgrade.hpp>
75 #include <NdbEnv.h>
76 #include <signaldata/CreateNodegroup.hpp>
77 #include <signaldata/CreateNodegroupImpl.hpp>
78 #include <signaldata/DropNodegroup.hpp>
79 #include <signaldata/DropNodegroupImpl.hpp>
80 #include <signaldata/DihGetTabInfo.hpp>
81 #include <SectionReader.hpp>
82 #include <signaldata/DihRestart.hpp>
83 
84 #include <EventLogger.hpp>
85 extern EventLogger * g_eventLogger;
86 
87 #define SYSFILE ((Sysfile *)&sysfileData[0])
88 #define MAX_CRASHED_REPLICAS 8
89 #define ZINIT_CREATE_GCI Uint32(0)
90 #define ZINIT_REPLICA_LAST_GCI Uint32(-1)
91 
92 #define RETURN_IF_NODE_NOT_ALIVE(node) \
93  if (!checkNodeAlive((node))) { \
94  jam(); \
95  return; \
96  } \
97 
98 #define receiveLoopMacro(sigName, receiveNodeId)\
99 { \
100  c_##sigName##_Counter.clearWaitingFor(receiveNodeId); \
101  if(c_##sigName##_Counter.done() == false){ \
102  jam(); \
103  return; \
104  } \
105 }
106 
107 #define sendLoopMacro(sigName, signalRoutine, extra) \
108 { \
109  c_##sigName##_Counter.clearWaitingFor(); \
110  NodeRecordPtr specNodePtr; \
111  specNodePtr.i = cfirstAliveNode; \
112  do { \
113  jam(); \
114  ptrCheckGuard(specNodePtr, MAX_NDB_NODES, nodeRecord); \
115  c_##sigName##_Counter.setWaitingFor(specNodePtr.i); \
116  signalRoutine(signal, specNodePtr.i, extra); \
117  specNodePtr.i = specNodePtr.p->nextNode; \
118  } while (specNodePtr.i != RNIL); \
119 }
120 
121 static
122 Uint32
123 prevLcpNo(Uint32 lcpNo){
124  if(lcpNo == 0)
125  return MAX_LCP_USED - 1;
126  return lcpNo - 1;
127 }
128 
129 static
130 Uint32
131 nextLcpNo(Uint32 lcpNo){
132  lcpNo++;
133  if(lcpNo >= MAX_LCP_USED)
134  return 0;
135  return lcpNo;
136 }
137 
138 void Dbdih::nullRoutine(Signal* signal, Uint32 nodeId, Uint32 extra)
139 {
140 }//Dbdih::nullRoutine()
141 
142 void Dbdih::sendCOPY_GCIREQ(Signal* signal, Uint32 nodeId, Uint32 extra)
143 {
144  ndbrequire(c_copyGCIMaster.m_copyReason != CopyGCIReq::IDLE);
145 
146  const BlockReference ref = calcDihBlockRef(nodeId);
147  const Uint32 wordPerSignal = CopyGCIReq::DATA_SIZE;
148  const Uint32 noOfSignals = ((Sysfile::SYSFILE_SIZE32 + (wordPerSignal - 1)) /
149  wordPerSignal);
150 
151  CopyGCIReq * const copyGCI = (CopyGCIReq *)&signal->theData[0];
152  copyGCI->anyData = nodeId;
153  copyGCI->copyReason = c_copyGCIMaster.m_copyReason;
154  copyGCI->startWord = 0;
155 
156  for(Uint32 i = 0; i < noOfSignals; i++) {
157  jam();
158  { // Do copy
159  const int startWord = copyGCI->startWord;
160  for(Uint32 j = 0; j < wordPerSignal; j++) {
161  copyGCI->data[j] = sysfileData[j+startWord];
162  }//for
163  }
164  sendSignal(ref, GSN_COPY_GCIREQ, signal, 25, JBB);
165  copyGCI->startWord += wordPerSignal;
166  }//for
167 }//Dbdih::sendCOPY_GCIREQ()
168 
169 
170 void Dbdih::sendDIH_SWITCH_REPLICA_REQ(Signal* signal, Uint32 nodeId,
171  Uint32 extra)
172 {
173  const BlockReference ref = calcDihBlockRef(nodeId);
174  sendSignal(ref, GSN_DIH_SWITCH_REPLICA_REQ, signal,
175  DihSwitchReplicaReq::SignalLength, JBB);
176 }//Dbdih::sendDIH_SWITCH_REPLICA_REQ()
177 
178 void Dbdih::sendEMPTY_LCP_REQ(Signal* signal, Uint32 nodeId, Uint32 extra)
179 {
180  BlockReference ref = calcLqhBlockRef(nodeId);
181  sendSignal(ref, GSN_EMPTY_LCP_REQ, signal, EmptyLcpReq::SignalLength, JBB);
182 }//Dbdih::sendEMPTY_LCPREQ()
183 
184 void Dbdih::sendGCP_COMMIT(Signal* signal, Uint32 nodeId, Uint32 extra)
185 {
186  BlockReference ref = calcDihBlockRef(nodeId);
187  GCPCommit *req = (GCPCommit*)signal->getDataPtrSend();
188  req->nodeId = cownNodeId;
189  req->gci_hi = Uint32(m_micro_gcp.m_master.m_new_gci >> 32);
190  req->gci_lo = Uint32(m_micro_gcp.m_master.m_new_gci);
191  sendSignal(ref, GSN_GCP_COMMIT, signal, GCPCommit::SignalLength, JBA);
192 
193  ndbassert(m_micro_gcp.m_enabled || Uint32(m_micro_gcp.m_new_gci) == 0);
194 }//Dbdih::sendGCP_COMMIT()
195 
196 void Dbdih::sendGCP_PREPARE(Signal* signal, Uint32 nodeId, Uint32 extra)
197 {
198  BlockReference ref = calcDihBlockRef(nodeId);
199  GCPPrepare *req = (GCPPrepare*)signal->getDataPtrSend();
200  req->nodeId = cownNodeId;
201  req->gci_hi = Uint32(m_micro_gcp.m_master.m_new_gci >> 32);
202  req->gci_lo = Uint32(m_micro_gcp.m_master.m_new_gci);
203 
204  if (! (ERROR_INSERTED(7201) || ERROR_INSERTED(7202)))
205  {
206  sendSignal(ref, GSN_GCP_PREPARE, signal, GCPPrepare::SignalLength, JBA);
207  }
208  else if (ERROR_INSERTED(7201))
209  {
210  sendSignal(ref, GSN_GCP_PREPARE, signal, GCPPrepare::SignalLength, JBB);
211  }
212  else if (ERROR_INSERTED(7202))
213  {
214  ndbrequire(nodeId == getOwnNodeId());
215  sendSignalWithDelay(ref, GSN_GCP_PREPARE, signal, 2000,
216  GCPPrepare::SignalLength);
217  }
218  else
219  {
220  ndbrequire(false); // should be dead code #ifndef ERROR_INSERT
221  }
222 
223  ndbassert(m_micro_gcp.m_enabled || Uint32(m_micro_gcp.m_new_gci) == 0);
224 }//Dbdih::sendGCP_PREPARE()
225 
226 void
227 Dbdih::sendSUB_GCP_COMPLETE_REP(Signal* signal, Uint32 nodeId, Uint32 extra)
228 {
229  ndbassert(m_micro_gcp.m_enabled || Uint32(m_micro_gcp.m_new_gci) == 0);
230  if (!ndbd_dih_sub_gcp_complete_ack(getNodeInfo(nodeId).m_version))
231  {
232  jam();
233  c_SUB_GCP_COMPLETE_REP_Counter.clearWaitingFor(nodeId);
234  }
235  BlockReference ref = calcDihBlockRef(nodeId);
236  sendSignal(ref, GSN_SUB_GCP_COMPLETE_REP, signal,
237  SubGcpCompleteRep::SignalLength, JBA);
238 }
239 
240 void Dbdih::sendGCP_SAVEREQ(Signal* signal, Uint32 nodeId, Uint32 extra)
241 {
242  GCPSaveReq * const saveReq = (GCPSaveReq*)&signal->theData[0];
243  BlockReference ref = calcDihBlockRef(nodeId);
244  saveReq->dihBlockRef = reference();
245  saveReq->dihPtr = nodeId;
246  saveReq->gci = m_gcp_save.m_master.m_new_gci;
247  sendSignal(ref, GSN_GCP_SAVEREQ, signal, GCPSaveReq::SignalLength, JBB);
248 }//Dbdih::sendGCP_SAVEREQ()
249 
250 void Dbdih::sendINCL_NODEREQ(Signal* signal, Uint32 nodeId, Uint32 extra)
251 {
252  BlockReference nodeDihRef = calcDihBlockRef(nodeId);
253  signal->theData[0] = reference();
254  signal->theData[1] = c_nodeStartMaster.startNode;
255  signal->theData[2] = c_nodeStartMaster.failNr;
256  signal->theData[3] = 0;
257  signal->theData[4] = (Uint32)(m_micro_gcp.m_current_gci >> 32);
258  signal->theData[5] = (Uint32)(m_micro_gcp.m_current_gci & 0xFFFFFFFF);
259  sendSignal(nodeDihRef, GSN_INCL_NODEREQ, signal, 6, JBA);
260 }//Dbdih::sendINCL_NODEREQ()
261 
262 void Dbdih::sendMASTER_GCPREQ(Signal* signal, Uint32 nodeId, Uint32 extra)
263 {
264  BlockReference ref = calcDihBlockRef(nodeId);
265  sendSignal(ref, GSN_MASTER_GCPREQ, signal, MasterGCPReq::SignalLength, JBB);
266 }//Dbdih::sendMASTER_GCPREQ()
267 
268 void Dbdih::sendMASTER_LCPREQ(Signal* signal, Uint32 nodeId, Uint32 extra)
269 {
270  BlockReference ref = calcDihBlockRef(nodeId);
271  sendSignal(ref, GSN_MASTER_LCPREQ, signal, MasterLCPReq::SignalLength, JBB);
272 }//Dbdih::sendMASTER_LCPREQ()
273 
274 void Dbdih::sendSTART_INFOREQ(Signal* signal, Uint32 nodeId, Uint32 extra)
275 {
276  const BlockReference ref = calcDihBlockRef(nodeId);
277  sendSignal(ref, GSN_START_INFOREQ, signal, StartInfoReq::SignalLength, JBB);
278 }//sendSTART_INFOREQ()
279 
280 void Dbdih::sendSTART_RECREQ(Signal* signal, Uint32 nodeId, Uint32 extra)
281 {
282  if (!m_sr_nodes.get(nodeId))
283  {
284  jam();
285  c_START_RECREQ_Counter.clearWaitingFor(nodeId);
286  return;
287  }
288 
289  Uint32 keepGCI = SYSFILE->keepGCI;
290  Uint32 lastCompletedGCI = SYSFILE->lastCompletedGCI[nodeId];
291  if (keepGCI > lastCompletedGCI)
292  {
293  jam();
294  keepGCI = lastCompletedGCI;
295  }
296 
297  StartRecReq * const req = (StartRecReq*)&signal->theData[0];
298  BlockReference ref = calcLqhBlockRef(nodeId);
299  req->receivingNodeId = nodeId;
300  req->senderRef = reference();
301  req->keepGci = keepGCI;
302  req->lastCompletedGci = lastCompletedGCI;
303  req->newestGci = SYSFILE->newestRestorableGCI;
304  req->senderData = extra;
305  m_sr_nodes.copyto(NdbNodeBitmask::Size, req->sr_nodes);
306  sendSignal(ref, GSN_START_RECREQ, signal, StartRecReq::SignalLength, JBB);
307 
308  signal->theData[0] = NDB_LE_StartREDOLog;
309  signal->theData[1] = nodeId;
310  signal->theData[2] = keepGCI;
311  signal->theData[3] = lastCompletedGCI;
312  signal->theData[4] = SYSFILE->newestRestorableGCI;
313  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 5, JBB);
314 }//Dbdih::sendSTART_RECREQ()
315 
316 void Dbdih::sendSTART_TOREQ(Signal* signal, Uint32 nodeId, Uint32 extra)
317 {
318  BlockReference ref = calcDihBlockRef(nodeId);
319  sendSignal(ref, GSN_START_TOREQ, signal, StartToReq::SignalLength, JBB);
320 }//Dbdih::sendSTART_TOREQ()
321 
322 void Dbdih::sendSTOP_ME_REQ(Signal* signal, Uint32 nodeId, Uint32 extra)
323 {
324  if (nodeId != getOwnNodeId()) {
325  jam();
326  const BlockReference ref = calcDihBlockRef(nodeId);
327  sendSignal(ref, GSN_STOP_ME_REQ, signal, StopMeReq::SignalLength, JBB);
328  }//if
329 }//Dbdih::sendSTOP_ME_REQ()
330 
331 void Dbdih::sendTC_CLOPSIZEREQ(Signal* signal, Uint32 nodeId, Uint32 extra)
332 {
333  BlockReference ref = calcTcBlockRef(nodeId);
334  signal->theData[0] = nodeId;
335  signal->theData[1] = reference();
336  sendSignal(ref, GSN_TC_CLOPSIZEREQ, signal, 2, JBB);
337 }//Dbdih::sendTC_CLOPSIZEREQ()
338 
339 void Dbdih::sendTCGETOPSIZEREQ(Signal* signal, Uint32 nodeId, Uint32 extra)
340 {
341  BlockReference ref = calcTcBlockRef(nodeId);
342  signal->theData[0] = nodeId;
343  signal->theData[1] = reference();
344  sendSignal(ref, GSN_TCGETOPSIZEREQ, signal, 2, JBB);
345 }//Dbdih::sendTCGETOPSIZEREQ()
346 
347 void Dbdih::sendUPDATE_TOREQ(Signal* signal, Uint32 nodeId, Uint32 extra)
348 {
349  const BlockReference ref = calcDihBlockRef(nodeId);
350  sendSignal(ref, GSN_UPDATE_TOREQ, signal, UpdateToReq::SignalLength, JBB);
351 }//sendUPDATE_TOREQ()
352 
353 void Dbdih::execCONTINUEB(Signal* signal)
354 {
355  jamEntry();
356  switch ((DihContinueB::Type)signal->theData[0]) {
357  case DihContinueB::ZPACK_TABLE_INTO_PAGES:
358  {
359  jam();
360  Uint32 tableId = signal->theData[1];
361  packTableIntoPagesLab(signal, tableId);
362  return;
363  break;
364  }
365  case DihContinueB::ZPACK_FRAG_INTO_PAGES:
366  {
367  RWFragment wf;
368  jam();
369  wf.rwfTabPtr.i = signal->theData[1];
370  ptrCheckGuard(wf.rwfTabPtr, ctabFileSize, tabRecord);
371  wf.fragId = signal->theData[2];
372  wf.pageIndex = signal->theData[3];
373  wf.wordIndex = signal->theData[4];
374  wf.totalfragments = signal->theData[5];
375  packFragIntoPagesLab(signal, &wf);
376  return;
377  break;
378  }
379  case DihContinueB::ZREAD_PAGES_INTO_TABLE:
380  {
381  jam();
382  Uint32 tableId = signal->theData[1];
383  readPagesIntoTableLab(signal, tableId);
384  return;
385  break;
386  }
387  case DihContinueB::ZREAD_PAGES_INTO_FRAG:
388  {
389  RWFragment rf;
390  jam();
391  rf.rwfTabPtr.i = signal->theData[1];
392  ptrCheckGuard(rf.rwfTabPtr, ctabFileSize, tabRecord);
393  rf.fragId = signal->theData[2];
394  rf.pageIndex = signal->theData[3];
395  rf.wordIndex = signal->theData[4];
396  readPagesIntoFragLab(signal, &rf);
397  return;
398  break;
399  }
400  case DihContinueB::ZCOPY_TABLE:
401  {
402  jam();
403  Uint32 tableId = signal->theData[1];
404  copyTableLab(signal, tableId);
405  return;
406  }
407  case DihContinueB::ZCOPY_TABLE_NODE:
408  {
409  NodeRecordPtr nodePtr;
410  CopyTableNode ctn;
411  jam();
412  ctn.ctnTabPtr.i = signal->theData[1];
413  ptrCheckGuard(ctn.ctnTabPtr, ctabFileSize, tabRecord);
414  nodePtr.i = signal->theData[2];
415  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
416  ctn.pageIndex = signal->theData[3];
417  ctn.wordIndex = signal->theData[4];
418  ctn.noOfWords = signal->theData[5];
419  copyTableNode(signal, &ctn, nodePtr);
420  return;
421  }
422  case DihContinueB::ZSTART_FRAGMENT:
423  {
424  jam();
425  Uint32 tableId = signal->theData[1];
426  Uint32 fragId = signal->theData[2];
427  startFragment(signal, tableId, fragId);
428  return;
429  }
430  case DihContinueB::ZCOMPLETE_RESTART:
431  jam();
432  completeRestartLab(signal);
433  return;
434  case DihContinueB::ZREAD_TABLE_FROM_PAGES:
435  {
436  TabRecordPtr tabPtr;
437  jam();
438  tabPtr.i = signal->theData[1];
439  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
440  readTableFromPagesLab(signal, tabPtr);
441  return;
442  }
443  case DihContinueB::ZSR_PHASE2_READ_TABLE:
444  {
445  TabRecordPtr tabPtr;
446  jam();
447  tabPtr.i = signal->theData[1];
448  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
449  srPhase2ReadTableLab(signal, tabPtr);
450  return;
451  }
452  case DihContinueB::ZCHECK_TC_COUNTER:
453  jam();
454 #ifndef NO_LCP
455  checkTcCounterLab(signal);
456 #endif
457  return;
458  case DihContinueB::ZCALCULATE_KEEP_GCI:
459  {
460  jam();
461  Uint32 tableId = signal->theData[1];
462  Uint32 fragId = signal->theData[2];
463  calculateKeepGciLab(signal, tableId, fragId);
464  return;
465  }
466  case DihContinueB::ZSTORE_NEW_LCP_ID:
467  jam();
468  storeNewLcpIdLab(signal);
469  return;
470  case DihContinueB::ZTABLE_UPDATE:
471  {
472  TabRecordPtr tabPtr;
473  jam();
474  tabPtr.i = signal->theData[1];
475  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
476  tableUpdateLab(signal, tabPtr);
477  return;
478  }
479  case DihContinueB::ZCHECK_LCP_COMPLETED:
480  {
481  jam();
482  checkLcpCompletedLab(signal);
483  return;
484  }
485  case DihContinueB::ZINIT_LCP:
486  {
487  jam();
488  Uint32 senderRef = signal->theData[1];
489  Uint32 tableId = signal->theData[2];
490  initLcpLab(signal, senderRef, tableId);
491  return;
492  }
493  case DihContinueB::ZADD_TABLE_MASTER_PAGES:
494  {
495  TabRecordPtr tabPtr;
496  jam();
497  tabPtr.i = signal->theData[1];
498  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
499  tabPtr.p->tabUpdateState = TabRecord::US_ADD_TABLE_MASTER;
500  tableUpdateLab(signal, tabPtr);
501  return;
502  break;
503  }
504  case DihContinueB::ZDIH_ADD_TABLE_MASTER:
505  {
506  jam();
507  addTable_closeConf(signal, signal->theData[1]);
508  return;
509  }
510  case DihContinueB::ZADD_TABLE_SLAVE_PAGES:
511  {
512  TabRecordPtr tabPtr;
513  jam();
514  tabPtr.i = signal->theData[1];
515  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
516  tabPtr.p->tabUpdateState = TabRecord::US_ADD_TABLE_SLAVE;
517  tableUpdateLab(signal, tabPtr);
518  return;
519  }
520  case DihContinueB::ZDIH_ADD_TABLE_SLAVE:
521  {
522  ndbrequire(false);
523  return;
524  }
525  case DihContinueB::ZSTART_GCP:
526  jam();
527 #ifndef NO_GCP
528  startGcpLab(signal, signal->theData[1]);
529 #endif
530  return;
531  break;
532  case DihContinueB::ZCOPY_GCI:{
533  jam();
534  CopyGCIReq::CopyReason reason = (CopyGCIReq::CopyReason)signal->theData[1];
535  ndbrequire(c_copyGCIMaster.m_copyReason == reason);
536 
537  // set to idle, to be able to reuse method
538  c_copyGCIMaster.m_copyReason = CopyGCIReq::IDLE;
539  copyGciLab(signal, reason);
540  return;
541  }
542  break;
543  case DihContinueB::ZEMPTY_VERIFY_QUEUE:
544  jam();
545  emptyverificbuffer(signal, signal->theData[1], true);
546  return;
547  break;
548  case DihContinueB::ZCHECK_GCP_STOP:
549  jam();
550 #ifndef NO_GCP
551  checkGcpStopLab(signal);
552 #endif
553  return;
554  break;
555  case DihContinueB::ZREMOVE_NODE_FROM_TABLE:
556  {
557  jam();
558  Uint32 nodeId = signal->theData[1];
559  Uint32 tableId = signal->theData[2];
560  removeNodeFromTables(signal, nodeId, tableId);
561  return;
562  }
563  case DihContinueB::ZCOPY_NODE:
564  {
565  jam();
566  Uint32 tableId = signal->theData[1];
567  copyNodeLab(signal, tableId);
568  return;
569  }
570  case DihContinueB::ZTO_START_COPY_FRAG:
571  {
572  jam();
573  Uint32 takeOverPtrI = signal->theData[1];
574  startNextCopyFragment(signal, takeOverPtrI);
575  return;
576  }
577  case DihContinueB::ZINVALIDATE_NODE_LCP:
578  {
579  jam();
580  const Uint32 nodeId = signal->theData[1];
581  const Uint32 tableId = signal->theData[2];
582  invalidateNodeLCP(signal, nodeId, tableId);
583  return;
584  }
585  case DihContinueB::ZINITIALISE_RECORDS:
586  jam();
587  initialiseRecordsLab(signal,
588  signal->theData[1],
589  signal->theData[2],
590  signal->theData[3]);
591  return;
592  break;
593  case DihContinueB::ZSTART_PERMREQ_AGAIN:
594  jam();
595  nodeRestartPh2Lab2(signal);
596  return;
597  break;
598  case DihContinueB::SwitchReplica:
599  {
600  jam();
601  const Uint32 nodeId = signal->theData[1];
602  const Uint32 tableId = signal->theData[2];
603  const Uint32 fragNo = signal->theData[3];
604  switchReplica(signal, nodeId, tableId, fragNo);
605  return;
606  }
607  case DihContinueB::ZSEND_ADD_FRAG:
608  {
609  jam();
610  Uint32 takeOverPtrI = signal->theData[1];
611  toCopyFragLab(signal, takeOverPtrI);
612  return;
613  }
614  case DihContinueB::ZSEND_START_TO:
615  {
616  jam();
617  Ptr<TakeOverRecord> takeOverPtr;
618  c_takeOverPool.getPtr(takeOverPtr, signal->theData[1]);
619  sendStartTo(signal, takeOverPtr);
620  return;
621  }
622  case DihContinueB::ZSEND_UPDATE_TO:
623  {
624  jam();
625  Ptr<TakeOverRecord> takeOverPtr;
626  c_takeOverPool.getPtr(takeOverPtr, signal->theData[1]);
627  sendUpdateTo(signal, takeOverPtr);
628  return;
629  }
630  case DihContinueB::WAIT_DROP_TAB_WRITING_TO_FILE:{
631  jam();
632  TabRecordPtr tabPtr;
633  tabPtr.i = signal->theData[1];
634  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
635  waitDropTabWritingToFile(signal, tabPtr);
636  return;
637  }
638  case DihContinueB::ZTO_START_FRAGMENTS:
639  {
640  TakeOverRecordPtr takeOverPtr;
641  c_takeOverPool.getPtr(takeOverPtr, signal->theData[1]);
642  nr_start_fragments(signal, takeOverPtr);
643  return;
644  }
645  case DihContinueB::ZCOPY_NODE_WAIT_CREATE_FRAG:
646  {
647  jam();
648  lcpBlockedLab(signal, true, signal->theData[1]);
649  return;
650  }
651  case DihContinueB::ZWAIT_OLD_SCAN:
652  {
653  jam();
654  wait_old_scan(signal);
655  return;
656  }
657  case DihContinueB::ZLCP_TRY_LOCK:
658  {
659  jam();
660  Mutex mutex(signal, c_mutexMgr, c_fragmentInfoMutex_lcp);
661  Callback c = { safe_cast(&Dbdih::lcpFragmentMutex_locked),
662  signal->theData[1] };
663  ndbrequire(mutex.trylock(c, false));
664  return;
665  }
666  case DihContinueB::ZDELAY_RELEASE_FRAGMENT_INFO_MUTEX:
667  {
668  jam();
670  mh.setHandle(signal->theData[1]);
671  Mutex mutex(signal, c_mutexMgr, mh);
672  mutex.unlock();
673  return;
674  }
675  case DihContinueB::ZTO_START_LOGGING:
676  {
677  jam();
678  TakeOverRecordPtr takeOverPtr;
679  c_takeOverPool.getPtr(takeOverPtr, signal->theData[1]);
680  nr_start_logging(signal, takeOverPtr);
681  return;
682  }
683  case DihContinueB::ZGET_TABINFO:
684  {
685  jam();
686  getTabInfo(signal);
687  return;
688  }
689  case DihContinueB::ZGET_TABINFO_SEND:
690  {
691  jam();
692  TabRecordPtr tabPtr;
693  jam();
694  tabPtr.i = signal->theData[1];
695  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
696  getTabInfo_send(signal, tabPtr);
697  return;
698  }
699  }
700 
701  ndbrequire(false);
702  return;
703 }//Dbdih::execCONTINUEB()
704 
705 void Dbdih::execCOPY_GCIREQ(Signal* signal)
706 {
707  CopyGCIReq * const copyGCI = (CopyGCIReq *)&signal->theData[0];
708  jamEntry();
709  CopyGCIReq::CopyReason reason = (CopyGCIReq::CopyReason)copyGCI->copyReason;
710  const Uint32 tstart = copyGCI->startWord;
711 
712  ndbrequire(cmasterdihref == signal->senderBlockRef()) ;
713  ndbrequire((reason == CopyGCIReq::GLOBAL_CHECKPOINT &&
714  c_copyGCISlave.m_copyReason == CopyGCIReq::GLOBAL_CHECKPOINT) ||
715  c_copyGCISlave.m_copyReason == CopyGCIReq::IDLE);
716  ndbrequire(c_copyGCISlave.m_expectedNextWord == tstart);
717  ndbrequire(reason != CopyGCIReq::IDLE);
718  bool isdone = (tstart + CopyGCIReq::DATA_SIZE) >= Sysfile::SYSFILE_SIZE32;
719 
720  if (ERROR_INSERTED(7177))
721  {
722  jam();
723 
724  if (signal->getLength() == 3)
725  {
726  jam();
727  goto done;
728  }
729  }
730 
731  arrGuard(tstart + CopyGCIReq::DATA_SIZE, sizeof(sysfileData)/4);
732  for(Uint32 i = 0; i<CopyGCIReq::DATA_SIZE; i++)
733  cdata[tstart+i] = copyGCI->data[i];
734 
735  if (ERROR_INSERTED(7177) && isMaster() && isdone)
736  {
737  sendSignalWithDelay(reference(), GSN_COPY_GCIREQ, signal, 1000, 3);
738  return;
739  }
740 
741 done:
742  if (isdone)
743  {
744  jam();
745  c_copyGCISlave.m_expectedNextWord = 0;
746  }
747  else
748  {
749  jam();
750  c_copyGCISlave.m_expectedNextWord += CopyGCIReq::DATA_SIZE;
751  return;
752  }
753 
754  if (cmasterdihref != reference())
755  {
756  jam();
757  Uint32 tmp= SYSFILE->m_restart_seq;
758  memcpy(sysfileData, cdata, sizeof(sysfileData));
759  SYSFILE->m_restart_seq = tmp;
760 
761  if (c_set_initial_start_flag)
762  {
763  jam();
764  Sysfile::setInitialStartOngoing(SYSFILE->systemRestartBits);
765  }
766  }
767 
768  c_copyGCISlave.m_copyReason = reason;
769  c_copyGCISlave.m_senderRef = signal->senderBlockRef();
770  c_copyGCISlave.m_senderData = copyGCI->anyData;
771 
772  CRASH_INSERTION2(7020, reason==CopyGCIReq::LOCAL_CHECKPOINT);
773  CRASH_INSERTION2(7008, reason==CopyGCIReq::GLOBAL_CHECKPOINT);
774 
775  if (m_local_lcp_state.check_cut_log_tail(c_newest_restorable_gci))
776  {
777  jam();
778 
779 #if NOT_YET
780  LcpCompleteRep* rep = (LcpCompleteRep*)signal->getDataPtrSend();
781  rep->nodeId = getOwnNodeId();
782  rep->blockNo = 0;
783  rep->lcpId = m_local_lcp_state.m_start_lcp_req.lcpId;
784  rep->keepGci = m_local_lcp_state.m_keep_gci;
785  sendSignal(DBLQH_REF, GSN_LCP_COMPLETE_REP, signal,
786  LcpCompleteRep::SignalLength, JBB);
787 
788  warningEvent("CUT LOG TAIL: reason: %u lcp: %u m_keep_gci: %u stop: %u",
789  reason,
790  m_local_lcp_state.m_start_lcp_req.lcpId,
791  m_local_lcp_state.m_keep_gci,
792  m_local_lcp_state.m_stop_gci);
793 #endif
794  m_local_lcp_state.reset();
795  }
796 
797  /* -------------------------------------------------------------------------*/
798  /* WE SET THE REQUESTER OF THE COPY GCI TO THE CURRENT MASTER. IF THE */
799  /* CURRENT MASTER WE DO NOT WANT THE NEW MASTER TO RECEIVE CONFIRM OF */
800  /* SOMETHING HE HAS NOT SENT. THE TAKE OVER MUST BE CAREFUL. */
801  /* -------------------------------------------------------------------------*/
802  bool ok = false;
803  switch(reason){
804  case CopyGCIReq::IDLE:
805  ok = true;
806  jam();
807  ndbrequire(false);
808  break;
809  case CopyGCIReq::LOCAL_CHECKPOINT: {
810  ok = true;
811  jam();
812  c_lcpState.setLcpStatus(LCP_COPY_GCI, __LINE__);
813  c_lcpState.m_masterLcpDihRef = cmasterdihref;
814  setNodeActiveStatus();
815  break;
816  }
817  case CopyGCIReq::RESTART: {
818  ok = true;
819  jam();
820  Uint32 newest = SYSFILE->newestRestorableGCI;
821  m_micro_gcp.m_old_gci = Uint64(newest) << 32;
822  crestartGci = newest;
823  c_newest_restorable_gci = newest;
824  Sysfile::setRestartOngoing(SYSFILE->systemRestartBits);
825  m_micro_gcp.m_current_gci = Uint64(newest + 1) << 32;
826  setNodeActiveStatus();
827  setNodeGroups();
828  if ((Sysfile::getLCPOngoing(SYSFILE->systemRestartBits))) {
829  jam();
830  /* -------------------------------------------------------------------- */
831  // IF THERE WAS A LOCAL CHECKPOINT ONGOING AT THE CRASH MOMENT WE WILL
832  // INVALIDATE THAT LOCAL CHECKPOINT.
833  /* -------------------------------------------------------------------- */
834  invalidateLcpInfoAfterSr(signal);
835  }//if
836 
837  if (m_micro_gcp.m_enabled == false &&
838  m_micro_gcp.m_master.m_time_between_gcp)
839  {
843  jam();
844  m_micro_gcp.m_enabled = true;
845  UpgradeProtocolOrd * ord = (UpgradeProtocolOrd*)signal->getDataPtrSend();
846  ord->type = UpgradeProtocolOrd::UPO_ENABLE_MICRO_GCP;
847  EXECUTE_DIRECT(QMGR,GSN_UPGRADE_PROTOCOL_ORD,signal,signal->getLength());
848  }
849  break;
850  }
851  case CopyGCIReq::GLOBAL_CHECKPOINT: {
852  ok = true;
853  jam();
854 
855  if (m_gcp_save.m_state == GcpSave::GCP_SAVE_COPY_GCI)
856  {
857  jam();
861  ndbrequire(c_newest_restorable_gci == SYSFILE->newestRestorableGCI);
862  m_gcp_save.m_master_ref = c_copyGCISlave.m_senderRef;
863  return;
864  }
865 
866  if (c_newest_restorable_gci == SYSFILE->newestRestorableGCI)
867  {
868  jam();
869 
873  m_gcp_save.m_master_ref = c_copyGCISlave.m_senderRef;
874  c_copyGCISlave.m_copyReason = CopyGCIReq::IDLE;
875  signal->theData[0] = c_copyGCISlave.m_senderData;
876  sendSignal(m_gcp_save.m_master_ref, GSN_COPY_GCICONF, signal, 1, JBB);
877  return;
878  }
879 
880  ndbrequire(m_gcp_save.m_state == GcpSave::GCP_SAVE_CONF);
881  m_gcp_save.m_state = GcpSave::GCP_SAVE_COPY_GCI;
882  m_gcp_save.m_master_ref = c_copyGCISlave.m_senderRef;
883  c_newest_restorable_gci = SYSFILE->newestRestorableGCI;
884  setNodeActiveStatus();
885  break;
886  }//if
887  case CopyGCIReq::INITIAL_START_COMPLETED:
888  ok = true;
889  jam();
890  break;
891  case CopyGCIReq::RESTART_NR:
892  jam();
893  setNodeGroups();
897  c_copyGCISlave.m_copyReason = CopyGCIReq::IDLE;
898  signal->theData[0] = c_copyGCISlave.m_senderData;
899  sendSignal(c_copyGCISlave.m_senderRef, GSN_COPY_GCICONF, signal, 1, JBB);
900  return;
901  }
902  ndbrequire(ok);
903 
904  CRASH_INSERTION(7183);
905 
906  if (ERROR_INSERTED(7185) && reason==CopyGCIReq::GLOBAL_CHECKPOINT)
907  {
908  jam();
909  return;
910  }
911 #ifdef GCP_TIMER_HACK
912  if (reason == CopyGCIReq::GLOBAL_CHECKPOINT) {
913  jam();
914  NdbTick_getMicroTimer(&globalData.gcp_timer_copygci[0]);
915  }
916 #endif
917 
918  /* ----------------------------------------------------------------------- */
919  /* WE START BY TRYING TO OPEN THE FIRST RESTORABLE GCI FILE. */
920  /* ----------------------------------------------------------------------- */
921  FileRecordPtr filePtr;
922  filePtr.i = crestartInfoFile[0];
923  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
924  if (filePtr.p->fileStatus == FileRecord::OPEN) {
925  jam();
926  openingCopyGciSkipInitLab(signal, filePtr);
927  return;
928  }//if
929  openFileRw(signal, filePtr);
930  filePtr.p->reqStatus = FileRecord::OPENING_COPY_GCI;
931  return;
932 }//Dbdih::execCOPY_GCIREQ()
933 
934 void Dbdih::execDICTSTARTCONF(Signal* signal)
935 {
936  jamEntry();
937  Uint32 nodeId = refToNode(signal->getSendersBlockRef());
938  if (nodeId != getOwnNodeId()) {
939  jam();
940  nodeDictStartConfLab(signal);
941  } else {
942  jam();
943  dictStartConfLab(signal);
944  }//if
945 }//Dbdih::execDICTSTARTCONF()
946 
947 void Dbdih::execFSCLOSECONF(Signal* signal)
948 {
949  FileRecordPtr filePtr;
950  jamEntry();
951  filePtr.i = signal->theData[0];
952  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
953  filePtr.p->fileStatus = FileRecord::CLOSED;
954  FileRecord::ReqStatus status = filePtr.p->reqStatus;
955  filePtr.p->reqStatus = FileRecord::IDLE;
956  switch (status) {
957  case FileRecord::CLOSING_GCP:
958  jam();
959  closingGcpLab(signal, filePtr);
960  break;
961  case FileRecord::CLOSING_GCP_CRASH:
962  jam();
963  closingGcpCrashLab(signal, filePtr);
964  break;
965  case FileRecord::CLOSING_TABLE_CRASH:
966  jam();
967  closingTableCrashLab(signal, filePtr);
968  break;
969  case FileRecord::CLOSING_TABLE_SR:
970  jam();
971  closingTableSrLab(signal, filePtr);
972  break;
973  case FileRecord::TABLE_CLOSE:
974  jam();
975  tableCloseLab(signal, filePtr);
976  break;
977  case FileRecord::TABLE_CLOSE_DELETE:
978  jam();
979  tableDeleteLab(signal, filePtr);
980  break;
981  default:
982  ndbrequire(false);
983  break;
984  }//switch
985  return;
986 }//Dbdih::execFSCLOSECONF()
987 
988 void Dbdih::execFSCLOSEREF(Signal* signal)
989 {
990  FileRecordPtr filePtr;
991  jamEntry();
992  filePtr.i = signal->theData[0];
993  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
994  FileRecord::ReqStatus status = filePtr.p->reqStatus;
995  filePtr.p->reqStatus = FileRecord::IDLE;
996  switch (status) {
997  case FileRecord::CLOSING_GCP:
998  jam();
999  break;
1000  case FileRecord::CLOSING_GCP_CRASH:
1001  jam();
1002  closingGcpCrashLab(signal, filePtr);
1003  return;
1004  case FileRecord::CLOSING_TABLE_CRASH:
1005  jam();
1006  closingTableCrashLab(signal, filePtr);
1007  return;
1008  case FileRecord::CLOSING_TABLE_SR:
1009  jam();
1010  break;
1011  case FileRecord::TABLE_CLOSE:
1012  jam();
1013  break;
1014  case FileRecord::TABLE_CLOSE_DELETE:
1015  jam();
1016  break;
1017  default:
1018  jam();
1019  break;
1020 
1021  }//switch
1022  {
1023  char msg[100];
1024  sprintf(msg, "File system close failed during FileRecord status %d", (Uint32)status);
1025  fsRefError(signal,__LINE__,msg);
1026  }
1027  return;
1028 }//Dbdih::execFSCLOSEREF()
1029 
1030 void Dbdih::execFSOPENCONF(Signal* signal)
1031 {
1032  FileRecordPtr filePtr;
1033  jamEntry();
1034  filePtr.i = signal->theData[0];
1035  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
1036  filePtr.p->fileRef = signal->theData[1];
1037  filePtr.p->fileStatus = FileRecord::OPEN;
1038  FileRecord::ReqStatus status = filePtr.p->reqStatus;
1039  filePtr.p->reqStatus = FileRecord::IDLE;
1040  switch (status) {
1041  case FileRecord::CREATING_GCP:
1042  jam();
1043  creatingGcpLab(signal, filePtr);
1044  break;
1045  case FileRecord::OPENING_COPY_GCI:
1046  jam();
1047  openingCopyGciSkipInitLab(signal, filePtr);
1048  break;
1049  case FileRecord::CREATING_COPY_GCI:
1050  jam();
1051  openingCopyGciSkipInitLab(signal, filePtr);
1052  break;
1053  case FileRecord::OPENING_GCP:
1054  jam();
1055  openingGcpLab(signal, filePtr);
1056  break;
1057  case FileRecord::OPENING_TABLE:
1058  jam();
1059  openingTableLab(signal, filePtr);
1060  break;
1061  case FileRecord::TABLE_CREATE:
1062  jam();
1063  tableCreateLab(signal, filePtr);
1064  break;
1065  case FileRecord::TABLE_OPEN_FOR_DELETE:
1066  jam();
1067  tableOpenLab(signal, filePtr);
1068  break;
1069  default:
1070  ndbrequire(false);
1071  break;
1072  }//switch
1073  return;
1074 }//Dbdih::execFSOPENCONF()
1075 
1076 void Dbdih::execFSOPENREF(Signal* signal)
1077 {
1078  FileRecordPtr filePtr;
1079  jamEntry();
1080  filePtr.i = signal->theData[0];
1081  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
1082  FileRecord::ReqStatus status = filePtr.p->reqStatus;
1083  filePtr.p->reqStatus = FileRecord::IDLE;
1084  switch (status) {
1085  case FileRecord::CREATING_GCP:
1086  /* --------------------------------------------------------------------- */
1087  /* WE DID NOT MANAGE TO CREATE A GLOBAL CHECKPOINT FILE. SERIOUS ERROR */
1088  /* WHICH CAUSES A SYSTEM RESTART. */
1089  /* --------------------------------------------------------------------- */
1090  jam();
1091  break;
1092  case FileRecord::OPENING_COPY_GCI:
1093  jam();
1094  openingCopyGciErrorLab(signal, filePtr);
1095  return;
1096  case FileRecord::CREATING_COPY_GCI:
1097  jam();
1098  break;
1099  case FileRecord::OPENING_GCP:
1100  jam();
1101  openingGcpErrorLab(signal, filePtr);
1102  return;
1103  case FileRecord::OPENING_TABLE:
1104  jam();
1105  openingTableErrorLab(signal, filePtr);
1106  return;
1107  case FileRecord::TABLE_CREATE:
1108  jam();
1109  break;
1110  case FileRecord::TABLE_OPEN_FOR_DELETE:
1111  jam();
1112  tableDeleteLab(signal, filePtr);
1113  return;
1114  default:
1115  jam();
1116  break;
1117  }//switch
1118  {
1119  char msg[100];
1120  sprintf(msg, "File system open failed during FileRecord status %d", (Uint32)status);
1121  fsRefError(signal,__LINE__,msg);
1122  }
1123  return;
1124 }//Dbdih::execFSOPENREF()
1125 
1126 void Dbdih::execFSREADCONF(Signal* signal)
1127 {
1128  FileRecordPtr filePtr;
1129  jamEntry();
1130  filePtr.i = signal->theData[0];
1131  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
1132  FileRecord::ReqStatus status = filePtr.p->reqStatus;
1133  filePtr.p->reqStatus = FileRecord::IDLE;
1134  switch (status) {
1135  case FileRecord::READING_GCP:
1136  jam();
1137  readingGcpLab(signal, filePtr);
1138  break;
1139  case FileRecord::READING_TABLE:
1140  jam();
1141  readingTableLab(signal, filePtr);
1142  break;
1143  default:
1144  ndbrequire(false);
1145  break;
1146  }//switch
1147  return;
1148 }//Dbdih::execFSREADCONF()
1149 
1150 void Dbdih::execFSREADREF(Signal* signal)
1151 {
1152  FileRecordPtr filePtr;
1153  jamEntry();
1154  filePtr.i = signal->theData[0];
1155  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
1156  FileRecord::ReqStatus status = filePtr.p->reqStatus;
1157  filePtr.p->reqStatus = FileRecord::IDLE;
1158  switch (status) {
1159  case FileRecord::READING_GCP:
1160  jam();
1161  readingGcpErrorLab(signal, filePtr);
1162  return;
1163  case FileRecord::READING_TABLE:
1164  jam();
1165  readingTableErrorLab(signal, filePtr);
1166  return;
1167  default:
1168  break;
1169  }//switch
1170  {
1171  char msg[100];
1172  sprintf(msg, "File system read failed during FileRecord status %d", (Uint32)status);
1173  fsRefError(signal,__LINE__,msg);
1174  }
1175 }//Dbdih::execFSREADREF()
1176 
1177 void Dbdih::execFSWRITECONF(Signal* signal)
1178 {
1179  FileRecordPtr filePtr;
1180  jamEntry();
1181  filePtr.i = signal->theData[0];
1182  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
1183  FileRecord::ReqStatus status = filePtr.p->reqStatus;
1184  filePtr.p->reqStatus = FileRecord::IDLE;
1185  switch (status) {
1186  case FileRecord::WRITING_COPY_GCI:
1187  jam();
1188  writingCopyGciLab(signal, filePtr);
1189  break;
1190  case FileRecord::WRITE_INIT_GCP:
1191  jam();
1192  writeInitGcpLab(signal, filePtr);
1193  break;
1194  case FileRecord::TABLE_WRITE:
1195  jam();
1196  tableWriteLab(signal, filePtr);
1197  break;
1198  default:
1199  ndbrequire(false);
1200  break;
1201  }//switch
1202  return;
1203 }//Dbdih::execFSWRITECONF()
1204 
1205 void Dbdih::execFSWRITEREF(Signal* signal)
1206 {
1207  FileRecordPtr filePtr;
1208  jamEntry();
1209  filePtr.i = signal->theData[0];
1210  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
1211  FileRecord::ReqStatus status = filePtr.p->reqStatus;
1212  filePtr.p->reqStatus = FileRecord::IDLE;
1213  switch (status) {
1214  case FileRecord::WRITING_COPY_GCI:
1215  /* --------------------------------------------------------------------- */
1216  /* EVEN CREATING THE FILE DID NOT WORK. WE WILL THEN CRASH. */
1217  /* ERROR IN WRITING FILE. WE WILL NOT CONTINUE FROM HERE. */
1218  /* --------------------------------------------------------------------- */
1219  jam();
1220  break;
1221  case FileRecord::WRITE_INIT_GCP:
1222  /* --------------------------------------------------------------------- */
1223  /* AN ERROR OCCURRED IN WRITING A GCI FILE WHICH IS A SERIOUS ERROR */
1224  /* THAT CAUSE A SYSTEM RESTART. */
1225  /* --------------------------------------------------------------------- */
1226  jam();
1227  break;
1228  case FileRecord::TABLE_WRITE:
1229  jam();
1230  break;
1231  default:
1232  jam();
1233  break;
1234  }//switch
1235  {
1236  char msg[100];
1237  sprintf(msg, "File system write failed during FileRecord status %d", (Uint32)status);
1238  fsRefError(signal,__LINE__,msg);
1239  }
1240  return;
1241 }//Dbdih::execFSWRITEREF()
1242 
1243 void Dbdih::execGETGCIREQ(Signal* signal)
1244 {
1245 
1246  jamEntry();
1247  Uint32 userPtr = signal->theData[0];
1248  BlockReference userRef = signal->theData[1];
1249  Uint32 type = signal->theData[2];
1250 
1251  Uint32 gci_hi = 0;
1252  Uint32 gci_lo = 0;
1253  switch(type){
1254  case 0:
1255  jam();
1256  gci_hi = SYSFILE->newestRestorableGCI;
1257  break;
1258  case 1:
1259  jam();
1260  gci_hi = Uint32(m_micro_gcp.m_current_gci >> 32);
1261  gci_lo = Uint32(m_micro_gcp.m_current_gci);
1262  break;
1263  }
1264 
1265  signal->theData[0] = userPtr;
1266  signal->theData[1] = gci_hi;
1267  signal->theData[2] = gci_lo;
1268 
1269  if (userRef)
1270  {
1271  jam();
1272  sendSignal(userRef, GSN_GETGCICONF, signal, 3, JBB);
1273  }
1274  else
1275  {
1276  jam();
1277  // Execute direct
1278  }
1279 }//Dbdih::execGETGCIREQ()
1280 
1281 void Dbdih::execREAD_CONFIG_REQ(Signal* signal)
1282 {
1283  const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
1284  Uint32 ref = req->senderRef;
1285  Uint32 senderData = req->senderData;
1286  ndbrequire(req->noOfParameters == 0);
1287 
1288  jamEntry();
1289 
1290  const ndb_mgm_configuration_iterator * p =
1291  m_ctx.m_config.getOwnConfigIterator();
1292  ndbrequireErr(p != 0, NDBD_EXIT_INVALID_CONFIG);
1293 
1294  initData();
1295 
1296  cconnectFileSize = 256; // Only used for DDL
1297 
1298  ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_API_CONNECT,
1299  &capiConnectFileSize),
1300  NDBD_EXIT_INVALID_CONFIG);
1301  capiConnectFileSize++; // Increase by 1...so that srsw queue never gets full
1302 
1303  ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_FRAG_CONNECT,
1304  &cfragstoreFileSize),
1305  NDBD_EXIT_INVALID_CONFIG);
1306  ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_REPLICAS,
1307  &creplicaFileSize),
1308  NDBD_EXIT_INVALID_CONFIG);
1309  ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_TABLE, &ctabFileSize),
1310  NDBD_EXIT_INVALID_CONFIG);
1311 
1312  if (isNdbMtLqh())
1313  {
1314  jam();
1315  c_fragments_per_node = getLqhWorkers();
1316  // try to get some LQH workers which initially handle no fragments
1317  if (ERROR_INSERTED(7215)) {
1318  c_fragments_per_node = 1;
1319  }
1320  }
1321  ndbout_c("Using %u fragments per node", c_fragments_per_node);
1322 
1323  ndb_mgm_get_int_parameter(p, CFG_DB_LCP_TRY_LOCK_TIMEOUT,
1324  &c_lcpState.m_lcp_trylock_timeout);
1325 
1326  cfileFileSize = (2 * ctabFileSize) + 2;
1327  initRecords();
1328  initialiseRecordsLab(signal, 0, ref, senderData);
1329 
1330  {
1331  Uint32 val = 0;
1332  ndb_mgm_get_int_parameter(p, CFG_DB_2PASS_INR,
1333  &val);
1334  c_2pass_inr = val ? true : false;
1335  }
1336 
1340  {
1341  NodeRecordPtr nodePtr;
1342  for (nodePtr.i = 0; nodePtr.i < MAX_NDB_NODES; nodePtr.i++)
1343  {
1344  ptrAss(nodePtr, nodeRecord);
1345  new (nodePtr.p) NodeRecord();
1346  nodePtr.p->nodeGroup = RNIL;
1347  }
1348 
1350  m_ctx.m_config.getClusterConfigIterator();
1351  for(ndb_mgm_first(iter); ndb_mgm_valid(iter); ndb_mgm_next(iter))
1352  {
1353  jam();
1354  Uint32 nodeId;
1355  Uint32 nodeType;
1356 
1357  ndbrequire(!ndb_mgm_get_int_parameter(iter,CFG_NODE_ID, &nodeId));
1358  ndbrequire(!ndb_mgm_get_int_parameter(iter,CFG_TYPE_OF_SECTION,
1359  &nodeType));
1360 
1361  if (nodeType == NodeInfo::DB)
1362  {
1363  jam();
1364  Uint32 ng;
1365  nodePtr.i = nodeId;
1366  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
1367  if (ndb_mgm_get_int_parameter(iter, CFG_DB_NODEGROUP, &ng) == 0)
1368  {
1369  jam();
1370  nodePtr.p->nodeGroup = ng;
1371  }
1372  else
1373  {
1374  jam();
1375  nodePtr.p->nodeGroup = RNIL;
1376  }
1377  }
1378  }
1379  }
1380  return;
1381 }//Dbdih::execSIZEALT_REP()
1382 
1383 void Dbdih::execSTART_COPYREF(Signal* signal)
1384 {
1385  jamEntry();
1386  ndbrequire(false);
1387 }//Dbdih::execSTART_COPYREF()
1388 
1389 void Dbdih::execSTART_FRAGCONF(Signal* signal)
1390 {
1391  (void)signal; // Don't want compiler warning
1392  /* ********************************************************************* */
1393  /* If anyone wants to add functionality in this method, be aware that */
1394  /* for temporary tables no START_FRAGREQ is sent and therefore no */
1395  /* START_FRAGCONF signal will be received for those tables!! */
1396  /* ********************************************************************* */
1397  jamEntry();
1398  return;
1399 }//Dbdih::execSTART_FRAGCONF()
1400 
1401 void Dbdih::execSTART_FRAGREF(Signal* signal)
1402 {
1403  jamEntry();
1404 
1408  Uint32 errCode = signal->theData[1];
1409  Uint32 nodeId = signal->theData[2];
1410 
1411  SystemError * const sysErr = (SystemError*)&signal->theData[0];
1412  sysErr->errorCode = SystemError::StartFragRefError;
1413  sysErr->errorRef = reference();
1414  sysErr->data[0] = errCode;
1415  sysErr->data[1] = 0;
1416  sendSignal(calcNdbCntrBlockRef(nodeId), GSN_SYSTEM_ERROR, signal,
1417  SystemError::SignalLength, JBB);
1418  return;
1419 }//Dbdih::execSTART_FRAGCONF()
1420 
1421 void Dbdih::execSTART_MEREF(Signal* signal)
1422 {
1423  jamEntry();
1424  ndbrequire(false);
1425 }//Dbdih::execSTART_MEREF()
1426 
1427 void Dbdih::execTAB_COMMITREQ(Signal* signal)
1428 {
1429  TabRecordPtr tabPtr;
1430  jamEntry();
1431  Uint32 tdictPtr = signal->theData[0];
1432  BlockReference tdictBlockref = signal->theData[1];
1433  tabPtr.i = signal->theData[2];
1434  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
1435 
1436  ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_CREATING);
1437  tabPtr.p->tabStatus = TabRecord::TS_ACTIVE;
1438  tabPtr.p->schemaTransId = 0;
1439  signal->theData[0] = tdictPtr;
1440  signal->theData[1] = cownNodeId;
1441  signal->theData[2] = tabPtr.i;
1442  sendSignal(tdictBlockref, GSN_TAB_COMMITCONF, signal, 3, JBB);
1443  return;
1444 }//Dbdih::execTAB_COMMITREQ()
1445 
1446 /*
1447  3.2 S T A N D A R D S U B P R O G R A M S I N P L E X
1448  *************************************************************
1449  */
1450 /*
1451  3.2.1 S T A R T / R E S T A R T
1452  **********************************
1453  */
1454 /*****************************************************************************/
1455 /* ********** START / RESTART MODULE *************/
1456 /*****************************************************************************/
1457 /*
1458  3.2.1.1 LOADING O W N B L O C K R E F E R E N C E (ABSOLUTE PHASE 1)
1459  *****************************************************************************
1460  */
1461 void Dbdih::execDIH_RESTARTREQ(Signal* signal)
1462 {
1463  jamEntry();
1464  const DihRestartReq* req = CAST_CONSTPTR(DihRestartReq,
1465  signal->getDataPtr());
1466  if (req->senderRef != 0)
1467  {
1468  jam();
1469  cntrlblockref = req->senderRef;
1470  if(m_ctx.m_config.getInitialStart())
1471  {
1472  sendDihRestartRef(signal);
1473  } else {
1474  readGciFileLab(signal);
1475  }
1476  }
1477  else
1478  {
1483  Uint32 i;
1484  NdbNodeBitmask mask;
1485  mask.assign(NdbNodeBitmask::Size, req->nodemask);
1486  const Uint32 *node_gcis = req->node_gcis;
1487  Uint32 node_group_gcis[MAX_NDB_NODES+1];
1488  memset(node_group_gcis, 0, sizeof(node_group_gcis));
1489  for (i = 0; i<MAX_NDB_NODES; i++)
1490  {
1491  if (mask.get(i))
1492  {
1493  jam();
1494  Uint32 ng = Sysfile::getNodeGroup(i, SYSFILE->nodeGroups);
1495  if (ng != NO_NODE_GROUP_ID)
1496  {
1497  ndbrequire(ng < MAX_NDB_NODES);
1498  Uint32 gci = node_gcis[i];
1499  if (gci < SYSFILE->lastCompletedGCI[i])
1500  {
1501  jam();
1507  gci = SYSFILE->lastCompletedGCI[i];
1508  }
1509 
1510  if (gci > node_group_gcis[ng])
1511  {
1512  jam();
1513  node_group_gcis[ng] = gci;
1514  }
1515  }
1516  }
1517  }
1518  for (i = 0; i<MAX_NDB_NODES && node_group_gcis[i] == 0; i++);
1519 
1520  Uint32 gci = node_group_gcis[i];
1521  for (i++ ; i<MAX_NDB_NODES; i++)
1522  {
1523  jam();
1524  if (node_group_gcis[i] && node_group_gcis[i] != gci)
1525  {
1526  jam();
1527  signal->theData[0] = i;
1528  return;
1529  }
1530  }
1531  signal->theData[0] = MAX_NDB_NODES;
1532  return;
1533  }
1534  return;
1535 }//Dbdih::execDIH_RESTARTREQ()
1536 
1537 void Dbdih::execSTTOR(Signal* signal)
1538 {
1539  jamEntry();
1540 
1541  Callback c = { safe_cast(&Dbdih::sendSTTORRY), 0 };
1542  m_sendSTTORRY = c;
1543 
1544  switch(signal->theData[1]){
1545  case 1:
1546  createMutexes(signal, 0);
1547  return;
1548  case 2:
1549  break;
1550  case 3:
1551  signal->theData[0] = reference();
1552  sendSignal(NDBCNTR_REF, GSN_READ_NODESREQ, signal, 1, JBB);
1553  return;
1554  }
1555 
1556  sendSTTORRY(signal);
1557 }//Dbdih::execSTTOR()
1558 
1559 void
1560 Dbdih::sendSTTORRY(Signal* signal, Uint32 senderData, Uint32 retVal)
1561 {
1562  signal->theData[0] = 0;
1563  signal->theData[1] = 0;
1564  signal->theData[2] = 0;
1565  signal->theData[3] = 1; // Next start phase
1566  signal->theData[4] = 2; // Next start phase
1567  signal->theData[5] = 3;
1568  signal->theData[6] = 255; // Next start phase
1569  sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 7, JBB);
1570  return;
1571 }
1572 
1573 void Dbdih::initialStartCompletedLab(Signal* signal)
1574 {
1575  /*-------------------------------------------------------------------------*/
1576  /* NOW THAT (RE)START IS COMPLETED WE CAN START THE LCP.*/
1577  /*-------------------------------------------------------------------------*/
1578  return;
1579 }//Dbdih::initialStartCompletedLab()
1580 
1581 /*
1582  * ***************************************************************************
1583  * S E N D I N G R E P L Y T O S T A R T / R E S T A R T R E Q U E S T S
1584  * ****************************************************************************
1585  */
1586 void Dbdih::ndbsttorry10Lab(Signal* signal, Uint32 _line)
1587 {
1588  /*-------------------------------------------------------------------------*/
1589  // AN NDB START PHASE HAS BEEN COMPLETED. WHEN START PHASE 6 IS COMPLETED WE
1590  // RECORD THAT THE SYSTEM IS RUNNING.
1591  /*-------------------------------------------------------------------------*/
1592  signal->theData[0] = reference();
1593  sendSignal(cntrlblockref, GSN_NDB_STTORRY, signal, 1, JBB);
1594  return;
1595 }//Dbdih::ndbsttorry10Lab()
1596 
1597 /*
1598 ****************************************
1599 I N T E R N A L P H A S E S
1600 ****************************************
1601 */
1602 /*---------------------------------------------------------------------------*/
1603 /*NDB_STTOR START SIGNAL AT START/RESTART */
1604 /*---------------------------------------------------------------------------*/
1605 void Dbdih::execNDB_STTOR(Signal* signal)
1606 {
1607  jamEntry();
1608  BlockReference cntrRef = signal->theData[0]; /* SENDERS BLOCK REFERENCE */
1609  Uint32 ownNodeId = signal->theData[1]; /* OWN PROCESSOR ID*/
1610  Uint32 phase = signal->theData[2]; /* INTERNAL START PHASE*/
1611  Uint32 typestart = signal->theData[3];
1612 
1613  cstarttype = typestart;
1614  cstartPhase = phase;
1615 
1616  switch (phase){
1617  case ZNDB_SPH1:
1618  jam();
1619  /*----------------------------------------------------------------------*/
1620  /* Set the delay between local checkpoints in ndb startphase 1. */
1621  /*----------------------------------------------------------------------*/
1622  cownNodeId = ownNodeId;
1623  /*-----------------------------------------------------------------------*/
1624  // Compute all static block references in this node as part of
1625  // ndb start phase 1.
1626  /*-----------------------------------------------------------------------*/
1627  cntrlblockref = cntrRef;
1628  clocaltcblockref = calcTcBlockRef(ownNodeId);
1629  clocallqhblockref = calcLqhBlockRef(ownNodeId);
1630  cdictblockref = calcDictBlockRef(ownNodeId);
1631  ndbsttorry10Lab(signal, __LINE__);
1632  break;
1633 
1634  case ZNDB_SPH2:
1635  jam();
1636  /*-----------------------------------------------------------------------*/
1637  // Set the number of replicas, maximum is 4 replicas.
1638  // Read the ndb nodes from the configuration.
1639  /*-----------------------------------------------------------------------*/
1640 
1641  /*-----------------------------------------------------------------------*/
1642  // For node restarts we will also add a request for permission
1643  // to continue the system restart.
1644  // The permission is given by the master node in the alive set.
1645  /*-----------------------------------------------------------------------*/
1646  if (cstarttype == NodeState::ST_INITIAL_NODE_RESTART)
1647  {
1648  jam();
1649  c_set_initial_start_flag = TRUE; // In sysfile...
1650  }
1651 
1652  if (cstarttype == NodeState::ST_INITIAL_START) {
1653  jam();
1654  // setInitialActiveStatus is moved into makeNodeGroups
1655  } else if (cstarttype == NodeState::ST_SYSTEM_RESTART) {
1656  jam();
1657  /*empty*/;
1658  } else if ((cstarttype == NodeState::ST_NODE_RESTART) ||
1659  (cstarttype == NodeState::ST_INITIAL_NODE_RESTART)) {
1660  jam();
1661  nodeRestartPh2Lab(signal);
1662  return;
1663  } else {
1664  ndbrequire(false);
1665  }//if
1666  ndbsttorry10Lab(signal, __LINE__);
1667  return;
1668 
1669  case ZNDB_SPH3:
1670  jam();
1671  /*-----------------------------------------------------------------------*/
1672  // Non-master nodes performing an initial start will execute
1673  // the start request here since the
1674  // initial start do not synchronise so much from the master.
1675  // In the master nodes the start
1676  // request will be sent directly to dih (in ndb_startreq) when all
1677  // nodes have completed phase 3 of the start.
1678  /*-----------------------------------------------------------------------*/
1679  cmasterState = MASTER_IDLE;
1680  if(cstarttype == NodeState::ST_INITIAL_START ||
1681  cstarttype == NodeState::ST_SYSTEM_RESTART){
1682  jam();
1683  cmasterState = isMaster() ? MASTER_ACTIVE : MASTER_IDLE;
1684  }
1685  if (!isMaster() && cstarttype == NodeState::ST_INITIAL_START) {
1686  jam();
1687  ndbStartReqLab(signal, cntrRef);
1688  return;
1689  }//if
1690  ndbsttorry10Lab(signal, __LINE__);
1691  break;
1692 
1693  case ZNDB_SPH4:
1694  jam();
1695  c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
1696  cmasterTakeOverNode = ZNIL;
1697  switch(typestart){
1698  case NodeState::ST_INITIAL_START:
1699  jam();
1700  ndbsttorry10Lab(signal, __LINE__);
1701  return;
1702  case NodeState::ST_SYSTEM_RESTART:
1703  jam();
1704  ndbsttorry10Lab(signal, __LINE__);
1705  return;
1706  case NodeState::ST_INITIAL_NODE_RESTART:
1707  case NodeState::ST_NODE_RESTART:
1708  jam();
1709 
1710  /***********************************************************************
1711  * When starting nodes while system is operational we must be controlled
1712  * by the master since only one node restart is allowed at a time.
1713  * When this signal is confirmed the master has also copied the
1714  * dictionary and the distribution information.
1715  */
1716  StartMeReq * req = (StartMeReq*)&signal->theData[0];
1717  req->startingRef = reference();
1718  req->startingVersion = 0; // Obsolete
1719  sendSignal(cmasterdihref, GSN_START_MEREQ, signal,
1720  StartMeReq::SignalLength, JBB);
1721  return;
1722  }
1723  ndbrequire(false);
1724  break;
1725  case ZNDB_SPH5:
1726  jam();
1727  if (m_gcp_monitor.m_micro_gcp.m_max_lag > 0)
1728  {
1729  infoEvent("GCP Monitor: Computed max GCP_SAVE lag to %u seconds",
1730  m_gcp_monitor.m_gcp_save.m_max_lag / 10);
1731  infoEvent("GCP Monitor: Computed max GCP_COMMIT lag to %u seconds",
1732  m_gcp_monitor.m_micro_gcp.m_max_lag / 10);
1733  }
1734  else
1735  {
1736  infoEvent("GCP Monitor: unlimited lags allowed");
1737  }
1738  switch(typestart){
1739  case NodeState::ST_INITIAL_START:
1740  case NodeState::ST_SYSTEM_RESTART:
1741  jam();
1742  jam();
1743  /*---------------------------------------------------------------------*/
1744  // WE EXECUTE A LOCAL CHECKPOINT AS A PART OF A SYSTEM RESTART.
1745  // THE IDEA IS THAT WE NEED TO
1746  // ENSURE THAT WE CAN RECOVER FROM PROBLEMS CAUSED BY MANY NODE
1747  // CRASHES THAT CAUSES THE LOG
1748  // TO GROW AND THE NUMBER OF LOG ROUNDS TO EXECUTE TO GROW.
1749  // THIS CAN OTHERWISE GET US INTO
1750  // A SITUATION WHICH IS UNREPAIRABLE. THUS WE EXECUTE A CHECKPOINT
1751  // BEFORE ALLOWING ANY TRANSACTIONS TO START.
1752  /*---------------------------------------------------------------------*/
1753  if (!isMaster()) {
1754  jam();
1755  ndbsttorry10Lab(signal, __LINE__);
1756  return;
1757  }//if
1758 
1759  c_lcpState.immediateLcpStart = true;
1760  cwaitLcpSr = true;
1761  checkLcpStart(signal, __LINE__);
1762  return;
1763  case NodeState::ST_NODE_RESTART:
1764  case NodeState::ST_INITIAL_NODE_RESTART:
1765  jam();
1766  {
1767  StartCopyReq* req = (StartCopyReq*)signal->getDataPtrSend();
1768  req->senderRef = reference();
1769  req->senderData = RNIL;
1770  req->flags = StartCopyReq::WAIT_LCP;
1771  req->startingNodeId = getOwnNodeId();
1772  if (!ndb_pnr(getNodeInfo(refToNode(cmasterdihref)).m_version))
1773  {
1774  jam();
1775  infoEvent("Detecting upgrade: Master(%u) does not support parallel node recovery",
1776  refToNode(cmasterdihref));
1777  sendSignal(cmasterdihref, GSN_START_COPYREQ, signal,
1778  StartCopyReq::SignalLength, JBB);
1779  }
1780  else
1781  {
1782  sendSignal(reference(), GSN_START_COPYREQ, signal,
1783  StartCopyReq::SignalLength, JBB);
1784  }
1785  }
1786  return;
1787  }
1788  ndbrequire(false);
1789  case ZNDB_SPH6:
1790  jam();
1791  switch(typestart){
1792  case NodeState::ST_INITIAL_START:
1793  case NodeState::ST_SYSTEM_RESTART:
1794  jam();
1795  if(isMaster()){
1796  jam();
1797  startGcp(signal);
1798  }
1799  ndbsttorry10Lab(signal, __LINE__);
1800  return;
1801  case NodeState::ST_NODE_RESTART:
1802  case NodeState::ST_INITIAL_NODE_RESTART:
1803  ndbsttorry10Lab(signal, __LINE__);
1804  return;
1805  }
1806  ndbrequire(false);
1807  break;
1808  default:
1809  jam();
1810  ndbsttorry10Lab(signal, __LINE__);
1811  break;
1812  }//switch
1813 }//Dbdih::execNDB_STTOR()
1814 
1815 void
1816 Dbdih::execNODE_START_REP(Signal* signal)
1817 {
1818  /*
1819  * Send DICT_UNLOCK_ORD when this node is SL_STARTED.
1820  *
1821  * Sending it before (sp 7) conflicts with code which assumes
1822  * SL_STARTING means we are in copy phase of NR.
1823  *
1824  * NodeState::starting.restartType is not supposed to be used
1825  * when SL_STARTED. Also it seems NODE_START_REP can arrive twice.
1826  *
1827  * For these reasons there are no consistency checks and
1828  * we rely on c_dictLockSlavePtrI_nodeRestart alone.
1829  */
1830  if (signal->theData[0] == getOwnNodeId())
1831  {
1836  jam();
1837  if (c_dictLockSlavePtrI_nodeRestart != RNIL) {
1838  sendDictUnlockOrd(signal, c_dictLockSlavePtrI_nodeRestart);
1839  c_dictLockSlavePtrI_nodeRestart = RNIL;
1840  }
1841  }
1842 }
1843 
1844 void
1845 Dbdih::createMutexes(Signal * signal, Uint32 count){
1846  Callback c = { safe_cast(&Dbdih::createMutex_done), count };
1847 
1848  switch(count){
1849  case 0:{
1850  Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
1851  mutex.create(c);
1852  return;
1853  }
1854  case 1:{
1855  Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
1856  mutex.create(c);
1857  return;
1858  }
1859  case 2:{
1860  Mutex mutex(signal, c_mutexMgr, c_fragmentInfoMutex_lcp);
1861  mutex.create(c);
1862  return;
1863  }
1864  }
1865 
1866  execute(signal, m_sendSTTORRY, 0);
1867 }
1868 
1869 void
1870 Dbdih::createMutex_done(Signal* signal, Uint32 senderData, Uint32 retVal){
1871  jamEntry();
1872  ndbrequire(retVal == 0);
1873 
1874  switch(senderData){
1875  case 0:{
1876  Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
1877  mutex.release();
1878  break;
1879  }
1880  case 1:{
1881  Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
1882  mutex.release();
1883  break;
1884  }
1885  case 2:{
1886  Mutex mutex(signal, c_mutexMgr, c_fragmentInfoMutex_lcp);
1887  mutex.release();
1888  break;
1889  }
1890  }
1891 
1892  createMutexes(signal, senderData + 1);
1893 }
1894 
1895 /*****************************************************************************/
1896 /* ------------------------------------------------------------------------- */
1897 /* WE HAVE BEEN REQUESTED BY NDBCNTR TO PERFORM A RESTART OF THE */
1898 /* DATABASE TABLES. */
1899 /* THIS SIGNAL IS SENT AFTER COMPLETING PHASE 3 IN ALL BLOCKS IN A */
1900 /* SYSTEM RESTART. WE WILL ALSO JUMP TO THIS LABEL FROM PHASE 3 IN AN */
1901 /* INITIAL START. */
1902 /* ------------------------------------------------------------------------- */
1903 /*****************************************************************************/
1904 void Dbdih::execNDB_STARTREQ(Signal* signal)
1905 {
1906  jamEntry();
1907  BlockReference ref = signal->theData[0];
1908  cstarttype = signal->theData[1];
1909  ndbStartReqLab(signal, ref);
1910 }//Dbdih::execNDB_STARTREQ()
1911 
1912 void Dbdih::ndbStartReqLab(Signal* signal, BlockReference ref)
1913 {
1914  cndbStartReqBlockref = ref;
1915  if (cstarttype == NodeState::ST_INITIAL_START) {
1916  jam();
1917  initRestartInfo(signal);
1918  initGciFilesLab(signal);
1919  return;
1920  }
1921 
1922  NodeRecordPtr nodePtr;
1923  Uint32 gci = SYSFILE->lastCompletedGCI[getOwnNodeId()];
1924  for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++)
1925  {
1926  jam();
1927  ptrAss(nodePtr, nodeRecord);
1928  if (SYSFILE->lastCompletedGCI[nodePtr.i] > gci)
1929  {
1930  jam();
1938  SYSFILE->lastCompletedGCI[nodePtr.i] = 0;
1939  ndbrequire(nodePtr.p->nodeStatus != NodeRecord::ALIVE);
1940  warningEvent("Making filesystem for node %d unusable (need --initial)",
1941  nodePtr.i);
1942  }
1943  else if (nodePtr.p->nodeStatus == NodeRecord::ALIVE &&
1944  SYSFILE->lastCompletedGCI[nodePtr.i] == 0)
1945  {
1946  jam();
1947  CRASH_INSERTION(7170);
1948  char buf[255];
1949  BaseString::snprintf(buf, sizeof(buf),
1950  "Cluster requires this node to be started "
1951  " with --initial as partial start has been performed"
1952  " and this filesystem is unusable");
1953  progError(__LINE__,
1954  NDBD_EXIT_SR_RESTARTCONFLICT,
1955  buf);
1956  ndbrequire(false);
1957  }
1958  }
1959 
1963  SYSFILE->newestRestorableGCI = gci;
1964  infoEvent("Restarting cluster to GCI: %u", gci);
1965 
1966  ndbrequire(isMaster());
1967  copyGciLab(signal, CopyGCIReq::RESTART); // We have already read the file!
1968 }//Dbdih::ndbStartReqLab()
1969 
1970 void Dbdih::execREAD_NODESCONF(Signal* signal)
1971 {
1972  unsigned i;
1973  ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
1974  jamEntry();
1975  Uint32 nodeArray[MAX_NDB_NODES+1];
1976 
1977  csystemnodes = readNodes->noOfNodes;
1978  cmasterNodeId = readNodes->masterNodeId;
1979  unsigned index = 0;
1980  NdbNodeBitmask tmp; tmp.assign(2, readNodes->allNodes);
1981  for (i = 1; i < MAX_NDB_NODES; i++){
1982  jam();
1983  if(tmp.get(i)){
1984  jam();
1985  nodeArray[index] = i;
1986  if(NdbNodeBitmask::get(readNodes->inactiveNodes, i) == false){
1987  jam();
1988  con_lineNodes++;
1989  }//if
1990  index++;
1991  }//if
1992  }//for
1993  nodeArray[index] = RNIL; // terminate
1994 
1995  if (c_2pass_inr)
1996  {
1997  jam();
1998  Uint32 workers = getNodeInfo(getOwnNodeId()).m_lqh_workers;
1999  printf("Checking 2-pass initial node restart: ");
2000  for (i = 0; i<index; i++)
2001  {
2002  if (NdbNodeBitmask::get(readNodes->inactiveNodes, nodeArray[i]))
2003  continue;
2004 
2005  if (!ndbd_non_trans_copy_frag_req(getNodeInfo(nodeArray[i]).m_version))
2006  {
2007  jam();
2008  c_2pass_inr = false;
2009  printf("not ok (version node %u) => disabled\n", nodeArray[i]);
2010  break;
2011  }
2012 
2013  if (workers > 1 &&
2014  workers != getNodeInfo(nodeArray[i]).m_lqh_workers)
2015  {
2016  c_2pass_inr = false;
2017  printf("not ok (different worker cnt node %u) => disabled\n",
2018  nodeArray[i]);
2019  break;
2020  }
2021  }
2022  if (c_2pass_inr)
2023  printf("ok\n");
2024 
2032  }
2033 
2034  if(cstarttype == NodeState::ST_SYSTEM_RESTART ||
2035  cstarttype == NodeState::ST_NODE_RESTART)
2036  {
2037 
2038  for(i = 1; i<MAX_NDB_NODES; i++){
2039  const Uint32 stat = Sysfile::getNodeStatus(i, SYSFILE->nodeStatus);
2040  if(stat == Sysfile::NS_NotDefined && !tmp.get(i))
2041  {
2042  jam();
2043  continue;
2044  }
2045 
2046  if(tmp.get(i) && stat != Sysfile::NS_NotDefined)
2047  {
2048  jam();
2049  continue;
2050  }
2051 
2052  if (stat == Sysfile::NS_NotDefined && tmp.get(i))
2053  {
2054  jam();
2055  infoEvent("Discovered new node %u", i);
2056  continue;
2057  }
2058 
2059  if (stat == Sysfile::NS_Configured && !tmp.get(i))
2060  {
2061  jam();
2062  infoEvent("Configured node %u not present, ignoring",
2063  i);
2064  continue;
2065  }
2066 
2067  char buf[255];
2068  BaseString::snprintf(buf, sizeof(buf),
2069  "Illegal configuration change."
2070  " Initial start needs to be performed "
2071  " when removing nodes with nodegroup (node %d)", i);
2072  progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
2073  }
2074  }
2075 
2076  ndbrequire(csystemnodes >= 1 && csystemnodes < MAX_NDB_NODES);
2077 
2078  cmasterdihref = calcDihBlockRef(cmasterNodeId);
2079  /*-------------------------------------------------------------------------*/
2080  /* MAKE THE LIST OF PRN-RECORD WHICH IS ONE OF THE NODES-LIST IN THIS BLOCK*/
2081  /*-------------------------------------------------------------------------*/
2082  makePrnList(readNodes, nodeArray);
2083  if (cstarttype == NodeState::ST_INITIAL_START) {
2084  jam();
2094  makeNodeGroups(nodeArray);
2095  }//if
2096  ndbrequire(checkNodeAlive(cmasterNodeId));
2097 
2103  m_sr_nodes.clear();
2104  m_to_nodes.clear();
2105 
2106  // Start with assumption that all can restore
2107  {
2108  NodeRecordPtr specNodePtr;
2109  specNodePtr.i = cfirstAliveNode;
2110  do {
2111  jam();
2112  m_sr_nodes.set(specNodePtr.i);
2113  ptrCheckGuard(specNodePtr, MAX_NDB_NODES, nodeRecord);
2114  specNodePtr.i = specNodePtr.p->nextNode;
2115  } while (specNodePtr.i != RNIL);
2116  }
2117 
2118  execute(signal, m_sendSTTORRY, 0);
2119 }//Dbdih::execREAD_NODESCONF()
2120 
2121 /*---------------------------------------------------------------------------*/
2122 /* START NODE LOGIC FOR NODE RESTART */
2123 /*---------------------------------------------------------------------------*/
2124 void Dbdih::nodeRestartPh2Lab(Signal* signal)
2125 {
2126  /*
2127  * Lock master DICT to avoid metadata operations during INR/NR.
2128  * Done just before START_PERMREQ.
2129  *
2130  * It would be more elegant to do this just before START_MEREQ.
2131  * The problem is, on INR we end up in massive invalidateNodeLCP
2132  * which is not fully protected against metadata ops.
2133  */
2134  ndbrequire(c_dictLockSlavePtrI_nodeRestart == RNIL);
2135 
2136  // check that we are not yet taking part in schema ops
2137  CRASH_INSERTION(7174);
2138 
2139  Uint32 lockType = DictLockReq::NodeRestartLock;
2140  Callback c = { safe_cast(&Dbdih::recvDictLockConf_nodeRestart), 0 };
2141  sendDictLockReq(signal, lockType, c);
2142 }
2143 
2144 void Dbdih::recvDictLockConf_nodeRestart(Signal* signal, Uint32 data, Uint32 ret)
2145 {
2146  ndbrequire(c_dictLockSlavePtrI_nodeRestart == RNIL);
2147  ndbrequire(data != RNIL);
2148  c_dictLockSlavePtrI_nodeRestart = data;
2149 
2150  nodeRestartPh2Lab2(signal);
2151 }
2152 
2153 void Dbdih::nodeRestartPh2Lab2(Signal* signal)
2154 {
2155  /*------------------------------------------------------------------------*/
2156  // REQUEST FOR PERMISSION FROM MASTER TO START A NODE IN AN ALREADY
2157  // RUNNING SYSTEM.
2158  /*------------------------------------------------------------------------*/
2159  StartPermReq * const req = (StartPermReq *)&signal->theData[0];
2160 
2161  req->blockRef = reference();
2162  req->nodeId = cownNodeId;
2163  req->startType = cstarttype;
2164  sendSignal(cmasterdihref, GSN_START_PERMREQ, signal, 3, JBB);
2165 
2166  if (ERROR_INSERTED(7203))
2167  {
2168  signal->theData[0] = 9999;
2169  sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 200, 1);
2170  }
2171 }
2172 
2173 void Dbdih::execSTART_PERMCONF(Signal* signal)
2174 {
2175  jamEntry();
2176  CRASH_INSERTION(7121);
2177  Uint32 nodeId = signal->theData[0];
2178  cfailurenr = signal->theData[1];
2179 
2180  bool microGCP = signal->theData[2];
2181  if (signal->getLength() < StartPermConf::SignalLength)
2182  {
2183  microGCP = false;
2184  }
2185  m_micro_gcp.m_enabled = microGCP;
2186  ndbrequire(nodeId == cownNodeId);
2187  ndbsttorry10Lab(signal, __LINE__);
2188 
2189  if (m_micro_gcp.m_enabled)
2190  {
2191  jam();
2192  UpgradeProtocolOrd * ord = (UpgradeProtocolOrd*)signal->getDataPtrSend();
2193  ord->type = UpgradeProtocolOrd::UPO_ENABLE_MICRO_GCP;
2194  EXECUTE_DIRECT(QMGR,GSN_UPGRADE_PROTOCOL_ORD,signal,signal->getLength());
2195  }
2196  else if(isMultiThreaded())
2197  {
2202  progError(__LINE__, NDBD_EXIT_SR_RESTARTCONFLICT,
2203  "Cluster requires that all old data nodes are upgraded "
2204  "while running single-threaded ndbd before starting "
2205  "multi-threaded ndbmtd data nodes.");
2206  }
2207 }//Dbdih::execSTART_PERMCONF()
2208 
2209 void Dbdih::execSTART_PERMREF(Signal* signal)
2210 {
2211  jamEntry();
2212  Uint32 errorCode = signal->theData[1];
2213  if (errorCode == StartPermRef::ZNODE_ALREADY_STARTING_ERROR ||
2214  errorCode == StartPermRef::ZNODE_START_DISALLOWED_ERROR) {
2215  jam();
2216  /*-----------------------------------------------------------------------*/
2217  // The master was busy adding another node. We will wait for a second and
2218  // try again.
2219  /*-----------------------------------------------------------------------*/
2220  infoEvent("Did not get permission to start (%u) retry in 3s",
2221  errorCode);
2222  signal->theData[0] = DihContinueB::ZSTART_PERMREQ_AGAIN;
2223  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 3000, 1);
2224  return;
2225  }//if
2226 
2227  if (errorCode == StartPermRef::InitialStartRequired)
2228  {
2229  CRASH_INSERTION(7170);
2230  char buf[255];
2231  BaseString::snprintf(buf, sizeof(buf),
2232  "Cluster requires this node to be started "
2233  " with --initial as partial start has been performed"
2234  " and this filesystem is unusable");
2235  progError(__LINE__,
2236  NDBD_EXIT_SR_RESTARTCONFLICT,
2237  buf);
2238  ndbrequire(false);
2239  }
2240 
2241  /*------------------------------------------------------------------------*/
2242  // Some node process in another node involving our node was still active. We
2243  // will recover from this by crashing here.
2244  // This is controlled restart using the
2245  // already existing features of node crashes. It is not a bug getting here.
2246  /*-------------------------------------------------------------------------*/
2247  ndbrequire(false);
2248  return;
2249 }//Dbdih::execSTART_PERMREF()
2250 
2251 /*---------------------------------------------------------------------------*/
2252 /* THIS SIGNAL IS RECEIVED IN THE STARTING NODE WHEN THE START_MEREQ */
2253 /* HAS BEEN EXECUTED IN THE MASTER NODE. */
2254 /*---------------------------------------------------------------------------*/
2255 void Dbdih::execSTART_MECONF(Signal* signal)
2256 {
2257  jamEntry();
2258  StartMeConf * const startMe = (StartMeConf *)&signal->theData[0];
2259  Uint32 nodeId = startMe->startingNodeId;
2260  const Uint32 startWord = startMe->startWord;
2261  Uint32 i;
2262 
2263  CRASH_INSERTION(7130);
2264  ndbrequire(nodeId == cownNodeId);
2265  arrGuard(startWord + StartMeConf::DATA_SIZE, sizeof(cdata)/4);
2266  for(i = 0; i < StartMeConf::DATA_SIZE; i++)
2267  cdata[startWord+i] = startMe->data[i];
2268 
2269  if(startWord + StartMeConf::DATA_SIZE < Sysfile::SYSFILE_SIZE32){
2270  jam();
2274  return;
2275  }
2276  jam();
2277 
2283  Uint32 key = SYSFILE->m_restart_seq;
2284  Uint32 tempGCP[MAX_NDB_NODES];
2285  for(i = 0; i < MAX_NDB_NODES; i++)
2286  tempGCP[i] = SYSFILE->lastCompletedGCI[i];
2287 
2288  for(i = 0; i < Sysfile::SYSFILE_SIZE32; i++)
2289  sysfileData[i] = cdata[i];
2290 
2291  SYSFILE->m_restart_seq = key;
2292  for(i = 0; i < MAX_NDB_NODES; i++)
2293  SYSFILE->lastCompletedGCI[i] = tempGCP[i];
2294 
2295  setNodeActiveStatus();
2296  setNodeGroups();
2297  ndbsttorry10Lab(signal, __LINE__);
2298 
2299  if (getNodeActiveStatus(getOwnNodeId()) == Sysfile::NS_Configured)
2300  {
2301  jam();
2302  c_set_initial_start_flag = FALSE;
2303  }
2304 }//Dbdih::execSTART_MECONF()
2305 
2306 void Dbdih::execSTART_COPYCONF(Signal* signal)
2307 {
2308  jamEntry();
2309 
2310  StartCopyConf* conf = (StartCopyConf*)signal->getDataPtr();
2311  Uint32 nodeId = conf->startingNodeId;
2312  Uint32 senderData = conf->senderData;
2313 
2314  if (!ndb_pnr(getNodeInfo(refToNode(signal->getSendersBlockRef())).m_version))
2315  {
2316  jam();
2317  senderData = RNIL;
2318  }
2319 
2320  if (senderData == RNIL)
2321  {
2325  jam();
2326  ndbrequire(nodeId == cownNodeId);
2327  CRASH_INSERTION(7132);
2328  ndbsttorry10Lab(signal, __LINE__);
2329  }
2330  else
2331  {
2335  infoEvent("Take-over of %u complete", nodeId);
2336 
2337  ndbrequire(senderData == getOwnNodeId());
2338  ndbrequire(m_to_nodes.get(nodeId));
2339  m_to_nodes.clear(nodeId);
2340  m_sr_nodes.set(nodeId);
2341  if (!m_to_nodes.isclear())
2342  {
2343  jam();
2344  return;
2345  }
2346 
2347  signal->theData[0] = reference();
2348  m_sr_nodes.copyto(NdbNodeBitmask::Size, signal->theData+1);
2349  sendSignal(cntrlblockref, GSN_NDB_STARTCONF, signal,
2350  1 + NdbNodeBitmask::Size, JBB);
2351  return;
2352  }
2353  return;
2354 }//Dbdih::execSTART_COPYCONF()
2355 
2356 /*---------------------------------------------------------------------------*/
2357 /* MASTER LOGIC FOR NODE RESTART */
2358 /*---------------------------------------------------------------------------*/
2359 /* NODE RESTART PERMISSION REQUEST */
2360 /*---------------------------------------------------------------------------*/
2361 // A REQUEST FROM A STARTING NODE TO PERFORM A NODE RESTART. IF NO OTHER NODE
2362 // IS ACTIVE IN PERFORMING A NODE RESTART AND THERE ARE NO ACTIVE PROCESSES IN
2363 // THIS NODE INVOLVING THE STARTING NODE THIS REQUEST WILL BE GRANTED.
2364 /*---------------------------------------------------------------------------*/
2365 void Dbdih::execSTART_PERMREQ(Signal* signal)
2366 {
2367  StartPermReq * const req = (StartPermReq*)&signal->theData[0];
2368  jamEntry();
2369  const BlockReference retRef = req->blockRef;
2370  const Uint32 nodeId = req->nodeId;
2371  const Uint32 typeStart = req->startType;
2372  CRASH_INSERTION(7122);
2373  ndbrequire(isMaster());
2374  ndbrequire(refToNode(retRef) == nodeId);
2375  if ((c_nodeStartMaster.activeState) ||
2376  (c_nodeStartMaster.wait != ZFALSE) ||
2377  ERROR_INSERTED_CLEAR(7175)) {
2378  jam();
2379  signal->theData[0] = nodeId;
2380  signal->theData[1] = StartPermRef::ZNODE_ALREADY_STARTING_ERROR;
2381  sendSignal(retRef, GSN_START_PERMREF, signal, 2, JBB);
2382  return;
2383  }//if
2384 
2385  if (!getAllowNodeStart(nodeId))
2386  {
2387  jam();
2388 ref:
2389  signal->theData[0] = nodeId;
2390  signal->theData[1] = StartPermRef::ZNODE_START_DISALLOWED_ERROR;
2391  sendSignal(retRef, GSN_START_PERMREF, signal, 2, JBB);
2392  return;
2393  }
2394  if (getNodeStatus(nodeId) != NodeRecord::DEAD)
2395  {
2396  jam();
2397  g_eventLogger->error("nodeStatus in START_PERMREQ = %u",
2398  (Uint32) getNodeStatus(nodeId));
2399  goto ref;
2400  }//if
2401 
2402  if (SYSFILE->lastCompletedGCI[nodeId] == 0 &&
2403  typeStart != NodeState::ST_INITIAL_NODE_RESTART)
2404  {
2405  jam();
2406  signal->theData[0] = nodeId;
2407  signal->theData[1] = StartPermRef::InitialStartRequired;
2408  sendSignal(retRef, GSN_START_PERMREF, signal, 2, JBB);
2409  return;
2410  }
2411 
2412  /*----------------------------------------------------------------------
2413  * WE START THE INCLUSION PROCEDURE
2414  * ---------------------------------------------------------------------*/
2415  c_nodeStartMaster.failNr = cfailurenr;
2416  c_nodeStartMaster.wait = ZFALSE;
2417  c_nodeStartMaster.startInfoErrorCode = 0;
2418  c_nodeStartMaster.startNode = nodeId;
2419  c_nodeStartMaster.activeState = true;
2420  c_nodeStartMaster.m_outstandingGsn = GSN_START_INFOREQ;
2421 
2422  setNodeStatus(nodeId, NodeRecord::STARTING);
2430  StartInfoReq *const r =(StartInfoReq*)&signal->theData[0];
2431  r->startingNodeId = nodeId;
2432  r->typeStart = typeStart;
2433  r->systemFailureNo = cfailurenr;
2434  sendLoopMacro(START_INFOREQ, sendSTART_INFOREQ, RNIL);
2435 }//Dbdih::execSTART_PERMREQ()
2436 
2437 void Dbdih::execSTART_INFOREF(Signal* signal)
2438 {
2439  StartInfoRef * ref = (StartInfoRef*)&signal->theData[0];
2440  if (getNodeStatus(ref->startingNodeId) != NodeRecord::STARTING) {
2441  jam();
2442  return;
2443  }//if
2444  ndbrequire(c_nodeStartMaster.startNode == ref->startingNodeId);
2445  c_nodeStartMaster.startInfoErrorCode = ref->errorCode;
2446  startInfoReply(signal, ref->sendingNodeId);
2447 }//Dbdih::execSTART_INFOREF()
2448 
2449 void Dbdih::execSTART_INFOCONF(Signal* signal)
2450 {
2451  jamEntry();
2452  StartInfoConf * conf = (StartInfoConf*)&signal->theData[0];
2453  if (getNodeStatus(conf->startingNodeId) != NodeRecord::STARTING) {
2454  jam();
2455  return;
2456  }//if
2457  ndbrequire(c_nodeStartMaster.startNode == conf->startingNodeId);
2458  startInfoReply(signal, conf->sendingNodeId);
2459 }//Dbdih::execSTART_INFOCONF()
2460 
2461 void Dbdih::startInfoReply(Signal* signal, Uint32 nodeId)
2462 {
2463  receiveLoopMacro(START_INFOREQ, nodeId);
2467  if (c_nodeStartMaster.startInfoErrorCode == 0) {
2468  jam();
2472  StartPermConf * conf = (StartPermConf*)&signal->theData[0];
2473  conf->startingNodeId = c_nodeStartMaster.startNode;
2474  conf->systemFailureNo = cfailurenr;
2475  conf->microGCP = m_micro_gcp.m_enabled;
2476  sendSignal(calcDihBlockRef(c_nodeStartMaster.startNode),
2477  GSN_START_PERMCONF, signal, StartPermConf::SignalLength, JBB);
2478  c_nodeStartMaster.m_outstandingGsn = GSN_START_PERMCONF;
2479  } else {
2480  jam();
2481  StartPermRef * ref = (StartPermRef*)&signal->theData[0];
2482  ref->startingNodeId = c_nodeStartMaster.startNode;
2483  ref->errorCode = c_nodeStartMaster.startInfoErrorCode;
2484  sendSignal(calcDihBlockRef(c_nodeStartMaster.startNode),
2485  GSN_START_PERMREF, signal, StartPermRef::SignalLength, JBB);
2486  nodeResetStart(signal);
2487  }//if
2488 }//Dbdih::startInfoReply()
2489 
2490 /*---------------------------------------------------------------------------*/
2491 /* NODE RESTART CONTINUE REQUEST */
2492 /*---------------------------------------------------------------------------*/
2493 // THIS SIGNAL AND THE CODE BELOW IS EXECUTED BY THE MASTER WHEN IT HAS BEEN
2494 // REQUESTED TO START UP A NEW NODE. The master instructs the starting node
2495 // how to set up its log for continued execution.
2496 /*---------------------------------------------------------------------------*/
2497 void Dbdih::execSTART_MEREQ(Signal* signal)
2498 {
2499  StartMeReq * req = (StartMeReq*)&signal->theData[0];
2500  jamEntry();
2501  const BlockReference Tblockref = req->startingRef;
2502  const Uint32 Tnodeid = refToNode(Tblockref);
2503 
2504  ndbrequire(isMaster());
2505  ndbrequire(c_nodeStartMaster.startNode == Tnodeid);
2506  ndbrequire(getNodeStatus(Tnodeid) == NodeRecord::STARTING);
2507 
2508  if (getNodeInfo(Tnodeid).m_version >= NDBD_COPY_GCI_RESTART_NR)
2509  {
2510  jam();
2520  c_nodeStartMaster.m_outstandingGsn = GSN_COPY_GCIREQ;
2521  copyGciLab(signal, CopyGCIReq::RESTART_NR);
2522  }
2523  else
2524  {
2525  jam();
2526  startme_copygci_conf(signal);
2527  }
2528 }//Dbdih::nodeRestartStartRecConfLab()
2529 
2530 void
2531 Dbdih::startme_copygci_conf(Signal* signal)
2532 {
2533  jam();
2534  Callback c = { safe_cast(&Dbdih::lcpBlockedLab),
2535  c_nodeStartMaster.startNode };
2536  Mutex mutex(signal, c_mutexMgr, c_nodeStartMaster.m_fragmentInfoMutex);
2537  mutex.lock(c, true, true);
2538 }
2539 
2540 void Dbdih::lcpBlockedLab(Signal* signal, Uint32 nodeId, Uint32 retVal)
2541 {
2542  jamEntry();
2543  if (c_nodeStartMaster.startNode != nodeId)
2544  {
2545  jam();
2546  if (retVal == 0 || retVal == UtilLockRef::InLockQueue)
2547  {
2548  infoEvent("Releasing table/fragment info lock for node %u", nodeId);
2549 
2550  Mutex mutex(signal, c_mutexMgr, c_nodeStartMaster.m_fragmentInfoMutex);
2551  mutex.unlock();
2552  return;
2553  }
2554  return;
2555  }
2556 
2557  if (retVal == UtilLockRef::InLockQueue)
2558  {
2559  jam();
2560  infoEvent("Node %u enqueued is waiting to copy table/fragment info",
2561  c_nodeStartMaster.startNode);
2562  return;
2563  }
2564 
2565  ndbrequire(retVal == 0); // Mutex error
2566  ndbrequire(getNodeStatus(c_nodeStartMaster.startNode)==NodeRecord::STARTING);
2567  /*------------------------------------------------------------------------*/
2568  // NOW WE HAVE COPIED ALL INFORMATION IN DICT WE ARE NOW READY TO COPY ALL
2569  // INFORMATION IN DIH TO THE NEW NODE.
2570  /*------------------------------------------------------------------------*/
2571 
2572  c_nodeStartMaster.wait = 10;
2573  signal->theData[0] = DihContinueB::ZCOPY_NODE;
2574  signal->theData[1] = 0;
2575  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
2576  c_nodeStartMaster.m_outstandingGsn = GSN_COPY_TABREQ;
2577 }//Dbdih::lcpBlockedLab()
2578 
2579 void Dbdih::nodeDictStartConfLab(Signal* signal)
2580 {
2581  /*-----------------------------------------------------------------*/
2582  // Report that node restart has completed copy of dictionary.
2583  /*-----------------------------------------------------------------*/
2584  signal->theData[0] = NDB_LE_NR_CopyDict;
2585  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
2586 
2587  /*-------------------------------------------------------------------------*/
2588  // NOW WE HAVE COPIED BOTH DIH AND DICT INFORMATION. WE ARE NOW READY TO
2589  // INTEGRATE THE NODE INTO THE LCP AND GCP PROTOCOLS AND TO ALLOW UPDATES OF
2590  // THE DICTIONARY AGAIN.
2591  /*-------------------------------------------------------------------------*/
2592  c_nodeStartMaster.wait = ZFALSE;
2593  c_nodeStartMaster.blockGcp = 1;
2594 
2595  return;
2596 }//Dbdih::nodeDictStartConfLab()
2597 
2598 void Dbdih::dihCopyCompletedLab(Signal* signal)
2599 {
2600  BlockReference ref = calcDictBlockRef(c_nodeStartMaster.startNode);
2601  DictStartReq * req = (DictStartReq*)&signal->theData[0];
2602  req->restartGci = (Uint32)(m_micro_gcp.m_new_gci >> 32);
2603  req->senderRef = reference();
2604  sendSignal(ref, GSN_DICTSTARTREQ,
2605  signal, DictStartReq::SignalLength, JBB);
2606  c_nodeStartMaster.m_outstandingGsn = GSN_DICTSTARTREQ;
2607  c_nodeStartMaster.wait = 0;
2608 }//Dbdih::dihCopyCompletedLab()
2609 
2610 void Dbdih::gcpBlockedLab(Signal* signal)
2611 {
2615  NodeRecordPtr nodePtr;
2616  nodePtr.i = c_nodeStartMaster.startNode;
2617  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
2618  nodePtr.p->m_inclDihLcp = true;
2619 
2624  if (getNodeActiveStatus(nodePtr.i) == Sysfile::NS_NotDefined)
2625  {
2626  jam();
2627  infoEvent("Adding node %d to sysfile, NS_Configured",
2628  nodePtr.i);
2629  setNodeActiveStatus(nodePtr.i, Sysfile::NS_Configured);
2630  Sysfile::setNodeGroup(nodePtr.i, SYSFILE->nodeGroups,
2631  NO_NODE_GROUP_ID);
2632  Sysfile::setNodeStatus(nodePtr.i,
2633  SYSFILE->nodeStatus, Sysfile::NS_Configured);
2634  }
2635 
2636  /*-------------------------------------------------------------------------*/
2637  // NOW IT IS TIME TO INFORM ALL OTHER NODES IN THE CLUSTER OF THE STARTED
2638  // NODE SUCH THAT THEY ALSO INCLUDE THE NODE IN THE NODE LISTS AND SO FORTH.
2639  /*------------------------------------------------------------------------*/
2640  sendLoopMacro(INCL_NODEREQ, sendINCL_NODEREQ, RNIL);
2641  /*-------------------------------------------------------------------------*/
2642  // We also need to send to the starting node to ensure he is aware of the
2643  // global checkpoint id and the correct state. We do not wait for any reply
2644  // since the starting node will not send any.
2645  /*-------------------------------------------------------------------------*/
2646  Uint32 startVersion = getNodeInfo(c_nodeStartMaster.startNode).m_version;
2647 
2648  if ((getMajor(startVersion) == 4 &&
2649  startVersion >= NDBD_INCL_NODECONF_VERSION_4) ||
2650  (getMajor(startVersion) == 5 &&
2651  startVersion >= NDBD_INCL_NODECONF_VERSION_5) ||
2652  (getMajor(startVersion) > 5))
2653  {
2654  c_INCL_NODEREQ_Counter.setWaitingFor(c_nodeStartMaster.startNode);
2655  }
2656 
2657  sendINCL_NODEREQ(signal, c_nodeStartMaster.startNode, RNIL);
2658 }//Dbdih::gcpBlockedLab()
2659 
2660 /*---------------------------------------------------------------------------*/
2661 // THIS SIGNAL IS EXECUTED IN BOTH SLAVES AND IN THE MASTER
2662 /*---------------------------------------------------------------------------*/
2663 void Dbdih::execINCL_NODECONF(Signal* signal)
2664 {
2665  jamEntry();
2666  Uint32 TstartNode = signal->theData[0];
2667  Uint32 TsendNodeId_or_blockref = signal->theData[1];
2668 
2669  Uint32 blocklist[7];
2670  blocklist[0] = clocallqhblockref;
2671  blocklist[1] = clocaltcblockref;
2672  blocklist[2] = cdictblockref;
2673  blocklist[3] = numberToRef(BACKUP, getOwnNodeId());
2674  blocklist[4] = numberToRef(SUMA, getOwnNodeId());
2675  blocklist[5] = numberToRef(DBSPJ, getOwnNodeId());
2676  blocklist[6] = 0;
2677 
2678  for (Uint32 i = 0; blocklist[i] != 0; i++)
2679  {
2680  if (TsendNodeId_or_blockref == blocklist[i])
2681  {
2682  jam();
2683 
2684  if (TstartNode != c_nodeStartSlave.nodeId)
2685  {
2686  jam();
2687  warningEvent("Recevied INCL_NODECONF for %u from %s"
2688  " while %u is starting",
2689  TstartNode,
2690  getBlockName(refToBlock(TsendNodeId_or_blockref)),
2691  c_nodeStartSlave.nodeId);
2692  return;
2693  }
2694 
2695  if (getNodeStatus(c_nodeStartSlave.nodeId) == NodeRecord::ALIVE &&
2696  blocklist[i+1] != 0)
2697  {
2701  jam();
2702  signal->theData[0] = reference();
2703  signal->theData[1] = c_nodeStartSlave.nodeId;
2704  sendSignal(blocklist[i+1], GSN_INCL_NODEREQ, signal, 2, JBB);
2705  return;
2706  }
2707  else
2708  {
2712  jam();
2713  signal->theData[0] = c_nodeStartSlave.nodeId;
2714  signal->theData[1] = cownNodeId;
2715  sendSignal(cmasterdihref, GSN_INCL_NODECONF, signal, 2, JBB);
2716 
2717  c_nodeStartSlave.nodeId = 0;
2718  return;
2719  }
2720  }
2721  }
2722 
2723  if (c_nodeStartMaster.startNode != TstartNode)
2724  {
2725  jam();
2726  warningEvent("Recevied INCL_NODECONF for %u from %u"
2727  " while %u is starting",
2728  TstartNode,
2729  TsendNodeId_or_blockref,
2730  c_nodeStartMaster.startNode);
2731  return;
2732  }
2733 
2734  ndbrequire(reference() == cmasterdihref);
2735  receiveLoopMacro(INCL_NODEREQ, TsendNodeId_or_blockref);
2736 
2737  CRASH_INSERTION(7128);
2738  /*-------------------------------------------------------------------------*/
2739  // Now that we have included the starting node in the node lists in the
2740  // various blocks we are ready to start the global checkpoint protocol
2741  /*------------------------------------------------------------------------*/
2742  c_nodeStartMaster.wait = 11;
2743  c_nodeStartMaster.blockGcp = 0;
2744 
2748  signal->theData[0] = reference();
2749  sendSignal(reference(), GSN_UNBLO_DICTCONF, signal, 1, JBB);
2750 
2751  signal->theData[0] = DihContinueB::ZSTART_GCP;
2752  sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
2760  signal->theData[0] = DihContinueB::ZDELAY_RELEASE_FRAGMENT_INFO_MUTEX;
2761  signal->theData[1] = c_nodeStartMaster.m_fragmentInfoMutex.getHandle();
2762  c_nodeStartMaster.m_fragmentInfoMutex.clear();
2763  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 500, 2);
2764 }//Dbdih::execINCL_NODECONF()
2765 
2766 void Dbdih::execUNBLO_DICTCONF(Signal* signal)
2767 {
2768  jamEntry();
2769  c_nodeStartMaster.wait = ZFALSE;
2770  if (!c_nodeStartMaster.activeState) {
2771  jam();
2772  return;
2773  }//if
2774 
2775  CRASH_INSERTION(7129);
2784  StartMeConf * const startMe = (StartMeConf *)&signal->theData[0];
2785 
2786  const Uint32 wordPerSignal = StartMeConf::DATA_SIZE;
2787  const int noOfSignals = ((Sysfile::SYSFILE_SIZE32 + (wordPerSignal - 1)) /
2788  wordPerSignal);
2789 
2790  Uint32 nodeId = startMe->startingNodeId = c_nodeStartMaster.startNode;
2791  startMe->startWord = 0;
2792 
2793  const Uint32 ref = calcDihBlockRef(c_nodeStartMaster.startNode);
2794  for(int i = 0; i < noOfSignals; i++){
2795  jam();
2796  { // Do copy
2797  const int startWord = startMe->startWord;
2798  for(Uint32 j = 0; j < wordPerSignal; j++){
2799  startMe->data[j] = sysfileData[j+startWord];
2800  }
2801  }
2802  sendSignal(ref, GSN_START_MECONF, signal, StartMeConf::SignalLength, JBB);
2803  startMe->startWord += wordPerSignal;
2804  }//for
2805  c_nodeStartMaster.m_outstandingGsn = GSN_START_MECONF;
2806  nodeResetStart(signal);
2807 
2811  signal->theData[0] = nodeId;
2812  sendSignal(NDBCNTR_REF, GSN_START_PERMREP, signal, 1, JBB);
2813 }//Dbdih::execUNBLO_DICTCONF()
2814 
2815 /*---------------------------------------------------------------------------*/
2816 /* NODE RESTART COPY REQUEST */
2817 /*---------------------------------------------------------------------------*/
2818 // A NODE RESTART HAS REACHED ITS FINAL PHASE WHEN THE DATA IS TO BE COPIED
2819 // TO THE NODE. START_COPYREQ IS EXECUTED BY THE STARTING NODE.
2820 /*---------------------------------------------------------------------------*/
2821 void Dbdih::execSTART_COPYREQ(Signal* signal)
2822 {
2823  jamEntry();
2824  StartCopyReq req = *(StartCopyReq*)signal->getDataPtr();
2825 
2826  Uint32 startNodeId = req.startingNodeId;
2827 
2828  /*-------------------------------------------------------------------------*/
2829  // REPORT Copy process of node restart is now about to start up.
2830  /*-------------------------------------------------------------------------*/
2831  signal->theData[0] = NDB_LE_NR_CopyFragsStarted;
2832  signal->theData[1] = req.startingNodeId;
2833  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
2834 
2835  CRASH_INSERTION(7131);
2836 
2837  switch (getNodeActiveStatus(startNodeId)) {
2838  case Sysfile::NS_Active:
2839  case Sysfile::NS_ActiveMissed_1:
2840  case Sysfile::NS_ActiveMissed_2:
2841  case Sysfile::NS_NotActive_NotTakenOver:
2842  case Sysfile::NS_Configured:
2843  jam();
2844  /*-----------------------------------------------------------------------*/
2845  // AN ACTIVE NODE HAS BEEN STARTED. THE ACTIVE NODE MUST THEN GET ALL DATA
2846  // IT HAD BEFORE ITS CRASH. WE START THE TAKE OVER IMMEDIATELY.
2847  // SINCE WE ARE AN ACTIVE NODE WE WILL TAKE OVER OUR OWN NODE THAT
2848  // PREVIOUSLY CRASHED.
2849  /*-----------------------------------------------------------------------*/
2850  startTakeOver(signal, startNodeId, startNodeId, &req);
2851  break;
2852  case Sysfile::NS_TakeOver:{
2853  jam();
2854  /*--------------------------------------------------------------------
2855  * We were in the process of taking over but it was not completed.
2856  * We will complete it now instead.
2857  *--------------------------------------------------------------------*/
2858  Uint32 takeOverNode = Sysfile::getTakeOverNode(startNodeId,
2859  SYSFILE->takeOver);
2860  if(takeOverNode == 0){
2861  jam();
2862  warningEvent("Bug in take-over code restarting");
2863  takeOverNode = startNodeId;
2864  }
2865 
2866  startTakeOver(signal, startNodeId, takeOverNode, &req);
2867  break;
2868  }
2869  default:
2870  ndbrequire(false);
2871  break;
2872  }//switch
2873 }//Dbdih::execSTART_COPYREQ()
2874 
2875 /*---------------------------------------------------------------------------*/
2876 /* SLAVE LOGIC FOR NODE RESTART */
2877 /*---------------------------------------------------------------------------*/
2878 void Dbdih::execSTART_INFOREQ(Signal* signal)
2879 {
2880  jamEntry();
2881  StartInfoReq *const req =(StartInfoReq*)&signal->theData[0];
2882  Uint32 startNode = req->startingNodeId;
2883  if (cfailurenr != req->systemFailureNo) {
2884  jam();
2885  //---------------------------------------------------------------
2886  // A failure occurred since master sent this request. We will ignore
2887  // this request since the node is already dead that is starting.
2888  //---------------------------------------------------------------
2889  return;
2890  }//if
2891  CRASH_INSERTION(7123);
2892  if (isMaster()) {
2893  jam();
2894  ndbrequire(getNodeStatus(startNode) == NodeRecord::STARTING);
2895  } else {
2896  jam();
2897  ndbrequire(getNodeStatus(startNode) == NodeRecord::DEAD);
2898  }//if
2899  if ((!getAllowNodeStart(startNode)) ||
2900  (c_nodeStartSlave.nodeId != 0) ||
2901  (ERROR_INSERTED(7124))) {
2902  jam();
2903  StartInfoRef *const ref =(StartInfoRef*)&signal->theData[0];
2904  ref->startingNodeId = startNode;
2905  ref->sendingNodeId = cownNodeId;
2906  ref->errorCode = StartPermRef::ZNODE_START_DISALLOWED_ERROR;
2907  sendSignal(cmasterdihref, GSN_START_INFOREF, signal,
2908  StartInfoRef::SignalLength, JBB);
2909  return;
2910  }//if
2911  setNodeStatus(startNode, NodeRecord::STARTING);
2912  if (req->typeStart == NodeState::ST_INITIAL_NODE_RESTART) {
2913  jam();
2914  setAllowNodeStart(startNode, false);
2915  invalidateNodeLCP(signal, startNode, 0);
2916  } else {
2917  jam();
2918  StartInfoConf * c = (StartInfoConf*)&signal->theData[0];
2919  c->sendingNodeId = cownNodeId;
2920  c->startingNodeId = startNode;
2921  sendSignal(cmasterdihref, GSN_START_INFOCONF, signal,
2922  StartInfoConf::SignalLength, JBB);
2923  return;
2924  }//if
2925 }//Dbdih::execSTART_INFOREQ()
2926 
2927 void Dbdih::execINCL_NODEREQ(Signal* signal)
2928 {
2929  jamEntry();
2930  Uint32 retRef = signal->theData[0];
2931  Uint32 nodeId = signal->theData[1];
2932  if (nodeId == getOwnNodeId() && ERROR_INSERTED(7165))
2933  {
2934  CLEAR_ERROR_INSERT_VALUE;
2935  sendSignalWithDelay(reference(), GSN_INCL_NODEREQ, signal, 5000,
2936  signal->getLength());
2937  return;
2938  }
2939 
2940  Uint32 tnodeStartFailNr = signal->theData[2];
2941  Uint32 gci_hi = signal->theData[4];
2942  Uint32 gci_lo = signal->theData[5];
2943  if (unlikely(signal->getLength() < 6))
2944  {
2945  jam();
2946  gci_lo = 0;
2947  }
2948 
2949  Uint64 gci = gci_lo | (Uint64(gci_hi) << 32);
2950  CRASH_INSERTION(7127);
2951  m_micro_gcp.m_current_gci = gci;
2952  m_micro_gcp.m_old_gci = gci - 1;
2953  if (!isMaster()) {
2954  jam();
2955  /*-----------------------------------------------------------------------*/
2956  // We don't want to change the state of the master since he can be in the
2957  // state LCP_TCGET at this time.
2958  /*-----------------------------------------------------------------------*/
2959  c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
2960  }//if
2961 
2962  /*-------------------------------------------------------------------------*/
2963  // When a node is restarted we must ensure that a lcp will be run
2964  // as soon as possible and the reset the delay according to the original
2965  // configuration.
2966  // Without an initial local checkpoint the new node will not be available.
2967  /*-------------------------------------------------------------------------*/
2968  if (getOwnNodeId() == nodeId) {
2969  jam();
2970  /*-----------------------------------------------------------------------*/
2971  // We are the starting node. We came here only to set the global checkpoint
2972  // id's and the lcp status.
2973  /*-----------------------------------------------------------------------*/
2974  CRASH_INSERTION(7171);
2975  Uint32 masterVersion = getNodeInfo(refToNode(cmasterdihref)).m_version;
2976 
2977  if ((NDB_VERSION_MAJOR == 4 &&
2978  masterVersion >= NDBD_INCL_NODECONF_VERSION_4) ||
2979  (NDB_VERSION_MAJOR == 5 &&
2980  masterVersion >= NDBD_INCL_NODECONF_VERSION_5) ||
2981  (NDB_VERSION_MAJOR > 5))
2982  {
2983  signal->theData[0] = getOwnNodeId();
2984  signal->theData[1] = getOwnNodeId();
2985  sendSignal(cmasterdihref, GSN_INCL_NODECONF, signal, 2, JBB);
2986  }
2987  return;
2988  }//if
2989  if (getNodeStatus(nodeId) != NodeRecord::STARTING) {
2990  jam();
2991  return;
2992  }//if
2993  ndbrequire(cfailurenr == tnodeStartFailNr);
2994  ndbrequire (c_nodeStartSlave.nodeId == 0);
2995  c_nodeStartSlave.nodeId = nodeId;
2996 
2997  ndbrequire (retRef == cmasterdihref);
2998 
2999  NodeRecordPtr nodePtr;
3000  nodePtr.i = nodeId;
3001  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
3002 
3003  Sysfile::ActiveStatus TsaveState = nodePtr.p->activeStatus;
3004  Uint32 TnodeGroup = nodePtr.p->nodeGroup;
3005 
3006  new (nodePtr.p) NodeRecord();
3007  nodePtr.p->nodeGroup = TnodeGroup;
3008  nodePtr.p->activeStatus = TsaveState;
3009  nodePtr.p->nodeStatus = NodeRecord::ALIVE;
3010  nodePtr.p->useInTransactions = true;
3011  nodePtr.p->m_inclDihLcp = true;
3012 
3013  removeDeadNode(nodePtr);
3014  insertAlive(nodePtr);
3015  con_lineNodes++;
3016 
3017  /*-------------------------------------------------------------------------*/
3018  // WE WILL ALSO SEND THE INCLUDE NODE REQUEST TO THE LOCAL LQH BLOCK.
3019  /*-------------------------------------------------------------------------*/
3020  signal->theData[0] = reference();
3021  signal->theData[1] = nodeId;
3022  signal->theData[2] = Uint32(m_micro_gcp.m_current_gci >> 32);
3023  sendSignal(clocallqhblockref, GSN_INCL_NODEREQ, signal, 3, JBB);
3024 }//Dbdih::execINCL_NODEREQ()
3025 
3026 /* ------------------------------------------------------------------------- */
3027 // execINCL_NODECONF() is found in the master logic part since it is used by
3028 // both the master and the slaves.
3029 /* ------------------------------------------------------------------------- */
3030 
3031 void Dbdih::execSTART_TOREQ(Signal* signal)
3032 {
3033  jamEntry();
3034  StartToReq req = *(StartToReq *)&signal->theData[0];
3035 
3036 
3037  if (ndb_pnr(getNodeInfo(refToNode(req.senderRef)).m_version))
3038  {
3039  jam();
3040  TakeOverRecordPtr takeOverPtr;
3041 
3042  c_activeTakeOverList.seize(takeOverPtr);
3043  takeOverPtr.p->toStartingNode = req.startingNodeId;
3044  takeOverPtr.p->m_senderRef = req.senderRef;
3045  takeOverPtr.p->m_senderData = req.senderData;
3046  takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_MASTER_IDLE;
3047  takeOverPtr.p->toStartTime = c_current_time;
3048  }
3049 
3050  StartToConf * conf = (StartToConf *)&signal->theData[0];
3051  conf->senderData = req.senderData;
3052  conf->sendingNodeId = cownNodeId;
3053  conf->startingNodeId = req.startingNodeId;
3054  sendSignal(req.senderRef, GSN_START_TOCONF,
3055  signal, StartToConf::SignalLength, JBB);
3056 }//Dbdih::execSTART_TOREQ()
3057 
3058 void Dbdih::execUPDATE_TOREQ(Signal* signal)
3059 {
3060  jamEntry();
3061  UpdateToReq req = *(UpdateToReq *)&signal->theData[0];
3062 
3063  Uint32 errCode;
3064  Uint32 extra;
3065  if (ndb_pnr(getNodeInfo(refToNode(req.senderRef)).m_version))
3066  {
3067  jam();
3071  TakeOverRecordPtr takeOverPtr;
3072  if (findTakeOver(takeOverPtr, req.startingNodeId) == false)
3073  {
3074  errCode = UpdateToRef::UnknownTakeOver;
3075  extra = RNIL;
3076  goto ref;
3077  }
3078 
3079  CRASH_INSERTION(7141);
3080 
3081  takeOverPtr.p->toCopyNode = req.copyNodeId;
3082  takeOverPtr.p->toCurrentTabref = req.tableId;
3083  takeOverPtr.p->toCurrentFragid = req.fragmentNo;
3084 
3085  NodeRecordPtr nodePtr;
3086  NodeGroupRecordPtr NGPtr;
3087  nodePtr.i = req.copyNodeId;
3088  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
3089  NGPtr.i = nodePtr.p->nodeGroup;
3090  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
3091 
3092  Mutex mutex(signal, c_mutexMgr, takeOverPtr.p->m_fragmentInfoMutex);
3093  Callback c = { safe_cast(&Dbdih::updateToReq_fragmentMutex_locked),
3094  takeOverPtr.i };
3095 
3096  switch(req.requestType){
3097  case UpdateToReq::BEFORE_STORED:
3098  jam();
3099 
3100  if (NGPtr.p->activeTakeOver == 0)
3101  {
3102  jam();
3103  NGPtr.p->activeTakeOver = req.startingNodeId;
3104  }
3105  else
3106  {
3107  jam();
3108  errCode = UpdateToRef::CopyFragInProgress;
3109  extra = NGPtr.p->activeTakeOver;
3110  goto ref;
3111  }
3112 
3113  takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_MUTEX_BEFORE_STORED;
3114  mutex.lock(c, false, true);
3115  return;
3116  case UpdateToReq::AFTER_STORED:
3117  {
3118  jam();
3119  mutex.unlock();
3120  takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_AFTER_STORED;
3121  // Send conf
3122  break;
3123  }
3124  case UpdateToReq::BEFORE_COMMIT_STORED:
3125  jam();
3126  takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_MUTEX_BEFORE_COMMIT;
3127  mutex.lock(c, false, true);
3128  return;
3129  case UpdateToReq::AFTER_COMMIT_STORED:
3130  {
3131  jam();
3132  mutex.unlock();
3133 
3134  Mutex mutex2(signal, c_mutexMgr,
3135  takeOverPtr.p->m_switchPrimaryMutexHandle);
3136  mutex2.unlock();
3137  takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_MASTER_IDLE;
3138  break; // send conf
3139  }
3140  }
3141  }
3142  else
3143  {
3144  CRASH_INSERTION(7154);
3145  RETURN_IF_NODE_NOT_ALIVE(req.startingNodeId);
3146  }
3147 
3148  {
3149  UpdateToConf * conf = (UpdateToConf *)&signal->theData[0];
3150  conf->senderData = req.senderData;
3151  conf->sendingNodeId = cownNodeId;
3152  conf->startingNodeId = req.startingNodeId;
3153  sendSignal(req.senderRef, GSN_UPDATE_TOCONF, signal,
3154  UpdateToConf::SignalLength, JBB);
3155  }
3156  return;
3157 
3158 ref:
3159  UpdateToRef* ref = (UpdateToRef*)signal->getDataPtrSend();
3160  ref->senderData = req.senderData;
3161  ref->senderRef = reference();
3162  ref->errorCode = errCode;
3163  ref->extra = extra;
3164  sendSignal(req.senderRef, GSN_UPDATE_TOREF, signal,
3165  UpdateToRef::SignalLength, JBB);
3166 }
3167 
3168 void
3169 Dbdih::updateToReq_fragmentMutex_locked(Signal * signal,
3170  Uint32 toPtrI, Uint32 retVal)
3171 {
3172  jamEntry();
3173  TakeOverRecordPtr takeOverPtr;
3174  c_takeOverPool.getPtr(takeOverPtr, toPtrI);
3175 
3176  Uint32 nodeId = takeOverPtr.p->toStartingNode;
3177 
3178  if (retVal == UtilLockRef::InLockQueue)
3179  {
3180  jam();
3181  infoEvent("Node %u waiting to continue copying table %u fragment: %u (%s)",
3182  nodeId,
3183  takeOverPtr.p->toCurrentTabref,
3184  takeOverPtr.p->toCurrentFragid,
3185  takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_MUTEX_BEFORE_STORED ? "STORED" : "COMMIT");
3186  return;
3187  }
3188 
3189  Uint32 errCode;
3190  Uint32 extra;
3191 
3192  NodeRecordPtr nodePtr;
3193  nodePtr.i = nodeId;
3194  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
3195  if (unlikely(nodePtr.p->nodeStatus != NodeRecord::ALIVE))
3196  {
3197  jam();
3201  abortTakeOver(signal, takeOverPtr);
3202  return;
3203  }
3204 
3205  switch(takeOverPtr.p->toMasterStatus){
3206  case TakeOverRecord::TO_MUTEX_BEFORE_STORED:
3207  {
3208  jam();
3209  // send conf
3210  takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_MUTEX_BEFORE_LOCKED;
3211  break;
3212  }
3213  case TakeOverRecord::TO_MUTEX_BEFORE_COMMIT:
3214  {
3215  jam();
3216 
3217  NodeRecordPtr nodePtr;
3218  NodeGroupRecordPtr NGPtr;
3219  nodePtr.i = takeOverPtr.p->toCopyNode;
3220  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
3221  NGPtr.i = nodePtr.p->nodeGroup;
3222  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
3223 
3224  if (NGPtr.p->activeTakeOver != nodeId)
3225  {
3226  ndbassert(false);
3227  errCode = UpdateToRef::InvalidRequest;
3228  extra = NGPtr.p->activeTakeOver;
3229  goto ref;
3230  }
3231  NGPtr.p->activeTakeOver = 0;
3232  takeOverPtr.p->toCopyNode = RNIL;
3233  Mutex mutex(signal, c_mutexMgr,
3234  takeOverPtr.p->m_switchPrimaryMutexHandle);
3235  Callback c = { safe_cast(&Dbdih::switchPrimaryMutex_locked),
3236  takeOverPtr.i };
3237  ndbrequire(mutex.lock(c));
3238  takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_MUTEX_BEFORE_SWITCH_REPLICA;
3239  return;
3240  break;
3241  }
3242  default:
3243  jamLine(takeOverPtr.p->toMasterStatus);
3244  ndbrequire(false);
3245  }
3246 
3247  {
3248  UpdateToConf * conf = (UpdateToConf *)&signal->theData[0];
3249  conf->senderData = takeOverPtr.p->m_senderData;
3250  conf->sendingNodeId = cownNodeId;
3251  conf->startingNodeId = takeOverPtr.p->toStartingNode;
3252  sendSignal(takeOverPtr.p->m_senderRef, GSN_UPDATE_TOCONF, signal,
3253  UpdateToConf::SignalLength, JBB);
3254  }
3255  return;
3256 
3257 ref:
3258  {
3259  Mutex mutex(signal, c_mutexMgr, takeOverPtr.p->m_fragmentInfoMutex);
3260  mutex.unlock();
3261 
3262  UpdateToRef* ref = (UpdateToRef*)signal->getDataPtrSend();
3263  ref->senderData = takeOverPtr.p->m_senderData;
3264  ref->senderRef = reference();
3265  ref->errorCode = errCode;
3266  ref->extra = extra;
3267  sendSignal(takeOverPtr.p->m_senderRef, GSN_UPDATE_TOREF, signal,
3268  UpdateToRef::SignalLength, JBB);
3269  return;
3270  }
3271 }
3272 
3273 void
3274 Dbdih::switchPrimaryMutex_locked(Signal* signal, Uint32 toPtrI, Uint32 retVal)
3275 {
3276  jamEntry();
3277  ndbrequire(retVal == 0);
3278 
3279  TakeOverRecordPtr takeOverPtr;
3280  c_takeOverPool.getPtr(takeOverPtr, toPtrI);
3281 
3282  Uint32 nodeId = takeOverPtr.p->toStartingNode;
3283  NodeRecordPtr nodePtr;
3284  nodePtr.i = nodeId;
3285  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
3286 
3287  if (unlikely(nodePtr.p->nodeStatus != NodeRecord::ALIVE))
3288  {
3289  jam();
3293  abortTakeOver(signal, takeOverPtr);
3294  return;
3295  }
3296 
3297  takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_MUTEX_AFTER_SWITCH_REPLICA;
3298 
3299  UpdateToConf * conf = (UpdateToConf *)&signal->theData[0];
3300  conf->senderData = takeOverPtr.p->m_senderData;
3301  conf->sendingNodeId = cownNodeId;
3302  conf->startingNodeId = takeOverPtr.p->toStartingNode;
3303  sendSignal(takeOverPtr.p->m_senderRef, GSN_UPDATE_TOCONF, signal,
3304  UpdateToConf::SignalLength, JBB);
3305 }
3306 
3307 void
3308 Dbdih::switchPrimaryMutex_unlocked(Signal* signal, Uint32 toPtrI, Uint32 retVal)
3309 {
3310  jamEntry();
3311  ndbrequire(retVal == 0);
3312 
3313  TakeOverRecordPtr takeOverPtr;
3314  c_takeOverPool.getPtr(takeOverPtr, toPtrI);
3315 
3316  UpdateToConf * conf = (UpdateToConf *)&signal->theData[0];
3317  conf->senderData = takeOverPtr.p->m_senderData;
3318  conf->sendingNodeId = cownNodeId;
3319  conf->startingNodeId = takeOverPtr.p->toStartingNode;
3320  sendSignal(takeOverPtr.p->m_senderRef, GSN_UPDATE_TOCONF, signal,
3321  UpdateToConf::SignalLength, JBB);
3322 }
3323 
3324 void
3325 Dbdih::abortTakeOver(Signal* signal, TakeOverRecordPtr takeOverPtr)
3326 {
3327  if (!takeOverPtr.p->m_switchPrimaryMutexHandle.isNull())
3328  {
3329  jam();
3330  Mutex mutex(signal, c_mutexMgr,
3331  takeOverPtr.p->m_switchPrimaryMutexHandle);
3332  mutex.unlock();
3333 
3334  }
3335 
3336  if (!takeOverPtr.p->m_fragmentInfoMutex.isNull())
3337  {
3338  jam();
3339  Mutex mutex(signal, c_mutexMgr,
3340  takeOverPtr.p->m_fragmentInfoMutex);
3341  mutex.unlock();
3342  }
3343 
3344  NodeRecordPtr nodePtr;
3345  nodePtr.i = takeOverPtr.p->toCopyNode;
3346  if (nodePtr.i != RNIL)
3347  {
3348  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
3349  NodeGroupRecordPtr NGPtr;
3350  NGPtr.i = nodePtr.p->nodeGroup;
3351  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
3352  if (NGPtr.p->activeTakeOver == takeOverPtr.p->toStartingNode)
3353  {
3354  jam();
3355  NGPtr.p->activeTakeOver = 0;
3356  }
3357  }
3358 
3359  releaseTakeOver(takeOverPtr);
3360 }
3361 
3362 static
3363 void
3364 add_lcp_counter(Uint32 * counter, Uint32 add)
3365 {
3366  Uint64 tmp = * counter;
3367  tmp += add;
3368  if (tmp > 0xFFFFFFFF)
3369  tmp = 0xFFFFFFFF;
3370  * counter = Uint32(tmp);
3371 }
3372 
3373 void
3374 Dbdih::check_force_lcp(Ptr<TakeOverRecord> takeOverPtr)
3375 {
3376  Uint64 duration = c_current_time - takeOverPtr.p->toStartTime;
3377  Uint64 lcp_time = c_lcpState.m_lcp_time;
3378 
3379  Ptr<TakeOverRecord> tmp;
3380  for (c_activeTakeOverList.first(tmp); !tmp.isNull();
3381  c_activeTakeOverList.next(tmp))
3382  {
3383  jam();
3384  if (tmp.p->toMasterStatus != TakeOverRecord::TO_WAIT_LCP)
3385  {
3386  jam();
3387 
3388  Uint64 elapsed = c_current_time - tmp.p->toStartTime;
3389  if (elapsed >= duration)
3390  {
3391  jam();
3397  infoEvent("Node %u not forcing LCP start(1 %llu >= %llu), wait on %u",
3398  takeOverPtr.p->toStartingNode,
3399  elapsed, duration,
3400  tmp.p->toStartingNode);
3401  return;
3402  }
3403 
3404  Uint64 left = duration - elapsed;
3405  if (left < lcp_time)
3406  {
3407  jam();
3412  infoEvent("Node %u not forcing LCP start(2 %llu < %llu), wait on %u",
3413  takeOverPtr.p->toStartingNode,
3414  left, lcp_time,
3415  tmp.p->toStartingNode);
3416  return;
3417  }
3418  }
3419  }
3420  add_lcp_counter(&c_lcpState.ctimer, (1 << 31));
3421 }
3422 
3423 void Dbdih::execEND_TOREQ(Signal* signal)
3424 {
3425  jamEntry();
3426  EndToReq req = *(EndToReq *)&signal->theData[0];
3427 
3428  Uint32 nodeId = refToNode(req.senderRef);
3429  TakeOverRecordPtr takeOverPtr;
3430 
3431  if (ndb_pnr(getNodeInfo(nodeId).m_version))
3432  {
3433  jam();
3437  ndbrequire(findTakeOver(takeOverPtr, nodeId));
3438  NodeRecordPtr nodePtr;
3439  nodePtr.i = nodeId;
3440  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
3441 
3442  if (req.flags & StartCopyReq::WAIT_LCP)
3443  {
3444  jam();
3445 
3449  nodePtr.p->copyCompleted = 2;
3450  takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_LCP;
3451 
3457  c_lcpState.lcpStopGcp = c_newest_restorable_gci;
3458 
3459  check_force_lcp(takeOverPtr);
3460  return;
3461  }
3462  nodePtr.p->copyCompleted = 1;
3463  releaseTakeOver(takeOverPtr);
3464  }
3465 
3466  EndToConf * conf = (EndToConf *)&signal->theData[0];
3467  conf->senderData = req.senderData;
3468  conf->sendingNodeId = cownNodeId;
3469  conf->startingNodeId = req.startingNodeId;
3470  sendSignal(req.senderRef, GSN_END_TOCONF, signal,
3471  EndToConf::SignalLength, JBB);
3472 }//Dbdih::execEND_TOREQ()
3473 
3474 #define DIH_TAB_WRITE_LOCK(tabPtrP) \
3475  do { assertOwnThread(); tabPtrP->m_lock.write_lock(); } while (0)
3476 
3477 #define DIH_TAB_WRITE_UNLOCK(tabPtrP) \
3478  do { assertOwnThread(); tabPtrP->m_lock.write_unlock(); } while (0)
3479 
3480 /* --------------------------------------------------------------------------*/
3481 /* AN ORDER TO START OR COMMIT THE REPLICA CREATION ARRIVED FROM THE */
3482 /* MASTER. */
3483 /* --------------------------------------------------------------------------*/
3484 void Dbdih::execCREATE_FRAGREQ(Signal* signal)
3485 {
3486  jamEntry();
3487  CreateFragReq * const req = (CreateFragReq *)&signal->theData[0];
3488 
3489  Uint32 senderData = req->senderData;
3490  Uint32 senderRef = req->senderRef;
3491 
3492  TabRecordPtr tabPtr;
3493  tabPtr.i = req->tableId;
3494  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
3495 
3496  Uint32 fragId = req->fragId;
3497  Uint32 tdestNodeid = req->startingNodeId;
3498  //Uint32 tsourceNodeid = req->copyNodeId;
3499  Uint32 startGci = req->startGci;
3500  Uint32 replicaType = req->replicaType;
3501  Uint32 tFailedNodeId = req->failedNodeId;
3502 
3503  if (!ndb_pnr(getNodeInfo(refToNode(senderRef)).m_version))
3504  {
3505  jam();
3506  tFailedNodeId = tdestNodeid;
3507  }
3508 
3509  FragmentstorePtr fragPtr;
3510  getFragstore(tabPtr.p, fragId, fragPtr);
3511  RETURN_IF_NODE_NOT_ALIVE(tdestNodeid);
3512  ReplicaRecordPtr frReplicaPtr;
3513  findReplica(frReplicaPtr, fragPtr.p, tFailedNodeId,
3514  replicaType == CreateFragReq::START_LOGGING ? false : true);
3515  if (frReplicaPtr.i == RNIL)
3516  {
3517  dump_replica_info(fragPtr.p);
3518  }
3519  ndbrequire(frReplicaPtr.i != RNIL);
3520 
3521  DIH_TAB_WRITE_LOCK(tabPtr.p);
3522  switch (replicaType) {
3523  case CreateFragReq::STORED:
3524  jam();
3525  CRASH_INSERTION(7138);
3526  /* ----------------------------------------------------------------------*/
3527  /* HERE WE ARE INSERTING THE NEW BACKUP NODE IN THE EXECUTION OF ALL */
3528  /* OPERATIONS. FROM HERE ON ALL OPERATIONS ON THIS FRAGMENT WILL INCLUDE*/
3529  /* USE OF THE NEW REPLICA. */
3530  /* --------------------------------------------------------------------- */
3531  insertBackup(fragPtr, tdestNodeid);
3532 
3533  fragPtr.p->distributionKey++;
3534  fragPtr.p->distributionKey &= 255;
3535  break;
3536  case CreateFragReq::COMMIT_STORED:
3537  jam();
3538  CRASH_INSERTION(7139);
3539  /* ----------------------------------------------------------------------*/
3540  /* HERE WE ARE MOVING THE REPLICA TO THE STORED SECTION SINCE IT IS NOW */
3541  /* FULLY LOADED WITH ALL DATA NEEDED. */
3542  // We also update the order of the replicas here so that if the new
3543  // replica is the desired primary we insert it as primary.
3544  /* ----------------------------------------------------------------------*/
3545  removeOldStoredReplica(fragPtr, frReplicaPtr);
3546  linkStoredReplica(fragPtr, frReplicaPtr);
3547  updateNodeInfo(fragPtr);
3548  break;
3549  case CreateFragReq::START_LOGGING:
3550  jam();
3551  break;
3552  default:
3553  ndbrequire(false);
3554  break;
3555  }//switch
3556  DIH_TAB_WRITE_UNLOCK(tabPtr.p);
3557 
3558  /* ------------------------------------------------------------------------*/
3559  /* THE NEW NODE OF THIS REPLICA IS THE STARTING NODE. */
3560  /* ------------------------------------------------------------------------*/
3561  if (tFailedNodeId != tdestNodeid)
3562  {
3563  jam();
3568  /* IF WE ARE STARTING A TAKE OVER NODE WE MUST INVALIDATE ALL LCP'S. */
3569  /* OTHERWISE WE WILL TRY TO START LCP'S THAT DO NOT EXIST. */
3570  /* ---------------------------------------------------------------------*/
3571  frReplicaPtr.p->procNode = tdestNodeid;
3572  frReplicaPtr.p->noCrashedReplicas = 0;
3573  frReplicaPtr.p->createGci[0] = startGci;
3574  frReplicaPtr.p->replicaLastGci[0] = (Uint32)-1;
3575  for (Uint32 i = 0; i < MAX_LCP_STORED; i++)
3576  {
3577  frReplicaPtr.p->lcpStatus[i] = ZINVALID;
3578  }
3579  }
3580  else
3581  {
3582  jam();
3583  const Uint32 noCrashed = frReplicaPtr.p->noCrashedReplicas;
3584  arrGuard(noCrashed, 8);
3585  frReplicaPtr.p->createGci[noCrashed] = startGci;
3586  frReplicaPtr.p->replicaLastGci[noCrashed] = (Uint32)-1;
3587  }
3588 
3589  CreateFragConf * const conf = (CreateFragConf *)&signal->theData[0];
3590  conf->senderData = senderData;
3591  conf->tableId = tabPtr.i;
3592  conf->fragId = fragId;
3593  conf->sendingNodeId = cownNodeId;
3594  conf->startingNodeId = tdestNodeid;
3595  conf->failedNodeId = tFailedNodeId;
3596  sendSignal(senderRef, GSN_CREATE_FRAGCONF, signal,
3597  CreateFragConf::SignalLength, JBB);
3598 }//Dbdih::execCREATE_FRAGREQ()
3599 
3600 /*****************************************************************************/
3601 /*********** NODE ADDING MODULE *************/
3602 /*********** CODE TO HANDLE TAKE OVER *************/
3603 /*****************************************************************************/
3604 // A take over can be initiated by a number of things:
3605 // 1) A node restart, usually the node takes over itself but can also take
3606 // over somebody else if its own data was already taken over
3607 // 2) At system restart it is necessary to use the take over code to recover
3608 // nodes which had too old checkpoints to be restorable by the usual
3609 // restoration from disk.
3610 // 3) When a node has missed too many local checkpoints and is decided by the
3611 // master to be taken over by a hot spare node that sits around waiting
3612 // for this to happen.
3613 //
3614 // To support multiple node failures efficiently the code is written such that
3615 // only one take over can handle transitions in state but during a copy
3616 // fragment other take over's can perform state transitions.
3617 /*****************************************************************************/
3618 void Dbdih::startTakeOver(Signal* signal,
3619  Uint32 startNode,
3620  Uint32 nodeTakenOver,
3621  const StartCopyReq* req)
3622 {
3623  jam();
3624 
3625  TakeOverRecordPtr takeOverPtr;
3626  ndbrequire(c_activeTakeOverList.seize(takeOverPtr));
3627  takeOverPtr.p->startGci = SYSFILE->lastCompletedGCI[startNode];
3628  takeOverPtr.p->restorableGci = SYSFILE->lastCompletedGCI[startNode];
3629  takeOverPtr.p->toStartingNode = startNode;
3630  takeOverPtr.p->toFailedNode = nodeTakenOver;
3631  takeOverPtr.p->toCurrentTabref = 0;
3632  takeOverPtr.p->toCurrentFragid = 0;
3633 
3634  if (req)
3635  {
3636  jam();
3637  takeOverPtr.p->m_flags = req->flags;
3638  takeOverPtr.p->m_senderData = req->senderData;
3639  takeOverPtr.p->m_senderRef = req->senderRef;
3640  }
3641 
3642  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_START_FRAGMENTS;
3643  nr_start_fragments(signal, takeOverPtr);
3644 }//Dbdih::startTakeOver()
3645 
3646 void
3647 Dbdih::nr_start_fragments(Signal* signal,
3648  TakeOverRecordPtr takeOverPtr)
3649 {
3650  Uint32 loopCount = 0 ;
3651  TabRecordPtr tabPtr;
3652  while (loopCount++ < 100) {
3653  tabPtr.i = takeOverPtr.p->toCurrentTabref;
3654  if (tabPtr.i >= ctabFileSize) {
3655  jam();
3656  nr_run_redo(signal, takeOverPtr);
3657  return;
3658  }//if
3659  ptrAss(tabPtr, tabRecord);
3660  if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE ||
3661  tabPtr.p->tabStorage != TabRecord::ST_NORMAL)
3662  {
3663  jam();
3664  takeOverPtr.p->toCurrentFragid = 0;
3665  takeOverPtr.p->toCurrentTabref++;
3666  continue;
3667  }//if
3668  Uint32 fragId = takeOverPtr.p->toCurrentFragid;
3669  if (fragId >= tabPtr.p->totalfragments) {
3670  jam();
3671  takeOverPtr.p->toCurrentFragid = 0;
3672  takeOverPtr.p->toCurrentTabref++;
3673  continue;
3674  }//if
3675  FragmentstorePtr fragPtr;
3676  getFragstore(tabPtr.p, fragId, fragPtr);
3677  ReplicaRecordPtr loopReplicaPtr;
3678  loopReplicaPtr.i = fragPtr.p->oldStoredReplicas;
3679  while (loopReplicaPtr.i != RNIL) {
3680  ptrCheckGuard(loopReplicaPtr, creplicaFileSize, replicaRecord);
3681  if (loopReplicaPtr.p->procNode == takeOverPtr.p->toStartingNode) {
3682  jam();
3683  nr_start_fragment(signal, takeOverPtr, loopReplicaPtr);
3684  break;
3685  } else {
3686  jam();
3687  loopReplicaPtr.i = loopReplicaPtr.p->nextReplica;
3688  }//if
3689  }//while
3690  takeOverPtr.p->toCurrentFragid++;
3691  }//while
3692  signal->theData[0] = DihContinueB::ZTO_START_FRAGMENTS;
3693  signal->theData[1] = takeOverPtr.i;
3694  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
3695 }
3696 
3697 void
3698 Dbdih::nr_start_fragment(Signal* signal,
3699  TakeOverRecordPtr takeOverPtr,
3700  ReplicaRecordPtr replicaPtr)
3701 {
3702  Uint32 i;
3703  Uint32 maxLcpId = 0;
3704  Uint32 maxLcpIndex = ~0;
3705 
3706  Uint32 gci = 0;
3707  Uint32 restorableGCI = takeOverPtr.p->restorableGci;
3708 
3709 #if defined VM_TRACE || defined ERROR_INSERT
3710  ndbout_c("tab: %d frag: %d replicaP->nextLcp: %d",
3711  takeOverPtr.p->toCurrentTabref,
3712  takeOverPtr.p->toCurrentFragid,
3713  replicaPtr.p->nextLcp);
3714 #endif
3715 
3716  Int32 j = replicaPtr.p->noCrashedReplicas - 1;
3717  Uint32 idx = prevLcpNo(replicaPtr.p->nextLcp);
3718  for(i = 0; i<MAX_LCP_USED; i++, idx = prevLcpNo(idx))
3719  {
3720 #if defined VM_TRACE || defined ERROR_INSERT
3721  printf("scanning idx: %d lcpId: %d crashed replicas: %u %s",
3722  idx, replicaPtr.p->lcpId[idx],
3723  replicaPtr.p->noCrashedReplicas,
3724  replicaPtr.p->lcpStatus[idx] == ZVALID ? "VALID" : "NOT VALID");
3725 #endif
3726  if (replicaPtr.p->lcpStatus[idx] == ZVALID)
3727  {
3728  Uint32 startGci = replicaPtr.p->maxGciCompleted[idx] + 1;
3729  Uint32 stopGci = replicaPtr.p->maxGciStarted[idx];
3730 #if defined VM_TRACE || defined ERROR_INSERT
3731  ndbout_c(" maxGciCompleted: %u maxGciStarted: %u", startGci - 1, stopGci);
3732 #endif
3733  for (; j>= 0; j--)
3734  {
3735 #if defined VM_TRACE || defined ERROR_INSERT
3736  ndbout_c("crashed replica: %d(%d) replica(createGci: %u lastGci: %d )",
3737  j,
3738  replicaPtr.p->noCrashedReplicas,
3739  replicaPtr.p->createGci[j],
3740  replicaPtr.p->replicaLastGci[j]);
3741 #endif
3742  if (replicaPtr.p->createGci[j] <= startGci &&
3743  replicaPtr.p->replicaLastGci[j] >= stopGci)
3744  {
3745  maxLcpId = replicaPtr.p->lcpId[idx];
3746  maxLcpIndex = idx;
3747  gci = replicaPtr.p->replicaLastGci[j];
3748  goto done;
3749  }
3750  }
3751  }
3752  else
3753  {
3754 #if defined VM_TRACE || defined ERROR_INSERT
3755  printf("\n");
3756 #endif
3757  }
3758  }
3759 
3760  idx = 2; // backward compat code
3761 #if defined VM_TRACE || defined ERROR_INSERT
3762  ndbout_c("- scanning idx: %d lcpId: %d", idx, replicaPtr.p->lcpId[idx]);
3763 #endif
3764  if (replicaPtr.p->lcpStatus[idx] == ZVALID)
3765  {
3766  Uint32 startGci = replicaPtr.p->maxGciCompleted[idx] + 1;
3767  Uint32 stopGci = replicaPtr.p->maxGciStarted[idx];
3768  for (;j >= 0; j--)
3769  {
3770 #if defined VM_TRACE || defined ERROR_INSERT
3771  ndbout_c("crashed replica: %d(%d) replica(createGci: %u lastGci: %d )",
3772  j,
3773  replicaPtr.p->noCrashedReplicas,
3774  replicaPtr.p->createGci[j],
3775  replicaPtr.p->replicaLastGci[j]);
3776 #endif
3777  if (replicaPtr.p->createGci[j] <= startGci &&
3778  replicaPtr.p->replicaLastGci[j] >= stopGci)
3779  {
3780  maxLcpId = replicaPtr.p->lcpId[idx];
3781  maxLcpIndex = idx;
3782  gci = replicaPtr.p->replicaLastGci[j];
3783  goto done;
3784  }
3785  }
3786  }
3787 
3788 done:
3789 
3790  StartFragReq *req = (StartFragReq *)signal->getDataPtrSend();
3791  req->requestInfo = StartFragReq::SFR_RESTORE_LCP;
3792  if (maxLcpIndex == ~ (Uint32) 0)
3793  {
3797  jam();
3798  ndbassert(gci == 0);
3799  replicaPtr.p->m_restorable_gci = gci;
3800 
3801  req->userPtr = 0;
3802  req->userRef = reference();
3803  req->lcpNo = ZNIL;
3804  req->lcpId = 0;
3805  req->tableId = takeOverPtr.p->toCurrentTabref;
3806  req->fragId = takeOverPtr.p->toCurrentFragid;
3807  req->noOfLogNodes = 0;
3808 
3809  if (c_2pass_inr && cstarttype == NodeState::ST_INITIAL_NODE_RESTART)
3810  {
3821  if (takeOverPtr.p->startGci == 0)
3822  {
3823  jam();
3829  takeOverPtr.p->startGci = SYSFILE->lastCompletedGCI[cmasterNodeId];
3830  }
3831 
3832  TabRecordPtr tabPtr;
3833  tabPtr.i = takeOverPtr.p->toCurrentTabref;
3834  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
3835 
3836  FragmentstorePtr fragPtr;
3837  getFragstore(tabPtr.p, takeOverPtr.p->toCurrentFragid, fragPtr);
3838  Uint32 nodes[MAX_REPLICAS];
3839  extractNodeInfo(fragPtr.p, nodes);
3840 
3841  req->lqhLogNode[0] = nodes[0]; // Source
3842  req->requestInfo = StartFragReq::SFR_COPY_FRAG;
3843  replicaPtr.p->m_restorable_gci = takeOverPtr.p->startGci;
3844  }
3845 
3846  if (req->requestInfo == StartFragReq::SFR_RESTORE_LCP)
3847  {
3848  ndbout_c("node: %d tab: %d frag: %d no lcp to restore",
3849  takeOverPtr.p->toStartingNode,
3850  takeOverPtr.p->toCurrentTabref,
3851  takeOverPtr.p->toCurrentFragid);
3852  }
3853  else
3854  {
3855  ndbout_c("node: %d tab: %d frag: %d copying data from %u (gci: %u)",
3856  takeOverPtr.p->toStartingNode,
3857  takeOverPtr.p->toCurrentTabref,
3858  takeOverPtr.p->toCurrentFragid,
3859  req->lqhLogNode[0],
3860  takeOverPtr.p->startGci);
3861  }
3862 
3863  BlockReference ref = numberToRef(DBLQH, takeOverPtr.p->toStartingNode);
3864  sendSignal(ref, GSN_START_FRAGREQ, signal,
3865  StartFragReq::SignalLength, JBB);
3866  }
3867  else
3868  {
3869  jam();
3870  if (gci != restorableGCI)
3871  {
3872  Ptr<TabRecord> tabPtr;
3873  tabPtr.i = takeOverPtr.p->toCurrentTabref;
3874  ptrAss(tabPtr, tabRecord);
3875 
3876  FragmentstorePtr fragPtr;
3877  getFragstore(tabPtr.p, takeOverPtr.p->toCurrentFragid, fragPtr);
3878  dump_replica_info(fragPtr.p);
3879  }
3880  ndbassert(gci == restorableGCI);
3881  replicaPtr.p->m_restorable_gci = gci;
3882  Uint32 startGci = replicaPtr.p->maxGciCompleted[maxLcpIndex] + 1;
3883  if (startGci > gci)
3884  startGci = gci;
3885  ndbout_c("node: %d tab: %d frag: %d restore lcp: %u(idx: %u) maxGciStarted: %u maxGciCompleted: %u (restorable: %u(%u) newestRestorableGCI: %u)",
3886  takeOverPtr.p->toStartingNode,
3887  takeOverPtr.p->toCurrentTabref,
3888  takeOverPtr.p->toCurrentFragid,
3889  maxLcpId,
3890  maxLcpIndex,
3891  replicaPtr.p->maxGciStarted[maxLcpIndex],
3892  replicaPtr.p->maxGciCompleted[maxLcpIndex],
3893  restorableGCI,
3894  SYSFILE->lastCompletedGCI[takeOverPtr.p->toStartingNode],
3895  SYSFILE->newestRestorableGCI);
3896 
3897  StartFragReq *req = (StartFragReq *)signal->getDataPtrSend();
3898  req->userPtr = 0;
3899  req->userRef = reference();
3900  req->lcpNo = maxLcpIndex;
3901  req->lcpId = maxLcpId;
3902  req->tableId = takeOverPtr.p->toCurrentTabref;
3903  req->fragId = takeOverPtr.p->toCurrentFragid;
3904  req->noOfLogNodes = 1;
3905  req->lqhLogNode[0] = takeOverPtr.p->toStartingNode;
3906  req->startGci[0] = startGci;
3907  req->lastGci[0] = gci;
3908 
3909  BlockReference ref = numberToRef(DBLQH, takeOverPtr.p->toStartingNode);
3910  sendSignal(ref, GSN_START_FRAGREQ, signal,
3911  StartFragReq::SignalLength, JBB);
3912 
3913  if (startGci < takeOverPtr.p->startGci)
3914  {
3915  jam();
3916  takeOverPtr.p->startGci = startGci;
3917  }
3918  }
3919 }
3920 
3921 void
3922 Dbdih::nr_run_redo(Signal* signal, TakeOverRecordPtr takeOverPtr)
3923 {
3929  NdbNodeBitmask save = m_sr_nodes;
3930  m_sr_nodes.clear();
3931  m_sr_nodes.set(takeOverPtr.p->toStartingNode);
3932 
3933  Uint32 save_keepGCI = SYSFILE->keepGCI;
3934  if (takeOverPtr.p->startGci < SYSFILE->keepGCI)
3935  {
3936  jam();
3937  SYSFILE->keepGCI = takeOverPtr.p->startGci;
3938  ndbout_c("GSN_START_RECREQ keepGci: %u (%u)",
3939  takeOverPtr.p->startGci, save_keepGCI);
3940  }
3941 
3942  takeOverPtr.p->toCurrentTabref = 0;
3943  takeOverPtr.p->toCurrentFragid = 0;
3944  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_RUN_REDO;
3945  sendSTART_RECREQ(signal, takeOverPtr.p->toStartingNode, takeOverPtr.i);
3946 
3947  m_sr_nodes = save; // restore
3948  SYSFILE->keepGCI = save_keepGCI;
3949 }
3950 
3951 void
3952 Dbdih::nr_start_logging(Signal* signal, TakeOverRecordPtr takeOverPtr)
3953 {
3954  Uint32 loopCount = 0 ;
3955  TabRecordPtr tabPtr;
3956  while (loopCount++ < 100)
3957  {
3958  tabPtr.i = takeOverPtr.p->toCurrentTabref;
3959  if (tabPtr.i >= ctabFileSize)
3960  {
3961  jam();
3962  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_END_TO;
3963  EndToReq* req = (EndToReq*)signal->getDataPtrSend();
3964  req->senderData = takeOverPtr.i;
3965  req->senderRef = reference();
3966  req->flags = takeOverPtr.p->m_flags;
3967  sendSignal(cmasterdihref, GSN_END_TOREQ,
3968  signal, EndToReq::SignalLength, JBB);
3969 
3970  return;
3971  }
3972  ptrAss(tabPtr, tabRecord);
3973  if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE ||
3974  tabPtr.p->tabStorage != TabRecord::ST_NORMAL)
3975  {
3976  jam();
3977  takeOverPtr.p->toCurrentFragid = 0;
3978  takeOverPtr.p->toCurrentTabref++;
3979  continue;
3980  }
3981 
3982  Uint32 fragId = takeOverPtr.p->toCurrentFragid;
3983  if (fragId >= tabPtr.p->totalfragments)
3984  {
3985  jam();
3986  takeOverPtr.p->toCurrentFragid = 0;
3987  takeOverPtr.p->toCurrentTabref++;
3988  continue;
3989  }
3990 
3991  FragmentstorePtr fragPtr;
3992  getFragstore(tabPtr.p, fragId, fragPtr);
3993  ReplicaRecordPtr loopReplicaPtr;
3994  loopReplicaPtr.i = fragPtr.p->storedReplicas;
3995  while (loopReplicaPtr.i != RNIL)
3996  {
3997  ptrCheckGuard(loopReplicaPtr, creplicaFileSize, replicaRecord);
3998  if (loopReplicaPtr.p->procNode == takeOverPtr.p->toStartingNode)
3999  {
4000  jam();
4001  ndbrequire(loopReplicaPtr.p->procNode == getOwnNodeId());
4002  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SL_COPY_ACTIVE;
4003 
4004  Uint32 instanceKey = dihGetInstanceKey(fragPtr);
4005  BlockReference lqhRef = numberToRef(DBLQH, instanceKey,
4006  takeOverPtr.p->toStartingNode);
4007 
4008  CopyActiveReq * const req = (CopyActiveReq *)&signal->theData[0];
4009  req->userPtr = takeOverPtr.i;
4010  req->userRef = reference();
4011  req->tableId = takeOverPtr.p->toCurrentTabref;
4012  req->fragId = takeOverPtr.p->toCurrentFragid;
4013  req->distributionKey = fragPtr.p->distributionKey;
4014  req->flags = 0;
4015  sendSignal(lqhRef,GSN_COPY_ACTIVEREQ, signal,
4016  CopyActiveReq::SignalLength, JBB);
4017  return;
4018  }
4019  else
4020  {
4021  jam();
4022  loopReplicaPtr.i = loopReplicaPtr.p->nextReplica;
4023  }
4024  }
4025  takeOverPtr.p->toCurrentFragid++;
4026  }
4027  signal->theData[0] = DihContinueB::ZTO_START_LOGGING;
4028  signal->theData[1] = takeOverPtr.i;
4029  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
4030 }
4031 
4032 void
4033 Dbdih::sendStartTo(Signal* signal, TakeOverRecordPtr takeOverPtr)
4034 {
4035  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_START_TO;
4036 
4037  StartToReq* req = (StartToReq*)signal->getDataPtrSend();
4038  req->senderData = takeOverPtr.i;
4039  req->senderRef = reference();
4040  req->startingNodeId = takeOverPtr.p->toStartingNode;
4041  sendSignal(cmasterdihref, GSN_START_TOREQ,
4042  signal, StartToReq::SignalLength, JBB);
4043 }
4044 
4045 void
4046 Dbdih::execSTART_TOREF(Signal* signal)
4047 {
4048  jamEntry();
4049 
4050  StartToRef* ref = (StartToRef*)signal->getDataPtr();
4051  Uint32 errCode = ref->errorCode;
4052  (void)errCode; // TODO check for "valid" error
4053 
4054  TakeOverRecordPtr takeOverPtr;
4055  c_takeOverPool.getPtr(takeOverPtr, ref->senderData);
4056 
4057  signal->theData[0] = DihContinueB::ZSEND_START_TO;
4058  signal->theData[1] = takeOverPtr.i;
4059 
4060  sendSignalWithDelay(reference(), GSN_CONTINUEB,
4061  signal, 5000, 2);
4062 }
4063 
4064 void
4065 Dbdih::execSTART_TOCONF(Signal* signal)
4066 {
4067  jamEntry();
4068  StartToConf * conf = (StartToConf*)signal->getDataPtr();
4069 
4070  TakeOverRecordPtr takeOverPtr;
4071  c_takeOverPool.getPtr(takeOverPtr, conf->senderData);
4072 
4073  CRASH_INSERTION(7133);
4074 
4078  startNextCopyFragment(signal, takeOverPtr.i);
4079 }
4080 
4081 void Dbdih::startNextCopyFragment(Signal* signal, Uint32 takeOverPtrI)
4082 {
4083  TabRecordPtr tabPtr;
4084  TakeOverRecordPtr takeOverPtr;
4085  c_takeOverPool.getPtr(takeOverPtr, takeOverPtrI);
4086 
4087  Uint32 loopCount;
4088  loopCount = 0;
4089  if (ERROR_INSERTED(7159)) {
4090  loopCount = 100;
4091  }//if
4092  while (loopCount++ < 100) {
4093  tabPtr.i = takeOverPtr.p->toCurrentTabref;
4094  if (tabPtr.i >= ctabFileSize) {
4095  jam();
4096  CRASH_INSERTION(7136);
4097  toCopyCompletedLab(signal, takeOverPtr);
4098  return;
4099  }//if
4100  ptrAss(tabPtr, tabRecord);
4101  if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE){
4102  jam();
4103  takeOverPtr.p->toCurrentFragid = 0;
4104  takeOverPtr.p->toCurrentTabref++;
4105  continue;
4106  }//if
4107  Uint32 fragId = takeOverPtr.p->toCurrentFragid;
4108  if (fragId >= tabPtr.p->totalfragments) {
4109  jam();
4110  takeOverPtr.p->toCurrentFragid = 0;
4111  takeOverPtr.p->toCurrentTabref++;
4112  if (ERROR_INSERTED(7135)) {
4113  if (takeOverPtr.p->toCurrentTabref == 1) {
4114  ndbrequire(false);
4115  }//if
4116  }//if
4117  continue;
4118  }//if
4119  FragmentstorePtr fragPtr;
4120  getFragstore(tabPtr.p, fragId, fragPtr);
4121  ReplicaRecordPtr loopReplicaPtr;
4122  loopReplicaPtr.i = fragPtr.p->oldStoredReplicas;
4123  while (loopReplicaPtr.i != RNIL) {
4124  ptrCheckGuard(loopReplicaPtr, creplicaFileSize, replicaRecord);
4125  if (loopReplicaPtr.p->procNode == takeOverPtr.p->toFailedNode) {
4126  jam();
4127  /* ----------------------------------------------------------------- */
4128  /* WE HAVE FOUND A REPLICA THAT BELONGED THE FAILED NODE THAT NEEDS */
4129  /* TAKE OVER. WE TAKE OVER THIS REPLICA TO THE NEW NODE. */
4130  /* ----------------------------------------------------------------- */
4131  takeOverPtr.p->toCurrentReplica = loopReplicaPtr.i;
4132  toCopyFragLab(signal, takeOverPtr.i);
4133  return;
4134  } else if (loopReplicaPtr.p->procNode == takeOverPtr.p->toStartingNode) {
4135  jam();
4136  /* ----------------------------------------------------------------- */
4137  /* WE HAVE OBVIOUSLY STARTED TAKING OVER THIS WITHOUT COMPLETING IT. */
4138  /* WE */
4139  /* NEED TO COMPLETE THE TAKE OVER OF THIS REPLICA. */
4140  /* ----------------------------------------------------------------- */
4141  takeOverPtr.p->toCurrentReplica = loopReplicaPtr.i;
4142  toCopyFragLab(signal, takeOverPtr.i);
4143  return;
4144  } else {
4145  jam();
4146  loopReplicaPtr.i = loopReplicaPtr.p->nextReplica;
4147  }//if
4148  }//while
4149  takeOverPtr.p->toCurrentFragid++;
4150  }//while
4151  signal->theData[0] = DihContinueB::ZTO_START_COPY_FRAG;
4152  signal->theData[1] = takeOverPtr.i;
4153  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
4154 }//Dbdih::startNextCopyFragment()
4155 
4156 void Dbdih::toCopyFragLab(Signal* signal,
4157  Uint32 takeOverPtrI)
4158 {
4159  TakeOverRecordPtr takeOverPtr;
4160  c_takeOverPool.getPtr(takeOverPtr, takeOverPtrI);
4161 
4165  TabRecordPtr tabPtr;
4166  tabPtr.i = takeOverPtr.p->toCurrentTabref;
4167  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
4168 
4169  FragmentstorePtr fragPtr;
4170  getFragstore(tabPtr.p, takeOverPtr.p->toCurrentFragid, fragPtr);
4171  Uint32 nodes[MAX_REPLICAS];
4172  extractNodeInfo(fragPtr.p, nodes);
4173  takeOverPtr.p->toCopyNode = nodes[0];
4174 
4175  PrepareCopyFragReq* req= (PrepareCopyFragReq*)signal->getDataPtrSend();
4176  req->senderRef = reference();
4177  req->senderData = takeOverPtrI;
4178  req->tableId = takeOverPtr.p->toCurrentTabref;
4179  req->fragId = takeOverPtr.p->toCurrentFragid;
4180  req->copyNodeId = takeOverPtr.p->toCopyNode;
4181  req->startingNodeId = takeOverPtr.p->toStartingNode; // Dst
4182 
4183  Uint32 instanceKey = dihGetInstanceKey(req->tableId, req->fragId);
4184  Uint32 ref = numberToRef(DBLQH, instanceKey, takeOverPtr.p->toStartingNode);
4185 
4186  sendSignal(ref, GSN_PREPARE_COPY_FRAG_REQ, signal,
4187  PrepareCopyFragReq::SignalLength, JBB);
4188 
4189  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_PREPARE_COPY;
4190 }
4191 
4192 void
4193 Dbdih::execPREPARE_COPY_FRAG_REF(Signal* signal)
4194 {
4195  jamEntry();
4196  PrepareCopyFragRef ref = *(PrepareCopyFragRef*)signal->getDataPtr();
4197 
4198  TakeOverRecordPtr takeOverPtr;
4199  c_takeOverPool.getPtr(takeOverPtr, ref.senderData);
4200 
4201  ndbrequire(takeOverPtr.p->toSlaveStatus == TakeOverRecord::TO_PREPARE_COPY);
4202 
4206  CopyFragRef * cfref = (CopyFragRef*)signal->getDataPtrSend();
4207  cfref->userPtr = ref.senderData;
4208  cfref->startingNodeId = ref.startingNodeId;
4209  cfref->errorCode = ref.errorCode;
4210  cfref->tableId = ref.tableId;
4211  cfref->fragId = ref.fragId;
4212  cfref->sendingNodeId = ref.copyNodeId;
4213  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_COPY_FRAG;
4214  execCOPY_FRAGREF(signal);
4215 }
4216 
4217 void
4218 Dbdih::execPREPARE_COPY_FRAG_CONF(Signal* signal)
4219 {
4220  jamEntry();
4221  PrepareCopyFragConf conf = *(PrepareCopyFragConf*)signal->getDataPtr();
4222 
4223  TakeOverRecordPtr takeOverPtr;
4224  c_takeOverPool.getPtr(takeOverPtr, conf.senderData);
4225 
4226  Uint32 version = getNodeInfo(refToNode(conf.senderRef)).m_version;
4227  ndbrequire(ndb_check_prep_copy_frag_version(version) >= 2);
4228  takeOverPtr.p->maxPage = conf.maxPageNo;
4229 
4233  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_UPDATE_BEFORE_STORED;
4234  sendUpdateTo(signal, takeOverPtr);
4235 }
4236 
4237 void
4238 Dbdih::sendUpdateTo(Signal* signal, TakeOverRecordPtr takeOverPtr)
4239 {
4240  UpdateToReq* req = (UpdateToReq*)signal->getDataPtrSend();
4241  req->senderData = takeOverPtr.i;
4242  req->senderRef = reference();
4243  req->startingNodeId = takeOverPtr.p->toStartingNode;
4244  req->copyNodeId = takeOverPtr.p->toCopyNode;
4245  req->tableId = takeOverPtr.p->toCurrentTabref;
4246  req->fragmentNo = takeOverPtr.p->toCurrentFragid;
4247  switch(takeOverPtr.p->toSlaveStatus){
4248  case TakeOverRecord::TO_UPDATE_BEFORE_STORED:
4249  jam();
4250  req->requestType = UpdateToReq::BEFORE_STORED;
4251  break;
4252  case TakeOverRecord::TO_UPDATE_AFTER_STORED:
4253  req->requestType = UpdateToReq::AFTER_STORED;
4254  break;
4255  case TakeOverRecord::TO_UPDATE_BEFORE_COMMIT:
4256  jam();
4257  req->requestType = UpdateToReq::BEFORE_COMMIT_STORED;
4258  break;
4259  case TakeOverRecord::TO_UPDATE_AFTER_COMMIT:
4260  jam();
4261  req->requestType = UpdateToReq::AFTER_COMMIT_STORED;
4262  break;
4263  default:
4264  jamLine(takeOverPtr.p->toSlaveStatus);
4265  ndbrequire(false);
4266  }
4267  sendSignal(cmasterdihref, GSN_UPDATE_TOREQ,
4268  signal, UpdateToReq::SignalLength, JBB);
4269 }
4270 
4271 void
4272 Dbdih::execUPDATE_TOREF(Signal* signal)
4273 {
4274  jamEntry();
4275  UpdateToRef* ref = (UpdateToRef*)signal->getDataPtr();
4276  Uint32 errCode = ref->errorCode;
4277  (void)errCode; // TODO check for "valid" error
4278 
4279  TakeOverRecordPtr takeOverPtr;
4280  c_takeOverPool.getPtr(takeOverPtr, ref->senderData);
4281 
4282  signal->theData[0] = DihContinueB::ZSEND_UPDATE_TO;
4283  signal->theData[1] = takeOverPtr.i;
4284 
4285  sendSignalWithDelay(reference(), GSN_CONTINUEB,
4286  signal, 5000, 2);
4287 }
4288 
4289 void
4290 Dbdih::execUPDATE_TOCONF(Signal* signal)
4291 {
4292  jamEntry();
4293 
4294  UpdateToConf* conf = (UpdateToConf*)signal->getDataPtr();
4295 
4296  TakeOverRecordPtr takeOverPtr;
4297  c_takeOverPool.getPtr(takeOverPtr, conf->senderData);
4298 
4299  switch(takeOverPtr.p->toSlaveStatus){
4300  case TakeOverRecord::TO_UPDATE_BEFORE_STORED:
4301  jam();
4302 
4303  CRASH_INSERTION(7154);
4304 
4305  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_CREATE_FRAG_STORED;
4306  sendCreateFragReq(signal, ZINIT_CREATE_GCI, CreateFragReq::STORED, takeOverPtr.i);
4307  return;
4308  case TakeOverRecord::TO_UPDATE_AFTER_STORED:
4309  jam();
4310 
4311  CRASH_INSERTION(7195);
4312 
4313  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_COPY_FRAG;
4314  toStartCopyFrag(signal, takeOverPtr);
4315  return;
4316  case TakeOverRecord::TO_UPDATE_BEFORE_COMMIT:
4317  jam();
4318 
4319  CRASH_INSERTION(7196);
4320 
4321  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_CREATE_FRAG_COMMIT;
4322  sendCreateFragReq(signal, takeOverPtr.p->startGci,
4323  CreateFragReq::COMMIT_STORED, takeOverPtr.i);
4324  return;
4325  case TakeOverRecord::TO_UPDATE_AFTER_COMMIT:
4326  jam();
4327 
4328  CRASH_INSERTION(7197);
4329 
4330  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SELECTING_NEXT;
4331  startNextCopyFragment(signal, takeOverPtr.i);
4332  return;
4333  default:
4334  ndbrequire(false);
4335  }
4336 }
4337 
4338 void
4339 Dbdih::toStartCopyFrag(Signal* signal, TakeOverRecordPtr takeOverPtr)
4340 {
4341  TabRecordPtr tabPtr;
4342  tabPtr.i = takeOverPtr.p->toCurrentTabref;
4343  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
4344 
4345  Uint32 fragId = takeOverPtr.p->toCurrentFragid;
4346 
4347  FragmentstorePtr fragPtr;
4348  getFragstore(tabPtr.p, fragId, fragPtr);
4349 
4350  ReplicaRecordPtr replicaPtr;
4351  findReplica(replicaPtr, fragPtr.p, getOwnNodeId(), true);
4352 
4353  Uint32 gci = replicaPtr.p->m_restorable_gci;
4354  replicaPtr.p->m_restorable_gci = 0; // used in union...
4355 
4356  Uint32 instanceKey = dihGetInstanceKey(tabPtr.i, fragId);
4357  BlockReference ref = numberToRef(DBLQH, instanceKey,
4358  takeOverPtr.p->toCopyNode);
4359  CopyFragReq * const copyFragReq = (CopyFragReq *)&signal->theData[0];
4360  copyFragReq->userPtr = takeOverPtr.i;
4361  copyFragReq->userRef = reference();
4362  copyFragReq->tableId = tabPtr.i;
4363  copyFragReq->fragId = fragId;
4364  copyFragReq->nodeId = takeOverPtr.p->toStartingNode;
4365  copyFragReq->schemaVersion = tabPtr.p->schemaVersion;
4366  copyFragReq->distributionKey = fragPtr.p->distributionKey;
4367  copyFragReq->gci = gci;
4368  Uint32 len = copyFragReq->nodeCount =
4369  extractNodeInfo(fragPtr.p,
4370  copyFragReq->nodeList);
4371  copyFragReq->nodeList[len] = takeOverPtr.p->maxPage;
4372  copyFragReq->nodeList[len+1] = CopyFragReq::CFR_TRANSACTIONAL;
4373  sendSignal(ref, GSN_COPY_FRAGREQ, signal,
4374  CopyFragReq::SignalLength + len, JBB);
4375 }//Dbdih::toStartCopy()
4376 
4377 void Dbdih::sendCreateFragReq(Signal* signal,
4378  Uint32 startGci,
4379  Uint32 replicaType,
4380  Uint32 takeOverPtrI)
4381 {
4382  Ptr<TakeOverRecord> takeOverPtr;
4383  c_takeOverPool.getPtr(takeOverPtr, takeOverPtrI);
4384 
4385  sendLoopMacro(CREATE_FRAGREQ, nullRoutine, RNIL);
4386 
4387  CreateFragReq * const req = (CreateFragReq *)&signal->theData[0];
4388  req->senderData = takeOverPtr.i;
4389  req->senderRef = reference();
4390  req->tableId = takeOverPtr.p->toCurrentTabref;
4391  req->fragId = takeOverPtr.p->toCurrentFragid;
4392  req->startingNodeId = takeOverPtr.p->toStartingNode;
4393  req->copyNodeId = takeOverPtr.p->toCopyNode;
4394  req->failedNodeId = takeOverPtr.p->toFailedNode;
4395  req->startGci = startGci;
4396  req->replicaType = replicaType;
4397 
4398  NodeRecordPtr nodePtr;
4399  nodePtr.i = cfirstAliveNode;
4400  do {
4401  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
4402  BlockReference ref = calcDihBlockRef(nodePtr.i);
4403  sendSignal(ref, GSN_CREATE_FRAGREQ, signal,
4404  CreateFragReq::SignalLength, JBB);
4405  nodePtr.i = nodePtr.p->nextNode;
4406  } while (nodePtr.i != RNIL);
4407 }//Dbdih::sendCreateFragReq()
4408 
4409 void Dbdih::execCREATE_FRAGCONF(Signal* signal)
4410 {
4411  jamEntry();
4412  CRASH_INSERTION(7148);
4413  CreateFragConf * conf = (CreateFragConf *)&signal->theData[0];
4414 
4415  TakeOverRecordPtr takeOverPtr;
4416  c_takeOverPool.getPtr(takeOverPtr, conf->senderData);
4417 
4418  receiveLoopMacro(CREATE_FRAGREQ, conf->sendingNodeId);
4419 
4420  switch(takeOverPtr.p->toSlaveStatus){
4421  case TakeOverRecord::TO_CREATE_FRAG_STORED:
4422  jam();
4423  CRASH_INSERTION(7198);
4424  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_UPDATE_AFTER_STORED;
4425  break;
4426  case TakeOverRecord::TO_CREATE_FRAG_COMMIT:
4427  jam();
4428  CRASH_INSERTION(7199);
4429  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_UPDATE_AFTER_COMMIT;
4430  break;
4431  case TakeOverRecord::TO_SL_CREATE_FRAG:
4432  jam();
4433  //CRASH_INSERTION(
4434  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_START_LOGGING;
4435  takeOverPtr.p->toCurrentFragid++;
4436  signal->theData[0] = DihContinueB::ZTO_START_LOGGING;
4437  signal->theData[1] = takeOverPtr.i;
4438  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
4439  return;
4440  default:
4441  jamLine(takeOverPtr.p->toSlaveStatus);
4442  ndbrequire(false);
4443  }
4444 
4445  sendUpdateTo(signal, takeOverPtr);
4446 }//Dbdih::execCREATE_FRAGCONF()
4447 
4448 void Dbdih::execCOPY_FRAGREF(Signal* signal)
4449 {
4450  const CopyFragRef * const ref = (CopyFragRef *)&signal->theData[0];
4451  jamEntry();
4452  Uint32 takeOverPtrI = ref->userPtr;
4453  Uint32 startingNodeId = ref->startingNodeId;
4454  Uint32 errorCode = ref->errorCode;
4455 
4456  TakeOverRecordPtr takeOverPtr;
4457  c_takeOverPool.getPtr(takeOverPtr, takeOverPtrI);
4458  ndbrequire(ref->tableId == takeOverPtr.p->toCurrentTabref);
4459  ndbrequire(ref->fragId == takeOverPtr.p->toCurrentFragid);
4460  ndbrequire(ref->startingNodeId == takeOverPtr.p->toStartingNode);
4461  ndbrequire(ref->sendingNodeId == takeOverPtr.p->toCopyNode);
4462  ndbrequire(takeOverPtr.p->toSlaveStatus == TakeOverRecord::TO_COPY_FRAG);
4463 
4464  //--------------------------------------------------------------------------
4465  // For some reason we did not succeed in copying a fragment. We treat this
4466  // as a serious failure and crash the starting node.
4467  //--------------------------------------------------------------------------
4468  BlockReference cntrRef = calcNdbCntrBlockRef(startingNodeId);
4469  SystemError * const sysErr = (SystemError*)&signal->theData[0];
4470  sysErr->errorCode = SystemError::CopyFragRefError;
4471  sysErr->errorRef = reference();
4472  sysErr->data[0] = errorCode;
4473  sysErr->data[1] = 0;
4474  sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal,
4475  SystemError::SignalLength, JBB);
4476  return;
4477 }//Dbdih::execCOPY_FRAGREF()
4478 
4479 void Dbdih::execCOPY_FRAGCONF(Signal* signal)
4480 {
4481  const CopyFragConf * const conf = (CopyFragConf *)&signal->theData[0];
4482  jamEntry();
4483  CRASH_INSERTION(7142);
4484 
4485  TakeOverRecordPtr takeOverPtr;
4486  c_takeOverPool.getPtr(takeOverPtr, conf->userPtr);
4487 
4488  Uint32 rows_lo = conf->rows_lo;
4489  Uint32 bytes_lo = conf->bytes_lo;
4490 
4491  ndbrequire(conf->tableId == takeOverPtr.p->toCurrentTabref);
4492  ndbrequire(conf->fragId == takeOverPtr.p->toCurrentFragid);
4493  ndbrequire(conf->startingNodeId == takeOverPtr.p->toStartingNode);
4494  ndbrequire(conf->sendingNodeId == takeOverPtr.p->toCopyNode);
4495  ndbrequire(takeOverPtr.p->toSlaveStatus == TakeOverRecord::TO_COPY_FRAG);
4496 
4497  TabRecordPtr tabPtr;
4498  tabPtr.i = takeOverPtr.p->toCurrentTabref;
4499  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
4500 
4501  FragmentstorePtr fragPtr;
4502  getFragstore(tabPtr.p, takeOverPtr.p->toCurrentFragid, fragPtr);
4503  Uint32 instanceKey = dihGetInstanceKey(fragPtr);
4504  BlockReference lqhRef = numberToRef(DBLQH, instanceKey,
4505  takeOverPtr.p->toStartingNode);
4506  CopyActiveReq * const req = (CopyActiveReq *)&signal->theData[0];
4507  req->userPtr = takeOverPtr.i;
4508  req->userRef = reference();
4509  req->tableId = takeOverPtr.p->toCurrentTabref;
4510  req->fragId = takeOverPtr.p->toCurrentFragid;
4511  req->distributionKey = fragPtr.p->distributionKey;
4512  req->flags = 0;
4513 
4514  Uint32 min_version = getNodeVersionInfo().m_type[NodeInfo::DB].m_min_version;
4515  if (ndb_delayed_copy_active_req(min_version))
4516  {
4517  jam();
4523  req->flags |= CopyActiveReq::CAR_NO_WAIT | CopyActiveReq::CAR_NO_LOGGING;
4524  }
4525 
4526  sendSignal(lqhRef, GSN_COPY_ACTIVEREQ, signal,
4527  CopyActiveReq::SignalLength, JBB);
4528 
4529  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_COPY_ACTIVE;
4530 
4531  signal->theData[0] = NDB_LE_NR_CopyFragDone;
4532  signal->theData[1] = getOwnNodeId();
4533  signal->theData[2] = takeOverPtr.p->toCurrentTabref;
4534  signal->theData[3] = takeOverPtr.p->toCurrentFragid;
4535  signal->theData[4] = rows_lo;
4536  signal->theData[5] = 0;
4537  signal->theData[6] = bytes_lo;
4538  signal->theData[7] = 0;
4539  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 8, JBB);
4540 }//Dbdih::execCOPY_FRAGCONF()
4541 
4542 void Dbdih::execCOPY_ACTIVECONF(Signal* signal)
4543 {
4544  const CopyActiveConf * const conf = (CopyActiveConf *)&signal->theData[0];
4545  jamEntry();
4546  CRASH_INSERTION(7143);
4547 
4548  TakeOverRecordPtr takeOverPtr;
4549  c_takeOverPool.getPtr(takeOverPtr, conf->userPtr);
4550 
4551  ndbrequire(conf->tableId == takeOverPtr.p->toCurrentTabref);
4552  ndbrequire(conf->fragId == takeOverPtr.p->toCurrentFragid);
4553  ndbrequire(checkNodeAlive(conf->startingNodeId));
4554 
4555  takeOverPtr.p->startGci = conf->startGci;
4556 
4557  if (takeOverPtr.p->toSlaveStatus == TakeOverRecord::TO_COPY_ACTIVE)
4558  {
4559  jam();
4560  ndbrequire(takeOverPtr.p->toSlaveStatus == TakeOverRecord::TO_COPY_ACTIVE);
4561  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_UPDATE_BEFORE_COMMIT;
4562  sendUpdateTo(signal, takeOverPtr);
4563  }
4564  else
4565  {
4566  jam();
4567  ndbrequire(takeOverPtr.p->toSlaveStatus==TakeOverRecord::TO_SL_COPY_ACTIVE);
4568  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SL_CREATE_FRAG;
4569  sendCreateFragReq(signal, takeOverPtr.p->startGci,
4570  CreateFragReq::START_LOGGING, takeOverPtr.i);
4571  }
4572 }//Dbdih::execCOPY_ACTIVECONF()
4573 
4574 void Dbdih::toCopyCompletedLab(Signal * signal, TakeOverRecordPtr takeOverPtr)
4575 {
4576  signal->theData[0] = NDB_LE_NR_CopyFragsCompleted;
4577  signal->theData[1] = takeOverPtr.p->toStartingNode;
4578  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
4579 
4580  Uint32 min_version = getNodeVersionInfo().m_type[NodeInfo::DB].m_min_version;
4581  if (ndb_delayed_copy_active_req(min_version))
4582  {
4583  jam();
4584  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_START_LOGGING;
4585  takeOverPtr.p->toCurrentTabref = 0;
4586  takeOverPtr.p->toCurrentFragid = 0;
4587  takeOverPtr.p->toCurrentReplica = RNIL;
4588  nr_start_logging(signal, takeOverPtr);
4589  return;
4590  }
4591  else
4592  {
4593  jam();
4594 
4595  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_END_TO;
4596 
4597  EndToReq* req = (EndToReq*)signal->getDataPtrSend();
4598  req->senderData = takeOverPtr.i;
4599  req->senderRef = reference();
4600  req->flags = takeOverPtr.p->m_flags;
4601  sendSignal(cmasterdihref, GSN_END_TOREQ,
4602  signal, EndToReq::SignalLength, JBB);
4603  return;
4604  }
4605 }//Dbdih::toCopyCompletedLab()
4606 
4607 void
4608 Dbdih::execEND_TOREF(Signal* signal)
4609 {
4610  jamEntry();
4611  EndToRef* ref = (EndToRef*)signal->getDataPtr();
4612 
4613  TakeOverRecordPtr takeOverPtr;
4614  c_takeOverPool.getPtr(takeOverPtr, ref->senderData);
4615 
4616  ndbrequire(false);
4617 }
4618 
4619 void
4620 Dbdih::execEND_TOCONF(Signal* signal)
4621 {
4622  jamEntry();
4623  EndToConf* conf = (EndToConf*)signal->getDataPtr();
4624 
4625  CRASH_INSERTION(7144);
4626 
4627  TakeOverRecordPtr takeOverPtr;
4628  c_takeOverPool.getPtr(takeOverPtr, conf->senderData);
4629 
4630  Uint32 senderData = takeOverPtr.p->m_senderData;
4631  Uint32 senderRef = takeOverPtr.p->m_senderRef;
4632  Uint32 nodeId = takeOverPtr.p->toStartingNode;
4633 
4634  releaseTakeOver(takeOverPtr);
4635 
4636  StartCopyConf* ret = (StartCopyConf*)signal->getDataPtrSend();
4637  ret->startingNodeId = nodeId;
4638  ret->senderData = senderData;
4639  ret->senderRef = reference();
4640  sendSignal(senderRef, GSN_START_COPYCONF, signal,
4641  StartCopyConf::SignalLength, JBB);
4642 }
4643 
4644 void Dbdih::releaseTakeOver(TakeOverRecordPtr takeOverPtr)
4645 {
4646  takeOverPtr.p->toCopyNode = RNIL;
4647  takeOverPtr.p->toCurrentFragid = RNIL;
4648  takeOverPtr.p->toCurrentReplica = RNIL;
4649  takeOverPtr.p->toCurrentTabref = RNIL;
4650  takeOverPtr.p->toFailedNode = RNIL;
4651  takeOverPtr.p->toStartingNode = RNIL;
4652  takeOverPtr.p->toStartTime = 0;
4653  takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_IDLE;
4654  takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_MASTER_IDLE;
4655 
4656  c_activeTakeOverList.release(takeOverPtr);
4657 }//Dbdih::releaseTakeOver()
4658 
4659 
4660 /*****************************************************************************/
4661 /* ------------------------------------------------------------------------- */
4662 /* WE HAVE BEEN REQUESTED TO PERFORM A SYSTEM RESTART. WE START BY */
4663 /* READING THE GCI FILES. THIS REQUEST WILL ONLY BE SENT TO THE MASTER */
4664 /* DIH. THAT MEANS WE HAVE TO REPLICATE THE INFORMATION WE READ FROM */
4665 /* OUR FILES TO ENSURE THAT ALL NODES HAVE THE SAME DISTRIBUTION */
4666 /* INFORMATION. */
4667 /* ------------------------------------------------------------------------- */
4668 /*****************************************************************************/
4669 void Dbdih::readGciFileLab(Signal* signal)
4670 {
4671  FileRecordPtr filePtr;
4672  filePtr.i = crestartInfoFile[0];
4673  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4674  filePtr.p->reqStatus = FileRecord::OPENING_GCP;
4675 
4676  openFileRo(signal, filePtr);
4677 }//Dbdih::readGciFileLab()
4678 
4679 void Dbdih::openingGcpLab(Signal* signal, FileRecordPtr filePtr)
4680 {
4681  /* ----------------------------------------------------------------------- */
4682  /* WE HAVE SUCCESSFULLY OPENED A FILE CONTAINING INFORMATION ABOUT */
4683  /* THE GLOBAL CHECKPOINTS THAT ARE POSSIBLE TO RESTART. */
4684  /* ----------------------------------------------------------------------- */
4685  readRestorableGci(signal, filePtr);
4686  filePtr.p->reqStatus = FileRecord::READING_GCP;
4687 }//Dbdih::openingGcpLab()
4688 
4689 void Dbdih::readingGcpLab(Signal* signal, FileRecordPtr filePtr)
4690 {
4691  /* ----------------------------------------------------------------------- */
4692  /* WE HAVE NOW SUCCESSFULLY MANAGED TO READ IN THE GLOBAL CHECKPOINT */
4693  /* INFORMATION FROM FILE. LATER WE WILL ADD SOME FUNCTIONALITY THAT */
4694  /* CHECKS THE RESTART TIMERS TO DEDUCE FROM WHERE TO RESTART. */
4695  /* NOW WE WILL SIMPLY RESTART FROM THE NEWEST GLOBAL CHECKPOINT */
4696  /* POSSIBLE TO RESTORE. */
4697  /* */
4698  /* BEFORE WE INVOKE DICT WE NEED TO COPY CRESTART_INFO TO ALL NODES. */
4699  /* WE ALSO COPY TO OUR OWN NODE. TO ENABLE US TO DO THIS PROPERLY WE */
4700  /* START BY CLOSING THIS FILE. */
4701  /* ----------------------------------------------------------------------- */
4702  globalData.m_restart_seq = ++SYSFILE->m_restart_seq;
4703  closeFile(signal, filePtr);
4704  filePtr.p->reqStatus = FileRecord::CLOSING_GCP;
4705 }//Dbdih::readingGcpLab()
4706 
4707 void Dbdih::closingGcpLab(Signal* signal, FileRecordPtr filePtr)
4708 {
4709  if (Sysfile::getInitialStartOngoing(SYSFILE->systemRestartBits) == false){
4710  jam();
4711  selectMasterCandidateAndSend(signal);
4712  return;
4713  } else {
4714  jam();
4715  sendDihRestartRef(signal);
4716  return;
4717  }//if
4718 }//Dbdih::closingGcpLab()
4719 
4720 void
4721 Dbdih::sendDihRestartRef(Signal* signal)
4722 {
4723  jam();
4724 
4729  NdbNodeBitmask no_nodegroup_mask;
4730 
4732  m_ctx.m_config.getClusterConfigIterator();
4733  for(ndb_mgm_first(iter); ndb_mgm_valid(iter); ndb_mgm_next(iter))
4734  {
4735  jam();
4736  Uint32 nodeId;
4737  Uint32 nodeType;
4738 
4739  ndbrequire(!ndb_mgm_get_int_parameter(iter,CFG_NODE_ID, &nodeId));
4740  ndbrequire(!ndb_mgm_get_int_parameter(iter,CFG_TYPE_OF_SECTION,
4741  &nodeType));
4742 
4743  if (nodeType == NodeInfo::DB)
4744  {
4745  jam();
4746  Uint32 ng;
4747  if (ndb_mgm_get_int_parameter(iter, CFG_DB_NODEGROUP, &ng) == 0)
4748  {
4749  jam();
4750  if (ng == NDB_NO_NODEGROUP)
4751  {
4752  no_nodegroup_mask.set(nodeId);
4753  }
4754  }
4755  }
4756  }
4757  DihRestartRef * ref = CAST_PTR(DihRestartRef, signal->getDataPtrSend());
4758  no_nodegroup_mask.copyto(NdbNodeBitmask::Size, ref->no_nodegroup_mask);
4759  sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal,
4760  DihRestartRef::SignalLength, JBB);
4761 }
4762 
4763 /* ------------------------------------------------------------------------- */
4764 /* SELECT THE MASTER CANDIDATE TO BE USED IN SYSTEM RESTARTS. */
4765 /* ------------------------------------------------------------------------- */
4766 void Dbdih::selectMasterCandidateAndSend(Signal* signal)
4767 {
4768  setNodeGroups();
4769 
4770  NodeRecordPtr nodePtr;
4771  Uint32 node_groups[MAX_NDB_NODES];
4772  memset(node_groups, 0, sizeof(node_groups));
4773  NdbNodeBitmask no_nodegroup_mask;
4774  for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
4775  jam();
4776  if (Sysfile::getNodeStatus(nodePtr.i, SYSFILE->nodeStatus) == Sysfile::NS_NotDefined)
4777  {
4778  jam();
4779  continue;
4780  }
4781  const Uint32 ng = Sysfile::getNodeGroup(nodePtr.i, SYSFILE->nodeGroups);
4782  if(ng != NO_NODE_GROUP_ID)
4783  {
4784  ndbrequire(ng < MAX_NDB_NODES);
4785  node_groups[ng]++;
4786  }
4787  else
4788  {
4789  no_nodegroup_mask.set(nodePtr.i);
4790  }
4791  }
4792 
4793  DihRestartConf * conf = CAST_PTR(DihRestartConf, signal->getDataPtrSend());
4794  conf->unused = getOwnNodeId();
4795  conf->latest_gci = SYSFILE->lastCompletedGCI[getOwnNodeId()];
4796  no_nodegroup_mask.copyto(NdbNodeBitmask::Size, conf->no_nodegroup_mask);
4797  sendSignal(cntrlblockref, GSN_DIH_RESTARTCONF, signal,
4798  DihRestartConf::SignalLength, JBB);
4799 
4800  for (nodePtr.i = 0; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
4801  jam();
4802  Uint32 count = node_groups[nodePtr.i];
4803  if(count != 0 && count != cnoReplicas){
4804  char buf[255];
4805  BaseString::snprintf(buf, sizeof(buf),
4806  "Illegal configuration change."
4807  " Initial start needs to be performed "
4808  " when changing no of replicas (%d != %d)",
4809  node_groups[nodePtr.i], cnoReplicas);
4810  progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
4811  }
4812  }
4813 }//Dbdih::selectMasterCandidate()
4814 
4815 /* ------------------------------------------------------------------------- */
4816 /* ERROR HANDLING DURING READING RESTORABLE GCI FROM FILE. */
4817 /* ------------------------------------------------------------------------- */
4818 void Dbdih::openingGcpErrorLab(Signal* signal, FileRecordPtr filePtr)
4819 {
4820  filePtr.p->fileStatus = FileRecord::CRASHED;
4821  filePtr.p->reqStatus = FileRecord::IDLE;
4822  if (crestartInfoFile[0] == filePtr.i) {
4823  jam();
4824  /* --------------------------------------------------------------------- */
4825  /* THE FIRST FILE WAS NOT ABLE TO BE OPENED. SET STATUS TO CRASHED AND */
4826  /* TRY OPEN THE NEXT FILE. */
4827  /* --------------------------------------------------------------------- */
4828  filePtr.i = crestartInfoFile[1];
4829  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4830  openFileRo(signal, filePtr);
4831  filePtr.p->reqStatus = FileRecord::OPENING_GCP;
4832  } else {
4833  jam();
4834  /* --------------------------------------------------------------------- */
4835  /* WE FAILED IN OPENING THE SECOND FILE. BOTH FILES WERE CORRUPTED. WE */
4836  /* CANNOT CONTINUE THE RESTART IN THIS CASE. TELL NDBCNTR OF OUR */
4837  /* FAILURE. */
4838  /*---------------------------------------------------------------------- */
4839  sendDihRestartRef(signal);
4840  return;
4841  }//if
4842 }//Dbdih::openingGcpErrorLab()
4843 
4844 void Dbdih::readingGcpErrorLab(Signal* signal, FileRecordPtr filePtr)
4845 {
4846  filePtr.p->fileStatus = FileRecord::CRASHED;
4847  /* ----------------------------------------------------------------------- */
4848  /* WE FAILED IN READING THE FILE AS WELL. WE WILL CLOSE THIS FILE. */
4849  /* ----------------------------------------------------------------------- */
4850  closeFile(signal, filePtr);
4851  filePtr.p->reqStatus = FileRecord::CLOSING_GCP_CRASH;
4852 }//Dbdih::readingGcpErrorLab()
4853 
4854 void Dbdih::closingGcpCrashLab(Signal* signal, FileRecordPtr filePtr)
4855 {
4856  if (crestartInfoFile[0] == filePtr.i) {
4857  jam();
4858  /* --------------------------------------------------------------------- */
4859  /* ERROR IN FIRST FILE, TRY THE SECOND FILE. */
4860  /* --------------------------------------------------------------------- */
4861  filePtr.i = crestartInfoFile[1];
4862  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4863  openFileRw(signal, filePtr);
4864  filePtr.p->reqStatus = FileRecord::OPENING_GCP;
4865  return;
4866  }//if
4867  /* ----------------------------------------------------------------------- */
4868  /* WE DISCOVERED A FAILURE WITH THE SECOND FILE AS WELL. THIS IS A */
4869  /* SERIOUS PROBLEM. REPORT FAILURE TO NDBCNTR. */
4870  /* ----------------------------------------------------------------------- */
4871  sendDihRestartRef(signal);
4872 }//Dbdih::closingGcpCrashLab()
4873 
4874 /*****************************************************************************/
4875 /* ------------------------------------------------------------------------- */
4876 /* THIS IS AN INITIAL RESTART. WE WILL CREATE THE TWO FILES DESCRIBING */
4877 /* THE GLOBAL CHECKPOINTS THAT ARE RESTORABLE. */
4878 /* ------------------------------------------------------------------------- */
4879 /*****************************************************************************/
4880 void Dbdih::initGciFilesLab(Signal* signal)
4881 {
4882  FileRecordPtr filePtr;
4883  filePtr.i = crestartInfoFile[0];
4884  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4885  createFileRw(signal, filePtr);
4886  filePtr.p->reqStatus = FileRecord::CREATING_GCP;
4887 }//Dbdih::initGciFilesLab()
4888 
4889 /* ------------------------------------------------------------------------- */
4890 /* GLOBAL CHECKPOINT FILE HAVE BEEN SUCCESSFULLY CREATED. */
4891 /* ------------------------------------------------------------------------- */
4892 void Dbdih::creatingGcpLab(Signal* signal, FileRecordPtr filePtr)
4893 {
4894  if (filePtr.i == crestartInfoFile[0]) {
4895  jam();
4896  /* --------------------------------------------------------------------- */
4897  /* IF CREATED FIRST THEN ALSO CREATE THE SECOND FILE. */
4898  /* --------------------------------------------------------------------- */
4899  filePtr.i = crestartInfoFile[1];
4900  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4901  createFileRw(signal, filePtr);
4902  filePtr.p->reqStatus = FileRecord::CREATING_GCP;
4903  } else {
4904  jam();
4905  /* --------------------------------------------------------------------- */
4906  /* BOTH FILES HAVE BEEN CREATED. NOW WRITE THE INITIAL DATA TO BOTH */
4907  /* OF THE FILES. */
4908  /* --------------------------------------------------------------------- */
4909  filePtr.i = crestartInfoFile[0];
4910  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4911  writeRestorableGci(signal, filePtr);
4912  filePtr.p->reqStatus = FileRecord::WRITE_INIT_GCP;
4913  }//if
4914 }//Dbdih::creatingGcpLab()
4915 
4916 /* ------------------------------------------------------------------------- */
4917 /* WE HAVE SUCCESSFULLY WRITTEN A GCI FILE. */
4918 /* ------------------------------------------------------------------------- */
4919 void Dbdih::writeInitGcpLab(Signal* signal, FileRecordPtr filePtr)
4920 {
4921  filePtr.p->reqStatus = FileRecord::IDLE;
4922  if (filePtr.i == crestartInfoFile[0]) {
4923  jam();
4924  /* --------------------------------------------------------------------- */
4925  /* WE HAVE WRITTEN THE FIRST FILE NOW ALSO WRITE THE SECOND FILE. */
4926  /* --------------------------------------------------------------------- */
4927  filePtr.i = crestartInfoFile[1];
4928  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4929  writeRestorableGci(signal, filePtr);
4930  filePtr.p->reqStatus = FileRecord::WRITE_INIT_GCP;
4931  } else {
4932  /* --------------------------------------------------------------------- */
4933  /* WE HAVE WRITTEN BOTH FILES. LEAVE BOTH FILES OPEN AND CONFIRM OUR */
4934  /* PART OF THE INITIAL START. */
4935  /* --------------------------------------------------------------------- */
4936  if (isMaster()) {
4937  jam();
4938  /*---------------------------------------------------------------------*/
4939  // IN MASTER NODES THE START REQUEST IS RECEIVED FROM NDBCNTR AND WE MUST
4940  // RESPOND WHEN COMPLETED.
4941  /*---------------------------------------------------------------------*/
4942  signal->theData[0] = reference();
4943  sendSignal(cndbStartReqBlockref, GSN_NDB_STARTCONF, signal, 1, JBB);
4944  } else {
4945  jam();
4946  ndbsttorry10Lab(signal, __LINE__);
4947  return;
4948  }//if
4949  }//if
4950 }//Dbdih::writeInitGcpLab()
4951 
4952 /*****************************************************************************/
4953 /* ********** NODES DELETION MODULE *************/
4954 /*****************************************************************************/
4955 /*---------------------------------------------------------------------------*/
4956 /* LOGIC FOR NODE FAILURE */
4957 /*---------------------------------------------------------------------------*/
4958 void Dbdih::execNODE_FAILREP(Signal* signal)
4959 {
4960  Uint32 i;
4961  Uint32 failedNodes[MAX_NDB_NODES];
4962  jamEntry();
4963  NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0];
4964 
4965  cfailurenr = nodeFail->failNo;
4966  Uint32 newMasterId = nodeFail->masterNodeId;
4967  const Uint32 noOfFailedNodes = nodeFail->noOfNodes;
4968 
4969  if (ERROR_INSERTED(7179) || ERROR_INSERTED(7217))
4970  {
4971  CLEAR_ERROR_INSERT_VALUE;
4972  }
4973 
4974  if (ERROR_INSERTED(7184))
4975  {
4976  SET_ERROR_INSERT_VALUE(7000);
4977  }
4978 
4979 
4980 
4981  /*-------------------------------------------------------------------------*/
4982  // The first step is to convert from a bit mask to an array of failed nodes.
4983  /*-------------------------------------------------------------------------*/
4984  Uint32 index = 0;
4985  for (i = 1; i < MAX_NDB_NODES; i++) {
4986  jam();
4987  if(NdbNodeBitmask::get(nodeFail->theNodes, i)){
4988  jam();
4989  failedNodes[index] = i;
4990  index++;
4991  }//if
4992  }//for
4993  ndbrequire(noOfFailedNodes == index);
4994  ndbrequire(noOfFailedNodes - 1 < MAX_NDB_NODES);
4995 
4996  /*-------------------------------------------------------------------------*/
4997  // The second step is to update the node status of the failed nodes, remove
4998  // them from the alive node list and put them into the dead node list. Also
4999  // update the number of nodes on-line.
5000  // We also set certain state variables ensuring that the node no longer is
5001  // used in transactions and also mark that we received this signal.
5002  /*-------------------------------------------------------------------------*/
5003  for (i = 0; i < noOfFailedNodes; i++) {
5004  jam();
5005  NodeRecordPtr TNodePtr;
5006  TNodePtr.i = failedNodes[i];
5007  ptrCheckGuard(TNodePtr, MAX_NDB_NODES, nodeRecord);
5008  TNodePtr.p->useInTransactions = false;
5009  TNodePtr.p->m_inclDihLcp = false;
5010  TNodePtr.p->recNODE_FAILREP = ZTRUE;
5011  if (TNodePtr.p->nodeStatus == NodeRecord::ALIVE) {
5012  jam();
5013  con_lineNodes--;
5014  TNodePtr.p->nodeStatus = NodeRecord::DIED_NOW;
5015  removeAlive(TNodePtr);
5016  insertDeadNode(TNodePtr);
5017  }//if
5018  }//for
5019 
5020  /*-------------------------------------------------------------------------*/
5021  // Verify that we can continue to operate the cluster. If we cannot we will
5022  // not return from checkEscalation.
5023  /*-------------------------------------------------------------------------*/
5024  checkEscalation();
5025 
5026  /*------------------------------------------------------------------------*/
5027  // Verify that a starting node has also crashed. Reset the node start record.
5028  /*-------------------------------------------------------------------------*/
5029 #if 0
5030 
5034  if (false && c_nodeStartMaster.startNode != RNIL && getNodeStatus(c_nodeStartMaster.startNode) == NodeRecord::ALIVE)
5035  {
5036  BlockReference cntrRef = calcNdbCntrBlockRef(c_nodeStartMaster.startNode);
5037  SystemError * const sysErr = (SystemError*)&signal->theData[0];
5038  sysErr->errorCode = SystemError::StartInProgressError;
5039  sysErr->errorRef = reference();
5040  sysErr->data[0]= 0;
5041  sysErr->data[1]= __LINE__;
5042  sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal, SystemError::SignalLength, JBA);
5043  nodeResetStart(signal);
5044  }//if
5045 #endif
5046 
5047  /*--------------------------------------------------*/
5048  /* */
5049  /* WE CHANGE THE REFERENCE TO MASTER DIH */
5050  /* BLOCK AND POINTER AT THIS PLACE IN THE CODE*/
5051  /*--------------------------------------------------*/
5052  Uint32 oldMasterId = cmasterNodeId;
5053  BlockReference oldMasterRef = cmasterdihref;
5054  cmasterdihref = calcDihBlockRef(newMasterId);
5055  cmasterNodeId = newMasterId;
5056 
5057  const bool masterTakeOver = (oldMasterId != newMasterId);
5058 
5059  for(i = 0; i < noOfFailedNodes; i++) {
5060  NodeRecordPtr failedNodePtr;
5061  failedNodePtr.i = failedNodes[i];
5062  ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
5063  if (oldMasterRef == reference()) {
5064  /*-------------------------------------------------------*/
5065  // Functions that need to be called only for master nodes.
5066  /*-------------------------------------------------------*/
5067  checkCopyTab(signal, failedNodePtr);
5068  checkStopPermMaster(signal, failedNodePtr);
5069  checkWaitGCPMaster(signal, failedNodes[i]);
5070 
5071  {
5072  Ptr<TakeOverRecord> takeOverPtr;
5073  if (findTakeOver(takeOverPtr, failedNodePtr.i))
5074  {
5075  handleTakeOver(signal, takeOverPtr);
5076  }
5077  }
5078  checkGcpOutstanding(signal, failedNodePtr.i);
5079  } else {
5080  jam();
5081  /*-----------------------------------------------------------*/
5082  // Functions that need to be called only for nodes that were
5083  // not master before these failures.
5084  /*-----------------------------------------------------------*/
5085  checkStopPermProxy(signal, failedNodes[i]);
5086  checkWaitGCPProxy(signal, failedNodes[i]);
5087  }//if
5088  /*--------------------------------------------------*/
5089  // Functions that need to be called for all nodes.
5090  /*--------------------------------------------------*/
5091  checkStopMe(signal, failedNodePtr);
5092  failedNodeLcpHandling(signal, failedNodePtr);
5093  startRemoveFailedNode(signal, failedNodePtr);
5094 
5099  failedNodeSynchHandling(signal, failedNodePtr);
5100  }//for
5101 
5102  if(masterTakeOver){
5103  jam();
5104  startLcpMasterTakeOver(signal, oldMasterId);
5105  startGcpMasterTakeOver(signal, oldMasterId);
5106 
5107  if(getNodeState().getNodeRestartInProgress()){
5108  jam();
5109  progError(__LINE__, NDBD_EXIT_MASTER_FAILURE_DURING_NR);
5110  }
5111  }
5112 
5113 
5114  if (isMaster()) {
5115  jam();
5116  setNodeRestartInfoBits(signal);
5117  }//if
5118 }//Dbdih::execNODE_FAILREP()
5119 
5120 void Dbdih::checkCopyTab(Signal* signal, NodeRecordPtr failedNodePtr)
5121 {
5122  jam();
5123 
5124  if(c_nodeStartMaster.startNode != failedNodePtr.i){
5125  jam();
5126  return;
5127  }
5128 
5129  switch(c_nodeStartMaster.m_outstandingGsn){
5130  case GSN_COPY_TABREQ:
5131  jam();
5132  ndbrequire(c_COPY_TABREQ_Counter.isWaitingFor(failedNodePtr.i));
5133  releaseTabPages(failedNodePtr.p->activeTabptr);
5134  c_COPY_TABREQ_Counter.clearWaitingFor(failedNodePtr.i);
5135  c_nodeStartMaster.wait = ZFALSE;
5136  break;
5137  case GSN_START_INFOREQ:
5138  case GSN_START_PERMCONF:
5139  case GSN_DICTSTARTREQ:
5140  case GSN_START_MECONF:
5141  case GSN_COPY_GCIREQ:
5142  jam();
5143  break;
5144  default:
5145  g_eventLogger->error("outstanding gsn: %s(%d)",
5146  getSignalName(c_nodeStartMaster.m_outstandingGsn),
5147  c_nodeStartMaster.m_outstandingGsn);
5148  ndbrequire(false);
5149  }
5150 
5151  if (!c_nodeStartMaster.m_fragmentInfoMutex.isNull())
5152  {
5153  jam();
5154  Mutex mutex(signal, c_mutexMgr, c_nodeStartMaster.m_fragmentInfoMutex);
5155  mutex.unlock();
5156  }
5157 
5158  nodeResetStart(signal);
5159 }//Dbdih::checkCopyTab()
5160 
5161 void Dbdih::checkStopMe(Signal* signal, NodeRecordPtr failedNodePtr)
5162 {
5163  jam();
5164  if (c_STOP_ME_REQ_Counter.isWaitingFor(failedNodePtr.i)){
5165  jam();
5166  ndbrequire(c_stopMe.clientRef != 0);
5167  StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
5168  stopMeConf->senderRef = calcDihBlockRef(failedNodePtr.i);
5169  stopMeConf->senderData = c_stopMe.clientData;
5170  sendSignal(reference(), GSN_STOP_ME_CONF, signal,
5171  StopMeConf::SignalLength, JBB);
5172  }//if
5173 }//Dbdih::checkStopMe()
5174 
5175 void Dbdih::checkStopPermMaster(Signal* signal, NodeRecordPtr failedNodePtr)
5176 {
5177  DihSwitchReplicaRef* const ref = (DihSwitchReplicaRef*)&signal->theData[0];
5178  jam();
5179  if (c_DIH_SWITCH_REPLICA_REQ_Counter.isWaitingFor(failedNodePtr.i)){
5180  jam();
5181  ndbrequire(c_stopPermMaster.clientRef != 0);
5182  ref->senderNode = failedNodePtr.i;
5183  ref->errorCode = StopPermRef::NF_CausedAbortOfStopProcedure;
5184  sendSignal(reference(), GSN_DIH_SWITCH_REPLICA_REF, signal,
5185  DihSwitchReplicaRef::SignalLength, JBB);
5186  return;
5187  }//if
5188 }//Dbdih::checkStopPermMaster()
5189 
5190 void Dbdih::checkStopPermProxy(Signal* signal, NodeId failedNodeId)
5191 {
5192  jam();
5193  if(c_stopPermProxy.clientRef != 0 &&
5194  refToNode(c_stopPermProxy.masterRef) == failedNodeId){
5195 
5199  jam();
5200  StopPermRef* const ref = (StopPermRef*)&signal->theData[0];
5201 
5202  ref->senderData = c_stopPermProxy.clientData;
5203  ref->errorCode = StopPermRef::NF_CausedAbortOfStopProcedure;
5204  sendSignal(c_stopPermProxy.clientRef, GSN_STOP_PERM_REF, signal, 2, JBB);
5205  c_stopPermProxy.clientRef = 0;
5206  }//if
5207 }//Dbdih::checkStopPermProxy()
5208 
5209 void
5210 Dbdih::handleTakeOver(Signal* signal, TakeOverRecordPtr takeOverPtr)
5211 {
5212  jam();
5213  switch(takeOverPtr.p->toMasterStatus){
5214  case TakeOverRecord::TO_MASTER_IDLE:
5215  jam();
5216  releaseTakeOver(takeOverPtr);
5217  return;
5218  case TakeOverRecord::TO_MUTEX_BEFORE_STORED:
5219  jam();
5224  return;
5225  case TakeOverRecord::TO_MUTEX_BEFORE_LOCKED:
5226  jam();
5230  abortTakeOver(signal, takeOverPtr);
5231  return;
5232  case TakeOverRecord::TO_AFTER_STORED:{
5233  jam();
5237  NodeRecordPtr nodePtr;
5238  NodeGroupRecordPtr NGPtr;
5239  nodePtr.i = takeOverPtr.p->toCopyNode;
5240  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
5241  NGPtr.i = nodePtr.p->nodeGroup;
5242  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
5243 
5244  ndbassert(NGPtr.p->activeTakeOver == takeOverPtr.p->toStartingNode);
5245  if (NGPtr.p->activeTakeOver == takeOverPtr.p->toStartingNode)
5246  {
5247  jam();
5248  NGPtr.p->activeTakeOver = 0;
5249  }
5250  releaseTakeOver(takeOverPtr);
5251  return;
5252  }
5253  case TakeOverRecord::TO_MUTEX_BEFORE_COMMIT:
5254  jam();
5259  return;
5260  case TakeOverRecord::TO_MUTEX_BEFORE_SWITCH_REPLICA:
5261  jam();
5266  return;
5267  case TakeOverRecord::TO_MUTEX_AFTER_SWITCH_REPLICA:
5268  jam();
5269  abortTakeOver(signal, takeOverPtr);
5270  return;
5271  case TakeOverRecord::TO_WAIT_LCP:{
5272  jam();
5276  NodeRecordPtr nodePtr;
5277  nodePtr.i = takeOverPtr.p->toStartingNode;
5278  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
5279  nodePtr.p->copyCompleted = 0;
5280  releaseTakeOver(takeOverPtr);
5281  return;
5282  }
5283  default:
5284  jamLine(takeOverPtr.p->toMasterStatus);
5285  ndbrequire(false);
5286  }
5287 }
5288 
5289 void Dbdih::failedNodeSynchHandling(Signal* signal,
5290  NodeRecordPtr failedNodePtr)
5291 {
5292  jam();
5293  /*----------------------------------------------------*/
5294  /* INITIALISE THE VARIABLES THAT KEEP TRACK OF */
5295  /* WHEN A NODE FAILURE IS COMPLETED. */
5296  /*----------------------------------------------------*/
5297  failedNodePtr.p->dbdictFailCompleted = ZFALSE;
5298  failedNodePtr.p->dbtcFailCompleted = ZFALSE;
5299  failedNodePtr.p->dbdihFailCompleted = ZFALSE;
5300  failedNodePtr.p->dblqhFailCompleted = ZFALSE;
5301 
5302  failedNodePtr.p->m_NF_COMPLETE_REP.clearWaitingFor();
5303 
5304  NodeRecordPtr nodePtr;
5305  for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
5306  ptrAss(nodePtr, nodeRecord);
5307  if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
5308  jam();
5314  failedNodePtr.p->m_NF_COMPLETE_REP.setWaitingFor(nodePtr.i);
5315  } else {
5316  jam();
5317  if ((nodePtr.p->nodeStatus == NodeRecord::DYING) &&
5318  (nodePtr.p->m_NF_COMPLETE_REP.isWaitingFor(failedNodePtr.i))){
5319  jam();
5320  /*----------------------------------------------------*/
5321  /* THE NODE FAILED BEFORE REPORTING THE FAILURE */
5322  /* HANDLING COMPLETED ON THIS FAILED NODE. */
5323  /* REPORT THAT NODE FAILURE HANDLING WAS */
5324  /* COMPLETED ON THE NEW FAILED NODE FOR THIS */
5325  /* PARTICULAR OLD FAILED NODE. */
5326  /*----------------------------------------------------*/
5327  NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
5328  nf->blockNo = 0;
5329  nf->nodeId = failedNodePtr.i;
5330  nf->failedNodeId = nodePtr.i;
5331  nf->from = __LINE__;
5332  sendSignal(reference(), GSN_NF_COMPLETEREP, signal,
5333  NFCompleteRep::SignalLength, JBB);
5334  }//if
5335  }//if
5336  }//for
5337  if (failedNodePtr.p->nodeStatus == NodeRecord::DIED_NOW) {
5338  jam();
5339  failedNodePtr.p->nodeStatus = NodeRecord::DYING;
5340  } else {
5341  jam();
5342  /*----------------------------------------------------*/
5343  // No more processing needed when node not even started
5344  // yet. We give the node status to DEAD since we do not
5345  // care whether all nodes complete the node failure
5346  // handling. The node have not been included in the
5347  // node failure protocols.
5348  /*----------------------------------------------------*/
5349  failedNodePtr.p->nodeStatus = NodeRecord::DEAD;
5354  NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
5355  nf->blockNo = DBDIH;
5356  nf->nodeId = cownNodeId;
5357  nf->failedNodeId = failedNodePtr.i;
5358  nf->from = __LINE__;
5359  sendSignal(reference(), GSN_NF_COMPLETEREP, signal,
5360  NFCompleteRep::SignalLength, JBB);
5361  }//if
5362 }//Dbdih::failedNodeSynchHandling()
5363 
5364 bool
5365 Dbdih::findTakeOver(Ptr<TakeOverRecord> & ptr, Uint32 failedNodeId)
5366 {
5367  for (c_activeTakeOverList.first(ptr); !ptr.isNull();
5368  c_activeTakeOverList.next(ptr))
5369  {
5370  jam();
5371  if (ptr.p->toStartingNode == failedNodeId)
5372  {
5373  jam();
5374  return true;
5375  }
5376  }
5377  ptr.setNull();
5378  return false;
5379 }//Dbdih::findTakeOver()
5380 
5381 void Dbdih::failedNodeLcpHandling(Signal* signal, NodeRecordPtr failedNodePtr)
5382 {
5383  jam();
5384  const Uint32 nodeId = failedNodePtr.i;
5385 
5386  if (isMaster() && c_lcpState.m_participatingLQH.get(failedNodePtr.i))
5387  {
5388  /*----------------------------------------------------*/
5389  /* THE NODE WAS INVOLVED IN A LOCAL CHECKPOINT. WE */
5390  /* MUST UPDATE THE ACTIVE STATUS TO INDICATE THAT */
5391  /* THE NODE HAVE MISSED A LOCAL CHECKPOINT. */
5392  /*----------------------------------------------------*/
5393 
5398  switch (failedNodePtr.p->activeStatus) {
5399  case Sysfile::NS_Active:
5400  jam();
5401  failedNodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
5402  break;
5403  case Sysfile::NS_ActiveMissed_1:
5404  jam();
5405  failedNodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
5406  break;
5407  case Sysfile::NS_ActiveMissed_2:
5408  jam();
5409  failedNodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
5410  break;
5411  case Sysfile::NS_TakeOver:
5412  jam();
5413  failedNodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
5414  break;
5415  case Sysfile::NS_Configured:
5416  jam();
5417  break;
5418  default:
5419  g_eventLogger->error("activeStatus = %u "
5420  "at failure after NODE_FAILREP of node = %u",
5421  (Uint32) failedNodePtr.p->activeStatus,
5422  failedNodePtr.i);
5423  ndbrequire(false);
5424  break;
5425  }//switch
5426  }//if
5427 
5428  c_lcpState.m_participatingDIH.clear(failedNodePtr.i);
5429  c_lcpState.m_participatingLQH.clear(failedNodePtr.i);
5430 
5431  bool wf = c_MASTER_LCPREQ_Counter.isWaitingFor(failedNodePtr.i);
5432 
5433  if(c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.isWaitingFor(failedNodePtr.i))
5434  {
5435  jam();
5436  LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
5437  rep->nodeId = failedNodePtr.i;
5438  rep->lcpId = SYSFILE->latestLCP_ID;
5439  rep->blockNo = DBDIH;
5440  sendSignal(reference(), GSN_LCP_COMPLETE_REP, signal,
5441  LcpCompleteRep::SignalLength, JBB);
5442  }
5443 
5444  bool lcp_complete_rep = false;
5445  if (!wf)
5446  {
5447  jam();
5448 
5454  if(c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.isWaitingFor(nodeId)){
5455  jam();
5456 
5457  lcp_complete_rep = true;
5458  LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
5459  rep->nodeId = nodeId;
5460  rep->lcpId = SYSFILE->latestLCP_ID;
5461  rep->blockNo = DBLQH;
5462  sendSignal(reference(), GSN_LCP_COMPLETE_REP, signal,
5463  LcpCompleteRep::SignalLength, JBB);
5464 
5465  if(c_lcpState.m_LAST_LCP_FRAG_ORD.isWaitingFor(nodeId)){
5466  jam();
5470  c_lcpState.m_LAST_LCP_FRAG_ORD.clearWaitingFor(nodeId);
5471  }
5472  }
5473  }
5474 
5475  if (c_TCGETOPSIZEREQ_Counter.isWaitingFor(failedNodePtr.i)) {
5476  jam();
5477  signal->theData[0] = failedNodePtr.i;
5478  signal->theData[1] = 0;
5479  sendSignal(reference(), GSN_TCGETOPSIZECONF, signal, 2, JBB);
5480  }//if
5481 
5482  if (c_TC_CLOPSIZEREQ_Counter.isWaitingFor(failedNodePtr.i)) {
5483  jam();
5484  signal->theData[0] = failedNodePtr.i;
5485  sendSignal(reference(), GSN_TC_CLOPSIZECONF, signal, 1, JBB);
5486  }//if
5487 
5488  if (c_START_LCP_REQ_Counter.isWaitingFor(failedNodePtr.i)) {
5489  jam();
5490  StartLcpConf * conf = (StartLcpConf*)signal->getDataPtrSend();
5491  conf->senderRef = numberToRef(DBLQH, failedNodePtr.i);
5492  conf->lcpId = SYSFILE->latestLCP_ID;
5493  sendSignal(reference(), GSN_START_LCP_CONF, signal,
5494  StartLcpConf::SignalLength, JBB);
5495  }//if
5496 
5497 dosend:
5498  if (c_EMPTY_LCP_REQ_Counter.isWaitingFor(failedNodePtr.i))
5499  {
5500  jam();
5501  EmptyLcpConf * const rep = (EmptyLcpConf *)&signal->theData[0];
5502  rep->senderNodeId = failedNodePtr.i;
5503  rep->tableId = ~0;
5504  rep->fragmentId = ~0;
5505  rep->lcpNo = 0;
5506  rep->lcpId = SYSFILE->latestLCP_ID;
5507  rep->idle = true;
5508  sendSignal(reference(), GSN_EMPTY_LCP_CONF, signal,
5509  EmptyLcpConf::SignalLength, JBB);
5510  }
5511  else if (!c_EMPTY_LCP_REQ_Counter.done() && lcp_complete_rep)
5512  {
5513  jam();
5514  c_EMPTY_LCP_REQ_Counter.setWaitingFor(failedNodePtr.i);
5515  goto dosend;
5516  }
5517 
5518  if (c_MASTER_LCPREQ_Counter.isWaitingFor(failedNodePtr.i)) {
5519  jam();
5520  MasterLCPRef * const ref = (MasterLCPRef *)&signal->theData[0];
5521  ref->senderNodeId = failedNodePtr.i;
5522  ref->failedNodeId = cmasterTakeOverNode;
5523  sendSignal(reference(), GSN_MASTER_LCPREF, signal,
5524  MasterLCPRef::SignalLength, JBB);
5525  }//if
5526 
5527 }//Dbdih::failedNodeLcpHandling()
5528 
5529 void Dbdih::checkGcpOutstanding(Signal* signal, Uint32 failedNodeId){
5530  if (c_GCP_PREPARE_Counter.isWaitingFor(failedNodeId)){
5531  jam();
5532  GCPPrepareConf* conf = (GCPPrepareConf*)signal->getDataPtrSend();
5533  conf->nodeId = failedNodeId;
5534  conf->gci_hi = Uint32(m_micro_gcp.m_master.m_new_gci >> 32);
5535  conf->gci_lo = Uint32(m_micro_gcp.m_master.m_new_gci);
5536  sendSignal(reference(), GSN_GCP_PREPARECONF, signal,
5537  GCPPrepareConf::SignalLength, JBB);
5538  }//if
5539 
5540  if (c_GCP_COMMIT_Counter.isWaitingFor(failedNodeId))
5541  {
5542  jam();
5543 
5551  c_GCP_COMMIT_Counter.clearWaitingFor(failedNodeId);
5552  if (!c_GCP_COMMIT_Counter.isWaitingFor(getOwnNodeId()))
5553  {
5554  jam();
5555  c_GCP_COMMIT_Counter.setWaitingFor(getOwnNodeId());
5556  m_micro_gcp.m_state = MicroGcp::M_GCP_COMMIT;
5557  }
5558 
5559  GCPNoMoreTrans* req = (GCPNoMoreTrans*)signal->getDataPtrSend();
5560  req->senderRef = reference();
5561  req->senderData = m_micro_gcp.m_master_ref;
5562  req->gci_hi = Uint32(m_micro_gcp.m_old_gci >> 32);
5563  req->gci_lo = Uint32(m_micro_gcp.m_old_gci);
5564  sendSignal(clocaltcblockref, GSN_GCP_NOMORETRANS, signal,
5565  GCPNoMoreTrans::SignalLength, JBB);
5566  }
5567 
5568  if (c_GCP_SAVEREQ_Counter.isWaitingFor(failedNodeId)) {
5569  jam();
5570  GCPSaveRef * const saveRef = (GCPSaveRef*)&signal->theData[0];
5571  saveRef->dihPtr = failedNodeId;
5572  saveRef->nodeId = failedNodeId;
5573  saveRef->gci = m_gcp_save.m_master.m_new_gci;
5574  saveRef->errorCode = GCPSaveRef::FakedSignalDueToNodeFailure;
5575  sendSignal(reference(), GSN_GCP_SAVEREF, signal,
5576  GCPSaveRef::SignalLength, JBB);
5577  }//if
5578 
5579  if (c_COPY_GCIREQ_Counter.isWaitingFor(failedNodeId)) {
5580  jam();
5581  signal->theData[0] = failedNodeId;
5582  sendSignal(reference(), GSN_COPY_GCICONF, signal, 1, JBB);
5583  }//if
5584 
5585  if (c_MASTER_GCPREQ_Counter.isWaitingFor(failedNodeId)){
5586  jam();
5587  MasterGCPRef * const ref = (MasterGCPRef *)&signal->theData[0];
5588  ref->senderNodeId = failedNodeId;
5589  ref->failedNodeId = cmasterTakeOverNode;
5590  sendSignal(reference(), GSN_MASTER_GCPREF, signal,
5591  MasterGCPRef::SignalLength, JBB);
5592  }//if
5593 
5594  if (c_SUB_GCP_COMPLETE_REP_Counter.isWaitingFor(failedNodeId))
5595  {
5596  jam();
5597  SubGcpCompleteAck* ack = CAST_PTR(SubGcpCompleteAck,
5598  signal->getDataPtrSend());
5599  ack->rep.senderRef = numberToRef(DBDIH, failedNodeId);
5600  sendSignal(reference(), GSN_SUB_GCP_COMPLETE_ACK, signal,
5601  SubGcpCompleteAck::SignalLength, JBB);
5602  }
5603 }//Dbdih::handleGcpStateInMaster()
5604 
5605 
5606 void
5607 Dbdih::startLcpMasterTakeOver(Signal* signal, Uint32 nodeId){
5608  jam();
5609 
5610  Uint32 oldNode = c_lcpMasterTakeOverState.failedNodeId;
5611 
5612  c_lcpMasterTakeOverState.minTableId = ~0;
5613  c_lcpMasterTakeOverState.minFragId = ~0;
5614  c_lcpMasterTakeOverState.failedNodeId = nodeId;
5615 
5616  c_lcpMasterTakeOverState.set(LMTOS_WAIT_EMPTY_LCP, __LINE__);
5617 
5618  EmptyLcpReq* req = (EmptyLcpReq*)signal->getDataPtrSend();
5619  req->senderRef = reference();
5620  {
5621  NodeRecordPtr specNodePtr;
5622  specNodePtr.i = cfirstAliveNode;
5623  do {
5624  jam();
5625  ptrCheckGuard(specNodePtr, MAX_NDB_NODES, nodeRecord);
5626  if (!c_EMPTY_LCP_REQ_Counter.isWaitingFor(specNodePtr.i))
5627  {
5628  jam();
5629  c_EMPTY_LCP_REQ_Counter.setWaitingFor(specNodePtr.i);
5630  if (!(ERROR_INSERTED(7209) && specNodePtr.i == getOwnNodeId()))
5631  {
5632  sendEMPTY_LCP_REQ(signal, specNodePtr.i, 0);
5633  }
5634  else
5635  {
5636  ndbout_c("NOT sending EMPTY_LCP_REQ to %u", specNodePtr.i);
5637  }
5638 
5639  if (c_lcpState.m_LAST_LCP_FRAG_ORD.isWaitingFor(specNodePtr.i))
5640  {
5641  jam();
5642  c_lcpState.m_LAST_LCP_FRAG_ORD.clearWaitingFor();
5643  }
5644  }
5645  specNodePtr.i = specNodePtr.p->nextNode;
5646  } while (specNodePtr.i != RNIL);
5647  }
5648 
5649  NodeRecordPtr nodePtr;
5650  nodePtr.i = oldNode;
5651  if (oldNode > 0 && oldNode < MAX_NDB_NODES)
5652  {
5653  jam();
5654  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
5655  if (nodePtr.p->m_nodefailSteps.get(NF_LCP_TAKE_OVER))
5656  {
5657  jam();
5658  checkLocalNodefailComplete(signal, oldNode, NF_LCP_TAKE_OVER);
5659  }
5660  }
5661 
5662  setLocalNodefailHandling(signal, nodeId, NF_LCP_TAKE_OVER);
5663 }
5664 
5665 void Dbdih::startGcpMasterTakeOver(Signal* signal, Uint32 oldMasterId){
5666  jam();
5667  /*--------------------------------------------------*/
5668  /* */
5669  /* THE MASTER HAVE FAILED AND WE WERE ELECTED */
5670  /* TO BE THE NEW MASTER NODE. WE NEED TO QUERY*/
5671  /* ALL THE OTHER NODES ABOUT THEIR STATUS IN */
5672  /* ORDER TO BE ABLE TO TAKE OVER CONTROL OF */
5673  /* THE GLOBAL CHECKPOINT PROTOCOL AND THE */
5674  /* LOCAL CHECKPOINT PROTOCOL. */
5675  /*--------------------------------------------------*/
5676  if(!isMaster()){
5677  jam();
5678  return;
5679  }
5680  cmasterState = MASTER_TAKE_OVER_GCP;
5681  cmasterTakeOverNode = oldMasterId;
5682  MasterGCPReq * const req = (MasterGCPReq *)&signal->theData[0];
5683  req->masterRef = reference();
5684  req->failedNodeId = oldMasterId;
5685  sendLoopMacro(MASTER_GCPREQ, sendMASTER_GCPREQ, RNIL);
5686 
5687  signal->theData[0] = NDB_LE_GCP_TakeoverStarted;
5688  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
5689 
5694  m_gcp_save.m_master.m_new_gci = m_gcp_save.m_gci;
5695 
5696  setLocalNodefailHandling(signal, oldMasterId, NF_GCP_TAKE_OVER);
5697 }//Dbdih::handleNewMaster()
5698 
5699 void Dbdih::startRemoveFailedNode(Signal* signal, NodeRecordPtr failedNodePtr)
5700 {
5701  Uint32 nodeId = failedNodePtr.i;
5702  if(failedNodePtr.p->nodeStatus != NodeRecord::DIED_NOW){
5703  jam();
5707  ndbrequire(!c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.isWaitingFor(nodeId));
5708 
5713  return;
5714  }
5715 
5721  failedNodePtr.p->m_remove_node_from_table_lcp_id = RNIL;
5722  if (c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.isWaitingFor(failedNodePtr.i))
5723  {
5724  jam();
5725  failedNodePtr.p->m_remove_node_from_table_lcp_id = SYSFILE->latestLCP_ID;
5726  }
5727 
5728  jam();
5729 
5730  if (!ERROR_INSERTED(7194) && !ERROR_INSERTED(7221))
5731  {
5732  signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
5733  signal->theData[1] = failedNodePtr.i;
5734  signal->theData[2] = 0; // Tab id
5735  sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
5736  }
5737  else
5738  {
5739  if (ERROR_INSERTED(7194))
5740  {
5741  ndbout_c("7194 Not starting ZREMOVE_NODE_FROM_TABLE");
5742  }
5743  else if (ERROR_INSERTED(7221))
5744  {
5745  ndbout_c("7221 Not starting ZREMOVE_NODE_FROM_TABLE");
5746  }
5747  }
5748 
5749  setLocalNodefailHandling(signal, failedNodePtr.i, NF_REMOVE_NODE_FROM_TABLE);
5750 }//Dbdih::startRemoveFailedNode()
5751 
5752 /*--------------------------------------------------*/
5753 /* THE MASTER HAS FAILED AND THE NEW MASTER IS*/
5754 /* QUERYING THIS NODE ABOUT THE STATE OF THE */
5755 /* GLOBAL CHECKPOINT PROTOCOL */
5756 /*--------------------------------------------------*/
5757 void Dbdih::execMASTER_GCPREQ(Signal* signal)
5758 {
5759  NodeRecordPtr failedNodePtr;
5760  MasterGCPReq * const masterGCPReq = (MasterGCPReq *)&signal->theData[0];
5761  jamEntry();
5762  const BlockReference newMasterBlockref = masterGCPReq->masterRef;
5763  const Uint32 failedNodeId = masterGCPReq->failedNodeId;
5764 
5765  failedNodePtr.i = failedNodeId;
5766  ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
5767  if (failedNodePtr.p->nodeStatus == NodeRecord::ALIVE) {
5768  jam();
5769  /*--------------------------------------------------*/
5770  /* ENSURE THAT WE HAVE PROCESSED THE SIGNAL */
5771  /* NODE_FAILURE BEFORE WE PROCESS THIS REQUEST*/
5772  /* FROM THE NEW MASTER. THIS ENSURES THAT WE */
5773  /* HAVE REMOVED THE FAILED NODE FROM THE LIST */
5774  /* OF ACTIVE NODES AND SO FORTH. */
5775  /*--------------------------------------------------*/
5776  sendSignalWithDelay(reference(), GSN_MASTER_GCPREQ,
5777  signal, 10, MasterGCPReq::SignalLength);
5778  return;
5779  } else {
5780  ndbrequire(failedNodePtr.p->nodeStatus == NodeRecord::DYING);
5781  }//if
5782 
5783  if (ERROR_INSERTED(7181))
5784  {
5785  ndbout_c("execGCP_TCFINISHED in MASTER_GCPREQ");
5786  CLEAR_ERROR_INSERT_VALUE;
5787  signal->theData[0] = c_error_7181_ref;
5788  signal->theData[1] = (Uint32)(m_micro_gcp.m_old_gci >> 32);
5789  signal->theData[2] = (Uint32)(m_micro_gcp.m_old_gci & 0xFFFFFFFF);
5790  execGCP_TCFINISHED(signal);
5791  }
5792 
5793  MasterGCPConf::State gcpState;
5794  switch(m_micro_gcp.m_state){
5795  case MicroGcp::M_GCP_IDLE:
5796  jam();
5797  gcpState = MasterGCPConf::GCP_READY;
5798  break;
5799  case MicroGcp::M_GCP_PREPARE:
5800  jam();
5802  break;
5803  case MicroGcp::M_GCP_COMMIT:
5804  jam();
5806  break;
5807  case MicroGcp::M_GCP_COMMITTED:
5808  jam();
5809  gcpState = MasterGCPConf::GCP_COMMITTED;
5810 
5815  m_micro_gcp.m_state = MicroGcp::M_GCP_COMMIT;
5816 
5817  {
5818  GCPNoMoreTrans* req2 = (GCPNoMoreTrans*)signal->getDataPtrSend();
5819  req2->senderRef = reference();
5820  req2->senderData = m_micro_gcp.m_master_ref;
5821  req2->gci_hi = (Uint32)(m_micro_gcp.m_old_gci >> 32);
5822  req2->gci_lo = (Uint32)(m_micro_gcp.m_old_gci & 0xFFFFFFFF);
5823  sendSignal(clocaltcblockref, GSN_GCP_NOMORETRANS, signal,
5824  GCPNoMoreTrans::SignalLength, JBB);
5825  }
5826  break;
5827  case MicroGcp::M_GCP_COMPLETE:
5831  ndbrequire(false);
5832  }
5833 
5834  MasterGCPConf::SaveState saveState;
5835  switch(m_gcp_save.m_state){
5836  case GcpSave::GCP_SAVE_IDLE:
5837  jam();
5838  saveState = MasterGCPConf::GCP_SAVE_IDLE;
5839  break;
5840  case GcpSave::GCP_SAVE_REQ:
5841  jam();
5842  saveState = MasterGCPConf::GCP_SAVE_REQ;
5843  break;
5844  case GcpSave::GCP_SAVE_CONF:
5845  jam();
5846  saveState = MasterGCPConf::GCP_SAVE_CONF;
5847  break;
5848  case GcpSave::GCP_SAVE_COPY_GCI:
5849  jam();
5851  break;
5852  }
5853 
5854  MasterGCPConf * const masterGCPConf = (MasterGCPConf *)&signal->theData[0];
5855  masterGCPConf->gcpState = gcpState;
5856  masterGCPConf->senderNodeId = cownNodeId;
5857  masterGCPConf->failedNodeId = failedNodeId;
5858  masterGCPConf->newGCP_hi = (Uint32)(m_micro_gcp.m_new_gci >> 32);
5859  masterGCPConf->latestLCP = SYSFILE->latestLCP_ID;
5860  masterGCPConf->oldestRestorableGCI = SYSFILE->oldestRestorableGCI;
5861  masterGCPConf->keepGCI = SYSFILE->keepGCI;
5862  masterGCPConf->newGCP_lo = Uint32(m_micro_gcp.m_new_gci);
5863  masterGCPConf->saveState = saveState;
5864  masterGCPConf->saveGCI = m_gcp_save.m_gci;
5865  for(Uint32 i = 0; i < NdbNodeBitmask::Size; i++)
5866  masterGCPConf->lcpActive[i] = SYSFILE->lcpActive[i];
5867 
5868  if (ERROR_INSERTED(7225))
5869  {
5870  CLEAR_ERROR_INSERT_VALUE;
5871  ndbrequire(refToNode(newMasterBlockref) == getOwnNodeId());
5872  sendSignalWithDelay(newMasterBlockref, GSN_MASTER_GCPCONF, signal,
5873  500, MasterGCPConf::SignalLength);
5874  }
5875  else
5876  {
5877  sendSignal(newMasterBlockref, GSN_MASTER_GCPCONF, signal,
5878  MasterGCPConf::SignalLength, JBB);
5879  }
5880 
5881  if (ERROR_INSERTED(7182))
5882  {
5883  ndbout_c("execGCP_TCFINISHED in MASTER_GCPREQ");
5884  CLEAR_ERROR_INSERT_VALUE;
5885  signal->theData[0] = c_error_7181_ref;
5886  signal->theData[1] = (Uint32)(m_micro_gcp.m_old_gci >> 32);
5887  signal->theData[2] = (Uint32)(m_micro_gcp.m_old_gci & 0xFFFFFFFF);
5888  execGCP_TCFINISHED(signal);
5889  }
5890 
5891  if (c_copyGCISlave.m_expectedNextWord != 0)
5892  {
5893  jam();
5894  c_copyGCISlave.m_expectedNextWord = 0;
5895  c_copyGCISlave.m_copyReason = CopyGCIReq::IDLE;
5896  }
5897 }//Dbdih::execMASTER_GCPREQ()
5898 
5899 void Dbdih::execMASTER_GCPCONF(Signal* signal)
5900 {
5901  NodeRecordPtr senderNodePtr;
5902  MasterGCPConf * const masterGCPConf = (MasterGCPConf *)&signal->theData[0];
5903  jamEntry();
5904  senderNodePtr.i = masterGCPConf->senderNodeId;
5905  ptrCheckGuard(senderNodePtr, MAX_NDB_NODES, nodeRecord);
5906 
5907  MasterGCPConf::State gcpState = (MasterGCPConf::State)masterGCPConf->gcpState;
5908  MasterGCPConf::SaveState saveState =
5909  (MasterGCPConf::SaveState)masterGCPConf->saveState;
5910  const Uint32 failedNodeId = masterGCPConf->failedNodeId;
5911  const Uint32 newGcp_hi = masterGCPConf->newGCP_hi;
5912  const Uint32 newGcp_lo = masterGCPConf->newGCP_lo;
5913  Uint64 newGCI = newGcp_lo | (Uint64(newGcp_hi) << 32);
5914  const Uint32 latestLcpId = masterGCPConf->latestLCP;
5915  const Uint32 oldestRestorableGci = masterGCPConf->oldestRestorableGCI;
5916  const Uint32 oldestKeepGci = masterGCPConf->keepGCI;
5917  const Uint32 saveGCI = masterGCPConf->saveGCI;
5918 
5919  if (latestLcpId > SYSFILE->latestLCP_ID) {
5920  jam();
5921 #if 0
5922  g_eventLogger->info("Dbdih: Setting SYSFILE->latestLCP_ID to %d",
5923  latestLcpId);
5924  SYSFILE->latestLCP_ID = latestLcpId;
5925 #endif
5926  SYSFILE->keepGCI = oldestKeepGci;
5927  SYSFILE->oldestRestorableGCI = oldestRestorableGci;
5928  for(Uint32 i = 0; i < NdbNodeBitmask::Size; i++)
5929  SYSFILE->lcpActive[i] = masterGCPConf->lcpActive[i];
5930  }//if
5931 
5932  bool ok = false;
5933  switch (gcpState) {
5934  case MasterGCPConf::GCP_READY:
5935  jam();
5936  ok = true;
5937  // Either not started or complete...
5938  break;
5940  jam();
5941  ok = true;
5942  if (m_micro_gcp.m_master.m_state == MicroGcp::M_GCP_IDLE)
5943  {
5944  jam();
5945  m_micro_gcp.m_master.m_state = MicroGcp::M_GCP_PREPARE;
5946  m_micro_gcp.m_master.m_new_gci = newGCI;
5947  }
5948  else
5949  {
5950  jam();
5951  ndbrequire(m_micro_gcp.m_master.m_new_gci == newGCI);
5952  }
5953  break;
5955  jam();
5957  jam();
5958  ok = true;
5959  if (m_micro_gcp.m_master.m_state != MicroGcp::M_GCP_IDLE)
5960  {
5961  ndbrequire(m_micro_gcp.m_master.m_new_gci == newGCI);
5962  }
5963  m_micro_gcp.m_master.m_new_gci = newGCI;
5964  m_micro_gcp.m_master.m_state = MicroGcp::M_GCP_COMMIT;
5965  break;
5966 #ifndef VM_TRACE
5967  default:
5968  jamLine(gcpState);
5969  ndbrequire(false);
5970 #endif
5971  }
5972  ndbassert(ok); // Unhandled case...
5973 
5974  ok = false;
5978  ndbrequire(saveGCI == m_gcp_save.m_gci ||
5979  saveGCI == m_gcp_save.m_gci + 1 ||
5980  saveGCI + 1 == m_gcp_save.m_gci);
5981  if (saveGCI > m_gcp_save.m_master.m_new_gci)
5982  {
5983  jam();
5984  m_gcp_save.m_master.m_new_gci = saveGCI;
5985  }
5986  switch(saveState){
5987  case MasterGCPConf::GCP_SAVE_IDLE:
5988  jam();
5989  break;
5991  jam();
5992  if (m_gcp_save.m_master.m_state == GcpSave::GCP_SAVE_IDLE)
5993  {
5994  jam();
5995  m_gcp_save.m_master.m_state = GcpSave::GCP_SAVE_REQ;
5996  }
5997  break;
5999  jam();
6000  if (m_gcp_save.m_master.m_state == GcpSave::GCP_SAVE_IDLE)
6001  {
6002  jam();
6003  m_gcp_save.m_master.m_state = GcpSave::GCP_SAVE_REQ;
6004  }
6005  break;
6007  jam();
6008  if (m_gcp_save.m_master.m_state == GcpSave::GCP_SAVE_IDLE)
6009  {
6010  jam();
6011  m_gcp_save.m_master.m_state = GcpSave::GCP_SAVE_COPY_GCI;
6012  }
6013  break;
6014 #ifndef VM_TRACE
6015  default:
6016  jamLine(saveState);
6017  ndbrequire(false);
6018 #endif
6019  }
6020  //ndbassert(ok); // Unhandled case
6021 
6022  receiveLoopMacro(MASTER_GCPREQ, senderNodePtr.i);
6023  /*-------------------------------------------------------------------------*/
6024  // We have now received all responses and are ready to take over the GCP
6025  // protocol as master.
6026  /*-------------------------------------------------------------------------*/
6027  MASTER_GCPhandling(signal, failedNodeId);
6028 
6029  return;
6030 }//Dbdih::execMASTER_GCPCONF()
6031 
6032 void Dbdih::execMASTER_GCPREF(Signal* signal)
6033 {
6034  const MasterGCPRef * const ref = (MasterGCPRef *)&signal->theData[0];
6035  jamEntry();
6036  receiveLoopMacro(MASTER_GCPREQ, ref->senderNodeId);
6037  /*-------------------------------------------------------------------------*/
6038  // We have now received all responses and are ready to take over the GCP
6039  // protocol as master.
6040  /*-------------------------------------------------------------------------*/
6041  MASTER_GCPhandling(signal, ref->failedNodeId);
6042 }//Dbdih::execMASTER_GCPREF()
6043 
6044 void Dbdih::MASTER_GCPhandling(Signal* signal, Uint32 failedNodeId)
6045 {
6046  cmasterState = MASTER_ACTIVE;
6047 
6048  m_micro_gcp.m_master.m_start_time = 0;
6049  m_gcp_save.m_master.m_start_time = 0;
6050  if (m_gcp_monitor.m_micro_gcp.m_max_lag > 0)
6051  {
6052  infoEvent("GCP Monitor: Computed max GCP_SAVE lag to %u seconds",
6053  m_gcp_monitor.m_gcp_save.m_max_lag / 10);
6054  infoEvent("GCP Monitor: Computed max GCP_COMMIT lag to %u seconds",
6055  m_gcp_monitor.m_micro_gcp.m_max_lag / 10);
6056  }
6057  else
6058  {
6059  infoEvent("GCP Monitor: unlimited lags allowed");
6060  }
6061 
6062  bool ok = false;
6063  switch(m_micro_gcp.m_master.m_state){
6064  case MicroGcp::M_GCP_IDLE:
6065  jam();
6066  ok = true;
6067  signal->theData[0] = DihContinueB::ZSTART_GCP;
6068  sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
6069  break;
6070  case MicroGcp::M_GCP_PREPARE:
6071  {
6072  jam();
6073  ok = true;
6074 
6078  sendLoopMacro(GCP_PREPARE, sendGCP_PREPARE, RNIL);
6079  break;
6080  }
6081  case MicroGcp::M_GCP_COMMIT:
6082  {
6083  jam();
6084  ok = true;
6085 
6089  sendLoopMacro(GCP_COMMIT, sendGCP_COMMIT, RNIL);
6090  break;
6091  }
6092  case MicroGcp::M_GCP_COMMITTED:
6093  jam();
6094  ndbrequire(false);
6095  case MicroGcp::M_GCP_COMPLETE:
6096  jam();
6097  ndbrequire(false);
6098 #ifndef VM_TRACE
6099  default:
6100  jamLine(m_micro_gcp.m_master.m_state);
6101  ndbrequire(false);
6102 #endif
6103  }
6104  ndbassert(ok);
6105 
6106  if (m_micro_gcp.m_enabled == false)
6107  {
6108  jam();
6109  m_gcp_save.m_master.m_state = GcpSave::GCP_SAVE_IDLE;
6110  }
6111  else
6112  {
6113  ok = false;
6114  switch(m_gcp_save.m_master.m_state){
6115  case GcpSave::GCP_SAVE_IDLE:
6116  jam();
6117  ok = true;
6118  break;
6119  case GcpSave::GCP_SAVE_REQ:
6120  {
6121  jam();
6122  ok = true;
6123 
6127  sendLoopMacro(GCP_SAVEREQ, sendGCP_SAVEREQ, RNIL);
6128  break;
6129  }
6130  case GcpSave::GCP_SAVE_CONF:
6131  jam();
6132  case GcpSave::GCP_SAVE_COPY_GCI:
6133  jam();
6134  ok = true;
6135  copyGciLab(signal, CopyGCIReq::GLOBAL_CHECKPOINT);
6136  m_gcp_save.m_master.m_state = GcpSave::GCP_SAVE_COPY_GCI;
6137  break;
6138 #ifndef VM_TRACE
6139  default:
6140  jamLine(m_gcp_save.m_master.m_state);
6141  ndbrequire(false);
6142 #endif
6143  }
6144  ndbrequire(ok);
6145  }
6146 
6147  signal->theData[0] = NDB_LE_GCP_TakeoverCompleted;
6148  signal->theData[1] = m_micro_gcp.m_master.m_state;
6149  signal->theData[2] = m_gcp_save.m_master.m_state;
6150  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
6151 
6152  infoEvent("kk: %u/%u %u %u",
6153  Uint32(m_micro_gcp.m_current_gci >> 32),
6154  Uint32(m_micro_gcp.m_current_gci),
6155  m_micro_gcp.m_master.m_state,
6156  m_gcp_save.m_master.m_state);
6157 
6158  /*--------------------------------------------------*/
6159  /* WE SEPARATE HANDLING OF GLOBAL CHECKPOINTS */
6160  /* AND LOCAL CHECKPOINTS HERE. LCP'S HAVE TO */
6161  /* REMOVE ALL FAILED FRAGMENTS BEFORE WE CAN */
6162  /* HANDLE THE LCP PROTOCOL. */
6163  /*--------------------------------------------------*/
6164  checkLocalNodefailComplete(signal, failedNodeId, NF_GCP_TAKE_OVER);
6165 
6166  startGcpMonitor(signal);
6167 
6168  return;
6169 }//Dbdih::masterGcpConfFromFailedLab()
6170 
6171 void
6172 Dbdih::invalidateNodeLCP(Signal* signal, Uint32 nodeId, Uint32 tableId)
6173 {
6174  jamEntry();
6175  TabRecordPtr tabPtr;
6176  tabPtr.i = tableId;
6177  const Uint32 RT_BREAK = 64;
6178  if (ERROR_INSERTED(7125)) {
6179  return;
6180  }//if
6181  for (Uint32 i = 0; i<RT_BREAK; i++) {
6182  jam();
6183  if (tabPtr.i >= ctabFileSize){
6184  jam();
6189  if (ERROR_INSERTED(7204))
6190  {
6191  CLEAR_ERROR_INSERT_VALUE;
6192  }
6193  setAllowNodeStart(nodeId, true);
6194  if (getNodeStatus(nodeId) == NodeRecord::STARTING) {
6195  jam();
6196  StartInfoConf * conf = (StartInfoConf*)&signal->theData[0];
6197  conf->sendingNodeId = cownNodeId;
6198  conf->startingNodeId = nodeId;
6199  sendSignal(cmasterdihref, GSN_START_INFOCONF, signal,
6200  StartInfoConf::SignalLength, JBB);
6201  }//if
6202  return;
6203  }//if
6204  ptrAss(tabPtr, tabRecord);
6205  if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
6206  jam();
6207  invalidateNodeLCP(signal, nodeId, tabPtr);
6208  return;
6209  }//if
6210  tabPtr.i++;
6211  }//for
6212  signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
6213  signal->theData[1] = nodeId;
6214  signal->theData[2] = tabPtr.i;
6215  sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
6216 }//Dbdih::invalidateNodeLCP()
6217 
6218 void
6219 Dbdih::invalidateNodeLCP(Signal* signal, Uint32 nodeId, TabRecordPtr tabPtr)
6220 {
6224  if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
6225  jam();
6226  signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
6227  signal->theData[1] = nodeId;
6228  signal->theData[2] = tabPtr.i;
6229  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 20, 3);
6230  return;
6231  }//if
6232 
6236  bool modified = false;
6237  FragmentstorePtr fragPtr;
6238  for(Uint32 fragNo = 0; fragNo < tabPtr.p->totalfragments; fragNo++){
6239  jam();
6240  getFragstore(tabPtr.p, fragNo, fragPtr);
6244  ReplicaRecordPtr replicaPtr;
6245  for(replicaPtr.i = fragPtr.p->oldStoredReplicas; replicaPtr.i != RNIL;
6246  replicaPtr.i = replicaPtr.p->nextReplica) {
6247  jam();
6248  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
6249  if(replicaPtr.p->procNode == nodeId){
6250  jam();
6257  modified = true;
6258  for(int i = 0; i < MAX_LCP_STORED; i++) {
6259  replicaPtr.p->lcpStatus[i] = ZINVALID;
6260  }//if
6264  replicaPtr.p->nextLcp = 0;
6265  replicaPtr.p->noCrashedReplicas = 0;
6266  }//if
6267  }//for
6268  }//for
6269 
6270  if (modified) {
6271  jam();
6275  tabPtr.p->tabCopyStatus = TabRecord::CS_INVALIDATE_NODE_LCP;
6276  tabPtr.p->tabUpdateState = TabRecord::US_INVALIDATE_NODE_LCP;
6277  tabPtr.p->tabRemoveNode = nodeId;
6278  signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
6279  signal->theData[1] = tabPtr.i;
6280  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
6281  return;
6282  }
6283 
6284  jam();
6288  tabPtr.i++;
6289  signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
6290  signal->theData[1] = nodeId;
6291  signal->theData[2] = tabPtr.i;
6292 
6293  if (ERROR_INSERTED(7204))
6294  {
6295  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 2000, 3);
6296  }
6297  else
6298  {
6299  sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
6300  }
6301  return;
6302 }//Dbdih::invalidateNodeLCP()
6303 
6304 /*------------------------------------------------*/
6305 /* INPUT: TABPTR */
6306 /* TNODEID */
6307 /*------------------------------------------------*/
6308 void Dbdih::removeNodeFromTables(Signal* signal,
6309  Uint32 nodeId, Uint32 tableId)
6310 {
6311  jamEntry();
6312  TabRecordPtr tabPtr;
6313  tabPtr.i = tableId;
6314  const Uint32 RT_BREAK = 64;
6315  for (Uint32 i = 0; i<RT_BREAK; i++) {
6316  jam();
6317  if (tabPtr.i >= ctabFileSize){
6318  jam();
6319  removeNodeFromTablesComplete(signal, nodeId);
6320  return;
6321  }//if
6322 
6323  ptrAss(tabPtr, tabRecord);
6324  if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
6325  jam();
6326  removeNodeFromTable(signal, nodeId, tabPtr);
6327  return;
6328  }//if
6329  tabPtr.i++;
6330  }//for
6331  signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
6332  signal->theData[1] = nodeId;
6333  signal->theData[2] = tabPtr.i;
6334  sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
6335 }
6336 
6337 void Dbdih::removeNodeFromTable(Signal* signal,
6338  Uint32 nodeId, TabRecordPtr tabPtr){
6339 
6343  if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
6344  jam();
6345  signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
6346  signal->theData[1] = nodeId;
6347  signal->theData[2] = tabPtr.i;
6348  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 20, 3);
6349  return;
6350  }//if
6351 
6352  NodeRecordPtr nodePtr;
6353  nodePtr.i = nodeId;
6354  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
6355  const Uint32 lcpId = nodePtr.p->m_remove_node_from_table_lcp_id;
6356 
6360  Uint32 noOfRemovedReplicas = 0; // No of replicas removed
6361  Uint32 noOfRemovedLcpReplicas = 0; // No of replicas in LCP removed
6362  Uint32 noOfRemainingLcpReplicas = 0;// No of replicas in LCP remaining
6363 
6364  const bool lcpOngoingFlag = (tabPtr.p->tabLcpStatus== TabRecord::TLS_ACTIVE);
6365  const bool unlogged = (tabPtr.p->tabStorage != TabRecord::ST_NORMAL);
6366 
6367  FragmentstorePtr fragPtr;
6368  for(Uint32 fragNo = 0; fragNo < tabPtr.p->totalfragments; fragNo++){
6369  jam();
6370  getFragstore(tabPtr.p, fragNo, fragPtr);
6371 
6375  bool found = false;
6376  ReplicaRecordPtr replicaPtr;
6377  for(replicaPtr.i = fragPtr.p->storedReplicas; replicaPtr.i != RNIL;
6378  replicaPtr.i = replicaPtr.p->nextReplica) {
6379  jam();
6380 
6381  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
6382  if(replicaPtr.p->procNode == nodeId){
6383  jam();
6384  found = true;
6385  noOfRemovedReplicas++;
6386  removeNodeFromStored(nodeId, fragPtr, replicaPtr, unlogged);
6387  if(replicaPtr.p->lcpOngoingFlag){
6388  jam();
6392  ndbrequire(fragPtr.p->noLcpReplicas > 0);
6393  fragPtr.p->noLcpReplicas --;
6394 
6395  noOfRemovedLcpReplicas ++;
6396  replicaPtr.p->lcpOngoingFlag = false;
6397  }
6398 
6399  if (lcpId != RNIL)
6400  {
6401  jam();
6402  Uint32 lcpNo = prevLcpNo(replicaPtr.p->nextLcp);
6403  if (replicaPtr.p->lcpStatus[lcpNo] == ZVALID &&
6404  replicaPtr.p->lcpId[lcpNo] == lcpId)
6405  {
6406  jam();
6407  replicaPtr.p->lcpStatus[lcpNo] = ZINVALID;
6408  replicaPtr.p->lcpId[lcpNo] = 0;
6409  replicaPtr.p->nextLcp = lcpNo;
6410  ndbout_c("REMOVING lcp: %u from table: %u frag: %u node: %u",
6411  SYSFILE->latestLCP_ID,
6412  tabPtr.i, fragNo, nodeId);
6413  }
6414  }
6415  }
6416  }
6417 
6422  updateNodeInfo(fragPtr);
6423  noOfRemainingLcpReplicas += fragPtr.p->noLcpReplicas;
6424  }
6425 
6426  if (noOfRemovedReplicas == 0)
6427  {
6428  jam();
6433  tabPtr.i++;
6434  signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
6435  signal->theData[1] = nodeId;
6436  signal->theData[2] = tabPtr.i;
6437  sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
6438  return;
6439  }
6440 
6444  bool ok = false;
6445  switch(tabPtr.p->tabLcpStatus){
6446  case TabRecord::TLS_COMPLETED:
6447  ok = true;
6448  jam();
6456  ndbrequire(noOfRemovedLcpReplicas == 0);
6457 
6458  tabPtr.p->tabCopyStatus = TabRecord::CS_REMOVE_NODE;
6459  tabPtr.p->tabUpdateState = TabRecord::US_REMOVE_NODE;
6460  tabPtr.p->tabRemoveNode = nodeId;
6461  signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
6462  signal->theData[1] = tabPtr.i;
6463  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
6464  return;
6465  break;
6466  case TabRecord::TLS_ACTIVE:
6467  ok = true;
6468  jam();
6472  // Fall through
6473  break;
6474  case TabRecord::TLS_WRITING_TO_FILE:
6475  ok = true;
6476  jam();
6481  ndbrequire(lcpOngoingFlag);
6482  ndbrequire(false);
6483  break;
6484  }
6485  ndbrequire(ok);
6486 
6491  ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
6492  ndbrequire(tabPtr.p->tabLcpStatus == TabRecord::TLS_ACTIVE);
6493 
6497  tabPtr.p->tabCopyStatus = TabRecord::CS_REMOVE_NODE;
6498  tabPtr.p->tabUpdateState = TabRecord::US_REMOVE_NODE;
6499  tabPtr.p->tabRemoveNode = nodeId;
6500  signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
6501  signal->theData[1] = tabPtr.i;
6502  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
6503 
6504  if(noOfRemainingLcpReplicas == 0){
6505  jam();
6509  tabPtr.p->tabLcpStatus = TabRecord::TLS_WRITING_TO_FILE;
6510  checkLcpAllTablesDoneInLqh(__LINE__);
6511  }
6512 }
6513 
6514 void
6515 Dbdih::removeNodeFromTablesComplete(Signal* signal, Uint32 nodeId){
6516  jam();
6517 
6521  checkLcpCompletedLab(signal);
6522 
6526  checkLocalNodefailComplete(signal, nodeId, NF_REMOVE_NODE_FROM_TABLE);
6527 }
6528 
6529 void
6530 Dbdih::checkLocalNodefailComplete(Signal* signal, Uint32 failedNodeId,
6531  NodefailHandlingStep step){
6532  jam();
6533 
6534  NodeRecordPtr nodePtr;
6535  nodePtr.i = failedNodeId;
6536  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
6537 
6538  ndbrequire(nodePtr.p->m_nodefailSteps.get(step));
6539  nodePtr.p->m_nodefailSteps.clear(step);
6540 
6541  if(nodePtr.p->m_nodefailSteps.count() > 0){
6542  jam();
6543  return;
6544  }
6545 
6546  if (ERROR_INSERTED(7030))
6547  {
6548  g_eventLogger->info("Reenable GCP_PREPARE");
6549  CLEAR_ERROR_INSERT_VALUE;
6550  }
6551 
6552  NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
6553  nf->blockNo = DBDIH;
6554  nf->nodeId = cownNodeId;
6555  nf->failedNodeId = failedNodeId;
6556  nf->from = __LINE__;
6557  sendSignal(reference(), GSN_NF_COMPLETEREP, signal,
6558  NFCompleteRep::SignalLength, JBB);
6559 }
6560 
6561 
6562 void
6563 Dbdih::setLocalNodefailHandling(Signal* signal, Uint32 failedNodeId,
6564  NodefailHandlingStep step){
6565  jam();
6566 
6567  NodeRecordPtr nodePtr;
6568  nodePtr.i = failedNodeId;
6569  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
6570 
6571  ndbrequire(!nodePtr.p->m_nodefailSteps.get(step));
6572  nodePtr.p->m_nodefailSteps.set(step);
6573 }
6574 
6575 void Dbdih::startLcpTakeOverLab(Signal* signal, Uint32 failedNodeId)
6576 {
6577  /*--------------------------------------------------------------------*/
6578  // Start LCP master take over process. Consists of the following steps.
6579  // 1) Ensure that all LQH's have reported all fragments they have been
6580  // told to checkpoint. Can be a fairly long step time-wise.
6581  // 2) Query all nodes about their LCP status.
6582  // During the query process we do not want our own state to change.
6583  // This can change due to delayed reception of LCP_REPORT, completed
6584  // save of table on disk or reception of DIH_LCPCOMPLETE from other
6585  // node.
6586  /*--------------------------------------------------------------------*/
6587 }//Dbdih::startLcpTakeOver()
6588 
6589 void
6590 Dbdih::execEMPTY_LCP_REP(Signal* signal)
6591 {
6592  jamEntry();
6593  EmptyLcpRep* rep = (EmptyLcpRep*)signal->getDataPtr();
6594 
6595  Uint32 len = signal->getLength();
6596  ndbrequire(len > EmptyLcpRep::SignalLength);
6597  len -= EmptyLcpRep::SignalLength;
6598 
6599  NdbNodeBitmask nodes;
6600  nodes.assign(NdbNodeBitmask::Size, rep->receiverGroup);
6601  NodeReceiverGroup rg (DBDIH, nodes);
6602  memmove(signal->getDataPtrSend(),
6603  signal->getDataPtr()+EmptyLcpRep::SignalLength, 4*len);
6604 
6605  sendSignal(rg, GSN_EMPTY_LCP_CONF, signal, len, JBB);
6606 }
6607 
6608 void Dbdih::execEMPTY_LCP_CONF(Signal* signal)
6609 {
6610  jamEntry();
6611 
6612  ndbrequire(c_lcpMasterTakeOverState.state == LMTOS_WAIT_EMPTY_LCP);
6613 
6614  const EmptyLcpConf * const conf = (EmptyLcpConf *)&signal->theData[0];
6615  Uint32 nodeId = conf->senderNodeId;
6616 
6617  CRASH_INSERTION(7206);
6618 
6619 
6620  if(!conf->idle){
6621  jam();
6622  if (conf->tableId < c_lcpMasterTakeOverState.minTableId) {
6623  jam();
6624  c_lcpMasterTakeOverState.minTableId = conf->tableId;
6625  c_lcpMasterTakeOverState.minFragId = conf->fragmentId;
6626  } else if (conf->tableId == c_lcpMasterTakeOverState.minTableId &&
6627  conf->fragmentId < c_lcpMasterTakeOverState.minFragId) {
6628  jam();
6629  c_lcpMasterTakeOverState.minFragId = conf->fragmentId;
6630  }//if
6631  if(isMaster()){
6632  jam();
6633  c_lcpState.m_LAST_LCP_FRAG_ORD.setWaitingFor(nodeId);
6634  }
6635  }
6636 
6637  receiveLoopMacro(EMPTY_LCP_REQ, nodeId);
6638  /*--------------------------------------------------------------------*/
6639  // Received all EMPTY_LCPCONF. We can continue with next phase of the
6640  // take over LCP master process.
6641  /*--------------------------------------------------------------------*/
6642  c_lcpMasterTakeOverState.set(LMTOS_WAIT_LCP_FRAG_REP, __LINE__);
6643  checkEmptyLcpComplete(signal);
6644  return;
6645 }//Dbdih::execEMPTY_LCPCONF()
6646 
6647 void
6648 Dbdih::checkEmptyLcpComplete(Signal *signal){
6649 
6650  ndbrequire(c_lcpMasterTakeOverState.state == LMTOS_WAIT_LCP_FRAG_REP);
6651 
6652  if(c_lcpState.noOfLcpFragRepOutstanding > 0){
6653  jam();
6654  return;
6655  }
6656 
6657  if(isMaster()){
6658  jam();
6659 
6660  signal->theData[0] = NDB_LE_LCP_TakeoverStarted;
6661  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
6662 
6663  signal->theData[0] = 7012;
6664  execDUMP_STATE_ORD(signal);
6665 
6666  if (ERROR_INSERTED(7194))
6667  {
6668  ndbout_c("7194 starting ZREMOVE_NODE_FROM_TABLE");
6669  signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
6670  signal->theData[1] = c_lcpMasterTakeOverState.failedNodeId;
6671  signal->theData[2] = 0; // Tab id
6672  sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
6673  }
6674 
6675  c_current_time = NdbTick_CurrentMillisecond();
6676  c_lcpState.m_start_time = c_current_time;
6677  c_lcpMasterTakeOverState.set(LMTOS_INITIAL, __LINE__);
6678  MasterLCPReq * const req = (MasterLCPReq *)&signal->theData[0];
6679  req->masterRef = reference();
6680  req->failedNodeId = c_lcpMasterTakeOverState.failedNodeId;
6681  sendLoopMacro(MASTER_LCPREQ, sendMASTER_LCPREQ, RNIL);
6682 
6683  } else {
6684  sendMASTER_LCPCONF(signal);
6685  }
6686 }
6687 
6688 /*--------------------------------------------------*/
6689 /* THE MASTER HAS FAILED AND THE NEW MASTER IS*/
6690 /* QUERYING THIS NODE ABOUT THE STATE OF THE */
6691 /* LOCAL CHECKPOINT PROTOCOL. */
6692 /*--------------------------------------------------*/
6693 void Dbdih::execMASTER_LCPREQ(Signal* signal)
6694 {
6695  const MasterLCPReq * const req = (MasterLCPReq *)&signal->theData[0];
6696  jamEntry();
6697  const BlockReference newMasterBlockref = req->masterRef;
6698 
6699  CRASH_INSERTION(7205);
6700 
6701  if (ERROR_INSERTED(7207))
6702  {
6703  jam();
6704  SET_ERROR_INSERT_VALUE(7208);
6705  sendSignalWithDelay(reference(), GSN_MASTER_LCPREQ, signal,
6706  500, signal->getLength());
6707  return;
6708  }
6709 
6710  if (ERROR_INSERTED(7208))
6711  {
6712  jam();
6713  signal->theData[0] = 9999;
6714  sendSignal(numberToRef(CMVMI, refToNode(newMasterBlockref)),
6715  GSN_NDB_TAMPER, signal, 1, JBB);
6716  }
6717 
6718  if (newMasterBlockref != cmasterdihref)
6719  {
6720  jam();
6721  ndbout_c("resending GSN_MASTER_LCPREQ");
6722  sendSignalWithDelay(reference(), GSN_MASTER_LCPREQ, signal,
6723  50, signal->getLength());
6724  return;
6725  }
6726  Uint32 failedNodeId = req->failedNodeId;
6727 
6731  ndbrequire(c_lcpState.m_masterLcpDihRef != newMasterBlockref);
6732  c_lcpState.m_masterLcpDihRef = newMasterBlockref;
6733  c_lcpState.m_MASTER_LCPREQ_Received = true;
6734  c_lcpState.m_MASTER_LCPREQ_FailedNodeId = failedNodeId;
6735 
6736  if(newMasterBlockref != cmasterdihref){
6737  jam();
6738  ndbrequire(0);
6739  }
6740 
6741  if (ERROR_INSERTED(7209))
6742  {
6743  SET_ERROR_INSERT_VALUE(7210);
6744  }
6745 
6746  sendMASTER_LCPCONF(signal);
6747 }//Dbdih::execMASTER_LCPREQ()
6748 
6749 void
6750 Dbdih::sendMASTER_LCPCONF(Signal * signal){
6751 
6752  if(!c_EMPTY_LCP_REQ_Counter.done()){
6757  jam();
6758  return;
6759  }
6760 
6761  if(!c_lcpState.m_MASTER_LCPREQ_Received){
6762  jam();
6766  return;
6767  }
6768 
6769  if(c_lcpState.lcpStatus == LCP_INIT_TABLES){
6770  jam();
6774  return;
6775  }
6776 
6777  if(c_lcpState.lcpStatus == LCP_COPY_GCI)
6778  {
6779  jam();
6783  //Uint32 lcpId = SYSFILE->latestLCP_ID;
6784  SYSFILE->latestLCP_ID--;
6785  Sysfile::clearLCPOngoing(SYSFILE->systemRestartBits);
6786  c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
6787 #if 0
6788  if(c_copyGCISlave.m_copyReason == CopyGCIReq::LOCAL_CHECKPOINT){
6789  g_eventLogger->info("Dbdih: Also resetting c_copyGCISlave");
6790  c_copyGCISlave.m_copyReason = CopyGCIReq::IDLE;
6791  c_copyGCISlave.m_expectedNextWord = 0;
6792  }
6793 #endif
6794  }
6795 
6796  MasterLCPConf::State lcpState;
6797  switch (c_lcpState.lcpStatus) {
6798  case LCP_STATUS_IDLE:
6799  jam();
6800  /*------------------------------------------------*/
6801  /* LOCAL CHECKPOINT IS CURRENTLY NOT ACTIVE */
6802  /* SINCE NO COPY OF RESTART INFORMATION HAVE*/
6803  /* BEEN RECEIVED YET. ALSO THE PREVIOUS */
6804  /* CHECKPOINT HAVE BEEN FULLY COMPLETED. */
6805  /*------------------------------------------------*/
6806  lcpState = MasterLCPConf::LCP_STATUS_IDLE;
6807  break;
6808  case LCP_STATUS_ACTIVE:
6809  jam();
6810  /*--------------------------------------------------*/
6811  /* COPY OF RESTART INFORMATION HAS BEEN */
6812  /* PERFORMED AND ALSO RESPONSE HAVE BEEN SENT.*/
6813  /*--------------------------------------------------*/
6814  lcpState = MasterLCPConf::LCP_STATUS_ACTIVE;
6815  break;
6816  case LCP_TAB_COMPLETED:
6817  jam();
6818  /*--------------------------------------------------------*/
6819  /* ALL LCP_REPORT'S HAVE BEEN COMPLETED FOR */
6820  /* ALL TABLES. SAVE OF AT LEAST ONE TABLE IS */
6821  /* ONGOING YET. */
6822  /*--------------------------------------------------------*/
6823  lcpState = MasterLCPConf::LCP_TAB_COMPLETED;
6824  break;
6825  case LCP_TAB_SAVED:
6826  jam();
6827  /*--------------------------------------------------------*/
6828  /* ALL LCP_REPORT'S HAVE BEEN COMPLETED FOR */
6829  /* ALL TABLES. ALL TABLES HAVE ALSO BEEN SAVED */
6830  /* ALL OTHER NODES ARE NOT YET FINISHED WITH */
6831  /* THE LOCAL CHECKPOINT. */
6832  /*--------------------------------------------------------*/
6833  lcpState = MasterLCPConf::LCP_TAB_SAVED;
6834  break;
6835  case LCP_TCGET:
6836  case LCP_CALCULATE_KEEP_GCI:
6837  case LCP_TC_CLOPSIZE:
6838  case LCP_START_LCP_ROUND:
6844  ndbrequire(false);
6845  lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning
6846  break;
6847  case LCP_COPY_GCI:
6848  case LCP_INIT_TABLES:
6852  ndbrequire(false);
6853  lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning
6854  break;
6855  default:
6856  ndbrequire(false);
6857  lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning
6858  }//switch
6859 
6860  Uint32 failedNodeId = c_lcpState.m_MASTER_LCPREQ_FailedNodeId;
6861  MasterLCPConf * const conf = (MasterLCPConf *)&signal->theData[0];
6862  conf->senderNodeId = cownNodeId;
6863  conf->lcpState = lcpState;
6864  conf->failedNodeId = failedNodeId;
6865  sendSignal(c_lcpState.m_masterLcpDihRef, GSN_MASTER_LCPCONF,
6866  signal, MasterLCPConf::SignalLength, JBB);
6867 
6868  // Answer to MASTER_LCPREQ sent, reset flag so
6869  // that it's not sent again before another request comes in
6870  c_lcpState.m_MASTER_LCPREQ_Received = false;
6871 
6872  if(c_lcpState.lcpStatus == LCP_TAB_SAVED){
6873 #ifdef VM_TRACE
6874  g_eventLogger->info("Sending extra GSN_LCP_COMPLETE_REP to new master");
6875 #endif
6876  sendLCP_COMPLETE_REP(signal);
6877  }
6878 
6879  if(!isMaster()){
6880  c_lcpMasterTakeOverState.set(LMTOS_IDLE, __LINE__);
6881  checkLocalNodefailComplete(signal, failedNodeId, NF_LCP_TAKE_OVER);
6882  }
6883 
6884  return;
6885 }
6886 
6887 NdbOut&
6888 operator<<(NdbOut& out, const Dbdih::LcpMasterTakeOverState state){
6889  switch(state){
6890  case Dbdih::LMTOS_IDLE:
6891  out << "LMTOS_IDLE";
6892  break;
6893  case Dbdih::LMTOS_WAIT_EMPTY_LCP:
6894  out << "LMTOS_WAIT_EMPTY_LCP";
6895  break;
6896  case Dbdih::LMTOS_WAIT_LCP_FRAG_REP:
6897  out << "LMTOS_WAIT_EMPTY_LCP";
6898  break;
6899  case Dbdih::LMTOS_INITIAL:
6900  out << "LMTOS_INITIAL";
6901  break;
6902  case Dbdih::LMTOS_ALL_IDLE:
6903  out << "LMTOS_ALL_IDLE";
6904  break;
6905  case Dbdih::LMTOS_ALL_ACTIVE:
6906  out << "LMTOS_ALL_ACTIVE";
6907  break;
6908  case Dbdih::LMTOS_LCP_CONCLUDING:
6909  out << "LMTOS_LCP_CONCLUDING";
6910  break;
6911  case Dbdih::LMTOS_COPY_ONGOING:
6912  out << "LMTOS_COPY_ONGOING";
6913  break;
6914  }
6915  return out;
6916 }
6917 
6919  Dbdih::LcpMasterTakeOverState CurrentState;
6920  MasterLCPConf::State ParticipantState;
6921  Dbdih::LcpMasterTakeOverState NewState;
6922 };
6923 
6924 static const
6925 MASTERLCP_StateTransitions g_masterLCPTakeoverStateTransitions[] = {
6929  { Dbdih::LMTOS_INITIAL,
6930  MasterLCPConf::LCP_STATUS_IDLE,
6931  Dbdih::LMTOS_ALL_IDLE },
6932 
6933  { Dbdih::LMTOS_INITIAL,
6934  MasterLCPConf::LCP_STATUS_ACTIVE,
6935  Dbdih::LMTOS_ALL_ACTIVE },
6936 
6937  { Dbdih::LMTOS_INITIAL,
6938  MasterLCPConf::LCP_TAB_COMPLETED,
6939  Dbdih::LMTOS_LCP_CONCLUDING },
6940 
6941  { Dbdih::LMTOS_INITIAL,
6942  MasterLCPConf::LCP_TAB_SAVED,
6943  Dbdih::LMTOS_LCP_CONCLUDING },
6944 
6948  { Dbdih::LMTOS_ALL_IDLE,
6949  MasterLCPConf::LCP_STATUS_IDLE,
6950  Dbdih::LMTOS_ALL_IDLE },
6951 
6952  { Dbdih::LMTOS_ALL_IDLE,
6953  MasterLCPConf::LCP_STATUS_ACTIVE,
6954  Dbdih::LMTOS_COPY_ONGOING },
6955 
6956  { Dbdih::LMTOS_ALL_IDLE,
6957  MasterLCPConf::LCP_TAB_COMPLETED,
6958  Dbdih::LMTOS_LCP_CONCLUDING },
6959 
6960  { Dbdih::LMTOS_ALL_IDLE,
6961  MasterLCPConf::LCP_TAB_SAVED,
6962  Dbdih::LMTOS_LCP_CONCLUDING },
6963 
6967  { Dbdih::LMTOS_COPY_ONGOING,
6968  MasterLCPConf::LCP_STATUS_IDLE,
6969  Dbdih::LMTOS_COPY_ONGOING },
6970 
6971  { Dbdih::LMTOS_COPY_ONGOING,
6972  MasterLCPConf::LCP_STATUS_ACTIVE,
6973  Dbdih::LMTOS_COPY_ONGOING },
6974 
6978  { Dbdih::LMTOS_ALL_ACTIVE,
6979  MasterLCPConf::LCP_STATUS_IDLE,
6980  Dbdih::LMTOS_COPY_ONGOING },
6981 
6982  { Dbdih::LMTOS_ALL_ACTIVE,
6983  MasterLCPConf::LCP_STATUS_ACTIVE,
6984  Dbdih::LMTOS_ALL_ACTIVE },
6985 
6986  { Dbdih::LMTOS_ALL_ACTIVE,
6987  MasterLCPConf::LCP_TAB_COMPLETED,
6988  Dbdih::LMTOS_LCP_CONCLUDING },
6989 
6990  { Dbdih::LMTOS_ALL_ACTIVE,
6991  MasterLCPConf::LCP_TAB_SAVED,
6992  Dbdih::LMTOS_LCP_CONCLUDING },
6993 
6997  { Dbdih::LMTOS_LCP_CONCLUDING,
6998  MasterLCPConf::LCP_STATUS_IDLE,
6999  Dbdih::LMTOS_LCP_CONCLUDING },
7000 
7001  { Dbdih::LMTOS_LCP_CONCLUDING,
7002  MasterLCPConf::LCP_STATUS_ACTIVE,
7003  Dbdih::LMTOS_LCP_CONCLUDING },
7004 
7005  { Dbdih::LMTOS_LCP_CONCLUDING,
7006  MasterLCPConf::LCP_TAB_COMPLETED,
7007  Dbdih::LMTOS_LCP_CONCLUDING },
7008 
7009  { Dbdih::LMTOS_LCP_CONCLUDING,
7010  MasterLCPConf::LCP_TAB_SAVED,
7011  Dbdih::LMTOS_LCP_CONCLUDING }
7012 };
7013 
7014 const Uint32 g_masterLCPTakeoverStateTransitionsRows =
7015 sizeof(g_masterLCPTakeoverStateTransitions) / sizeof(struct MASTERLCP_StateTransitions);
7016 
7017 void Dbdih::execMASTER_LCPCONF(Signal* signal)
7018 {
7019  const MasterLCPConf * const conf = (MasterLCPConf *)&signal->theData[0];
7020  jamEntry();
7021 
7022  if (ERROR_INSERTED(7194))
7023  {
7024  ndbout_c("delaying MASTER_LCPCONF due to error 7194");
7025  sendSignalWithDelay(reference(), GSN_MASTER_LCPCONF, signal,
7026  300, signal->getLength());
7027  return;
7028  }
7029 
7030  Uint32 senderNodeId = conf->senderNodeId;
7031  MasterLCPConf::State lcpState = (MasterLCPConf::State)conf->lcpState;
7032  const Uint32 failedNodeId = conf->failedNodeId;
7033  NodeRecordPtr nodePtr;
7034  nodePtr.i = senderNodeId;
7035  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
7036  nodePtr.p->lcpStateAtTakeOver = lcpState;
7037 
7038  CRASH_INSERTION(7180);
7039 
7040 #ifdef VM_TRACE
7041  g_eventLogger->info("MASTER_LCPCONF");
7042  printMASTER_LCP_CONF(stdout, &signal->theData[0], 0, 0);
7043 #endif
7044 
7045  bool found = false;
7046  for(Uint32 i = 0; i<g_masterLCPTakeoverStateTransitionsRows; i++){
7047  const struct MASTERLCP_StateTransitions * valid =
7048  &g_masterLCPTakeoverStateTransitions[i];
7049 
7050  if(valid->CurrentState == c_lcpMasterTakeOverState.state &&
7051  valid->ParticipantState == lcpState){
7052  jam();
7053  found = true;
7054  c_lcpMasterTakeOverState.set(valid->NewState, __LINE__);
7055  break;
7056  }
7057  }
7058  ndbrequire(found);
7059 
7060  bool ok = false;
7061  switch(lcpState){
7062  case MasterLCPConf::LCP_STATUS_IDLE:
7063  ok = true;
7064  break;
7065  case MasterLCPConf::LCP_STATUS_ACTIVE:
7066  case MasterLCPConf::LCP_TAB_COMPLETED:
7067  case MasterLCPConf::LCP_TAB_SAVED:
7068  ok = true;
7069  c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.setWaitingFor(nodePtr.i);
7070  break;
7071  }
7072  ndbrequire(ok);
7073 
7074  receiveLoopMacro(MASTER_LCPREQ, senderNodeId);
7075  /*-------------------------------------------------------------------------*/
7076  // We have now received all responses and are ready to take over the LCP
7077  // protocol as master.
7078  /*-------------------------------------------------------------------------*/
7079  MASTER_LCPhandling(signal, failedNodeId);
7080 }//Dbdih::execMASTER_LCPCONF()
7081 
7082 void Dbdih::execMASTER_LCPREF(Signal* signal)
7083 {
7084  const MasterLCPRef * const ref = (MasterLCPRef *)&signal->theData[0];
7085  jamEntry();
7086 
7087  Uint32 senderNodeId = ref->senderNodeId;
7088  Uint32 failedNodeId = ref->failedNodeId;
7089 
7090  if (c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.isWaitingFor(senderNodeId))
7091  {
7092  jam();
7093  c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.clearWaitingFor(senderNodeId);
7094  }
7095 
7096  receiveLoopMacro(MASTER_LCPREQ, senderNodeId);
7097  /*-------------------------------------------------------------------------*/
7098  // We have now received all responses and are ready to take over the LCP
7099  // protocol as master.
7100  /*-------------------------------------------------------------------------*/
7101  MASTER_LCPhandling(signal, failedNodeId);
7102 }//Dbdih::execMASTER_LCPREF()
7103 
7104 void Dbdih::MASTER_LCPhandling(Signal* signal, Uint32 failedNodeId)
7105 {
7106  /*-------------------------------------------------------------------------
7107  *
7108  * WE ARE NOW READY TO CONCLUDE THE TAKE OVER AS MASTER.
7109  * WE HAVE ENOUGH INFO TO START UP ACTIVITIES IN THE PROPER PLACE.
7110  * ALSO SET THE PROPER STATE VARIABLES.
7111  *------------------------------------------------------------------------*/
7112  c_lcpState.currentFragment.tableId = c_lcpMasterTakeOverState.minTableId;
7113  c_lcpState.currentFragment.fragmentId = c_lcpMasterTakeOverState.minFragId;
7114  c_lcpState.m_LAST_LCP_FRAG_ORD = c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH;
7115 
7116  NodeRecordPtr failedNodePtr;
7117  failedNodePtr.i = failedNodeId;
7118  ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
7119 
7120  switch (c_lcpMasterTakeOverState.state) {
7121  case LMTOS_ALL_IDLE:
7122  jam();
7123  /* --------------------------------------------------------------------- */
7124  // All nodes were idle in the LCP protocol. Start checking for start of LCP
7125  // protocol.
7126  /* --------------------------------------------------------------------- */
7127 #ifdef VM_TRACE
7128  g_eventLogger->info("MASTER_LCPhandling:: LMTOS_ALL_IDLE -> checkLcpStart");
7129 #endif
7130  checkLcpStart(signal, __LINE__);
7131  break;
7132  case LMTOS_COPY_ONGOING:
7133  jam();
7134  /* --------------------------------------------------------------------- */
7135  // We were in the starting process of the LCP protocol. We will restart the
7136  // protocol by calculating the keep gci and storing the new lcp id.
7137  /* --------------------------------------------------------------------- */
7138 #ifdef VM_TRACE
7139  g_eventLogger->info("MASTER_LCPhandling:: LMTOS_COPY_ONGOING -> storeNewLcpId");
7140 #endif
7141  if (c_lcpState.lcpStatus == LCP_STATUS_ACTIVE) {
7142  jam();
7143  /*---------------------------------------------------------------------*/
7144  /* WE NEED TO DECREASE THE LATEST LCP ID SINCE WE HAVE ALREADY */
7145  /* STARTED THIS */
7146  /* LOCAL CHECKPOINT. */
7147  /*---------------------------------------------------------------------*/
7148  Uint32 lcpId = SYSFILE->latestLCP_ID;
7149 #ifdef VM_TRACE
7150  g_eventLogger->info("Decreasing latestLCP_ID from %d to %d", lcpId, lcpId - 1);
7151 #endif
7152  SYSFILE->latestLCP_ID--;
7153  }//if
7154 
7155  {
7156  Mutex mutex(signal, c_mutexMgr, c_fragmentInfoMutex_lcp);
7157  Callback c = { safe_cast(&Dbdih::lcpFragmentMutex_locked), 0 };
7158  ndbrequire(mutex.lock(c, false));
7159  }
7160  break;
7161  case LMTOS_ALL_ACTIVE:
7162  {
7163  jam();
7164  /* -------------------------------------------------------------------
7165  * Everybody was in the active phase. We will restart sending
7166  * LCP_FRAGORD to the nodes from the new master.
7167  * We also need to set dihLcpStatus to ZACTIVE
7168  * in the master node since the master will wait for all nodes to
7169  * complete before finalising the LCP process.
7170  * ------------------------------------------------------------------ */
7171 #ifdef VM_TRACE
7172  g_eventLogger->info("MASTER_LCPhandling:: LMTOS_ALL_ACTIVE -> "
7173  "startLcpRoundLoopLab(table=%u, fragment=%u)",
7174  c_lcpMasterTakeOverState.minTableId,
7175  c_lcpMasterTakeOverState.minFragId);
7176 #endif
7177 
7178  c_lcpState.keepGci = SYSFILE->keepGCI;
7179 
7183  Mutex mutex(signal, c_mutexMgr, c_fragmentInfoMutex_lcp);
7184  Callback c =
7185  { safe_cast(&Dbdih::master_lcp_fragmentMutex_locked), failedNodePtr.i };
7186  ndbrequire(mutex.lock(c, false));
7187  return;
7188  }
7189  case LMTOS_LCP_CONCLUDING:
7190  {
7191  jam();
7192  /* ------------------------------------------------------------------- */
7193  // The LCP process is in the finalisation phase. We simply wait for it to
7194  // complete with signals arriving in. We need to check also if we should
7195  // change state due to table write completion during state
7196  // collection phase.
7197  /* ------------------------------------------------------------------- */
7198  ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
7199 
7203  Mutex mutex(signal, c_mutexMgr, c_fragmentInfoMutex_lcp);
7204  Callback c =
7205  { safe_cast(&Dbdih::master_lcp_fragmentMutex_locked), failedNodePtr.i };
7206  ndbrequire(mutex.lock(c, false));
7207  return;
7208  }
7209  default:
7210  ndbrequire(false);
7211  break;
7212  }//switch
7213  signal->theData[0] = NDB_LE_LCP_TakeoverCompleted;
7214  signal->theData[1] = c_lcpMasterTakeOverState.state;
7215  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
7216 
7217  signal->theData[0] = 7012;
7218  execDUMP_STATE_ORD(signal);
7219 
7220  c_lcpMasterTakeOverState.set(LMTOS_IDLE, __LINE__);
7221 
7222  checkLocalNodefailComplete(signal, failedNodePtr.i, NF_LCP_TAKE_OVER);
7223 }
7224 
7225 /* ------------------------------------------------------------------------- */
7226 /* A BLOCK OR A NODE HAS COMPLETED THE HANDLING OF THE NODE FAILURE. */
7227 /* ------------------------------------------------------------------------- */
7228 void Dbdih::execNF_COMPLETEREP(Signal* signal)
7229 {
7230  NodeRecordPtr failedNodePtr;
7231  NFCompleteRep * const nfCompleteRep = (NFCompleteRep *)&signal->theData[0];
7232  jamEntry();
7233  const Uint32 blockNo = nfCompleteRep->blockNo;
7234  Uint32 nodeId = nfCompleteRep->nodeId;
7235  failedNodePtr.i = nfCompleteRep->failedNodeId;
7236 
7237  ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
7238  switch (blockNo) {
7239  case DBTC:
7240  jam();
7241  ndbrequire(failedNodePtr.p->dbtcFailCompleted == ZFALSE);
7242  /* -------------------------------------------------------------------- */
7243  // Report the event that DBTC completed node failure handling.
7244  /* -------------------------------------------------------------------- */
7245  signal->theData[0] = NDB_LE_NodeFailCompleted;
7246  signal->theData[1] = DBTC;
7247  signal->theData[2] = failedNodePtr.i;
7248  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
7249 
7250  failedNodePtr.p->dbtcFailCompleted = ZTRUE;
7251  break;
7252  case DBDICT:
7253  jam();
7254  ndbrequire(failedNodePtr.p->dbdictFailCompleted == ZFALSE);
7255  /* --------------------------------------------------------------------- */
7256  // Report the event that DBDICT completed node failure handling.
7257  /* --------------------------------------------------------------------- */
7258  signal->theData[0] = NDB_LE_NodeFailCompleted;
7259  signal->theData[1] = DBDICT;
7260  signal->theData[2] = failedNodePtr.i;
7261  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
7262 
7263  failedNodePtr.p->dbdictFailCompleted = ZTRUE;
7264  break;
7265  case DBDIH:
7266  jam();
7267  ndbrequire(failedNodePtr.p->dbdihFailCompleted == ZFALSE);
7268  /* --------------------------------------------------------------------- */
7269  // Report the event that DBDIH completed node failure handling.
7270  /* --------------------------------------------------------------------- */
7271  signal->theData[0] = NDB_LE_NodeFailCompleted;
7272  signal->theData[1] = DBDIH;
7273  signal->theData[2] = failedNodePtr.i;
7274  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
7275 
7276  failedNodePtr.p->dbdihFailCompleted = ZTRUE;
7277  break;
7278  case DBLQH:
7279  jam();
7280  ndbrequire(failedNodePtr.p->dblqhFailCompleted == ZFALSE);
7281  /* --------------------------------------------------------------------- */
7282  // Report the event that DBDIH completed node failure handling.
7283  /* --------------------------------------------------------------------- */
7284  signal->theData[0] = NDB_LE_NodeFailCompleted;
7285  signal->theData[1] = DBLQH;
7286  signal->theData[2] = failedNodePtr.i;
7287  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
7288 
7289  failedNodePtr.p->dblqhFailCompleted = ZTRUE;
7290  break;
7291  case 0: /* Node has finished */
7292  jam();
7293  ndbrequire(nodeId < MAX_NDB_NODES);
7294 
7295  if (failedNodePtr.p->recNODE_FAILREP == ZFALSE) {
7296  jam();
7297  /* ------------------------------------------------------------------- */
7298  // We received a report about completion of node failure before we
7299  // received the message about the NODE failure ourselves.
7300  // We will send the signal to ourselves with a small delay
7301  // (10 milliseconds).
7302  /* ------------------------------------------------------------------- */
7303  //nf->from = __LINE__;
7304  sendSignalWithDelay(reference(), GSN_NF_COMPLETEREP, signal, 10,
7305  signal->length());
7306  return;
7307  }//if
7308 
7309  if (!failedNodePtr.p->m_NF_COMPLETE_REP.isWaitingFor(nodeId)){
7310  jam();
7311  return;
7312  }
7313 
7314  failedNodePtr.p->m_NF_COMPLETE_REP.clearWaitingFor(nodeId);;
7315 
7316  /* -------------------------------------------------------------------- */
7317  // Report the event that nodeId has completed node failure handling.
7318  /* -------------------------------------------------------------------- */
7319  signal->theData[0] = NDB_LE_NodeFailCompleted;
7320  signal->theData[1] = 0;
7321  signal->theData[2] = failedNodePtr.i;
7322  signal->theData[3] = nodeId;
7323  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
7324 
7325  nodeFailCompletedCheckLab(signal, failedNodePtr);
7326  return;
7327  break;
7328  default:
7329  ndbrequire(false);
7330  return;
7331  break;
7332  }//switch
7333  if (failedNodePtr.p->dbtcFailCompleted == ZFALSE) {
7334  jam();
7335  return;
7336  }//if
7337  if (failedNodePtr.p->dbdictFailCompleted == ZFALSE) {
7338  jam();
7339  return;
7340  }//if
7341  if (failedNodePtr.p->dbdihFailCompleted == ZFALSE) {
7342  jam();
7343  return;
7344  }//if
7345  if (failedNodePtr.p->dblqhFailCompleted == ZFALSE) {
7346  jam();
7347  return;
7348  }//if
7349  /* ----------------------------------------------------------------------- */
7350  /* ALL BLOCKS IN THIS NODE HAVE COMPLETED THEIR PART OF HANDLING THE */
7351  /* NODE FAILURE. WE CAN NOW REPORT THIS COMPLETION TO ALL OTHER NODES. */
7352  /* ----------------------------------------------------------------------- */
7353  NodeRecordPtr nodePtr;
7354  for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
7355  jam();
7356  ptrAss(nodePtr, nodeRecord);
7357  if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
7358  jam();
7359  BlockReference ref = calcDihBlockRef(nodePtr.i);
7360  NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
7361  nf->blockNo = 0;
7362  nf->nodeId = cownNodeId;
7363  nf->failedNodeId = failedNodePtr.i;
7364  nf->from = __LINE__;
7365  sendSignal(ref, GSN_NF_COMPLETEREP, signal,
7366  NFCompleteRep::SignalLength, JBB);
7367  }//if
7368  }//for
7369  return;
7370 }//Dbdih::execNF_COMPLETEREP()
7371 
7372 void Dbdih::nodeFailCompletedCheckLab(Signal* signal,
7373  NodeRecordPtr failedNodePtr)
7374 {
7375  jam();
7376  if (!failedNodePtr.p->m_NF_COMPLETE_REP.done()){
7377  jam();
7378  return;
7379  }//if
7380  /* ---------------------------------------------------------------------- */
7381  /* ALL BLOCKS IN ALL NODES HAVE NOW REPORTED COMPLETION OF THE NODE */
7382  /* FAILURE HANDLING. WE ARE NOW READY TO ACCEPT THAT THIS NODE STARTS */
7383  /* AGAIN. */
7384  /* ---------------------------------------------------------------------- */
7385  jam();
7386  failedNodePtr.p->nodeStatus = NodeRecord::DEAD;
7387  failedNodePtr.p->recNODE_FAILREP = ZFALSE;
7388 
7389  /* ---------------------------------------------------------------------- */
7390  // Report the event that all nodes completed node failure handling.
7391  /* ---------------------------------------------------------------------- */
7392  signal->theData[0] = NDB_LE_NodeFailCompleted;
7393  signal->theData[1] = 0;
7394  signal->theData[2] = failedNodePtr.i;
7395  signal->theData[3] = 0;
7396  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
7397 
7398  /* ---------------------------------------------------------------------- */
7399  // Report to QMGR that we have concluded recovery handling of this node.
7400  /* ---------------------------------------------------------------------- */
7401  signal->theData[0] = failedNodePtr.i;
7402  sendSignal(QMGR_REF, GSN_NDB_FAILCONF, signal, 1, JBB);
7403 
7404  return;
7405 }//Dbdih::nodeFailCompletedCheckLab()
7406 
7407 /*****************************************************************************/
7408 /* ********** SEIZING / RELEASING MODULE *************/
7409 /*****************************************************************************/
7410 /*
7411  3.4 L O C A L N O D E S E I Z E
7412  ************************************
7413  */
7414 /*
7415  3.7 A D D T A B L E
7416  **********************=
7417  */
7418 /*****************************************************************************/
7419 /* ********** TABLE ADDING MODULE *************/
7420 /*****************************************************************************/
7421 /*
7422  3.7.1 A D D T A B L E M A I N L Y
7423  ***************************************
7424  */
7425 
7426 static inline void inc_node_or_group(Uint32 &node, Uint32 max_node)
7427 {
7428  Uint32 next = node + 1;
7429  node = (next == max_node ? 0 : next);
7430 }
7431 
7432 /*
7433  Spread fragments in backwards compatible mode
7434 */
7435 static void set_default_node_groups(Signal *signal, Uint32 noFrags)
7436 {
7437  Uint16 *node_group_array = (Uint16*)&signal->theData[25];
7438  Uint32 i;
7439  node_group_array[0] = 0;
7440  for (i = 1; i < noFrags; i++)
7441  node_group_array[i] = NDB_UNDEF_NODEGROUP;
7442 }
7443 
7444 static Uint32 find_min_index(const Uint32* array, Uint32 cnt)
7445 {
7446  Uint32 m = 0;
7447  Uint32 mv = array[0];
7448  for (Uint32 i = 1; i<cnt; i++)
7449  {
7450  if (array[i] < mv)
7451  {
7452  m = i;
7453  mv = array[i];
7454  }
7455  }
7456  return m;
7457 }
7458 
7459 void Dbdih::execCREATE_FRAGMENTATION_REQ(Signal * signal)
7460 {
7461  Uint16 node_group_id[MAX_NDB_PARTITIONS];
7462  jamEntry();
7463  CreateFragmentationReq * const req =
7464  (CreateFragmentationReq*)signal->getDataPtr();
7465 
7466  const Uint32 senderRef = req->senderRef;
7467  const Uint32 senderData = req->senderData;
7468  Uint32 noOfFragments = req->noOfFragments;
7469  const Uint32 fragType = req->fragmentationType;
7470  const Uint32 primaryTableId = req->primaryTableId;
7471  const Uint32 map_ptr_i = req->map_ptr_i;
7472  const Uint32 flags = req->requestInfo;
7473 
7474  Uint32 err = 0;
7475  const Uint32 defaultFragments =
7476  c_fragments_per_node * cnoOfNodeGroups * cnoReplicas;
7477 
7478  do {
7479  NodeGroupRecordPtr NGPtr;
7480  TabRecordPtr primTabPtr;
7481  Uint32 count = 2;
7482  Uint16 noOfReplicas = cnoReplicas;
7483  Uint16 *fragments = (Uint16*)(signal->theData+25);
7484  if (primaryTableId == RNIL) {
7485  jam();
7486  switch ((DictTabInfo::FragmentType)fragType){
7487  /*
7488  Backward compatability and for all places in code not changed.
7489  */
7490  case DictTabInfo::AllNodesSmallTable:
7491  jam();
7492  noOfFragments = defaultFragments;
7493  set_default_node_groups(signal, noOfFragments);
7494  break;
7495  case DictTabInfo::AllNodesMediumTable:
7496  jam();
7497  noOfFragments = 2 * defaultFragments;
7498  set_default_node_groups(signal, noOfFragments);
7499  break;
7500  case DictTabInfo::AllNodesLargeTable:
7501  jam();
7502  noOfFragments = 4 * defaultFragments;
7503  set_default_node_groups(signal, noOfFragments);
7504  break;
7505  case DictTabInfo::SingleFragment:
7506  jam();
7507  noOfFragments = 1;
7508  set_default_node_groups(signal, noOfFragments);
7509  break;
7510  case DictTabInfo::DistrKeyHash:
7511  jam();
7512  case DictTabInfo::DistrKeyLin:
7513  jam();
7514  if (noOfFragments == 0)
7515  {
7516  jam();
7517  noOfFragments = defaultFragments;
7518  set_default_node_groups(signal, noOfFragments);
7519  }
7520  break;
7521  case DictTabInfo::HashMapPartition:
7522  {
7523  jam();
7524  ndbrequire(map_ptr_i != RNIL);
7526  g_hash_map.getPtr(ptr, map_ptr_i);
7527  if (noOfFragments == 0)
7528  {
7529  jam();
7530  noOfFragments = ptr.p->m_fragments;
7531  }
7532  else if (noOfFragments != ptr.p->m_fragments)
7533  {
7534  jam();
7535  err = CreateFragmentationRef::InvalidFragmentationType;
7536  break;
7537  }
7538  set_default_node_groups(signal, noOfFragments);
7539  break;
7540  }
7541  default:
7542  jam();
7543  if (noOfFragments == 0)
7544  {
7545  jam();
7546  err = CreateFragmentationRef::InvalidFragmentationType;
7547  }
7548  break;
7549  }
7550  if (err)
7551  break;
7552  /*
7553  When we come here the the exact partition is specified
7554  and there is an array of node groups sent along as well.
7555  */
7556  memcpy(&node_group_id[0], &signal->theData[25], 2 * noOfFragments);
7557  Uint16 next_replica_node[MAX_NDB_NODES];
7558  memset(next_replica_node,0,sizeof(next_replica_node));
7559  Uint32 default_node_group= c_nextNodeGroup;
7560  for(Uint32 fragNo = 0; fragNo < noOfFragments; fragNo++)
7561  {
7562  jam();
7563  NGPtr.i = node_group_id[fragNo];
7564  if (NGPtr.i == NDB_UNDEF_NODEGROUP)
7565  {
7566  jam();
7567  NGPtr.i = c_node_groups[default_node_group];
7568  }
7569  if (NGPtr.i >= MAX_NDB_NODES)
7570  {
7571  jam();
7572  err = CreateFragmentationRef::InvalidNodeGroup;
7573  break;
7574  }
7575  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
7576  if (NGPtr.p->nodegroupIndex == RNIL)
7577  {
7578  jam();
7579  err = CreateFragmentationRef::InvalidNodeGroup;
7580  break;
7581  }
7582  const Uint32 max = NGPtr.p->nodeCount;
7583 
7584  fragments[count++] = (NGPtr.p->m_next_log_part++ / cnoReplicas); // Store logpart first
7585  Uint32 tmp= next_replica_node[NGPtr.i];
7586  for(Uint32 replicaNo = 0; replicaNo < noOfReplicas; replicaNo++)
7587  {
7588  jam();
7589  const Uint16 nodeId = NGPtr.p->nodesInGroup[tmp];
7590  fragments[count++]= nodeId;
7591  inc_node_or_group(tmp, max);
7592  }
7593  inc_node_or_group(tmp, max);
7594  next_replica_node[NGPtr.i]= tmp;
7595 
7599  inc_node_or_group(default_node_group, cnoOfNodeGroups);
7600  }
7601  if (err)
7602  {
7603  jam();
7604  break;
7605  }
7606  else
7607  {
7608  jam();
7609  c_nextNodeGroup = default_node_group;
7610  }
7611  } else {
7612  if (primaryTableId >= ctabFileSize) {
7613  jam();
7614  err = CreateFragmentationRef::InvalidPrimaryTable;
7615  break;
7616  }
7617  primTabPtr.i = primaryTableId;
7618  ptrAss(primTabPtr, tabRecord);
7619  if (primTabPtr.p->tabStatus != TabRecord::TS_ACTIVE) {
7620  jam();
7621  err = CreateFragmentationRef::InvalidPrimaryTable;
7622  break;
7623  }
7624  Uint32 fragments_per_node[MAX_NDB_NODES]; // Keep track of no of (primary) fragments per node
7625  bzero(fragments_per_node, sizeof(fragments_per_node));
7626  for (Uint32 fragNo = 0; fragNo < primTabPtr.p->totalfragments; fragNo++) {
7627  jam();
7628  FragmentstorePtr fragPtr;
7629  ReplicaRecordPtr replicaPtr;
7630  getFragstore(primTabPtr.p, fragNo, fragPtr);
7631  fragments[count++] = fragPtr.p->m_log_part_id;
7632  fragments[count++] = fragPtr.p->preferredPrimary;
7633  fragments_per_node[fragPtr.p->preferredPrimary]++;
7634  for (replicaPtr.i = fragPtr.p->storedReplicas;
7635  replicaPtr.i != RNIL;
7636  replicaPtr.i = replicaPtr.p->nextReplica) {
7637  jam();
7638  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
7639  if (replicaPtr.p->procNode != fragPtr.p->preferredPrimary) {
7640  jam();
7641  fragments[count++]= replicaPtr.p->procNode;
7642  }
7643  }
7644  for (replicaPtr.i = fragPtr.p->oldStoredReplicas;
7645  replicaPtr.i != RNIL;
7646  replicaPtr.i = replicaPtr.p->nextReplica) {
7647  jam();
7648  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
7649  if (replicaPtr.p->procNode != fragPtr.p->preferredPrimary) {
7650  jam();
7651  fragments[count++]= replicaPtr.p->procNode;
7652  }
7653  }
7654  }
7655 
7656  if (flags & CreateFragmentationReq::RI_GET_FRAGMENTATION)
7657  {
7658  jam();
7659  noOfFragments = primTabPtr.p->totalfragments;
7660  }
7661  else if (flags & CreateFragmentationReq::RI_ADD_PARTITION)
7662  {
7663  jam();
7668  for (Uint32 i = 0; i<MAX_NDB_NODES; i++)
7669  {
7670  if (getNodeStatus(i) == NodeRecord::NOT_IN_CLUSTER ||
7671  getNodeGroup(i) >= cnoOfNodeGroups) // XXX todo
7672  {
7673  jam();
7674  ndbassert(fragments_per_node[i] == 0);
7675  fragments_per_node[i] = ~(Uint32)0;
7676  }
7677  }
7678  for (Uint32 i = primTabPtr.p->totalfragments; i<noOfFragments; i++)
7679  {
7680  jam();
7681  Uint32 node = find_min_index(fragments_per_node,
7682  NDB_ARRAY_SIZE(fragments_per_node));
7683  NGPtr.i = getNodeGroup(node);
7684  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
7685  fragments[count++] = NGPtr.p->m_next_log_part++;
7686  fragments[count++] = node;
7687  fragments_per_node[node]++;
7688  for (Uint32 r = 0; r<noOfReplicas; r++)
7689  {
7690  jam();
7691  if (NGPtr.p->nodesInGroup[r] != node)
7692  {
7693  jam();
7694  fragments[count++] = NGPtr.p->nodesInGroup[r];
7695  }
7696  }
7697  }
7698  }
7699  }
7700  if(count != (2U + (1 + noOfReplicas) * noOfFragments)){
7701  char buf[255];
7702  BaseString::snprintf(buf, sizeof(buf),
7703  "Illegal configuration change: NoOfReplicas."
7704  " Can't be applied online ");
7705  progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
7706  }
7707 
7708  CreateFragmentationConf * const conf =
7709  (CreateFragmentationConf*)signal->getDataPtrSend();
7710  conf->senderRef = reference();
7711  conf->senderData = senderData;
7712  conf->noOfReplicas = (Uint32)noOfReplicas;
7713  conf->noOfFragments = (Uint32)noOfFragments;
7714 
7715  fragments[0]= noOfReplicas;
7716  fragments[1]= noOfFragments;
7717 
7718  if(senderRef != 0)
7719  {
7720  jam();
7721  LinearSectionPtr ptr[3];
7722  ptr[0].p = (Uint32*)&fragments[0];
7723  ptr[0].sz = (count + 1) / 2;
7724  sendSignal(senderRef,
7725  GSN_CREATE_FRAGMENTATION_CONF,
7726  signal,
7727  CreateFragmentationConf::SignalLength,
7728  JBB,
7729  ptr,
7730  1);
7731  }
7732  // Always ACK/NACK (here ACK)
7733  signal->theData[0] = 0;
7734  return;
7735  } while(false);
7736  // Always ACK/NACK (here NACK)
7737  signal->theData[0] = err;
7738 }
7739 
7740 void Dbdih::execDIADDTABREQ(Signal* signal)
7741 {
7742  Uint32 fragType;
7743  jamEntry();
7744 
7745  DiAddTabReq * const req = (DiAddTabReq*)signal->getDataPtr();
7746 
7747  // Seize connect record
7748  ndbrequire(cfirstconnect != RNIL);
7749  ConnectRecordPtr connectPtr;
7750  connectPtr.i = cfirstconnect;
7751  ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
7752  cfirstconnect = connectPtr.p->nextPool;
7753 
7754  const Uint32 userPtr = req->connectPtr;
7755  const BlockReference userRef = signal->getSendersBlockRef();
7756  connectPtr.p->nextPool = RNIL;
7757  connectPtr.p->userpointer = userPtr;
7758  connectPtr.p->userblockref = userRef;
7759  connectPtr.p->connectState = ConnectRecord::INUSE;
7760  connectPtr.p->table = req->tableId;
7761  connectPtr.p->m_alter.m_changeMask = 0;
7762  connectPtr.p->m_create.m_map_ptr_i = req->hashMapPtrI;
7763 
7764  TabRecordPtr tabPtr;
7765  tabPtr.i = req->tableId;
7766  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7767  tabPtr.p->connectrec = connectPtr.i;
7768  tabPtr.p->tableType = req->tableType;
7769  fragType= req->fragType;
7770  tabPtr.p->schemaVersion = req->schemaVersion;
7771  tabPtr.p->primaryTableId = req->primaryTableId;
7772  tabPtr.p->schemaTransId = req->schemaTransId;
7773  tabPtr.p->m_scan_count[0] = 0;
7774  tabPtr.p->m_scan_count[1] = 0;
7775  tabPtr.p->m_scan_reorg_flag = 0;
7776 
7777  if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE)
7778  {
7779  jam();
7780  tabPtr.p->tabStatus = TabRecord::TS_CREATING;
7781  connectPtr.p->m_alter.m_totalfragments = tabPtr.p->totalfragments;
7782  sendAddFragreq(signal, connectPtr, tabPtr, 0);
7783  return;
7784  }
7785 
7786  if (getNodeState().getSystemRestartInProgress() &&
7787  tabPtr.p->tabStatus == TabRecord::TS_IDLE)
7788  {
7789  jam();
7790 
7791  ndbrequire(cmasterNodeId == getOwnNodeId());
7792  tabPtr.p->tabStatus = TabRecord::TS_CREATING;
7793 
7794  initTableFile(tabPtr);
7795  FileRecordPtr filePtr;
7796  filePtr.i = tabPtr.p->tabFile[0];
7797  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
7798  openFileRw(signal, filePtr);
7799  filePtr.p->reqStatus = FileRecord::OPENING_TABLE;
7800  return;
7801  }
7802 
7803  /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
7804  /* AT THE TIME OF INITIATING THE FILE OF TABLE */
7805  /* DESCRIPTION IS CREATED FOR APPROPRIATE SIZE. EACH */
7806  /* EACH RECORD IN THIS FILE HAS THE INFORMATION ABOUT */
7807  /* ONE TABLE. THE POINTER TO THIS RECORD IS THE TABLE */
7808  /* REFERENCE. IN THE BEGINNING ALL RECORDS ARE CREATED */
7809  /* BUT THEY DO NOT HAVE ANY INFORMATION ABOUT ANY TABLE*/
7810  /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
7811  tabPtr.p->tabStatus = TabRecord::TS_CREATING;
7812  if(req->loggedTable)
7813  tabPtr.p->tabStorage= TabRecord::ST_NORMAL;
7814  else if(req->temporaryTable)
7815  tabPtr.p->tabStorage= TabRecord::ST_TEMPORARY;
7816  else
7817  tabPtr.p->tabStorage= TabRecord::ST_NOLOGGING;
7818  tabPtr.p->kvalue = req->kValue;
7819 
7820  switch ((DictTabInfo::FragmentType)fragType){
7821  case DictTabInfo::HashMapPartition:
7822  tabPtr.p->method = TabRecord::HASH_MAP;
7823  break;
7824  case DictTabInfo::AllNodesSmallTable:
7825  case DictTabInfo::AllNodesMediumTable:
7826  case DictTabInfo::AllNodesLargeTable:
7827  case DictTabInfo::SingleFragment:
7828  jam();
7829  case DictTabInfo::DistrKeyLin:
7830  jam();
7831  tabPtr.p->method = TabRecord::LINEAR_HASH;
7832  break;
7833  case DictTabInfo::DistrKeyHash:
7834  jam();
7835  tabPtr.p->method = TabRecord::NORMAL_HASH;
7836  break;
7837  case DictTabInfo::DistrKeyOrderedIndex:
7838  {
7839  TabRecordPtr primTabPtr;
7840  primTabPtr.i = req->primaryTableId;
7841  ptrCheckGuard(primTabPtr, ctabFileSize, tabRecord);
7842  tabPtr.p->method = primTabPtr.p->method;
7843  req->hashMapPtrI = primTabPtr.p->m_map_ptr_i;
7844  break;
7845  }
7846  case DictTabInfo::UserDefined:
7847  jam();
7848  tabPtr.p->method = TabRecord::USER_DEFINED;
7849  break;
7850  default:
7851  ndbrequire(false);
7852  }
7853 
7854  union {
7855  Uint16 fragments[2 + MAX_FRAG_PER_NODE*MAX_REPLICAS*MAX_NDB_NODES];
7856  Uint32 align;
7857  };
7858  (void)align; // kill warning
7859  SectionHandle handle(this, signal);
7860  SegmentedSectionPtr fragDataPtr;
7861  ndbrequire(handle.getSection(fragDataPtr, DiAddTabReq::FRAGMENTATION));
7862  copy((Uint32*)fragments, fragDataPtr);
7863  releaseSections(handle);
7864 
7865  const Uint32 noReplicas = fragments[0];
7866  const Uint32 noFragments = fragments[1];
7867 
7868  tabPtr.p->noOfBackups = noReplicas - 1;
7869  tabPtr.p->totalfragments = noFragments;
7870  ndbrequire(noReplicas == cnoReplicas); // Only allowed
7871 
7872  if (ERROR_INSERTED(7173)) {
7873  CLEAR_ERROR_INSERT_VALUE;
7874  addtabrefuseLab(signal, connectPtr, ZREPLERROR1);
7875  return;
7876  }
7877  if ((noReplicas * noFragments) > cnoFreeReplicaRec) {
7878  jam();
7879  addtabrefuseLab(signal, connectPtr, ZREPLERROR1);
7880  return;
7881  }//if
7882  if (noFragments > cremainingfrags) {
7883  jam();
7884  addtabrefuseLab(signal, connectPtr, ZREPLERROR2);
7885  return;
7886  }//if
7887 
7888  Uint32 logTotalFragments = 1;
7889  while (logTotalFragments <= tabPtr.p->totalfragments) {
7890  jam();
7891  logTotalFragments <<= 1;
7892  }
7893  logTotalFragments >>= 1;
7894  tabPtr.p->mask = logTotalFragments - 1;
7895  tabPtr.p->hashpointer = tabPtr.p->totalfragments - logTotalFragments;
7896  allocFragments(tabPtr.p->totalfragments, tabPtr);
7897 
7898  if (tabPtr.p->method == TabRecord::HASH_MAP)
7899  {
7900  jam();
7901  tabPtr.p->m_map_ptr_i = req->hashMapPtrI;
7902  tabPtr.p->m_new_map_ptr_i = RNIL;
7903  Ptr<Hash2FragmentMap> mapPtr;
7904  g_hash_map.getPtr(mapPtr, tabPtr.p->m_map_ptr_i);
7905  ndbrequire(tabPtr.p->totalfragments >= mapPtr.p->m_fragments);
7906  }
7907 
7908  Uint32 index = 2;
7909  for (Uint32 fragId = 0; fragId < noFragments; fragId++) {
7910  jam();
7911  FragmentstorePtr fragPtr;
7912  Uint32 activeIndex = 0;
7913  getFragstore(tabPtr.p, fragId, fragPtr);
7914  fragPtr.p->m_log_part_id = fragments[index++];
7915  fragPtr.p->preferredPrimary = fragments[index];
7916 
7917  inc_ng_refcount(getNodeGroup(fragPtr.p->preferredPrimary));
7918 
7919  for (Uint32 i = 0; i<noReplicas; i++) {
7920  const Uint32 nodeId = fragments[index++];
7921  ReplicaRecordPtr replicaPtr;
7922  allocStoredReplica(fragPtr, replicaPtr, nodeId);
7923  if (getNodeStatus(nodeId) == NodeRecord::ALIVE) {
7924  jam();
7925  ndbrequire(activeIndex < MAX_REPLICAS);
7926  fragPtr.p->activeNodes[activeIndex] = nodeId;
7927  activeIndex++;
7928  } else {
7929  jam();
7930  removeStoredReplica(fragPtr, replicaPtr);
7931  linkOldStoredReplica(fragPtr, replicaPtr);
7932  }//if
7933  }//for
7934  fragPtr.p->fragReplicas = activeIndex;
7935  ndbrequire(activeIndex > 0 && fragPtr.p->storedReplicas != RNIL);
7936  }
7937  initTableFile(tabPtr);
7938  tabPtr.p->tabCopyStatus = TabRecord::CS_ADD_TABLE_MASTER;
7939  signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
7940  signal->theData[1] = tabPtr.i;
7941  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
7942 }
7943 
7944 void
7945 Dbdih::addTable_closeConf(Signal * signal, Uint32 tabPtrI){
7946  TabRecordPtr tabPtr;
7947  tabPtr.i = tabPtrI;
7948  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7949 
7950  ConnectRecordPtr connectPtr;
7951  connectPtr.i = tabPtr.p->connectrec;
7952  ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
7953  connectPtr.p->m_alter.m_totalfragments = tabPtr.p->totalfragments;
7954 
7955  sendAddFragreq(signal, connectPtr, tabPtr, 0);
7956 }
7957 
7958 void
7959 Dbdih::sendAddFragreq(Signal* signal, ConnectRecordPtr connectPtr,
7960  TabRecordPtr tabPtr, Uint32 fragId){
7961  jam();
7962  const Uint32 fragCount = connectPtr.p->m_alter.m_totalfragments;
7963  ReplicaRecordPtr replicaPtr;
7964  LINT_INIT(replicaPtr.p);
7965  replicaPtr.i = RNIL;
7966  FragmentstorePtr fragPtr;
7967  for(; fragId<fragCount; fragId++){
7968  jam();
7969  getFragstore(tabPtr.p, fragId, fragPtr);
7970 
7971  replicaPtr.i = fragPtr.p->storedReplicas;
7972  while(replicaPtr.i != RNIL){
7973  jam();
7974  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
7975  if(replicaPtr.p->procNode == getOwnNodeId()){
7976  break;
7977  }
7978  replicaPtr.i = replicaPtr.p->nextReplica;
7979  }
7980 
7981  if(replicaPtr.i != RNIL){
7982  jam();
7983  break;
7984  }
7985 
7986  replicaPtr.i = fragPtr.p->oldStoredReplicas;
7987  while(replicaPtr.i != RNIL){
7988  jam();
7989  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
7990  if(replicaPtr.p->procNode == getOwnNodeId()){
7991  break;
7992  }
7993  replicaPtr.i = replicaPtr.p->nextReplica;
7994  }
7995 
7996  if(replicaPtr.i != RNIL){
7997  jam();
7998  break;
7999  }
8000  }
8001 
8002  if(replicaPtr.i != RNIL){
8003  jam();
8004  ndbrequire(fragId < fragCount);
8005  ndbrequire(replicaPtr.p->procNode == getOwnNodeId());
8006 
8007  Uint32 requestInfo = 0;
8008  if(tabPtr.p->tabStorage != TabRecord::ST_NORMAL){
8009  requestInfo |= LqhFragReq::TemporaryTable;
8010  }
8011 
8012  if(getNodeState().getNodeRestartInProgress()){
8013  requestInfo |= LqhFragReq::CreateInRunning;
8014  }
8015 
8016  AddFragReq* const req = (AddFragReq*)signal->getDataPtr();
8017  req->dihPtr = connectPtr.i;
8018  req->senderData = connectPtr.p->userpointer;
8019  req->fragmentId = fragId;
8020  req->requestInfo = requestInfo;
8021  req->tableId = tabPtr.i;
8022  req->nextLCP = 0;
8023  req->nodeId = getOwnNodeId();
8024  req->totalFragments = fragCount;
8025  req->startGci = SYSFILE->newestRestorableGCI;
8026  req->logPartId = fragPtr.p->m_log_part_id;
8027  req->changeMask = 0;
8028 
8029  if (connectPtr.p->connectState == ConnectRecord::ALTER_TABLE)
8030  {
8031  jam();
8032  req->changeMask = connectPtr.p->m_alter.m_changeMask;
8033  }
8034 
8035  sendSignal(DBDICT_REF, GSN_ADD_FRAGREQ, signal,
8036  AddFragReq::SignalLength, JBB);
8037  return;
8038  }
8039 
8040  if (connectPtr.p->connectState == ConnectRecord::ALTER_TABLE)
8041  {
8042  jam();
8043  // Request handled successfully
8044 
8045  if (AlterTableReq::getReorgFragFlag(connectPtr.p->m_alter.m_changeMask))
8046  {
8047  jam();
8048  DIH_TAB_WRITE_LOCK(tabPtr.p);
8049  tabPtr.p->m_new_map_ptr_i = connectPtr.p->m_alter.m_new_map_ptr_i;
8050  DIH_TAB_WRITE_UNLOCK(tabPtr.p);
8051  }
8052 
8053  if (AlterTableReq::getAddFragFlag(connectPtr.p->m_alter.m_changeMask))
8054  {
8055  jam();
8056  Callback cb;
8057  cb.m_callbackData = connectPtr.i;
8058  cb.m_callbackFunction = safe_cast(&Dbdih::alter_table_writeTable_conf);
8059  saveTableFile(signal, connectPtr, tabPtr, TabRecord::CS_ALTER_TABLE, cb);
8060  return;
8061  }
8062 
8063  send_alter_tab_conf(signal, connectPtr);
8064  }
8065  else
8066  {
8067  // Done
8068  DiAddTabConf * const conf = (DiAddTabConf*)signal->getDataPtr();
8069  conf->senderData = connectPtr.p->userpointer;
8070  sendSignal(connectPtr.p->userblockref, GSN_DIADDTABCONF, signal,
8071  DiAddTabConf::SignalLength, JBB);
8072 
8073 
8074  if (tabPtr.p->method == TabRecord::HASH_MAP)
8075  {
8076  Uint32 newValue = RNIL;
8077  if (DictTabInfo::isOrderedIndex(tabPtr.p->tableType))
8078  {
8079  jam();
8080  TabRecordPtr primTabPtr;
8081  primTabPtr.i = tabPtr.p->primaryTableId;
8082  ptrCheckGuard(primTabPtr, ctabFileSize, tabRecord);
8083  newValue = primTabPtr.p->m_map_ptr_i;
8084  }
8085  else
8086  {
8087  jam();
8088  newValue = connectPtr.p->m_create.m_map_ptr_i;
8089  }
8090 
8091  tabPtr.p->m_map_ptr_i = newValue;
8092  }
8093  // Release
8094  ndbrequire(tabPtr.p->connectrec == connectPtr.i);
8095  tabPtr.p->connectrec = RNIL;
8096  release_connect(connectPtr);
8097  }
8098 
8099 }
8100 void
8101 Dbdih::release_connect(ConnectRecordPtr ptr)
8102 {
8103  TabRecordPtr tabPtr;
8104  tabPtr.i = ptr.p->table;
8105  if (tabPtr.i != RNIL)
8106  {
8107  jam();
8108  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
8109  if (tabPtr.p->connectrec == ptr.i)
8110  {
8111  ndbassert(false); // should be fixed elsewhere
8112  tabPtr.p->connectrec = RNIL;
8113  }
8114  }
8115 
8116  ptr.p->table = RNIL;
8117  ptr.p->userblockref = ZNIL;
8118  ptr.p->userpointer = RNIL;
8119  ptr.p->connectState = ConnectRecord::FREE;
8120  ptr.p->nextPool = cfirstconnect;
8121  cfirstconnect = ptr.i;
8122 }
8123 
8124 void
8125 Dbdih::execADD_FRAGCONF(Signal* signal){
8126  jamEntry();
8127  AddFragConf * const conf = (AddFragConf*)signal->getDataPtr();
8128 
8129  ConnectRecordPtr connectPtr;
8130  connectPtr.i = conf->dihPtr;
8131  ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
8132 
8133  TabRecordPtr tabPtr;
8134  tabPtr.i = connectPtr.p->table;
8135  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
8136 
8137  sendAddFragreq(signal, connectPtr, tabPtr, conf->fragId + 1);
8138 }
8139 
8140 void
8141 Dbdih::execADD_FRAGREF(Signal* signal){
8142  jamEntry();
8143  AddFragRef * const ref = (AddFragRef*)signal->getDataPtr();
8144 
8145  ConnectRecordPtr connectPtr;
8146  connectPtr.i = ref->dihPtr;
8147  ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
8148 
8149  if (connectPtr.p->connectState == ConnectRecord::ALTER_TABLE)
8150  {
8151  jam();
8152 
8153  connectPtr.p->connectState = ConnectRecord::ALTER_TABLE_ABORT;
8154  drop_fragments(signal, connectPtr, connectPtr.p->m_alter.m_totalfragments);
8155  return;
8156  }
8157  else
8158  {
8159  DiAddTabRef * const ref = (DiAddTabRef*)signal->getDataPtr();
8160  ref->senderData = connectPtr.p->userpointer;
8161  ref->errorCode = ~0;
8162  sendSignal(connectPtr.p->userblockref, GSN_DIADDTABREF, signal,
8163  DiAddTabRef::SignalLength, JBB);
8164 
8165  // Release
8166  Ptr<TabRecord> tabPtr;
8167  tabPtr.i = connectPtr.p->table;
8168  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
8169  ndbrequire(tabPtr.p->connectrec == connectPtr.i);
8170  tabPtr.p->connectrec = RNIL;
8171  release_connect(connectPtr);
8172  }
8173 }
8174 
8175 /*
8176  3.7.1.3 R E F U S E
8177  *********************
8178  */
8179 void
8180 Dbdih::addtabrefuseLab(Signal* signal,
8181  ConnectRecordPtr connectPtr, Uint32 errorCode)
8182 {
8183  signal->theData[0] = connectPtr.p->userpointer;
8184  signal->theData[1] = errorCode;
8185  sendSignal(connectPtr.p->userblockref, GSN_DIADDTABREF, signal, 2, JBB);
8186 
8187  Ptr<TabRecord> tabPtr;
8188  tabPtr.i = connectPtr.p->table;
8189  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
8190  ndbrequire(tabPtr.p->connectrec == connectPtr.i);
8191  tabPtr.p->connectrec = RNIL;
8192 
8193  release_connect(connectPtr);
8194  return;
8195 }//Dbdih::addtabrefuseLab()
8196 
8197 /*
8198  3.7.2 A D D T A B L E D U P L I C A T I O N
8199  *************************************************
8200  */
8201 /*
8202  3.7.2.1 A D D T A B L E D U P L I C A T I O N R E Q U E S T
8203  *******************************************************************=
8204  */
8205 
8206 /*
8207  D E L E T E T A B L E
8208  **********************=
8209  */
8210 /*****************************************************************************/
8211 /*********** DELETE TABLE MODULE *************/
8212 /*****************************************************************************/
8213 void
8214 Dbdih::execDROP_TAB_REQ(Signal* signal)
8215 {
8216  jamEntry();
8217  DropTabReq* req = (DropTabReq*)signal->getDataPtr();
8218 
8219  TabRecordPtr tabPtr;
8220  tabPtr.i = req->tableId;
8221  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
8222 
8223  tabPtr.p->m_dropTab.tabUserRef = req->senderRef;
8224  tabPtr.p->m_dropTab.tabUserPtr = req->senderData;
8225 
8226  DropTabReq::RequestType rt = (DropTabReq::RequestType)req->requestType;
8227 
8228  switch(rt){
8229  case DropTabReq::OnlineDropTab:
8230  jam();
8231  ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_DROPPING);
8232  break;
8233  case DropTabReq::CreateTabDrop:
8234  jam();
8235  break;
8236  case DropTabReq::RestartDropTab:
8237  break;
8238  }
8239 
8240  if(isMaster())
8241  {
8245  NodeRecordPtr nodePtr;
8246  for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
8247  jam();
8248  ptrAss(nodePtr, nodeRecord);
8249  if (c_lcpState.m_participatingLQH.get(nodePtr.i))
8250  {
8251 
8252  Uint32 index = 0;
8253  Uint32 count = nodePtr.p->noOfQueuedChkpt;
8254  while(index < count){
8255  if(nodePtr.p->queuedChkpt[index].tableId == tabPtr.i){
8256  jam();
8257  // g_eventLogger->info("Unqueuing %d", index);
8258 
8259  count--;
8260  for(Uint32 i = index; i<count; i++){
8261  jam();
8262  nodePtr.p->queuedChkpt[i] = nodePtr.p->queuedChkpt[i + 1];
8263  }
8264  } else {
8265  index++;
8266  }
8267  }
8268  nodePtr.p->noOfQueuedChkpt = count;
8269  }
8270  }
8271  }
8272 
8273  {
8277  bool ok = false;
8278  switch(tabPtr.p->tabLcpStatus){
8279  case TabRecord::TLS_COMPLETED:
8280  case TabRecord::TLS_WRITING_TO_FILE:
8281  ok = true;
8282  jam();
8283  break;
8284  return;
8285  case TabRecord::TLS_ACTIVE:
8286  ok = true;
8287  jam();
8288 
8289  tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
8290 
8294  if (checkLcpAllTablesDoneInLqh(__LINE__))
8295  {
8296  jam();
8297 
8298  g_eventLogger->info("This is the last table");
8299 
8303  LcpStatus a = c_lcpState.lcpStatus;
8304  checkLcpCompletedLab(signal);
8305 
8306  if(a != c_lcpState.lcpStatus)
8307  {
8308  g_eventLogger->info("And all tables are written to already written disk");
8309  }
8310  }
8311  break;
8312  }
8313  ndbrequire(ok);
8314  }
8315 
8316  waitDropTabWritingToFile(signal, tabPtr);
8317 }
8318 
8319 void Dbdih::startDeleteFile(Signal* signal, TabRecordPtr tabPtr)
8320 {
8321  if (tabPtr.p->tabFile[0] == RNIL) {
8322  jam();
8323  initTableFile(tabPtr);
8324  }//if
8325  openTableFileForDelete(signal, tabPtr.p->tabFile[0]);
8326 }//Dbdih::startDeleteFile()
8327 
8328 void Dbdih::openTableFileForDelete(Signal* signal, Uint32 fileIndex)
8329 {
8330  FileRecordPtr filePtr;
8331  filePtr.i = fileIndex;
8332  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
8333  openFileRw(signal, filePtr);
8334  filePtr.p->reqStatus = FileRecord::TABLE_OPEN_FOR_DELETE;
8335 }//Dbdih::openTableFileForDelete()
8336 
8337 void Dbdih::tableOpenLab(Signal* signal, FileRecordPtr filePtr)
8338 {
8339  closeFileDelete(signal, filePtr);
8340  filePtr.p->reqStatus = FileRecord::TABLE_CLOSE_DELETE;
8341  return;
8342 }//Dbdih::tableOpenLab()
8343 
8344 void Dbdih::tableDeleteLab(Signal* signal, FileRecordPtr filePtr)
8345 {
8346  TabRecordPtr tabPtr;
8347  tabPtr.i = filePtr.p->tabRef;
8348  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
8349  if (filePtr.i == tabPtr.p->tabFile[0]) {
8350  jam();
8351  openTableFileForDelete(signal, tabPtr.p->tabFile[1]);
8352  return;
8353  }//if
8354  ndbrequire(filePtr.i == tabPtr.p->tabFile[1]);
8355 
8356  releaseFile(tabPtr.p->tabFile[0]);
8357  releaseFile(tabPtr.p->tabFile[1]);
8358  tabPtr.p->tabFile[0] = tabPtr.p->tabFile[1] = RNIL;
8359 
8360  tabPtr.p->tabStatus = TabRecord::TS_IDLE;
8361 
8362  DropTabConf * const dropConf = (DropTabConf *)signal->getDataPtrSend();
8363  dropConf->senderRef = reference();
8364  dropConf->senderData = tabPtr.p->m_dropTab.tabUserPtr;
8365  dropConf->tableId = tabPtr.i;
8366  sendSignal(tabPtr.p->m_dropTab.tabUserRef, GSN_DROP_TAB_CONF,
8367  signal, DropTabConf::SignalLength, JBB);
8368 
8369  tabPtr.p->m_dropTab.tabUserPtr = RNIL;
8370  tabPtr.p->m_dropTab.tabUserRef = 0;
8371  releaseTable(tabPtr);
8372 }//Dbdih::tableDeleteLab()
8373 
8374 
8375 void Dbdih::releaseTable(TabRecordPtr tabPtr)
8376 {
8377  FragmentstorePtr fragPtr;
8378  if (tabPtr.p->noOfFragChunks > 0) {
8379  for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
8380  jam();
8381  getFragstore(tabPtr.p, fragId, fragPtr);
8382  dec_ng_refcount(getNodeGroup(fragPtr.p->preferredPrimary));
8383  releaseReplicas(& fragPtr.p->storedReplicas);
8384  releaseReplicas(& fragPtr.p->oldStoredReplicas);
8385  }//for
8386  releaseFragments(tabPtr);
8387  }
8388  if (tabPtr.p->tabFile[0] != RNIL) {
8389  jam();
8390  releaseFile(tabPtr.p->tabFile[0]);
8391  releaseFile(tabPtr.p->tabFile[1]);
8392  tabPtr.p->tabFile[0] = tabPtr.p->tabFile[1] = RNIL;
8393  }//if
8394 }//Dbdih::releaseTable()
8395 
8396 void Dbdih::releaseReplicas(Uint32 * replicaPtrI)
8397 {
8398  ReplicaRecordPtr replicaPtr;
8399  replicaPtr.i = * replicaPtrI;
8400  jam();
8401  while (replicaPtr.i != RNIL) {
8402  jam();
8403  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
8404  Uint32 tmp = replicaPtr.p->nextReplica;
8405  replicaPtr.p->nextReplica = cfirstfreeReplica;
8406  cfirstfreeReplica = replicaPtr.i;
8407  replicaPtr.i = tmp;
8408  cnoFreeReplicaRec++;
8409  }//while
8410 
8411  * replicaPtrI = RNIL;
8412 }//Dbdih::releaseReplicas()
8413 
8414 void Dbdih::seizeReplicaRec(ReplicaRecordPtr& replicaPtr)
8415 {
8416  replicaPtr.i = cfirstfreeReplica;
8417  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
8418  cfirstfreeReplica = replicaPtr.p->nextReplica;
8419  cnoFreeReplicaRec--;
8420  replicaPtr.p->nextReplica = RNIL;
8421 }//Dbdih::seizeReplicaRec()
8422 
8423 void Dbdih::releaseFile(Uint32 fileIndex)
8424 {
8425  FileRecordPtr filePtr;
8426  filePtr.i = fileIndex;
8427  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
8428  filePtr.p->nextFile = cfirstfreeFile;
8429  cfirstfreeFile = filePtr.i;
8430 }//Dbdih::releaseFile()
8431 
8432 
8433 void Dbdih::execALTER_TAB_REQ(Signal * signal)
8434 {
8435  const AlterTabReq* req = (const AlterTabReq*)signal->getDataPtr();
8436  const Uint32 senderRef = req->senderRef;
8437  const Uint32 senderData = req->senderData;
8438  const Uint32 tableId = req->tableId;
8439  const Uint32 tableVersion = req->tableVersion;
8440  const Uint32 newTableVersion = req->newTableVersion;
8441  AlterTabReq::RequestType requestType =
8442  (AlterTabReq::RequestType) req->requestType;
8443 
8444  TabRecordPtr tabPtr;
8445  tabPtr.i = tableId;
8446  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
8447 
8448  switch(requestType){
8449  case AlterTabReq::AlterTablePrepare:
8450  jam();
8451  // fall through
8452  case AlterTabReq::AlterTableRevert:
8453  jam();
8454  if (AlterTableReq::getAddFragFlag(req->changeMask) &&
8455  tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE)
8456  {
8457  jam();
8458  SectionHandle handle(this, signal);
8459  sendSignalWithDelay(reference(), GSN_ALTER_TAB_REQ, signal, 100,
8460  signal->getLength(), &handle);
8461  return;
8462  }
8463  case AlterTabReq::AlterTableCommit:
8464  jam();
8465  case AlterTabReq::AlterTableComplete:
8466  jam();
8467  case AlterTabReq::AlterTableWaitScan:
8468  jam();
8469  break;
8470  default:
8471  jamLine(requestType);
8472  }
8473 
8474  ConnectRecordPtr connectPtr;
8475  connectPtr.i = RNIL;
8476  switch (requestType) {
8477  case AlterTabReq::AlterTablePrepare:
8478  jam();
8479 
8480  ndbrequire(cfirstconnect != RNIL);
8481  connectPtr.i = cfirstconnect;
8482  ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
8483  cfirstconnect = connectPtr.p->nextPool;
8484 
8485  connectPtr.p->m_alter.m_totalfragments = tabPtr.p->totalfragments;
8486  connectPtr.p->m_alter.m_org_totalfragments = tabPtr.p->totalfragments;
8487  connectPtr.p->m_alter.m_changeMask = req->changeMask;
8488  connectPtr.p->m_alter.m_new_map_ptr_i = req->new_map_ptr_i;
8489  connectPtr.p->userpointer = senderData;
8490  connectPtr.p->userblockref = senderRef;
8491  connectPtr.p->connectState = ConnectRecord::ALTER_TABLE;
8492  connectPtr.p->table = tabPtr.i;
8493  tabPtr.p->connectrec = connectPtr.i;
8494  break;
8495  case AlterTabReq::AlterTableRevert:
8496  jam();
8497  tabPtr.p->schemaVersion = tableVersion;
8498 
8499  connectPtr.i = req->connectPtr;
8500  ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
8501 
8502  ndbrequire(connectPtr.p->connectState == ConnectRecord::ALTER_TABLE);
8503 
8504  connectPtr.p->userpointer = senderData;
8505  connectPtr.p->userblockref = senderRef;
8506 
8507  if (AlterTableReq::getAddFragFlag(req->changeMask))
8508  {
8509  jam();
8510  tabPtr.p->tabCopyStatus = TabRecord::CS_ALTER_TABLE;
8511  connectPtr.p->connectState = ConnectRecord::ALTER_TABLE_REVERT;
8512  drop_fragments(signal, connectPtr,
8513  connectPtr.p->m_alter.m_totalfragments);
8514  return;
8515  }
8516 
8517  send_alter_tab_conf(signal, connectPtr);
8518 
8519  ndbrequire(tabPtr.p->connectrec == connectPtr.i);
8520  tabPtr.p->connectrec = RNIL;
8521  release_connect(connectPtr);
8522  return;
8523  break;
8524  case AlterTabReq::AlterTableCommit:
8525  jam();
8526  tabPtr.p->schemaVersion = newTableVersion;
8527 
8528  connectPtr.i = req->connectPtr;
8529  ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
8530  connectPtr.p->userpointer = senderData;
8531  connectPtr.p->userblockref = senderRef;
8532  ndbrequire(connectPtr.p->connectState == ConnectRecord::ALTER_TABLE);
8533 
8534  tabPtr.p->totalfragments = connectPtr.p->m_alter.m_totalfragments;
8535  if (AlterTableReq::getReorgFragFlag(connectPtr.p->m_alter.m_changeMask))
8536  {
8537  jam();
8538  DIH_TAB_WRITE_LOCK(tabPtr.p);
8539  Uint32 save = tabPtr.p->m_map_ptr_i;
8540  tabPtr.p->m_map_ptr_i = tabPtr.p->m_new_map_ptr_i;
8541  tabPtr.p->m_new_map_ptr_i = save;
8542 
8543  for (Uint32 i = 0; i<tabPtr.p->totalfragments; i++)
8544  {
8545  jam();
8546  FragmentstorePtr fragPtr;
8547  getFragstore(tabPtr.p, i, fragPtr);
8548  fragPtr.p->distributionKey = (fragPtr.p->distributionKey + 1) & 0xFF;
8549  }
8550  DIH_TAB_WRITE_UNLOCK(tabPtr.p);
8551 
8552  ndbassert(tabPtr.p->m_scan_count[1] == 0);
8553  tabPtr.p->m_scan_count[1] = tabPtr.p->m_scan_count[0];
8554  tabPtr.p->m_scan_count[0] = 0;
8555  tabPtr.p->m_scan_reorg_flag = 1;
8556 
8557  send_alter_tab_conf(signal, connectPtr);
8558  return;
8559  }
8560 
8561  send_alter_tab_conf(signal, connectPtr);
8562  ndbrequire(tabPtr.p->connectrec == connectPtr.i);
8563  tabPtr.p->connectrec = RNIL;
8564  release_connect(connectPtr);
8565  return;
8566  case AlterTabReq::AlterTableComplete:
8567  jam();
8568  connectPtr.i = req->connectPtr;
8569  ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
8570  connectPtr.p->userpointer = senderData;
8571  connectPtr.p->userblockref = senderRef;
8572 
8573  send_alter_tab_conf(signal, connectPtr);
8574 
8575  DIH_TAB_WRITE_LOCK(tabPtr.p);
8576  tabPtr.p->m_new_map_ptr_i = RNIL;
8577  tabPtr.p->m_scan_reorg_flag = 0;
8578  DIH_TAB_WRITE_UNLOCK(tabPtr.p);
8579 
8580  ndbrequire(tabPtr.p->connectrec == connectPtr.i);
8581  tabPtr.p->connectrec = RNIL;
8582  release_connect(connectPtr);
8583  return;
8584  case AlterTabReq::AlterTableWaitScan:{
8585  jam();
8586  Uint64 now = NdbTick_CurrentMillisecond();
8587  now /= 1000;
8588  signal->theData[0] = DihContinueB::ZWAIT_OLD_SCAN;
8589  signal->theData[1] = tabPtr.i;
8590  signal->theData[2] = senderRef;
8591  signal->theData[3] = senderData;
8592  signal->theData[4] = connectPtr.i;
8593  signal->theData[5] = Uint32(now >> 32);
8594  signal->theData[6] = Uint32(now);
8595  signal->theData[7] = 3;
8596  sendSignal(reference(), GSN_CONTINUEB, signal, 8, JBB);
8597  return;
8598  }
8599  default:
8600  ndbrequire(false);
8601  break;
8602  }
8603 
8604  if (AlterTableReq::getAddFragFlag(req->changeMask))
8605  {
8606  jam();
8607  SegmentedSectionPtr ptr;
8608  SectionHandle handle(this, signal);
8609  handle.getSection(ptr, 0);
8610  union {
8611  Uint16 buf[2+2*MAX_NDB_PARTITIONS];
8612  Uint32 _align[1];
8613  };
8614  copy(_align, ptr);
8615  releaseSections(handle);
8616  Uint32 err;
8617  Uint32 save = tabPtr.p->totalfragments;
8618  if ((err = add_fragments_to_table(tabPtr, buf)))
8619  {
8620  jam();
8621  ndbrequire(tabPtr.p->totalfragments == save);
8622  ndbrequire(connectPtr.p->m_alter.m_org_totalfragments == save);
8623  send_alter_tab_ref(signal, tabPtr, connectPtr, err);
8624 
8625  ndbrequire(tabPtr.p->connectrec == connectPtr.i);
8626  tabPtr.p->connectrec = RNIL;
8627  release_connect(connectPtr);
8628  return;
8629  }
8630 
8631  tabPtr.p->tabCopyStatus = TabRecord::CS_ALTER_TABLE;
8632  connectPtr.p->m_alter.m_totalfragments = tabPtr.p->totalfragments;
8633  tabPtr.p->totalfragments = save; // Dont make the available yet...
8634  sendAddFragreq(signal, connectPtr, tabPtr,
8635  connectPtr.p->m_alter.m_org_totalfragments);
8636  return;
8637  }
8638 
8639  send_alter_tab_conf(signal, connectPtr);
8640 }
8641 
8642 Uint32
8643 Dbdih::add_fragments_to_table(Ptr<TabRecord> tabPtr, const Uint16 buf[])
8644 {
8645  Uint32 replicas = buf[0];
8646  Uint32 cnt = buf[1];
8647 
8648  Uint32 i = 0;
8649  Uint32 err = 0;
8650  Uint32 current = tabPtr.p->totalfragments;
8651  for (i = 0; i<cnt; i++)
8652  {
8653  FragmentstorePtr fragPtr;
8654  if (ERROR_INSERTED(7212) && cnt)
8655  {
8656  err = 1;
8657  CLEAR_ERROR_INSERT_VALUE;
8658  goto error;
8659  }
8660 
8661  if ((err = add_fragment_to_table(tabPtr, current + i, fragPtr)))
8662  goto error;
8663 
8664  fragPtr.p->m_log_part_id = buf[2+(1 + replicas)*i];
8665  fragPtr.p->preferredPrimary = buf[2+(1 + replicas)*i + 1];
8666 
8667  inc_ng_refcount(getNodeGroup(fragPtr.p->preferredPrimary));
8668 
8669  Uint32 activeIndex = 0;
8670  for (Uint32 j = 0; j<replicas; j++)
8671  {
8672  const Uint32 nodeId = buf[2+(1 + replicas)*i + 1 + j];
8673  ReplicaRecordPtr replicaPtr;
8674  allocStoredReplica(fragPtr, replicaPtr, nodeId);
8675  if (getNodeStatus(nodeId) == NodeRecord::ALIVE) {
8676  jam();
8677  ndbrequire(activeIndex < MAX_REPLICAS);
8678  fragPtr.p->activeNodes[activeIndex] = nodeId;
8679  activeIndex++;
8680  } else {
8681  jam();
8682  removeStoredReplica(fragPtr, replicaPtr);
8683  linkOldStoredReplica(fragPtr, replicaPtr);
8684  }
8685  }
8686  fragPtr.p->fragReplicas = activeIndex;
8687  }
8688 
8689  return 0;
8690 error:
8691  for(i = i + current; i != current; i--)
8692  {
8693  release_fragment_from_table(tabPtr, i);
8694  }
8695 
8696  return err;
8697 }
8698 
8699 void
8700 Dbdih::wait_old_scan(Signal* signal)
8701 {
8702  jam();
8703 
8704  TabRecordPtr tabPtr;
8705  tabPtr.i = signal->theData[1];
8706  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
8707 
8708  if (tabPtr.p->m_scan_count[1] == 0)
8709  {
8710  jam();
8711  Uint32 senderRef = signal->theData[2];
8712  Uint32 senderData = signal->theData[3];
8713  Uint32 connectPtrI = signal->theData[4];
8714 
8715  AlterTabConf* conf = (AlterTabConf*)signal->getDataPtrSend();
8716  conf->senderRef = reference();
8717  conf->senderData = senderData;
8718  conf->connectPtr = connectPtrI;
8719  sendSignal(senderRef, GSN_ALTER_TAB_CONF, signal,
8720  AlterTabConf::SignalLength, JBB);
8721  return;
8722  }
8723 
8724  Uint32 start_hi = signal->theData[5];
8725  Uint32 start_lo = signal->theData[6];
8726  Uint64 start = (Uint64(start_hi) << 32) + start_lo;
8727  Uint32 wait = signal->theData[7];
8728  Uint64 now = NdbTick_CurrentMillisecond() / 1000;
8729  if (now > start + wait)
8730  {
8731  infoEvent("Waiting(%u) for scans(%u) to complete on table %u",
8732  Uint32(now - start),
8733  tabPtr.p->m_scan_count[1],
8734  tabPtr.i);
8735 
8736  if (wait == 3)
8737  {
8738  signal->theData[7] = 3 + 7;
8739  }
8740  else
8741  {
8742  signal->theData[7] = 2 * wait;
8743  }
8744  }
8745 
8746  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 7);
8747 }
8748 
8749 Uint32
8750 Dbdih::add_fragment_to_table(Ptr<TabRecord> tabPtr,
8751  Uint32 fragId,
8752  Ptr<Fragmentstore>& fragPtr)
8753 {
8754  Uint32 fragments = tabPtr.p->totalfragments;
8755  Uint32 chunks = tabPtr.p->noOfFragChunks;
8756 
8757  ndbrequire(fragId == fragments); // Only add at the end
8758 
8759  if (ERROR_INSERTED(7211))
8760  {
8761  CLEAR_ERROR_INSERT_VALUE;
8762  return 1;
8763  }
8764 
8765  Uint32 allocated = chunks << LOG_NO_OF_FRAGS_PER_CHUNK;
8766  if (fragId < allocated)
8767  {
8768  jam();
8769  tabPtr.p->totalfragments++;
8770  getFragstore(tabPtr.p, fragId, fragPtr);
8771  return 0;
8772  }
8773 
8777  fragPtr.i = cfirstfragstore;
8778  if (fragPtr.i == RNIL)
8779  {
8780  jam();
8781  return -1;
8782  }
8783 
8784  ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
8785  cfirstfragstore = fragPtr.p->nextFragmentChunk;
8786  ndbrequire(cremainingfrags >= NO_OF_FRAGS_PER_CHUNK);
8787  cremainingfrags -= NO_OF_FRAGS_PER_CHUNK;
8788 
8789  ndbrequire(chunks < NDB_ARRAY_SIZE(tabPtr.p->startFid));
8790  tabPtr.p->startFid[chunks] = fragPtr.i;
8791  for (Uint32 i = 0; i<NO_OF_FRAGS_PER_CHUNK; i++)
8792  {
8793  jam();
8794  Ptr<Fragmentstore> tmp;
8795  tmp.i = fragPtr.i + i;
8796  ptrCheckGuard(tmp, cfragstoreFileSize, fragmentstore);
8797  initFragstore(tmp);
8798  }
8799 
8800  tabPtr.p->totalfragments++;
8801  tabPtr.p->noOfFragChunks++;
8802 
8803  return 0;
8804 }
8805 
8806 void
8807 Dbdih::release_fragment_from_table(Ptr<TabRecord> tabPtr, Uint32 fragId)
8808 {
8809  FragmentstorePtr fragPtr;
8810  Uint32 fragments = tabPtr.p->totalfragments;
8811  Uint32 chunks = tabPtr.p->noOfFragChunks;
8812 
8813  if (fragId >= fragments)
8814  {
8815  jam();
8816  return;
8817  }
8818  ndbrequire(fragId == fragments - 1); // only remove at end
8819  ndbrequire(fragments != 0);
8820 
8821  getFragstore(tabPtr.p, fragId, fragPtr);
8822  dec_ng_refcount(getNodeGroup(fragPtr.p->preferredPrimary));
8823 
8824  releaseReplicas(& fragPtr.p->storedReplicas);
8825  releaseReplicas(& fragPtr.p->oldStoredReplicas);
8826 
8827  if (fragId == ((chunks - 1) << LOG_NO_OF_FRAGS_PER_CHUNK))
8828  {
8829  jam();
8830 
8831  getFragstore(tabPtr.p, fragId, fragPtr);
8832 
8833  fragPtr.p->nextFragmentChunk = cfirstfragstore;
8834  cfirstfragstore = fragPtr.i;
8835  cremainingfrags += NO_OF_FRAGS_PER_CHUNK;
8836  tabPtr.p->noOfFragChunks = chunks - 1;
8837  }
8838 
8839  tabPtr.p->totalfragments--;
8840 }
8841 
8842 void
8843 Dbdih::send_alter_tab_ref(Signal* signal,
8844  Ptr<TabRecord> tabPtr,
8845  Ptr<ConnectRecord> connectPtr,
8846  Uint32 errCode)
8847 {
8848  AlterTabRef* ref = (AlterTabRef*)signal->getDataPtrSend();
8849  ref->senderRef = reference();
8850  ref->senderData = connectPtr.p->userpointer;
8851  ref->errorCode = errCode;
8852  sendSignal(connectPtr.p->userblockref, GSN_ALTER_TAB_REF, signal,
8853  AlterTabRef::SignalLength, JBB);
8854 }
8855 
8856 void
8857 Dbdih::send_alter_tab_conf(Signal* signal, Ptr<ConnectRecord> connectPtr)
8858 {
8859  AlterTabConf* conf = (AlterTabConf*)signal->getDataPtrSend();
8860  conf->senderRef = reference();
8861  conf->senderData = connectPtr.p->userpointer;
8862  conf->connectPtr = connectPtr.i;
8863  sendSignal(connectPtr.p->userblockref, GSN_ALTER_TAB_CONF, signal,
8864  AlterTabConf::SignalLength, JBB);
8865 }
8866 
8867 void
8868 Dbdih::saveTableFile(Signal* signal,
8869  Ptr<ConnectRecord> connectPtr,
8870  Ptr<TabRecord> tabPtr,
8871  TabRecord::CopyStatus expectedStatus,
8872  Callback& cb)
8873 {
8874  ndbrequire(connectPtr.i == cb.m_callbackData); // required
8875  ndbrequire(tabPtr.p->tabCopyStatus == expectedStatus); // locking
8876  memcpy(&connectPtr.p->m_callback, &cb, sizeof(Callback));
8877 
8878  tabPtr.p->tabCopyStatus = TabRecord::CS_COPY_TO_SAVE;
8879  tabPtr.p->tabUpdateState = TabRecord::US_CALLBACK;
8880  signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
8881  signal->theData[1] = tabPtr.i;
8882  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
8883 }
8884 
8885 void
8886 Dbdih::alter_table_writeTable_conf(Signal* signal, Uint32 ptrI, Uint32 err)
8887 {
8888  jamEntry();
8889  ndbrequire(err == 0);
8890 
8891  ConnectRecordPtr connectPtr;
8892  connectPtr.i = ptrI;
8893  ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
8894 
8895  switch(connectPtr.p->connectState){
8896  case ConnectRecord::ALTER_TABLE_REVERT:
8897  {
8898  jam();
8899  send_alter_tab_conf(signal, connectPtr);
8900 
8901  Ptr<TabRecord> tabPtr;
8902  tabPtr.i = connectPtr.p->table;
8903  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
8904  ndbrequire(tabPtr.p->connectrec == connectPtr.i);
8905  tabPtr.p->connectrec = RNIL;
8906  release_connect(connectPtr);
8907  return;
8908  }
8909  case ConnectRecord::ALTER_TABLE:
8910  {
8911  jam();
8912  send_alter_tab_conf(signal, connectPtr);
8913  return;
8914  }
8915  default:
8916  jamLine(connectPtr.p->connectState);
8917  ndbrequire(false);
8918  }
8919 }
8920 
8921 void
8922 Dbdih::drop_fragments(Signal* signal, Ptr<ConnectRecord> connectPtr,
8923  Uint32 curr)
8924 {
8925  ndbrequire(curr >= connectPtr.p->m_alter.m_org_totalfragments);
8926  if (curr == connectPtr.p->m_alter.m_org_totalfragments)
8927  {
8931  jam();
8932  Ptr<TabRecord> tabPtr;
8933  tabPtr.i = connectPtr.p->table;
8934  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
8935 
8936  Uint32 new_frags = connectPtr.p->m_alter.m_totalfragments;
8937  Uint32 org_frags = connectPtr.p->m_alter.m_org_totalfragments;
8938  tabPtr.p->totalfragments = new_frags;
8939  for (Uint32 i = new_frags - 1; i >= org_frags; i--)
8940  {
8941  jam();
8942  release_fragment_from_table(tabPtr, i);
8943  }
8944  connectPtr.p->m_alter.m_totalfragments = org_frags;
8945 
8946  switch(connectPtr.p->connectState){
8947  case ConnectRecord::ALTER_TABLE_ABORT:
8948  {
8949  jam();
8950  ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_ALTER_TABLE);
8951  tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
8952  send_alter_tab_ref(signal, tabPtr, connectPtr, ~0);
8953 
8954  connectPtr.p->connectState = ConnectRecord::ALTER_TABLE;
8955  return;
8956  }
8957  case ConnectRecord::ALTER_TABLE_REVERT:
8958  {
8959  jam();
8960  Callback cb;
8961  cb.m_callbackData = connectPtr.i;
8962  cb.m_callbackFunction = safe_cast(&Dbdih::alter_table_writeTable_conf);
8963  saveTableFile(signal, connectPtr, tabPtr, TabRecord::CS_ALTER_TABLE, cb);
8964  return;
8965  }
8966  default:
8967  jamLine(connectPtr.p->connectState);
8968  ndbrequire(false);
8969  }
8970  return;
8971  }
8972 
8973  ndbrequire(curr > 0);
8974  DropFragReq* req = (DropFragReq*)signal->getDataPtrSend();
8975  req->senderRef = reference();
8976  req->senderData = connectPtr.i;
8977  req->tableId = connectPtr.p->table;
8978  req->fragId = curr - 1;
8979  req->requestInfo = DropFragReq::AlterTableAbort;
8980  sendSignal(DBLQH_REF, GSN_DROP_FRAG_REQ, signal,
8981  DropFragReq::SignalLength, JBB);
8982 }
8983 
8984 void
8985 Dbdih::execDROP_FRAG_REF(Signal* signal)
8986 {
8987  ndbrequire(false);
8988 }
8989 
8990 void
8991 Dbdih::execDROP_FRAG_CONF(Signal* signal)
8992 {
8993  DropFragConf* conf = (DropFragConf*)signal->getDataPtr();
8994 
8995  ConnectRecordPtr connectPtr;
8996  connectPtr.i = conf->senderData;
8997  ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
8998 
8999  drop_fragments(signal, connectPtr, conf->fragId);
9000 }
9001 
9002 /*
9003  G E T N O D E S
9004  **********************=
9005  */
9006 /*****************************************************************************/
9007 /* ********** TRANSACTION HANDLING MODULE *************/
9008 /*****************************************************************************/
9009 /*
9010  3.8.1 G E T N O D E S R E Q U E S T
9011  ******************************************
9012  Asks what nodes should be part of a transaction.
9013 */
9014 void Dbdih::execDIGETNODESREQ(Signal* signal)
9015 {
9016  const DiGetNodesReq * const req = (DiGetNodesReq *)&signal->theData[0];
9017  FragmentstorePtr fragPtr;
9018  TabRecordPtr tabPtr;
9019  tabPtr.i = req->tableId;
9020  Uint32 hashValue = req->hashValue;
9021  Uint32 ttabFileSize = ctabFileSize;
9022  Uint32 fragId, newFragId = RNIL;
9023  DiGetNodesConf * const conf = (DiGetNodesConf *)&signal->theData[0];
9024  TabRecord* regTabDesc = tabRecord;
9025  EmulatedJamBuffer * jambuf = * (EmulatedJamBuffer**)(req->jamBuffer);
9026  thrjamEntry(jambuf);
9027  ptrCheckGuard(tabPtr, ttabFileSize, regTabDesc);
9028 
9029  if (DictTabInfo::isOrderedIndex(tabPtr.p->tableType))
9030  {
9031  thrjam(jambuf);
9032  tabPtr.i = tabPtr.p->primaryTableId;
9033  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9034  }
9035 
9036 loop:
9037  Uint32 val = tabPtr.p->m_lock.read_lock();
9038  Uint32 map_ptr_i = tabPtr.p->m_map_ptr_i;
9039  Uint32 new_map_ptr_i = tabPtr.p->m_new_map_ptr_i;
9040 
9041  /* When distr key indicator is set, regardless
9042  * of distribution algorithm in use, hashValue
9043  * IS fragment id.
9044  */
9045  if (req->distr_key_indicator)
9046  {
9047  fragId = hashValue;
9048  if (unlikely(fragId >= tabPtr.p->totalfragments))
9049  {
9050  thrjam(jambuf);
9051  conf->zero= 1; //Indicate error;
9052  signal->theData[1]= ZUNDEFINED_FRAGMENT_ERROR;
9053  return;
9054  }
9055  }
9056  else if (tabPtr.p->method == TabRecord::HASH_MAP)
9057  {
9058  thrjam(jambuf);
9060  g_hash_map.getPtr(ptr, map_ptr_i);
9061  fragId = ptr.p->m_map[hashValue % ptr.p->m_cnt];
9062 
9063  if (unlikely(new_map_ptr_i != RNIL))
9064  {
9065  thrjam(jambuf);
9066  g_hash_map.getPtr(ptr, new_map_ptr_i);
9067  newFragId = ptr.p->m_map[hashValue % ptr.p->m_cnt];
9068  if (newFragId == fragId)
9069  {
9070  thrjam(jambuf);
9071  newFragId = RNIL;
9072  }
9073  }
9074  }
9075  else if (tabPtr.p->method == TabRecord::LINEAR_HASH)
9076  {
9077  thrjam(jambuf);
9078  fragId = hashValue & tabPtr.p->mask;
9079  if (fragId < tabPtr.p->hashpointer) {
9080  thrjam(jambuf);
9081  fragId = hashValue & ((tabPtr.p->mask << 1) + 1);
9082  }//if
9083  }
9084  else if (tabPtr.p->method == TabRecord::NORMAL_HASH)
9085  {
9086  thrjam(jambuf);
9087  fragId= hashValue % tabPtr.p->totalfragments;
9088  }
9089  else
9090  {
9091  thrjam(jambuf);
9092  ndbassert(tabPtr.p->method == TabRecord::USER_DEFINED);
9093 
9094  /* User defined partitioning, but no distribution key passed */
9095  conf->zero= 1; //Indicate error;
9096  signal->theData[1]= ZUNDEFINED_FRAGMENT_ERROR;
9097  return;
9098  }
9099  getFragstore(tabPtr.p, fragId, fragPtr);
9100  Uint32 nodeCount = extractNodeInfo(fragPtr.p, conf->nodes);
9101  Uint32 sig2 = (nodeCount - 1) +
9102  (fragPtr.p->distributionKey << 16) +
9103  (dihGetInstanceKey(fragPtr) << 24);
9104  conf->zero = 0;
9105  conf->reqinfo = sig2;
9106  conf->fragId = fragId;
9107 
9108  if (unlikely(newFragId != RNIL))
9109  {
9110  thrjam(jambuf);
9111  conf->reqinfo |= DiGetNodesConf::REORG_MOVING;
9112  getFragstore(tabPtr.p, newFragId, fragPtr);
9113  nodeCount = extractNodeInfo(fragPtr.p, conf->nodes + 2 + MAX_REPLICAS);
9114  conf->nodes[MAX_REPLICAS] = newFragId;
9115  conf->nodes[MAX_REPLICAS + 1] = (nodeCount - 1) +
9116  (fragPtr.p->distributionKey << 16) +
9117  (dihGetInstanceKey(fragPtr) << 24);
9118  }
9119 
9120  if (unlikely(!tabPtr.p->m_lock.read_unlock(val)))
9121  goto loop;
9122 }//Dbdih::execDIGETNODESREQ()
9123 
9124 Uint32 Dbdih::extractNodeInfo(const Fragmentstore * fragPtr, Uint32 nodes[])
9125 {
9126  Uint32 nodeCount = 0;
9127  nodes[0] = nodes[1] = nodes[2] = nodes[3] = 0;
9128  for (Uint32 i = 0; i < fragPtr->fragReplicas; i++) {
9129  jam();
9130  NodeRecordPtr nodePtr;
9131  ndbrequire(i < MAX_REPLICAS);
9132  nodePtr.i = fragPtr->activeNodes[i];
9133  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
9134  if (nodePtr.p->useInTransactions) {
9135  jam();
9136  nodes[nodeCount] = nodePtr.i;
9137  nodeCount++;
9138  }//if
9139  }//for
9140  ndbrequire(nodeCount > 0);
9141  return nodeCount;
9142 }//Dbdih::extractNodeInfo()
9143 
9144 void
9145 Dbdih::getFragstore(TabRecord * tab, //In parameter
9146  Uint32 fragNo, //In parameter
9147  FragmentstorePtr & fragptr) //Out parameter
9148 {
9149  FragmentstorePtr fragPtr;
9150  Uint32 TfragstoreFileSize = cfragstoreFileSize;
9151  Fragmentstore* TfragStore = fragmentstore;
9152  Uint32 chunkNo = fragNo >> LOG_NO_OF_FRAGS_PER_CHUNK;
9153  Uint32 chunkIndex = fragNo & (NO_OF_FRAGS_PER_CHUNK - 1);
9154  fragPtr.i = tab->startFid[chunkNo] + chunkIndex;
9155  if (likely(chunkNo < NDB_ARRAY_SIZE(tab->startFid))) {
9156  ptrCheckGuard(fragPtr, TfragstoreFileSize, TfragStore);
9157  fragptr = fragPtr;
9158  return;
9159  }//if
9160  ndbrequire(false);
9161 }//Dbdih::getFragstore()
9162 
9163 void Dbdih::allocFragments(Uint32 noOfFragments, TabRecordPtr tabPtr)
9164 {
9165  FragmentstorePtr fragPtr;
9166  Uint32 noOfChunks = (noOfFragments + (NO_OF_FRAGS_PER_CHUNK - 1)) >> LOG_NO_OF_FRAGS_PER_CHUNK;
9167  ndbrequire(cremainingfrags >= noOfFragments);
9168  for (Uint32 i = 0; i < noOfChunks; i++) {
9169  jam();
9170  Uint32 baseFrag = cfirstfragstore;
9171  ndbrequire(i < NDB_ARRAY_SIZE(tabPtr.p->startFid));
9172  tabPtr.p->startFid[i] = baseFrag;
9173  fragPtr.i = baseFrag;
9174  ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
9175  cfirstfragstore = fragPtr.p->nextFragmentChunk;
9176  cremainingfrags -= NO_OF_FRAGS_PER_CHUNK;
9177  for (Uint32 j = 0; j < NO_OF_FRAGS_PER_CHUNK; j++) {
9178  jam();
9179  fragPtr.i = baseFrag + j;
9180  ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
9181  initFragstore(fragPtr);
9182  }//if
9183  }//for
9184  tabPtr.p->noOfFragChunks = noOfChunks;
9185 }//Dbdih::allocFragments()
9186 
9187 void Dbdih::releaseFragments(TabRecordPtr tabPtr)
9188 {
9189  FragmentstorePtr fragPtr;
9190  for (Uint32 i = 0; i < tabPtr.p->noOfFragChunks; i++) {
9191  jam();
9192  ndbrequire(i < NDB_ARRAY_SIZE(tabPtr.p->startFid));
9193  Uint32 baseFrag = tabPtr.p->startFid[i];
9194  fragPtr.i = baseFrag;
9195  ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
9196  fragPtr.p->nextFragmentChunk = cfirstfragstore;
9197  cfirstfragstore = baseFrag;
9198  tabPtr.p->startFid[i] = RNIL;
9199  cremainingfrags += NO_OF_FRAGS_PER_CHUNK;
9200  }//for
9201  tabPtr.p->noOfFragChunks = 0;
9202 }//Dbdih::releaseFragments()
9203 
9204 void Dbdih::initialiseFragstore()
9205 {
9206  Uint32 i;
9207  FragmentstorePtr fragPtr;
9208  for (i = 0; i < cfragstoreFileSize; i++) {
9209  fragPtr.i = i;
9210  ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
9211  initFragstore(fragPtr);
9212  }//for
9213  Uint32 noOfChunks = cfragstoreFileSize >> LOG_NO_OF_FRAGS_PER_CHUNK;
9214  fragPtr.i = 0;
9215  cfirstfragstore = RNIL;
9216  cremainingfrags = 0;
9217  for (i = 0; i < noOfChunks; i++) {
9219  ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
9220  fragPtr.p->nextFragmentChunk = cfirstfragstore;
9221  cfirstfragstore = fragPtr.i;
9222  fragPtr.i += NO_OF_FRAGS_PER_CHUNK;
9223  cremainingfrags += NO_OF_FRAGS_PER_CHUNK;
9224  }//for
9225 }//Dbdih::initialiseFragstore()
9226 
9227 #ifndef NDB_HAVE_RMB
9228 #define rmb() do { } while (0)
9229 #endif
9230 
9231 #ifndef NDB_HAVE_WMB
9232 #define wmb() do { } while (0)
9233 #endif
9234 
9235 inline
9236 bool
9237 Dbdih::isEmpty(const DIVERIFY_queue & q)
9238 {
9239  return q.cfirstVerifyQueue == q.clastVerifyQueue;
9240 }
9241 
9242 inline
9243 void
9244 Dbdih::enqueue(DIVERIFY_queue & q, Uint32 senderData, Uint64 gci)
9245 {
9246 #ifndef NDEBUG
9247 
9253  Uint32 first = q.cfirstVerifyQueue;
9254 #endif
9255 
9256  Uint32 last = q.clastVerifyQueue;
9257  ApiConnectRecord * apiConnectRecord = q.apiConnectRecord;
9258 
9259  apiConnectRecord[last].senderData = senderData;
9260  apiConnectRecord[last].apiGci = gci;
9261  wmb();
9262  if (last + 1 == capiConnectFileSize)
9263  {
9264  q.clastVerifyQueue = 0;
9265  }
9266  else
9267  {
9268  q.clastVerifyQueue = last + 1;
9269  }
9270  assert(q.clastVerifyQueue != first);
9271 }
9272 
9273 inline
9274 void
9275 Dbdih::dequeue(DIVERIFY_queue & q, ApiConnectRecord & conRecord)
9276 {
9277  Uint32 first = q.cfirstVerifyQueue;
9278  ApiConnectRecord * apiConnectRecord = q.apiConnectRecord;
9279 
9280  rmb();
9281  conRecord.senderData = apiConnectRecord[first].senderData;
9282  conRecord.apiGci = apiConnectRecord[first].apiGci;
9283 
9284  if (first + 1 == capiConnectFileSize)
9285  {
9286  q.cfirstVerifyQueue = 0;
9287  }
9288  else
9289  {
9290  q.cfirstVerifyQueue = first + 1;
9291  }
9292 }
9293 
9294 /*
9295  3.9 V E R I F I C A T I O N
9296  ****************************=
9297  */
9298 /****************************************************************************/
9299 /* ********** VERIFICATION SUB-MODULE *************/
9300 /****************************************************************************/
9301 /*
9302  3.9.1 R E C E I V I N G O F V E R I F I C A T I O N R E Q U E S T
9303  *************************************************************************
9304  */
9305 void Dbdih::execDIVERIFYREQ(Signal* signal)
9306 {
9307  EmulatedJamBuffer * jambuf = * (EmulatedJamBuffer**)(signal->theData+2);
9308  thrjamEntry(jambuf);
9309  Uint32 qno = signal->theData[1];
9310  ndbassert(qno < NDB_ARRAY_SIZE(c_diverify_queue));
9311  DIVERIFY_queue & q = c_diverify_queue[qno];
9312 loop:
9313  Uint32 val = m_micro_gcp.m_lock.read_lock();
9314  Uint32 blocked = getBlockCommit() == true ? 1 : 0;
9315  if (blocked == 0 && isEmpty(q))
9316  {
9317  thrjam(jambuf);
9318  /*-----------------------------------------------------------------------*/
9319  // We are not blocked and the verify queue was empty currently so we can
9320  // simply reply back to TC immediately. The method was called with
9321  // EXECUTE_DIRECT so we reply back by setting signal data and returning.
9322  // theData[0] already contains the correct information so
9323  // we need not touch it.
9324  /*-----------------------------------------------------------------------*/
9325  signal->theData[1] = (Uint32)(m_micro_gcp.m_current_gci >> 32);
9326  signal->theData[2] = (Uint32)(m_micro_gcp.m_current_gci & 0xFFFFFFFF);
9327  signal->theData[3] = 0;
9328  if (unlikely(! m_micro_gcp.m_lock.read_unlock(val)))
9329  goto loop;
9330  return;
9331  }//if
9332  /*-------------------------------------------------------------------------*/
9333  // Since we are blocked we need to put this operation last in the verify
9334  // queue to ensure that operation starts up in the correct order.
9335  /*-------------------------------------------------------------------------*/
9336  enqueue(q, signal->theData[0], m_micro_gcp.m_new_gci);
9337  if (blocked == 0 && jambuf == jamBuffer())
9338  {
9339  emptyverificbuffer(signal, 0, false);
9340  }
9341  signal->theData[3] = blocked + 1; // Indicate no immediate return
9342  return;
9343 }//Dbdih::execDIVERIFYREQ()
9344 
9345 void Dbdih::execDIH_SCAN_TAB_REQ(Signal* signal)
9346 {
9347  DihScanTabReq * req = (DihScanTabReq*)signal->getDataPtr();
9348  TabRecordPtr tabPtr;
9349  const Uint32 senderData = req->senderData;
9350  const Uint32 senderRef = req->senderRef;
9351  const Uint32 schemaTransId = req->schemaTransId;
9352 
9353  jamEntry();
9354 
9355  tabPtr.i = req->tableId;
9356  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9357 
9358  if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
9359  {
9360  if (! (tabPtr.p->tabStatus == TabRecord::TS_CREATING &&
9361  tabPtr.p->schemaTransId == schemaTransId))
9362  {
9363  jam();
9364  goto error;
9365  }
9366  }
9367 
9368  tabPtr.p->m_scan_count[0]++;
9369 
9370  {
9371  DihScanTabConf* conf = (DihScanTabConf*)signal->getDataPtrSend();
9372  conf->tableId = tabPtr.i;
9373  conf->senderData = senderData;
9374  conf->fragmentCount = tabPtr.p->totalfragments;
9375  conf->noOfBackups = tabPtr.p->noOfBackups;
9376  conf->scanCookie = tabPtr.p->m_map_ptr_i;
9377  conf->reorgFlag = tabPtr.p->m_scan_reorg_flag;
9378  sendSignal(senderRef, GSN_DIH_SCAN_TAB_CONF, signal,
9379  DihScanTabConf::SignalLength, JBB);
9380  }
9381  return;
9382 
9383 error:
9384  DihScanTabRef* ref = (DihScanTabRef*)signal->getDataPtrSend();
9385  ref->tableId = tabPtr.i;
9386  ref->senderData = senderData;
9387  ref->error = DihScanTabRef::ErroneousTableState;
9388  ref->tableStatus = tabPtr.p->tabStatus;
9389  ref->schemaTransId = schemaTransId;
9390  sendSignal(senderRef, GSN_DIH_SCAN_TAB_REF, signal,
9391  DihScanTabRef::SignalLength, JBB);
9392  return;
9393 
9394 }//Dbdih::execDI_FCOUNTREQ()
9395 
9396 void Dbdih::execDIH_SCAN_GET_NODES_REQ(Signal* signal)
9397 {
9398  FragmentstorePtr fragPtr;
9399  TabRecordPtr tabPtr;
9400  jamEntry();
9401  DihScanGetNodesReq* req = (DihScanGetNodesReq*)signal->getDataPtrSend();
9402  Uint32 senderRef = req->senderRef;
9403  Uint32 senderData = req->senderData;
9404  Uint32 fragId = req->fragId;
9405 
9406  tabPtr.i = req->tableId;
9407  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9408  if (DictTabInfo::isOrderedIndex(tabPtr.p->tableType)) {
9409  jam();
9410  tabPtr.i = tabPtr.p->primaryTableId;
9411  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9412  }
9413 
9414  Uint32 nodes[MAX_REPLICAS];
9415  getFragstore(tabPtr.p, fragId, fragPtr);
9416  Uint32 count = extractNodeInfo(fragPtr.p, nodes);
9417 
9418  DihScanGetNodesConf* conf = (DihScanGetNodesConf*)signal->getDataPtrSend();
9419  conf->senderData = senderData;
9420  conf->nodes[0] = nodes[0];
9421  conf->nodes[1] = nodes[1];
9422  conf->nodes[2] = nodes[2];
9423  conf->nodes[3] = nodes[3];
9424  conf->count = count;
9425  conf->tableId = tabPtr.i;
9426  conf->fragId = fragId;
9427  conf->instanceKey = dihGetInstanceKey(fragPtr);
9428  sendSignal(senderRef, GSN_DIH_SCAN_GET_NODES_CONF, signal,
9429  DihScanGetNodesConf::SignalLength, JBB);
9430 }//Dbdih::execDIGETPRIMREQ()
9431 
9432 void
9433 Dbdih::execDIH_SCAN_TAB_COMPLETE_REP(Signal* signal)
9434 {
9435  jamEntry();
9436  DihScanTabCompleteRep* rep = (DihScanTabCompleteRep*)signal->getDataPtr();
9437  TabRecordPtr tabPtr;
9438  tabPtr.i = rep->tableId;
9439  Uint32 map_ptr_i = rep->scanCookie;
9440  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9441 
9442  if (map_ptr_i == tabPtr.p->m_map_ptr_i)
9443  {
9444  jam();
9445  ndbassert(tabPtr.p->m_scan_count[0]);
9446  tabPtr.p->m_scan_count[0]--;
9447  }
9448  else
9449  {
9450  jam();
9451  ndbassert(tabPtr.p->m_scan_count[1]);
9452  tabPtr.p->m_scan_count[1]--;
9453  }
9454 }
9455 
9456 
9457 /****************************************************************************/
9458 /* ********** GLOBAL-CHECK-POINT HANDLING MODULE *************/
9459 /****************************************************************************/
9460 /*
9461  3.10 G L O B A L C H E C K P O I N T ( IN M A S T E R R O L E)
9462  *******************************************************************
9463  */
9464 
9465 bool
9466 Dbdih::check_enable_micro_gcp(Signal* signal, bool broadcast)
9467 {
9468  ndbassert(m_micro_gcp.m_enabled == false);
9469  ndbassert(NodeVersionInfo::DataLength == 6);
9470  Uint32 min = ~(Uint32)0;
9471  const NodeVersionInfo& info = getNodeVersionInfo();
9472  for (Uint32 i = 0; i<3; i++)
9473  {
9474  Uint32 tmp = info.m_type[i].m_min_version;
9475  if (tmp)
9476  {
9477  min = (min < tmp) ? min : tmp;
9478  }
9479  }
9480 
9481  if (ndb_check_micro_gcp(min))
9482  {
9483  jam();
9484  m_micro_gcp.m_enabled = true;
9485 
9486  infoEvent("Enabling micro GCP");
9487  if (broadcast)
9488  {
9489  jam();
9490  UpgradeProtocolOrd * ord = (UpgradeProtocolOrd*)signal->getDataPtrSend();
9491  ord->type = UpgradeProtocolOrd::UPO_ENABLE_MICRO_GCP;
9492 
9496  NodeRecordPtr specNodePtr;
9497  specNodePtr.i = cfirstAliveNode;
9498  do {
9499  jam();
9500  ptrCheckGuard(specNodePtr, MAX_NDB_NODES, nodeRecord);
9501  sendSignal(calcDihBlockRef(specNodePtr.i), GSN_UPGRADE_PROTOCOL_ORD,
9502  signal, UpgradeProtocolOrd::SignalLength, JBA);
9503  specNodePtr.i = specNodePtr.p->nextNode;
9504  } while (specNodePtr.i != RNIL);
9505  EXECUTE_DIRECT(QMGR,GSN_UPGRADE_PROTOCOL_ORD,signal,signal->getLength());
9506  }
9507  }
9508  return m_micro_gcp.m_enabled;
9509 }
9510 
9511 void
9512 Dbdih::execUPGRADE_PROTOCOL_ORD(Signal* signal)
9513 {
9514  const UpgradeProtocolOrd* ord = (UpgradeProtocolOrd*)signal->getDataPtr();
9515  switch(ord->type){
9516  case UpgradeProtocolOrd::UPO_ENABLE_MICRO_GCP:
9517  jam();
9518  m_micro_gcp.m_enabled = true;
9519  EXECUTE_DIRECT(QMGR, GSN_UPGRADE_PROTOCOL_ORD,signal, signal->getLength());
9520  return;
9521  }
9522 }
9523 
9524 void
9525 Dbdih::startGcpLab(Signal* signal, Uint32 aWaitTime)
9526 {
9527  for (Uint32 i = 0; i < c_diverify_queue_cnt; i++)
9528  {
9529  if (c_diverify_queue[i].m_empty_done == 0)
9530  {
9531  // Previous global checkpoint is not yet completed.
9532  jam();
9533  signal->theData[0] = DihContinueB::ZSTART_GCP;
9534  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 10, 1);
9535  return;
9536  }
9537  }
9538 
9539  emptyWaitGCPMasterQueue(signal,
9540  m_micro_gcp.m_current_gci,
9541  c_waitEpochMasterList);
9542 
9543  if (c_nodeStartMaster.blockGcp != 0 &&
9544  m_gcp_save.m_master.m_state == GcpSave::GCP_SAVE_IDLE)
9545  {
9546  jam();
9547 
9548  /* ------------------------------------------------------------------ */
9549  /* A NEW NODE WANTS IN AND WE MUST ALLOW IT TO COME IN NOW SINCE THE */
9550  /* GCP IS COMPLETED. */
9551  /* ------------------------------------------------------------------ */
9552 
9553  if (ERROR_INSERTED(7217))
9554  {
9555  jam();
9556 
9557  signal->theData[0] = 9999;
9558  sendSignal(numberToRef(CMVMI, refToNode(c_nodeStartMaster.startNode)),
9559  GSN_NDB_TAMPER, signal, 1, JBB);
9560 
9561  m_micro_gcp.m_master.m_start_time = 0; // Force start
9562  // fall through
9563  }
9564  else
9565  {
9566  jam();
9567  ndbrequire(c_nodeStartMaster.blockGcp == 1); // Ordered...
9568  c_nodeStartMaster.blockGcp = 2; // effective
9569  gcpBlockedLab(signal);
9570  return;
9571  }
9572  }
9573 
9574  if (cgcpOrderBlocked)
9575  {
9576  jam();
9577  signal->theData[0] = DihContinueB::ZSTART_GCP;
9578  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 10, 1);
9579  return;
9580  }
9581 
9582  Uint32 delayMicro = m_micro_gcp.m_enabled ?
9583  m_micro_gcp.m_master.m_time_between_gcp :
9584  m_gcp_save.m_master.m_time_between_gcp;
9585 
9586  Uint64 now = c_current_time = NdbTick_CurrentMillisecond();
9587  if (! (now >= m_micro_gcp.m_master.m_start_time + delayMicro))
9588  {
9589  jam();
9590  signal->theData[0] = DihContinueB::ZSTART_GCP;
9591  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 10, 1);
9592  return;
9593  }
9594 
9595  m_micro_gcp.m_master.m_start_time = now;
9596 
9597  if (m_micro_gcp.m_enabled == false &&
9598  m_micro_gcp.m_master.m_time_between_gcp)
9599  {
9603  jam();
9604  check_enable_micro_gcp(signal, true);
9605  }
9606 
9610  Uint64 currGCI = m_micro_gcp.m_current_gci;
9611  ndbrequire(Uint32(currGCI) != ~(Uint32)0);
9612  m_micro_gcp.m_master.m_new_gci = currGCI + 1;
9613 
9614  Uint32 delaySave = m_gcp_save.m_master.m_time_between_gcp;
9615  if ((m_micro_gcp.m_enabled == false) ||
9616  (now >= m_gcp_save.m_master.m_start_time + delaySave &&
9617  m_gcp_save.m_master.m_state == GcpSave::GCP_SAVE_IDLE))
9618  {
9619  jam();
9623  m_gcp_save.m_master.m_start_time = now;
9624  m_micro_gcp.m_master.m_new_gci = Uint64((currGCI >> 32) + 1) << 32;
9625 
9626  signal->theData[0] = NDB_LE_GlobalCheckpointStarted; //Event type
9627  signal->theData[1] = Uint32(currGCI >> 32);
9628  signal->theData[2] = Uint32(currGCI);
9629  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
9630  }
9631 
9632  ndbassert(m_micro_gcp.m_enabled || Uint32(m_micro_gcp.m_new_gci) == 0);
9633 
9634 
9635  /***************************************************************************/
9636  // Report the event that a global checkpoint has started.
9637  /***************************************************************************/
9638 
9639  CRASH_INSERTION(7000);
9640  m_micro_gcp.m_master.m_state = MicroGcp::M_GCP_PREPARE;
9641  signal->setTrace(TestOrd::TraceGlobalCheckpoint);
9642 
9643 #ifdef ERROR_INSERT
9644  if (ERROR_INSERTED(7186))
9645  {
9646  sendToRandomNodes("GCP_PREPARE",
9647  signal, &c_GCP_PREPARE_Counter, &Dbdih::sendGCP_PREPARE);
9648  signal->theData[0] = 9999;
9649  sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 1000, 1);
9650  return;
9651  }
9652  else if (ERROR_INSERTED(7200))
9653  {
9654  c_GCP_PREPARE_Counter.clearWaitingFor();
9655  NodeRecordPtr nodePtr;
9656  nodePtr.i = cfirstAliveNode;
9657  do {
9658  jam();
9659  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
9660  c_GCP_PREPARE_Counter.setWaitingFor(nodePtr.i);
9661  if (nodePtr.i != getOwnNodeId())
9662  {
9663  SET_ERROR_INSERT_VALUE(7201);
9664  sendGCP_PREPARE(signal, nodePtr.i, RNIL);
9665  }
9666  else
9667  {
9668  SET_ERROR_INSERT_VALUE(7202);
9669  sendGCP_PREPARE(signal, nodePtr.i, RNIL);
9670  }
9671  nodePtr.i = nodePtr.p->nextNode;
9672  } while (nodePtr.i != RNIL);
9673 
9674  NodeReceiverGroup rg(CMVMI, c_GCP_PREPARE_Counter);
9675  rg.m_nodes.clear(getOwnNodeId());
9676  Uint32 victim = rg.m_nodes.find(0);
9677 
9678  signal->theData[0] = 9999;
9679  sendSignal(numberToRef(CMVMI, victim),
9680  GSN_NDB_TAMPER, signal, 1, JBA);
9681 
9682  CLEAR_ERROR_INSERT_VALUE;
9683  return;
9684  }
9685  else if (ERROR_INSERTED(7227))
9686  {
9687  ndbout_c("Not sending GCP_PREPARE to %u", c_error_insert_extra);
9688  c_GCP_PREPARE_Counter.clearWaitingFor();
9689  NodeRecordPtr nodePtr;
9690  nodePtr.i = cfirstAliveNode;
9691  do {
9692  jam();
9693  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
9694  c_GCP_PREPARE_Counter.setWaitingFor(nodePtr.i);
9695  if (nodePtr.i != c_error_insert_extra)
9696  {
9697  sendGCP_PREPARE(signal, nodePtr.i, RNIL);
9698  }
9699  nodePtr.i = nodePtr.p->nextNode;
9700  } while (nodePtr.i != RNIL);
9701 
9702  signal->theData[0] = 9999;
9703  sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 200, 1);
9704  return;
9705  }
9706 #endif
9707 
9708  sendLoopMacro(GCP_PREPARE, sendGCP_PREPARE, RNIL);
9709 }//Dbdih::startGcpLab()
9710 
9711 void Dbdih::execGCP_PREPARECONF(Signal* signal)
9712 {
9713  jamEntry();
9714  Uint32 senderNodeId = signal->theData[0];
9715  Uint32 gci_hi = signal->theData[1];
9716  Uint32 gci_lo = signal->theData[2];
9717 
9718  if (unlikely(signal->getLength() < GCPPrepareConf::SignalLength))
9719  {
9720  gci_lo = 0;
9721  ndbassert(!ndb_check_micro_gcp(getNodeInfo(senderNodeId).m_version));
9722  }
9723 
9724  Uint64 gci = gci_lo | (Uint64(gci_hi) << 32);
9725  ndbrequire(gci == m_micro_gcp.m_master.m_new_gci);
9726  receiveLoopMacro(GCP_PREPARE, senderNodeId);
9727  //-------------------------------------------------------------
9728  // We have now received all replies. We are ready to continue
9729  // with committing the global checkpoint.
9730  //-------------------------------------------------------------
9731  gcpcommitreqLab(signal);
9732 }//Dbdih::execGCP_PREPARECONF()
9733 
9734 void Dbdih::gcpcommitreqLab(Signal* signal)
9735 {
9736  CRASH_INSERTION(7001);
9737 
9738  m_micro_gcp.m_master.m_state = MicroGcp::M_GCP_COMMIT;
9739 
9740 #ifdef ERROR_INSERT
9741  if (ERROR_INSERTED(7187))
9742  {
9743  sendToRandomNodes("GCP_COMMIT",
9744  signal, &c_GCP_COMMIT_Counter, &Dbdih::sendGCP_COMMIT);
9745  signal->theData[0] = 9999;
9746  sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 1000, 1);
9747  return;
9748  }
9749 #endif
9750 
9751  sendLoopMacro(GCP_COMMIT, sendGCP_COMMIT, RNIL);
9752  return;
9753 }//Dbdih::gcpcommitreqLab()
9754 
9755 void Dbdih::execGCP_NODEFINISH(Signal* signal)
9756 {
9757  jamEntry();
9758  const Uint32 senderNodeId = signal->theData[0];
9759  const Uint32 gci_hi = signal->theData[1];
9760  const Uint32 failureNr = signal->theData[2];
9761  const Uint32 gci_lo = signal->theData[3];
9762  const Uint64 gci = gci_lo | (Uint64(gci_hi) << 32);
9763 
9764  (void)gci; // TODO validate
9765  (void)failureNr; // kill warning
9766 
9767  ndbrequire(m_micro_gcp.m_master.m_state == MicroGcp::M_GCP_COMMIT);
9768  receiveLoopMacro(GCP_COMMIT, senderNodeId);
9769 
9770  jam();
9771 
9772  if (m_micro_gcp.m_enabled)
9773  {
9774  jam();
9775 
9776  m_micro_gcp.m_master.m_state = MicroGcp::M_GCP_COMPLETE;
9777 
9778  SubGcpCompleteRep * rep = (SubGcpCompleteRep*)signal->getDataPtr();
9779  rep->senderRef = reference();
9780  rep->gci_hi = (Uint32)(m_micro_gcp.m_old_gci >> 32);
9781  rep->gci_lo = (Uint32)(m_micro_gcp.m_old_gci & 0xFFFFFFFF);
9782  rep->flags = SubGcpCompleteRep::IN_MEMORY;
9783 
9784 #ifdef ERROR_INSERT
9785  if (ERROR_INSERTED(7190))
9786  {
9787  sendToRandomNodes("GCP_COMPLETE_REP", signal,
9788  &c_SUB_GCP_COMPLETE_REP_Counter,
9789  &Dbdih::sendSUB_GCP_COMPLETE_REP);
9790  signal->theData[0] = 9999;
9791  sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 1000, 1);
9792  }
9793  else if (ERROR_INSERTED(7226))
9794  {
9795  ndbout_c("Not sending SUB_GCP_COMPLETE_REP to %u", c_error_insert_extra);
9796  c_SUB_GCP_COMPLETE_REP_Counter.clearWaitingFor();
9797  NodeRecordPtr nodePtr;
9798  nodePtr.i = cfirstAliveNode;
9799  do {
9800  jam();
9801  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
9802  c_SUB_GCP_COMPLETE_REP_Counter.setWaitingFor(nodePtr.i);
9803  if (nodePtr.i != c_error_insert_extra)
9804  {
9805  sendSignal(calcDihBlockRef(nodePtr.i), GSN_SUB_GCP_COMPLETE_REP,
9806  signal, SubGcpCompleteRep::SignalLength, JBA);
9807  }
9808  nodePtr.i = nodePtr.p->nextNode;
9809  } while (nodePtr.i != RNIL);
9810  SET_ERROR_INSERT_VALUE(7227);
9811 
9812  signal->theData[0] = 9999;
9813  sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 200, 1);
9814  }
9815  else
9816 #endif
9817  {
9818  jam();
9819  // Normal path...
9820  sendLoopMacro(SUB_GCP_COMPLETE_REP, sendSUB_GCP_COMPLETE_REP, RNIL);
9821  }
9822  }
9823 
9824  //-------------------------------------------------------------
9825  // We have now received all replies. We are ready to continue
9826  // with saving the global checkpoint to disk.
9827  //-------------------------------------------------------------
9828  CRASH_INSERTION(7002);
9829 
9830  Uint32 curr_hi = (Uint32)(m_micro_gcp.m_current_gci >> 32);
9831  Uint32 old_hi = (Uint32)(m_micro_gcp.m_old_gci >> 32);
9832 
9833  if (m_micro_gcp.m_enabled)
9834  {
9835  jam();
9836  }
9837  else
9838  {
9839  ndbrequire(curr_hi != old_hi);
9840  }
9841 
9842  if (curr_hi == old_hi)
9843  {
9844  jam();
9845  return;
9846  }
9847 
9851  Uint32 saveGCI = old_hi;
9852  m_gcp_save.m_master.m_state = GcpSave::GCP_SAVE_REQ;
9853  m_gcp_save.m_master.m_new_gci = saveGCI;
9854 
9855 #ifdef ERROR_INSERT
9856  if (ERROR_INSERTED(7188))
9857  {
9858  sendToRandomNodes("GCP_SAVE",
9859  signal, &c_GCP_SAVEREQ_Counter, &Dbdih::sendGCP_SAVEREQ);
9860  signal->theData[0] = 9999;
9861  sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 1000, 1);
9862  return;
9863  }
9864  else if (ERROR_INSERTED(7216))
9865  {
9866  infoEvent("GCP_SAVE all/%u", c_error_insert_extra);
9867  NodeRecordPtr nodePtr;
9868  nodePtr.i = c_error_insert_extra;
9869  ptrAss(nodePtr, nodeRecord);
9870 
9871  removeAlive(nodePtr);
9872  sendLoopMacro(GCP_SAVEREQ, sendGCP_SAVEREQ, RNIL);
9873  insertAlive(nodePtr);
9874  signal->theData[0] = 9999;
9875  sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 1000, 1);
9876  c_GCP_SAVEREQ_Counter.setWaitingFor(c_error_insert_extra);
9877  return;
9878  }
9879 #endif
9880 
9881  sendLoopMacro(GCP_SAVEREQ, sendGCP_SAVEREQ, RNIL);
9882 }
9883 
9884 void
9885 Dbdih::execSUB_GCP_COMPLETE_ACK(Signal* signal)
9886 {
9887  jamEntry();
9888  SubGcpCompleteAck ack = * CAST_CONSTPTR(SubGcpCompleteAck,
9889  signal->getDataPtr());
9890  Uint32 senderNodeId = refToNode(ack.rep.senderRef);
9891 
9892  ndbrequire(m_micro_gcp.m_master.m_state == MicroGcp::M_GCP_COMPLETE);
9893  receiveLoopMacro(SUB_GCP_COMPLETE_REP, senderNodeId);
9894 
9895  m_micro_gcp.m_master.m_state = MicroGcp::M_GCP_IDLE;
9896 
9897  if (!ERROR_INSERTED(7190))
9898  {
9899  signal->theData[0] = DihContinueB::ZSTART_GCP;
9900  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 10, 1);
9901  }
9902 }
9903 
9904 void
9905 Dbdih::execGCP_SAVEREQ(Signal* signal)
9906 {
9907  jamEntry();
9908  GCPSaveReq * req = (GCPSaveReq*)&signal->theData[0];
9909 
9910  if (m_gcp_save.m_state == GcpSave::GCP_SAVE_REQ)
9911  {
9912  jam();
9917  ndbrequire(m_gcp_save.m_gci == req->gci);
9918  m_gcp_save.m_master_ref = req->dihBlockRef;
9919  return;
9920  }
9921 
9922  if (m_gcp_save.m_gci == req->gci)
9923  {
9924  jam();
9929  m_gcp_save.m_master_ref = req->dihBlockRef;
9930 
9931  GCPSaveReq save = (* req);
9932  GCPSaveConf * conf = (GCPSaveConf*)signal->getDataPtrSend();
9933  conf->dihPtr = save.dihPtr;
9934  conf->nodeId = getOwnNodeId();
9935  conf->gci = save.gci;
9936  sendSignal(m_gcp_save.m_master_ref, GSN_GCP_SAVECONF, signal,
9937  GCPSaveConf::SignalLength, JBA);
9938  return;
9939  }
9940 
9941  ndbrequire(m_gcp_save.m_state == GcpSave::GCP_SAVE_IDLE);
9942  m_gcp_save.m_state = GcpSave::GCP_SAVE_REQ;
9943  m_gcp_save.m_master_ref = req->dihBlockRef;
9944  m_gcp_save.m_gci = req->gci;
9945 
9946  req->dihBlockRef = reference();
9947  sendSignal(DBLQH_REF, GSN_GCP_SAVEREQ, signal, signal->getLength(), JBA);
9948 }
9949 
9950 void Dbdih::execGCP_SAVECONF(Signal* signal)
9951 {
9952  jamEntry();
9953  GCPSaveConf * saveConf = (GCPSaveConf*)&signal->theData[0];
9954 
9955  if (refToBlock(signal->getSendersBlockRef()) == DBLQH)
9956  {
9957  jam();
9958 
9959  ndbrequire(m_gcp_save.m_state == GcpSave::GCP_SAVE_REQ);
9960  m_gcp_save.m_state = GcpSave::GCP_SAVE_CONF;
9961 
9962  sendSignal(m_gcp_save.m_master_ref,
9963  GSN_GCP_SAVECONF, signal, signal->getLength(), JBA);
9964  return;
9965  }
9966 
9967  ndbrequire(saveConf->gci == m_gcp_save.m_master.m_new_gci);
9968  ndbrequire(saveConf->nodeId == saveConf->dihPtr);
9969  SYSFILE->lastCompletedGCI[saveConf->nodeId] = saveConf->gci;
9970  GCP_SAVEhandling(signal, saveConf->nodeId);
9971 }//Dbdih::execGCP_SAVECONF()
9972 
9973 void Dbdih::execGCP_SAVEREF(Signal* signal)
9974 {
9975  jamEntry();
9976  GCPSaveRef * const saveRef = (GCPSaveRef*)&signal->theData[0];
9977 
9978  if (refToBlock(signal->getSendersBlockRef()) == DBLQH)
9979  {
9980  jam();
9981 
9982  ndbrequire(m_gcp_save.m_state == GcpSave::GCP_SAVE_REQ);
9983  m_gcp_save.m_state = GcpSave::GCP_SAVE_CONF;
9984 
9985  sendSignal(m_gcp_save.m_master_ref,
9986  GSN_GCP_SAVEREF, signal, signal->getLength(), JBA);
9987  return;
9988  }
9989 
9990  ndbrequire(saveRef->gci == m_gcp_save.m_master.m_new_gci);
9991  ndbrequire(saveRef->nodeId == saveRef->dihPtr);
9992 
9996  ndbrequire(saveRef->errorCode == GCPSaveRef::NodeShutdownInProgress ||
9997  saveRef->errorCode == GCPSaveRef::FakedSignalDueToNodeFailure ||
9998  saveRef->errorCode == GCPSaveRef::NodeRestartInProgress);
9999  GCP_SAVEhandling(signal, saveRef->nodeId);
10000 }//Dbdih::execGCP_SAVEREF()
10001 
10002 void Dbdih::GCP_SAVEhandling(Signal* signal, Uint32 nodeId)
10003 {
10004  ndbrequire(m_gcp_save.m_master.m_state == GcpSave::GCP_SAVE_REQ);
10005  receiveLoopMacro(GCP_SAVEREQ, nodeId);
10006  /*-------------------------------------------------------------------------*/
10007  // All nodes have replied. We are ready to update the system file.
10008  /*-------------------------------------------------------------------------*/
10009 
10010  CRASH_INSERTION(7003);
10018  SYSFILE->newestRestorableGCI = m_gcp_save.m_gci;
10019  if(Sysfile::getInitialStartOngoing(SYSFILE->systemRestartBits) &&
10020  getNodeState().startLevel == NodeState::SL_STARTED){
10021  jam();
10022 #if 0
10023  g_eventLogger->info("Dbdih: Clearing initial start ongoing");
10024 #endif
10025  Sysfile::clearInitialStartOngoing(SYSFILE->systemRestartBits);
10026  }
10027  copyGciLab(signal, CopyGCIReq::GLOBAL_CHECKPOINT);
10028 
10029  m_gcp_save.m_master.m_state = GcpSave::GCP_SAVE_COPY_GCI;
10030 
10031 }//Dbdih::GCP_SAVEhandling()
10032 
10033 /*
10034  3.11 G L O B A L C H E C K P O I N T (N O T - M A S T E R)
10035  *************************************************************
10036  */
10037 void Dbdih::execGCP_PREPARE(Signal* signal)
10038 {
10039  jamEntry();
10040  CRASH_INSERTION(7005);
10041 
10042  if (ERROR_INSERTED(7030))
10043  {
10044  cgckptflag = true;
10045  g_eventLogger->info("Delayed GCP_PREPARE 5s");
10046  sendSignalWithDelay(reference(), GSN_GCP_PREPARE, signal, 5000,
10047  signal->getLength());
10048  return;
10049  }
10050 
10051  GCPPrepare* req = (GCPPrepare*)signal->getDataPtr();
10052  GCPPrepareConf * conf = (GCPPrepareConf*)signal->getDataPtrSend();
10053  Uint32 masterNodeId = req->nodeId;
10054  Uint32 gci_hi = req->gci_hi;
10055  Uint32 gci_lo = req->gci_lo;
10056  if (unlikely(signal->getLength() < GCPPrepare::SignalLength))
10057  {
10058  jam();
10059  gci_lo = 0;
10060  ndbassert(!ndb_check_micro_gcp(getNodeInfo(masterNodeId).m_version));
10061  }
10062  Uint64 gci = gci_lo | (Uint64(gci_hi) << 32);
10063 
10064  BlockReference retRef = calcDihBlockRef(masterNodeId);
10065 
10066  if (isMaster())
10067  {
10068  ndbrequire(m_micro_gcp.m_master.m_state == MicroGcp::M_GCP_PREPARE);
10069  }
10070 
10071  if (m_micro_gcp.m_state == MicroGcp::M_GCP_PREPARE)
10072  {
10073  jam();
10078  ndbrequire(m_micro_gcp.m_new_gci == gci);
10079  m_micro_gcp.m_master_ref = retRef;
10080  goto reply;
10081  }
10082 
10083  if (m_micro_gcp.m_new_gci == gci)
10084  {
10085  jam();
10090  m_micro_gcp.m_master_ref = retRef;
10091  goto reply;
10092  }
10093 
10094  ndbrequire(m_micro_gcp.m_state == MicroGcp::M_GCP_IDLE);
10095 
10096  m_micro_gcp.m_lock.write_lock();
10097  cgckptflag = true;
10098  m_micro_gcp.m_state = MicroGcp::M_GCP_PREPARE;
10099  m_micro_gcp.m_new_gci = gci;
10100  m_micro_gcp.m_master_ref = retRef;
10101  m_micro_gcp.m_lock.write_unlock();
10102 
10103  if (ERROR_INSERTED(7031))
10104  {
10105  g_eventLogger->info("Crashing delayed in GCP_PREPARE 3s");
10106  signal->theData[0] = 9999;
10107  sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 3000, 1);
10108  return;
10109  }
10110 #ifdef GCP_TIMER_HACK
10111  NdbTick_getMicroTimer(&globalData.gcp_timer_commit[0]);
10112 #endif
10113 
10114 reply:
10122  sendSignal(SUMA_REF, GSN_GCP_PREPARE, signal, signal->length(), JBB);
10123 
10124  /* Send reply. */
10125  conf->nodeId = cownNodeId;
10126  conf->gci_hi = gci_hi;
10127  conf->gci_lo = gci_lo;
10128  sendSignal(retRef, GSN_GCP_PREPARECONF, signal,
10129  GCPPrepareConf::SignalLength, JBA);
10130  return;
10131 }
10132 
10133 void Dbdih::execGCP_COMMIT(Signal* signal)
10134 {
10135  jamEntry();
10136  CRASH_INSERTION(7006);
10137 
10138  GCPCommit * req = (GCPCommit*)signal->getDataPtr();
10139  Uint32 masterNodeId = req->nodeId;
10140  Uint32 gci_hi = req->gci_hi;
10141  Uint32 gci_lo = req->gci_lo;
10142 
10143  if (unlikely(signal->getLength() < GCPCommit::SignalLength))
10144  {
10145  gci_lo = 0;
10146  ndbassert(!ndb_check_micro_gcp(getNodeInfo(masterNodeId).m_version));
10147  }
10148  Uint64 gci = gci_lo | (Uint64(gci_hi) << 32);
10149 
10150 #ifdef ERROR_INSERT
10151  if (ERROR_INSERTED(7213))
10152  {
10153  ndbout_c("err 7213 killing %d", c_error_insert_extra);
10154  Uint32 save = signal->theData[0];
10155  signal->theData[0] = 5048;
10156  sendSignal(numberToRef(DBLQH, c_error_insert_extra),
10157  GSN_NDB_TAMPER, signal, 1, JBB);
10158  signal->theData[0] = save;
10159  CLEAR_ERROR_INSERT_VALUE;
10160 
10161  signal->theData[0] = 9999;
10162  sendSignal(numberToRef(CMVMI, c_error_insert_extra),
10163  GSN_DUMP_STATE_ORD, signal, 1, JBB);
10164 
10165  signal->theData[0] = save;
10166  CLEAR_ERROR_INSERT_VALUE;
10167 
10168  return;
10169  }
10170 #endif
10171 
10172  Uint32 masterRef = calcDihBlockRef(masterNodeId);
10173  ndbrequire(masterNodeId == cmasterNodeId);
10174  if (isMaster())
10175  {
10176  ndbrequire(m_micro_gcp.m_master.m_state == MicroGcp::M_GCP_COMMIT);
10177  }
10178 
10179  if (m_micro_gcp.m_state == MicroGcp::M_GCP_COMMIT)
10180  {
10181  jam();
10186  ndbrequire(m_micro_gcp.m_current_gci == gci);
10187  m_micro_gcp.m_master_ref = masterRef;
10188  return;
10189  }
10190 
10191  if (m_micro_gcp.m_current_gci == gci)
10192  {
10193  jam();
10198  m_micro_gcp.m_master_ref = masterRef;
10199 
10200  GCPNodeFinished* conf = (GCPNodeFinished*)signal->getDataPtrSend();
10201  conf->nodeId = cownNodeId;
10202  conf->gci_hi = (Uint32)(m_micro_gcp.m_old_gci >> 32);
10203  conf->failno = cfailurenr;
10204  conf->gci_lo = (Uint32)(m_micro_gcp.m_old_gci & 0xFFFFFFFF);
10205  sendSignal(masterRef, GSN_GCP_NODEFINISH, signal,
10206  GCPNodeFinished::SignalLength, JBB);
10207  return;
10208  }
10209 
10210  ndbrequire(m_micro_gcp.m_new_gci == gci);
10211  ndbrequire(m_micro_gcp.m_state == MicroGcp::M_GCP_PREPARE);
10212  m_micro_gcp.m_state = MicroGcp::M_GCP_COMMIT;
10213  m_micro_gcp.m_master_ref = calcDihBlockRef(masterNodeId);
10214 
10215  m_micro_gcp.m_lock.write_lock();
10216  m_micro_gcp.m_old_gci = m_micro_gcp.m_current_gci;
10217  m_micro_gcp.m_current_gci = gci;
10218  cgckptflag = false;
10219  m_micro_gcp.m_lock.write_unlock();
10220 
10221  for (Uint32 i = 0; i < c_diverify_queue_cnt; i++)
10222  {
10223  jam();
10224  c_diverify_queue[i].m_empty_done = 0;
10225  emptyverificbuffer(signal, i, true);
10226  }
10227 
10228  GCPNoMoreTrans* req2 = (GCPNoMoreTrans*)signal->getDataPtrSend();
10229  req2->senderRef = reference();
10230  req2->senderData = calcDihBlockRef(masterNodeId);
10231  req2->gci_hi = (Uint32)(m_micro_gcp.m_old_gci >> 32);
10232  req2->gci_lo = (Uint32)(m_micro_gcp.m_old_gci & 0xFFFFFFFF);
10233  sendSignal(clocaltcblockref, GSN_GCP_NOMORETRANS, signal,
10234  GCPNoMoreTrans::SignalLength, JBB);
10235  return;
10236 }//Dbdih::execGCP_COMMIT()
10237 
10238 void Dbdih::execGCP_TCFINISHED(Signal* signal)
10239 {
10240  jamEntry();
10241  CRASH_INSERTION(7007);
10242  GCPTCFinished* conf = (GCPTCFinished*)signal->getDataPtr();
10243  Uint32 retRef = conf->senderData;
10244  Uint32 gci_hi = conf->gci_hi;
10245  Uint32 gci_lo = conf->gci_lo;
10246  Uint64 gci = gci_lo | (Uint64(gci_hi) << 32);
10247  ndbrequire(gci == m_micro_gcp.m_old_gci);
10248 
10249  if (ERROR_INSERTED(7181) || ERROR_INSERTED(7182))
10250  {
10251  c_error_7181_ref = retRef; // Save ref
10252  ndbout_c("killing %d", refToNode(cmasterdihref));
10253  signal->theData[0] = 9999;
10254  sendSignal(numberToRef(CMVMI, refToNode(cmasterdihref)),
10255  GSN_NDB_TAMPER, signal, 1, JBB);
10256  return;
10257  }
10258 
10259 #ifdef ERROR_INSERT
10260  if (ERROR_INSERTED(7214))
10261  {
10262  ndbout_c("err 7214 killing %d", c_error_insert_extra);
10263  Uint32 save = signal->theData[0];
10264  signal->theData[0] = 9999;
10265  sendSignal(numberToRef(CMVMI, c_error_insert_extra),
10266  GSN_NDB_TAMPER, signal, 1, JBB);
10267  signal->theData[0] = save;
10268  CLEAR_ERROR_INSERT_VALUE;
10269  }
10270 #endif
10271 
10272 #ifdef GCP_TIMER_HACK
10273  NdbTick_getMicroTimer(&globalData.gcp_timer_commit[1]);
10274 #endif
10275 
10276  ndbrequire(m_micro_gcp.m_state == MicroGcp::M_GCP_COMMIT);
10277 
10282  Callback cb;
10283  cb.m_callbackData = 10;
10284  cb.m_callbackFunction = safe_cast(&Dbdih::execGCP_TCFINISHED_sync_conf);
10285  Uint32 path[] = { DBLQH, SUMA, 0 };
10286  synchronize_path(signal, path, cb);
10287 }//Dbdih::execGCP_TCFINISHED()
10288 
10289 void
10290 Dbdih::execGCP_TCFINISHED_sync_conf(Signal* signal, Uint32 cb, Uint32 err)
10291 {
10292  ndbrequire(m_micro_gcp.m_state == MicroGcp::M_GCP_COMMIT);
10293 
10294  m_micro_gcp.m_state = MicroGcp::M_GCP_COMMITTED;
10295  Uint32 retRef = m_micro_gcp.m_master_ref;
10296 
10297  GCPNodeFinished* conf2 = (GCPNodeFinished*)signal->getDataPtrSend();
10298  conf2->nodeId = cownNodeId;
10299  conf2->gci_hi = (Uint32)(m_micro_gcp.m_old_gci >> 32);
10300  conf2->failno = cfailurenr;
10301  conf2->gci_lo = (Uint32)(m_micro_gcp.m_old_gci & 0xFFFFFFFF);
10302  sendSignal(retRef, GSN_GCP_NODEFINISH, signal,
10303  GCPNodeFinished::SignalLength, JBB);
10304 }
10305 
10306 void
10307 Dbdih::execSUB_GCP_COMPLETE_REP(Signal* signal)
10308 {
10309  jamEntry();
10310 
10311  CRASH_INSERTION(7228);
10312  SubGcpCompleteRep rep = * (SubGcpCompleteRep*)signal->getDataPtr();
10313  if (isMaster())
10314  {
10315  ndbrequire(m_micro_gcp.m_master.m_state == MicroGcp::M_GCP_COMPLETE);
10316  }
10317 
10318  Uint32 masterRef = rep.senderRef;
10319  if (m_micro_gcp.m_state == MicroGcp::M_GCP_IDLE)
10320  {
10321  jam();
10326  m_micro_gcp.m_master_ref = masterRef;
10327  goto reply;
10328  }
10329 
10330  ndbrequire(m_micro_gcp.m_state == MicroGcp::M_GCP_COMMITTED);
10331  m_micro_gcp.m_state = MicroGcp::M_GCP_IDLE;
10332 
10337  sendSignal(DBLQH_REF, GSN_SUB_GCP_COMPLETE_REP, signal,
10338  signal->length(), JBB);
10339 reply:
10340  Uint32 nodeId = refToNode(masterRef);
10341  if (!ndbd_dih_sub_gcp_complete_ack(getNodeInfo(nodeId).m_version))
10342  {
10343  jam();
10344  return;
10345  }
10346 
10347  SubGcpCompleteAck* ack = CAST_PTR(SubGcpCompleteAck,
10348  signal->getDataPtrSend());
10349  ack->rep = rep;
10350  ack->rep.senderRef = reference();
10351  sendSignal(masterRef, GSN_SUB_GCP_COMPLETE_ACK,
10352  signal, SubGcpCompleteAck::SignalLength, JBA);
10353 }
10354 
10355 /*****************************************************************************/
10356 //****** RECEIVING TAMPER REQUEST FROM NDBAPI ******
10357 /*****************************************************************************/
10358 void Dbdih::execDIHNDBTAMPER(Signal* signal)
10359 {
10360  jamEntry();
10361  Uint32 tcgcpblocked = signal->theData[0];
10362  /* ACTION TO BE TAKEN BY DIH */
10363  Uint32 tuserpointer = signal->theData[1];
10364  BlockReference tuserblockref = signal->theData[2];
10365  switch (tcgcpblocked) {
10366  case 1:
10367  jam();
10368  if (isMaster()) {
10369  jam();
10370  cgcpOrderBlocked = 1;
10371  } else {
10372  jam();
10373  /* TRANSFER THE REQUEST */
10374  /* TO MASTER*/
10375  signal->theData[0] = tcgcpblocked;
10376  signal->theData[1] = tuserpointer;
10377  signal->theData[2] = tuserblockref;
10378  sendSignal(cmasterdihref, GSN_DIHNDBTAMPER, signal, 3, JBB);
10379  }//if
10380  break;
10381  case 2:
10382  jam();
10383  if (isMaster()) {
10384  jam();
10385  cgcpOrderBlocked = 0;
10386  } else {
10387  jam();
10388  /* TRANSFER THE REQUEST */
10389  /* TO MASTER*/
10390  signal->theData[0] = tcgcpblocked;
10391  signal->theData[1] = tuserpointer;
10392  signal->theData[2] = tuserblockref;
10393  sendSignal(cmasterdihref, GSN_DIHNDBTAMPER, signal, 3, JBB);
10394  }//if
10395  break;
10396  case 3:
10397  ndbrequire(false);
10398  return;
10399  break;
10400  case 4:
10401  jam();
10402  signal->theData[0] = tuserpointer;
10403  signal->theData[1] = crestartGci;
10404  sendSignal(tuserblockref, GSN_DIHNDBTAMPER, signal, 2, JBB);
10405  break;
10406 #ifdef ERROR_INSERT
10407  case 5:
10408  jam();
10409  if (tuserpointer >= 30000 && tuserpointer < 40000) {
10410  jam();
10411  /*--------------------------------------------------------------------*/
10412  // Redirect errors to master DIH in the 30000-range.
10413  /*--------------------------------------------------------------------*/
10414  tuserblockref = cmasterdihref;
10415  tuserpointer -= 30000;
10416  signal->theData[0] = 5;
10417  signal->theData[1] = tuserpointer;
10418  signal->theData[2] = tuserblockref;
10419  sendSignal(tuserblockref, GSN_DIHNDBTAMPER, signal, 3, JBB);
10420  return;
10421  } else if (tuserpointer >= 40000 && tuserpointer < 50000) {
10422  NodeRecordPtr localNodeptr;
10423  Uint32 Tfound = 0;
10424  jam();
10425  /*--------------------------------------------------------------------*/
10426  // Redirect errors to non-master DIH in the 40000-range.
10427  /*--------------------------------------------------------------------*/
10428  tuserpointer -= 40000;
10429  for (localNodeptr.i = 1;
10430  localNodeptr.i < MAX_NDB_NODES;
10431  localNodeptr.i++) {
10432  jam();
10433  ptrAss(localNodeptr, nodeRecord);
10434  if ((localNodeptr.p->nodeStatus == NodeRecord::ALIVE) &&
10435  (localNodeptr.i != cmasterNodeId)) {
10436  jam();
10437  tuserblockref = calcDihBlockRef(localNodeptr.i);
10438  Tfound = 1;
10439  break;
10440  }//if
10441  }//for
10442  if (Tfound == 0) {
10443  jam();
10444  /*-------------------------------------------------------------------*/
10445  // Ignore since no non-master node existed.
10446  /*-------------------------------------------------------------------*/
10447  return;
10448  }//if
10449  signal->theData[0] = 5;
10450  signal->theData[1] = tuserpointer;
10451  signal->theData[2] = tuserblockref;
10452  sendSignal(tuserblockref, GSN_DIHNDBTAMPER, signal, 3, JBB);
10453  return;
10454  } else {
10455  jam();
10456  return;
10457  }//if
10458  break;
10459 #endif
10460  default:
10461  ndbrequire(false);
10462  break;
10463  }//switch
10464  return;
10465 }//Dbdih::execDIHNDBTAMPER()
10466 
10467 /*****************************************************************************/
10468 /* ********** FILE HANDLING MODULE *************/
10469 /*****************************************************************************/
10470 void Dbdih::copyGciLab(Signal* signal, CopyGCIReq::CopyReason reason)
10471 {
10472  if(c_copyGCIMaster.m_copyReason != CopyGCIReq::IDLE)
10473  {
10474  jam();
10478  for (Uint32 i = 0; i<CopyGCIMaster::WAIT_CNT; i++)
10479  {
10480  jam();
10481  if (c_copyGCIMaster.m_waiting[i] == CopyGCIReq::IDLE)
10482  {
10483  jam();
10484  c_copyGCIMaster.m_waiting[i] = reason;
10485  return;
10486  }
10487  }
10488 
10493  ndbrequire(false);
10494  return;
10495  }
10496  c_copyGCIMaster.m_copyReason = reason;
10497 
10498 #ifdef ERROR_INSERT
10499  if (reason == CopyGCIReq::GLOBAL_CHECKPOINT && ERROR_INSERTED(7189))
10500  {
10501  sendToRandomNodes("COPY_GCI",
10502  signal, &c_COPY_GCIREQ_Counter, &Dbdih::sendCOPY_GCIREQ);
10503  signal->theData[0] = 9999;
10504  sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 1000, 1);
10505  return;
10506  }
10507 #endif
10508 
10509  if (reason == CopyGCIReq::RESTART_NR)
10510  {
10511  jam();
10512  if (c_nodeStartMaster.startNode != RNIL)
10513  {
10514  jam();
10515  c_COPY_GCIREQ_Counter.clearWaitingFor();
10516  c_COPY_GCIREQ_Counter.setWaitingFor(c_nodeStartMaster.startNode);
10517  sendCOPY_GCIREQ(signal, c_nodeStartMaster.startNode, RNIL);
10518  return;
10519  }
10520  else
10521  {
10522  jam();
10523  reason = c_copyGCIMaster.m_copyReason = c_copyGCIMaster.m_waiting[0];
10524  for (Uint32 i = 1; i<CopyGCIMaster::WAIT_CNT; i++)
10525  {
10526  jam();
10527  c_copyGCIMaster.m_waiting[i-1] = c_copyGCIMaster.m_waiting[i];
10528  }
10529  c_copyGCIMaster.m_waiting[CopyGCIMaster::WAIT_CNT-1] =
10530  CopyGCIReq::IDLE;
10531 
10532  if (reason == CopyGCIReq::IDLE)
10533  {
10534  jam();
10535  return;
10536  }
10537  // fall-through
10538  }
10539  }
10540 
10541  sendLoopMacro(COPY_GCIREQ, sendCOPY_GCIREQ, RNIL);
10542 
10543 }//Dbdih::copyGciLab()
10544 
10545 /* ------------------------------------------------------------------------- */
10546 /* COPY_GCICONF RESPONSE TO COPY_GCIREQ */
10547 /* ------------------------------------------------------------------------- */
10548 void Dbdih::execCOPY_GCICONF(Signal* signal)
10549 {
10550  jamEntry();
10551  NodeRecordPtr senderNodePtr;
10552  senderNodePtr.i = signal->theData[0];
10553  receiveLoopMacro(COPY_GCIREQ, senderNodePtr.i);
10554 
10555  CopyGCIReq::CopyReason current = c_copyGCIMaster.m_copyReason;
10556  c_copyGCIMaster.m_copyReason = CopyGCIReq::IDLE;
10557 
10558  bool ok = false;
10559  switch(current){
10560  case CopyGCIReq::RESTART:{
10561  ok = true;
10562  jam();
10563  DictStartReq * req = (DictStartReq*)&signal->theData[0];
10564  req->restartGci = SYSFILE->newestRestorableGCI;
10565  req->senderRef = reference();
10566  sendSignal(cdictblockref, GSN_DICTSTARTREQ,
10567  signal, DictStartReq::SignalLength, JBB);
10568  break;
10569  }
10570  case CopyGCIReq::LOCAL_CHECKPOINT:{
10571  ok = true;
10572  jam();
10573  startLcpRoundLab(signal);
10574  break;
10575  }
10576  case CopyGCIReq::GLOBAL_CHECKPOINT:
10577  {
10578  ok = true;
10579  jam();
10580 
10581  /************************************************************************/
10582  // Report the event that a global checkpoint has completed.
10583  /************************************************************************/
10584  signal->setTrace(0);
10585  signal->theData[0] = NDB_LE_GlobalCheckpointCompleted; //Event type
10586  signal->theData[1] = m_gcp_save.m_gci;
10587  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
10588 
10589  c_newest_restorable_gci = m_gcp_save.m_gci;
10590 #ifdef ERROR_INSERT
10591  if ((ERROR_INSERTED(7222) || ERROR_INSERTED(7223)) &&
10592  !Sysfile::getLCPOngoing(SYSFILE->systemRestartBits) &&
10593  c_newest_restorable_gci >= c_lcpState.lcpStopGcp)
10594  {
10595  if (ERROR_INSERTED(7222))
10596  {
10597  sendLoopMacro(COPY_TABREQ, nullRoutine, 0);
10598  NodeReceiverGroup rg(CMVMI, c_COPY_TABREQ_Counter);
10599 
10600  rg.m_nodes.clear(getOwnNodeId());
10601  if (!rg.m_nodes.isclear())
10602  {
10603  signal->theData[0] = 9999;
10604  sendSignal(rg, GSN_NDB_TAMPER, signal, 1, JBA);
10605  }
10606  signal->theData[0] = 9999;
10607  sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 1000, 1);
10608 
10609  signal->theData[0] = 932;
10610  EXECUTE_DIRECT(QMGR, GSN_NDB_TAMPER, signal, 1);
10611 
10612  return;
10613  }
10614  if (ERROR_INSERTED(7223))
10615  {
10616  CLEAR_ERROR_INSERT_VALUE;
10617  signal->theData[0] = 9999;
10618  sendSignal(numberToRef(CMVMI, c_error_insert_extra)
10619  , GSN_NDB_TAMPER, signal, 1, JBA);
10620  }
10621  }
10622 #endif
10623 
10624  if (m_micro_gcp.m_enabled == false)
10625  {
10626  jam();
10630  signal->theData[0] = DihContinueB::ZSTART_GCP;
10631  sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
10632  }
10633  m_gcp_save.m_master.m_state = GcpSave::GCP_SAVE_IDLE;
10634 
10635  CRASH_INSERTION(7004);
10636  emptyWaitGCPMasterQueue(signal,
10637  Uint64(m_gcp_save.m_gci) << 32,
10638  c_waitGCPMasterList);
10639  break;
10640  }
10641  case CopyGCIReq::INITIAL_START_COMPLETED:
10642  ok = true;
10643  jam();
10644  initialStartCompletedLab(signal);
10645  break;
10646  case CopyGCIReq::IDLE:
10647  ok = false;
10648  jam();
10649  break;
10650  case CopyGCIReq::RESTART_NR:
10651  ok = true;
10652  jam();
10653  startme_copygci_conf(signal);
10654  break;
10655  }
10656  ndbrequire(ok);
10657 
10658 
10659  c_copyGCIMaster.m_copyReason = c_copyGCIMaster.m_waiting[0];
10660  for (Uint32 i = 1; i<CopyGCIMaster::WAIT_CNT; i++)
10661  {
10662  jam();
10663  c_copyGCIMaster.m_waiting[i-1] = c_copyGCIMaster.m_waiting[i];
10664  }
10665  c_copyGCIMaster.m_waiting[CopyGCIMaster::WAIT_CNT-1] = CopyGCIReq::IDLE;
10666 
10670  if(c_copyGCIMaster.m_copyReason != CopyGCIReq::IDLE)
10671  {
10672  jam();
10673 
10674  signal->theData[0] = DihContinueB::ZCOPY_GCI;
10675  signal->theData[1] = c_copyGCIMaster.m_copyReason;
10676  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
10677  }
10678 }//Dbdih::execCOPY_GCICONF()
10679 
10680 void Dbdih::invalidateLcpInfoAfterSr(Signal* signal)
10681 {
10682  NodeRecordPtr nodePtr;
10683  SYSFILE->latestLCP_ID--;
10684  Sysfile::clearLCPOngoing(SYSFILE->systemRestartBits);
10685  for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
10686  jam();
10687  ptrAss(nodePtr, nodeRecord);
10688  if (!NdbNodeBitmask::get(SYSFILE->lcpActive, nodePtr.i)){
10689  jam();
10690  /* ------------------------------------------------------------------- */
10691  // The node was not active in the local checkpoint.
10692  // To avoid that we step the active status too fast to not
10693  // active we step back one step from Sysfile::NS_ActiveMissed_x.
10694  /* ------------------------------------------------------------------- */
10695  switch (nodePtr.p->activeStatus) {
10696  case Sysfile::NS_Active:
10697  nodePtr.p->activeStatus = Sysfile::NS_Active;
10698  break;
10699  case Sysfile::NS_ActiveMissed_1:
10700  jam();
10701  nodePtr.p->activeStatus = Sysfile::NS_Active;
10702  break;
10703  case Sysfile::NS_ActiveMissed_2:
10704  jam();
10705  nodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
10706  break;
10707  default:
10708  jam();
10709  break;
10710  }//switch
10711  }
10712  else
10713  {
10714  jam();
10715  ndbassert(nodePtr.p->activeStatus == Sysfile::NS_Active);
10716  }
10717  }//for
10718  setNodeRestartInfoBits(signal);
10719 }//Dbdih::invalidateLcpInfoAfterSr()
10720 
10721 /* ------------------------------------------------------------------------- */
10722 /* THE NEXT STEP IS TO WRITE THE FILE. */
10723 /* ------------------------------------------------------------------------- */
10724 void Dbdih::openingCopyGciSkipInitLab(Signal* signal, FileRecordPtr filePtr)
10725 {
10726  writeRestorableGci(signal, filePtr);
10727  filePtr.p->reqStatus = FileRecord::WRITING_COPY_GCI;
10728  return;
10729 }//Dbdih::openingCopyGciSkipInitLab()
10730 
10731 void Dbdih::writingCopyGciLab(Signal* signal, FileRecordPtr filePtr)
10732 {
10733  /* ----------------------------------------------------------------------- */
10734  /* WE HAVE NOW WRITTEN THIS FILE. WRITE ALSO NEXT FILE IF THIS IS NOT */
10735  /* ALREADY THE LAST. */
10736  /* ----------------------------------------------------------------------- */
10737  CRASH_INSERTION(7219);
10738 
10739  filePtr.p->reqStatus = FileRecord::IDLE;
10740  if (filePtr.i == crestartInfoFile[0]) {
10741  jam();
10742  filePtr.i = crestartInfoFile[1];
10743  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
10744  if (filePtr.p->fileStatus == FileRecord::OPEN) {
10745  jam();
10746  openingCopyGciSkipInitLab(signal, filePtr);
10747  return;
10748  }//if
10749  openFileRw(signal, filePtr);
10750  filePtr.p->reqStatus = FileRecord::OPENING_COPY_GCI;
10751  return;
10752  }//if
10753  /* ----------------------------------------------------------------------- */
10754  /* WE HAVE COMPLETED WRITING BOTH FILES SUCCESSFULLY. NOW REPORT OUR */
10755  /* SUCCESS TO THE MASTER DIH. BUT FIRST WE NEED TO RESET A NUMBER OF */
10756  /* VARIABLES USED BY THE LOCAL CHECKPOINT PROCESS (ONLY IF TRIGGERED */
10757  /* BY LOCAL CHECKPOINT PROCESS. */
10758  /* ----------------------------------------------------------------------- */
10759  CopyGCIReq::CopyReason reason = c_copyGCISlave.m_copyReason;
10760 
10761  if (reason == CopyGCIReq::GLOBAL_CHECKPOINT) {
10762  jam();
10763  m_gcp_save.m_state = GcpSave::GCP_SAVE_IDLE;
10764 
10765  SubGcpCompleteRep * const rep = (SubGcpCompleteRep*)signal->getDataPtr();
10766  rep->gci_hi = SYSFILE->newestRestorableGCI;
10767  rep->gci_lo = 0;
10768  rep->flags = SubGcpCompleteRep::ON_DISK;
10769 
10770  sendSignal(LGMAN_REF, GSN_SUB_GCP_COMPLETE_REP, signal,
10771  SubGcpCompleteRep::SignalLength, JBB);
10772 
10773  jamEntry();
10774 
10775  if (m_micro_gcp.m_enabled == false)
10776  {
10777  jam();
10778  sendSignal(DBLQH_REF, GSN_SUB_GCP_COMPLETE_REP, signal,
10779  SubGcpCompleteRep::SignalLength, JBB);
10780  jamEntry();
10781  ndbrequire(m_micro_gcp.m_state == MicroGcp::M_GCP_COMMITTED);
10782  m_micro_gcp.m_state = MicroGcp::M_GCP_IDLE;
10783 
10784  CRASH_INSERTION(7190);
10785  }
10786 
10787 #ifdef GCP_TIMER_HACK
10788  NdbTick_getMicroTimer(&globalData.gcp_timer_copygci[1]);
10789 
10790  // this is last timer point so we send local report here
10791  {
10792  const GlobalData& g = globalData;
10793  Uint32 ms_commit = NdbTick_getMicrosPassed(
10794  g.gcp_timer_commit[0], g.gcp_timer_commit[1]) / 1000;
10795  Uint32 ms_save = NdbTick_getMicrosPassed(
10796  g.gcp_timer_save[0], g.gcp_timer_save[1]) / 1000;
10797  Uint32 ms_copygci = NdbTick_getMicrosPassed(
10798  g.gcp_timer_copygci[0], g.gcp_timer_copygci[1]) / 1000;
10799 
10800  Uint32 ms_total = ms_commit + ms_save + ms_copygci;
10801 
10802  // random formula to report excessive duration
10803  bool report =
10804  g.gcp_timer_limit != 0 ?
10805  (ms_total > g.gcp_timer_limit) :
10806  (ms_total > 3000 * (1 + cgcpDelay / 1000));
10807  if (report)
10808  infoEvent("GCP %u ms: total:%u commit:%u save:%u copygci:%u",
10809  coldgcp, ms_total, ms_commit, ms_save, ms_copygci);
10810  }
10811 #endif
10812  }
10813 
10814  jam();
10815  c_copyGCISlave.m_copyReason = CopyGCIReq::IDLE;
10816 
10817  if (reason == CopyGCIReq::GLOBAL_CHECKPOINT)
10818  {
10819  jam();
10820  signal->theData[0] = c_copyGCISlave.m_senderData;
10821  sendSignal(m_gcp_save.m_master_ref, GSN_COPY_GCICONF, signal, 1, JBB);
10822  }
10823  else if (c_copyGCISlave.m_senderRef == cmasterdihref)
10824  {
10825  jam();
10829  signal->theData[0] = c_copyGCISlave.m_senderData;
10830  sendSignal(c_copyGCISlave.m_senderRef, GSN_COPY_GCICONF, signal, 1, JBB);
10831  }
10832  return;
10833 }//Dbdih::writingCopyGciLab()
10834 
10835 void Dbdih::execSTART_LCP_REQ(Signal* signal)
10836 {
10837  jamEntry();
10838  StartLcpReq * req = (StartLcpReq*)signal->getDataPtr();
10839 
10843  m_local_lcp_state.init(req);
10844 
10845  CRASH_INSERTION2(7021, isMaster());
10846  CRASH_INSERTION2(7022, !isMaster());
10847 
10848  ndbrequire(c_lcpState.m_masterLcpDihRef == req->senderRef);
10849  c_lcpState.m_participatingDIH = req->participatingDIH;
10850  c_lcpState.m_participatingLQH = req->participatingLQH;
10851 
10852  c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH = req->participatingLQH;
10853  if(isMaster())
10854  {
10855  jam();
10856  c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH = req->participatingDIH;
10857  }
10858  else
10859  {
10860  jam();
10861  c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.clearWaitingFor();
10862  }
10863 
10864  c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received = false;
10865 
10866  c_lcpState.setLcpStatus(LCP_INIT_TABLES, __LINE__);
10867 
10868  signal->theData[0] = DihContinueB::ZINIT_LCP;
10869  signal->theData[1] = c_lcpState.m_masterLcpDihRef;
10870  signal->theData[2] = 0;
10871  sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
10872 }
10873 
10874 void
10875 Dbdih::LocalLCPState::reset()
10876 {
10877  m_state = LS_INITIAL;
10878  m_keep_gci = RNIL;
10879  m_stop_gci = RNIL;
10880 }
10881 
10882 void
10883 Dbdih::LocalLCPState::init(const StartLcpReq * req)
10884 {
10885  m_state = LS_RUNNING;
10886  m_start_lcp_req = *req;
10887  m_keep_gci = ~(Uint32)0;
10888  m_stop_gci = 0;
10889 }
10890 
10891 void
10892 Dbdih::LocalLCPState::lcp_frag_rep(const LcpFragRep * rep)
10893 {
10894  assert(m_state == LS_RUNNING);
10895  if (rep->maxGciCompleted < m_keep_gci)
10896  {
10897  m_keep_gci = rep->maxGciCompleted;
10898  }
10899 
10900  if (rep->maxGciStarted > m_stop_gci)
10901  {
10902  m_stop_gci = rep->maxGciStarted;
10903  }
10904 }
10905 
10906 void
10907 Dbdih::LocalLCPState::lcp_complete_rep(Uint32 gci)
10908 {
10909  assert(m_state == LS_RUNNING);
10910  m_state = LS_COMPLETE;
10911  if (gci > m_stop_gci)
10912  m_stop_gci = gci;
10913 }
10914 
10915 bool
10916 Dbdih::LocalLCPState::check_cut_log_tail(Uint32 gci) const
10917 {
10918  if (m_state == LS_COMPLETE)
10919  {
10920  if (gci >= m_stop_gci)
10921  return true;
10922  }
10923  return false;
10924 }
10925 
10926 void Dbdih::initLcpLab(Signal* signal, Uint32 senderRef, Uint32 tableId)
10927 {
10928  TabRecordPtr tabPtr;
10929  tabPtr.i = tableId;
10930 
10931  if(c_lcpState.m_masterLcpDihRef != senderRef){
10932  jam();
10936 #ifdef VM_TRACE
10937  g_eventLogger->info("initLcpLab aborted due to LCP master takeover - 1");
10938 #endif
10939  c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
10940  sendMASTER_LCPCONF(signal);
10941  return;
10942  }
10943 
10944  if(c_lcpState.m_masterLcpDihRef != cmasterdihref){
10945  jam();
10949 #ifdef VM_TRACE
10950  g_eventLogger->info("initLcpLab aborted due to LCP master takeover - 2");
10951 #endif
10952  return;
10953  }
10954 
10955  //const Uint32 lcpId = SYSFILE->latestLCP_ID;
10956 
10957  for(; tabPtr.i < ctabFileSize; tabPtr.i++){
10958 
10959  ptrAss(tabPtr, tabRecord);
10960 
10961  if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
10962  {
10963  jam();
10964  tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
10965  continue;
10966  }
10967 
10968  if (tabPtr.p->tabStorage != TabRecord::ST_NORMAL) {
10972  jam();
10973  tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
10974  continue;
10975  }
10976 
10977  if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
10978  /* ----------------------------------------------------------------- */
10979  // We protect the updates of table data structures by this variable.
10980  /* ----------------------------------------------------------------- */
10981  jam();
10982  signal->theData[0] = DihContinueB::ZINIT_LCP;
10983  signal->theData[1] = senderRef;
10984  signal->theData[2] = tabPtr.i;
10985  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 20, 3);
10986  return;
10987  }//if
10988 
10992  tabPtr.p->tabLcpStatus = TabRecord::TLS_ACTIVE;
10993 
10997  for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
10998  jam();
10999  FragmentstorePtr fragPtr;
11000  getFragstore(tabPtr.p, fragId, fragPtr);
11001 
11005  Uint32 replicaCount = 0;
11006  ReplicaRecordPtr replicaPtr;
11007  for(replicaPtr.i = fragPtr.p->storedReplicas; replicaPtr.i != RNIL;
11008  replicaPtr.i = replicaPtr.p->nextReplica) {
11009  jam();
11010 
11011  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
11012  Uint32 nodeId = replicaPtr.p->procNode;
11013  if(c_lcpState.m_participatingLQH.get(nodeId)){
11014  jam();
11015  replicaCount++;
11016  replicaPtr.p->lcpOngoingFlag = true;
11017  }
11018  }
11019 
11020  fragPtr.p->noLcpReplicas = replicaCount;
11021  }//for
11022 
11023  signal->theData[0] = DihContinueB::ZINIT_LCP;
11024  signal->theData[1] = senderRef;
11025  signal->theData[2] = tabPtr.i + 1;
11026  sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
11027  return;
11028  }
11029 
11033  jam();
11034 
11035  if (c_lcpState.m_masterLcpDihRef != reference()){
11036  jam();
11037  ndbrequire(!isMaster());
11038  c_lcpState.setLcpStatus(LCP_STATUS_ACTIVE, __LINE__);
11039  } else {
11040  jam();
11041  ndbrequire(isMaster());
11042  }
11043 
11044  CRASH_INSERTION2(7023, isMaster());
11045  CRASH_INSERTION2(7024, !isMaster());
11046 
11047  jam();
11048  StartLcpConf * conf = (StartLcpConf*)signal->getDataPtrSend();
11049  conf->senderRef = reference();
11050  sendSignal(c_lcpState.m_masterLcpDihRef, GSN_START_LCP_CONF, signal,
11051  StartLcpConf::SignalLength, JBB);
11052  return;
11053 }//Dbdih::initLcpLab()
11054 
11055 /* ------------------------------------------------------------------------- */
11056 /* ERROR HANDLING FOR COPY RESTORABLE GCI FILE. */
11057 /* ------------------------------------------------------------------------- */
11058 void Dbdih::openingCopyGciErrorLab(Signal* signal, FileRecordPtr filePtr)
11059 {
11060  createFileRw(signal, filePtr);
11061  /* ------------------------------------------------------------------------- */
11062  /* ERROR IN OPENING FILE. WE WILL TRY BY CREATING FILE INSTEAD. */
11063  /* ------------------------------------------------------------------------- */
11064  filePtr.p->reqStatus = FileRecord::CREATING_COPY_GCI;
11065  return;
11066 }//Dbdih::openingCopyGciErrorLab()
11067 
11068 /* ------------------------------------------------------------------------- */
11069 /* ENTER DICTSTARTCONF WITH */
11070 /* TBLOCKREF */
11071 /* ------------------------------------------------------------------------- */
11072 void Dbdih::dictStartConfLab(Signal* signal)
11073 {
11074  /* ----------------------------------------------------------------------- */
11075  /* WE HAVE NOW RECEIVED ALL THE TABLES TO RESTART. */
11076  /* ----------------------------------------------------------------------- */
11077  signal->theData[0] = DihContinueB::ZSTART_FRAGMENT;
11078  signal->theData[1] = 0; /* START WITH TABLE 0 */
11079  signal->theData[2] = 0; /* AND FRAGMENT 0 */
11080  sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
11081  return;
11082 }//Dbdih::dictStartConfLab()
11083 
11084 
11085 void Dbdih::openingTableLab(Signal* signal, FileRecordPtr filePtr)
11086 {
11087  /* ---------------------------------------------------------------------- */
11088  /* SUCCESSFULLY OPENED A FILE. READ THE FIRST PAGE OF THIS FILE. */
11089  /* ---------------------------------------------------------------------- */
11090  TabRecordPtr tabPtr;
11091  PageRecordPtr pagePtr;
11092 
11093  tabPtr.i = filePtr.p->tabRef;
11094  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
11095  tabPtr.p->noPages = 1;
11096  allocpage(pagePtr);
11097  tabPtr.p->pageRef[0] = pagePtr.i;
11098  readTabfile(signal, tabPtr.p, filePtr);
11099  filePtr.p->reqStatus = FileRecord::READING_TABLE;
11100  return;
11101 }//Dbdih::openingTableLab()
11102 
11103 void Dbdih::openingTableErrorLab(Signal* signal, FileRecordPtr filePtr)
11104 {
11105  TabRecordPtr tabPtr;
11106  tabPtr.i = filePtr.p->tabRef;
11107  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
11108  /* ---------------------------------------------------------------------- */
11109  /* WE FAILED IN OPENING A FILE. IF THE FIRST FILE THEN TRY WITH THE */
11110  /* DUPLICATE FILE, OTHERWISE WE REPORT AN ERROR IN THE SYSTEM RESTART. */
11111  /* ---------------------------------------------------------------------- */
11112  if (filePtr.i == tabPtr.p->tabFile[0])
11113  {
11114  filePtr.i = tabPtr.p->tabFile[1];
11115  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
11116  openFileRw(signal, filePtr);
11117  filePtr.p->reqStatus = FileRecord::OPENING_TABLE;
11118  }
11119  else
11120  {
11121  char buf[256];
11122  BaseString::snprintf(buf, sizeof(buf),
11123  "Error opening DIH schema files for table: %d",
11124  tabPtr.i);
11125  progError(__LINE__, NDBD_EXIT_AFS_NO_SUCH_FILE, buf);
11126  }
11127 }//Dbdih::openingTableErrorLab()
11128 
11129 void Dbdih::readingTableLab(Signal* signal, FileRecordPtr filePtr)
11130 {
11131  TabRecordPtr tabPtr;
11132  PageRecordPtr pagePtr;
11133  /* ---------------------------------------------------------------------- */
11134  /* WE HAVE SUCCESSFULLY READ A NUMBER OF PAGES IN THE TABLE FILE. IF */
11135  /* MORE PAGES EXIST IN THE FILE THEN READ ALL PAGES IN THE FILE. */
11136  /* ---------------------------------------------------------------------- */
11137  filePtr.p->reqStatus = FileRecord::IDLE;
11138  tabPtr.i = filePtr.p->tabRef;
11139  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
11140  pagePtr.i = tabPtr.p->pageRef[0];
11141  ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
11142  Uint32 noOfStoredPages = pagePtr.p->word[33];
11143  if (tabPtr.p->noPages < noOfStoredPages) {
11144  jam();
11145  ndbrequire(noOfStoredPages <= NDB_ARRAY_SIZE(tabPtr.p->pageRef));
11146  for (Uint32 i = tabPtr.p->noPages; i < noOfStoredPages; i++) {
11147  jam();
11148  allocpage(pagePtr);
11149  tabPtr.p->pageRef[i] = pagePtr.i;
11150  }//for
11151  tabPtr.p->noPages = noOfStoredPages;
11152  readTabfile(signal, tabPtr.p, filePtr);
11153  filePtr.p->reqStatus = FileRecord::READING_TABLE;
11154  } else {
11155  ndbrequire(tabPtr.p->noPages == pagePtr.p->word[33]);
11156  ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
11157  jam();
11158  /* --------------------------------------------------------------------- */
11159  /* WE HAVE READ ALL PAGES. NOW READ FROM PAGES INTO TABLE AND FRAGMENT */
11160  /* DATA STRUCTURES. */
11161  /* --------------------------------------------------------------------- */
11162  tabPtr.p->tabCopyStatus = TabRecord::CS_SR_PHASE1_READ_PAGES;
11163  signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_TABLE;
11164  signal->theData[1] = tabPtr.i;
11165  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11166  return;
11167  }//if
11168  return;
11169 }//Dbdih::readingTableLab()
11170 
11171 void Dbdih::readTableFromPagesLab(Signal* signal, TabRecordPtr tabPtr)
11172 {
11173  FileRecordPtr filePtr;
11174  filePtr.i = tabPtr.p->tabFile[0];
11175  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
11176  /* ---------------------------------------------------------------------- */
11177  /* WE HAVE NOW COPIED TO OUR NODE. WE HAVE NOW COMPLETED RESTORING */
11178  /* THIS TABLE. CONTINUE WITH THE NEXT TABLE. */
11179  /* WE ALSO NEED TO CLOSE THE TABLE FILE. */
11180  /* ---------------------------------------------------------------------- */
11181  if (filePtr.p->fileStatus != FileRecord::OPEN) {
11182  jam();
11183  filePtr.i = tabPtr.p->tabFile[1];
11184  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
11185  }//if
11186  closeFile(signal, filePtr);
11187  filePtr.p->reqStatus = FileRecord::CLOSING_TABLE_SR;
11188  return;
11189 }//Dbdih::readTableFromPagesLab()
11190 
11191 void Dbdih::closingTableSrLab(Signal* signal, FileRecordPtr filePtr)
11192 {
11196  TabRecordPtr tabPtr;
11197  tabPtr.i = filePtr.p->tabRef;
11198  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
11199  resetReplicaSr(tabPtr);
11200 
11201  signal->theData[0] = DihContinueB::ZCOPY_TABLE;
11202  signal->theData[1] = filePtr.p->tabRef;
11203  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11204 
11205  return;
11206 }//Dbdih::closingTableSrLab()
11207 
11208 void
11209 Dbdih::execDIH_GET_TABINFO_REQ(Signal* signal)
11210 {
11211  jamEntry();
11212 
11213  DihGetTabInfoReq req = * (DihGetTabInfoReq*)signal->getDataPtr();
11214 
11215  Uint32 err = 0;
11216  do
11217  {
11218  TabRecordPtr tabPtr;
11219  tabPtr.i = req.tableId;
11220  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
11221 
11222  if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
11223  {
11224  jam();
11225  err = DihGetTabInfoRef::TableNotDefined;
11226  break;
11227  }
11228 
11229  if (cfirstconnect == RNIL)
11230  {
11231  jam();
11232  err = DihGetTabInfoRef::OutOfConnectionRecords;
11233  break;
11234  }
11235 
11236  if (tabPtr.p->connectrec != RNIL)
11237  {
11238  jam();
11239 
11240  ConnectRecordPtr connectPtr;
11241  connectPtr.i = tabPtr.p->connectrec;
11242  ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
11243 
11244  if (connectPtr.p->connectState != ConnectRecord::GET_TABINFO)
11245  {
11246  jam();
11247  err = DihGetTabInfoRef::TableBusy;
11248  break;
11249  }
11250  }
11251 
11252  ConnectRecordPtr connectPtr;
11253  connectPtr.i = cfirstconnect;
11254  ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
11255  cfirstconnect = connectPtr.p->nextPool;
11256 
11257  connectPtr.p->nextPool = tabPtr.p->connectrec;
11258  tabPtr.p->connectrec = connectPtr.i;
11259 
11260  connectPtr.p->m_get_tabinfo.m_requestInfo = req.requestInfo;
11261  connectPtr.p->userpointer = req.senderData;
11262  connectPtr.p->userblockref = req.senderRef;
11263  connectPtr.p->connectState = ConnectRecord::GET_TABINFO;
11264  connectPtr.p->table = tabPtr.i;
11265 
11266  if (connectPtr.p->nextPool == RNIL)
11267  {
11268  jam();
11269 
11273  signal->theData[0] = DihContinueB::ZGET_TABINFO;
11274  signal->theData[1] = tabPtr.i;
11275  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11276  }
11277 
11278  return;
11279  } while (0);
11280 
11281  DihGetTabInfoRef * ref = (DihGetTabInfoRef*)signal->getDataPtrSend();
11282  ref->senderData = req.senderData;
11283  ref->senderRef = reference();
11284  ref->errorCode = err;
11285  sendSignal(req.senderRef, GSN_DIH_GET_TABINFO_REF, signal,
11286  DihGetTabInfoRef::SignalLength, JBB);
11287 }
11288 
11289 void
11290 Dbdih::getTabInfo(Signal* signal)
11291 {
11292  TabRecordPtr tabPtr;
11293  tabPtr.i = signal->theData[1];
11294  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
11295 
11296  if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE)
11297  {
11298  jam();
11299  signal->theData[0] = DihContinueB::ZGET_TABINFO;
11300  signal->theData[1] = tabPtr.i;
11301  sendSignalWithDelay(reference(), GSN_CONTINUEB,
11302  signal, 100, signal->length());
11303  return;
11304  }
11305 
11306  tabPtr.p->tabCopyStatus = TabRecord::CS_GET_TABINFO;
11307 
11308  signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
11309  signal->theData[1] = tabPtr.i;
11310  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11311 }
11312 
11313 int
11314 Dbdih::getTabInfo_copyTableToSection(SegmentedSectionPtr & ptr,
11315  CopyTableNode ctn)
11316 {
11317  PageRecordPtr pagePtr;
11318  pagePtr.i = ctn.ctnTabPtr.p->pageRef[0];
11319  ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
11320 
11321  while (ctn.noOfWords > 2048)
11322  {
11323  jam();
11324  ndbrequire(import(ptr, pagePtr.p->word, 2048));
11325  ctn.noOfWords -= 2048;
11326 
11327  ctn.pageIndex++;
11328  pagePtr.i = ctn.ctnTabPtr.p->pageRef[ctn.pageIndex];
11329  ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
11330  }
11331 
11332  ndbrequire(import(ptr, pagePtr.p->word, ctn.noOfWords));
11333  return 0;
11334 }
11335 
11336 int
11337 Dbdih::getTabInfo_copySectionToPages(TabRecordPtr tabPtr,
11338  SegmentedSectionPtr ptr)
11339 {
11340  jam();
11341  Uint32 sz = ptr.sz;
11342  SectionReader reader(ptr, getSectionSegmentPool());
11343 
11344  while (sz)
11345  {
11346  jam();
11347  PageRecordPtr pagePtr;
11348  allocpage(pagePtr);
11349  tabPtr.p->pageRef[tabPtr.p->noPages] = pagePtr.i;
11350  tabPtr.p->noPages++;
11351 
11352  Uint32 len = sz > 2048 ? 2048 : sz;
11353  ndbrequire(reader.getWords(pagePtr.p->word, len));
11354  sz -= len;
11355  }
11356  return 0;
11357 }
11358 
11359 void
11360 Dbdih::getTabInfo_send(Signal* signal,
11361  TabRecordPtr tabPtr)
11362 {
11363  ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_GET_TABINFO);
11364 
11365  ConnectRecordPtr connectPtr;
11366  connectPtr.i = tabPtr.p->connectrec;
11367 
11371  if (connectPtr.i == RNIL)
11372  {
11373  jam();
11374  tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
11375  return;
11376  }
11377 
11378  ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
11379 
11380  ndbrequire(connectPtr.p->connectState == ConnectRecord::GET_TABINFO);
11381  ndbrequire(connectPtr.p->table == tabPtr.i);
11382 
11388  PageRecordPtr pagePtr;
11389  pagePtr.i = tabPtr.p->pageRef[0];
11390  ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
11391  Uint32 words = pagePtr.p->word[34];
11392 
11393  CopyTableNode ctn;
11394  ctn.ctnTabPtr = tabPtr;
11395  ctn.pageIndex = 0;
11396  ctn.wordIndex = 0;
11397  ctn.noOfWords = words;
11398 
11399  SegmentedSectionPtr ptr;
11400  ndbrequire(getTabInfo_copyTableToSection(ptr, ctn) == 0);
11401 
11402  Callback cb = { safe_cast(&Dbdih::getTabInfo_sendComplete), connectPtr.i };
11403 
11404  SectionHandle handle(this, signal);
11405  handle.m_ptr[0] = ptr;
11406  handle.m_cnt = 1;
11407 
11408  DihGetTabInfoConf* conf = (DihGetTabInfoConf*)signal->getDataPtrSend();
11409  conf->senderData = connectPtr.p->userpointer;
11410  conf->senderRef = reference();
11411  sendFragmentedSignal(connectPtr.p->userblockref, GSN_DIH_GET_TABINFO_CONF, signal,
11412  DihGetTabInfoConf::SignalLength, JBB, &handle, cb);
11413 }
11414 
11415 void
11416 Dbdih::getTabInfo_sendComplete(Signal * signal,
11417  Uint32 senderData,
11418  Uint32 retVal)
11419 {
11420  ndbrequire(retVal == 0);
11421 
11422  ConnectRecordPtr connectPtr;
11423  connectPtr.i = senderData;
11424  ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
11425 
11426  ndbrequire(connectPtr.p->connectState == ConnectRecord::GET_TABINFO);
11427 
11428  TabRecordPtr tabPtr;
11429  tabPtr.i = connectPtr.p->table;
11430  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
11431  tabPtr.p->connectrec = connectPtr.p->nextPool;
11432 
11433  signal->theData[0] = DihContinueB::ZGET_TABINFO_SEND;
11434  signal->theData[1] = tabPtr.i;
11435  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11436 
11437  release_connect(connectPtr);
11438 }
11439 
11440 void
11441 Dbdih::resetReplicaSr(TabRecordPtr tabPtr){
11442 
11443  const Uint32 newestRestorableGCI = SYSFILE->newestRestorableGCI;
11444 
11445  for(Uint32 i = 0; i<tabPtr.p->totalfragments; i++)
11446  {
11447  FragmentstorePtr fragPtr;
11448  getFragstore(tabPtr.p, i, fragPtr);
11449 
11453  fragPtr.p->distributionKey = 0;
11454 
11458  prepareReplicas(fragPtr);
11459 
11464  ReplicaRecordPtr replicaPtr;
11465  replicaPtr.i = fragPtr.p->oldStoredReplicas;
11466  while (replicaPtr.i != RNIL)
11467  {
11468  jam();
11469  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
11470 
11474  resetReplica(replicaPtr);
11475 
11476  const Uint32 nextReplicaPtrI = replicaPtr.p->nextReplica;
11477 
11478  NodeRecordPtr nodePtr;
11479  nodePtr.i = replicaPtr.p->procNode;
11480  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
11481 
11482  const Uint32 noCrashedReplicas = replicaPtr.p->noCrashedReplicas;
11483 
11484  if (nodePtr.p->nodeStatus == NodeRecord::ALIVE)
11485  {
11486  jam();
11487  switch (nodePtr.p->activeStatus) {
11488  case Sysfile::NS_Active:
11489  case Sysfile::NS_ActiveMissed_1:
11490  case Sysfile::NS_ActiveMissed_2:{
11491  jam();
11492  /* --------------------------------------------------------------- */
11493  /* THE NODE IS ALIVE AND KICKING AND ACTIVE, LET'S USE IT. */
11494  /* --------------------------------------------------------------- */
11495  arrGuardErr(noCrashedReplicas, MAX_CRASHED_REPLICAS, NDBD_EXIT_MAX_CRASHED_REPLICAS);
11496 
11497  // Create new crashed replica
11498  newCrashedReplica(replicaPtr);
11499 
11500  // Create a new redo-interval
11501  Uint32 nextCrashed = replicaPtr.p->noCrashedReplicas;
11502  replicaPtr.p->createGci[nextCrashed] = newestRestorableGCI + 1;
11503  replicaPtr.p->replicaLastGci[nextCrashed] = ZINIT_REPLICA_LAST_GCI;
11504 
11505  // merge
11506  mergeCrashedReplicas(replicaPtr);
11507 
11508  resetReplicaLcp(replicaPtr.p, newestRestorableGCI);
11509 
11513  {
11514  CreateReplicaRecord createReplica;
11515  ConstPtr<ReplicaRecord> constReplicaPtr;
11516  constReplicaPtr.i = replicaPtr.i;
11517  constReplicaPtr.p = replicaPtr.p;
11518  if (tabPtr.p->tabStorage != TabRecord::ST_NORMAL ||
11519  setup_create_replica(fragPtr,
11520  &createReplica, constReplicaPtr))
11521  {
11522  jam();
11523  removeOldStoredReplica(fragPtr, replicaPtr);
11524  linkStoredReplica(fragPtr, replicaPtr);
11525  }
11526  else
11527  {
11528  jam();
11529  infoEvent("Forcing take-over of node %d due to unsufficient REDO"
11530  " for table %d fragment: %d",
11531  nodePtr.i, tabPtr.i, i);
11532 
11533  m_sr_nodes.clear(nodePtr.i);
11534  m_to_nodes.set(nodePtr.i);
11535  setNodeActiveStatus(nodePtr.i,
11536  Sysfile::NS_NotActive_NotTakenOver);
11537  }
11538  }
11539  }
11540  default:
11541  jam();
11542  /*empty*/;
11543  break;
11544  }
11545  }
11546  replicaPtr.i = nextReplicaPtrI;
11547  }//while
11548  updateNodeInfo(fragPtr);
11549  }
11550 }
11551 
11552 void
11553 Dbdih::resetReplica(ReplicaRecordPtr readReplicaPtr)
11554 {
11555  Uint32 i;
11556  /* ---------------------------------------------------------------------- */
11557  /* IF THE LAST COMPLETED LOCAL CHECKPOINT IS VALID AND LARGER THAN */
11558  /* THE LAST COMPLETED CHECKPOINT THEN WE WILL INVALIDATE THIS LOCAL */
11559  /* CHECKPOINT FOR THIS REPLICA. */
11560  /* ---------------------------------------------------------------------- */
11561  for (i = 0; i < MAX_LCP_STORED; i++)
11562  {
11563  jam();
11564  if (readReplicaPtr.p->lcpStatus[i] == ZVALID &&
11565  readReplicaPtr.p->lcpId[i] > SYSFILE->latestLCP_ID)
11566  {
11567  jam();
11568  readReplicaPtr.p->lcpStatus[i] = ZINVALID;
11569  }
11570  }
11571 
11572  /* ---------------------------------------------------------------------- */
11573  /* WE ALSO HAVE TO INVALIDATE ANY LOCAL CHECKPOINTS THAT HAVE BEEN */
11574  /* INVALIDATED BY MOVING BACK THE RESTART GCI. */
11575  /* ---------------------------------------------------------------------- */
11576  Uint32 lastCompletedGCI = SYSFILE->newestRestorableGCI;
11577  for (i = 0; i < MAX_LCP_STORED; i++)
11578  {
11579  jam();
11580  if (readReplicaPtr.p->lcpStatus[i] == ZVALID &&
11581  readReplicaPtr.p->maxGciStarted[i] > lastCompletedGCI)
11582  {
11583  jam();
11584  readReplicaPtr.p->lcpStatus[i] = ZINVALID;
11585  }
11586  }
11587 
11588  /* ---------------------------------------------------------------------- */
11589  /* WE WILL REMOVE ANY OCCURRENCES OF REPLICAS THAT HAVE CRASHED */
11590  /* THAT ARE NO LONGER VALID DUE TO MOVING RESTART GCI BACKWARDS. */
11591  /* ---------------------------------------------------------------------- */
11592  removeTooNewCrashedReplicas(readReplicaPtr, lastCompletedGCI);
11593 
11600  //removeOldCrashedReplicas(readReplicaPtr);
11601 
11602  /* ---------------------------------------------------------------------- */
11603  /* FIND PROCESSOR RECORD */
11604  /* ---------------------------------------------------------------------- */
11605 }
11606 
11607 void
11608 Dbdih::resetReplicaLcp(ReplicaRecord * replicaP, Uint32 stopGci){
11609 
11610  Uint32 lcpNo = replicaP->nextLcp;
11611  const Uint32 startLcpNo = lcpNo;
11612  do {
11613  lcpNo = prevLcpNo(lcpNo);
11614  ndbrequire(lcpNo < MAX_LCP_STORED);
11615  if (replicaP->lcpStatus[lcpNo] == ZVALID)
11616  {
11617  if (replicaP->maxGciStarted[lcpNo] <= stopGci)
11618  {
11619  jam();
11620  /* ----------------------------------------------------------------- */
11621  /* WE HAVE FOUND A USEFUL LOCAL CHECKPOINT THAT CAN BE USED FOR */
11622  /* RESTARTING THIS FRAGMENT REPLICA. */
11623  /* ----------------------------------------------------------------- */
11624  return ;
11625  }//if
11626  }//if
11627 
11634  replicaP->nextLcp = lcpNo;
11635  replicaP->lcpId[lcpNo] = 0;
11636  replicaP->lcpStatus[lcpNo] = ZINVALID;
11637  } while (lcpNo != startLcpNo);
11638 
11639  replicaP->nextLcp = 0;
11640 }
11641 
11642 void Dbdih::readingTableErrorLab(Signal* signal, FileRecordPtr filePtr)
11643 {
11644  TabRecordPtr tabPtr;
11645  tabPtr.i = filePtr.p->tabRef;
11646  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
11647  /* ---------------------------------------------------------------------- */
11648  /* READING THIS FILE FAILED. CLOSE IT AFTER RELEASING ALL PAGES. */
11649  /* ---------------------------------------------------------------------- */
11650  ndbrequire(tabPtr.p->noPages <= NDB_ARRAY_SIZE(tabPtr.p->pageRef));
11651  for (Uint32 i = 0; i < tabPtr.p->noPages; i++) {
11652  jam();
11653  releasePage(tabPtr.p->pageRef[i]);
11654  }//for
11655  closeFile(signal, filePtr);
11656  filePtr.p->reqStatus = FileRecord::CLOSING_TABLE_CRASH;
11657  return;
11658 }//Dbdih::readingTableErrorLab()
11659 
11660 void Dbdih::closingTableCrashLab(Signal* signal, FileRecordPtr filePtr)
11661 {
11662  TabRecordPtr tabPtr;
11663  /* ---------------------------------------------------------------------- */
11664  /* WE HAVE NOW CLOSED A FILE WHICH WE HAD A READ ERROR WITH. PROCEED */
11665  /* WITH NEXT FILE IF NOT THE LAST OTHERWISE REPORT ERROR. */
11666  /* ---------------------------------------------------------------------- */
11667  tabPtr.i = filePtr.p->tabRef;
11668  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
11669  ndbrequire(filePtr.i == tabPtr.p->tabFile[0]);
11670  filePtr.i = tabPtr.p->tabFile[1];
11671  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
11672  openFileRw(signal, filePtr);
11673  filePtr.p->reqStatus = FileRecord::OPENING_TABLE;
11674 }//Dbdih::closingTableCrashLab()
11675 
11676 /*****************************************************************************/
11677 /* ********** COPY TABLE MODULE *************/
11678 /*****************************************************************************/
11679 void Dbdih::execCOPY_TABREQ(Signal* signal)
11680 {
11681  CRASH_INSERTION(7172);
11682 
11683  TabRecordPtr tabPtr;
11684  PageRecordPtr pagePtr;
11685  jamEntry();
11686  BlockReference ref = signal->theData[0];
11687  Uint32 reqinfo = signal->theData[1];
11688  tabPtr.i = signal->theData[2];
11689  Uint32 schemaVersion = signal->theData[3];
11690  Uint32 noOfWords = signal->theData[4];
11691  ndbrequire(ref == cmasterdihref);
11692  ndbrequire(!isMaster());
11693  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
11694  if (reqinfo == 1) {
11695  jam();
11696  tabPtr.p->schemaVersion = schemaVersion;
11697  initTableFile(tabPtr);
11698  }//if
11699  ndbrequire(tabPtr.p->noPages < NDB_ARRAY_SIZE(tabPtr.p->pageRef));
11700  if (tabPtr.p->noOfWords == 0) {
11701  jam();
11702  allocpage(pagePtr);
11703  tabPtr.p->pageRef[tabPtr.p->noPages] = pagePtr.i;
11704  tabPtr.p->noPages++;
11705  } else {
11706  jam();
11707  pagePtr.i = tabPtr.p->pageRef[tabPtr.p->noPages - 1];
11708  ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
11709  }//if
11710  ndbrequire(tabPtr.p->noOfWords + 15 < 2048);
11711  ndbrequire(tabPtr.p->noOfWords < 2048);
11712  MEMCOPY_NO_WORDS(&pagePtr.p->word[tabPtr.p->noOfWords], &signal->theData[5], 16);
11713  tabPtr.p->noOfWords += 16;
11714  if (tabPtr.p->noOfWords == 2048) {
11715  jam();
11716  tabPtr.p->noOfWords = 0;
11717  }//if
11718  if (noOfWords > 16) {
11719  jam();
11720  return;
11721  }//if
11722  tabPtr.p->noOfWords = 0;
11723  ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
11724  tabPtr.p->tabCopyStatus = TabRecord::CS_COPY_TAB_REQ;
11725  signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_TABLE;
11726  signal->theData[1] = tabPtr.i;
11727  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11728 }//Dbdih::execCOPY_TABREQ()
11729 
11730 void
11731 Dbdih::copyTabReq_complete(Signal* signal, TabRecordPtr tabPtr){
11732  if (!isMaster()) {
11733  jam();
11734  //----------------------------------------------------------------------------
11735  // In this particular case we do not release table pages if we are master. The
11736  // reason is that the master could still be sending the table info to another
11737  // node.
11738  //----------------------------------------------------------------------------
11739  releaseTabPages(tabPtr.i);
11740  tabPtr.p->tabStatus = TabRecord::TS_ACTIVE;
11741  for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
11742  jam();
11743  FragmentstorePtr fragPtr;
11744  getFragstore(tabPtr.p, fragId, fragPtr);
11745  updateNodeInfo(fragPtr);
11746  }//for
11747  }//if
11748  signal->theData[0] = cownNodeId;
11749  signal->theData[1] = tabPtr.i;
11750  sendSignal(cmasterdihref, GSN_COPY_TABCONF, signal, 2, JBB);
11751 }
11752 
11753 /*****************************************************************************/
11754 /* ****** READ FROM A NUMBER OF PAGES INTO THE TABLE DATA STRUCTURES ********/
11755 /*****************************************************************************/
11756 void Dbdih::readPagesIntoTableLab(Signal* signal, Uint32 tableId)
11757 {
11758  RWFragment rf;
11759  rf.wordIndex = 35;
11760  rf.pageIndex = 0;
11761  rf.rwfTabPtr.i = tableId;
11762  ptrCheckGuard(rf.rwfTabPtr, ctabFileSize, tabRecord);
11763  rf.rwfPageptr.i = rf.rwfTabPtr.p->pageRef[0];
11764  ptrCheckGuard(rf.rwfPageptr, cpageFileSize, pageRecord);
11765  rf.rwfTabPtr.p->totalfragments = readPageWord(&rf);
11766  rf.rwfTabPtr.p->noOfBackups = readPageWord(&rf);
11767  rf.rwfTabPtr.p->hashpointer = readPageWord(&rf);
11768  rf.rwfTabPtr.p->kvalue = readPageWord(&rf);
11769  rf.rwfTabPtr.p->mask = readPageWord(&rf);
11770  rf.rwfTabPtr.p->method = (TabRecord::Method)readPageWord(&rf);
11771  /* ------------- */
11772  /* Type of table */
11773  /* ------------- */
11774  rf.rwfTabPtr.p->tabStorage = (TabRecord::Storage)(readPageWord(&rf));
11775 
11776  Uint32 noOfFrags = rf.rwfTabPtr.p->totalfragments;
11777  ndbrequire(noOfFrags > 0);
11778  ndbrequire((noOfFrags * (rf.rwfTabPtr.p->noOfBackups + 1)) <= cnoFreeReplicaRec);
11779  allocFragments(noOfFrags, rf.rwfTabPtr);
11780 
11781  signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_FRAG;
11782  signal->theData[1] = rf.rwfTabPtr.i;
11783  signal->theData[2] = 0;
11784  signal->theData[3] = rf.pageIndex;
11785  signal->theData[4] = rf.wordIndex;
11786  sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
11787  return;
11788 }//Dbdih::readPagesIntoTableLab()
11789 
11790 void Dbdih::readPagesIntoFragLab(Signal* signal, RWFragment* rf)
11791 {
11792  ndbrequire(rf->pageIndex < NDB_ARRAY_SIZE(rf->rwfTabPtr.p->pageRef));
11793  rf->rwfPageptr.i = rf->rwfTabPtr.p->pageRef[rf->pageIndex];
11794  ptrCheckGuard(rf->rwfPageptr, cpageFileSize, pageRecord);
11795  FragmentstorePtr fragPtr;
11796  getFragstore(rf->rwfTabPtr.p, rf->fragId, fragPtr);
11797  readFragment(rf, fragPtr);
11798  readReplicas(rf, fragPtr);
11799  rf->fragId++;
11800  if (rf->fragId == rf->rwfTabPtr.p->totalfragments) {
11801  jam();
11802  switch (rf->rwfTabPtr.p->tabCopyStatus) {
11803  case TabRecord::CS_SR_PHASE1_READ_PAGES:
11804  jam();
11805  releaseTabPages(rf->rwfTabPtr.i);
11806  rf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
11807  signal->theData[0] = DihContinueB::ZREAD_TABLE_FROM_PAGES;
11808  signal->theData[1] = rf->rwfTabPtr.i;
11809  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11810  return;
11811  break;
11812  case TabRecord::CS_COPY_TAB_REQ:
11813  jam();
11814  rf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
11815  if (getNodeState().getSystemRestartInProgress() &&
11816  rf->rwfTabPtr.p->tabStorage == TabRecord::ST_NORMAL)
11817  {
11822  jam();
11823  copyTabReq_complete(signal, rf->rwfTabPtr);
11824  return;
11825  }
11826  rf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
11827  rf->rwfTabPtr.p->tabUpdateState = TabRecord::US_COPY_TAB_REQ;
11828  signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
11829  signal->theData[1] = rf->rwfTabPtr.i;
11830  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11831  return;
11832  break;
11833  default:
11834  ndbrequire(false);
11835  return;
11836  break;
11837  }//switch
11838  } else {
11839  jam();
11840  signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_FRAG;
11841  signal->theData[1] = rf->rwfTabPtr.i;
11842  signal->theData[2] = rf->fragId;
11843  signal->theData[3] = rf->pageIndex;
11844  signal->theData[4] = rf->wordIndex;
11845  sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
11846  }//if
11847  return;
11848 }//Dbdih::readPagesIntoFragLab()
11849 
11850 /*****************************************************************************/
11851 /***** WRITING FROM TABLE DATA STRUCTURES INTO A SET OF PAGES ******/
11852 // execCONTINUEB(ZPACK_TABLE_INTO_PAGES)
11853 /*****************************************************************************/
11854 void Dbdih::packTableIntoPagesLab(Signal* signal, Uint32 tableId)
11855 {
11856  RWFragment wf;
11857  TabRecordPtr tabPtr;
11858  allocpage(wf.rwfPageptr);
11859  tabPtr.i = tableId;
11860  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
11861  tabPtr.p->pageRef[0] = wf.rwfPageptr.i;
11862  tabPtr.p->noPages = 1;
11863  wf.wordIndex = 35;
11864  wf.pageIndex = 0;
11865  Uint32 totalfragments = tabPtr.p->totalfragments;
11866  if (tabPtr.p->connectrec != RNIL)
11867  {
11868  jam();
11869  Ptr<ConnectRecord> connectPtr;
11870  connectPtr.i = tabPtr.p->connectrec;
11871  ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
11872  ndbrequire(connectPtr.p->table == tabPtr.i);
11873  if (connectPtr.p->connectState == ConnectRecord::ALTER_TABLE)
11874  {
11875  jam();
11876  totalfragments = connectPtr.p->m_alter.m_totalfragments;
11877  }
11878  }
11879 
11880  writePageWord(&wf, totalfragments);
11881  writePageWord(&wf, tabPtr.p->noOfBackups);
11882  writePageWord(&wf, tabPtr.p->hashpointer);
11883  writePageWord(&wf, tabPtr.p->kvalue);
11884  writePageWord(&wf, tabPtr.p->mask);
11885  writePageWord(&wf, tabPtr.p->method);
11886  writePageWord(&wf, tabPtr.p->tabStorage);
11887 
11888  signal->theData[0] = DihContinueB::ZPACK_FRAG_INTO_PAGES;
11889  signal->theData[1] = tabPtr.i;
11890  signal->theData[2] = 0;
11891  signal->theData[3] = wf.pageIndex;
11892  signal->theData[4] = wf.wordIndex;
11893  signal->theData[5] = totalfragments;
11894  sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
11895 }//Dbdih::packTableIntoPagesLab()
11896 
11897 /*****************************************************************************/
11898 // execCONTINUEB(ZPACK_FRAG_INTO_PAGES)
11899 /*****************************************************************************/
11900 void Dbdih::packFragIntoPagesLab(Signal* signal, RWFragment* wf)
11901 {
11902  ndbrequire(wf->pageIndex < NDB_ARRAY_SIZE(wf->rwfTabPtr.p->pageRef));
11903  wf->rwfPageptr.i = wf->rwfTabPtr.p->pageRef[wf->pageIndex];
11904  ptrCheckGuard(wf->rwfPageptr, cpageFileSize, pageRecord);
11905  FragmentstorePtr fragPtr;
11906  getFragstore(wf->rwfTabPtr.p, wf->fragId, fragPtr);
11907  writeFragment(wf, fragPtr);
11908  writeReplicas(wf, fragPtr.p->storedReplicas);
11909  writeReplicas(wf, fragPtr.p->oldStoredReplicas);
11910  wf->fragId++;
11911  if (wf->fragId == wf->totalfragments) {
11912  jam();
11913  PageRecordPtr pagePtr;
11914  pagePtr.i = wf->rwfTabPtr.p->pageRef[0];
11915  ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
11916  pagePtr.p->word[33] = wf->rwfTabPtr.p->noPages;
11917  pagePtr.p->word[34] = ((wf->rwfTabPtr.p->noPages - 1) * 2048) + wf->wordIndex;
11918  switch (wf->rwfTabPtr.p->tabCopyStatus) {
11919  case TabRecord::CS_SR_PHASE2_READ_TABLE:
11920  /* -------------------------------------------------------------------*/
11921  // We are performing a system restart and we are now ready to copy the
11922  // table from this node (the master) to all other nodes.
11923  /* -------------------------------------------------------------------*/
11924  jam();
11925  wf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
11926  signal->theData[0] = DihContinueB::ZSR_PHASE2_READ_TABLE;
11927  signal->theData[1] = wf->rwfTabPtr.i;
11928  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11929  return;
11930  break;
11931  case TabRecord::CS_COPY_NODE_STATE:
11932  jam();
11933  tableCopyNodeLab(signal, wf->rwfTabPtr);
11934  return;
11935  break;
11936  case TabRecord::CS_LCP_READ_TABLE:
11937  jam();
11938  signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
11939  signal->theData[1] = wf->rwfTabPtr.i;
11940  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11941  return;
11942  break;
11943  case TabRecord::CS_REMOVE_NODE:
11944  case TabRecord::CS_INVALIDATE_NODE_LCP:
11945  jam();
11946  signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
11947  signal->theData[1] = wf->rwfTabPtr.i;
11948  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11949  return;
11950  break;
11951  case TabRecord::CS_ADD_TABLE_MASTER:
11952  jam();
11953  wf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
11954  signal->theData[0] = DihContinueB::ZADD_TABLE_MASTER_PAGES;
11955  signal->theData[1] = wf->rwfTabPtr.i;
11956  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11957  return;
11958  break;
11959  case TabRecord::CS_ADD_TABLE_SLAVE:
11960  jam();
11961  wf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
11962  signal->theData[0] = DihContinueB::ZADD_TABLE_SLAVE_PAGES;
11963  signal->theData[1] = wf->rwfTabPtr.i;
11964  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11965  return;
11966  case TabRecord::CS_COPY_TO_SAVE:
11967  signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
11968  signal->theData[1] = wf->rwfTabPtr.i;
11969  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11970  return;
11971  case TabRecord::CS_GET_TABINFO:
11972  jam();
11973  signal->theData[0] = DihContinueB::ZGET_TABINFO_SEND;
11974  signal->theData[1] = wf->rwfTabPtr.i;
11975  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11976  return;
11977  default:
11978  ndbrequire(false);
11979  return;
11980  break;
11981  }//switch
11982  } else {
11983  jam();
11984  signal->theData[0] = DihContinueB::ZPACK_FRAG_INTO_PAGES;
11985  signal->theData[1] = wf->rwfTabPtr.i;
11986  signal->theData[2] = wf->fragId;
11987  signal->theData[3] = wf->pageIndex;
11988  signal->theData[4] = wf->wordIndex;
11989  signal->theData[5] = wf->totalfragments;
11990  sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
11991  }//if
11992  return;
11993 }//Dbdih::packFragIntoPagesLab()
11994 
11995 /*****************************************************************************/
11996 /* ********** START FRAGMENT MODULE *************/
11997 /*****************************************************************************/
11998 void
11999 Dbdih::dump_replica_info()
12000 {
12001  TabRecordPtr tabPtr;
12002  FragmentstorePtr fragPtr;
12003 
12004  for(tabPtr.i = 0; tabPtr.i < ctabFileSize; tabPtr.i++)
12005  {
12006  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
12007  if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
12008  continue;
12009 
12010  for(Uint32 fid = 0; fid<tabPtr.p->totalfragments; fid++)
12011  {
12012  getFragstore(tabPtr.p, fid, fragPtr);
12013  ndbout_c("tab: %d frag: %d gci: %d\n",
12014  tabPtr.i, fid, SYSFILE->newestRestorableGCI);
12015 
12016  dump_replica_info(fragPtr.p);
12017  }
12018  }
12019 }
12020 
12021 void
12022 Dbdih::dump_replica_info(const Fragmentstore* fragPtrP)
12023 {
12024  ndbout_c(" -- storedReplicas: ");
12025  Uint32 i;
12026  ReplicaRecordPtr replicaPtr;
12027  replicaPtr.i = fragPtrP->storedReplicas;
12028  for(; replicaPtr.i != RNIL; replicaPtr.i = replicaPtr.p->nextReplica)
12029  {
12030  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
12031  ndbout_c(" node: %d initialGci: %d nextLcp: %d noCrashedReplicas: %d",
12032  replicaPtr.p->procNode,
12033  replicaPtr.p->initialGci,
12034  replicaPtr.p->nextLcp,
12035  replicaPtr.p->noCrashedReplicas);
12036  for(i = 0; i<MAX_LCP_STORED; i++)
12037  {
12038  ndbout_c(" i: %d %s : lcpId: %d maxGci Completed: %d Started: %d",
12039  i,
12040  (replicaPtr.p->lcpStatus[i] == ZVALID ?"VALID":"INVALID"),
12041  replicaPtr.p->lcpId[i],
12042  replicaPtr.p->maxGciCompleted[i],
12043  replicaPtr.p->maxGciStarted[i]);
12044  }
12045 
12046  for (i = 0; i < 8; i++)
12047  {
12048  ndbout_c(" crashed replica: %d replicaLastGci: %d createGci: %d",
12049  i,
12050  replicaPtr.p->replicaLastGci[i],
12051  replicaPtr.p->createGci[i]);
12052  }
12053  }
12054  ndbout_c(" -- oldStoredReplicas");
12055  replicaPtr.i = fragPtrP->oldStoredReplicas;
12056  for(; replicaPtr.i != RNIL; replicaPtr.i = replicaPtr.p->nextReplica)
12057  {
12058  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
12059  ndbout_c(" node: %d initialGci: %d nextLcp: %d noCrashedReplicas: %d",
12060  replicaPtr.p->procNode,
12061  replicaPtr.p->initialGci,
12062  replicaPtr.p->nextLcp,
12063  replicaPtr.p->noCrashedReplicas);
12064  for(i = 0; i<MAX_LCP_STORED; i++)
12065  {
12066  ndbout_c(" i: %d %s : lcpId: %d maxGci Completed: %d Started: %d",
12067  i,
12068  (replicaPtr.p->lcpStatus[i] == ZVALID ?"VALID":"INVALID"),
12069  replicaPtr.p->lcpId[i],
12070  replicaPtr.p->maxGciCompleted[i],
12071  replicaPtr.p->maxGciStarted[i]);
12072  }
12073 
12074  for (i = 0; i < 8; i++)
12075  {
12076  ndbout_c(" crashed replica: %d replicaLastGci: %d createGci: %d",
12077  i,
12078  replicaPtr.p->replicaLastGci[i],
12079  replicaPtr.p->createGci[i]);
12080  }
12081  }
12082 }
12083 
12084 void Dbdih::startFragment(Signal* signal, Uint32 tableId, Uint32 fragId)
12085 {
12086  Uint32 TloopCount = 0;
12087  TabRecordPtr tabPtr;
12088  while (true) {
12089  if (TloopCount > 100) {
12090  jam();
12091  signal->theData[0] = DihContinueB::ZSTART_FRAGMENT;
12092  signal->theData[1] = tableId;
12093  signal->theData[2] = 0;
12094  sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
12095  return;
12096  }
12097 
12098  if (tableId >= ctabFileSize) {
12099  jam();
12100  signal->theData[0] = DihContinueB::ZCOMPLETE_RESTART;
12101  sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
12102  return;
12103  }//if
12104 
12105  tabPtr.i = tableId;
12106  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
12107  if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE){
12108  jam();
12109  TloopCount++;
12110  tableId++;
12111  fragId = 0;
12112  continue;
12113  }
12114 
12115  if(tabPtr.p->tabStorage != TabRecord::ST_NORMAL){
12116  jam();
12117  TloopCount++;
12118  tableId++;
12119  fragId = 0;
12120  continue;
12121  }
12122 
12123  jam();
12124  break;
12125  }//while
12126 
12127  FragmentstorePtr fragPtr;
12128  getFragstore(tabPtr.p, fragId, fragPtr);
12129  /* ----------------------------------------------------------------------- */
12130  /* WE NEED TO RESET THE REPLICA DATA STRUCTURES. THIS MEANS THAT WE */
12131  /* MUST REMOVE REPLICAS THAT WAS NOT STARTED AT THE GCI TO RESTORE. WE */
12132  /* NEED TO PUT ALL STORED REPLICAS ON THE LIST OF OLD STORED REPLICAS */
12133  /* RESET THE NUMBER OF REPLICAS TO CREATE. */
12134  /* ----------------------------------------------------------------------- */
12135  cnoOfCreateReplicas = 0;
12136  /* ----------------------------------------------------------------------- */
12137  /* WE WILL NEVER START MORE THAN FOUR FRAGMENT REPLICAS WHATEVER THE */
12138  /* DESIRED REPLICATION IS. */
12139  /* ----------------------------------------------------------------------- */
12140  ndbrequire(tabPtr.p->noOfBackups < MAX_REPLICAS);
12141  /* ----------------------------------------------------------------------- */
12142  /* SEARCH FOR STORED REPLICAS THAT CAN BE USED TO RESTART THE SYSTEM. */
12143  /* ----------------------------------------------------------------------- */
12144  searchStoredReplicas(fragPtr);
12145 
12146  if (cnoOfCreateReplicas == 0) {
12147  /* --------------------------------------------------------------------- */
12148  /* THERE WERE NO STORED REPLICAS AVAILABLE THAT CAN SERVE AS REPLICA TO*/
12149  /* RESTART THE SYSTEM FROM. IN A LATER RELEASE WE WILL ADD */
12150  /* FUNCTIONALITY TO CHECK IF THERE ARE ANY STANDBY NODES THAT COULD DO */
12151  /* THIS TASK INSTEAD IN THIS IMPLEMENTATION WE SIMPLY CRASH THE SYSTEM.*/
12152  /* THIS WILL DECREASE THE GCI TO RESTORE WHICH HOPEFULLY WILL MAKE IT */
12153  /* POSSIBLE TO RESTORE THE SYSTEM. */
12154  /* --------------------------------------------------------------------- */
12155  char buf[64];
12156  BaseString::snprintf(buf, sizeof(buf), "table: %d fragment: %d gci: %d",
12157  tableId, fragId, SYSFILE->newestRestorableGCI);
12158 
12159  ndbout_c("%s", buf);
12160  dump_replica_info();
12161 
12162  progError(__LINE__, NDBD_EXIT_NO_RESTORABLE_REPLICA, buf);
12163  ndbrequire(false);
12164  return;
12165  }//if
12166 
12167  /* ----------------------------------------------------------------------- */
12168  /* WE HAVE CHANGED THE NODE TO BE PRIMARY REPLICA AND THE NODES TO BE */
12169  /* BACKUP NODES. WE MUST UPDATE THIS NODES DATA STRUCTURE SINCE WE */
12170  /* WILL NOT COPY THE TABLE DATA TO OURSELF. */
12171  /* ----------------------------------------------------------------------- */
12172  updateNodeInfo(fragPtr);
12173  /* ----------------------------------------------------------------------- */
12174  /* NOW WE HAVE COLLECTED ALL THE REPLICAS WE COULD GET. WE WILL NOW */
12175  /* RESTART THE FRAGMENT REPLICAS WE HAVE FOUND IRRESPECTIVE OF IF THERE*/
12176  /* ARE ENOUGH ACCORDING TO THE DESIRED REPLICATION. */
12177  /* ----------------------------------------------------------------------- */
12178  /* WE START BY SENDING ADD_FRAGREQ FOR THOSE REPLICAS THAT NEED IT. */
12179  /* ----------------------------------------------------------------------- */
12180  CreateReplicaRecordPtr createReplicaPtr;
12181  for (createReplicaPtr.i = 0;
12182  createReplicaPtr.i < cnoOfCreateReplicas;
12183  createReplicaPtr.i++) {
12184  jam();
12185  ptrCheckGuard(createReplicaPtr, 4, createReplicaRecord);
12186  }//for
12187 
12188  sendStartFragreq(signal, tabPtr, fragId);
12189 
12193  fragId++;
12194  if (fragId >= tabPtr.p->totalfragments) {
12195  jam();
12196  tabPtr.i++;
12197  fragId = 0;
12198  }//if
12199  signal->theData[0] = DihContinueB::ZSTART_FRAGMENT;
12200  signal->theData[1] = tabPtr.i;
12201  signal->theData[2] = fragId;
12202  sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
12203 
12204  return;
12205 }//Dbdih::startFragmentLab()
12206 
12207 
12208 /*****************************************************************************/
12209 /* ********** COMPLETE RESTART MODULE *************/
12210 /*****************************************************************************/
12211 void Dbdih::completeRestartLab(Signal* signal)
12212 {
12213  sendLoopMacro(START_RECREQ, sendSTART_RECREQ, RNIL);
12214 }//completeRestartLab()
12215 
12216 /* ------------------------------------------------------------------------- */
12217 // SYSTEM RESTART:
12218 /* A NODE HAS COMPLETED RESTORING ALL DATABASE FRAGMENTS. */
12219 // NODE RESTART:
12220 // THE STARTING NODE HAS PREPARED ITS LOG FILES TO ENABLE EXECUTION
12221 // OF TRANSACTIONS.
12222 // Precondition:
12223 // This signal must be received by the master node.
12224 /* ------------------------------------------------------------------------- */
12225 void Dbdih::execSTART_RECCONF(Signal* signal)
12226 {
12227  jamEntry();
12228  Uint32 senderNodeId = signal->theData[0];
12229  Uint32 senderData = signal->theData[1];
12230 
12231  if (senderData != RNIL)
12232  {
12236  Ptr<TakeOverRecord> takeOverPtr;
12237  c_takeOverPool.getPtr(takeOverPtr, senderData);
12238  sendStartTo(signal, takeOverPtr);
12239  return;
12240  }
12241 
12242  /* --------------------------------------------------------------------- */
12243  // This was the system restart case. We set the state indicating that the
12244  // node has completed restoration of all fragments.
12245  /* --------------------------------------------------------------------- */
12246  receiveLoopMacro(START_RECREQ, senderNodeId);
12247 
12251  Uint32 i = 0;
12252  while ((i = m_to_nodes.find(i + 1)) != NdbNodeBitmask::NotFound)
12253  {
12254  jam();
12255  NodeRecordPtr nodePtr;
12256  nodePtr.i = i;
12257  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
12258  nodePtr.p->copyCompleted = 0;
12259  }
12260 
12261  if (m_to_nodes.get(getOwnNodeId()))
12262  {
12267  jam();
12268  c_sr_wait_to = true;
12269  }
12270 
12271  if (!m_to_nodes.isclear() && c_sr_wait_to)
12272  {
12273  jam();
12274 
12275  StartCopyReq* req = (StartCopyReq*)signal->getDataPtrSend();
12276  req->senderRef = reference();
12277  req->senderData = getOwnNodeId();
12278  req->flags = 0; // Note dont wait for LCP
12279 
12280  i = 0;
12281  while ((i = m_to_nodes.find(i + 1)) != NdbNodeBitmask::NotFound)
12282  {
12283  jam();
12284  req->startingNodeId = i;
12285  sendSignal(calcDihBlockRef(i), GSN_START_COPYREQ, signal,
12286  StartCopyReq::SignalLength, JBB);
12287  }
12288 
12289  char buf[100];
12290  infoEvent("Starting take-over of %s", m_to_nodes.getText(buf));
12291  return;
12292  }
12293 
12294  signal->theData[0] = reference();
12295  m_sr_nodes.copyto(NdbNodeBitmask::Size, signal->theData+1);
12296  sendSignal(cntrlblockref, GSN_NDB_STARTCONF, signal,
12297  1 + NdbNodeBitmask::Size, JBB);
12298 }//Dbdih::execSTART_RECCONF()
12299 
12300 void Dbdih::copyNodeLab(Signal* signal, Uint32 tableId)
12301 {
12302  /* ----------------------------------------------------------------------- */
12303  // This code is executed by the master to assist a node restart in receiving
12304  // the data in the master.
12305  /* ----------------------------------------------------------------------- */
12306  Uint32 TloopCount = 0;
12307 
12308  if (!c_nodeStartMaster.activeState) {
12309  jam();
12310  /* --------------------------------------------------------------------- */
12311  // Obviously the node crashed in the middle of its node restart. We will
12312  // stop this process simply by returning after resetting the wait indicator.
12313  /* ---------------------------------------------------------------------- */
12314  c_nodeStartMaster.wait = ZFALSE;
12315  return;
12316  }//if
12317  TabRecordPtr tabPtr;
12318  tabPtr.i = tableId;
12319  while (tabPtr.i < ctabFileSize) {
12320  ptrAss(tabPtr, tabRecord);
12321  if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE)
12322  {
12323  /* -------------------------------------------------------------------- */
12324  // The table is defined. We will start by packing the table into pages.
12325  // The tabCopyStatus indicates to the CONTINUEB(ZPACK_TABLE_INTO_PAGES)
12326  // who called it. After packing the table into page(s) it will be sent to
12327  // the starting node by COPY_TABREQ signals. After returning from the
12328  // starting node we will return to this subroutine and continue
12329  // with the next table.
12330  /* -------------------------------------------------------------------- */
12331  if (! (tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE))
12332  {
12333  jam();
12334  signal->theData[0] = DihContinueB::ZCOPY_NODE;
12335  signal->theData[1] = tabPtr.i;
12336  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
12337  return;
12338  }
12339  ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
12340  tabPtr.p->tabCopyStatus = TabRecord::CS_COPY_NODE_STATE;
12341  signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
12342  signal->theData[1] = tabPtr.i;
12343  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
12344  return;
12345  } else {
12346  jam();
12347  if (TloopCount > 100) {
12348  /* ------------------------------------------------------------------ */
12349  // Introduce real-time break after looping through 100 not copied tables
12350  /* ----------------------------------------------------------------- */
12351  jam();
12352  signal->theData[0] = DihContinueB::ZCOPY_NODE;
12353  signal->theData[1] = tabPtr.i + 1;
12354  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
12355  return;
12356  } else {
12357  jam();
12358  TloopCount++;
12359  tabPtr.i++;
12360  }//if
12361  }//if
12362  }//while
12363  dihCopyCompletedLab(signal);
12364  return;
12365 }//Dbdih::copyNodeLab()
12366 
12367 void Dbdih::tableCopyNodeLab(Signal* signal, TabRecordPtr tabPtr)
12368 {
12369  /* ----------------------------------------------------------------------- */
12370  /* COPY PAGES READ TO STARTING NODE. */
12371  /* ----------------------------------------------------------------------- */
12372  if (!c_nodeStartMaster.activeState) {
12373  jam();
12374  releaseTabPages(tabPtr.i);
12375  c_nodeStartMaster.wait = ZFALSE;
12376  return;
12377  }//if
12378  NodeRecordPtr copyNodePtr;
12379  PageRecordPtr pagePtr;
12380  copyNodePtr.i = c_nodeStartMaster.startNode;
12381  ptrCheckGuard(copyNodePtr, MAX_NDB_NODES, nodeRecord);
12382 
12383  copyNodePtr.p->activeTabptr = tabPtr.i;
12384  pagePtr.i = tabPtr.p->pageRef[0];
12385  ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
12386 
12387  signal->theData[0] = DihContinueB::ZCOPY_TABLE_NODE;
12388  signal->theData[1] = tabPtr.i;
12389  signal->theData[2] = copyNodePtr.i;
12390  signal->theData[3] = 0;
12391  signal->theData[4] = 0;
12392  signal->theData[5] = pagePtr.p->word[34];
12393  sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
12394 }//Dbdih::tableCopyNodeLab()
12395 
12396 /* ------------------------------------------------------------------------- */
12397 // execCONTINUEB(ZCOPY_TABLE)
12398 // This routine is used to copy the table descriptions from the master to
12399 // other nodes. It is used in the system restart to copy from master to all
12400 // starting nodes.
12401 /* ------------------------------------------------------------------------- */
12402 void Dbdih::copyTableLab(Signal* signal, Uint32 tableId)
12403 {
12404  TabRecordPtr tabPtr;
12405  tabPtr.i = tableId;
12406  ptrAss(tabPtr, tabRecord);
12407 
12408  ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
12409  tabPtr.p->tabCopyStatus = TabRecord::CS_SR_PHASE2_READ_TABLE;
12410  signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
12411  signal->theData[1] = tabPtr.i;
12412  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
12413  return;
12414 }//Dbdih::copyTableLab()
12415 
12416 /* ------------------------------------------------------------------------- */
12417 // execCONTINUEB(ZSR_PHASE2_READ_TABLE)
12418 /* ------------------------------------------------------------------------- */
12419 void Dbdih::srPhase2ReadTableLab(Signal* signal, TabRecordPtr tabPtr)
12420 {
12421  /* ----------------------------------------------------------------------- */
12422  // We set the sendCOPY_TABREQState to ZACTIVE for all nodes since it is a long
12423  // process to send off all table descriptions. Thus we ensure that we do
12424  // not encounter race conditions where one node is completed before the
12425  // sending process is completed. This could lead to that we start off the
12426  // system before we actually finished all copying of table descriptions
12427  // and could lead to strange errors.
12428  /* ----------------------------------------------------------------------- */
12429 
12430  //sendLoopMacro(COPY_TABREQ, nullRoutine);
12431 
12432  breakCopyTableLab(signal, tabPtr, cfirstAliveNode);
12433  return;
12434 }//Dbdih::srPhase2ReadTableLab()
12435 
12436 /* ------------------------------------------------------------------------- */
12437 /* COPY PAGES READ TO ALL NODES. */
12438 /* ------------------------------------------------------------------------- */
12439 void Dbdih::breakCopyTableLab(Signal* signal, TabRecordPtr tabPtr, Uint32 nodeId)
12440 {
12441  NodeRecordPtr nodePtr;
12442  nodePtr.i = nodeId;
12443  while (nodePtr.i != RNIL) {
12444  jam();
12445  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
12446  if (nodePtr.i == getOwnNodeId()){
12447  jam();
12448  /* ------------------------------------------------------------------- */
12449  /* NOT NECESSARY TO COPY TO MY OWN NODE. I ALREADY HAVE THE PAGES. */
12450  /* I DO HOWEVER NEED TO STORE THE TABLE DESCRIPTION ONTO DISK. */
12451  /* ------------------------------------------------------------------- */
12452  /* IF WE ARE MASTER WE ONLY NEED TO SAVE THE TABLE ON DISK. WE ALREADY */
12453  /* HAVE THE TABLE DESCRIPTION IN THE DATA STRUCTURES. */
12454  // AFTER COMPLETING THE WRITE TO DISK THE MASTER WILL ALSO SEND
12455  // COPY_TABCONF AS ALL THE OTHER NODES.
12456  /* ------------------------------------------------------------------- */
12457  c_COPY_TABREQ_Counter.setWaitingFor(nodePtr.i);
12458  tabPtr.p->tabUpdateState = TabRecord::US_COPY_TAB_REQ;
12459  signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
12460  signal->theData[1] = tabPtr.i;
12461  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
12462  nodePtr.i = nodePtr.p->nextNode;
12463  } else {
12464  PageRecordPtr pagePtr;
12465  /* -------------------------------------------------------------------- */
12466  // RATHER THAN SENDING ALL COPY_TABREQ IN PARALLEL WE WILL SERIALISE THIS
12467  // ACTIVITY AND WILL THUS CALL breakCopyTableLab AGAIN WHEN COMPLETED THE
12468  // SENDING OF COPY_TABREQ'S.
12469  /* -------------------------------------------------------------------- */
12470  jam();
12471  tabPtr.p->tabCopyStatus = TabRecord::CS_SR_PHASE3_COPY_TABLE;
12472  pagePtr.i = tabPtr.p->pageRef[0];
12473  ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
12474  signal->theData[0] = DihContinueB::ZCOPY_TABLE_NODE;
12475  signal->theData[1] = tabPtr.i;
12476  signal->theData[2] = nodePtr.i;
12477  signal->theData[3] = 0;
12478  signal->theData[4] = 0;
12479  signal->theData[5] = pagePtr.p->word[34];
12480  sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
12481  return;
12482  }//if
12483  }//while
12484  /* ----------------------------------------------------------------------- */
12485  /* WE HAVE NOW SENT THE TABLE PAGES TO ALL NODES. EXIT AND WAIT FOR ALL */
12486  /* REPLIES. */
12487  /* ----------------------------------------------------------------------- */
12488  return;
12489 }//Dbdih::breakCopyTableLab()
12490 
12491 /* ------------------------------------------------------------------------- */
12492 // execCONTINUEB(ZCOPY_TABLE_NODE)
12493 /* ------------------------------------------------------------------------- */
12494 void Dbdih::copyTableNode(Signal* signal,
12495  CopyTableNode* ctn, NodeRecordPtr nodePtr)
12496 {
12497  if (getNodeState().startLevel >= NodeState::SL_STARTED){
12498  /* --------------------------------------------------------------------- */
12499  // We are in the process of performing a node restart and are copying a
12500  // table description to a starting node. We will check that no nodes have
12501  // crashed in this process.
12502  /* --------------------------------------------------------------------- */
12503  if (!c_nodeStartMaster.activeState) {
12504  jam();
12509  releaseTabPages(ctn->ctnTabPtr.i);
12510  c_nodeStartMaster.wait = ZFALSE;
12511  return;
12512  }//if
12513  }//if
12514  ndbrequire(ctn->pageIndex < NDB_ARRAY_SIZE(ctn->ctnTabPtr.p->pageRef));
12515  ctn->ctnPageptr.i = ctn->ctnTabPtr.p->pageRef[ctn->pageIndex];
12516  ptrCheckGuard(ctn->ctnPageptr, cpageFileSize, pageRecord);
12520  Uint32 reqinfo = (ctn->pageIndex == 0) && (ctn->wordIndex == 0);
12521  if(reqinfo == 1){
12522  c_COPY_TABREQ_Counter.setWaitingFor(nodePtr.i);
12523  }
12524 
12525  for (Uint32 i = 0; i < 16; i++) {
12526  jam();
12527  sendCopyTable(signal, ctn, calcDihBlockRef(nodePtr.i), reqinfo);
12528  reqinfo = 0;
12529  if (ctn->noOfWords <= 16) {
12530  jam();
12531  switch (ctn->ctnTabPtr.p->tabCopyStatus) {
12532  case TabRecord::CS_SR_PHASE3_COPY_TABLE:
12533  /* ------------------------------------------------------------------ */
12534  // We have copied the table description to this node.
12535  // We will now proceed
12536  // with sending the table description to the next node in the node list.
12537  /* ------------------------------------------------------------------ */
12538  jam();
12539  ctn->ctnTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
12540  breakCopyTableLab(signal, ctn->ctnTabPtr, nodePtr.p->nextNode);
12541  return;
12542  break;
12543  case TabRecord::CS_COPY_NODE_STATE:
12544  jam();
12545  ctn->ctnTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
12546  return;
12547  break;
12548  default:
12549  ndbrequire(false);
12550  break;
12551  }//switch
12552  } else {
12553  jam();
12554  ctn->wordIndex += 16;
12555  if (ctn->wordIndex == 2048) {
12556  jam();
12557  ctn->wordIndex = 0;
12558  ctn->pageIndex++;
12559  ndbrequire(ctn->pageIndex < NDB_ARRAY_SIZE(ctn->ctnTabPtr.p->pageRef));
12560  ctn->ctnPageptr.i = ctn->ctnTabPtr.p->pageRef[ctn->pageIndex];
12561  ptrCheckGuard(ctn->ctnPageptr, cpageFileSize, pageRecord);
12562  }//if
12563  ctn->noOfWords -= 16;
12564  }//if
12565  }//for
12566  signal->theData[0] = DihContinueB::ZCOPY_TABLE_NODE;
12567  signal->theData[1] = ctn->ctnTabPtr.i;
12568  signal->theData[2] = nodePtr.i;
12569  signal->theData[3] = ctn->pageIndex;
12570  signal->theData[4] = ctn->wordIndex;
12571  signal->theData[5] = ctn->noOfWords;
12572  sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
12573 }//Dbdih::copyTableNodeLab()
12574 
12575 void Dbdih::sendCopyTable(Signal* signal, CopyTableNode* ctn,
12576  BlockReference ref, Uint32 reqinfo)
12577 {
12578  signal->theData[0] = reference();
12579  signal->theData[1] = reqinfo;
12580  signal->theData[2] = ctn->ctnTabPtr.i;
12581  signal->theData[3] = ctn->ctnTabPtr.p->schemaVersion;
12582  signal->theData[4] = ctn->noOfWords;
12583  ndbrequire(ctn->wordIndex + 15 < 2048);
12584  MEMCOPY_NO_WORDS(&signal->theData[5], &ctn->ctnPageptr.p->word[ctn->wordIndex], 16);
12585  sendSignal(ref, GSN_COPY_TABREQ, signal, 21, JBB);
12586 }//Dbdih::sendCopyTable()
12587 
12588 void Dbdih::execCOPY_TABCONF(Signal* signal)
12589 {
12590  NodeRecordPtr nodePtr;
12591  jamEntry();
12592  nodePtr.i = signal->theData[0];
12593  Uint32 tableId = signal->theData[1];
12594  if (getNodeState().startLevel >= NodeState::SL_STARTED){
12595  /* --------------------------------------------------------------------- */
12596  // We are in the process of performing a node restart. Continue by copying
12597  // the next table to the starting node.
12598  /* --------------------------------------------------------------------- */
12599  jam();
12600  NodeRecordPtr nodePtr;
12601  nodePtr.i = signal->theData[0];
12602  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
12603  c_COPY_TABREQ_Counter.clearWaitingFor(nodePtr.i);
12604 
12605  releaseTabPages(tableId);
12606  signal->theData[0] = DihContinueB::ZCOPY_NODE;
12607  signal->theData[1] = tableId + 1;
12608  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
12609  return;
12610  } else {
12611  /* --------------------------------------------------------------------- */
12612  // We are in the process of performing a system restart. Check if all nodes
12613  // have saved the new table description to file and then continue with the
12614  // next table.
12615  /* --------------------------------------------------------------------- */
12616  receiveLoopMacro(COPY_TABREQ, nodePtr.i);
12617  /* --------------------------------------------------------------------- */
12618  /* WE HAVE NOW COPIED TO ALL NODES. WE HAVE NOW COMPLETED RESTORING */
12619  /* THIS TABLE. CONTINUE WITH THE NEXT TABLE. */
12620  /* WE NEED TO RELEASE THE PAGES IN THE TABLE IN THIS NODE HERE. */
12621  /* WE ALSO NEED TO CLOSE THE TABLE FILE. */
12622  /* --------------------------------------------------------------------- */
12623  releaseTabPages(tableId);
12624 
12625  TabRecordPtr tabPtr;
12626  tabPtr.i = tableId;
12627  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
12628 
12629  ConnectRecordPtr connectPtr;
12630  connectPtr.i = tabPtr.p->connectrec;
12631  ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
12632 
12633  connectPtr.p->m_alter.m_totalfragments = tabPtr.p->totalfragments;
12634  sendAddFragreq(signal, connectPtr, tabPtr, 0);
12635  return;
12636  }//if
12637 }//Dbdih::execCOPY_TABCONF()
12638 
12639 /*
12640  3.13 L O C A L C H E C K P O I N T (M A S T E R)
12641  ****************************************************
12642  */
12643 /*****************************************************************************/
12644 /* ********** LOCAL-CHECK-POINT-HANDLING MODULE *************/
12645 /*****************************************************************************/
12646 /* ------------------------------------------------------------------------- */
12647 /* IT IS TIME TO CHECK IF IT IS TIME TO START A LOCAL CHECKPOINT. */
12648 /* WE WILL EITHER START AFTER 1 MILLION WORDS HAVE ARRIVED OR WE WILL */
12649 /* EXECUTE AFTER ABOUT 16 MINUTES HAVE PASSED BY. */
12650 /* ------------------------------------------------------------------------- */
12651 void Dbdih::checkTcCounterLab(Signal* signal)
12652 {
12653  CRASH_INSERTION(7009);
12654  if (c_lcpState.lcpStatus != LCP_STATUS_IDLE) {
12655  g_eventLogger->error("lcpStatus = %u"
12656  "lcpStatusUpdatedPlace = %d",
12657  (Uint32) c_lcpState.lcpStatus,
12658  c_lcpState.lcpStatusUpdatedPlace);
12659  ndbrequire(false);
12660  return;
12661  }//if
12662  add_lcp_counter(&c_lcpState.ctimer, 32);
12663  if ((c_nodeStartMaster.blockLcp == true) ||
12664  (c_lcpState.lcpStopGcp >= c_newest_restorable_gci)) {
12665  jam();
12666  /* --------------------------------------------------------------------- */
12667  // No reason to start juggling the states and checking for start of LCP if
12668  // we are blocked to start an LCP anyway.
12669  // We also block LCP start if we have not completed one global checkpoints
12670  // before starting another local checkpoint.
12671  /* --------------------------------------------------------------------- */
12672  signal->theData[0] = DihContinueB::ZCHECK_TC_COUNTER;
12673  signal->theData[1] = __LINE__;
12674  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1 * 100, 2);
12675  return;
12676  }//if
12677  c_lcpState.setLcpStatus(LCP_TCGET, __LINE__);
12678 
12679  c_lcpState.ctcCounter = c_lcpState.ctimer;
12680  sendLoopMacro(TCGETOPSIZEREQ, sendTCGETOPSIZEREQ, RNIL);
12681 }//Dbdih::checkTcCounterLab()
12682 
12683 void Dbdih::checkLcpStart(Signal* signal, Uint32 lineNo)
12684 {
12685  /* ----------------------------------------------------------------------- */
12686  // Verify that we are not attempting to start another instance of the LCP
12687  // when it is not alright to do so.
12688  /* ----------------------------------------------------------------------- */
12689  ndbrequire(c_lcpState.lcpStart == ZIDLE);
12690  c_lcpState.lcpStart = ZACTIVE;
12691  signal->theData[0] = DihContinueB::ZCHECK_TC_COUNTER;
12692  signal->theData[1] = lineNo;
12693  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 2);
12694 }//Dbdih::checkLcpStart()
12695 
12696 /* ------------------------------------------------------------------------- */
12697 /*TCGETOPSIZECONF HOW MUCH OPERATION SIZE HAVE BEEN EXECUTED BY TC */
12698 /* ------------------------------------------------------------------------- */
12699 void Dbdih::execTCGETOPSIZECONF(Signal* signal)
12700 {
12701  jamEntry();
12702  Uint32 senderNodeId = signal->theData[0];
12703  add_lcp_counter(&c_lcpState.ctcCounter, signal->theData[1]);
12704 
12705  receiveLoopMacro(TCGETOPSIZEREQ, senderNodeId);
12706 
12707  ndbrequire(c_lcpState.lcpStatus == LCP_TCGET);
12708  ndbrequire(c_lcpState.lcpStart == ZACTIVE);
12709  /* ----------------------------------------------------------------------- */
12710  // We are not actively starting another LCP, still we receive this signal.
12711  // This is not ok.
12712  /* ---------------------------------------------------------------------- */
12713  /* ALL TC'S HAVE RESPONDED NOW. NOW WE WILL CHECK IF ENOUGH OPERATIONS */
12714  /* HAVE EXECUTED TO ENABLE US TO START A NEW LOCAL CHECKPOINT. */
12715  /* WHILE COPYING DICTIONARY AND DISTRIBUTION INFO TO A STARTING NODE */
12716  /* WE WILL ALSO NOT ALLOW THE LOCAL CHECKPOINT TO PROCEED. */
12717  /*----------------------------------------------------------------------- */
12718  if (c_lcpState.immediateLcpStart == false)
12719  {
12720  Uint64 cnt = Uint64(c_lcpState.ctcCounter);
12721  Uint64 limit = Uint64(1) << c_lcpState.clcpDelay;
12722  bool dostart = cnt >= limit;
12723  if (dostart == false || c_nodeStartMaster.blockLcp == true)
12724  {
12725  jam();
12726  c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
12727 
12728  signal->theData[0] = DihContinueB::ZCHECK_TC_COUNTER;
12729  signal->theData[1] = __LINE__;
12730  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1 * 100, 2);
12731  return;
12732  }//if
12733  }//if
12734  c_lcpState.lcpStart = ZIDLE;
12735  c_lcpState.immediateLcpStart = false;
12736  /* -----------------------------------------------------------------------
12737  * Now the initial lcp is started,
12738  * we can reset the delay to its orginal value
12739  * --------------------------------------------------------------------- */
12740  CRASH_INSERTION(7010);
12741  /* ----------------------------------------------------------------------- */
12742  /* IF MORE THAN 1 MILLION WORDS PASSED THROUGH THE TC'S THEN WE WILL */
12743  /* START A NEW LOCAL CHECKPOINT. CLEAR CTIMER. START CHECKPOINT */
12744  /* ACTIVITY BY CALCULATING THE KEEP GLOBAL CHECKPOINT. */
12745  // Also remember the current global checkpoint to ensure that we run at least
12746  // one global checkpoints between each local checkpoint that we start up.
12747  /* ----------------------------------------------------------------------- */
12748  c_lcpState.ctimer = 0;
12749  c_lcpState.keepGci = (Uint32)(m_micro_gcp.m_old_gci >> 32);
12750  c_lcpState.oldestRestorableGci = SYSFILE->oldestRestorableGCI;
12751 
12752  CRASH_INSERTION(7014);
12753  c_lcpState.setLcpStatus(LCP_TC_CLOPSIZE, __LINE__);
12754  sendLoopMacro(TC_CLOPSIZEREQ, sendTC_CLOPSIZEREQ, RNIL);
12755 }
12756 
12757 void Dbdih::execTC_CLOPSIZECONF(Signal* signal)
12758 {
12759  jamEntry();
12760  Uint32 senderNodeId = signal->theData[0];
12761  receiveLoopMacro(TC_CLOPSIZEREQ, senderNodeId);
12762 
12763  ndbrequire(c_lcpState.lcpStatus == LCP_TC_CLOPSIZE);
12764 
12765  /* ----------------------------------------------------------------------- */
12766  /* UPDATE THE NEW LATEST LOCAL CHECKPOINT ID. */
12767  /* ----------------------------------------------------------------------- */
12768  cnoOfActiveTables = 0;
12769  c_lcpState.setLcpStatus(LCP_CALCULATE_KEEP_GCI, __LINE__);
12770  ndbrequire(((int)c_lcpState.oldestRestorableGci) > 0);
12771 
12772  if (ERROR_INSERTED(7011)) {
12773  signal->theData[0] = NDB_LE_LCPStoppedInCalcKeepGci;
12774  signal->theData[1] = 0;
12775  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
12776  return;
12777  }//if
12778 
12779  Mutex mutex(signal, c_mutexMgr, c_fragmentInfoMutex_lcp);
12780  Callback c = { safe_cast(&Dbdih::lcpFragmentMutex_locked), 0 };
12781  ndbrequire(mutex.trylock(c, false));
12782 }
12783 
12784 void
12785 Dbdih::lcpFragmentMutex_locked(Signal* signal,
12786  Uint32 senderData,
12787  Uint32 retVal)
12788 {
12789  jamEntry();
12790 
12791  if (retVal == UtilLockRef::LockAlreadyHeld)
12792  {
12793  jam();
12794  Mutex mutex(signal, c_mutexMgr, c_fragmentInfoMutex_lcp);
12795  mutex.release();
12796 
12797  if (senderData == 0)
12798  {
12799  jam();
12800  infoEvent("Local checkpoint blocked waiting for node-restart");
12801  }
12802 
12803  // 2* is as parameter is in seconds, and we sendSignalWithDelay 500ms
12804  if (senderData >= 2*c_lcpState.m_lcp_trylock_timeout)
12805  {
12806  jam();
12807  Callback c = { safe_cast(&Dbdih::lcpFragmentMutex_locked), 0 };
12808  ndbrequire(mutex.lock(c, false));
12809  return;
12810  }
12811  signal->theData[0] = DihContinueB::ZLCP_TRY_LOCK;
12812  signal->theData[1] = senderData + 1;
12813  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 500, 2);
12814  return;
12815  }
12816 
12817  ndbrequire(retVal == 0);
12818 
12819  c_lcpState.m_start_time = c_current_time;
12820 
12821  setLcpActiveStatusStart(signal);
12822 
12823  c_lcpState.keepGci = m_micro_gcp.m_old_gci >> 32;
12824  c_lcpState.oldestRestorableGci = SYSFILE->oldestRestorableGCI;
12825 
12826  signal->theData[0] = DihContinueB::ZCALCULATE_KEEP_GCI;
12827  signal->theData[1] = 0; /* TABLE ID = 0 */
12828  signal->theData[2] = 0; /* FRAGMENT ID = 0 */
12829  sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
12830  return;
12831 }//Dbdih::execTCGETOPSIZECONF()
12832 
12833 /* ------------------------------------------------------------------------- */
12834 /* WE NEED TO CALCULATE THE OLDEST GLOBAL CHECKPOINT THAT WILL BE */
12835 /* COMPLETELY RESTORABLE AFTER EXECUTING THIS LOCAL CHECKPOINT. */
12836 /* ------------------------------------------------------------------------- */
12837 void Dbdih::calculateKeepGciLab(Signal* signal, Uint32 tableId, Uint32 fragId)
12838 {
12839  TabRecordPtr tabPtr;
12840  Uint32 TloopCount = 1;
12841  tabPtr.i = tableId;
12842  do {
12843  if (tabPtr.i >= ctabFileSize) {
12844  if (cnoOfActiveTables > 0) {
12845  jam();
12846  signal->theData[0] = DihContinueB::ZSTORE_NEW_LCP_ID;
12847  sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
12848  return;
12849  } else {
12850  jam();
12851  /* ------------------------------------------------------------------ */
12852  /* THERE ARE NO TABLES TO CHECKPOINT. WE STOP THE CHECKPOINT ALREADY */
12853  /* HERE TO AVOID STRANGE PROBLEMS LATER. */
12854  /* ------------------------------------------------------------------ */
12855  c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
12856  checkLcpStart(signal, __LINE__);
12857  return;
12858  }//if
12859  }//if
12860  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
12861  if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE ||
12862  tabPtr.p->tabStorage != TabRecord::ST_NORMAL) {
12863  if (TloopCount > 100) {
12864  jam();
12865  signal->theData[0] = DihContinueB::ZCALCULATE_KEEP_GCI;
12866  signal->theData[1] = tabPtr.i + 1;
12867  signal->theData[2] = 0;
12868  sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
12869  return;
12870  } else {
12871  jam();
12872  TloopCount++;
12873  tabPtr.i++;
12874  }//if
12875  } else {
12876  jam();
12877  TloopCount = 0;
12878  }//if
12879  } while (TloopCount != 0);
12880  cnoOfActiveTables++;
12881  FragmentstorePtr fragPtr;
12882  getFragstore(tabPtr.p, fragId, fragPtr);
12883  checkKeepGci(tabPtr, fragId, fragPtr.p, fragPtr.p->storedReplicas);
12884  checkKeepGci(tabPtr, fragId, fragPtr.p, fragPtr.p->oldStoredReplicas);
12885  fragId++;
12886  if (fragId >= tabPtr.p->totalfragments) {
12887  jam();
12888  tabPtr.i++;
12889  fragId = 0;
12890  }//if
12891  signal->theData[0] = DihContinueB::ZCALCULATE_KEEP_GCI;
12892  signal->theData[1] = tabPtr.i;
12893  signal->theData[2] = fragId;
12894  sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
12895  return;
12896 }//Dbdih::calculateKeepGciLab()
12897 
12898 /* ------------------------------------------------------------------------- */
12899 /* WE NEED TO STORE ON DISK THE FACT THAT WE ARE STARTING THIS LOCAL */
12900 /* CHECKPOINT ROUND. THIS WILL INVALIDATE ALL THE LOCAL CHECKPOINTS */
12901 /* THAT WILL EVENTUALLY BE OVERWRITTEN AS PART OF THIS LOCAL CHECKPOINT*/
12902 /* ------------------------------------------------------------------------- */
12903 void Dbdih::storeNewLcpIdLab(Signal* signal)
12904 {
12905  signal->theData[0] = NDB_LE_LocalCheckpointStarted; //Event type
12906  signal->theData[1] = SYSFILE->latestLCP_ID + 1;
12907  signal->theData[2] = c_lcpState.keepGci;
12908  signal->theData[3] = c_lcpState.oldestRestorableGci;
12909  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
12910 
12911  /***************************************************************************/
12912  // Report the event that a local checkpoint has started.
12913  /***************************************************************************/
12914 
12915  signal->setTrace(TestOrd::TraceLocalCheckpoint);
12916 
12917  CRASH_INSERTION(7013);
12918  SYSFILE->keepGCI = c_lcpState.keepGci;
12919  //Uint32 lcpId = SYSFILE->latestLCP_ID;
12920  SYSFILE->latestLCP_ID++;
12921  SYSFILE->oldestRestorableGCI = c_lcpState.oldestRestorableGci;
12922 
12923  const Uint32 oldestRestorableGCI = SYSFILE->oldestRestorableGCI;
12924  //const Uint32 newestRestorableGCI = SYSFILE->newestRestorableGCI;
12925  //ndbrequire(newestRestorableGCI >= oldestRestorableGCI);
12926 
12927  Int32 val = oldestRestorableGCI;
12928  ndbrequire(val > 0);
12929 
12930  /* ----------------------------------------------------------------------- */
12931  /* SET BIT INDICATING THAT LOCAL CHECKPOINT IS ONGOING. THIS IS CLEARED */
12932  /* AT THE END OF A LOCAL CHECKPOINT. */
12933  /* ----------------------------------------------------------------------- */
12934  SYSFILE->setLCPOngoing(SYSFILE->systemRestartBits);
12935  /* ---------------------------------------------------------------------- */
12936  /* CHECK IF ANY NODE MUST BE TAKEN OUT OF SERVICE AND REFILLED WITH */
12937  /* NEW FRESH DATA FROM AN ACTIVE NODE. */
12938  /* ---------------------------------------------------------------------- */
12939 
12945  setNodeRestartInfoBits(signal);
12946 
12947  c_lcpState.setLcpStatus(LCP_COPY_GCI, __LINE__);
12948  //#ifdef VM_TRACE
12949  // infoEvent("LocalCheckpoint %d started", SYSFILE->latestLCP_ID);
12950  // signal->theData[0] = 7012;
12951  // execDUMP_STATE_ORD(signal);
12952  //#endif
12953 
12954  copyGciLab(signal, CopyGCIReq::LOCAL_CHECKPOINT);
12955 }//Dbdih::storeNewLcpIdLab()
12956 
12957 void Dbdih::startLcpRoundLab(Signal* signal) {
12958  jam();
12959 
12960  CRASH_INSERTION(7218);
12961 
12962  Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
12963  Callback c = { safe_cast(&Dbdih::startLcpMutex_locked), 0 };
12964  ndbrequire(mutex.lock(c));
12965 }
12966 
12967 void
12968 Dbdih::startLcpMutex_locked(Signal* signal, Uint32 senderData, Uint32 retVal){
12969  jamEntry();
12970  ndbrequire(retVal == 0);
12971 
12972  StartLcpReq* req = (StartLcpReq*)signal->getDataPtrSend();
12973  req->senderRef = reference();
12974  req->lcpId = SYSFILE->latestLCP_ID;
12975  req->participatingLQH = c_lcpState.m_participatingLQH;
12976  req->participatingDIH = c_lcpState.m_participatingDIH;
12977  sendLoopMacro(START_LCP_REQ, sendSTART_LCP_REQ, RNIL);
12978 }
12979 
12980 void
12981 Dbdih::sendSTART_LCP_REQ(Signal* signal, Uint32 nodeId, Uint32 extra){
12982  BlockReference ref = calcDihBlockRef(nodeId);
12983  if (ERROR_INSERTED(7021) && nodeId == getOwnNodeId())
12984  {
12985  sendSignalWithDelay(ref, GSN_START_LCP_REQ, signal, 500,
12986  StartLcpReq::SignalLength);
12987  return;
12988  }
12989  else if (ERROR_INSERTED(7021) && ((rand() % 10) > 4))
12990  {
12991  infoEvent("Dont sent STARTLCPREQ to %u", nodeId);
12992  return;
12993  }
12994  sendSignal(ref, GSN_START_LCP_REQ, signal, StartLcpReq::SignalLength, JBB);
12995 }
12996 
12997 void
12998 Dbdih::execSTART_LCP_CONF(Signal* signal){
12999  StartLcpConf * conf = (StartLcpConf*)signal->getDataPtr();
13000 
13001  Uint32 nodeId = refToNode(conf->senderRef);
13002  receiveLoopMacro(START_LCP_REQ, nodeId);
13003 
13004  Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
13005  Callback c = { safe_cast(&Dbdih::startLcpMutex_unlocked), 0 };
13006  mutex.unlock(c);
13007 }
13008 
13009 void
13010 Dbdih::startLcpMutex_unlocked(Signal* signal, Uint32 data, Uint32 retVal){
13011  jamEntry();
13012  ndbrequire(retVal == 0);
13013 
13014  Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
13015  mutex.release();
13016 
13017  /* ----------------------------------------------------------------------- */
13018  /* NOW PROCEED BY STARTING THE LOCAL CHECKPOINT IN EACH LQH. */
13019  /* ----------------------------------------------------------------------- */
13020  c_lcpState.m_LAST_LCP_FRAG_ORD = c_lcpState.m_participatingLQH;
13021 
13022  CRASH_INSERTION(7015);
13023  c_lcpState.setLcpStatus(LCP_START_LCP_ROUND, __LINE__);
13024  startLcpRoundLoopLab(signal, 0, 0);
13025 }
13026 
13027 void
13028 Dbdih::master_lcp_fragmentMutex_locked(Signal* signal,
13029  Uint32 failedNodePtrI, Uint32 retVal)
13030 {
13031  jamEntry();
13032  ndbrequire(retVal == 0);
13033 
13034  signal->theData[0] = NDB_LE_LCP_TakeoverCompleted;
13035  signal->theData[1] = c_lcpMasterTakeOverState.state;
13036  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
13037 
13038  signal->theData[0] = 7012;
13039  execDUMP_STATE_ORD(signal);
13040 
13041  c_lcpMasterTakeOverState.set(LMTOS_IDLE, __LINE__);
13042 
13043  checkLocalNodefailComplete(signal, failedNodePtrI, NF_LCP_TAKE_OVER);
13044 
13045  startLcpRoundLoopLab(signal, 0, 0);
13046 }
13047 
13048 void Dbdih::startLcpRoundLoopLab(Signal* signal,
13049  Uint32 startTableId, Uint32 startFragId)
13050 {
13051  NodeRecordPtr nodePtr;
13052  for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
13053  ptrAss(nodePtr, nodeRecord);
13054  if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
13055  ndbrequire(nodePtr.p->noOfStartedChkpt == 0);
13056  ndbrequire(nodePtr.p->noOfQueuedChkpt == 0);
13057  }//if
13058  }//if
13059  c_lcpState.currentFragment.tableId = startTableId;
13060  c_lcpState.currentFragment.fragmentId = startFragId;
13061  startNextChkpt(signal);
13062 }//Dbdih::startLcpRoundLoopLab()
13063 
13064 void Dbdih::startNextChkpt(Signal* signal)
13065 {
13066  Uint32 lcpId = SYSFILE->latestLCP_ID;
13067 
13068  NdbNodeBitmask busyNodes;
13069  busyNodes.clear();
13070  const Uint32 lcpNodes = c_lcpState.m_participatingLQH.count();
13071 
13072  bool save = true;
13073  LcpState::CurrentFragment curr = c_lcpState.currentFragment;
13074 
13075  while (curr.tableId < ctabFileSize) {
13076  TabRecordPtr tabPtr;
13077  tabPtr.i = curr.tableId;
13078  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
13079  if ((tabPtr.p->tabStatus != TabRecord::TS_ACTIVE) ||
13080  (tabPtr.p->tabLcpStatus != TabRecord::TLS_ACTIVE)) {
13081  curr.tableId++;
13082  curr.fragmentId = 0;
13083  continue;
13084  }//if
13085 
13086  FragmentstorePtr fragPtr;
13087  getFragstore(tabPtr.p, curr.fragmentId, fragPtr);
13088 
13089  ReplicaRecordPtr replicaPtr;
13090  for(replicaPtr.i = fragPtr.p->storedReplicas;
13091  replicaPtr.i != RNIL ;
13092  replicaPtr.i = replicaPtr.p->nextReplica){
13093 
13094  jam();
13095  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
13096 
13097  NodeRecordPtr nodePtr;
13098  nodePtr.i = replicaPtr.p->procNode;
13099  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
13100 
13101  if (c_lcpState.m_participatingLQH.get(nodePtr.i))
13102  {
13103  if (replicaPtr.p->lcpOngoingFlag &&
13104  replicaPtr.p->lcpIdStarted < lcpId)
13105  {
13106  jam();
13107  //-------------------------------------------------------------------
13108  // We have found a replica on a node that performs local checkpoint
13109  // that is alive and that have not yet been started.
13110  //-------------------------------------------------------------------
13111 
13112  if (nodePtr.p->noOfStartedChkpt < 2)
13113  {
13114  jam();
13122  replicaPtr.p->lcpIdStarted = lcpId;
13123 
13124  Uint32 i = nodePtr.p->noOfStartedChkpt;
13125  nodePtr.p->startedChkpt[i].tableId = tabPtr.i;
13126  nodePtr.p->startedChkpt[i].fragId = curr.fragmentId;
13127  nodePtr.p->startedChkpt[i].replicaPtr = replicaPtr.i;
13128  nodePtr.p->noOfStartedChkpt = i + 1;
13129 
13130  sendLCP_FRAG_ORD(signal, nodePtr.p->startedChkpt[i]);
13131  }
13132  else if (nodePtr.p->noOfQueuedChkpt < 2)
13133  {
13134  jam();
13142  replicaPtr.p->lcpIdStarted = lcpId;
13143 
13144  Uint32 i = nodePtr.p->noOfQueuedChkpt;
13145  nodePtr.p->queuedChkpt[i].tableId = tabPtr.i;
13146  nodePtr.p->queuedChkpt[i].fragId = curr.fragmentId;
13147  nodePtr.p->queuedChkpt[i].replicaPtr = replicaPtr.i;
13148  nodePtr.p->noOfQueuedChkpt = i + 1;
13149  }
13150  else
13151  {
13152  jam();
13153 
13154  if(save)
13155  {
13159  c_lcpState.currentFragment = curr;
13160  save = false;
13161  }
13162 
13163  busyNodes.set(nodePtr.i);
13164  if(busyNodes.count() == lcpNodes)
13165  {
13173  return;
13174  }//if
13175  }//if
13176  }
13177  }//while
13178  }
13179  curr.fragmentId++;
13180  if (curr.fragmentId >= tabPtr.p->totalfragments) {
13181  jam();
13182  curr.fragmentId = 0;
13183  curr.tableId++;
13184  }//if
13185  }//while
13186 
13187  sendLastLCP_FRAG_ORD(signal);
13188 }//Dbdih::startNextChkpt()
13189 
13190 void Dbdih::sendLastLCP_FRAG_ORD(Signal* signal)
13191 {
13192  LcpFragOrd * const lcpFragOrd = (LcpFragOrd *)&signal->theData[0];
13193  lcpFragOrd->tableId = RNIL;
13194  lcpFragOrd->fragmentId = 0;
13195  lcpFragOrd->lcpId = SYSFILE->latestLCP_ID;
13196  lcpFragOrd->lcpNo = 0;
13197  lcpFragOrd->keepGci = c_lcpState.keepGci;
13198  lcpFragOrd->lastFragmentFlag = true;
13199 
13200  NodeRecordPtr nodePtr;
13201  for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
13202  jam();
13203  ptrAss(nodePtr, nodeRecord);
13204 
13205  if(nodePtr.p->noOfQueuedChkpt == 0 &&
13206  nodePtr.p->noOfStartedChkpt == 0 &&
13207  c_lcpState.m_LAST_LCP_FRAG_ORD.isWaitingFor(nodePtr.i)){
13208  jam();
13209 
13210  CRASH_INSERTION(7028);
13211 
13216  c_lcpState.m_LAST_LCP_FRAG_ORD.clearWaitingFor(nodePtr.i);
13217  if(ERROR_INSERTED(7075)){
13218  continue;
13219  }
13220 
13221  CRASH_INSERTION(7193);
13222  BlockReference ref = calcLqhBlockRef(nodePtr.i);
13223  sendSignal(ref, GSN_LCP_FRAG_ORD, signal,LcpFragOrd::SignalLength, JBB);
13224  }
13225  }
13226  if(ERROR_INSERTED(7075))
13227  {
13228  if(c_lcpState.m_LAST_LCP_FRAG_ORD.done())
13229  {
13230  CRASH_INSERTION(7075);
13231  }
13232  }
13233 }//Dbdih::sendLastLCP_FRAGORD()
13234 
13235 /* ------------------------------------------------------------------------- */
13236 /* A FRAGMENT REPLICA HAS COMPLETED EXECUTING ITS LOCAL CHECKPOINT. */
13237 /* CHECK IF ALL REPLICAS IN THE TABLE HAVE COMPLETED. IF SO STORE THE */
13238 /* THE TABLE DISTRIBUTION ON DISK. ALSO SEND LCP_REPORT TO ALL OTHER */
13239 /* NODES SO THAT THEY CAN STORE THE TABLE ONTO DISK AS WELL. */
13240 /* ------------------------------------------------------------------------- */
13241 void Dbdih::execLCP_FRAG_REP(Signal* signal)
13242 {
13243  jamEntry();
13244 
13245  LcpFragRep * const lcpReport = (LcpFragRep *)&signal->theData[0];
13246 
13250  const bool broadcast_req = lcpReport->nodeId == LcpFragRep::BROADCAST_REQ;
13251  if (broadcast_req)
13252  {
13253  jam();
13254  ndbrequire(refToNode(signal->getSendersBlockRef()) == getOwnNodeId());
13255 
13259  lcpReport->nodeId = getOwnNodeId();
13260 
13261  NodeReceiverGroup rg(DBDIH, c_lcpState.m_participatingDIH);
13262  rg.m_nodes.clear(getOwnNodeId());
13263  sendSignal(rg, GSN_LCP_FRAG_REP, signal, signal->getLength(), JBB);
13264 
13268  }
13269 
13270  ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
13271 
13272 #if 0
13273  printLCP_FRAG_REP(stdout,
13274  signal->getDataPtr(),
13275  signal->length(), number());
13276 #endif
13277 
13278  Uint32 nodeId = lcpReport->nodeId;
13279  Uint32 tableId = lcpReport->tableId;
13280  Uint32 fragId = lcpReport->fragId;
13281 
13282  jamEntry();
13283 
13284  if (ERROR_INSERTED(7178) && nodeId != getOwnNodeId())
13285  {
13286  jam();
13287  Uint32 owng =Sysfile::getNodeGroup(getOwnNodeId(), SYSFILE->nodeGroups);
13288  Uint32 nodeg = Sysfile::getNodeGroup(nodeId, SYSFILE->nodeGroups);
13289  if (owng == nodeg)
13290  {
13291  jam();
13292  ndbout_c("throwing away LCP_FRAG_REP from (and killing) %d", nodeId);
13293  SET_ERROR_INSERT_VALUE(7179);
13294  signal->theData[0] = 9999;
13295  sendSignal(numberToRef(CMVMI, nodeId),
13296  GSN_NDB_TAMPER, signal, 1, JBA);
13297  return;
13298  }
13299  }
13300 
13301  if (ERROR_INSERTED(7179) && nodeId != getOwnNodeId())
13302  {
13303  jam();
13304  Uint32 owng =Sysfile::getNodeGroup(getOwnNodeId(), SYSFILE->nodeGroups);
13305  Uint32 nodeg = Sysfile::getNodeGroup(nodeId, SYSFILE->nodeGroups);
13306  if (owng == nodeg)
13307  {
13308  jam();
13309  ndbout_c("throwing away LCP_FRAG_REP from %d", nodeId);
13310  return;
13311  }
13312  }
13313 
13314  CRASH_INSERTION2(7025, isMaster());
13315  CRASH_INSERTION2(7016, !isMaster());
13316  CRASH_INSERTION2(7191, (!isMaster() && tableId));
13317 
13318  bool fromTimeQueue = (signal->senderBlockRef()==reference()&&!broadcast_req);
13319 
13320  TabRecordPtr tabPtr;
13321  tabPtr.i = tableId;
13322  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
13323  if(tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
13324  jam();
13325  /*-----------------------------------------------------------------------*/
13326  // If the table is currently copied to disk we also
13327  // stop already here to avoid strange half-way updates
13328  // of the table data structures.
13329  /*-----------------------------------------------------------------------*/
13330  /*
13331  We need to send this signal without a delay since we have discovered
13332  that we have run out of space in the short time queue. This problem
13333  is very erunlikely to happen but it has and it results in a node crash.
13334  This should be considered a "quick fix" and not a permanent solution.
13335  A cleaner/better way would be to check the time queue if it is full or
13336  not before sending this signal.
13337  */
13338  sendSignal(reference(), GSN_LCP_FRAG_REP, signal, signal->length(), JBB);
13339  /* Kept here for reference
13340  sendSignalWithDelay(reference(), GSN_LCP_FRAG_REP,
13341  signal, 20, signal->length());
13342  */
13343 
13344  if(!fromTimeQueue){
13345  c_lcpState.noOfLcpFragRepOutstanding++;
13346  }
13347 
13348  return;
13349  }//if
13350 
13351  if(fromTimeQueue)
13352  {
13353  jam();
13354  ndbrequire(c_lcpState.noOfLcpFragRepOutstanding > 0);
13355  c_lcpState.noOfLcpFragRepOutstanding--;
13356  }
13357 
13358  bool tableDone = reportLcpCompletion(lcpReport);
13359 
13360  Uint32 started = lcpReport->maxGciStarted;
13361  Uint32 completed = lcpReport->maxGciCompleted;
13362 
13363  if (started > c_lcpState.lcpStopGcp)
13364  {
13365  jam();
13366  c_lcpState.lcpStopGcp = started;
13367  }
13368 
13375  m_local_lcp_state.lcp_frag_rep(lcpReport);
13376 
13377  if (tableDone)
13378  {
13379  jam();
13380 
13381  if (tabPtr.p->tabStatus == TabRecord::TS_IDLE ||
13382  tabPtr.p->tabStatus == TabRecord::TS_DROPPING)
13383  {
13384  jam();
13385  g_eventLogger->info("TS_DROPPING - Neglecting to save Table: %d Frag: %d - ",
13386  tableId, fragId);
13387  }
13388  else
13389  {
13390  jam();
13394  tabPtr.p->tabLcpStatus = TabRecord::TLS_WRITING_TO_FILE;
13395  tabPtr.p->tabCopyStatus = TabRecord::CS_LCP_READ_TABLE;
13396  tabPtr.p->tabUpdateState = TabRecord::US_LOCAL_CHECKPOINT;
13397  signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
13398  signal->theData[1] = tabPtr.i;
13399  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
13400 
13401  bool ret = checkLcpAllTablesDoneInLqh(__LINE__);
13402  if (ret && ERROR_INSERTED(7209))
13403  {
13404  jam();
13405 
13406  signal->theData[0] = 9999;
13407  sendSignal(numberToRef(CMVMI, cmasterNodeId),
13408  GSN_NDB_TAMPER, signal, 1, JBB);
13409  }
13410  }
13411  }
13412 
13413 #ifdef VM_TRACE
13414  /* --------------------------------------------------------------------- */
13415  // REPORT that local checkpoint have completed this fragment.
13416  /* --------------------------------------------------------------------- */
13417  signal->theData[0] = NDB_LE_LCPFragmentCompleted;
13418  signal->theData[1] = nodeId;
13419  signal->theData[2] = tableId;
13420  signal->theData[3] = fragId;
13421  signal->theData[4] = started;
13422  signal->theData[5] = completed;
13423  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 6, JBB);
13424 #endif
13425 
13426  bool ok = false;
13427  switch(c_lcpMasterTakeOverState.state){
13428  case LMTOS_IDLE:
13429  ok = true;
13430  jam();
13434  break;
13435  case LMTOS_WAIT_EMPTY_LCP: // LCP Take over waiting for EMPTY_LCPCONF
13436  jam();
13437  return;
13438  case LMTOS_WAIT_LCP_FRAG_REP:
13439  jam();
13440  checkEmptyLcpComplete(signal);
13441  return;
13442  case LMTOS_INITIAL:
13443  case LMTOS_ALL_IDLE:
13444  case LMTOS_ALL_ACTIVE:
13445  case LMTOS_LCP_CONCLUDING:
13446  case LMTOS_COPY_ONGOING:
13447  ndbrequire(false);
13448  }
13449  ndbrequire(ok);
13450 
13451  /* ----------------------------------------------------------------------- */
13452  // Check if there are more LCP's to start up.
13453  /* ----------------------------------------------------------------------- */
13454  if(isMaster())
13455  {
13456  jam();
13457 
13461  NodeRecordPtr nodePtr;
13462  nodePtr.i = nodeId;
13463  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
13464 
13465  const Uint32 outstanding = nodePtr.p->noOfStartedChkpt;
13466  ndbrequire(outstanding > 0);
13467  if(nodePtr.p->startedChkpt[0].tableId != tableId ||
13468  nodePtr.p->startedChkpt[0].fragId != fragId){
13469  jam();
13470  ndbrequire(outstanding > 1);
13471  ndbrequire(nodePtr.p->startedChkpt[1].tableId == tableId);
13472  ndbrequire(nodePtr.p->startedChkpt[1].fragId == fragId);
13473  } else {
13474  jam();
13475  nodePtr.p->startedChkpt[0] = nodePtr.p->startedChkpt[1];
13476  }
13477  nodePtr.p->noOfStartedChkpt--;
13478  checkStartMoreLcp(signal, nodeId);
13479  }
13480 }
13481 
13482 bool
13483 Dbdih::checkLcpAllTablesDoneInLqh(Uint32 line){
13484  TabRecordPtr tabPtr;
13485 
13489  for (tabPtr.i = 0; tabPtr.i < ctabFileSize; tabPtr.i++) {
13490  jam();
13491  ptrAss(tabPtr, tabRecord);
13492  if ((tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) &&
13493  (tabPtr.p->tabLcpStatus == TabRecord::TLS_ACTIVE))
13494  {
13495  jam();
13499  return false;
13500  }//if
13501  }//for
13502 
13503  CRASH_INSERTION2(7026, isMaster());
13504  CRASH_INSERTION2(7017, !isMaster());
13505 
13506  c_lcpState.setLcpStatus(LCP_TAB_COMPLETED, line);
13507 
13508  if (ERROR_INSERTED(7194))
13509  {
13510  ndbout_c("CLEARING 7194");
13511  CLEAR_ERROR_INSERT_VALUE;
13512  }
13513 
13514  return true;
13515 }
13516 
13517 void Dbdih::findReplica(ReplicaRecordPtr& replicaPtr,
13518  Fragmentstore* fragPtrP,
13519  Uint32 nodeId,
13520  bool old)
13521 {
13522  replicaPtr.i = old ? fragPtrP->oldStoredReplicas : fragPtrP->storedReplicas;
13523  while(replicaPtr.i != RNIL){
13524  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
13525  if (replicaPtr.p->procNode == nodeId) {
13526  jam();
13527  return;
13528  } else {
13529  jam();
13530  replicaPtr.i = replicaPtr.p->nextReplica;
13531  }//if
13532  };
13533 
13534 #ifdef VM_TRACE
13535  g_eventLogger->info("Fragment Replica(node=%d) not found", nodeId);
13536  replicaPtr.i = fragPtrP->oldStoredReplicas;
13537  while(replicaPtr.i != RNIL){
13538  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
13539  if (replicaPtr.p->procNode == nodeId) {
13540  jam();
13541  break;
13542  } else {
13543  jam();
13544  replicaPtr.i = replicaPtr.p->nextReplica;
13545  }//if
13546  };
13547  if(replicaPtr.i != RNIL){
13548  g_eventLogger->info("...But was found in oldStoredReplicas");
13549  } else {
13550  g_eventLogger->info("...And wasn't found in oldStoredReplicas");
13551  }
13552 #endif
13553  ndbrequire(false);
13554 }//Dbdih::findReplica()
13555 
13556 
13557 int
13558 Dbdih::handle_invalid_lcp_no(const LcpFragRep* rep,
13559  ReplicaRecordPtr replicaPtr)
13560 {
13561  ndbrequire(!isMaster());
13562  Uint32 lcpNo = rep->lcpNo;
13563  Uint32 lcpId = rep->lcpId;
13564 
13565  if (!ndb_pnr(getNodeInfo(refToNode(cmasterdihref)).m_version))
13566  {
13567  }
13568  else
13569  {
13570  warningEvent("Detected previous node failure of %d during lcp",
13571  rep->nodeId);
13572  }
13573 
13574  replicaPtr.p->nextLcp = lcpNo;
13575  replicaPtr.p->lcpId[lcpNo] = 0;
13576  replicaPtr.p->lcpStatus[lcpNo] = ZINVALID;
13577 
13578  for (Uint32 i = lcpNo; i != lcpNo; i = nextLcpNo(i))
13579  {
13580  jam();
13581  if (replicaPtr.p->lcpStatus[i] == ZVALID &&
13582  replicaPtr.p->lcpId[i] >= lcpId)
13583  {
13584  ndbout_c("i: %d lcpId: %d", i, replicaPtr.p->lcpId[i]);
13585  ndbrequire(false);
13586  }
13587  }
13588 
13589  return 0;
13590 }
13591 
13597 bool
13598 Dbdih::reportLcpCompletion(const LcpFragRep* lcpReport)
13599 {
13600  Uint32 lcpNo = lcpReport->lcpNo;
13601  Uint32 lcpId = lcpReport->lcpId;
13602  Uint32 maxGciStarted = lcpReport->maxGciStarted;
13603  Uint32 maxGciCompleted = lcpReport->maxGciCompleted;
13604  Uint32 tableId = lcpReport->tableId;
13605  Uint32 fragId = lcpReport->fragId;
13606  Uint32 nodeId = lcpReport->nodeId;
13607 
13608  TabRecordPtr tabPtr;
13609  tabPtr.i = tableId;
13610  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
13611 
13612  if (tabPtr.p->tabStatus == TabRecord::TS_DROPPING ||
13613  tabPtr.p->tabStatus == TabRecord::TS_IDLE)
13614  {
13615  jam();
13616  return true;
13617  }
13618 
13619  FragmentstorePtr fragPtr;
13620  getFragstore(tabPtr.p, fragId, fragPtr);
13621 
13622  ReplicaRecordPtr replicaPtr;
13623  findReplica(replicaPtr, fragPtr.p, nodeId);
13624 
13625  ndbrequire(replicaPtr.p->lcpOngoingFlag == true);
13626  if(lcpNo != replicaPtr.p->nextLcp){
13627  if (handle_invalid_lcp_no(lcpReport, replicaPtr))
13628  {
13629  g_eventLogger->error("lcpNo = %d replicaPtr.p->nextLcp = %d",
13630  lcpNo, replicaPtr.p->nextLcp);
13631  ndbrequire(false);
13632  }
13633  }
13634  ndbrequire(lcpNo == replicaPtr.p->nextLcp);
13635  ndbrequire(lcpNo < MAX_LCP_STORED);
13636  ndbrequire(replicaPtr.p->lcpId[lcpNo] != lcpId);
13637 
13638  replicaPtr.p->lcpIdStarted = lcpId;
13639  replicaPtr.p->lcpOngoingFlag = false;
13640 
13641  removeOldCrashedReplicas(tableId, fragId, replicaPtr);
13642  replicaPtr.p->lcpId[lcpNo] = lcpId;
13643  replicaPtr.p->lcpStatus[lcpNo] = ZVALID;
13644  replicaPtr.p->maxGciStarted[lcpNo] = maxGciStarted;
13645  replicaPtr.p->maxGciCompleted[lcpNo] = maxGciCompleted;
13646  replicaPtr.p->nextLcp = nextLcpNo(replicaPtr.p->nextLcp);
13647  ndbrequire(fragPtr.p->noLcpReplicas > 0);
13648  fragPtr.p->noLcpReplicas --;
13649 
13650  if(fragPtr.p->noLcpReplicas > 0){
13651  jam();
13652  return false;
13653  }
13654 
13655  for (Uint32 fid = 0; fid < tabPtr.p->totalfragments; fid++) {
13656  jam();
13657  getFragstore(tabPtr.p, fid, fragPtr);
13658  if (fragPtr.p->noLcpReplicas > 0){
13659  jam();
13660  /* ----------------------------------------------------------------- */
13661  // Not all fragments in table have been checkpointed.
13662  /* ----------------------------------------------------------------- */
13663  if(0)
13664  g_eventLogger->info("reportLcpCompletion: fragment %d not ready", fid);
13665  return false;
13666  }//if
13667  }//for
13668  return true;
13669 }//Dbdih::reportLcpCompletion()
13670 
13671 void Dbdih::checkStartMoreLcp(Signal* signal, Uint32 nodeId)
13672 {
13673  ndbrequire(isMaster());
13674 
13675  NodeRecordPtr nodePtr;
13676  nodePtr.i = nodeId;
13677  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
13678 
13679  ndbrequire(nodePtr.p->noOfStartedChkpt < 2);
13680 
13681  if (nodePtr.p->noOfQueuedChkpt > 0) {
13682  jam();
13683  nodePtr.p->noOfQueuedChkpt--;
13684  Uint32 i = nodePtr.p->noOfStartedChkpt;
13685  nodePtr.p->startedChkpt[i] = nodePtr.p->queuedChkpt[0];
13686  nodePtr.p->queuedChkpt[0] = nodePtr.p->queuedChkpt[1];
13687  //-------------------------------------------------------------------
13688  // We can send a LCP_FRAGORD to the node ordering it to perform a
13689  // local checkpoint on this fragment replica.
13690  //-------------------------------------------------------------------
13691  nodePtr.p->noOfStartedChkpt = i + 1;
13692 
13693  sendLCP_FRAG_ORD(signal, nodePtr.p->startedChkpt[i]);
13694  }
13695 
13696  /* ----------------------------------------------------------------------- */
13697  // When there are no more outstanding LCP reports and there are no one queued
13698  // in at least one node, then we are ready to make sure all nodes have at
13699  // least two outstanding LCP requests per node and at least two queued for
13700  // sending.
13701  /* ----------------------------------------------------------------------- */
13702  startNextChkpt(signal);
13703 }//Dbdih::checkStartMoreLcp()
13704 
13705 void
13706 Dbdih::sendLCP_FRAG_ORD(Signal* signal,
13707  NodeRecord::FragmentCheckpointInfo info){
13708 
13709  ReplicaRecordPtr replicaPtr;
13710  replicaPtr.i = info.replicaPtr;
13711  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
13712 
13713  // MT LQH goes via proxy for DD reasons
13714  BlockReference ref = calcLqhBlockRef(replicaPtr.p->procNode);
13715 
13716  if (ERROR_INSERTED(7193) && replicaPtr.p->procNode == getOwnNodeId())
13717  {
13718  return;
13719  }
13720 
13721  if (replicaPtr.p->nextLcp >= MAX_LCP_USED)
13722  {
13723  jam();
13724  infoEvent("Updating nextLcp from %u to %u tab: %u",
13725  replicaPtr.p->nextLcp, 0,
13726  info.tableId);
13727  replicaPtr.p->nextLcp = 0;
13728  }
13729 
13730  Uint32 keepGci = c_lcpState.keepGci;
13731  if (keepGci > SYSFILE->lastCompletedGCI[replicaPtr.p->procNode])
13732  {
13733  jam();
13734  keepGci = SYSFILE->lastCompletedGCI[replicaPtr.p->procNode];
13735  }
13736 
13737  LcpFragOrd * const lcpFragOrd = (LcpFragOrd *)&signal->theData[0];
13738  lcpFragOrd->tableId = info.tableId;
13739  lcpFragOrd->fragmentId = info.fragId;
13740  lcpFragOrd->lcpId = SYSFILE->latestLCP_ID;
13741  lcpFragOrd->lcpNo = replicaPtr.p->nextLcp;
13742  lcpFragOrd->keepGci = keepGci;
13743  lcpFragOrd->lastFragmentFlag = false;
13744  sendSignal(ref, GSN_LCP_FRAG_ORD, signal, LcpFragOrd::SignalLength, JBB);
13745 }
13746 
13747 void Dbdih::checkLcpCompletedLab(Signal* signal)
13748 {
13749  if(c_lcpState.lcpStatus < LCP_TAB_COMPLETED)
13750  {
13751  jam();
13752  return;
13753  }
13754 
13755  TabRecordPtr tabPtr;
13756  for (tabPtr.i = 0; tabPtr.i < ctabFileSize; tabPtr.i++) {
13757  jam();
13758  ptrAss(tabPtr, tabRecord);
13759  if (tabPtr.p->tabLcpStatus != TabRecord::TLS_COMPLETED)
13760  {
13761  jam();
13762  return;
13763  }
13764  }
13765 
13766  CRASH_INSERTION2(7027, isMaster());
13767  CRASH_INSERTION2(7018, !isMaster());
13768 
13769  if(c_lcpState.lcpStatus == LCP_TAB_COMPLETED)
13770  {
13775  if (ERROR_INSERTED(7209))
13776  {
13777  signal->theData[0] = DihContinueB::ZCHECK_LCP_COMPLETED;
13778  sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
13779  return;
13780  }
13781 
13782  c_lcpState.setLcpStatus(LCP_TAB_SAVED, __LINE__);
13783  sendLCP_COMPLETE_REP(signal);
13784 
13785  if (ERROR_INSERTED(7210))
13786  {
13787  CLEAR_ERROR_INSERT_VALUE;
13788  EmptyLcpReq* req = (EmptyLcpReq*)signal->getDataPtr();
13789  req->senderRef = reference();
13790  sendEMPTY_LCP_REQ(signal, getOwnNodeId(), 0);
13791  }
13792 
13793  return;
13794  }
13795 
13796  ndbrequire(c_lcpState.lcpStatus == LCP_TAB_SAVED);
13797  allNodesLcpCompletedLab(signal);
13798  return;
13799 }//Dbdih::checkLcpCompletedLab()
13800 
13801 void
13802 Dbdih::sendLCP_COMPLETE_REP(Signal* signal){
13803  jam();
13804 
13809  bool alreadysent =
13810  c_lcpState.m_lastLCP_COMPLETE_REP_id == SYSFILE->latestLCP_ID &&
13811  c_lcpState.m_lastLCP_COMPLETE_REP_ref == c_lcpState.m_masterLcpDihRef;
13812 
13813  if (!alreadysent)
13814  {
13815  LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
13816  rep->nodeId = getOwnNodeId();
13817  rep->lcpId = SYSFILE->latestLCP_ID;
13818  rep->blockNo = DBDIH;
13819 
13820  sendSignal(c_lcpState.m_masterLcpDihRef, GSN_LCP_COMPLETE_REP, signal,
13821  LcpCompleteRep::SignalLength, JBB);
13822 
13823  c_lcpState.m_lastLCP_COMPLETE_REP_id = SYSFILE->latestLCP_ID;
13824  c_lcpState.m_lastLCP_COMPLETE_REP_ref = c_lcpState.m_masterLcpDihRef;
13825  }
13826 
13831  if (c_set_initial_start_flag &&
13832  c_lcpState.m_participatingLQH.get(getOwnNodeId()))
13833  {
13834  jam();
13835  c_set_initial_start_flag = FALSE;
13836  }
13837 }
13838 
13839 /*-------------------------------------------------------------------------- */
13840 /* COMP_LCP_ROUND A LQH HAS COMPLETED A LOCAL CHECKPOINT */
13841 /*------------------------------------------------------------------------- */
13842 void Dbdih::execLCP_COMPLETE_REP(Signal* signal)
13843 {
13844  jamEntry();
13845 
13846  CRASH_INSERTION(7191);
13847 
13848 #if 0
13849  g_eventLogger->info("LCP_COMPLETE_REP");
13850  printLCP_COMPLETE_REP(stdout,
13851  signal->getDataPtr(),
13852  signal->length(), number());
13853 #endif
13854 
13855  LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtr();
13856 
13857  if (rep->nodeId == LcpFragRep::BROADCAST_REQ)
13858  {
13859  jam();
13860  ndbrequire(refToNode(signal->getSendersBlockRef()) == getOwnNodeId());
13861 
13865  rep->nodeId = getOwnNodeId();
13866 
13867  NodeReceiverGroup rg(DBDIH, c_lcpState.m_participatingDIH);
13868  rg.m_nodes.clear(getOwnNodeId());
13869  sendSignal(rg, GSN_LCP_COMPLETE_REP, signal, signal->getLength(), JBB);
13870 
13874  }
13875 
13876  Uint32 lcpId = rep->lcpId;
13877  Uint32 nodeId = rep->nodeId;
13878  Uint32 blockNo = rep->blockNo;
13879 
13880  if(c_lcpMasterTakeOverState.state > LMTOS_WAIT_LCP_FRAG_REP){
13881  jam();
13886  ndbrequire(isMaster());
13887  ndbrequire(blockNo == DBDIH);
13888  sendSignalWithDelay(reference(), GSN_LCP_COMPLETE_REP, signal, 100,
13889  signal->length());
13890  return;
13891  }
13892 
13893  ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
13894 
13895  switch(blockNo){
13896  case DBLQH:
13897  jam();
13898  c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.clearWaitingFor(nodeId);
13899  ndbrequire(!c_lcpState.m_LAST_LCP_FRAG_ORD.isWaitingFor(nodeId));
13900  break;
13901  case DBDIH:
13902  jam();
13903  ndbrequire(isMaster());
13904  c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.clearWaitingFor(nodeId);
13905  break;
13906  case 0:
13907  jam();
13908  ndbrequire(!isMaster());
13909  ndbrequire(c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received == false);
13910  c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received = true;
13911  break;
13912  default:
13913  ndbrequire(false);
13914  }
13915  ndbrequire(lcpId == SYSFILE->latestLCP_ID);
13916 
13917  allNodesLcpCompletedLab(signal);
13918  return;
13919 }
13920 
13921 void Dbdih::allNodesLcpCompletedLab(Signal* signal)
13922 {
13923  jam();
13924 
13925  if (c_lcpState.lcpStatus != LCP_TAB_SAVED) {
13926  jam();
13930  return;
13931  }//if
13932 
13933  if (!c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.done()){
13934  jam();
13935  return;
13936  }
13937 
13938  if (!c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.done()){
13939  jam();
13940  return;
13941  }
13942 
13943  if (!isMaster() &&
13944  c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received == false){
13945  jam();
13949  return;
13950  }
13951 
13952  if(c_lcpMasterTakeOverState.state != LMTOS_IDLE){
13953  jam();
13954 #ifdef VM_TRACE
13955  g_eventLogger->info("Exiting from allNodesLcpCompletedLab");
13956 #endif
13957  return;
13958  }
13959 
13960 
13961  /*------------------------------------------------------------------------ */
13962  /* WE HAVE NOW COMPLETED A LOCAL CHECKPOINT. WE ARE NOW READY TO WAIT */
13963  /* FOR THE NEXT LOCAL CHECKPOINT. SEND WITHOUT TIME-OUT SINCE IT MIGHT */
13964  /* BE TIME TO START THE NEXT LOCAL CHECKPOINT IMMEDIATELY. */
13965  /* CLEAR BIT 3 OF SYSTEM RESTART BITS TO INDICATE THAT THERE IS NO */
13966  /* LOCAL CHECKPOINT ONGOING. THIS WILL BE WRITTEN AT SOME LATER TIME */
13967  /* DURING A GLOBAL CHECKPOINT. IT IS NOT NECESSARY TO WRITE IT */
13968  /* IMMEDIATELY. WE WILL ALSO CLEAR BIT 2 OF SYSTEM RESTART BITS IF ALL */
13969  /* CURRENTLY ACTIVE NODES COMPLETED THE LOCAL CHECKPOINT. */
13970  /*------------------------------------------------------------------------ */
13971  CRASH_INSERTION(7019);
13972  signal->setTrace(0);
13973 
13974  c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
13975 
13979  m_local_lcp_state.lcp_complete_rep(c_newest_restorable_gci);
13980 
13981  if (isMaster())
13982  {
13986  TakeOverRecordPtr takeOverPtr;
13987  for (c_activeTakeOverList.first(takeOverPtr); !takeOverPtr.isNull();
13988  c_activeTakeOverList.next(takeOverPtr))
13989  {
13990  jam();
13991  Ptr<NodeRecord> nodePtr;
13992  nodePtr.i = takeOverPtr.p->toStartingNode;
13993  if (takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_WAIT_LCP)
13994  {
13995  jam();
13996  if (c_lcpState.m_participatingLQH.get(nodePtr.i))
13997  {
13998  jam();
13999  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
14000  ndbrequire(nodePtr.p->copyCompleted == 2);
14001 
14002  EndToConf * conf = (EndToConf *)signal->getDataPtrSend();
14003  conf->senderData = takeOverPtr.p->m_senderData;
14004  conf->sendingNodeId = cownNodeId;
14005  conf->startingNodeId = nodePtr.i;
14006  sendSignal(takeOverPtr.p->m_senderRef, GSN_END_TOCONF, signal,
14007  EndToConf::SignalLength, JBB);
14008 
14009  releaseTakeOver(takeOverPtr);
14010  }
14011  }
14012  }
14013  }
14014 
14015  Sysfile::clearLCPOngoing(SYSFILE->systemRestartBits);
14016  setLcpActiveStatusEnd(signal);
14017 
14018  if(!isMaster()){
14019  jam();
14023  return;
14024  }
14025 
14026  // Send LCP_COMPLETE_REP to all other nodes
14027  // allowing them to set their lcpStatus to LCP_STATUS_IDLE
14028  LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
14029  rep->nodeId = getOwnNodeId();
14030  rep->lcpId = SYSFILE->latestLCP_ID;
14031  rep->blockNo = 0; // 0 = Sent from master
14032 
14033  NodeRecordPtr nodePtr;
14034  nodePtr.i = cfirstAliveNode;
14035  do {
14036  jam();
14037  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
14038  if (nodePtr.i != cownNodeId){
14039  BlockReference ref = calcDihBlockRef(nodePtr.i);
14040  sendSignal(ref, GSN_LCP_COMPLETE_REP, signal,
14041  LcpCompleteRep::SignalLength, JBB);
14042  }
14043  nodePtr.i = nodePtr.p->nextNode;
14044  } while (nodePtr.i != RNIL);
14045 
14046 
14047  jam();
14048  /***************************************************************************/
14049  // Report the event that a local checkpoint has completed.
14050  /***************************************************************************/
14051  signal->theData[0] = NDB_LE_LocalCheckpointCompleted; //Event type
14052  signal->theData[1] = SYSFILE->latestLCP_ID;
14053  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
14054 
14055  if (c_newest_restorable_gci > c_lcpState.lcpStopGcp &&
14056  !(ERROR_INSERTED(7222) || ERROR_INSERTED(7223)))
14057  {
14058  jam();
14059  c_lcpState.lcpStopGcp = c_newest_restorable_gci;
14060  }
14061 
14065  checkLcpStart(signal, __LINE__);
14066 
14067  Mutex mutex(signal, c_mutexMgr, c_fragmentInfoMutex_lcp);
14068  mutex.unlock();
14069 
14070  c_lcpState.m_lcp_time = c_current_time - c_lcpState.m_start_time;
14071 
14072  if (cwaitLcpSr == true) {
14073  jam();
14074  cwaitLcpSr = false;
14075  ndbsttorry10Lab(signal, __LINE__);
14076  return;
14077  }//if
14078 
14079 
14080  if (c_nodeStartMaster.blockLcp == true) {
14081  jam();
14082  lcpBlockedLab(signal, false, c_nodeStartMaster.startNode);
14083  return;
14084  }//if
14085  return;
14086 }//Dbdih::allNodesLcpCompletedLab()
14087 
14088 /******************************************************************************/
14089 /* ********** TABLE UPDATE MODULE *************/
14090 /* ****************************************************************************/
14091 /* ------------------------------------------------------------------------- */
14092 /* THIS MODULE IS USED TO UPDATE THE TABLE DESCRIPTION. IT STARTS BY */
14093 /* CREATING THE FIRST TABLE FILE, THEN UPDATES THIS FILE AND CLOSES IT.*/
14094 /* AFTER THAT THE SAME HAPPENS WITH THE SECOND FILE. AFTER THAT THE */
14095 /* TABLE DISTRIBUTION HAS BEEN UPDATED. */
14096 /* */
14097 /* THE REASON FOR CREATING THE FILE AND NOT OPENING IT IS TO ENSURE */
14098 /* THAT WE DO NOT GET A MIX OF OLD AND NEW INFORMATION IN THE FILE IN */
14099 /* ERROR SITUATIONS. */
14100 /* ------------------------------------------------------------------------- */
14101 void Dbdih::tableUpdateLab(Signal* signal, TabRecordPtr tabPtr) {
14102  FileRecordPtr filePtr;
14103  if(tabPtr.p->tabStorage == TabRecord::ST_TEMPORARY) {
14104  // For temporary tables we do not write to disk. Mark both copies 0 and 1
14105  // as done, and go straight to the after-close code.
14106  filePtr.i = tabPtr.p->tabFile[1];
14107  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
14108  tableCloseLab(signal, filePtr);
14109  return;
14110  }
14111  filePtr.i = tabPtr.p->tabFile[0];
14112  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
14113  createFileRw(signal, filePtr);
14114  filePtr.p->reqStatus = FileRecord::TABLE_CREATE;
14115  return;
14116 }//Dbdih::tableUpdateLab()
14117 
14118 void Dbdih::tableCreateLab(Signal* signal, FileRecordPtr filePtr)
14119 {
14120  TabRecordPtr tabPtr;
14121  tabPtr.i = filePtr.p->tabRef;
14122  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
14123  writeTabfile(signal, tabPtr.p, filePtr);
14124  filePtr.p->reqStatus = FileRecord::TABLE_WRITE;
14125  return;
14126 }//Dbdih::tableCreateLab()
14127 
14128 void Dbdih::tableWriteLab(Signal* signal, FileRecordPtr filePtr)
14129 {
14130  closeFile(signal, filePtr);
14131  filePtr.p->reqStatus = FileRecord::TABLE_CLOSE;
14132  return;
14133 }//Dbdih::tableWriteLab()
14134 
14135 void Dbdih::tableCloseLab(Signal* signal, FileRecordPtr filePtr)
14136 {
14137  TabRecordPtr tabPtr;
14138  tabPtr.i = filePtr.p->tabRef;
14139  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
14140  if (filePtr.i == tabPtr.p->tabFile[0]) {
14141  jam();
14142  filePtr.i = tabPtr.p->tabFile[1];
14143  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
14144  createFileRw(signal, filePtr);
14145  filePtr.p->reqStatus = FileRecord::TABLE_CREATE;
14146  return;
14147  }//if
14148  switch (tabPtr.p->tabUpdateState) {
14149  case TabRecord::US_LOCAL_CHECKPOINT:
14150  jam();
14151  releaseTabPages(tabPtr.i);
14152  signal->theData[0] = DihContinueB::ZCHECK_LCP_COMPLETED;
14153  sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
14154 
14155  tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
14156  tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
14157  tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
14158  return;
14159  break;
14160  case TabRecord::US_REMOVE_NODE:
14161  jam();
14162  releaseTabPages(tabPtr.i);
14163  tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
14164  tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
14165  if (tabPtr.p->tabLcpStatus == TabRecord::TLS_WRITING_TO_FILE) {
14166  jam();
14167  tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
14168  signal->theData[0] = DihContinueB::ZCHECK_LCP_COMPLETED;
14169  sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
14170  }//if
14171  signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
14172  signal->theData[1] = tabPtr.p->tabRemoveNode;
14173  signal->theData[2] = tabPtr.i + 1;
14174  sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
14175  return;
14176  break;
14177  case TabRecord::US_INVALIDATE_NODE_LCP:
14178  jam();
14179  releaseTabPages(tabPtr.i);
14180  tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
14181  tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
14182 
14183  signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
14184  signal->theData[1] = tabPtr.p->tabRemoveNode;
14185  signal->theData[2] = tabPtr.i + 1;
14186  if (ERROR_INSERTED(7204))
14187  {
14188  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 2000, 3);
14189  }
14190  else
14191  {
14192  sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
14193  }
14194  return;
14195  case TabRecord::US_COPY_TAB_REQ:
14196  jam();
14197  tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
14198  copyTabReq_complete(signal, tabPtr);
14199  return;
14200  break;
14201  case TabRecord::US_ADD_TABLE_MASTER:
14202  jam();
14203  releaseTabPages(tabPtr.i);
14204  tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
14205  signal->theData[0] = DihContinueB::ZDIH_ADD_TABLE_MASTER;
14206  signal->theData[1] = tabPtr.i;
14207  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
14208  return;
14209  break;
14210  case TabRecord::US_ADD_TABLE_SLAVE:
14211  jam();
14212  releaseTabPages(tabPtr.i);
14213  tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
14214  signal->theData[0] = DihContinueB::ZDIH_ADD_TABLE_SLAVE;
14215  signal->theData[1] = tabPtr.i;
14216  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
14217  return;
14218  break;
14219  case TabRecord::US_CALLBACK:
14220  {
14221  jam();
14222  releaseTabPages(tabPtr.i);
14223  tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
14224  tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
14225 
14226  Ptr<ConnectRecord> connectPtr;
14227  connectPtr.i = tabPtr.p->connectrec;
14228  ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
14229  execute(signal, connectPtr.p->m_callback, 0);
14230  return;
14231  }
14232  default:
14233  ndbrequire(false);
14234  return;
14235  break;
14236  }//switch
14237 }//Dbdih::tableCloseLab()
14238 
14239 void Dbdih::checkGcpStopLab(Signal* signal)
14240 {
14241  Uint32 cnt0 = ++m_gcp_monitor.m_gcp_save.m_counter;
14242  Uint32 cnt1 = ++m_gcp_monitor.m_micro_gcp.m_counter;
14243 
14244  if (m_gcp_monitor.m_gcp_save.m_gci == m_gcp_save.m_gci)
14245  {
14246  jam();
14247  if (m_gcp_monitor.m_gcp_save.m_max_lag &&
14248  cnt0 == m_gcp_monitor.m_gcp_save.m_max_lag)
14249  {
14250  crashSystemAtGcpStop(signal, false);
14251  return;
14252  }
14253 
14254  Uint32 threshold = 60; // seconds
14255  if (cnt0 && ((cnt0 % (threshold * 10)) == 0))
14256  {
14257  if (m_gcp_monitor.m_gcp_save.m_max_lag)
14258  {
14259  warningEvent("GCP Monitor: GCP_SAVE lag %u seconds"
14260  " (max lag: %us)",
14261  cnt0/10, m_gcp_monitor.m_gcp_save.m_max_lag/10);
14262  }
14263  else
14264  {
14265  warningEvent("GCP Monitor: GCP_SAVE lag %u seconds"
14266  " (no max lag)",
14267  cnt0/10);
14268  }
14269  }
14270  }
14271  else
14272  {
14273  jam();
14274  m_gcp_monitor.m_gcp_save.m_gci = m_gcp_save.m_gci;
14275  m_gcp_monitor.m_gcp_save.m_counter = 0;
14276  }
14277 
14278  if (m_gcp_monitor.m_micro_gcp.m_gci == m_micro_gcp.m_current_gci)
14279  {
14280  jam();
14281  Uint32 cmp = m_micro_gcp.m_enabled ?
14282  m_gcp_monitor.m_micro_gcp.m_max_lag :
14283  m_gcp_monitor.m_gcp_save.m_max_lag;
14284 
14285  if (cmp && cnt1 == cmp)
14286  {
14287  crashSystemAtGcpStop(signal, false);
14288  return;
14289  }
14290 
14291  Uint32 threshold = 10; // seconds
14292  if (cnt1 && ((cnt0 % (threshold * 10)) == 0))
14293  {
14294  if (m_gcp_monitor.m_micro_gcp.m_max_lag)
14295  {
14296  warningEvent("GCP Monitor: GCP_COMMIT lag %u seconds"
14297  " (max lag: %u)",
14298  cnt1/10, m_gcp_monitor.m_micro_gcp.m_max_lag/10);
14299  }
14300  else
14301  {
14302  warningEvent("GCP Monitor: GCP_COMMIT lag %u seconds"
14303  " (no max lag)",
14304  cnt1/10);
14305  }
14306  }
14307  }
14308  else
14309  {
14310  jam();
14311  m_gcp_monitor.m_micro_gcp.m_counter = 0;
14312  m_gcp_monitor.m_micro_gcp.m_gci = m_micro_gcp.m_current_gci;
14313  }
14314 
14315  signal->theData[0] = DihContinueB::ZCHECK_GCP_STOP;
14316  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
14317  return;
14318 }//Dbdih::checkGcpStopLab()
14319 
14320 void
14321 Dbdih::dumpGcpStop()
14322 {
14323  ndbout_c("c_nodeStartMaster.blockGcp: %u %u",
14324  c_nodeStartMaster.blockGcp,
14325  c_nodeStartMaster.startNode);
14326  ndbout_c("m_gcp_save.m_counter: %u m_gcp_save.m_max_lag: %u",
14327  m_gcp_monitor.m_gcp_save.m_counter,
14328  m_gcp_monitor.m_gcp_save.m_max_lag);
14329  ndbout_c("m_micro_gcp.m_counter: %u m_micro_gcp.m_max_lag: %u",
14330  m_gcp_monitor.m_micro_gcp.m_counter,
14331  m_gcp_monitor.m_micro_gcp.m_max_lag);
14332 
14333 
14334  ndbout_c("m_gcp_save.m_state: %u", m_gcp_save.m_state);
14335  ndbout_c("m_gcp_save.m_master.m_state: %u", m_gcp_save.m_master.m_state);
14336  ndbout_c("m_micro_gcp.m_state: %u", m_micro_gcp.m_state);
14337  ndbout_c("m_micro_gcp.m_master.m_state: %u", m_micro_gcp.m_master.m_state);
14338 
14339  ndbout_c("c_COPY_GCIREQ_Counter = %s", c_COPY_GCIREQ_Counter.getText());
14340  ndbout_c("c_COPY_TABREQ_Counter = %s", c_COPY_TABREQ_Counter.getText());
14341  ndbout_c("c_CREATE_FRAGREQ_Counter = %s", c_CREATE_FRAGREQ_Counter.getText());
14342  ndbout_c("c_DIH_SWITCH_REPLICA_REQ_Counter = %s",
14343  c_DIH_SWITCH_REPLICA_REQ_Counter.getText());
14344  ndbout_c("c_EMPTY_LCP_REQ_Counter = %s",c_EMPTY_LCP_REQ_Counter.getText());
14345  ndbout_c("c_GCP_COMMIT_Counter = %s", c_GCP_COMMIT_Counter.getText());
14346  ndbout_c("c_GCP_PREPARE_Counter = %s", c_GCP_PREPARE_Counter.getText());
14347  ndbout_c("c_GCP_SAVEREQ_Counter = %s", c_GCP_SAVEREQ_Counter.getText());
14348  ndbout_c("c_SUB_GCP_COMPLETE_REP_Counter = %s",
14349  c_SUB_GCP_COMPLETE_REP_Counter.getText());
14350  ndbout_c("c_INCL_NODEREQ_Counter = %s", c_INCL_NODEREQ_Counter.getText());
14351  ndbout_c("c_MASTER_GCPREQ_Counter = %s", c_MASTER_GCPREQ_Counter.getText());
14352  ndbout_c("c_MASTER_LCPREQ_Counter = %s", c_MASTER_LCPREQ_Counter.getText());
14353  ndbout_c("c_START_INFOREQ_Counter = %s", c_START_INFOREQ_Counter.getText());
14354  ndbout_c("c_START_RECREQ_Counter = %s", c_START_RECREQ_Counter.getText());
14355  ndbout_c("c_STOP_ME_REQ_Counter = %s", c_STOP_ME_REQ_Counter.getText());
14356  ndbout_c("c_TC_CLOPSIZEREQ_Counter = %s", c_TC_CLOPSIZEREQ_Counter.getText());
14357  ndbout_c("c_TCGETOPSIZEREQ_Counter = %s", c_TCGETOPSIZEREQ_Counter.getText());
14358 
14359  ndbout_c("m_copyReason: %d m_waiting: %u %u",
14360  c_copyGCIMaster.m_copyReason,
14361  c_copyGCIMaster.m_waiting[0],
14362  c_copyGCIMaster.m_waiting[1]);
14363 
14364  ndbout_c("c_copyGCISlave: sender{Data, Ref} %d %x reason: %d nextWord: %d",
14365  c_copyGCISlave.m_senderData,
14366  c_copyGCISlave.m_senderRef,
14367  c_copyGCISlave.m_copyReason,
14368  c_copyGCISlave.m_expectedNextWord);
14369 }
14370 
14375 void Dbdih::crashSystemAtGcpStop(Signal* signal, bool local)
14376 {
14377  dumpGcpStop();
14378  Uint32 save_counter = m_gcp_monitor.m_gcp_save.m_counter;
14379  Uint32 micro_counter = m_gcp_monitor.m_micro_gcp.m_counter;
14380  m_gcp_monitor.m_gcp_save.m_counter = 0;
14381  m_gcp_monitor.m_micro_gcp.m_counter = 0;
14382 
14383  if (local)
14384  goto dolocal;
14385 
14386  if (c_nodeStartMaster.blockGcp == 2)
14387  {
14388  jam();
14393  SystemError * const sysErr = (SystemError*)&signal->theData[0];
14394  sysErr->errorCode = SystemError::GCPStopDetected;
14395  sysErr->errorRef = reference();
14396  sysErr->data[0] = m_gcp_save.m_master.m_state;
14397  sysErr->data[1] = cgcpOrderBlocked;
14398  sysErr->data[2] = m_micro_gcp.m_master.m_state;
14399  sendSignal(calcNdbCntrBlockRef(c_nodeStartMaster.startNode),
14400  GSN_SYSTEM_ERROR, signal, SystemError::SignalLength, JBA);
14401  return;
14402  }
14403 
14404  if (save_counter == m_gcp_monitor.m_gcp_save.m_max_lag)
14405  {
14406  switch(m_gcp_save.m_master.m_state){
14407  case GcpSave::GCP_SAVE_IDLE:
14408  {
14412  local = true;
14413  break;
14414  }
14415  case GcpSave::GCP_SAVE_REQ:
14416  {
14417  jam();
14418  NodeReceiverGroup rg(DBLQH, c_GCP_SAVEREQ_Counter);
14419  signal->theData[0] = 2305;
14420  sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBB);
14421 
14422  warningEvent("Detected GCP stop(%d)...sending kill to %s",
14423  m_gcp_save.m_master.m_state, c_GCP_SAVEREQ_Counter.getText());
14424  ndbout_c("Detected GCP stop(%d)...sending kill to %s",
14425  m_gcp_save.m_master.m_state, c_GCP_SAVEREQ_Counter.getText());
14426  ndbrequire(!c_GCP_SAVEREQ_Counter.done());
14427  return;
14428  }
14429  case GcpSave::GCP_SAVE_COPY_GCI:
14430  {
14434  warningEvent("Detected GCP stop(%d)...sending kill to %s",
14435  m_gcp_save.m_master.m_state, c_COPY_GCIREQ_Counter.getText());
14436  ndbout_c("Detected GCP stop(%d)...sending kill to %s",
14437  m_gcp_save.m_master.m_state, c_COPY_GCIREQ_Counter.getText());
14438 
14439  {
14440  NodeReceiverGroup rg(DBDIH, c_COPY_GCIREQ_Counter);
14441  signal->theData[0] = 7022;
14442  sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBA);
14443  }
14444 
14445  {
14446  NodeReceiverGroup rg(NDBCNTR, c_COPY_GCIREQ_Counter);
14447  SystemError * const sysErr = (SystemError*)&signal->theData[0];
14448  sysErr->errorCode = SystemError::GCPStopDetected;
14449  sysErr->errorRef = reference();
14450  sysErr->data[0] = m_gcp_save.m_master.m_state;
14451  sysErr->data[1] = cgcpOrderBlocked;
14452  sysErr->data[2] = m_micro_gcp.m_master.m_state;
14453  sendSignal(rg, GSN_SYSTEM_ERROR, signal,
14454  SystemError::SignalLength, JBA);
14455  }
14456  ndbrequire(!c_COPY_GCIREQ_Counter.done());
14457  return;
14458  }
14459  case GcpSave::GCP_SAVE_CONF:
14463  local = true;
14464  break;
14465  }
14466  }
14467 
14468  if (micro_counter == m_gcp_monitor.m_micro_gcp.m_max_lag)
14469  {
14470  switch(m_micro_gcp.m_master.m_state){
14471  case MicroGcp::M_GCP_IDLE:
14472  {
14476  local = true;
14477  break;
14478  }
14479  case MicroGcp::M_GCP_PREPARE:
14480  {
14484  warningEvent("Detected GCP stop(%d)...sending kill to %s",
14485  m_micro_gcp.m_state, c_GCP_PREPARE_Counter.getText());
14486  ndbout_c("Detected GCP stop(%d)...sending kill to %s",
14487  m_micro_gcp.m_state, c_GCP_PREPARE_Counter.getText());
14488 
14489  {
14490  NodeReceiverGroup rg(DBDIH, c_GCP_PREPARE_Counter);
14491  signal->theData[0] = 7022;
14492  sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBA);
14493  }
14494 
14495  {
14496  NodeReceiverGroup rg(NDBCNTR, c_GCP_PREPARE_Counter);
14497  SystemError * const sysErr = (SystemError*)&signal->theData[0];
14498  sysErr->errorCode = SystemError::GCPStopDetected;
14499  sysErr->errorRef = reference();
14500  sysErr->data[0] = m_gcp_save.m_master.m_state;
14501  sysErr->data[1] = cgcpOrderBlocked;
14502  sysErr->data[2] = m_micro_gcp.m_master.m_state;
14503  sendSignal(rg, GSN_SYSTEM_ERROR, signal,
14504  SystemError::SignalLength, JBA);
14505  }
14506  ndbrequire(!c_GCP_PREPARE_Counter.done());
14507  return;
14508  }
14509  case MicroGcp::M_GCP_COMMIT:
14510  {
14511  warningEvent("Detected GCP stop(%d)...sending kill to %s",
14512  m_micro_gcp.m_state, c_GCP_COMMIT_Counter.getText());
14513  ndbout_c("Detected GCP stop(%d)...sending kill to %s",
14514  m_micro_gcp.m_state, c_GCP_COMMIT_Counter.getText());
14515 
14516  {
14517  NodeReceiverGroup rg(DBDIH, c_GCP_COMMIT_Counter);
14518  signal->theData[0] = 7022;
14519  sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBA);
14520  }
14521 
14522  {
14523  NodeReceiverGroup rg(NDBCNTR, c_GCP_COMMIT_Counter);
14524  SystemError * const sysErr = (SystemError*)&signal->theData[0];
14525  sysErr->errorCode = SystemError::GCPStopDetected;
14526  sysErr->errorRef = reference();
14527  sysErr->data[0] = m_gcp_save.m_master.m_state;
14528  sysErr->data[1] = cgcpOrderBlocked;
14529  sysErr->data[2] = m_micro_gcp.m_master.m_state;
14530  sendSignal(rg, GSN_SYSTEM_ERROR, signal,
14531  SystemError::SignalLength, JBA);
14532  }
14533  ndbrequire(!c_GCP_COMMIT_Counter.done());
14534  return;
14535  }
14536  case MicroGcp::M_GCP_COMMITTED:
14540  local = true;
14541  break;
14542  case MicroGcp::M_GCP_COMPLETE:
14543  infoEvent("Detected GCP stop(%d)...sending kill to %s",
14544  m_micro_gcp.m_state, c_SUB_GCP_COMPLETE_REP_Counter.getText());
14545  ndbout_c("Detected GCP stop(%d)...sending kill to %s",
14546  m_micro_gcp.m_state, c_SUB_GCP_COMPLETE_REP_Counter.getText());
14547 
14548  {
14549  NodeReceiverGroup rg(DBDIH, c_SUB_GCP_COMPLETE_REP_Counter);
14550  signal->theData[0] = 7022;
14551  sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBA);
14552  }
14553 
14554  {
14555  NodeReceiverGroup rg(NDBCNTR, c_SUB_GCP_COMPLETE_REP_Counter);
14556  SystemError * const sysErr = (SystemError*)&signal->theData[0];
14557  sysErr->errorCode = SystemError::GCPStopDetected;
14558  sysErr->errorRef = reference();
14559  sysErr->data[0] = m_gcp_save.m_master.m_state;
14560  sysErr->data[1] = cgcpOrderBlocked;
14561  sysErr->data[2] = m_micro_gcp.m_master.m_state;
14562  sendSignal(rg, GSN_SYSTEM_ERROR, signal,
14563  SystemError::SignalLength, JBA);
14564  }
14565  ndbrequire(!c_SUB_GCP_COMPLETE_REP_Counter.done());
14566  return;
14567  }
14568  }
14569 
14570 dolocal:
14571  FileRecordPtr file0Ptr;
14572  file0Ptr.i = crestartInfoFile[0];
14573  ptrCheckGuard(file0Ptr, cfileFileSize, fileRecord);
14574  FileRecordPtr file1Ptr;
14575  file1Ptr.i = crestartInfoFile[1];
14576  ptrCheckGuard(file1Ptr, cfileFileSize, fileRecord);
14577 
14578  ndbout_c("file[0] status: %d type: %d reqStatus: %d file1: %d %d %d",
14579  file0Ptr.p->fileStatus, file0Ptr.p->fileType, file0Ptr.p->reqStatus,
14580  file1Ptr.p->fileStatus, file1Ptr.p->fileType, file1Ptr.p->reqStatus
14581  );
14582 
14583  signal->theData[0] = 404;
14584  signal->theData[1] = file0Ptr.p->fileRef;
14585  EXECUTE_DIRECT(NDBFS, GSN_DUMP_STATE_ORD, signal, 2);
14586 
14587  signal->theData[0] = 404;
14588  signal->theData[1] = file1Ptr.p->fileRef;
14589  EXECUTE_DIRECT(NDBFS, GSN_DUMP_STATE_ORD, signal, 2);
14590 
14591  jam();
14592  SystemError * const sysErr = (SystemError*)&signal->theData[0];
14593  sysErr->errorCode = SystemError::GCPStopDetected;
14594  sysErr->errorRef = reference();
14595  sysErr->data[0] = m_gcp_save.m_master.m_state;
14596  sysErr->data[1] = cgcpOrderBlocked;
14597  sysErr->data[2] = m_micro_gcp.m_master.m_state;
14598  EXECUTE_DIRECT(NDBCNTR, GSN_SYSTEM_ERROR,
14599  signal, SystemError::SignalLength);
14600  ndbrequire(false);
14601  return;
14602 }//Dbdih::crashSystemAtGcpStop()
14603 
14604 /*************************************************************************/
14605 /* */
14606 /* MODULE: ALLOCPAGE */
14607 /* DESCRIPTION: THE SUBROUTINE IS CALLED WITH POINTER TO PAGE */
14608 /* RECORD. A PAGE RECORD IS TAKEN FROM */
14609 /* THE FREE PAGE LIST */
14610 /*************************************************************************/
14611 void Dbdih::allocpage(PageRecordPtr& pagePtr)
14612 {
14613  ndbrequire(cfirstfreepage != RNIL);
14614  pagePtr.i = cfirstfreepage;
14615  ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
14616  cfirstfreepage = pagePtr.p->nextfreepage;
14617  pagePtr.p->nextfreepage = RNIL;
14618 }//Dbdih::allocpage()
14619 
14620 /*************************************************************************/
14621 /* */
14622 /* MODULE: ALLOC_STORED_REPLICA */
14623 /* DESCRIPTION: THE SUBROUTINE IS CALLED TO GET A REPLICA RECORD, */
14624 /* TO INITIALISE IT AND TO LINK IT INTO THE FRAGMENT */
14625 /* STORE RECORD. USED FOR STORED REPLICAS. */
14626 /*************************************************************************/
14627 void Dbdih::allocStoredReplica(FragmentstorePtr fragPtr,
14628  ReplicaRecordPtr& newReplicaPtr,
14629  Uint32 nodeId)
14630 {
14631  Uint32 i;
14632  ReplicaRecordPtr arrReplicaPtr;
14633  ReplicaRecordPtr arrPrevReplicaPtr;
14634 
14635  seizeReplicaRec(newReplicaPtr);
14636  for (i = 0; i < MAX_LCP_STORED; i++) {
14637  newReplicaPtr.p->maxGciCompleted[i] = 0;
14638  newReplicaPtr.p->maxGciStarted[i] = 0;
14639  newReplicaPtr.p->lcpId[i] = 0;
14640  newReplicaPtr.p->lcpStatus[i] = ZINVALID;
14641  }//for
14642  newReplicaPtr.p->noCrashedReplicas = 0;
14643  newReplicaPtr.p->initialGci = (Uint32)(m_micro_gcp.m_current_gci >> 32);
14644  for (i = 0; i < MAX_CRASHED_REPLICAS; i++) {
14645  newReplicaPtr.p->replicaLastGci[i] = ZINIT_REPLICA_LAST_GCI;
14646  newReplicaPtr.p->createGci[i] = ZINIT_CREATE_GCI;
14647  }//for
14648  newReplicaPtr.p->createGci[0] = (Uint32)(m_micro_gcp.m_current_gci >> 32);
14649  newReplicaPtr.p->nextLcp = 0;
14650  newReplicaPtr.p->procNode = nodeId;
14651  newReplicaPtr.p->lcpOngoingFlag = false;
14652  newReplicaPtr.p->lcpIdStarted = 0;
14653 
14654  arrPrevReplicaPtr.i = RNIL;
14655  arrReplicaPtr.i = fragPtr.p->storedReplicas;
14656  while (arrReplicaPtr.i != RNIL) {
14657  jam();
14658  ptrCheckGuard(arrReplicaPtr, creplicaFileSize, replicaRecord);
14659  arrPrevReplicaPtr = arrReplicaPtr;
14660  arrReplicaPtr.i = arrReplicaPtr.p->nextReplica;
14661  }//while
14662  if (arrPrevReplicaPtr.i == RNIL) {
14663  jam();
14664  fragPtr.p->storedReplicas = newReplicaPtr.i;
14665  } else {
14666  jam();
14667  arrPrevReplicaPtr.p->nextReplica = newReplicaPtr.i;
14668  }//if
14669  fragPtr.p->noStoredReplicas++;
14670 }//Dbdih::allocStoredReplica()
14671 
14672 /*************************************************************************/
14673 /* CHECK IF THE NODE CRASH IS TO ESCALATE INTO A SYSTEM CRASH. WE COULD */
14674 /* DO THIS BECAUSE ALL REPLICAS OF SOME FRAGMENT ARE LOST. WE COULD ALSO */
14675 /* DO IT AFTER MANY NODE FAILURES THAT MAKE IT VERY DIFFICULT TO RESTORE */
14676 /* DATABASE AFTER A SYSTEM CRASH. IT MIGHT EVEN BE IMPOSSIBLE AND THIS */
14677 /* MUST BE AVOIDED EVEN MORE THAN AVOIDING SYSTEM CRASHES. */
14678 /*************************************************************************/
14679 void Dbdih::checkEscalation()
14680 {
14681  Uint32 TnodeGroup[MAX_NDB_NODES];
14682  NodeRecordPtr nodePtr;
14683  Uint32 i;
14684  for (i = 0; i < cnoOfNodeGroups; i++) {
14685  TnodeGroup[i] = ZFALSE;
14686  }//for
14687  for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
14688  jam();
14689  ptrAss(nodePtr, nodeRecord);
14690  if (nodePtr.p->nodeStatus == NodeRecord::ALIVE &&
14691  nodePtr.p->activeStatus == Sysfile::NS_Active){
14692  ndbrequire(nodePtr.p->nodeGroup < MAX_NDB_NODES);
14693  TnodeGroup[nodePtr.p->nodeGroup] = ZTRUE;
14694  }
14695  }
14696  for (i = 0; i < cnoOfNodeGroups; i++) {
14697  jam();
14698  if (TnodeGroup[c_node_groups[i]] == ZFALSE) {
14699  jam();
14700  progError(__LINE__, NDBD_EXIT_LOST_NODE_GROUP, "Lost node group");
14701  }//if
14702  }//for
14703 }//Dbdih::checkEscalation()
14704 
14705 /*************************************************************************/
14706 /* */
14707 /* MODULE: CHECK_KEEP_GCI */
14708 /* DESCRIPTION: CHECK FOR MINIMUM GCI RESTORABLE WITH NEW LOCAL */
14709 /* CHECKPOINT. */
14710 /*************************************************************************/
14711 void Dbdih::checkKeepGci(TabRecordPtr tabPtr, Uint32 fragId, Fragmentstore*,
14712  Uint32 replicaStartIndex)
14713 {
14714  ReplicaRecordPtr ckgReplicaPtr;
14715  ckgReplicaPtr.i = replicaStartIndex;
14716  while (ckgReplicaPtr.i != RNIL) {
14717  jam();
14718  ptrCheckGuard(ckgReplicaPtr, creplicaFileSize, replicaRecord);
14719  if (c_lcpState.m_participatingLQH.get(ckgReplicaPtr.p->procNode))
14720  {
14721  Uint32 keepGci;
14722  Uint32 oldestRestorableGci;
14723  findMinGci(ckgReplicaPtr, keepGci, oldestRestorableGci);
14724  if (keepGci < c_lcpState.keepGci) {
14725  jam();
14726  /* ----------------------------------------------------------------- */
14727  /* WE MUST KEEP LOG RECORDS SO THAT WE CAN USE ALL LOCAL CHECKPOINTS */
14728  /* THAT ARE AVAILABLE. THUS WE NEED TO CALCULATE THE MINIMUM OVER ALL*/
14729  /* FRAGMENTS. */
14730  /* ----------------------------------------------------------------- */
14731  c_lcpState.keepGci = keepGci;
14732  }//if
14733  if (oldestRestorableGci > c_lcpState.oldestRestorableGci) {
14734  jam();
14735  c_lcpState.oldestRestorableGci = oldestRestorableGci;
14736  }//if
14737  }
14738  ckgReplicaPtr.i = ckgReplicaPtr.p->nextReplica;
14739  }//while
14740 }//Dbdih::checkKeepGci()
14741 
14742 void Dbdih::closeFile(Signal* signal, FileRecordPtr filePtr)
14743 {
14744  signal->theData[0] = filePtr.p->fileRef;
14745  signal->theData[1] = reference();
14746  signal->theData[2] = filePtr.i;
14747  signal->theData[3] = ZCLOSE_NO_DELETE;
14748  sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, 4, JBA);
14749 }//Dbdih::closeFile()
14750 
14751 void Dbdih::closeFileDelete(Signal* signal, FileRecordPtr filePtr)
14752 {
14753  signal->theData[0] = filePtr.p->fileRef;
14754  signal->theData[1] = reference();
14755  signal->theData[2] = filePtr.i;
14756  signal->theData[3] = ZCLOSE_DELETE;
14757  sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, 4, JBA);
14758 }//Dbdih::closeFileDelete()
14759 
14760 void Dbdih::createFileRw(Signal* signal, FileRecordPtr filePtr)
14761 {
14762  signal->theData[0] = reference();
14763  signal->theData[1] = filePtr.i;
14764  signal->theData[2] = filePtr.p->fileName[0];
14765  signal->theData[3] = filePtr.p->fileName[1];
14766  signal->theData[4] = filePtr.p->fileName[2];
14767  signal->theData[5] = filePtr.p->fileName[3];
14768  signal->theData[6] = ZCREATE_READ_WRITE;
14769  sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
14770 }//Dbdih::createFileRw()
14771 
14772 void
14773 Dbdih::emptyverificbuffer(Signal* signal, Uint32 q, bool aContinueB)
14774 {
14775  if(unlikely(getBlockCommit() == true))
14776  {
14777  jam();
14778  return;
14779  }
14780 
14781  if (!isEmpty(c_diverify_queue[q]))
14782  {
14783  jam();
14784 
14785  ApiConnectRecord localApiConnect;
14786  dequeue(c_diverify_queue[q], localApiConnect);
14787  ndbrequire(localApiConnect.apiGci <= m_micro_gcp.m_current_gci);
14788  signal->theData[0] = localApiConnect.senderData;
14789  signal->theData[1] = (Uint32)(m_micro_gcp.m_current_gci >> 32);
14790  signal->theData[2] = (Uint32)(m_micro_gcp.m_current_gci & 0xFFFFFFFF);
14791  signal->theData[3] = 0;
14792  sendSignal(c_diverify_queue[q].m_ref, GSN_DIVERIFYCONF, signal, 4, JBB);
14793  }
14794  else if (aContinueB == true)
14795  {
14796  jam();
14802  Uint32 blocks[] = { DBTC, 0 };
14803  Callback c = { safe_cast(&Dbdih::emptyverificbuffer_check), q };
14804  synchronize_threads_for_blocks(signal, blocks, c);
14805  return;
14806  }
14807 
14808  if (aContinueB == true)
14809  {
14810  jam();
14811  //-----------------------------------------------------------------------
14812  // This emptying happened as part of a take-out process by continueb signals
14813  // This ensures that we will empty the queue eventually. We will also empty
14814  // one item every time we insert one item to ensure that the list doesn't
14815  // grow when it is not blocked.
14816  //-----------------------------------------------------------------------
14817  signal->theData[0] = DihContinueB::ZEMPTY_VERIFY_QUEUE;
14818  signal->theData[1] = q;
14819  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
14820  }//if
14821 
14822  return;
14823 }//Dbdih::emptyverificbuffer()
14824 
14825 void
14826 Dbdih::emptyverificbuffer_check(Signal* signal, Uint32 q, Uint32 retVal)
14827 {
14828  ndbrequire(retVal == 0);
14829  if (!isEmpty(c_diverify_queue[q]))
14830  {
14831  jam();
14832  signal->theData[0] = DihContinueB::ZEMPTY_VERIFY_QUEUE;
14833  signal->theData[1] = q;
14834  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
14835  }
14836  else
14837  {
14841  c_diverify_queue[q].m_empty_done = 1;
14842  }
14843 }
14844 
14845 /*************************************************************************/
14846 /* FIND THE NODES FROM WHICH WE CAN EXECUTE THE LOG TO RESTORE THE */
14847 /* DATA NODE IN A SYSTEM RESTART. */
14848 /*************************************************************************/
14849 bool Dbdih::findLogNodes(CreateReplicaRecord* createReplica,
14850  FragmentstorePtr fragPtr,
14851  Uint32 startGci,
14852  Uint32 stopGci)
14853 {
14854  ConstPtr<ReplicaRecord> flnReplicaPtr;
14855  flnReplicaPtr.i = createReplica->replicaRec;
14856  ptrCheckGuard(flnReplicaPtr, creplicaFileSize, replicaRecord);
14857  /* --------------------------------------------------------------------- */
14858  /* WE START BY CHECKING IF THE DATA NODE CAN HANDLE THE LOG ALL BY */
14859  /* ITSELF. THIS IS THE DESIRED BEHAVIOUR. IF THIS IS NOT POSSIBLE */
14860  /* THEN WE SEARCH FOR THE BEST POSSIBLE NODES AMONG THE NODES THAT */
14861  /* ARE PART OF THIS SYSTEM RESTART. */
14862  /* THIS CAN ONLY BE HANDLED BY THE LAST CRASHED REPLICA. */
14863  /* The condition is that the replica was created before or at the */
14864  /* time of the starting gci, in addition it must have been alive */
14865  /* at the time of the stopping gci. This is checked by two */
14866  /* conditions, the first checks replicaLastGci and the second */
14867  /* checks that it is also smaller than the last gci the node was */
14868  /* involved in. This is necessary to check since createGci is set */
14869  /* Last + 1 and sometimes startGci = stopGci + 1 and in that case */
14870  /* it could happen that replicaLastGci is set to -1 with CreateGci */
14871  /* set to LastGci + 1. */
14872  /* --------------------------------------------------------------------- */
14873  arrGuard(flnReplicaPtr.p->noCrashedReplicas, MAX_CRASHED_REPLICAS);
14874  const Uint32 noCrashed = flnReplicaPtr.p->noCrashedReplicas;
14875 
14876  if (!(ERROR_INSERTED(7073) || ERROR_INSERTED(7074))&&
14877  (startGci >= flnReplicaPtr.p->createGci[noCrashed]) &&
14878  (stopGci <= flnReplicaPtr.p->replicaLastGci[noCrashed]) &&
14879  (stopGci <= SYSFILE->lastCompletedGCI[flnReplicaPtr.p->procNode])) {
14880  jam();
14881  /* --------------------------------------------------------------------- */
14882  /* WE FOUND ALL THE LOG RECORDS NEEDED IN THE DATA NODE. WE WILL */
14883  /* USE THOSE. */
14884  /* --------------------------------------------------------------------- */
14885  createReplica->noLogNodes = 1;
14886  createReplica->logStartGci[0] = startGci;
14887  createReplica->logStopGci[0] = stopGci;
14888  createReplica->logNodeId[0] = flnReplicaPtr.p->procNode;
14889  return true;
14890  }//if
14891  Uint32 logNode = 0;
14892  do {
14893  Uint32 fblStopGci;
14894  jam();
14895  if(!findBestLogNode(createReplica,
14896  fragPtr,
14897  startGci,
14898  stopGci,
14899  logNode,
14900  fblStopGci)){
14901  jam();
14902  return false;
14903  }
14904 
14905  logNode++;
14906  if (fblStopGci >= stopGci) {
14907  jam();
14908  createReplica->noLogNodes = logNode;
14909  return true;
14910  }//if
14911  startGci = fblStopGci + 1;
14912  if (logNode >= MAX_LOG_EXEC)
14913  {
14914  jam();
14915  break;
14916  }//if
14917  } while (1);
14918  /* --------------------------------------------------------------------- */
14919  /* IT WAS NOT POSSIBLE TO RESTORE THE REPLICA. THIS CAN EITHER BE */
14920  /* BECAUSE OF LACKING NODES OR BECAUSE OF A REALLY SERIOUS PROBLEM.*/
14921  /* --------------------------------------------------------------------- */
14922  return false;
14923 }//Dbdih::findLogNodes()
14924 
14925 /*************************************************************************/
14926 /* FIND THE BEST POSSIBLE LOG NODE TO EXECUTE THE LOG AS SPECIFIED */
14927 /* BY THE INPUT PARAMETERS. WE SCAN THROUGH ALL ALIVE REPLICAS. */
14928 /* THIS MEANS STORED, OLD_STORED */
14929 /*************************************************************************/
14930 bool
14931 Dbdih::findBestLogNode(CreateReplicaRecord* createReplica,
14932  FragmentstorePtr fragPtr,
14933  Uint32 startGci,
14934  Uint32 stopGci,
14935  Uint32 logNode,
14936  Uint32& fblStopGci)
14937 {
14938  ConstPtr<ReplicaRecord> fblFoundReplicaPtr;
14939  ConstPtr<ReplicaRecord> fblReplicaPtr;
14940  LINT_INIT(fblFoundReplicaPtr.p);
14941 
14942  /* --------------------------------------------------------------------- */
14943  /* WE START WITH ZERO AS FOUND TO ENSURE THAT FIRST HIT WILL BE */
14944  /* BETTER. */
14945  /* --------------------------------------------------------------------- */
14946  fblStopGci = 0;
14947  fblReplicaPtr.i = fragPtr.p->storedReplicas;
14948  while (fblReplicaPtr.i != RNIL) {
14949  jam();
14950  ptrCheckGuard(fblReplicaPtr, creplicaFileSize, replicaRecord);
14951  if (m_sr_nodes.get(fblReplicaPtr.p->procNode))
14952  {
14953  jam();
14954  Uint32 fliStopGci = findLogInterval(fblReplicaPtr, startGci);
14955  if (fliStopGci > fblStopGci)
14956  {
14957  jam();
14958  fblStopGci = fliStopGci;
14959  fblFoundReplicaPtr = fblReplicaPtr;
14960  }//if
14961  }//if
14962  fblReplicaPtr.i = fblReplicaPtr.p->nextReplica;
14963  }//while
14964  fblReplicaPtr.i = fragPtr.p->oldStoredReplicas;
14965  while (fblReplicaPtr.i != RNIL) {
14966  jam();
14967  ptrCheckGuard(fblReplicaPtr, creplicaFileSize, replicaRecord);
14968  if (m_sr_nodes.get(fblReplicaPtr.p->procNode))
14969  {
14970  jam();
14971  Uint32 fliStopGci = findLogInterval(fblReplicaPtr, startGci);
14972  if (fliStopGci > fblStopGci)
14973  {
14974  jam();
14975  fblStopGci = fliStopGci;
14976  fblFoundReplicaPtr = fblReplicaPtr;
14977  }//if
14978  }//if
14979  fblReplicaPtr.i = fblReplicaPtr.p->nextReplica;
14980  }//while
14981  if (fblStopGci != 0) {
14982  jam();
14983  ndbrequire(logNode < MAX_LOG_EXEC);
14984  createReplica->logNodeId[logNode] = fblFoundReplicaPtr.p->procNode;
14985  createReplica->logStartGci[logNode] = startGci;
14986  if (fblStopGci >= stopGci) {
14987  jam();
14988  createReplica->logStopGci[logNode] = stopGci;
14989  } else {
14990  jam();
14991  createReplica->logStopGci[logNode] = fblStopGci;
14992  }//if
14993  }//if
14994 
14995  return fblStopGci != 0;
14996 }//Dbdih::findBestLogNode()
14997 
14998 Uint32 Dbdih::findLogInterval(ConstPtr<ReplicaRecord> replicaPtr,
14999  Uint32 startGci)
15000 {
15001  ndbrequire(replicaPtr.p->noCrashedReplicas <= MAX_CRASHED_REPLICAS);
15002  Uint32 loopLimit = replicaPtr.p->noCrashedReplicas + 1;
15003  for (Uint32 i = 0; i < loopLimit; i++) {
15004  jam();
15005  if (replicaPtr.p->createGci[i] <= startGci) {
15006  if (replicaPtr.p->replicaLastGci[i] >= startGci) {
15007  jam();
15008  return replicaPtr.p->replicaLastGci[i];
15009  }//if
15010  }//if
15011  }//for
15012  return 0;
15013 }//Dbdih::findLogInterval()
15014 
15015 /*************************************************************************/
15016 /* */
15017 /* MODULE: FIND THE MINIMUM GCI THAT THIS NODE HAS LOG RECORDS FOR.*/
15018 /*************************************************************************/
15019 void Dbdih::findMinGci(ReplicaRecordPtr fmgReplicaPtr,
15020  Uint32& keepGci,
15021  Uint32& oldestRestorableGci)
15022 {
15023  keepGci = (Uint32)-1;
15024  oldestRestorableGci = 0;
15025 
15026  Uint32 maxLcpId = 0; // LcpId of latest valid LCP
15027  Uint32 maxLcpNo = MAX_LCP_STORED; // Index of latest valid LCP
15028  for (Uint32 i = 0; i < MAX_LCP_STORED; i++)
15029  {
15030  jam();
15031  if (fmgReplicaPtr.p->lcpStatus[i] == ZVALID)
15032  {
15033  if ((fmgReplicaPtr.p->lcpId[i] + MAX_LCP_STORED) <= (SYSFILE->latestLCP_ID + 1))
15034  {
15035  jam();
15036  /*-----------------------------------------------------------------*/
15037  // We invalidate the checkpoint we are preparing to overwrite.
15038  // The LCP id is still the old lcp id,
15039  // this is the reason of comparing with lcpId + 1.
15040  /*-----------------------------------------------------------------*/
15041  fmgReplicaPtr.p->lcpStatus[i] = ZINVALID;
15042  }
15043  else if (fmgReplicaPtr.p->lcpId[i] > maxLcpId)
15044  {
15045  jam();
15046  maxLcpId = fmgReplicaPtr.p->lcpId[i];
15047  maxLcpNo = i;
15048  }
15049  }
15050  }
15051 
15052  if (maxLcpNo < MAX_LCP_STORED)
15053  {
15057  jam();
15058  keepGci = fmgReplicaPtr.p->maxGciCompleted[maxLcpNo];
15059  oldestRestorableGci = fmgReplicaPtr.p->maxGciStarted[maxLcpNo];
15060  }
15061 
15062  if (oldestRestorableGci == 0 && keepGci == Uint32(-1))
15063  {
15064  jam();
15065  if (fmgReplicaPtr.p->createGci[0] == fmgReplicaPtr.p->initialGci)
15066  {
15067  keepGci = fmgReplicaPtr.p->createGci[0];
15068  // XXX Jonas
15069  //oldestRestorableGci = fmgReplicaPtr.p->createGci[0];
15070  }
15071  }
15072  else
15073  {
15074  ndbassert(oldestRestorableGci <= c_newest_restorable_gci);
15075  }
15076  return;
15077 }//Dbdih::findMinGci()
15078 
15079 bool Dbdih::findStartGci(ConstPtr<ReplicaRecord> replicaPtr,
15080  Uint32 stopGci,
15081  Uint32& startGci,
15082  Uint32& lcpNo)
15083 {
15084  Uint32 cnt = 0;
15085  Uint32 tmp[MAX_LCP_STORED];
15086  for (Uint32 i = 0; i<MAX_LCP_STORED; i++)
15087  {
15088  jam();
15089  if (replicaPtr.p->lcpStatus[i] == ZVALID &&
15090  replicaPtr.p->maxGciStarted[i] <= stopGci)
15091  {
15097  jam();
15098  tmp[cnt] = i;
15099  cnt++;
15100  }
15101  }
15102 
15103  if (cnt)
15104  {
15105  jam();
15109  lcpNo = tmp[0];
15110  Uint32 lcpId = replicaPtr.p->lcpId[lcpNo];
15111  for (Uint32 i = 1; i<cnt; i++)
15112  {
15113  jam();
15114  if (replicaPtr.p->lcpId[tmp[i]] > lcpId)
15115  {
15116  jam();
15117  lcpNo = tmp[i];
15118  lcpId = replicaPtr.p->lcpId[lcpNo];
15119  }
15120  }
15121  startGci = replicaPtr.p->maxGciCompleted[lcpNo] + 1;
15122  return true;
15123  }
15124 
15125  /* --------------------------------------------------------------------- */
15126  /* NO VALID LOCAL CHECKPOINT WAS AVAILABLE. WE WILL ADD THE */
15127  /* FRAGMENT. THUS THE NEXT LCP MUST BE SET TO ZERO. */
15128  /* WE MUST EXECUTE THE LOG FROM THE INITIAL GLOBAL CHECKPOINT WHEN */
15129  /* THE TABLE WAS CREATED. */
15130  /* --------------------------------------------------------------------- */
15131  startGci = replicaPtr.p->initialGci;
15132  ndbrequire(replicaPtr.p->nextLcp == 0);
15133  return false;
15134 }//Dbdih::findStartGci()
15135 
15136 static
15137 Uint32
15138 count_db_nodes(ndb_mgm_configuration_iterator * iter)
15139 {
15140  Uint32 cnt = 0;
15141  for (ndb_mgm_first(iter); ndb_mgm_valid(iter); ndb_mgm_next(iter))
15142  {
15143  Uint32 nodeId = 0;
15144  Uint32 type = ~Uint32(0);
15145  if (ndb_mgm_get_int_parameter(iter, CFG_NODE_ID, &nodeId) == 0 &&
15146  ndb_mgm_get_int_parameter(iter,CFG_TYPE_OF_SECTION, &type) == 0 &&
15147  type == NodeInfo::DB)
15148  {
15149  cnt++;
15150  }
15151  }
15152  return cnt;
15153 }
15154 
15159 static
15160 Uint32
15161 compute_max_failure_time(const ndb_mgm_configuration_iterator * p,
15163 {
15164  Uint32 dbnodes = count_db_nodes(cluster);
15165 
15166  Uint32 hbDBDB = 1500;
15167  Uint32 arbitTimeout = 1000;
15168  ndb_mgm_get_int_parameter(p, CFG_DB_HEARTBEAT_INTERVAL, &hbDBDB);
15169  ndb_mgm_get_int_parameter(p, CFG_DB_ARBIT_TIMEOUT, &arbitTimeout);
15170 
15171  /*
15172  * Max time for 1 node failure is
15173  */
15174  Uint32 max_time_one_failure = arbitTimeout + 4 * hbDBDB;
15175 
15179  Uint32 max_time_total_failure = (dbnodes - 1) * max_time_one_failure;
15180 
15181  return max_time_total_failure;
15182 }
15183 
15184 void Dbdih::initCommonData()
15185 {
15186  c_blockCommit = false;
15187  c_blockCommitNo = 0;
15188  cfailurenr = 1;
15189  cfirstAliveNode = RNIL;
15190  cfirstDeadNode = RNIL;
15191  cgckptflag = false;
15192  cgcpOrderBlocked = 0;
15193 
15194  c_lcpMasterTakeOverState.set(LMTOS_IDLE, __LINE__);
15195 
15196  c_lcpState.clcpDelay = 0;
15197  c_lcpState.lcpStart = ZIDLE;
15198  c_lcpState.lcpStopGcp = 0;
15199  c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
15200  c_lcpState.currentFragment.tableId = 0;
15201  c_lcpState.currentFragment.fragmentId = 0;
15202  c_lcpState.noOfLcpFragRepOutstanding = 0;
15203  c_lcpState.keepGci = 0;
15204  c_lcpState.oldestRestorableGci = 0;
15205  c_lcpState.ctcCounter = 0;
15206  c_lcpState.ctimer = 0;
15207  c_lcpState.immediateLcpStart = false;
15208  c_lcpState.m_MASTER_LCPREQ_Received = false;
15209  c_lcpState.m_lastLCP_COMPLETE_REP_ref = 0;
15210  cmasterdihref = 0;
15211  cmasterNodeId = 0;
15212  cmasterState = MASTER_IDLE;
15213  cmasterTakeOverNode = 0;
15214  cnoOfActiveTables = 0;
15215  cnoOfNodeGroups = 0;
15216  c_nextNodeGroup = 0;
15217  cnoReplicas = 0;
15218  con_lineNodes = 0;
15219  creceivedfrag = 0;
15220  crestartGci = 0;
15221  crestartInfoFile[0] = RNIL;
15222  crestartInfoFile[1] = RNIL;
15223  cstartPhase = 0;
15224  cstarttype = (Uint32)-1;
15225  csystemnodes = 0;
15226  c_newest_restorable_gci = 0;
15227  cwaitLcpSr = false;
15228  c_nodeStartMaster.blockGcp = 0;
15229 
15230  nodeResetStart(0);
15231  c_nodeStartMaster.wait = ZFALSE;
15232 
15233  memset(&sysfileData[0], 0, sizeof(sysfileData));
15234 
15235  const ndb_mgm_configuration_iterator * p =
15236  m_ctx.m_config.getOwnConfigIterator();
15237  ndbrequire(p != 0);
15238 
15239  c_lcpState.clcpDelay = 20;
15240  ndb_mgm_get_int_parameter(p, CFG_DB_LCP_INTERVAL, &c_lcpState.clcpDelay);
15241  c_lcpState.clcpDelay = c_lcpState.clcpDelay > 31 ? 31 : c_lcpState.clcpDelay;
15242 
15243  //ndb_mgm_get_int_parameter(p, CFG_DB_MIN_HOT_SPARES, &cminHotSpareNodes);
15244 
15245  cnoReplicas = 1;
15246  ndb_mgm_get_int_parameter(p, CFG_DB_NO_REPLICAS, &cnoReplicas);
15247  if (cnoReplicas > MAX_REPLICAS)
15248  {
15249  progError(__LINE__, NDBD_EXIT_INVALID_CONFIG,
15250  "Only up to four replicas are supported. Check NoOfReplicas.");
15251  }
15252 
15253  Uint32 max_failure_time = compute_max_failure_time
15254  (p, m_ctx.m_config.getClusterConfigIterator());
15255 
15256  bzero(&m_gcp_save, sizeof(m_gcp_save));
15257  bzero(&m_micro_gcp, sizeof(m_micro_gcp));
15258  {
15259  { // Set time-between global checkpoint
15260  Uint32 tmp = 2000;
15261  ndb_mgm_get_int_parameter(p, CFG_DB_GCP_INTERVAL, &tmp);
15262  tmp = tmp > 60000 ? 60000 : (tmp < 10 ? 10 : tmp);
15263  m_gcp_save.m_master.m_time_between_gcp = tmp;
15264  }
15265 
15266  Uint32 tmp = 0;
15267  if (ndb_mgm_get_int_parameter(p, CFG_DB_MICRO_GCP_INTERVAL, &tmp) == 0 &&
15268  tmp)
15269  {
15273  if (tmp > m_gcp_save.m_master.m_time_between_gcp)
15274  tmp = m_gcp_save.m_master.m_time_between_gcp;
15275  if (tmp < 10)
15276  tmp = 10;
15277  m_micro_gcp.m_master.m_time_between_gcp = tmp;
15278  }
15279 
15280  { // Set time-between global checkpoint timeout
15281  Uint32 tmp = 120000; // No config, hard code 2 minutes
15282  tmp += max_failure_time; //
15283  m_gcp_monitor.m_gcp_save.m_max_lag =
15284  (m_gcp_save.m_master.m_time_between_gcp + tmp) / 100;
15285  }
15286 
15287  { // Set time-between epochs timeout
15288  Uint32 tmp = 4000;
15289  ndb_mgm_get_int_parameter(p, CFG_DB_MICRO_GCP_TIMEOUT, &tmp);
15290  if (tmp != 0)
15291  {
15292  jam();
15293  tmp += max_failure_time;
15294  m_gcp_monitor.m_micro_gcp.m_max_lag =
15295  (m_micro_gcp.m_master.m_time_between_gcp + tmp) / 100;
15296  }
15297  else
15298  {
15299  jam();
15300  m_gcp_monitor.m_gcp_save.m_max_lag = 0;
15301  m_gcp_monitor.m_micro_gcp.m_max_lag = 0;
15302  }
15303  }
15304  }
15305 }//Dbdih::initCommonData()
15306 
15307 void Dbdih::initFragstore(FragmentstorePtr fragPtr)
15308 {
15309  fragPtr.p->storedReplicas = RNIL;
15310  fragPtr.p->oldStoredReplicas = RNIL;
15311 
15312  fragPtr.p->noStoredReplicas = 0;
15313  fragPtr.p->noOldStoredReplicas = 0;
15314  fragPtr.p->fragReplicas = 0;
15315  fragPtr.p->preferredPrimary = 0;
15316 
15317  for (Uint32 i = 0; i < MAX_REPLICAS; i++)
15318  fragPtr.p->activeNodes[i] = 0;
15319 
15320  fragPtr.p->noLcpReplicas = 0;
15321  fragPtr.p->distributionKey = 0;
15322 }//Dbdih::initFragstore()
15323 
15324 /*************************************************************************/
15325 /* */
15326 /* MODULE: INIT_RESTART_INFO */
15327 /* DESCRIPTION: INITIATE RESTART INFO VARIABLE AND VARIABLES FOR */
15328 /* GLOBAL CHECKPOINTS. */
15329 /*************************************************************************/
15330 void Dbdih::initRestartInfo(Signal* signal)
15331 {
15332  Uint32 i;
15333  for (i = 0; i < MAX_NDB_NODES; i++) {
15334  SYSFILE->lastCompletedGCI[i] = 0;
15335  }//for
15336  NodeRecordPtr nodePtr;
15337  nodePtr.i = cfirstAliveNode;
15338  do {
15339  jam();
15340  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15341  SYSFILE->lastCompletedGCI[nodePtr.i] = 1;
15342  /* FIRST GCP = 1 ALREADY SET BY LQH */
15343  nodePtr.i = nodePtr.p->nextNode;
15344  } while (nodePtr.i != RNIL);
15345 
15346  Uint32 startGci = 1;
15347 #ifndef DBUG_OFF
15348  {
15349  char envBuf[256];
15350  const char* v = NdbEnv_GetEnv("NDB_START_GCI",
15351  envBuf,
15352  256);
15353  if (v && *v != 0)
15354  {
15355  startGci = strtoull(v, NULL, 0);
15356 
15357  ndbout_c("DbDih : Using value of %u from NDB_START_GCI",
15358  startGci);
15359  }
15360  }
15361 #endif
15362 
15363  m_micro_gcp.m_old_gci = Uint64(startGci) << 32;
15364  m_micro_gcp.m_current_gci = Uint64(startGci + 1) << 32;
15365  crestartGci = startGci;
15366  c_newest_restorable_gci = startGci;
15367 
15368  SYSFILE->keepGCI = startGci;
15369  SYSFILE->oldestRestorableGCI = startGci;
15370  SYSFILE->newestRestorableGCI = startGci;
15371  SYSFILE->systemRestartBits = 0;
15372  for (i = 0; i < NdbNodeBitmask::Size; i++) {
15373  SYSFILE->lcpActive[0] = 0;
15374  }//for
15375  for (i = 0; i < Sysfile::TAKE_OVER_SIZE; i++) {
15376  SYSFILE->takeOver[i] = 0;
15377  }//for
15378  Sysfile::setInitialStartOngoing(SYSFILE->systemRestartBits);
15379  srand((unsigned int)time(0));
15380  globalData.m_restart_seq = SYSFILE->m_restart_seq = 0;
15381 
15382  if (m_micro_gcp.m_enabled == false &&
15383  m_micro_gcp.m_master.m_time_between_gcp)
15384  {
15388  jam();
15389  m_micro_gcp.m_enabled = true;
15390  UpgradeProtocolOrd * ord = (UpgradeProtocolOrd*)signal->getDataPtrSend();
15391  ord->type = UpgradeProtocolOrd::UPO_ENABLE_MICRO_GCP;
15392  EXECUTE_DIRECT(QMGR,GSN_UPGRADE_PROTOCOL_ORD,signal,signal->getLength());
15393  }
15394 }//Dbdih::initRestartInfo()
15395 
15396 /*--------------------------------------------------------------------*/
15397 /* NODE GROUP BITS ARE INITIALISED BEFORE THIS. */
15398 /* NODE ACTIVE BITS ARE INITIALISED BEFORE THIS. */
15399 /*--------------------------------------------------------------------*/
15400 /*************************************************************************/
15401 /* */
15402 /* MODULE: INIT_RESTORABLE_GCI_FILES */
15403 /* DESCRIPTION: THE SUBROUTINE SETS UP THE FILES THAT REFERS TO THE*/
15404 /* FILES THAT KEEP THE VARIABLE CRESTART_INFO */
15405 /*************************************************************************/
15406 void Dbdih::initRestorableGciFiles()
15407 {
15408  Uint32 tirgTmp;
15409  FileRecordPtr filePtr;
15410  seizeFile(filePtr);
15411  filePtr.p->tabRef = RNIL;
15412  filePtr.p->fileType = FileRecord::GCP_FILE;
15413  filePtr.p->reqStatus = FileRecord::IDLE;
15414  filePtr.p->fileStatus = FileRecord::CLOSED;
15415  crestartInfoFile[0] = filePtr.i;
15416  filePtr.p->fileName[0] = (Uint32)-1; /* T DIRECTORY NOT USED */
15417  filePtr.p->fileName[1] = (Uint32)-1; /* F DIRECTORY NOT USED */
15418  filePtr.p->fileName[2] = (Uint32)-1; /* S PART IGNORED */
15419  tirgTmp = 1; /* FILE NAME VERSION 1 */
15420  tirgTmp = (tirgTmp << 8) + 6; /* .SYSFILE */
15421  tirgTmp = (tirgTmp << 8) + 1; /* D1 DIRECTORY */
15422  tirgTmp = (tirgTmp << 8) + 0; /* P0 FILE NAME */
15423  filePtr.p->fileName[3] = tirgTmp;
15424  /* --------------------------------------------------------------------- */
15425  /* THE NAME BECOMES /D1/DBDICT/S0.SYSFILE */
15426  /* --------------------------------------------------------------------- */
15427  seizeFile(filePtr);
15428  filePtr.p->tabRef = RNIL;
15429  filePtr.p->fileType = FileRecord::GCP_FILE;
15430  filePtr.p->reqStatus = FileRecord::IDLE;
15431  filePtr.p->fileStatus = FileRecord::CLOSED;
15432  crestartInfoFile[1] = filePtr.i;
15433  filePtr.p->fileName[0] = (Uint32)-1; /* T DIRECTORY NOT USED */
15434  filePtr.p->fileName[1] = (Uint32)-1; /* F DIRECTORY NOT USED */
15435  filePtr.p->fileName[2] = (Uint32)-1; /* S PART IGNORED */
15436  tirgTmp = 1; /* FILE NAME VERSION 1 */
15437  tirgTmp = (tirgTmp << 8) + 6; /* .SYSFILE */
15438  tirgTmp = (tirgTmp << 8) + 2; /* D1 DIRECTORY */
15439  tirgTmp = (tirgTmp << 8) + 0; /* P0 FILE NAME */
15440  filePtr.p->fileName[3] = tirgTmp;
15441  /* --------------------------------------------------------------------- */
15442  /* THE NAME BECOMES /D2/DBDICT/P0.SYSFILE */
15443  /* --------------------------------------------------------------------- */
15444 }//Dbdih::initRestorableGciFiles()
15445 
15446 void Dbdih::initTable(TabRecordPtr tabPtr)
15447 {
15448  new (tabPtr.p) TabRecord();
15449  tabPtr.p->noOfFragChunks = 0;
15450  tabPtr.p->method = TabRecord::NOTDEFINED;
15451  tabPtr.p->tabStatus = TabRecord::TS_IDLE;
15452  tabPtr.p->noOfWords = 0;
15453  tabPtr.p->noPages = 0;
15454  tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
15455  tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
15456  tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
15457  tabPtr.p->noOfBackups = 0;
15458  tabPtr.p->kvalue = 0;
15459  tabPtr.p->hashpointer = (Uint32)-1;
15460  tabPtr.p->mask = 0;
15461  tabPtr.p->tabStorage = TabRecord::ST_NORMAL;
15462  tabPtr.p->tabErrorCode = 0;
15463  tabPtr.p->schemaVersion = (Uint32)-1;
15464  tabPtr.p->tabRemoveNode = RNIL;
15465  tabPtr.p->totalfragments = (Uint32)-1;
15466  tabPtr.p->connectrec = RNIL;
15467  tabPtr.p->tabFile[0] = RNIL;
15468  tabPtr.p->tabFile[1] = RNIL;
15469  tabPtr.p->m_dropTab.tabUserRef = 0;
15470  tabPtr.p->m_dropTab.tabUserPtr = RNIL;
15471  Uint32 i;
15472  for (i = 0; i < NDB_ARRAY_SIZE(tabPtr.p->startFid); i++) {
15473  tabPtr.p->startFid[i] = RNIL;
15474  }//for
15475  for (i = 0; i < NDB_ARRAY_SIZE(tabPtr.p->pageRef); i++) {
15476  tabPtr.p->pageRef[i] = RNIL;
15477  }//for
15478  tabPtr.p->tableType = DictTabInfo::UndefTableType;
15479  tabPtr.p->schemaTransId = 0;
15480 }//Dbdih::initTable()
15481 
15482 /*************************************************************************/
15483 /* */
15484 /* MODULE: INIT_TABLE_FILES */
15485 /* DESCRIPTION: THE SUBROUTINE SETS UP THE FILES THAT REFERS TO THE*/
15486 /* FILES THAT KEEP THE TABLE FRAGMENTATION DESCRIPTION. */
15487 /*************************************************************************/
15488 void Dbdih::initTableFile(TabRecordPtr tabPtr)
15489 {
15490  Uint32 titfTmp;
15491  FileRecordPtr filePtr;
15492  seizeFile(filePtr);
15493  filePtr.p->tabRef = tabPtr.i;
15494  filePtr.p->fileType = FileRecord::TABLE_FILE;
15495  filePtr.p->reqStatus = FileRecord::IDLE;
15496  filePtr.p->fileStatus = FileRecord::CLOSED;
15497  tabPtr.p->tabFile[0] = filePtr.i;
15498  filePtr.p->fileName[0] = (Uint32)-1; /* T DIRECTORY NOT USED */
15499  filePtr.p->fileName[1] = (Uint32)-1; /* F DIRECTORY NOT USED */
15500  filePtr.p->fileName[2] = tabPtr.i; /* Stid FILE NAME */
15501  titfTmp = 1; /* FILE NAME VERSION 1 */
15502  titfTmp = (titfTmp << 8) + 3; /* .FRAGLIST */
15503  titfTmp = (titfTmp << 8) + 1; /* D1 DIRECTORY */
15504  titfTmp = (titfTmp << 8) + 255; /* P PART IGNORED */
15505  filePtr.p->fileName[3] = titfTmp;
15506  /* --------------------------------------------------------------------- */
15507  /* THE NAME BECOMES /D1/DBDICT/Stid.FRAGLIST */
15508  /* --------------------------------------------------------------------- */
15509  seizeFile(filePtr);
15510  filePtr.p->tabRef = tabPtr.i;
15511  filePtr.p->fileType = FileRecord::TABLE_FILE;
15512  filePtr.p->reqStatus = FileRecord::IDLE;
15513  filePtr.p->fileStatus = FileRecord::CLOSED;
15514  tabPtr.p->tabFile[1] = filePtr.i;
15515  filePtr.p->fileName[0] = (Uint32)-1; /* T DIRECTORY NOT USED */
15516  filePtr.p->fileName[1] = (Uint32)-1; /* F DIRECTORY NOT USED */
15517  filePtr.p->fileName[2] = tabPtr.i; /* Stid FILE NAME */
15518  titfTmp = 1; /* FILE NAME VERSION 1 */
15519  titfTmp = (titfTmp << 8) + 3; /* .FRAGLIST */
15520  titfTmp = (titfTmp << 8) + 2; /* D2 DIRECTORY */
15521  titfTmp = (titfTmp << 8) + 255; /* P PART IGNORED */
15522  filePtr.p->fileName[3] = titfTmp;
15523  /* --------------------------------------------------------------------- */
15524  /* THE NAME BECOMES /D2/DBDICT/Stid.FRAGLIST */
15525  /* --------------------------------------------------------------------- */
15526 }//Dbdih::initTableFile()
15527 
15528 void Dbdih::initialiseRecordsLab(Signal* signal,
15529  Uint32 stepNo, Uint32 retRef, Uint32 retData)
15530 {
15531  switch (stepNo) {
15532  case 0:
15533  jam();
15534  initCommonData();
15535  break;
15536  case 1:{
15537  ApiConnectRecordPtr apiConnectptr;
15538  jam();
15539  c_diverify_queue[0].m_ref = calcTcBlockRef(getOwnNodeId());
15540  for (Uint32 i = 0; i < c_diverify_queue_cnt; i++)
15541  {
15542  if (c_diverify_queue_cnt > 1)
15543  {
15544  c_diverify_queue[i].m_ref = numberToRef(DBTC, i + 1, 0);
15545  }
15546  /******** INTIALIZING API CONNECT RECORDS ********/
15547  for (apiConnectptr.i = 0;
15548  apiConnectptr.i < capiConnectFileSize; apiConnectptr.i++)
15549  {
15551  ptrAss(apiConnectptr, c_diverify_queue[i].apiConnectRecord);
15552  apiConnectptr.p->senderData = RNIL;
15553  apiConnectptr.p->apiGci = ~(Uint64)0;
15554  }//for
15555  }
15556  jam();
15557  break;
15558  }
15559  case 2:{
15560  ConnectRecordPtr connectPtr;
15561  jam();
15562  /****** CONNECT ******/
15563  for (connectPtr.i = 0; connectPtr.i < cconnectFileSize; connectPtr.i++) {
15565  ptrAss(connectPtr, connectRecord);
15566  connectPtr.p->userpointer = RNIL;
15567  connectPtr.p->userblockref = ZNIL;
15568  connectPtr.p->connectState = ConnectRecord::FREE;
15569  connectPtr.p->table = RNIL;
15570  connectPtr.p->nextPool = connectPtr.i + 1;
15571  bzero(connectPtr.p->nodes, sizeof(connectPtr.p->nodes));
15572  }//for
15573  connectPtr.i = cconnectFileSize - 1;
15574  ptrAss(connectPtr, connectRecord);
15575  connectPtr.p->nextPool = RNIL;
15576  cfirstconnect = 0;
15577  break;
15578  }
15579  case 3:
15580  {
15581  FileRecordPtr filePtr;
15582  jam();
15583  /******** INTIALIZING FILE RECORDS ********/
15584  for (filePtr.i = 0; filePtr.i < cfileFileSize; filePtr.i++) {
15585  ptrAss(filePtr, fileRecord);
15586  filePtr.p->nextFile = filePtr.i + 1;
15587  filePtr.p->fileStatus = FileRecord::CLOSED;
15588  filePtr.p->reqStatus = FileRecord::IDLE;
15589  }//for
15590  filePtr.i = cfileFileSize - 1;
15591  ptrAss(filePtr, fileRecord);
15592  filePtr.p->nextFile = RNIL;
15593  cfirstfreeFile = 0;
15594  initRestorableGciFiles();
15595  break;
15596  }
15597  case 4:
15598  jam();
15599  initialiseFragstore();
15600  break;
15601  case 5:
15602  {
15603  jam();
15604  /******* NODE GROUP RECORD ******/
15605  /******* NODE RECORD ******/
15606  NodeGroupRecordPtr loopNGPtr;
15607  for (loopNGPtr.i = 0; loopNGPtr.i < MAX_NDB_NODES; loopNGPtr.i++) {
15608  ptrAss(loopNGPtr, nodeGroupRecord);
15609  loopNGPtr.p->nodesInGroup[0] = RNIL;
15610  loopNGPtr.p->nodesInGroup[1] = RNIL;
15611  loopNGPtr.p->nodesInGroup[2] = RNIL;
15612  loopNGPtr.p->nodesInGroup[3] = RNIL;
15613  loopNGPtr.p->nextReplicaNode = 0;
15614  loopNGPtr.p->nodeCount = 0;
15615  loopNGPtr.p->activeTakeOver = false;
15616  loopNGPtr.p->nodegroupIndex = RNIL;
15617  loopNGPtr.p->m_ref_count = 0;
15618  loopNGPtr.p->m_next_log_part = 0;
15619  }//for
15620  break;
15621  }
15622  case 6:
15623  {
15624  PageRecordPtr pagePtr;
15625  jam();
15626  /******* PAGE RECORD ******/
15627  for (pagePtr.i = 0; pagePtr.i < cpageFileSize; pagePtr.i++) {
15629  ptrAss(pagePtr, pageRecord);
15630  pagePtr.p->nextfreepage = pagePtr.i + 1;
15631  }//for
15632  pagePtr.i = cpageFileSize - 1;
15633  ptrAss(pagePtr, pageRecord);
15634  pagePtr.p->nextfreepage = RNIL;
15635  cfirstfreepage = 0;
15636  break;
15637  }
15638  case 7:
15639  {
15640  ReplicaRecordPtr initReplicaPtr;
15641  jam();
15642  /******* REPLICA RECORD ******/
15643  for (initReplicaPtr.i = 0; initReplicaPtr.i < creplicaFileSize;
15644  initReplicaPtr.i++) {
15646  ptrAss(initReplicaPtr, replicaRecord);
15647  initReplicaPtr.p->lcpIdStarted = 0;
15648  initReplicaPtr.p->lcpOngoingFlag = false;
15649  initReplicaPtr.p->nextReplica = initReplicaPtr.i + 1;
15650  }//for
15651  initReplicaPtr.i = creplicaFileSize - 1;
15652  ptrAss(initReplicaPtr, replicaRecord);
15653  initReplicaPtr.p->nextReplica = RNIL;
15654  cnoFreeReplicaRec = creplicaFileSize;
15655  cfirstfreeReplica = 0;
15656  break;
15657  }
15658  case 8:
15659  {
15660  TabRecordPtr loopTabptr;
15661  jam();
15662  /********* TAB-DESCRIPTOR ********/
15663  for (loopTabptr.i = 0; loopTabptr.i < ctabFileSize; loopTabptr.i++) {
15664  ptrAss(loopTabptr, tabRecord);
15666  initTable(loopTabptr);
15667  }//for
15668  break;
15669  }
15670  case 9:
15671  {
15672  jam();
15673  ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
15674  conf->senderRef = reference();
15675  conf->senderData = retData;
15676  sendSignal(retRef, GSN_READ_CONFIG_CONF, signal,
15677  ReadConfigConf::SignalLength, JBB);
15678  return;
15679  break;
15680  }
15681  default:
15682  ndbrequire(false);
15683  break;
15684  }//switch
15685  jam();
15686  /* ---------------------------------------------------------------------- */
15687  /* SEND REAL-TIME BREAK DURING INIT OF VARIABLES DURING SYSTEM RESTART. */
15688  /* ---------------------------------------------------------------------- */
15689  signal->theData[0] = DihContinueB::ZINITIALISE_RECORDS;
15690  signal->theData[1] = stepNo + 1;
15691  signal->theData[2] = retRef;
15692  signal->theData[3] = retData;
15693  sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
15694 }//Dbdih::initialiseRecordsLab()
15695 
15696 /*************************************************************************/
15697 /* INSERT THE NODE INTO THE LINKED LIST OF NODES INVOLVED ALL */
15698 /* DISTRIBUTED PROTOCOLS (EXCEPT GCP PROTOCOL THAT USES THE DIH */
15699 /* LINKED LIST INSTEAD). */
15700 /*************************************************************************/
15701 void Dbdih::insertAlive(NodeRecordPtr newNodePtr)
15702 {
15703  NodeRecordPtr nodePtr;
15704 
15705  nodePtr.i = cfirstAliveNode;
15706  if (nodePtr.i == RNIL) {
15707  jam();
15708  cfirstAliveNode = newNodePtr.i;
15709  } else {
15710  do {
15711  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15712  if (nodePtr.p->nextNode == RNIL) {
15713  jam();
15714  nodePtr.p->nextNode = newNodePtr.i;
15715  break;
15716  } else {
15717  jam();
15718  nodePtr.i = nodePtr.p->nextNode;
15719  }//if
15720  } while (1);
15721  }//if
15722  newNodePtr.p->nextNode = RNIL;
15723 }//Dbdih::insertAlive()
15724 
15725 void Dbdih::insertBackup(FragmentstorePtr fragPtr, Uint32 nodeId)
15726 {
15727  for (Uint32 i = fragPtr.p->fragReplicas; i > 1; i--) {
15728  jam();
15729  ndbrequire(i < MAX_REPLICAS && i > 0);
15730  fragPtr.p->activeNodes[i] = fragPtr.p->activeNodes[i - 1];
15731  }//for
15732  fragPtr.p->activeNodes[1] = nodeId;
15733  fragPtr.p->fragReplicas++;
15734 }//Dbdih::insertBackup()
15735 
15736 void Dbdih::insertDeadNode(NodeRecordPtr newNodePtr)
15737 {
15738  NodeRecordPtr nodePtr;
15739 
15740  nodePtr.i = cfirstDeadNode;
15741  if (nodePtr.i == RNIL) {
15742  jam();
15743  cfirstDeadNode = newNodePtr.i;
15744  } else {
15745  do {
15746  jam();
15747  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15748  if (nodePtr.p->nextNode == RNIL) {
15749  jam();
15750  nodePtr.p->nextNode = newNodePtr.i;
15751  break;
15752  } else {
15753  jam();
15754  nodePtr.i = nodePtr.p->nextNode;
15755  }//if
15756  } while (1);
15757  }//if
15758  newNodePtr.p->nextNode = RNIL;
15759 }//Dbdih::insertDeadNode()
15760 
15761 void Dbdih::linkOldStoredReplica(FragmentstorePtr fragPtr,
15762  ReplicaRecordPtr replicatePtr)
15763 {
15764  ReplicaRecordPtr losReplicaPtr;
15765 
15766  replicatePtr.p->nextReplica = RNIL;
15767  fragPtr.p->noOldStoredReplicas++;
15768  losReplicaPtr.i = fragPtr.p->oldStoredReplicas;
15769  if (losReplicaPtr.i == RNIL) {
15770  jam();
15771  fragPtr.p->oldStoredReplicas = replicatePtr.i;
15772  return;
15773  }//if
15774  ptrCheckGuard(losReplicaPtr, creplicaFileSize, replicaRecord);
15775  while (losReplicaPtr.p->nextReplica != RNIL) {
15776  jam();
15777  losReplicaPtr.i = losReplicaPtr.p->nextReplica;
15778  ptrCheckGuard(losReplicaPtr, creplicaFileSize, replicaRecord);
15779  }//if
15780  losReplicaPtr.p->nextReplica = replicatePtr.i;
15781 }//Dbdih::linkOldStoredReplica()
15782 
15783 void Dbdih::linkStoredReplica(FragmentstorePtr fragPtr,
15784  ReplicaRecordPtr replicatePtr)
15785 {
15786  ReplicaRecordPtr lsrReplicaPtr;
15787 
15788  fragPtr.p->noStoredReplicas++;
15789  replicatePtr.p->nextReplica = RNIL;
15790  lsrReplicaPtr.i = fragPtr.p->storedReplicas;
15791  if (fragPtr.p->storedReplicas == RNIL) {
15792  jam();
15793  fragPtr.p->storedReplicas = replicatePtr.i;
15794  return;
15795  }//if
15796  ptrCheckGuard(lsrReplicaPtr, creplicaFileSize, replicaRecord);
15797  while (lsrReplicaPtr.p->nextReplica != RNIL) {
15798  jam();
15799  lsrReplicaPtr.i = lsrReplicaPtr.p->nextReplica;
15800  ptrCheckGuard(lsrReplicaPtr, creplicaFileSize, replicaRecord);
15801  }//if
15802  lsrReplicaPtr.p->nextReplica = replicatePtr.i;
15803 }//Dbdih::linkStoredReplica()
15804 
15805 /*************************************************************************/
15806 /* MAKE NODE GROUPS BASED ON THE LIST OF NODES RECEIVED FROM CNTR */
15807 /*************************************************************************/
15808 void
15809 Dbdih::add_nodegroup(NodeGroupRecordPtr NGPtr)
15810 {
15811  if (NGPtr.p->nodegroupIndex == RNIL)
15812  {
15813  jam();
15814  NGPtr.p->nodegroupIndex = cnoOfNodeGroups;
15815  c_node_groups[cnoOfNodeGroups++] = NGPtr.i;
15816  }
15817 }
15818 
15819 void
15820 Dbdih::inc_ng_refcount(Uint32 i)
15821 {
15822  NodeGroupRecordPtr NGPtr;
15823  NGPtr.i = i;
15824  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
15825  NGPtr.p->m_ref_count++;
15826 }
15827 
15828 void
15829 Dbdih::dec_ng_refcount(Uint32 i)
15830 {
15831  NodeGroupRecordPtr NGPtr;
15832  NGPtr.i = i;
15833  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
15834  ndbrequire(NGPtr.p->m_ref_count);
15835  NGPtr.p->m_ref_count--;
15836 }
15837 
15838 void Dbdih::makeNodeGroups(Uint32 nodeArray[])
15839 {
15840  NodeGroupRecordPtr NGPtr;
15841  NodeRecordPtr mngNodeptr;
15842  Uint32 j;
15843 
15848  cnoOfNodeGroups = 0;
15849  for (Uint32 i = 0; nodeArray[i] != RNIL; i++)
15850  {
15851  jam();
15852  mngNodeptr.i = nodeArray[i];
15853  ptrCheckGuard(mngNodeptr, MAX_NDB_NODES, nodeRecord);
15854  if (mngNodeptr.p->nodeGroup == NDB_NO_NODEGROUP)
15855  {
15856  jam();
15857  mngNodeptr.p->nodeGroup = ZNIL;
15858  ndbout_c("setting nodeGroup = ZNIL for node %u",
15859  mngNodeptr.i);
15860  }
15861  else if (mngNodeptr.p->nodeGroup != RNIL)
15862  {
15863  jam();
15864  NGPtr.i = mngNodeptr.p->nodeGroup;
15865  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
15866  arrGuard(NGPtr.p->nodeCount, MAX_REPLICAS);
15867  NGPtr.p->nodesInGroup[NGPtr.p->nodeCount++] = mngNodeptr.i;
15868 
15869  add_nodegroup(NGPtr);
15870  }
15871  }
15872  NGPtr.i = 0;
15873  for (; NGPtr.i < MAX_NDB_NODES; NGPtr.i++)
15874  {
15875  jam();
15876  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
15877  if (NGPtr.p->nodeCount < cnoReplicas)
15878  break;
15879  }
15880 
15881  for (Uint32 i = 0; nodeArray[i] != RNIL; i++)
15882  {
15883  jam();
15884  mngNodeptr.i = nodeArray[i];
15885  ptrCheckGuard(mngNodeptr, MAX_NDB_NODES, nodeRecord);
15886  if (mngNodeptr.p->nodeGroup == RNIL)
15887  {
15888  mngNodeptr.p->nodeGroup = NGPtr.i;
15889  NGPtr.p->nodesInGroup[NGPtr.p->nodeCount++] = mngNodeptr.i;
15890 
15891  add_nodegroup(NGPtr);
15892 
15893  if (NGPtr.p->nodeCount == cnoReplicas)
15894  {
15895  jam();
15896  for (; NGPtr.i < MAX_NDB_NODES; NGPtr.i++)
15897  {
15898  jam();
15899  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
15900  if (NGPtr.p->nodeCount < cnoReplicas)
15901  break;
15902  }
15903  }
15904  }
15905  }
15906 
15907  Uint32 maxNG = 0;
15908  for (Uint32 i = 0; i<cnoOfNodeGroups; i++)
15909  {
15910  jam();
15911  NGPtr.i = c_node_groups[i];
15912  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
15913  if (NGPtr.p->nodeCount == 0)
15914  {
15915  jam();
15916  }
15917  else if (NGPtr.p->nodeCount != cnoReplicas)
15918  {
15919  ndbrequire(false);
15920  }
15921  else
15922  {
15923  if (NGPtr.i > maxNG)
15924  {
15925  maxNG = NGPtr.i;
15926  }
15927  }
15928  }
15929 
15930  ndbrequire(csystemnodes < MAX_NDB_NODES);
15931 
15935  for(Uint32 i = 0; i < MAX_NDB_NODES; i++)
15936  {
15937  jam();
15938  Sysfile::setNodeGroup(i, SYSFILE->nodeGroups, NO_NODE_GROUP_ID);
15939  Sysfile::setNodeStatus(i, SYSFILE->nodeStatus,Sysfile::NS_NotDefined);
15940  }
15941 
15942  for (Uint32 i = 0; nodeArray[i] != RNIL; i++)
15943  {
15944  jam();
15945  Uint32 nodeId = mngNodeptr.i = nodeArray[i];
15946  ptrCheckGuard(mngNodeptr, MAX_NDB_NODES, nodeRecord);
15947 
15948  if (mngNodeptr.p->nodeGroup != ZNIL)
15949  {
15950  jam();
15951  Sysfile::setNodeGroup(nodeId, SYSFILE->nodeGroups,
15952  mngNodeptr.p->nodeGroup);
15953 
15954  if (mngNodeptr.p->nodeStatus == NodeRecord::ALIVE)
15955  {
15956  jam();
15957  mngNodeptr.p->activeStatus = Sysfile::NS_Active;
15958  }
15959  else
15960  {
15961  jam();
15962  mngNodeptr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
15963  }
15964  }
15965  else
15966  {
15967  jam();
15968  Sysfile::setNodeGroup(mngNodeptr.i, SYSFILE->nodeGroups,
15969  NO_NODE_GROUP_ID);
15970  mngNodeptr.p->activeStatus = Sysfile::NS_Configured;
15971  }
15972  Sysfile::setNodeStatus(nodeId, SYSFILE->nodeStatus,
15973  mngNodeptr.p->activeStatus);
15974  }
15975 
15976  for (Uint32 i = 0; i<cnoOfNodeGroups; i++)
15977  {
15978  jam();
15979  bool alive = false;
15980  NodeGroupRecordPtr NGPtr;
15981  NGPtr.i = c_node_groups[i];
15982  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
15983  for (j = 0; j<NGPtr.p->nodeCount; j++)
15984  {
15985  jam();
15986  mngNodeptr.i = NGPtr.p->nodesInGroup[j];
15987  ptrCheckGuard(mngNodeptr, MAX_NDB_NODES, nodeRecord);
15988  if (checkNodeAlive(NGPtr.p->nodesInGroup[j]))
15989  {
15990  alive = true;
15991  break;
15992  }
15993  }
15994 
15995  if (!alive)
15996  {
15997  char buf[255];
15999  (buf, sizeof(buf),
16000  "Illegal initial start, no alive node in nodegroup %u", i);
16001  progError(__LINE__,
16002  NDBD_EXIT_INSUFFICENT_NODES,
16003  buf);
16004  }
16005  }
16006 }//Dbdih::makeNodeGroups()
16007 
16017 void Dbdih::execCHECKNODEGROUPSREQ(Signal* signal)
16018 {
16019  jamEntry();
16020  CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0];
16021 
16022  bool direct = (sd->requestType & CheckNodeGroups::Direct);
16023  bool ok = false;
16024  switch(sd->requestType & ~CheckNodeGroups::Direct){
16025  case CheckNodeGroups::ArbitCheck:{
16026  ok = true;
16027  jam();
16028  unsigned missall = 0;
16029  unsigned haveall = 0;
16030  for (Uint32 i = 0; i < cnoOfNodeGroups; i++) {
16031  jam();
16032  NodeGroupRecordPtr ngPtr;
16033  ngPtr.i = c_node_groups[i];
16034  ptrAss(ngPtr, nodeGroupRecord);
16035  Uint32 count = 0;
16036  for (Uint32 j = 0; j < ngPtr.p->nodeCount; j++) {
16037  jam();
16038  Uint32 nodeId = ngPtr.p->nodesInGroup[j];
16039  if (sd->mask.get(nodeId)) {
16040  jam();
16041  count++;
16042  }//if
16043  }//for
16044  if (count == 0) {
16045  jam();
16046  missall++;
16047  }//if
16048  if (count == ngPtr.p->nodeCount) {
16049  haveall++;
16050  }//if
16051  }//for
16052 
16053  if (missall) {
16054  jam();
16055  sd->output = CheckNodeGroups::Lose;
16056  } else if (haveall) {
16057  jam();
16058  sd->output = CheckNodeGroups::Win;
16059  } else {
16060  jam();
16061  sd->output = CheckNodeGroups::Partitioning;
16062  }//if
16063  }
16064  break;
16065  case CheckNodeGroups::GetNodeGroup:{
16066  ok = true;
16067  Uint32 ng = Sysfile::getNodeGroup(getOwnNodeId(), SYSFILE->nodeGroups);
16068  if (ng == NO_NODE_GROUP_ID)
16069  ng = RNIL;
16070  sd->output = ng;
16071  break;
16072  }
16073  case CheckNodeGroups::GetNodeGroupMembers: {
16074  ok = true;
16075  Uint32 ng = Sysfile::getNodeGroup(sd->nodeId, SYSFILE->nodeGroups);
16076  if (ng == NO_NODE_GROUP_ID)
16077  ng = RNIL;
16078 
16079  sd->output = ng;
16080  sd->mask.clear();
16081 
16082  NodeGroupRecordPtr ngPtr;
16083  ngPtr.i = ng;
16084  if (ngPtr.i != RNIL)
16085  {
16086  jam();
16087  ptrAss(ngPtr, nodeGroupRecord);
16088  for (Uint32 j = 0; j < ngPtr.p->nodeCount; j++) {
16089  jam();
16090  sd->mask.set(ngPtr.p->nodesInGroup[j]);
16091  }
16092  }
16093  break;
16094  }
16095  case CheckNodeGroups::GetDefaultFragments:
16096  jam();
16097  ok = true;
16098  sd->output = (cnoOfNodeGroups + sd->extraNodeGroups)
16099  * c_fragments_per_node * cnoReplicas;
16100  break;
16101  }
16102  ndbrequire(ok);
16103 
16104  if (!direct)
16105  sendSignal(sd->blockRef, GSN_CHECKNODEGROUPSCONF, signal,
16106  CheckNodeGroups::SignalLength, JBB);
16107 }//Dbdih::execCHECKNODEGROUPSREQ()
16108 
16109 void
16110  Dbdih::makePrnList(ReadNodesConf * readNodes, Uint32 nodeArray[])
16111 {
16112  cfirstAliveNode = RNIL;
16113  ndbrequire(con_lineNodes > 0);
16114  ndbrequire(csystemnodes < MAX_NDB_NODES);
16115  for (Uint32 i = 0; i < csystemnodes; i++) {
16116  NodeRecordPtr nodePtr;
16117  jam();
16118  nodePtr.i = nodeArray[i];
16119  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
16120  new (nodePtr.p) NodeRecord();
16121  if (NdbNodeBitmask::get(readNodes->inactiveNodes, nodePtr.i) == false){
16122  jam();
16123  nodePtr.p->nodeStatus = NodeRecord::ALIVE;
16124  nodePtr.p->useInTransactions = true;
16125  nodePtr.p->copyCompleted = true;
16126  nodePtr.p->m_inclDihLcp = true;
16127  insertAlive(nodePtr);
16128  } else {
16129  jam();
16130  nodePtr.p->nodeStatus = NodeRecord::DEAD;
16131  insertDeadNode(nodePtr);
16132  }//if
16133  }//for
16134 }//Dbdih::makePrnList()
16135 
16136 /*************************************************************************/
16137 /* A NEW CRASHED REPLICA IS ADDED BY A NODE FAILURE. */
16138 /*************************************************************************/
16139 void Dbdih::newCrashedReplica(ReplicaRecordPtr ncrReplicaPtr)
16140 {
16141  /*----------------------------------------------------------------------*/
16142  /* SET THE REPLICA_LAST_GCI OF THE CRASHED REPLICA TO LAST GCI */
16143  /* EXECUTED BY THE FAILED NODE. */
16144  /*----------------------------------------------------------------------*/
16145  /* WE HAVE A NEW CRASHED REPLICA. INITIATE CREATE GCI TO INDICATE */
16146  /* THAT THE NEW REPLICA IS NOT STARTED YET AND REPLICA_LAST_GCI IS*/
16147  /* SET TO -1 TO INDICATE THAT IT IS NOT DEAD YET. */
16148  /*----------------------------------------------------------------------*/
16149  Uint32 nodeId = ncrReplicaPtr.p->procNode;
16150  Uint32 lastGCI = SYSFILE->lastCompletedGCI[nodeId];
16151  if (ncrReplicaPtr.p->noCrashedReplicas + 1 == MAX_CRASHED_REPLICAS)
16152  {
16153  jam();
16154  packCrashedReplicas(ncrReplicaPtr);
16155  }
16156 
16157  Uint32 noCrashedReplicas = ncrReplicaPtr.p->noCrashedReplicas;
16158  arrGuardErr(ncrReplicaPtr.p->noCrashedReplicas + 1, MAX_CRASHED_REPLICAS,
16159  NDBD_EXIT_MAX_CRASHED_REPLICAS);
16160 
16161  if (noCrashedReplicas > 0 &&
16162  ncrReplicaPtr.p->replicaLastGci[noCrashedReplicas - 1] == lastGCI)
16163  {
16164  jam();
16169  ncrReplicaPtr.p->createGci[ncrReplicaPtr.p->noCrashedReplicas] =
16170  ZINIT_CREATE_GCI;
16171  ncrReplicaPtr.p->replicaLastGci[ncrReplicaPtr.p->noCrashedReplicas] =
16172  ZINIT_REPLICA_LAST_GCI;
16173  }
16174  else if (ncrReplicaPtr.p->createGci[noCrashedReplicas] <= lastGCI)
16175  {
16176  jam();
16177  ncrReplicaPtr.p->replicaLastGci[ncrReplicaPtr.p->noCrashedReplicas] =
16178  lastGCI;
16179  ncrReplicaPtr.p->noCrashedReplicas = ncrReplicaPtr.p->noCrashedReplicas + 1;
16180  ncrReplicaPtr.p->createGci[ncrReplicaPtr.p->noCrashedReplicas] =
16181  ZINIT_CREATE_GCI;
16182  ncrReplicaPtr.p->replicaLastGci[ncrReplicaPtr.p->noCrashedReplicas] =
16183  ZINIT_REPLICA_LAST_GCI;
16184  }
16185  else
16186  {
16197  ncrReplicaPtr.p->createGci[noCrashedReplicas] = ZINIT_CREATE_GCI;
16198  }
16199 
16200 }//Dbdih::newCrashedReplica()
16201 
16202 /*************************************************************************/
16203 /* AT NODE FAILURE DURING START OF A NEW NODE WE NEED TO RESET A */
16204 /* SET OF VARIABLES CONTROLLING THE START AND INDICATING ONGOING */
16205 /* START OF A NEW NODE. */
16206 /*************************************************************************/
16207 void Dbdih::nodeResetStart(Signal *signal)
16208 {
16209  jam();
16210  Uint32 startGCP = c_nodeStartMaster.blockGcp;
16211 
16212  c_nodeStartSlave.nodeId = 0;
16213  c_nodeStartMaster.startNode = RNIL;
16214  c_nodeStartMaster.failNr = cfailurenr;
16215  c_nodeStartMaster.activeState = false;
16216  c_nodeStartMaster.blockGcp = 0;
16217  c_nodeStartMaster.blockLcp = false;
16218  c_nodeStartMaster.m_outstandingGsn = 0;
16219 
16220  if (startGCP == 2) // effective
16221  {
16222  jam();
16223  ndbrequire(isMaster());
16224  ndbrequire(m_micro_gcp.m_master.m_state == MicroGcp::M_GCP_IDLE);
16225  signal->theData[0] = DihContinueB::ZSTART_GCP;
16226  sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
16227  }
16228 }//Dbdih::nodeResetStart()
16229 
16230 void Dbdih::openFileRw(Signal* signal, FileRecordPtr filePtr)
16231 {
16232  signal->theData[0] = reference();
16233  signal->theData[1] = filePtr.i;
16234  signal->theData[2] = filePtr.p->fileName[0];
16235  signal->theData[3] = filePtr.p->fileName[1];
16236  signal->theData[4] = filePtr.p->fileName[2];
16237  signal->theData[5] = filePtr.p->fileName[3];
16238  signal->theData[6] = FsOpenReq::OM_READWRITE;
16239  sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
16240 }//Dbdih::openFileRw()
16241 
16242 void Dbdih::openFileRo(Signal* signal, FileRecordPtr filePtr)
16243 {
16244  signal->theData[0] = reference();
16245  signal->theData[1] = filePtr.i;
16246  signal->theData[2] = filePtr.p->fileName[0];
16247  signal->theData[3] = filePtr.p->fileName[1];
16248  signal->theData[4] = filePtr.p->fileName[2];
16249  signal->theData[5] = filePtr.p->fileName[3];
16250  signal->theData[6] = FsOpenReq::OM_READONLY;
16251  sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
16252 }//Dbdih::openFileRw()
16253 
16254 /*************************************************************************/
16255 /* REMOVE A CRASHED REPLICA BY PACKING THE ARRAY OF CREATED GCI AND*/
16256 /* THE LAST GCI OF THE CRASHED REPLICA. */
16257 /*************************************************************************/
16258 void Dbdih::packCrashedReplicas(ReplicaRecordPtr replicaPtr)
16259 {
16260  ndbrequire(replicaPtr.p->noCrashedReplicas > 0);
16261  ndbrequire(replicaPtr.p->noCrashedReplicas <= MAX_CRASHED_REPLICAS);
16262  for (Uint32 i = 0; i < replicaPtr.p->noCrashedReplicas; i++) {
16263  jam();
16264  replicaPtr.p->createGci[i] = replicaPtr.p->createGci[i + 1];
16265  replicaPtr.p->replicaLastGci[i] = replicaPtr.p->replicaLastGci[i + 1];
16266  }//for
16267  replicaPtr.p->noCrashedReplicas--;
16268  replicaPtr.p->createGci[replicaPtr.p->noCrashedReplicas + 1] =
16269  ZINIT_CREATE_GCI;
16270  replicaPtr.p->replicaLastGci[replicaPtr.p->noCrashedReplicas + 1] =
16271  ZINIT_REPLICA_LAST_GCI;
16272 }//Dbdih::packCrashedReplicas()
16273 
16274 void
16275 Dbdih::mergeCrashedReplicas(ReplicaRecordPtr replicaPtr)
16276 {
16280  for (Uint32 i = replicaPtr.p->noCrashedReplicas; i > 0; i--)
16281  {
16282  jam();
16283  if (replicaPtr.p->createGci[i] == 1 + replicaPtr.p->replicaLastGci[i-1])
16284  {
16285  jam();
16286  replicaPtr.p->replicaLastGci[i-1] = replicaPtr.p->replicaLastGci[i];
16287  replicaPtr.p->createGci[i] = ZINIT_CREATE_GCI;
16288  replicaPtr.p->replicaLastGci[i] = ZINIT_REPLICA_LAST_GCI;
16289  replicaPtr.p->noCrashedReplicas--;
16290  }
16291  else
16292  {
16293  jam();
16294  break;
16295  }
16296  }
16297 }
16298 
16299 void Dbdih::prepareReplicas(FragmentstorePtr fragPtr)
16300 {
16301  ReplicaRecordPtr prReplicaPtr;
16302  Uint32 prevReplica = RNIL;
16303 
16304  /* --------------------------------------------------------------------- */
16305  /* BEGIN BY LINKING ALL REPLICA RECORDS ONTO THE OLD STORED REPLICA*/
16306  /* LIST. */
16307  /* AT A SYSTEM RESTART OBVIOUSLY ALL NODES ARE OLD. */
16308  /* --------------------------------------------------------------------- */
16309  prReplicaPtr.i = fragPtr.p->storedReplicas;
16310  while (prReplicaPtr.i != RNIL) {
16311  jam();
16312  prevReplica = prReplicaPtr.i;
16313  ptrCheckGuard(prReplicaPtr, creplicaFileSize, replicaRecord);
16314  prReplicaPtr.i = prReplicaPtr.p->nextReplica;
16315  }//while
16316  /* --------------------------------------------------------------------- */
16317  /* LIST OF STORED REPLICAS WILL BE EMPTY NOW. */
16318  /* --------------------------------------------------------------------- */
16319  if (prevReplica != RNIL) {
16320  prReplicaPtr.i = prevReplica;
16321  ptrCheckGuard(prReplicaPtr, creplicaFileSize, replicaRecord);
16322  prReplicaPtr.p->nextReplica = fragPtr.p->oldStoredReplicas;
16323  fragPtr.p->oldStoredReplicas = fragPtr.p->storedReplicas;
16324  fragPtr.p->storedReplicas = RNIL;
16325  fragPtr.p->noOldStoredReplicas += fragPtr.p->noStoredReplicas;
16326  fragPtr.p->noStoredReplicas = 0;
16327  }//if
16328 }//Dbdih::prepareReplicas()
16329 
16330 void Dbdih::readFragment(RWFragment* rf, FragmentstorePtr fragPtr)
16331 {
16332  Uint32 TreadFid = readPageWord(rf);
16333  fragPtr.p->preferredPrimary = readPageWord(rf);
16334  fragPtr.p->noStoredReplicas = readPageWord(rf);
16335  fragPtr.p->noOldStoredReplicas = readPageWord(rf);
16336  Uint32 TdistKey = readPageWord(rf);
16337 
16338  ndbrequire(fragPtr.p->noStoredReplicas > 0);
16339  ndbrequire(TreadFid == rf->fragId);
16340  ndbrequire(TdistKey < 256);
16341  fragPtr.p->distributionKey = TdistKey;
16342 
16343  fragPtr.p->m_log_part_id = readPageWord(rf);
16344  inc_ng_refcount(getNodeGroup(fragPtr.p->preferredPrimary));
16345 }//Dbdih::readFragment()
16346 
16347 Uint32 Dbdih::readPageWord(RWFragment* rf)
16348 {
16349  if (rf->wordIndex >= 2048) {
16350  jam();
16351  ndbrequire(rf->wordIndex == 2048);
16352  rf->pageIndex++;
16353  ndbrequire(rf->pageIndex < NDB_ARRAY_SIZE(rf->rwfTabPtr.p->pageRef));
16354  rf->rwfPageptr.i = rf->rwfTabPtr.p->pageRef[rf->pageIndex];
16355  ptrCheckGuard(rf->rwfPageptr, cpageFileSize, pageRecord);
16356  rf->wordIndex = 32;
16357  }//if
16358  Uint32 dataWord = rf->rwfPageptr.p->word[rf->wordIndex];
16359  rf->wordIndex++;
16360  return dataWord;
16361 }//Dbdih::readPageWord()
16362 
16363 void Dbdih::readReplica(RWFragment* rf, ReplicaRecordPtr readReplicaPtr)
16364 {
16365  Uint32 i;
16366  readReplicaPtr.p->procNode = readPageWord(rf);
16367  readReplicaPtr.p->initialGci = readPageWord(rf);
16368  readReplicaPtr.p->noCrashedReplicas = readPageWord(rf);
16369  readReplicaPtr.p->nextLcp = readPageWord(rf);
16370 
16371  for (i = 0; i < MAX_LCP_STORED; i++) {
16372  readReplicaPtr.p->maxGciCompleted[i] = readPageWord(rf);
16373  readReplicaPtr.p->maxGciStarted[i] = readPageWord(rf);
16374  readReplicaPtr.p->lcpId[i] = readPageWord(rf);
16375  readReplicaPtr.p->lcpStatus[i] = readPageWord(rf);
16376  }//for
16377  const Uint32 noCrashedReplicas = readReplicaPtr.p->noCrashedReplicas;
16378  ndbrequire(noCrashedReplicas < MAX_CRASHED_REPLICAS);
16379  for (i = 0; i < noCrashedReplicas; i++) {
16380  readReplicaPtr.p->createGci[i] = readPageWord(rf);
16381  readReplicaPtr.p->replicaLastGci[i] = readPageWord(rf);
16382  }//for
16383  for(i = noCrashedReplicas; i<MAX_CRASHED_REPLICAS; i++){
16384  readReplicaPtr.p->createGci[i] = readPageWord(rf);
16385  readReplicaPtr.p->replicaLastGci[i] = readPageWord(rf);
16386  }
16387 }//Dbdih::readReplica()
16388 
16389 void Dbdih::readReplicas(RWFragment* rf, FragmentstorePtr fragPtr)
16390 {
16391  Uint32 i;
16392  ReplicaRecordPtr newReplicaPtr;
16393  Uint32 noStoredReplicas = fragPtr.p->noStoredReplicas;
16394  Uint32 noOldStoredReplicas = fragPtr.p->noOldStoredReplicas;
16395  /* ----------------------------------------------------------------------- */
16396  /* WE CLEAR THE NUMBER OF STORED REPLICAS SINCE IT WILL BE CALCULATED */
16397  /* BY THE LINKING SUBROUTINES. */
16398  /* ----------------------------------------------------------------------- */
16399  fragPtr.p->noStoredReplicas = 0;
16400  fragPtr.p->noOldStoredReplicas = 0;
16401  Uint32 replicaIndex = 0;
16402  ndbrequire(noStoredReplicas + noOldStoredReplicas <= MAX_REPLICAS);
16403  for (i = 0; i < noStoredReplicas; i++)
16404  {
16405  seizeReplicaRec(newReplicaPtr);
16406  readReplica(rf, newReplicaPtr);
16407  ndbrequire(replicaIndex < MAX_REPLICAS);
16408  fragPtr.p->activeNodes[replicaIndex] = newReplicaPtr.p->procNode;
16409  replicaIndex++;
16410  linkStoredReplica(fragPtr, newReplicaPtr);
16411  }//for
16412  fragPtr.p->fragReplicas = noStoredReplicas;
16413  for (i = 0; i < noOldStoredReplicas; i++) {
16414  jam();
16415  seizeReplicaRec(newReplicaPtr);
16416  readReplica(rf, newReplicaPtr);
16417  linkOldStoredReplica(fragPtr, newReplicaPtr);
16418  }//for
16419 }//Dbdih::readReplicas()
16420 
16421 void Dbdih::readRestorableGci(Signal* signal, FileRecordPtr filePtr)
16422 {
16423  signal->theData[0] = filePtr.p->fileRef;
16424  signal->theData[1] = reference();
16425  signal->theData[2] = filePtr.i;
16426  signal->theData[3] = ZLIST_OF_PAIRS;
16427  signal->theData[4] = ZVAR_NO_CRESTART_INFO;
16428  signal->theData[5] = 1;
16429  signal->theData[6] = 0;
16430  signal->theData[7] = 0;
16431  sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
16432 }//Dbdih::readRestorableGci()
16433 
16434 void Dbdih::readTabfile(Signal* signal, TabRecord* tab, FileRecordPtr filePtr)
16435 {
16436  signal->theData[0] = filePtr.p->fileRef;
16437  signal->theData[1] = reference();
16438  signal->theData[2] = filePtr.i;
16439  signal->theData[3] = ZLIST_OF_PAIRS;
16440  signal->theData[4] = ZVAR_NO_WORD;
16441  signal->theData[5] = tab->noPages;
16442  Uint32 section[2 * NDB_ARRAY_SIZE(tab->pageRef)];
16443  for (Uint32 i = 0; i < tab->noPages; i++)
16444  {
16445  section[(2 * i) + 0] = tab->pageRef[i];
16446  section[(2 * i) + 1] = i;
16447  }
16448  LinearSectionPtr ptr[3];
16449  ptr[0].p = section;
16450  ptr[0].sz = 2 * tab->noPages;
16451  sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 6, JBA, ptr, 1);
16452 }//Dbdih::readTabfile()
16453 
16454 void Dbdih::releasePage(Uint32 pageIndex)
16455 {
16456  PageRecordPtr pagePtr;
16457  pagePtr.i = pageIndex;
16458  ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
16459  pagePtr.p->nextfreepage = cfirstfreepage;
16460  cfirstfreepage = pagePtr.i;
16461 }//Dbdih::releasePage()
16462 
16463 void Dbdih::releaseTabPages(Uint32 tableId)
16464 {
16465  TabRecordPtr tabPtr;
16466  tabPtr.i = tableId;
16467  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
16468  ndbrequire(tabPtr.p->noPages <= NDB_ARRAY_SIZE(tabPtr.p->pageRef));
16469  for (Uint32 i = 0; i < tabPtr.p->noPages; i++) {
16470  jam();
16471  releasePage(tabPtr.p->pageRef[i]);
16472  }//for
16473  tabPtr.p->noPages = 0;
16474 }//Dbdih::releaseTabPages()
16475 
16476 /*************************************************************************/
16477 /* REMOVE NODE FROM SET OF ALIVE NODES. */
16478 /*************************************************************************/
16479 void Dbdih::removeAlive(NodeRecordPtr removeNodePtr)
16480 {
16481  NodeRecordPtr nodePtr;
16482 
16483  nodePtr.i = cfirstAliveNode;
16484  if (nodePtr.i == removeNodePtr.i) {
16485  jam();
16486  cfirstAliveNode = removeNodePtr.p->nextNode;
16487  return;
16488  }//if
16489  do {
16490  jam();
16491  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
16492  if (nodePtr.p->nextNode == removeNodePtr.i) {
16493  jam();
16494  nodePtr.p->nextNode = removeNodePtr.p->nextNode;
16495  break;
16496  } else {
16497  jam();
16498  nodePtr.i = nodePtr.p->nextNode;
16499  }//if
16500  } while (1);
16501 }//Dbdih::removeAlive()
16502 
16503 /*************************************************************************/
16504 /* REMOVE NODE FROM SET OF DEAD NODES. */
16505 /*************************************************************************/
16506 void Dbdih::removeDeadNode(NodeRecordPtr removeNodePtr)
16507 {
16508  NodeRecordPtr nodePtr;
16509 
16510  nodePtr.i = cfirstDeadNode;
16511  if (nodePtr.i == removeNodePtr.i) {
16512  jam();
16513  cfirstDeadNode = removeNodePtr.p->nextNode;
16514  return;
16515  }//if
16516  do {
16517  jam();
16518  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
16519  if (nodePtr.p->nextNode == removeNodePtr.i) {
16520  jam();
16521  nodePtr.p->nextNode = removeNodePtr.p->nextNode;
16522  break;
16523  } else {
16524  jam();
16525  nodePtr.i = nodePtr.p->nextNode;
16526  }//if
16527  } while (1);
16528 }//Dbdih::removeDeadNode()
16529 
16530 /*---------------------------------------------------------------*/
16531 /* REMOVE REPLICAS OF A FAILED NODE FROM LIST OF STORED */
16532 /* REPLICAS AND MOVE IT TO THE LIST OF OLD STORED REPLICAS.*/
16533 /* ALSO UPDATE THE CRASHED REPLICA INFORMATION. */
16534 /*---------------------------------------------------------------*/
16535 void Dbdih::removeNodeFromStored(Uint32 nodeId,
16536  FragmentstorePtr fragPtr,
16537  ReplicaRecordPtr replicatePtr,
16538  bool temporary)
16539 {
16540  if (!temporary)
16541  {
16542  jam();
16543  newCrashedReplica(replicatePtr);
16544  }
16545  else
16546  {
16547  jam();
16548  }
16549  removeStoredReplica(fragPtr, replicatePtr);
16550  linkOldStoredReplica(fragPtr, replicatePtr);
16551  ndbrequire(fragPtr.p->storedReplicas != RNIL);
16552 }//Dbdih::removeNodeFromStored()
16553 
16554 /*************************************************************************/
16555 /* REMOVE ANY OLD CRASHED REPLICAS THAT ARE NOT RESTORABLE ANY MORE*/
16556 /*************************************************************************/
16557 void Dbdih::removeOldCrashedReplicas(Uint32 tab, Uint32 frag,
16558  ReplicaRecordPtr rocReplicaPtr)
16559 {
16560  mergeCrashedReplicas(rocReplicaPtr);
16561  while (rocReplicaPtr.p->noCrashedReplicas > 0) {
16562  jam();
16563  /* --------------------------------------------------------------------- */
16564  /* ONLY IF THERE IS AT LEAST ONE REPLICA THEN CAN WE REMOVE ANY. */
16565  /* --------------------------------------------------------------------- */
16566  if (rocReplicaPtr.p->replicaLastGci[0] < SYSFILE->oldestRestorableGCI){
16567  jam();
16568  /* ------------------------------------------------------------------- */
16569  /* THIS CRASHED REPLICA HAS BECOME EXTINCT AND MUST BE REMOVED TO */
16570  /* GIVE SPACE FOR NEW CRASHED REPLICAS. */
16571  /* ------------------------------------------------------------------- */
16572  packCrashedReplicas(rocReplicaPtr);
16573  } else {
16574  break;
16575  }//if
16576  }//while
16577 
16578  while (rocReplicaPtr.p->createGci[0] < SYSFILE->keepGCI)
16579  {
16580  jam();
16581  /* --------------------------------------------------------------------- */
16582  /* MOVE FORWARD THE CREATE GCI TO A GCI THAT CAN BE USED. WE HAVE */
16583  /* NO CERTAINTY IN FINDING ANY LOG RECORDS FROM OLDER GCI'S. */
16584  /* --------------------------------------------------------------------- */
16585  rocReplicaPtr.p->createGci[0] = SYSFILE->keepGCI;
16586 
16587  if (rocReplicaPtr.p->noCrashedReplicas)
16588  {
16593  if (rocReplicaPtr.p->createGci[0] > rocReplicaPtr.p->replicaLastGci[0])
16594  {
16595  jam();
16596  packCrashedReplicas(rocReplicaPtr);
16597  }
16598  }
16599  }
16600 }
16601 
16602 void Dbdih::removeOldStoredReplica(FragmentstorePtr fragPtr,
16603  ReplicaRecordPtr replicatePtr)
16604 {
16605  ReplicaRecordPtr rosTmpReplicaPtr;
16606  ReplicaRecordPtr rosPrevReplicaPtr;
16607 
16608  fragPtr.p->noOldStoredReplicas--;
16609  if (fragPtr.p->oldStoredReplicas == replicatePtr.i) {
16610  jam();
16611  fragPtr.p->oldStoredReplicas = replicatePtr.p->nextReplica;
16612  } else {
16613  rosPrevReplicaPtr.i = fragPtr.p->oldStoredReplicas;
16614  ptrCheckGuard(rosPrevReplicaPtr, creplicaFileSize, replicaRecord);
16615  rosTmpReplicaPtr.i = rosPrevReplicaPtr.p->nextReplica;
16616  while (rosTmpReplicaPtr.i != replicatePtr.i) {
16617  jam();
16618  rosPrevReplicaPtr.i = rosTmpReplicaPtr.i;
16619  ptrCheckGuard(rosPrevReplicaPtr, creplicaFileSize, replicaRecord);
16620  ptrCheckGuard(rosTmpReplicaPtr, creplicaFileSize, replicaRecord);
16621  rosTmpReplicaPtr.i = rosTmpReplicaPtr.p->nextReplica;
16622  }//if
16623  rosPrevReplicaPtr.p->nextReplica = replicatePtr.p->nextReplica;
16624  }//if
16625 }//Dbdih::removeOldStoredReplica()
16626 
16627 void Dbdih::removeStoredReplica(FragmentstorePtr fragPtr,
16628  ReplicaRecordPtr replicatePtr)
16629 {
16630  ReplicaRecordPtr rsrTmpReplicaPtr;
16631  ReplicaRecordPtr rsrPrevReplicaPtr;
16632 
16633  fragPtr.p->noStoredReplicas--;
16634  if (fragPtr.p->storedReplicas == replicatePtr.i) {
16635  jam();
16636  fragPtr.p->storedReplicas = replicatePtr.p->nextReplica;
16637  } else {
16638  jam();
16639  rsrPrevReplicaPtr.i = fragPtr.p->storedReplicas;
16640  rsrTmpReplicaPtr.i = fragPtr.p->storedReplicas;
16641  ptrCheckGuard(rsrTmpReplicaPtr, creplicaFileSize, replicaRecord);
16642  rsrTmpReplicaPtr.i = rsrTmpReplicaPtr.p->nextReplica;
16643  while (rsrTmpReplicaPtr.i != replicatePtr.i) {
16644  jam();
16645  rsrPrevReplicaPtr.i = rsrTmpReplicaPtr.i;
16646  ptrCheckGuard(rsrTmpReplicaPtr, creplicaFileSize, replicaRecord);
16647  rsrTmpReplicaPtr.i = rsrTmpReplicaPtr.p->nextReplica;
16648  }//while
16649  ptrCheckGuard(rsrPrevReplicaPtr, creplicaFileSize, replicaRecord);
16650  rsrPrevReplicaPtr.p->nextReplica = replicatePtr.p->nextReplica;
16651  }//if
16652 }//Dbdih::removeStoredReplica()
16653 
16654 /*************************************************************************/
16655 /* REMOVE ALL TOO NEW CRASHED REPLICAS THAT IS IN THIS REPLICA. */
16656 /*************************************************************************/
16657 void Dbdih::removeTooNewCrashedReplicas(ReplicaRecordPtr rtnReplicaPtr, Uint32 lastCompletedGCI)
16658 {
16659  while (rtnReplicaPtr.p->noCrashedReplicas > 0) {
16660  jam();
16661  /* --------------------------------------------------------------------- */
16662  /* REMOVE ALL REPLICAS THAT ONLY LIVED IN A PERIOD THAT HAVE BEEN */
16663  /* REMOVED FROM THE RESTART INFORMATION SINCE THE RESTART FAILED */
16664  /* TOO MANY TIMES. */
16665  /* --------------------------------------------------------------------- */
16666  arrGuard(rtnReplicaPtr.p->noCrashedReplicas - 1, MAX_CRASHED_REPLICAS);
16667  if (rtnReplicaPtr.p->createGci[rtnReplicaPtr.p->noCrashedReplicas - 1] > lastCompletedGCI)
16668  {
16669  jam();
16670  rtnReplicaPtr.p->createGci[rtnReplicaPtr.p->noCrashedReplicas - 1] =
16671  ZINIT_CREATE_GCI;
16672  rtnReplicaPtr.p->replicaLastGci[rtnReplicaPtr.p->noCrashedReplicas - 1] =
16673  ZINIT_REPLICA_LAST_GCI;
16674  rtnReplicaPtr.p->noCrashedReplicas--;
16675  } else {
16676  break;
16677  }//if
16678  }//while
16679 }//Dbdih::removeTooNewCrashedReplicas()
16680 
16681 /*************************************************************************/
16682 /* */
16683 /* MODULE: SEARCH FOR POSSIBLE REPLICAS THAT CAN HANDLE THE GLOBAL */
16684 /* CHECKPOINT WITHOUT NEEDING ANY EXTRA LOGGING FACILITIES.*/
16685 /* A MAXIMUM OF FOUR NODES IS RETRIEVED. */
16686 /*************************************************************************/
16687 bool
16688 Dbdih::setup_create_replica(FragmentstorePtr fragPtr,
16689  CreateReplicaRecord* createReplicaPtrP,
16690  ConstPtr<ReplicaRecord> replicaPtr)
16691 {
16692  createReplicaPtrP->dataNodeId = replicaPtr.p->procNode;
16693  createReplicaPtrP->replicaRec = replicaPtr.i;
16694 
16695  /* ----------------------------------------------------------------- */
16696  /* WE NEED TO SEARCH FOR A PROPER LOCAL CHECKPOINT TO USE FOR THE */
16697  /* SYSTEM RESTART. */
16698  /* ----------------------------------------------------------------- */
16699  Uint32 startGci;
16700  Uint32 startLcpNo;
16701  Uint32 stopGci = SYSFILE->newestRestorableGCI;
16702  bool result = findStartGci(replicaPtr,
16703  stopGci,
16704  startGci,
16705  startLcpNo);
16706  if (!result)
16707  {
16708  jam();
16709  /* --------------------------------------------------------------- */
16710  /* WE COULD NOT FIND ANY LOCAL CHECKPOINT. THE FRAGMENT THUS DO NOT*/
16711  /* CONTAIN ANY VALID LOCAL CHECKPOINT. IT DOES HOWEVER CONTAIN A */
16712  /* VALID FRAGMENT LOG. THUS BY FIRST CREATING THE FRAGMENT AND THEN*/
16713  /* EXECUTING THE FRAGMENT LOG WE CAN CREATE THE FRAGMENT AS */
16714  /* DESIRED. THIS SHOULD ONLY OCCUR AFTER CREATING A FRAGMENT. */
16715  /* */
16716  /* TO INDICATE THAT NO LOCAL CHECKPOINT IS TO BE USED WE SET THE */
16717  /* LOCAL CHECKPOINT TO ZNIL. */
16718  /* --------------------------------------------------------------- */
16719  createReplicaPtrP->lcpNo = ZNIL;
16720  }
16721  else
16722  {
16723  jam();
16724  /* --------------------------------------------------------------- */
16725  /* WE FOUND A PROPER LOCAL CHECKPOINT TO RESTART FROM. */
16726  /* SET LOCAL CHECKPOINT ID AND LOCAL CHECKPOINT NUMBER. */
16727  /* --------------------------------------------------------------- */
16728  createReplicaPtrP->lcpNo = startLcpNo;
16729  arrGuard(startLcpNo, MAX_LCP_STORED);
16730  createReplicaPtrP->createLcpId = replicaPtr.p->lcpId[startLcpNo];
16731  }//if
16732 
16733 
16734  /* ----------------------------------------------------------------- */
16735  /* WE HAVE EITHER FOUND A LOCAL CHECKPOINT OR WE ARE PLANNING TO */
16736  /* EXECUTE THE LOG FROM THE INITIAL CREATION OF THE TABLE. IN BOTH */
16737  /* CASES WE NEED TO FIND A SET OF LOGS THAT CAN EXECUTE SUCH THAT */
16738  /* WE RECOVER TO THE SYSTEM RESTART GLOBAL CHECKPOINT. */
16739  /* -_--------------------------------------------------------------- */
16740  return findLogNodes(createReplicaPtrP, fragPtr, startGci, stopGci);
16741 }
16742 
16743 void Dbdih::searchStoredReplicas(FragmentstorePtr fragPtr)
16744 {
16745  Uint32 nextReplicaPtrI;
16746  Ptr<ReplicaRecord> replicaPtr;
16747 
16748  replicaPtr.i = fragPtr.p->storedReplicas;
16749  while (replicaPtr.i != RNIL) {
16750  jam();
16751  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
16752  nextReplicaPtrI = replicaPtr.p->nextReplica;
16753  ConstPtr<ReplicaRecord> constReplicaPtr;
16754  constReplicaPtr.i = replicaPtr.i;
16755  constReplicaPtr.p = replicaPtr.p;
16756  NodeRecordPtr nodePtr;
16757  nodePtr.i = replicaPtr.p->procNode;
16758  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
16759  if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
16760  jam();
16761  switch (nodePtr.p->activeStatus) {
16762  case Sysfile::NS_Active:
16763  case Sysfile::NS_ActiveMissed_1:
16764  case Sysfile::NS_ActiveMissed_2:{
16765  /* ----------------------------------------------------------------- */
16766  /* INITIALISE THE CREATE REPLICA STRUCTURE THAT IS USED FOR SENDING*/
16767  /* TO LQH START_FRAGREQ. */
16768  /* SET THE DATA NODE WHERE THE LOCAL CHECKPOINT IS FOUND. ALSO */
16769  /* SET A REFERENCE TO THE REPLICA POINTER OF THAT. */
16770  /* ----------------------------------------------------------------- */
16771  CreateReplicaRecordPtr createReplicaPtr;
16772  createReplicaPtr.i = cnoOfCreateReplicas;
16773  ptrCheckGuard(createReplicaPtr, 4, createReplicaRecord);
16774  cnoOfCreateReplicas++;
16775 
16779  ndbrequire(setup_create_replica(fragPtr,
16780  createReplicaPtr.p,
16781  constReplicaPtr));
16782  break;
16783  }
16784  default:
16785  jam();
16786  /*empty*/;
16787  break;
16788  }//switch
16789  }
16790  replicaPtr.i = nextReplicaPtrI;
16791  }//while
16792 }//Dbdih::searchStoredReplicas()
16793 
16794 /*************************************************************************/
16795 /* */
16796 /* MODULE: SEIZE_FILE */
16797 /* DESCRIPTION: THE SUBROUTINE SEIZES A FILE RECORD FROM THE */
16798 /* FREE LIST. */
16799 /*************************************************************************/
16800 void Dbdih::seizeFile(FileRecordPtr& filePtr)
16801 {
16802  filePtr.i = cfirstfreeFile;
16803  ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
16804  cfirstfreeFile = filePtr.p->nextFile;
16805  filePtr.p->nextFile = RNIL;
16806 }//Dbdih::seizeFile()
16807 
16808 /*************************************************************************/
16809 /* SEND CREATE_FRAGREQ TO ALL NODES IN THE NDB CLUSTER. */
16810 /*************************************************************************/
16811 /*************************************************************************/
16812 /* */
16813 /* MODULE: FIND THE START GCI AND LOCAL CHECKPOINT TO USE. */
16814 /*************************************************************************/
16815 void Dbdih::sendStartFragreq(Signal* signal,
16816  TabRecordPtr tabPtr, Uint32 fragId)
16817 {
16818  CreateReplicaRecordPtr replicaPtr;
16819  for (replicaPtr.i = 0; replicaPtr.i < cnoOfCreateReplicas; replicaPtr.i++) {
16820  jam();
16821  ptrAss(replicaPtr, createReplicaRecord);
16822 
16823  BlockReference ref = numberToRef(DBLQH, replicaPtr.p->dataNodeId);
16824 
16825  StartFragReq * const startFragReq = (StartFragReq *)&signal->theData[0];
16826  startFragReq->userPtr = replicaPtr.p->replicaRec;
16827  startFragReq->userRef = reference();
16828  startFragReq->lcpNo = replicaPtr.p->lcpNo;
16829  startFragReq->lcpId = replicaPtr.p->createLcpId;
16830  startFragReq->tableId = tabPtr.i;
16831  startFragReq->fragId = fragId;
16832  startFragReq->requestInfo = StartFragReq::SFR_RESTORE_LCP;
16833 
16834  if(ERROR_INSERTED(7072) || ERROR_INSERTED(7074)){
16835  jam();
16836  const Uint32 noNodes = replicaPtr.p->noLogNodes;
16837  Uint32 start = replicaPtr.p->logStartGci[noNodes - 1];
16838  const Uint32 stop = replicaPtr.p->logStopGci[noNodes - 1];
16839 
16840  for(Uint32 i = noNodes; i < MAX_LOG_EXEC && (stop - start) > 0; i++){
16841  replicaPtr.p->noLogNodes++;
16842  replicaPtr.p->logStopGci[i - 1] = start;
16843 
16844  replicaPtr.p->logNodeId[i] = replicaPtr.p->logNodeId[i-1];
16845  replicaPtr.p->logStartGci[i] = start + 1;
16846  replicaPtr.p->logStopGci[i] = stop;
16847  start += 1;
16848  }
16849  }
16850 
16851  startFragReq->noOfLogNodes = replicaPtr.p->noLogNodes;
16852 
16853  for (Uint32 i = 0; i < MAX_LOG_EXEC ; i++) {
16854  startFragReq->lqhLogNode[i] = replicaPtr.p->logNodeId[i];
16855  startFragReq->startGci[i] = replicaPtr.p->logStartGci[i];
16856  startFragReq->lastGci[i] = replicaPtr.p->logStopGci[i];
16857  }//for
16858 
16859  sendSignal(ref, GSN_START_FRAGREQ, signal,
16860  StartFragReq::SignalLength, JBB);
16861  }//for
16862 }//Dbdih::sendStartFragreq()
16863 
16864 /*************************************************************************/
16865 /* SET LCP ACTIVE STATUS BEFORE STARTING A LOCAL CHECKPOINT. */
16866 /*************************************************************************/
16867 void Dbdih::setLcpActiveStatusStart(Signal* signal)
16868 {
16869  NodeRecordPtr nodePtr;
16870 
16871  c_lcpState.m_participatingLQH.clear();
16872  c_lcpState.m_participatingDIH.clear();
16873 
16874  for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
16875  ptrAss(nodePtr, nodeRecord);
16876 #if 0
16877  if(nodePtr.p->nodeStatus != NodeRecord::NOT_IN_CLUSTER){
16878  infoEvent("Node %d nodeStatus=%d activeStatus=%d copyCompleted=%d lcp=%d",
16879  nodePtr.i,
16880  nodePtr.p->nodeStatus,
16881  nodePtr.p->activeStatus,
16882  nodePtr.p->copyCompleted,
16883  nodePtr.p->m_inclDihLcp);
16884  }
16885 #endif
16886  if(nodePtr.p->nodeStatus == NodeRecord::ALIVE)
16887  {
16888  jam();
16889  if (nodePtr.p->m_inclDihLcp)
16890  {
16891  jam();
16892  c_lcpState.m_participatingDIH.set(nodePtr.i);
16893  }
16894 
16895  if (nodePtr.p->copyCompleted)
16896  {
16897  jam();
16898  c_lcpState.m_participatingLQH.set(nodePtr.i);
16899  }
16900  else if (nodePtr.p->activeStatus == Sysfile::NS_Configured)
16901  {
16902  jam();
16903  continue;
16904  }
16905  else
16906  {
16907  jam();
16908  nodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
16909  }
16910  }
16911  else if (nodePtr.p->activeStatus == Sysfile::NS_Configured)
16912  {
16913  jam();
16914  continue;
16915  }
16916  else if (nodePtr.p->activeStatus != Sysfile::NS_NotDefined)
16917  {
16918  jam();
16919  nodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
16920  }
16921  }
16922 }//Dbdih::setLcpActiveStatusStart()
16923 
16924 /*************************************************************************/
16925 /* SET LCP ACTIVE STATUS AT THE END OF A LOCAL CHECKPOINT. */
16926 /*************************************************************************/
16927 void Dbdih::setLcpActiveStatusEnd(Signal* signal)
16928 {
16929  NodeRecordPtr nodePtr;
16930 
16931  for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
16932  jam();
16933  ptrAss(nodePtr, nodeRecord);
16934  if (c_lcpState.m_participatingLQH.get(nodePtr.i))
16935  {
16936  jam();
16937  nodePtr.p->copyCompleted = 1;
16938  if (! (nodePtr.p->activeStatus == Sysfile::NS_Configured))
16939  {
16940  jam();
16941  nodePtr.p->activeStatus = Sysfile::NS_Active;
16942  }
16943  else
16944  {
16945  jam();
16946  // Do nothing
16947  }
16948  }
16949  else if (nodePtr.p->activeStatus == Sysfile::NS_Configured)
16950  {
16951  jam();
16952  continue;
16953  }
16954  else if (nodePtr.p->activeStatus != Sysfile::NS_NotDefined)
16955  {
16956  jam();
16957  nodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
16958  }
16959  }
16960 
16961  c_lcpState.m_participatingDIH.clear();
16962  c_lcpState.m_participatingLQH.clear();
16963  if (isMaster()) {
16964  jam();
16965  setNodeRestartInfoBits(signal);
16966  }//if
16967 }//Dbdih::setLcpActiveStatusEnd()
16968 
16969 /*************************************************************************/
16970 /* SET NODE ACTIVE STATUS AT SYSTEM RESTART AND WHEN UPDATED BY MASTER */
16971 /*************************************************************************/
16972 void Dbdih::setNodeActiveStatus()
16973 {
16974  NodeRecordPtr snaNodeptr;
16975 
16976  for (snaNodeptr.i = 1; snaNodeptr.i < MAX_NDB_NODES; snaNodeptr.i++)
16977  {
16978  ptrAss(snaNodeptr, nodeRecord);
16979  const Uint32 tsnaNodeBits = Sysfile::getNodeStatus(snaNodeptr.i,
16980  SYSFILE->nodeStatus);
16981  switch (tsnaNodeBits) {
16982  case Sysfile::NS_Active:
16983  jam();
16984  snaNodeptr.p->activeStatus = Sysfile::NS_Active;
16985  break;
16986  case Sysfile::NS_ActiveMissed_1:
16987  jam();
16988  snaNodeptr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
16989  break;
16990  case Sysfile::NS_ActiveMissed_2:
16991  jam();
16992  snaNodeptr.p->activeStatus = Sysfile::NS_ActiveMissed_2;
16993  break;
16994  case Sysfile::NS_TakeOver:
16995  jam();
16996  snaNodeptr.p->activeStatus = Sysfile::NS_TakeOver;
16997  break;
16998  case Sysfile::NS_NotActive_NotTakenOver:
16999  jam();
17000  snaNodeptr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
17001  break;
17002  case Sysfile::NS_NotDefined:
17003  jam();
17004  snaNodeptr.p->activeStatus = Sysfile::NS_NotDefined;
17005  break;
17006  case Sysfile::NS_Configured:
17007  jam();
17008  snaNodeptr.p->activeStatus = Sysfile::NS_Configured;
17009  break;
17010  default:
17011  ndbrequire(false);
17012  break;
17013  }//switch
17014  }//for
17015 }//Dbdih::setNodeActiveStatus()
17016 
17017 /***************************************************************************/
17018 /* SET THE NODE GROUP BASED ON THE RESTART INFORMATION OR AS SET BY MASTER */
17019 /***************************************************************************/
17020 void Dbdih::setNodeGroups()
17021 {
17022  NodeGroupRecordPtr NGPtr;
17023  NodeRecordPtr sngNodeptr;
17024  Uint32 Ti;
17025 
17026  for (Ti = 0; Ti < cnoOfNodeGroups; Ti++) {
17027  NGPtr.i = c_node_groups[Ti];
17028  ptrAss(NGPtr, nodeGroupRecord);
17029  NGPtr.p->nodeCount = 0;
17030  NGPtr.p->nodegroupIndex = RNIL;
17031  }//for
17032  cnoOfNodeGroups = 0;
17033  for (sngNodeptr.i = 1; sngNodeptr.i < MAX_NDB_NODES; sngNodeptr.i++) {
17034  ptrAss(sngNodeptr, nodeRecord);
17036  (Sysfile::ActiveStatus)Sysfile::getNodeStatus(sngNodeptr.i,
17037  SYSFILE->nodeStatus);
17038  switch (s){
17039  case Sysfile::NS_Active:
17040  case Sysfile::NS_ActiveMissed_1:
17041  case Sysfile::NS_ActiveMissed_2:
17042  case Sysfile::NS_NotActive_NotTakenOver:
17043  case Sysfile::NS_TakeOver:
17044  jam();
17045  sngNodeptr.p->nodeGroup = Sysfile::getNodeGroup(sngNodeptr.i,
17046  SYSFILE->nodeGroups);
17047  NGPtr.i = sngNodeptr.p->nodeGroup;
17048  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
17049  NGPtr.p->nodesInGroup[NGPtr.p->nodeCount] = sngNodeptr.i;
17050  NGPtr.p->nodeCount++;
17051  add_nodegroup(NGPtr);
17052  break;
17053  case Sysfile::NS_NotDefined:
17054  case Sysfile::NS_Configured:
17055  jam();
17056  sngNodeptr.p->nodeGroup = ZNIL;
17057  break;
17058  default:
17059  ndbrequire(false);
17060  return;
17061  break;
17062  }//switch
17063  }//for
17064 }//Dbdih::setNodeGroups()
17065 
17066 /*************************************************************************/
17067 /* SET THE RESTART INFO BITS BASED ON THE NODES ACTIVE STATUS. */
17068 /*************************************************************************/
17069 void Dbdih::setNodeRestartInfoBits(Signal * signal)
17070 {
17071  NodeRecordPtr nodePtr;
17072  Uint32 tsnrNodeGroup;
17073  Uint32 tsnrNodeActiveStatus;
17074  Uint32 i;
17075  for(i = 1; i < MAX_NDB_NODES; i++){
17076  Sysfile::setNodeStatus(i, SYSFILE->nodeStatus, Sysfile::NS_Active);
17077  }//for
17078  for(i = 1; i < Sysfile::NODE_GROUPS_SIZE; i++){
17079  SYSFILE->nodeGroups[i] = 0;
17080  }//for
17081  NdbNodeBitmask::clear(SYSFILE->lcpActive);
17082 
17083 #ifdef ERROR_INSERT
17084  NdbNodeBitmask tmp;
17085 #endif
17086 
17087  for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
17088  ptrAss(nodePtr, nodeRecord);
17089  switch (nodePtr.p->activeStatus) {
17090  case Sysfile::NS_Active:
17091  jam();
17092  tsnrNodeActiveStatus = Sysfile::NS_Active;
17093  break;
17094  case Sysfile::NS_ActiveMissed_1:
17095  jam();
17096  tsnrNodeActiveStatus = Sysfile::NS_ActiveMissed_1;
17097  break;
17098  case Sysfile::NS_ActiveMissed_2:
17099  jam();
17100  tsnrNodeActiveStatus = Sysfile::NS_ActiveMissed_2;
17101  break;
17102  case Sysfile::NS_TakeOver:
17103  jam();
17104  tsnrNodeActiveStatus = Sysfile::NS_TakeOver;
17105  break;
17106  case Sysfile::NS_NotActive_NotTakenOver:
17107  jam();
17108  tsnrNodeActiveStatus = Sysfile::NS_NotActive_NotTakenOver;
17109  break;
17110  case Sysfile::NS_NotDefined:
17111  jam();
17112  tsnrNodeActiveStatus = Sysfile::NS_NotDefined;
17113  break;
17114  case Sysfile::NS_Configured:
17115  jam();
17116  tsnrNodeActiveStatus = Sysfile::NS_Configured;
17117  break;
17118  default:
17119  ndbrequire(false);
17120  tsnrNodeActiveStatus = Sysfile::NS_NotDefined; // remove warning
17121  break;
17122  }//switch
17123  Sysfile::setNodeStatus(nodePtr.i, SYSFILE->nodeStatus,
17124  tsnrNodeActiveStatus);
17125  if (nodePtr.p->nodeGroup == ZNIL) {
17126  jam();
17127  tsnrNodeGroup = NO_NODE_GROUP_ID;
17128  } else {
17129  jam();
17130  tsnrNodeGroup = nodePtr.p->nodeGroup;
17131  }//if
17132  Sysfile::setNodeGroup(nodePtr.i, SYSFILE->nodeGroups, tsnrNodeGroup);
17133  if (c_lcpState.m_participatingLQH.get(nodePtr.i))
17134  {
17135  jam();
17136  NdbNodeBitmask::set(SYSFILE->lcpActive, nodePtr.i);
17137  }//if
17138 #ifdef ERROR_INSERT
17139  else if (Sysfile::getLCPOngoing(SYSFILE->systemRestartBits))
17140  {
17141  jam();
17142  if (nodePtr.p->activeStatus == Sysfile::NS_Active)
17143  tmp.set(nodePtr.i);
17144  }
17145 #endif
17146  }//for
17147 
17148 #ifdef ERROR_INSERT
17149  if (ERROR_INSERTED(7220) && !tmp.isclear())
17150  {
17151  jam();
17152 
17153  NdbNodeBitmask all;
17154  nodePtr.i = cfirstAliveNode;
17155  do {
17156  jam();
17157  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
17158  all.set(nodePtr.i);
17159  nodePtr.i = nodePtr.p->nextNode;
17160  } while (nodePtr.i != RNIL);
17161 
17162 
17163  NodeReceiverGroup rg(DBDIH, all);
17164  signal->theData[0] = 7219;
17165  sendSignal(rg, GSN_NDB_TAMPER, signal, 1, JBA);
17166  }
17167 #endif
17168 }//Dbdih::setNodeRestartInfoBits()
17169 
17170 /*************************************************************************/
17171 /* START THE GLOBAL CHECKPOINT PROTOCOL IN MASTER AT START-UP */
17172 /*************************************************************************/
17173 void Dbdih::startGcp(Signal* signal)
17174 {
17175  signal->theData[0] = DihContinueB::ZSTART_GCP;
17176  sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
17177 
17178  startGcpMonitor(signal);
17179 }//Dbdih::startGcp()
17180 
17181 void
17182 Dbdih::startGcpMonitor(Signal* signal)
17183 {
17184  jam();
17185  m_gcp_monitor.m_gcp_save.m_gci = m_gcp_save.m_gci;
17186  m_gcp_monitor.m_gcp_save.m_counter = 0;
17187  m_gcp_monitor.m_micro_gcp.m_gci = m_micro_gcp.m_current_gci;
17188  m_gcp_monitor.m_micro_gcp.m_counter = 0;
17189 
17190  signal->theData[0] = DihContinueB::ZCHECK_GCP_STOP;
17191  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
17192 }
17193 
17194 void Dbdih::updateNodeInfo(FragmentstorePtr fragPtr)
17195 {
17196  ReplicaRecordPtr replicatePtr;
17197  Uint32 index = 0;
17198  replicatePtr.i = fragPtr.p->storedReplicas;
17199  do {
17200  jam();
17201  ptrCheckGuard(replicatePtr, creplicaFileSize, replicaRecord);
17202  ndbrequire(index < MAX_REPLICAS);
17203  fragPtr.p->activeNodes[index] = replicatePtr.p->procNode;
17204  index++;
17205  replicatePtr.i = replicatePtr.p->nextReplica;
17206  } while (replicatePtr.i != RNIL);
17207  fragPtr.p->fragReplicas = index;
17208 
17209  /* ----------------------------------------------------------------------- */
17210  // We switch primary to the preferred primary if the preferred primary is
17211  // in the list.
17212  /* ----------------------------------------------------------------------- */
17213  const Uint32 prefPrim = fragPtr.p->preferredPrimary;
17214  for (Uint32 i = 1; i < index; i++) {
17215  jam();
17216  ndbrequire(i < MAX_REPLICAS);
17217  if (fragPtr.p->activeNodes[i] == prefPrim){
17218  jam();
17219  Uint32 switchNode = fragPtr.p->activeNodes[0];
17220  fragPtr.p->activeNodes[0] = prefPrim;
17221  fragPtr.p->activeNodes[i] = switchNode;
17222  break;
17223  }//if
17224  }//for
17225 }//Dbdih::updateNodeInfo()
17226 
17227 void Dbdih::writeFragment(RWFragment* wf, FragmentstorePtr fragPtr)
17228 {
17229  writePageWord(wf, wf->fragId);
17230  writePageWord(wf, fragPtr.p->preferredPrimary);
17231  writePageWord(wf, fragPtr.p->noStoredReplicas);
17232  writePageWord(wf, fragPtr.p->noOldStoredReplicas);
17233  writePageWord(wf, fragPtr.p->distributionKey);
17234  writePageWord(wf, fragPtr.p->m_log_part_id);
17235 }//Dbdih::writeFragment()
17236 
17237 void Dbdih::writePageWord(RWFragment* wf, Uint32 dataWord)
17238 {
17239  if (wf->wordIndex >= 2048) {
17240  jam();
17241  ndbrequire(wf->wordIndex == 2048);
17242  allocpage(wf->rwfPageptr);
17243  wf->wordIndex = 32;
17244  wf->pageIndex++;
17245  ndbrequire(wf->pageIndex < NDB_ARRAY_SIZE(wf->rwfTabPtr.p->pageRef));
17246  wf->rwfTabPtr.p->pageRef[wf->pageIndex] = wf->rwfPageptr.i;
17247  wf->rwfTabPtr.p->noPages++;
17248  }//if
17249  wf->rwfPageptr.p->word[wf->wordIndex] = dataWord;
17250  wf->wordIndex++;
17251 }//Dbdih::writePageWord()
17252 
17253 void Dbdih::writeReplicas(RWFragment* wf, Uint32 replicaStartIndex)
17254 {
17255  ReplicaRecordPtr wfReplicaPtr;
17256  wfReplicaPtr.i = replicaStartIndex;
17257  while (wfReplicaPtr.i != RNIL) {
17258  jam();
17259  ptrCheckGuard(wfReplicaPtr, creplicaFileSize, replicaRecord);
17260  writePageWord(wf, wfReplicaPtr.p->procNode);
17261  writePageWord(wf, wfReplicaPtr.p->initialGci);
17262  writePageWord(wf, wfReplicaPtr.p->noCrashedReplicas);
17263  writePageWord(wf, wfReplicaPtr.p->nextLcp);
17264  Uint32 i;
17265  for (i = 0; i < MAX_LCP_STORED; i++) {
17266  writePageWord(wf, wfReplicaPtr.p->maxGciCompleted[i]);
17267  writePageWord(wf, wfReplicaPtr.p->maxGciStarted[i]);
17268  writePageWord(wf, wfReplicaPtr.p->lcpId[i]);
17269  writePageWord(wf, wfReplicaPtr.p->lcpStatus[i]);
17270  }//if
17271  for (i = 0; i < MAX_CRASHED_REPLICAS; i++) {
17272  writePageWord(wf, wfReplicaPtr.p->createGci[i]);
17273  writePageWord(wf, wfReplicaPtr.p->replicaLastGci[i]);
17274  }//if
17275 
17276  wfReplicaPtr.i = wfReplicaPtr.p->nextReplica;
17277  }//while
17278 }//Dbdih::writeReplicas()
17279 
17280 void Dbdih::writeRestorableGci(Signal* signal, FileRecordPtr filePtr)
17281 {
17282  for (Uint32 i = 0; i < Sysfile::SYSFILE_SIZE32; i++) {
17283  sysfileDataToFile[i] = sysfileData[i];
17284  }//for
17285  signal->theData[0] = filePtr.p->fileRef;
17286  signal->theData[1] = reference();
17287  signal->theData[2] = filePtr.i;
17288  signal->theData[3] = ZLIST_OF_PAIRS_SYNCH;
17289  signal->theData[4] = ZVAR_NO_CRESTART_INFO_TO_FILE;
17290  signal->theData[5] = 1; /* AMOUNT OF PAGES */
17291  signal->theData[6] = 0; /* MEMORY PAGE = 0 SINCE COMMON STORED VARIABLE */
17292  signal->theData[7] = 0;
17293 
17294  if (ERROR_INSERTED(7224) && filePtr.i == crestartInfoFile[1])
17295  {
17296  jam();
17297  SET_ERROR_INSERT_VALUE(7225);
17298  sendSignalWithDelay(NDBFS_REF, GSN_FSWRITEREQ, signal, 500, 8);
17299 
17300  signal->theData[0] = 9999;
17301  sendSignal(numberToRef(CMVMI, refToNode(cmasterdihref)),
17302  GSN_NDB_TAMPER, signal, 1, JBB);
17303  return;
17304  }
17305  sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
17306 }//Dbdih::writeRestorableGci()
17307 
17308 void Dbdih::writeTabfile(Signal* signal, TabRecord* tab, FileRecordPtr filePtr)
17309 {
17310  signal->theData[0] = filePtr.p->fileRef;
17311  signal->theData[1] = reference();
17312  signal->theData[2] = filePtr.i;
17313  signal->theData[3] = ZLIST_OF_PAIRS_SYNCH;
17314  signal->theData[4] = ZVAR_NO_WORD;
17315  signal->theData[5] = tab->noPages;
17316 
17317  Uint32 section[2 * NDB_ARRAY_SIZE(tab->pageRef)];
17318  for (Uint32 i = 0; i < tab->noPages; i++)
17319  {
17320  section[(2 * i) + 0] = tab->pageRef[i];
17321  section[(2 * i) + 1] = i;
17322  }
17323  LinearSectionPtr ptr[3];
17324  ptr[0].p = section;
17325  ptr[0].sz = 2 * tab->noPages;
17326  sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 6, JBA, ptr, 1);
17327 }//Dbdih::writeTabfile()
17328 
17329 void Dbdih::execDEBUG_SIG(Signal* signal)
17330 {
17331  signal = signal; //Avoid compiler warnings
17332 }//Dbdih::execDEBUG_SIG()
17333 
17334 void
17335 Dbdih::execDUMP_STATE_ORD(Signal* signal)
17336 {
17337  DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0];
17338  Uint32 arg = dumpState->args[0];
17339  if (arg == DumpStateOrd::DihDumpNodeRestartInfo) {
17340  infoEvent("c_nodeStartMaster.blockLcp = %d, c_nodeStartMaster.blockGcp = %d, c_nodeStartMaster.wait = %d",
17341  c_nodeStartMaster.blockLcp, c_nodeStartMaster.blockGcp, c_nodeStartMaster.wait);
17342  for (Uint32 i = 0; i < c_diverify_queue_cnt; i++)
17343  {
17344  infoEvent("[ %u : cfirstVerifyQueue = %u clastVerifyQueue = %u sz: %u]",
17345  i,
17346  c_diverify_queue[i].cfirstVerifyQueue,
17347  c_diverify_queue[i].clastVerifyQueue,
17348  capiConnectFileSize);
17349  }
17350  infoEvent("cgcpOrderBlocked = %d",
17351  cgcpOrderBlocked);
17352  }//if
17353  if (arg == DumpStateOrd::DihDumpNodeStatusInfo) {
17354  NodeRecordPtr localNodePtr;
17355  infoEvent("Printing nodeStatus of all nodes");
17356  for (localNodePtr.i = 1; localNodePtr.i < MAX_NDB_NODES; localNodePtr.i++) {
17357  ptrAss(localNodePtr, nodeRecord);
17358  if (localNodePtr.p->nodeStatus != NodeRecord::NOT_IN_CLUSTER) {
17359  infoEvent("Node = %d has status = %d",
17360  localNodePtr.i, localNodePtr.p->nodeStatus);
17361  }//if
17362  }//for
17363  }//if
17364 
17365  if (arg == DumpStateOrd::DihPrintFragmentation)
17366  {
17367  infoEvent("Printing nodegroups --");
17368  for (Uint32 i = 0; i<cnoOfNodeGroups; i++)
17369  {
17370  NodeGroupRecordPtr NGPtr;
17371  NGPtr.i = c_node_groups[i];
17372  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
17373 
17374  infoEvent("NG %u(%u) ref: %u [ cnt: %u : %u %u %u %u ]",
17375  NGPtr.i, NGPtr.p->nodegroupIndex, NGPtr.p->m_ref_count,
17376  NGPtr.p->nodeCount,
17377  NGPtr.p->nodesInGroup[0], NGPtr.p->nodesInGroup[1], NGPtr.p->nodesInGroup[2], NGPtr.p->nodesInGroup[3]);
17378  }
17379 
17380  infoEvent("Printing fragmentation of all tables --");
17381  for(Uint32 i = 0; i<ctabFileSize; i++){
17382  TabRecordPtr tabPtr;
17383  tabPtr.i = i;
17384  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
17385 
17386  if(tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
17387  continue;
17388 
17389  for(Uint32 j = 0; j < tabPtr.p->totalfragments; j++){
17390  FragmentstorePtr fragPtr;
17391  getFragstore(tabPtr.p, j, fragPtr);
17392 
17393  Uint32 nodeOrder[MAX_REPLICAS];
17394  const Uint32 noOfReplicas = extractNodeInfo(fragPtr.p, nodeOrder);
17395  char buf[100];
17396  BaseString::snprintf(buf, sizeof(buf), " Table %d Fragment %d(%u) LP: %u - ", tabPtr.i, j, dihGetInstanceKey(fragPtr), fragPtr.p->m_log_part_id);
17397  for(Uint32 k = 0; k < noOfReplicas; k++){
17398  char tmp[100];
17399  BaseString::snprintf(tmp, sizeof(tmp), "%d ", nodeOrder[k]);
17400  strcat(buf, tmp);
17401  }
17402  infoEvent("%s", buf);
17403  }
17404  }
17405  }
17406 
17407  if (signal->theData[0] == 7000) {
17408  infoEvent("ctimer = %d",
17409  c_lcpState.ctimer);
17410  infoEvent("cmasterState = %d", cmasterState);
17411  infoEvent("cmasterTakeOverNode = %d, ctcCounter = %d",
17412  cmasterTakeOverNode, c_lcpState.ctcCounter);
17413  }//if
17414  if (signal->theData[0] == 7001) {
17415  infoEvent("c_lcpState.keepGci = %d",
17416  c_lcpState.keepGci);
17417  infoEvent("c_lcpState.lcpStatus = %d, clcpStopGcp = %d",
17418  c_lcpState.lcpStatus,
17419  c_lcpState.lcpStopGcp);
17420  infoEvent("cimmediateLcpStart = %d",
17421  c_lcpState.immediateLcpStart);
17422  }//if
17423  if (signal->theData[0] == 7002) {
17424  infoEvent("cnoOfActiveTables = %d",
17425  cnoOfActiveTables);
17426  infoEvent("cdictblockref = %d, cfailurenr = %d",
17427  cdictblockref, cfailurenr);
17428  infoEvent("con_lineNodes = %d, reference() = %d, creceivedfrag = %d",
17429  con_lineNodes, reference(), creceivedfrag);
17430  }//if
17431  if (signal->theData[0] == 7003) {
17432  infoEvent("cfirstAliveNode = %d, cgckptflag = %d",
17433  cfirstAliveNode, cgckptflag);
17434  infoEvent("clocallqhblockref = %d, clocaltcblockref = %d, cgcpOrderBlocked = %d",
17435  clocallqhblockref, clocaltcblockref, cgcpOrderBlocked);
17436  infoEvent("cstarttype = %d, csystemnodes = %d",
17437  cstarttype, csystemnodes);
17438  }//if
17439  if (signal->theData[0] == 7004) {
17440  infoEvent("cmasterdihref = %d, cownNodeId = %d",
17441  cmasterdihref, cownNodeId);
17442  infoEvent("cndbStartReqBlockref = %d, cremainingfrags = %d",
17443  cndbStartReqBlockref, cremainingfrags);
17444  }//if
17445  if (signal->theData[0] == 7005) {
17446  infoEvent("crestartGci = %d",
17447  crestartGci);
17448  }//if
17449  if (signal->theData[0] == 7006) {
17450  infoEvent("clcpDelay = %d",
17451  c_lcpState.clcpDelay);
17452  infoEvent("cmasterNodeId = %d", cmasterNodeId);
17453  infoEvent("c_nodeStartMaster.startNode = %d, c_nodeStartMaster.wait = %d",
17454  c_nodeStartMaster.startNode, c_nodeStartMaster.wait);
17455  }//if
17456  if (signal->theData[0] == 7007) {
17457  infoEvent("c_nodeStartMaster.failNr = %d", c_nodeStartMaster.failNr);
17458  infoEvent("c_nodeStartMaster.startInfoErrorCode = %d",
17459  c_nodeStartMaster.startInfoErrorCode);
17460  infoEvent("c_nodeStartMaster.blockLcp = %d, c_nodeStartMaster.blockGcp = %d",
17461  c_nodeStartMaster.blockLcp, c_nodeStartMaster.blockGcp);
17462  }//if
17463  if (signal->theData[0] == 7008) {
17464  infoEvent("cfirstDeadNode = %d, cstartPhase = %d, cnoReplicas = %d",
17465  cfirstDeadNode, cstartPhase, cnoReplicas);
17466  infoEvent("cwaitLcpSr = %d",cwaitLcpSr);
17467  }//if
17468  if (signal->theData[0] == 7009) {
17469  infoEvent("ccalcOldestRestorableGci = %d, cnoOfNodeGroups = %d",
17470  c_lcpState.oldestRestorableGci, cnoOfNodeGroups);
17471  infoEvent("crestartGci = %d",
17472  crestartGci);
17473  }//if
17474  if (signal->theData[0] == 7010) {
17475  infoEvent("c_lcpState.lcpStatusUpdatedPlace = %d, cLcpStart = %d",
17476  c_lcpState.lcpStatusUpdatedPlace, c_lcpState.lcpStart);
17477  infoEvent("c_blockCommit = %d, c_blockCommitNo = %d",
17478  c_blockCommit, c_blockCommitNo);
17479  }//if
17480  if (signal->theData[0] == 7011){
17481  infoEvent("c_COPY_GCIREQ_Counter = %s",
17482  c_COPY_GCIREQ_Counter.getText());
17483  infoEvent("c_COPY_TABREQ_Counter = %s",
17484  c_COPY_TABREQ_Counter.getText());
17485  infoEvent("c_CREATE_FRAGREQ_Counter = %s",
17486  c_CREATE_FRAGREQ_Counter.getText());
17487  infoEvent("c_DIH_SWITCH_REPLICA_REQ_Counter = %s",
17488  c_DIH_SWITCH_REPLICA_REQ_Counter.getText());
17489  infoEvent("c_EMPTY_LCP_REQ_Counter = %s",c_EMPTY_LCP_REQ_Counter.getText());
17490  infoEvent("c_GCP_COMMIT_Counter = %s", c_GCP_COMMIT_Counter.getText());
17491  infoEvent("c_GCP_PREPARE_Counter = %s", c_GCP_PREPARE_Counter.getText());
17492  infoEvent("c_GCP_SAVEREQ_Counter = %s", c_GCP_SAVEREQ_Counter.getText());
17493  infoEvent("c_SUB_GCP_COMPLETE_REP_Counter = %s",
17494  c_SUB_GCP_COMPLETE_REP_Counter.getText());
17495  infoEvent("c_INCL_NODEREQ_Counter = %s", c_INCL_NODEREQ_Counter.getText());
17496  infoEvent("c_MASTER_GCPREQ_Counter = %s",
17497  c_MASTER_GCPREQ_Counter.getText());
17498  infoEvent("c_MASTER_LCPREQ_Counter = %s",
17499  c_MASTER_LCPREQ_Counter.getText());
17500  infoEvent("c_START_INFOREQ_Counter = %s",
17501  c_START_INFOREQ_Counter.getText());
17502  infoEvent("c_START_RECREQ_Counter = %s", c_START_RECREQ_Counter.getText());
17503  infoEvent("c_STOP_ME_REQ_Counter = %s", c_STOP_ME_REQ_Counter.getText());
17504  infoEvent("c_TC_CLOPSIZEREQ_Counter = %s",
17505  c_TC_CLOPSIZEREQ_Counter.getText());
17506  infoEvent("c_TCGETOPSIZEREQ_Counter = %s",
17507  c_TCGETOPSIZEREQ_Counter.getText());
17508  }
17509 
17510  if(signal->theData[0] == 7012){
17511  char buf[8*_NDB_NODE_BITMASK_SIZE+1];
17512  infoEvent("ParticipatingDIH = %s", c_lcpState.m_participatingDIH.getText(buf));
17513  infoEvent("ParticipatingLQH = %s", c_lcpState.m_participatingLQH.getText(buf));
17514  infoEvent("m_LCP_COMPLETE_REP_Counter_DIH = %s",
17515  c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.getText());
17516  infoEvent("m_LCP_COMPLETE_REP_Counter_LQH = %s",
17517  c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.getText());
17518  infoEvent("m_LAST_LCP_FRAG_ORD = %s",
17519  c_lcpState.m_LAST_LCP_FRAG_ORD.getText());
17520  infoEvent("m_LCP_COMPLETE_REP_From_Master_Received = %d",
17521  c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received);
17522 
17523  NodeRecordPtr nodePtr;
17524  for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
17525  jam();
17526  ptrAss(nodePtr, nodeRecord);
17527  if(nodePtr.p->nodeStatus == NodeRecord::ALIVE){
17528  Uint32 i;
17529  for(i = 0; i<nodePtr.p->noOfStartedChkpt; i++){
17530  infoEvent("Node %d: started: table=%d fragment=%d replica=%d",
17531  nodePtr.i,
17532  nodePtr.p->startedChkpt[i].tableId,
17533  nodePtr.p->startedChkpt[i].fragId,
17534  nodePtr.p->startedChkpt[i].replicaPtr);
17535  }
17536 
17537  for(i = 0; i<nodePtr.p->noOfQueuedChkpt; i++){
17538  infoEvent("Node %d: queued: table=%d fragment=%d replica=%d",
17539  nodePtr.i,
17540  nodePtr.p->queuedChkpt[i].tableId,
17541  nodePtr.p->queuedChkpt[i].fragId,
17542  nodePtr.p->queuedChkpt[i].replicaPtr);
17543  }
17544  }
17545  }
17546  }
17547 
17548  if(arg == 7019 && signal->getLength() == 2 &&
17549  signal->theData[1] < MAX_NDB_NODES)
17550  {
17551  char buf2[8+1];
17552  NodeRecordPtr nodePtr;
17553  nodePtr.i = signal->theData[1];
17554  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
17555  infoEvent("NF Node %d tc: %d lqh: %d dih: %d dict: %d recNODE_FAILREP: %d",
17556  nodePtr.i,
17557  nodePtr.p->dbtcFailCompleted,
17558  nodePtr.p->dblqhFailCompleted,
17559  nodePtr.p->dbdihFailCompleted,
17560  nodePtr.p->dbdictFailCompleted,
17561  nodePtr.p->recNODE_FAILREP);
17562  infoEvent(" m_NF_COMPLETE_REP: %s m_nodefailSteps: %s",
17563  nodePtr.p->m_NF_COMPLETE_REP.getText(),
17564  nodePtr.p->m_nodefailSteps.getText(buf2));
17565  }
17566 
17567  if(arg == 7020 && signal->getLength() > 3)
17568  {
17569  Uint32 gsn= signal->theData[1];
17570  Uint32 block= signal->theData[2];
17571  Uint32 length= signal->length() - 3;
17572  memmove(signal->theData, signal->theData+3, 4*length);
17573  sendSignal(numberToRef(block, getOwnNodeId()), gsn, signal, length, JBB);
17574 
17575  warningEvent("-- SENDING CUSTOM SIGNAL --");
17576  char buf[100], buf2[100];
17577  buf2[0]= 0;
17578  for(Uint32 i = 0; i<length; i++)
17579  {
17580  BaseString::snprintf(buf, 100, "%s %.8x", buf2, signal->theData[i]);
17581  BaseString::snprintf(buf2, 100, "%s", buf);
17582  }
17583  warningEvent("gsn: %d block: %s, length: %d theData: %s",
17584  gsn, getBlockName(block, "UNKNOWN"), length, buf);
17585 
17586  g_eventLogger->warning("-- SENDING CUSTOM SIGNAL --");
17587  g_eventLogger->warning("gsn: %d block: %s, length: %d theData: %s",
17588  gsn, getBlockName(block, "UNKNOWN"), length, buf);
17589  }
17590 
17591  if(arg == DumpStateOrd::DihDumpLCPState){
17592  infoEvent("-- Node %d LCP STATE --", getOwnNodeId());
17593  infoEvent("lcpStatus = %d (update place = %d) ",
17594  c_lcpState.lcpStatus, c_lcpState.lcpStatusUpdatedPlace);
17595  infoEvent
17596  ("lcpStart = %d lcpStopGcp = %d keepGci = %d oldestRestorable = %d",
17597  c_lcpState.lcpStart, c_lcpState.lcpStopGcp,
17598  c_lcpState.keepGci, c_lcpState.oldestRestorableGci);
17599 
17600  infoEvent
17601  ("immediateLcpStart = %d masterLcpNodeId = %d",
17602  c_lcpState.immediateLcpStart,
17603  refToNode(c_lcpState.m_masterLcpDihRef));
17604 
17605  for (Uint32 i = 0; i<10; i++)
17606  {
17607  infoEvent("%u : status: %u place: %u", i,
17608  c_lcpState.m_saveState[i].m_status,
17609  c_lcpState.m_saveState[i].m_place);
17610  }
17611 
17612  infoEvent("-- Node %d LCP STATE --", getOwnNodeId());
17613  }
17614 
17615  if(arg == DumpStateOrd::DihDumpLCPMasterTakeOver){
17616  infoEvent("-- Node %d LCP MASTER TAKE OVER STATE --", getOwnNodeId());
17617  infoEvent
17618  ("c_lcpMasterTakeOverState.state = %d updatePlace = %d failedNodeId = %d",
17619  c_lcpMasterTakeOverState.state,
17620  c_lcpMasterTakeOverState.updatePlace,
17621  c_lcpMasterTakeOverState.failedNodeId);
17622 
17623  infoEvent("c_lcpMasterTakeOverState.minTableId = %u minFragId = %u",
17624  c_lcpMasterTakeOverState.minTableId,
17625  c_lcpMasterTakeOverState.minFragId);
17626 
17627  infoEvent("-- Node %d LCP MASTER TAKE OVER STATE --", getOwnNodeId());
17628  }
17629 
17630  if (signal->theData[0] == 7015)
17631  {
17632  if (signal->getLength() == 1)
17633  {
17634  signal->theData[1] = 0;
17635  }
17636 
17637  Uint32 tableId = signal->theData[1];
17638  if (tableId < ctabFileSize)
17639  {
17640  signal->theData[0] = 7021;
17641  execDUMP_STATE_ORD(signal);
17642  signal->theData[0] = 7015;
17643  signal->theData[1] = tableId + 1;
17644  sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 2, JBB);
17645  }
17646  }
17647 
17648  if(arg == DumpStateOrd::EnableUndoDelayDataWrite){
17649  g_eventLogger->info("Dbdih:: delay write of datapages for table = %d",
17650  dumpState->args[1]);
17651  // Send this dump to ACC and TUP
17652  sendSignal(DBACC_REF, GSN_DUMP_STATE_ORD, signal, 2, JBB);
17653  sendSignal(DBTUP_REF, GSN_DUMP_STATE_ORD, signal, 2, JBB);
17654 
17655  // Start immediate LCP
17656  add_lcp_counter(&c_lcpState.ctimer, (1 << 31));
17657  return;
17658  }
17659 
17660  if (signal->theData[0] == DumpStateOrd::DihAllAllowNodeStart) {
17661  for (Uint32 i = 1; i < MAX_NDB_NODES; i++)
17662  setAllowNodeStart(i, true);
17663  return;
17664  }//if
17665  if (signal->theData[0] == DumpStateOrd::DihMinTimeBetweenLCP) {
17666  // Set time between LCP to min value
17667  if (signal->getLength() == 2)
17668  {
17669  Uint32 tmp;
17670  const ndb_mgm_configuration_iterator * p =
17671  m_ctx.m_config.getOwnConfigIterator();
17672  ndbrequire(p != 0);
17673  ndb_mgm_get_int_parameter(p, CFG_DB_LCP_INTERVAL, &tmp);
17674  g_eventLogger->info("Reset time between LCP to %u", tmp);
17675  c_lcpState.clcpDelay = tmp;
17676  }
17677  else
17678  {
17679  g_eventLogger->info("Set time between LCP to min value");
17680  c_lcpState.clcpDelay = 0; // TimeBetweenLocalCheckpoints.min
17681  }
17682  return;
17683  }
17684  if (signal->theData[0] == DumpStateOrd::DihMaxTimeBetweenLCP) {
17685  // Set time between LCP to max value
17686  g_eventLogger->info("Set time between LCP to max value");
17687  c_lcpState.clcpDelay = 31; // TimeBetweenLocalCheckpoints.max
17688  return;
17689  }
17690 
17691  if(arg == 7098){
17692  if(signal->length() == 3){
17693  jam();
17694  infoEvent("startLcpRoundLoopLab(tabel=%d, fragment=%d)",
17695  signal->theData[1], signal->theData[2]);
17696  startLcpRoundLoopLab(signal, signal->theData[1], signal->theData[2]);
17697  return;
17698  } else {
17699  infoEvent("Invalid no of arguments to 7098 - startLcpRoundLoopLab -"
17700  " expected 2 (tableId, fragmentId)");
17701  }
17702  }
17703 
17704  if (arg == DumpStateOrd::DihStartLcpImmediately)
17705  {
17706  jam();
17707  add_lcp_counter(&c_lcpState.ctimer, (1 << 31));
17708 
17712  if (cmasterNodeId != getOwnNodeId() &&
17713  refToMain(signal->getSendersBlockRef()) == DBLQH)
17714  {
17715  jam();
17716  sendSignal(cmasterdihref, GSN_DUMP_STATE_ORD, signal, 1, JBB);
17717  }
17718  return;
17719  }
17720 
17721  if (arg == DumpStateOrd::DihSetTimeBetweenGcp)
17722  {
17723  Uint32 tmp = 0;
17724  if (signal->getLength() == 1)
17725  {
17726  const ndb_mgm_configuration_iterator * p =
17727  m_ctx.m_config.getOwnConfigIterator();
17728  ndbrequire(p != 0);
17729  ndb_mgm_get_int_parameter(p, CFG_DB_GCP_INTERVAL, &tmp);
17730  }
17731  else
17732  {
17733  tmp = signal->theData[1];
17734  }
17735  m_gcp_save.m_master.m_time_between_gcp = tmp;
17736  g_eventLogger->info("Setting time between gcp : %d", tmp);
17737  }
17738 
17739  if (arg == 7021 && signal->getLength() == 2)
17740  {
17741  TabRecordPtr tabPtr;
17742  tabPtr.i = signal->theData[1];
17743  if (tabPtr.i >= ctabFileSize)
17744  return;
17745 
17746  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
17747 
17748  if(tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
17749  return;
17750 
17751  infoEvent
17752  ("Table %d: TabCopyStatus: %d TabUpdateStatus: %d TabLcpStatus: %d",
17753  tabPtr.i,
17754  tabPtr.p->tabCopyStatus,
17755  tabPtr.p->tabUpdateState,
17756  tabPtr.p->tabLcpStatus);
17757 
17758  FragmentstorePtr fragPtr;
17759  for (Uint32 fid = 0; fid < tabPtr.p->totalfragments; fid++) {
17760  jam();
17761  getFragstore(tabPtr.p, fid, fragPtr);
17762 
17763  char buf[100], buf2[100];
17764  BaseString::snprintf(buf, sizeof(buf), " Fragment %d: noLcpReplicas==%d ",
17765  fid, fragPtr.p->noLcpReplicas);
17766 
17767  Uint32 num=0;
17768  ReplicaRecordPtr replicaPtr;
17769  replicaPtr.i = fragPtr.p->storedReplicas;
17770  do {
17771  ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
17772  BaseString::snprintf(buf2, sizeof(buf2), "%s %d(on %d)=%d(%s)",
17773  buf, num,
17774  replicaPtr.p->procNode,
17775  replicaPtr.p->lcpIdStarted,
17776  replicaPtr.p->lcpOngoingFlag ? "Ongoing" : "Idle");
17777  BaseString::snprintf(buf, sizeof(buf), "%s", buf2);
17778 
17779  num++;
17780  replicaPtr.i = replicaPtr.p->nextReplica;
17781  } while (replicaPtr.i != RNIL);
17782  infoEvent("%s", buf);
17783  }
17784  }
17785 
17786  if (arg == 7022)
17787  {
17788  jam();
17789  crashSystemAtGcpStop(signal, true);
17790  }
17791 
17792  if (arg == 7025)
17793  {
17794  jam();
17795  dumpGcpStop();
17796  return;
17797  }
17798 
17799 #ifdef GCP_TIMER_HACK
17800  if (signal->theData[0] == 7901)
17801  globalData.gcp_timer_limit = signal->theData[1];
17802 #endif
17803  if (arg == 7023)
17804  {
17808  Ptr<TakeOverRecord> ptr;
17809  ptr.i = signal->theData[1];
17810  if (signal->getLength() == 1)
17811  {
17812  infoEvent("Starting dump all active take-over");
17813  c_activeTakeOverList.first(ptr);
17814  }
17815 
17816  if (ptr.i == RNIL)
17817  {
17818  infoEvent("Dump all active take-over done");
17819  return;
17820  }
17821 
17822  c_activeTakeOverList.getPtr(ptr);
17823  infoEvent("TakeOverPtr(%u) starting: %u flags: 0x%x ref: 0x%x, data: %u",
17824  ptr.i,
17825  ptr.p->toStartingNode,
17826  ptr.p->m_flags,
17827  ptr.p->m_senderRef,
17828  ptr.p->m_senderData);
17829  infoEvent("slaveState: %u masterState: %u",
17830  ptr.p->toSlaveStatus, ptr.p->toMasterStatus);
17831  infoEvent("restorableGci: %u startGci: %u tab: %u frag: %u src: %u max: %u",
17832  ptr.p->restorableGci, ptr.p->startGci,
17833  ptr.p->toCurrentTabref, ptr.p->toCurrentFragid,
17834  ptr.p->toCopyNode, ptr.p->maxPage);
17835 
17836  c_activeTakeOverList.next(ptr);
17837  signal->theData[0] = arg;
17838  signal->theData[1] = ptr.i;
17839  }
17840 
17841  if (arg == DumpStateOrd::SchemaResourceSnapshot)
17842  {
17843  RSS_OP_SNAPSHOT_SAVE(cremainingfrags);
17844  RSS_OP_SNAPSHOT_SAVE(cnoFreeReplicaRec);
17845 
17846  {
17847  Uint32 cnghash = 0;
17848  NodeGroupRecordPtr NGPtr;
17849  for (Uint32 i = 0; i<cnoOfNodeGroups; i++)
17850  {
17851  NGPtr.i = c_node_groups[i];
17852  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
17853  cnghash = (cnghash * 33) + NGPtr.p->m_ref_count;
17854  }
17855  RSS_OP_SNAPSHOT_SAVE(cnghash);
17856  }
17857  return;
17858  }
17859 
17860  if (arg == DumpStateOrd::SchemaResourceCheckLeak)
17861  {
17862  RSS_OP_SNAPSHOT_CHECK(cremainingfrags);
17863  RSS_OP_SNAPSHOT_SAVE(cnoFreeReplicaRec);
17864 
17865  {
17866  Uint32 cnghash = 0;
17867  NodeGroupRecordPtr NGPtr;
17868  for (Uint32 i = 0; i<cnoOfNodeGroups; i++)
17869  {
17870  NGPtr.i = c_node_groups[i];
17871  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
17872  cnghash = (cnghash * 33) + NGPtr.p->m_ref_count;
17873  }
17874  RSS_OP_SNAPSHOT_CHECK(cnghash);
17875  }
17876  }
17877 
17878  DECLARE_DUMP0(DBDIH, 7213, "Set error 7213 with extra arg")
17879  {
17880  SET_ERROR_INSERT_VALUE2(7213, signal->theData[1]);
17881  return;
17882  }
17883  DECLARE_DUMP0(DBDIH, 7214, "Set error 7214 with extra arg")
17884  {
17885  SET_ERROR_INSERT_VALUE2(7214, signal->theData[1]);
17886  return;
17887  }
17888 
17889  DECLARE_DUMP0(DBDIH, 7216, "Set error 7216 with extra arg")
17890  {
17891  SET_ERROR_INSERT_VALUE2(7216, signal->theData[1]);
17892  return;
17893  }
17894  DECLARE_DUMP0(DBDIH, 6099, "Start microgcp")
17895  {
17896  if (isMaster())
17897  {
17898  jam();
17899  m_micro_gcp.m_master.m_start_time = 0;
17900  }
17901  else
17902  {
17903  jam();
17904  sendSignal(cmasterdihref, GSN_DUMP_STATE_ORD, signal, 1, JBB);
17905  }
17906  return;
17907  }
17908  DECLARE_DUMP0(DBDIH, 7999, "Set error code with extra arg")
17909  {
17910  SET_ERROR_INSERT_VALUE2(signal->theData[1],
17911  signal->theData[2]);
17912  }
17913 }//Dbdih::execDUMP_STATE_ORD()
17914 
17915 void
17916 Dbdih::execPREP_DROP_TAB_REQ(Signal* signal){
17917  jamEntry();
17918 
17919  PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
17920 
17921  TabRecordPtr tabPtr;
17922  tabPtr.i = req->tableId;
17923  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
17924 
17925  Uint32 senderRef = req->senderRef;
17926  Uint32 senderData = req->senderData;
17927 
17928  PrepDropTabRef::ErrorCode err = PrepDropTabRef::OK;
17929  {
17932  bool ok = false;
17933  switch(tabPtr.p->tabStatus){
17934  case TabRecord::TS_IDLE:
17935  ok = true;
17936  jam();
17937  err = PrepDropTabRef::NoSuchTable;
17938  break;
17939  case TabRecord::TS_DROPPING:
17940  ok = true;
17941  jam();
17942  err = PrepDropTabRef::PrepDropInProgress;
17943  break;
17944  case TabRecord::TS_CREATING:
17945  jam();
17946  ok = true;
17947  break;
17948  case TabRecord::TS_ACTIVE:
17949  ok = true;
17950  jam();
17951  break;
17952  }
17953  ndbrequire(ok);
17954  }
17955 
17956  if(err != PrepDropTabRef::OK)
17957  {
17958  jam();
17959  PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
17960  ref->senderRef = reference();
17961  ref->senderData = senderData;
17962  ref->tableId = tabPtr.i;
17963  ref->errorCode = err;
17964  sendSignal(senderRef, GSN_PREP_DROP_TAB_REF, signal,
17965  PrepDropTabRef::SignalLength, JBB);
17966  return;
17967  }
17968 
17969  tabPtr.p->tabStatus = TabRecord::TS_DROPPING;
17970  PrepDropTabConf* conf = (PrepDropTabConf*)signal->getDataPtrSend();
17971  conf->tableId = tabPtr.i;
17972  conf->senderRef = reference();
17973  conf->senderData = senderData;
17974  sendSignal(senderRef, GSN_PREP_DROP_TAB_CONF,
17975  signal, PrepDropTabConf::SignalLength, JBB);
17976 }
17977 
17978 void
17979 Dbdih::waitDropTabWritingToFile(Signal* signal, TabRecordPtr tabPtr){
17980 
17981  if (tabPtr.p->tabLcpStatus == TabRecord::TLS_WRITING_TO_FILE)
17982  {
17983  jam();
17984  signal->theData[0] = DihContinueB::WAIT_DROP_TAB_WRITING_TO_FILE;
17985  signal->theData[1] = tabPtr.i;
17986  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
17987  return;
17988  }
17989 
17990  ndbrequire(tabPtr.p->tabLcpStatus == TabRecord::TLS_COMPLETED);
17991  checkDropTabComplete(signal, tabPtr);
17992 }
17993 
17994 void
17995 Dbdih::checkDropTabComplete(Signal* signal, TabRecordPtr tabPtr)
17996 {
17997  startDeleteFile(signal, tabPtr);
17998 }
17999 
18000 void
18001 Dbdih::execNDB_TAMPER(Signal* signal)
18002 {
18003  if ((ERROR_INSERTED(7011)) &&
18004  (signal->theData[0] == 7012)) {
18005  CLEAR_ERROR_INSERT_VALUE;
18006  calculateKeepGciLab(signal, 0, 0);
18007  return;
18008  }//if
18009  SET_ERROR_INSERT_VALUE(signal->theData[0]);
18010  return;
18011 }//Dbdih::execNDB_TAMPER()
18012 
18013 void Dbdih::execBLOCK_COMMIT_ORD(Signal* signal){
18014  BlockCommitOrd* const block = (BlockCommitOrd *)&signal->theData[0];
18015 
18016  jamEntry();
18017 
18018  c_blockCommit = true;
18019  c_blockCommitNo = block->failNo;
18020 }
18021 
18022 void Dbdih::execUNBLOCK_COMMIT_ORD(Signal* signal){
18023  UnblockCommitOrd* const unblock = (UnblockCommitOrd *)&signal->theData[0];
18024  (void)unblock;
18025 
18026  jamEntry();
18027 
18028  if(c_blockCommit == true)
18029  {
18030  jam();
18031 
18032  c_blockCommit = false;
18033  for (Uint32 i = 0; i<c_diverify_queue_cnt; i++)
18034  {
18035  c_diverify_queue[i].m_empty_done = 0;
18036  emptyverificbuffer(signal, i, true);
18037  }
18038  }
18039 }
18040 
18041 void Dbdih::execSTOP_PERM_REQ(Signal* signal){
18042 
18043  jamEntry();
18044 
18045  StopPermReq* const req = (StopPermReq*)&signal->theData[0];
18046  StopPermRef* const ref = (StopPermRef*)&signal->theData[0];
18047 
18048  const Uint32 senderData = req->senderData;
18049  const BlockReference senderRef = req->senderRef;
18050  const NodeId nodeId = refToNode(senderRef);
18051 
18052  if (isMaster()) {
18056  jam();
18057  CRASH_INSERTION(7065);
18058  if (c_stopPermMaster.clientRef != 0) {
18059  jam();
18060 
18061  ref->senderData = senderData;
18062  ref->errorCode = StopPermRef::NodeShutdownInProgress;
18063  sendSignal(senderRef, GSN_STOP_PERM_REF, signal,
18064  StopPermRef::SignalLength, JBB);
18065  return;
18066  }//if
18067 
18068  if (c_nodeStartMaster.activeState) {
18069  jam();
18070  ref->senderData = senderData;
18071  ref->errorCode = StopPermRef::NodeStartInProgress;
18072  sendSignal(senderRef, GSN_STOP_PERM_REF, signal,
18073  StopPermRef::SignalLength, JBB);
18074  return;
18075  }//if
18076 
18080  c_nodeStartMaster.activeState = true;
18081  c_stopPermMaster.clientRef = senderRef;
18082 
18083  c_stopPermMaster.clientData = senderData;
18084  c_stopPermMaster.returnValue = 0;
18085  c_switchReplicas.clear();
18086 
18087  Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
18088  Callback c = { safe_cast(&Dbdih::switch_primary_stop_node), nodeId };
18089  ndbrequire(mutex.lock(c));
18090  } else {
18094  jam();
18095  CRASH_INSERTION(7066);
18096  if(c_stopPermProxy.clientRef != 0){
18097  jam();
18098  ref->senderData = senderData;
18099  ref->errorCode = StopPermRef::NodeShutdownInProgress;
18100  sendSignal(senderRef, GSN_STOP_PERM_REF, signal, 2, JBB);
18101  return;
18102  }//if
18103 
18104  c_stopPermProxy.clientRef = senderRef;
18105  c_stopPermProxy.masterRef = cmasterdihref;
18106  c_stopPermProxy.clientData = senderData;
18107 
18108  req->senderRef = reference();
18109  req->senderData = senderData;
18110  sendSignal(cmasterdihref, GSN_STOP_PERM_REQ, signal,
18111  StopPermReq::SignalLength, JBB);
18112  }//if
18113 }//Dbdih::execSTOP_PERM_REQ()
18114 
18115 void
18116 Dbdih::switch_primary_stop_node(Signal* signal, Uint32 node_id, Uint32 ret_val)
18117 {
18118  ndbrequire(ret_val == 0);
18119  signal->theData[0] = DihContinueB::SwitchReplica;
18120  signal->theData[1] = node_id;
18121  signal->theData[2] = 0; // table id
18122  signal->theData[3] = 0; // fragment id
18123  sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
18124 }
18125 
18126 void Dbdih::execSTOP_PERM_REF(Signal* signal)
18127 {
18128  jamEntry();
18129  ndbrequire(c_stopPermProxy.clientRef != 0);
18130  ndbrequire(c_stopPermProxy.masterRef == signal->senderBlockRef());
18131  sendSignal(c_stopPermProxy.clientRef, GSN_STOP_PERM_REF, signal, 2, JBB);
18132  c_stopPermProxy.clientRef = 0;
18133 }//Dbdih::execSTOP_PERM_REF()
18134 
18135 void Dbdih::execSTOP_PERM_CONF(Signal* signal)
18136 {
18137  jamEntry();
18138  ndbrequire(c_stopPermProxy.clientRef != 0);
18139  ndbrequire(c_stopPermProxy.masterRef == signal->senderBlockRef());
18140  sendSignal(c_stopPermProxy.clientRef, GSN_STOP_PERM_CONF, signal, 1, JBB);
18141  c_stopPermProxy.clientRef = 0;
18142 }//Dbdih::execSTOP_PERM_CONF()
18143 
18144 void Dbdih::execDIH_SWITCH_REPLICA_REQ(Signal* signal)
18145 {
18146  jamEntry();
18147  DihSwitchReplicaReq* const req = (DihSwitchReplicaReq*)&signal->theData[0];
18148  const Uint32 tableId = req->tableId;
18149  const Uint32 fragNo = req->fragNo;
18150  const BlockReference senderRef = req->senderRef;
18151 
18152  CRASH_INSERTION(7067);
18153  TabRecordPtr tabPtr;
18154  tabPtr.i = tableId;
18155  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
18156 
18157  ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
18158  if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
18159  jam();
18160  sendSignal(reference(), GSN_DIH_SWITCH_REPLICA_REQ, signal,
18161  DihSwitchReplicaReq::SignalLength, JBB);
18162  return;
18163  }//if
18164  FragmentstorePtr fragPtr;
18165  getFragstore(tabPtr.p, fragNo, fragPtr);
18166 
18170  Uint32 oldOrder[MAX_REPLICAS];
18171  const Uint32 noOfReplicas = extractNodeInfo(fragPtr.p, oldOrder);
18172 
18173  if (noOfReplicas < req->noOfReplicas) {
18174  jam();
18175  //---------------------------------------------------------------------
18176  // A crash occurred in the middle of our switch handling.
18177  //---------------------------------------------------------------------
18178  DihSwitchReplicaRef* const ref = (DihSwitchReplicaRef*)&signal->theData[0];
18179  ref->senderNode = cownNodeId;
18180  ref->errorCode = StopPermRef::NF_CausedAbortOfStopProcedure;
18181  sendSignal(senderRef, GSN_DIH_SWITCH_REPLICA_REF, signal,
18182  DihSwitchReplicaRef::SignalLength, JBB);
18183  }//if
18184 
18185  DIH_TAB_WRITE_LOCK(tabPtr.p);
18186  for (Uint32 i = 0; i < noOfReplicas; i++) {
18187  jam();
18188  ndbrequire(i < MAX_REPLICAS);
18189  fragPtr.p->activeNodes[i] = req->newNodeOrder[i];
18190  }//for
18191  DIH_TAB_WRITE_UNLOCK(tabPtr.p);
18192 
18196  DihSwitchReplicaConf* const conf = (DihSwitchReplicaConf*)&signal->theData[0];
18197  conf->senderNode = cownNodeId;
18198  sendSignal(senderRef, GSN_DIH_SWITCH_REPLICA_CONF, signal,
18199  DihSwitchReplicaConf::SignalLength, JBB);
18200 }//Dbdih::execDIH_SWITCH_REPLICA_REQ()
18201 
18202 void Dbdih::execDIH_SWITCH_REPLICA_CONF(Signal* signal)
18203 {
18204  jamEntry();
18208  CRASH_INSERTION(7068);
18209  DihSwitchReplicaConf* const conf = (DihSwitchReplicaConf*)&signal->theData[0];
18210  switchReplicaReply(signal, conf->senderNode);
18211 }//Dbdih::execDIH_SWITCH_REPLICA_CONF()
18212 
18213 void Dbdih::execDIH_SWITCH_REPLICA_REF(Signal* signal)
18214 {
18215  jamEntry();
18216  DihSwitchReplicaRef* const ref = (DihSwitchReplicaRef*)&signal->theData[0];
18217  if(c_stopPermMaster.returnValue == 0){
18218  jam();
18219  c_stopPermMaster.returnValue = ref->errorCode;
18220  }//if
18221  switchReplicaReply(signal, ref->senderNode);
18222 }//Dbdih::execDIH_SWITCH_REPLICA_REF()
18223 
18224 void Dbdih::switchReplicaReply(Signal* signal,
18225  NodeId nodeId){
18226  jam();
18227  receiveLoopMacro(DIH_SWITCH_REPLICA_REQ, nodeId);
18228  //------------------------------------------------------
18229  // We have received all responses from the nodes. Thus
18230  // we have completed switching replica roles. Continue
18231  // with the next fragment.
18232  //------------------------------------------------------
18233  if(c_stopPermMaster.returnValue != 0){
18234  jam();
18235  c_switchReplicas.tableId = ctabFileSize + 1;
18236  }//if
18237  c_switchReplicas.fragNo++;
18238 
18239  signal->theData[0] = DihContinueB::SwitchReplica;
18240  signal->theData[1] = c_switchReplicas.nodeId;
18241  signal->theData[2] = c_switchReplicas.tableId;
18242  signal->theData[3] = c_switchReplicas.fragNo;
18243  sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
18244 }//Dbdih::switchReplicaReply()
18245 
18246 void
18247 Dbdih::switchReplica(Signal* signal,
18248  Uint32 nodeId,
18249  Uint32 tableId,
18250  Uint32 fragNo){
18251  jam();
18252  DihSwitchReplicaReq* const req = (DihSwitchReplicaReq*)&signal->theData[0];
18253 
18254  const Uint32 RT_BREAK = 64;
18255 
18256  for (Uint32 i = 0; i < RT_BREAK; i++) {
18257  jam();
18258  if (tableId >= ctabFileSize) {
18259  jam();
18260  StopPermConf* const conf = (StopPermConf*)&signal->theData[0];
18261  StopPermRef* const ref = (StopPermRef*)&signal->theData[0];
18265  if(c_stopPermMaster.returnValue == 0) {
18266  jam();
18267  conf->senderData = c_stopPermMaster.clientData;
18268  sendSignal(c_stopPermMaster.clientRef, GSN_STOP_PERM_CONF,
18269  signal, 1, JBB);
18270  } else {
18271  jam();
18272  ref->senderData = c_stopPermMaster.clientData;
18273  ref->errorCode = c_stopPermMaster.returnValue;
18274  sendSignal(c_stopPermMaster.clientRef, GSN_STOP_PERM_REF, signal, 2,JBB);
18275  }//if
18276 
18280  c_nodeStartMaster.activeState = false;
18281  c_stopPermMaster.clientRef = 0;
18282  c_stopPermMaster.clientData = 0;
18283  c_stopPermMaster.returnValue = 0;
18284  Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
18285  mutex.unlock(); // ignore result
18286  return;
18287  }//if
18288 
18289  TabRecordPtr tabPtr;
18290  tabPtr.i = tableId;
18291  ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
18292 
18293  if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE) {
18294  jam();
18295  tableId++;
18296  fragNo = 0;
18297  continue;
18298  }//if
18299  if (fragNo >= tabPtr.p->totalfragments) {
18300  jam();
18301  tableId++;
18302  fragNo = 0;
18303  continue;
18304  }//if
18305  FragmentstorePtr fragPtr;
18306  getFragstore(tabPtr.p, fragNo, fragPtr);
18307 
18308  Uint32 oldOrder[MAX_REPLICAS];
18309  const Uint32 noOfReplicas = extractNodeInfo(fragPtr.p, oldOrder);
18310 
18311  if(oldOrder[0] != nodeId) {
18312  jam();
18313  fragNo++;
18314  continue;
18315  }//if
18316  req->tableId = tableId;
18317  req->fragNo = fragNo;
18318  req->noOfReplicas = noOfReplicas;
18319  for (Uint32 i = 0; i < (noOfReplicas - 1); i++) {
18320  req->newNodeOrder[i] = oldOrder[i+1];
18321  }//for
18322  req->newNodeOrder[noOfReplicas-1] = nodeId;
18323  req->senderRef = reference();
18324 
18328  c_switchReplicas.tableId = tableId;
18329  c_switchReplicas.fragNo = fragNo;
18330  c_switchReplicas.nodeId = nodeId;
18331 
18332  sendLoopMacro(DIH_SWITCH_REPLICA_REQ, sendDIH_SWITCH_REPLICA_REQ, RNIL);
18333  return;
18334  }//for
18335 
18336  signal->theData[0] = DihContinueB::SwitchReplica;
18337  signal->theData[1] = nodeId;
18338  signal->theData[2] = tableId;
18339  signal->theData[3] = fragNo;
18340  sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
18341 }//Dbdih::switchReplica()
18342 
18343 void Dbdih::execSTOP_ME_REQ(Signal* signal)
18344 {
18345  jamEntry();
18346  StopMeReq* const req = (StopMeReq*)&signal->theData[0];
18347  const BlockReference senderRef = req->senderRef;
18348  const Uint32 senderData = req->senderData;
18349  const Uint32 nodeId = refToNode(senderRef);
18350  {
18354  NodeRecordPtr nodePtr;
18355  nodePtr.i = nodeId;
18356  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
18357  nodePtr.p->useInTransactions = false;
18358  }
18359  if (nodeId != getOwnNodeId()) {
18360  jam();
18361  StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
18362  stopMeConf->senderData = senderData;
18363  stopMeConf->senderRef = reference();
18364  sendSignal(senderRef, GSN_STOP_ME_CONF, signal,
18365  StopMeConf::SignalLength, JBB);
18366  return;
18367  }//if
18368 
18372  jam();
18373  ndbrequire(c_stopMe.clientRef == 0);
18374 
18375  c_stopMe.clientData = senderData;
18376  c_stopMe.clientRef = senderRef;
18377 
18378  req->senderData = senderData;
18379  req->senderRef = reference();
18380 
18381  sendLoopMacro(STOP_ME_REQ, sendSTOP_ME_REQ, RNIL);
18382 
18386  StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
18387  stopMeConf->senderData = senderData;
18388  stopMeConf->senderRef = reference();
18389  sendSignal(reference(), GSN_STOP_ME_CONF, signal,
18390  StopMeConf::SignalLength, JBB);
18391 }//Dbdih::execSTOP_ME_REQ()
18392 
18393 void Dbdih::execSTOP_ME_REF(Signal* signal)
18394 {
18395  ndbrequire(false);
18396 }
18397 
18398 void Dbdih::execSTOP_ME_CONF(Signal* signal)
18399 {
18400  jamEntry();
18401  StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
18402 
18403  const Uint32 senderRef = stopMeConf->senderRef;
18404  const Uint32 senderData = stopMeConf->senderData;
18405  const Uint32 nodeId = refToNode(senderRef);
18406 
18407  ndbrequire(c_stopMe.clientRef != 0);
18408  ndbrequire(c_stopMe.clientData == senderData);
18409 
18410  receiveLoopMacro(STOP_ME_REQ, nodeId);
18411  //---------------------------------------------------------
18412  // All STOP_ME_REQ have been received. We will send the
18413  // confirmation back to the requesting block.
18414  //---------------------------------------------------------
18415 
18416  stopMeConf->senderRef = reference();
18417  stopMeConf->senderData = c_stopMe.clientData;
18418  sendSignal(c_stopMe.clientRef, GSN_STOP_ME_CONF, signal,
18419  StopMeConf::SignalLength, JBB);
18420  c_stopMe.clientRef = 0;
18421 }//Dbdih::execSTOP_ME_CONF()
18422 
18423 void Dbdih::execWAIT_GCP_REQ(Signal* signal)
18424 {
18425  jamEntry();
18426  WaitGCPReq* const req = (WaitGCPReq*)&signal->theData[0];
18427  WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
18428  WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
18429  const Uint32 senderData = req->senderData;
18430  const BlockReference senderRef = req->senderRef;
18431  const Uint32 requestType = req->requestType;
18432  Uint32 errorCode = 0;
18433 
18434  if(requestType == WaitGCPReq::CurrentGCI)
18435  {
18436  jam();
18437  conf->senderData = senderData;
18438  conf->gci_hi = Uint32(m_micro_gcp.m_current_gci >> 32);
18439  conf->gci_lo = Uint32(m_micro_gcp.m_current_gci);
18440  conf->blockStatus = cgcpOrderBlocked;
18441  sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal,
18442  WaitGCPConf::SignalLength, JBB);
18443  return;
18444  }//if
18445 
18446  if(requestType == WaitGCPReq::RestartGCI)
18447  {
18448  jam();
18449  conf->senderData = senderData;
18450  conf->gci_hi = Uint32(crestartGci);
18451  conf->gci_lo = 0;
18452  conf->blockStatus = cgcpOrderBlocked;
18453  sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal,
18454  WaitGCPConf::SignalLength, JBB);
18455  return;
18456  }//if
18457 
18458  if (requestType == WaitGCPReq::BlockStartGcp)
18459  {
18460  jam();
18461  conf->senderData = senderData;
18462  conf->gci_hi = Uint32(m_micro_gcp.m_current_gci >> 32);
18463  conf->gci_lo = Uint32(m_micro_gcp.m_current_gci);
18464  conf->blockStatus = cgcpOrderBlocked;
18465  sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal,
18466  WaitGCPConf::SignalLength, JBB);
18467  cgcpOrderBlocked = 1;
18468  return;
18469  }
18470 
18471  if (requestType == WaitGCPReq::UnblockStartGcp)
18472  {
18473  jam();
18474  conf->senderData = senderData;
18475  conf->gci_hi = Uint32(m_micro_gcp.m_current_gci >> 32);
18476  conf->gci_lo = Uint32(m_micro_gcp.m_current_gci);
18477  conf->blockStatus = cgcpOrderBlocked;
18478  sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal,
18479  WaitGCPConf::SignalLength, JBB);
18480  cgcpOrderBlocked = 0;
18481  return;
18482  }
18483 
18484  if(isMaster())
18485  {
18490  if (!isActiveMaster())
18491  {
18492  ndbassert(cmasterState == MASTER_TAKE_OVER_GCP);
18493  errorCode = WaitGCPRef::NF_MasterTakeOverInProgress;
18494  goto error;
18495  }
18496 
18497  if((requestType == WaitGCPReq::CompleteIfRunning) &&
18498  (m_gcp_save.m_master.m_state == GcpSave::GCP_SAVE_IDLE))
18499  {
18500  jam();
18501  conf->senderData = senderData;
18502  conf->gci_hi = Uint32(m_micro_gcp.m_old_gci >> 32);
18503  conf->gci_lo = Uint32(m_micro_gcp.m_old_gci);
18504  conf->blockStatus = cgcpOrderBlocked;
18505  sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal,
18506  WaitGCPConf::SignalLength, JBB);
18507  return;
18508  }//if
18509 
18510  WaitGCPMasterPtr ptr;
18511  WaitGCPList * list = &c_waitGCPMasterList;
18512  if (requestType == WaitGCPReq::WaitEpoch)
18513  {
18514  jam();
18515  list = &c_waitEpochMasterList;
18516  }
18517 
18518  if(list->seize(ptr) == false)
18519  {
18520  jam();
18521  errorCode = WaitGCPRef::NoWaitGCPRecords;
18522  goto error;
18523  return;
18524  }
18525 
18526  ptr.p->clientRef = senderRef;
18527  ptr.p->clientData = senderData;
18528 
18529  if((requestType == WaitGCPReq::CompleteForceStart) &&
18530  (m_gcp_save.m_master.m_state == GcpSave::GCP_SAVE_IDLE))
18531  {
18532  jam();
18533  m_micro_gcp.m_master.m_start_time = m_gcp_save.m_master.m_start_time = 0;
18534  }//if
18535  return;
18536  }
18537  else
18538  {
18542  jam();
18543  WaitGCPProxyPtr ptr;
18544  if (c_waitGCPProxyList.seize(ptr) == false)
18545  {
18546  jam();
18547  errorCode = WaitGCPRef::NoWaitGCPRecords;
18548  goto error;
18549  }//if
18550  ptr.p->clientRef = senderRef;
18551  ptr.p->clientData = senderData;
18552  ptr.p->masterRef = cmasterdihref;
18553 
18554  req->senderData = ptr.i;
18555  req->senderRef = reference();
18556  req->requestType = requestType;
18557 
18558  sendSignal(cmasterdihref, GSN_WAIT_GCP_REQ, signal,
18559  WaitGCPReq::SignalLength, JBB);
18560  return;
18561  }//if
18562 
18563 error:
18564  ref->senderData = senderData;
18565  ref->errorCode = errorCode;
18566  sendSignal(senderRef, GSN_WAIT_GCP_REF, signal,
18567  WaitGCPRef::SignalLength, JBB);
18568 }//Dbdih::execWAIT_GCP_REQ()
18569 
18570 void Dbdih::execWAIT_GCP_REF(Signal* signal)
18571 {
18572  jamEntry();
18573  ndbrequire(!isMaster());
18574  WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
18575 
18576  const Uint32 proxyPtr = ref->senderData;
18577  const Uint32 errorCode = ref->errorCode;
18578 
18579  WaitGCPProxyPtr ptr;
18580  ptr.i = proxyPtr;
18581  c_waitGCPProxyList.getPtr(ptr);
18582 
18583  ref->senderData = ptr.p->clientData;
18584  ref->errorCode = errorCode;
18585  sendSignal(ptr.p->clientRef, GSN_WAIT_GCP_REF, signal,
18586  WaitGCPRef::SignalLength, JBB);
18587 
18588  c_waitGCPProxyList.release(ptr);
18589 }//Dbdih::execWAIT_GCP_REF()
18590 
18591 void Dbdih::execWAIT_GCP_CONF(Signal* signal)
18592 {
18593  jamEntry();
18594  ndbrequire(!isMaster());
18595  WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
18596  const Uint32 proxyPtr = conf->senderData;
18597  const Uint32 gci_hi = conf->gci_hi;
18598  const Uint32 gci_lo = conf->gci_lo;
18599  WaitGCPProxyPtr ptr;
18600 
18601  ptr.i = proxyPtr;
18602  c_waitGCPProxyList.getPtr(ptr);
18603 
18604  conf->senderData = ptr.p->clientData;
18605  conf->gci_hi = gci_hi;
18606  conf->gci_lo = gci_lo;
18607  conf->blockStatus = cgcpOrderBlocked;
18608  sendSignal(ptr.p->clientRef, GSN_WAIT_GCP_CONF, signal,
18609  WaitGCPConf::SignalLength, JBB);
18610 
18611  c_waitGCPProxyList.release(ptr);
18612 }//Dbdih::execWAIT_GCP_CONF()
18613 
18614 void Dbdih::checkWaitGCPProxy(Signal* signal, NodeId failedNodeId)
18615 {
18616  jam();
18617  WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
18618  ref->errorCode = WaitGCPRef::NF_CausedAbortOfProcedure;
18619 
18620  WaitGCPProxyPtr ptr;
18621  c_waitGCPProxyList.first(ptr);
18622  while(ptr.i != RNIL) {
18623  jam();
18624  const Uint32 i = ptr.i;
18625  const Uint32 clientData = ptr.p->clientData;
18626  const BlockReference clientRef = ptr.p->clientRef;
18627  const BlockReference masterRef = ptr.p->masterRef;
18628 
18629  c_waitGCPProxyList.next(ptr);
18630  if(refToNode(masterRef) == failedNodeId) {
18631  jam();
18632  c_waitGCPProxyList.release(i);
18633  ref->senderData = clientData;
18634  sendSignal(clientRef, GSN_WAIT_GCP_REF, signal,
18635  WaitGCPRef::SignalLength, JBB);
18636  }//if
18637  }//while
18638 }//Dbdih::checkWaitGCPProxy()
18639 
18640 void Dbdih::checkWaitGCPMaster(Signal* signal, NodeId failedNodeId)
18641 {
18642  jam();
18643  WaitGCPMasterPtr ptr;
18644  c_waitGCPMasterList.first(ptr);
18645 
18646  while (ptr.i != RNIL) {
18647  jam();
18648  const Uint32 i = ptr.i;
18649  const NodeId nodeId = refToNode(ptr.p->clientRef);
18650 
18651  c_waitGCPMasterList.next(ptr);
18652  if (nodeId == failedNodeId) {
18653  jam();
18654  c_waitGCPMasterList.release(i);
18655  }//if
18656  }//while
18657 }//Dbdih::checkWaitGCPMaster()
18658 
18659 void Dbdih::emptyWaitGCPMasterQueue(Signal* signal,
18660  Uint64 gci,
18661  WaitGCPList & list)
18662 {
18663  jam();
18664  WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
18665  conf->gci_hi = Uint32(gci >> 32);
18666  conf->gci_lo = Uint32(gci);
18667 
18668  WaitGCPMasterPtr ptr;
18669  list.first(ptr);
18670  while(ptr.i != RNIL) {
18671  jam();
18672  const Uint32 i = ptr.i;
18673  const Uint32 clientData = ptr.p->clientData;
18674  const BlockReference clientRef = ptr.p->clientRef;
18675 
18676  c_waitGCPMasterList.next(ptr);
18677  conf->senderData = clientData;
18678  conf->blockStatus = cgcpOrderBlocked;
18679  sendSignal(clientRef, GSN_WAIT_GCP_CONF, signal,
18680  WaitGCPConf::SignalLength, JBB);
18681 
18682  list.release(i);
18683  }//while
18684 }//Dbdih::emptyWaitGCPMasterQueue()
18685 
18686 void Dbdih::setNodeStatus(Uint32 nodeId, NodeRecord::NodeStatus newStatus)
18687 {
18688  NodeRecordPtr nodePtr;
18689  nodePtr.i = nodeId;
18690  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
18691  nodePtr.p->nodeStatus = newStatus;
18692 }//Dbdih::setNodeStatus()
18693 
18694 Dbdih::NodeRecord::NodeStatus Dbdih::getNodeStatus(Uint32 nodeId)
18695 {
18696  NodeRecordPtr nodePtr;
18697  nodePtr.i = nodeId;
18698  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
18699  return nodePtr.p->nodeStatus;
18700 }//Dbdih::getNodeStatus()
18701 
18703 Dbdih::getNodeActiveStatus(Uint32 nodeId)
18704 {
18705  NodeRecordPtr nodePtr;
18706  nodePtr.i = nodeId;
18707  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
18708  return nodePtr.p->activeStatus;
18709 }//Dbdih::getNodeActiveStatus()
18710 
18711 
18712 void
18713 Dbdih::setNodeActiveStatus(Uint32 nodeId, Sysfile::ActiveStatus newStatus)
18714 {
18715  NodeRecordPtr nodePtr;
18716  nodePtr.i = nodeId;
18717  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
18718  nodePtr.p->activeStatus = newStatus;
18719 }//Dbdih::setNodeActiveStatus()
18720 
18721 void Dbdih::setAllowNodeStart(Uint32 nodeId, bool newState)
18722 {
18723  NodeRecordPtr nodePtr;
18724  nodePtr.i = nodeId;
18725  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
18726  nodePtr.p->allowNodeStart = newState;
18727 }//Dbdih::setAllowNodeStart()
18728 
18729 bool Dbdih::getAllowNodeStart(Uint32 nodeId)
18730 {
18731  NodeRecordPtr nodePtr;
18732  nodePtr.i = nodeId;
18733  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
18734  return nodePtr.p->allowNodeStart;
18735 }//Dbdih::getAllowNodeStart()
18736 
18737 Uint32
18738 Dbdih::getNodeGroup(Uint32 nodeId) const
18739 {
18740  NodeRecordPtr nodePtr;
18741  nodePtr.i = nodeId;
18742  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
18743  return nodePtr.p->nodeGroup;
18744 }
18745 
18746 bool Dbdih::checkNodeAlive(Uint32 nodeId)
18747 {
18748  NodeRecordPtr nodePtr;
18749  nodePtr.i = nodeId;
18750  ndbrequire(nodeId > 0);
18751  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
18752  if (nodePtr.p->nodeStatus != NodeRecord::ALIVE) {
18753  return false;
18754  } else {
18755  return true;
18756  }//if
18757 }//Dbdih::checkNodeAlive()
18758 
18759 bool Dbdih::isMaster()
18760 {
18761  return (reference() == cmasterdihref);
18762 }//Dbdih::isMaster()
18763 
18764 bool Dbdih::isActiveMaster()
18765 {
18766  return ((reference() == cmasterdihref) && (cmasterState == MASTER_ACTIVE));
18767 }//Dbdih::isActiveMaster()
18768 
18769 Dbdih::NodeRecord::NodeRecord(){
18770  m_nodefailSteps.clear();
18771 
18772  activeStatus = Sysfile::NS_NotDefined;
18773  recNODE_FAILREP = ZFALSE;
18774  dbtcFailCompleted = ZTRUE;
18775  dbdictFailCompleted = ZTRUE;
18776  dbdihFailCompleted = ZTRUE;
18777  dblqhFailCompleted = ZTRUE;
18778  noOfStartedChkpt = 0;
18779  noOfQueuedChkpt = 0;
18780  lcpStateAtTakeOver = (MasterLCPConf::State)255;
18781 
18782  activeTabptr = RNIL;
18783  nodeStatus = NodeRecord::NOT_IN_CLUSTER;
18784  useInTransactions = false;
18785  copyCompleted = false;
18786  allowNodeStart = true;
18787 }
18788 
18789 // DICT lock slave
18790 
18791 void
18792 Dbdih::sendDictLockReq(Signal* signal, Uint32 lockType, Callback c)
18793 {
18794  DictLockReq* req = (DictLockReq*)&signal->theData[0];
18795  DictLockSlavePtr lockPtr;
18796 
18797  c_dictLockSlavePool.seize(lockPtr);
18798  ndbrequire(lockPtr.i != RNIL);
18799 
18800  req->userPtr = lockPtr.i;
18801  req->lockType = lockType;
18802  req->userRef = reference();
18803 
18804  lockPtr.p->lockPtr = RNIL;
18805  lockPtr.p->lockType = lockType;
18806  lockPtr.p->locked = false;
18807  lockPtr.p->callback = c;
18808 
18809  // handle rolling upgrade
18810  {
18811  Uint32 masterVersion = getNodeInfo(cmasterNodeId).m_version;
18812 
18813  const unsigned int get_major = getMajor(masterVersion);
18814  const unsigned int get_minor = getMinor(masterVersion);
18815  const unsigned int get_build = getBuild(masterVersion);
18816  ndbrequire(get_major >= 4);
18817 
18818  if (masterVersion < NDBD_DICT_LOCK_VERSION_5 ||
18819  (masterVersion < NDBD_DICT_LOCK_VERSION_5_1 &&
18820  get_major == 5 && get_minor == 1) ||
18821  ERROR_INSERTED(7176)) {
18822  jam();
18823 
18824  infoEvent("DIH: detect upgrade: master node %u old version %u.%u.%u",
18825  (unsigned int)cmasterNodeId, get_major, get_minor, get_build);
18826 
18827  DictLockConf* conf = (DictLockConf*)&signal->theData[0];
18828  conf->userPtr = lockPtr.i;
18829  conf->lockType = lockType;
18830  conf->lockPtr = ZNIL;
18831 
18832  sendSignal(reference(), GSN_DICT_LOCK_CONF, signal,
18833  DictLockConf::SignalLength, JBB);
18834  return;
18835  }
18836  }
18837 
18838  BlockReference dictMasterRef = calcDictBlockRef(cmasterNodeId);
18839  sendSignal(dictMasterRef, GSN_DICT_LOCK_REQ, signal,
18840  DictLockReq::SignalLength, JBB);
18841 }
18842 
18843 void
18844 Dbdih::execDICT_LOCK_CONF(Signal* signal)
18845 {
18846  jamEntry();
18847  recvDictLockConf(signal);
18848 }
18849 
18850 void
18851 Dbdih::execDICT_LOCK_REF(Signal* signal)
18852 {
18853  jamEntry();
18854  ndbrequire(false);
18855 }
18856 
18857 void
18858 Dbdih::recvDictLockConf(Signal* signal)
18859 {
18860  const DictLockConf* conf = (const DictLockConf*)&signal->theData[0];
18861 
18862  DictLockSlavePtr lockPtr;
18863  c_dictLockSlavePool.getPtr(lockPtr, conf->userPtr);
18864 
18865  lockPtr.p->lockPtr = conf->lockPtr;
18866  ndbrequire(lockPtr.p->lockType == conf->lockType);
18867  ndbrequire(lockPtr.p->locked == false);
18868  lockPtr.p->locked = true;
18869 
18870  lockPtr.p->callback.m_callbackData = lockPtr.i;
18871  execute(signal, lockPtr.p->callback, 0);
18872 }
18873 
18874 void
18875 Dbdih::sendDictUnlockOrd(Signal* signal, Uint32 lockSlavePtrI)
18876 {
18877  DictUnlockOrd* ord = (DictUnlockOrd*)&signal->theData[0];
18878 
18879  DictLockSlavePtr lockPtr;
18880  c_dictLockSlavePool.getPtr(lockPtr, lockSlavePtrI);
18881 
18882  ord->lockPtr = lockPtr.p->lockPtr;
18883  ord->lockType = lockPtr.p->lockType;
18884  ord->senderData = lockPtr.i;
18885  ord->senderRef = reference();
18886 
18887  c_dictLockSlavePool.release(lockPtr);
18888 
18889  // handle rolling upgrade
18890  {
18891  Uint32 masterVersion = getNodeInfo(cmasterNodeId).m_version;
18892 
18893  const unsigned int get_major = getMajor(masterVersion);
18894  const unsigned int get_minor = getMinor(masterVersion);
18895  ndbrequire(get_major >= 4);
18896 
18897  if (masterVersion < NDBD_DICT_LOCK_VERSION_5 ||
18898  (masterVersion < NDBD_DICT_LOCK_VERSION_5_1 &&
18899  get_major == 5 && get_minor == 1) ||
18900  ERROR_INSERTED(7176)) {
18901  return;
18902  }
18903  }
18904 
18905  Uint32 len = DictUnlockOrd::SignalLength;
18906  if (unlikely(getNodeInfo(cmasterNodeId).m_version < NDB_MAKE_VERSION(6,3,0)))
18907  {
18908  jam();
18909  len = 2;
18910  }
18911 
18912  BlockReference dictMasterRef = calcDictBlockRef(cmasterNodeId);
18913  sendSignal(dictMasterRef, GSN_DICT_UNLOCK_ORD, signal, len, JBB);
18914 }
18915 
18916 #ifdef ERROR_INSERT
18917 void
18918 Dbdih::sendToRandomNodes(const char * msg,
18919  Signal* signal,
18920  SignalCounter* counter,
18921  SendFunction fun,
18922  Uint32 extra,
18923  Uint32 block,
18924  Uint32 gsn,
18925  Uint32 len,
18926  JobBufferLevel level)
18927 {
18928 
18929  if (counter)
18930  counter->clearWaitingFor();
18931 
18932  Vector<Uint32> nodes;
18933  NodeRecordPtr nodePtr;
18934  nodePtr.i = cfirstAliveNode;
18935  do {
18936  jam();
18937  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
18938  if (nodePtr.i != getOwnNodeId())
18939  {
18940  nodes.push_back(nodePtr.i);
18941  }
18942  nodePtr.i = nodePtr.p->nextNode;
18943  } while (nodePtr.i != RNIL);
18944 
18945 
18946  NdbNodeBitmask masked;
18947  Uint32 cnt = nodes.size();
18948  if (cnt <= 1)
18949  {
18950  goto do_send;
18951  }
18952 
18953  {
18954  Uint32 remove = (rand() % cnt);
18955  if (remove == 0)
18956  remove = 1;
18957 
18958  for (Uint32 i = 0; i<remove; i++)
18959  {
18960  Uint32 rand_node = rand() % nodes.size();
18961  masked.set(nodes[rand_node]);
18962  nodes.erase(rand_node);
18963  }
18964  }
18965 
18966 do_send:
18967  char bufpos = 0;
18968  char buf[256];
18969 
18970  nodePtr.i = cfirstAliveNode;
18971  do {
18972  jam();
18973  ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
18974  if (counter)
18975  counter->setWaitingFor(nodePtr.i);
18976  if (!masked.get(nodePtr.i))
18977  {
18978  if (fun)
18979  {
18980  (this->*fun)(signal, nodePtr.i, extra);
18981  }
18982  else
18983  {
18984  Uint32 ref = numberToRef(block, nodePtr.i);
18985  sendSignal(ref, gsn, signal, len, level);
18986  }
18987  BaseString::snprintf(buf+bufpos, sizeof(buf)-bufpos, "%u ", nodePtr.i);
18988  }
18989  else
18990  {
18991  BaseString::snprintf(buf+bufpos, sizeof(buf)-bufpos, "[%u] ", nodePtr.i);
18992  }
18993  bufpos = strlen(buf);
18994  nodePtr.i = nodePtr.p->nextNode;
18995  } while (nodePtr.i != RNIL);
18996  infoEvent("%s %s", msg, buf);
18997 }
18998 
18999 #endif
19000 
19001 // MT LQH
19002 
19003 Uint32
19004 Dbdih::dihGetInstanceKey(Uint32 tabId, Uint32 fragId)
19005 {
19006  TabRecordPtr tTabPtr;
19007  tTabPtr.i = tabId;
19008  ptrCheckGuard(tTabPtr, ctabFileSize, tabRecord);
19009  FragmentstorePtr tFragPtr;
19010  getFragstore(tTabPtr.p, fragId, tFragPtr);
19011  Uint32 instanceKey = dihGetInstanceKey(tFragPtr);
19012  return instanceKey;
19013 }
19014 
19018 void
19019 Dbdih::execCREATE_NODEGROUP_IMPL_REQ(Signal* signal)
19020 {
19021  jamEntry();
19022  CreateNodegroupImplReq reqCopy = *(CreateNodegroupImplReq*)signal->getDataPtr();
19023  CreateNodegroupImplReq *req = &reqCopy;
19024 
19025  Uint32 err = 0;
19026  Uint32 rt = req->requestType;
19027  Uint64 gci = 0;
19028  switch(rt){
19029  case CreateNodegroupImplReq::RT_ABORT:
19030  jam(); // do nothing
19031  break;
19032  case CreateNodegroupImplReq::RT_PARSE:
19033  case CreateNodegroupImplReq::RT_PREPARE:
19034  case CreateNodegroupImplReq::RT_COMMIT:
19035  {
19036  Uint32 cnt = 0;
19037  for (Uint32 i = 0; i<NDB_ARRAY_SIZE(req->nodes) && req->nodes[i] ; i++)
19038  {
19039  cnt++;
19040  if (getNodeActiveStatus(req->nodes[i]) != Sysfile::NS_Configured)
19041  {
19042  jam();
19043  err = CreateNodegroupRef::NodeAlreadyInNodegroup;
19044  goto error;
19045  }
19046  }
19047 
19048  if (cnt != cnoReplicas)
19049  {
19050  jam();
19051  err = CreateNodegroupRef::InvalidNoOfNodesInNodegroup;
19052  goto error;
19053  }
19054 
19055  Uint32 ng = req->nodegroupId;
19056  NdbNodeBitmask tmp;
19057  tmp.set();
19058  for (Uint32 i = 0; i<cnoOfNodeGroups; i++)
19059  {
19060  tmp.clear(c_node_groups[i]);
19061  }
19062 
19063  if (ng == RNIL && rt == CreateNodegroupImplReq::RT_PARSE)
19064  {
19065  jam();
19066  ng = tmp.find(0);
19067  }
19068 
19069  if (ng > MAX_NDB_NODES)
19070  {
19071  jam();
19072  err = CreateNodegroupRef::InvalidNodegroupId;
19073  goto error;
19074  }
19075 
19076  if (tmp.get(ng) == false)
19077  {
19078  jam();
19079  err = CreateNodegroupRef::NodegroupInUse;
19080  goto error;
19081  }
19082 
19083  if (rt == CreateNodegroupImplReq::RT_PARSE || rt == CreateNodegroupImplReq::RT_PREPARE)
19084  {
19088  bool alive = false;
19089  for (Uint32 i = 0; i<cnoReplicas; i++)
19090  {
19091  jam();
19092  Uint32 nodeId = req->nodes[i];
19093  if (getNodeStatus(nodeId) == NodeRecord::ALIVE)
19094  {
19095  jam();
19096  alive = true;
19097  break;
19098  }
19099  }
19100 
19101  jam();
19102  if (alive == false)
19103  {
19104  jam();
19105  err = CreateNodegroupRef::NoNodeAlive;
19106  goto error;
19107  }
19108  }
19109 
19110  if (rt == CreateNodegroupImplReq::RT_PARSE)
19111  {
19112  jam();
19113  signal->theData[0] = 0;
19114  signal->theData[1] = ng;
19115  return;
19116  }
19117 
19118  if (rt == CreateNodegroupImplReq::RT_PREPARE)
19119  {
19120  jam(); // do nothing
19121  break;
19122  }
19123 
19124  ndbrequire(rt == CreateNodegroupImplReq::RT_COMMIT);
19125  for (Uint32 i = 0; i<cnoReplicas; i++)
19126  {
19127  Uint32 nodeId = req->nodes[i];
19128  Sysfile::setNodeGroup(nodeId, SYSFILE->nodeGroups, req->nodegroupId);
19129  if (getNodeStatus(nodeId) == NodeRecord::ALIVE)
19130  {
19131  jam();
19132  Sysfile::setNodeStatus(nodeId, SYSFILE->nodeStatus, Sysfile::NS_Active);
19133  }
19134  else
19135  {
19136  jam();
19137  Sysfile::setNodeStatus(nodeId, SYSFILE->nodeStatus, Sysfile::NS_ActiveMissed_1);
19138  }
19139  setNodeActiveStatus();
19140  setNodeGroups();
19141  }
19142  break;
19143  }
19144  case CreateNodegroupImplReq::RT_COMPLETE:
19145  jam();
19146  gci = m_micro_gcp.m_current_gci;
19147  break;
19148  }
19149 
19150  {
19151  CreateNodegroupImplConf* conf = (CreateNodegroupImplConf*)signal->getDataPtrSend();
19152  conf->senderRef = reference();
19153  conf->senderData = req->senderData;
19154  conf->gci_hi = Uint32(gci >> 32);
19155  conf->gci_lo = Uint32(gci);
19156  sendSignal(req->senderRef, GSN_CREATE_NODEGROUP_IMPL_CONF, signal,
19157  CreateNodegroupImplConf::SignalLength, JBB);
19158  }
19159  return;
19160 
19161 error:
19162  if (rt == CreateNodegroupImplReq::RT_PARSE)
19163  {
19164  jam();
19165  signal->theData[0] = err;
19166  return;
19167  }
19168 
19169  if (rt == CreateNodegroupImplReq::RT_PREPARE)
19170  {
19171  jam();
19172  CreateNodegroupImplRef * ref = (CreateNodegroupImplRef*)signal->getDataPtrSend();
19173  ref->senderRef = reference();
19174  ref->senderData = req->senderData;
19175  ref->errorCode = err;
19176  sendSignal(req->senderRef, GSN_CREATE_NODEGROUP_IMPL_REF, signal,
19177  CreateNodegroupImplRef::SignalLength, JBB);
19178  return;
19179  }
19180 
19181  jamLine(err);
19182  ndbrequire(false);
19183 }
19184 
19188 void
19189 Dbdih::execDROP_NODEGROUP_IMPL_REQ(Signal* signal)
19190 {
19191  jamEntry();
19192  DropNodegroupImplReq reqCopy = *(DropNodegroupImplReq*)signal->getDataPtr();
19193  DropNodegroupImplReq *req = &reqCopy;
19194 
19195  NodeGroupRecordPtr NGPtr;
19196 
19197  Uint32 err = 0;
19198  Uint32 rt = req->requestType;
19199  Uint64 gci = 0;
19200  switch(rt){
19201  case DropNodegroupImplReq::RT_ABORT:
19202  jam(); // do nothing
19203  break;
19204  case DropNodegroupImplReq::RT_PARSE:
19205  case DropNodegroupImplReq::RT_PREPARE:
19206  jam();
19207  NGPtr.i = req->nodegroupId;
19208  if (NGPtr.i >= MAX_NDB_NODES)
19209  {
19210  jam();
19211  err = DropNodegroupRef::NoSuchNodegroup;
19212  goto error;
19213  }
19214  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
19215 
19216  if (NGPtr.p->nodegroupIndex == RNIL)
19217  {
19218  jam();
19219  err = DropNodegroupRef::NoSuchNodegroup;
19220  goto error;
19221  }
19222 
19223  if (NGPtr.p->m_ref_count)
19224  {
19225  jam();
19226  err = DropNodegroupRef::NodegroupInUse;
19227  goto error;
19228  }
19229  break;
19230  case DropNodegroupImplReq::RT_COMMIT:
19231  {
19232  jam();
19233  gci = m_micro_gcp.m_current_gci;
19234  break;
19235  }
19236  case DropNodegroupImplReq::RT_COMPLETE:
19237  {
19238  NGPtr.i = req->nodegroupId;
19239  ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
19240  for (Uint32 i = 0; i<NGPtr.p->nodeCount; i++)
19241  {
19242  jam();
19243  Uint32 nodeId = NGPtr.p->nodesInGroup[i];
19244  Sysfile::setNodeGroup(nodeId, SYSFILE->nodeGroups, NO_NODE_GROUP_ID);
19245  Sysfile::setNodeStatus(nodeId, SYSFILE->nodeStatus, Sysfile::NS_Configured);
19246  }
19247  setNodeActiveStatus();
19248  setNodeGroups();
19249  break;
19250  }
19251  }
19252 
19253  {
19254  DropNodegroupImplConf* conf = (DropNodegroupImplConf*)signal->getDataPtrSend();
19255  conf->senderRef = reference();
19256  conf->senderData = req->senderData;
19257  conf->gci_hi = Uint32(gci >> 32);
19258  conf->gci_lo = Uint32(gci);
19259  sendSignal(req->senderRef, GSN_DROP_NODEGROUP_IMPL_CONF, signal,
19260  DropNodegroupImplConf::SignalLength, JBB);
19261  }
19262  return;
19263 
19264 error:
19265  DropNodegroupImplRef * ref = (DropNodegroupImplRef*)signal->getDataPtrSend();
19266  ref->senderRef = reference();
19267  ref->senderData = req->senderData;
19268  ref->errorCode = err;
19269  sendSignal(req->senderRef, GSN_DROP_NODEGROUP_IMPL_REF, signal,
19270  DropNodegroupImplRef::SignalLength, JBB);
19271 }