1 /* Copyright (c) 2003-2007 MySQL AB
2 Use is subject to license terms
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 Street, Fifth Floor, Boston, MA 02110-1301, USA */
16
17 #define DBDIH_C
18 #include <ndb_limits.h>
19 #include <ndb_version.h>
20 #include <NdbOut.hpp>
21
22 #include "Dbdih.hpp"
23 #include "Configuration.hpp"
24
25 #include <signaldata/BlockCommitOrd.hpp>
26 #include <signaldata/CheckNodeGroups.hpp>
27 #include <signaldata/CreateFrag.hpp>
28 #include <signaldata/CopyActive.hpp>
29 #include <signaldata/CopyFrag.hpp>
30 #include <signaldata/CopyGCIReq.hpp>
31 #include <signaldata/DiAddTab.hpp>
32 #include <signaldata/DictStart.hpp>
33 #include <signaldata/DiGetNodes.hpp>
34 #include <signaldata/DihContinueB.hpp>
35 #include <signaldata/DihSwitchReplica.hpp>
36 #include <signaldata/DumpStateOrd.hpp>
37 #include <signaldata/EmptyLcp.hpp>
38 #include <signaldata/EndTo.hpp>
39 #include <signaldata/EventReport.hpp>
40 #include <signaldata/GCPSave.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/StartTo.hpp>
53 #include <signaldata/StopPerm.hpp>
54 #include <signaldata/StopMe.hpp>
55 #include <signaldata/TestOrd.hpp>
56 #include <signaldata/UpdateTo.hpp>
57 #include <signaldata/WaitGCP.hpp>
58 #include <signaldata/DihStartTab.hpp>
59 #include <signaldata/LCP.hpp>
60 #include <signaldata/SystemError.hpp>
61
62 #include <signaldata/DropTab.hpp>
63 #include <signaldata/AlterTab.hpp>
64 #include <signaldata/PrepDropTab.hpp>
65 #include <signaldata/SumaImpl.hpp>
66 #include <signaldata/DictTabInfo.hpp>
67 #include <signaldata/CreateFragmentation.hpp>
68 #include <signaldata/LqhFrag.hpp>
69 #include <signaldata/FsOpenReq.hpp>
70 #include <signaldata/DihFragCount.hpp>
71 #include <signaldata/DictLock.hpp>
72 #include <DebuggerNames.hpp>
73
74 #include <EventLogger.hpp>
75 extern EventLogger g_eventLogger;
76
77 #define SYSFILE ((Sysfile *)&sysfileData[0])
78
79 #define RETURN_IF_NODE_NOT_ALIVE(node) \
80 if (!checkNodeAlive((node))) { \
81 jam(); \
82 return; \
83 } \
84
85 #define RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverIndex, regTOPtr) \
86 regTOPtr.i = takeOverIndex; \
87 ptrCheckGuard(regTOPtr, MAX_NDB_NODES, takeOverRecord); \
88 if (checkToInterrupted(regTOPtr)) { \
89 jam(); \
90 return; \
91 } \
92
93 #define receiveLoopMacro(sigName, receiveNodeId)\
94 { \
95 c_##sigName##_Counter.clearWaitingFor(receiveNodeId); \
96 if(c_##sigName##_Counter.done() == false){ \
97 jam(); \
98 return; \
99 } \
100 }
101
102 #define sendLoopMacro(sigName, signalRoutine) \
103 { \
104 c_##sigName##_Counter.clearWaitingFor(); \
105 NodeRecordPtr specNodePtr; \
106 specNodePtr.i = cfirstAliveNode; \
107 do { \
108 jam(); \
109 ptrCheckGuard(specNodePtr, MAX_NDB_NODES, nodeRecord); \
110 c_##sigName##_Counter.setWaitingFor(specNodePtr.i); \
111 signalRoutine(signal, specNodePtr.i); \
112 specNodePtr.i = specNodePtr.p->nextNode; \
113 } while (specNodePtr.i != RNIL); \
114 }
115
116 static
117 Uint32
prevLcpNo(Uint32 lcpNo)118 prevLcpNo(Uint32 lcpNo){
119 if(lcpNo == 0)
120 return MAX_LCP_STORED - 1;
121 return lcpNo - 1;
122 }
123
124 static
125 Uint32
nextLcpNo(Uint32 lcpNo)126 nextLcpNo(Uint32 lcpNo){
127 lcpNo++;
128 if(lcpNo == MAX_LCP_STORED)
129 return 0;
130 return lcpNo;
131 }
132
133 #define gth(x, y) ndbrequire(((int)x)>((int)y))
134
nullRoutine(Signal * signal,Uint32 nodeId)135 void Dbdih::nullRoutine(Signal* signal, Uint32 nodeId)
136 {
137 }//Dbdih::nullRoutine()
138
sendCOPY_GCIREQ(Signal * signal,Uint32 nodeId)139 void Dbdih::sendCOPY_GCIREQ(Signal* signal, Uint32 nodeId)
140 {
141 ndbrequire(c_copyGCIMaster.m_copyReason != CopyGCIReq::IDLE);
142
143 const BlockReference ref = calcDihBlockRef(nodeId);
144 const Uint32 wordPerSignal = CopyGCIReq::DATA_SIZE;
145 const Uint32 noOfSignals = ((Sysfile::SYSFILE_SIZE32 + (wordPerSignal - 1)) /
146 wordPerSignal);
147
148 CopyGCIReq * const copyGCI = (CopyGCIReq *)&signal->theData[0];
149 copyGCI->anyData = nodeId;
150 copyGCI->copyReason = c_copyGCIMaster.m_copyReason;
151 copyGCI->startWord = 0;
152
153 for(Uint32 i = 0; i < noOfSignals; i++) {
154 jam();
155 { // Do copy
156 const int startWord = copyGCI->startWord;
157 for(Uint32 j = 0; j < wordPerSignal; j++) {
158 copyGCI->data[j] = sysfileData[j+startWord];
159 }//for
160 }
161 sendSignal(ref, GSN_COPY_GCIREQ, signal, 25, JBB);
162 copyGCI->startWord += wordPerSignal;
163 }//for
164 }//Dbdih::sendCOPY_GCIREQ()
165
166
sendDIH_SWITCH_REPLICA_REQ(Signal * signal,Uint32 nodeId)167 void Dbdih::sendDIH_SWITCH_REPLICA_REQ(Signal* signal, Uint32 nodeId)
168 {
169 const BlockReference ref = calcDihBlockRef(nodeId);
170 sendSignal(ref, GSN_DIH_SWITCH_REPLICA_REQ, signal,
171 DihSwitchReplicaReq::SignalLength, JBB);
172 }//Dbdih::sendDIH_SWITCH_REPLICA_REQ()
173
sendEMPTY_LCP_REQ(Signal * signal,Uint32 nodeId)174 void Dbdih::sendEMPTY_LCP_REQ(Signal* signal, Uint32 nodeId)
175 {
176 BlockReference ref = calcLqhBlockRef(nodeId);
177 sendSignal(ref, GSN_EMPTY_LCP_REQ, signal, EmptyLcpReq::SignalLength, JBB);
178 }//Dbdih::sendEMPTY_LCPREQ()
179
sendEND_TOREQ(Signal * signal,Uint32 nodeId)180 void Dbdih::sendEND_TOREQ(Signal* signal, Uint32 nodeId)
181 {
182 BlockReference ref = calcDihBlockRef(nodeId);
183 sendSignal(ref, GSN_END_TOREQ, signal, EndToReq::SignalLength, JBB);
184 }//Dbdih::sendEND_TOREQ()
185
sendGCP_COMMIT(Signal * signal,Uint32 nodeId)186 void Dbdih::sendGCP_COMMIT(Signal* signal, Uint32 nodeId)
187 {
188 BlockReference ref = calcDihBlockRef(nodeId);
189 signal->theData[0] = cownNodeId;
190 signal->theData[1] = cnewgcp;
191 sendSignal(ref, GSN_GCP_COMMIT, signal, 2, JBA);
192 }//Dbdih::sendGCP_COMMIT()
193
sendGCP_PREPARE(Signal * signal,Uint32 nodeId)194 void Dbdih::sendGCP_PREPARE(Signal* signal, Uint32 nodeId)
195 {
196 BlockReference ref = calcDihBlockRef(nodeId);
197 signal->theData[0] = cownNodeId;
198 signal->theData[1] = cnewgcp;
199 sendSignal(ref, GSN_GCP_PREPARE, signal, 2, JBA);
200 }//Dbdih::sendGCP_PREPARE()
201
sendGCP_SAVEREQ(Signal * signal,Uint32 nodeId)202 void Dbdih::sendGCP_SAVEREQ(Signal* signal, Uint32 nodeId)
203 {
204 GCPSaveReq * const saveReq = (GCPSaveReq*)&signal->theData[0];
205 BlockReference ref = calcLqhBlockRef(nodeId);
206 saveReq->dihBlockRef = reference();
207 saveReq->dihPtr = nodeId;
208 saveReq->gci = coldgcp;
209 sendSignal(ref, GSN_GCP_SAVEREQ, signal, GCPSaveReq::SignalLength, JBB);
210 }//Dbdih::sendGCP_SAVEREQ()
211
sendINCL_NODEREQ(Signal * signal,Uint32 nodeId)212 void Dbdih::sendINCL_NODEREQ(Signal* signal, Uint32 nodeId)
213 {
214 BlockReference nodeDihRef = calcDihBlockRef(nodeId);
215 signal->theData[0] = reference();
216 signal->theData[1] = c_nodeStartMaster.startNode;
217 signal->theData[2] = c_nodeStartMaster.failNr;
218 signal->theData[3] = 0;
219 signal->theData[4] = currentgcp;
220 sendSignal(nodeDihRef, GSN_INCL_NODEREQ, signal, 5, JBA);
221 }//Dbdih::sendINCL_NODEREQ()
222
sendMASTER_GCPREQ(Signal * signal,Uint32 nodeId)223 void Dbdih::sendMASTER_GCPREQ(Signal* signal, Uint32 nodeId)
224 {
225 BlockReference ref = calcDihBlockRef(nodeId);
226 sendSignal(ref, GSN_MASTER_GCPREQ, signal, MasterGCPReq::SignalLength, JBB);
227 }//Dbdih::sendMASTER_GCPREQ()
228
sendMASTER_LCPREQ(Signal * signal,Uint32 nodeId)229 void Dbdih::sendMASTER_LCPREQ(Signal* signal, Uint32 nodeId)
230 {
231 BlockReference ref = calcDihBlockRef(nodeId);
232 sendSignal(ref, GSN_MASTER_LCPREQ, signal, MasterLCPReq::SignalLength, JBB);
233 }//Dbdih::sendMASTER_LCPREQ()
234
sendSTART_INFOREQ(Signal * signal,Uint32 nodeId)235 void Dbdih::sendSTART_INFOREQ(Signal* signal, Uint32 nodeId)
236 {
237 const BlockReference ref = calcDihBlockRef(nodeId);
238 sendSignal(ref, GSN_START_INFOREQ, signal, StartInfoReq::SignalLength, JBB);
239 }//sendSTART_INFOREQ()
240
sendSTART_RECREQ(Signal * signal,Uint32 nodeId)241 void Dbdih::sendSTART_RECREQ(Signal* signal, Uint32 nodeId)
242 {
243 StartRecReq * const req = (StartRecReq*)&signal->theData[0];
244 BlockReference ref = calcLqhBlockRef(nodeId);
245 req->receivingNodeId = nodeId;
246 req->senderRef = reference();
247 req->keepGci = SYSFILE->keepGCI;
248 req->lastCompletedGci = SYSFILE->lastCompletedGCI[nodeId];
249 req->newestGci = SYSFILE->newestRestorableGCI;
250 sendSignal(ref, GSN_START_RECREQ, signal, StartRecReq::SignalLength, JBB);
251
252 signal->theData[0] = NDB_LE_StartREDOLog;
253 signal->theData[1] = nodeId;
254 signal->theData[2] = SYSFILE->keepGCI;
255 signal->theData[3] = SYSFILE->lastCompletedGCI[nodeId];
256 signal->theData[4] = SYSFILE->newestRestorableGCI;
257 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 5, JBB);
258 }//Dbdih::sendSTART_RECREQ()
259
sendSTART_TOREQ(Signal * signal,Uint32 nodeId)260 void Dbdih::sendSTART_TOREQ(Signal* signal, Uint32 nodeId)
261 {
262 BlockReference ref = calcDihBlockRef(nodeId);
263 sendSignal(ref, GSN_START_TOREQ, signal, StartToReq::SignalLength, JBB);
264 }//Dbdih::sendSTART_TOREQ()
265
sendSTOP_ME_REQ(Signal * signal,Uint32 nodeId)266 void Dbdih::sendSTOP_ME_REQ(Signal* signal, Uint32 nodeId)
267 {
268 if (nodeId != getOwnNodeId()) {
269 jam();
270 const BlockReference ref = calcDihBlockRef(nodeId);
271 sendSignal(ref, GSN_STOP_ME_REQ, signal, StopMeReq::SignalLength, JBB);
272 }//if
273 }//Dbdih::sendSTOP_ME_REQ()
274
sendTC_CLOPSIZEREQ(Signal * signal,Uint32 nodeId)275 void Dbdih::sendTC_CLOPSIZEREQ(Signal* signal, Uint32 nodeId)
276 {
277 BlockReference ref = calcTcBlockRef(nodeId);
278 signal->theData[0] = nodeId;
279 signal->theData[1] = reference();
280 sendSignal(ref, GSN_TC_CLOPSIZEREQ, signal, 2, JBB);
281 }//Dbdih::sendTC_CLOPSIZEREQ()
282
sendTCGETOPSIZEREQ(Signal * signal,Uint32 nodeId)283 void Dbdih::sendTCGETOPSIZEREQ(Signal* signal, Uint32 nodeId)
284 {
285 BlockReference ref = calcTcBlockRef(nodeId);
286 signal->theData[0] = nodeId;
287 signal->theData[1] = reference();
288 sendSignal(ref, GSN_TCGETOPSIZEREQ, signal, 2, JBB);
289 }//Dbdih::sendTCGETOPSIZEREQ()
290
sendUPDATE_TOREQ(Signal * signal,Uint32 nodeId)291 void Dbdih::sendUPDATE_TOREQ(Signal* signal, Uint32 nodeId)
292 {
293 const BlockReference ref = calcDihBlockRef(nodeId);
294 sendSignal(ref, GSN_UPDATE_TOREQ, signal, UpdateToReq::SignalLength, JBB);
295 }//sendUPDATE_TOREQ()
296
execCONTINUEB(Signal * signal)297 void Dbdih::execCONTINUEB(Signal* signal)
298 {
299 jamEntry();
300 switch ((DihContinueB::Type)signal->theData[0]) {
301 case DihContinueB::ZPACK_TABLE_INTO_PAGES:
302 {
303 jam();
304 Uint32 tableId = signal->theData[1];
305 packTableIntoPagesLab(signal, tableId);
306 return;
307 break;
308 }
309 case DihContinueB::ZPACK_FRAG_INTO_PAGES:
310 {
311 RWFragment wf;
312 jam();
313 wf.rwfTabPtr.i = signal->theData[1];
314 ptrCheckGuard(wf.rwfTabPtr, ctabFileSize, tabRecord);
315 wf.fragId = signal->theData[2];
316 wf.pageIndex = signal->theData[3];
317 wf.wordIndex = signal->theData[4];
318 packFragIntoPagesLab(signal, &wf);
319 return;
320 break;
321 }
322 case DihContinueB::ZREAD_PAGES_INTO_TABLE:
323 {
324 jam();
325 Uint32 tableId = signal->theData[1];
326 readPagesIntoTableLab(signal, tableId);
327 return;
328 break;
329 }
330 case DihContinueB::ZREAD_PAGES_INTO_FRAG:
331 {
332 RWFragment rf;
333 jam();
334 rf.rwfTabPtr.i = signal->theData[1];
335 ptrCheckGuard(rf.rwfTabPtr, ctabFileSize, tabRecord);
336 rf.fragId = signal->theData[2];
337 rf.pageIndex = signal->theData[3];
338 rf.wordIndex = signal->theData[4];
339 readPagesIntoFragLab(signal, &rf);
340 return;
341 break;
342 }
343 case DihContinueB::ZCOPY_TABLE:
344 {
345 jam();
346 Uint32 tableId = signal->theData[1];
347 copyTableLab(signal, tableId);
348 return;
349 }
350 case DihContinueB::ZCOPY_TABLE_NODE:
351 {
352 NodeRecordPtr nodePtr;
353 CopyTableNode ctn;
354 jam();
355 ctn.ctnTabPtr.i = signal->theData[1];
356 ptrCheckGuard(ctn.ctnTabPtr, ctabFileSize, tabRecord);
357 nodePtr.i = signal->theData[2];
358 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
359 ctn.pageIndex = signal->theData[3];
360 ctn.wordIndex = signal->theData[4];
361 ctn.noOfWords = signal->theData[5];
362 copyTableNode(signal, &ctn, nodePtr);
363 return;
364 }
365 case DihContinueB::ZSTART_FRAGMENT:
366 {
367 jam();
368 Uint32 tableId = signal->theData[1];
369 Uint32 fragId = signal->theData[2];
370 startFragment(signal, tableId, fragId);
371 return;
372 }
373 case DihContinueB::ZCOMPLETE_RESTART:
374 jam();
375 completeRestartLab(signal);
376 return;
377 case DihContinueB::ZREAD_TABLE_FROM_PAGES:
378 {
379 TabRecordPtr tabPtr;
380 jam();
381 tabPtr.i = signal->theData[1];
382 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
383 readTableFromPagesLab(signal, tabPtr);
384 return;
385 }
386 case DihContinueB::ZSR_PHASE2_READ_TABLE:
387 {
388 TabRecordPtr tabPtr;
389 jam();
390 tabPtr.i = signal->theData[1];
391 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
392 srPhase2ReadTableLab(signal, tabPtr);
393 return;
394 }
395 case DihContinueB::ZCHECK_TC_COUNTER:
396 jam();
397 #ifndef NO_LCP
398 checkTcCounterLab(signal);
399 #endif
400 return;
401 case DihContinueB::ZCALCULATE_KEEP_GCI:
402 {
403 jam();
404 Uint32 tableId = signal->theData[1];
405 Uint32 fragId = signal->theData[2];
406 calculateKeepGciLab(signal, tableId, fragId);
407 return;
408 }
409 case DihContinueB::ZSTORE_NEW_LCP_ID:
410 jam();
411 storeNewLcpIdLab(signal);
412 return;
413 case DihContinueB::ZTABLE_UPDATE:
414 {
415 TabRecordPtr tabPtr;
416 jam();
417 tabPtr.i = signal->theData[1];
418 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
419 tableUpdateLab(signal, tabPtr);
420 return;
421 }
422 case DihContinueB::ZCHECK_LCP_COMPLETED:
423 {
424 jam();
425 checkLcpCompletedLab(signal);
426 return;
427 }
428 case DihContinueB::ZINIT_LCP:
429 {
430 jam();
431 Uint32 senderRef = signal->theData[1];
432 Uint32 tableId = signal->theData[2];
433 initLcpLab(signal, senderRef, tableId);
434 return;
435 }
436 case DihContinueB::ZADD_TABLE_MASTER_PAGES:
437 {
438 TabRecordPtr tabPtr;
439 jam();
440 tabPtr.i = signal->theData[1];
441 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
442 tabPtr.p->tabUpdateState = TabRecord::US_ADD_TABLE_MASTER;
443 tableUpdateLab(signal, tabPtr);
444 return;
445 break;
446 }
447 case DihContinueB::ZDIH_ADD_TABLE_MASTER:
448 {
449 jam();
450 addTable_closeConf(signal, signal->theData[1]);
451 return;
452 }
453 case DihContinueB::ZADD_TABLE_SLAVE_PAGES:
454 {
455 TabRecordPtr tabPtr;
456 jam();
457 tabPtr.i = signal->theData[1];
458 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
459 tabPtr.p->tabUpdateState = TabRecord::US_ADD_TABLE_SLAVE;
460 tableUpdateLab(signal, tabPtr);
461 return;
462 }
463 case DihContinueB::ZDIH_ADD_TABLE_SLAVE:
464 {
465 ndbrequire(false);
466 return;
467 }
468 case DihContinueB::ZSTART_GCP:
469 jam();
470 #ifndef NO_GCP
471 startGcpLab(signal, signal->theData[1]);
472 #endif
473 return;
474 break;
475 case DihContinueB::ZCOPY_GCI:{
476 jam();
477 CopyGCIReq::CopyReason reason = (CopyGCIReq::CopyReason)signal->theData[1];
478 ndbrequire(c_copyGCIMaster.m_copyReason == reason);
479 sendLoopMacro(COPY_GCIREQ, sendCOPY_GCIREQ);
480 return;
481 }
482 break;
483 case DihContinueB::ZEMPTY_VERIFY_QUEUE:
484 jam();
485 emptyverificbuffer(signal, true);
486 return;
487 break;
488 case DihContinueB::ZCHECK_GCP_STOP:
489 jam();
490 #ifndef NO_GCP
491 checkGcpStopLab(signal);
492 #endif
493 return;
494 break;
495 case DihContinueB::ZREMOVE_NODE_FROM_TABLE:
496 {
497 jam();
498 Uint32 nodeId = signal->theData[1];
499 Uint32 tableId = signal->theData[2];
500 removeNodeFromTables(signal, nodeId, tableId);
501 return;
502 }
503 case DihContinueB::ZCOPY_NODE:
504 {
505 jam();
506 Uint32 tableId = signal->theData[1];
507 copyNodeLab(signal, tableId);
508 return;
509 }
510 case DihContinueB::ZSTART_TAKE_OVER:
511 {
512 jam();
513 Uint32 takeOverPtrI = signal->theData[1];
514 Uint32 startNode = signal->theData[2];
515 Uint32 toNode = signal->theData[3];
516 startTakeOver(signal, takeOverPtrI, startNode, toNode);
517 return;
518 break;
519 }
520 case DihContinueB::ZCHECK_START_TAKE_OVER:
521 jam();
522 checkStartTakeOver(signal);
523 break;
524 case DihContinueB::ZTO_START_COPY_FRAG:
525 {
526 jam();
527 Uint32 takeOverPtrI = signal->theData[1];
528 startNextCopyFragment(signal, takeOverPtrI);
529 return;
530 }
531 case DihContinueB::ZINVALIDATE_NODE_LCP:
532 {
533 jam();
534 const Uint32 nodeId = signal->theData[1];
535 const Uint32 tableId = signal->theData[2];
536 invalidateNodeLCP(signal, nodeId, tableId);
537 return;
538 }
539 case DihContinueB::ZINITIALISE_RECORDS:
540 jam();
541 initialiseRecordsLab(signal,
542 signal->theData[1],
543 signal->theData[2],
544 signal->theData[3]);
545 return;
546 break;
547 case DihContinueB::ZSTART_PERMREQ_AGAIN:
548 jam();
549 nodeRestartPh2Lab2(signal);
550 return;
551 break;
552 case DihContinueB::SwitchReplica:
553 {
554 jam();
555 const Uint32 nodeId = signal->theData[1];
556 const Uint32 tableId = signal->theData[2];
557 const Uint32 fragNo = signal->theData[3];
558 switchReplica(signal, nodeId, tableId, fragNo);
559 return;
560 }
561 case DihContinueB::ZSEND_START_TO:
562 {
563 jam();
564 Uint32 takeOverPtrI = signal->theData[1];
565 sendStartTo(signal, takeOverPtrI);
566 return;
567 }
568 case DihContinueB::ZSEND_ADD_FRAG:
569 {
570 jam();
571 Uint32 takeOverPtrI = signal->theData[1];
572 toCopyFragLab(signal, takeOverPtrI);
573 return;
574 }
575 case DihContinueB::ZSEND_UPDATE_TO:
576 {
577 jam();
578 Uint32 takeOverPtrI = signal->theData[1];
579 Uint32 updateState = signal->theData[4];
580 sendUpdateTo(signal, takeOverPtrI, updateState);
581 return;
582 }
583 case DihContinueB::ZSEND_END_TO:
584 {
585 jam();
586 Uint32 takeOverPtrI = signal->theData[1];
587 sendEndTo(signal, takeOverPtrI);
588 return;
589 }
590 case DihContinueB::ZSEND_CREATE_FRAG:
591 {
592 jam();
593 Uint32 takeOverPtrI = signal->theData[1];
594 Uint32 storedType = signal->theData[2];
595 Uint32 startGci = signal->theData[3];
596 sendCreateFragReq(signal, startGci, storedType, takeOverPtrI);
597 return;
598 }
599 case DihContinueB::WAIT_DROP_TAB_WRITING_TO_FILE:{
600 jam();
601 TabRecordPtr tabPtr;
602 tabPtr.i = signal->theData[1];
603 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
604 waitDropTabWritingToFile(signal, tabPtr);
605 return;
606 }
607 case DihContinueB::CHECK_WAIT_DROP_TAB_FAILED_LQH:{
608 jam();
609 Uint32 nodeId = signal->theData[1];
610 Uint32 tableId = signal->theData[2];
611 checkWaitDropTabFailedLqh(signal, nodeId, tableId);
612 return;
613 }
614 case DihContinueB::ZTO_START_FRAGMENTS:
615 {
616 TakeOverRecordPtr takeOverPtr;
617 takeOverPtr.i = signal->theData[1];
618 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
619 nr_start_fragments(signal, takeOverPtr);
620 return;
621 }
622 }//switch
623
624 ndbrequire(false);
625 return;
626 }//Dbdih::execCONTINUEB()
627
execCOPY_GCIREQ(Signal * signal)628 void Dbdih::execCOPY_GCIREQ(Signal* signal)
629 {
630 CopyGCIReq * const copyGCI = (CopyGCIReq *)&signal->theData[0];
631 jamEntry();
632 CopyGCIReq::CopyReason reason = (CopyGCIReq::CopyReason)copyGCI->copyReason;
633 const Uint32 tstart = copyGCI->startWord;
634
635 ndbrequire(cmasterdihref == signal->senderBlockRef()) ;
636 ndbrequire(c_copyGCISlave.m_copyReason == CopyGCIReq::IDLE);
637 ndbrequire(c_copyGCISlave.m_expectedNextWord == tstart);
638 ndbrequire(reason != CopyGCIReq::IDLE);
639 bool isdone = (tstart + CopyGCIReq::DATA_SIZE) >= Sysfile::SYSFILE_SIZE32;
640
641 if (ERROR_INSERTED(7177))
642 {
643 jam();
644
645 if (signal->getLength() == 3)
646 {
647 jam();
648 goto done;
649 }
650 }
651
652 arrGuard(tstart + CopyGCIReq::DATA_SIZE, sizeof(sysfileData)/4);
653 for(Uint32 i = 0; i<CopyGCIReq::DATA_SIZE; i++)
654 cdata[tstart+i] = copyGCI->data[i];
655
656 if (ERROR_INSERTED(7177) && isMaster() && isdone)
657 {
658 sendSignalWithDelay(reference(), GSN_COPY_GCIREQ, signal, 1000, 3);
659 return;
660 }
661
662 done:
663 if (isdone)
664 {
665 jam();
666 c_copyGCISlave.m_expectedNextWord = 0;
667 }
668 else
669 {
670 jam();
671 c_copyGCISlave.m_expectedNextWord += CopyGCIReq::DATA_SIZE;
672 return;
673 }
674
675 if (cmasterdihref != reference())
676 {
677 jam();
678 Uint32 tmp= SYSFILE->m_restart_seq;
679 memcpy(sysfileData, cdata, sizeof(sysfileData));
680 SYSFILE->m_restart_seq = tmp;
681
682 if (c_set_initial_start_flag)
683 {
684 jam();
685 Sysfile::setInitialStartOngoing(SYSFILE->systemRestartBits);
686 }
687 }
688
689 c_copyGCISlave.m_copyReason = reason;
690 c_copyGCISlave.m_senderRef = signal->senderBlockRef();
691 c_copyGCISlave.m_senderData = copyGCI->anyData;
692
693 CRASH_INSERTION2(7020, reason==CopyGCIReq::LOCAL_CHECKPOINT);
694 CRASH_INSERTION2(7008, reason==CopyGCIReq::GLOBAL_CHECKPOINT);
695
696 /* -------------------------------------------------------------------------*/
697 /* WE SET THE REQUESTER OF THE COPY GCI TO THE CURRENT MASTER. IF THE */
698 /* CURRENT MASTER WE DO NOT WANT THE NEW MASTER TO RECEIVE CONFIRM OF */
699 /* SOMETHING HE HAS NOT SENT. THE TAKE OVER MUST BE CAREFUL. */
700 /* -------------------------------------------------------------------------*/
701 bool ok = false;
702 switch(reason){
703 case CopyGCIReq::IDLE:
704 ok = true;
705 jam();
706 ndbrequire(false);
707 break;
708 case CopyGCIReq::LOCAL_CHECKPOINT: {
709 ok = true;
710 jam();
711 c_lcpState.setLcpStatus(LCP_COPY_GCI, __LINE__);
712 c_lcpState.m_masterLcpDihRef = cmasterdihref;
713 setNodeInfo(signal);
714 break;
715 }
716 case CopyGCIReq::RESTART: {
717 ok = true;
718 jam();
719 coldgcp = SYSFILE->newestRestorableGCI;
720 crestartGci = SYSFILE->newestRestorableGCI;
721 c_newest_restorable_gci = SYSFILE->newestRestorableGCI;
722 Sysfile::setRestartOngoing(SYSFILE->systemRestartBits);
723 currentgcp = coldgcp + 1;
724 cnewgcp = coldgcp + 1;
725 setNodeInfo(signal);
726 if ((Sysfile::getLCPOngoing(SYSFILE->systemRestartBits))) {
727 jam();
728 /* -------------------------------------------------------------------- */
729 // IF THERE WAS A LOCAL CHECKPOINT ONGOING AT THE CRASH MOMENT WE WILL
730 // INVALIDATE THAT LOCAL CHECKPOINT.
731 /* -------------------------------------------------------------------- */
732 invalidateLcpInfoAfterSr();
733 }//if
734 break;
735 }
736 case CopyGCIReq::GLOBAL_CHECKPOINT: {
737 ok = true;
738 jam();
739 cgcpParticipantState = GCP_PARTICIPANT_COPY_GCI_RECEIVED;
740 c_newest_restorable_gci = SYSFILE->newestRestorableGCI;
741 setNodeInfo(signal);
742 break;
743 }//if
744 case CopyGCIReq::INITIAL_START_COMPLETED:
745 ok = true;
746 jam();
747 break;
748 }
749 ndbrequire(ok);
750
751 CRASH_INSERTION(7183);
752
753 if (ERROR_INSERTED(7185) && reason==CopyGCIReq::GLOBAL_CHECKPOINT)
754 {
755 jam();
756 return;
757 }
758
759 /* ----------------------------------------------------------------------- */
760 /* WE START BY TRYING TO OPEN THE FIRST RESTORABLE GCI FILE. */
761 /* ----------------------------------------------------------------------- */
762 FileRecordPtr filePtr;
763 filePtr.i = crestartInfoFile[0];
764 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
765 if (filePtr.p->fileStatus == FileRecord::OPEN) {
766 jam();
767 openingCopyGciSkipInitLab(signal, filePtr);
768 return;
769 }//if
770 openFileRw(signal, filePtr);
771 filePtr.p->reqStatus = FileRecord::OPENING_COPY_GCI;
772 return;
773 }//Dbdih::execCOPY_GCIREQ()
774
execDICTSTARTCONF(Signal * signal)775 void Dbdih::execDICTSTARTCONF(Signal* signal)
776 {
777 jamEntry();
778 Uint32 nodeId = refToNode(signal->getSendersBlockRef());
779 if (nodeId != getOwnNodeId()) {
780 jam();
781 nodeDictStartConfLab(signal);
782 } else {
783 jam();
784 dictStartConfLab(signal);
785 }//if
786 }//Dbdih::execDICTSTARTCONF()
787
execFSCLOSECONF(Signal * signal)788 void Dbdih::execFSCLOSECONF(Signal* signal)
789 {
790 FileRecordPtr filePtr;
791 jamEntry();
792 filePtr.i = signal->theData[0];
793 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
794 filePtr.p->fileStatus = FileRecord::CLOSED;
795 FileRecord::ReqStatus status = filePtr.p->reqStatus;
796 filePtr.p->reqStatus = FileRecord::IDLE;
797 switch (status) {
798 case FileRecord::CLOSING_GCP:
799 jam();
800 closingGcpLab(signal, filePtr);
801 break;
802 case FileRecord::CLOSING_GCP_CRASH:
803 jam();
804 closingGcpCrashLab(signal, filePtr);
805 break;
806 case FileRecord::CLOSING_TABLE_CRASH:
807 jam();
808 closingTableCrashLab(signal, filePtr);
809 break;
810 case FileRecord::CLOSING_TABLE_SR:
811 jam();
812 closingTableSrLab(signal, filePtr);
813 break;
814 case FileRecord::TABLE_CLOSE:
815 jam();
816 tableCloseLab(signal, filePtr);
817 break;
818 case FileRecord::TABLE_CLOSE_DELETE:
819 jam();
820 tableDeleteLab(signal, filePtr);
821 break;
822 default:
823 ndbrequire(false);
824 break;
825 }//switch
826 return;
827 }//Dbdih::execFSCLOSECONF()
828
execFSCLOSEREF(Signal * signal)829 void Dbdih::execFSCLOSEREF(Signal* signal)
830 {
831 FileRecordPtr filePtr;
832 jamEntry();
833 filePtr.i = signal->theData[0];
834 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
835 FileRecord::ReqStatus status = filePtr.p->reqStatus;
836 filePtr.p->reqStatus = FileRecord::IDLE;
837 switch (status) {
838 case FileRecord::CLOSING_GCP:
839 jam();
840 break;
841 case FileRecord::CLOSING_GCP_CRASH:
842 jam();
843 closingGcpCrashLab(signal, filePtr);
844 return;
845 case FileRecord::CLOSING_TABLE_CRASH:
846 jam();
847 closingTableCrashLab(signal, filePtr);
848 return;
849 case FileRecord::CLOSING_TABLE_SR:
850 jam();
851 break;
852 case FileRecord::TABLE_CLOSE:
853 jam();
854 break;
855 case FileRecord::TABLE_CLOSE_DELETE:
856 jam();
857 break;
858 default:
859 jam();
860 break;
861
862 }//switch
863 {
864 char msg[100];
865 sprintf(msg, "File system close failed during FileRecord status %d", (Uint32)status);
866 fsRefError(signal,__LINE__,msg);
867 }
868
869 return;
870 }//Dbdih::execFSCLOSEREF()
871
execFSOPENCONF(Signal * signal)872 void Dbdih::execFSOPENCONF(Signal* signal)
873 {
874 FileRecordPtr filePtr;
875 jamEntry();
876 filePtr.i = signal->theData[0];
877 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
878 filePtr.p->fileRef = signal->theData[1];
879 filePtr.p->fileStatus = FileRecord::OPEN;
880 FileRecord::ReqStatus status = filePtr.p->reqStatus;
881 filePtr.p->reqStatus = FileRecord::IDLE;
882 switch (status) {
883 case FileRecord::CREATING_GCP:
884 jam();
885 creatingGcpLab(signal, filePtr);
886 break;
887 case FileRecord::OPENING_COPY_GCI:
888 jam();
889 openingCopyGciSkipInitLab(signal, filePtr);
890 break;
891 case FileRecord::CREATING_COPY_GCI:
892 jam();
893 openingCopyGciSkipInitLab(signal, filePtr);
894 break;
895 case FileRecord::OPENING_GCP:
896 jam();
897 openingGcpLab(signal, filePtr);
898 break;
899 case FileRecord::OPENING_TABLE:
900 jam();
901 openingTableLab(signal, filePtr);
902 break;
903 case FileRecord::TABLE_CREATE:
904 jam();
905 tableCreateLab(signal, filePtr);
906 break;
907 case FileRecord::TABLE_OPEN_FOR_DELETE:
908 jam();
909 tableOpenLab(signal, filePtr);
910 break;
911 default:
912 ndbrequire(false);
913 break;
914 }//switch
915 return;
916 }//Dbdih::execFSOPENCONF()
917
execFSOPENREF(Signal * signal)918 void Dbdih::execFSOPENREF(Signal* signal)
919 {
920 FileRecordPtr filePtr;
921 jamEntry();
922 filePtr.i = signal->theData[0];
923 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
924 FileRecord::ReqStatus status = filePtr.p->reqStatus;
925 filePtr.p->reqStatus = FileRecord::IDLE;
926 switch (status) {
927 case FileRecord::CREATING_GCP:
928 /* --------------------------------------------------------------------- */
929 /* WE DID NOT MANAGE TO CREATE A GLOBAL CHECKPOINT FILE. SERIOUS ERROR */
930 /* WHICH CAUSES A SYSTEM RESTART. */
931 /* --------------------------------------------------------------------- */
932 jam();
933 break;
934 case FileRecord::OPENING_COPY_GCI:
935 jam();
936 openingCopyGciErrorLab(signal, filePtr);
937 return;
938 case FileRecord::CREATING_COPY_GCI:
939 jam();
940 break;
941 case FileRecord::OPENING_GCP:
942 jam();
943 openingGcpErrorLab(signal, filePtr);
944 return;
945 case FileRecord::OPENING_TABLE:
946 jam();
947 openingTableErrorLab(signal, filePtr);
948 return;
949 case FileRecord::TABLE_CREATE:
950 jam();
951 break;
952 case FileRecord::TABLE_OPEN_FOR_DELETE:
953 jam();
954 tableDeleteLab(signal, filePtr);
955 return;
956 default:
957 jam();
958 break;
959 }//switch
960 {
961 char msg[100];
962 sprintf(msg, "File system open failed during FileRecord status %d", (Uint32)status);
963 fsRefError(signal,__LINE__,msg);
964 }
965 return;
966 }//Dbdih::execFSOPENREF()
967
execFSREADCONF(Signal * signal)968 void Dbdih::execFSREADCONF(Signal* signal)
969 {
970 FileRecordPtr filePtr;
971 jamEntry();
972 filePtr.i = signal->theData[0];
973 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
974 FileRecord::ReqStatus status = filePtr.p->reqStatus;
975 filePtr.p->reqStatus = FileRecord::IDLE;
976 switch (status) {
977 case FileRecord::READING_GCP:
978 jam();
979 readingGcpLab(signal, filePtr);
980 break;
981 case FileRecord::READING_TABLE:
982 jam();
983 readingTableLab(signal, filePtr);
984 break;
985 default:
986 ndbrequire(false);
987 break;
988 }//switch
989 return;
990 }//Dbdih::execFSREADCONF()
991
execFSREADREF(Signal * signal)992 void Dbdih::execFSREADREF(Signal* signal)
993 {
994 FileRecordPtr filePtr;
995 jamEntry();
996 filePtr.i = signal->theData[0];
997 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
998 FileRecord::ReqStatus status = filePtr.p->reqStatus;
999 filePtr.p->reqStatus = FileRecord::IDLE;
1000 switch (status) {
1001 case FileRecord::READING_GCP:
1002 jam();
1003 readingGcpErrorLab(signal, filePtr);
1004 return;
1005 case FileRecord::READING_TABLE:
1006 jam();
1007 readingTableErrorLab(signal, filePtr);
1008 return;
1009 default:
1010 break;
1011 }//switch
1012 {
1013 char msg[100];
1014 sprintf(msg, "File system read failed during FileRecord status %d", (Uint32)status);
1015 fsRefError(signal,__LINE__,msg);
1016 }
1017 }//Dbdih::execFSREADREF()
1018
execFSWRITECONF(Signal * signal)1019 void Dbdih::execFSWRITECONF(Signal* signal)
1020 {
1021 FileRecordPtr filePtr;
1022 jamEntry();
1023 filePtr.i = signal->theData[0];
1024 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
1025 FileRecord::ReqStatus status = filePtr.p->reqStatus;
1026 filePtr.p->reqStatus = FileRecord::IDLE;
1027 switch (status) {
1028 case FileRecord::WRITING_COPY_GCI:
1029 jam();
1030 writingCopyGciLab(signal, filePtr);
1031 break;
1032 case FileRecord::WRITE_INIT_GCP:
1033 jam();
1034 writeInitGcpLab(signal, filePtr);
1035 break;
1036 case FileRecord::TABLE_WRITE:
1037 jam();
1038 tableWriteLab(signal, filePtr);
1039 break;
1040 default:
1041 ndbrequire(false);
1042 break;
1043 }//switch
1044 return;
1045 }//Dbdih::execFSWRITECONF()
1046
execFSWRITEREF(Signal * signal)1047 void Dbdih::execFSWRITEREF(Signal* signal)
1048 {
1049 FileRecordPtr filePtr;
1050 jamEntry();
1051 filePtr.i = signal->theData[0];
1052 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
1053 FileRecord::ReqStatus status = filePtr.p->reqStatus;
1054 filePtr.p->reqStatus = FileRecord::IDLE;
1055 switch (status) {
1056 case FileRecord::WRITING_COPY_GCI:
1057 /* --------------------------------------------------------------------- */
1058 /* EVEN CREATING THE FILE DID NOT WORK. WE WILL THEN CRASH. */
1059 /* ERROR IN WRITING FILE. WE WILL NOT CONTINUE FROM HERE. */
1060 /* --------------------------------------------------------------------- */
1061 jam();
1062 break;
1063 case FileRecord::WRITE_INIT_GCP:
1064 /* --------------------------------------------------------------------- */
1065 /* AN ERROR OCCURRED IN WRITING A GCI FILE WHICH IS A SERIOUS ERROR */
1066 /* THAT CAUSE A SYSTEM RESTART. */
1067 /* --------------------------------------------------------------------- */
1068 jam();
1069 break;
1070 case FileRecord::TABLE_WRITE:
1071 jam();
1072 break;
1073 default:
1074 jam();
1075 break;
1076 }//switch
1077 {
1078 char msg[100];
1079 sprintf(msg, "File system write failed during FileRecord status %d", (Uint32)status);
1080 fsRefError(signal,__LINE__,msg);
1081 }
1082 return;
1083 }//Dbdih::execFSWRITEREF()
1084
execGETGCIREQ(Signal * signal)1085 void Dbdih::execGETGCIREQ(Signal* signal)
1086 {
1087
1088 jamEntry();
1089 Uint32 userPtr = signal->theData[0];
1090 BlockReference userRef = signal->theData[1];
1091
1092 signal->theData[0] = userPtr;
1093 signal->theData[1] = SYSFILE->newestRestorableGCI;
1094 sendSignal(userRef, GSN_GETGCICONF, signal, 2, JBB);
1095 }//Dbdih::execGETGCIREQ()
1096
execREAD_CONFIG_REQ(Signal * signal)1097 void Dbdih::execREAD_CONFIG_REQ(Signal* signal)
1098 {
1099 const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
1100 Uint32 ref = req->senderRef;
1101 Uint32 senderData = req->senderData;
1102 ndbrequire(req->noOfParameters == 0);
1103
1104 jamEntry();
1105
1106 const ndb_mgm_configuration_iterator * p =
1107 m_ctx.m_config.getOwnConfigIterator();
1108 ndbrequireErr(p != 0, NDBD_EXIT_INVALID_CONFIG);
1109
1110 initData();
1111
1112 ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_API_CONNECT,
1113 &capiConnectFileSize),
1114 NDBD_EXIT_INVALID_CONFIG);
1115 ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_CONNECT,
1116 &cconnectFileSize),
1117 NDBD_EXIT_INVALID_CONFIG);
1118 ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_FRAG_CONNECT,
1119 &cfragstoreFileSize),
1120 NDBD_EXIT_INVALID_CONFIG);
1121 ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_REPLICAS,
1122 &creplicaFileSize),
1123 NDBD_EXIT_INVALID_CONFIG);
1124 ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_TABLE, &ctabFileSize),
1125 NDBD_EXIT_INVALID_CONFIG);
1126 cfileFileSize = (2 * ctabFileSize) + 2;
1127 initRecords();
1128 initialiseRecordsLab(signal, 0, ref, senderData);
1129 return;
1130 }//Dbdih::execSIZEALT_REP()
1131
execSTART_COPYREF(Signal * signal)1132 void Dbdih::execSTART_COPYREF(Signal* signal)
1133 {
1134 jamEntry();
1135 ndbrequire(false);
1136 }//Dbdih::execSTART_COPYREF()
1137
execSTART_FRAGCONF(Signal * signal)1138 void Dbdih::execSTART_FRAGCONF(Signal* signal)
1139 {
1140 (void)signal; // Don't want compiler warning
1141 /* ********************************************************************* */
1142 /* If anyone wants to add functionality in this method, be aware that */
1143 /* for temporary tables no START_FRAGREQ is sent and therefore no */
1144 /* START_FRAGCONF signal will be received for those tables!! */
1145 /* ********************************************************************* */
1146 jamEntry();
1147 return;
1148 }//Dbdih::execSTART_FRAGCONF()
1149
execSTART_FRAGREF(Signal * signal)1150 void Dbdih::execSTART_FRAGREF(Signal* signal)
1151 {
1152 jamEntry();
1153
1154 /**
1155 * Kill starting node
1156 */
1157 Uint32 errCode = signal->theData[1];
1158 Uint32 nodeId = signal->theData[2];
1159
1160 SystemError * const sysErr = (SystemError*)&signal->theData[0];
1161 sysErr->errorCode = SystemError::StartFragRefError;
1162 sysErr->errorRef = reference();
1163 sysErr->data1 = errCode;
1164 sysErr->data2 = 0;
1165 sendSignal(calcNdbCntrBlockRef(nodeId), GSN_SYSTEM_ERROR, signal,
1166 SystemError::SignalLength, JBB);
1167 return;
1168 }//Dbdih::execSTART_FRAGCONF()
1169
execSTART_MEREF(Signal * signal)1170 void Dbdih::execSTART_MEREF(Signal* signal)
1171 {
1172 jamEntry();
1173 ndbrequire(false);
1174 }//Dbdih::execSTART_MEREF()
1175
execTAB_COMMITREQ(Signal * signal)1176 void Dbdih::execTAB_COMMITREQ(Signal* signal)
1177 {
1178 TabRecordPtr tabPtr;
1179 jamEntry();
1180 Uint32 tdictPtr = signal->theData[0];
1181 BlockReference tdictBlockref = signal->theData[1];
1182 tabPtr.i = signal->theData[2];
1183 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
1184
1185 ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_CREATING);
1186 tabPtr.p->tabStatus = TabRecord::TS_ACTIVE;
1187 signal->theData[0] = tdictPtr;
1188 signal->theData[1] = cownNodeId;
1189 signal->theData[2] = tabPtr.i;
1190 sendSignal(tdictBlockref, GSN_TAB_COMMITCONF, signal, 3, JBB);
1191 return;
1192 }//Dbdih::execTAB_COMMITREQ()
1193
1194 /*
1195 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
1196 *************************************************************
1197 */
1198 /*
1199 3.2.1 S T A R T / R E S T A R T
1200 **********************************
1201 */
1202 /*****************************************************************************/
1203 /* ********** START / RESTART MODULE *************/
1204 /*****************************************************************************/
1205 /*
1206 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)
1207 *****************************************************************************
1208 */
execDIH_RESTARTREQ(Signal * signal)1209 void Dbdih::execDIH_RESTARTREQ(Signal* signal)
1210 {
1211 jamEntry();
1212 if (signal->theData[0])
1213 {
1214 jam();
1215 cntrlblockref = signal->theData[0];
1216 if(m_ctx.m_config.getInitialStart()){
1217 sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
1218 } else {
1219 readGciFileLab(signal);
1220 }
1221 }
1222 else
1223 {
1224 /**
1225 * Precondition, (not checked)
1226 * atleast 1 node in each node group
1227 */
1228 Uint32 i;
1229 NdbNodeBitmask mask;
1230 mask.assign(NdbNodeBitmask::Size, signal->theData + 1);
1231 Uint32 *node_gcis = signal->theData+1+NdbNodeBitmask::Size;
1232 Uint32 node_group_gcis[MAX_NDB_NODES+1];
1233 bzero(node_group_gcis, sizeof(node_group_gcis));
1234 for (i = 0; i<MAX_NDB_NODES; i++)
1235 {
1236 if (mask.get(i))
1237 {
1238 jam();
1239 Uint32 ng = Sysfile::getNodeGroup(i, SYSFILE->nodeGroups);
1240 ndbrequire(ng < MAX_NDB_NODES);
1241 Uint32 gci = node_gcis[i];
1242 if (gci < SYSFILE->lastCompletedGCI[i])
1243 {
1244 jam();
1245 /**
1246 * Handle case, where *I* know that node complete GCI
1247 * but node does not...bug#29167
1248 * i.e node died before it wrote own sysfile
1249 */
1250 gci = SYSFILE->lastCompletedGCI[i];
1251 }
1252
1253 if (gci > node_group_gcis[ng])
1254 {
1255 jam();
1256 node_group_gcis[ng] = gci;
1257 }
1258 }
1259 }
1260 for (i = 0; i<MAX_NDB_NODES && node_group_gcis[i] == 0; i++);
1261
1262 Uint32 gci = node_group_gcis[i];
1263 for (i++ ; i<MAX_NDB_NODES; i++)
1264 {
1265 jam();
1266 if (node_group_gcis[i] && node_group_gcis[i] != gci)
1267 {
1268 jam();
1269 signal->theData[0] = i;
1270 return;
1271 }
1272 }
1273 signal->theData[0] = MAX_NDB_NODES;
1274 return;
1275 }
1276 return;
1277 }//Dbdih::execDIH_RESTARTREQ()
1278
execSTTOR(Signal * signal)1279 void Dbdih::execSTTOR(Signal* signal)
1280 {
1281 jamEntry();
1282
1283 signal->theData[0] = 0;
1284 signal->theData[1] = 0;
1285 signal->theData[2] = 0;
1286 signal->theData[3] = 1; // Next start phase
1287 signal->theData[4] = 255; // Next start phase
1288 sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 5, JBB);
1289 return;
1290 }//Dbdih::execSTTOR()
1291
initialStartCompletedLab(Signal * signal)1292 void Dbdih::initialStartCompletedLab(Signal* signal)
1293 {
1294 /*-------------------------------------------------------------------------*/
1295 /* NOW THAT (RE)START IS COMPLETED WE CAN START THE LCP.*/
1296 /*-------------------------------------------------------------------------*/
1297 return;
1298 }//Dbdih::initialStartCompletedLab()
1299
1300 /*
1301 * ***************************************************************************
1302 * 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
1303 * ****************************************************************************
1304 */
ndbsttorry10Lab(Signal * signal,Uint32 _line)1305 void Dbdih::ndbsttorry10Lab(Signal* signal, Uint32 _line)
1306 {
1307 /*-------------------------------------------------------------------------*/
1308 // AN NDB START PHASE HAS BEEN COMPLETED. WHEN START PHASE 6 IS COMPLETED WE
1309 // RECORD THAT THE SYSTEM IS RUNNING.
1310 /*-------------------------------------------------------------------------*/
1311 signal->theData[0] = reference();
1312 sendSignal(cntrlblockref, GSN_NDB_STTORRY, signal, 1, JBB);
1313 return;
1314 }//Dbdih::ndbsttorry10Lab()
1315
1316 /*
1317 ****************************************
1318 I N T E R N A L P H A S E S
1319 ****************************************
1320 */
1321 /*---------------------------------------------------------------------------*/
1322 /*NDB_STTOR START SIGNAL AT START/RESTART */
1323 /*---------------------------------------------------------------------------*/
execNDB_STTOR(Signal * signal)1324 void Dbdih::execNDB_STTOR(Signal* signal)
1325 {
1326 jamEntry();
1327 BlockReference cntrRef = signal->theData[0]; /* SENDERS BLOCK REFERENCE */
1328 Uint32 ownNodeId = signal->theData[1]; /* OWN PROCESSOR ID*/
1329 Uint32 phase = signal->theData[2]; /* INTERNAL START PHASE*/
1330 Uint32 typestart = signal->theData[3];
1331
1332 cstarttype = typestart;
1333 cstartPhase = phase;
1334
1335 switch (phase){
1336 case ZNDB_SPH1:
1337 jam();
1338 /*----------------------------------------------------------------------*/
1339 /* Set the delay between local checkpoints in ndb startphase 1. */
1340 /*----------------------------------------------------------------------*/
1341 cownNodeId = ownNodeId;
1342 /*-----------------------------------------------------------------------*/
1343 // Compute all static block references in this node as part of
1344 // ndb start phase 1.
1345 /*-----------------------------------------------------------------------*/
1346 cntrlblockref = cntrRef;
1347 clocaltcblockref = calcTcBlockRef(ownNodeId);
1348 clocallqhblockref = calcLqhBlockRef(ownNodeId);
1349 cdictblockref = calcDictBlockRef(ownNodeId);
1350 ndbsttorry10Lab(signal, __LINE__);
1351 break;
1352
1353 case ZNDB_SPH2:
1354 jam();
1355 /*-----------------------------------------------------------------------*/
1356 // Set the number of replicas, maximum is 4 replicas.
1357 // Read the ndb nodes from the configuration.
1358 /*-----------------------------------------------------------------------*/
1359
1360 /*-----------------------------------------------------------------------*/
1361 // For node restarts we will also add a request for permission
1362 // to continue the system restart.
1363 // The permission is given by the master node in the alive set.
1364 /*-----------------------------------------------------------------------*/
1365 createMutexes(signal, 0);
1366 if (cstarttype == NodeState::ST_INITIAL_NODE_RESTART)
1367 {
1368 jam();
1369 c_set_initial_start_flag = TRUE; // In sysfile...
1370 }
1371 break;
1372
1373 case ZNDB_SPH3:
1374 jam();
1375 /*-----------------------------------------------------------------------*/
1376 // Non-master nodes performing an initial start will execute
1377 // the start request here since the
1378 // initial start do not synchronise so much from the master.
1379 // In the master nodes the start
1380 // request will be sent directly to dih (in ndb_startreq) when all
1381 // nodes have completed phase 3 of the start.
1382 /*-----------------------------------------------------------------------*/
1383 cmasterState = MASTER_IDLE;
1384 if(cstarttype == NodeState::ST_INITIAL_START ||
1385 cstarttype == NodeState::ST_SYSTEM_RESTART){
1386 jam();
1387 cmasterState = isMaster() ? MASTER_ACTIVE : MASTER_IDLE;
1388 }
1389 if (!isMaster() && cstarttype == NodeState::ST_INITIAL_START) {
1390 jam();
1391 ndbStartReqLab(signal, cntrRef);
1392 return;
1393 }//if
1394 ndbsttorry10Lab(signal, __LINE__);
1395 break;
1396
1397 case ZNDB_SPH4:
1398 jam();
1399 c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
1400 cmasterTakeOverNode = ZNIL;
1401 switch(typestart){
1402 case NodeState::ST_INITIAL_START:
1403 jam();
1404 ndbsttorry10Lab(signal, __LINE__);
1405 return;
1406 case NodeState::ST_SYSTEM_RESTART:
1407 jam();
1408 if (isMaster()) {
1409 jam();
1410 systemRestartTakeOverLab(signal);
1411 if (anyActiveTakeOver())
1412 {
1413 jam();
1414 return;
1415 }
1416 }
1417 ndbsttorry10Lab(signal, __LINE__);
1418 return;
1419 case NodeState::ST_INITIAL_NODE_RESTART:
1420 case NodeState::ST_NODE_RESTART:
1421 jam();
1422
1423 /***********************************************************************
1424 * When starting nodes while system is operational we must be controlled
1425 * by the master since only one node restart is allowed at a time.
1426 * When this signal is confirmed the master has also copied the
1427 * dictionary and the distribution information.
1428 */
1429 StartMeReq * req = (StartMeReq*)&signal->theData[0];
1430 req->startingRef = reference();
1431 req->startingVersion = 0; // Obsolete
1432 sendSignal(cmasterdihref, GSN_START_MEREQ, signal,
1433 StartMeReq::SignalLength, JBB);
1434 return;
1435 }
1436 ndbrequire(false);
1437 break;
1438 case ZNDB_SPH5:
1439 jam();
1440 switch(typestart){
1441 case NodeState::ST_INITIAL_START:
1442 case NodeState::ST_SYSTEM_RESTART:
1443 jam();
1444 jam();
1445 /*---------------------------------------------------------------------*/
1446 // WE EXECUTE A LOCAL CHECKPOINT AS A PART OF A SYSTEM RESTART.
1447 // THE IDEA IS THAT WE NEED TO
1448 // ENSURE THAT WE CAN RECOVER FROM PROBLEMS CAUSED BY MANY NODE
1449 // CRASHES THAT CAUSES THE LOG
1450 // TO GROW AND THE NUMBER OF LOG ROUNDS TO EXECUTE TO GROW.
1451 // THIS CAN OTHERWISE GET US INTO
1452 // A SITUATION WHICH IS UNREPAIRABLE. THUS WE EXECUTE A CHECKPOINT
1453 // BEFORE ALLOWING ANY TRANSACTIONS TO START.
1454 /*---------------------------------------------------------------------*/
1455 if (!isMaster()) {
1456 jam();
1457 ndbsttorry10Lab(signal, __LINE__);
1458 return;
1459 }//if
1460
1461 c_lcpState.immediateLcpStart = true;
1462 cwaitLcpSr = true;
1463 checkLcpStart(signal, __LINE__);
1464 return;
1465 case NodeState::ST_NODE_RESTART:
1466 case NodeState::ST_INITIAL_NODE_RESTART:
1467 jam();
1468 signal->theData[0] = cownNodeId;
1469 signal->theData[1] = reference();
1470 sendSignal(cmasterdihref, GSN_START_COPYREQ, signal, 2, JBB);
1471 return;
1472 }
1473 ndbrequire(false);
1474 case ZNDB_SPH6:
1475 jam();
1476 switch(typestart){
1477 case NodeState::ST_INITIAL_START:
1478 case NodeState::ST_SYSTEM_RESTART:
1479 jam();
1480 if(isMaster()){
1481 jam();
1482 startGcp(signal);
1483 }
1484 ndbsttorry10Lab(signal, __LINE__);
1485 return;
1486 case NodeState::ST_NODE_RESTART:
1487 case NodeState::ST_INITIAL_NODE_RESTART:
1488 ndbsttorry10Lab(signal, __LINE__);
1489 return;
1490 }
1491 ndbrequire(false);
1492 break;
1493 default:
1494 jam();
1495 ndbsttorry10Lab(signal, __LINE__);
1496 break;
1497 }//switch
1498 }//Dbdih::execNDB_STTOR()
1499
1500 void
execNODE_START_REP(Signal * signal)1501 Dbdih::execNODE_START_REP(Signal* signal)
1502 {
1503 /*
1504 * Send DICT_UNLOCK_ORD when this node is SL_STARTED.
1505 *
1506 * Sending it before (sp 7) conflicts with code which assumes
1507 * SL_STARTING means we are in copy phase of NR.
1508 *
1509 * NodeState::starting.restartType is not supposed to be used
1510 * when SL_STARTED. Also it seems NODE_START_REP can arrive twice.
1511 *
1512 * For these reasons there are no consistency checks and
1513 * we rely on c_dictLockSlavePtrI_nodeRestart alone.
1514 */
1515 if (c_dictLockSlavePtrI_nodeRestart != RNIL) {
1516 sendDictUnlockOrd(signal, c_dictLockSlavePtrI_nodeRestart);
1517 c_dictLockSlavePtrI_nodeRestart = RNIL;
1518 }
1519 }
1520
1521 void
createMutexes(Signal * signal,Uint32 count)1522 Dbdih::createMutexes(Signal * signal, Uint32 count){
1523 Callback c = { safe_cast(&Dbdih::createMutex_done), count };
1524
1525 switch(count){
1526 case 0:{
1527 Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
1528 mutex.create(c);
1529 return;
1530 }
1531 case 1:{
1532 Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
1533 mutex.create(c);
1534 return;
1535 }
1536 }
1537
1538 signal->theData[0] = reference();
1539 sendSignal(cntrlblockref, GSN_READ_NODESREQ, signal, 1, JBB);
1540 }
1541
1542 void
createMutex_done(Signal * signal,Uint32 senderData,Uint32 retVal)1543 Dbdih::createMutex_done(Signal* signal, Uint32 senderData, Uint32 retVal){
1544 jamEntry();
1545 ndbrequire(retVal == 0);
1546
1547 switch(senderData){
1548 case 0:{
1549 Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
1550 mutex.release();
1551 }
1552 case 1:{
1553 Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
1554 mutex.release();
1555 }
1556 }
1557
1558 createMutexes(signal, senderData + 1);
1559 }
1560
1561 /*****************************************************************************/
1562 /* ------------------------------------------------------------------------- */
1563 /* WE HAVE BEEN REQUESTED BY NDBCNTR TO PERFORM A RESTART OF THE */
1564 /* DATABASE TABLES. */
1565 /* THIS SIGNAL IS SENT AFTER COMPLETING PHASE 3 IN ALL BLOCKS IN A */
1566 /* SYSTEM RESTART. WE WILL ALSO JUMP TO THIS LABEL FROM PHASE 3 IN AN */
1567 /* INITIAL START. */
1568 /* ------------------------------------------------------------------------- */
1569 /*****************************************************************************/
execNDB_STARTREQ(Signal * signal)1570 void Dbdih::execNDB_STARTREQ(Signal* signal)
1571 {
1572 jamEntry();
1573 BlockReference ref = signal->theData[0];
1574 cstarttype = signal->theData[1];
1575 ndbStartReqLab(signal, ref);
1576 }//Dbdih::execNDB_STARTREQ()
1577
ndbStartReqLab(Signal * signal,BlockReference ref)1578 void Dbdih::ndbStartReqLab(Signal* signal, BlockReference ref)
1579 {
1580 cndbStartReqBlockref = ref;
1581 if (cstarttype == NodeState::ST_INITIAL_START) {
1582 jam();
1583 initRestartInfo();
1584 initGciFilesLab(signal);
1585 return;
1586 }
1587
1588 NodeRecordPtr nodePtr;
1589 Uint32 gci = SYSFILE->lastCompletedGCI[getOwnNodeId()];
1590 for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++)
1591 {
1592 jam();
1593 ptrAss(nodePtr, nodeRecord);
1594 if (SYSFILE->lastCompletedGCI[nodePtr.i] > gci)
1595 {
1596 jam();
1597 /**
1598 * Since we're starting(is master) and there
1599 * there are other nodes with higher GCI...
1600 * there gci's must be invalidated...
1601 * and they _must_ do an initial start
1602 * indicate this by setting lastCompletedGCI = 0
1603 */
1604 SYSFILE->lastCompletedGCI[nodePtr.i] = 0;
1605 ndbrequire(nodePtr.p->nodeStatus != NodeRecord::ALIVE);
1606 warningEvent("Making filesystem for node %d unusable (need --initial)",
1607 nodePtr.i);
1608 }
1609 else if (nodePtr.p->nodeStatus == NodeRecord::ALIVE &&
1610 SYSFILE->lastCompletedGCI[nodePtr.i] == 0)
1611 {
1612 jam();
1613 CRASH_INSERTION(7170);
1614 char buf[255];
1615 BaseString::snprintf(buf, sizeof(buf),
1616 "Cluster requires this node to be started "
1617 " with --initial as partial start has been performed"
1618 " and this filesystem is unusable");
1619 progError(__LINE__,
1620 NDBD_EXIT_SR_RESTARTCONFLICT,
1621 buf);
1622 ndbrequire(false);
1623 }
1624 }
1625
1626 /**
1627 * This set which GCI we will try to restart to
1628 */
1629 SYSFILE->newestRestorableGCI = gci;
1630
1631 ndbrequire(isMaster());
1632 copyGciLab(signal, CopyGCIReq::RESTART); // We have already read the file!
1633 }//Dbdih::ndbStartReqLab()
1634
execREAD_NODESCONF(Signal * signal)1635 void Dbdih::execREAD_NODESCONF(Signal* signal)
1636 {
1637 unsigned i;
1638 ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
1639 jamEntry();
1640 Uint32 nodeArray[MAX_NDB_NODES];
1641
1642 csystemnodes = readNodes->noOfNodes;
1643 cmasterNodeId = readNodes->masterNodeId;
1644 int index = 0;
1645 NdbNodeBitmask tmp; tmp.assign(2, readNodes->allNodes);
1646 for (i = 1; i < MAX_NDB_NODES; i++){
1647 jam();
1648 if(tmp.get(i)){
1649 jam();
1650 nodeArray[index] = i;
1651 if(NodeBitmask::get(readNodes->inactiveNodes, i) == false){
1652 jam();
1653 con_lineNodes++;
1654 }//if
1655 index++;
1656 }//if
1657 }//for
1658
1659 if(cstarttype == NodeState::ST_SYSTEM_RESTART ||
1660 cstarttype == NodeState::ST_NODE_RESTART){
1661
1662 for(i = 1; i<MAX_NDB_NODES; i++){
1663 const Uint32 stat = Sysfile::getNodeStatus(i, SYSFILE->nodeStatus);
1664 if(stat == Sysfile::NS_NotDefined && !tmp.get(i)){
1665 jam();
1666 continue;
1667 }
1668
1669 if(tmp.get(i) && stat != Sysfile::NS_NotDefined){
1670 jam();
1671 continue;
1672 }
1673 char buf[255];
1674 BaseString::snprintf(buf, sizeof(buf),
1675 "Illegal configuration change."
1676 " Initial start needs to be performed "
1677 " when changing no of storage nodes (node %d)", i);
1678 progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
1679 }
1680 }
1681
1682 ndbrequire(csystemnodes >= 1 && csystemnodes < MAX_NDB_NODES);
1683 if (cstarttype == NodeState::ST_INITIAL_START) {
1684 jam();
1685 ndbrequire(cnoReplicas <= csystemnodes);
1686 calculateHotSpare();
1687 ndbrequire(cnoReplicas <= (csystemnodes - cnoHotSpare));
1688 }//if
1689
1690 cmasterdihref = calcDihBlockRef(cmasterNodeId);
1691 /*-------------------------------------------------------------------------*/
1692 /* MAKE THE LIST OF PRN-RECORD WHICH IS ONE OF THE NODES-LIST IN THIS BLOCK*/
1693 /*-------------------------------------------------------------------------*/
1694 makePrnList(readNodes, nodeArray);
1695 if (cstarttype == NodeState::ST_INITIAL_START) {
1696 jam();
1697 /**----------------------------------------------------------------------
1698 * WHEN WE INITIALLY START A DATABASE WE WILL CREATE NODE GROUPS.
1699 * ALL NODES ARE PUT INTO NODE GROUPS ALTHOUGH HOT SPARE NODES ARE PUT
1700 * INTO A SPECIAL NODE GROUP. IN EACH NODE GROUP WE HAVE THE SAME AMOUNT
1701 * OF NODES AS THERE ARE NUMBER OF REPLICAS.
1702 * ONE POSSIBLE USAGE OF NODE GROUPS ARE TO MAKE A NODE GROUP A COMPLETE
1703 * FRAGMENT OF THE DATABASE. THIS MEANS THAT ALL REPLICAS WILL BE STORED
1704 * IN THE NODE GROUP.
1705 *-----------------------------------------------------------------------*/
1706 makeNodeGroups(nodeArray);
1707 }//if
1708 ndbrequire(checkNodeAlive(cmasterNodeId));
1709 if (cstarttype == NodeState::ST_INITIAL_START) {
1710 jam();
1711 /**-----------------------------------------------------------------------
1712 * INITIALISE THE SECOND NODE-LIST AND SET NODE BITS AND SOME NODE STATUS.
1713 * VERY CONNECTED WITH MAKE_NODE_GROUPS. CHANGING ONE WILL AFFECT THE
1714 * OTHER AS WELL.
1715 *-----------------------------------------------------------------------*/
1716 setInitialActiveStatus();
1717 } else if (cstarttype == NodeState::ST_SYSTEM_RESTART) {
1718 jam();
1719 /*empty*/;
1720 } else if ((cstarttype == NodeState::ST_NODE_RESTART) ||
1721 (cstarttype == NodeState::ST_INITIAL_NODE_RESTART)) {
1722 jam();
1723 nodeRestartPh2Lab(signal);
1724 return;
1725 } else {
1726 ndbrequire(false);
1727 }//if
1728 /**------------------------------------------------------------------------
1729 * ESTABLISH CONNECTIONS WITH THE OTHER DIH BLOCKS AND INITIALISE THIS
1730 * NODE-LIST THAT HANDLES CONNECTION WITH OTHER DIH BLOCKS.
1731 *-------------------------------------------------------------------------*/
1732 ndbsttorry10Lab(signal, __LINE__);
1733 }//Dbdih::execREAD_NODESCONF()
1734
1735 /*---------------------------------------------------------------------------*/
1736 /* START NODE LOGIC FOR NODE RESTART */
1737 /*---------------------------------------------------------------------------*/
nodeRestartPh2Lab(Signal * signal)1738 void Dbdih::nodeRestartPh2Lab(Signal* signal)
1739 {
1740 /*
1741 * Lock master DICT to avoid metadata operations during INR/NR.
1742 * Done just before START_PERMREQ.
1743 *
1744 * It would be more elegant to do this just before START_MEREQ.
1745 * The problem is, on INR we end up in massive invalidateNodeLCP
1746 * which is not fully protected against metadata ops.
1747 */
1748 ndbrequire(c_dictLockSlavePtrI_nodeRestart == RNIL);
1749
1750 // check that we are not yet taking part in schema ops
1751 CRASH_INSERTION(7174);
1752
1753 Uint32 lockType = DictLockReq::NodeRestartLock;
1754 Callback c = { safe_cast(&Dbdih::recvDictLockConf_nodeRestart), 0 };
1755 sendDictLockReq(signal, lockType, c);
1756 }
1757
recvDictLockConf_nodeRestart(Signal * signal,Uint32 data,Uint32 ret)1758 void Dbdih::recvDictLockConf_nodeRestart(Signal* signal, Uint32 data, Uint32 ret)
1759 {
1760 ndbrequire(c_dictLockSlavePtrI_nodeRestart == RNIL);
1761 ndbrequire(data != RNIL);
1762 c_dictLockSlavePtrI_nodeRestart = data;
1763
1764 nodeRestartPh2Lab2(signal);
1765 }
1766
nodeRestartPh2Lab2(Signal * signal)1767 void Dbdih::nodeRestartPh2Lab2(Signal* signal)
1768 {
1769 /*------------------------------------------------------------------------*/
1770 // REQUEST FOR PERMISSION FROM MASTER TO START A NODE IN AN ALREADY
1771 // RUNNING SYSTEM.
1772 /*------------------------------------------------------------------------*/
1773 StartPermReq * const req = (StartPermReq *)&signal->theData[0];
1774
1775 req->blockRef = reference();
1776 req->nodeId = cownNodeId;
1777 req->startType = cstarttype;
1778 sendSignal(cmasterdihref, GSN_START_PERMREQ, signal, 3, JBB);
1779 }
1780
execSTART_PERMCONF(Signal * signal)1781 void Dbdih::execSTART_PERMCONF(Signal* signal)
1782 {
1783 jamEntry();
1784 CRASH_INSERTION(7121);
1785 Uint32 nodeId = signal->theData[0];
1786 cfailurenr = signal->theData[1];
1787 ndbrequire(nodeId == cownNodeId);
1788 ndbsttorry10Lab(signal, __LINE__);
1789 }//Dbdih::execSTART_PERMCONF()
1790
execSTART_PERMREF(Signal * signal)1791 void Dbdih::execSTART_PERMREF(Signal* signal)
1792 {
1793 jamEntry();
1794 Uint32 errorCode = signal->theData[1];
1795 if (errorCode == StartPermRef::ZNODE_ALREADY_STARTING_ERROR ||
1796 errorCode == StartPermRef::ZNODE_START_DISALLOWED_ERROR) {
1797 jam();
1798 /*-----------------------------------------------------------------------*/
1799 // The master was busy adding another node. We will wait for a second and
1800 // try again.
1801 /*-----------------------------------------------------------------------*/
1802 signal->theData[0] = DihContinueB::ZSTART_PERMREQ_AGAIN;
1803 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 3000, 1);
1804 return;
1805 }//if
1806
1807 if (errorCode == StartPermRef::InitialStartRequired)
1808 {
1809 CRASH_INSERTION(7170);
1810 char buf[255];
1811 BaseString::snprintf(buf, sizeof(buf),
1812 "Cluster requires this node to be started "
1813 " with --initial as partial start has been performed"
1814 " and this filesystem is unusable");
1815 progError(__LINE__,
1816 NDBD_EXIT_SR_RESTARTCONFLICT,
1817 buf);
1818 ndbrequire(false);
1819 }
1820 /*------------------------------------------------------------------------*/
1821 // Some node process in another node involving our node was still active. We
1822 // will recover from this by crashing here.
1823 // This is controlled restart using the
1824 // already existing features of node crashes. It is not a bug getting here.
1825 /*-------------------------------------------------------------------------*/
1826 ndbrequire(false);
1827 return;
1828 }//Dbdih::execSTART_PERMREF()
1829
1830 /*---------------------------------------------------------------------------*/
1831 /* THIS SIGNAL IS RECEIVED IN THE STARTING NODE WHEN THE START_MEREQ */
1832 /* HAS BEEN EXECUTED IN THE MASTER NODE. */
1833 /*---------------------------------------------------------------------------*/
execSTART_MECONF(Signal * signal)1834 void Dbdih::execSTART_MECONF(Signal* signal)
1835 {
1836 jamEntry();
1837 StartMeConf * const startMe = (StartMeConf *)&signal->theData[0];
1838 Uint32 nodeId = startMe->startingNodeId;
1839 const Uint32 startWord = startMe->startWord;
1840 Uint32 i;
1841
1842 CRASH_INSERTION(7130);
1843 ndbrequire(nodeId == cownNodeId);
1844 arrGuard(startWord + StartMeConf::DATA_SIZE, sizeof(cdata)/4);
1845 for(i = 0; i < StartMeConf::DATA_SIZE; i++)
1846 cdata[startWord+i] = startMe->data[i];
1847
1848 if(startWord + StartMeConf::DATA_SIZE < Sysfile::SYSFILE_SIZE32){
1849 jam();
1850 /**
1851 * We are still waiting for data
1852 */
1853 return;
1854 }
1855 jam();
1856
1857 /**
1858 * Copy into sysfile
1859 *
1860 * But dont copy lastCompletedGCI:s
1861 */
1862 Uint32 key = SYSFILE->m_restart_seq;
1863 Uint32 tempGCP[MAX_NDB_NODES];
1864 for(i = 0; i < MAX_NDB_NODES; i++)
1865 tempGCP[i] = SYSFILE->lastCompletedGCI[i];
1866
1867 for(i = 0; i < Sysfile::SYSFILE_SIZE32; i++)
1868 sysfileData[i] = cdata[i];
1869
1870 SYSFILE->m_restart_seq = key;
1871 for(i = 0; i < MAX_NDB_NODES; i++)
1872 SYSFILE->lastCompletedGCI[i] = tempGCP[i];
1873
1874 setNodeActiveStatus();
1875 setNodeGroups();
1876 ndbsttorry10Lab(signal, __LINE__);
1877 }//Dbdih::execSTART_MECONF()
1878
execSTART_COPYCONF(Signal * signal)1879 void Dbdih::execSTART_COPYCONF(Signal* signal)
1880 {
1881 jamEntry();
1882 Uint32 nodeId = signal->theData[0];
1883 ndbrequire(nodeId == cownNodeId);
1884 CRASH_INSERTION(7132);
1885 ndbsttorry10Lab(signal, __LINE__);
1886 return;
1887 }//Dbdih::execSTART_COPYCONF()
1888
1889 /*---------------------------------------------------------------------------*/
1890 /* MASTER LOGIC FOR NODE RESTART */
1891 /*---------------------------------------------------------------------------*/
1892 /* NODE RESTART PERMISSION REQUEST */
1893 /*---------------------------------------------------------------------------*/
1894 // A REQUEST FROM A STARTING NODE TO PERFORM A NODE RESTART. IF NO OTHER NODE
1895 // IS ACTIVE IN PERFORMING A NODE RESTART AND THERE ARE NO ACTIVE PROCESSES IN
1896 // THIS NODE INVOLVING THE STARTING NODE THIS REQUEST WILL BE GRANTED.
1897 /*---------------------------------------------------------------------------*/
execSTART_PERMREQ(Signal * signal)1898 void Dbdih::execSTART_PERMREQ(Signal* signal)
1899 {
1900 StartPermReq * const req = (StartPermReq*)&signal->theData[0];
1901 jamEntry();
1902 const BlockReference retRef = req->blockRef;
1903 const Uint32 nodeId = req->nodeId;
1904 const Uint32 typeStart = req->startType;
1905 CRASH_INSERTION(7122);
1906 ndbrequire(isMaster());
1907 ndbrequire(refToNode(retRef) == nodeId);
1908 if ((c_nodeStartMaster.activeState) ||
1909 (c_nodeStartMaster.wait != ZFALSE) ||
1910 ERROR_INSERTED_CLEAR(7175)) {
1911 jam();
1912 signal->theData[0] = nodeId;
1913 signal->theData[1] = StartPermRef::ZNODE_ALREADY_STARTING_ERROR;
1914 sendSignal(retRef, GSN_START_PERMREF, signal, 2, JBB);
1915 return;
1916 }//if
1917 if (getNodeStatus(nodeId) != NodeRecord::DEAD){
1918 g_eventLogger.error("nodeStatus in START_PERMREQ = %u",
1919 (Uint32) getNodeStatus(nodeId));
1920 ndbrequire(false);
1921 }//if
1922
1923 if (SYSFILE->lastCompletedGCI[nodeId] == 0 &&
1924 typeStart != NodeState::ST_INITIAL_NODE_RESTART)
1925 {
1926 jam();
1927 signal->theData[0] = nodeId;
1928 signal->theData[1] = StartPermRef::InitialStartRequired;
1929 sendSignal(retRef, GSN_START_PERMREF, signal, 2, JBB);
1930 return;
1931 }
1932
1933 /*----------------------------------------------------------------------
1934 * WE START THE INCLUSION PROCEDURE
1935 * ---------------------------------------------------------------------*/
1936 c_nodeStartMaster.failNr = cfailurenr;
1937 c_nodeStartMaster.wait = ZFALSE;
1938 c_nodeStartMaster.startInfoErrorCode = 0;
1939 c_nodeStartMaster.startNode = nodeId;
1940 c_nodeStartMaster.activeState = true;
1941 c_nodeStartMaster.m_outstandingGsn = GSN_START_INFOREQ;
1942
1943 setNodeStatus(nodeId, NodeRecord::STARTING);
1944 /**
1945 * But if it's a NodeState::ST_INITIAL_NODE_RESTART
1946 *
1947 * We first have to clear LCP's
1948 * For normal node restart we simply ensure that all nodes
1949 * are informed of the node restart
1950 */
1951 StartInfoReq *const r =(StartInfoReq*)&signal->theData[0];
1952 r->startingNodeId = nodeId;
1953 r->typeStart = typeStart;
1954 r->systemFailureNo = cfailurenr;
1955 sendLoopMacro(START_INFOREQ, sendSTART_INFOREQ);
1956 }//Dbdih::execSTART_PERMREQ()
1957
execSTART_INFOREF(Signal * signal)1958 void Dbdih::execSTART_INFOREF(Signal* signal)
1959 {
1960 StartInfoRef * ref = (StartInfoRef*)&signal->theData[0];
1961 if (getNodeStatus(ref->startingNodeId) != NodeRecord::STARTING) {
1962 jam();
1963 return;
1964 }//if
1965 ndbrequire(c_nodeStartMaster.startNode == ref->startingNodeId);
1966 c_nodeStartMaster.startInfoErrorCode = ref->errorCode;
1967 startInfoReply(signal, ref->sendingNodeId);
1968 }//Dbdih::execSTART_INFOREF()
1969
execSTART_INFOCONF(Signal * signal)1970 void Dbdih::execSTART_INFOCONF(Signal* signal)
1971 {
1972 jamEntry();
1973 StartInfoConf * conf = (StartInfoConf*)&signal->theData[0];
1974 if (getNodeStatus(conf->startingNodeId) != NodeRecord::STARTING) {
1975 jam();
1976 return;
1977 }//if
1978 ndbrequire(c_nodeStartMaster.startNode == conf->startingNodeId);
1979 startInfoReply(signal, conf->sendingNodeId);
1980 }//Dbdih::execSTART_INFOCONF()
1981
startInfoReply(Signal * signal,Uint32 nodeId)1982 void Dbdih::startInfoReply(Signal* signal, Uint32 nodeId)
1983 {
1984 receiveLoopMacro(START_INFOREQ, nodeId);
1985 /**
1986 * We're finished with the START_INFOREQ's
1987 */
1988 if (c_nodeStartMaster.startInfoErrorCode == 0) {
1989 jam();
1990 /**
1991 * Everything has been a success so far
1992 */
1993 StartPermConf * conf = (StartPermConf*)&signal->theData[0];
1994 conf->startingNodeId = c_nodeStartMaster.startNode;
1995 conf->systemFailureNo = cfailurenr;
1996 sendSignal(calcDihBlockRef(c_nodeStartMaster.startNode),
1997 GSN_START_PERMCONF, signal, StartPermConf::SignalLength, JBB);
1998 c_nodeStartMaster.m_outstandingGsn = GSN_START_PERMCONF;
1999 } else {
2000 jam();
2001 StartPermRef * ref = (StartPermRef*)&signal->theData[0];
2002 ref->startingNodeId = c_nodeStartMaster.startNode;
2003 ref->errorCode = c_nodeStartMaster.startInfoErrorCode;
2004 sendSignal(calcDihBlockRef(c_nodeStartMaster.startNode),
2005 GSN_START_PERMREF, signal, StartPermRef::SignalLength, JBB);
2006 nodeResetStart();
2007 }//if
2008 }//Dbdih::startInfoReply()
2009
2010 /*---------------------------------------------------------------------------*/
2011 /* NODE RESTART CONTINUE REQUEST */
2012 /*---------------------------------------------------------------------------*/
2013 // THIS SIGNAL AND THE CODE BELOW IS EXECUTED BY THE MASTER WHEN IT HAS BEEN
2014 // REQUESTED TO START UP A NEW NODE. The master instructs the starting node
2015 // how to set up its log for continued execution.
2016 /*---------------------------------------------------------------------------*/
execSTART_MEREQ(Signal * signal)2017 void Dbdih::execSTART_MEREQ(Signal* signal)
2018 {
2019 StartMeReq * req = (StartMeReq*)&signal->theData[0];
2020 jamEntry();
2021 const BlockReference Tblockref = req->startingRef;
2022 const Uint32 Tnodeid = refToNode(Tblockref);
2023
2024 ndbrequire(isMaster());
2025 ndbrequire(c_nodeStartMaster.startNode == Tnodeid);
2026 ndbrequire(getNodeStatus(Tnodeid) == NodeRecord::STARTING);
2027
2028 c_nodeStartMaster.blockLcp = true;
2029 if ((c_lcpState.lcpStatus != LCP_STATUS_IDLE) &&
2030 (c_lcpState.lcpStatus != LCP_TCGET)) {
2031 jam();
2032 /*-----------------------------------------------------------------------*/
2033 // WE WILL NOT ALLOW A NODE RESTART TO COME IN WHEN A LOCAL CHECKPOINT IS
2034 // ONGOING. IT WOULD COMPLICATE THE LCP PROTOCOL TOO MUCH. WE WILL ADD THIS
2035 // LATER.
2036 /*-----------------------------------------------------------------------*/
2037 return;
2038 }//if
2039 lcpBlockedLab(signal);
2040 }//Dbdih::nodeRestartStartRecConfLab()
2041
lcpBlockedLab(Signal * signal)2042 void Dbdih::lcpBlockedLab(Signal* signal)
2043 {
2044 ndbrequire(getNodeStatus(c_nodeStartMaster.startNode)==NodeRecord::STARTING);
2045 /*------------------------------------------------------------------------*/
2046 // NOW WE HAVE COPIED ALL INFORMATION IN DICT WE ARE NOW READY TO COPY ALL
2047 // INFORMATION IN DIH TO THE NEW NODE.
2048 /*------------------------------------------------------------------------*/
2049 c_nodeStartMaster.wait = 10;
2050 signal->theData[0] = DihContinueB::ZCOPY_NODE;
2051 signal->theData[1] = 0;
2052 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
2053 c_nodeStartMaster.m_outstandingGsn = GSN_COPY_TABREQ;
2054 }//Dbdih::lcpBlockedLab()
2055
nodeDictStartConfLab(Signal * signal)2056 void Dbdih::nodeDictStartConfLab(Signal* signal)
2057 {
2058 /*-------------------------------------------------------------------------*/
2059 // NOW WE HAVE COPIED BOTH DIH AND DICT INFORMATION. WE ARE NOW READY TO
2060 // INTEGRATE THE NODE INTO THE LCP AND GCP PROTOCOLS AND TO ALLOW UPDATES OF
2061 // THE DICTIONARY AGAIN.
2062 /*-------------------------------------------------------------------------*/
2063 c_nodeStartMaster.wait = ZFALSE;
2064 c_nodeStartMaster.blockGcp = true;
2065 if (cgcpStatus != GCP_READY) {
2066 /*-----------------------------------------------------------------------*/
2067 // The global checkpoint is executing. Wait until it is completed before we
2068 // continue processing the node recovery.
2069 /*-----------------------------------------------------------------------*/
2070 jam();
2071 return;
2072 }//if
2073 gcpBlockedLab(signal);
2074
2075 /*-----------------------------------------------------------------*/
2076 // Report that node restart has completed copy of dictionary.
2077 /*-----------------------------------------------------------------*/
2078 signal->theData[0] = NDB_LE_NR_CopyDict;
2079 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
2080 }//Dbdih::nodeDictStartConfLab()
2081
dihCopyCompletedLab(Signal * signal)2082 void Dbdih::dihCopyCompletedLab(Signal* signal)
2083 {
2084 BlockReference ref = calcDictBlockRef(c_nodeStartMaster.startNode);
2085 DictStartReq * req = (DictStartReq*)&signal->theData[0];
2086 req->restartGci = cnewgcp;
2087 req->senderRef = reference();
2088 sendSignal(ref, GSN_DICTSTARTREQ,
2089 signal, DictStartReq::SignalLength, JBB);
2090 c_nodeStartMaster.m_outstandingGsn = GSN_DICTSTARTREQ;
2091 c_nodeStartMaster.wait = 0;
2092 }//Dbdih::dihCopyCompletedLab()
2093
gcpBlockedLab(Signal * signal)2094 void Dbdih::gcpBlockedLab(Signal* signal)
2095 {
2096 /*-----------------------------------------------------------------*/
2097 // Report that node restart has completed copy of distribution info.
2098 /*-----------------------------------------------------------------*/
2099 signal->theData[0] = NDB_LE_NR_CopyDistr;
2100 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
2101
2102 /**
2103 * The node DIH will be part of LCP
2104 */
2105 NodeRecordPtr nodePtr;
2106 nodePtr.i = c_nodeStartMaster.startNode;
2107 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
2108 nodePtr.p->m_inclDihLcp = true;
2109
2110 /*-------------------------------------------------------------------------*/
2111 // NOW IT IS TIME TO INFORM ALL OTHER NODES IN THE CLUSTER OF THE STARTED
2112 // NODE SUCH THAT THEY ALSO INCLUDE THE NODE IN THE NODE LISTS AND SO FORTH.
2113 /*------------------------------------------------------------------------*/
2114 sendLoopMacro(INCL_NODEREQ, sendINCL_NODEREQ);
2115 /*-------------------------------------------------------------------------*/
2116 // We also need to send to the starting node to ensure he is aware of the
2117 // global checkpoint id and the correct state. We do not wait for any reply
2118 // since the starting node will not send any.
2119 /*-------------------------------------------------------------------------*/
2120 Uint32 startVersion = getNodeInfo(c_nodeStartMaster.startNode).m_version;
2121
2122 if ((getMajor(startVersion) == 4 &&
2123 startVersion >= NDBD_INCL_NODECONF_VERSION_4) ||
2124 (getMajor(startVersion) == 5 &&
2125 startVersion >= NDBD_INCL_NODECONF_VERSION_5) ||
2126 (getMajor(startVersion) > 5))
2127 {
2128 c_INCL_NODEREQ_Counter.setWaitingFor(c_nodeStartMaster.startNode);
2129 }
2130
2131 sendINCL_NODEREQ(signal, c_nodeStartMaster.startNode);
2132 }//Dbdih::gcpBlockedLab()
2133
2134 /*---------------------------------------------------------------------------*/
2135 // THIS SIGNAL IS EXECUTED IN BOTH SLAVES AND IN THE MASTER
2136 /*---------------------------------------------------------------------------*/
execINCL_NODECONF(Signal * signal)2137 void Dbdih::execINCL_NODECONF(Signal* signal)
2138 {
2139 jamEntry();
2140 Uint32 TstartNode = signal->theData[0];
2141 Uint32 TsendNodeId_or_blockref = signal->theData[1];
2142
2143 Uint32 blocklist[6];
2144 blocklist[0] = clocallqhblockref;
2145 blocklist[1] = clocaltcblockref;
2146 blocklist[2] = cdictblockref;
2147 blocklist[3] = numberToRef(BACKUP, getOwnNodeId());
2148 blocklist[4] = numberToRef(SUMA, getOwnNodeId());
2149 blocklist[5] = 0;
2150
2151 for (Uint32 i = 0; blocklist[i] != 0; i++)
2152 {
2153 if (TsendNodeId_or_blockref == blocklist[i])
2154 {
2155 jam();
2156
2157 if (TstartNode != c_nodeStartSlave.nodeId)
2158 {
2159 jam();
2160 warningEvent("Recevied INCL_NODECONF for %u from %s"
2161 " while %u is starting",
2162 TstartNode,
2163 getBlockName(refToBlock(TsendNodeId_or_blockref)),
2164 c_nodeStartSlave.nodeId);
2165 return;
2166 }
2167
2168 if (getNodeStatus(c_nodeStartSlave.nodeId) == NodeRecord::ALIVE &&
2169 blocklist[i+1] != 0)
2170 {
2171 /**
2172 * Send to next in block list
2173 */
2174 jam();
2175 signal->theData[0] = reference();
2176 signal->theData[1] = c_nodeStartSlave.nodeId;
2177 sendSignal(blocklist[i+1], GSN_INCL_NODEREQ, signal, 2, JBB);
2178 return;
2179 }
2180 else
2181 {
2182 /**
2183 * All done, reply to master
2184 */
2185 jam();
2186 signal->theData[0] = c_nodeStartSlave.nodeId;
2187 signal->theData[1] = cownNodeId;
2188 sendSignal(cmasterdihref, GSN_INCL_NODECONF, signal, 2, JBB);
2189
2190 c_nodeStartSlave.nodeId = 0;
2191 return;
2192 }
2193 }
2194 }
2195
2196 if (c_nodeStartMaster.startNode != TstartNode)
2197 {
2198 jam();
2199 warningEvent("Recevied INCL_NODECONF for %u from %u"
2200 " while %u is starting",
2201 TstartNode,
2202 TsendNodeId_or_blockref,
2203 c_nodeStartMaster.startNode);
2204 return;
2205 }
2206
2207 ndbrequire(cmasterdihref = reference());
2208 receiveLoopMacro(INCL_NODEREQ, TsendNodeId_or_blockref);
2209
2210 CRASH_INSERTION(7128);
2211 /*-------------------------------------------------------------------------*/
2212 // Now that we have included the starting node in the node lists in the
2213 // various blocks we are ready to start the global checkpoint protocol
2214 /*------------------------------------------------------------------------*/
2215 c_nodeStartMaster.wait = 11;
2216 c_nodeStartMaster.blockGcp = false;
2217
2218 signal->theData[0] = reference();
2219 sendSignal(reference(), GSN_UNBLO_DICTCONF, signal, 1, JBB);
2220 }//Dbdih::execINCL_NODECONF()
2221
execUNBLO_DICTCONF(Signal * signal)2222 void Dbdih::execUNBLO_DICTCONF(Signal* signal)
2223 {
2224 jamEntry();
2225 c_nodeStartMaster.wait = ZFALSE;
2226 if (!c_nodeStartMaster.activeState) {
2227 jam();
2228 return;
2229 }//if
2230
2231 CRASH_INSERTION(7129);
2232 /**-----------------------------------------------------------------------
2233 * WE HAVE NOW PREPARED IT FOR INCLUSION IN THE LCP PROTOCOL.
2234 * WE CAN NOW START THE LCP PROTOCOL AGAIN.
2235 * WE HAVE ALSO MADE THIS FOR THE GCP PROTOCOL.
2236 * WE ARE READY TO START THE PROTOCOLS AND RESPOND TO THE START REQUEST
2237 * FROM THE STARTING NODE.
2238 *------------------------------------------------------------------------*/
2239
2240 StartMeConf * const startMe = (StartMeConf *)&signal->theData[0];
2241
2242 const Uint32 wordPerSignal = StartMeConf::DATA_SIZE;
2243 const int noOfSignals = ((Sysfile::SYSFILE_SIZE32 + (wordPerSignal - 1)) /
2244 wordPerSignal);
2245
2246 startMe->startingNodeId = c_nodeStartMaster.startNode;
2247 startMe->startWord = 0;
2248
2249 const Uint32 ref = calcDihBlockRef(c_nodeStartMaster.startNode);
2250 for(int i = 0; i < noOfSignals; i++){
2251 jam();
2252 { // Do copy
2253 const int startWord = startMe->startWord;
2254 for(Uint32 j = 0; j < wordPerSignal; j++){
2255 startMe->data[j] = sysfileData[j+startWord];
2256 }
2257 }
2258 sendSignal(ref, GSN_START_MECONF, signal, StartMeConf::SignalLength, JBB);
2259 startMe->startWord += wordPerSignal;
2260 }//for
2261 c_nodeStartMaster.m_outstandingGsn = GSN_START_MECONF;
2262 }//Dbdih::execUNBLO_DICTCONF()
2263
2264 /*---------------------------------------------------------------------------*/
2265 /* NODE RESTART COPY REQUEST */
2266 /*---------------------------------------------------------------------------*/
2267 // A NODE RESTART HAS REACHED ITS FINAL PHASE WHEN THE DATA IS TO BE COPIED
2268 // TO THE NODE. START_COPYREQ IS EXECUTED BY THE MASTER NODE.
2269 /*---------------------------------------------------------------------------*/
execSTART_COPYREQ(Signal * signal)2270 void Dbdih::execSTART_COPYREQ(Signal* signal)
2271 {
2272 jamEntry();
2273 Uint32 startNodeId = signal->theData[0];
2274 //BlockReference startingRef = signal->theData[1];
2275 ndbrequire(c_nodeStartMaster.startNode == startNodeId);
2276 /*-------------------------------------------------------------------------*/
2277 // REPORT Copy process of node restart is now about to start up.
2278 /*-------------------------------------------------------------------------*/
2279 signal->theData[0] = NDB_LE_NR_CopyFragsStarted;
2280 signal->theData[1] = startNodeId;
2281 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
2282
2283 CRASH_INSERTION(7131);
2284 nodeRestartTakeOver(signal, startNodeId);
2285 // BlockReference ref = calcQmgrBlockRef(startNodeId);
2286 // signal->theData[0] = cownNodeId;
2287 // Remove comments as soon as I open up the Qmgr block
2288 // TODO_RONM
2289 // sendSignal(ref, GSN_ALLOW_NODE_CRASHORD, signal, 1, JBB);
2290 }//Dbdih::execSTART_COPYREQ()
2291
2292 /*---------------------------------------------------------------------------*/
2293 /* SLAVE LOGIC FOR NODE RESTART */
2294 /*---------------------------------------------------------------------------*/
execSTART_INFOREQ(Signal * signal)2295 void Dbdih::execSTART_INFOREQ(Signal* signal)
2296 {
2297 jamEntry();
2298 StartInfoReq *const req =(StartInfoReq*)&signal->theData[0];
2299 Uint32 startNode = req->startingNodeId;
2300 if (cfailurenr != req->systemFailureNo) {
2301 jam();
2302 //---------------------------------------------------------------
2303 // A failure occurred since master sent this request. We will ignore
2304 // this request since the node is already dead that is starting.
2305 //---------------------------------------------------------------
2306 return;
2307 }//if
2308 CRASH_INSERTION(7123);
2309 if (isMaster()) {
2310 jam();
2311 ndbrequire(getNodeStatus(startNode) == NodeRecord::STARTING);
2312 } else {
2313 jam();
2314 ndbrequire(getNodeStatus(startNode) == NodeRecord::DEAD);
2315 }//if
2316 if ((!getAllowNodeStart(startNode)) ||
2317 (c_nodeStartSlave.nodeId != 0) ||
2318 (ERROR_INSERTED(7124))) {
2319 jam();
2320 StartInfoRef *const ref =(StartInfoRef*)&signal->theData[0];
2321 ref->startingNodeId = startNode;
2322 ref->sendingNodeId = cownNodeId;
2323 ref->errorCode = StartPermRef::ZNODE_START_DISALLOWED_ERROR;
2324 sendSignal(cmasterdihref, GSN_START_INFOREF, signal,
2325 StartInfoRef::SignalLength, JBB);
2326 return;
2327 }//if
2328 setNodeStatus(startNode, NodeRecord::STARTING);
2329 if (req->typeStart == NodeState::ST_INITIAL_NODE_RESTART) {
2330 jam();
2331 setAllowNodeStart(startNode, false);
2332 invalidateNodeLCP(signal, startNode, 0);
2333 } else {
2334 jam();
2335 StartInfoConf * c = (StartInfoConf*)&signal->theData[0];
2336 c->sendingNodeId = cownNodeId;
2337 c->startingNodeId = startNode;
2338 sendSignal(cmasterdihref, GSN_START_INFOCONF, signal,
2339 StartInfoConf::SignalLength, JBB);
2340 return;
2341 }//if
2342 }//Dbdih::execSTART_INFOREQ()
2343
execINCL_NODEREQ(Signal * signal)2344 void Dbdih::execINCL_NODEREQ(Signal* signal)
2345 {
2346 jamEntry();
2347 Uint32 retRef = signal->theData[0];
2348 Uint32 nodeId = signal->theData[1];
2349 if (nodeId == getOwnNodeId() && ERROR_INSERTED(7165))
2350 {
2351 CLEAR_ERROR_INSERT_VALUE;
2352 sendSignalWithDelay(reference(), GSN_INCL_NODEREQ, signal, 5000, signal->getLength());
2353 return;
2354 }
2355
2356 Uint32 tnodeStartFailNr = signal->theData[2];
2357 currentgcp = signal->theData[4];
2358 CRASH_INSERTION(7127);
2359 cnewgcp = currentgcp;
2360 coldgcp = currentgcp - 1;
2361 if (!isMaster()) {
2362 jam();
2363 /*-----------------------------------------------------------------------*/
2364 // We don't want to change the state of the master since he can be in the
2365 // state LCP_TCGET at this time.
2366 /*-----------------------------------------------------------------------*/
2367 c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
2368 }//if
2369
2370 /*-------------------------------------------------------------------------*/
2371 // When a node is restarted we must ensure that a lcp will be run
2372 // as soon as possible and the reset the delay according to the original
2373 // configuration.
2374 // Without an initial local checkpoint the new node will not be available.
2375 /*-------------------------------------------------------------------------*/
2376 if (getOwnNodeId() == nodeId) {
2377 jam();
2378 /*-----------------------------------------------------------------------*/
2379 // We are the starting node. We came here only to set the global checkpoint
2380 // id's and the lcp status.
2381 /*-----------------------------------------------------------------------*/
2382 CRASH_INSERTION(7171);
2383 Uint32 masterVersion = getNodeInfo(refToNode(cmasterdihref)).m_version;
2384
2385 if ((NDB_VERSION_MAJOR == 4 &&
2386 masterVersion >= NDBD_INCL_NODECONF_VERSION_4) ||
2387 (NDB_VERSION_MAJOR == 5 &&
2388 masterVersion >= NDBD_INCL_NODECONF_VERSION_5) ||
2389 (NDB_VERSION_MAJOR > 5))
2390 {
2391 signal->theData[0] = getOwnNodeId();
2392 signal->theData[1] = getOwnNodeId();
2393 sendSignal(cmasterdihref, GSN_INCL_NODECONF, signal, 2, JBB);
2394 }
2395 return;
2396 }//if
2397 if (getNodeStatus(nodeId) != NodeRecord::STARTING) {
2398 jam();
2399 return;
2400 }//if
2401 ndbrequire(cfailurenr == tnodeStartFailNr);
2402 ndbrequire (c_nodeStartSlave.nodeId == 0);
2403 c_nodeStartSlave.nodeId = nodeId;
2404
2405 ndbrequire (retRef == cmasterdihref);
2406
2407 NodeRecordPtr nodePtr;
2408 nodePtr.i = nodeId;
2409 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
2410
2411 Sysfile::ActiveStatus TsaveState = nodePtr.p->activeStatus;
2412 Uint32 TnodeGroup = nodePtr.p->nodeGroup;
2413
2414 new (nodePtr.p) NodeRecord();
2415 nodePtr.p->nodeGroup = TnodeGroup;
2416 nodePtr.p->activeStatus = TsaveState;
2417 nodePtr.p->nodeStatus = NodeRecord::ALIVE;
2418 nodePtr.p->useInTransactions = true;
2419 nodePtr.p->m_inclDihLcp = true;
2420
2421 removeDeadNode(nodePtr);
2422 insertAlive(nodePtr);
2423 con_lineNodes++;
2424
2425 /*-------------------------------------------------------------------------*/
2426 // WE WILL ALSO SEND THE INCLUDE NODE REQUEST TO THE LOCAL LQH BLOCK.
2427 /*-------------------------------------------------------------------------*/
2428 signal->theData[0] = reference();
2429 signal->theData[1] = nodeId;
2430 signal->theData[2] = currentgcp;
2431 sendSignal(clocallqhblockref, GSN_INCL_NODEREQ, signal, 3, JBB);
2432 }//Dbdih::execINCL_NODEREQ()
2433
2434 /* ------------------------------------------------------------------------- */
2435 // execINCL_NODECONF() is found in the master logic part since it is used by
2436 // both the master and the slaves.
2437 /* ------------------------------------------------------------------------- */
2438
2439 /*****************************************************************************/
2440 /*********** TAKE OVER DECISION MODULE *************/
2441 /*****************************************************************************/
2442 // This module contains the subroutines that take the decision whether to take
2443 // over a node now or not.
2444 /* ------------------------------------------------------------------------- */
2445 /* MASTER LOGIC FOR SYSTEM RESTART */
2446 /* ------------------------------------------------------------------------- */
2447 // WE ONLY COME HERE IF WE ARE THE MASTER AND WE ARE PERFORMING A SYSTEM
2448 // RESTART. WE ALSO COME HERE DURING THIS SYSTEM RESTART ONE TIME PER NODE
2449 // THAT NEEDS TAKE OVER.
2450 /*---------------------------------------------------------------------------*/
2451 // WE CHECK IF ANY NODE NEEDS TO BE TAKEN OVER AND THE TAKE OVER HAS NOT YET
2452 // BEEN STARTED OR COMPLETED.
2453 /*---------------------------------------------------------------------------*/
2454 void
systemRestartTakeOverLab(Signal * signal)2455 Dbdih::systemRestartTakeOverLab(Signal* signal)
2456 {
2457 NodeRecordPtr nodePtr;
2458 for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
2459 jam();
2460 ptrAss(nodePtr, nodeRecord);
2461 switch (nodePtr.p->activeStatus) {
2462 case Sysfile::NS_Active:
2463 case Sysfile::NS_ActiveMissed_1:
2464 jam();
2465 break;
2466 /*---------------------------------------------------------------------*/
2467 // WE HAVE NOT REACHED A STATE YET WHERE THIS NODE NEEDS TO BE TAKEN OVER
2468 /*---------------------------------------------------------------------*/
2469 case Sysfile::NS_ActiveMissed_2:
2470 case Sysfile::NS_NotActive_NotTakenOver:
2471 jam();
2472 /*---------------------------------------------------------------------*/
2473 // THIS NODE IS IN TROUBLE.
2474 // WE MUST SUCCEED WITH A LOCAL CHECKPOINT WITH THIS NODE TO REMOVE THE
2475 // DANGER. IF THE NODE IS NOT ALIVE THEN THIS WILL NOT BE
2476 // POSSIBLE AND WE CAN START THE TAKE OVER IMMEDIATELY IF WE HAVE ANY
2477 // NODES THAT CAN PERFORM A TAKE OVER.
2478 /*---------------------------------------------------------------------*/
2479 if (nodePtr.p->nodeStatus != NodeRecord::ALIVE) {
2480 jam();
2481 Uint32 ThotSpareNode = findHotSpare();
2482 if (ThotSpareNode != RNIL) {
2483 jam();
2484 startTakeOver(signal, RNIL, ThotSpareNode, nodePtr.i);
2485 }//if
2486 } else if(nodePtr.p->activeStatus == Sysfile::NS_NotActive_NotTakenOver){
2487 jam();
2488 /*-------------------------------------------------------------------*/
2489 // NOT ACTIVE NODES THAT HAVE NOT YET BEEN TAKEN OVER NEEDS TAKE OVER
2490 // IMMEDIATELY. IF WE ARE ALIVE WE TAKE OVER OUR OWN NODE.
2491 /*-------------------------------------------------------------------*/
2492 infoEvent("Take over of node %d started",
2493 nodePtr.i);
2494 startTakeOver(signal, RNIL, nodePtr.i, nodePtr.i);
2495 }//if
2496 break;
2497 case Sysfile::NS_TakeOver:
2498 /**-------------------------------------------------------------------
2499 * WE MUST HAVE FAILED IN THE MIDDLE OF THE TAKE OVER PROCESS.
2500 * WE WILL CONCLUDE THE TAKE OVER PROCESS NOW.
2501 *-------------------------------------------------------------------*/
2502 if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
2503 jam();
2504 Uint32 takeOverNode = Sysfile::getTakeOverNode(nodePtr.i,
2505 SYSFILE->takeOver);
2506 if(takeOverNode == 0){
2507 jam();
2508 warningEvent("Bug in take-over code restarting");
2509 takeOverNode = nodePtr.i;
2510 }
2511 startTakeOver(signal, RNIL, nodePtr.i, takeOverNode);
2512 } else {
2513 jam();
2514 /**-------------------------------------------------------------------
2515 * We are not currently taking over, change our active status.
2516 *-------------------------------------------------------------------*/
2517 nodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
2518 setNodeRestartInfoBits();
2519 }//if
2520 break;
2521 case Sysfile::NS_HotSpare:
2522 jam();
2523 break;
2524 /*---------------------------------------------------------------------*/
2525 // WE NEED NOT TAKE OVER NODES THAT ARE HOT SPARE.
2526 /*---------------------------------------------------------------------*/
2527 case Sysfile::NS_NotDefined:
2528 jam();
2529 break;
2530 /*---------------------------------------------------------------------*/
2531 // WE NEED NOT TAKE OVER NODES THAT DO NOT EVEN EXIST IN THE CLUSTER.
2532 /*---------------------------------------------------------------------*/
2533 default:
2534 ndbrequire(false);
2535 break;
2536 }//switch
2537 }//for
2538 /*-------------------------------------------------------------------------*/
2539 /* NO TAKE OVER HAS BEEN INITIATED. */
2540 /*-------------------------------------------------------------------------*/
2541 }//Dbdih::systemRestartTakeOverLab()
2542
2543 /*---------------------------------------------------------------------------*/
2544 // This subroutine is called as part of node restart in the master node.
2545 /*---------------------------------------------------------------------------*/
nodeRestartTakeOver(Signal * signal,Uint32 startNodeId)2546 void Dbdih::nodeRestartTakeOver(Signal* signal, Uint32 startNodeId)
2547 {
2548 switch (getNodeActiveStatus(startNodeId)) {
2549 case Sysfile::NS_Active:
2550 case Sysfile::NS_ActiveMissed_1:
2551 case Sysfile::NS_ActiveMissed_2:
2552 jam();
2553 /*-----------------------------------------------------------------------*/
2554 // AN ACTIVE NODE HAS BEEN STARTED. THE ACTIVE NODE MUST THEN GET ALL DATA
2555 // IT HAD BEFORE ITS CRASH. WE START THE TAKE OVER IMMEDIATELY.
2556 // SINCE WE ARE AN ACTIVE NODE WE WILL TAKE OVER OUR OWN NODE THAT
2557 // PREVIOUSLY CRASHED.
2558 /*-----------------------------------------------------------------------*/
2559 startTakeOver(signal, RNIL, startNodeId, startNodeId);
2560 break;
2561 case Sysfile::NS_HotSpare:{
2562 jam();
2563 /*-----------------------------------------------------------------------*/
2564 // WHEN STARTING UP A HOT SPARE WE WILL CHECK IF ANY NODE NEEDS TO TAKEN
2565 // OVER. IF SO THEN WE WILL START THE TAKE OVER.
2566 /*-----------------------------------------------------------------------*/
2567 bool takeOverStarted = false;
2568 NodeRecordPtr nodePtr;
2569 for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
2570 jam();
2571 ptrAss(nodePtr, nodeRecord);
2572 if (nodePtr.p->activeStatus == Sysfile::NS_NotActive_NotTakenOver) {
2573 jam();
2574 takeOverStarted = true;
2575 startTakeOver(signal, RNIL, startNodeId, nodePtr.i);
2576 }//if
2577 }//for
2578 if (!takeOverStarted) {
2579 jam();
2580 /*-------------------------------------------------------------------*/
2581 // NO TAKE OVER WAS NEEDED AT THE MOMENT WE START-UP AND WAIT UNTIL A
2582 // TAKE OVER IS NEEDED.
2583 /*-------------------------------------------------------------------*/
2584 BlockReference ref = calcDihBlockRef(startNodeId);
2585 signal->theData[0] = startNodeId;
2586 sendSignal(ref, GSN_START_COPYCONF, signal, 1, JBB);
2587 }//if
2588 break;
2589 }
2590 case Sysfile::NS_NotActive_NotTakenOver:
2591 jam();
2592 /*-----------------------------------------------------------------------*/
2593 // ALL DATA IN THE NODE IS LOST BUT WE HAVE NOT TAKEN OVER YET. WE WILL
2594 // TAKE OVER OUR OWN NODE
2595 /*-----------------------------------------------------------------------*/
2596 startTakeOver(signal, RNIL, startNodeId, startNodeId);
2597 break;
2598 case Sysfile::NS_TakeOver:{
2599 jam();
2600 /*--------------------------------------------------------------------
2601 * We were in the process of taking over but it was not completed.
2602 * We will complete it now instead.
2603 *--------------------------------------------------------------------*/
2604 Uint32 takeOverNode = Sysfile::getTakeOverNode(startNodeId,
2605 SYSFILE->takeOver);
2606 if(takeOverNode == 0){
2607 jam();
2608 warningEvent("Bug in take-over code restarting");
2609 takeOverNode = startNodeId;
2610 }
2611
2612 startTakeOver(signal, RNIL, startNodeId, takeOverNode);
2613 break;
2614 }
2615 default:
2616 ndbrequire(false);
2617 break;
2618 }//switch
2619 nodeResetStart();
2620 }//Dbdih::nodeRestartTakeOver()
2621
2622 /*************************************************************************/
2623 // Ths routine is called when starting a local checkpoint.
2624 /*************************************************************************/
checkStartTakeOver(Signal * signal)2625 void Dbdih::checkStartTakeOver(Signal* signal)
2626 {
2627 NodeRecordPtr csoNodeptr;
2628 Uint32 tcsoHotSpareNode;
2629 Uint32 tcsoTakeOverNode;
2630 if (isMaster()) {
2631 /*-----------------------------------------------------------------*/
2632 /* WE WILL ONLY START TAKE OVER IF WE ARE MASTER. */
2633 /*-----------------------------------------------------------------*/
2634 /* WE WILL ONLY START THE TAKE OVER IF THERE WERE A NEED OF */
2635 /* A TAKE OVER. */
2636 /*-----------------------------------------------------------------*/
2637 /* WE CAN ONLY PERFORM THE TAKE OVER IF WE HAVE A HOT SPARE */
2638 /* AVAILABLE. */
2639 /*-----------------------------------------------------------------*/
2640 tcsoTakeOverNode = 0;
2641 tcsoHotSpareNode = 0;
2642 for (csoNodeptr.i = 1; csoNodeptr.i < MAX_NDB_NODES; csoNodeptr.i++) {
2643 ptrAss(csoNodeptr, nodeRecord);
2644 if (csoNodeptr.p->activeStatus == Sysfile::NS_NotActive_NotTakenOver) {
2645 jam();
2646 tcsoTakeOverNode = csoNodeptr.i;
2647 } else {
2648 jam();
2649 if (csoNodeptr.p->activeStatus == Sysfile::NS_HotSpare) {
2650 jam();
2651 tcsoHotSpareNode = csoNodeptr.i;
2652 }//if
2653 }//if
2654 }//for
2655 if ((tcsoTakeOverNode != 0) &&
2656 (tcsoHotSpareNode != 0)) {
2657 jam();
2658 startTakeOver(signal, RNIL, tcsoHotSpareNode, tcsoTakeOverNode);
2659 }//if
2660 }//if
2661 }//Dbdih::checkStartTakeOver()
2662
2663 /*****************************************************************************/
2664 /*********** NODE ADDING MODULE *************/
2665 /*********** CODE TO HANDLE TAKE OVER *************/
2666 /*****************************************************************************/
2667 // A take over can be initiated by a number of things:
2668 // 1) A node restart, usually the node takes over itself but can also take
2669 // over somebody else if its own data was already taken over
2670 // 2) At system restart it is necessary to use the take over code to recover
2671 // nodes which had too old checkpoints to be restorable by the usual
2672 // restoration from disk.
2673 // 3) When a node has missed too many local checkpoints and is decided by the
2674 // master to be taken over by a hot spare node that sits around waiting
2675 // for this to happen.
2676 //
2677 // To support multiple node failures efficiently the code is written such that
2678 // only one take over can handle transitions in state but during a copy
2679 // fragment other take over's can perform state transitions.
2680 /*****************************************************************************/
startTakeOver(Signal * signal,Uint32 takeOverPtrI,Uint32 startNode,Uint32 nodeTakenOver)2681 void Dbdih::startTakeOver(Signal* signal,
2682 Uint32 takeOverPtrI,
2683 Uint32 startNode,
2684 Uint32 nodeTakenOver)
2685 {
2686 NodeRecordPtr toNodePtr;
2687 NodeGroupRecordPtr NGPtr;
2688 toNodePtr.i = nodeTakenOver;
2689 ptrCheckGuard(toNodePtr, MAX_NDB_NODES, nodeRecord);
2690 NGPtr.i = toNodePtr.p->nodeGroup;
2691 ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
2692 TakeOverRecordPtr takeOverPtr;
2693 if (takeOverPtrI == RNIL) {
2694 jam();
2695 setAllowNodeStart(startNode, false);
2696 seizeTakeOver(takeOverPtr);
2697 if (startNode == c_nodeStartMaster.startNode) {
2698 jam();
2699 takeOverPtr.p->toNodeRestart = true;
2700 }//if
2701 takeOverPtr.p->toStartingNode = startNode;
2702 takeOverPtr.p->toFailedNode = nodeTakenOver;
2703 } else {
2704 jam();
2705 RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
2706 ndbrequire(takeOverPtr.p->toStartingNode == startNode);
2707 ndbrequire(takeOverPtr.p->toFailedNode == nodeTakenOver);
2708 ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_WAIT_START_TAKE_OVER);
2709 }//if
2710 if ((NGPtr.p->activeTakeOver) || (ERROR_INSERTED(7157))) {
2711 jam();
2712 /**------------------------------------------------------------------------
2713 * A take over is already active in this node group. We only allow one
2714 * take over per node group. Otherwise we will overload the node group and
2715 * also we will require much more checks when starting up copying of
2716 * fragments. The parallelism for take over is mainly to ensure that we
2717 * can handle take over efficiently in large systems with 4 nodes and above
2718 * A typical case is a 8 node system executing on two 8-cpu boxes.
2719 * A box crash in one of the boxes will mean 4 nodes crashes.
2720 * We want to be able to restart those four nodes to some
2721 * extent in parallel.
2722 *
2723 * We will wait for a few seconds and then try again.
2724 */
2725 takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_START_TAKE_OVER;
2726 signal->theData[0] = DihContinueB::ZSTART_TAKE_OVER;
2727 signal->theData[1] = takeOverPtr.i;
2728 signal->theData[2] = startNode;
2729 signal->theData[3] = nodeTakenOver;
2730 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 5000, 4);
2731 return;
2732 }//if
2733 NGPtr.p->activeTakeOver = true;
2734 if (startNode == nodeTakenOver) {
2735 jam();
2736 switch (getNodeActiveStatus(nodeTakenOver)) {
2737 case Sysfile::NS_Active:
2738 case Sysfile::NS_ActiveMissed_1:
2739 case Sysfile::NS_ActiveMissed_2:
2740 jam();
2741 break;
2742 case Sysfile::NS_NotActive_NotTakenOver:
2743 case Sysfile::NS_TakeOver:
2744 jam();
2745 setNodeActiveStatus(nodeTakenOver, Sysfile::NS_TakeOver);
2746 break;
2747 default:
2748 ndbrequire(false);
2749 }//switch
2750 } else {
2751 jam();
2752 setNodeActiveStatus(nodeTakenOver, Sysfile::NS_HotSpare);
2753 setNodeActiveStatus(startNode, Sysfile::NS_TakeOver);
2754 changeNodeGroups(startNode, nodeTakenOver);
2755 }//if
2756 setNodeRestartInfoBits();
2757 /* ---------------------------------------------------------------------- */
2758 /* WE SET THE RESTART INFORMATION TO INDICATE THAT WE ARE ABOUT TO TAKE */
2759 /* OVER THE FAILED NODE. WE SET THIS INFORMATION AND WAIT UNTIL THE */
2760 /* GLOBAL CHECKPOINT HAS WRITTEN THE RESTART INFORMATION. */
2761 /* ---------------------------------------------------------------------- */
2762 Sysfile::setTakeOverNode(takeOverPtr.p->toFailedNode, SYSFILE->takeOver,
2763 startNode);
2764 takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_START_COPY;
2765
2766 if (getNodeState().getSystemRestartInProgress())
2767 {
2768 jam();
2769 checkToCopy();
2770 checkToCopyCompleted(signal);
2771 return;
2772 }
2773 cstartGcpNow = true;
2774 }//Dbdih::startTakeOver()
2775
changeNodeGroups(Uint32 startNode,Uint32 nodeTakenOver)2776 void Dbdih::changeNodeGroups(Uint32 startNode, Uint32 nodeTakenOver)
2777 {
2778 NodeRecordPtr startNodePtr;
2779 NodeRecordPtr toNodePtr;
2780 startNodePtr.i = startNode;
2781 ptrCheckGuard(startNodePtr, MAX_NDB_NODES, nodeRecord);
2782 toNodePtr.i = nodeTakenOver;
2783 ptrCheckGuard(toNodePtr, MAX_NDB_NODES, nodeRecord);
2784 ndbrequire(startNodePtr.p->nodeGroup == ZNIL);
2785 NodeGroupRecordPtr NGPtr;
2786
2787 NGPtr.i = toNodePtr.p->nodeGroup;
2788 ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
2789 bool nodeFound = false;
2790 for (Uint32 i = 0; i < NGPtr.p->nodeCount; i++) {
2791 jam();
2792 if (NGPtr.p->nodesInGroup[i] == nodeTakenOver) {
2793 jam();
2794 NGPtr.p->nodesInGroup[i] = startNode;
2795 nodeFound = true;
2796 }//if
2797 }//for
2798 ndbrequire(nodeFound);
2799 Sysfile::setNodeGroup(startNodePtr.i, SYSFILE->nodeGroups, toNodePtr.p->nodeGroup);
2800 startNodePtr.p->nodeGroup = toNodePtr.p->nodeGroup;
2801 Sysfile::setNodeGroup(toNodePtr.i, SYSFILE->nodeGroups, NO_NODE_GROUP_ID);
2802 toNodePtr.p->nodeGroup = ZNIL;
2803 }//Dbdih::changeNodeGroups()
2804
checkToCopy()2805 void Dbdih::checkToCopy()
2806 {
2807 TakeOverRecordPtr takeOverPtr;
2808 for (takeOverPtr.i = 0;takeOverPtr.i < MAX_NDB_NODES; takeOverPtr.i++) {
2809 ptrAss(takeOverPtr, takeOverRecord);
2810 /*----------------------------------------------------------------------*/
2811 // TAKE OVER HANDLING WRITES RESTART INFORMATION THROUGH
2812 // THE GLOBAL CHECKPOINT
2813 // PROTOCOL. WE CHECK HERE BEFORE STARTING A WRITE OF THE RESTART
2814 // INFORMATION.
2815 /*-----------------------------------------------------------------------*/
2816 if (takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_START_COPY) {
2817 jam();
2818 takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_START_COPY_ONGOING;
2819 } else if (takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_END_COPY) {
2820 jam();
2821 takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_END_COPY_ONGOING;
2822 }//if
2823 }//for
2824 }//Dbdih::checkToCopy()
2825
checkToCopyCompleted(Signal * signal)2826 void Dbdih::checkToCopyCompleted(Signal* signal)
2827 {
2828 /* ------------------------------------------------------------------------*/
2829 /* WE CHECK HERE IF THE WRITING OF TAKE OVER INFORMATION ALSO HAS BEEN */
2830 /* COMPLETED. */
2831 /* ------------------------------------------------------------------------*/
2832 TakeOverRecordPtr toPtr;
2833 for (toPtr.i = 0; toPtr.i < MAX_NDB_NODES; toPtr.i++) {
2834 ptrAss(toPtr, takeOverRecord);
2835 if (toPtr.p->toMasterStatus == TakeOverRecord::TO_START_COPY_ONGOING){
2836 jam();
2837 sendStartTo(signal, toPtr.i);
2838 } else if (toPtr.p->toMasterStatus == TakeOverRecord::TO_END_COPY_ONGOING){
2839 jam();
2840 sendEndTo(signal, toPtr.i);
2841 } else {
2842 jam();
2843 }//if
2844 }//for
2845 }//Dbdih::checkToCopyCompleted()
2846
checkToInterrupted(TakeOverRecordPtr & takeOverPtr)2847 bool Dbdih::checkToInterrupted(TakeOverRecordPtr& takeOverPtr)
2848 {
2849 if (checkNodeAlive(takeOverPtr.p->toStartingNode)) {
2850 jam();
2851 return false;
2852 } else {
2853 jam();
2854 endTakeOver(takeOverPtr.i);
2855 return true;
2856 }//if
2857 }//Dbdih::checkToInterrupted()
2858
sendStartTo(Signal * signal,Uint32 takeOverPtrI)2859 void Dbdih::sendStartTo(Signal* signal, Uint32 takeOverPtrI)
2860 {
2861 TakeOverRecordPtr takeOverPtr;
2862 CRASH_INSERTION(7155);
2863 RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
2864 if ((c_startToLock != RNIL) || (ERROR_INSERTED(7158))) {
2865 jam();
2866 takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_START;
2867 signal->theData[0] = DihContinueB::ZSEND_START_TO;
2868 signal->theData[1] = takeOverPtrI;
2869 signal->theData[2] = takeOverPtr.p->toStartingNode;
2870 signal->theData[3] = takeOverPtr.p->toFailedNode;
2871 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 30, 4);
2872 return;
2873 }//if
2874 c_startToLock = takeOverPtrI;
2875
2876 takeOverPtr.p->toMasterStatus = TakeOverRecord::STARTING;
2877 StartToReq * const req = (StartToReq *)&signal->theData[0];
2878 req->userPtr = takeOverPtr.i;
2879 req->userRef = reference();
2880 req->startingNodeId = takeOverPtr.p->toStartingNode;
2881 req->nodeTakenOver = takeOverPtr.p->toFailedNode;
2882 req->nodeRestart = takeOverPtr.p->toNodeRestart;
2883 sendLoopMacro(START_TOREQ, sendSTART_TOREQ);
2884 }//Dbdih::sendStartTo()
2885
execSTART_TOREQ(Signal * signal)2886 void Dbdih::execSTART_TOREQ(Signal* signal)
2887 {
2888 TakeOverRecordPtr takeOverPtr;
2889 jamEntry();
2890 const StartToReq * const req = (StartToReq *)&signal->theData[0];
2891 takeOverPtr.i = req->userPtr;
2892 BlockReference ref = req->userRef;
2893 Uint32 startingNode = req->startingNodeId;
2894
2895 CRASH_INSERTION(7133);
2896 RETURN_IF_NODE_NOT_ALIVE(req->startingNodeId);
2897 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
2898 allocateTakeOver(takeOverPtr);
2899 initStartTakeOver(req, takeOverPtr);
2900
2901 StartToConf * const conf = (StartToConf *)&signal->theData[0];
2902 conf->userPtr = takeOverPtr.i;
2903 conf->sendingNodeId = cownNodeId;
2904 conf->startingNodeId = startingNode;
2905 sendSignal(ref, GSN_START_TOCONF, signal, StartToConf::SignalLength, JBB);
2906 }//Dbdih::execSTART_TOREQ()
2907
execSTART_TOCONF(Signal * signal)2908 void Dbdih::execSTART_TOCONF(Signal* signal)
2909 {
2910 TakeOverRecordPtr takeOverPtr;
2911 jamEntry();
2912 const StartToConf * const conf = (StartToConf *)&signal->theData[0];
2913
2914 CRASH_INSERTION(7147);
2915
2916 RETURN_IF_NODE_NOT_ALIVE(conf->startingNodeId);
2917
2918 takeOverPtr.i = conf->userPtr;
2919 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
2920 ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::STARTING);
2921 ndbrequire(takeOverPtr.p->toStartingNode == conf->startingNodeId);
2922 receiveLoopMacro(START_TOREQ, conf->sendingNodeId);
2923 CRASH_INSERTION(7134);
2924 c_startToLock = RNIL;
2925
2926 if (takeOverPtr.p->toNodeRestart)
2927 {
2928 jam();
2929 takeOverPtr.p->toMasterStatus = TakeOverRecord::STARTING_LOCAL_FRAGMENTS;
2930 nr_start_fragments(signal, takeOverPtr);
2931 return;
2932 }
2933
2934 startNextCopyFragment(signal, takeOverPtr.i);
2935 }//Dbdih::execSTART_TOCONF()
2936
2937 void
nr_start_fragments(Signal * signal,TakeOverRecordPtr takeOverPtr)2938 Dbdih::nr_start_fragments(Signal* signal,
2939 TakeOverRecordPtr takeOverPtr)
2940 {
2941 Uint32 loopCount = 0 ;
2942 TabRecordPtr tabPtr;
2943 while (loopCount++ < 100) {
2944 tabPtr.i = takeOverPtr.p->toCurrentTabref;
2945 if (tabPtr.i >= ctabFileSize) {
2946 jam();
2947 nr_run_redo(signal, takeOverPtr);
2948 return;
2949 }//if
2950 ptrAss(tabPtr, tabRecord);
2951 if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE ||
2952 tabPtr.p->tabStorage != TabRecord::ST_NORMAL)
2953 {
2954 jam();
2955 takeOverPtr.p->toCurrentFragid = 0;
2956 takeOverPtr.p->toCurrentTabref++;
2957 continue;
2958 }//if
2959 Uint32 fragId = takeOverPtr.p->toCurrentFragid;
2960 if (fragId >= tabPtr.p->totalfragments) {
2961 jam();
2962 takeOverPtr.p->toCurrentFragid = 0;
2963 takeOverPtr.p->toCurrentTabref++;
2964 continue;
2965 }//if
2966 FragmentstorePtr fragPtr;
2967 getFragstore(tabPtr.p, fragId, fragPtr);
2968 ReplicaRecordPtr loopReplicaPtr;
2969 loopReplicaPtr.i = fragPtr.p->oldStoredReplicas;
2970 while (loopReplicaPtr.i != RNIL) {
2971 ptrCheckGuard(loopReplicaPtr, creplicaFileSize, replicaRecord);
2972 if (loopReplicaPtr.p->procNode == takeOverPtr.p->toStartingNode) {
2973 jam();
2974 nr_start_fragment(signal, takeOverPtr, loopReplicaPtr);
2975 break;
2976 } else {
2977 jam();
2978 loopReplicaPtr.i = loopReplicaPtr.p->nextReplica;
2979 }//if
2980 }//while
2981 takeOverPtr.p->toCurrentFragid++;
2982 }//while
2983 signal->theData[0] = DihContinueB::ZTO_START_FRAGMENTS;
2984 signal->theData[1] = takeOverPtr.i;
2985 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
2986 }
2987
2988 void
nr_start_fragment(Signal * signal,TakeOverRecordPtr takeOverPtr,ReplicaRecordPtr replicaPtr)2989 Dbdih::nr_start_fragment(Signal* signal,
2990 TakeOverRecordPtr takeOverPtr,
2991 ReplicaRecordPtr replicaPtr)
2992 {
2993 Uint32 i, j = 0;
2994 Uint32 maxLcpId = 0;
2995 Uint32 maxLcpIndex = ~0;
2996
2997 Uint32 restorableGCI = 0;
2998
2999 ndbout_c("tab: %d frag: %d replicaP->nextLcp: %d",
3000 takeOverPtr.p->toCurrentTabref,
3001 takeOverPtr.p->toCurrentFragid,
3002 replicaPtr.p->nextLcp);
3003
3004 Uint32 idx = replicaPtr.p->nextLcp;
3005 for(i = 0; i<MAX_LCP_STORED; i++, idx = nextLcpNo(idx))
3006 {
3007 ndbout_c("scanning idx: %d lcpId: %d", idx, replicaPtr.p->lcpId[idx]);
3008 if (replicaPtr.p->lcpStatus[idx] == ZVALID)
3009 {
3010 ndbrequire(replicaPtr.p->lcpId[idx] > maxLcpId);
3011 Uint32 stopGci = replicaPtr.p->maxGciStarted[idx];
3012 for (;j < replicaPtr.p->noCrashedReplicas; j++)
3013 {
3014 ndbout_c("crashed replica: %d(%d) replicaLastGci: %d",
3015 j,
3016 replicaPtr.p->noCrashedReplicas,
3017 replicaPtr.p->replicaLastGci[j]);
3018 if (replicaPtr.p->replicaLastGci[j] > stopGci)
3019 {
3020 maxLcpId = replicaPtr.p->lcpId[idx];
3021 maxLcpIndex = idx;
3022 restorableGCI = replicaPtr.p->replicaLastGci[j];
3023 break;
3024 }
3025 }
3026 }
3027 }
3028
3029 if (maxLcpIndex == ~ (Uint32) 0)
3030 {
3031 ndbout_c("Didnt find any LCP for node: %d tab: %d frag: %d",
3032 takeOverPtr.p->toStartingNode,
3033 takeOverPtr.p->toCurrentTabref,
3034 takeOverPtr.p->toCurrentFragid);
3035 replicaPtr.p->lcpIdStarted = 0;
3036 BlockReference ref = calcLqhBlockRef(takeOverPtr.p->toStartingNode);
3037 StartFragReq *req = (StartFragReq *)signal->getDataPtrSend();
3038 req->userPtr = 0;
3039 req->userRef = reference();
3040 req->lcpNo = ZNIL;
3041 req->lcpId = 0;
3042 req->tableId = takeOverPtr.p->toCurrentTabref;
3043 req->fragId = takeOverPtr.p->toCurrentFragid;
3044 req->noOfLogNodes = 0;
3045 sendSignal(ref, GSN_START_FRAGREQ, signal,
3046 StartFragReq::SignalLength, JBB);
3047 }
3048 else
3049 {
3050 ndbout_c("Found LCP: %d(%d) maxGciStarted: %d maxGciCompleted: %d restorable: %d(%d) newestRestorableGCI: %d",
3051 maxLcpId,
3052 maxLcpIndex,
3053 replicaPtr.p->maxGciStarted[maxLcpIndex],
3054 replicaPtr.p->maxGciCompleted[maxLcpIndex],
3055 restorableGCI,
3056 SYSFILE->lastCompletedGCI[takeOverPtr.p->toStartingNode],
3057 SYSFILE->newestRestorableGCI);
3058
3059 replicaPtr.p->lcpIdStarted = restorableGCI;
3060 BlockReference ref = calcLqhBlockRef(takeOverPtr.p->toStartingNode);
3061 StartFragReq *req = (StartFragReq *)signal->getDataPtrSend();
3062 req->userPtr = 0;
3063 req->userRef = reference();
3064 req->lcpNo = maxLcpIndex;
3065 req->lcpId = maxLcpId;
3066 req->tableId = takeOverPtr.p->toCurrentTabref;
3067 req->fragId = takeOverPtr.p->toCurrentFragid;
3068 req->noOfLogNodes = 1;
3069 req->lqhLogNode[0] = takeOverPtr.p->toStartingNode;
3070 req->startGci[0] = replicaPtr.p->maxGciCompleted[maxLcpIndex];
3071 req->lastGci[0] = restorableGCI;
3072 sendSignal(ref, GSN_START_FRAGREQ, signal,
3073 StartFragReq::SignalLength, JBB);
3074 }
3075 }
3076
3077 void
nr_run_redo(Signal * signal,TakeOverRecordPtr takeOverPtr)3078 Dbdih::nr_run_redo(Signal* signal, TakeOverRecordPtr takeOverPtr)
3079 {
3080 takeOverPtr.p->toCurrentTabref = 0;
3081 takeOverPtr.p->toCurrentFragid = 0;
3082 sendSTART_RECREQ(signal, takeOverPtr.p->toStartingNode);
3083 }
3084
initStartTakeOver(const StartToReq * req,TakeOverRecordPtr takeOverPtr)3085 void Dbdih::initStartTakeOver(const StartToReq * req,
3086 TakeOverRecordPtr takeOverPtr)
3087 {
3088 takeOverPtr.p->toCurrentTabref = 0;
3089 takeOverPtr.p->toCurrentFragid = 0;
3090 takeOverPtr.p->toStartingNode = req->startingNodeId;
3091 takeOverPtr.p->toFailedNode = req->nodeTakenOver;
3092 takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_STARTED;
3093 takeOverPtr.p->toCopyNode = RNIL;
3094 takeOverPtr.p->toCurrentReplica = RNIL;
3095 takeOverPtr.p->toNodeRestart = req->nodeRestart;
3096 }//Dbdih::initStartTakeOver()
3097
startNextCopyFragment(Signal * signal,Uint32 takeOverPtrI)3098 void Dbdih::startNextCopyFragment(Signal* signal, Uint32 takeOverPtrI)
3099 {
3100 TabRecordPtr tabPtr;
3101 TakeOverRecordPtr takeOverPtr;
3102 Uint32 loopCount;
3103 RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
3104 takeOverPtr.p->toMasterStatus = TakeOverRecord::SELECTING_NEXT;
3105 loopCount = 0;
3106 if (ERROR_INSERTED(7159)) {
3107 loopCount = 100;
3108 }//if
3109 while (loopCount++ < 100) {
3110 tabPtr.i = takeOverPtr.p->toCurrentTabref;
3111 if (tabPtr.i >= ctabFileSize) {
3112 jam();
3113 CRASH_INSERTION(7136);
3114 sendUpdateTo(signal, takeOverPtr.i, UpdateToReq::TO_COPY_COMPLETED);
3115 return;
3116 }//if
3117 ptrAss(tabPtr, tabRecord);
3118 if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE){
3119 jam();
3120 takeOverPtr.p->toCurrentFragid = 0;
3121 takeOverPtr.p->toCurrentTabref++;
3122 continue;
3123 }//if
3124 Uint32 fragId = takeOverPtr.p->toCurrentFragid;
3125 if (fragId >= tabPtr.p->totalfragments) {
3126 jam();
3127 takeOverPtr.p->toCurrentFragid = 0;
3128 takeOverPtr.p->toCurrentTabref++;
3129 if (ERROR_INSERTED(7135)) {
3130 if (takeOverPtr.p->toCurrentTabref == 1) {
3131 ndbrequire(false);
3132 }//if
3133 }//if
3134 continue;
3135 }//if
3136 FragmentstorePtr fragPtr;
3137 getFragstore(tabPtr.p, fragId, fragPtr);
3138 ReplicaRecordPtr loopReplicaPtr;
3139 loopReplicaPtr.i = fragPtr.p->oldStoredReplicas;
3140 while (loopReplicaPtr.i != RNIL) {
3141 ptrCheckGuard(loopReplicaPtr, creplicaFileSize, replicaRecord);
3142 if (loopReplicaPtr.p->procNode == takeOverPtr.p->toFailedNode) {
3143 jam();
3144 /* ----------------------------------------------------------------- */
3145 /* WE HAVE FOUND A REPLICA THAT BELONGED THE FAILED NODE THAT NEEDS */
3146 /* TAKE OVER. WE TAKE OVER THIS REPLICA TO THE NEW NODE. */
3147 /* ----------------------------------------------------------------- */
3148 takeOverPtr.p->toCurrentReplica = loopReplicaPtr.i;
3149 toCopyFragLab(signal, takeOverPtr.i);
3150 return;
3151 } else if (loopReplicaPtr.p->procNode == takeOverPtr.p->toStartingNode) {
3152 jam();
3153 /* ----------------------------------------------------------------- */
3154 /* WE HAVE OBVIOUSLY STARTED TAKING OVER THIS WITHOUT COMPLETING IT. */
3155 /* WE */
3156 /* NEED TO COMPLETE THE TAKE OVER OF THIS REPLICA. */
3157 /* ----------------------------------------------------------------- */
3158 takeOverPtr.p->toCurrentReplica = loopReplicaPtr.i;
3159 toCopyFragLab(signal, takeOverPtr.i);
3160 return;
3161 } else {
3162 jam();
3163 loopReplicaPtr.i = loopReplicaPtr.p->nextReplica;
3164 }//if
3165 }//while
3166 takeOverPtr.p->toCurrentFragid++;
3167 }//while
3168 signal->theData[0] = DihContinueB::ZTO_START_COPY_FRAG;
3169 signal->theData[1] = takeOverPtr.i;
3170 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
3171 }//Dbdih::startNextCopyFragment()
3172
toCopyFragLab(Signal * signal,Uint32 takeOverPtrI)3173 void Dbdih::toCopyFragLab(Signal* signal,
3174 Uint32 takeOverPtrI)
3175 {
3176 TakeOverRecordPtr takeOverPtr;
3177 RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
3178
3179 /**
3180 * Inform starting node that TakeOver is about to start
3181 */
3182 Uint32 nodeId = takeOverPtr.p->toStartingNode;
3183
3184 Uint32 version = getNodeInfo(nodeId).m_version;
3185 if (ndb_check_prep_copy_frag_version(version))
3186 {
3187 jam();
3188 TabRecordPtr tabPtr;
3189 tabPtr.i = takeOverPtr.p->toCurrentTabref;
3190 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
3191
3192 FragmentstorePtr fragPtr;
3193 getFragstore(tabPtr.p, takeOverPtr.p->toCurrentFragid, fragPtr);
3194 Uint32 nodes[MAX_REPLICAS];
3195 extractNodeInfo(fragPtr.p, nodes);
3196
3197 PrepareCopyFragReq* req= (PrepareCopyFragReq*)signal->getDataPtrSend();
3198 req->senderRef = reference();
3199 req->senderData = takeOverPtrI;
3200 req->tableId = takeOverPtr.p->toCurrentTabref;
3201 req->fragId = takeOverPtr.p->toCurrentFragid;
3202 req->copyNodeId = nodes[0]; // Src
3203 req->startingNodeId = takeOverPtr.p->toStartingNode; // Dst
3204 Uint32 ref = calcLqhBlockRef(takeOverPtr.p->toStartingNode);
3205
3206 sendSignal(ref, GSN_PREPARE_COPY_FRAG_REQ, signal,
3207 PrepareCopyFragReq::SignalLength, JBB);
3208
3209 takeOverPtr.p->toMasterStatus = TakeOverRecord::PREPARE_COPY;
3210 return;
3211 }
3212
3213 takeOverPtr.p->maxPage = RNIL;
3214 toStartCopyFrag(signal, takeOverPtr);
3215 }
3216
3217 void
execPREPARE_COPY_FRAG_REF(Signal * signal)3218 Dbdih::execPREPARE_COPY_FRAG_REF(Signal* signal)
3219 {
3220 jamEntry();
3221 PrepareCopyFragRef ref = *(PrepareCopyFragRef*)signal->getDataPtr();
3222
3223 TakeOverRecordPtr takeOverPtr;
3224 RETURN_IF_TAKE_OVER_INTERRUPTED(ref.senderData, takeOverPtr);
3225
3226 ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::PREPARE_COPY);
3227
3228 /**
3229 * Treat this as copy frag ref
3230 */
3231 CopyFragRef * cfref = (CopyFragRef*)signal->getDataPtrSend();
3232 cfref->userPtr = ref.senderData;
3233 cfref->startingNodeId = ref.startingNodeId;
3234 cfref->errorCode = ref.errorCode;
3235 cfref->tableId = ref.tableId;
3236 cfref->fragId = ref.fragId;
3237 cfref->sendingNodeId = ref.copyNodeId;
3238 takeOverPtr.p->toMasterStatus = TakeOverRecord::COPY_FRAG;
3239 execCOPY_FRAGREF(signal);
3240 }
3241
3242 void
execPREPARE_COPY_FRAG_CONF(Signal * signal)3243 Dbdih::execPREPARE_COPY_FRAG_CONF(Signal* signal)
3244 {
3245 PrepareCopyFragConf conf = *(PrepareCopyFragConf*)signal->getDataPtr();
3246
3247 TakeOverRecordPtr takeOverPtr;
3248 RETURN_IF_TAKE_OVER_INTERRUPTED(conf.senderData, takeOverPtr);
3249
3250 Uint32 version = getNodeInfo(refToNode(conf.senderRef)).m_version;
3251 if (ndb_check_prep_copy_frag_version(version) >= 2)
3252 {
3253 jam();
3254 takeOverPtr.p->maxPage = conf.maxPageNo;
3255 }
3256 else
3257 {
3258 jam();
3259 takeOverPtr.p->maxPage = RNIL;
3260 }
3261 toStartCopyFrag(signal, takeOverPtr);
3262 }
3263
3264 void
toStartCopyFrag(Signal * signal,TakeOverRecordPtr takeOverPtr)3265 Dbdih::toStartCopyFrag(Signal* signal, TakeOverRecordPtr takeOverPtr)
3266 {
3267 CreateReplicaRecordPtr createReplicaPtr;
3268 createReplicaPtr.i = 0;
3269 ptrAss(createReplicaPtr, createReplicaRecord);
3270
3271 ReplicaRecordPtr replicaPtr;
3272 replicaPtr.i = takeOverPtr.p->toCurrentReplica;
3273 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
3274
3275 TabRecordPtr tabPtr;
3276 tabPtr.i = takeOverPtr.p->toCurrentTabref;
3277 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
3278 /* ----------------------------------------------------------------------- */
3279 /* WE HAVE FOUND A REPLICA THAT NEEDS TAKE OVER. WE WILL START THIS TAKE */
3280 /* OVER BY ADDING THE FRAGMENT WHEREAFTER WE WILL ORDER THE PRIMARY */
3281 /* REPLICA TO COPY ITS CONTENT TO THE NEW STARTING REPLICA. */
3282 /* THIS OPERATION IS A SINGLE USER OPERATION UNTIL WE HAVE SENT */
3283 /* COPY_FRAGREQ. AFTER SENDING COPY_FRAGREQ WE ARE READY TO START A NEW */
3284 /* FRAGMENT REPLICA. WE WILL NOT IMPLEMENT THIS IN THE FIRST PHASE. */
3285 /* ----------------------------------------------------------------------- */
3286 cnoOfCreateReplicas = 1;
3287 createReplicaPtr.p->hotSpareUse = true;
3288 createReplicaPtr.p->dataNodeId = takeOverPtr.p->toStartingNode;
3289
3290 prepareSendCreateFragReq(signal, takeOverPtr.i);
3291 }//Dbdih::toStartCopy()
3292
prepareSendCreateFragReq(Signal * signal,Uint32 takeOverPtrI)3293 void Dbdih::prepareSendCreateFragReq(Signal* signal, Uint32 takeOverPtrI)
3294 {
3295 TakeOverRecordPtr takeOverPtr;
3296 RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
3297
3298 TabRecordPtr tabPtr;
3299 tabPtr.i = takeOverPtr.p->toCurrentTabref;
3300 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
3301 FragmentstorePtr fragPtr;
3302
3303 getFragstore(tabPtr.p, takeOverPtr.p->toCurrentFragid, fragPtr);
3304 Uint32 nodes[MAX_REPLICAS];
3305 extractNodeInfo(fragPtr.p, nodes);
3306 takeOverPtr.p->toCopyNode = nodes[0];
3307 sendCreateFragReq(signal, 0, CreateFragReq::STORED, takeOverPtr.i);
3308 }//Dbdih::prepareSendCreateFragReq()
3309
sendCreateFragReq(Signal * signal,Uint32 startGci,Uint32 replicaType,Uint32 takeOverPtrI)3310 void Dbdih::sendCreateFragReq(Signal* signal,
3311 Uint32 startGci,
3312 Uint32 replicaType,
3313 Uint32 takeOverPtrI)
3314 {
3315 TakeOverRecordPtr takeOverPtr;
3316 RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
3317 if ((c_createFragmentLock != RNIL) ||
3318 ((ERROR_INSERTED(7161))&&(replicaType == CreateFragReq::STORED)) ||
3319 ((ERROR_INSERTED(7162))&&(replicaType == CreateFragReq::COMMIT_STORED))){
3320 if (replicaType == CreateFragReq::STORED) {
3321 jam();
3322 takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_PREPARE_CREATE;
3323 } else {
3324 ndbrequire(replicaType == CreateFragReq::COMMIT_STORED);
3325 jam();
3326 takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_COMMIT_CREATE;
3327 }//if
3328 signal->theData[0] = DihContinueB::ZSEND_CREATE_FRAG;
3329 signal->theData[1] = takeOverPtr.i;
3330 signal->theData[2] = replicaType;
3331 signal->theData[3] = startGci;
3332 signal->theData[4] = takeOverPtr.p->toStartingNode;
3333 signal->theData[5] = takeOverPtr.p->toFailedNode;
3334 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 50, 6);
3335 return;
3336 }//if
3337 c_createFragmentLock = takeOverPtr.i;
3338 sendLoopMacro(CREATE_FRAGREQ, nullRoutine);
3339
3340 CreateFragReq * const req = (CreateFragReq *)&signal->theData[0];
3341 req->userPtr = takeOverPtr.i;
3342 req->userRef = reference();
3343 req->tableId = takeOverPtr.p->toCurrentTabref;
3344 req->fragId = takeOverPtr.p->toCurrentFragid;
3345 req->startingNodeId = takeOverPtr.p->toStartingNode;
3346 req->copyNodeId = takeOverPtr.p->toCopyNode;
3347 req->startGci = startGci;
3348 req->replicaType = replicaType;
3349
3350 NodeRecordPtr nodePtr;
3351 nodePtr.i = cfirstAliveNode;
3352 do {
3353 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
3354 BlockReference ref = calcDihBlockRef(nodePtr.i);
3355 sendSignal(ref, GSN_CREATE_FRAGREQ, signal,
3356 CreateFragReq::SignalLength, JBB);
3357 nodePtr.i = nodePtr.p->nextNode;
3358 } while (nodePtr.i != RNIL);
3359
3360 if (replicaType == CreateFragReq::STORED) {
3361 jam();
3362 takeOverPtr.p->toMasterStatus = TakeOverRecord::PREPARE_CREATE;
3363 } else {
3364 ndbrequire(replicaType == CreateFragReq::COMMIT_STORED);
3365 jam();
3366 takeOverPtr.p->toMasterStatus = TakeOverRecord::COMMIT_CREATE;
3367 }
3368 }//Dbdih::sendCreateFragReq()
3369
3370 /* --------------------------------------------------------------------------*/
3371 /* AN ORDER TO START OR COMMIT THE REPLICA CREATION ARRIVED FROM THE */
3372 /* MASTER. */
3373 /* --------------------------------------------------------------------------*/
execCREATE_FRAGREQ(Signal * signal)3374 void Dbdih::execCREATE_FRAGREQ(Signal* signal)
3375 {
3376 jamEntry();
3377 CreateFragReq * const req = (CreateFragReq *)&signal->theData[0];
3378
3379 TakeOverRecordPtr takeOverPtr;
3380 takeOverPtr.i = req->userPtr;
3381 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3382
3383 BlockReference retRef = req->userRef;
3384
3385 TabRecordPtr tabPtr;
3386 tabPtr.i = req->tableId;
3387 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
3388
3389 Uint32 fragId = req->fragId;
3390 Uint32 tdestNodeid = req->startingNodeId;
3391 Uint32 tsourceNodeid = req->copyNodeId;
3392 Uint32 startGci = req->startGci;
3393 Uint32 replicaType = req->replicaType;
3394
3395 FragmentstorePtr fragPtr;
3396 getFragstore(tabPtr.p, fragId, fragPtr);
3397 RETURN_IF_NODE_NOT_ALIVE(tdestNodeid);
3398 ReplicaRecordPtr frReplicaPtr;
3399 findToReplica(takeOverPtr.p, replicaType, fragPtr, frReplicaPtr);
3400 ndbrequire(frReplicaPtr.i != RNIL);
3401
3402 switch (replicaType) {
3403 case CreateFragReq::STORED:
3404 jam();
3405 CRASH_INSERTION(7138);
3406 /* ----------------------------------------------------------------------*/
3407 /* HERE WE ARE INSERTING THE NEW BACKUP NODE IN THE EXECUTION OF ALL */
3408 /* OPERATIONS. FROM HERE ON ALL OPERATIONS ON THIS FRAGMENT WILL INCLUDE*/
3409 /* USE OF THE NEW REPLICA. */
3410 /* --------------------------------------------------------------------- */
3411 insertBackup(fragPtr, tdestNodeid);
3412 takeOverPtr.p->toCopyNode = tsourceNodeid;
3413 takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_CREATE_PREPARE;
3414
3415 fragPtr.p->distributionKey++;
3416 fragPtr.p->distributionKey &= 255;
3417 break;
3418 case CreateFragReq::COMMIT_STORED:
3419 jam();
3420 CRASH_INSERTION(7139);
3421 /* ----------------------------------------------------------------------*/
3422 /* HERE WE ARE MOVING THE REPLICA TO THE STORED SECTION SINCE IT IS NOW */
3423 /* FULLY LOADED WITH ALL DATA NEEDED. */
3424 // We also update the order of the replicas here so that if the new
3425 // replica is the desired primary we insert it as primary.
3426 /* ----------------------------------------------------------------------*/
3427 takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_CREATE_COMMIT;
3428 removeOldStoredReplica(fragPtr, frReplicaPtr);
3429 linkStoredReplica(fragPtr, frReplicaPtr);
3430 updateNodeInfo(fragPtr);
3431 break;
3432 default:
3433 ndbrequire(false);
3434 break;
3435 }//switch
3436
3437 /* ------------------------------------------------------------------------*/
3438 /* THE NEW NODE OF THIS REPLICA IS THE STARTING NODE. */
3439 /* ------------------------------------------------------------------------*/
3440 if (frReplicaPtr.p->procNode != takeOverPtr.p->toStartingNode) {
3441 jam();
3442 /* ---------------------------------------------------------------------*/
3443 /* IF WE ARE STARTING A TAKE OVER NODE WE MUST INVALIDATE ALL LCP'S. */
3444 /* OTHERWISE WE WILL TRY TO START LCP'S THAT DO NOT EXIST. */
3445 /* ---------------------------------------------------------------------*/
3446 frReplicaPtr.p->procNode = takeOverPtr.p->toStartingNode;
3447 frReplicaPtr.p->noCrashedReplicas = 0;
3448 frReplicaPtr.p->createGci[0] = startGci;
3449 ndbrequire(startGci != 0xF1F1F1F1);
3450 frReplicaPtr.p->replicaLastGci[0] = (Uint32)-1;
3451 for (Uint32 i = 0; i < MAX_LCP_STORED; i++) {
3452 frReplicaPtr.p->lcpStatus[i] = ZINVALID;
3453 }//for
3454 } else {
3455 jam();
3456 const Uint32 noCrashed = frReplicaPtr.p->noCrashedReplicas;
3457 arrGuard(noCrashed, 8);
3458 frReplicaPtr.p->createGci[noCrashed] = startGci;
3459 ndbrequire(startGci != 0xF1F1F1F1);
3460 frReplicaPtr.p->replicaLastGci[noCrashed] = (Uint32)-1;
3461 }//if
3462 takeOverPtr.p->toCurrentTabref = tabPtr.i;
3463 takeOverPtr.p->toCurrentFragid = fragId;
3464 CreateFragConf * const conf = (CreateFragConf *)&signal->theData[0];
3465 conf->userPtr = takeOverPtr.i;
3466 conf->tableId = tabPtr.i;
3467 conf->fragId = fragId;
3468 conf->sendingNodeId = cownNodeId;
3469 conf->startingNodeId = tdestNodeid;
3470 sendSignal(retRef, GSN_CREATE_FRAGCONF, signal,
3471 CreateFragConf::SignalLength, JBB);
3472 }//Dbdih::execCREATE_FRAGREQ()
3473
execCREATE_FRAGCONF(Signal * signal)3474 void Dbdih::execCREATE_FRAGCONF(Signal* signal)
3475 {
3476 jamEntry();
3477 CRASH_INSERTION(7148);
3478 const CreateFragConf * const conf = (CreateFragConf *)&signal->theData[0];
3479 Uint32 fragId = conf->fragId;
3480
3481 RETURN_IF_NODE_NOT_ALIVE(conf->startingNodeId);
3482
3483 TabRecordPtr tabPtr;
3484 tabPtr.i = conf->tableId;
3485 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
3486
3487 TakeOverRecordPtr takeOverPtr;
3488 takeOverPtr.i = conf->userPtr;
3489 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3490
3491 ndbrequire(tabPtr.i == takeOverPtr.p->toCurrentTabref);
3492 ndbrequire(fragId == takeOverPtr.p->toCurrentFragid);
3493 receiveLoopMacro(CREATE_FRAGREQ, conf->sendingNodeId);
3494 c_createFragmentLock = RNIL;
3495
3496 if (takeOverPtr.p->toMasterStatus == TakeOverRecord::PREPARE_CREATE) {
3497 jam();
3498 CRASH_INSERTION(7140);
3499 /* --------------------------------------------------------------------- */
3500 /* ALL NODES HAVE PREPARED THE INTRODUCTION OF THIS NEW NODE AND IT IS */
3501 /* ALREADY IN USE. WE CAN NOW START COPYING THE FRAGMENT. */
3502 /*---------------------------------------------------------------------- */
3503 FragmentstorePtr fragPtr;
3504 getFragstore(tabPtr.p, fragId, fragPtr);
3505 Uint32 gci = 0;
3506 if (takeOverPtr.p->toNodeRestart)
3507 {
3508 ReplicaRecordPtr replicaPtr;
3509 findReplica(replicaPtr, fragPtr.p, takeOverPtr.p->toStartingNode, true);
3510 gci = replicaPtr.p->lcpIdStarted;
3511 replicaPtr.p->lcpIdStarted = 0;
3512 }
3513 takeOverPtr.p->toMasterStatus = TakeOverRecord::COPY_FRAG;
3514 BlockReference ref = calcLqhBlockRef(takeOverPtr.p->toCopyNode);
3515 CopyFragReq * const copyFragReq = (CopyFragReq *)&signal->theData[0];
3516 copyFragReq->userPtr = takeOverPtr.i;
3517 copyFragReq->userRef = reference();
3518 copyFragReq->tableId = tabPtr.i;
3519 copyFragReq->fragId = fragId;
3520 copyFragReq->nodeId = takeOverPtr.p->toStartingNode;
3521 copyFragReq->schemaVersion = tabPtr.p->schemaVersion;
3522 copyFragReq->distributionKey = fragPtr.p->distributionKey;
3523 copyFragReq->gci = gci;
3524 Uint32 len = copyFragReq->nodeCount =
3525 extractNodeInfo(fragPtr.p,
3526 copyFragReq->nodeList);
3527 copyFragReq->nodeList[len] = takeOverPtr.p->maxPage;
3528 sendSignal(ref, GSN_COPY_FRAGREQ, signal,
3529 CopyFragReq::SignalLength + len, JBB);
3530 } else {
3531 ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COMMIT_CREATE);
3532 jam();
3533 CRASH_INSERTION(7141);
3534 /* --------------------------------------------------------------------- */
3535 // REPORT that copy of fragment has been completed.
3536 /* --------------------------------------------------------------------- */
3537 signal->theData[0] = NDB_LE_NR_CopyFragDone;
3538 signal->theData[1] = takeOverPtr.p->toStartingNode;
3539 signal->theData[2] = tabPtr.i;
3540 signal->theData[3] = takeOverPtr.p->toCurrentFragid;
3541 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
3542 /* --------------------------------------------------------------------- */
3543 /* WE HAVE NOW CREATED THIS NEW REPLICA AND WE ARE READY TO TAKE THE */
3544 /* THE NEXT REPLICA. */
3545 /* --------------------------------------------------------------------- */
3546
3547 Mutex mutex(signal, c_mutexMgr, takeOverPtr.p->m_switchPrimaryMutexHandle);
3548 mutex.unlock(); // ignore result
3549
3550 takeOverPtr.p->toCurrentFragid++;
3551 startNextCopyFragment(signal, takeOverPtr.i);
3552 }//if
3553 }//Dbdih::execCREATE_FRAGCONF()
3554
execCOPY_FRAGREF(Signal * signal)3555 void Dbdih::execCOPY_FRAGREF(Signal* signal)
3556 {
3557 const CopyFragRef * const ref = (CopyFragRef *)&signal->theData[0];
3558 jamEntry();
3559 Uint32 takeOverPtrI = ref->userPtr;
3560 Uint32 startingNodeId = ref->startingNodeId;
3561 Uint32 errorCode = ref->errorCode;
3562
3563 TakeOverRecordPtr takeOverPtr;
3564 RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
3565 ndbrequire(errorCode != ZNODE_FAILURE_ERROR);
3566 ndbrequire(ref->tableId == takeOverPtr.p->toCurrentTabref);
3567 ndbrequire(ref->fragId == takeOverPtr.p->toCurrentFragid);
3568 ndbrequire(ref->startingNodeId == takeOverPtr.p->toStartingNode);
3569 ndbrequire(ref->sendingNodeId == takeOverPtr.p->toCopyNode);
3570 ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_FRAG);
3571 endTakeOver(takeOverPtrI);
3572 //--------------------------------------------------------------------------
3573 // For some reason we did not succeed in copying a fragment. We treat this
3574 // as a serious failure and crash the starting node.
3575 //--------------------------------------------------------------------------
3576 BlockReference cntrRef = calcNdbCntrBlockRef(startingNodeId);
3577 SystemError * const sysErr = (SystemError*)&signal->theData[0];
3578 sysErr->errorCode = SystemError::CopyFragRefError;
3579 sysErr->errorRef = reference();
3580 sysErr->data1 = errorCode;
3581 sysErr->data2 = 0;
3582 sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal,
3583 SystemError::SignalLength, JBB);
3584 return;
3585 }//Dbdih::execCOPY_FRAGREF()
3586
execCOPY_FRAGCONF(Signal * signal)3587 void Dbdih::execCOPY_FRAGCONF(Signal* signal)
3588 {
3589 const CopyFragConf * const conf = (CopyFragConf *)&signal->theData[0];
3590 jamEntry();
3591 CRASH_INSERTION(7142);
3592
3593 TakeOverRecordPtr takeOverPtr;
3594 Uint32 takeOverPtrI = conf->userPtr;
3595 RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
3596
3597 ndbrequire(conf->tableId == takeOverPtr.p->toCurrentTabref);
3598 ndbrequire(conf->fragId == takeOverPtr.p->toCurrentFragid);
3599 ndbrequire(conf->startingNodeId == takeOverPtr.p->toStartingNode);
3600 ndbrequire(conf->sendingNodeId == takeOverPtr.p->toCopyNode);
3601 ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_FRAG);
3602 sendUpdateTo(signal, takeOverPtr.i,
3603 (Uint32)UpdateToReq::TO_COPY_FRAG_COMPLETED);
3604 }//Dbdih::execCOPY_FRAGCONF()
3605
sendUpdateTo(Signal * signal,Uint32 takeOverPtrI,Uint32 updateState)3606 void Dbdih::sendUpdateTo(Signal* signal,
3607 Uint32 takeOverPtrI, Uint32 updateState)
3608 {
3609 TakeOverRecordPtr takeOverPtr;
3610 RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
3611 if ((c_updateToLock != RNIL) ||
3612 ((ERROR_INSERTED(7163)) &&
3613 (updateState == UpdateToReq::TO_COPY_FRAG_COMPLETED)) ||
3614 ((ERROR_INSERTED(7169)) &&
3615 (updateState == UpdateToReq::TO_COPY_COMPLETED))) {
3616 jam();
3617 takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_UPDATE_TO;
3618 signal->theData[0] = DihContinueB::ZSEND_UPDATE_TO;
3619 signal->theData[1] = takeOverPtrI;
3620 signal->theData[2] = takeOverPtr.p->toStartingNode;
3621 signal->theData[3] = takeOverPtr.p->toFailedNode;
3622 signal->theData[4] = updateState;
3623 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 30, 5);
3624 return;
3625 }//if
3626 c_updateToLock = takeOverPtrI;
3627 if (updateState == UpdateToReq::TO_COPY_FRAG_COMPLETED) {
3628 jam();
3629 takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_UPDATE_TO;
3630 } else {
3631 jam();
3632 ndbrequire(updateState == UpdateToReq::TO_COPY_COMPLETED);
3633 takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_COPY_COMPLETED;
3634 }//if
3635
3636 UpdateToReq * const req = (UpdateToReq *)&signal->theData[0];
3637 req->userPtr = takeOverPtr.i;
3638 req->userRef = reference();
3639 req->updateState = (UpdateToReq::UpdateState)updateState;
3640 req->startingNodeId = takeOverPtr.p->toStartingNode;
3641 req->tableId = takeOverPtr.p->toCurrentTabref;
3642 req->fragmentNo = takeOverPtr.p->toCurrentFragid;
3643 sendLoopMacro(UPDATE_TOREQ, sendUPDATE_TOREQ);
3644 }//Dbdih::sendUpdateTo()
3645
execUPDATE_TOREQ(Signal * signal)3646 void Dbdih::execUPDATE_TOREQ(Signal* signal)
3647 {
3648 jamEntry();
3649 const UpdateToReq * const req = (UpdateToReq *)&signal->theData[0];
3650 BlockReference ref = req->userRef;
3651 ndbrequire(cmasterdihref == ref);
3652
3653 CRASH_INSERTION(7154);
3654 RETURN_IF_NODE_NOT_ALIVE(req->startingNodeId);
3655
3656 TakeOverRecordPtr takeOverPtr;
3657 takeOverPtr.i = req->userPtr;
3658 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3659
3660 ndbrequire(req->startingNodeId == takeOverPtr.p->toStartingNode);
3661 if (req->updateState == UpdateToReq::TO_COPY_FRAG_COMPLETED) {
3662 jam();
3663 ndbrequire(takeOverPtr.p->toSlaveStatus == TakeOverRecord::TO_SLAVE_CREATE_PREPARE);
3664 takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_COPY_FRAG_COMPLETED;
3665 takeOverPtr.p->toCurrentTabref = req->tableId;
3666 takeOverPtr.p->toCurrentFragid = req->fragmentNo;
3667 } else {
3668 jam();
3669 ndbrequire(req->updateState == UpdateToReq::TO_COPY_COMPLETED);
3670 takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_COPY_COMPLETED;
3671 setNodeCopyCompleted(takeOverPtr.p->toStartingNode, true);
3672 }//if
3673
3674
3675 UpdateToConf * const conf = (UpdateToConf *)&signal->theData[0];
3676 conf->userPtr = takeOverPtr.i;
3677 conf->sendingNodeId = cownNodeId;
3678 conf->startingNodeId = takeOverPtr.p->toStartingNode;
3679 sendSignal(ref, GSN_UPDATE_TOCONF, signal, UpdateToConf::SignalLength, JBB);
3680 }//Dbdih::execUPDATE_TOREQ()
3681
execUPDATE_TOCONF(Signal * signal)3682 void Dbdih::execUPDATE_TOCONF(Signal* signal)
3683 {
3684 const UpdateToConf * const conf = (UpdateToConf *)&signal->theData[0];
3685 CRASH_INSERTION(7152);
3686
3687 RETURN_IF_NODE_NOT_ALIVE(conf->startingNodeId);
3688
3689 TakeOverRecordPtr takeOverPtr;
3690 takeOverPtr.i = conf->userPtr;
3691 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3692
3693 receiveLoopMacro(UPDATE_TOREQ, conf->sendingNodeId);
3694 CRASH_INSERTION(7153);
3695 c_updateToLock = RNIL;
3696
3697 if (takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_COPY_COMPLETED) {
3698 jam();
3699 toCopyCompletedLab(signal, takeOverPtr);
3700 return;
3701 } else {
3702 ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_UPDATE_TO);
3703 }//if
3704 TabRecordPtr tabPtr;
3705 tabPtr.i = takeOverPtr.p->toCurrentTabref;
3706 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
3707
3708 FragmentstorePtr fragPtr;
3709 getFragstore(tabPtr.p, takeOverPtr.p->toCurrentFragid, fragPtr);
3710 takeOverPtr.p->toMasterStatus = TakeOverRecord::COPY_ACTIVE;
3711 BlockReference lqhRef = calcLqhBlockRef(takeOverPtr.p->toStartingNode);
3712 CopyActiveReq * const req = (CopyActiveReq *)&signal->theData[0];
3713 req->userPtr = takeOverPtr.i;
3714 req->userRef = reference();
3715 req->tableId = takeOverPtr.p->toCurrentTabref;
3716 req->fragId = takeOverPtr.p->toCurrentFragid;
3717 req->distributionKey = fragPtr.p->distributionKey;
3718
3719 sendSignal(lqhRef, GSN_COPY_ACTIVEREQ, signal,
3720 CopyActiveReq::SignalLength, JBB);
3721 }//Dbdih::execUPDATE_TOCONF()
3722
execCOPY_ACTIVECONF(Signal * signal)3723 void Dbdih::execCOPY_ACTIVECONF(Signal* signal)
3724 {
3725 const CopyActiveConf * const conf = (CopyActiveConf *)&signal->theData[0];
3726 jamEntry();
3727 CRASH_INSERTION(7143);
3728
3729 TakeOverRecordPtr takeOverPtr;
3730 takeOverPtr.i = conf->userPtr;
3731 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3732
3733 ndbrequire(conf->tableId == takeOverPtr.p->toCurrentTabref);
3734 ndbrequire(conf->fragId == takeOverPtr.p->toCurrentFragid);
3735 ndbrequire(checkNodeAlive(conf->startingNodeId));
3736 ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_ACTIVE);
3737
3738 takeOverPtr.p->startGci = conf->startGci;
3739 takeOverPtr.p->toMasterStatus = TakeOverRecord::LOCK_MUTEX;
3740
3741 Mutex mutex(signal, c_mutexMgr, takeOverPtr.p->m_switchPrimaryMutexHandle);
3742 Callback c = { safe_cast(&Dbdih::switchPrimaryMutex_locked), takeOverPtr.i };
3743 ndbrequire(mutex.lock(c));
3744 }//Dbdih::execCOPY_ACTIVECONF()
3745
3746 void
switchPrimaryMutex_locked(Signal * signal,Uint32 toPtrI,Uint32 retVal)3747 Dbdih::switchPrimaryMutex_locked(Signal* signal, Uint32 toPtrI, Uint32 retVal){
3748 jamEntry();
3749 ndbrequire(retVal == 0);
3750
3751 TakeOverRecordPtr takeOverPtr;
3752 takeOverPtr.i = toPtrI;
3753 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3754
3755 ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::LOCK_MUTEX);
3756
3757 if (!checkNodeAlive((takeOverPtr.p->toStartingNode))) {
3758 // We have mutex
3759 Mutex mutex(signal, c_mutexMgr, takeOverPtr.p->m_switchPrimaryMutexHandle);
3760 mutex.unlock(); // Ignore result
3761
3762 c_createFragmentLock = RNIL;
3763 c_CREATE_FRAGREQ_Counter.clearWaitingFor();
3764 endTakeOver(takeOverPtr.i);
3765 return;
3766 }
3767
3768 takeOverPtr.p->toMasterStatus = TakeOverRecord::COMMIT_CREATE;
3769 sendCreateFragReq(signal, takeOverPtr.p->startGci,
3770 CreateFragReq::COMMIT_STORED, takeOverPtr.i);
3771 }
3772
toCopyCompletedLab(Signal * signal,TakeOverRecordPtr takeOverPtr)3773 void Dbdih::toCopyCompletedLab(Signal * signal, TakeOverRecordPtr takeOverPtr)
3774 {
3775 signal->theData[0] = NDB_LE_NR_CopyFragsCompleted;
3776 signal->theData[1] = takeOverPtr.p->toStartingNode;
3777 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
3778
3779 if (getNodeState().getSystemRestartInProgress())
3780 {
3781 jam();
3782 infoEvent("Take over of node %d complete", takeOverPtr.p->toStartingNode);
3783 setNodeActiveStatus(takeOverPtr.p->toStartingNode, Sysfile::NS_Active);
3784 takeOverPtr.p->toMasterStatus = TakeOverRecord::WAIT_LCP;
3785 takeOverCompleted(takeOverPtr.p->toStartingNode);
3786 checkToCopy();
3787 checkToCopyCompleted(signal);
3788 return;
3789 }
3790
3791 c_lcpState.immediateLcpStart = true;
3792 takeOverPtr.p->toMasterStatus = TakeOverRecord::WAIT_LCP;
3793
3794 /*-----------------------------------------------------------------------*/
3795 /* NOW WE CAN ALLOW THE NEW NODE TO PARTICIPATE IN LOCAL CHECKPOINTS. */
3796 /* WHEN THE FIRST LOCAL CHECKPOINT IS READY WE DECLARE THE TAKE OVER AS */
3797 /* COMPLETED. SINCE LOCAL CHECKPOINTS HAVE BEEN BLOCKED DURING THE COPY */
3798 /* PROCESS WE MUST ALSO START A NEW LOCAL CHECKPOINT PROCESS BY ENSURING */
3799 /* THAT IT LOOKS LIKE IT IS TIME FOR A NEW LOCAL CHECKPOINT AND BY */
3800 /* UNBLOCKING THE LOCAL CHECKPOINT AGAIN. */
3801 /* --------------------------------------------------------------------- */
3802 }//Dbdih::toCopyCompletedLab()
3803
sendEndTo(Signal * signal,Uint32 takeOverPtrI)3804 void Dbdih::sendEndTo(Signal* signal, Uint32 takeOverPtrI)
3805 {
3806 TakeOverRecordPtr takeOverPtr;
3807 CRASH_INSERTION(7156);
3808 RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
3809 if ((c_endToLock != RNIL) || (ERROR_INSERTED(7164))) {
3810 jam();
3811 takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_ENDING;
3812 signal->theData[0] = DihContinueB::ZSEND_END_TO;
3813 signal->theData[1] = takeOverPtrI;
3814 signal->theData[2] = takeOverPtr.p->toStartingNode;
3815 signal->theData[3] = takeOverPtr.p->toFailedNode;
3816 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 30, 4);
3817 return;
3818 }//if
3819 c_endToLock = takeOverPtr.i;
3820 takeOverPtr.p->toMasterStatus = TakeOverRecord::ENDING;
3821 EndToReq * const req = (EndToReq *)&signal->theData[0];
3822 req->userPtr = takeOverPtr.i;
3823 req->userRef = reference();
3824 req->startingNodeId = takeOverPtr.p->toStartingNode;
3825 sendLoopMacro(END_TOREQ, sendEND_TOREQ);
3826 }//Dbdih::sendStartTo()
3827
execEND_TOREQ(Signal * signal)3828 void Dbdih::execEND_TOREQ(Signal* signal)
3829 {
3830 jamEntry();
3831 const EndToReq * const req = (EndToReq *)&signal->theData[0];
3832 BlockReference ref = req->userRef;
3833 Uint32 startingNodeId = req->startingNodeId;
3834
3835 CRASH_INSERTION(7144);
3836 RETURN_IF_NODE_NOT_ALIVE(startingNodeId);
3837
3838 TakeOverRecordPtr takeOverPtr;
3839 takeOverPtr.i = req->userPtr;
3840 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3841
3842 ndbrequire(startingNodeId == takeOverPtr.p->toStartingNode);
3843 takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_IDLE;
3844
3845 if (!isMaster()) {
3846 jam();
3847 endTakeOver(takeOverPtr.i);
3848 }//if
3849
3850 EndToConf * const conf = (EndToConf *)&signal->theData[0];
3851 conf->userPtr = takeOverPtr.i;
3852 conf->sendingNodeId = cownNodeId;
3853 conf->startingNodeId = startingNodeId;
3854 sendSignal(ref, GSN_END_TOCONF, signal, EndToConf::SignalLength, JBB);
3855 }//Dbdih::execEND_TOREQ()
3856
execEND_TOCONF(Signal * signal)3857 void Dbdih::execEND_TOCONF(Signal* signal)
3858 {
3859 const EndToConf * const conf = (EndToConf *)&signal->theData[0];
3860 jamEntry();
3861
3862 const Uint32 nodeId = conf->startingNodeId;
3863 CRASH_INSERTION(7145);
3864
3865 RETURN_IF_NODE_NOT_ALIVE(nodeId);
3866
3867 TakeOverRecordPtr takeOverPtr;
3868 takeOverPtr.i = conf->userPtr;
3869 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3870
3871 ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::ENDING);
3872 ndbrequire(nodeId == takeOverPtr.p->toStartingNode);
3873
3874 receiveLoopMacro(END_TOREQ, conf->sendingNodeId);
3875 CRASH_INSERTION(7146);
3876 c_endToLock = RNIL;
3877
3878 /* -----------------------------------------------------------------------*/
3879 /* WE HAVE FINALLY COMPLETED THE TAKE OVER. WE RESET THE STATUS AND CHECK*/
3880 /* IF ANY MORE TAKE OVERS ARE NEEDED AT THE MOMENT. */
3881 /* FIRST WE CHECK IF A RESTART IS ONGOING. IN THAT CASE WE RESTART PHASE */
3882 /* 4 AND CHECK IF ANY MORE TAKE OVERS ARE NEEDED BEFORE WE START NDB */
3883 /* CLUSTER. THIS CAN ONLY HAPPEN IN A SYSTEM RESTART. */
3884 /* ---------------------------------------------------------------------- */
3885 if (takeOverPtr.p->toNodeRestart) {
3886 jam();
3887 /* ----------------------------------------------------------------------*/
3888 /* THE TAKE OVER NODE WAS A STARTING NODE. WE WILL SEND START_COPYCONF */
3889 /* TO THE STARTING NODE SUCH THAT THE NODE CAN COMPLETE THE START-UP. */
3890 /* --------------------------------------------------------------------- */
3891 BlockReference ref = calcDihBlockRef(takeOverPtr.p->toStartingNode);
3892 signal->theData[0] = takeOverPtr.p->toStartingNode;
3893 sendSignal(ref, GSN_START_COPYCONF, signal, 1,JBB);
3894 }//if
3895 endTakeOver(takeOverPtr.i);
3896
3897 if (cstartPhase == ZNDB_SPH4) {
3898 jam();
3899 if (anyActiveTakeOver()) {
3900 jam();
3901 return;
3902 }//if
3903 ndbsttorry10Lab(signal, __LINE__);
3904 return;
3905 }//if
3906 checkStartTakeOver(signal);
3907 }//Dbdih::execEND_TOCONF()
3908
allocateTakeOver(TakeOverRecordPtr & takeOverPtr)3909 void Dbdih::allocateTakeOver(TakeOverRecordPtr& takeOverPtr)
3910 {
3911 if (isMaster()) {
3912 jam();
3913 //--------------------------------------------
3914 // Master already seized the take over record.
3915 //--------------------------------------------
3916 return;
3917 }//if
3918 if (takeOverPtr.i == cfirstfreeTakeOver) {
3919 jam();
3920 seizeTakeOver(takeOverPtr);
3921 } else {
3922 TakeOverRecordPtr nextTakeOverptr;
3923 TakeOverRecordPtr prevTakeOverptr;
3924 nextTakeOverptr.i = takeOverPtr.p->nextTakeOver;
3925 prevTakeOverptr.i = takeOverPtr.p->prevTakeOver;
3926 if (prevTakeOverptr.i != RNIL) {
3927 jam();
3928 ptrCheckGuard(prevTakeOverptr, MAX_NDB_NODES, takeOverRecord);
3929 prevTakeOverptr.p->nextTakeOver = nextTakeOverptr.i;
3930 }//if
3931 if (nextTakeOverptr.i != RNIL) {
3932 jam();
3933 ptrCheckGuard(nextTakeOverptr, MAX_NDB_NODES, takeOverRecord);
3934 nextTakeOverptr.p->prevTakeOver = prevTakeOverptr.i;
3935 }//if
3936 }//if
3937 }//Dbdih::allocateTakeOver()
3938
seizeTakeOver(TakeOverRecordPtr & takeOverPtr)3939 void Dbdih::seizeTakeOver(TakeOverRecordPtr& takeOverPtr)
3940 {
3941 TakeOverRecordPtr nextTakeOverptr;
3942 ndbrequire(cfirstfreeTakeOver != RNIL);
3943 takeOverPtr.i = cfirstfreeTakeOver;
3944 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3945 cfirstfreeTakeOver = takeOverPtr.p->nextTakeOver;
3946 nextTakeOverptr.i = takeOverPtr.p->nextTakeOver;
3947 if (nextTakeOverptr.i != RNIL) {
3948 jam();
3949 ptrCheckGuard(nextTakeOverptr, MAX_NDB_NODES, takeOverRecord);
3950 nextTakeOverptr.p->prevTakeOver = RNIL;
3951 }//if
3952 takeOverPtr.p->nextTakeOver = RNIL;
3953 takeOverPtr.p->prevTakeOver = RNIL;
3954 }//Dbdih::seizeTakeOver()
3955
endTakeOver(Uint32 takeOverPtrI)3956 void Dbdih::endTakeOver(Uint32 takeOverPtrI)
3957 {
3958 TakeOverRecordPtr takeOverPtr;
3959 takeOverPtr.i = takeOverPtrI;
3960 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3961
3962 if ((takeOverPtr.p->toMasterStatus != TakeOverRecord::IDLE) &&
3963 (takeOverPtr.p->toMasterStatus != TakeOverRecord::TO_WAIT_START_TAKE_OVER)) {
3964 jam();
3965 NodeGroupRecordPtr NGPtr;
3966 NodeRecordPtr nodePtr;
3967 nodePtr.i = takeOverPtr.p->toStartingNode;
3968 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
3969 NGPtr.i = nodePtr.p->nodeGroup;
3970 ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
3971 NGPtr.p->activeTakeOver = false;
3972 }//if
3973 setAllowNodeStart(takeOverPtr.p->toStartingNode, true);
3974 initTakeOver(takeOverPtr);
3975 releaseTakeOver(takeOverPtrI);
3976 }//Dbdih::endTakeOver()
3977
releaseTakeOver(Uint32 takeOverPtrI)3978 void Dbdih::releaseTakeOver(Uint32 takeOverPtrI)
3979 {
3980 TakeOverRecordPtr takeOverPtr;
3981 takeOverPtr.i = takeOverPtrI;
3982 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
3983
3984 takeOverPtr.p->nextTakeOver = cfirstfreeTakeOver;
3985 cfirstfreeTakeOver = takeOverPtr.i;
3986 }//Dbdih::releaseTakeOver()
3987
initTakeOver(TakeOverRecordPtr takeOverPtr)3988 void Dbdih::initTakeOver(TakeOverRecordPtr takeOverPtr)
3989 {
3990 takeOverPtr.p->toCopyNode = RNIL;
3991 takeOverPtr.p->toCurrentFragid = RNIL;
3992 takeOverPtr.p->toCurrentReplica = RNIL;
3993 takeOverPtr.p->toCurrentTabref = RNIL;
3994 takeOverPtr.p->toFailedNode = RNIL;
3995 takeOverPtr.p->toStartingNode = RNIL;
3996 takeOverPtr.p->prevTakeOver = RNIL;
3997 takeOverPtr.p->nextTakeOver = RNIL;
3998 takeOverPtr.p->toNodeRestart = false;
3999 takeOverPtr.p->toMasterStatus = TakeOverRecord::IDLE;
4000 takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_IDLE;
4001 }//Dbdih::initTakeOver()
4002
anyActiveTakeOver()4003 bool Dbdih::anyActiveTakeOver()
4004 {
4005 TakeOverRecordPtr takeOverPtr;
4006 for (takeOverPtr.i = 0; takeOverPtr.i < MAX_NDB_NODES; takeOverPtr.i++) {
4007 ptrAss(takeOverPtr, takeOverRecord);
4008 if (takeOverPtr.p->toMasterStatus != TakeOverRecord::IDLE) {
4009 jam();
4010 return true;
4011 }//if
4012 }//for
4013 return false;
4014 }//Dbdih::anyActiveTakeOver()
4015
4016 /*****************************************************************************/
4017 /* ------------------------------------------------------------------------- */
4018 /* WE HAVE BEEN REQUESTED TO PERFORM A SYSTEM RESTART. WE START BY */
4019 /* READING THE GCI FILES. THIS REQUEST WILL ONLY BE SENT TO THE MASTER */
4020 /* DIH. THAT MEANS WE HAVE TO REPLICATE THE INFORMATION WE READ FROM */
4021 /* OUR FILES TO ENSURE THAT ALL NODES HAVE THE SAME DISTRIBUTION */
4022 /* INFORMATION. */
4023 /* ------------------------------------------------------------------------- */
4024 /*****************************************************************************/
readGciFileLab(Signal * signal)4025 void Dbdih::readGciFileLab(Signal* signal)
4026 {
4027 FileRecordPtr filePtr;
4028 filePtr.i = crestartInfoFile[0];
4029 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4030 filePtr.p->reqStatus = FileRecord::OPENING_GCP;
4031
4032 openFileRo(signal, filePtr);
4033 }//Dbdih::readGciFileLab()
4034
openingGcpLab(Signal * signal,FileRecordPtr filePtr)4035 void Dbdih::openingGcpLab(Signal* signal, FileRecordPtr filePtr)
4036 {
4037 /* ----------------------------------------------------------------------- */
4038 /* WE HAVE SUCCESSFULLY OPENED A FILE CONTAINING INFORMATION ABOUT */
4039 /* THE GLOBAL CHECKPOINTS THAT ARE POSSIBLE TO RESTART. */
4040 /* ----------------------------------------------------------------------- */
4041 readRestorableGci(signal, filePtr);
4042 filePtr.p->reqStatus = FileRecord::READING_GCP;
4043 }//Dbdih::openingGcpLab()
4044
readingGcpLab(Signal * signal,FileRecordPtr filePtr)4045 void Dbdih::readingGcpLab(Signal* signal, FileRecordPtr filePtr)
4046 {
4047 /* ----------------------------------------------------------------------- */
4048 /* WE HAVE NOW SUCCESSFULLY MANAGED TO READ IN THE GLOBAL CHECKPOINT */
4049 /* INFORMATION FROM FILE. LATER WE WILL ADD SOME FUNCTIONALITY THAT */
4050 /* CHECKS THE RESTART TIMERS TO DEDUCE FROM WHERE TO RESTART. */
4051 /* NOW WE WILL SIMPLY RESTART FROM THE NEWEST GLOBAL CHECKPOINT */
4052 /* POSSIBLE TO RESTORE. */
4053 /* */
4054 /* BEFORE WE INVOKE DICT WE NEED TO COPY CRESTART_INFO TO ALL NODES. */
4055 /* WE ALSO COPY TO OUR OWN NODE. TO ENABLE US TO DO THIS PROPERLY WE */
4056 /* START BY CLOSING THIS FILE. */
4057 /* ----------------------------------------------------------------------- */
4058 globalData.m_restart_seq = ++SYSFILE->m_restart_seq;
4059 closeFile(signal, filePtr);
4060 filePtr.p->reqStatus = FileRecord::CLOSING_GCP;
4061 }//Dbdih::readingGcpLab()
4062
closingGcpLab(Signal * signal,FileRecordPtr filePtr)4063 void Dbdih::closingGcpLab(Signal* signal, FileRecordPtr filePtr)
4064 {
4065 if (Sysfile::getInitialStartOngoing(SYSFILE->systemRestartBits) == false){
4066 jam();
4067 selectMasterCandidateAndSend(signal);
4068 return;
4069 } else {
4070 jam();
4071 sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
4072 return;
4073 }//if
4074 }//Dbdih::closingGcpLab()
4075
4076 /* ------------------------------------------------------------------------- */
4077 /* SELECT THE MASTER CANDIDATE TO BE USED IN SYSTEM RESTARTS. */
4078 /* ------------------------------------------------------------------------- */
selectMasterCandidateAndSend(Signal * signal)4079 void Dbdih::selectMasterCandidateAndSend(Signal* signal)
4080 {
4081 setNodeGroups();
4082 signal->theData[0] = getOwnNodeId();
4083 signal->theData[1] = SYSFILE->lastCompletedGCI[getOwnNodeId()];
4084 sendSignal(cntrlblockref, GSN_DIH_RESTARTCONF, signal, 2, JBB);
4085
4086 NodeRecordPtr nodePtr;
4087 Uint32 node_groups[MAX_NDB_NODES];
4088 memset(node_groups, 0, sizeof(node_groups));
4089 for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
4090 jam();
4091 const Uint32 ng = Sysfile::getNodeGroup(nodePtr.i, SYSFILE->nodeGroups);
4092 if(ng != NO_NODE_GROUP_ID){
4093 ndbrequire(ng < MAX_NDB_NODES);
4094 node_groups[ng]++;
4095 }
4096 }
4097
4098 for (nodePtr.i = 0; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
4099 jam();
4100 Uint32 count = node_groups[nodePtr.i];
4101 if(count != 0 && count != cnoReplicas){
4102 char buf[255];
4103 BaseString::snprintf(buf, sizeof(buf),
4104 "Illegal configuration change."
4105 " Initial start needs to be performed "
4106 " when changing no of replicas (%d != %d)",
4107 node_groups[nodePtr.i], cnoReplicas);
4108 progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
4109 }
4110 }
4111 }//Dbdih::selectMasterCandidate()
4112
4113 /* ------------------------------------------------------------------------- */
4114 /* ERROR HANDLING DURING READING RESTORABLE GCI FROM FILE. */
4115 /* ------------------------------------------------------------------------- */
openingGcpErrorLab(Signal * signal,FileRecordPtr filePtr)4116 void Dbdih::openingGcpErrorLab(Signal* signal, FileRecordPtr filePtr)
4117 {
4118 filePtr.p->fileStatus = FileRecord::CRASHED;
4119 filePtr.p->reqStatus = FileRecord::IDLE;
4120 if (crestartInfoFile[0] == filePtr.i) {
4121 jam();
4122 /* --------------------------------------------------------------------- */
4123 /* THE FIRST FILE WAS NOT ABLE TO BE OPENED. SET STATUS TO CRASHED AND */
4124 /* TRY OPEN THE NEXT FILE. */
4125 /* --------------------------------------------------------------------- */
4126 filePtr.i = crestartInfoFile[1];
4127 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4128 openFileRo(signal, filePtr);
4129 filePtr.p->reqStatus = FileRecord::OPENING_GCP;
4130 } else {
4131 jam();
4132 /* --------------------------------------------------------------------- */
4133 /* WE FAILED IN OPENING THE SECOND FILE. BOTH FILES WERE CORRUPTED. WE */
4134 /* CANNOT CONTINUE THE RESTART IN THIS CASE. TELL NDBCNTR OF OUR */
4135 /* FAILURE. */
4136 /*---------------------------------------------------------------------- */
4137 sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
4138 return;
4139 }//if
4140 }//Dbdih::openingGcpErrorLab()
4141
readingGcpErrorLab(Signal * signal,FileRecordPtr filePtr)4142 void Dbdih::readingGcpErrorLab(Signal* signal, FileRecordPtr filePtr)
4143 {
4144 filePtr.p->fileStatus = FileRecord::CRASHED;
4145 /* ----------------------------------------------------------------------- */
4146 /* WE FAILED IN READING THE FILE AS WELL. WE WILL CLOSE THIS FILE. */
4147 /* ----------------------------------------------------------------------- */
4148 closeFile(signal, filePtr);
4149 filePtr.p->reqStatus = FileRecord::CLOSING_GCP_CRASH;
4150 }//Dbdih::readingGcpErrorLab()
4151
closingGcpCrashLab(Signal * signal,FileRecordPtr filePtr)4152 void Dbdih::closingGcpCrashLab(Signal* signal, FileRecordPtr filePtr)
4153 {
4154 if (crestartInfoFile[0] == filePtr.i) {
4155 jam();
4156 /* --------------------------------------------------------------------- */
4157 /* ERROR IN FIRST FILE, TRY THE SECOND FILE. */
4158 /* --------------------------------------------------------------------- */
4159 filePtr.i = crestartInfoFile[1];
4160 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4161 openFileRw(signal, filePtr);
4162 filePtr.p->reqStatus = FileRecord::OPENING_GCP;
4163 return;
4164 }//if
4165 /* ----------------------------------------------------------------------- */
4166 /* WE DISCOVERED A FAILURE WITH THE SECOND FILE AS WELL. THIS IS A */
4167 /* SERIOUS PROBLEM. REPORT FAILURE TO NDBCNTR. */
4168 /* ----------------------------------------------------------------------- */
4169 sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
4170 }//Dbdih::closingGcpCrashLab()
4171
4172 /*****************************************************************************/
4173 /* ------------------------------------------------------------------------- */
4174 /* THIS IS AN INITIAL RESTART. WE WILL CREATE THE TWO FILES DESCRIBING */
4175 /* THE GLOBAL CHECKPOINTS THAT ARE RESTORABLE. */
4176 /* ------------------------------------------------------------------------- */
4177 /*****************************************************************************/
initGciFilesLab(Signal * signal)4178 void Dbdih::initGciFilesLab(Signal* signal)
4179 {
4180 FileRecordPtr filePtr;
4181 filePtr.i = crestartInfoFile[0];
4182 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4183 createFileRw(signal, filePtr);
4184 filePtr.p->reqStatus = FileRecord::CREATING_GCP;
4185 }//Dbdih::initGciFilesLab()
4186
4187 /* ------------------------------------------------------------------------- */
4188 /* GLOBAL CHECKPOINT FILE HAVE BEEN SUCCESSFULLY CREATED. */
4189 /* ------------------------------------------------------------------------- */
creatingGcpLab(Signal * signal,FileRecordPtr filePtr)4190 void Dbdih::creatingGcpLab(Signal* signal, FileRecordPtr filePtr)
4191 {
4192 if (filePtr.i == crestartInfoFile[0]) {
4193 jam();
4194 /* --------------------------------------------------------------------- */
4195 /* IF CREATED FIRST THEN ALSO CREATE THE SECOND FILE. */
4196 /* --------------------------------------------------------------------- */
4197 filePtr.i = crestartInfoFile[1];
4198 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4199 createFileRw(signal, filePtr);
4200 filePtr.p->reqStatus = FileRecord::CREATING_GCP;
4201 } else {
4202 jam();
4203 /* --------------------------------------------------------------------- */
4204 /* BOTH FILES HAVE BEEN CREATED. NOW WRITE THE INITIAL DATA TO BOTH */
4205 /* OF THE FILES. */
4206 /* --------------------------------------------------------------------- */
4207 filePtr.i = crestartInfoFile[0];
4208 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4209 writeRestorableGci(signal, filePtr);
4210 filePtr.p->reqStatus = FileRecord::WRITE_INIT_GCP;
4211 }//if
4212 }//Dbdih::creatingGcpLab()
4213
4214 /* ------------------------------------------------------------------------- */
4215 /* WE HAVE SUCCESSFULLY WRITTEN A GCI FILE. */
4216 /* ------------------------------------------------------------------------- */
writeInitGcpLab(Signal * signal,FileRecordPtr filePtr)4217 void Dbdih::writeInitGcpLab(Signal* signal, FileRecordPtr filePtr)
4218 {
4219 filePtr.p->reqStatus = FileRecord::IDLE;
4220 if (filePtr.i == crestartInfoFile[0]) {
4221 jam();
4222 /* --------------------------------------------------------------------- */
4223 /* WE HAVE WRITTEN THE FIRST FILE NOW ALSO WRITE THE SECOND FILE. */
4224 /* --------------------------------------------------------------------- */
4225 filePtr.i = crestartInfoFile[1];
4226 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
4227 writeRestorableGci(signal, filePtr);
4228 filePtr.p->reqStatus = FileRecord::WRITE_INIT_GCP;
4229 } else {
4230 /* --------------------------------------------------------------------- */
4231 /* WE HAVE WRITTEN BOTH FILES. LEAVE BOTH FILES OPEN AND CONFIRM OUR */
4232 /* PART OF THE INITIAL START. */
4233 /* --------------------------------------------------------------------- */
4234 if (isMaster()) {
4235 jam();
4236 /*---------------------------------------------------------------------*/
4237 // IN MASTER NODES THE START REQUEST IS RECEIVED FROM NDBCNTR AND WE MUST
4238 // RESPOND WHEN COMPLETED.
4239 /*---------------------------------------------------------------------*/
4240 signal->theData[0] = reference();
4241 sendSignal(cndbStartReqBlockref, GSN_NDB_STARTCONF, signal, 1, JBB);
4242 } else {
4243 jam();
4244 ndbsttorry10Lab(signal, __LINE__);
4245 return;
4246 }//if
4247 }//if
4248 }//Dbdih::writeInitGcpLab()
4249
4250 /*****************************************************************************/
4251 /* ********** NODES DELETION MODULE *************/
4252 /*****************************************************************************/
4253 /*---------------------------------------------------------------------------*/
4254 /* LOGIC FOR NODE FAILURE */
4255 /*---------------------------------------------------------------------------*/
execNODE_FAILREP(Signal * signal)4256 void Dbdih::execNODE_FAILREP(Signal* signal)
4257 {
4258 Uint32 i;
4259 Uint32 failedNodes[MAX_NDB_NODES];
4260 jamEntry();
4261 NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0];
4262
4263 cfailurenr = nodeFail->failNo;
4264 Uint32 newMasterId = nodeFail->masterNodeId;
4265 const Uint32 noOfFailedNodes = nodeFail->noOfNodes;
4266
4267 if (ERROR_INSERTED(7179))
4268 {
4269 CLEAR_ERROR_INSERT_VALUE;
4270 }
4271
4272 if (ERROR_INSERTED(7184))
4273 {
4274 SET_ERROR_INSERT_VALUE(7000);
4275 }
4276
4277 /*-------------------------------------------------------------------------*/
4278 // The first step is to convert from a bit mask to an array of failed nodes.
4279 /*-------------------------------------------------------------------------*/
4280 Uint32 index = 0;
4281 for (i = 1; i < MAX_NDB_NODES; i++) {
4282 jam();
4283 if(NodeBitmask::get(nodeFail->theNodes, i)){
4284 jam();
4285 failedNodes[index] = i;
4286 index++;
4287 }//if
4288 }//for
4289 ndbrequire(noOfFailedNodes == index);
4290 ndbrequire(noOfFailedNodes - 1 < MAX_NDB_NODES);
4291
4292 /*-------------------------------------------------------------------------*/
4293 // The second step is to update the node status of the failed nodes, remove
4294 // them from the alive node list and put them into the dead node list. Also
4295 // update the number of nodes on-line.
4296 // We also set certain state variables ensuring that the node no longer is
4297 // used in transactions and also mark that we received this signal.
4298 /*-------------------------------------------------------------------------*/
4299 for (i = 0; i < noOfFailedNodes; i++) {
4300 jam();
4301 NodeRecordPtr TNodePtr;
4302 TNodePtr.i = failedNodes[i];
4303 ptrCheckGuard(TNodePtr, MAX_NDB_NODES, nodeRecord);
4304 TNodePtr.p->useInTransactions = false;
4305 TNodePtr.p->m_inclDihLcp = false;
4306 TNodePtr.p->recNODE_FAILREP = ZTRUE;
4307 if (TNodePtr.p->nodeStatus == NodeRecord::ALIVE) {
4308 jam();
4309 con_lineNodes--;
4310 TNodePtr.p->nodeStatus = NodeRecord::DIED_NOW;
4311 removeAlive(TNodePtr);
4312 insertDeadNode(TNodePtr);
4313 }//if
4314 }//for
4315
4316 /*-------------------------------------------------------------------------*/
4317 // Verify that we can continue to operate the cluster. If we cannot we will
4318 // not return from checkEscalation.
4319 /*-------------------------------------------------------------------------*/
4320 checkEscalation();
4321
4322 /*------------------------------------------------------------------------*/
4323 // Verify that a starting node has also crashed. Reset the node start record.
4324 /*-------------------------------------------------------------------------*/
4325 #if 0
4326 /**
4327 * Node will crash by itself...
4328 * nodeRestart is run then...
4329 */
4330 if (false && c_nodeStartMaster.startNode != RNIL && getNodeStatus(c_nodeStartMaster.startNode) == NodeRecord::ALIVE)
4331 {
4332 BlockReference cntrRef = calcNdbCntrBlockRef(c_nodeStartMaster.startNode);
4333 SystemError * const sysErr = (SystemError*)&signal->theData[0];
4334 sysErr->errorCode = SystemError::StartInProgressError;
4335 sysErr->errorRef = reference();
4336 sysErr->data1= 0;
4337 sysErr->data2= __LINE__;
4338 sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal, SystemError::SignalLength, JBA);
4339 nodeResetStart();
4340 }//if
4341 #endif
4342
4343 /*--------------------------------------------------*/
4344 /* */
4345 /* WE CHANGE THE REFERENCE TO MASTER DIH */
4346 /* BLOCK AND POINTER AT THIS PLACE IN THE CODE*/
4347 /*--------------------------------------------------*/
4348 Uint32 oldMasterId = cmasterNodeId;
4349 BlockReference oldMasterRef = cmasterdihref;
4350 cmasterdihref = calcDihBlockRef(newMasterId);
4351 cmasterNodeId = newMasterId;
4352
4353 const bool masterTakeOver = (oldMasterId != newMasterId);
4354
4355 for(i = 0; i < noOfFailedNodes; i++) {
4356 NodeRecordPtr failedNodePtr;
4357 failedNodePtr.i = failedNodes[i];
4358 ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
4359 Uint32 activeTakeOverPtr = findTakeOver(failedNodes[i]);
4360 if (oldMasterRef == reference()) {
4361 /*-------------------------------------------------------*/
4362 // Functions that need to be called only for master nodes.
4363 /*-------------------------------------------------------*/
4364 checkCopyTab(failedNodePtr);
4365 checkStopPermMaster(signal, failedNodePtr);
4366 checkWaitGCPMaster(signal, failedNodes[i]);
4367 checkTakeOverInMasterAllNodeFailure(signal, failedNodePtr);
4368 checkTakeOverInMasterCopyNodeFailure(signal, failedNodePtr.i);
4369 checkTakeOverInMasterStartNodeFailure(signal, activeTakeOverPtr);
4370 checkGcpOutstanding(signal, failedNodePtr.i);
4371 } else {
4372 jam();
4373 /*-----------------------------------------------------------*/
4374 // Functions that need to be called only for nodes that were
4375 // not master before these failures.
4376 /*-----------------------------------------------------------*/
4377 checkStopPermProxy(signal, failedNodes[i]);
4378 checkWaitGCPProxy(signal, failedNodes[i]);
4379 if (isMaster()) {
4380 /*-----------------------------------------------------------*/
4381 // We take over as master since old master has failed
4382 /*-----------------------------------------------------------*/
4383 handleTakeOverNewMaster(signal, activeTakeOverPtr);
4384 } else {
4385 /*-----------------------------------------------------------*/
4386 // We are not master and will not become master.
4387 /*-----------------------------------------------------------*/
4388 checkTakeOverInNonMasterStartNodeFailure(signal, activeTakeOverPtr);
4389 }//if
4390 }//if
4391 /*--------------------------------------------------*/
4392 // Functions that need to be called for all nodes.
4393 /*--------------------------------------------------*/
4394 checkStopMe(signal, failedNodePtr);
4395 failedNodeLcpHandling(signal, failedNodePtr);
4396 checkWaitDropTabFailedLqh(signal, failedNodePtr.i, 0); // 0 = start w/ tab 0
4397 startRemoveFailedNode(signal, failedNodePtr);
4398
4399 /**
4400 * This is the last function called
4401 * It modifies failedNodePtr.p->nodeStatus
4402 */
4403 failedNodeSynchHandling(signal, failedNodePtr);
4404 }//for
4405
4406 if(masterTakeOver){
4407 jam();
4408 startLcpMasterTakeOver(signal, oldMasterId);
4409 startGcpMasterTakeOver(signal, oldMasterId);
4410
4411 if(getNodeState().getNodeRestartInProgress()){
4412 jam();
4413 progError(__LINE__, NDBD_EXIT_MASTER_FAILURE_DURING_NR);
4414 }
4415 }
4416
4417
4418 if (isMaster()) {
4419 jam();
4420 setNodeRestartInfoBits();
4421 }//if
4422 }//Dbdih::execNODE_FAILREP()
4423
checkCopyTab(NodeRecordPtr failedNodePtr)4424 void Dbdih::checkCopyTab(NodeRecordPtr failedNodePtr)
4425 {
4426 jam();
4427
4428 if(c_nodeStartMaster.startNode != failedNodePtr.i){
4429 jam();
4430 return;
4431 }
4432
4433 switch(c_nodeStartMaster.m_outstandingGsn){
4434 case GSN_COPY_TABREQ:
4435 jam();
4436 ndbrequire(c_COPY_TABREQ_Counter.isWaitingFor(failedNodePtr.i));
4437 releaseTabPages(failedNodePtr.p->activeTabptr);
4438 c_COPY_TABREQ_Counter.clearWaitingFor(failedNodePtr.i);
4439 c_nodeStartMaster.wait = ZFALSE;
4440 break;
4441 case GSN_START_INFOREQ:
4442 case GSN_START_PERMCONF:
4443 case GSN_DICTSTARTREQ:
4444 case GSN_START_MECONF:
4445 jam();
4446 break;
4447 default:
4448 g_eventLogger.error("outstanding gsn: %s(%d)",
4449 getSignalName(c_nodeStartMaster.m_outstandingGsn),
4450 c_nodeStartMaster.m_outstandingGsn);
4451 ndbrequire(false);
4452 }
4453
4454 nodeResetStart();
4455 }//Dbdih::checkCopyTab()
4456
checkStopMe(Signal * signal,NodeRecordPtr failedNodePtr)4457 void Dbdih::checkStopMe(Signal* signal, NodeRecordPtr failedNodePtr)
4458 {
4459 jam();
4460 if (c_STOP_ME_REQ_Counter.isWaitingFor(failedNodePtr.i)){
4461 jam();
4462 ndbrequire(c_stopMe.clientRef != 0);
4463 StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
4464 stopMeConf->senderRef = calcDihBlockRef(failedNodePtr.i);
4465 stopMeConf->senderData = c_stopMe.clientData;
4466 sendSignal(reference(), GSN_STOP_ME_CONF, signal,
4467 StopMeConf::SignalLength, JBB);
4468 }//if
4469 }//Dbdih::checkStopMe()
4470
checkStopPermMaster(Signal * signal,NodeRecordPtr failedNodePtr)4471 void Dbdih::checkStopPermMaster(Signal* signal, NodeRecordPtr failedNodePtr)
4472 {
4473 DihSwitchReplicaRef* const ref = (DihSwitchReplicaRef*)&signal->theData[0];
4474 jam();
4475 if (c_DIH_SWITCH_REPLICA_REQ_Counter.isWaitingFor(failedNodePtr.i)){
4476 jam();
4477 ndbrequire(c_stopPermMaster.clientRef != 0);
4478 ref->senderNode = failedNodePtr.i;
4479 ref->errorCode = StopPermRef::NF_CausedAbortOfStopProcedure;
4480 sendSignal(reference(), GSN_DIH_SWITCH_REPLICA_REF, signal,
4481 DihSwitchReplicaRef::SignalLength, JBB);
4482 return;
4483 }//if
4484 }//Dbdih::checkStopPermMaster()
4485
checkStopPermProxy(Signal * signal,NodeId failedNodeId)4486 void Dbdih::checkStopPermProxy(Signal* signal, NodeId failedNodeId)
4487 {
4488 jam();
4489 if(c_stopPermProxy.clientRef != 0 &&
4490 refToNode(c_stopPermProxy.masterRef) == failedNodeId){
4491
4492 /**
4493 * The master has failed report to proxy-client
4494 */
4495 jam();
4496 StopPermRef* const ref = (StopPermRef*)&signal->theData[0];
4497
4498 ref->senderData = c_stopPermProxy.clientData;
4499 ref->errorCode = StopPermRef::NF_CausedAbortOfStopProcedure;
4500 sendSignal(c_stopPermProxy.clientRef, GSN_STOP_PERM_REF, signal, 2, JBB);
4501 c_stopPermProxy.clientRef = 0;
4502 }//if
4503 }//Dbdih::checkStopPermProxy()
4504
4505 void
checkTakeOverInMasterAllNodeFailure(Signal * signal,NodeRecordPtr failedNodePtr)4506 Dbdih::checkTakeOverInMasterAllNodeFailure(Signal* signal,
4507 NodeRecordPtr failedNodePtr)
4508 {
4509 //------------------------------------------------------------------------
4510 // This code is used to handle the failure of "all" nodes during the
4511 // take over when "all" nodes are informed about state changes in
4512 // the take over protocol.
4513 //--------------------------------------------------------------------------
4514 if (c_START_TOREQ_Counter.isWaitingFor(failedNodePtr.i)){
4515 jam();
4516 StartToConf * const conf = (StartToConf *)&signal->theData[0];
4517 conf->userPtr = c_startToLock;
4518 conf->sendingNodeId = failedNodePtr.i;
4519 conf->startingNodeId = getStartNode(c_startToLock);
4520 sendSignal(reference(), GSN_START_TOCONF, signal,
4521 StartToConf::SignalLength, JBB);
4522 }//if
4523 if (c_CREATE_FRAGREQ_Counter.isWaitingFor(failedNodePtr.i)){
4524 jam();
4525 CreateFragConf * const conf = (CreateFragConf *)&signal->theData[0];
4526 TakeOverRecordPtr takeOverPtr;
4527 takeOverPtr.i = c_createFragmentLock;
4528 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
4529 conf->userPtr = takeOverPtr.i;
4530 conf->tableId = takeOverPtr.p->toCurrentTabref;
4531 conf->fragId = takeOverPtr.p->toCurrentFragid;
4532 conf->sendingNodeId = failedNodePtr.i;
4533 conf->startingNodeId = takeOverPtr.p->toStartingNode;
4534 sendSignal(reference(), GSN_CREATE_FRAGCONF, signal,
4535 CreateFragConf::SignalLength, JBB);
4536 }//if
4537 if (c_UPDATE_TOREQ_Counter.isWaitingFor(failedNodePtr.i)){
4538 jam();
4539 UpdateToConf * const conf = (UpdateToConf *)&signal->theData[0];
4540 conf->userPtr = c_updateToLock;
4541 conf->sendingNodeId = failedNodePtr.i;
4542 conf->startingNodeId = getStartNode(c_updateToLock);
4543 sendSignal(reference(), GSN_UPDATE_TOCONF, signal,
4544 UpdateToConf::SignalLength, JBB);
4545 }//if
4546
4547 if (c_END_TOREQ_Counter.isWaitingFor(failedNodePtr.i)){
4548 jam();
4549 EndToConf * const conf = (EndToConf *)&signal->theData[0];
4550 conf->userPtr = c_endToLock;
4551 conf->sendingNodeId = failedNodePtr.i;
4552 conf->startingNodeId = getStartNode(c_endToLock);
4553 sendSignal(reference(), GSN_END_TOCONF, signal,
4554 EndToConf::SignalLength, JBB);
4555 }//if
4556 }//Dbdih::checkTakeOverInMasterAllNodeFailure()
4557
checkTakeOverInMasterCopyNodeFailure(Signal * signal,Uint32 failedNodeId)4558 void Dbdih::checkTakeOverInMasterCopyNodeFailure(Signal* signal,
4559 Uint32 failedNodeId)
4560 {
4561 //---------------------------------------------------------------------------
4562 // This code is used to handle failure of the copying node during a take over
4563 //---------------------------------------------------------------------------
4564 TakeOverRecordPtr takeOverPtr;
4565 for (Uint32 i = 0; i < MAX_NDB_NODES; i++) {
4566 jam();
4567 takeOverPtr.i = i;
4568 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
4569 if ((takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_FRAG) &&
4570 (takeOverPtr.p->toCopyNode == failedNodeId)) {
4571 jam();
4572 /**
4573 * The copying node failed but the system is still operational.
4574 * We restart the copy process by selecting a new copy node.
4575 * We do not need to add a fragment however since it is already added.
4576 * We start again from the prepare create fragment phase.
4577 */
4578 prepareSendCreateFragReq(signal, takeOverPtr.i);
4579 }//if
4580 }//for
4581 }//Dbdih::checkTakeOverInMasterCopyNodeFailure()
4582
checkTakeOverInMasterStartNodeFailure(Signal * signal,Uint32 takeOverPtrI)4583 void Dbdih::checkTakeOverInMasterStartNodeFailure(Signal* signal,
4584 Uint32 takeOverPtrI)
4585 {
4586 jam();
4587 ndbout_c("checkTakeOverInMasterStartNodeFailure %x",
4588 takeOverPtrI);
4589 if (takeOverPtrI == RNIL) {
4590 jam();
4591 return;
4592 }
4593 //-----------------------------------------------------------------------
4594 // We are the master and the starting node has failed during a take over.
4595 // We need to handle this failure in different ways depending on the state.
4596 //-----------------------------------------------------------------------
4597
4598 TakeOverRecordPtr takeOverPtr;
4599 takeOverPtr.i = takeOverPtrI;
4600 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
4601
4602 ndbout_c("takeOverPtr.p->toMasterStatus: %x",
4603 takeOverPtr.p->toMasterStatus);
4604
4605 bool ok = false;
4606 switch (takeOverPtr.p->toMasterStatus) {
4607 case TakeOverRecord::IDLE:
4608 //-----------------------------------------------------------------------
4609 // The state cannot be idle when it has a starting node.
4610 //-----------------------------------------------------------------------
4611 ndbrequire(false);
4612 break;
4613 case TakeOverRecord::TO_WAIT_START_TAKE_OVER:
4614 jam();
4615 case TakeOverRecord::TO_START_COPY:
4616 jam();
4617 case TakeOverRecord::TO_START_COPY_ONGOING:
4618 jam();
4619 case TakeOverRecord::TO_WAIT_START:
4620 jam();
4621 case TakeOverRecord::TO_WAIT_PREPARE_CREATE:
4622 jam();
4623 case TakeOverRecord::TO_WAIT_UPDATE_TO:
4624 jam();
4625 case TakeOverRecord::TO_WAIT_COMMIT_CREATE:
4626 jam();
4627 case TakeOverRecord::TO_END_COPY:
4628 jam();
4629 case TakeOverRecord::TO_END_COPY_ONGOING:
4630 jam();
4631 case TakeOverRecord::TO_WAIT_ENDING:
4632 jam();
4633 //-----------------------------------------------------------------------
4634 // We will not do anything since an internal signal process is outstanding.
4635 // When the signal arrives the take over will be released.
4636 //-----------------------------------------------------------------------
4637 ok = true;
4638 break;
4639 case TakeOverRecord::STARTING:
4640 jam();
4641 ok = true;
4642 c_startToLock = RNIL;
4643 c_START_TOREQ_Counter.clearWaitingFor();
4644 endTakeOver(takeOverPtr.i);
4645 break;
4646 case TakeOverRecord::TO_UPDATE_TO:
4647 jam();
4648 ok = true;
4649 c_updateToLock = RNIL;
4650 c_UPDATE_TOREQ_Counter.clearWaitingFor();
4651 endTakeOver(takeOverPtr.i);
4652 break;
4653 case TakeOverRecord::ENDING:
4654 jam();
4655 ok = true;
4656 c_endToLock = RNIL;
4657 c_END_TOREQ_Counter.clearWaitingFor();
4658 endTakeOver(takeOverPtr.i);
4659 break;
4660 case TakeOverRecord::COMMIT_CREATE:
4661 ok = true;
4662 jam();
4663 {// We have mutex
4664 Mutex m(signal, c_mutexMgr, takeOverPtr.p->m_switchPrimaryMutexHandle);
4665 m.unlock(); // Ignore result
4666 }
4667 // Fall through
4668 case TakeOverRecord::PREPARE_CREATE:
4669 ok = true;
4670 jam();
4671 c_createFragmentLock = RNIL;
4672 c_CREATE_FRAGREQ_Counter.clearWaitingFor();
4673 endTakeOver(takeOverPtr.i);
4674 break;
4675 case TakeOverRecord::LOCK_MUTEX:
4676 ok = true;
4677 jam();
4678 // Lock mutex will return and do endTakeOver
4679 break;
4680
4681 //-----------------------------------------------------------------------
4682 // Signals are outstanding to external nodes. These signals carry the node
4683 // id of the starting node and will not use the take over record if the
4684 // starting node has failed.
4685 //-----------------------------------------------------------------------
4686 case TakeOverRecord::COPY_FRAG:
4687 ok = true;
4688 jam();
4689 //-----------------------------------------------------------------------
4690 // The copying node will discover the problem. We will receive either
4691 // COPY_FRAGREQ or COPY_FRAGCONF and then we can release the take over
4692 // record and end the process. If the copying node should also die then
4693 // we will try to send prepare create fragment and will then discover
4694 // that the starting node has failed.
4695 //-----------------------------------------------------------------------
4696 break;
4697 case TakeOverRecord::PREPARE_COPY:
4698 ok = true;
4699 jam();
4700 /**
4701 * We're waiting for the starting node...which just died...
4702 * endTakeOver
4703 */
4704 endTakeOver(takeOverPtr.i);
4705 break;
4706 case TakeOverRecord::COPY_ACTIVE:
4707 ok = true;
4708 jam();
4709 //-----------------------------------------------------------------------
4710 // In this we are waiting for a signal from the starting node. Thus we
4711 // can release the take over record and end the process.
4712 //-----------------------------------------------------------------------
4713 endTakeOver(takeOverPtr.i);
4714 break;
4715 case TakeOverRecord::WAIT_LCP:
4716 ok = true;
4717 jam();
4718 //-----------------------------------------------------------------------
4719 //-----------------------------------------------------------------------
4720 endTakeOver(takeOverPtr.i);
4721 break;
4722
4723 case TakeOverRecord::STARTING_LOCAL_FRAGMENTS:
4724 ok = true;
4725 jam();
4726 endTakeOver(takeOverPtr.i);
4727 break;
4728
4729 /**
4730 * The following are states that it should not be possible to "be" in
4731 */
4732 case TakeOverRecord::SELECTING_NEXT:
4733 jam();
4734 case TakeOverRecord::TO_COPY_COMPLETED:
4735 jam();
4736 ndbrequire(false);
4737 }
4738 if(!ok){
4739 jamLine(takeOverPtr.p->toSlaveStatus);
4740 ndbrequire(ok);
4741 }
4742 }//Dbdih::checkTakeOverInMasterStartNodeFailure()
4743
checkTakeOverInNonMasterStartNodeFailure(Signal * signal,Uint32 takeOverPtrI)4744 void Dbdih::checkTakeOverInNonMasterStartNodeFailure(Signal* signal,
4745 Uint32 takeOverPtrI)
4746 {
4747 jam();
4748 if (takeOverPtrI == RNIL) {
4749 jam();
4750 return;
4751 }
4752 //-----------------------------------------------------------------------
4753 // We are not master and not taking over as master. A take over was ongoing
4754 // but the starting node has now failed. Handle it according to the state
4755 // of the take over.
4756 //-----------------------------------------------------------------------
4757 TakeOverRecordPtr takeOverPtr;
4758 takeOverPtr.i = takeOverPtrI;
4759 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
4760 bool ok = false;
4761 switch (takeOverPtr.p->toSlaveStatus) {
4762 case TakeOverRecord::TO_SLAVE_IDLE:
4763 ndbrequire(false);
4764 break;
4765 case TakeOverRecord::TO_SLAVE_STARTED:
4766 jam();
4767 case TakeOverRecord::TO_SLAVE_CREATE_PREPARE:
4768 jam();
4769 case TakeOverRecord::TO_SLAVE_COPY_FRAG_COMPLETED:
4770 jam();
4771 case TakeOverRecord::TO_SLAVE_CREATE_COMMIT:
4772 jam();
4773 case TakeOverRecord::TO_SLAVE_COPY_COMPLETED:
4774 jam();
4775 ok = true;
4776 endTakeOver(takeOverPtr.i);
4777 break;
4778 }//switch
4779 if(!ok){
4780 jamLine(takeOverPtr.p->toSlaveStatus);
4781 ndbrequire(ok);
4782 }
4783 }//Dbdih::checkTakeOverInNonMasterStartNodeFailure()
4784
failedNodeSynchHandling(Signal * signal,NodeRecordPtr failedNodePtr)4785 void Dbdih::failedNodeSynchHandling(Signal* signal,
4786 NodeRecordPtr failedNodePtr)
4787 {
4788 jam();
4789 /*----------------------------------------------------*/
4790 /* INITIALISE THE VARIABLES THAT KEEP TRACK OF */
4791 /* WHEN A NODE FAILURE IS COMPLETED. */
4792 /*----------------------------------------------------*/
4793 failedNodePtr.p->dbdictFailCompleted = ZFALSE;
4794 failedNodePtr.p->dbtcFailCompleted = ZFALSE;
4795 failedNodePtr.p->dbdihFailCompleted = ZFALSE;
4796 failedNodePtr.p->dblqhFailCompleted = ZFALSE;
4797
4798 failedNodePtr.p->m_NF_COMPLETE_REP.clearWaitingFor();
4799
4800 NodeRecordPtr nodePtr;
4801 for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
4802 ptrAss(nodePtr, nodeRecord);
4803 if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
4804 jam();
4805 /**
4806 * We'r waiting for nodePtr.i to complete
4807 * handling of failedNodePtr.i's death
4808 */
4809
4810 failedNodePtr.p->m_NF_COMPLETE_REP.setWaitingFor(nodePtr.i);
4811 } else {
4812 jam();
4813 if ((nodePtr.p->nodeStatus == NodeRecord::DYING) &&
4814 (nodePtr.p->m_NF_COMPLETE_REP.isWaitingFor(failedNodePtr.i))){
4815 jam();
4816 /*----------------------------------------------------*/
4817 /* THE NODE FAILED BEFORE REPORTING THE FAILURE */
4818 /* HANDLING COMPLETED ON THIS FAILED NODE. */
4819 /* REPORT THAT NODE FAILURE HANDLING WAS */
4820 /* COMPLETED ON THE NEW FAILED NODE FOR THIS */
4821 /* PARTICULAR OLD FAILED NODE. */
4822 /*----------------------------------------------------*/
4823 NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
4824 nf->blockNo = 0;
4825 nf->nodeId = failedNodePtr.i;
4826 nf->failedNodeId = nodePtr.i;
4827 nf->from = __LINE__;
4828 sendSignal(reference(), GSN_NF_COMPLETEREP, signal,
4829 NFCompleteRep::SignalLength, JBB);
4830 }//if
4831 }//if
4832 }//for
4833 if (failedNodePtr.p->nodeStatus == NodeRecord::DIED_NOW) {
4834 jam();
4835 failedNodePtr.p->nodeStatus = NodeRecord::DYING;
4836 } else {
4837 jam();
4838 /*----------------------------------------------------*/
4839 // No more processing needed when node not even started
4840 // yet. We give the node status to DEAD since we do not
4841 // care whether all nodes complete the node failure
4842 // handling. The node have not been included in the
4843 // node failure protocols.
4844 /*----------------------------------------------------*/
4845 failedNodePtr.p->nodeStatus = NodeRecord::DEAD;
4846 /**-----------------------------------------------------------------------
4847 * WE HAVE COMPLETED HANDLING THE NODE FAILURE IN DIH. WE CAN REPORT THIS
4848 * TO DIH THAT WAIT FOR THE OTHER BLOCKS TO BE CONCLUDED AS WELL.
4849 *-----------------------------------------------------------------------*/
4850 NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
4851 nf->blockNo = DBDIH;
4852 nf->nodeId = cownNodeId;
4853 nf->failedNodeId = failedNodePtr.i;
4854 nf->from = __LINE__;
4855 sendSignal(reference(), GSN_NF_COMPLETEREP, signal,
4856 NFCompleteRep::SignalLength, JBB);
4857 }//if
4858 }//Dbdih::failedNodeSynchHandling()
4859
findTakeOver(Uint32 failedNodeId)4860 Uint32 Dbdih::findTakeOver(Uint32 failedNodeId)
4861 {
4862 for (Uint32 i = 0; i < MAX_NDB_NODES; i++) {
4863 jam();
4864 TakeOverRecordPtr takeOverPtr;
4865 takeOverPtr.i = i;
4866 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
4867 if (takeOverPtr.p->toStartingNode == failedNodeId) {
4868 jam();
4869 return i;
4870 }//if
4871 }//for
4872 return RNIL;
4873 }//Dbdih::findTakeOver()
4874
getStartNode(Uint32 takeOverPtrI)4875 Uint32 Dbdih::getStartNode(Uint32 takeOverPtrI)
4876 {
4877 TakeOverRecordPtr takeOverPtr;
4878 takeOverPtr.i = takeOverPtrI;
4879 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
4880 return takeOverPtr.p->toStartingNode;
4881 }//Dbdih::getStartNode()
4882
failedNodeLcpHandling(Signal * signal,NodeRecordPtr failedNodePtr)4883 void Dbdih::failedNodeLcpHandling(Signal* signal, NodeRecordPtr failedNodePtr)
4884 {
4885 jam();
4886 const Uint32 nodeId = failedNodePtr.i;
4887
4888 if (isMaster() && c_lcpState.m_participatingLQH.get(failedNodePtr.i))
4889 {
4890 /*----------------------------------------------------*/
4891 /* THE NODE WAS INVOLVED IN A LOCAL CHECKPOINT. WE */
4892 /* MUST UPDATE THE ACTIVE STATUS TO INDICATE THAT */
4893 /* THE NODE HAVE MISSED A LOCAL CHECKPOINT. */
4894 /*----------------------------------------------------*/
4895
4896 /**
4897 * Bug#28717, Only master should do this, as this status is copied
4898 * to other nodes
4899 */
4900 switch (failedNodePtr.p->activeStatus) {
4901 case Sysfile::NS_Active:
4902 jam();
4903 failedNodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
4904 break;
4905 case Sysfile::NS_ActiveMissed_1:
4906 jam();
4907 failedNodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_2;
4908 break;
4909 case Sysfile::NS_ActiveMissed_2:
4910 jam();
4911 failedNodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
4912 break;
4913 case Sysfile::NS_TakeOver:
4914 jam();
4915 failedNodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
4916 break;
4917 default:
4918 g_eventLogger.error("activeStatus = %u "
4919 "at failure after NODE_FAILREP of node = %u",
4920 (Uint32) failedNodePtr.p->activeStatus,
4921 failedNodePtr.i);
4922 ndbrequire(false);
4923 break;
4924 }//switch
4925 }//if
4926
4927 c_lcpState.m_participatingDIH.clear(failedNodePtr.i);
4928 c_lcpState.m_participatingLQH.clear(failedNodePtr.i);
4929
4930 if(c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.isWaitingFor(failedNodePtr.i)){
4931 jam();
4932 LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
4933 rep->nodeId = failedNodePtr.i;
4934 rep->lcpId = SYSFILE->latestLCP_ID;
4935 rep->blockNo = DBDIH;
4936 sendSignal(reference(), GSN_LCP_COMPLETE_REP, signal,
4937 LcpCompleteRep::SignalLength, JBB);
4938 }
4939
4940 /**
4941 * Check if we'r waiting for the failed node's LQH to complete
4942 *
4943 * Note that this is ran "before" LCP master take over
4944 */
4945 if(c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.isWaitingFor(nodeId)){
4946 jam();
4947
4948 LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
4949 rep->nodeId = nodeId;
4950 rep->lcpId = SYSFILE->latestLCP_ID;
4951 rep->blockNo = DBLQH;
4952 sendSignal(reference(), GSN_LCP_COMPLETE_REP, signal,
4953 LcpCompleteRep::SignalLength, JBB);
4954
4955 if(c_lcpState.m_LAST_LCP_FRAG_ORD.isWaitingFor(nodeId)){
4956 jam();
4957 /**
4958 * Make sure we're ready to accept it
4959 */
4960 c_lcpState.m_LAST_LCP_FRAG_ORD.clearWaitingFor(nodeId);
4961 }
4962 }
4963
4964 if (c_TCGETOPSIZEREQ_Counter.isWaitingFor(failedNodePtr.i)) {
4965 jam();
4966 signal->theData[0] = failedNodePtr.i;
4967 signal->theData[1] = 0;
4968 sendSignal(reference(), GSN_TCGETOPSIZECONF, signal, 2, JBB);
4969 }//if
4970
4971 if (c_TC_CLOPSIZEREQ_Counter.isWaitingFor(failedNodePtr.i)) {
4972 jam();
4973 signal->theData[0] = failedNodePtr.i;
4974 sendSignal(reference(), GSN_TC_CLOPSIZECONF, signal, 1, JBB);
4975 }//if
4976
4977 if (c_START_LCP_REQ_Counter.isWaitingFor(failedNodePtr.i)) {
4978 jam();
4979 StartLcpConf * conf = (StartLcpConf*)signal->getDataPtrSend();
4980 conf->senderRef = numberToRef(DBLQH, failedNodePtr.i);
4981 conf->lcpId = SYSFILE->latestLCP_ID;
4982 sendSignal(reference(), GSN_START_LCP_CONF, signal,
4983 StartLcpConf::SignalLength, JBB);
4984 }//if
4985
4986 if (c_EMPTY_LCP_REQ_Counter.isWaitingFor(failedNodePtr.i)) {
4987 jam();
4988 EmptyLcpConf * const rep = (EmptyLcpConf *)&signal->theData[0];
4989 rep->senderNodeId = failedNodePtr.i;
4990 rep->tableId = ~0;
4991 rep->fragmentId = ~0;
4992 rep->lcpNo = 0;
4993 rep->lcpId = SYSFILE->latestLCP_ID;
4994 rep->idle = true;
4995 sendSignal(reference(), GSN_EMPTY_LCP_CONF, signal,
4996 EmptyLcpConf::SignalLength, JBB);
4997 }//if
4998
4999 if (c_MASTER_LCPREQ_Counter.isWaitingFor(failedNodePtr.i)) {
5000 jam();
5001 MasterLCPRef * const ref = (MasterLCPRef *)&signal->theData[0];
5002 ref->senderNodeId = failedNodePtr.i;
5003 ref->failedNodeId = cmasterTakeOverNode;
5004 sendSignal(reference(), GSN_MASTER_LCPREF, signal,
5005 MasterLCPRef::SignalLength, JBB);
5006 }//if
5007
5008 }//Dbdih::failedNodeLcpHandling()
5009
checkGcpOutstanding(Signal * signal,Uint32 failedNodeId)5010 void Dbdih::checkGcpOutstanding(Signal* signal, Uint32 failedNodeId){
5011 if (c_GCP_PREPARE_Counter.isWaitingFor(failedNodeId)){
5012 jam();
5013 signal->theData[0] = failedNodeId;
5014 signal->theData[1] = cnewgcp;
5015 sendSignal(reference(), GSN_GCP_PREPARECONF, signal, 2, JBB);
5016 }//if
5017
5018 if (c_GCP_COMMIT_Counter.isWaitingFor(failedNodeId)) {
5019 jam();
5020 signal->theData[0] = failedNodeId;
5021 signal->theData[1] = coldgcp;
5022 signal->theData[2] = cfailurenr;
5023 sendSignal(reference(), GSN_GCP_NODEFINISH, signal, 3, JBB);
5024 }//if
5025
5026 if (c_GCP_SAVEREQ_Counter.isWaitingFor(failedNodeId)) {
5027 jam();
5028 GCPSaveRef * const saveRef = (GCPSaveRef*)&signal->theData[0];
5029 saveRef->dihPtr = failedNodeId;
5030 saveRef->nodeId = failedNodeId;
5031 saveRef->gci = coldgcp;
5032 saveRef->errorCode = GCPSaveRef::FakedSignalDueToNodeFailure;
5033 sendSignal(reference(), GSN_GCP_SAVEREF, signal,
5034 GCPSaveRef::SignalLength, JBB);
5035 }//if
5036
5037 if (c_COPY_GCIREQ_Counter.isWaitingFor(failedNodeId)) {
5038 jam();
5039 signal->theData[0] = failedNodeId;
5040 sendSignal(reference(), GSN_COPY_GCICONF, signal, 1, JBB);
5041 }//if
5042
5043 if (c_MASTER_GCPREQ_Counter.isWaitingFor(failedNodeId)){
5044 jam();
5045 MasterGCPRef * const ref = (MasterGCPRef *)&signal->theData[0];
5046 ref->senderNodeId = failedNodeId;
5047 ref->failedNodeId = cmasterTakeOverNode;
5048 sendSignal(reference(), GSN_MASTER_GCPREF, signal,
5049 MasterGCPRef::SignalLength, JBB);
5050 }//if
5051 }//Dbdih::handleGcpStateInMaster()
5052
5053
5054 void
startLcpMasterTakeOver(Signal * signal,Uint32 nodeId)5055 Dbdih::startLcpMasterTakeOver(Signal* signal, Uint32 nodeId){
5056 jam();
5057
5058 Uint32 oldNode = c_lcpMasterTakeOverState.failedNodeId;
5059
5060 c_lcpMasterTakeOverState.minTableId = ~0;
5061 c_lcpMasterTakeOverState.minFragId = ~0;
5062 c_lcpMasterTakeOverState.failedNodeId = nodeId;
5063
5064 c_lcpMasterTakeOverState.set(LMTOS_WAIT_EMPTY_LCP, __LINE__);
5065
5066 if(c_EMPTY_LCP_REQ_Counter.done()){
5067 jam();
5068 c_lcpState.m_LAST_LCP_FRAG_ORD.clearWaitingFor();
5069
5070 EmptyLcpReq* req = (EmptyLcpReq*)signal->getDataPtrSend();
5071 req->senderRef = reference();
5072 sendLoopMacro(EMPTY_LCP_REQ, sendEMPTY_LCP_REQ);
5073 ndbrequire(!c_EMPTY_LCP_REQ_Counter.done());
5074 } else {
5075 /**
5076 * Node failure during master take over...
5077 */
5078 g_eventLogger.info("Nodefail during master take over (old: %d)", oldNode);
5079 }
5080
5081 NodeRecordPtr nodePtr;
5082 nodePtr.i = oldNode;
5083 if (oldNode > 0 && oldNode < MAX_NDB_NODES)
5084 {
5085 jam();
5086 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
5087 if (nodePtr.p->m_nodefailSteps.get(NF_LCP_TAKE_OVER))
5088 {
5089 jam();
5090 checkLocalNodefailComplete(signal, oldNode, NF_LCP_TAKE_OVER);
5091 }
5092 }
5093
5094 setLocalNodefailHandling(signal, nodeId, NF_LCP_TAKE_OVER);
5095 }
5096
startGcpMasterTakeOver(Signal * signal,Uint32 oldMasterId)5097 void Dbdih::startGcpMasterTakeOver(Signal* signal, Uint32 oldMasterId){
5098 jam();
5099 /*--------------------------------------------------*/
5100 /* */
5101 /* THE MASTER HAVE FAILED AND WE WERE ELECTED */
5102 /* TO BE THE NEW MASTER NODE. WE NEED TO QUERY*/
5103 /* ALL THE OTHER NODES ABOUT THEIR STATUS IN */
5104 /* ORDER TO BE ABLE TO TAKE OVER CONTROL OF */
5105 /* THE GLOBAL CHECKPOINT PROTOCOL AND THE */
5106 /* LOCAL CHECKPOINT PROTOCOL. */
5107 /*--------------------------------------------------*/
5108 if(!isMaster()){
5109 jam();
5110 return;
5111 }
5112 cmasterState = MASTER_TAKE_OVER_GCP;
5113 cmasterTakeOverNode = oldMasterId;
5114 MasterGCPReq * const req = (MasterGCPReq *)&signal->theData[0];
5115 req->masterRef = reference();
5116 req->failedNodeId = oldMasterId;
5117 sendLoopMacro(MASTER_GCPREQ, sendMASTER_GCPREQ);
5118 cgcpMasterTakeOverState = GMTOS_INITIAL;
5119
5120 signal->theData[0] = NDB_LE_GCP_TakeoverStarted;
5121 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
5122
5123 setLocalNodefailHandling(signal, oldMasterId, NF_GCP_TAKE_OVER);
5124 }//Dbdih::handleNewMaster()
5125
handleTakeOverNewMaster(Signal * signal,Uint32 takeOverPtrI)5126 void Dbdih::handleTakeOverNewMaster(Signal* signal, Uint32 takeOverPtrI)
5127 {
5128 jam();
5129 if (takeOverPtrI != RNIL) {
5130 jam();
5131 TakeOverRecordPtr takeOverPtr;
5132 takeOverPtr.i = takeOverPtrI;
5133 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
5134 bool ok = false;
5135 switch (takeOverPtr.p->toSlaveStatus) {
5136 case TakeOverRecord::TO_SLAVE_IDLE:
5137 ndbrequire(false);
5138 break;
5139 case TakeOverRecord::TO_SLAVE_STARTED:
5140 jam();
5141 case TakeOverRecord::TO_SLAVE_CREATE_PREPARE:
5142 jam();
5143 case TakeOverRecord::TO_SLAVE_COPY_FRAG_COMPLETED:
5144 jam();
5145 case TakeOverRecord::TO_SLAVE_CREATE_COMMIT:
5146 jam();
5147 ok = true;
5148 infoEvent("Unhandled MasterTO of TO slaveStatus=%d killing node %d",
5149 takeOverPtr.p->toSlaveStatus,
5150 takeOverPtr.p->toStartingNode);
5151 takeOverPtr.p->toMasterStatus = TakeOverRecord::COPY_ACTIVE;
5152
5153 {
5154 BlockReference cntrRef = calcNdbCntrBlockRef(takeOverPtr.p->toStartingNode);
5155 SystemError * const sysErr = (SystemError*)&signal->theData[0];
5156 sysErr->errorCode = SystemError::CopyFragRefError;
5157 sysErr->errorRef = reference();
5158 sysErr->data1= 0;
5159 sysErr->data2= __LINE__;
5160 sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal,
5161 SystemError::SignalLength, JBB);
5162 }
5163 break;
5164 case TakeOverRecord::TO_SLAVE_COPY_COMPLETED:
5165 ok = true;
5166 jam();
5167 takeOverPtr.p->toMasterStatus = TakeOverRecord::WAIT_LCP;
5168 break;
5169 }
5170 ndbrequire(ok);
5171 endTakeOver(takeOverPtr.i);
5172 }//if
5173 }//Dbdih::handleTakeOverNewMaster()
5174
startRemoveFailedNode(Signal * signal,NodeRecordPtr failedNodePtr)5175 void Dbdih::startRemoveFailedNode(Signal* signal, NodeRecordPtr failedNodePtr)
5176 {
5177 Uint32 nodeId = failedNodePtr.i;
5178 if(failedNodePtr.p->nodeStatus != NodeRecord::DIED_NOW){
5179 jam();
5180 /**
5181 * Is node isn't alive. It can't be part of LCP
5182 */
5183 ndbrequire(!c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.isWaitingFor(nodeId));
5184
5185 /**
5186 * And there is no point in removing any replicas
5187 * It's dead...
5188 */
5189 return;
5190 }
5191
5192 /**
5193 * If node has node complete LCP
5194 * we need to remove it as undo might not be complete
5195 * bug#31257
5196 */
5197 failedNodePtr.p->m_remove_node_from_table_lcp_id = RNIL;
5198 if (c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.isWaitingFor(failedNodePtr.i))
5199 {
5200 jam();
5201 failedNodePtr.p->m_remove_node_from_table_lcp_id = SYSFILE->latestLCP_ID;
5202 }
5203
5204 jam();
5205
5206 if (!ERROR_INSERTED(7194))
5207 {
5208 signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
5209 signal->theData[1] = failedNodePtr.i;
5210 signal->theData[2] = 0; // Tab id
5211 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
5212 }
5213 else
5214 {
5215 ndbout_c("7194 Not starting ZREMOVE_NODE_FROM_TABLE");
5216 }
5217
5218 setLocalNodefailHandling(signal, failedNodePtr.i, NF_REMOVE_NODE_FROM_TABLE);
5219 }//Dbdih::startRemoveFailedNode()
5220
5221 /*--------------------------------------------------*/
5222 /* THE MASTER HAS FAILED AND THE NEW MASTER IS*/
5223 /* QUERYING THIS NODE ABOUT THE STATE OF THE */
5224 /* GLOBAL CHECKPOINT PROTOCOL */
5225 /*--------------------------------------------------*/
execMASTER_GCPREQ(Signal * signal)5226 void Dbdih::execMASTER_GCPREQ(Signal* signal)
5227 {
5228 NodeRecordPtr failedNodePtr;
5229 MasterGCPReq * const masterGCPReq = (MasterGCPReq *)&signal->theData[0];
5230 jamEntry();
5231 const BlockReference newMasterBlockref = masterGCPReq->masterRef;
5232 const Uint32 failedNodeId = masterGCPReq->failedNodeId;
5233 if (c_copyGCISlave.m_copyReason != CopyGCIReq::IDLE) {
5234 jam();
5235 /*--------------------------------------------------*/
5236 /* WE ARE CURRENTLY WRITING THE RESTART INFO */
5237 /* IN THIS NODE. SINCE ONLY ONE PROCESS IS */
5238 /* ALLOWED TO DO THIS AT A TIME WE MUST ENSURE*/
5239 /* THAT THIS IS NOT ONGOING WHEN THE NEW */
5240 /* MASTER TAKES OVER CONTROL. IF NOT ALL NODES*/
5241 /* RECEIVE THE SAME RESTART INFO DUE TO THE */
5242 /* FAILURE OF THE MASTER IT IS TAKEN CARE OF */
5243 /* BY THE NEW MASTER. */
5244 /*--------------------------------------------------*/
5245 sendSignalWithDelay(reference(), GSN_MASTER_GCPREQ,
5246 signal, 10, MasterGCPReq::SignalLength);
5247 return;
5248 }//if
5249 failedNodePtr.i = failedNodeId;
5250 ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
5251 if (failedNodePtr.p->nodeStatus == NodeRecord::ALIVE) {
5252 jam();
5253 /*--------------------------------------------------*/
5254 /* ENSURE THAT WE HAVE PROCESSED THE SIGNAL */
5255 /* NODE_FAILURE BEFORE WE PROCESS THIS REQUEST*/
5256 /* FROM THE NEW MASTER. THIS ENSURES THAT WE */
5257 /* HAVE REMOVED THE FAILED NODE FROM THE LIST */
5258 /* OF ACTIVE NODES AND SO FORTH. */
5259 /*--------------------------------------------------*/
5260 sendSignalWithDelay(reference(), GSN_MASTER_GCPREQ,
5261 signal, 10, MasterGCPReq::SignalLength);
5262 return;
5263 } else {
5264 ndbrequire(failedNodePtr.p->nodeStatus == NodeRecord::DYING);
5265 }//if
5266
5267 if (ERROR_INSERTED(7181))
5268 {
5269 ndbout_c("execGCP_TCFINISHED in MASTER_GCPREQ");
5270 CLEAR_ERROR_INSERT_VALUE;
5271 signal->theData[0] = c_error_7181_ref;
5272 signal->theData[1] = coldgcp;
5273 execGCP_TCFINISHED(signal);
5274 }
5275
5276 MasterGCPConf::State gcpState;
5277 switch (cgcpParticipantState) {
5278 case GCP_PARTICIPANT_READY:
5279 jam();
5280 /*--------------------------------------------------*/
5281 /* THE GLOBAL CHECKPOINT IS NOT ACTIVE SINCE */
5282 /* THE PREVIOUS GLOBAL CHECKPOINT IS COMPLETED*/
5283 /* AND THE NEW HAVE NOT STARTED YET. */
5284 /*--------------------------------------------------*/
5285 gcpState = MasterGCPConf::GCP_READY;
5286 break;
5287 case GCP_PARTICIPANT_PREPARE_RECEIVED:
5288 jam();
5289 /*--------------------------------------------------*/
5290 /* GCP_PREPARE HAVE BEEN RECEIVED AND RESPONSE*/
5291 /* HAVE BEEN SENT. */
5292 /*--------------------------------------------------*/
5293 gcpState = MasterGCPConf::GCP_PREPARE_RECEIVED;
5294 break;
5295 case GCP_PARTICIPANT_COMMIT_RECEIVED:
5296 jam();
5297 /*------------------------------------------------*/
5298 /* GCP_COMMIT HAVE BEEN RECEIVED BUT NOT YET*/
5299 /* GCP_TCFINISHED FROM LOCAL TC. */
5300 /*------------------------------------------------*/
5301 gcpState = MasterGCPConf::GCP_COMMIT_RECEIVED;
5302 break;
5303 case GCP_PARTICIPANT_TC_FINISHED:
5304 jam();
5305 /*------------------------------------------------*/
5306 /* GCP_COMMIT HAS BEEN RECEIVED AND ALSO */
5307 /* GCP_TCFINISHED HAVE BEEN RECEIVED. */
5308 /*------------------------------------------------*/
5309 gcpState = MasterGCPConf::GCP_TC_FINISHED;
5310 break;
5311 case GCP_PARTICIPANT_COPY_GCI_RECEIVED:
5312 /*--------------------------------------------------*/
5313 /* COPY RESTART INFORMATION HAS BEEN RECEIVED */
5314 /* BUT NOT YET COMPLETED. */
5315 /*--------------------------------------------------*/
5316 ndbrequire(false);
5317 gcpState= MasterGCPConf::GCP_READY; // remove warning
5318 break;
5319 default:
5320 /*------------------------------------------------*/
5321 /* */
5322 /* THIS SHOULD NOT OCCUR SINCE THE ABOVE */
5323 /* STATES ARE THE ONLY POSSIBLE STATES AT A */
5324 /* NODE WHICH WAS NOT A MASTER NODE. */
5325 /*------------------------------------------------*/
5326 ndbrequire(false);
5327 gcpState= MasterGCPConf::GCP_READY; // remove warning
5328 break;
5329 }//switch
5330 MasterGCPConf * const masterGCPConf = (MasterGCPConf *)&signal->theData[0];
5331 masterGCPConf->gcpState = gcpState;
5332 masterGCPConf->senderNodeId = cownNodeId;
5333 masterGCPConf->failedNodeId = failedNodeId;
5334 masterGCPConf->newGCP = cnewgcp;
5335 masterGCPConf->latestLCP = SYSFILE->latestLCP_ID;
5336 masterGCPConf->oldestRestorableGCI = SYSFILE->oldestRestorableGCI;
5337 masterGCPConf->keepGCI = SYSFILE->keepGCI;
5338 for(Uint32 i = 0; i < NdbNodeBitmask::Size; i++)
5339 masterGCPConf->lcpActive[i] = SYSFILE->lcpActive[i];
5340 sendSignal(newMasterBlockref, GSN_MASTER_GCPCONF, signal,
5341 MasterGCPConf::SignalLength, JBB);
5342
5343 if (ERROR_INSERTED(7182))
5344 {
5345 ndbout_c("execGCP_TCFINISHED in MASTER_GCPREQ");
5346 CLEAR_ERROR_INSERT_VALUE;
5347 signal->theData[0] = c_error_7181_ref;
5348 signal->theData[1] = coldgcp;
5349 execGCP_TCFINISHED(signal);
5350 }
5351 }//Dbdih::execMASTER_GCPREQ()
5352
execMASTER_GCPCONF(Signal * signal)5353 void Dbdih::execMASTER_GCPCONF(Signal* signal)
5354 {
5355 NodeRecordPtr senderNodePtr;
5356 MasterGCPConf * const masterGCPConf = (MasterGCPConf *)&signal->theData[0];
5357 jamEntry();
5358 senderNodePtr.i = masterGCPConf->senderNodeId;
5359 ptrCheckGuard(senderNodePtr, MAX_NDB_NODES, nodeRecord);
5360
5361 MasterGCPConf::State gcpState = (MasterGCPConf::State)masterGCPConf->gcpState;
5362 const Uint32 failedNodeId = masterGCPConf->failedNodeId;
5363 const Uint32 newGcp = masterGCPConf->newGCP;
5364 const Uint32 latestLcpId = masterGCPConf->latestLCP;
5365 const Uint32 oldestRestorableGci = masterGCPConf->oldestRestorableGCI;
5366 const Uint32 oldestKeepGci = masterGCPConf->keepGCI;
5367 if (latestLcpId > SYSFILE->latestLCP_ID) {
5368 jam();
5369 #if 0
5370 g_eventLogger.info("Dbdih: Setting SYSFILE->latestLCP_ID to %d",
5371 latestLcpId);
5372 SYSFILE->latestLCP_ID = latestLcpId;
5373 #endif
5374 SYSFILE->keepGCI = oldestKeepGci;
5375 SYSFILE->oldestRestorableGCI = oldestRestorableGci;
5376 for(Uint32 i = 0; i < NdbNodeBitmask::Size; i++)
5377 SYSFILE->lcpActive[i] = masterGCPConf->lcpActive[i];
5378 }//if
5379 switch (gcpState) {
5380 case MasterGCPConf::GCP_READY:
5381 jam();
5382 senderNodePtr.p->gcpstate = NodeRecord::READY;
5383 break;
5384 case MasterGCPConf::GCP_PREPARE_RECEIVED:
5385 jam();
5386 senderNodePtr.p->gcpstate = NodeRecord::PREPARE_RECEIVED;
5387 cnewgcp = newGcp;
5388 break;
5389 case MasterGCPConf::GCP_COMMIT_RECEIVED:
5390 jam();
5391 senderNodePtr.p->gcpstate = NodeRecord::COMMIT_SENT;
5392 break;
5393 case MasterGCPConf::GCP_TC_FINISHED:
5394 jam();
5395 senderNodePtr.p->gcpstate = NodeRecord::NODE_FINISHED;
5396 break;
5397 default:
5398 ndbrequire(false);
5399 break;
5400 }//switch
5401 switch (cgcpMasterTakeOverState) {
5402 case GMTOS_INITIAL:
5403 switch (gcpState) {
5404 case MasterGCPConf::GCP_READY:
5405 jam();
5406 cgcpMasterTakeOverState = ALL_READY;
5407 break;
5408 case MasterGCPConf::GCP_PREPARE_RECEIVED:
5409 jam();
5410 cgcpMasterTakeOverState = ALL_PREPARED;
5411 break;
5412 case MasterGCPConf::GCP_COMMIT_RECEIVED:
5413 jam();
5414 cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
5415 break;
5416 case MasterGCPConf::GCP_TC_FINISHED:
5417 jam();
5418 cgcpMasterTakeOverState = COMMIT_COMPLETED;
5419 break;
5420 default:
5421 ndbrequire(false);
5422 break;
5423 }//switch
5424 break;
5425 case ALL_READY:
5426 switch (gcpState) {
5427 case MasterGCPConf::GCP_READY:
5428 jam();
5429 /*empty*/;
5430 break;
5431 case MasterGCPConf::GCP_PREPARE_RECEIVED:
5432 jam();
5433 cgcpMasterTakeOverState = PREPARE_STARTED_NOT_COMMITTED;
5434 break;
5435 case MasterGCPConf::GCP_COMMIT_RECEIVED:
5436 ndbrequire(false);
5437 break;
5438 case MasterGCPConf::GCP_TC_FINISHED:
5439 jam();
5440 cgcpMasterTakeOverState = SAVE_STARTED_NOT_COMPLETED;
5441 break;
5442 default:
5443 ndbrequire(false);
5444 break;
5445 }//switch
5446 break;
5447 case PREPARE_STARTED_NOT_COMMITTED:
5448 switch (gcpState) {
5449 case MasterGCPConf::GCP_READY:
5450 jam();
5451 break;
5452 case MasterGCPConf::GCP_PREPARE_RECEIVED:
5453 jam();
5454 break;
5455 case MasterGCPConf::GCP_COMMIT_RECEIVED:
5456 ndbrequire(false);
5457 break;
5458 case MasterGCPConf::GCP_TC_FINISHED:
5459 ndbrequire(false);
5460 break;
5461 default:
5462 ndbrequire(false);
5463 break;
5464 }//switch
5465 break;
5466 case ALL_PREPARED:
5467 switch (gcpState) {
5468 case MasterGCPConf::GCP_READY:
5469 jam();
5470 cgcpMasterTakeOverState = PREPARE_STARTED_NOT_COMMITTED;
5471 break;
5472 case MasterGCPConf::GCP_PREPARE_RECEIVED:
5473 jam();
5474 break;
5475 case MasterGCPConf::GCP_COMMIT_RECEIVED:
5476 jam();
5477 cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
5478 break;
5479 case MasterGCPConf::GCP_TC_FINISHED:
5480 jam();
5481 cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
5482 break;
5483 default:
5484 ndbrequire(false);
5485 break;
5486 }//switch
5487 break;
5488 case COMMIT_STARTED_NOT_COMPLETED:
5489 switch (gcpState) {
5490 case MasterGCPConf::GCP_READY:
5491 ndbrequire(false);
5492 break;
5493 case MasterGCPConf::GCP_PREPARE_RECEIVED:
5494 jam();
5495 break;
5496 case MasterGCPConf::GCP_COMMIT_RECEIVED:
5497 jam();
5498 break;
5499 case MasterGCPConf::GCP_TC_FINISHED:
5500 jam();
5501 break;
5502 default:
5503 ndbrequire(false);
5504 break;
5505 }//switch
5506 break;
5507 case COMMIT_COMPLETED:
5508 switch (gcpState) {
5509 case MasterGCPConf::GCP_READY:
5510 cgcpMasterTakeOverState = SAVE_STARTED_NOT_COMPLETED;
5511 break;
5512 case MasterGCPConf::GCP_PREPARE_RECEIVED:
5513 jam();
5514 cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
5515 break;
5516 case MasterGCPConf::GCP_COMMIT_RECEIVED:
5517 jam();
5518 cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
5519 break;
5520 case MasterGCPConf::GCP_TC_FINISHED:
5521 jam();
5522 break;
5523 default:
5524 ndbrequire(false);
5525 break;
5526 }//switch
5527 break;
5528 case SAVE_STARTED_NOT_COMPLETED:
5529 switch (gcpState) {
5530 case MasterGCPConf::GCP_READY:
5531 jam();
5532 break;
5533 case MasterGCPConf::GCP_PREPARE_RECEIVED:
5534 ndbrequire(false);
5535 break;
5536 case MasterGCPConf::GCP_COMMIT_RECEIVED:
5537 ndbrequire(false);
5538 break;
5539 case MasterGCPConf::GCP_TC_FINISHED:
5540 jam();
5541 break;
5542 default:
5543 ndbrequire(false);
5544 break;
5545 }//switch
5546 break;
5547 default:
5548 ndbrequire(false);
5549 break;
5550 }//switch
5551 receiveLoopMacro(MASTER_GCPREQ, senderNodePtr.i);
5552 /*-------------------------------------------------------------------------*/
5553 // We have now received all responses and are ready to take over the GCP
5554 // protocol as master.
5555 /*-------------------------------------------------------------------------*/
5556 MASTER_GCPhandling(signal, failedNodeId);
5557 return;
5558 }//Dbdih::execMASTER_GCPCONF()
5559
execMASTER_GCPREF(Signal * signal)5560 void Dbdih::execMASTER_GCPREF(Signal* signal)
5561 {
5562 const MasterGCPRef * const ref = (MasterGCPRef *)&signal->theData[0];
5563 jamEntry();
5564 receiveLoopMacro(MASTER_GCPREQ, ref->senderNodeId);
5565 /*-------------------------------------------------------------------------*/
5566 // We have now received all responses and are ready to take over the GCP
5567 // protocol as master.
5568 /*-------------------------------------------------------------------------*/
5569 MASTER_GCPhandling(signal, ref->failedNodeId);
5570 }//Dbdih::execMASTER_GCPREF()
5571
MASTER_GCPhandling(Signal * signal,Uint32 failedNodeId)5572 void Dbdih::MASTER_GCPhandling(Signal* signal, Uint32 failedNodeId)
5573 {
5574 NodeRecordPtr failedNodePtr;
5575 cmasterState = MASTER_ACTIVE;
5576 /*----------------------------------------------------------*/
5577 /* REMOVE ALL ACTIVE STATUS ON ALREADY FAILED NODES */
5578 /* THIS IS PERFORMED HERE SINCE WE GET THE LCP ACTIVE */
5579 /* STATUS AS PART OF THE COPY RESTART INFO AND THIS IS*/
5580 /* HANDLED BY THE MASTER GCP TAKE OVER PROTOCOL. */
5581 /*----------------------------------------------------------*/
5582
5583 failedNodePtr.i = failedNodeId;
5584 ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
5585 switch (cgcpMasterTakeOverState) {
5586 case ALL_READY:
5587 jam();
5588 startGcp(signal);
5589 break;
5590 case PREPARE_STARTED_NOT_COMMITTED:
5591 {
5592 NodeRecordPtr nodePtr;
5593 jam();
5594 c_GCP_PREPARE_Counter.clearWaitingFor();
5595 nodePtr.i = cfirstAliveNode;
5596 do {
5597 jam();
5598 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
5599 if (nodePtr.p->gcpstate == NodeRecord::READY) {
5600 jam();
5601 c_GCP_PREPARE_Counter.setWaitingFor(nodePtr.i);
5602 sendGCP_PREPARE(signal, nodePtr.i);
5603 }//if
5604 nodePtr.i = nodePtr.p->nextNode;
5605 } while(nodePtr.i != RNIL);
5606 if (c_GCP_PREPARE_Counter.done()) {
5607 jam();
5608 gcpcommitreqLab(signal);
5609 }//if
5610 break;
5611 }
5612 case ALL_PREPARED:
5613 jam();
5614 gcpcommitreqLab(signal);
5615 break;
5616 case COMMIT_STARTED_NOT_COMPLETED:
5617 {
5618 NodeRecordPtr nodePtr;
5619 jam();
5620 c_GCP_COMMIT_Counter.clearWaitingFor();
5621 nodePtr.i = cfirstAliveNode;
5622 do {
5623 jam();
5624 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
5625 if (nodePtr.p->gcpstate == NodeRecord::PREPARE_RECEIVED) {
5626 jam();
5627 sendGCP_COMMIT(signal, nodePtr.i);
5628 c_GCP_COMMIT_Counter.setWaitingFor(nodePtr.i);
5629 } else {
5630 ndbrequire((nodePtr.p->gcpstate == NodeRecord::NODE_FINISHED) ||
5631 (nodePtr.p->gcpstate == NodeRecord::COMMIT_SENT));
5632 }//if
5633 nodePtr.i = nodePtr.p->nextNode;
5634 } while(nodePtr.i != RNIL);
5635 if (c_GCP_COMMIT_Counter.done()){
5636 jam();
5637 gcpsavereqLab(signal);
5638 }//if
5639 break;
5640 }
5641 case COMMIT_COMPLETED:
5642 jam();
5643 gcpsavereqLab(signal);
5644 break;
5645 case SAVE_STARTED_NOT_COMPLETED:
5646 {
5647 NodeRecordPtr nodePtr;
5648 jam();
5649 SYSFILE->newestRestorableGCI = coldgcp;
5650 nodePtr.i = cfirstAliveNode;
5651 do {
5652 jam();
5653 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
5654 SYSFILE->lastCompletedGCI[nodePtr.i] = coldgcp;
5655 nodePtr.i = nodePtr.p->nextNode;
5656 } while (nodePtr.i != RNIL);
5657 /**-------------------------------------------------------------------
5658 * THE FAILED NODE DID ALSO PARTICIPATE IN THIS GLOBAL CHECKPOINT
5659 * WHICH IS RECORDED.
5660 *-------------------------------------------------------------------*/
5661 SYSFILE->lastCompletedGCI[failedNodeId] = coldgcp;
5662 copyGciLab(signal, CopyGCIReq::GLOBAL_CHECKPOINT);
5663 break;
5664 }
5665 default:
5666 ndbrequire(false);
5667 break;
5668 }//switch
5669
5670 signal->theData[0] = NDB_LE_GCP_TakeoverCompleted;
5671 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
5672
5673 /*--------------------------------------------------*/
5674 /* WE SEPARATE HANDLING OF GLOBAL CHECKPOINTS */
5675 /* AND LOCAL CHECKPOINTS HERE. LCP'S HAVE TO */
5676 /* REMOVE ALL FAILED FRAGMENTS BEFORE WE CAN */
5677 /* HANDLE THE LCP PROTOCOL. */
5678 /*--------------------------------------------------*/
5679 checkLocalNodefailComplete(signal, failedNodeId, NF_GCP_TAKE_OVER);
5680
5681 return;
5682 }//Dbdih::masterGcpConfFromFailedLab()
5683
5684 void
invalidateNodeLCP(Signal * signal,Uint32 nodeId,Uint32 tableId)5685 Dbdih::invalidateNodeLCP(Signal* signal, Uint32 nodeId, Uint32 tableId)
5686 {
5687 jamEntry();
5688 TabRecordPtr tabPtr;
5689 tabPtr.i = tableId;
5690 const Uint32 RT_BREAK = 64;
5691 if (ERROR_INSERTED(7125)) {
5692 return;
5693 }//if
5694 for (Uint32 i = 0; i<RT_BREAK; i++) {
5695 jam();
5696 if (tabPtr.i >= ctabFileSize){
5697 jam();
5698 /**
5699 * Ready with entire loop
5700 * Return to master
5701 */
5702 setAllowNodeStart(nodeId, true);
5703 if (getNodeStatus(nodeId) == NodeRecord::STARTING) {
5704 jam();
5705 StartInfoConf * conf = (StartInfoConf*)&signal->theData[0];
5706 conf->sendingNodeId = cownNodeId;
5707 conf->startingNodeId = nodeId;
5708 sendSignal(cmasterdihref, GSN_START_INFOCONF, signal,
5709 StartInfoConf::SignalLength, JBB);
5710 }//if
5711 return;
5712 }//if
5713 ptrAss(tabPtr, tabRecord);
5714 if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
5715 jam();
5716 invalidateNodeLCP(signal, nodeId, tabPtr);
5717 return;
5718 }//if
5719 tabPtr.i++;
5720 }//for
5721 signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
5722 signal->theData[1] = nodeId;
5723 signal->theData[2] = tabPtr.i;
5724 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
5725 }//Dbdih::invalidateNodeLCP()
5726
5727 void
invalidateNodeLCP(Signal * signal,Uint32 nodeId,TabRecordPtr tabPtr)5728 Dbdih::invalidateNodeLCP(Signal* signal, Uint32 nodeId, TabRecordPtr tabPtr)
5729 {
5730 /**
5731 * Check so that no one else is using the tab descriptior
5732 */
5733 if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
5734 jam();
5735 signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
5736 signal->theData[1] = nodeId;
5737 signal->theData[2] = tabPtr.i;
5738 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 20, 3);
5739 return;
5740 }//if
5741
5742 /**
5743 * For each fragment
5744 */
5745 bool modified = false;
5746 FragmentstorePtr fragPtr;
5747 for(Uint32 fragNo = 0; fragNo < tabPtr.p->totalfragments; fragNo++){
5748 jam();
5749 getFragstore(tabPtr.p, fragNo, fragPtr);
5750 /**
5751 * For each of replica record
5752 */
5753 ReplicaRecordPtr replicaPtr;
5754 for(replicaPtr.i = fragPtr.p->oldStoredReplicas; replicaPtr.i != RNIL;
5755 replicaPtr.i = replicaPtr.p->nextReplica) {
5756 jam();
5757 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
5758 if(replicaPtr.p->procNode == nodeId){
5759 jam();
5760 /**
5761 * Found one with correct node id
5762 */
5763 /**
5764 * Invalidate all LCP's
5765 */
5766 modified = true;
5767 for(int i = 0; i < MAX_LCP_STORED; i++) {
5768 replicaPtr.p->lcpStatus[i] = ZINVALID;
5769 }//if
5770 /**
5771 * And reset nextLcp
5772 */
5773 replicaPtr.p->nextLcp = 0;
5774 replicaPtr.p->noCrashedReplicas = 0;
5775 }//if
5776 }//for
5777 }//for
5778
5779 if (modified) {
5780 jam();
5781 /**
5782 * Save table description to disk
5783 */
5784 tabPtr.p->tabCopyStatus = TabRecord::CS_INVALIDATE_NODE_LCP;
5785 tabPtr.p->tabUpdateState = TabRecord::US_INVALIDATE_NODE_LCP;
5786 tabPtr.p->tabRemoveNode = nodeId;
5787 signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
5788 signal->theData[1] = tabPtr.i;
5789 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
5790 return;
5791 }
5792
5793 jam();
5794 /**
5795 * Move to next table
5796 */
5797 tabPtr.i++;
5798 signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
5799 signal->theData[1] = nodeId;
5800 signal->theData[2] = tabPtr.i;
5801 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
5802 return;
5803 }//Dbdih::invalidateNodeLCP()
5804
5805 /*------------------------------------------------*/
5806 /* INPUT: TABPTR */
5807 /* TNODEID */
5808 /*------------------------------------------------*/
removeNodeFromTables(Signal * signal,Uint32 nodeId,Uint32 tableId)5809 void Dbdih::removeNodeFromTables(Signal* signal,
5810 Uint32 nodeId, Uint32 tableId)
5811 {
5812 jamEntry();
5813 TabRecordPtr tabPtr;
5814 tabPtr.i = tableId;
5815 const Uint32 RT_BREAK = 64;
5816 for (Uint32 i = 0; i<RT_BREAK; i++) {
5817 jam();
5818 if (tabPtr.i >= ctabFileSize){
5819 jam();
5820 removeNodeFromTablesComplete(signal, nodeId);
5821 return;
5822 }//if
5823
5824 ptrAss(tabPtr, tabRecord);
5825 if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
5826 jam();
5827 removeNodeFromTable(signal, nodeId, tabPtr);
5828 return;
5829 }//if
5830 tabPtr.i++;
5831 }//for
5832 signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
5833 signal->theData[1] = nodeId;
5834 signal->theData[2] = tabPtr.i;
5835 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
5836 }
5837
removeNodeFromTable(Signal * signal,Uint32 nodeId,TabRecordPtr tabPtr)5838 void Dbdih::removeNodeFromTable(Signal* signal,
5839 Uint32 nodeId, TabRecordPtr tabPtr){
5840
5841 /**
5842 * Check so that no one else is using the tab descriptior
5843 */
5844 if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
5845 jam();
5846 signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
5847 signal->theData[1] = nodeId;
5848 signal->theData[2] = tabPtr.i;
5849 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 20, 3);
5850 return;
5851 }//if
5852
5853 NodeRecordPtr nodePtr;
5854 nodePtr.i = nodeId;
5855 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
5856 const Uint32 lcpId = nodePtr.p->m_remove_node_from_table_lcp_id;
5857
5858 /**
5859 * For each fragment
5860 */
5861 Uint32 noOfRemovedReplicas = 0; // No of replicas removed
5862 Uint32 noOfRemovedLcpReplicas = 0; // No of replicas in LCP removed
5863 Uint32 noOfRemainingLcpReplicas = 0;// No of replicas in LCP remaining
5864
5865 const bool lcpOngoingFlag = (tabPtr.p->tabLcpStatus== TabRecord::TLS_ACTIVE);
5866 const bool unlogged = (tabPtr.p->tabStorage != TabRecord::ST_NORMAL);
5867
5868 FragmentstorePtr fragPtr;
5869 for(Uint32 fragNo = 0; fragNo < tabPtr.p->totalfragments; fragNo++){
5870 jam();
5871 getFragstore(tabPtr.p, fragNo, fragPtr);
5872
5873 /**
5874 * For each of replica record
5875 */
5876 bool found = false;
5877 ReplicaRecordPtr replicaPtr;
5878 for(replicaPtr.i = fragPtr.p->storedReplicas; replicaPtr.i != RNIL;
5879 replicaPtr.i = replicaPtr.p->nextReplica) {
5880 jam();
5881
5882 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
5883 if(replicaPtr.p->procNode == nodeId){
5884 jam();
5885 found = true;
5886 noOfRemovedReplicas++;
5887 removeNodeFromStored(nodeId, fragPtr, replicaPtr, unlogged);
5888 if(replicaPtr.p->lcpOngoingFlag){
5889 jam();
5890 /**
5891 * This replica is currently LCP:ed
5892 */
5893 ndbrequire(fragPtr.p->noLcpReplicas > 0);
5894 fragPtr.p->noLcpReplicas --;
5895
5896 noOfRemovedLcpReplicas ++;
5897 replicaPtr.p->lcpOngoingFlag = false;
5898 }
5899
5900 if (lcpId != RNIL)
5901 {
5902 jam();
5903 Uint32 lcpNo = prevLcpNo(replicaPtr.p->nextLcp);
5904 if (replicaPtr.p->lcpStatus[lcpNo] == ZVALID &&
5905 replicaPtr.p->lcpId[lcpNo] == SYSFILE->latestLCP_ID)
5906 {
5907 jam();
5908 replicaPtr.p->lcpStatus[lcpNo] = ZINVALID;
5909 replicaPtr.p->lcpId[lcpNo] = 0;
5910 replicaPtr.p->nextLcp = lcpNo;
5911 ndbout_c("REMOVING lcp: %u from table: %u frag: %u node: %u",
5912 SYSFILE->latestLCP_ID,
5913 tabPtr.i, fragNo, nodeId);
5914 }
5915 }
5916 }
5917 }
5918 if (!found)
5919 {
5920 jam();
5921 /**
5922 * Run updateNodeInfo to remove any dead nodes from list of activeNodes
5923 * see bug#15587
5924 */
5925 updateNodeInfo(fragPtr);
5926 }
5927 noOfRemainingLcpReplicas += fragPtr.p->noLcpReplicas;
5928 }
5929
5930 if(noOfRemovedReplicas == 0){
5931 jam();
5932 /**
5933 * The table had no replica on the failed node
5934 * continue with next table
5935 */
5936 tabPtr.i++;
5937 signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
5938 signal->theData[1] = nodeId;
5939 signal->theData[2] = tabPtr.i;
5940 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
5941 return;
5942 }
5943
5944 /**
5945 * We did remove at least one replica
5946 */
5947 bool ok = false;
5948 switch(tabPtr.p->tabLcpStatus){
5949 case TabRecord::TLS_COMPLETED:
5950 ok = true;
5951 jam();
5952 /**
5953 * WE WILL WRITE THE TABLE DESCRIPTION TO DISK AT THIS TIME
5954 * INDEPENDENT OF WHAT THE LOCAL CHECKPOINT NEEDED.
5955 * THIS IS TO ENSURE THAT THE FAILED NODES ARE ALSO UPDATED ON DISK
5956 * IN THE DIH DATA STRUCTURES BEFORE WE COMPLETE HANDLING OF THE
5957 * NODE FAILURE.
5958 */
5959 ndbrequire(noOfRemovedLcpReplicas == 0);
5960
5961 tabPtr.p->tabCopyStatus = TabRecord::CS_REMOVE_NODE;
5962 tabPtr.p->tabUpdateState = TabRecord::US_REMOVE_NODE;
5963 tabPtr.p->tabRemoveNode = nodeId;
5964 signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
5965 signal->theData[1] = tabPtr.i;
5966 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
5967 return;
5968 break;
5969 case TabRecord::TLS_ACTIVE:
5970 ok = true;
5971 jam();
5972 /**
5973 * The table is participating in an LCP currently
5974 */
5975 // Fall through
5976 break;
5977 case TabRecord::TLS_WRITING_TO_FILE:
5978 ok = true;
5979 jam();
5980 /**
5981 * This should never happen since we in the beginning of this function
5982 * checks the tabCopyStatus
5983 */
5984 ndbrequire(lcpOngoingFlag);
5985 ndbrequire(false);
5986 break;
5987 }
5988 ndbrequire(ok);
5989
5990 /**
5991 * The table is participating in an LCP currently
5992 * and we removed some replicas that should have been checkpointed
5993 */
5994 ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
5995 ndbrequire(tabPtr.p->tabLcpStatus == TabRecord::TLS_ACTIVE);
5996
5997 /**
5998 * Save the table
5999 */
6000 tabPtr.p->tabCopyStatus = TabRecord::CS_REMOVE_NODE;
6001 tabPtr.p->tabUpdateState = TabRecord::US_REMOVE_NODE;
6002 tabPtr.p->tabRemoveNode = nodeId;
6003 signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
6004 signal->theData[1] = tabPtr.i;
6005 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
6006
6007 if(noOfRemainingLcpReplicas == 0){
6008 jam();
6009 /**
6010 * The removal on the failed node made the LCP complete
6011 */
6012 tabPtr.p->tabLcpStatus = TabRecord::TLS_WRITING_TO_FILE;
6013 checkLcpAllTablesDoneInLqh();
6014 }
6015 }
6016
6017 void
removeNodeFromTablesComplete(Signal * signal,Uint32 nodeId)6018 Dbdih::removeNodeFromTablesComplete(Signal* signal, Uint32 nodeId){
6019 jam();
6020
6021 /**
6022 * Check if we "accidently" completed a LCP
6023 */
6024 checkLcpCompletedLab(signal);
6025
6026 /**
6027 * Check if we (DIH) are finished with node fail handling
6028 */
6029 checkLocalNodefailComplete(signal, nodeId, NF_REMOVE_NODE_FROM_TABLE);
6030 }
6031
6032 void
checkLocalNodefailComplete(Signal * signal,Uint32 failedNodeId,NodefailHandlingStep step)6033 Dbdih::checkLocalNodefailComplete(Signal* signal, Uint32 failedNodeId,
6034 NodefailHandlingStep step){
6035 jam();
6036
6037 NodeRecordPtr nodePtr;
6038 nodePtr.i = failedNodeId;
6039 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
6040
6041 ndbrequire(nodePtr.p->m_nodefailSteps.get(step));
6042 nodePtr.p->m_nodefailSteps.clear(step);
6043
6044 if(nodePtr.p->m_nodefailSteps.count() > 0){
6045 jam();
6046 return;
6047 }
6048
6049 if (ERROR_INSERTED(7030))
6050 {
6051 g_eventLogger.info("Reenable GCP_PREPARE");
6052 CLEAR_ERROR_INSERT_VALUE;
6053 }
6054
6055 NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
6056 nf->blockNo = DBDIH;
6057 nf->nodeId = cownNodeId;
6058 nf->failedNodeId = failedNodeId;
6059 nf->from = __LINE__;
6060 sendSignal(reference(), GSN_NF_COMPLETEREP, signal,
6061 NFCompleteRep::SignalLength, JBB);
6062 }
6063
6064
6065 void
setLocalNodefailHandling(Signal * signal,Uint32 failedNodeId,NodefailHandlingStep step)6066 Dbdih::setLocalNodefailHandling(Signal* signal, Uint32 failedNodeId,
6067 NodefailHandlingStep step){
6068 jam();
6069
6070 NodeRecordPtr nodePtr;
6071 nodePtr.i = failedNodeId;
6072 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
6073
6074 ndbrequire(!nodePtr.p->m_nodefailSteps.get(step));
6075 nodePtr.p->m_nodefailSteps.set(step);
6076 }
6077
startLcpTakeOverLab(Signal * signal,Uint32 failedNodeId)6078 void Dbdih::startLcpTakeOverLab(Signal* signal, Uint32 failedNodeId)
6079 {
6080 /*--------------------------------------------------------------------*/
6081 // Start LCP master take over process. Consists of the following steps.
6082 // 1) Ensure that all LQH's have reported all fragments they have been
6083 // told to checkpoint. Can be a fairly long step time-wise.
6084 // 2) Query all nodes about their LCP status.
6085 // During the query process we do not want our own state to change.
6086 // This can change due to delayed reception of LCP_REPORT, completed
6087 // save of table on disk or reception of DIH_LCPCOMPLETE from other
6088 // node.
6089 /*--------------------------------------------------------------------*/
6090 }//Dbdih::startLcpTakeOver()
6091
execEMPTY_LCP_CONF(Signal * signal)6092 void Dbdih::execEMPTY_LCP_CONF(Signal* signal)
6093 {
6094 jamEntry();
6095
6096 ndbrequire(c_lcpMasterTakeOverState.state == LMTOS_WAIT_EMPTY_LCP);
6097
6098 const EmptyLcpConf * const conf = (EmptyLcpConf *)&signal->theData[0];
6099 Uint32 nodeId = conf->senderNodeId;
6100
6101 if(!conf->idle){
6102 jam();
6103 if (conf->tableId < c_lcpMasterTakeOverState.minTableId) {
6104 jam();
6105 c_lcpMasterTakeOverState.minTableId = conf->tableId;
6106 c_lcpMasterTakeOverState.minFragId = conf->fragmentId;
6107 } else if (conf->tableId == c_lcpMasterTakeOverState.minTableId &&
6108 conf->fragmentId < c_lcpMasterTakeOverState.minFragId) {
6109 jam();
6110 c_lcpMasterTakeOverState.minFragId = conf->fragmentId;
6111 }//if
6112 if(isMaster()){
6113 jam();
6114 c_lcpState.m_LAST_LCP_FRAG_ORD.setWaitingFor(nodeId);
6115 }
6116 }
6117
6118 receiveLoopMacro(EMPTY_LCP_REQ, nodeId);
6119 /*--------------------------------------------------------------------*/
6120 // Received all EMPTY_LCPCONF. We can continue with next phase of the
6121 // take over LCP master process.
6122 /*--------------------------------------------------------------------*/
6123 c_lcpMasterTakeOverState.set(LMTOS_WAIT_LCP_FRAG_REP, __LINE__);
6124 checkEmptyLcpComplete(signal);
6125 return;
6126 }//Dbdih::execEMPTY_LCPCONF()
6127
6128 void
checkEmptyLcpComplete(Signal * signal)6129 Dbdih::checkEmptyLcpComplete(Signal *signal){
6130
6131 ndbrequire(c_lcpMasterTakeOverState.state == LMTOS_WAIT_LCP_FRAG_REP);
6132
6133 if(c_lcpState.noOfLcpFragRepOutstanding > 0){
6134 jam();
6135 return;
6136 }
6137
6138 if(isMaster()){
6139 jam();
6140
6141 signal->theData[0] = NDB_LE_LCP_TakeoverStarted;
6142 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
6143
6144 signal->theData[0] = 7012;
6145 execDUMP_STATE_ORD(signal);
6146
6147 if (ERROR_INSERTED(7194))
6148 {
6149 ndbout_c("7194 starting ZREMOVE_NODE_FROM_TABLE");
6150 signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
6151 signal->theData[1] = c_lcpMasterTakeOverState.failedNodeId;
6152 signal->theData[2] = 0; // Tab id
6153 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
6154 }
6155
6156 c_lcpMasterTakeOverState.set(LMTOS_INITIAL, __LINE__);
6157 MasterLCPReq * const req = (MasterLCPReq *)&signal->theData[0];
6158 req->masterRef = reference();
6159 req->failedNodeId = c_lcpMasterTakeOverState.failedNodeId;
6160 sendLoopMacro(MASTER_LCPREQ, sendMASTER_LCPREQ);
6161
6162 } else {
6163 sendMASTER_LCPCONF(signal);
6164 }
6165 }
6166
6167 /*--------------------------------------------------*/
6168 /* THE MASTER HAS FAILED AND THE NEW MASTER IS*/
6169 /* QUERYING THIS NODE ABOUT THE STATE OF THE */
6170 /* LOCAL CHECKPOINT PROTOCOL. */
6171 /*--------------------------------------------------*/
execMASTER_LCPREQ(Signal * signal)6172 void Dbdih::execMASTER_LCPREQ(Signal* signal)
6173 {
6174 const MasterLCPReq * const req = (MasterLCPReq *)&signal->theData[0];
6175 jamEntry();
6176 const BlockReference newMasterBlockref = req->masterRef;
6177
6178 if (newMasterBlockref != cmasterdihref)
6179 {
6180 jam();
6181 ndbout_c("resending GSN_MASTER_LCPREQ");
6182 sendSignalWithDelay(reference(), GSN_MASTER_LCPREQ, signal,
6183 50, signal->getLength());
6184 return;
6185 }
6186 Uint32 failedNodeId = req->failedNodeId;
6187
6188 /**
6189 * There can be no take over with the same master
6190 */
6191 ndbrequire(c_lcpState.m_masterLcpDihRef != newMasterBlockref);
6192 c_lcpState.m_masterLcpDihRef = newMasterBlockref;
6193 c_lcpState.m_MASTER_LCPREQ_Received = true;
6194 c_lcpState.m_MASTER_LCPREQ_FailedNodeId = failedNodeId;
6195
6196 if(newMasterBlockref != cmasterdihref){
6197 jam();
6198 ndbrequire(0);
6199 }
6200
6201 sendMASTER_LCPCONF(signal);
6202 }//Dbdih::execMASTER_LCPREQ()
6203
6204 void
sendMASTER_LCPCONF(Signal * signal)6205 Dbdih::sendMASTER_LCPCONF(Signal * signal){
6206
6207 if(!c_EMPTY_LCP_REQ_Counter.done()){
6208 /**
6209 * Have not received all EMPTY_LCP_REP
6210 * dare not answer MASTER_LCP_CONF yet
6211 */
6212 jam();
6213 return;
6214 }
6215
6216 if(!c_lcpState.m_MASTER_LCPREQ_Received){
6217 jam();
6218 /**
6219 * Has not received MASTER_LCPREQ yet
6220 */
6221 return;
6222 }
6223
6224 if(c_lcpState.lcpStatus == LCP_INIT_TABLES){
6225 jam();
6226 /**
6227 * Still aborting old initLcpLab
6228 */
6229 return;
6230 }
6231
6232 if(c_lcpState.lcpStatus == LCP_COPY_GCI){
6233 jam();
6234 /**
6235 * Restart it
6236 */
6237 //Uint32 lcpId = SYSFILE->latestLCP_ID;
6238 SYSFILE->latestLCP_ID--;
6239 c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
6240 #if 0
6241 if(c_copyGCISlave.m_copyReason == CopyGCIReq::LOCAL_CHECKPOINT){
6242 g_eventLogger.info("Dbdih: Also resetting c_copyGCISlave");
6243 c_copyGCISlave.m_copyReason = CopyGCIReq::IDLE;
6244 c_copyGCISlave.m_expectedNextWord = 0;
6245 }
6246 #endif
6247 }
6248
6249 MasterLCPConf::State lcpState;
6250 switch (c_lcpState.lcpStatus) {
6251 case LCP_STATUS_IDLE:
6252 jam();
6253 /*------------------------------------------------*/
6254 /* LOCAL CHECKPOINT IS CURRENTLY NOT ACTIVE */
6255 /* SINCE NO COPY OF RESTART INFORMATION HAVE*/
6256 /* BEEN RECEIVED YET. ALSO THE PREVIOUS */
6257 /* CHECKPOINT HAVE BEEN FULLY COMPLETED. */
6258 /*------------------------------------------------*/
6259 lcpState = MasterLCPConf::LCP_STATUS_IDLE;
6260 break;
6261 case LCP_STATUS_ACTIVE:
6262 jam();
6263 /*--------------------------------------------------*/
6264 /* COPY OF RESTART INFORMATION HAS BEEN */
6265 /* PERFORMED AND ALSO RESPONSE HAVE BEEN SENT.*/
6266 /*--------------------------------------------------*/
6267 lcpState = MasterLCPConf::LCP_STATUS_ACTIVE;
6268 break;
6269 case LCP_TAB_COMPLETED:
6270 jam();
6271 /*--------------------------------------------------------*/
6272 /* ALL LCP_REPORT'S HAVE BEEN COMPLETED FOR */
6273 /* ALL TABLES. SAVE OF AT LEAST ONE TABLE IS */
6274 /* ONGOING YET. */
6275 /*--------------------------------------------------------*/
6276 lcpState = MasterLCPConf::LCP_TAB_COMPLETED;
6277 break;
6278 case LCP_TAB_SAVED:
6279 jam();
6280 /*--------------------------------------------------------*/
6281 /* ALL LCP_REPORT'S HAVE BEEN COMPLETED FOR */
6282 /* ALL TABLES. ALL TABLES HAVE ALSO BEEN SAVED */
6283 /* ALL OTHER NODES ARE NOT YET FINISHED WITH */
6284 /* THE LOCAL CHECKPOINT. */
6285 /*--------------------------------------------------------*/
6286 lcpState = MasterLCPConf::LCP_TAB_SAVED;
6287 break;
6288 case LCP_TCGET:
6289 case LCP_CALCULATE_KEEP_GCI:
6290 case LCP_TC_CLOPSIZE:
6291 case LCP_START_LCP_ROUND:
6292 /**
6293 * These should only exists on the master
6294 * but since this is master take over
6295 * it not allowed
6296 */
6297 ndbrequire(false);
6298 lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning
6299 break;
6300 case LCP_COPY_GCI:
6301 case LCP_INIT_TABLES:
6302 /**
6303 * These two states are handled by if statements above
6304 */
6305 ndbrequire(false);
6306 lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning
6307 break;
6308 default:
6309 ndbrequire(false);
6310 lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning
6311 }//switch
6312
6313 Uint32 failedNodeId = c_lcpState.m_MASTER_LCPREQ_FailedNodeId;
6314 MasterLCPConf * const conf = (MasterLCPConf *)&signal->theData[0];
6315 conf->senderNodeId = cownNodeId;
6316 conf->lcpState = lcpState;
6317 conf->failedNodeId = failedNodeId;
6318 sendSignal(c_lcpState.m_masterLcpDihRef, GSN_MASTER_LCPCONF,
6319 signal, MasterLCPConf::SignalLength, JBB);
6320
6321 // Answer to MASTER_LCPREQ sent, reset flag so
6322 // that it's not sent again before another request comes in
6323 c_lcpState.m_MASTER_LCPREQ_Received = false;
6324
6325 if(c_lcpState.lcpStatus == LCP_TAB_SAVED){
6326 #ifdef VM_TRACE
6327 g_eventLogger.info("Sending extra GSN_LCP_COMPLETE_REP to new master");
6328 #endif
6329 sendLCP_COMPLETE_REP(signal);
6330 }
6331
6332 if(!isMaster()){
6333 c_lcpMasterTakeOverState.set(LMTOS_IDLE, __LINE__);
6334 checkLocalNodefailComplete(signal, failedNodeId, NF_LCP_TAKE_OVER);
6335 }
6336
6337 return;
6338 }
6339
6340 NdbOut&
operator <<(NdbOut & out,const Dbdih::LcpMasterTakeOverState state)6341 operator<<(NdbOut& out, const Dbdih::LcpMasterTakeOverState state){
6342 switch(state){
6343 case Dbdih::LMTOS_IDLE:
6344 out << "LMTOS_IDLE";
6345 break;
6346 case Dbdih::LMTOS_WAIT_EMPTY_LCP:
6347 out << "LMTOS_WAIT_EMPTY_LCP";
6348 break;
6349 case Dbdih::LMTOS_WAIT_LCP_FRAG_REP:
6350 out << "LMTOS_WAIT_EMPTY_LCP";
6351 break;
6352 case Dbdih::LMTOS_INITIAL:
6353 out << "LMTOS_INITIAL";
6354 break;
6355 case Dbdih::LMTOS_ALL_IDLE:
6356 out << "LMTOS_ALL_IDLE";
6357 break;
6358 case Dbdih::LMTOS_ALL_ACTIVE:
6359 out << "LMTOS_ALL_ACTIVE";
6360 break;
6361 case Dbdih::LMTOS_LCP_CONCLUDING:
6362 out << "LMTOS_LCP_CONCLUDING";
6363 break;
6364 case Dbdih::LMTOS_COPY_ONGOING:
6365 out << "LMTOS_COPY_ONGOING";
6366 break;
6367 }
6368 return out;
6369 }
6370
6371 struct MASTERLCP_StateTransitions {
6372 Dbdih::LcpMasterTakeOverState CurrentState;
6373 MasterLCPConf::State ParticipantState;
6374 Dbdih::LcpMasterTakeOverState NewState;
6375 };
6376
6377 static const
6378 MASTERLCP_StateTransitions g_masterLCPTakeoverStateTransitions[] = {
6379 /**
6380 * Current = LMTOS_INITIAL
6381 */
6382 { Dbdih::LMTOS_INITIAL,
6383 MasterLCPConf::LCP_STATUS_IDLE,
6384 Dbdih::LMTOS_ALL_IDLE },
6385
6386 { Dbdih::LMTOS_INITIAL,
6387 MasterLCPConf::LCP_STATUS_ACTIVE,
6388 Dbdih::LMTOS_ALL_ACTIVE },
6389
6390 { Dbdih::LMTOS_INITIAL,
6391 MasterLCPConf::LCP_TAB_COMPLETED,
6392 Dbdih::LMTOS_LCP_CONCLUDING },
6393
6394 { Dbdih::LMTOS_INITIAL,
6395 MasterLCPConf::LCP_TAB_SAVED,
6396 Dbdih::LMTOS_LCP_CONCLUDING },
6397
6398 /**
6399 * Current = LMTOS_ALL_IDLE
6400 */
6401 { Dbdih::LMTOS_ALL_IDLE,
6402 MasterLCPConf::LCP_STATUS_IDLE,
6403 Dbdih::LMTOS_ALL_IDLE },
6404
6405 { Dbdih::LMTOS_ALL_IDLE,
6406 MasterLCPConf::LCP_STATUS_ACTIVE,
6407 Dbdih::LMTOS_COPY_ONGOING },
6408
6409 { Dbdih::LMTOS_ALL_IDLE,
6410 MasterLCPConf::LCP_TAB_COMPLETED,
6411 Dbdih::LMTOS_LCP_CONCLUDING },
6412
6413 { Dbdih::LMTOS_ALL_IDLE,
6414 MasterLCPConf::LCP_TAB_SAVED,
6415 Dbdih::LMTOS_LCP_CONCLUDING },
6416
6417 /**
6418 * Current = LMTOS_COPY_ONGOING
6419 */
6420 { Dbdih::LMTOS_COPY_ONGOING,
6421 MasterLCPConf::LCP_STATUS_IDLE,
6422 Dbdih::LMTOS_COPY_ONGOING },
6423
6424 { Dbdih::LMTOS_COPY_ONGOING,
6425 MasterLCPConf::LCP_STATUS_ACTIVE,
6426 Dbdih::LMTOS_COPY_ONGOING },
6427
6428 /**
6429 * Current = LMTOS_ALL_ACTIVE
6430 */
6431 { Dbdih::LMTOS_ALL_ACTIVE,
6432 MasterLCPConf::LCP_STATUS_IDLE,
6433 Dbdih::LMTOS_COPY_ONGOING },
6434
6435 { Dbdih::LMTOS_ALL_ACTIVE,
6436 MasterLCPConf::LCP_STATUS_ACTIVE,
6437 Dbdih::LMTOS_ALL_ACTIVE },
6438
6439 { Dbdih::LMTOS_ALL_ACTIVE,
6440 MasterLCPConf::LCP_TAB_COMPLETED,
6441 Dbdih::LMTOS_LCP_CONCLUDING },
6442
6443 { Dbdih::LMTOS_ALL_ACTIVE,
6444 MasterLCPConf::LCP_TAB_SAVED,
6445 Dbdih::LMTOS_LCP_CONCLUDING },
6446
6447 /**
6448 * Current = LMTOS_LCP_CONCLUDING
6449 */
6450 { Dbdih::LMTOS_LCP_CONCLUDING,
6451 MasterLCPConf::LCP_STATUS_IDLE,
6452 Dbdih::LMTOS_LCP_CONCLUDING },
6453
6454 { Dbdih::LMTOS_LCP_CONCLUDING,
6455 MasterLCPConf::LCP_STATUS_ACTIVE,
6456 Dbdih::LMTOS_LCP_CONCLUDING },
6457
6458 { Dbdih::LMTOS_LCP_CONCLUDING,
6459 MasterLCPConf::LCP_TAB_COMPLETED,
6460 Dbdih::LMTOS_LCP_CONCLUDING },
6461
6462 { Dbdih::LMTOS_LCP_CONCLUDING,
6463 MasterLCPConf::LCP_TAB_SAVED,
6464 Dbdih::LMTOS_LCP_CONCLUDING }
6465 };
6466
6467 const Uint32 g_masterLCPTakeoverStateTransitionsRows =
6468 sizeof(g_masterLCPTakeoverStateTransitions) / sizeof(struct MASTERLCP_StateTransitions);
6469
execMASTER_LCPCONF(Signal * signal)6470 void Dbdih::execMASTER_LCPCONF(Signal* signal)
6471 {
6472 const MasterLCPConf * const conf = (MasterLCPConf *)&signal->theData[0];
6473 jamEntry();
6474
6475 if (ERROR_INSERTED(7194))
6476 {
6477 ndbout_c("delaying MASTER_LCPCONF due to error 7194");
6478 sendSignalWithDelay(reference(), GSN_MASTER_LCPCONF, signal,
6479 300, signal->getLength());
6480 return;
6481 }
6482
6483 Uint32 senderNodeId = conf->senderNodeId;
6484 MasterLCPConf::State lcpState = (MasterLCPConf::State)conf->lcpState;
6485 const Uint32 failedNodeId = conf->failedNodeId;
6486 NodeRecordPtr nodePtr;
6487 nodePtr.i = senderNodeId;
6488 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
6489 nodePtr.p->lcpStateAtTakeOver = lcpState;
6490
6491 CRASH_INSERTION(7180);
6492
6493 #ifdef VM_TRACE
6494 g_eventLogger.info("MASTER_LCPCONF");
6495 printMASTER_LCP_CONF(stdout, &signal->theData[0], 0, 0);
6496 #endif
6497
6498 bool found = false;
6499 for(Uint32 i = 0; i<g_masterLCPTakeoverStateTransitionsRows; i++){
6500 const struct MASTERLCP_StateTransitions * valid =
6501 &g_masterLCPTakeoverStateTransitions[i];
6502
6503 if(valid->CurrentState == c_lcpMasterTakeOverState.state &&
6504 valid->ParticipantState == lcpState){
6505 jam();
6506 found = true;
6507 c_lcpMasterTakeOverState.set(valid->NewState, __LINE__);
6508 break;
6509 }
6510 }
6511 ndbrequire(found);
6512
6513 bool ok = false;
6514 switch(lcpState){
6515 case MasterLCPConf::LCP_STATUS_IDLE:
6516 ok = true;
6517 break;
6518 case MasterLCPConf::LCP_STATUS_ACTIVE:
6519 case MasterLCPConf::LCP_TAB_COMPLETED:
6520 case MasterLCPConf::LCP_TAB_SAVED:
6521 ok = true;
6522 c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.setWaitingFor(nodePtr.i);
6523 break;
6524 }
6525 ndbrequire(ok);
6526
6527 receiveLoopMacro(MASTER_LCPREQ, senderNodeId);
6528 /*-------------------------------------------------------------------------*/
6529 // We have now received all responses and are ready to take over the LCP
6530 // protocol as master.
6531 /*-------------------------------------------------------------------------*/
6532 MASTER_LCPhandling(signal, failedNodeId);
6533 }//Dbdih::execMASTER_LCPCONF()
6534
execMASTER_LCPREF(Signal * signal)6535 void Dbdih::execMASTER_LCPREF(Signal* signal)
6536 {
6537 const MasterLCPRef * const ref = (MasterLCPRef *)&signal->theData[0];
6538 jamEntry();
6539 receiveLoopMacro(MASTER_LCPREQ, ref->senderNodeId);
6540 /*-------------------------------------------------------------------------*/
6541 // We have now received all responses and are ready to take over the LCP
6542 // protocol as master.
6543 /*-------------------------------------------------------------------------*/
6544 MASTER_LCPhandling(signal, ref->failedNodeId);
6545 }//Dbdih::execMASTER_LCPREF()
6546
MASTER_LCPhandling(Signal * signal,Uint32 failedNodeId)6547 void Dbdih::MASTER_LCPhandling(Signal* signal, Uint32 failedNodeId)
6548 {
6549 /*-------------------------------------------------------------------------
6550 *
6551 * WE ARE NOW READY TO CONCLUDE THE TAKE OVER AS MASTER.
6552 * WE HAVE ENOUGH INFO TO START UP ACTIVITIES IN THE PROPER PLACE.
6553 * ALSO SET THE PROPER STATE VARIABLES.
6554 *------------------------------------------------------------------------*/
6555 c_lcpState.currentFragment.tableId = c_lcpMasterTakeOverState.minTableId;
6556 c_lcpState.currentFragment.fragmentId = c_lcpMasterTakeOverState.minFragId;
6557 c_lcpState.m_LAST_LCP_FRAG_ORD = c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH;
6558
6559 NodeRecordPtr failedNodePtr;
6560 failedNodePtr.i = failedNodeId;
6561 ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
6562
6563 switch (c_lcpMasterTakeOverState.state) {
6564 case LMTOS_ALL_IDLE:
6565 jam();
6566 /* --------------------------------------------------------------------- */
6567 // All nodes were idle in the LCP protocol. Start checking for start of LCP
6568 // protocol.
6569 /* --------------------------------------------------------------------- */
6570 #ifdef VM_TRACE
6571 g_eventLogger.info("MASTER_LCPhandling:: LMTOS_ALL_IDLE -> checkLcpStart");
6572 #endif
6573 checkLcpStart(signal, __LINE__);
6574 break;
6575 case LMTOS_COPY_ONGOING:
6576 jam();
6577 /* --------------------------------------------------------------------- */
6578 // We were in the starting process of the LCP protocol. We will restart the
6579 // protocol by calculating the keep gci and storing the new lcp id.
6580 /* --------------------------------------------------------------------- */
6581 #ifdef VM_TRACE
6582 g_eventLogger.info("MASTER_LCPhandling:: LMTOS_COPY_ONGOING -> storeNewLcpId");
6583 #endif
6584 if (c_lcpState.lcpStatus == LCP_STATUS_ACTIVE) {
6585 jam();
6586 /*---------------------------------------------------------------------*/
6587 /* WE NEED TO DECREASE THE LATEST LCP ID SINCE WE HAVE ALREADY */
6588 /* STARTED THIS */
6589 /* LOCAL CHECKPOINT. */
6590 /*---------------------------------------------------------------------*/
6591 Uint32 lcpId = SYSFILE->latestLCP_ID;
6592 #ifdef VM_TRACE
6593 g_eventLogger.info("Decreasing latestLCP_ID from %d to %d", lcpId, lcpId - 1);
6594 #endif
6595 SYSFILE->latestLCP_ID--;
6596 }//if
6597 storeNewLcpIdLab(signal);
6598 break;
6599 case LMTOS_ALL_ACTIVE:
6600 {
6601 jam();
6602 /* -------------------------------------------------------------------
6603 * Everybody was in the active phase. We will restart sending
6604 * LCP_FRAGORD to the nodes from the new master.
6605 * We also need to set dihLcpStatus to ZACTIVE
6606 * in the master node since the master will wait for all nodes to
6607 * complete before finalising the LCP process.
6608 * ------------------------------------------------------------------ */
6609 #ifdef VM_TRACE
6610 g_eventLogger.info("MASTER_LCPhandling:: LMTOS_ALL_ACTIVE -> "
6611 "startLcpRoundLoopLab(table=%u, fragment=%u)",
6612 c_lcpMasterTakeOverState.minTableId,
6613 c_lcpMasterTakeOverState.minFragId);
6614 #endif
6615
6616 c_lcpState.keepGci = SYSFILE->keepGCI;
6617 startLcpRoundLoopLab(signal, 0, 0);
6618 break;
6619 }
6620 case LMTOS_LCP_CONCLUDING:
6621 {
6622 jam();
6623 /* ------------------------------------------------------------------- */
6624 // The LCP process is in the finalisation phase. We simply wait for it to
6625 // complete with signals arriving in. We need to check also if we should
6626 // change state due to table write completion during state
6627 // collection phase.
6628 /* ------------------------------------------------------------------- */
6629 ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
6630 startLcpRoundLoopLab(signal, 0, 0);
6631 break;
6632 }
6633 default:
6634 ndbrequire(false);
6635 break;
6636 }//switch
6637 signal->theData[0] = NDB_LE_LCP_TakeoverCompleted;
6638 signal->theData[1] = c_lcpMasterTakeOverState.state;
6639 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
6640
6641 signal->theData[0] = 7012;
6642 execDUMP_STATE_ORD(signal);
6643
6644 c_lcpMasterTakeOverState.set(LMTOS_IDLE, __LINE__);
6645
6646 checkLocalNodefailComplete(signal, failedNodePtr.i, NF_LCP_TAKE_OVER);
6647 }
6648
6649 /* ------------------------------------------------------------------------- */
6650 /* A BLOCK OR A NODE HAS COMPLETED THE HANDLING OF THE NODE FAILURE. */
6651 /* ------------------------------------------------------------------------- */
execNF_COMPLETEREP(Signal * signal)6652 void Dbdih::execNF_COMPLETEREP(Signal* signal)
6653 {
6654 NodeRecordPtr failedNodePtr;
6655 NFCompleteRep * const nfCompleteRep = (NFCompleteRep *)&signal->theData[0];
6656 jamEntry();
6657 const Uint32 blockNo = nfCompleteRep->blockNo;
6658 Uint32 nodeId = nfCompleteRep->nodeId;
6659 failedNodePtr.i = nfCompleteRep->failedNodeId;
6660
6661 ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
6662 switch (blockNo) {
6663 case DBTC:
6664 jam();
6665 ndbrequire(failedNodePtr.p->dbtcFailCompleted == ZFALSE);
6666 /* -------------------------------------------------------------------- */
6667 // Report the event that DBTC completed node failure handling.
6668 /* -------------------------------------------------------------------- */
6669 signal->theData[0] = NDB_LE_NodeFailCompleted;
6670 signal->theData[1] = DBTC;
6671 signal->theData[2] = failedNodePtr.i;
6672 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
6673
6674 failedNodePtr.p->dbtcFailCompleted = ZTRUE;
6675 break;
6676 case DBDICT:
6677 jam();
6678 ndbrequire(failedNodePtr.p->dbdictFailCompleted == ZFALSE);
6679 /* --------------------------------------------------------------------- */
6680 // Report the event that DBDICT completed node failure handling.
6681 /* --------------------------------------------------------------------- */
6682 signal->theData[0] = NDB_LE_NodeFailCompleted;
6683 signal->theData[1] = DBDICT;
6684 signal->theData[2] = failedNodePtr.i;
6685 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
6686
6687 failedNodePtr.p->dbdictFailCompleted = ZTRUE;
6688 break;
6689 case DBDIH:
6690 jam();
6691 ndbrequire(failedNodePtr.p->dbdihFailCompleted == ZFALSE);
6692 /* --------------------------------------------------------------------- */
6693 // Report the event that DBDIH completed node failure handling.
6694 /* --------------------------------------------------------------------- */
6695 signal->theData[0] = NDB_LE_NodeFailCompleted;
6696 signal->theData[1] = DBDIH;
6697 signal->theData[2] = failedNodePtr.i;
6698 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
6699
6700 failedNodePtr.p->dbdihFailCompleted = ZTRUE;
6701 break;
6702 case DBLQH:
6703 jam();
6704 ndbrequire(failedNodePtr.p->dblqhFailCompleted == ZFALSE);
6705 /* --------------------------------------------------------------------- */
6706 // Report the event that DBDIH completed node failure handling.
6707 /* --------------------------------------------------------------------- */
6708 signal->theData[0] = NDB_LE_NodeFailCompleted;
6709 signal->theData[1] = DBLQH;
6710 signal->theData[2] = failedNodePtr.i;
6711 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
6712
6713 failedNodePtr.p->dblqhFailCompleted = ZTRUE;
6714 break;
6715 case 0: /* Node has finished */
6716 jam();
6717 ndbrequire(nodeId < MAX_NDB_NODES);
6718
6719 if (failedNodePtr.p->recNODE_FAILREP == ZFALSE) {
6720 jam();
6721 /* ------------------------------------------------------------------- */
6722 // We received a report about completion of node failure before we
6723 // received the message about the NODE failure ourselves.
6724 // We will send the signal to ourselves with a small delay
6725 // (10 milliseconds).
6726 /* ------------------------------------------------------------------- */
6727 //nf->from = __LINE__;
6728 sendSignalWithDelay(reference(), GSN_NF_COMPLETEREP, signal, 10,
6729 signal->length());
6730 return;
6731 }//if
6732
6733 if (!failedNodePtr.p->m_NF_COMPLETE_REP.isWaitingFor(nodeId)){
6734 jam();
6735 return;
6736 }
6737
6738 failedNodePtr.p->m_NF_COMPLETE_REP.clearWaitingFor(nodeId);;
6739
6740 /* -------------------------------------------------------------------- */
6741 // Report the event that nodeId has completed node failure handling.
6742 /* -------------------------------------------------------------------- */
6743 signal->theData[0] = NDB_LE_NodeFailCompleted;
6744 signal->theData[1] = 0;
6745 signal->theData[2] = failedNodePtr.i;
6746 signal->theData[3] = nodeId;
6747 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
6748
6749 nodeFailCompletedCheckLab(signal, failedNodePtr);
6750 return;
6751 break;
6752 default:
6753 ndbrequire(false);
6754 return;
6755 break;
6756 }//switch
6757 if (failedNodePtr.p->dbtcFailCompleted == ZFALSE) {
6758 jam();
6759 return;
6760 }//if
6761 if (failedNodePtr.p->dbdictFailCompleted == ZFALSE) {
6762 jam();
6763 return;
6764 }//if
6765 if (failedNodePtr.p->dbdihFailCompleted == ZFALSE) {
6766 jam();
6767 return;
6768 }//if
6769 if (failedNodePtr.p->dblqhFailCompleted == ZFALSE) {
6770 jam();
6771 return;
6772 }//if
6773 /* ----------------------------------------------------------------------- */
6774 /* ALL BLOCKS IN THIS NODE HAVE COMPLETED THEIR PART OF HANDLING THE */
6775 /* NODE FAILURE. WE CAN NOW REPORT THIS COMPLETION TO ALL OTHER NODES. */
6776 /* ----------------------------------------------------------------------- */
6777 NodeRecordPtr nodePtr;
6778 for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
6779 jam();
6780 ptrAss(nodePtr, nodeRecord);
6781 if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
6782 jam();
6783 BlockReference ref = calcDihBlockRef(nodePtr.i);
6784 NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
6785 nf->blockNo = 0;
6786 nf->nodeId = cownNodeId;
6787 nf->failedNodeId = failedNodePtr.i;
6788 nf->from = __LINE__;
6789 sendSignal(ref, GSN_NF_COMPLETEREP, signal,
6790 NFCompleteRep::SignalLength, JBB);
6791 }//if
6792 }//for
6793 return;
6794 }//Dbdih::execNF_COMPLETEREP()
6795
nodeFailCompletedCheckLab(Signal * signal,NodeRecordPtr failedNodePtr)6796 void Dbdih::nodeFailCompletedCheckLab(Signal* signal,
6797 NodeRecordPtr failedNodePtr)
6798 {
6799 jam();
6800 if (!failedNodePtr.p->m_NF_COMPLETE_REP.done()){
6801 jam();
6802 return;
6803 }//if
6804 /* ---------------------------------------------------------------------- */
6805 /* ALL BLOCKS IN ALL NODES HAVE NOW REPORTED COMPLETION OF THE NODE */
6806 /* FAILURE HANDLING. WE ARE NOW READY TO ACCEPT THAT THIS NODE STARTS */
6807 /* AGAIN. */
6808 /* ---------------------------------------------------------------------- */
6809 jam();
6810 failedNodePtr.p->nodeStatus = NodeRecord::DEAD;
6811 failedNodePtr.p->recNODE_FAILREP = ZFALSE;
6812
6813 /* ---------------------------------------------------------------------- */
6814 // Report the event that all nodes completed node failure handling.
6815 /* ---------------------------------------------------------------------- */
6816 signal->theData[0] = NDB_LE_NodeFailCompleted;
6817 signal->theData[1] = 0;
6818 signal->theData[2] = failedNodePtr.i;
6819 signal->theData[3] = 0;
6820 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
6821
6822 /* ---------------------------------------------------------------------- */
6823 // Report to QMGR that we have concluded recovery handling of this node.
6824 /* ---------------------------------------------------------------------- */
6825 signal->theData[0] = failedNodePtr.i;
6826 sendSignal(QMGR_REF, GSN_NDB_FAILCONF, signal, 1, JBB);
6827
6828 if (isMaster()) {
6829 jam();
6830 /* --------------------------------------------------------------------- */
6831 /* IF WE ARE MASTER WE MUST CHECK IF COPY FRAGMENT WAS INTERRUPTED */
6832 /* BY THE FAILED NODES. */
6833 /* --------------------------------------------------------------------- */
6834 TakeOverRecordPtr takeOverPtr;
6835 takeOverPtr.i = 0;
6836 ptrAss(takeOverPtr, takeOverRecord);
6837 if ((takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_FRAG) &&
6838 (failedNodePtr.i == takeOverPtr.p->toCopyNode)) {
6839 jam();
6840 #ifdef VM_TRACE
6841 ndbrequire("Tell jonas" == 0);
6842 #endif
6843 /*------------------------------------------------------------------*/
6844 /* WE ARE CURRENTLY IN THE PROCESS OF COPYING A FRAGMENT. WE */
6845 /* WILL CHECK IF THE COPY NODE HAVE FAILED. */
6846 /*------------------------------------------------------------------*/
6847 takeOverPtr.p->toMasterStatus = TakeOverRecord::SELECTING_NEXT;
6848 startNextCopyFragment(signal, takeOverPtr.i);
6849 return;
6850 }//if
6851 checkStartTakeOver(signal);
6852 }//if
6853 return;
6854 }//Dbdih::nodeFailCompletedCheckLab()
6855
6856 /*****************************************************************************/
6857 /* ********** SEIZING / RELEASING MODULE *************/
6858 /*****************************************************************************/
6859 /*
6860 3.4 L O C A L N O D E S E I Z E
6861 ************************************
6862 */
6863 /*
6864 3.4.1 L O C A L N O D E S E I Z E R E Q U E S T
6865 ******************************************************
6866 */
execDISEIZEREQ(Signal * signal)6867 void Dbdih::execDISEIZEREQ(Signal* signal)
6868 {
6869 ConnectRecordPtr connectPtr;
6870 jamEntry();
6871 Uint32 userPtr = signal->theData[0];
6872 BlockReference userRef = signal->theData[1];
6873 ndbrequire(cfirstconnect != RNIL);
6874 connectPtr.i = cfirstconnect;
6875 ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
6876 cfirstconnect = connectPtr.p->nfConnect;
6877 connectPtr.p->nfConnect = RNIL;
6878 connectPtr.p->userpointer = userPtr;
6879 connectPtr.p->userblockref = userRef;
6880 connectPtr.p->connectState = ConnectRecord::INUSE;
6881 signal->theData[0] = connectPtr.p->userpointer;
6882 signal->theData[1] = connectPtr.i;
6883 sendSignal(userRef, GSN_DISEIZECONF, signal, 2, JBB);
6884 }//Dbdih::execDISEIZEREQ()
6885
6886 /*
6887 3.5 L O C A L N O D E R E L E A S E
6888 ****************************************
6889 */
6890 /*
6891 3.5.1 L O C A L N O D E R E L E A S E R E Q U E S T
6892 *******************************************************=
6893 */
execDIRELEASEREQ(Signal * signal)6894 void Dbdih::execDIRELEASEREQ(Signal* signal)
6895 {
6896 ConnectRecordPtr connectPtr;
6897 jamEntry();
6898 connectPtr.i = signal->theData[0];
6899 Uint32 userRef = signal->theData[2];
6900 ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
6901 ndbrequire(connectPtr.p->connectState != ConnectRecord::FREE);
6902 ndbrequire(connectPtr.p->userblockref == userRef);
6903 signal->theData[0] = connectPtr.p->userpointer;
6904 sendSignal(connectPtr.p->userblockref, GSN_DIRELEASECONF, signal, 1, JBB);
6905 release_connect(connectPtr);
6906 }//Dbdih::execDIRELEASEREQ()
6907
6908 /*
6909 3.7 A D D T A B L E
6910 **********************=
6911 */
6912 /*****************************************************************************/
6913 /* ********** TABLE ADDING MODULE *************/
6914 /*****************************************************************************/
6915 /*
6916 3.7.1 A D D T A B L E M A I N L Y
6917 ***************************************
6918 */
6919
inc_node_or_group(Uint32 & node,Uint32 max_node)6920 static inline void inc_node_or_group(Uint32 &node, Uint32 max_node)
6921 {
6922 Uint32 next = node + 1;
6923 node = (next == max_node ? 0 : next);
6924 }
6925
6926 /*
6927 Spread fragments in backwards compatible mode
6928 */
set_default_node_groups(Signal * signal,Uint32 noFrags)6929 static void set_default_node_groups(Signal *signal, Uint32 noFrags)
6930 {
6931 Uint16 *node_group_array = (Uint16*)&signal->theData[25];
6932 Uint32 i;
6933 node_group_array[0] = 0;
6934 for (i = 1; i < noFrags; i++)
6935 node_group_array[i] = UNDEF_NODEGROUP;
6936 }
execCREATE_FRAGMENTATION_REQ(Signal * signal)6937 void Dbdih::execCREATE_FRAGMENTATION_REQ(Signal * signal)
6938 {
6939 Uint16 node_group_id[MAX_NDB_PARTITIONS];
6940 jamEntry();
6941 CreateFragmentationReq * const req =
6942 (CreateFragmentationReq*)signal->getDataPtr();
6943
6944 const Uint32 senderRef = req->senderRef;
6945 const Uint32 senderData = req->senderData;
6946 Uint32 noOfFragments = req->noOfFragments;
6947 const Uint32 fragType = req->fragmentationType;
6948 const Uint32 primaryTableId = req->primaryTableId;
6949
6950 Uint32 err = 0;
6951
6952 do {
6953 NodeGroupRecordPtr NGPtr;
6954 TabRecordPtr primTabPtr;
6955 Uint32 count = 2;
6956 Uint16 noOfReplicas = cnoReplicas;
6957 Uint16 *fragments = (Uint16*)(signal->theData+25);
6958 if (primaryTableId == RNIL) {
6959 jam();
6960 switch ((DictTabInfo::FragmentType)fragType)
6961 {
6962 /*
6963 Backward compatability and for all places in code not changed.
6964 */
6965 case DictTabInfo::AllNodesSmallTable:
6966 jam();
6967 noOfFragments = csystemnodes;
6968 set_default_node_groups(signal, noOfFragments);
6969 break;
6970 case DictTabInfo::AllNodesMediumTable:
6971 jam();
6972 noOfFragments = 2 * csystemnodes;
6973 set_default_node_groups(signal, noOfFragments);
6974 break;
6975 case DictTabInfo::AllNodesLargeTable:
6976 jam();
6977 noOfFragments = 4 * csystemnodes;
6978 set_default_node_groups(signal, noOfFragments);
6979 break;
6980 case DictTabInfo::SingleFragment:
6981 jam();
6982 noOfFragments = 1;
6983 set_default_node_groups(signal, noOfFragments);
6984 break;
6985 case DictTabInfo::DistrKeyHash:
6986 jam();
6987 case DictTabInfo::DistrKeyLin:
6988 jam();
6989 if (noOfFragments == 0)
6990 {
6991 jam();
6992 noOfFragments = csystemnodes;
6993 set_default_node_groups(signal, noOfFragments);
6994 }
6995 break;
6996 default:
6997 jam();
6998 if (noOfFragments == 0)
6999 {
7000 jam();
7001 err = CreateFragmentationRef::InvalidFragmentationType;
7002 }
7003 break;
7004 }
7005 if (err)
7006 break;
7007 /*
7008 When we come here the the exact partition is specified
7009 and there is an array of node groups sent along as well.
7010 */
7011 memcpy(&node_group_id[0], &signal->theData[25], 2 * noOfFragments);
7012 Uint16 next_replica_node[MAX_NDB_NODES];
7013 memset(next_replica_node,0,sizeof(next_replica_node));
7014 Uint32 default_node_group= c_nextNodeGroup;
7015 for(Uint32 fragNo = 0; fragNo < noOfFragments; fragNo++)
7016 {
7017 jam();
7018 NGPtr.i = node_group_id[fragNo];
7019 if (NGPtr.i == UNDEF_NODEGROUP)
7020 {
7021 jam();
7022 NGPtr.i = default_node_group;
7023 }
7024 if (NGPtr.i > cnoOfNodeGroups)
7025 {
7026 jam();
7027 err = CreateFragmentationRef::InvalidNodeGroup;
7028 break;
7029 }
7030 ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
7031 const Uint32 max = NGPtr.p->nodeCount;
7032
7033 fragments[count++] = c_nextLogPart++; // Store logpart first
7034 Uint32 tmp= next_replica_node[NGPtr.i];
7035 for(Uint32 replicaNo = 0; replicaNo < noOfReplicas; replicaNo++)
7036 {
7037 jam();
7038 const Uint16 nodeId = NGPtr.p->nodesInGroup[tmp];
7039 fragments[count++]= nodeId;
7040 inc_node_or_group(tmp, max);
7041 }
7042 inc_node_or_group(tmp, max);
7043 next_replica_node[NGPtr.i]= tmp;
7044
7045 /**
7046 * Next node group for next fragment
7047 */
7048 inc_node_or_group(default_node_group, cnoOfNodeGroups);
7049 }
7050 if (err)
7051 {
7052 jam();
7053 break;
7054 }
7055 else
7056 {
7057 jam();
7058 c_nextNodeGroup = default_node_group;
7059 }
7060 } else {
7061 if (primaryTableId >= ctabFileSize) {
7062 jam();
7063 err = CreateFragmentationRef::InvalidPrimaryTable;
7064 break;
7065 }
7066 primTabPtr.i = primaryTableId;
7067 ptrAss(primTabPtr, tabRecord);
7068 if (primTabPtr.p->tabStatus != TabRecord::TS_ACTIVE) {
7069 jam();
7070 err = CreateFragmentationRef::InvalidPrimaryTable;
7071 break;
7072 }
7073 noOfFragments= primTabPtr.p->totalfragments;
7074 for (Uint32 fragNo = 0;
7075 fragNo < noOfFragments; fragNo++) {
7076 jam();
7077 FragmentstorePtr fragPtr;
7078 ReplicaRecordPtr replicaPtr;
7079 getFragstore(primTabPtr.p, fragNo, fragPtr);
7080 fragments[count++] = fragPtr.p->m_log_part_id;
7081 fragments[count++] = fragPtr.p->preferredPrimary;
7082 for (replicaPtr.i = fragPtr.p->storedReplicas;
7083 replicaPtr.i != RNIL;
7084 replicaPtr.i = replicaPtr.p->nextReplica) {
7085 jam();
7086 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
7087 if (replicaPtr.p->procNode != fragPtr.p->preferredPrimary) {
7088 jam();
7089 fragments[count++]= replicaPtr.p->procNode;
7090 }
7091 }
7092 for (replicaPtr.i = fragPtr.p->oldStoredReplicas;
7093 replicaPtr.i != RNIL;
7094 replicaPtr.i = replicaPtr.p->nextReplica) {
7095 jam();
7096 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
7097 if (replicaPtr.p->procNode != fragPtr.p->preferredPrimary) {
7098 jam();
7099 fragments[count++]= replicaPtr.p->procNode;
7100 }
7101 }
7102 }
7103 }
7104 if(count != (2U + (1 + noOfReplicas) * noOfFragments)){
7105 char buf[255];
7106 BaseString::snprintf(buf, sizeof(buf),
7107 "Illegal configuration change: NoOfReplicas."
7108 " Can't be applied online ");
7109 progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
7110 }
7111
7112 CreateFragmentationConf * const conf =
7113 (CreateFragmentationConf*)signal->getDataPtrSend();
7114 conf->senderRef = reference();
7115 conf->senderData = senderData;
7116 conf->noOfReplicas = (Uint32)noOfReplicas;
7117 conf->noOfFragments = (Uint32)noOfFragments;
7118
7119 fragments[0]= noOfReplicas;
7120 fragments[1]= noOfFragments;
7121
7122 if(senderRef != 0)
7123 {
7124 jam();
7125 LinearSectionPtr ptr[3];
7126 ptr[0].p = (Uint32*)&fragments[0];
7127 ptr[0].sz = (count + 1) / 2;
7128 sendSignal(senderRef,
7129 GSN_CREATE_FRAGMENTATION_CONF,
7130 signal,
7131 CreateFragmentationConf::SignalLength,
7132 JBB,
7133 ptr,
7134 1);
7135 }
7136 // Always ACK/NACK (here ACK)
7137 signal->theData[0] = 0;
7138 return;
7139 } while(false);
7140 // Always ACK/NACK (here NACK)
7141 signal->theData[0] = err;
7142 }
7143
execDIADDTABREQ(Signal * signal)7144 void Dbdih::execDIADDTABREQ(Signal* signal)
7145 {
7146 Uint32 fragType;
7147 jamEntry();
7148
7149 DiAddTabReq * const req = (DiAddTabReq*)signal->getDataPtr();
7150
7151 // Seize connect record
7152 ndbrequire(cfirstconnect != RNIL);
7153 ConnectRecordPtr connectPtr;
7154 connectPtr.i = cfirstconnect;
7155 ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
7156 cfirstconnect = connectPtr.p->nfConnect;
7157
7158 const Uint32 userPtr = req->connectPtr;
7159 const BlockReference userRef = signal->getSendersBlockRef();
7160 connectPtr.p->nfConnect = RNIL;
7161 connectPtr.p->userpointer = userPtr;
7162 connectPtr.p->userblockref = userRef;
7163 connectPtr.p->connectState = ConnectRecord::INUSE;
7164 connectPtr.p->table = req->tableId;
7165
7166 TabRecordPtr tabPtr;
7167 tabPtr.i = req->tableId;
7168 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7169 tabPtr.p->connectrec = connectPtr.i;
7170 tabPtr.p->tableType = req->tableType;
7171 fragType= req->fragType;
7172 tabPtr.p->schemaVersion = req->schemaVersion;
7173 tabPtr.p->primaryTableId = req->primaryTableId;
7174
7175 if(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE){
7176 jam();
7177 tabPtr.p->tabStatus = TabRecord::TS_CREATING;
7178 sendAddFragreq(signal, connectPtr, tabPtr, 0);
7179 return;
7180 }
7181
7182 if(getNodeState().getSystemRestartInProgress() &&
7183 tabPtr.p->tabStatus == TabRecord::TS_IDLE){
7184 jam();
7185
7186 ndbrequire(cmasterNodeId == getOwnNodeId());
7187 tabPtr.p->tabStatus = TabRecord::TS_CREATING;
7188
7189 initTableFile(tabPtr);
7190 FileRecordPtr filePtr;
7191 filePtr.i = tabPtr.p->tabFile[0];
7192 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
7193 openFileRw(signal, filePtr);
7194 filePtr.p->reqStatus = FileRecord::OPENING_TABLE;
7195 return;
7196 }
7197
7198 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
7199 /* AT THE TIME OF INITIATING THE FILE OF TABLE */
7200 /* DESCRIPTION IS CREATED FOR APPROPRIATE SIZE. EACH */
7201 /* EACH RECORD IN THIS FILE HAS THE INFORMATION ABOUT */
7202 /* ONE TABLE. THE POINTER TO THIS RECORD IS THE TABLE */
7203 /* REFERENCE. IN THE BEGINNING ALL RECORDS ARE CREATED */
7204 /* BUT THEY DO NOT HAVE ANY INFORMATION ABOUT ANY TABLE*/
7205 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
7206 tabPtr.p->tabStatus = TabRecord::TS_CREATING;
7207 if(req->loggedTable)
7208 tabPtr.p->tabStorage= TabRecord::ST_NORMAL;
7209 else if(req->temporaryTable)
7210 tabPtr.p->tabStorage= TabRecord::ST_TEMPORARY;
7211 else
7212 tabPtr.p->tabStorage= TabRecord::ST_NOLOGGING;
7213 tabPtr.p->kvalue = req->kValue;
7214
7215 switch ((DictTabInfo::FragmentType)fragType)
7216 {
7217 case DictTabInfo::AllNodesSmallTable:
7218 case DictTabInfo::AllNodesMediumTable:
7219 case DictTabInfo::AllNodesLargeTable:
7220 case DictTabInfo::SingleFragment:
7221 jam();
7222 case DictTabInfo::DistrKeyLin:
7223 jam();
7224 tabPtr.p->method= TabRecord::LINEAR_HASH;
7225 break;
7226 case DictTabInfo::DistrKeyHash:
7227 case DictTabInfo::DistrKeyUniqueHashIndex:
7228 case DictTabInfo::DistrKeyOrderedIndex:
7229 jam();
7230 tabPtr.p->method= TabRecord::NORMAL_HASH;
7231 break;
7232 case DictTabInfo::UserDefined:
7233 jam();
7234 tabPtr.p->method= TabRecord::USER_DEFINED;
7235 break;
7236 default:
7237 ndbrequire(false);
7238 }
7239
7240 union {
7241 Uint16 fragments[2 + MAX_FRAG_PER_NODE*MAX_REPLICAS*MAX_NDB_NODES];
7242 Uint32 align;
7243 };
7244 SegmentedSectionPtr fragDataPtr;
7245 LINT_INIT(fragDataPtr.i);
7246 LINT_INIT(fragDataPtr.sz);
7247 signal->getSection(fragDataPtr, DiAddTabReq::FRAGMENTATION);
7248 copy((Uint32*)fragments, fragDataPtr);
7249 releaseSections(signal);
7250
7251 const Uint32 noReplicas = fragments[0];
7252 const Uint32 noFragments = fragments[1];
7253
7254 tabPtr.p->noOfBackups = noReplicas - 1;
7255 tabPtr.p->totalfragments = noFragments;
7256 ndbrequire(noReplicas == cnoReplicas); // Only allowed
7257
7258 if (ERROR_INSERTED(7173)) {
7259 CLEAR_ERROR_INSERT_VALUE;
7260 addtabrefuseLab(signal, connectPtr, ZREPLERROR1);
7261 return;
7262 }
7263 if ((noReplicas * noFragments) > cnoFreeReplicaRec) {
7264 jam();
7265 addtabrefuseLab(signal, connectPtr, ZREPLERROR1);
7266 return;
7267 }//if
7268 if (noFragments > cremainingfrags) {
7269 jam();
7270 addtabrefuseLab(signal, connectPtr, ZREPLERROR1);
7271 return;
7272 }//if
7273
7274 Uint32 logTotalFragments = 1;
7275 while (logTotalFragments <= tabPtr.p->totalfragments) {
7276 jam();
7277 logTotalFragments <<= 1;
7278 }
7279 logTotalFragments >>= 1;
7280 tabPtr.p->mask = logTotalFragments - 1;
7281 tabPtr.p->hashpointer = tabPtr.p->totalfragments - logTotalFragments;
7282 allocFragments(tabPtr.p->totalfragments, tabPtr);
7283
7284 Uint32 index = 2;
7285 for (Uint32 fragId = 0; fragId < noFragments; fragId++) {
7286 jam();
7287 FragmentstorePtr fragPtr;
7288 Uint32 activeIndex = 0;
7289 getFragstore(tabPtr.p, fragId, fragPtr);
7290 fragPtr.p->m_log_part_id = fragments[index++];
7291 fragPtr.p->preferredPrimary = fragments[index];
7292
7293 for (Uint32 i = 0; i<noReplicas; i++) {
7294 const Uint32 nodeId = fragments[index++];
7295 ReplicaRecordPtr replicaPtr;
7296 allocStoredReplica(fragPtr, replicaPtr, nodeId);
7297 if (getNodeStatus(nodeId) == NodeRecord::ALIVE) {
7298 jam();
7299 ndbrequire(activeIndex < MAX_REPLICAS);
7300 fragPtr.p->activeNodes[activeIndex] = nodeId;
7301 activeIndex++;
7302 } else {
7303 jam();
7304 removeStoredReplica(fragPtr, replicaPtr);
7305 linkOldStoredReplica(fragPtr, replicaPtr);
7306 }//if
7307 }//for
7308 fragPtr.p->fragReplicas = activeIndex;
7309 ndbrequire(activeIndex > 0 && fragPtr.p->storedReplicas != RNIL);
7310 }
7311 initTableFile(tabPtr);
7312 tabPtr.p->tabCopyStatus = TabRecord::CS_ADD_TABLE_MASTER;
7313 signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
7314 signal->theData[1] = tabPtr.i;
7315 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
7316 }
7317
7318 void
addTable_closeConf(Signal * signal,Uint32 tabPtrI)7319 Dbdih::addTable_closeConf(Signal * signal, Uint32 tabPtrI){
7320 TabRecordPtr tabPtr;
7321 tabPtr.i = tabPtrI;
7322 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7323
7324 ConnectRecordPtr connectPtr;
7325 connectPtr.i = tabPtr.p->connectrec;
7326 ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
7327
7328 sendAddFragreq(signal, connectPtr, tabPtr, 0);
7329 }
7330
7331 void
sendAddFragreq(Signal * signal,ConnectRecordPtr connectPtr,TabRecordPtr tabPtr,Uint32 fragId)7332 Dbdih::sendAddFragreq(Signal* signal, ConnectRecordPtr connectPtr,
7333 TabRecordPtr tabPtr, Uint32 fragId){
7334 jam();
7335 const Uint32 fragCount = tabPtr.p->totalfragments;
7336 ReplicaRecordPtr replicaPtr;
7337 LINT_INIT(replicaPtr.p);
7338 replicaPtr.i = RNIL;
7339 FragmentstorePtr fragPtr;
7340 for(; fragId<fragCount; fragId++){
7341 jam();
7342 getFragstore(tabPtr.p, fragId, fragPtr);
7343
7344 replicaPtr.i = fragPtr.p->storedReplicas;
7345 while(replicaPtr.i != RNIL){
7346 jam();
7347 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
7348 if(replicaPtr.p->procNode == getOwnNodeId()){
7349 break;
7350 }
7351 replicaPtr.i = replicaPtr.p->nextReplica;
7352 }
7353
7354 if(replicaPtr.i != RNIL){
7355 jam();
7356 break;
7357 }
7358
7359 replicaPtr.i = fragPtr.p->oldStoredReplicas;
7360 while(replicaPtr.i != RNIL){
7361 jam();
7362 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
7363 if(replicaPtr.p->procNode == getOwnNodeId()){
7364 break;
7365 }
7366 replicaPtr.i = replicaPtr.p->nextReplica;
7367 }
7368
7369 if(replicaPtr.i != RNIL){
7370 jam();
7371 break;
7372 }
7373 }
7374
7375 if(replicaPtr.i != RNIL){
7376 jam();
7377 ndbrequire(fragId < fragCount);
7378 ndbrequire(replicaPtr.p->procNode == getOwnNodeId());
7379
7380 Uint32 requestInfo = 0;
7381 if(tabPtr.p->tabStorage != TabRecord::ST_NORMAL){
7382 requestInfo |= LqhFragReq::TemporaryTable;
7383 }
7384
7385 if(getNodeState().getNodeRestartInProgress()){
7386 requestInfo |= LqhFragReq::CreateInRunning;
7387 }
7388
7389 AddFragReq* const req = (AddFragReq*)signal->getDataPtr();
7390 req->dihPtr = connectPtr.i;
7391 req->senderData = connectPtr.p->userpointer;
7392 req->fragmentId = fragId;
7393 req->requestInfo = requestInfo;
7394 req->tableId = tabPtr.i;
7395 req->nextLCP = 0;
7396 req->nodeId = getOwnNodeId();
7397 req->totalFragments = fragCount;
7398 req->startGci = SYSFILE->newestRestorableGCI;
7399 req->logPartId = fragPtr.p->m_log_part_id;
7400 sendSignal(DBDICT_REF, GSN_ADD_FRAGREQ, signal,
7401 AddFragReq::SignalLength, JBB);
7402 return;
7403 }
7404
7405 // Done
7406 DiAddTabConf * const conf = (DiAddTabConf*)signal->getDataPtr();
7407 conf->senderData = connectPtr.p->userpointer;
7408 sendSignal(connectPtr.p->userblockref, GSN_DIADDTABCONF, signal,
7409 DiAddTabConf::SignalLength, JBB);
7410
7411 // Release
7412 release_connect(connectPtr);
7413 }
7414 void
release_connect(ConnectRecordPtr ptr)7415 Dbdih::release_connect(ConnectRecordPtr ptr)
7416 {
7417 ptr.p->userblockref = ZNIL;
7418 ptr.p->userpointer = RNIL;
7419 ptr.p->connectState = ConnectRecord::FREE;
7420 ptr.p->nfConnect = cfirstconnect;
7421 cfirstconnect = ptr.i;
7422 }
7423
7424 void
execADD_FRAGCONF(Signal * signal)7425 Dbdih::execADD_FRAGCONF(Signal* signal){
7426 jamEntry();
7427 AddFragConf * const conf = (AddFragConf*)signal->getDataPtr();
7428
7429 ConnectRecordPtr connectPtr;
7430 connectPtr.i = conf->dihPtr;
7431 ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
7432
7433 TabRecordPtr tabPtr;
7434 tabPtr.i = connectPtr.p->table;
7435 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7436
7437 sendAddFragreq(signal, connectPtr, tabPtr, conf->fragId + 1);
7438 }
7439
7440 void
execADD_FRAGREF(Signal * signal)7441 Dbdih::execADD_FRAGREF(Signal* signal){
7442 jamEntry();
7443 AddFragRef * const ref = (AddFragRef*)signal->getDataPtr();
7444
7445 ConnectRecordPtr connectPtr;
7446 connectPtr.i = ref->dihPtr;
7447 ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
7448
7449 {
7450 DiAddTabRef * const ref = (DiAddTabRef*)signal->getDataPtr();
7451 ref->senderData = connectPtr.p->userpointer;
7452 ref->errorCode = ~0;
7453 sendSignal(connectPtr.p->userblockref, GSN_DIADDTABREF, signal,
7454 DiAddTabRef::SignalLength, JBB);
7455 }
7456
7457 // Release
7458 release_connect(connectPtr);
7459 }
7460
7461 /*
7462 3.7.1.3 R E F U S E
7463 *********************
7464 */
addtabrefuseLab(Signal * signal,ConnectRecordPtr connectPtr,Uint32 errorCode)7465 void Dbdih::addtabrefuseLab(Signal* signal, ConnectRecordPtr connectPtr, Uint32 errorCode)
7466 {
7467 signal->theData[0] = connectPtr.p->userpointer;
7468 signal->theData[1] = errorCode;
7469 sendSignal(connectPtr.p->userblockref, GSN_DIADDTABREF, signal, 2, JBB);
7470 release_connect(connectPtr);
7471 return;
7472 }//Dbdih::addtabrefuseLab()
7473
7474 /*
7475 3.7.2 A D D T A B L E D U P L I C A T I O N
7476 *************************************************
7477 */
7478 /*
7479 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
7480 *******************************************************************=
7481 */
7482
7483 /*
7484 D E L E T E T A B L E
7485 **********************=
7486 */
7487 /*****************************************************************************/
7488 /*********** DELETE TABLE MODULE *************/
7489 /*****************************************************************************/
7490 void
execDROP_TAB_REQ(Signal * signal)7491 Dbdih::execDROP_TAB_REQ(Signal* signal){
7492 jamEntry();
7493 DropTabReq* req = (DropTabReq*)signal->getDataPtr();
7494
7495 TabRecordPtr tabPtr;
7496 tabPtr.i = req->tableId;
7497 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7498
7499 tabPtr.p->m_dropTab.tabUserRef = req->senderRef;
7500 tabPtr.p->m_dropTab.tabUserPtr = req->senderData;
7501
7502 DropTabReq::RequestType rt = (DropTabReq::RequestType)req->requestType;
7503
7504 switch(rt){
7505 case DropTabReq::OnlineDropTab:
7506 jam();
7507 ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_DROPPING);
7508 releaseTable(tabPtr);
7509 break;
7510 case DropTabReq::CreateTabDrop:
7511 jam();
7512 releaseTable(tabPtr);
7513 break;
7514 case DropTabReq::RestartDropTab:
7515 break;
7516 }
7517
7518 startDeleteFile(signal, tabPtr);
7519 }
7520
startDeleteFile(Signal * signal,TabRecordPtr tabPtr)7521 void Dbdih::startDeleteFile(Signal* signal, TabRecordPtr tabPtr)
7522 {
7523 if (tabPtr.p->tabFile[0] == RNIL) {
7524 jam();
7525 initTableFile(tabPtr);
7526 }//if
7527 openTableFileForDelete(signal, tabPtr.p->tabFile[0]);
7528 }//Dbdih::startDeleteFile()
7529
openTableFileForDelete(Signal * signal,Uint32 fileIndex)7530 void Dbdih::openTableFileForDelete(Signal* signal, Uint32 fileIndex)
7531 {
7532 FileRecordPtr filePtr;
7533 filePtr.i = fileIndex;
7534 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
7535 openFileRw(signal, filePtr);
7536 filePtr.p->reqStatus = FileRecord::TABLE_OPEN_FOR_DELETE;
7537 }//Dbdih::openTableFileForDelete()
7538
tableOpenLab(Signal * signal,FileRecordPtr filePtr)7539 void Dbdih::tableOpenLab(Signal* signal, FileRecordPtr filePtr)
7540 {
7541 closeFileDelete(signal, filePtr);
7542 filePtr.p->reqStatus = FileRecord::TABLE_CLOSE_DELETE;
7543 return;
7544 }//Dbdih::tableOpenLab()
7545
tableDeleteLab(Signal * signal,FileRecordPtr filePtr)7546 void Dbdih::tableDeleteLab(Signal* signal, FileRecordPtr filePtr)
7547 {
7548 TabRecordPtr tabPtr;
7549 tabPtr.i = filePtr.p->tabRef;
7550 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7551 if (filePtr.i == tabPtr.p->tabFile[0]) {
7552 jam();
7553 openTableFileForDelete(signal, tabPtr.p->tabFile[1]);
7554 return;
7555 }//if
7556 ndbrequire(filePtr.i == tabPtr.p->tabFile[1]);
7557
7558 releaseFile(tabPtr.p->tabFile[0]);
7559 releaseFile(tabPtr.p->tabFile[1]);
7560 tabPtr.p->tabFile[0] = tabPtr.p->tabFile[1] = RNIL;
7561
7562 tabPtr.p->tabStatus = TabRecord::TS_IDLE;
7563
7564 DropTabConf * const dropConf = (DropTabConf *)signal->getDataPtrSend();
7565 dropConf->senderRef = reference();
7566 dropConf->senderData = tabPtr.p->m_dropTab.tabUserPtr;
7567 dropConf->tableId = tabPtr.i;
7568 sendSignal(tabPtr.p->m_dropTab.tabUserRef, GSN_DROP_TAB_CONF,
7569 signal, DropTabConf::SignalLength, JBB);
7570
7571 tabPtr.p->m_dropTab.tabUserPtr = RNIL;
7572 tabPtr.p->m_dropTab.tabUserRef = 0;
7573 }//Dbdih::tableDeleteLab()
7574
7575
releaseTable(TabRecordPtr tabPtr)7576 void Dbdih::releaseTable(TabRecordPtr tabPtr)
7577 {
7578 FragmentstorePtr fragPtr;
7579 if (tabPtr.p->noOfFragChunks > 0) {
7580 for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
7581 jam();
7582 getFragstore(tabPtr.p, fragId, fragPtr);
7583 releaseReplicas(fragPtr.p->storedReplicas);
7584 releaseReplicas(fragPtr.p->oldStoredReplicas);
7585 }//for
7586 releaseFragments(tabPtr);
7587 }
7588 if (tabPtr.p->tabFile[0] != RNIL) {
7589 jam();
7590 releaseFile(tabPtr.p->tabFile[0]);
7591 releaseFile(tabPtr.p->tabFile[1]);
7592 tabPtr.p->tabFile[0] = tabPtr.p->tabFile[1] = RNIL;
7593 }//if
7594 }//Dbdih::releaseTable()
7595
releaseReplicas(Uint32 replicaPtrI)7596 void Dbdih::releaseReplicas(Uint32 replicaPtrI)
7597 {
7598 ReplicaRecordPtr replicaPtr;
7599 replicaPtr.i = replicaPtrI;
7600 jam();
7601 while (replicaPtr.i != RNIL) {
7602 jam();
7603 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
7604 Uint32 tmp = replicaPtr.p->nextReplica;
7605 replicaPtr.p->nextReplica = cfirstfreeReplica;
7606 cfirstfreeReplica = replicaPtr.i;
7607 replicaPtr.i = tmp;
7608 cnoFreeReplicaRec++;
7609 }//while
7610 }//Dbdih::releaseReplicas()
7611
seizeReplicaRec(ReplicaRecordPtr & replicaPtr)7612 void Dbdih::seizeReplicaRec(ReplicaRecordPtr& replicaPtr)
7613 {
7614 replicaPtr.i = cfirstfreeReplica;
7615 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
7616 cfirstfreeReplica = replicaPtr.p->nextReplica;
7617 cnoFreeReplicaRec--;
7618 replicaPtr.p->nextReplica = RNIL;
7619 }//Dbdih::seizeReplicaRec()
7620
releaseFile(Uint32 fileIndex)7621 void Dbdih::releaseFile(Uint32 fileIndex)
7622 {
7623 FileRecordPtr filePtr;
7624 filePtr.i = fileIndex;
7625 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
7626 filePtr.p->nextFile = cfirstfreeFile;
7627 cfirstfreeFile = filePtr.i;
7628 }//Dbdih::releaseFile()
7629
7630
execALTER_TAB_REQ(Signal * signal)7631 void Dbdih::execALTER_TAB_REQ(Signal * signal)
7632 {
7633 AlterTabReq* const req = (AlterTabReq*)signal->getDataPtr();
7634 const Uint32 senderRef = req->senderRef;
7635 const Uint32 senderData = req->senderData;
7636 const Uint32 changeMask = req->changeMask;
7637 const Uint32 tableId = req->tableId;
7638 const Uint32 tableVersion = req->tableVersion;
7639 const Uint32 gci = req->gci;
7640 AlterTabReq::RequestType requestType =
7641 (AlterTabReq::RequestType) req->requestType;
7642
7643 TabRecordPtr tabPtr;
7644 tabPtr.i = tableId;
7645 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7646 tabPtr.p->schemaVersion = tableVersion;
7647
7648 // Request handled successfully
7649 AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
7650 conf->senderRef = reference();
7651 conf->senderData = senderData;
7652 conf->changeMask = changeMask;
7653 conf->tableId = tableId;
7654 conf->tableVersion = tableVersion;
7655 conf->gci = gci;
7656 conf->requestType = requestType;
7657 sendSignal(senderRef, GSN_ALTER_TAB_CONF, signal,
7658 AlterTabConf::SignalLength, JBB);
7659 }
7660
7661 /*
7662 G E T N O D E S
7663 **********************=
7664 */
7665 /*****************************************************************************/
7666 /* ********** TRANSACTION HANDLING MODULE *************/
7667 /*****************************************************************************/
7668 /*
7669 3.8.1 G E T N O D E S R E Q U E S T
7670 ******************************************
7671 Asks what nodes should be part of a transaction.
7672 */
execDIGETNODESREQ(Signal * signal)7673 void Dbdih::execDIGETNODESREQ(Signal* signal)
7674 {
7675 const DiGetNodesReq * const req = (DiGetNodesReq *)&signal->theData[0];
7676 FragmentstorePtr fragPtr;
7677 TabRecordPtr tabPtr;
7678 tabPtr.i = req->tableId;
7679 Uint32 hashValue = req->hashValue;
7680 Uint32 ttabFileSize = ctabFileSize;
7681 Uint32 fragId;
7682 DiGetNodesConf * const conf = (DiGetNodesConf *)&signal->theData[0];
7683 TabRecord* regTabDesc = tabRecord;
7684 jamEntry();
7685 ptrCheckGuard(tabPtr, ttabFileSize, regTabDesc);
7686 if (tabPtr.p->method == TabRecord::LINEAR_HASH)
7687 {
7688 jam();
7689 fragId = hashValue & tabPtr.p->mask;
7690 ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
7691 if (fragId < tabPtr.p->hashpointer) {
7692 jam();
7693 fragId = hashValue & ((tabPtr.p->mask << 1) + 1);
7694 }//if
7695 }
7696 else if (tabPtr.p->method == TabRecord::NORMAL_HASH)
7697 {
7698 jam();
7699 fragId= hashValue % tabPtr.p->totalfragments;
7700 }
7701 else
7702 {
7703 jam();
7704 ndbassert(tabPtr.p->method == TabRecord::USER_DEFINED);
7705 fragId= hashValue;
7706 if (fragId >= tabPtr.p->totalfragments)
7707 {
7708 jam();
7709 conf->zero= 1; //Indicate error;
7710 signal->theData[1]= ZUNDEFINED_FRAGMENT_ERROR;
7711 return;
7712 }
7713 }
7714 getFragstore(tabPtr.p, fragId, fragPtr);
7715 Uint32 nodeCount = extractNodeInfo(fragPtr.p, conf->nodes);
7716 Uint32 sig2 = (nodeCount - 1) +
7717 (fragPtr.p->distributionKey << 16);
7718 conf->zero = 0;
7719 conf->reqinfo = sig2;
7720 conf->fragId = fragId;
7721 }//Dbdih::execDIGETNODESREQ()
7722
extractNodeInfo(const Fragmentstore * fragPtr,Uint32 nodes[])7723 Uint32 Dbdih::extractNodeInfo(const Fragmentstore * fragPtr, Uint32 nodes[])
7724 {
7725 Uint32 nodeCount = 0;
7726 for (Uint32 i = 0; i < fragPtr->fragReplicas; i++) {
7727 jam();
7728 NodeRecordPtr nodePtr;
7729 ndbrequire(i < MAX_REPLICAS);
7730 nodePtr.i = fragPtr->activeNodes[i];
7731 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
7732 if (nodePtr.p->useInTransactions) {
7733 jam();
7734 nodes[nodeCount] = nodePtr.i;
7735 nodeCount++;
7736 }//if
7737 }//for
7738 ndbrequire(nodeCount > 0);
7739 return nodeCount;
7740 }//Dbdih::extractNodeInfo()
7741
7742 void
getFragstore(TabRecord * tab,Uint32 fragNo,FragmentstorePtr & fragptr)7743 Dbdih::getFragstore(TabRecord * tab, //In parameter
7744 Uint32 fragNo, //In parameter
7745 FragmentstorePtr & fragptr) //Out parameter
7746 {
7747 FragmentstorePtr fragPtr;
7748 Uint32 chunkNo = fragNo >> LOG_NO_OF_FRAGS_PER_CHUNK;
7749 Uint32 chunkIndex = fragNo & (NO_OF_FRAGS_PER_CHUNK - 1);
7750 Uint32 TfragstoreFileSize = cfragstoreFileSize;
7751 Fragmentstore* TfragStore = fragmentstore;
7752 if (chunkNo < MAX_NDB_NODES) {
7753 fragPtr.i = tab->startFid[chunkNo] + chunkIndex;
7754 ptrCheckGuard(fragPtr, TfragstoreFileSize, TfragStore);
7755 fragptr = fragPtr;
7756 return;
7757 }//if
7758 ndbrequire(false);
7759 }//Dbdih::getFragstore()
7760
allocFragments(Uint32 noOfFragments,TabRecordPtr tabPtr)7761 void Dbdih::allocFragments(Uint32 noOfFragments, TabRecordPtr tabPtr)
7762 {
7763 FragmentstorePtr fragPtr;
7764 Uint32 noOfChunks = (noOfFragments + (NO_OF_FRAGS_PER_CHUNK - 1)) >> LOG_NO_OF_FRAGS_PER_CHUNK;
7765 ndbrequire(cremainingfrags >= noOfFragments);
7766 for (Uint32 i = 0; i < noOfChunks; i++) {
7767 jam();
7768 Uint32 baseFrag = cfirstfragstore;
7769 tabPtr.p->startFid[i] = baseFrag;
7770 fragPtr.i = baseFrag;
7771 ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
7772 cfirstfragstore = fragPtr.p->nextFragmentChunk;
7773 cremainingfrags -= NO_OF_FRAGS_PER_CHUNK;
7774 for (Uint32 j = 0; j < NO_OF_FRAGS_PER_CHUNK; j++) {
7775 jam();
7776 fragPtr.i = baseFrag + j;
7777 ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
7778 initFragstore(fragPtr);
7779 }//if
7780 }//for
7781 tabPtr.p->noOfFragChunks = noOfChunks;
7782 }//Dbdih::allocFragments()
7783
releaseFragments(TabRecordPtr tabPtr)7784 void Dbdih::releaseFragments(TabRecordPtr tabPtr)
7785 {
7786 FragmentstorePtr fragPtr;
7787 for (Uint32 i = 0; i < tabPtr.p->noOfFragChunks; i++) {
7788 jam();
7789 Uint32 baseFrag = tabPtr.p->startFid[i];
7790 fragPtr.i = baseFrag;
7791 ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
7792 fragPtr.p->nextFragmentChunk = cfirstfragstore;
7793 cfirstfragstore = baseFrag;
7794 tabPtr.p->startFid[i] = RNIL;
7795 cremainingfrags += NO_OF_FRAGS_PER_CHUNK;
7796 }//for
7797 tabPtr.p->noOfFragChunks = 0;
7798 }//Dbdih::releaseFragments()
7799
initialiseFragstore()7800 void Dbdih::initialiseFragstore()
7801 {
7802 Uint32 i;
7803 FragmentstorePtr fragPtr;
7804 for (i = 0; i < cfragstoreFileSize; i++) {
7805 fragPtr.i = i;
7806 ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
7807 initFragstore(fragPtr);
7808 }//for
7809 Uint32 noOfChunks = cfragstoreFileSize >> LOG_NO_OF_FRAGS_PER_CHUNK;
7810 fragPtr.i = 0;
7811 cfirstfragstore = RNIL;
7812 cremainingfrags = 0;
7813 for (i = 0; i < noOfChunks; i++) {
7814 refresh_watch_dog();
7815 ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
7816 fragPtr.p->nextFragmentChunk = cfirstfragstore;
7817 cfirstfragstore = fragPtr.i;
7818 fragPtr.i += NO_OF_FRAGS_PER_CHUNK;
7819 cremainingfrags += NO_OF_FRAGS_PER_CHUNK;
7820 }//for
7821 }//Dbdih::initialiseFragstore()
7822
7823 /*
7824 3.9 V E R I F I C A T I O N
7825 ****************************=
7826 */
7827 /****************************************************************************/
7828 /* ********** VERIFICATION SUB-MODULE *************/
7829 /****************************************************************************/
7830 /*
7831 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
7832 *************************************************************************
7833 */
execDIVERIFYREQ(Signal * signal)7834 void Dbdih::execDIVERIFYREQ(Signal* signal)
7835 {
7836
7837 jamEntry();
7838 if ((getBlockCommit() == false) &&
7839 (cfirstVerifyQueue == RNIL)) {
7840 jam();
7841 /*-----------------------------------------------------------------------*/
7842 // We are not blocked and the verify queue was empty currently so we can
7843 // simply reply back to TC immediately. The method was called with
7844 // EXECUTE_DIRECT so we reply back by setting signal data and returning.
7845 // theData[0] already contains the correct information so
7846 // we need not touch it.
7847 /*-----------------------------------------------------------------------*/
7848 signal->theData[1] = currentgcp;
7849 signal->theData[2] = 0;
7850 return;
7851 }//if
7852 /*-------------------------------------------------------------------------*/
7853 // Since we are blocked we need to put this operation last in the verify
7854 // queue to ensure that operation starts up in the correct order.
7855 /*-------------------------------------------------------------------------*/
7856 ApiConnectRecordPtr tmpApiConnectptr;
7857 ApiConnectRecordPtr localApiConnectptr;
7858
7859 cverifyQueueCounter++;
7860 localApiConnectptr.i = signal->theData[0];
7861 tmpApiConnectptr.i = clastVerifyQueue;
7862 ptrCheckGuard(localApiConnectptr, capiConnectFileSize, apiConnectRecord);
7863 localApiConnectptr.p->apiGci = cnewgcp;
7864 localApiConnectptr.p->nextApi = RNIL;
7865 clastVerifyQueue = localApiConnectptr.i;
7866 if (tmpApiConnectptr.i == RNIL) {
7867 jam();
7868 cfirstVerifyQueue = localApiConnectptr.i;
7869 } else {
7870 jam();
7871 ptrCheckGuard(tmpApiConnectptr, capiConnectFileSize, apiConnectRecord);
7872 tmpApiConnectptr.p->nextApi = localApiConnectptr.i;
7873 }//if
7874 emptyverificbuffer(signal, false);
7875 signal->theData[2] = 1; // Indicate no immediate return
7876 return;
7877 }//Dbdih::execDIVERIFYREQ()
7878
execDI_FCOUNTREQ(Signal * signal)7879 void Dbdih::execDI_FCOUNTREQ(Signal* signal)
7880 {
7881 DihFragCountReq * const req = (DihFragCountReq*)signal->getDataPtr();
7882 ConnectRecordPtr connectPtr;
7883 TabRecordPtr tabPtr;
7884 const BlockReference senderRef = signal->senderBlockRef();
7885 const Uint32 senderData = req->m_senderData;
7886 jamEntry();
7887 connectPtr.i = req->m_connectionData;
7888 tabPtr.i = req->m_tableRef;
7889 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7890
7891 if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
7892 {
7893 DihFragCountRef* ref = (DihFragCountRef*)signal->getDataPtrSend();
7894 //connectPtr.i == RNIL -> question without connect record
7895 if(connectPtr.i == RNIL)
7896 ref->m_connectionData = RNIL;
7897 else
7898 {
7899 jam();
7900 ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
7901 ref->m_connectionData = connectPtr.p->userpointer;
7902 }
7903 ref->m_tableRef = tabPtr.i;
7904 ref->m_senderData = senderData;
7905 ref->m_error = DihFragCountRef::ErroneousTableState;
7906 ref->m_tableStatus = tabPtr.p->tabStatus;
7907 sendSignal(senderRef, GSN_DI_FCOUNTREF, signal,
7908 DihFragCountRef::SignalLength, JBB);
7909 return;
7910 }
7911
7912 if(connectPtr.i != RNIL){
7913 ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
7914 if (connectPtr.p->connectState == ConnectRecord::INUSE) {
7915 jam();
7916 DihFragCountConf* conf = (DihFragCountConf*)signal->getDataPtrSend();
7917 conf->m_connectionData = connectPtr.p->userpointer;
7918 conf->m_tableRef = tabPtr.i;
7919 conf->m_senderData = senderData;
7920 conf->m_fragmentCount = tabPtr.p->totalfragments;
7921 conf->m_noOfBackups = tabPtr.p->noOfBackups;
7922 sendSignal(connectPtr.p->userblockref, GSN_DI_FCOUNTCONF, signal,
7923 DihFragCountConf::SignalLength, JBB);
7924 return;
7925 }//if
7926 DihFragCountRef* ref = (DihFragCountRef*)signal->getDataPtrSend();
7927 ref->m_connectionData = connectPtr.p->userpointer;
7928 ref->m_tableRef = tabPtr.i;
7929 ref->m_senderData = senderData;
7930 ref->m_error = DihFragCountRef::ErroneousTableState;
7931 ref->m_tableStatus = tabPtr.p->tabStatus;
7932 sendSignal(connectPtr.p->userblockref, GSN_DI_FCOUNTREF, signal,
7933 DihFragCountRef::SignalLength, JBB);
7934 return;
7935 }//if
7936 DihFragCountConf* conf = (DihFragCountConf*)signal->getDataPtrSend();
7937 //connectPtr.i == RNIL -> question without connect record
7938 conf->m_connectionData = RNIL;
7939 conf->m_tableRef = tabPtr.i;
7940 conf->m_senderData = senderData;
7941 conf->m_fragmentCount = tabPtr.p->totalfragments;
7942 conf->m_noOfBackups = tabPtr.p->noOfBackups;
7943 sendSignal(senderRef, GSN_DI_FCOUNTCONF, signal,
7944 DihFragCountConf::SignalLength, JBB);
7945 }//Dbdih::execDI_FCOUNTREQ()
7946
execDIGETPRIMREQ(Signal * signal)7947 void Dbdih::execDIGETPRIMREQ(Signal* signal)
7948 {
7949 FragmentstorePtr fragPtr;
7950 ConnectRecordPtr connectPtr;
7951 TabRecordPtr tabPtr;
7952 jamEntry();
7953 Uint32 passThrough = signal->theData[1];
7954 tabPtr.i = signal->theData[2];
7955 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7956 if (DictTabInfo::isOrderedIndex(tabPtr.p->tableType)) {
7957 jam();
7958 tabPtr.i = tabPtr.p->primaryTableId;
7959 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
7960 }
7961 Uint32 fragId = signal->theData[3];
7962
7963 ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
7964 connectPtr.i = signal->theData[0];
7965 if(connectPtr.i != RNIL)
7966 {
7967 jam();
7968 ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
7969 signal->theData[0] = connectPtr.p->userpointer;
7970 }
7971 else
7972 {
7973 jam();
7974 signal->theData[0] = RNIL;
7975 }
7976
7977 Uint32 nodes[MAX_REPLICAS];
7978 getFragstore(tabPtr.p, fragId, fragPtr);
7979 Uint32 count = extractNodeInfo(fragPtr.p, nodes);
7980
7981 signal->theData[1] = passThrough;
7982 signal->theData[2] = nodes[0];
7983 signal->theData[3] = nodes[1];
7984 signal->theData[4] = nodes[2];
7985 signal->theData[5] = nodes[3];
7986 signal->theData[6] = count;
7987 signal->theData[7] = tabPtr.i;
7988 signal->theData[8] = fragId;
7989
7990 const BlockReference senderRef = signal->senderBlockRef();
7991 sendSignal(senderRef, GSN_DIGETPRIMCONF, signal, 9, JBB);
7992 }//Dbdih::execDIGETPRIMREQ()
7993
7994 /****************************************************************************/
7995 /* ********** GLOBAL-CHECK-POINT HANDLING MODULE *************/
7996 /****************************************************************************/
7997 /*
7998 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)
7999 *******************************************************************
8000 */
checkGcpStopLab(Signal * signal)8001 void Dbdih::checkGcpStopLab(Signal* signal)
8002 {
8003 Uint32 tgcpStatus;
8004
8005 tgcpStatus = cgcpStatus;
8006 if (tgcpStatus == coldGcpStatus) {
8007 jam();
8008 if (coldGcpId == cnewgcp) {
8009 jam();
8010 if (cgcpStatus != GCP_READY) {
8011 jam();
8012 cgcpSameCounter++;
8013 if (cgcpSameCounter == 1200) {
8014 jam();
8015 #ifdef VM_TRACE
8016 g_eventLogger.error("System crash due to GCP Stop in state = %u",
8017 (Uint32) cgcpStatus);
8018 #endif
8019 crashSystemAtGcpStop(signal, false);
8020 return;
8021 }//if
8022 } else {
8023 jam();
8024 if (cgcpOrderBlocked == 0) {
8025 jam();
8026 cgcpSameCounter++;
8027 if (cgcpSameCounter == 1200) {
8028 jam();
8029 #ifdef VM_TRACE
8030 g_eventLogger.error("System crash due to GCP Stop in state = %u",
8031 (Uint32) cgcpStatus);
8032 #endif
8033 crashSystemAtGcpStop(signal, false);
8034 return;
8035 }//if
8036 } else {
8037 jam();
8038 cgcpSameCounter = 0;
8039 }//if
8040 }//if
8041 } else {
8042 jam();
8043 cgcpSameCounter = 0;
8044 }//if
8045 } else {
8046 jam();
8047 cgcpSameCounter = 0;
8048 }//if
8049 signal->theData[0] = DihContinueB::ZCHECK_GCP_STOP;
8050 signal->theData[1] = coldGcpStatus;
8051 signal->theData[2] = cgcpStatus;
8052 signal->theData[3] = coldGcpId;
8053 signal->theData[4] = cnewgcp;
8054 signal->theData[5] = cgcpSameCounter;
8055 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 6);
8056 coldGcpStatus = cgcpStatus;
8057 coldGcpId = cnewgcp;
8058 return;
8059 }//Dbdih::checkGcpStopLab()
8060
startGcpLab(Signal * signal,Uint32 aWaitTime)8061 void Dbdih::startGcpLab(Signal* signal, Uint32 aWaitTime)
8062 {
8063 if ((cgcpOrderBlocked == 1) ||
8064 (c_nodeStartMaster.blockGcp == true) ||
8065 (cfirstVerifyQueue != RNIL)) {
8066 /*************************************************************************/
8067 // 1: Global Checkpoint has been stopped by management command
8068 // 2: Global Checkpoint is blocked by node recovery activity
8069 // 3: Previous global checkpoint is not yet completed.
8070 // All this means that global checkpoint cannot start now.
8071 /*************************************************************************/
8072 jam();
8073 cgcpStartCounter++;
8074 signal->theData[0] = DihContinueB::ZSTART_GCP;
8075 signal->theData[1] = aWaitTime > 100 ? (aWaitTime - 100) : 0;
8076 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
8077 return;
8078 }//if
8079 if (cstartGcpNow == false && aWaitTime > 100){
8080 /*************************************************************************/
8081 // We still have more than 100 milliseconds before we start the next and
8082 // nobody has ordered immediate start of a global checkpoint.
8083 // During initial start we will use continuos global checkpoints to
8084 // speed it up since we need to complete a global checkpoint after
8085 // inserting a lot of records.
8086 /*************************************************************************/
8087 jam();
8088 cgcpStartCounter++;
8089 signal->theData[0] = DihContinueB::ZSTART_GCP;
8090 signal->theData[1] = (aWaitTime - 100);
8091 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
8092 return;
8093 }//if
8094 cgcpStartCounter = 0;
8095 cstartGcpNow = false;
8096 /***************************************************************************/
8097 // Report the event that a global checkpoint has started.
8098 /***************************************************************************/
8099 signal->theData[0] = NDB_LE_GlobalCheckpointStarted; //Event type
8100 signal->theData[1] = cnewgcp;
8101 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
8102
8103 CRASH_INSERTION(7000);
8104 cnewgcp++;
8105 signal->setTrace(TestOrd::TraceGlobalCheckpoint);
8106 sendLoopMacro(GCP_PREPARE, sendGCP_PREPARE);
8107 cgcpStatus = GCP_PREPARE_SENT;
8108 }//Dbdih::startGcpLab()
8109
execGCP_PREPARECONF(Signal * signal)8110 void Dbdih::execGCP_PREPARECONF(Signal* signal)
8111 {
8112 jamEntry();
8113 Uint32 senderNodeId = signal->theData[0];
8114 Uint32 gci = signal->theData[1];
8115 ndbrequire(gci == cnewgcp);
8116 receiveLoopMacro(GCP_PREPARE, senderNodeId);
8117 //-------------------------------------------------------------
8118 // We have now received all replies. We are ready to continue
8119 // with committing the global checkpoint.
8120 //-------------------------------------------------------------
8121 gcpcommitreqLab(signal);
8122 }//Dbdih::execGCP_PREPARECONF()
8123
gcpcommitreqLab(Signal * signal)8124 void Dbdih::gcpcommitreqLab(Signal* signal)
8125 {
8126 CRASH_INSERTION(7001);
8127 sendLoopMacro(GCP_COMMIT, sendGCP_COMMIT);
8128 cgcpStatus = GCP_COMMIT_SENT;
8129 return;
8130 }//Dbdih::gcpcommitreqLab()
8131
execGCP_NODEFINISH(Signal * signal)8132 void Dbdih::execGCP_NODEFINISH(Signal* signal)
8133 {
8134 jamEntry();
8135 const Uint32 senderNodeId = signal->theData[0];
8136 const Uint32 gci = signal->theData[1];
8137 const Uint32 failureNr = signal->theData[2];
8138 if (!isMaster()) {
8139 jam();
8140 ndbrequire(failureNr > cfailurenr);
8141 //-------------------------------------------------------------
8142 // Another node thinks we are master. This could happen when he
8143 // has heard of a node failure which I have not heard of. Ignore
8144 // signal in this case since we will discover it by sending
8145 // MASTER_GCPREQ to the node.
8146 //-------------------------------------------------------------
8147 return;
8148 } else if (cmasterState == MASTER_TAKE_OVER_GCP) {
8149 jam();
8150 //-------------------------------------------------------------
8151 // We are currently taking over as master. Ignore
8152 // signal in this case since we will discover it in reception of
8153 // MASTER_GCPCONF.
8154 //-------------------------------------------------------------
8155 return;
8156 } else {
8157 ndbrequire(cmasterState == MASTER_ACTIVE);
8158 }//if
8159 ndbrequire(gci == coldgcp);
8160 receiveLoopMacro(GCP_COMMIT, senderNodeId);
8161 //-------------------------------------------------------------
8162 // We have now received all replies. We are ready to continue
8163 // with saving the global checkpoint to disk.
8164 //-------------------------------------------------------------
8165 CRASH_INSERTION(7002);
8166 gcpsavereqLab(signal);
8167 return;
8168 }//Dbdih::execGCP_NODEFINISH()
8169
gcpsavereqLab(Signal * signal)8170 void Dbdih::gcpsavereqLab(Signal* signal)
8171 {
8172 sendLoopMacro(GCP_SAVEREQ, sendGCP_SAVEREQ);
8173 cgcpStatus = GCP_NODE_FINISHED;
8174 }//Dbdih::gcpsavereqLab()
8175
execGCP_SAVECONF(Signal * signal)8176 void Dbdih::execGCP_SAVECONF(Signal* signal)
8177 {
8178 jamEntry();
8179 const GCPSaveConf * const saveConf = (GCPSaveConf*)&signal->theData[0];
8180 ndbrequire(saveConf->gci == coldgcp);
8181 ndbrequire(saveConf->nodeId == saveConf->dihPtr);
8182 SYSFILE->lastCompletedGCI[saveConf->nodeId] = saveConf->gci;
8183 GCP_SAVEhandling(signal, saveConf->nodeId);
8184 }//Dbdih::execGCP_SAVECONF()
8185
execGCP_SAVEREF(Signal * signal)8186 void Dbdih::execGCP_SAVEREF(Signal* signal)
8187 {
8188 jamEntry();
8189 const GCPSaveRef * const saveRef = (GCPSaveRef*)&signal->theData[0];
8190 ndbrequire(saveRef->gci == coldgcp);
8191 ndbrequire(saveRef->nodeId == saveRef->dihPtr);
8192 /**
8193 * Only allow reason not to save
8194 */
8195 ndbrequire(saveRef->errorCode == GCPSaveRef::NodeShutdownInProgress ||
8196 saveRef->errorCode == GCPSaveRef::FakedSignalDueToNodeFailure ||
8197 saveRef->errorCode == GCPSaveRef::NodeRestartInProgress);
8198 GCP_SAVEhandling(signal, saveRef->nodeId);
8199 }//Dbdih::execGCP_SAVEREF()
8200
GCP_SAVEhandling(Signal * signal,Uint32 nodeId)8201 void Dbdih::GCP_SAVEhandling(Signal* signal, Uint32 nodeId)
8202 {
8203 receiveLoopMacro(GCP_SAVEREQ, nodeId);
8204 /*-------------------------------------------------------------------------*/
8205 // All nodes have replied. We are ready to update the system file.
8206 /*-------------------------------------------------------------------------*/
8207 cgcpStatus = GCP_SAVE_LQH_FINISHED;
8208 CRASH_INSERTION(7003);
8209 checkToCopy();
8210 /**------------------------------------------------------------------------
8211 * SET NEW RECOVERABLE GCI. ALSO RESET RESTART COUNTER TO ZERO.
8212 * THIS INDICATES THAT THE SYSTEM HAS BEEN RECOVERED AND SURVIVED AT
8213 * LEAST ONE GLOBAL CHECKPOINT PERIOD. WE WILL USE THIS PARAMETER TO
8214 * SET BACK THE RESTART GCI IF WE ENCOUNTER MORE THAN ONE UNSUCCESSFUL
8215 * RESTART.
8216 *------------------------------------------------------------------------*/
8217 SYSFILE->newestRestorableGCI = coldgcp;
8218 if(Sysfile::getInitialStartOngoing(SYSFILE->systemRestartBits) &&
8219 getNodeState().startLevel == NodeState::SL_STARTED){
8220 jam();
8221 #if 0
8222 g_eventLogger.info("Dbdih: Clearing initial start ongoing");
8223 #endif
8224 Sysfile::clearInitialStartOngoing(SYSFILE->systemRestartBits);
8225 }
8226 copyGciLab(signal, CopyGCIReq::GLOBAL_CHECKPOINT);
8227 }//Dbdih::GCP_SAVEhandling()
8228
8229 /*
8230 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)
8231 *************************************************************
8232 */
execGCP_PREPARE(Signal * signal)8233 void Dbdih::execGCP_PREPARE(Signal* signal)
8234 {
8235 jamEntry();
8236 CRASH_INSERTION(7005);
8237
8238 if (ERROR_INSERTED(7030))
8239 {
8240 cgckptflag = true;
8241 g_eventLogger.info("Delayed GCP_PREPARE 5s");
8242 sendSignalWithDelay(reference(), GSN_GCP_PREPARE, signal, 5000,
8243 signal->getLength());
8244 return;
8245 }
8246
8247 Uint32 masterNodeId = signal->theData[0];
8248 Uint32 gci = signal->theData[1];
8249 BlockReference retRef = calcDihBlockRef(masterNodeId);
8250
8251 ndbrequire (cmasterdihref == retRef);
8252 ndbrequire (cgcpParticipantState == GCP_PARTICIPANT_READY);
8253 ndbrequire (gci == (currentgcp + 1));
8254
8255 cgckptflag = true;
8256 cgcpParticipantState = GCP_PARTICIPANT_PREPARE_RECEIVED;
8257 cnewgcp = gci;
8258
8259 if (ERROR_INSERTED(7031))
8260 {
8261 g_eventLogger.info("Crashing delayed in GCP_PREPARE 3s");
8262 signal->theData[0] = 9999;
8263 sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 3000, 1);
8264 return;
8265 }
8266
8267 signal->theData[0] = cownNodeId;
8268 signal->theData[1] = gci;
8269 sendSignal(retRef, GSN_GCP_PREPARECONF, signal, 2, JBA);
8270 return;
8271 }//Dbdih::execGCP_PREPARE()
8272
execGCP_COMMIT(Signal * signal)8273 void Dbdih::execGCP_COMMIT(Signal* signal)
8274 {
8275 jamEntry();
8276 CRASH_INSERTION(7006);
8277 Uint32 masterNodeId = signal->theData[0];
8278 Uint32 gci = signal->theData[1];
8279
8280 ndbrequire(gci == (currentgcp + 1));
8281 ndbrequire(masterNodeId = cmasterNodeId);
8282 ndbrequire(cgcpParticipantState == GCP_PARTICIPANT_PREPARE_RECEIVED);
8283
8284 coldgcp = currentgcp;
8285 currentgcp = cnewgcp;
8286 cgckptflag = false;
8287 emptyverificbuffer(signal, true);
8288 cgcpParticipantState = GCP_PARTICIPANT_COMMIT_RECEIVED;
8289 signal->theData[0] = calcDihBlockRef(masterNodeId);
8290 signal->theData[1] = coldgcp;
8291 sendSignal(clocaltcblockref, GSN_GCP_NOMORETRANS, signal, 2, JBB);
8292 return;
8293 }//Dbdih::execGCP_COMMIT()
8294
execGCP_TCFINISHED(Signal * signal)8295 void Dbdih::execGCP_TCFINISHED(Signal* signal)
8296 {
8297 jamEntry();
8298 CRASH_INSERTION(7007);
8299 Uint32 retRef = signal->theData[0];
8300 Uint32 gci = signal->theData[1];
8301 ndbrequire(gci == coldgcp);
8302
8303 if (ERROR_INSERTED(7181) || ERROR_INSERTED(7182))
8304 {
8305 c_error_7181_ref = retRef; // Save ref
8306 ndbout_c("killing %d", refToNode(cmasterdihref));
8307 signal->theData[0] = 9999;
8308 sendSignal(numberToRef(CMVMI, refToNode(cmasterdihref)),
8309 GSN_NDB_TAMPER, signal, 1, JBB);
8310 return;
8311 }
8312
8313 cgcpParticipantState = GCP_PARTICIPANT_TC_FINISHED;
8314 signal->theData[0] = cownNodeId;
8315 signal->theData[1] = coldgcp;
8316 signal->theData[2] = cfailurenr;
8317 sendSignal(retRef, GSN_GCP_NODEFINISH, signal, 3, JBB);
8318 }//Dbdih::execGCP_TCFINISHED()
8319
8320 /*****************************************************************************/
8321 //****** RECEIVING TAMPER REQUEST FROM NDBAPI ******
8322 /*****************************************************************************/
execDIHNDBTAMPER(Signal * signal)8323 void Dbdih::execDIHNDBTAMPER(Signal* signal)
8324 {
8325 jamEntry();
8326 Uint32 tcgcpblocked = signal->theData[0];
8327 /* ACTION TO BE TAKEN BY DIH */
8328 Uint32 tuserpointer = signal->theData[1];
8329 BlockReference tuserblockref = signal->theData[2];
8330 switch (tcgcpblocked) {
8331 case 1:
8332 jam();
8333 if (isMaster()) {
8334 jam();
8335 cgcpOrderBlocked = 1;
8336 } else {
8337 jam();
8338 /* TRANSFER THE REQUEST */
8339 /* TO MASTER*/
8340 signal->theData[0] = tcgcpblocked;
8341 signal->theData[1] = tuserpointer;
8342 signal->theData[2] = tuserblockref;
8343 sendSignal(cmasterdihref, GSN_DIHNDBTAMPER, signal, 3, JBB);
8344 }//if
8345 break;
8346 case 2:
8347 jam();
8348 if (isMaster()) {
8349 jam();
8350 cgcpOrderBlocked = 0;
8351 } else {
8352 jam();
8353 /* TRANSFER THE REQUEST */
8354 /* TO MASTER*/
8355 signal->theData[0] = tcgcpblocked;
8356 signal->theData[1] = tuserpointer;
8357 signal->theData[2] = tuserblockref;
8358 sendSignal(cmasterdihref, GSN_DIHNDBTAMPER, signal, 3, JBB);
8359 }//if
8360 break;
8361 case 3:
8362 ndbrequire(false);
8363 return;
8364 break;
8365 case 4:
8366 jam();
8367 signal->theData[0] = tuserpointer;
8368 signal->theData[1] = crestartGci;
8369 sendSignal(tuserblockref, GSN_DIHNDBTAMPER, signal, 2, JBB);
8370 break;
8371 #ifdef ERROR_INSERT
8372 case 5:
8373 jam();
8374 if(tuserpointer == 0)
8375 {
8376 jam();
8377 signal->theData[0] = 0;
8378 sendSignal(QMGR_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8379 sendSignal(NDBCNTR_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8380 sendSignal(NDBFS_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8381 sendSignal(DBACC_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8382 sendSignal(DBTUP_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8383 sendSignal(DBLQH_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8384 sendSignal(DBDICT_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8385 sendSignal(DBDIH_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8386 sendSignal(DBTC_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8387 sendSignal(CMVMI_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8388 return;
8389 }
8390 /*----------------------------------------------------------------------*/
8391 // Insert errors.
8392 /*----------------------------------------------------------------------*/
8393 if (tuserpointer < 1000) {
8394 /*--------------------------------------------------------------------*/
8395 // Insert errors into QMGR.
8396 /*--------------------------------------------------------------------*/
8397 jam();
8398 tuserblockref = QMGR_REF;
8399 } else if (tuserpointer < 2000) {
8400 /*--------------------------------------------------------------------*/
8401 // Insert errors into NDBCNTR.
8402 /*--------------------------------------------------------------------*/
8403 jam();
8404 tuserblockref = NDBCNTR_REF;
8405 } else if (tuserpointer < 3000) {
8406 /*--------------------------------------------------------------------*/
8407 // Insert errors into NDBFS.
8408 /*--------------------------------------------------------------------*/
8409 jam();
8410 tuserblockref = NDBFS_REF;
8411 } else if (tuserpointer < 4000) {
8412 /*--------------------------------------------------------------------*/
8413 // Insert errors into DBACC.
8414 /*--------------------------------------------------------------------*/
8415 jam();
8416 tuserblockref = DBACC_REF;
8417 } else if (tuserpointer < 5000) {
8418 /*--------------------------------------------------------------------*/
8419 // Insert errors into DBTUP.
8420 /*--------------------------------------------------------------------*/
8421 jam();
8422 tuserblockref = DBTUP_REF;
8423 } else if (tuserpointer < 6000) {
8424 /*---------------------------------------------------------------------*/
8425 // Insert errors into DBLQH.
8426 /*---------------------------------------------------------------------*/
8427 jam();
8428 tuserblockref = DBLQH_REF;
8429 } else if (tuserpointer < 7000) {
8430 /*---------------------------------------------------------------------*/
8431 // Insert errors into DBDICT.
8432 /*---------------------------------------------------------------------*/
8433 jam();
8434 tuserblockref = DBDICT_REF;
8435 } else if (tuserpointer < 8000) {
8436 /*---------------------------------------------------------------------*/
8437 // Insert errors into DBDIH.
8438 /*--------------------------------------------------------------------*/
8439 jam();
8440 tuserblockref = DBDIH_REF;
8441 } else if (tuserpointer < 9000) {
8442 /*--------------------------------------------------------------------*/
8443 // Insert errors into DBTC.
8444 /*--------------------------------------------------------------------*/
8445 jam();
8446 tuserblockref = DBTC_REF;
8447 } else if (tuserpointer < 10000) {
8448 /*--------------------------------------------------------------------*/
8449 // Insert errors into CMVMI.
8450 /*--------------------------------------------------------------------*/
8451 jam();
8452 tuserblockref = CMVMI_REF;
8453 } else if (tuserpointer < 11000) {
8454 jam();
8455 tuserblockref = BACKUP_REF;
8456 } else if (tuserpointer < 12000) {
8457 // DBUTIL_REF ?
8458 jam();
8459 } else if (tuserpointer < 13000) {
8460 jam();
8461 tuserblockref = DBTUX_REF;
8462 } else if (tuserpointer < 14000) {
8463 jam();
8464 tuserblockref = SUMA_REF;
8465 } else if (tuserpointer < 15000) {
8466 jam();
8467 tuserblockref = DBDICT_REF;
8468 } else if (tuserpointer < 16000) {
8469 jam();
8470 tuserblockref = LGMAN_REF;
8471 } else if (tuserpointer < 17000) {
8472 jam();
8473 tuserblockref = TSMAN_REF;
8474 } else if (tuserpointer < 30000) {
8475 /*--------------------------------------------------------------------*/
8476 // Ignore errors in the 20000-range.
8477 /*--------------------------------------------------------------------*/
8478 jam();
8479 return;
8480 } else if (tuserpointer < 40000) {
8481 jam();
8482 /*--------------------------------------------------------------------*/
8483 // Redirect errors to master DIH in the 30000-range.
8484 /*--------------------------------------------------------------------*/
8485 tuserblockref = cmasterdihref;
8486 tuserpointer -= 30000;
8487 signal->theData[0] = 5;
8488 signal->theData[1] = tuserpointer;
8489 signal->theData[2] = tuserblockref;
8490 sendSignal(tuserblockref, GSN_DIHNDBTAMPER, signal, 3, JBB);
8491 return;
8492 } else if (tuserpointer < 50000) {
8493 NodeRecordPtr localNodeptr;
8494 Uint32 Tfound = 0;
8495 jam();
8496 /*--------------------------------------------------------------------*/
8497 // Redirect errors to non-master DIH in the 40000-range.
8498 /*--------------------------------------------------------------------*/
8499 tuserpointer -= 40000;
8500 for (localNodeptr.i = 1;
8501 localNodeptr.i < MAX_NDB_NODES;
8502 localNodeptr.i++) {
8503 jam();
8504 ptrAss(localNodeptr, nodeRecord);
8505 if ((localNodeptr.p->nodeStatus == NodeRecord::ALIVE) &&
8506 (localNodeptr.i != cmasterNodeId)) {
8507 jam();
8508 tuserblockref = calcDihBlockRef(localNodeptr.i);
8509 Tfound = 1;
8510 break;
8511 }//if
8512 }//for
8513 if (Tfound == 0) {
8514 jam();
8515 /*-------------------------------------------------------------------*/
8516 // Ignore since no non-master node existed.
8517 /*-------------------------------------------------------------------*/
8518 return;
8519 }//if
8520 signal->theData[0] = 5;
8521 signal->theData[1] = tuserpointer;
8522 signal->theData[2] = tuserblockref;
8523 sendSignal(tuserblockref, GSN_DIHNDBTAMPER, signal, 3, JBB);
8524 return;
8525 } else {
8526 jam();
8527 return;
8528 }//if
8529 signal->theData[0] = tuserpointer;
8530 if (tuserpointer != 0) {
8531 sendSignal(tuserblockref, GSN_NDB_TAMPER, signal, 1, JBB);
8532 } else {
8533 sendSignal(QMGR_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8534 sendSignal(NDBCNTR_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8535 sendSignal(NDBFS_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8536 sendSignal(DBACC_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8537 sendSignal(DBTUP_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8538 sendSignal(DBLQH_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8539 sendSignal(DBDICT_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8540 sendSignal(DBDIH_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8541 sendSignal(DBTC_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8542 sendSignal(CMVMI_REF, GSN_NDB_TAMPER, signal, 1, JBB);
8543 }//if
8544 break;
8545 #endif
8546 default:
8547 ndbrequire(false);
8548 break;
8549 }//switch
8550 return;
8551 }//Dbdih::execDIHNDBTAMPER()
8552
8553 /*****************************************************************************/
8554 /* ********** FILE HANDLING MODULE *************/
8555 /*****************************************************************************/
copyGciLab(Signal * signal,CopyGCIReq::CopyReason reason)8556 void Dbdih::copyGciLab(Signal* signal, CopyGCIReq::CopyReason reason)
8557 {
8558 if(c_copyGCIMaster.m_copyReason != CopyGCIReq::IDLE){
8559 /**
8560 * There can currently only be one waiting
8561 */
8562 ndbrequire(c_copyGCIMaster.m_waiting == CopyGCIReq::IDLE);
8563 c_copyGCIMaster.m_waiting = reason;
8564 return;
8565 }
8566 c_copyGCIMaster.m_copyReason = reason;
8567 sendLoopMacro(COPY_GCIREQ, sendCOPY_GCIREQ);
8568
8569 }//Dbdih::copyGciLab()
8570
8571 /* ------------------------------------------------------------------------- */
8572 /* COPY_GCICONF RESPONSE TO COPY_GCIREQ */
8573 /* ------------------------------------------------------------------------- */
execCOPY_GCICONF(Signal * signal)8574 void Dbdih::execCOPY_GCICONF(Signal* signal)
8575 {
8576 jamEntry();
8577 NodeRecordPtr senderNodePtr;
8578 senderNodePtr.i = signal->theData[0];
8579 receiveLoopMacro(COPY_GCIREQ, senderNodePtr.i);
8580
8581 CopyGCIReq::CopyReason waiting = c_copyGCIMaster.m_waiting;
8582 CopyGCIReq::CopyReason current = c_copyGCIMaster.m_copyReason;
8583
8584 c_copyGCIMaster.m_copyReason = CopyGCIReq::IDLE;
8585 c_copyGCIMaster.m_waiting = CopyGCIReq::IDLE;
8586
8587 bool ok = false;
8588 switch(current){
8589 case CopyGCIReq::RESTART:{
8590 ok = true;
8591 jam();
8592 DictStartReq * req = (DictStartReq*)&signal->theData[0];
8593 req->restartGci = SYSFILE->newestRestorableGCI;
8594 req->senderRef = reference();
8595 sendSignal(cdictblockref, GSN_DICTSTARTREQ,
8596 signal, DictStartReq::SignalLength, JBB);
8597 break;
8598 }
8599 case CopyGCIReq::LOCAL_CHECKPOINT:{
8600 ok = true;
8601 jam();
8602 startLcpRoundLab(signal);
8603 break;
8604 }
8605 case CopyGCIReq::GLOBAL_CHECKPOINT:
8606 ok = true;
8607 jam();
8608 checkToCopyCompleted(signal);
8609
8610 /************************************************************************/
8611 // Report the event that a global checkpoint has completed.
8612 /************************************************************************/
8613 signal->setTrace(0);
8614 signal->theData[0] = NDB_LE_GlobalCheckpointCompleted; //Event type
8615 signal->theData[1] = coldgcp;
8616 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
8617
8618 c_newest_restorable_gci = coldgcp;
8619
8620 CRASH_INSERTION(7004);
8621 emptyWaitGCPMasterQueue(signal);
8622 cgcpStatus = GCP_READY;
8623 signal->theData[0] = DihContinueB::ZSTART_GCP;
8624 signal->theData[1] = cgcpDelay;
8625 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
8626 if (c_nodeStartMaster.blockGcp == true) {
8627 jam();
8628 /* ------------------------------------------------------------------ */
8629 /* A NEW NODE WANTS IN AND WE MUST ALLOW IT TO COME IN NOW SINCE THE */
8630 /* GCP IS COMPLETED. */
8631 /* ------------------------------------------------------------------ */
8632 gcpBlockedLab(signal);
8633 }//if
8634 break;
8635 case CopyGCIReq::INITIAL_START_COMPLETED:
8636 ok = true;
8637 jam();
8638 initialStartCompletedLab(signal);
8639 break;
8640 case CopyGCIReq::IDLE:
8641 ok = false;
8642 jam();
8643 }
8644 ndbrequire(ok);
8645
8646 /**
8647 * Pop queue
8648 */
8649 if(waiting != CopyGCIReq::IDLE){
8650 c_copyGCIMaster.m_copyReason = waiting;
8651 signal->theData[0] = DihContinueB::ZCOPY_GCI;
8652 signal->theData[1] = waiting;
8653 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
8654 }
8655 }//Dbdih::execCOPY_GCICONF()
8656
invalidateLcpInfoAfterSr()8657 void Dbdih::invalidateLcpInfoAfterSr()
8658 {
8659 NodeRecordPtr nodePtr;
8660 SYSFILE->latestLCP_ID--;
8661 Sysfile::clearLCPOngoing(SYSFILE->systemRestartBits);
8662 for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
8663 jam();
8664 ptrAss(nodePtr, nodeRecord);
8665 if (!NdbNodeBitmask::get(SYSFILE->lcpActive, nodePtr.i)){
8666 jam();
8667 /* ------------------------------------------------------------------- */
8668 // The node was not active in the local checkpoint.
8669 // To avoid that we step the active status too fast to not
8670 // active we step back one step from Sysfile::NS_ActiveMissed_x.
8671 /* ------------------------------------------------------------------- */
8672 switch (nodePtr.p->activeStatus) {
8673 case Sysfile::NS_Active:
8674 /* ----------------------------------------------------------------- */
8675 // When not active in ongoing LCP and still active is a contradiction.
8676 /* ----------------------------------------------------------------- */
8677 ndbrequire(false);
8678 case Sysfile::NS_ActiveMissed_1:
8679 jam();
8680 nodePtr.p->activeStatus = Sysfile::NS_Active;
8681 break;
8682 case Sysfile::NS_ActiveMissed_2:
8683 jam();
8684 nodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
8685 break;
8686 default:
8687 jam();
8688 break;
8689 }//switch
8690 }//if
8691 }//for
8692 setNodeRestartInfoBits();
8693 }//Dbdih::invalidateLcpInfoAfterSr()
8694
8695 /* ------------------------------------------------------------------------- */
8696 /* THE NEXT STEP IS TO WRITE THE FILE. */
8697 /* ------------------------------------------------------------------------- */
openingCopyGciSkipInitLab(Signal * signal,FileRecordPtr filePtr)8698 void Dbdih::openingCopyGciSkipInitLab(Signal* signal, FileRecordPtr filePtr)
8699 {
8700 writeRestorableGci(signal, filePtr);
8701 filePtr.p->reqStatus = FileRecord::WRITING_COPY_GCI;
8702 return;
8703 }//Dbdih::openingCopyGciSkipInitLab()
8704
writingCopyGciLab(Signal * signal,FileRecordPtr filePtr)8705 void Dbdih::writingCopyGciLab(Signal* signal, FileRecordPtr filePtr)
8706 {
8707 /* ----------------------------------------------------------------------- */
8708 /* WE HAVE NOW WRITTEN THIS FILE. WRITE ALSO NEXT FILE IF THIS IS NOT */
8709 /* ALREADY THE LAST. */
8710 /* ----------------------------------------------------------------------- */
8711 filePtr.p->reqStatus = FileRecord::IDLE;
8712 if (filePtr.i == crestartInfoFile[0]) {
8713 jam();
8714 filePtr.i = crestartInfoFile[1];
8715 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
8716 if (filePtr.p->fileStatus == FileRecord::OPEN) {
8717 jam();
8718 openingCopyGciSkipInitLab(signal, filePtr);
8719 return;
8720 }//if
8721 openFileRw(signal, filePtr);
8722 filePtr.p->reqStatus = FileRecord::OPENING_COPY_GCI;
8723 return;
8724 }//if
8725 /* ----------------------------------------------------------------------- */
8726 /* WE HAVE COMPLETED WRITING BOTH FILES SUCCESSFULLY. NOW REPORT OUR */
8727 /* SUCCESS TO THE MASTER DIH. BUT FIRST WE NEED TO RESET A NUMBER OF */
8728 /* VARIABLES USED BY THE LOCAL CHECKPOINT PROCESS (ONLY IF TRIGGERED */
8729 /* BY LOCAL CHECKPOINT PROCESS. */
8730 /* ----------------------------------------------------------------------- */
8731 CopyGCIReq::CopyReason reason = c_copyGCISlave.m_copyReason;
8732
8733 if (reason == CopyGCIReq::GLOBAL_CHECKPOINT) {
8734 jam();
8735 cgcpParticipantState = GCP_PARTICIPANT_READY;
8736
8737 SubGcpCompleteRep * const rep = (SubGcpCompleteRep*)signal->getDataPtr();
8738 rep->gci = coldgcp;
8739 sendSignal(SUMA_REF, GSN_SUB_GCP_COMPLETE_REP, signal,
8740 SubGcpCompleteRep::SignalLength, JBB);
8741
8742 EXECUTE_DIRECT(LGMAN, GSN_SUB_GCP_COMPLETE_REP, signal,
8743 SubGcpCompleteRep::SignalLength);
8744 jamEntry();
8745 }
8746
8747 jam();
8748 c_copyGCISlave.m_copyReason = CopyGCIReq::IDLE;
8749
8750 if(c_copyGCISlave.m_senderRef == cmasterdihref){
8751 jam();
8752 /**
8753 * Only if same master
8754 */
8755 signal->theData[0] = c_copyGCISlave.m_senderData;
8756 sendSignal(c_copyGCISlave.m_senderRef, GSN_COPY_GCICONF, signal, 1, JBB);
8757
8758 }
8759 return;
8760 }//Dbdih::writingCopyGciLab()
8761
execSTART_LCP_REQ(Signal * signal)8762 void Dbdih::execSTART_LCP_REQ(Signal* signal){
8763 StartLcpReq * req = (StartLcpReq*)signal->getDataPtr();
8764
8765 CRASH_INSERTION2(7021, isMaster());
8766 CRASH_INSERTION2(7022, !isMaster());
8767
8768 ndbrequire(c_lcpState.m_masterLcpDihRef = req->senderRef);
8769 c_lcpState.m_participatingDIH = req->participatingDIH;
8770 c_lcpState.m_participatingLQH = req->participatingLQH;
8771
8772 c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH = req->participatingLQH;
8773 if(isMaster()){
8774 jam();
8775 ndbrequire(isActiveMaster());
8776 c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH = req->participatingDIH;
8777
8778 } else {
8779 c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.clearWaitingFor();
8780 }
8781
8782 c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received = false;
8783
8784 c_lcpState.setLcpStatus(LCP_INIT_TABLES, __LINE__);
8785
8786 signal->theData[0] = DihContinueB::ZINIT_LCP;
8787 signal->theData[1] = c_lcpState.m_masterLcpDihRef;
8788 signal->theData[2] = 0;
8789 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
8790 }
8791
initLcpLab(Signal * signal,Uint32 senderRef,Uint32 tableId)8792 void Dbdih::initLcpLab(Signal* signal, Uint32 senderRef, Uint32 tableId)
8793 {
8794 TabRecordPtr tabPtr;
8795 tabPtr.i = tableId;
8796
8797 if(c_lcpState.m_masterLcpDihRef != senderRef){
8798 jam();
8799 /**
8800 * This is LCP master takeover
8801 */
8802 #ifdef VM_TRACE
8803 g_eventLogger.info("initLcpLab aborted due to LCP master takeover - 1");
8804 #endif
8805 c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
8806 sendMASTER_LCPCONF(signal);
8807 return;
8808 }
8809
8810 if(c_lcpState.m_masterLcpDihRef != cmasterdihref){
8811 jam();
8812 /**
8813 * Master take over but has not yet received MASTER_LCPREQ
8814 */
8815 #ifdef VM_TRACE
8816 g_eventLogger.info("initLcpLab aborted due to LCP master takeover - 2");
8817 #endif
8818 return;
8819 }
8820
8821 //const Uint32 lcpId = SYSFILE->latestLCP_ID;
8822
8823 for(; tabPtr.i < ctabFileSize; tabPtr.i++){
8824
8825 ptrAss(tabPtr, tabRecord);
8826
8827 if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE) {
8828 jam();
8829 tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
8830 continue;
8831 }
8832
8833 if (tabPtr.p->tabStorage != TabRecord::ST_NORMAL) {
8834 /**
8835 * Table is not logged
8836 */
8837 jam();
8838 tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
8839 continue;
8840 }
8841
8842 if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
8843 /* ----------------------------------------------------------------- */
8844 // We protect the updates of table data structures by this variable.
8845 /* ----------------------------------------------------------------- */
8846 jam();
8847 signal->theData[0] = DihContinueB::ZINIT_LCP;
8848 signal->theData[1] = senderRef;
8849 signal->theData[2] = tabPtr.i;
8850 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 20, 3);
8851 return;
8852 }//if
8853
8854 /**
8855 * Found a table
8856 */
8857 tabPtr.p->tabLcpStatus = TabRecord::TLS_ACTIVE;
8858
8859 /**
8860 * For each fragment
8861 */
8862 for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
8863 jam();
8864 FragmentstorePtr fragPtr;
8865 getFragstore(tabPtr.p, fragId, fragPtr);
8866
8867 /**
8868 * For each of replica record
8869 */
8870 Uint32 replicaCount = 0;
8871 ReplicaRecordPtr replicaPtr;
8872 for(replicaPtr.i = fragPtr.p->storedReplicas; replicaPtr.i != RNIL;
8873 replicaPtr.i = replicaPtr.p->nextReplica) {
8874 jam();
8875
8876 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
8877 Uint32 nodeId = replicaPtr.p->procNode;
8878 if(c_lcpState.m_participatingLQH.get(nodeId)){
8879 jam();
8880 replicaCount++;
8881 replicaPtr.p->lcpOngoingFlag = true;
8882 }
8883 }
8884
8885 fragPtr.p->noLcpReplicas = replicaCount;
8886 }//for
8887
8888 signal->theData[0] = DihContinueB::ZINIT_LCP;
8889 signal->theData[1] = senderRef;
8890 signal->theData[2] = tabPtr.i + 1;
8891 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
8892 return;
8893 }
8894
8895 /**
8896 * No more tables
8897 */
8898 jam();
8899
8900 if (c_lcpState.m_masterLcpDihRef != reference()){
8901 jam();
8902 ndbrequire(!isMaster());
8903 c_lcpState.setLcpStatus(LCP_STATUS_ACTIVE, __LINE__);
8904 } else {
8905 jam();
8906 ndbrequire(isMaster());
8907 }
8908
8909 CRASH_INSERTION2(7023, isMaster());
8910 CRASH_INSERTION2(7024, !isMaster());
8911
8912 jam();
8913 StartLcpConf * conf = (StartLcpConf*)signal->getDataPtrSend();
8914 conf->senderRef = reference();
8915 sendSignal(c_lcpState.m_masterLcpDihRef, GSN_START_LCP_CONF, signal,
8916 StartLcpConf::SignalLength, JBB);
8917 return;
8918 }//Dbdih::initLcpLab()
8919
8920 /* ------------------------------------------------------------------------- */
8921 /* ERROR HANDLING FOR COPY RESTORABLE GCI FILE. */
8922 /* ------------------------------------------------------------------------- */
openingCopyGciErrorLab(Signal * signal,FileRecordPtr filePtr)8923 void Dbdih::openingCopyGciErrorLab(Signal* signal, FileRecordPtr filePtr)
8924 {
8925 createFileRw(signal, filePtr);
8926 /* ------------------------------------------------------------------------- */
8927 /* ERROR IN OPENING FILE. WE WILL TRY BY CREATING FILE INSTEAD. */
8928 /* ------------------------------------------------------------------------- */
8929 filePtr.p->reqStatus = FileRecord::CREATING_COPY_GCI;
8930 return;
8931 }//Dbdih::openingCopyGciErrorLab()
8932
8933 /* ------------------------------------------------------------------------- */
8934 /* ENTER DICTSTARTCONF WITH */
8935 /* TBLOCKREF */
8936 /* ------------------------------------------------------------------------- */
dictStartConfLab(Signal * signal)8937 void Dbdih::dictStartConfLab(Signal* signal)
8938 {
8939 /* ----------------------------------------------------------------------- */
8940 /* WE HAVE NOW RECEIVED ALL THE TABLES TO RESTART. */
8941 /* ----------------------------------------------------------------------- */
8942 signal->theData[0] = DihContinueB::ZSTART_FRAGMENT;
8943 signal->theData[1] = 0; /* START WITH TABLE 0 */
8944 signal->theData[2] = 0; /* AND FRAGMENT 0 */
8945 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
8946 return;
8947 }//Dbdih::dictStartConfLab()
8948
8949
openingTableLab(Signal * signal,FileRecordPtr filePtr)8950 void Dbdih::openingTableLab(Signal* signal, FileRecordPtr filePtr)
8951 {
8952 /* ---------------------------------------------------------------------- */
8953 /* SUCCESSFULLY OPENED A FILE. READ THE FIRST PAGE OF THIS FILE. */
8954 /* ---------------------------------------------------------------------- */
8955 TabRecordPtr tabPtr;
8956 PageRecordPtr pagePtr;
8957
8958 tabPtr.i = filePtr.p->tabRef;
8959 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
8960 tabPtr.p->noPages = 1;
8961 allocpage(pagePtr);
8962 tabPtr.p->pageRef[0] = pagePtr.i;
8963 readTabfile(signal, tabPtr.p, filePtr);
8964 filePtr.p->reqStatus = FileRecord::READING_TABLE;
8965 return;
8966 }//Dbdih::openingTableLab()
8967
openingTableErrorLab(Signal * signal,FileRecordPtr filePtr)8968 void Dbdih::openingTableErrorLab(Signal* signal, FileRecordPtr filePtr)
8969 {
8970 TabRecordPtr tabPtr;
8971 tabPtr.i = filePtr.p->tabRef;
8972 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
8973 /* ---------------------------------------------------------------------- */
8974 /* WE FAILED IN OPENING A FILE. IF THE FIRST FILE THEN TRY WITH THE */
8975 /* DUPLICATE FILE, OTHERWISE WE REPORT AN ERROR IN THE SYSTEM RESTART. */
8976 /* ---------------------------------------------------------------------- */
8977 if (filePtr.i == tabPtr.p->tabFile[0])
8978 {
8979 filePtr.i = tabPtr.p->tabFile[1];
8980 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
8981 openFileRw(signal, filePtr);
8982 filePtr.p->reqStatus = FileRecord::OPENING_TABLE;
8983 }
8984 else
8985 {
8986 char buf[256];
8987 BaseString::snprintf(buf, sizeof(buf),
8988 "Error opening DIH schema files for table: %d",
8989 tabPtr.i);
8990 progError(__LINE__, NDBD_EXIT_AFS_NO_SUCH_FILE, buf);
8991 }
8992 }//Dbdih::openingTableErrorLab()
8993
readingTableLab(Signal * signal,FileRecordPtr filePtr)8994 void Dbdih::readingTableLab(Signal* signal, FileRecordPtr filePtr)
8995 {
8996 TabRecordPtr tabPtr;
8997 PageRecordPtr pagePtr;
8998 /* ---------------------------------------------------------------------- */
8999 /* WE HAVE SUCCESSFULLY READ A NUMBER OF PAGES IN THE TABLE FILE. IF */
9000 /* MORE PAGES EXIST IN THE FILE THEN READ ALL PAGES IN THE FILE. */
9001 /* ---------------------------------------------------------------------- */
9002 filePtr.p->reqStatus = FileRecord::IDLE;
9003 tabPtr.i = filePtr.p->tabRef;
9004 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9005 pagePtr.i = tabPtr.p->pageRef[0];
9006 ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
9007 Uint32 noOfStoredPages = pagePtr.p->word[33];
9008 if (tabPtr.p->noPages < noOfStoredPages) {
9009 jam();
9010 ndbrequire(noOfStoredPages <= 8);
9011 for (Uint32 i = tabPtr.p->noPages; i < noOfStoredPages; i++) {
9012 jam();
9013 allocpage(pagePtr);
9014 tabPtr.p->pageRef[i] = pagePtr.i;
9015 }//for
9016 tabPtr.p->noPages = noOfStoredPages;
9017 readTabfile(signal, tabPtr.p, filePtr);
9018 filePtr.p->reqStatus = FileRecord::READING_TABLE;
9019 } else {
9020 ndbrequire(tabPtr.p->noPages == pagePtr.p->word[33]);
9021 ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
9022 jam();
9023 /* --------------------------------------------------------------------- */
9024 /* WE HAVE READ ALL PAGES. NOW READ FROM PAGES INTO TABLE AND FRAGMENT */
9025 /* DATA STRUCTURES. */
9026 /* --------------------------------------------------------------------- */
9027 tabPtr.p->tabCopyStatus = TabRecord::CS_SR_PHASE1_READ_PAGES;
9028 signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_TABLE;
9029 signal->theData[1] = tabPtr.i;
9030 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9031 return;
9032 }//if
9033 return;
9034 }//Dbdih::readingTableLab()
9035
readTableFromPagesLab(Signal * signal,TabRecordPtr tabPtr)9036 void Dbdih::readTableFromPagesLab(Signal* signal, TabRecordPtr tabPtr)
9037 {
9038 FileRecordPtr filePtr;
9039 filePtr.i = tabPtr.p->tabFile[0];
9040 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
9041 /* ---------------------------------------------------------------------- */
9042 /* WE HAVE NOW COPIED TO OUR NODE. WE HAVE NOW COMPLETED RESTORING */
9043 /* THIS TABLE. CONTINUE WITH THE NEXT TABLE. */
9044 /* WE ALSO NEED TO CLOSE THE TABLE FILE. */
9045 /* ---------------------------------------------------------------------- */
9046 if (filePtr.p->fileStatus != FileRecord::OPEN) {
9047 jam();
9048 filePtr.i = tabPtr.p->tabFile[1];
9049 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
9050 }//if
9051 closeFile(signal, filePtr);
9052 filePtr.p->reqStatus = FileRecord::CLOSING_TABLE_SR;
9053 return;
9054 }//Dbdih::readTableFromPagesLab()
9055
closingTableSrLab(Signal * signal,FileRecordPtr filePtr)9056 void Dbdih::closingTableSrLab(Signal* signal, FileRecordPtr filePtr)
9057 {
9058 /**
9059 * Update table/fragment info
9060 */
9061 TabRecordPtr tabPtr;
9062 tabPtr.i = filePtr.p->tabRef;
9063 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9064 resetReplicaSr(tabPtr);
9065
9066 signal->theData[0] = DihContinueB::ZCOPY_TABLE;
9067 signal->theData[1] = filePtr.p->tabRef;
9068 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9069
9070 return;
9071 }//Dbdih::closingTableSrLab()
9072
9073 void
resetReplicaSr(TabRecordPtr tabPtr)9074 Dbdih::resetReplicaSr(TabRecordPtr tabPtr){
9075
9076 const Uint32 newestRestorableGCI = SYSFILE->newestRestorableGCI;
9077
9078 for(Uint32 i = 0; i<tabPtr.p->totalfragments; i++){
9079 FragmentstorePtr fragPtr;
9080 getFragstore(tabPtr.p, i, fragPtr);
9081
9082 /**
9083 * 1) Start by moving all replicas into oldStoredReplicas
9084 */
9085 prepareReplicas(fragPtr);
9086
9087 /**
9088 * 2) Move all "alive" replicas into storedReplicas
9089 * + update noCrashedReplicas...
9090 */
9091 ReplicaRecordPtr replicaPtr;
9092 replicaPtr.i = fragPtr.p->oldStoredReplicas;
9093 while (replicaPtr.i != RNIL) {
9094 jam();
9095 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
9096 const Uint32 nextReplicaPtrI = replicaPtr.p->nextReplica;
9097
9098 NodeRecordPtr nodePtr;
9099 nodePtr.i = replicaPtr.p->procNode;
9100 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
9101
9102 const Uint32 noCrashedReplicas = replicaPtr.p->noCrashedReplicas;
9103 if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
9104 jam();
9105 switch (nodePtr.p->activeStatus) {
9106 case Sysfile::NS_Active:
9107 case Sysfile::NS_ActiveMissed_1:
9108 case Sysfile::NS_ActiveMissed_2:{
9109 jam();
9110 /* --------------------------------------------------------------- */
9111 /* THE NODE IS ALIVE AND KICKING AND ACTIVE, LET'S USE IT. */
9112 /* --------------------------------------------------------------- */
9113 arrGuardErr(noCrashedReplicas, 8, NDBD_EXIT_MAX_CRASHED_REPLICAS);
9114 Uint32 lastGci = replicaPtr.p->replicaLastGci[noCrashedReplicas];
9115 if(lastGci >= newestRestorableGCI){
9116 jam();
9117 /** -------------------------------------------------------------
9118 * THE REPLICA WAS ALIVE AT THE SYSTEM FAILURE. WE WILL SET THE
9119 * LAST REPLICA GCI TO MINUS ONE SINCE IT HASN'T FAILED YET IN THE
9120 * NEW SYSTEM.
9121 *-------------------------------------------------------------- */
9122 replicaPtr.p->replicaLastGci[noCrashedReplicas] = (Uint32)-1;
9123 } else {
9124 jam();
9125 /*--------------------------------------------------------------
9126 * SINCE IT WAS NOT ALIVE AT THE TIME OF THE SYSTEM CRASH THIS IS
9127 * A COMPLETELY NEW REPLICA. WE WILL SET THE CREATE GCI TO BE THE
9128 * NEXT GCI TO BE EXECUTED.
9129 *--------_----------------------------------------------------- */
9130 const Uint32 nextCrashed = noCrashedReplicas + 1;
9131 replicaPtr.p->noCrashedReplicas = nextCrashed;
9132 arrGuardErr(nextCrashed, 8, NDBD_EXIT_MAX_CRASHED_REPLICAS);
9133 replicaPtr.p->createGci[nextCrashed] = newestRestorableGCI + 1;
9134 ndbrequire(newestRestorableGCI + 1 != 0xF1F1F1F1);
9135 replicaPtr.p->replicaLastGci[nextCrashed] = (Uint32)-1;
9136 }//if
9137
9138 resetReplicaLcp(replicaPtr.p, newestRestorableGCI);
9139
9140 /**
9141 * Make sure we can also find REDO for restoring replica...
9142 */
9143 {
9144 CreateReplicaRecord createReplica;
9145 ConstPtr<ReplicaRecord> constReplicaPtr;
9146 constReplicaPtr.i = replicaPtr.i;
9147 constReplicaPtr.p = replicaPtr.p;
9148 if (tabPtr.p->tabStorage != TabRecord::ST_NORMAL ||
9149 setup_create_replica(fragPtr,
9150 &createReplica, constReplicaPtr))
9151 {
9152 jam();
9153 removeOldStoredReplica(fragPtr, replicaPtr);
9154 linkStoredReplica(fragPtr, replicaPtr);
9155 }
9156 else
9157 {
9158 jam();
9159 infoEvent("Forcing take-over of node %d due to unsufficient REDO"
9160 " for table %d fragment: %d",
9161 nodePtr.i, tabPtr.i, i);
9162
9163 setNodeActiveStatus(nodePtr.i,
9164 Sysfile::NS_NotActive_NotTakenOver);
9165 }
9166 }
9167 }
9168 default:
9169 jam();
9170 /*empty*/;
9171 break;
9172 }
9173 }
9174 replicaPtr.i = nextReplicaPtrI;
9175 }//while
9176 updateNodeInfo(fragPtr);
9177 }
9178 }
9179
9180 void
resetReplicaLcp(ReplicaRecord * replicaP,Uint32 stopGci)9181 Dbdih::resetReplicaLcp(ReplicaRecord * replicaP, Uint32 stopGci){
9182
9183 Uint32 lcpNo = replicaP->nextLcp;
9184 const Uint32 startLcpNo = lcpNo;
9185 do {
9186 lcpNo = prevLcpNo(lcpNo);
9187 ndbrequire(lcpNo < MAX_LCP_STORED);
9188 if (replicaP->lcpStatus[lcpNo] == ZVALID) {
9189 if (replicaP->maxGciStarted[lcpNo] < stopGci) {
9190 jam();
9191 /* ----------------------------------------------------------------- */
9192 /* WE HAVE FOUND A USEFUL LOCAL CHECKPOINT THAT CAN BE USED FOR */
9193 /* RESTARTING THIS FRAGMENT REPLICA. */
9194 /* ----------------------------------------------------------------- */
9195 return ;
9196 }//if
9197 }//if
9198
9199 /**
9200 * WE COULD NOT USE THIS LOCAL CHECKPOINT. IT WAS TOO
9201 * RECENT OR SIMPLY NOT A VALID CHECKPOINT.
9202 * WE SHOULD THUS REMOVE THIS LOCAL CHECKPOINT SINCE IT WILL NEVER
9203 * AGAIN BE USED. SET LCP_STATUS TO INVALID.
9204 */
9205 replicaP->nextLcp = lcpNo;
9206 replicaP->lcpId[lcpNo] = 0;
9207 replicaP->lcpStatus[lcpNo] = ZINVALID;
9208 } while (lcpNo != startLcpNo);
9209
9210 replicaP->nextLcp = 0;
9211 }
9212
readingTableErrorLab(Signal * signal,FileRecordPtr filePtr)9213 void Dbdih::readingTableErrorLab(Signal* signal, FileRecordPtr filePtr)
9214 {
9215 TabRecordPtr tabPtr;
9216 tabPtr.i = filePtr.p->tabRef;
9217 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9218 /* ---------------------------------------------------------------------- */
9219 /* READING THIS FILE FAILED. CLOSE IT AFTER RELEASING ALL PAGES. */
9220 /* ---------------------------------------------------------------------- */
9221 ndbrequire(tabPtr.p->noPages <= 8);
9222 for (Uint32 i = 0; i < tabPtr.p->noPages; i++) {
9223 jam();
9224 releasePage(tabPtr.p->pageRef[i]);
9225 }//for
9226 closeFile(signal, filePtr);
9227 filePtr.p->reqStatus = FileRecord::CLOSING_TABLE_CRASH;
9228 return;
9229 }//Dbdih::readingTableErrorLab()
9230
closingTableCrashLab(Signal * signal,FileRecordPtr filePtr)9231 void Dbdih::closingTableCrashLab(Signal* signal, FileRecordPtr filePtr)
9232 {
9233 TabRecordPtr tabPtr;
9234 /* ---------------------------------------------------------------------- */
9235 /* WE HAVE NOW CLOSED A FILE WHICH WE HAD A READ ERROR WITH. PROCEED */
9236 /* WITH NEXT FILE IF NOT THE LAST OTHERWISE REPORT ERROR. */
9237 /* ---------------------------------------------------------------------- */
9238 tabPtr.i = filePtr.p->tabRef;
9239 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9240 ndbrequire(filePtr.i == tabPtr.p->tabFile[0]);
9241 filePtr.i = tabPtr.p->tabFile[1];
9242 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
9243 openFileRw(signal, filePtr);
9244 filePtr.p->reqStatus = FileRecord::OPENING_TABLE;
9245 }//Dbdih::closingTableCrashLab()
9246
9247 /*****************************************************************************/
9248 /* ********** COPY TABLE MODULE *************/
9249 /*****************************************************************************/
execCOPY_TABREQ(Signal * signal)9250 void Dbdih::execCOPY_TABREQ(Signal* signal)
9251 {
9252 CRASH_INSERTION(7172);
9253
9254 TabRecordPtr tabPtr;
9255 PageRecordPtr pagePtr;
9256 jamEntry();
9257 BlockReference ref = signal->theData[0];
9258 Uint32 reqinfo = signal->theData[1];
9259 tabPtr.i = signal->theData[2];
9260 Uint32 schemaVersion = signal->theData[3];
9261 Uint32 noOfWords = signal->theData[4];
9262 ndbrequire(ref == cmasterdihref);
9263 ndbrequire(!isMaster());
9264 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9265 if (reqinfo == 1) {
9266 jam();
9267 tabPtr.p->schemaVersion = schemaVersion;
9268 initTableFile(tabPtr);
9269 }//if
9270 ndbrequire(tabPtr.p->noPages < 8);
9271 if (tabPtr.p->noOfWords == 0) {
9272 jam();
9273 allocpage(pagePtr);
9274 tabPtr.p->pageRef[tabPtr.p->noPages] = pagePtr.i;
9275 tabPtr.p->noPages++;
9276 } else {
9277 jam();
9278 pagePtr.i = tabPtr.p->pageRef[tabPtr.p->noPages - 1];
9279 ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
9280 }//if
9281 ndbrequire(tabPtr.p->noOfWords + 15 < 2048);
9282 ndbrequire(tabPtr.p->noOfWords < 2048);
9283 MEMCOPY_NO_WORDS(&pagePtr.p->word[tabPtr.p->noOfWords], &signal->theData[5], 16);
9284 tabPtr.p->noOfWords += 16;
9285 if (tabPtr.p->noOfWords == 2048) {
9286 jam();
9287 tabPtr.p->noOfWords = 0;
9288 }//if
9289 if (noOfWords > 16) {
9290 jam();
9291 return;
9292 }//if
9293 tabPtr.p->noOfWords = 0;
9294 ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
9295 tabPtr.p->tabCopyStatus = TabRecord::CS_COPY_TAB_REQ;
9296 signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_TABLE;
9297 signal->theData[1] = tabPtr.i;
9298 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9299 }//Dbdih::execCOPY_TABREQ()
9300
9301 void
copyTabReq_complete(Signal * signal,TabRecordPtr tabPtr)9302 Dbdih::copyTabReq_complete(Signal* signal, TabRecordPtr tabPtr){
9303 if (!isMaster()) {
9304 jam();
9305 //----------------------------------------------------------------------------
9306 // In this particular case we do not release table pages if we are master. The
9307 // reason is that the master could still be sending the table info to another
9308 // node.
9309 //----------------------------------------------------------------------------
9310 releaseTabPages(tabPtr.i);
9311 tabPtr.p->tabStatus = TabRecord::TS_ACTIVE;
9312 for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
9313 jam();
9314 FragmentstorePtr fragPtr;
9315 getFragstore(tabPtr.p, fragId, fragPtr);
9316 updateNodeInfo(fragPtr);
9317 }//for
9318 }//if
9319 signal->theData[0] = cownNodeId;
9320 signal->theData[1] = tabPtr.i;
9321 sendSignal(cmasterdihref, GSN_COPY_TABCONF, signal, 2, JBB);
9322 }
9323
9324 /*****************************************************************************/
9325 /* ****** READ FROM A NUMBER OF PAGES INTO THE TABLE DATA STRUCTURES ********/
9326 /*****************************************************************************/
readPagesIntoTableLab(Signal * signal,Uint32 tableId)9327 void Dbdih::readPagesIntoTableLab(Signal* signal, Uint32 tableId)
9328 {
9329 RWFragment rf;
9330 rf.wordIndex = 35;
9331 rf.pageIndex = 0;
9332 rf.rwfTabPtr.i = tableId;
9333 ptrCheckGuard(rf.rwfTabPtr, ctabFileSize, tabRecord);
9334 rf.rwfPageptr.i = rf.rwfTabPtr.p->pageRef[0];
9335 ptrCheckGuard(rf.rwfPageptr, cpageFileSize, pageRecord);
9336 rf.rwfTabPtr.p->totalfragments = readPageWord(&rf);
9337 rf.rwfTabPtr.p->noOfBackups = readPageWord(&rf);
9338 rf.rwfTabPtr.p->hashpointer = readPageWord(&rf);
9339 rf.rwfTabPtr.p->kvalue = readPageWord(&rf);
9340 rf.rwfTabPtr.p->mask = readPageWord(&rf);
9341 rf.rwfTabPtr.p->method = (TabRecord::Method)readPageWord(&rf);
9342 /* ------------- */
9343 /* Type of table */
9344 /* ------------- */
9345 rf.rwfTabPtr.p->tabStorage = (TabRecord::Storage)(readPageWord(&rf));
9346
9347 Uint32 noOfFrags = rf.rwfTabPtr.p->totalfragments;
9348 ndbrequire(noOfFrags > 0);
9349 ndbrequire((noOfFrags * (rf.rwfTabPtr.p->noOfBackups + 1)) <= cnoFreeReplicaRec);
9350 allocFragments(noOfFrags, rf.rwfTabPtr);
9351
9352 signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_FRAG;
9353 signal->theData[1] = rf.rwfTabPtr.i;
9354 signal->theData[2] = 0;
9355 signal->theData[3] = rf.pageIndex;
9356 signal->theData[4] = rf.wordIndex;
9357 sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
9358 return;
9359 }//Dbdih::readPagesIntoTableLab()
9360
readPagesIntoFragLab(Signal * signal,RWFragment * rf)9361 void Dbdih::readPagesIntoFragLab(Signal* signal, RWFragment* rf)
9362 {
9363 ndbrequire(rf->pageIndex < 8);
9364 rf->rwfPageptr.i = rf->rwfTabPtr.p->pageRef[rf->pageIndex];
9365 ptrCheckGuard(rf->rwfPageptr, cpageFileSize, pageRecord);
9366 FragmentstorePtr fragPtr;
9367 getFragstore(rf->rwfTabPtr.p, rf->fragId, fragPtr);
9368 readFragment(rf, fragPtr);
9369 readReplicas(rf, fragPtr);
9370 rf->fragId++;
9371 if (rf->fragId == rf->rwfTabPtr.p->totalfragments) {
9372 jam();
9373 switch (rf->rwfTabPtr.p->tabCopyStatus) {
9374 case TabRecord::CS_SR_PHASE1_READ_PAGES:
9375 jam();
9376 releaseTabPages(rf->rwfTabPtr.i);
9377 rf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
9378 signal->theData[0] = DihContinueB::ZREAD_TABLE_FROM_PAGES;
9379 signal->theData[1] = rf->rwfTabPtr.i;
9380 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9381 return;
9382 break;
9383 case TabRecord::CS_COPY_TAB_REQ:
9384 jam();
9385 rf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
9386 if(getNodeState().getSystemRestartInProgress()){
9387 jam();
9388 copyTabReq_complete(signal, rf->rwfTabPtr);
9389 return;
9390 }
9391 rf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
9392 rf->rwfTabPtr.p->tabUpdateState = TabRecord::US_COPY_TAB_REQ;
9393 signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
9394 signal->theData[1] = rf->rwfTabPtr.i;
9395 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9396 return;
9397 break;
9398 default:
9399 ndbrequire(false);
9400 return;
9401 break;
9402 }//switch
9403 } else {
9404 jam();
9405 signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_FRAG;
9406 signal->theData[1] = rf->rwfTabPtr.i;
9407 signal->theData[2] = rf->fragId;
9408 signal->theData[3] = rf->pageIndex;
9409 signal->theData[4] = rf->wordIndex;
9410 sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
9411 }//if
9412 return;
9413 }//Dbdih::readPagesIntoFragLab()
9414
9415 /*****************************************************************************/
9416 /***** WRITING FROM TABLE DATA STRUCTURES INTO A SET OF PAGES ******/
9417 // execCONTINUEB(ZPACK_TABLE_INTO_PAGES)
9418 /*****************************************************************************/
packTableIntoPagesLab(Signal * signal,Uint32 tableId)9419 void Dbdih::packTableIntoPagesLab(Signal* signal, Uint32 tableId)
9420 {
9421 RWFragment wf;
9422 TabRecordPtr tabPtr;
9423 allocpage(wf.rwfPageptr);
9424 tabPtr.i = tableId;
9425 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9426 tabPtr.p->pageRef[0] = wf.rwfPageptr.i;
9427 tabPtr.p->noPages = 1;
9428 wf.wordIndex = 35;
9429 wf.pageIndex = 0;
9430 writePageWord(&wf, tabPtr.p->totalfragments);
9431 writePageWord(&wf, tabPtr.p->noOfBackups);
9432 writePageWord(&wf, tabPtr.p->hashpointer);
9433 writePageWord(&wf, tabPtr.p->kvalue);
9434 writePageWord(&wf, tabPtr.p->mask);
9435 writePageWord(&wf, tabPtr.p->method);
9436 writePageWord(&wf, tabPtr.p->tabStorage);
9437
9438 signal->theData[0] = DihContinueB::ZPACK_FRAG_INTO_PAGES;
9439 signal->theData[1] = tabPtr.i;
9440 signal->theData[2] = 0;
9441 signal->theData[3] = wf.pageIndex;
9442 signal->theData[4] = wf.wordIndex;
9443 sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
9444 }//Dbdih::packTableIntoPagesLab()
9445
9446 /*****************************************************************************/
9447 // execCONTINUEB(ZPACK_FRAG_INTO_PAGES)
9448 /*****************************************************************************/
packFragIntoPagesLab(Signal * signal,RWFragment * wf)9449 void Dbdih::packFragIntoPagesLab(Signal* signal, RWFragment* wf)
9450 {
9451 ndbrequire(wf->pageIndex < 8);
9452 wf->rwfPageptr.i = wf->rwfTabPtr.p->pageRef[wf->pageIndex];
9453 ptrCheckGuard(wf->rwfPageptr, cpageFileSize, pageRecord);
9454 FragmentstorePtr fragPtr;
9455 getFragstore(wf->rwfTabPtr.p, wf->fragId, fragPtr);
9456 writeFragment(wf, fragPtr);
9457 writeReplicas(wf, fragPtr.p->storedReplicas);
9458 writeReplicas(wf, fragPtr.p->oldStoredReplicas);
9459 wf->fragId++;
9460 if (wf->fragId == wf->rwfTabPtr.p->totalfragments) {
9461 jam();
9462 PageRecordPtr pagePtr;
9463 pagePtr.i = wf->rwfTabPtr.p->pageRef[0];
9464 ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
9465 pagePtr.p->word[33] = wf->rwfTabPtr.p->noPages;
9466 pagePtr.p->word[34] = ((wf->rwfTabPtr.p->noPages - 1) * 2048) + wf->wordIndex;
9467 switch (wf->rwfTabPtr.p->tabCopyStatus) {
9468 case TabRecord::CS_SR_PHASE2_READ_TABLE:
9469 /* -------------------------------------------------------------------*/
9470 // We are performing a system restart and we are now ready to copy the
9471 // table from this node (the master) to all other nodes.
9472 /* -------------------------------------------------------------------*/
9473 jam();
9474 wf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
9475 signal->theData[0] = DihContinueB::ZSR_PHASE2_READ_TABLE;
9476 signal->theData[1] = wf->rwfTabPtr.i;
9477 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9478 return;
9479 break;
9480 case TabRecord::CS_COPY_NODE_STATE:
9481 jam();
9482 tableCopyNodeLab(signal, wf->rwfTabPtr);
9483 return;
9484 break;
9485 case TabRecord::CS_LCP_READ_TABLE:
9486 jam();
9487 signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
9488 signal->theData[1] = wf->rwfTabPtr.i;
9489 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9490 return;
9491 break;
9492 case TabRecord::CS_REMOVE_NODE:
9493 case TabRecord::CS_INVALIDATE_NODE_LCP:
9494 jam();
9495 signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
9496 signal->theData[1] = wf->rwfTabPtr.i;
9497 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9498 return;
9499 break;
9500 case TabRecord::CS_ADD_TABLE_MASTER:
9501 jam();
9502 wf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
9503 signal->theData[0] = DihContinueB::ZADD_TABLE_MASTER_PAGES;
9504 signal->theData[1] = wf->rwfTabPtr.i;
9505 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9506 return;
9507 break;
9508 case TabRecord::CS_ADD_TABLE_SLAVE:
9509 jam();
9510 wf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
9511 signal->theData[0] = DihContinueB::ZADD_TABLE_SLAVE_PAGES;
9512 signal->theData[1] = wf->rwfTabPtr.i;
9513 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9514 return;
9515 break;
9516 default:
9517 ndbrequire(false);
9518 return;
9519 break;
9520 }//switch
9521 } else {
9522 jam();
9523 signal->theData[0] = DihContinueB::ZPACK_FRAG_INTO_PAGES;
9524 signal->theData[1] = wf->rwfTabPtr.i;
9525 signal->theData[2] = wf->fragId;
9526 signal->theData[3] = wf->pageIndex;
9527 signal->theData[4] = wf->wordIndex;
9528 sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
9529 }//if
9530 return;
9531 }//Dbdih::packFragIntoPagesLab()
9532
9533 /*****************************************************************************/
9534 /* ********** START FRAGMENT MODULE *************/
9535 /*****************************************************************************/
9536 void
dump_replica_info()9537 Dbdih::dump_replica_info()
9538 {
9539 TabRecordPtr tabPtr;
9540 FragmentstorePtr fragPtr;
9541
9542 for(tabPtr.i = 0; tabPtr.i < ctabFileSize; tabPtr.i++)
9543 {
9544 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9545 if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
9546 continue;
9547
9548 for(Uint32 fid = 0; fid<tabPtr.p->totalfragments; fid++)
9549 {
9550 getFragstore(tabPtr.p, fid, fragPtr);
9551 ndbout_c("tab: %d frag: %d gci: %d\n -- storedReplicas:",
9552 tabPtr.i, fid, SYSFILE->newestRestorableGCI);
9553
9554 Uint32 i;
9555 ReplicaRecordPtr replicaPtr;
9556 replicaPtr.i = fragPtr.p->storedReplicas;
9557 for(; replicaPtr.i != RNIL; replicaPtr.i = replicaPtr.p->nextReplica)
9558 {
9559 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
9560 ndbout_c(" node: %d initialGci: %d nextLcp: %d noCrashedReplicas: %d",
9561 replicaPtr.p->procNode,
9562 replicaPtr.p->initialGci,
9563 replicaPtr.p->nextLcp,
9564 replicaPtr.p->noCrashedReplicas);
9565 for(i = 0; i<MAX_LCP_STORED; i++)
9566 {
9567 ndbout_c(" i: %d %s : lcpId: %d maxGci Completed: %d Started: %d",
9568 i,
9569 (replicaPtr.p->lcpStatus[i] == ZVALID ?"VALID":"INVALID"),
9570 replicaPtr.p->lcpId[i],
9571 replicaPtr.p->maxGciCompleted[i],
9572 replicaPtr.p->maxGciStarted[i]);
9573 }
9574
9575 for (i = 0; i < 8; i++)
9576 {
9577 ndbout_c(" crashed replica: %d replicaLastGci: %d createGci: %d",
9578 i,
9579 replicaPtr.p->replicaLastGci[i],
9580 replicaPtr.p->createGci[i]);
9581 }
9582 }
9583 ndbout_c(" -- oldStoredReplicas");
9584 replicaPtr.i = fragPtr.p->oldStoredReplicas;
9585 for(; replicaPtr.i != RNIL; replicaPtr.i = replicaPtr.p->nextReplica)
9586 {
9587 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
9588 for(i = 0; i<MAX_LCP_STORED; i++)
9589 {
9590 ndbout_c(" i: %d %s : lcpId: %d maxGci Completed: %d Started: %d",
9591 i,
9592 (replicaPtr.p->lcpStatus[i] == ZVALID ?"VALID":"INVALID"),
9593 replicaPtr.p->lcpId[i],
9594 replicaPtr.p->maxGciCompleted[i],
9595 replicaPtr.p->maxGciStarted[i]);
9596 }
9597
9598 for (i = 0; i < 8; i++)
9599 {
9600 ndbout_c(" crashed replica: %d replicaLastGci: %d createGci: %d",
9601 i,
9602 replicaPtr.p->replicaLastGci[i],
9603 replicaPtr.p->createGci[i]);
9604 }
9605 }
9606 }
9607 }
9608 }
9609
startFragment(Signal * signal,Uint32 tableId,Uint32 fragId)9610 void Dbdih::startFragment(Signal* signal, Uint32 tableId, Uint32 fragId)
9611 {
9612 Uint32 TloopCount = 0;
9613 TabRecordPtr tabPtr;
9614 while (true) {
9615 if (TloopCount > 100) {
9616 jam();
9617 signal->theData[0] = DihContinueB::ZSTART_FRAGMENT;
9618 signal->theData[1] = tableId;
9619 signal->theData[2] = 0;
9620 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
9621 return;
9622 }
9623
9624 if (tableId >= ctabFileSize) {
9625 jam();
9626 signal->theData[0] = DihContinueB::ZCOMPLETE_RESTART;
9627 sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
9628 return;
9629 }//if
9630
9631 tabPtr.i = tableId;
9632 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
9633 if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE){
9634 jam();
9635 TloopCount++;
9636 tableId++;
9637 fragId = 0;
9638 continue;
9639 }
9640
9641 if(tabPtr.p->tabStorage != TabRecord::ST_NORMAL){
9642 jam();
9643 TloopCount++;
9644 tableId++;
9645 fragId = 0;
9646 continue;
9647 }
9648
9649 jam();
9650 break;
9651 }//while
9652
9653 FragmentstorePtr fragPtr;
9654 getFragstore(tabPtr.p, fragId, fragPtr);
9655 /* ----------------------------------------------------------------------- */
9656 /* WE NEED TO RESET THE REPLICA DATA STRUCTURES. THIS MEANS THAT WE */
9657 /* MUST REMOVE REPLICAS THAT WAS NOT STARTED AT THE GCI TO RESTORE. WE */
9658 /* NEED TO PUT ALL STORED REPLICAS ON THE LIST OF OLD STORED REPLICAS */
9659 /* RESET THE NUMBER OF REPLICAS TO CREATE. */
9660 /* ----------------------------------------------------------------------- */
9661 cnoOfCreateReplicas = 0;
9662 /* ----------------------------------------------------------------------- */
9663 /* WE WILL NEVER START MORE THAN FOUR FRAGMENT REPLICAS WHATEVER THE */
9664 /* DESIRED REPLICATION IS. */
9665 /* ----------------------------------------------------------------------- */
9666 ndbrequire(tabPtr.p->noOfBackups < 4);
9667 /* ----------------------------------------------------------------------- */
9668 /* SEARCH FOR STORED REPLICAS THAT CAN BE USED TO RESTART THE SYSTEM. */
9669 /* ----------------------------------------------------------------------- */
9670 searchStoredReplicas(fragPtr);
9671
9672 if (cnoOfCreateReplicas == 0) {
9673 /* --------------------------------------------------------------------- */
9674 /* THERE WERE NO STORED REPLICAS AVAILABLE THAT CAN SERVE AS REPLICA TO*/
9675 /* RESTART THE SYSTEM FROM. IN A LATER RELEASE WE WILL ADD */
9676 /* FUNCTIONALITY TO CHECK IF THERE ARE ANY STANDBY NODES THAT COULD DO */
9677 /* THIS TASK INSTEAD IN THIS IMPLEMENTATION WE SIMPLY CRASH THE SYSTEM.*/
9678 /* THIS WILL DECREASE THE GCI TO RESTORE WHICH HOPEFULLY WILL MAKE IT */
9679 /* POSSIBLE TO RESTORE THE SYSTEM. */
9680 /* --------------------------------------------------------------------- */
9681 char buf[64];
9682 BaseString::snprintf(buf, sizeof(buf), "table: %d fragment: %d gci: %d",
9683 tableId, fragId, SYSFILE->newestRestorableGCI);
9684
9685 ndbout_c(buf);
9686 dump_replica_info();
9687
9688 progError(__LINE__, NDBD_EXIT_NO_RESTORABLE_REPLICA, buf);
9689 ndbrequire(false);
9690 return;
9691 }//if
9692
9693 /* ----------------------------------------------------------------------- */
9694 /* WE HAVE CHANGED THE NODE TO BE PRIMARY REPLICA AND THE NODES TO BE */
9695 /* BACKUP NODES. WE MUST UPDATE THIS NODES DATA STRUCTURE SINCE WE */
9696 /* WILL NOT COPY THE TABLE DATA TO OURSELF. */
9697 /* ----------------------------------------------------------------------- */
9698 updateNodeInfo(fragPtr);
9699 /* ----------------------------------------------------------------------- */
9700 /* NOW WE HAVE COLLECTED ALL THE REPLICAS WE COULD GET. WE WILL NOW */
9701 /* RESTART THE FRAGMENT REPLICAS WE HAVE FOUND IRRESPECTIVE OF IF THERE*/
9702 /* ARE ENOUGH ACCORDING TO THE DESIRED REPLICATION. */
9703 /* ----------------------------------------------------------------------- */
9704 /* WE START BY SENDING ADD_FRAGREQ FOR THOSE REPLICAS THAT NEED IT. */
9705 /* ----------------------------------------------------------------------- */
9706 CreateReplicaRecordPtr createReplicaPtr;
9707 for (createReplicaPtr.i = 0;
9708 createReplicaPtr.i < cnoOfCreateReplicas;
9709 createReplicaPtr.i++) {
9710 jam();
9711 ptrCheckGuard(createReplicaPtr, 4, createReplicaRecord);
9712 createReplicaPtr.p->hotSpareUse = false;
9713 }//for
9714
9715 sendStartFragreq(signal, tabPtr, fragId);
9716
9717 /**
9718 * Don't wait for START_FRAGCONF
9719 */
9720 fragId++;
9721 if (fragId >= tabPtr.p->totalfragments) {
9722 jam();
9723 tabPtr.i++;
9724 fragId = 0;
9725 }//if
9726 signal->theData[0] = DihContinueB::ZSTART_FRAGMENT;
9727 signal->theData[1] = tabPtr.i;
9728 signal->theData[2] = fragId;
9729 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
9730
9731 return;
9732 }//Dbdih::startFragmentLab()
9733
9734
9735 /*****************************************************************************/
9736 /* ********** COMPLETE RESTART MODULE *************/
9737 /*****************************************************************************/
completeRestartLab(Signal * signal)9738 void Dbdih::completeRestartLab(Signal* signal)
9739 {
9740 sendLoopMacro(START_RECREQ, sendSTART_RECREQ);
9741 }//completeRestartLab()
9742
9743 /* ------------------------------------------------------------------------- */
9744 // SYSTEM RESTART:
9745 /* A NODE HAS COMPLETED RESTORING ALL DATABASE FRAGMENTS. */
9746 // NODE RESTART:
9747 // THE STARTING NODE HAS PREPARED ITS LOG FILES TO ENABLE EXECUTION
9748 // OF TRANSACTIONS.
9749 // Precondition:
9750 // This signal must be received by the master node.
9751 /* ------------------------------------------------------------------------- */
execSTART_RECCONF(Signal * signal)9752 void Dbdih::execSTART_RECCONF(Signal* signal)
9753 {
9754 jamEntry();
9755 Uint32 senderNodeId = signal->theData[0];
9756 ndbrequire(isMaster());
9757 if (getNodeState().startLevel >= NodeState::SL_STARTED){
9758 /* --------------------------------------------------------------------- */
9759 // Since our node is already up and running this must be a node restart.
9760 // This means that we should be the master node,
9761 // otherwise we have a problem.
9762 /* --------------------------------------------------------------------- */
9763 jam();
9764 ndbout_c("startNextCopyFragment");
9765 startNextCopyFragment(signal, findTakeOver(senderNodeId));
9766 return;
9767 } else {
9768 /* --------------------------------------------------------------------- */
9769 // This was the system restart case. We set the state indicating that the
9770 // node has completed restoration of all fragments.
9771 /* --------------------------------------------------------------------- */
9772 receiveLoopMacro(START_RECREQ, senderNodeId);
9773
9774 signal->theData[0] = reference();
9775 sendSignal(cntrlblockref, GSN_NDB_STARTCONF, signal, 1, JBB);
9776 return;
9777 }//if
9778 }//Dbdih::execSTART_RECCONF()
9779
copyNodeLab(Signal * signal,Uint32 tableId)9780 void Dbdih::copyNodeLab(Signal* signal, Uint32 tableId)
9781 {
9782 /* ----------------------------------------------------------------------- */
9783 // This code is executed by the master to assist a node restart in receiving
9784 // the data in the master.
9785 /* ----------------------------------------------------------------------- */
9786 Uint32 TloopCount = 0;
9787
9788 if (!c_nodeStartMaster.activeState) {
9789 jam();
9790 /* --------------------------------------------------------------------- */
9791 // Obviously the node crashed in the middle of its node restart. We will
9792 // stop this process simply by returning after resetting the wait indicator.
9793 /* ---------------------------------------------------------------------- */
9794 c_nodeStartMaster.wait = ZFALSE;
9795 return;
9796 }//if
9797 TabRecordPtr tabPtr;
9798 tabPtr.i = tableId;
9799 while (tabPtr.i < ctabFileSize) {
9800 ptrAss(tabPtr, tabRecord);
9801 if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
9802 /* -------------------------------------------------------------------- */
9803 // The table is defined. We will start by packing the table into pages.
9804 // The tabCopyStatus indicates to the CONTINUEB(ZPACK_TABLE_INTO_PAGES)
9805 // who called it. After packing the table into page(s) it will be sent to
9806 // the starting node by COPY_TABREQ signals. After returning from the
9807 // starting node we will return to this subroutine and continue
9808 // with the next table.
9809 /* -------------------------------------------------------------------- */
9810 ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
9811 tabPtr.p->tabCopyStatus = TabRecord::CS_COPY_NODE_STATE;
9812 signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
9813 signal->theData[1] = tabPtr.i;
9814 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9815 return;
9816 } else {
9817 jam();
9818 if (TloopCount > 100) {
9819 /* ------------------------------------------------------------------ */
9820 // Introduce real-time break after looping through 100 not copied tables
9821 /* ----------------------------------------------------------------- */
9822 jam();
9823 signal->theData[0] = DihContinueB::ZCOPY_NODE;
9824 signal->theData[1] = tabPtr.i + 1;
9825 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9826 return;
9827 } else {
9828 jam();
9829 TloopCount++;
9830 tabPtr.i++;
9831 }//if
9832 }//if
9833 }//while
9834 dihCopyCompletedLab(signal);
9835 return;
9836 }//Dbdih::copyNodeLab()
9837
tableCopyNodeLab(Signal * signal,TabRecordPtr tabPtr)9838 void Dbdih::tableCopyNodeLab(Signal* signal, TabRecordPtr tabPtr)
9839 {
9840 /* ----------------------------------------------------------------------- */
9841 /* COPY PAGES READ TO STARTING NODE. */
9842 /* ----------------------------------------------------------------------- */
9843 if (!c_nodeStartMaster.activeState) {
9844 jam();
9845 releaseTabPages(tabPtr.i);
9846 c_nodeStartMaster.wait = ZFALSE;
9847 return;
9848 }//if
9849 NodeRecordPtr copyNodePtr;
9850 PageRecordPtr pagePtr;
9851 copyNodePtr.i = c_nodeStartMaster.startNode;
9852 ptrCheckGuard(copyNodePtr, MAX_NDB_NODES, nodeRecord);
9853
9854 copyNodePtr.p->activeTabptr = tabPtr.i;
9855 pagePtr.i = tabPtr.p->pageRef[0];
9856 ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
9857
9858 signal->theData[0] = DihContinueB::ZCOPY_TABLE_NODE;
9859 signal->theData[1] = tabPtr.i;
9860 signal->theData[2] = copyNodePtr.i;
9861 signal->theData[3] = 0;
9862 signal->theData[4] = 0;
9863 signal->theData[5] = pagePtr.p->word[34];
9864 sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
9865 }//Dbdih::tableCopyNodeLab()
9866
9867 /* ------------------------------------------------------------------------- */
9868 // execCONTINUEB(ZCOPY_TABLE)
9869 // This routine is used to copy the table descriptions from the master to
9870 // other nodes. It is used in the system restart to copy from master to all
9871 // starting nodes.
9872 /* ------------------------------------------------------------------------- */
copyTableLab(Signal * signal,Uint32 tableId)9873 void Dbdih::copyTableLab(Signal* signal, Uint32 tableId)
9874 {
9875 TabRecordPtr tabPtr;
9876 tabPtr.i = tableId;
9877 ptrAss(tabPtr, tabRecord);
9878
9879 ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
9880 tabPtr.p->tabCopyStatus = TabRecord::CS_SR_PHASE2_READ_TABLE;
9881 signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
9882 signal->theData[1] = tabPtr.i;
9883 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9884 return;
9885 }//Dbdih::copyTableLab()
9886
9887 /* ------------------------------------------------------------------------- */
9888 // execCONTINUEB(ZSR_PHASE2_READ_TABLE)
9889 /* ------------------------------------------------------------------------- */
srPhase2ReadTableLab(Signal * signal,TabRecordPtr tabPtr)9890 void Dbdih::srPhase2ReadTableLab(Signal* signal, TabRecordPtr tabPtr)
9891 {
9892 /* ----------------------------------------------------------------------- */
9893 // We set the sendCOPY_TABREQState to ZACTIVE for all nodes since it is a long
9894 // process to send off all table descriptions. Thus we ensure that we do
9895 // not encounter race conditions where one node is completed before the
9896 // sending process is completed. This could lead to that we start off the
9897 // system before we actually finished all copying of table descriptions
9898 // and could lead to strange errors.
9899 /* ----------------------------------------------------------------------- */
9900
9901 //sendLoopMacro(COPY_TABREQ, nullRoutine);
9902
9903 breakCopyTableLab(signal, tabPtr, cfirstAliveNode);
9904 return;
9905 }//Dbdih::srPhase2ReadTableLab()
9906
9907 /* ------------------------------------------------------------------------- */
9908 /* COPY PAGES READ TO ALL NODES. */
9909 /* ------------------------------------------------------------------------- */
breakCopyTableLab(Signal * signal,TabRecordPtr tabPtr,Uint32 nodeId)9910 void Dbdih::breakCopyTableLab(Signal* signal, TabRecordPtr tabPtr, Uint32 nodeId)
9911 {
9912 NodeRecordPtr nodePtr;
9913 nodePtr.i = nodeId;
9914 while (nodePtr.i != RNIL) {
9915 jam();
9916 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
9917 if (nodePtr.i == getOwnNodeId()){
9918 jam();
9919 /* ------------------------------------------------------------------- */
9920 /* NOT NECESSARY TO COPY TO MY OWN NODE. I ALREADY HAVE THE PAGES. */
9921 /* I DO HOWEVER NEED TO STORE THE TABLE DESCRIPTION ONTO DISK. */
9922 /* ------------------------------------------------------------------- */
9923 /* IF WE ARE MASTER WE ONLY NEED TO SAVE THE TABLE ON DISK. WE ALREADY */
9924 /* HAVE THE TABLE DESCRIPTION IN THE DATA STRUCTURES. */
9925 // AFTER COMPLETING THE WRITE TO DISK THE MASTER WILL ALSO SEND
9926 // COPY_TABCONF AS ALL THE OTHER NODES.
9927 /* ------------------------------------------------------------------- */
9928 c_COPY_TABREQ_Counter.setWaitingFor(nodePtr.i);
9929 tabPtr.p->tabUpdateState = TabRecord::US_COPY_TAB_REQ;
9930 signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
9931 signal->theData[1] = tabPtr.i;
9932 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
9933 nodePtr.i = nodePtr.p->nextNode;
9934 } else {
9935 PageRecordPtr pagePtr;
9936 /* -------------------------------------------------------------------- */
9937 // RATHER THAN SENDING ALL COPY_TABREQ IN PARALLEL WE WILL SERIALISE THIS
9938 // ACTIVITY AND WILL THUS CALL breakCopyTableLab AGAIN WHEN COMPLETED THE
9939 // SENDING OF COPY_TABREQ'S.
9940 /* -------------------------------------------------------------------- */
9941 jam();
9942 tabPtr.p->tabCopyStatus = TabRecord::CS_SR_PHASE3_COPY_TABLE;
9943 pagePtr.i = tabPtr.p->pageRef[0];
9944 ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
9945 signal->theData[0] = DihContinueB::ZCOPY_TABLE_NODE;
9946 signal->theData[1] = tabPtr.i;
9947 signal->theData[2] = nodePtr.i;
9948 signal->theData[3] = 0;
9949 signal->theData[4] = 0;
9950 signal->theData[5] = pagePtr.p->word[34];
9951 sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
9952 return;
9953 }//if
9954 }//while
9955 /* ----------------------------------------------------------------------- */
9956 /* WE HAVE NOW SENT THE TABLE PAGES TO ALL NODES. EXIT AND WAIT FOR ALL */
9957 /* REPLIES. */
9958 /* ----------------------------------------------------------------------- */
9959 return;
9960 }//Dbdih::breakCopyTableLab()
9961
9962 /* ------------------------------------------------------------------------- */
9963 // execCONTINUEB(ZCOPY_TABLE_NODE)
9964 /* ------------------------------------------------------------------------- */
copyTableNode(Signal * signal,CopyTableNode * ctn,NodeRecordPtr nodePtr)9965 void Dbdih::copyTableNode(Signal* signal,
9966 CopyTableNode* ctn, NodeRecordPtr nodePtr)
9967 {
9968 if (getNodeState().startLevel >= NodeState::SL_STARTED){
9969 /* --------------------------------------------------------------------- */
9970 // We are in the process of performing a node restart and are copying a
9971 // table description to a starting node. We will check that no nodes have
9972 // crashed in this process.
9973 /* --------------------------------------------------------------------- */
9974 if (!c_nodeStartMaster.activeState) {
9975 jam();
9976 /** ------------------------------------------------------------------
9977 * The starting node crashed. We will release table pages and stop this
9978 * copy process and allow new node restarts to start.
9979 * ------------------------------------------------------------------ */
9980 releaseTabPages(ctn->ctnTabPtr.i);
9981 c_nodeStartMaster.wait = ZFALSE;
9982 return;
9983 }//if
9984 }//if
9985 ndbrequire(ctn->pageIndex < 8);
9986 ctn->ctnPageptr.i = ctn->ctnTabPtr.p->pageRef[ctn->pageIndex];
9987 ptrCheckGuard(ctn->ctnPageptr, cpageFileSize, pageRecord);
9988 /**
9989 * If first page & firstWord reqinfo = 1 (first signal)
9990 */
9991 Uint32 reqinfo = (ctn->pageIndex == 0) && (ctn->wordIndex == 0);
9992 if(reqinfo == 1){
9993 c_COPY_TABREQ_Counter.setWaitingFor(nodePtr.i);
9994 }
9995
9996 for (Uint32 i = 0; i < 16; i++) {
9997 jam();
9998 sendCopyTable(signal, ctn, calcDihBlockRef(nodePtr.i), reqinfo);
9999 reqinfo = 0;
10000 if (ctn->noOfWords <= 16) {
10001 jam();
10002 switch (ctn->ctnTabPtr.p->tabCopyStatus) {
10003 case TabRecord::CS_SR_PHASE3_COPY_TABLE:
10004 /* ------------------------------------------------------------------ */
10005 // We have copied the table description to this node.
10006 // We will now proceed
10007 // with sending the table description to the next node in the node list.
10008 /* ------------------------------------------------------------------ */
10009 jam();
10010 ctn->ctnTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
10011 breakCopyTableLab(signal, ctn->ctnTabPtr, nodePtr.p->nextNode);
10012 return;
10013 break;
10014 case TabRecord::CS_COPY_NODE_STATE:
10015 jam();
10016 ctn->ctnTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
10017 return;
10018 break;
10019 default:
10020 ndbrequire(false);
10021 break;
10022 }//switch
10023 } else {
10024 jam();
10025 ctn->wordIndex += 16;
10026 if (ctn->wordIndex == 2048) {
10027 jam();
10028 ctn->wordIndex = 0;
10029 ctn->pageIndex++;
10030 ndbrequire(ctn->pageIndex < 8);
10031 ctn->ctnPageptr.i = ctn->ctnTabPtr.p->pageRef[ctn->pageIndex];
10032 ptrCheckGuard(ctn->ctnPageptr, cpageFileSize, pageRecord);
10033 }//if
10034 ctn->noOfWords -= 16;
10035 }//if
10036 }//for
10037 signal->theData[0] = DihContinueB::ZCOPY_TABLE_NODE;
10038 signal->theData[1] = ctn->ctnTabPtr.i;
10039 signal->theData[2] = nodePtr.i;
10040 signal->theData[3] = ctn->pageIndex;
10041 signal->theData[4] = ctn->wordIndex;
10042 signal->theData[5] = ctn->noOfWords;
10043 sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
10044 }//Dbdih::copyTableNodeLab()
10045
sendCopyTable(Signal * signal,CopyTableNode * ctn,BlockReference ref,Uint32 reqinfo)10046 void Dbdih::sendCopyTable(Signal* signal, CopyTableNode* ctn,
10047 BlockReference ref, Uint32 reqinfo)
10048 {
10049 signal->theData[0] = reference();
10050 signal->theData[1] = reqinfo;
10051 signal->theData[2] = ctn->ctnTabPtr.i;
10052 signal->theData[3] = ctn->ctnTabPtr.p->schemaVersion;
10053 signal->theData[4] = ctn->noOfWords;
10054 ndbrequire(ctn->wordIndex + 15 < 2048);
10055 MEMCOPY_NO_WORDS(&signal->theData[5], &ctn->ctnPageptr.p->word[ctn->wordIndex], 16);
10056 sendSignal(ref, GSN_COPY_TABREQ, signal, 21, JBB);
10057 }//Dbdih::sendCopyTable()
10058
execCOPY_TABCONF(Signal * signal)10059 void Dbdih::execCOPY_TABCONF(Signal* signal)
10060 {
10061 NodeRecordPtr nodePtr;
10062 jamEntry();
10063 nodePtr.i = signal->theData[0];
10064 Uint32 tableId = signal->theData[1];
10065 if (getNodeState().startLevel >= NodeState::SL_STARTED){
10066 /* --------------------------------------------------------------------- */
10067 // We are in the process of performing a node restart. Continue by copying
10068 // the next table to the starting node.
10069 /* --------------------------------------------------------------------- */
10070 jam();
10071 NodeRecordPtr nodePtr;
10072 nodePtr.i = signal->theData[0];
10073 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
10074 c_COPY_TABREQ_Counter.clearWaitingFor(nodePtr.i);
10075
10076 releaseTabPages(tableId);
10077 signal->theData[0] = DihContinueB::ZCOPY_NODE;
10078 signal->theData[1] = tableId + 1;
10079 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
10080 return;
10081 } else {
10082 /* --------------------------------------------------------------------- */
10083 // We are in the process of performing a system restart. Check if all nodes
10084 // have saved the new table description to file and then continue with the
10085 // next table.
10086 /* --------------------------------------------------------------------- */
10087 receiveLoopMacro(COPY_TABREQ, nodePtr.i);
10088 /* --------------------------------------------------------------------- */
10089 /* WE HAVE NOW COPIED TO ALL NODES. WE HAVE NOW COMPLETED RESTORING */
10090 /* THIS TABLE. CONTINUE WITH THE NEXT TABLE. */
10091 /* WE NEED TO RELEASE THE PAGES IN THE TABLE IN THIS NODE HERE. */
10092 /* WE ALSO NEED TO CLOSE THE TABLE FILE. */
10093 /* --------------------------------------------------------------------- */
10094 releaseTabPages(tableId);
10095
10096 TabRecordPtr tabPtr;
10097 tabPtr.i = tableId;
10098 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
10099
10100 ConnectRecordPtr connectPtr;
10101 connectPtr.i = tabPtr.p->connectrec;
10102 ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
10103
10104 sendAddFragreq(signal, connectPtr, tabPtr, 0);
10105 return;
10106 }//if
10107 }//Dbdih::execCOPY_TABCONF()
10108
10109 /*
10110 3.13 L O C A L C H E C K P O I N T (M A S T E R)
10111 ****************************************************
10112 */
10113 /*****************************************************************************/
10114 /* ********** LOCAL-CHECK-POINT-HANDLING MODULE *************/
10115 /*****************************************************************************/
10116 /* ------------------------------------------------------------------------- */
10117 /* IT IS TIME TO CHECK IF IT IS TIME TO START A LOCAL CHECKPOINT. */
10118 /* WE WILL EITHER START AFTER 1 MILLION WORDS HAVE ARRIVED OR WE WILL */
10119 /* EXECUTE AFTER ABOUT 16 MINUTES HAVE PASSED BY. */
10120 /* ------------------------------------------------------------------------- */
checkTcCounterLab(Signal * signal)10121 void Dbdih::checkTcCounterLab(Signal* signal)
10122 {
10123 CRASH_INSERTION(7009);
10124 if (c_lcpState.lcpStatus != LCP_STATUS_IDLE) {
10125 g_eventLogger.error("lcpStatus = %u"
10126 "lcpStatusUpdatedPlace = %d",
10127 (Uint32) c_lcpState.lcpStatus,
10128 c_lcpState.lcpStatusUpdatedPlace);
10129 ndbrequire(false);
10130 return;
10131 }//if
10132 c_lcpState.ctimer += 32;
10133 if ((c_nodeStartMaster.blockLcp == true) ||
10134 (c_lcpState.lcpStopGcp >= c_newest_restorable_gci)) {
10135 jam();
10136 /* --------------------------------------------------------------------- */
10137 // No reason to start juggling the states and checking for start of LCP if
10138 // we are blocked to start an LCP anyway.
10139 // We also block LCP start if we have not completed one global checkpoints
10140 // before starting another local checkpoint.
10141 /* --------------------------------------------------------------------- */
10142 signal->theData[0] = DihContinueB::ZCHECK_TC_COUNTER;
10143 signal->theData[1] = __LINE__;
10144 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1 * 100, 2);
10145 return;
10146 }//if
10147 c_lcpState.setLcpStatus(LCP_TCGET, __LINE__);
10148
10149 c_lcpState.ctcCounter = c_lcpState.ctimer;
10150 sendLoopMacro(TCGETOPSIZEREQ, sendTCGETOPSIZEREQ);
10151 }//Dbdih::checkTcCounterLab()
10152
checkLcpStart(Signal * signal,Uint32 lineNo)10153 void Dbdih::checkLcpStart(Signal* signal, Uint32 lineNo)
10154 {
10155 /* ----------------------------------------------------------------------- */
10156 // Verify that we are not attempting to start another instance of the LCP
10157 // when it is not alright to do so.
10158 /* ----------------------------------------------------------------------- */
10159 ndbrequire(c_lcpState.lcpStart == ZIDLE);
10160 c_lcpState.lcpStart = ZACTIVE;
10161 signal->theData[0] = DihContinueB::ZCHECK_TC_COUNTER;
10162 signal->theData[1] = lineNo;
10163 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 2);
10164 }//Dbdih::checkLcpStart()
10165
10166 /* ------------------------------------------------------------------------- */
10167 /*TCGETOPSIZECONF HOW MUCH OPERATION SIZE HAVE BEEN EXECUTED BY TC */
10168 /* ------------------------------------------------------------------------- */
execTCGETOPSIZECONF(Signal * signal)10169 void Dbdih::execTCGETOPSIZECONF(Signal* signal)
10170 {
10171 jamEntry();
10172 Uint32 senderNodeId = signal->theData[0];
10173 c_lcpState.ctcCounter += signal->theData[1];
10174
10175 receiveLoopMacro(TCGETOPSIZEREQ, senderNodeId);
10176
10177 ndbrequire(c_lcpState.lcpStatus == LCP_TCGET);
10178 ndbrequire(c_lcpState.lcpStart == ZACTIVE);
10179 /* ----------------------------------------------------------------------- */
10180 // We are not actively starting another LCP, still we receive this signal.
10181 // This is not ok.
10182 /* ---------------------------------------------------------------------- */
10183 /* ALL TC'S HAVE RESPONDED NOW. NOW WE WILL CHECK IF ENOUGH OPERATIONS */
10184 /* HAVE EXECUTED TO ENABLE US TO START A NEW LOCAL CHECKPOINT. */
10185 /* WHILE COPYING DICTIONARY AND DISTRIBUTION INFO TO A STARTING NODE */
10186 /* WE WILL ALSO NOT ALLOW THE LOCAL CHECKPOINT TO PROCEED. */
10187 /*----------------------------------------------------------------------- */
10188 if (c_lcpState.immediateLcpStart == false) {
10189 if ((c_lcpState.ctcCounter <
10190 ((Uint32)1 << c_lcpState.clcpDelay)) ||
10191 (c_nodeStartMaster.blockLcp == true)) {
10192 jam();
10193 c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
10194
10195 signal->theData[0] = DihContinueB::ZCHECK_TC_COUNTER;
10196 signal->theData[1] = __LINE__;
10197 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1 * 100, 2);
10198 return;
10199 }//if
10200 }//if
10201 c_lcpState.lcpStart = ZIDLE;
10202 c_lcpState.immediateLcpStart = false;
10203 /* -----------------------------------------------------------------------
10204 * Now the initial lcp is started,
10205 * we can reset the delay to its orginal value
10206 * --------------------------------------------------------------------- */
10207 CRASH_INSERTION(7010);
10208 /* ----------------------------------------------------------------------- */
10209 /* IF MORE THAN 1 MILLION WORDS PASSED THROUGH THE TC'S THEN WE WILL */
10210 /* START A NEW LOCAL CHECKPOINT. CLEAR CTIMER. START CHECKPOINT */
10211 /* ACTIVITY BY CALCULATING THE KEEP GLOBAL CHECKPOINT. */
10212 // Also remember the current global checkpoint to ensure that we run at least
10213 // one global checkpoints between each local checkpoint that we start up.
10214 /* ----------------------------------------------------------------------- */
10215 c_lcpState.ctimer = 0;
10216 c_lcpState.keepGci = coldgcp;
10217 /* ----------------------------------------------------------------------- */
10218 /* UPDATE THE NEW LATEST LOCAL CHECKPOINT ID. */
10219 /* ----------------------------------------------------------------------- */
10220 cnoOfActiveTables = 0;
10221 c_lcpState.setLcpStatus(LCP_CALCULATE_KEEP_GCI, __LINE__);
10222 c_lcpState.oldestRestorableGci = SYSFILE->oldestRestorableGCI;
10223 ndbrequire(((int)c_lcpState.oldestRestorableGci) > 0);
10224
10225 if (ERROR_INSERTED(7011)) {
10226 signal->theData[0] = NDB_LE_LCPStoppedInCalcKeepGci;
10227 signal->theData[1] = 0;
10228 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
10229 return;
10230 }//if
10231 signal->theData[0] = DihContinueB::ZCALCULATE_KEEP_GCI;
10232 signal->theData[1] = 0; /* TABLE ID = 0 */
10233 signal->theData[2] = 0; /* FRAGMENT ID = 0 */
10234 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
10235 return;
10236 }//Dbdih::execTCGETOPSIZECONF()
10237
10238 /* ------------------------------------------------------------------------- */
10239 /* WE NEED TO CALCULATE THE OLDEST GLOBAL CHECKPOINT THAT WILL BE */
10240 /* COMPLETELY RESTORABLE AFTER EXECUTING THIS LOCAL CHECKPOINT. */
10241 /* ------------------------------------------------------------------------- */
calculateKeepGciLab(Signal * signal,Uint32 tableId,Uint32 fragId)10242 void Dbdih::calculateKeepGciLab(Signal* signal, Uint32 tableId, Uint32 fragId)
10243 {
10244 TabRecordPtr tabPtr;
10245 Uint32 TloopCount = 1;
10246 tabPtr.i = tableId;
10247 do {
10248 if (tabPtr.i >= ctabFileSize) {
10249 if (cnoOfActiveTables > 0) {
10250 jam();
10251 signal->theData[0] = DihContinueB::ZSTORE_NEW_LCP_ID;
10252 sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
10253 return;
10254 } else {
10255 jam();
10256 /* ------------------------------------------------------------------ */
10257 /* THERE ARE NO TABLES TO CHECKPOINT. WE STOP THE CHECKPOINT ALREADY */
10258 /* HERE TO AVOID STRANGE PROBLEMS LATER. */
10259 /* ------------------------------------------------------------------ */
10260 c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
10261 checkLcpStart(signal, __LINE__);
10262 return;
10263 }//if
10264 }//if
10265 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
10266 if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE ||
10267 tabPtr.p->tabStorage != TabRecord::ST_NORMAL) {
10268 if (TloopCount > 100) {
10269 jam();
10270 signal->theData[0] = DihContinueB::ZCALCULATE_KEEP_GCI;
10271 signal->theData[1] = tabPtr.i + 1;
10272 signal->theData[2] = 0;
10273 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
10274 return;
10275 } else {
10276 jam();
10277 TloopCount++;
10278 tabPtr.i++;
10279 }//if
10280 } else {
10281 jam();
10282 TloopCount = 0;
10283 }//if
10284 } while (TloopCount != 0);
10285 cnoOfActiveTables++;
10286 FragmentstorePtr fragPtr;
10287 getFragstore(tabPtr.p, fragId, fragPtr);
10288 checkKeepGci(tabPtr, fragId, fragPtr.p, fragPtr.p->storedReplicas);
10289 checkKeepGci(tabPtr, fragId, fragPtr.p, fragPtr.p->oldStoredReplicas);
10290 fragId++;
10291 if (fragId >= tabPtr.p->totalfragments) {
10292 jam();
10293 tabPtr.i++;
10294 fragId = 0;
10295 }//if
10296 signal->theData[0] = DihContinueB::ZCALCULATE_KEEP_GCI;
10297 signal->theData[1] = tabPtr.i;
10298 signal->theData[2] = fragId;
10299 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
10300 return;
10301 }//Dbdih::calculateKeepGciLab()
10302
10303 /* ------------------------------------------------------------------------- */
10304 /* WE NEED TO STORE ON DISK THE FACT THAT WE ARE STARTING THIS LOCAL */
10305 /* CHECKPOINT ROUND. THIS WILL INVALIDATE ALL THE LOCAL CHECKPOINTS */
10306 /* THAT WILL EVENTUALLY BE OVERWRITTEN AS PART OF THIS LOCAL CHECKPOINT*/
10307 /* ------------------------------------------------------------------------- */
storeNewLcpIdLab(Signal * signal)10308 void Dbdih::storeNewLcpIdLab(Signal* signal)
10309 {
10310 /***************************************************************************/
10311 // Report the event that a local checkpoint has started.
10312 /***************************************************************************/
10313 signal->theData[0] = NDB_LE_LocalCheckpointStarted; //Event type
10314 signal->theData[1] = SYSFILE->latestLCP_ID + 1;
10315 signal->theData[2] = c_lcpState.keepGci;
10316 signal->theData[3] = c_lcpState.oldestRestorableGci;
10317 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
10318
10319 signal->setTrace(TestOrd::TraceLocalCheckpoint);
10320
10321 CRASH_INSERTION(7013);
10322 SYSFILE->keepGCI = c_lcpState.keepGci;
10323 //Uint32 lcpId = SYSFILE->latestLCP_ID;
10324 SYSFILE->latestLCP_ID++;
10325 SYSFILE->oldestRestorableGCI = c_lcpState.oldestRestorableGci;
10326
10327 const Uint32 oldestRestorableGCI = SYSFILE->oldestRestorableGCI;
10328 //const Uint32 newestRestorableGCI = SYSFILE->newestRestorableGCI;
10329 //ndbrequire(newestRestorableGCI >= oldestRestorableGCI);
10330
10331 Int32 val = oldestRestorableGCI;
10332 ndbrequire(val > 0);
10333
10334 /* ----------------------------------------------------------------------- */
10335 /* SET BIT INDICATING THAT LOCAL CHECKPOINT IS ONGOING. THIS IS CLEARED */
10336 /* AT THE END OF A LOCAL CHECKPOINT. */
10337 /* ----------------------------------------------------------------------- */
10338 SYSFILE->setLCPOngoing(SYSFILE->systemRestartBits);
10339 /* ---------------------------------------------------------------------- */
10340 /* CHECK IF ANY NODE MUST BE TAKEN OUT OF SERVICE AND REFILLED WITH */
10341 /* NEW FRESH DATA FROM AN ACTIVE NODE. */
10342 /* ---------------------------------------------------------------------- */
10343 setLcpActiveStatusStart(signal);
10344 c_lcpState.setLcpStatus(LCP_COPY_GCI, __LINE__);
10345 //#ifdef VM_TRACE
10346 // infoEvent("LocalCheckpoint %d started", SYSFILE->latestLCP_ID);
10347 // signal->theData[0] = 7012;
10348 // execDUMP_STATE_ORD(signal);
10349 //#endif
10350
10351 copyGciLab(signal, CopyGCIReq::LOCAL_CHECKPOINT);
10352 }//Dbdih::storeNewLcpIdLab()
10353
startLcpRoundLab(Signal * signal)10354 void Dbdih::startLcpRoundLab(Signal* signal) {
10355 jam();
10356
10357 Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
10358 Callback c = { safe_cast(&Dbdih::startLcpMutex_locked), 0 };
10359 ndbrequire(mutex.lock(c));
10360 }
10361
10362 void
startLcpMutex_locked(Signal * signal,Uint32 senderData,Uint32 retVal)10363 Dbdih::startLcpMutex_locked(Signal* signal, Uint32 senderData, Uint32 retVal){
10364 jamEntry();
10365 ndbrequire(retVal == 0);
10366
10367 StartLcpReq* req = (StartLcpReq*)signal->getDataPtrSend();
10368 req->senderRef = reference();
10369 req->lcpId = SYSFILE->latestLCP_ID;
10370 req->participatingLQH = c_lcpState.m_participatingLQH;
10371 req->participatingDIH = c_lcpState.m_participatingDIH;
10372 sendLoopMacro(START_LCP_REQ, sendSTART_LCP_REQ);
10373 }
10374 void
sendSTART_LCP_REQ(Signal * signal,Uint32 nodeId)10375 Dbdih::sendSTART_LCP_REQ(Signal* signal, Uint32 nodeId){
10376 BlockReference ref = calcDihBlockRef(nodeId);
10377 sendSignal(ref, GSN_START_LCP_REQ, signal, StartLcpReq::SignalLength, JBB);
10378 }
10379
10380 void
execSTART_LCP_CONF(Signal * signal)10381 Dbdih::execSTART_LCP_CONF(Signal* signal){
10382 StartLcpConf * conf = (StartLcpConf*)signal->getDataPtr();
10383
10384 Uint32 nodeId = refToNode(conf->senderRef);
10385 receiveLoopMacro(START_LCP_REQ, nodeId);
10386
10387 Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
10388 Callback c = { safe_cast(&Dbdih::startLcpMutex_unlocked), 0 };
10389 mutex.unlock(c);
10390 }
10391
10392 void
startLcpMutex_unlocked(Signal * signal,Uint32 data,Uint32 retVal)10393 Dbdih::startLcpMutex_unlocked(Signal* signal, Uint32 data, Uint32 retVal){
10394 jamEntry();
10395 ndbrequire(retVal == 0);
10396
10397 Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
10398 mutex.release();
10399
10400 CRASH_INSERTION(7014);
10401 c_lcpState.setLcpStatus(LCP_TC_CLOPSIZE, __LINE__);
10402 sendLoopMacro(TC_CLOPSIZEREQ, sendTC_CLOPSIZEREQ);
10403 }
10404
execTC_CLOPSIZECONF(Signal * signal)10405 void Dbdih::execTC_CLOPSIZECONF(Signal* signal) {
10406 jamEntry();
10407 Uint32 senderNodeId = signal->theData[0];
10408 receiveLoopMacro(TC_CLOPSIZEREQ, senderNodeId);
10409
10410 ndbrequire(c_lcpState.lcpStatus == LCP_TC_CLOPSIZE);
10411 /* ----------------------------------------------------------------------- */
10412 /* ALL TC'S HAVE CLEARED THEIR OPERATION SIZE COUNTERS. NOW PROCEED BY */
10413 /* STARTING THE LOCAL CHECKPOINT IN EACH LQH. */
10414 /* ----------------------------------------------------------------------- */
10415 c_lcpState.m_LAST_LCP_FRAG_ORD = c_lcpState.m_participatingLQH;
10416
10417 CRASH_INSERTION(7015);
10418 c_lcpState.setLcpStatus(LCP_START_LCP_ROUND, __LINE__);
10419 startLcpRoundLoopLab(signal, 0, 0);
10420 }//Dbdih::execTC_CLOPSIZECONF()
10421
startLcpRoundLoopLab(Signal * signal,Uint32 startTableId,Uint32 startFragId)10422 void Dbdih::startLcpRoundLoopLab(Signal* signal,
10423 Uint32 startTableId, Uint32 startFragId)
10424 {
10425 NodeRecordPtr nodePtr;
10426 for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
10427 ptrAss(nodePtr, nodeRecord);
10428 if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
10429 ndbrequire(nodePtr.p->noOfStartedChkpt == 0);
10430 ndbrequire(nodePtr.p->noOfQueuedChkpt == 0);
10431 }//if
10432 }//if
10433 c_lcpState.currentFragment.tableId = startTableId;
10434 c_lcpState.currentFragment.fragmentId = startFragId;
10435 startNextChkpt(signal);
10436 }//Dbdih::startLcpRoundLoopLab()
10437
startNextChkpt(Signal * signal)10438 void Dbdih::startNextChkpt(Signal* signal)
10439 {
10440 Uint32 lcpId = SYSFILE->latestLCP_ID;
10441
10442 NdbNodeBitmask busyNodes;
10443 busyNodes.clear();
10444 const Uint32 lcpNodes = c_lcpState.m_participatingLQH.count();
10445
10446 bool save = true;
10447 LcpState::CurrentFragment curr = c_lcpState.currentFragment;
10448
10449 while (curr.tableId < ctabFileSize) {
10450 TabRecordPtr tabPtr;
10451 tabPtr.i = curr.tableId;
10452 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
10453 if ((tabPtr.p->tabStatus != TabRecord::TS_ACTIVE) ||
10454 (tabPtr.p->tabLcpStatus != TabRecord::TLS_ACTIVE)) {
10455 curr.tableId++;
10456 curr.fragmentId = 0;
10457 continue;
10458 }//if
10459
10460 FragmentstorePtr fragPtr;
10461 getFragstore(tabPtr.p, curr.fragmentId, fragPtr);
10462
10463 ReplicaRecordPtr replicaPtr;
10464 for(replicaPtr.i = fragPtr.p->storedReplicas;
10465 replicaPtr.i != RNIL ;
10466 replicaPtr.i = replicaPtr.p->nextReplica){
10467
10468 jam();
10469 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
10470
10471 NodeRecordPtr nodePtr;
10472 nodePtr.i = replicaPtr.p->procNode;
10473 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
10474
10475 if (c_lcpState.m_participatingLQH.get(nodePtr.i))
10476 {
10477 if (replicaPtr.p->lcpOngoingFlag &&
10478 replicaPtr.p->lcpIdStarted < lcpId)
10479 {
10480 jam();
10481 //-------------------------------------------------------------------
10482 // We have found a replica on a node that performs local checkpoint
10483 // that is alive and that have not yet been started.
10484 //-------------------------------------------------------------------
10485
10486 if (nodePtr.p->noOfStartedChkpt < 2)
10487 {
10488 jam();
10489 /**
10490 * Send LCP_FRAG_ORD to LQH
10491 */
10492
10493 /**
10494 * Mark the replica so with lcpIdStarted == true
10495 */
10496 replicaPtr.p->lcpIdStarted = lcpId;
10497
10498 Uint32 i = nodePtr.p->noOfStartedChkpt;
10499 nodePtr.p->startedChkpt[i].tableId = tabPtr.i;
10500 nodePtr.p->startedChkpt[i].fragId = curr.fragmentId;
10501 nodePtr.p->startedChkpt[i].replicaPtr = replicaPtr.i;
10502 nodePtr.p->noOfStartedChkpt = i + 1;
10503
10504 sendLCP_FRAG_ORD(signal, nodePtr.p->startedChkpt[i]);
10505 }
10506 else if (nodePtr.p->noOfQueuedChkpt < 2)
10507 {
10508 jam();
10509 /**
10510 * Put LCP_FRAG_ORD "in queue"
10511 */
10512
10513 /**
10514 * Mark the replica so with lcpIdStarted == true
10515 */
10516 replicaPtr.p->lcpIdStarted = lcpId;
10517
10518 Uint32 i = nodePtr.p->noOfQueuedChkpt;
10519 nodePtr.p->queuedChkpt[i].tableId = tabPtr.i;
10520 nodePtr.p->queuedChkpt[i].fragId = curr.fragmentId;
10521 nodePtr.p->queuedChkpt[i].replicaPtr = replicaPtr.i;
10522 nodePtr.p->noOfQueuedChkpt = i + 1;
10523 }
10524 else
10525 {
10526 jam();
10527
10528 if(save)
10529 {
10530 /**
10531 * Stop increasing value on first that was "full"
10532 */
10533 c_lcpState.currentFragment = curr;
10534 save = false;
10535 }
10536
10537 busyNodes.set(nodePtr.i);
10538 if(busyNodes.count() == lcpNodes)
10539 {
10540 /**
10541 * There were no possibility to start the local checkpoint
10542 * and it was not possible to queue it up. In this case we
10543 * stop the start of local checkpoints until the nodes with a
10544 * backlog have performed more checkpoints. We will return and
10545 * will not continue the process of starting any more checkpoints.
10546 */
10547 return;
10548 }//if
10549 }//if
10550 }
10551 }//while
10552 }
10553 curr.fragmentId++;
10554 if (curr.fragmentId >= tabPtr.p->totalfragments) {
10555 jam();
10556 curr.fragmentId = 0;
10557 curr.tableId++;
10558 }//if
10559 }//while
10560
10561 sendLastLCP_FRAG_ORD(signal);
10562 }//Dbdih::startNextChkpt()
10563
sendLastLCP_FRAG_ORD(Signal * signal)10564 void Dbdih::sendLastLCP_FRAG_ORD(Signal* signal)
10565 {
10566 LcpFragOrd * const lcpFragOrd = (LcpFragOrd *)&signal->theData[0];
10567 lcpFragOrd->tableId = RNIL;
10568 lcpFragOrd->fragmentId = 0;
10569 lcpFragOrd->lcpId = SYSFILE->latestLCP_ID;
10570 lcpFragOrd->lcpNo = 0;
10571 lcpFragOrd->keepGci = c_lcpState.keepGci;
10572 lcpFragOrd->lastFragmentFlag = true;
10573
10574 NodeRecordPtr nodePtr;
10575 for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
10576 jam();
10577 ptrAss(nodePtr, nodeRecord);
10578
10579 if(nodePtr.p->noOfQueuedChkpt == 0 &&
10580 nodePtr.p->noOfStartedChkpt == 0 &&
10581 c_lcpState.m_LAST_LCP_FRAG_ORD.isWaitingFor(nodePtr.i)){
10582 jam();
10583
10584 CRASH_INSERTION(7028);
10585
10586 /**
10587 * Nothing queued or started <=> Complete on that node
10588 *
10589 */
10590 c_lcpState.m_LAST_LCP_FRAG_ORD.clearWaitingFor(nodePtr.i);
10591 if(ERROR_INSERTED(7075)){
10592 continue;
10593 }
10594
10595 CRASH_INSERTION(7193);
10596 BlockReference ref = calcLqhBlockRef(nodePtr.i);
10597 sendSignal(ref, GSN_LCP_FRAG_ORD, signal,LcpFragOrd::SignalLength, JBB);
10598 }
10599 }
10600 if(ERROR_INSERTED(7075)){
10601 if(c_lcpState.m_LAST_LCP_FRAG_ORD.done())
10602 CRASH_INSERTION(7075);
10603 }
10604 }//Dbdih::sendLastLCP_FRAGORD()
10605
10606 /* ------------------------------------------------------------------------- */
10607 /* A FRAGMENT REPLICA HAS COMPLETED EXECUTING ITS LOCAL CHECKPOINT. */
10608 /* CHECK IF ALL REPLICAS IN THE TABLE HAVE COMPLETED. IF SO STORE THE */
10609 /* THE TABLE DISTRIBUTION ON DISK. ALSO SEND LCP_REPORT TO ALL OTHER */
10610 /* NODES SO THAT THEY CAN STORE THE TABLE ONTO DISK AS WELL. */
10611 /* ------------------------------------------------------------------------- */
execLCP_FRAG_REP(Signal * signal)10612 void Dbdih::execLCP_FRAG_REP(Signal* signal)
10613 {
10614 jamEntry();
10615 ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
10616
10617 #if 0
10618 printLCP_FRAG_REP(stdout,
10619 signal->getDataPtr(),
10620 signal->length(), number());
10621 #endif
10622
10623 LcpFragRep * const lcpReport = (LcpFragRep *)&signal->theData[0];
10624 Uint32 nodeId = lcpReport->nodeId;
10625 Uint32 tableId = lcpReport->tableId;
10626 Uint32 fragId = lcpReport->fragId;
10627
10628 jamEntry();
10629
10630 if (ERROR_INSERTED(7178) && nodeId != getOwnNodeId())
10631 {
10632 jam();
10633 Uint32 owng =Sysfile::getNodeGroup(getOwnNodeId(), SYSFILE->nodeGroups);
10634 Uint32 nodeg = Sysfile::getNodeGroup(nodeId, SYSFILE->nodeGroups);
10635 if (owng == nodeg)
10636 {
10637 jam();
10638 ndbout_c("throwing away LCP_FRAG_REP from (and killing) %d", nodeId);
10639 SET_ERROR_INSERT_VALUE(7179);
10640 signal->theData[0] = 9999;
10641 sendSignal(numberToRef(CMVMI, nodeId),
10642 GSN_NDB_TAMPER, signal, 1, JBA);
10643 return;
10644 }
10645 }
10646
10647 if (ERROR_INSERTED(7179) && nodeId != getOwnNodeId())
10648 {
10649 jam();
10650 Uint32 owng =Sysfile::getNodeGroup(getOwnNodeId(), SYSFILE->nodeGroups);
10651 Uint32 nodeg = Sysfile::getNodeGroup(nodeId, SYSFILE->nodeGroups);
10652 if (owng == nodeg)
10653 {
10654 jam();
10655 ndbout_c("throwing away LCP_FRAG_REP from %d", nodeId);
10656 return;
10657 }
10658 }
10659
10660 CRASH_INSERTION2(7025, isMaster());
10661 CRASH_INSERTION2(7016, !isMaster());
10662
10663 bool fromTimeQueue = (signal->senderBlockRef() == reference());
10664
10665 TabRecordPtr tabPtr;
10666 tabPtr.i = tableId;
10667 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
10668 if(tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
10669 jam();
10670 /*-----------------------------------------------------------------------*/
10671 // If the table is currently copied to disk we also
10672 // stop already here to avoid strange half-way updates
10673 // of the table data structures.
10674 /*-----------------------------------------------------------------------*/
10675 /*
10676 We need to send this signal without a delay since we have discovered
10677 that we have run out of space in the short time queue. This problem
10678 is very erunlikely to happen but it has and it results in a node crash.
10679 This should be considered a "quick fix" and not a permanent solution.
10680 A cleaner/better way would be to check the time queue if it is full or
10681 not before sending this signal.
10682 */
10683 sendSignal(reference(), GSN_LCP_FRAG_REP, signal, signal->length(), JBB);
10684 /* Kept here for reference
10685 sendSignalWithDelay(reference(), GSN_LCP_FRAG_REP,
10686 signal, 20, signal->length());
10687 */
10688
10689 if(!fromTimeQueue){
10690 c_lcpState.noOfLcpFragRepOutstanding++;
10691 }
10692
10693 return;
10694 }//if
10695
10696 if(fromTimeQueue){
10697 jam();
10698
10699 ndbrequire(c_lcpState.noOfLcpFragRepOutstanding > 0);
10700 c_lcpState.noOfLcpFragRepOutstanding--;
10701 }
10702
10703 bool tableDone = reportLcpCompletion(lcpReport);
10704
10705 Uint32 started = lcpReport->maxGciStarted;
10706 Uint32 completed = lcpReport->maxGciCompleted;
10707
10708 if (started > c_lcpState.lcpStopGcp)
10709 {
10710 jam();
10711 c_lcpState.lcpStopGcp = started;
10712 }
10713
10714 if(tableDone){
10715 jam();
10716
10717 if(tabPtr.p->tabStatus == TabRecord::TS_DROPPING){
10718 jam();
10719 g_eventLogger.info("TS_DROPPING - Neglecting to save Table: %d Frag: %d - ",
10720 tableId, fragId);
10721 } else {
10722 jam();
10723 /**
10724 * Write table description to file
10725 */
10726 tabPtr.p->tabLcpStatus = TabRecord::TLS_WRITING_TO_FILE;
10727 tabPtr.p->tabCopyStatus = TabRecord::CS_LCP_READ_TABLE;
10728 tabPtr.p->tabUpdateState = TabRecord::US_LOCAL_CHECKPOINT;
10729 signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
10730 signal->theData[1] = tabPtr.i;
10731 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
10732
10733 checkLcpAllTablesDoneInLqh();
10734 }
10735 }
10736
10737 #ifdef VM_TRACE
10738 /* --------------------------------------------------------------------- */
10739 // REPORT that local checkpoint have completed this fragment.
10740 /* --------------------------------------------------------------------- */
10741 signal->theData[0] = NDB_LE_LCPFragmentCompleted;
10742 signal->theData[1] = nodeId;
10743 signal->theData[2] = tableId;
10744 signal->theData[3] = fragId;
10745 signal->theData[4] = started;
10746 signal->theData[5] = completed;
10747 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 6, JBB);
10748 #endif
10749
10750 bool ok = false;
10751 switch(c_lcpMasterTakeOverState.state){
10752 case LMTOS_IDLE:
10753 ok = true;
10754 jam();
10755 /**
10756 * Fall through
10757 */
10758 break;
10759 case LMTOS_WAIT_EMPTY_LCP: // LCP Take over waiting for EMPTY_LCPCONF
10760 jam();
10761 return;
10762 case LMTOS_WAIT_LCP_FRAG_REP:
10763 jam();
10764 checkEmptyLcpComplete(signal);
10765 return;
10766 case LMTOS_INITIAL:
10767 case LMTOS_ALL_IDLE:
10768 case LMTOS_ALL_ACTIVE:
10769 case LMTOS_LCP_CONCLUDING:
10770 case LMTOS_COPY_ONGOING:
10771 ndbrequire(false);
10772 }
10773 ndbrequire(ok);
10774
10775 /* ----------------------------------------------------------------------- */
10776 // Check if there are more LCP's to start up.
10777 /* ----------------------------------------------------------------------- */
10778 if(isMaster()){
10779 jam();
10780
10781 /**
10782 * Remove from "running" array
10783 */
10784 NodeRecordPtr nodePtr;
10785 nodePtr.i = nodeId;
10786 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
10787
10788 const Uint32 outstanding = nodePtr.p->noOfStartedChkpt;
10789 ndbrequire(outstanding > 0);
10790 if(nodePtr.p->startedChkpt[0].tableId != tableId ||
10791 nodePtr.p->startedChkpt[0].fragId != fragId){
10792 jam();
10793 ndbrequire(outstanding > 1);
10794 ndbrequire(nodePtr.p->startedChkpt[1].tableId == tableId);
10795 ndbrequire(nodePtr.p->startedChkpt[1].fragId == fragId);
10796 } else {
10797 jam();
10798 nodePtr.p->startedChkpt[0] = nodePtr.p->startedChkpt[1];
10799 }
10800 nodePtr.p->noOfStartedChkpt--;
10801 checkStartMoreLcp(signal, nodeId);
10802 }
10803 }
10804
10805 bool
checkLcpAllTablesDoneInLqh()10806 Dbdih::checkLcpAllTablesDoneInLqh(){
10807 TabRecordPtr tabPtr;
10808
10809 /**
10810 * Check if finished with all tables
10811 */
10812 for (tabPtr.i = 0; tabPtr.i < ctabFileSize; tabPtr.i++) {
10813 jam();
10814 ptrAss(tabPtr, tabRecord);
10815 if ((tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) &&
10816 (tabPtr.p->tabLcpStatus == TabRecord::TLS_ACTIVE)) {
10817 jam();
10818 /**
10819 * Nope, not finished with all tables
10820 */
10821 return false;
10822 }//if
10823 }//for
10824
10825 CRASH_INSERTION2(7026, isMaster());
10826 CRASH_INSERTION2(7017, !isMaster());
10827
10828 c_lcpState.setLcpStatus(LCP_TAB_COMPLETED, __LINE__);
10829
10830 if (ERROR_INSERTED(7194))
10831 {
10832 ndbout_c("CLEARING 7194");
10833 CLEAR_ERROR_INSERT_VALUE;
10834 }
10835
10836 return true;
10837 }
10838
findReplica(ReplicaRecordPtr & replicaPtr,Fragmentstore * fragPtrP,Uint32 nodeId,bool old)10839 void Dbdih::findReplica(ReplicaRecordPtr& replicaPtr,
10840 Fragmentstore* fragPtrP,
10841 Uint32 nodeId,
10842 bool old)
10843 {
10844 replicaPtr.i = old ? fragPtrP->oldStoredReplicas : fragPtrP->storedReplicas;
10845 while(replicaPtr.i != RNIL){
10846 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
10847 if (replicaPtr.p->procNode == nodeId) {
10848 jam();
10849 return;
10850 } else {
10851 jam();
10852 replicaPtr.i = replicaPtr.p->nextReplica;
10853 }//if
10854 };
10855
10856 #ifdef VM_TRACE
10857 g_eventLogger.info("Fragment Replica(node=%d) not found", nodeId);
10858 replicaPtr.i = fragPtrP->oldStoredReplicas;
10859 while(replicaPtr.i != RNIL){
10860 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
10861 if (replicaPtr.p->procNode == nodeId) {
10862 jam();
10863 break;
10864 } else {
10865 jam();
10866 replicaPtr.i = replicaPtr.p->nextReplica;
10867 }//if
10868 };
10869 if(replicaPtr.i != RNIL){
10870 g_eventLogger.info("...But was found in oldStoredReplicas");
10871 } else {
10872 g_eventLogger.info("...And wasn't found in oldStoredReplicas");
10873 }
10874 #endif
10875 ndbrequire(false);
10876 }//Dbdih::findReplica()
10877
10878
10879 int
handle_invalid_lcp_no(const LcpFragRep * rep,ReplicaRecordPtr replicaPtr)10880 Dbdih::handle_invalid_lcp_no(const LcpFragRep* rep,
10881 ReplicaRecordPtr replicaPtr)
10882 {
10883 ndbrequire(!isMaster());
10884 Uint32 lcpNo = rep->lcpNo;
10885 Uint32 lcpId = rep->lcpId;
10886
10887 warningEvent("Detected previous node failure of %d during lcp",
10888 rep->nodeId);
10889 replicaPtr.p->nextLcp = lcpNo;
10890 replicaPtr.p->lcpId[lcpNo] = 0;
10891 replicaPtr.p->lcpStatus[lcpNo] = ZINVALID;
10892
10893 for (Uint32 i = lcpNo; i != lcpNo; i = nextLcpNo(i))
10894 {
10895 jam();
10896 if (replicaPtr.p->lcpStatus[i] == ZVALID &&
10897 replicaPtr.p->lcpId[i] >= lcpId)
10898 {
10899 ndbout_c("i: %d lcpId: %d", i, replicaPtr.p->lcpId[i]);
10900 ndbrequire(false);
10901 }
10902 }
10903
10904 return 0;
10905 }
10906
10907 /**
10908 * Return true if table is all fragment replicas have been checkpointed
10909 * to disk (in all LQHs)
10910 * false otherwise
10911 */
10912 bool
reportLcpCompletion(const LcpFragRep * lcpReport)10913 Dbdih::reportLcpCompletion(const LcpFragRep* lcpReport)
10914 {
10915 Uint32 lcpNo = lcpReport->lcpNo;
10916 Uint32 lcpId = lcpReport->lcpId;
10917 Uint32 maxGciStarted = lcpReport->maxGciStarted;
10918 Uint32 maxGciCompleted = lcpReport->maxGciCompleted;
10919 Uint32 tableId = lcpReport->tableId;
10920 Uint32 fragId = lcpReport->fragId;
10921 Uint32 nodeId = lcpReport->nodeId;
10922
10923 TabRecordPtr tabPtr;
10924 tabPtr.i = tableId;
10925 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
10926
10927 FragmentstorePtr fragPtr;
10928 getFragstore(tabPtr.p, fragId, fragPtr);
10929
10930 ReplicaRecordPtr replicaPtr;
10931 findReplica(replicaPtr, fragPtr.p, nodeId);
10932
10933 ndbrequire(replicaPtr.p->lcpOngoingFlag == true);
10934 if(lcpNo != replicaPtr.p->nextLcp){
10935 if (handle_invalid_lcp_no(lcpReport, replicaPtr))
10936 {
10937 g_eventLogger.error("lcpNo = %d replicaPtr.p->nextLcp = %d",
10938 lcpNo, replicaPtr.p->nextLcp);
10939 ndbrequire(false);
10940 }
10941 }
10942 ndbrequire(lcpNo == replicaPtr.p->nextLcp);
10943 ndbrequire(lcpNo < MAX_LCP_STORED);
10944 ndbrequire(replicaPtr.p->lcpId[lcpNo] != lcpId);
10945
10946 replicaPtr.p->lcpIdStarted = lcpId;
10947 replicaPtr.p->lcpOngoingFlag = false;
10948
10949 removeOldCrashedReplicas(replicaPtr);
10950 replicaPtr.p->lcpId[lcpNo] = lcpId;
10951 replicaPtr.p->lcpStatus[lcpNo] = ZVALID;
10952 replicaPtr.p->maxGciStarted[lcpNo] = maxGciStarted;
10953 gth(maxGciStarted + 1, 0);
10954 replicaPtr.p->maxGciCompleted[lcpNo] = maxGciCompleted;
10955 replicaPtr.p->nextLcp = nextLcpNo(replicaPtr.p->nextLcp);
10956
10957 ndbrequire(fragPtr.p->noLcpReplicas > 0);
10958 fragPtr.p->noLcpReplicas --;
10959
10960 if(fragPtr.p->noLcpReplicas > 0){
10961 jam();
10962 return false;
10963 }
10964
10965 for (Uint32 fid = 0; fid < tabPtr.p->totalfragments; fid++) {
10966 jam();
10967 getFragstore(tabPtr.p, fid, fragPtr);
10968 if (fragPtr.p->noLcpReplicas > 0){
10969 jam();
10970 /* ----------------------------------------------------------------- */
10971 // Not all fragments in table have been checkpointed.
10972 /* ----------------------------------------------------------------- */
10973 if(0)
10974 g_eventLogger.info("reportLcpCompletion: fragment %d not ready", fid);
10975 return false;
10976 }//if
10977 }//for
10978 return true;
10979 }//Dbdih::reportLcpCompletion()
10980
checkStartMoreLcp(Signal * signal,Uint32 nodeId)10981 void Dbdih::checkStartMoreLcp(Signal* signal, Uint32 nodeId)
10982 {
10983 ndbrequire(isMaster());
10984
10985 NodeRecordPtr nodePtr;
10986 nodePtr.i = nodeId;
10987 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
10988
10989 ndbrequire(nodePtr.p->noOfStartedChkpt < 2);
10990
10991 if (nodePtr.p->noOfQueuedChkpt > 0) {
10992 jam();
10993 nodePtr.p->noOfQueuedChkpt--;
10994 Uint32 i = nodePtr.p->noOfStartedChkpt;
10995 nodePtr.p->startedChkpt[i] = nodePtr.p->queuedChkpt[0];
10996 nodePtr.p->queuedChkpt[0] = nodePtr.p->queuedChkpt[1];
10997 //-------------------------------------------------------------------
10998 // We can send a LCP_FRAGORD to the node ordering it to perform a
10999 // local checkpoint on this fragment replica.
11000 //-------------------------------------------------------------------
11001 nodePtr.p->noOfStartedChkpt = i + 1;
11002
11003 sendLCP_FRAG_ORD(signal, nodePtr.p->startedChkpt[i]);
11004 }
11005
11006 /* ----------------------------------------------------------------------- */
11007 // When there are no more outstanding LCP reports and there are no one queued
11008 // in at least one node, then we are ready to make sure all nodes have at
11009 // least two outstanding LCP requests per node and at least two queued for
11010 // sending.
11011 /* ----------------------------------------------------------------------- */
11012 startNextChkpt(signal);
11013 }//Dbdih::checkStartMoreLcp()
11014
11015 void
sendLCP_FRAG_ORD(Signal * signal,NodeRecord::FragmentCheckpointInfo info)11016 Dbdih::sendLCP_FRAG_ORD(Signal* signal,
11017 NodeRecord::FragmentCheckpointInfo info){
11018
11019 ReplicaRecordPtr replicaPtr;
11020 replicaPtr.i = info.replicaPtr;
11021 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
11022
11023 BlockReference ref = calcLqhBlockRef(replicaPtr.p->procNode);
11024
11025 if (ERROR_INSERTED(7193) && replicaPtr.p->procNode == getOwnNodeId())
11026 {
11027 return;
11028 }
11029
11030 LcpFragOrd * const lcpFragOrd = (LcpFragOrd *)&signal->theData[0];
11031 lcpFragOrd->tableId = info.tableId;
11032 lcpFragOrd->fragmentId = info.fragId;
11033 lcpFragOrd->lcpId = SYSFILE->latestLCP_ID;
11034 lcpFragOrd->lcpNo = replicaPtr.p->nextLcp;
11035 lcpFragOrd->keepGci = c_lcpState.keepGci;
11036 lcpFragOrd->lastFragmentFlag = false;
11037 sendSignal(ref, GSN_LCP_FRAG_ORD, signal, LcpFragOrd::SignalLength, JBB);
11038 }
11039
checkLcpCompletedLab(Signal * signal)11040 void Dbdih::checkLcpCompletedLab(Signal* signal)
11041 {
11042 if(c_lcpState.lcpStatus < LCP_TAB_COMPLETED){
11043 jam();
11044 return;
11045 }
11046
11047 TabRecordPtr tabPtr;
11048 for (tabPtr.i = 0; tabPtr.i < ctabFileSize; tabPtr.i++) {
11049 jam();
11050 ptrAss(tabPtr, tabRecord);
11051 if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
11052 if (tabPtr.p->tabLcpStatus != TabRecord::TLS_COMPLETED) {
11053 jam();
11054 return;
11055 }//if
11056 }//if
11057 }//for
11058
11059 CRASH_INSERTION2(7027, isMaster());
11060 CRASH_INSERTION2(7018, !isMaster());
11061
11062 if(c_lcpState.lcpStatus == LCP_TAB_COMPLETED){
11063 /**
11064 * We'r done
11065 */
11066 c_lcpState.setLcpStatus(LCP_TAB_SAVED, __LINE__);
11067 sendLCP_COMPLETE_REP(signal);
11068 return;
11069 }
11070
11071 ndbrequire(c_lcpState.lcpStatus == LCP_TAB_SAVED);
11072 allNodesLcpCompletedLab(signal);
11073 return;
11074 }//Dbdih::checkLcpCompletedLab()
11075
11076 void
sendLCP_COMPLETE_REP(Signal * signal)11077 Dbdih::sendLCP_COMPLETE_REP(Signal* signal){
11078 jam();
11079 LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
11080 rep->nodeId = getOwnNodeId();
11081 rep->lcpId = SYSFILE->latestLCP_ID;
11082 rep->blockNo = DBDIH;
11083
11084 sendSignal(c_lcpState.m_masterLcpDihRef, GSN_LCP_COMPLETE_REP, signal,
11085 LcpCompleteRep::SignalLength, JBB);
11086
11087 /**
11088 * Say that an initial node restart does not need to be redone
11089 * once node has been part of first LCP
11090 */
11091 if (c_set_initial_start_flag &&
11092 c_lcpState.m_participatingLQH.get(getOwnNodeId()))
11093 {
11094 jam();
11095 c_set_initial_start_flag = FALSE;
11096 }
11097 }
11098
11099 /*-------------------------------------------------------------------------- */
11100 /* COMP_LCP_ROUND A LQH HAS COMPLETED A LOCAL CHECKPOINT */
11101 /*------------------------------------------------------------------------- */
execLCP_COMPLETE_REP(Signal * signal)11102 void Dbdih::execLCP_COMPLETE_REP(Signal* signal)
11103 {
11104 jamEntry();
11105
11106 CRASH_INSERTION(7191);
11107
11108 #if 0
11109 g_eventLogger.info("LCP_COMPLETE_REP");
11110 printLCP_COMPLETE_REP(stdout,
11111 signal->getDataPtr(),
11112 signal->length(), number());
11113 #endif
11114
11115 LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtr();
11116 Uint32 lcpId = rep->lcpId;
11117 Uint32 nodeId = rep->nodeId;
11118 Uint32 blockNo = rep->blockNo;
11119
11120 if(c_lcpMasterTakeOverState.state > LMTOS_WAIT_LCP_FRAG_REP){
11121 jam();
11122 /**
11123 * Don't allow LCP_COMPLETE_REP to arrive during
11124 * LCP master take over
11125 */
11126 ndbrequire(isMaster());
11127 ndbrequire(blockNo == DBDIH);
11128 sendSignalWithDelay(reference(), GSN_LCP_COMPLETE_REP, signal, 100,
11129 signal->length());
11130 return;
11131 }
11132
11133 ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
11134
11135 switch(blockNo){
11136 case DBLQH:
11137 jam();
11138 c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.clearWaitingFor(nodeId);
11139 ndbrequire(!c_lcpState.m_LAST_LCP_FRAG_ORD.isWaitingFor(nodeId));
11140 break;
11141 case DBDIH:
11142 jam();
11143 ndbrequire(isMaster());
11144 c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.clearWaitingFor(nodeId);
11145 break;
11146 case 0:
11147 jam();
11148 ndbrequire(!isMaster());
11149 ndbrequire(c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received == false);
11150 c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received = true;
11151 break;
11152 default:
11153 ndbrequire(false);
11154 }
11155 ndbrequire(lcpId == SYSFILE->latestLCP_ID);
11156
11157 allNodesLcpCompletedLab(signal);
11158 return;
11159 }
11160
allNodesLcpCompletedLab(Signal * signal)11161 void Dbdih::allNodesLcpCompletedLab(Signal* signal)
11162 {
11163 jam();
11164
11165 if (c_lcpState.lcpStatus != LCP_TAB_SAVED) {
11166 jam();
11167 /**
11168 * We have not sent LCP_COMPLETE_REP to master DIH yet
11169 */
11170 return;
11171 }//if
11172
11173 if (!c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.done()){
11174 jam();
11175 return;
11176 }
11177
11178 if (!c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.done()){
11179 jam();
11180 return;
11181 }
11182
11183 if (!isMaster() &&
11184 c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received == false){
11185 jam();
11186 /**
11187 * Wait until master DIH has signaled lcp is complete
11188 */
11189 return;
11190 }
11191
11192 if(c_lcpMasterTakeOverState.state != LMTOS_IDLE){
11193 jam();
11194 #ifdef VM_TRACE
11195 g_eventLogger.info("Exiting from allNodesLcpCompletedLab");
11196 #endif
11197 return;
11198 }
11199
11200
11201 /*------------------------------------------------------------------------ */
11202 /* WE HAVE NOW COMPLETED A LOCAL CHECKPOINT. WE ARE NOW READY TO WAIT */
11203 /* FOR THE NEXT LOCAL CHECKPOINT. SEND WITHOUT TIME-OUT SINCE IT MIGHT */
11204 /* BE TIME TO START THE NEXT LOCAL CHECKPOINT IMMEDIATELY. */
11205 /* CLEAR BIT 3 OF SYSTEM RESTART BITS TO INDICATE THAT THERE IS NO */
11206 /* LOCAL CHECKPOINT ONGOING. THIS WILL BE WRITTEN AT SOME LATER TIME */
11207 /* DURING A GLOBAL CHECKPOINT. IT IS NOT NECESSARY TO WRITE IT */
11208 /* IMMEDIATELY. WE WILL ALSO CLEAR BIT 2 OF SYSTEM RESTART BITS IF ALL */
11209 /* CURRENTLY ACTIVE NODES COMPLETED THE LOCAL CHECKPOINT. */
11210 /*------------------------------------------------------------------------ */
11211 CRASH_INSERTION(7019);
11212 signal->setTrace(0);
11213
11214 c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
11215 setLcpActiveStatusEnd();
11216 Sysfile::clearLCPOngoing(SYSFILE->systemRestartBits);
11217
11218 if(!isMaster()){
11219 jam();
11220 /**
11221 * We're not master, be content
11222 */
11223 return;
11224 }
11225
11226 // Send LCP_COMPLETE_REP to all other nodes
11227 // allowing them to set their lcpStatus to LCP_STATUS_IDLE
11228 LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
11229 rep->nodeId = getOwnNodeId();
11230 rep->lcpId = SYSFILE->latestLCP_ID;
11231 rep->blockNo = 0; // 0 = Sent from master
11232
11233 NodeRecordPtr nodePtr;
11234 nodePtr.i = cfirstAliveNode;
11235 do {
11236 jam();
11237 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
11238 if (nodePtr.i != cownNodeId){
11239 BlockReference ref = calcDihBlockRef(nodePtr.i);
11240 sendSignal(ref, GSN_LCP_COMPLETE_REP, signal,
11241 LcpCompleteRep::SignalLength, JBB);
11242 }
11243 nodePtr.i = nodePtr.p->nextNode;
11244 } while (nodePtr.i != RNIL);
11245
11246
11247 jam();
11248 /***************************************************************************/
11249 // Report the event that a local checkpoint has completed.
11250 /***************************************************************************/
11251 signal->theData[0] = NDB_LE_LocalCheckpointCompleted; //Event type
11252 signal->theData[1] = SYSFILE->latestLCP_ID;
11253 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
11254
11255 if (c_newest_restorable_gci > c_lcpState.lcpStopGcp)
11256 {
11257 jam();
11258 c_lcpState.lcpStopGcp = c_newest_restorable_gci;
11259 }
11260
11261 /**
11262 * Start checking for next LCP
11263 */
11264 checkLcpStart(signal, __LINE__);
11265
11266 if (cwaitLcpSr == true) {
11267 jam();
11268 cwaitLcpSr = false;
11269 ndbsttorry10Lab(signal, __LINE__);
11270 return;
11271 }//if
11272
11273 if (c_nodeStartMaster.blockLcp == true) {
11274 jam();
11275 lcpBlockedLab(signal);
11276 return;
11277 }//if
11278 return;
11279 }//Dbdih::allNodesLcpCompletedLab()
11280
11281 /******************************************************************************/
11282 /* ********** TABLE UPDATE MODULE *************/
11283 /* ****************************************************************************/
11284 /* ------------------------------------------------------------------------- */
11285 /* THIS MODULE IS USED TO UPDATE THE TABLE DESCRIPTION. IT STARTS BY */
11286 /* CREATING THE FIRST TABLE FILE, THEN UPDATES THIS FILE AND CLOSES IT.*/
11287 /* AFTER THAT THE SAME HAPPENS WITH THE SECOND FILE. AFTER THAT THE */
11288 /* TABLE DISTRIBUTION HAS BEEN UPDATED. */
11289 /* */
11290 /* THE REASON FOR CREATING THE FILE AND NOT OPENING IT IS TO ENSURE */
11291 /* THAT WE DO NOT GET A MIX OF OLD AND NEW INFORMATION IN THE FILE IN */
11292 /* ERROR SITUATIONS. */
11293 /* ------------------------------------------------------------------------- */
tableUpdateLab(Signal * signal,TabRecordPtr tabPtr)11294 void Dbdih::tableUpdateLab(Signal* signal, TabRecordPtr tabPtr) {
11295 FileRecordPtr filePtr;
11296 if(tabPtr.p->tabStorage == TabRecord::ST_TEMPORARY) {
11297 // For temporary tables we do not write to disk. Mark both copies 0 and 1
11298 // as done, and go straight to the after-close code.
11299 filePtr.i = tabPtr.p->tabFile[1];
11300 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
11301 tableCloseLab(signal, filePtr);
11302 return;
11303 }
11304 filePtr.i = tabPtr.p->tabFile[0];
11305 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
11306 createFileRw(signal, filePtr);
11307 filePtr.p->reqStatus = FileRecord::TABLE_CREATE;
11308 return;
11309 }//Dbdih::tableUpdateLab()
11310
tableCreateLab(Signal * signal,FileRecordPtr filePtr)11311 void Dbdih::tableCreateLab(Signal* signal, FileRecordPtr filePtr)
11312 {
11313 TabRecordPtr tabPtr;
11314 tabPtr.i = filePtr.p->tabRef;
11315 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
11316 writeTabfile(signal, tabPtr.p, filePtr);
11317 filePtr.p->reqStatus = FileRecord::TABLE_WRITE;
11318 return;
11319 }//Dbdih::tableCreateLab()
11320
tableWriteLab(Signal * signal,FileRecordPtr filePtr)11321 void Dbdih::tableWriteLab(Signal* signal, FileRecordPtr filePtr)
11322 {
11323 closeFile(signal, filePtr);
11324 filePtr.p->reqStatus = FileRecord::TABLE_CLOSE;
11325 return;
11326 }//Dbdih::tableWriteLab()
11327
tableCloseLab(Signal * signal,FileRecordPtr filePtr)11328 void Dbdih::tableCloseLab(Signal* signal, FileRecordPtr filePtr)
11329 {
11330 TabRecordPtr tabPtr;
11331 tabPtr.i = filePtr.p->tabRef;
11332 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
11333 if (filePtr.i == tabPtr.p->tabFile[0]) {
11334 jam();
11335 filePtr.i = tabPtr.p->tabFile[1];
11336 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
11337 createFileRw(signal, filePtr);
11338 filePtr.p->reqStatus = FileRecord::TABLE_CREATE;
11339 return;
11340 }//if
11341 switch (tabPtr.p->tabUpdateState) {
11342 case TabRecord::US_LOCAL_CHECKPOINT:
11343 jam();
11344 releaseTabPages(tabPtr.i);
11345 signal->theData[0] = DihContinueB::ZCHECK_LCP_COMPLETED;
11346 sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
11347
11348 tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
11349 tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
11350 tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
11351 return;
11352 break;
11353 case TabRecord::US_REMOVE_NODE:
11354 jam();
11355 releaseTabPages(tabPtr.i);
11356 for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
11357 jam();
11358 FragmentstorePtr fragPtr;
11359 getFragstore(tabPtr.p, fragId, fragPtr);
11360 updateNodeInfo(fragPtr);
11361 }//for
11362 tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
11363 tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
11364 if (tabPtr.p->tabLcpStatus == TabRecord::TLS_WRITING_TO_FILE) {
11365 jam();
11366 tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
11367 signal->theData[0] = DihContinueB::ZCHECK_LCP_COMPLETED;
11368 sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
11369 }//if
11370 signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
11371 signal->theData[1] = tabPtr.p->tabRemoveNode;
11372 signal->theData[2] = tabPtr.i + 1;
11373 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
11374 return;
11375 break;
11376 case TabRecord::US_INVALIDATE_NODE_LCP:
11377 jam();
11378 releaseTabPages(tabPtr.i);
11379 tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
11380 tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
11381
11382 signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
11383 signal->theData[1] = tabPtr.p->tabRemoveNode;
11384 signal->theData[2] = tabPtr.i + 1;
11385 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
11386 return;
11387 case TabRecord::US_COPY_TAB_REQ:
11388 jam();
11389 tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
11390 copyTabReq_complete(signal, tabPtr);
11391 return;
11392 break;
11393 case TabRecord::US_ADD_TABLE_MASTER:
11394 jam();
11395 releaseTabPages(tabPtr.i);
11396 tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
11397 signal->theData[0] = DihContinueB::ZDIH_ADD_TABLE_MASTER;
11398 signal->theData[1] = tabPtr.i;
11399 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11400 return;
11401 break;
11402 case TabRecord::US_ADD_TABLE_SLAVE:
11403 jam();
11404 releaseTabPages(tabPtr.i);
11405 tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
11406 signal->theData[0] = DihContinueB::ZDIH_ADD_TABLE_SLAVE;
11407 signal->theData[1] = tabPtr.i;
11408 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
11409 return;
11410 break;
11411 default:
11412 ndbrequire(false);
11413 return;
11414 break;
11415 }//switch
11416 }//Dbdih::tableCloseLab()
11417
11418 /**
11419 * GCP stop detected,
11420 * send SYSTEM_ERROR to all other alive nodes
11421 */
crashSystemAtGcpStop(Signal * signal,bool local)11422 void Dbdih::crashSystemAtGcpStop(Signal* signal, bool local)
11423 {
11424 if (local)
11425 goto dolocal;
11426
11427 switch(cgcpStatus){
11428 case GCP_PREPARE_SENT:
11429 {
11430 jam();
11431 /**
11432 * We're waiting for a GCP PREPARE CONF
11433 */
11434 infoEvent("Detected GCP stop(%d)...sending kill to %s",
11435 cgcpStatus, c_GCP_PREPARE_Counter.getText());
11436 ndbout_c("Detected GCP stop(%d)...sending kill to %s",
11437 cgcpStatus, c_GCP_PREPARE_Counter.getText());
11438
11439 {
11440 NodeReceiverGroup rg(DBDIH, c_GCP_PREPARE_Counter);
11441 signal->theData[0] = 7022;
11442 sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBA);
11443 }
11444
11445 {
11446 NodeReceiverGroup rg(NDBCNTR, c_GCP_PREPARE_Counter);
11447 SystemError * const sysErr = (SystemError*)&signal->theData[0];
11448 sysErr->errorCode = SystemError::GCPStopDetected;
11449 sysErr->errorRef = reference();
11450 sysErr->data1 = cgcpStatus;
11451 sysErr->data2 = cgcpOrderBlocked;
11452 sendSignal(rg, GSN_SYSTEM_ERROR, signal,
11453 SystemError::SignalLength, JBA);
11454 }
11455 ndbrequire(!c_GCP_PREPARE_Counter.done());
11456 return;
11457 }
11458 case GCP_COMMIT_SENT:
11459 {
11460 jam();
11461 /**
11462 * We're waiting for a GCP_NODEFINISH
11463 */
11464 infoEvent("Detected GCP stop(%d)...sending kill to %s",
11465 cgcpStatus, c_GCP_COMMIT_Counter.getText());
11466 ndbout_c("Detected GCP stop(%d)...sending kill to %s",
11467 cgcpStatus, c_GCP_COMMIT_Counter.getText());
11468
11469 {
11470 NodeReceiverGroup rg(DBDIH, c_GCP_COMMIT_Counter);
11471 signal->theData[0] = 7022;
11472 sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBA);
11473 }
11474
11475 {
11476 NodeReceiverGroup rg(NDBCNTR, c_GCP_COMMIT_Counter);
11477 SystemError * const sysErr = (SystemError*)&signal->theData[0];
11478 sysErr->errorCode = SystemError::GCPStopDetected;
11479 sysErr->errorRef = reference();
11480 sysErr->data1 = cgcpStatus;
11481 sysErr->data2 = cgcpOrderBlocked;
11482 sendSignal(rg, GSN_SYSTEM_ERROR, signal,
11483 SystemError::SignalLength, JBA);
11484 }
11485 ndbrequire(!c_GCP_COMMIT_Counter.done());
11486 return;
11487 }
11488 case GCP_NODE_FINISHED:
11489 {
11490 jam();
11491 /**
11492 * We're waiting for a GCP save conf
11493 */
11494 NodeReceiverGroup rg(DBLQH, c_GCP_SAVEREQ_Counter);
11495 signal->theData[0] = 2305;
11496 sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBB);
11497
11498 infoEvent("Detected GCP stop(%d)...sending kill to %s",
11499 cgcpStatus, c_GCP_SAVEREQ_Counter.getText());
11500 ndbout_c("Detected GCP stop(%d)...sending kill to %s",
11501 cgcpStatus, c_GCP_SAVEREQ_Counter.getText());
11502 ndbrequire(!c_GCP_SAVEREQ_Counter.done());
11503 return;
11504 }
11505 case GCP_SAVE_LQH_FINISHED:
11506 {
11507 jam();
11508 /**
11509 * We're waiting for a COPY_GCICONF
11510 */
11511 infoEvent("Detected GCP stop(%d)...sending kill to %s",
11512 cgcpStatus, c_COPY_GCIREQ_Counter.getText());
11513 ndbout_c("Detected GCP stop(%d)...sending kill to %s",
11514 cgcpStatus, c_COPY_GCIREQ_Counter.getText());
11515
11516 {
11517 NodeReceiverGroup rg(DBDIH, c_COPY_GCIREQ_Counter);
11518 signal->theData[0] = 7022;
11519 sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBA);
11520 }
11521
11522 {
11523 NodeReceiverGroup rg(NDBCNTR, c_COPY_GCIREQ_Counter);
11524 SystemError * const sysErr = (SystemError*)&signal->theData[0];
11525 sysErr->errorCode = SystemError::GCPStopDetected;
11526 sysErr->errorRef = reference();
11527 sysErr->data1 = cgcpStatus;
11528 sysErr->data2 = cgcpOrderBlocked;
11529 sendSignal(rg, GSN_SYSTEM_ERROR, signal,
11530 SystemError::SignalLength, JBA);
11531 }
11532 ndbrequire(!c_COPY_GCIREQ_Counter.done());
11533 return;
11534 }
11535 case GCP_READY: (void)1;
11536 }
11537
11538 dolocal:
11539 ndbout_c("m_copyReason: %d m_waiting: %d",
11540 c_copyGCIMaster.m_copyReason,
11541 c_copyGCIMaster.m_waiting);
11542
11543 ndbout_c("c_copyGCISlave: sender{Data, Ref} %d %x reason: %d nextWord: %d",
11544 c_copyGCISlave.m_senderData,
11545 c_copyGCISlave.m_senderRef,
11546 c_copyGCISlave.m_copyReason,
11547 c_copyGCISlave.m_expectedNextWord);
11548
11549 FileRecordPtr file0Ptr;
11550 file0Ptr.i = crestartInfoFile[0];
11551 ptrCheckGuard(file0Ptr, cfileFileSize, fileRecord);
11552 FileRecordPtr file1Ptr;
11553 file1Ptr.i = crestartInfoFile[1];
11554 ptrCheckGuard(file1Ptr, cfileFileSize, fileRecord);
11555
11556 ndbout_c("file[0] status: %d type: %d reqStatus: %d file1: %d %d %d",
11557 file0Ptr.p->fileStatus, file0Ptr.p->fileType, file0Ptr.p->reqStatus,
11558 file1Ptr.p->fileStatus, file1Ptr.p->fileType, file1Ptr.p->reqStatus
11559 );
11560
11561 signal->theData[0] = 404;
11562 signal->theData[1] = file0Ptr.p->fileRef;
11563 EXECUTE_DIRECT(NDBFS, GSN_DUMP_STATE_ORD, signal, 2);
11564
11565 signal->theData[0] = 404;
11566 signal->theData[1] = file1Ptr.p->fileRef;
11567 EXECUTE_DIRECT(NDBFS, GSN_DUMP_STATE_ORD, signal, 2);
11568
11569 ndbout_c("c_COPY_GCIREQ_Counter = %s",
11570 c_COPY_GCIREQ_Counter.getText());
11571 ndbout_c("c_COPY_TABREQ_Counter = %s",
11572 c_COPY_TABREQ_Counter.getText());
11573 ndbout_c("c_CREATE_FRAGREQ_Counter = %s",
11574 c_CREATE_FRAGREQ_Counter.getText());
11575 ndbout_c("c_DIH_SWITCH_REPLICA_REQ_Counter = %s",
11576 c_DIH_SWITCH_REPLICA_REQ_Counter.getText());
11577 ndbout_c("c_EMPTY_LCP_REQ_Counter = %s",c_EMPTY_LCP_REQ_Counter.getText());
11578 ndbout_c("c_END_TOREQ_Counter = %s", c_END_TOREQ_Counter.getText());
11579 ndbout_c("c_GCP_COMMIT_Counter = %s", c_GCP_COMMIT_Counter.getText());
11580 ndbout_c("c_GCP_PREPARE_Counter = %s", c_GCP_PREPARE_Counter.getText());
11581 ndbout_c("c_GCP_SAVEREQ_Counter = %s", c_GCP_SAVEREQ_Counter.getText());
11582 ndbout_c("c_INCL_NODEREQ_Counter = %s", c_INCL_NODEREQ_Counter.getText());
11583 ndbout_c("c_MASTER_GCPREQ_Counter = %s",
11584 c_MASTER_GCPREQ_Counter.getText());
11585 ndbout_c("c_MASTER_LCPREQ_Counter = %s",
11586 c_MASTER_LCPREQ_Counter.getText());
11587 ndbout_c("c_START_INFOREQ_Counter = %s",
11588 c_START_INFOREQ_Counter.getText());
11589 ndbout_c("c_START_RECREQ_Counter = %s", c_START_RECREQ_Counter.getText());
11590 ndbout_c("c_START_TOREQ_Counter = %s", c_START_TOREQ_Counter.getText());
11591 ndbout_c("c_STOP_ME_REQ_Counter = %s", c_STOP_ME_REQ_Counter.getText());
11592 ndbout_c("c_TC_CLOPSIZEREQ_Counter = %s",
11593 c_TC_CLOPSIZEREQ_Counter.getText());
11594 ndbout_c("c_TCGETOPSIZEREQ_Counter = %s",
11595 c_TCGETOPSIZEREQ_Counter.getText());
11596 ndbout_c("c_UPDATE_TOREQ_Counter = %s", c_UPDATE_TOREQ_Counter.getText());
11597
11598 if (local == false)
11599 {
11600 jam();
11601 NodeRecordPtr nodePtr;
11602 for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
11603 jam();
11604 ptrAss(nodePtr, nodeRecord);
11605 if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
11606 jam();
11607 const BlockReference ref =
11608 numberToRef(refToBlock(cntrlblockref), nodePtr.i);
11609 SystemError * const sysErr = (SystemError*)&signal->theData[0];
11610 sysErr->errorCode = SystemError::GCPStopDetected;
11611 sysErr->errorRef = reference();
11612 sysErr->data1 = cgcpStatus;
11613 sysErr->data2 = cgcpOrderBlocked;
11614 sendSignal(ref, GSN_SYSTEM_ERROR, signal,
11615 SystemError::SignalLength, JBA);
11616 }//if
11617 }//for
11618 }
11619 else
11620 {
11621 jam();
11622 SystemError * const sysErr = (SystemError*)&signal->theData[0];
11623 sysErr->errorCode = SystemError::GCPStopDetected;
11624 sysErr->errorRef = reference();
11625 sysErr->data1 = cgcpStatus;
11626 sysErr->data2 = cgcpOrderBlocked;
11627 EXECUTE_DIRECT(NDBCNTR, GSN_SYSTEM_ERROR,
11628 signal, SystemError::SignalLength);
11629 ndbrequire(false);
11630 }
11631 return;
11632 }//Dbdih::crashSystemAtGcpStop()
11633
11634 /*************************************************************************/
11635 /* */
11636 /* MODULE: ALLOCPAGE */
11637 /* DESCRIPTION: THE SUBROUTINE IS CALLED WITH POINTER TO PAGE */
11638 /* RECORD. A PAGE RECORD IS TAKEN FROM */
11639 /* THE FREE PAGE LIST */
11640 /*************************************************************************/
allocpage(PageRecordPtr & pagePtr)11641 void Dbdih::allocpage(PageRecordPtr& pagePtr)
11642 {
11643 ndbrequire(cfirstfreepage != RNIL);
11644 pagePtr.i = cfirstfreepage;
11645 ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
11646 cfirstfreepage = pagePtr.p->nextfreepage;
11647 pagePtr.p->nextfreepage = RNIL;
11648 }//Dbdih::allocpage()
11649
11650 /*************************************************************************/
11651 /* */
11652 /* MODULE: ALLOC_STORED_REPLICA */
11653 /* DESCRIPTION: THE SUBROUTINE IS CALLED TO GET A REPLICA RECORD, */
11654 /* TO INITIALISE IT AND TO LINK IT INTO THE FRAGMENT */
11655 /* STORE RECORD. USED FOR STORED REPLICAS. */
11656 /*************************************************************************/
allocStoredReplica(FragmentstorePtr fragPtr,ReplicaRecordPtr & newReplicaPtr,Uint32 nodeId)11657 void Dbdih::allocStoredReplica(FragmentstorePtr fragPtr,
11658 ReplicaRecordPtr& newReplicaPtr,
11659 Uint32 nodeId)
11660 {
11661 Uint32 i;
11662 ReplicaRecordPtr arrReplicaPtr;
11663 ReplicaRecordPtr arrPrevReplicaPtr;
11664
11665 seizeReplicaRec(newReplicaPtr);
11666 for (i = 0; i < MAX_LCP_STORED; i++) {
11667 newReplicaPtr.p->maxGciCompleted[i] = 0;
11668 newReplicaPtr.p->maxGciStarted[i] = 0;
11669 newReplicaPtr.p->lcpId[i] = 0;
11670 newReplicaPtr.p->lcpStatus[i] = ZINVALID;
11671 }//for
11672 newReplicaPtr.p->noCrashedReplicas = 0;
11673 newReplicaPtr.p->initialGci = currentgcp;
11674 for (i = 0; i < 8; i++) {
11675 newReplicaPtr.p->replicaLastGci[i] = (Uint32)-1;
11676 newReplicaPtr.p->createGci[i] = 0;
11677 }//for
11678 newReplicaPtr.p->createGci[0] = currentgcp;
11679 ndbrequire(currentgcp != 0xF1F1F1F1);
11680 newReplicaPtr.p->nextLcp = 0;
11681 newReplicaPtr.p->procNode = nodeId;
11682 newReplicaPtr.p->lcpOngoingFlag = false;
11683 newReplicaPtr.p->lcpIdStarted = 0;
11684
11685 arrPrevReplicaPtr.i = RNIL;
11686 arrReplicaPtr.i = fragPtr.p->storedReplicas;
11687 while (arrReplicaPtr.i != RNIL) {
11688 jam();
11689 ptrCheckGuard(arrReplicaPtr, creplicaFileSize, replicaRecord);
11690 arrPrevReplicaPtr = arrReplicaPtr;
11691 arrReplicaPtr.i = arrReplicaPtr.p->nextReplica;
11692 }//while
11693 if (arrPrevReplicaPtr.i == RNIL) {
11694 jam();
11695 fragPtr.p->storedReplicas = newReplicaPtr.i;
11696 } else {
11697 jam();
11698 arrPrevReplicaPtr.p->nextReplica = newReplicaPtr.i;
11699 }//if
11700 fragPtr.p->noStoredReplicas++;
11701 }//Dbdih::allocStoredReplica()
11702
11703 /*************************************************************************/
11704 /* CALCULATE HOW MANY HOT SPARES THAT ARE TO BE ASSIGNED IN THIS SYSTEM */
11705 /*************************************************************************/
calculateHotSpare()11706 void Dbdih::calculateHotSpare()
11707 {
11708 Uint32 tchsTmp;
11709 Uint32 tchsNoNodes;
11710
11711 switch (cnoReplicas) {
11712 case 1:
11713 jam();
11714 cnoHotSpare = 0;
11715 break;
11716 case 2:
11717 case 3:
11718 case 4:
11719 jam();
11720 if (csystemnodes > cnoReplicas) {
11721 jam();
11722 /* --------------------------------------------------------------------- */
11723 /* WITH MORE NODES THAN REPLICAS WE WILL ALWAYS USE AT LEAST ONE HOT */
11724 /* SPARE IF THAT HAVE BEEN REQUESTED BY THE CONFIGURATION FILE. THE */
11725 /* NUMBER OF NODES TO BE USED FOR NORMAL OPERATION IS ALWAYS */
11726 /* A MULTIPLE OF THE NUMBER OF REPLICAS SINCE WE WILL ORGANISE NODES */
11727 /* INTO NODE GROUPS. THE REMAINING NODES WILL BE HOT SPARE NODES. */
11728 /* --------------------------------------------------------------------- */
11729 if ((csystemnodes - cnoReplicas) >= cminHotSpareNodes) {
11730 jam();
11731 /* --------------------------------------------------------------------- */
11732 // We set the minimum number of hot spares according to users request
11733 // through the configuration file.
11734 /* --------------------------------------------------------------------- */
11735 tchsNoNodes = csystemnodes - cminHotSpareNodes;
11736 cnoHotSpare = cminHotSpareNodes;
11737 } else if (cminHotSpareNodes > 0) {
11738 jam();
11739 /* --------------------------------------------------------------------- */
11740 // The user requested at least one hot spare node and we will support him
11741 // in that.
11742 /* --------------------------------------------------------------------- */
11743 tchsNoNodes = csystemnodes - 1;
11744 cnoHotSpare = 1;
11745 } else {
11746 jam();
11747 /* --------------------------------------------------------------------- */
11748 // The user did not request any hot spare nodes so in this case we will
11749 // only use hot spare nodes if the number of nodes is such that we cannot
11750 // use all nodes as normal nodes.
11751 /* --------------------------------------------------------------------- */
11752 tchsNoNodes = csystemnodes;
11753 cnoHotSpare = 0;
11754 }//if
11755 } else {
11756 jam();
11757 /* --------------------------------------------------------------------- */
11758 // We only have enough to support the replicas. We will not have any hot
11759 // spares.
11760 /* --------------------------------------------------------------------- */
11761 tchsNoNodes = csystemnodes;
11762 cnoHotSpare = 0;
11763 }//if
11764 tchsTmp = tchsNoNodes - (cnoReplicas * (tchsNoNodes / cnoReplicas));
11765 cnoHotSpare = cnoHotSpare + tchsTmp;
11766 break;
11767 default:
11768 jam();
11769 ndbrequire(false);
11770 break;
11771 }//switch
11772 }//Dbdih::calculateHotSpare()
11773
11774 /*************************************************************************/
11775 /* CHECK IF THE NODE CRASH IS TO ESCALATE INTO A SYSTEM CRASH. WE COULD */
11776 /* DO THIS BECAUSE ALL REPLICAS OF SOME FRAGMENT ARE LOST. WE COULD ALSO */
11777 /* DO IT AFTER MANY NODE FAILURES THAT MAKE IT VERY DIFFICULT TO RESTORE */
11778 /* DATABASE AFTER A SYSTEM CRASH. IT MIGHT EVEN BE IMPOSSIBLE AND THIS */
11779 /* MUST BE AVOIDED EVEN MORE THAN AVOIDING SYSTEM CRASHES. */
11780 /*************************************************************************/
checkEscalation()11781 void Dbdih::checkEscalation()
11782 {
11783 Uint32 TnodeGroup[MAX_NDB_NODES];
11784 NodeRecordPtr nodePtr;
11785 Uint32 i;
11786 for (i = 0; i < MAX_NDB_NODES; i++) {
11787 TnodeGroup[i] = ZFALSE;
11788 }//for
11789 for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
11790 jam();
11791 ptrAss(nodePtr, nodeRecord);
11792 if (nodePtr.p->nodeStatus == NodeRecord::ALIVE &&
11793 nodePtr.p->activeStatus == Sysfile::NS_Active){
11794 ndbrequire(nodePtr.p->nodeGroup < MAX_NDB_NODES);
11795 TnodeGroup[nodePtr.p->nodeGroup] = ZTRUE;
11796 }
11797 }
11798 for (i = 0; i < cnoOfNodeGroups; i++) {
11799 jam();
11800 if (TnodeGroup[i] == ZFALSE) {
11801 jam();
11802 progError(__LINE__, NDBD_EXIT_LOST_NODE_GROUP, "Lost node group");
11803 }//if
11804 }//for
11805 }//Dbdih::checkEscalation()
11806
11807 /*************************************************************************/
11808 /* */
11809 /* MODULE: CHECK_KEEP_GCI */
11810 /* DESCRIPTION: CHECK FOR MINIMUM GCI RESTORABLE WITH NEW LOCAL */
11811 /* CHECKPOINT. */
11812 /*************************************************************************/
checkKeepGci(TabRecordPtr tabPtr,Uint32 fragId,Fragmentstore *,Uint32 replicaStartIndex)11813 void Dbdih::checkKeepGci(TabRecordPtr tabPtr, Uint32 fragId, Fragmentstore*,
11814 Uint32 replicaStartIndex)
11815 {
11816 ReplicaRecordPtr ckgReplicaPtr;
11817 ckgReplicaPtr.i = replicaStartIndex;
11818 while (ckgReplicaPtr.i != RNIL) {
11819 jam();
11820 ptrCheckGuard(ckgReplicaPtr, creplicaFileSize, replicaRecord);
11821 Uint32 keepGci;
11822 Uint32 oldestRestorableGci;
11823 findMinGci(ckgReplicaPtr, keepGci, oldestRestorableGci);
11824 if (keepGci < c_lcpState.keepGci) {
11825 jam();
11826 /* ------------------------------------------------------------------- */
11827 /* WE MUST KEEP LOG RECORDS SO THAT WE CAN USE ALL LOCAL CHECKPOINTS */
11828 /* THAT ARE AVAILABLE. THUS WE NEED TO CALCULATE THE MINIMUM OVER ALL */
11829 /* FRAGMENTS. */
11830 /* ------------------------------------------------------------------- */
11831 c_lcpState.keepGci = keepGci;
11832 }//if
11833 if (oldestRestorableGci > c_lcpState.oldestRestorableGci) {
11834 jam();
11835 c_lcpState.oldestRestorableGci = oldestRestorableGci;
11836 }//if
11837 ckgReplicaPtr.i = ckgReplicaPtr.p->nextReplica;
11838 }//while
11839 }//Dbdih::checkKeepGci()
11840
closeFile(Signal * signal,FileRecordPtr filePtr)11841 void Dbdih::closeFile(Signal* signal, FileRecordPtr filePtr)
11842 {
11843 signal->theData[0] = filePtr.p->fileRef;
11844 signal->theData[1] = reference();
11845 signal->theData[2] = filePtr.i;
11846 signal->theData[3] = ZCLOSE_NO_DELETE;
11847 sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, 4, JBA);
11848 }//Dbdih::closeFile()
11849
closeFileDelete(Signal * signal,FileRecordPtr filePtr)11850 void Dbdih::closeFileDelete(Signal* signal, FileRecordPtr filePtr)
11851 {
11852 signal->theData[0] = filePtr.p->fileRef;
11853 signal->theData[1] = reference();
11854 signal->theData[2] = filePtr.i;
11855 signal->theData[3] = ZCLOSE_DELETE;
11856 sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, 4, JBA);
11857 }//Dbdih::closeFileDelete()
11858
createFileRw(Signal * signal,FileRecordPtr filePtr)11859 void Dbdih::createFileRw(Signal* signal, FileRecordPtr filePtr)
11860 {
11861 signal->theData[0] = reference();
11862 signal->theData[1] = filePtr.i;
11863 signal->theData[2] = filePtr.p->fileName[0];
11864 signal->theData[3] = filePtr.p->fileName[1];
11865 signal->theData[4] = filePtr.p->fileName[2];
11866 signal->theData[5] = filePtr.p->fileName[3];
11867 signal->theData[6] = ZCREATE_READ_WRITE;
11868 sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
11869 }//Dbdih::createFileRw()
11870
emptyverificbuffer(Signal * signal,bool aContinueB)11871 void Dbdih::emptyverificbuffer(Signal* signal, bool aContinueB)
11872 {
11873 if(cfirstVerifyQueue == RNIL){
11874 jam();
11875 return;
11876 }//if
11877 ApiConnectRecordPtr localApiConnectptr;
11878 if(getBlockCommit() == false){
11879 jam();
11880 ndbrequire(cverifyQueueCounter > 0);
11881 cverifyQueueCounter--;
11882 localApiConnectptr.i = cfirstVerifyQueue;
11883 ptrCheckGuard(localApiConnectptr, capiConnectFileSize, apiConnectRecord);
11884 ndbrequire(localApiConnectptr.p->apiGci <= currentgcp);
11885 cfirstVerifyQueue = localApiConnectptr.p->nextApi;
11886 if (cfirstVerifyQueue == RNIL) {
11887 jam();
11888 ndbrequire(cverifyQueueCounter == 0);
11889 clastVerifyQueue = RNIL;
11890 }//if
11891 signal->theData[0] = localApiConnectptr.i;
11892 signal->theData[1] = currentgcp;
11893 sendSignal(clocaltcblockref, GSN_DIVERIFYCONF, signal, 2, JBB);
11894 if (aContinueB == true) {
11895 jam();
11896 //-----------------------------------------------------------------------
11897 // This emptying happened as part of a take-out process by continueb signals.
11898 // This ensures that we will empty the queue eventually. We will also empty
11899 // one item every time we insert one item to ensure that the list doesn't
11900 // grow when it is not blocked.
11901 //-----------------------------------------------------------------------
11902 signal->theData[0] = DihContinueB::ZEMPTY_VERIFY_QUEUE;
11903 sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
11904 }//if
11905 } else {
11906 jam();
11907 //-----------------------------------------------------------------------
11908 // We are blocked so it is no use in continuing the emptying of the
11909 // verify buffer. Whenever the block is removed the emptying will
11910 // restart.
11911 //-----------------------------------------------------------------------
11912 }
11913 return;
11914 }//Dbdih::emptyverificbuffer()
11915
11916 /*----------------------------------------------------------------*/
11917 /* FIND A FREE HOT SPARE IF AVAILABLE AND ALIVE. */
11918 /*----------------------------------------------------------------*/
findHotSpare()11919 Uint32 Dbdih::findHotSpare()
11920 {
11921 NodeRecordPtr nodePtr;
11922 for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
11923 jam();
11924 ptrAss(nodePtr, nodeRecord);
11925 if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
11926 if (nodePtr.p->activeStatus == Sysfile::NS_HotSpare) {
11927 jam();
11928 return nodePtr.i;
11929 }//if
11930 }//if
11931 }//for
11932 return RNIL;
11933 }//Dbdih::findHotSpare()
11934
11935 /*************************************************************************/
11936 /* FIND THE NODES FROM WHICH WE CAN EXECUTE THE LOG TO RESTORE THE */
11937 /* DATA NODE IN A SYSTEM RESTART. */
11938 /*************************************************************************/
findLogNodes(CreateReplicaRecord * createReplica,FragmentstorePtr fragPtr,Uint32 startGci,Uint32 stopGci)11939 bool Dbdih::findLogNodes(CreateReplicaRecord* createReplica,
11940 FragmentstorePtr fragPtr,
11941 Uint32 startGci,
11942 Uint32 stopGci)
11943 {
11944 ConstPtr<ReplicaRecord> flnReplicaPtr;
11945 flnReplicaPtr.i = createReplica->replicaRec;
11946 ptrCheckGuard(flnReplicaPtr, creplicaFileSize, replicaRecord);
11947 /* --------------------------------------------------------------------- */
11948 /* WE START BY CHECKING IF THE DATA NODE CAN HANDLE THE LOG ALL BY */
11949 /* ITSELF. THIS IS THE DESIRED BEHAVIOUR. IF THIS IS NOT POSSIBLE */
11950 /* THEN WE SEARCH FOR THE BEST POSSIBLE NODES AMONG THE NODES THAT */
11951 /* ARE PART OF THIS SYSTEM RESTART. */
11952 /* THIS CAN ONLY BE HANDLED BY THE LAST CRASHED REPLICA. */
11953 /* The condition is that the replica was created before or at the */
11954 /* time of the starting gci, in addition it must have been alive */
11955 /* at the time of the stopping gci. This is checked by two */
11956 /* conditions, the first checks replicaLastGci and the second */
11957 /* checks that it is also smaller than the last gci the node was */
11958 /* involved in. This is necessary to check since createGci is set */
11959 /* Last + 1 and sometimes startGci = stopGci + 1 and in that case */
11960 /* it could happen that replicaLastGci is set to -1 with CreateGci */
11961 /* set to LastGci + 1. */
11962 /* --------------------------------------------------------------------- */
11963 arrGuard(flnReplicaPtr.p->noCrashedReplicas, 8);
11964 const Uint32 noCrashed = flnReplicaPtr.p->noCrashedReplicas;
11965
11966 if (!(ERROR_INSERTED(7073) || ERROR_INSERTED(7074))&&
11967 (startGci >= flnReplicaPtr.p->createGci[noCrashed]) &&
11968 (stopGci <= flnReplicaPtr.p->replicaLastGci[noCrashed]) &&
11969 (stopGci <= SYSFILE->lastCompletedGCI[flnReplicaPtr.p->procNode])) {
11970 jam();
11971 /* --------------------------------------------------------------------- */
11972 /* WE FOUND ALL THE LOG RECORDS NEEDED IN THE DATA NODE. WE WILL */
11973 /* USE THOSE. */
11974 /* --------------------------------------------------------------------- */
11975 createReplica->noLogNodes = 1;
11976 createReplica->logStartGci[0] = startGci;
11977 createReplica->logStopGci[0] = stopGci;
11978 createReplica->logNodeId[0] = flnReplicaPtr.p->procNode;
11979 return true;
11980 }//if
11981 Uint32 logNode = 0;
11982 do {
11983 Uint32 fblStopGci;
11984 jam();
11985 if(!findBestLogNode(createReplica,
11986 fragPtr,
11987 startGci,
11988 stopGci,
11989 logNode,
11990 fblStopGci)){
11991 jam();
11992 return false;
11993 }
11994
11995 logNode++;
11996 if (fblStopGci >= stopGci) {
11997 jam();
11998 createReplica->noLogNodes = logNode;
11999 return true;
12000 }//if
12001 startGci = fblStopGci + 1;
12002 if (logNode >= 4) { // Why??
12003 jam();
12004 break;
12005 }//if
12006 } while (1);
12007 /* --------------------------------------------------------------------- */
12008 /* IT WAS NOT POSSIBLE TO RESTORE THE REPLICA. THIS CAN EITHER BE */
12009 /* BECAUSE OF LACKING NODES OR BECAUSE OF A REALLY SERIOUS PROBLEM.*/
12010 /* --------------------------------------------------------------------- */
12011 return false;
12012 }//Dbdih::findLogNodes()
12013
12014 /*************************************************************************/
12015 /* FIND THE BEST POSSIBLE LOG NODE TO EXECUTE THE LOG AS SPECIFIED */
12016 /* BY THE INPUT PARAMETERS. WE SCAN THROUGH ALL ALIVE REPLICAS. */
12017 /* THIS MEANS STORED, OLD_STORED */
12018 /*************************************************************************/
12019 bool
findBestLogNode(CreateReplicaRecord * createReplica,FragmentstorePtr fragPtr,Uint32 startGci,Uint32 stopGci,Uint32 logNode,Uint32 & fblStopGci)12020 Dbdih::findBestLogNode(CreateReplicaRecord* createReplica,
12021 FragmentstorePtr fragPtr,
12022 Uint32 startGci,
12023 Uint32 stopGci,
12024 Uint32 logNode,
12025 Uint32& fblStopGci)
12026 {
12027 ConstPtr<ReplicaRecord> fblFoundReplicaPtr;
12028 ConstPtr<ReplicaRecord> fblReplicaPtr;
12029 LINT_INIT(fblFoundReplicaPtr.p);
12030
12031 /* --------------------------------------------------------------------- */
12032 /* WE START WITH ZERO AS FOUND TO ENSURE THAT FIRST HIT WILL BE */
12033 /* BETTER. */
12034 /* --------------------------------------------------------------------- */
12035 fblStopGci = 0;
12036 fblReplicaPtr.i = fragPtr.p->storedReplicas;
12037 while (fblReplicaPtr.i != RNIL) {
12038 jam();
12039 ptrCheckGuard(fblReplicaPtr, creplicaFileSize, replicaRecord);
12040 if (checkNodeAlive(fblReplicaPtr.p->procNode)) {
12041 jam();
12042 Uint32 fliStopGci = findLogInterval(fblReplicaPtr, startGci);
12043 if (fliStopGci > fblStopGci) {
12044 jam();
12045 fblStopGci = fliStopGci;
12046 fblFoundReplicaPtr = fblReplicaPtr;
12047 }//if
12048 }//if
12049 fblReplicaPtr.i = fblReplicaPtr.p->nextReplica;
12050 }//while
12051 fblReplicaPtr.i = fragPtr.p->oldStoredReplicas;
12052 while (fblReplicaPtr.i != RNIL) {
12053 jam();
12054 ptrCheckGuard(fblReplicaPtr, creplicaFileSize, replicaRecord);
12055 if (checkNodeAlive(fblReplicaPtr.p->procNode)) {
12056 jam();
12057 Uint32 fliStopGci = findLogInterval(fblReplicaPtr, startGci);
12058 if (fliStopGci > fblStopGci) {
12059 jam();
12060 fblStopGci = fliStopGci;
12061 fblFoundReplicaPtr = fblReplicaPtr;
12062 }//if
12063 }//if
12064 fblReplicaPtr.i = fblReplicaPtr.p->nextReplica;
12065 }//while
12066 if (fblStopGci != 0) {
12067 jam();
12068 ndbrequire(logNode < MAX_LOG_EXEC);
12069 createReplica->logNodeId[logNode] = fblFoundReplicaPtr.p->procNode;
12070 createReplica->logStartGci[logNode] = startGci;
12071 if (fblStopGci >= stopGci) {
12072 jam();
12073 createReplica->logStopGci[logNode] = stopGci;
12074 } else {
12075 jam();
12076 createReplica->logStopGci[logNode] = fblStopGci;
12077 }//if
12078 }//if
12079
12080 return fblStopGci != 0;
12081 }//Dbdih::findBestLogNode()
12082
findLogInterval(ConstPtr<ReplicaRecord> replicaPtr,Uint32 startGci)12083 Uint32 Dbdih::findLogInterval(ConstPtr<ReplicaRecord> replicaPtr,
12084 Uint32 startGci)
12085 {
12086 ndbrequire(replicaPtr.p->noCrashedReplicas <= 8);
12087 Uint32 loopLimit = replicaPtr.p->noCrashedReplicas + 1;
12088 for (Uint32 i = 0; i < loopLimit; i++) {
12089 jam();
12090 if (replicaPtr.p->createGci[i] <= startGci) {
12091 if (replicaPtr.p->replicaLastGci[i] >= startGci) {
12092 jam();
12093 return replicaPtr.p->replicaLastGci[i];
12094 }//if
12095 }//if
12096 }//for
12097 return 0;
12098 }//Dbdih::findLogInterval()
12099
12100 /*************************************************************************/
12101 /* */
12102 /* MODULE: FIND THE MINIMUM GCI THAT THIS NODE HAS LOG RECORDS FOR.*/
12103 /*************************************************************************/
findMinGci(ReplicaRecordPtr fmgReplicaPtr,Uint32 & keepGci,Uint32 & oldestRestorableGci)12104 void Dbdih::findMinGci(ReplicaRecordPtr fmgReplicaPtr,
12105 Uint32& keepGci,
12106 Uint32& oldestRestorableGci)
12107 {
12108 Uint32 nextLcpNo;
12109 Uint32 lcpNo;
12110 for (Uint32 i = 0; i < MAX_LCP_STORED; i++) {
12111 jam();
12112 if ((fmgReplicaPtr.p->lcpStatus[i] == ZVALID) &&
12113 ((fmgReplicaPtr.p->lcpId[i] + MAX_LCP_STORED) <= (SYSFILE->latestLCP_ID + 1))) {
12114 jam();
12115 /*--------------------------------------------------------------------*/
12116 // We invalidate the checkpoint we are preparing to overwrite.
12117 // The LCP id is still the old lcp id,
12118 // this is the reason of comparing with lcpId + 1.
12119 /*---------------------------------------------------------------------*/
12120 fmgReplicaPtr.p->lcpStatus[i] = ZINVALID;
12121 }//if
12122 }//for
12123 keepGci = (Uint32)-1;
12124 oldestRestorableGci = 0;
12125 nextLcpNo = fmgReplicaPtr.p->nextLcp;
12126 lcpNo = fmgReplicaPtr.p->nextLcp;
12127 do {
12128 ndbrequire(lcpNo < MAX_LCP_STORED);
12129 if (fmgReplicaPtr.p->lcpStatus[lcpNo] == ZVALID)
12130 {
12131 jam();
12132 keepGci = fmgReplicaPtr.p->maxGciCompleted[lcpNo];
12133 oldestRestorableGci = fmgReplicaPtr.p->maxGciStarted[lcpNo];
12134 ndbassert(fmgReplicaPtr.p->maxGciStarted[lcpNo] <c_newest_restorable_gci);
12135 return;
12136 } else {
12137 jam();
12138 if (fmgReplicaPtr.p->createGci[0] == fmgReplicaPtr.p->initialGci) {
12139 jam();
12140 /*-------------------------------------------------------------------
12141 * WE CAN STILL RESTORE THIS REPLICA WITHOUT ANY LOCAL CHECKPOINTS BY
12142 * ONLY USING THE LOG. IF THIS IS NOT POSSIBLE THEN WE REPORT THE LAST
12143 * VALID LOCAL CHECKPOINT AS THE MINIMUM GCI RECOVERABLE.
12144 *-----------------------------------------------------------------*/
12145 keepGci = fmgReplicaPtr.p->createGci[0];
12146 }//if
12147 }//if
12148 lcpNo = prevLcpNo(lcpNo);
12149 } while (lcpNo != nextLcpNo);
12150 return;
12151 }//Dbdih::findMinGci()
12152
findStartGci(ConstPtr<ReplicaRecord> replicaPtr,Uint32 stopGci,Uint32 & startGci,Uint32 & lcpNo)12153 bool Dbdih::findStartGci(ConstPtr<ReplicaRecord> replicaPtr,
12154 Uint32 stopGci,
12155 Uint32& startGci,
12156 Uint32& lcpNo)
12157 {
12158 lcpNo = replicaPtr.p->nextLcp;
12159 const Uint32 startLcpNo = lcpNo;
12160 do {
12161 lcpNo = prevLcpNo(lcpNo);
12162 ndbrequire(lcpNo < MAX_LCP_STORED);
12163 if (replicaPtr.p->lcpStatus[lcpNo] == ZVALID) {
12164 if (replicaPtr.p->maxGciStarted[lcpNo] < stopGci) {
12165 jam();
12166 /* ----------------------------------------------------------------- */
12167 /* WE HAVE FOUND A USEFUL LOCAL CHECKPOINT THAT CAN BE USED FOR */
12168 /* RESTARTING THIS FRAGMENT REPLICA. */
12169 /* ----------------------------------------------------------------- */
12170 startGci = replicaPtr.p->maxGciCompleted[lcpNo] + 1;
12171 return true;
12172 }
12173 }
12174 } while (lcpNo != startLcpNo);
12175 /* --------------------------------------------------------------------- */
12176 /* NO VALID LOCAL CHECKPOINT WAS AVAILABLE. WE WILL ADD THE */
12177 /* FRAGMENT. THUS THE NEXT LCP MUST BE SET TO ZERO. */
12178 /* WE MUST EXECUTE THE LOG FROM THE INITIAL GLOBAL CHECKPOINT WHEN */
12179 /* THE TABLE WAS CREATED. */
12180 /* --------------------------------------------------------------------- */
12181 startGci = replicaPtr.p->initialGci;
12182 ndbrequire(replicaPtr.p->nextLcp == 0);
12183 return false;
12184 }//Dbdih::findStartGci()
12185
12186 /**************************************************************************/
12187 /* ---------------------------------------------------------------------- */
12188 /* FIND A TAKE OVER REPLICA WHICH IS TO BE STARTED OR COMMITTED WHEN*/
12189 /* TAKING OVER A FAILED NODE. */
12190 /* ---------------------------------------------------------------------- */
12191 /*************************************************************************/
findToReplica(TakeOverRecord * regTakeOver,Uint32 replicaType,FragmentstorePtr fragPtr,ReplicaRecordPtr & ftrReplicaPtr)12192 void Dbdih::findToReplica(TakeOverRecord* regTakeOver,
12193 Uint32 replicaType,
12194 FragmentstorePtr fragPtr,
12195 ReplicaRecordPtr& ftrReplicaPtr)
12196 {
12197 switch (replicaType) {
12198 case CreateFragReq::STORED:
12199 case CreateFragReq::COMMIT_STORED:
12200 /* ----------------------------------------------------------------------*/
12201 /* HERE WE SEARCH FOR STORED REPLICAS. THE REPLICA MUST BE STORED IN THE */
12202 /* SECTION FOR OLD STORED REPLICAS SINCE WE HAVE NOT TAKEN OVER YET. */
12203 /* ----------------------------------------------------------------------*/
12204 ftrReplicaPtr.i = fragPtr.p->oldStoredReplicas;
12205 while (ftrReplicaPtr.i != RNIL) {
12206 ptrCheckGuard(ftrReplicaPtr, creplicaFileSize, replicaRecord);
12207 if (ftrReplicaPtr.p->procNode == regTakeOver->toStartingNode) {
12208 jam();
12209 return;
12210 } else {
12211 if (ftrReplicaPtr.p->procNode == regTakeOver->toFailedNode) {
12212 jam();
12213 return;
12214 } else {
12215 jam();
12216 ftrReplicaPtr.i = ftrReplicaPtr.p->nextReplica;
12217 }//if
12218 }//if
12219 }//while
12220 break;
12221 default:
12222 ndbrequire(false);
12223 break;
12224 }//switch
12225 }//Dbdih::findToReplica()
12226
initCommonData()12227 void Dbdih::initCommonData()
12228 {
12229 c_blockCommit = false;
12230 c_blockCommitNo = 0;
12231 c_createFragmentLock = RNIL;
12232 c_endToLock = RNIL;
12233 cfailurenr = 1;
12234 cfirstAliveNode = RNIL;
12235 cfirstDeadNode = RNIL;
12236 cfirstVerifyQueue = RNIL;
12237 cgckptflag = false;
12238 cgcpDelay = 0;
12239 cgcpMasterTakeOverState = GMTOS_IDLE;
12240 cgcpOrderBlocked = 0;
12241 cgcpParticipantState = GCP_PARTICIPANT_READY;
12242 cgcpSameCounter = 0;
12243 cgcpStartCounter = 0;
12244 cgcpStatus = GCP_READY;
12245
12246 clastVerifyQueue = RNIL;
12247 c_lcpMasterTakeOverState.set(LMTOS_IDLE, __LINE__);
12248
12249 c_lcpState.clcpDelay = 0;
12250 c_lcpState.lcpStart = ZIDLE;
12251 c_lcpState.lcpStopGcp = 0;
12252 c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
12253 c_lcpState.currentFragment.tableId = 0;
12254 c_lcpState.currentFragment.fragmentId = 0;
12255 c_lcpState.noOfLcpFragRepOutstanding = 0;
12256 c_lcpState.keepGci = 0;
12257 c_lcpState.oldestRestorableGci = 0;
12258 c_lcpState.ctcCounter = 0;
12259 c_lcpState.ctimer = 0;
12260 c_lcpState.immediateLcpStart = false;
12261 c_lcpState.m_MASTER_LCPREQ_Received = false;
12262
12263 cmasterdihref = 0;
12264 cmasterNodeId = 0;
12265 cmasterState = MASTER_IDLE;
12266 cmasterTakeOverNode = 0;
12267 cnewgcp = 0;
12268 cnoHotSpare = 0;
12269 cnoOfActiveTables = 0;
12270 cnoOfNodeGroups = 0;
12271 c_nextNodeGroup = 0;
12272 cnoReplicas = 0;
12273 coldgcp = 0;
12274 coldGcpId = 0;
12275 coldGcpStatus = cgcpStatus;
12276 con_lineNodes = 0;
12277 creceivedfrag = 0;
12278 crestartGci = 0;
12279 crestartInfoFile[0] = RNIL;
12280 crestartInfoFile[1] = RNIL;
12281 cstartGcpNow = false;
12282 cstartPhase = 0;
12283 c_startToLock = RNIL;
12284 cstarttype = (Uint32)-1;
12285 csystemnodes = 0;
12286 c_updateToLock = RNIL;
12287 currentgcp = 0;
12288 c_newest_restorable_gci = 0;
12289 cverifyQueueCounter = 0;
12290 cwaitLcpSr = false;
12291 c_nextLogPart = 0;
12292
12293 nodeResetStart();
12294 c_nodeStartMaster.wait = ZFALSE;
12295
12296 memset(&sysfileData[0], 0, sizeof(sysfileData));
12297
12298 const ndb_mgm_configuration_iterator * p =
12299 m_ctx.m_config.getOwnConfigIterator();
12300 ndbrequire(p != 0);
12301
12302 c_lcpState.clcpDelay = 20;
12303 ndb_mgm_get_int_parameter(p, CFG_DB_LCP_INTERVAL, &c_lcpState.clcpDelay);
12304 c_lcpState.clcpDelay = c_lcpState.clcpDelay > 31 ? 31 : c_lcpState.clcpDelay;
12305
12306 cminHotSpareNodes = 0;
12307 //ndb_mgm_get_int_parameter(p, CFG_DB_MIN_HOT_SPARES, &cminHotSpareNodes);
12308 cminHotSpareNodes = cminHotSpareNodes > 2 ? 2 : cminHotSpareNodes;
12309
12310 cnoReplicas = 1;
12311 ndb_mgm_get_int_parameter(p, CFG_DB_NO_REPLICAS, &cnoReplicas);
12312 if (cnoReplicas > 4)
12313 {
12314 progError(__LINE__, NDBD_EXIT_INVALID_CONFIG,
12315 "Only up to four replicas are supported. Check NoOfReplicas.");
12316 }
12317
12318 cgcpDelay = 2000;
12319 ndb_mgm_get_int_parameter(p, CFG_DB_GCP_INTERVAL, &cgcpDelay);
12320 cgcpDelay = cgcpDelay > 60000 ? 60000 : (cgcpDelay < 10 ? 10 : cgcpDelay);
12321 }//Dbdih::initCommonData()
12322
initFragstore(FragmentstorePtr fragPtr)12323 void Dbdih::initFragstore(FragmentstorePtr fragPtr)
12324 {
12325 fragPtr.p->storedReplicas = RNIL;
12326 fragPtr.p->oldStoredReplicas = RNIL;
12327
12328 fragPtr.p->noStoredReplicas = 0;
12329 fragPtr.p->noOldStoredReplicas = 0;
12330 fragPtr.p->fragReplicas = 0;
12331 fragPtr.p->preferredPrimary = 0;
12332
12333 for (Uint32 i = 0; i < MAX_REPLICAS; i++)
12334 fragPtr.p->activeNodes[i] = 0;
12335
12336 fragPtr.p->noLcpReplicas = 0;
12337 fragPtr.p->distributionKey = 0;
12338 }//Dbdih::initFragstore()
12339
12340 /*************************************************************************/
12341 /* */
12342 /* MODULE: INIT_RESTART_INFO */
12343 /* DESCRIPTION: INITIATE RESTART INFO VARIABLE AND VARIABLES FOR */
12344 /* GLOBAL CHECKPOINTS. */
12345 /*************************************************************************/
initRestartInfo()12346 void Dbdih::initRestartInfo()
12347 {
12348 Uint32 i;
12349 for (i = 0; i < MAX_NDB_NODES; i++) {
12350 SYSFILE->lastCompletedGCI[i] = 0;
12351 }//for
12352 NodeRecordPtr nodePtr;
12353 nodePtr.i = cfirstAliveNode;
12354 do {
12355 jam();
12356 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
12357 SYSFILE->lastCompletedGCI[nodePtr.i] = 1;
12358 /* FIRST GCP = 1 ALREADY SET BY LQH */
12359 nodePtr.i = nodePtr.p->nextNode;
12360 } while (nodePtr.i != RNIL);
12361 coldgcp = 1;
12362 currentgcp = 2;
12363 cnewgcp = 2;
12364 crestartGci = 1;
12365 c_newest_restorable_gci = 1;
12366
12367 SYSFILE->keepGCI = 1;
12368 SYSFILE->oldestRestorableGCI = 1;
12369 SYSFILE->newestRestorableGCI = 1;
12370 SYSFILE->systemRestartBits = 0;
12371 for (i = 0; i < NodeBitmask::Size; i++) {
12372 SYSFILE->lcpActive[0] = 0;
12373 }//for
12374 for (i = 0; i < Sysfile::TAKE_OVER_SIZE; i++) {
12375 SYSFILE->takeOver[i] = 0;
12376 }//for
12377 Sysfile::setInitialStartOngoing(SYSFILE->systemRestartBits);
12378 srand(time(0));
12379 globalData.m_restart_seq = SYSFILE->m_restart_seq = 0;
12380 }//Dbdih::initRestartInfo()
12381
12382 /*--------------------------------------------------------------------*/
12383 /* NODE GROUP BITS ARE INITIALISED BEFORE THIS. */
12384 /* NODE ACTIVE BITS ARE INITIALISED BEFORE THIS. */
12385 /*--------------------------------------------------------------------*/
12386 /*************************************************************************/
12387 /* */
12388 /* MODULE: INIT_RESTORABLE_GCI_FILES */
12389 /* DESCRIPTION: THE SUBROUTINE SETS UP THE FILES THAT REFERS TO THE*/
12390 /* FILES THAT KEEP THE VARIABLE CRESTART_INFO */
12391 /*************************************************************************/
initRestorableGciFiles()12392 void Dbdih::initRestorableGciFiles()
12393 {
12394 Uint32 tirgTmp;
12395 FileRecordPtr filePtr;
12396 seizeFile(filePtr);
12397 filePtr.p->tabRef = RNIL;
12398 filePtr.p->fileType = FileRecord::GCP_FILE;
12399 filePtr.p->reqStatus = FileRecord::IDLE;
12400 filePtr.p->fileStatus = FileRecord::CLOSED;
12401 crestartInfoFile[0] = filePtr.i;
12402 filePtr.p->fileName[0] = (Uint32)-1; /* T DIRECTORY NOT USED */
12403 filePtr.p->fileName[1] = (Uint32)-1; /* F DIRECTORY NOT USED */
12404 filePtr.p->fileName[2] = (Uint32)-1; /* S PART IGNORED */
12405 tirgTmp = 1; /* FILE NAME VERSION 1 */
12406 tirgTmp = (tirgTmp << 8) + 6; /* .SYSFILE */
12407 tirgTmp = (tirgTmp << 8) + 1; /* D1 DIRECTORY */
12408 tirgTmp = (tirgTmp << 8) + 0; /* P0 FILE NAME */
12409 filePtr.p->fileName[3] = tirgTmp;
12410 /* --------------------------------------------------------------------- */
12411 /* THE NAME BECOMES /D1/DBDICT/S0.SYSFILE */
12412 /* --------------------------------------------------------------------- */
12413 seizeFile(filePtr);
12414 filePtr.p->tabRef = RNIL;
12415 filePtr.p->fileType = FileRecord::GCP_FILE;
12416 filePtr.p->reqStatus = FileRecord::IDLE;
12417 filePtr.p->fileStatus = FileRecord::CLOSED;
12418 crestartInfoFile[1] = filePtr.i;
12419 filePtr.p->fileName[0] = (Uint32)-1; /* T DIRECTORY NOT USED */
12420 filePtr.p->fileName[1] = (Uint32)-1; /* F DIRECTORY NOT USED */
12421 filePtr.p->fileName[2] = (Uint32)-1; /* S PART IGNORED */
12422 tirgTmp = 1; /* FILE NAME VERSION 1 */
12423 tirgTmp = (tirgTmp << 8) + 6; /* .SYSFILE */
12424 tirgTmp = (tirgTmp << 8) + 2; /* D1 DIRECTORY */
12425 tirgTmp = (tirgTmp << 8) + 0; /* P0 FILE NAME */
12426 filePtr.p->fileName[3] = tirgTmp;
12427 /* --------------------------------------------------------------------- */
12428 /* THE NAME BECOMES /D2/DBDICT/P0.SYSFILE */
12429 /* --------------------------------------------------------------------- */
12430 }//Dbdih::initRestorableGciFiles()
12431
initTable(TabRecordPtr tabPtr)12432 void Dbdih::initTable(TabRecordPtr tabPtr)
12433 {
12434 tabPtr.p->noOfFragChunks = 0;
12435 tabPtr.p->method = TabRecord::NOTDEFINED;
12436 tabPtr.p->tabStatus = TabRecord::TS_IDLE;
12437 tabPtr.p->noOfWords = 0;
12438 tabPtr.p->noPages = 0;
12439 tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
12440 tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
12441 tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
12442 tabPtr.p->noOfBackups = 0;
12443 tabPtr.p->kvalue = 0;
12444 tabPtr.p->hashpointer = (Uint32)-1;
12445 tabPtr.p->mask = 0;
12446 tabPtr.p->tabStorage = TabRecord::ST_NORMAL;
12447 tabPtr.p->tabErrorCode = 0;
12448 tabPtr.p->schemaVersion = (Uint32)-1;
12449 tabPtr.p->tabRemoveNode = RNIL;
12450 tabPtr.p->totalfragments = (Uint32)-1;
12451 tabPtr.p->connectrec = RNIL;
12452 tabPtr.p->tabFile[0] = RNIL;
12453 tabPtr.p->tabFile[1] = RNIL;
12454 tabPtr.p->m_dropTab.tabUserRef = 0;
12455 tabPtr.p->m_dropTab.tabUserPtr = RNIL;
12456 Uint32 i;
12457 for (i = 0; i < MAX_NDB_NODES; i++) {
12458 tabPtr.p->startFid[i] = RNIL;
12459 }//for
12460 for (i = 0; i < 8; i++) {
12461 tabPtr.p->pageRef[i] = RNIL;
12462 }//for
12463 tabPtr.p->tableType = DictTabInfo::UndefTableType;
12464 }//Dbdih::initTable()
12465
12466 /*************************************************************************/
12467 /* */
12468 /* MODULE: INIT_TABLE_FILES */
12469 /* DESCRIPTION: THE SUBROUTINE SETS UP THE FILES THAT REFERS TO THE*/
12470 /* FILES THAT KEEP THE TABLE FRAGMENTATION DESCRIPTION. */
12471 /*************************************************************************/
initTableFile(TabRecordPtr tabPtr)12472 void Dbdih::initTableFile(TabRecordPtr tabPtr)
12473 {
12474 Uint32 titfTmp;
12475 FileRecordPtr filePtr;
12476 seizeFile(filePtr);
12477 filePtr.p->tabRef = tabPtr.i;
12478 filePtr.p->fileType = FileRecord::TABLE_FILE;
12479 filePtr.p->reqStatus = FileRecord::IDLE;
12480 filePtr.p->fileStatus = FileRecord::CLOSED;
12481 tabPtr.p->tabFile[0] = filePtr.i;
12482 filePtr.p->fileName[0] = (Uint32)-1; /* T DIRECTORY NOT USED */
12483 filePtr.p->fileName[1] = (Uint32)-1; /* F DIRECTORY NOT USED */
12484 filePtr.p->fileName[2] = tabPtr.i; /* Stid FILE NAME */
12485 titfTmp = 1; /* FILE NAME VERSION 1 */
12486 titfTmp = (titfTmp << 8) + 3; /* .FRAGLIST */
12487 titfTmp = (titfTmp << 8) + 1; /* D1 DIRECTORY */
12488 titfTmp = (titfTmp << 8) + 255; /* P PART IGNORED */
12489 filePtr.p->fileName[3] = titfTmp;
12490 /* --------------------------------------------------------------------- */
12491 /* THE NAME BECOMES /D1/DBDICT/Stid.FRAGLIST */
12492 /* --------------------------------------------------------------------- */
12493 seizeFile(filePtr);
12494 filePtr.p->tabRef = tabPtr.i;
12495 filePtr.p->fileType = FileRecord::TABLE_FILE;
12496 filePtr.p->reqStatus = FileRecord::IDLE;
12497 filePtr.p->fileStatus = FileRecord::CLOSED;
12498 tabPtr.p->tabFile[1] = filePtr.i;
12499 filePtr.p->fileName[0] = (Uint32)-1; /* T DIRECTORY NOT USED */
12500 filePtr.p->fileName[1] = (Uint32)-1; /* F DIRECTORY NOT USED */
12501 filePtr.p->fileName[2] = tabPtr.i; /* Stid FILE NAME */
12502 titfTmp = 1; /* FILE NAME VERSION 1 */
12503 titfTmp = (titfTmp << 8) + 3; /* .FRAGLIST */
12504 titfTmp = (titfTmp << 8) + 2; /* D2 DIRECTORY */
12505 titfTmp = (titfTmp << 8) + 255; /* P PART IGNORED */
12506 filePtr.p->fileName[3] = titfTmp;
12507 /* --------------------------------------------------------------------- */
12508 /* THE NAME BECOMES /D2/DBDICT/Stid.FRAGLIST */
12509 /* --------------------------------------------------------------------- */
12510 }//Dbdih::initTableFile()
12511
initialiseRecordsLab(Signal * signal,Uint32 stepNo,Uint32 retRef,Uint32 retData)12512 void Dbdih::initialiseRecordsLab(Signal* signal,
12513 Uint32 stepNo, Uint32 retRef, Uint32 retData)
12514 {
12515 switch (stepNo) {
12516 case 0:
12517 jam();
12518 initCommonData();
12519 break;
12520 case 1:{
12521 ApiConnectRecordPtr apiConnectptr;
12522 jam();
12523 /******** INTIALIZING API CONNECT RECORDS ********/
12524 for (apiConnectptr.i = 0; apiConnectptr.i < capiConnectFileSize; apiConnectptr.i++) {
12525 refresh_watch_dog();
12526 ptrAss(apiConnectptr, apiConnectRecord);
12527 apiConnectptr.p->nextApi = RNIL;
12528 }//for
12529 jam();
12530 break;
12531 }
12532 case 2:{
12533 ConnectRecordPtr connectPtr;
12534 jam();
12535 /****** CONNECT ******/
12536 for (connectPtr.i = 0; connectPtr.i < cconnectFileSize; connectPtr.i++) {
12537 refresh_watch_dog();
12538 ptrAss(connectPtr, connectRecord);
12539 connectPtr.p->userpointer = RNIL;
12540 connectPtr.p->userblockref = ZNIL;
12541 connectPtr.p->connectState = ConnectRecord::FREE;
12542 connectPtr.p->table = RNIL;
12543 connectPtr.p->nfConnect = connectPtr.i + 1;
12544 }//for
12545 connectPtr.i = cconnectFileSize - 1;
12546 ptrAss(connectPtr, connectRecord);
12547 connectPtr.p->nfConnect = RNIL;
12548 cfirstconnect = 0;
12549 break;
12550 }
12551 case 3:
12552 {
12553 FileRecordPtr filePtr;
12554 jam();
12555 /******** INTIALIZING FILE RECORDS ********/
12556 for (filePtr.i = 0; filePtr.i < cfileFileSize; filePtr.i++) {
12557 ptrAss(filePtr, fileRecord);
12558 filePtr.p->nextFile = filePtr.i + 1;
12559 filePtr.p->fileStatus = FileRecord::CLOSED;
12560 filePtr.p->reqStatus = FileRecord::IDLE;
12561 }//for
12562 filePtr.i = cfileFileSize - 1;
12563 ptrAss(filePtr, fileRecord);
12564 filePtr.p->nextFile = RNIL;
12565 cfirstfreeFile = 0;
12566 initRestorableGciFiles();
12567 break;
12568 }
12569 case 4:
12570 jam();
12571 initialiseFragstore();
12572 break;
12573 case 5:
12574 {
12575 jam();
12576 /******* NODE GROUP RECORD ******/
12577 /******* NODE RECORD ******/
12578 NodeGroupRecordPtr loopNGPtr;
12579 for (loopNGPtr.i = 0; loopNGPtr.i < MAX_NDB_NODES; loopNGPtr.i++) {
12580 ptrAss(loopNGPtr, nodeGroupRecord);
12581 loopNGPtr.p->nodesInGroup[0] = RNIL;
12582 loopNGPtr.p->nodesInGroup[1] = RNIL;
12583 loopNGPtr.p->nodesInGroup[2] = RNIL;
12584 loopNGPtr.p->nodesInGroup[3] = RNIL;
12585 loopNGPtr.p->nextReplicaNode = 0;
12586 loopNGPtr.p->nodeCount = 0;
12587 loopNGPtr.p->activeTakeOver = false;
12588 }//for
12589 NodeRecordPtr nodePtr;
12590 for (nodePtr.i = 0; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
12591 ptrAss(nodePtr, nodeRecord);
12592 new (nodePtr.p) NodeRecord();
12593 }//for
12594 break;
12595 }
12596 case 6:
12597 {
12598 PageRecordPtr pagePtr;
12599 jam();
12600 /******* PAGE RECORD ******/
12601 for (pagePtr.i = 0; pagePtr.i < cpageFileSize; pagePtr.i++) {
12602 refresh_watch_dog();
12603 ptrAss(pagePtr, pageRecord);
12604 pagePtr.p->nextfreepage = pagePtr.i + 1;
12605 }//for
12606 pagePtr.i = cpageFileSize - 1;
12607 ptrAss(pagePtr, pageRecord);
12608 pagePtr.p->nextfreepage = RNIL;
12609 cfirstfreepage = 0;
12610 break;
12611 }
12612 case 7:
12613 {
12614 ReplicaRecordPtr initReplicaPtr;
12615 jam();
12616 /******* REPLICA RECORD ******/
12617 for (initReplicaPtr.i = 0; initReplicaPtr.i < creplicaFileSize;
12618 initReplicaPtr.i++) {
12619 refresh_watch_dog();
12620 ptrAss(initReplicaPtr, replicaRecord);
12621 initReplicaPtr.p->lcpIdStarted = 0;
12622 initReplicaPtr.p->lcpOngoingFlag = false;
12623 initReplicaPtr.p->nextReplica = initReplicaPtr.i + 1;
12624 }//for
12625 initReplicaPtr.i = creplicaFileSize - 1;
12626 ptrAss(initReplicaPtr, replicaRecord);
12627 initReplicaPtr.p->nextReplica = RNIL;
12628 cnoFreeReplicaRec = creplicaFileSize;
12629 cfirstfreeReplica = 0;
12630 break;
12631 }
12632 case 8:
12633 {
12634 TabRecordPtr loopTabptr;
12635 jam();
12636 /********* TAB-DESCRIPTOR ********/
12637 for (loopTabptr.i = 0; loopTabptr.i < ctabFileSize; loopTabptr.i++) {
12638 ptrAss(loopTabptr, tabRecord);
12639 refresh_watch_dog();
12640 initTable(loopTabptr);
12641 }//for
12642 break;
12643 }
12644 case 9:
12645 {
12646 TakeOverRecordPtr takeOverPtr;
12647 jam();
12648 cfirstfreeTakeOver = RNIL;
12649 for (takeOverPtr.i = 0; takeOverPtr.i < MAX_NDB_NODES; takeOverPtr.i++) {
12650 ptrAss(takeOverPtr, takeOverRecord);
12651 initTakeOver(takeOverPtr);
12652 releaseTakeOver(takeOverPtr.i);
12653 }//for
12654
12655 ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
12656 conf->senderRef = reference();
12657 conf->senderData = retData;
12658 sendSignal(retRef, GSN_READ_CONFIG_CONF, signal,
12659 ReadConfigConf::SignalLength, JBB);
12660 return;
12661 break;
12662 }
12663 default:
12664 ndbrequire(false);
12665 break;
12666 }//switch
12667 jam();
12668 /* ---------------------------------------------------------------------- */
12669 /* SEND REAL-TIME BREAK DURING INIT OF VARIABLES DURING SYSTEM RESTART. */
12670 /* ---------------------------------------------------------------------- */
12671 signal->theData[0] = DihContinueB::ZINITIALISE_RECORDS;
12672 signal->theData[1] = stepNo + 1;
12673 signal->theData[2] = retRef;
12674 signal->theData[3] = retData;
12675 sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
12676 }//Dbdih::initialiseRecordsLab()
12677
12678 /*************************************************************************/
12679 /* INSERT THE NODE INTO THE LINKED LIST OF NODES INVOLVED ALL */
12680 /* DISTRIBUTED PROTOCOLS (EXCEPT GCP PROTOCOL THAT USES THE DIH */
12681 /* LINKED LIST INSTEAD). */
12682 /*************************************************************************/
insertAlive(NodeRecordPtr newNodePtr)12683 void Dbdih::insertAlive(NodeRecordPtr newNodePtr)
12684 {
12685 NodeRecordPtr nodePtr;
12686
12687 nodePtr.i = cfirstAliveNode;
12688 if (nodePtr.i == RNIL) {
12689 jam();
12690 cfirstAliveNode = newNodePtr.i;
12691 } else {
12692 do {
12693 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
12694 if (nodePtr.p->nextNode == RNIL) {
12695 jam();
12696 nodePtr.p->nextNode = newNodePtr.i;
12697 break;
12698 } else {
12699 jam();
12700 nodePtr.i = nodePtr.p->nextNode;
12701 }//if
12702 } while (1);
12703 }//if
12704 newNodePtr.p->nextNode = RNIL;
12705 }//Dbdih::insertAlive()
12706
insertBackup(FragmentstorePtr fragPtr,Uint32 nodeId)12707 void Dbdih::insertBackup(FragmentstorePtr fragPtr, Uint32 nodeId)
12708 {
12709 for (Uint32 i = fragPtr.p->fragReplicas; i > 1; i--) {
12710 jam();
12711 ndbrequire(i < MAX_REPLICAS && i > 0);
12712 fragPtr.p->activeNodes[i] = fragPtr.p->activeNodes[i - 1];
12713 }//for
12714 fragPtr.p->activeNodes[1] = nodeId;
12715 fragPtr.p->fragReplicas++;
12716 }//Dbdih::insertBackup()
12717
insertDeadNode(NodeRecordPtr newNodePtr)12718 void Dbdih::insertDeadNode(NodeRecordPtr newNodePtr)
12719 {
12720 NodeRecordPtr nodePtr;
12721
12722 nodePtr.i = cfirstDeadNode;
12723 if (nodePtr.i == RNIL) {
12724 jam();
12725 cfirstDeadNode = newNodePtr.i;
12726 } else {
12727 do {
12728 jam();
12729 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
12730 if (nodePtr.p->nextNode == RNIL) {
12731 jam();
12732 nodePtr.p->nextNode = newNodePtr.i;
12733 break;
12734 } else {
12735 jam();
12736 nodePtr.i = nodePtr.p->nextNode;
12737 }//if
12738 } while (1);
12739 }//if
12740 newNodePtr.p->nextNode = RNIL;
12741 }//Dbdih::insertDeadNode()
12742
linkOldStoredReplica(FragmentstorePtr fragPtr,ReplicaRecordPtr replicatePtr)12743 void Dbdih::linkOldStoredReplica(FragmentstorePtr fragPtr,
12744 ReplicaRecordPtr replicatePtr)
12745 {
12746 ReplicaRecordPtr losReplicaPtr;
12747
12748 replicatePtr.p->nextReplica = RNIL;
12749 fragPtr.p->noOldStoredReplicas++;
12750 losReplicaPtr.i = fragPtr.p->oldStoredReplicas;
12751 if (losReplicaPtr.i == RNIL) {
12752 jam();
12753 fragPtr.p->oldStoredReplicas = replicatePtr.i;
12754 return;
12755 }//if
12756 ptrCheckGuard(losReplicaPtr, creplicaFileSize, replicaRecord);
12757 while (losReplicaPtr.p->nextReplica != RNIL) {
12758 jam();
12759 losReplicaPtr.i = losReplicaPtr.p->nextReplica;
12760 ptrCheckGuard(losReplicaPtr, creplicaFileSize, replicaRecord);
12761 }//if
12762 losReplicaPtr.p->nextReplica = replicatePtr.i;
12763 }//Dbdih::linkOldStoredReplica()
12764
linkStoredReplica(FragmentstorePtr fragPtr,ReplicaRecordPtr replicatePtr)12765 void Dbdih::linkStoredReplica(FragmentstorePtr fragPtr,
12766 ReplicaRecordPtr replicatePtr)
12767 {
12768 ReplicaRecordPtr lsrReplicaPtr;
12769
12770 fragPtr.p->noStoredReplicas++;
12771 replicatePtr.p->nextReplica = RNIL;
12772 lsrReplicaPtr.i = fragPtr.p->storedReplicas;
12773 if (fragPtr.p->storedReplicas == RNIL) {
12774 jam();
12775 fragPtr.p->storedReplicas = replicatePtr.i;
12776 return;
12777 }//if
12778 ptrCheckGuard(lsrReplicaPtr, creplicaFileSize, replicaRecord);
12779 while (lsrReplicaPtr.p->nextReplica != RNIL) {
12780 jam();
12781 lsrReplicaPtr.i = lsrReplicaPtr.p->nextReplica;
12782 ptrCheckGuard(lsrReplicaPtr, creplicaFileSize, replicaRecord);
12783 }//if
12784 lsrReplicaPtr.p->nextReplica = replicatePtr.i;
12785 }//Dbdih::linkStoredReplica()
12786
12787 /*************************************************************************/
12788 /* MAKE NODE GROUPS BASED ON THE LIST OF NODES RECEIVED FROM CNTR */
12789 /*************************************************************************/
makeNodeGroups(Uint32 nodeArray[])12790 void Dbdih::makeNodeGroups(Uint32 nodeArray[])
12791 {
12792 NodeRecordPtr mngNodeptr;
12793 Uint32 tmngNode;
12794 Uint32 tmngNodeGroup;
12795 Uint32 tmngLimit;
12796 Uint32 i, j;
12797
12798 /**-----------------------------------------------------------------------
12799 * ASSIGN ALL ACTIVE NODES INTO NODE GROUPS. HOT SPARE NODES ARE ASSIGNED
12800 * TO NODE GROUP ZNIL
12801 *-----------------------------------------------------------------------*/
12802 tmngNodeGroup = 0;
12803 tmngLimit = csystemnodes - cnoHotSpare;
12804 ndbrequire(tmngLimit < MAX_NDB_NODES);
12805 for (i = 0; i < tmngLimit; i++) {
12806 NodeGroupRecordPtr NGPtr;
12807 jam();
12808 tmngNode = nodeArray[i];
12809 mngNodeptr.i = tmngNode;
12810 ptrCheckGuard(mngNodeptr, MAX_NDB_NODES, nodeRecord);
12811 mngNodeptr.p->nodeGroup = tmngNodeGroup;
12812 NGPtr.i = tmngNodeGroup;
12813 ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
12814 arrGuard(NGPtr.p->nodeCount, MAX_REPLICAS);
12815 NGPtr.p->nodesInGroup[NGPtr.p->nodeCount++] = mngNodeptr.i;
12816 if (NGPtr.p->nodeCount == cnoReplicas) {
12817 jam();
12818 tmngNodeGroup++;
12819 }//if
12820 }//for
12821 cnoOfNodeGroups = tmngNodeGroup;
12822 ndbrequire(csystemnodes < MAX_NDB_NODES);
12823 for (i = tmngLimit + 1; i < csystemnodes; i++) {
12824 jam();
12825 tmngNode = nodeArray[i];
12826 mngNodeptr.i = tmngNode;
12827 ptrCheckGuard(mngNodeptr, MAX_NDB_NODES, nodeRecord);
12828 mngNodeptr.p->nodeGroup = ZNIL;
12829 }//for
12830 for(i = 0; i < MAX_NDB_NODES; i++){
12831 jam();
12832 Sysfile::setNodeGroup(i, SYSFILE->nodeGroups, NO_NODE_GROUP_ID);
12833 }//for
12834 for (mngNodeptr.i = 1; mngNodeptr.i < MAX_NDB_NODES; mngNodeptr.i++) {
12835 jam();
12836 ptrAss(mngNodeptr, nodeRecord);
12837 if (mngNodeptr.p->nodeGroup != ZNIL) {
12838 jam();
12839 Sysfile::setNodeGroup(mngNodeptr.i, SYSFILE->nodeGroups, mngNodeptr.p->nodeGroup);
12840 }//if
12841 }//for
12842
12843 for (i = 0; i<cnoOfNodeGroups; i++)
12844 {
12845 jam();
12846 bool alive = false;
12847 NodeGroupRecordPtr NGPtr;
12848 NGPtr.i = i;
12849 ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
12850 for (j = 0; j<NGPtr.p->nodeCount; j++)
12851 {
12852 jam();
12853 mngNodeptr.i = NGPtr.p->nodesInGroup[j];
12854 ptrCheckGuard(mngNodeptr, MAX_NDB_NODES, nodeRecord);
12855 if (checkNodeAlive(NGPtr.p->nodesInGroup[j]))
12856 {
12857 alive = true;
12858 break;
12859 }
12860 }
12861
12862 if (!alive)
12863 {
12864 char buf[255];
12865 BaseString::snprintf
12866 (buf, sizeof(buf),
12867 "Illegal initial start, no alive node in nodegroup %u", i);
12868 progError(__LINE__,
12869 NDBD_EXIT_INSUFFICENT_NODES,
12870 buf);
12871
12872 }
12873 }
12874 }//Dbdih::makeNodeGroups()
12875
12876 /**
12877 * On node failure QMGR asks DIH about node groups. This is
12878 * a direct signal (function call in same process). Input is
12879 * bitmask of surviving nodes. The routine is not concerned
12880 * about node count. Reply is one of:
12881 * 1) win - we can survive, and nobody else can
12882 * 2) lose - we cannot survive
12883 * 3) partition - we can survive but there could be others
12884 */
execCHECKNODEGROUPSREQ(Signal * signal)12885 void Dbdih::execCHECKNODEGROUPSREQ(Signal* signal)
12886 {
12887 jamEntry();
12888 CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0];
12889
12890 bool direct = (sd->requestType & CheckNodeGroups::Direct);
12891 bool ok = false;
12892 switch(sd->requestType & ~CheckNodeGroups::Direct){
12893 case CheckNodeGroups::ArbitCheck:{
12894 ok = true;
12895 jam();
12896 unsigned missall = 0;
12897 unsigned haveall = 0;
12898 for (Uint32 i = 0; i < cnoOfNodeGroups; i++) {
12899 jam();
12900 NodeGroupRecordPtr ngPtr;
12901 ngPtr.i = i;
12902 ptrAss(ngPtr, nodeGroupRecord);
12903 Uint32 count = 0;
12904 for (Uint32 j = 0; j < ngPtr.p->nodeCount; j++) {
12905 jam();
12906 Uint32 nodeId = ngPtr.p->nodesInGroup[j];
12907 if (sd->mask.get(nodeId)) {
12908 jam();
12909 count++;
12910 }//if
12911 }//for
12912 if (count == 0) {
12913 jam();
12914 missall++;
12915 }//if
12916 if (count == ngPtr.p->nodeCount) {
12917 haveall++;
12918 }//if
12919 }//for
12920
12921 if (missall) {
12922 jam();
12923 sd->output = CheckNodeGroups::Lose;
12924 } else if (haveall) {
12925 jam();
12926 sd->output = CheckNodeGroups::Win;
12927 } else {
12928 jam();
12929 sd->output = CheckNodeGroups::Partitioning;
12930 }//if
12931 }
12932 break;
12933 case CheckNodeGroups::GetNodeGroup:
12934 ok = true;
12935 sd->output = Sysfile::getNodeGroup(getOwnNodeId(), SYSFILE->nodeGroups);
12936 break;
12937 case CheckNodeGroups::GetNodeGroupMembers: {
12938 ok = true;
12939 Uint32 ownNodeGroup =
12940 Sysfile::getNodeGroup(sd->nodeId, SYSFILE->nodeGroups);
12941
12942 sd->output = ownNodeGroup;
12943 sd->mask.clear();
12944
12945 NodeGroupRecordPtr ngPtr;
12946 ngPtr.i = ownNodeGroup;
12947 ptrAss(ngPtr, nodeGroupRecord);
12948 for (Uint32 j = 0; j < ngPtr.p->nodeCount; j++) {
12949 jam();
12950 sd->mask.set(ngPtr.p->nodesInGroup[j]);
12951 }
12952 #if 0
12953 for (int i = 0; i < MAX_NDB_NODES; i++) {
12954 if (ownNodeGroup ==
12955 Sysfile::getNodeGroup(i, SYSFILE->nodeGroups)) {
12956 sd->mask.set(i);
12957 }
12958 }
12959 #endif
12960 }
12961 break;
12962 }
12963 ndbrequire(ok);
12964
12965 if (!direct)
12966 sendSignal(sd->blockRef, GSN_CHECKNODEGROUPSCONF, signal,
12967 CheckNodeGroups::SignalLength, JBB);
12968 }//Dbdih::execCHECKNODEGROUPSREQ()
12969
makePrnList(ReadNodesConf * readNodes,Uint32 nodeArray[])12970 void Dbdih::makePrnList(ReadNodesConf * readNodes, Uint32 nodeArray[])
12971 {
12972 cfirstAliveNode = RNIL;
12973 ndbrequire(con_lineNodes > 0);
12974 ndbrequire(csystemnodes < MAX_NDB_NODES);
12975 for (Uint32 i = 0; i < csystemnodes; i++) {
12976 NodeRecordPtr nodePtr;
12977 jam();
12978 nodePtr.i = nodeArray[i];
12979 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
12980 new (nodePtr.p) NodeRecord();
12981 if (NodeBitmask::get(readNodes->inactiveNodes, nodePtr.i) == false){
12982 jam();
12983 nodePtr.p->nodeStatus = NodeRecord::ALIVE;
12984 nodePtr.p->useInTransactions = true;
12985 nodePtr.p->copyCompleted = true;
12986 nodePtr.p->m_inclDihLcp = true;
12987 insertAlive(nodePtr);
12988 } else {
12989 jam();
12990 nodePtr.p->nodeStatus = NodeRecord::DEAD;
12991 insertDeadNode(nodePtr);
12992 }//if
12993 }//for
12994 }//Dbdih::makePrnList()
12995
12996 /*************************************************************************/
12997 /* A NEW CRASHED REPLICA IS ADDED BY A NODE FAILURE. */
12998 /*************************************************************************/
newCrashedReplica(Uint32 nodeId,ReplicaRecordPtr ncrReplicaPtr)12999 void Dbdih::newCrashedReplica(Uint32 nodeId, ReplicaRecordPtr ncrReplicaPtr)
13000 {
13001 /*----------------------------------------------------------------------*/
13002 /* SET THE REPLICA_LAST_GCI OF THE CRASHED REPLICA TO LAST GCI */
13003 /* EXECUTED BY THE FAILED NODE. */
13004 /*----------------------------------------------------------------------*/
13005 /* WE HAVE A NEW CRASHED REPLICA. INITIATE CREATE GCI TO INDICATE */
13006 /* THAT THE NEW REPLICA IS NOT STARTED YET AND REPLICA_LAST_GCI IS*/
13007 /* SET TO -1 TO INDICATE THAT IT IS NOT DEAD YET. */
13008 /*----------------------------------------------------------------------*/
13009 Uint32 lastGCI = SYSFILE->lastCompletedGCI[nodeId];
13010 arrGuardErr(ncrReplicaPtr.p->noCrashedReplicas + 1, 8,
13011 NDBD_EXIT_MAX_CRASHED_REPLICAS);
13012 ncrReplicaPtr.p->replicaLastGci[ncrReplicaPtr.p->noCrashedReplicas] =
13013 lastGCI;
13014 ncrReplicaPtr.p->noCrashedReplicas = ncrReplicaPtr.p->noCrashedReplicas + 1;
13015 ncrReplicaPtr.p->createGci[ncrReplicaPtr.p->noCrashedReplicas] = 0;
13016 ncrReplicaPtr.p->replicaLastGci[ncrReplicaPtr.p->noCrashedReplicas] =
13017 (Uint32)-1;
13018
13019 if (ncrReplicaPtr.p->noCrashedReplicas == 7 && lastGCI)
13020 {
13021 jam();
13022 SYSFILE->lastCompletedGCI[nodeId] = 0;
13023 warningEvent("Making filesystem for node %d unusable (need --initial)",
13024 nodeId);
13025 }
13026 }//Dbdih::newCrashedReplica()
13027
13028 /*************************************************************************/
13029 /* AT NODE FAILURE DURING START OF A NEW NODE WE NEED TO RESET A */
13030 /* SET OF VARIABLES CONTROLLING THE START AND INDICATING ONGOING */
13031 /* START OF A NEW NODE. */
13032 /*************************************************************************/
nodeResetStart()13033 void Dbdih::nodeResetStart()
13034 {
13035 jam();
13036 c_nodeStartSlave.nodeId = 0;
13037 c_nodeStartMaster.startNode = RNIL;
13038 c_nodeStartMaster.failNr = cfailurenr;
13039 c_nodeStartMaster.activeState = false;
13040 c_nodeStartMaster.blockGcp = false;
13041 c_nodeStartMaster.blockLcp = false;
13042 c_nodeStartMaster.m_outstandingGsn = 0;
13043 }//Dbdih::nodeResetStart()
13044
openFileRw(Signal * signal,FileRecordPtr filePtr)13045 void Dbdih::openFileRw(Signal* signal, FileRecordPtr filePtr)
13046 {
13047 signal->theData[0] = reference();
13048 signal->theData[1] = filePtr.i;
13049 signal->theData[2] = filePtr.p->fileName[0];
13050 signal->theData[3] = filePtr.p->fileName[1];
13051 signal->theData[4] = filePtr.p->fileName[2];
13052 signal->theData[5] = filePtr.p->fileName[3];
13053 signal->theData[6] = FsOpenReq::OM_READWRITE;
13054 sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
13055 }//Dbdih::openFileRw()
13056
openFileRo(Signal * signal,FileRecordPtr filePtr)13057 void Dbdih::openFileRo(Signal* signal, FileRecordPtr filePtr)
13058 {
13059 signal->theData[0] = reference();
13060 signal->theData[1] = filePtr.i;
13061 signal->theData[2] = filePtr.p->fileName[0];
13062 signal->theData[3] = filePtr.p->fileName[1];
13063 signal->theData[4] = filePtr.p->fileName[2];
13064 signal->theData[5] = filePtr.p->fileName[3];
13065 signal->theData[6] = FsOpenReq::OM_READONLY;
13066 sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
13067 }//Dbdih::openFileRw()
13068
13069 /*************************************************************************/
13070 /* REMOVE A CRASHED REPLICA BY PACKING THE ARRAY OF CREATED GCI AND*/
13071 /* THE LAST GCI OF THE CRASHED REPLICA. */
13072 /*************************************************************************/
packCrashedReplicas(ReplicaRecordPtr replicaPtr)13073 void Dbdih::packCrashedReplicas(ReplicaRecordPtr replicaPtr)
13074 {
13075 ndbrequire(replicaPtr.p->noCrashedReplicas > 0);
13076 ndbrequire(replicaPtr.p->noCrashedReplicas <= 8);
13077 for (Uint32 i = 0; i < replicaPtr.p->noCrashedReplicas; i++) {
13078 jam();
13079 replicaPtr.p->createGci[i] = replicaPtr.p->createGci[i + 1];
13080 replicaPtr.p->replicaLastGci[i] = replicaPtr.p->replicaLastGci[i + 1];
13081 }//for
13082 replicaPtr.p->noCrashedReplicas--;
13083
13084 #ifdef VM_TRACE
13085 for (Uint32 i = 0; i < replicaPtr.p->noCrashedReplicas; i++) {
13086 jam();
13087 ndbrequire(replicaPtr.p->createGci[i] != 0xF1F1F1F1);
13088 ndbrequire(replicaPtr.p->replicaLastGci[i] != 0xF1F1F1F1);
13089 }//for
13090 #endif
13091 }//Dbdih::packCrashedReplicas()
13092
prepareReplicas(FragmentstorePtr fragPtr)13093 void Dbdih::prepareReplicas(FragmentstorePtr fragPtr)
13094 {
13095 ReplicaRecordPtr prReplicaPtr;
13096 Uint32 prevReplica = RNIL;
13097
13098 /* --------------------------------------------------------------------- */
13099 /* BEGIN BY LINKING ALL REPLICA RECORDS ONTO THE OLD STORED REPLICA*/
13100 /* LIST. */
13101 /* AT A SYSTEM RESTART OBVIOUSLY ALL NODES ARE OLD. */
13102 /* --------------------------------------------------------------------- */
13103 prReplicaPtr.i = fragPtr.p->storedReplicas;
13104 while (prReplicaPtr.i != RNIL) {
13105 jam();
13106 prevReplica = prReplicaPtr.i;
13107 ptrCheckGuard(prReplicaPtr, creplicaFileSize, replicaRecord);
13108 prReplicaPtr.i = prReplicaPtr.p->nextReplica;
13109 }//while
13110 /* --------------------------------------------------------------------- */
13111 /* LIST OF STORED REPLICAS WILL BE EMPTY NOW. */
13112 /* --------------------------------------------------------------------- */
13113 if (prevReplica != RNIL) {
13114 prReplicaPtr.i = prevReplica;
13115 ptrCheckGuard(prReplicaPtr, creplicaFileSize, replicaRecord);
13116 prReplicaPtr.p->nextReplica = fragPtr.p->oldStoredReplicas;
13117 fragPtr.p->oldStoredReplicas = fragPtr.p->storedReplicas;
13118 fragPtr.p->storedReplicas = RNIL;
13119 fragPtr.p->noOldStoredReplicas += fragPtr.p->noStoredReplicas;
13120 fragPtr.p->noStoredReplicas = 0;
13121 }//if
13122 }//Dbdih::prepareReplicas()
13123
readFragment(RWFragment * rf,FragmentstorePtr fragPtr)13124 void Dbdih::readFragment(RWFragment* rf, FragmentstorePtr fragPtr)
13125 {
13126 Uint32 TreadFid = readPageWord(rf);
13127 fragPtr.p->preferredPrimary = readPageWord(rf);
13128 fragPtr.p->noStoredReplicas = readPageWord(rf);
13129 fragPtr.p->noOldStoredReplicas = readPageWord(rf);
13130 Uint32 TdistKey = readPageWord(rf);
13131
13132 ndbrequire(fragPtr.p->noStoredReplicas > 0);
13133 ndbrequire(TreadFid == rf->fragId);
13134 ndbrequire(TdistKey < 256);
13135 if ((cstarttype == NodeState::ST_NODE_RESTART) ||
13136 (cstarttype == NodeState::ST_INITIAL_NODE_RESTART)) {
13137 jam();
13138 fragPtr.p->distributionKey = TdistKey;
13139 }//if
13140
13141 fragPtr.p->m_log_part_id = readPageWord(rf);
13142 }//Dbdih::readFragment()
13143
readPageWord(RWFragment * rf)13144 Uint32 Dbdih::readPageWord(RWFragment* rf)
13145 {
13146 if (rf->wordIndex >= 2048) {
13147 jam();
13148 ndbrequire(rf->wordIndex == 2048);
13149 rf->pageIndex++;
13150 ndbrequire(rf->pageIndex < 8);
13151 rf->rwfPageptr.i = rf->rwfTabPtr.p->pageRef[rf->pageIndex];
13152 ptrCheckGuard(rf->rwfPageptr, cpageFileSize, pageRecord);
13153 rf->wordIndex = 32;
13154 }//if
13155 Uint32 dataWord = rf->rwfPageptr.p->word[rf->wordIndex];
13156 rf->wordIndex++;
13157 return dataWord;
13158 }//Dbdih::readPageWord()
13159
readReplica(RWFragment * rf,ReplicaRecordPtr readReplicaPtr)13160 void Dbdih::readReplica(RWFragment* rf, ReplicaRecordPtr readReplicaPtr)
13161 {
13162 Uint32 i;
13163 readReplicaPtr.p->procNode = readPageWord(rf);
13164 readReplicaPtr.p->initialGci = readPageWord(rf);
13165 readReplicaPtr.p->noCrashedReplicas = readPageWord(rf);
13166 readReplicaPtr.p->nextLcp = readPageWord(rf);
13167
13168 for (i = 0; i < MAX_LCP_STORED; i++) {
13169 readReplicaPtr.p->maxGciCompleted[i] = readPageWord(rf);
13170 readReplicaPtr.p->maxGciStarted[i] = readPageWord(rf);
13171 readReplicaPtr.p->lcpId[i] = readPageWord(rf);
13172 readReplicaPtr.p->lcpStatus[i] = readPageWord(rf);
13173 }//for
13174 const Uint32 noCrashedReplicas = readReplicaPtr.p->noCrashedReplicas;
13175 ndbrequire(noCrashedReplicas < 8);
13176 for (i = 0; i < noCrashedReplicas; i++) {
13177 readReplicaPtr.p->createGci[i] = readPageWord(rf);
13178 readReplicaPtr.p->replicaLastGci[i] = readPageWord(rf);
13179 ndbrequire(readReplicaPtr.p->createGci[i] != 0xF1F1F1F1);
13180 ndbrequire(readReplicaPtr.p->replicaLastGci[i] != 0xF1F1F1F1);
13181 }//for
13182 for(i = noCrashedReplicas; i<8; i++){
13183 readReplicaPtr.p->createGci[i] = readPageWord(rf);
13184 readReplicaPtr.p->replicaLastGci[i] = readPageWord(rf);
13185 // They are not initialized...
13186 readReplicaPtr.p->createGci[i] = 0;
13187 readReplicaPtr.p->replicaLastGci[i] = ~0;
13188 }
13189 /* ---------------------------------------------------------------------- */
13190 /* IF THE LAST COMPLETED LOCAL CHECKPOINT IS VALID AND LARGER THAN */
13191 /* THE LAST COMPLETED CHECKPOINT THEN WE WILL INVALIDATE THIS LOCAL */
13192 /* CHECKPOINT FOR THIS REPLICA. */
13193 /* ---------------------------------------------------------------------- */
13194 Uint32 trraLcp = prevLcpNo(readReplicaPtr.p->nextLcp);
13195 ndbrequire(trraLcp < MAX_LCP_STORED);
13196 if ((readReplicaPtr.p->lcpStatus[trraLcp] == ZVALID) &&
13197 (readReplicaPtr.p->lcpId[trraLcp] > SYSFILE->latestLCP_ID)) {
13198 jam();
13199 readReplicaPtr.p->lcpStatus[trraLcp] = ZINVALID;
13200 }//if
13201 /* ---------------------------------------------------------------------- */
13202 /* WE ALSO HAVE TO INVALIDATE ANY LOCAL CHECKPOINTS THAT HAVE BEEN */
13203 /* INVALIDATED BY MOVING BACK THE RESTART GCI. */
13204 /* ---------------------------------------------------------------------- */
13205 for (i = 0; i < MAX_LCP_STORED; i++) {
13206 jam();
13207 if ((readReplicaPtr.p->lcpStatus[i] == ZVALID) &&
13208 (readReplicaPtr.p->maxGciStarted[i] > SYSFILE->newestRestorableGCI)) {
13209 jam();
13210 readReplicaPtr.p->lcpStatus[i] = ZINVALID;
13211 }//if
13212 }//for
13213 /* ---------------------------------------------------------------------- */
13214 /* WE WILL REMOVE ANY OCCURRENCES OF REPLICAS THAT HAVE CRASHED */
13215 /* THAT ARE NO LONGER VALID DUE TO MOVING RESTART GCI BACKWARDS. */
13216 /* ---------------------------------------------------------------------- */
13217 removeTooNewCrashedReplicas(readReplicaPtr);
13218 /* ---------------------------------------------------------------------- */
13219 /* WE WILL REMOVE ANY OCCURRENCES OF REPLICAS THAT HAVE CRASHED */
13220 /* THAT ARE NO LONGER VALID SINCE THEY ARE NO LONGER RESTORABLE. */
13221 /* ---------------------------------------------------------------------- */
13222 removeOldCrashedReplicas(readReplicaPtr);
13223 /* --------------------------------------------------------------------- */
13224 // We set the last GCI of the replica that was alive before the node
13225 // crashed last time. We set it to the last GCI which the node participated in.
13226 /* --------------------------------------------------------------------- */
13227 ndbrequire(readReplicaPtr.p->noCrashedReplicas < 8);
13228 readReplicaPtr.p->replicaLastGci[readReplicaPtr.p->noCrashedReplicas] =
13229 SYSFILE->lastCompletedGCI[readReplicaPtr.p->procNode];
13230 /* ---------------------------------------------------------------------- */
13231 /* FIND PROCESSOR RECORD */
13232 /* ---------------------------------------------------------------------- */
13233 }//Dbdih::readReplica()
13234
readReplicas(RWFragment * rf,FragmentstorePtr fragPtr)13235 void Dbdih::readReplicas(RWFragment* rf, FragmentstorePtr fragPtr)
13236 {
13237 Uint32 i;
13238 ReplicaRecordPtr newReplicaPtr;
13239 Uint32 noStoredReplicas = fragPtr.p->noStoredReplicas;
13240 Uint32 noOldStoredReplicas = fragPtr.p->noOldStoredReplicas;
13241 /* ----------------------------------------------------------------------- */
13242 /* WE CLEAR THE NUMBER OF STORED REPLICAS SINCE IT WILL BE CALCULATED */
13243 /* BY THE LINKING SUBROUTINES. */
13244 /* ----------------------------------------------------------------------- */
13245 fragPtr.p->noStoredReplicas = 0;
13246 fragPtr.p->noOldStoredReplicas = 0;
13247 Uint32 replicaIndex = 0;
13248 ndbrequire(noStoredReplicas + noOldStoredReplicas <= MAX_REPLICAS);
13249 for (i = 0; i < noStoredReplicas; i++) {
13250 seizeReplicaRec(newReplicaPtr);
13251 readReplica(rf, newReplicaPtr);
13252 if (checkNodeAlive(newReplicaPtr.p->procNode)) {
13253 jam();
13254 ndbrequire(replicaIndex < MAX_REPLICAS);
13255 fragPtr.p->activeNodes[replicaIndex] = newReplicaPtr.p->procNode;
13256 replicaIndex++;
13257 linkStoredReplica(fragPtr, newReplicaPtr);
13258 } else {
13259 jam();
13260 linkOldStoredReplica(fragPtr, newReplicaPtr);
13261 }//if
13262 }//for
13263 fragPtr.p->fragReplicas = noStoredReplicas;
13264 for (i = 0; i < noOldStoredReplicas; i++) {
13265 jam();
13266 seizeReplicaRec(newReplicaPtr);
13267 readReplica(rf, newReplicaPtr);
13268 linkOldStoredReplica(fragPtr, newReplicaPtr);
13269 }//for
13270 }//Dbdih::readReplicas()
13271
readRestorableGci(Signal * signal,FileRecordPtr filePtr)13272 void Dbdih::readRestorableGci(Signal* signal, FileRecordPtr filePtr)
13273 {
13274 signal->theData[0] = filePtr.p->fileRef;
13275 signal->theData[1] = reference();
13276 signal->theData[2] = filePtr.i;
13277 signal->theData[3] = ZLIST_OF_PAIRS;
13278 signal->theData[4] = ZVAR_NO_CRESTART_INFO;
13279 signal->theData[5] = 1;
13280 signal->theData[6] = 0;
13281 signal->theData[7] = 0;
13282 sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
13283 }//Dbdih::readRestorableGci()
13284
readTabfile(Signal * signal,TabRecord * tab,FileRecordPtr filePtr)13285 void Dbdih::readTabfile(Signal* signal, TabRecord* tab, FileRecordPtr filePtr)
13286 {
13287 signal->theData[0] = filePtr.p->fileRef;
13288 signal->theData[1] = reference();
13289 signal->theData[2] = filePtr.i;
13290 signal->theData[3] = ZLIST_OF_PAIRS;
13291 signal->theData[4] = ZVAR_NO_WORD;
13292 signal->theData[5] = tab->noPages;
13293 for (Uint32 i = 0; i < tab->noPages; i++) {
13294 signal->theData[6 + (2 * i)] = tab->pageRef[i];
13295 signal->theData[7 + (2 * i)] = i;
13296 }//for
13297 sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 22, JBA);
13298 }//Dbdih::readTabfile()
13299
releasePage(Uint32 pageIndex)13300 void Dbdih::releasePage(Uint32 pageIndex)
13301 {
13302 PageRecordPtr pagePtr;
13303 pagePtr.i = pageIndex;
13304 ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
13305 pagePtr.p->nextfreepage = cfirstfreepage;
13306 cfirstfreepage = pagePtr.i;
13307 }//Dbdih::releasePage()
13308
releaseTabPages(Uint32 tableId)13309 void Dbdih::releaseTabPages(Uint32 tableId)
13310 {
13311 TabRecordPtr tabPtr;
13312 tabPtr.i = tableId;
13313 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
13314 ndbrequire(tabPtr.p->noPages <= 8);
13315 for (Uint32 i = 0; i < tabPtr.p->noPages; i++) {
13316 jam();
13317 releasePage(tabPtr.p->pageRef[i]);
13318 }//for
13319 tabPtr.p->noPages = 0;
13320 }//Dbdih::releaseTabPages()
13321
13322 /*************************************************************************/
13323 /* REMOVE NODE FROM SET OF ALIVE NODES. */
13324 /*************************************************************************/
removeAlive(NodeRecordPtr removeNodePtr)13325 void Dbdih::removeAlive(NodeRecordPtr removeNodePtr)
13326 {
13327 NodeRecordPtr nodePtr;
13328
13329 nodePtr.i = cfirstAliveNode;
13330 if (nodePtr.i == removeNodePtr.i) {
13331 jam();
13332 cfirstAliveNode = removeNodePtr.p->nextNode;
13333 return;
13334 }//if
13335 do {
13336 jam();
13337 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
13338 if (nodePtr.p->nextNode == removeNodePtr.i) {
13339 jam();
13340 nodePtr.p->nextNode = removeNodePtr.p->nextNode;
13341 break;
13342 } else {
13343 jam();
13344 nodePtr.i = nodePtr.p->nextNode;
13345 }//if
13346 } while (1);
13347 }//Dbdih::removeAlive()
13348
13349 /*************************************************************************/
13350 /* REMOVE NODE FROM SET OF DEAD NODES. */
13351 /*************************************************************************/
removeDeadNode(NodeRecordPtr removeNodePtr)13352 void Dbdih::removeDeadNode(NodeRecordPtr removeNodePtr)
13353 {
13354 NodeRecordPtr nodePtr;
13355
13356 nodePtr.i = cfirstDeadNode;
13357 if (nodePtr.i == removeNodePtr.i) {
13358 jam();
13359 cfirstDeadNode = removeNodePtr.p->nextNode;
13360 return;
13361 }//if
13362 do {
13363 jam();
13364 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
13365 if (nodePtr.p->nextNode == removeNodePtr.i) {
13366 jam();
13367 nodePtr.p->nextNode = removeNodePtr.p->nextNode;
13368 break;
13369 } else {
13370 jam();
13371 nodePtr.i = nodePtr.p->nextNode;
13372 }//if
13373 } while (1);
13374 }//Dbdih::removeDeadNode()
13375
13376 /*---------------------------------------------------------------*/
13377 /* REMOVE REPLICAS OF A FAILED NODE FROM LIST OF STORED */
13378 /* REPLICAS AND MOVE IT TO THE LIST OF OLD STORED REPLICAS.*/
13379 /* ALSO UPDATE THE CRASHED REPLICA INFORMATION. */
13380 /*---------------------------------------------------------------*/
removeNodeFromStored(Uint32 nodeId,FragmentstorePtr fragPtr,ReplicaRecordPtr replicatePtr,bool temporary)13381 void Dbdih::removeNodeFromStored(Uint32 nodeId,
13382 FragmentstorePtr fragPtr,
13383 ReplicaRecordPtr replicatePtr,
13384 bool temporary)
13385 {
13386 if (!temporary)
13387 {
13388 jam();
13389 newCrashedReplica(nodeId, replicatePtr);
13390 }
13391 else
13392 {
13393 jam();
13394 }
13395 removeStoredReplica(fragPtr, replicatePtr);
13396 linkOldStoredReplica(fragPtr, replicatePtr);
13397 ndbrequire(fragPtr.p->storedReplicas != RNIL);
13398 }//Dbdih::removeNodeFromStored()
13399
13400 /*************************************************************************/
13401 /* REMOVE ANY OLD CRASHED REPLICAS THAT ARE NOT RESTORABLE ANY MORE*/
13402 /*************************************************************************/
removeOldCrashedReplicas(ReplicaRecordPtr rocReplicaPtr)13403 void Dbdih::removeOldCrashedReplicas(ReplicaRecordPtr rocReplicaPtr)
13404 {
13405 while (rocReplicaPtr.p->noCrashedReplicas > 0) {
13406 jam();
13407 /* --------------------------------------------------------------------- */
13408 /* ONLY IF THERE IS AT LEAST ONE REPLICA THEN CAN WE REMOVE ANY. */
13409 /* --------------------------------------------------------------------- */
13410 if (rocReplicaPtr.p->replicaLastGci[0] < SYSFILE->oldestRestorableGCI){
13411 jam();
13412 /* ------------------------------------------------------------------- */
13413 /* THIS CRASHED REPLICA HAS BECOME EXTINCT AND MUST BE REMOVED TO */
13414 /* GIVE SPACE FOR NEW CRASHED REPLICAS. */
13415 /* ------------------------------------------------------------------- */
13416 packCrashedReplicas(rocReplicaPtr);
13417 } else {
13418 break;
13419 }//if
13420 }//while
13421 if (rocReplicaPtr.p->createGci[0] < SYSFILE->keepGCI){
13422 jam();
13423 /* --------------------------------------------------------------------- */
13424 /* MOVE FORWARD THE CREATE GCI TO A GCI THAT CAN BE USED. WE HAVE */
13425 /* NO CERTAINTY IN FINDING ANY LOG RECORDS FROM OLDER GCI'S. */
13426 /* --------------------------------------------------------------------- */
13427 rocReplicaPtr.p->createGci[0] = SYSFILE->keepGCI;
13428 ndbrequire(SYSFILE->keepGCI != 0xF1F1F1F1);
13429 }//if
13430 }//Dbdih::removeOldCrashedReplicas()
13431
removeOldStoredReplica(FragmentstorePtr fragPtr,ReplicaRecordPtr replicatePtr)13432 void Dbdih::removeOldStoredReplica(FragmentstorePtr fragPtr,
13433 ReplicaRecordPtr replicatePtr)
13434 {
13435 ReplicaRecordPtr rosTmpReplicaPtr;
13436 ReplicaRecordPtr rosPrevReplicaPtr;
13437
13438 fragPtr.p->noOldStoredReplicas--;
13439 if (fragPtr.p->oldStoredReplicas == replicatePtr.i) {
13440 jam();
13441 fragPtr.p->oldStoredReplicas = replicatePtr.p->nextReplica;
13442 } else {
13443 rosPrevReplicaPtr.i = fragPtr.p->oldStoredReplicas;
13444 ptrCheckGuard(rosPrevReplicaPtr, creplicaFileSize, replicaRecord);
13445 rosTmpReplicaPtr.i = rosPrevReplicaPtr.p->nextReplica;
13446 while (rosTmpReplicaPtr.i != replicatePtr.i) {
13447 jam();
13448 rosPrevReplicaPtr.i = rosTmpReplicaPtr.i;
13449 ptrCheckGuard(rosPrevReplicaPtr, creplicaFileSize, replicaRecord);
13450 ptrCheckGuard(rosTmpReplicaPtr, creplicaFileSize, replicaRecord);
13451 rosTmpReplicaPtr.i = rosTmpReplicaPtr.p->nextReplica;
13452 }//if
13453 rosPrevReplicaPtr.p->nextReplica = replicatePtr.p->nextReplica;
13454 }//if
13455 }//Dbdih::removeOldStoredReplica()
13456
removeStoredReplica(FragmentstorePtr fragPtr,ReplicaRecordPtr replicatePtr)13457 void Dbdih::removeStoredReplica(FragmentstorePtr fragPtr,
13458 ReplicaRecordPtr replicatePtr)
13459 {
13460 ReplicaRecordPtr rsrTmpReplicaPtr;
13461 ReplicaRecordPtr rsrPrevReplicaPtr;
13462
13463 fragPtr.p->noStoredReplicas--;
13464 if (fragPtr.p->storedReplicas == replicatePtr.i) {
13465 jam();
13466 fragPtr.p->storedReplicas = replicatePtr.p->nextReplica;
13467 } else {
13468 jam();
13469 rsrPrevReplicaPtr.i = fragPtr.p->storedReplicas;
13470 rsrTmpReplicaPtr.i = fragPtr.p->storedReplicas;
13471 ptrCheckGuard(rsrTmpReplicaPtr, creplicaFileSize, replicaRecord);
13472 rsrTmpReplicaPtr.i = rsrTmpReplicaPtr.p->nextReplica;
13473 while (rsrTmpReplicaPtr.i != replicatePtr.i) {
13474 jam();
13475 rsrPrevReplicaPtr.i = rsrTmpReplicaPtr.i;
13476 ptrCheckGuard(rsrTmpReplicaPtr, creplicaFileSize, replicaRecord);
13477 rsrTmpReplicaPtr.i = rsrTmpReplicaPtr.p->nextReplica;
13478 }//while
13479 ptrCheckGuard(rsrPrevReplicaPtr, creplicaFileSize, replicaRecord);
13480 rsrPrevReplicaPtr.p->nextReplica = replicatePtr.p->nextReplica;
13481 }//if
13482 }//Dbdih::removeStoredReplica()
13483
13484 /*************************************************************************/
13485 /* REMOVE ALL TOO NEW CRASHED REPLICAS THAT IS IN THIS REPLICA. */
13486 /*************************************************************************/
removeTooNewCrashedReplicas(ReplicaRecordPtr rtnReplicaPtr)13487 void Dbdih::removeTooNewCrashedReplicas(ReplicaRecordPtr rtnReplicaPtr)
13488 {
13489 while (rtnReplicaPtr.p->noCrashedReplicas > 0) {
13490 jam();
13491 /* --------------------------------------------------------------------- */
13492 /* REMOVE ALL REPLICAS THAT ONLY LIVED IN A PERIOD THAT HAVE BEEN */
13493 /* REMOVED FROM THE RESTART INFORMATION SINCE THE RESTART FAILED */
13494 /* TOO MANY TIMES. */
13495 /* --------------------------------------------------------------------- */
13496 arrGuard(rtnReplicaPtr.p->noCrashedReplicas - 1, 8);
13497 if (rtnReplicaPtr.p->createGci[rtnReplicaPtr.p->noCrashedReplicas - 1] >
13498 SYSFILE->newestRestorableGCI){
13499 jam();
13500 rtnReplicaPtr.p->createGci[rtnReplicaPtr.p->noCrashedReplicas - 1] =
13501 (Uint32)-1;
13502 rtnReplicaPtr.p->replicaLastGci[rtnReplicaPtr.p->noCrashedReplicas - 1] =
13503 (Uint32)-1;
13504 rtnReplicaPtr.p->noCrashedReplicas--;
13505 } else {
13506 break;
13507 }//if
13508 }//while
13509 }//Dbdih::removeTooNewCrashedReplicas()
13510
13511 /*************************************************************************/
13512 /* */
13513 /* MODULE: SEARCH FOR POSSIBLE REPLICAS THAT CAN HANDLE THE GLOBAL */
13514 /* CHECKPOINT WITHOUT NEEDING ANY EXTRA LOGGING FACILITIES.*/
13515 /* A MAXIMUM OF FOUR NODES IS RETRIEVED. */
13516 /*************************************************************************/
13517 bool
setup_create_replica(FragmentstorePtr fragPtr,CreateReplicaRecord * createReplicaPtrP,ConstPtr<ReplicaRecord> replicaPtr)13518 Dbdih::setup_create_replica(FragmentstorePtr fragPtr,
13519 CreateReplicaRecord* createReplicaPtrP,
13520 ConstPtr<ReplicaRecord> replicaPtr)
13521 {
13522 createReplicaPtrP->dataNodeId = replicaPtr.p->procNode;
13523 createReplicaPtrP->replicaRec = replicaPtr.i;
13524
13525 /* ----------------------------------------------------------------- */
13526 /* WE NEED TO SEARCH FOR A PROPER LOCAL CHECKPOINT TO USE FOR THE */
13527 /* SYSTEM RESTART. */
13528 /* ----------------------------------------------------------------- */
13529 Uint32 startGci;
13530 Uint32 startLcpNo;
13531 Uint32 stopGci = SYSFILE->newestRestorableGCI;
13532 bool result = findStartGci(replicaPtr,
13533 stopGci,
13534 startGci,
13535 startLcpNo);
13536 if (!result)
13537 {
13538 jam();
13539 /* --------------------------------------------------------------- */
13540 /* WE COULD NOT FIND ANY LOCAL CHECKPOINT. THE FRAGMENT THUS DO NOT*/
13541 /* CONTAIN ANY VALID LOCAL CHECKPOINT. IT DOES HOWEVER CONTAIN A */
13542 /* VALID FRAGMENT LOG. THUS BY FIRST CREATING THE FRAGMENT AND THEN*/
13543 /* EXECUTING THE FRAGMENT LOG WE CAN CREATE THE FRAGMENT AS */
13544 /* DESIRED. THIS SHOULD ONLY OCCUR AFTER CREATING A FRAGMENT. */
13545 /* */
13546 /* TO INDICATE THAT NO LOCAL CHECKPOINT IS TO BE USED WE SET THE */
13547 /* LOCAL CHECKPOINT TO ZNIL. */
13548 /* --------------------------------------------------------------- */
13549 createReplicaPtrP->lcpNo = ZNIL;
13550 }
13551 else
13552 {
13553 jam();
13554 /* --------------------------------------------------------------- */
13555 /* WE FOUND A PROPER LOCAL CHECKPOINT TO RESTART FROM. */
13556 /* SET LOCAL CHECKPOINT ID AND LOCAL CHECKPOINT NUMBER. */
13557 /* --------------------------------------------------------------- */
13558 createReplicaPtrP->lcpNo = startLcpNo;
13559 arrGuard(startLcpNo, MAX_LCP_STORED);
13560 createReplicaPtrP->createLcpId = replicaPtr.p->lcpId[startLcpNo];
13561 }//if
13562
13563
13564 /* ----------------------------------------------------------------- */
13565 /* WE HAVE EITHER FOUND A LOCAL CHECKPOINT OR WE ARE PLANNING TO */
13566 /* EXECUTE THE LOG FROM THE INITIAL CREATION OF THE TABLE. IN BOTH */
13567 /* CASES WE NEED TO FIND A SET OF LOGS THAT CAN EXECUTE SUCH THAT */
13568 /* WE RECOVER TO THE SYSTEM RESTART GLOBAL CHECKPOINT. */
13569 /* -_--------------------------------------------------------------- */
13570 return findLogNodes(createReplicaPtrP, fragPtr, startGci, stopGci);
13571 }
13572
searchStoredReplicas(FragmentstorePtr fragPtr)13573 void Dbdih::searchStoredReplicas(FragmentstorePtr fragPtr)
13574 {
13575 Uint32 nextReplicaPtrI;
13576 Ptr<ReplicaRecord> replicaPtr;
13577
13578 replicaPtr.i = fragPtr.p->storedReplicas;
13579 while (replicaPtr.i != RNIL) {
13580 jam();
13581 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
13582 nextReplicaPtrI = replicaPtr.p->nextReplica;
13583 ConstPtr<ReplicaRecord> constReplicaPtr;
13584 constReplicaPtr.i = replicaPtr.i;
13585 constReplicaPtr.p = replicaPtr.p;
13586 NodeRecordPtr nodePtr;
13587 nodePtr.i = replicaPtr.p->procNode;
13588 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
13589 if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
13590 jam();
13591 switch (nodePtr.p->activeStatus) {
13592 case Sysfile::NS_Active:
13593 case Sysfile::NS_ActiveMissed_1:
13594 case Sysfile::NS_ActiveMissed_2:{
13595 /* ----------------------------------------------------------------- */
13596 /* INITIALISE THE CREATE REPLICA STRUCTURE THAT IS USED FOR SENDING*/
13597 /* TO LQH START_FRAGREQ. */
13598 /* SET THE DATA NODE WHERE THE LOCAL CHECKPOINT IS FOUND. ALSO */
13599 /* SET A REFERENCE TO THE REPLICA POINTER OF THAT. */
13600 /* ----------------------------------------------------------------- */
13601 CreateReplicaRecordPtr createReplicaPtr;
13602 createReplicaPtr.i = cnoOfCreateReplicas;
13603 ptrCheckGuard(createReplicaPtr, 4, createReplicaRecord);
13604 cnoOfCreateReplicas++;
13605
13606 /**
13607 * Should have been checked in resetReplicaSr
13608 */
13609 ndbrequire(setup_create_replica(fragPtr,
13610 createReplicaPtr.p,
13611 constReplicaPtr));
13612 break;
13613 }
13614 default:
13615 jam();
13616 /*empty*/;
13617 break;
13618 }//switch
13619 }
13620 replicaPtr.i = nextReplicaPtrI;
13621 }//while
13622 }//Dbdih::searchStoredReplicas()
13623
13624 /*************************************************************************/
13625 /* */
13626 /* MODULE: SEIZE_FILE */
13627 /* DESCRIPTION: THE SUBROUTINE SEIZES A FILE RECORD FROM THE */
13628 /* FREE LIST. */
13629 /*************************************************************************/
seizeFile(FileRecordPtr & filePtr)13630 void Dbdih::seizeFile(FileRecordPtr& filePtr)
13631 {
13632 filePtr.i = cfirstfreeFile;
13633 ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
13634 cfirstfreeFile = filePtr.p->nextFile;
13635 filePtr.p->nextFile = RNIL;
13636 }//Dbdih::seizeFile()
13637
13638 /*************************************************************************/
13639 /* SEND CREATE_FRAGREQ TO ALL NODES IN THE NDB CLUSTER. */
13640 /*************************************************************************/
13641 /*************************************************************************/
13642 /* */
13643 /* MODULE: FIND THE START GCI AND LOCAL CHECKPOINT TO USE. */
13644 /*************************************************************************/
sendStartFragreq(Signal * signal,TabRecordPtr tabPtr,Uint32 fragId)13645 void Dbdih::sendStartFragreq(Signal* signal,
13646 TabRecordPtr tabPtr, Uint32 fragId)
13647 {
13648 CreateReplicaRecordPtr replicaPtr;
13649 for (replicaPtr.i = 0; replicaPtr.i < cnoOfCreateReplicas; replicaPtr.i++) {
13650 jam();
13651 ptrAss(replicaPtr, createReplicaRecord);
13652 BlockReference ref = calcLqhBlockRef(replicaPtr.p->dataNodeId);
13653 StartFragReq * const startFragReq = (StartFragReq *)&signal->theData[0];
13654 startFragReq->userPtr = replicaPtr.p->replicaRec;
13655 startFragReq->userRef = reference();
13656 startFragReq->lcpNo = replicaPtr.p->lcpNo;
13657 startFragReq->lcpId = replicaPtr.p->createLcpId;
13658 startFragReq->tableId = tabPtr.i;
13659 startFragReq->fragId = fragId;
13660
13661 if(ERROR_INSERTED(7072) || ERROR_INSERTED(7074)){
13662 jam();
13663 const Uint32 noNodes = replicaPtr.p->noLogNodes;
13664 Uint32 start = replicaPtr.p->logStartGci[noNodes - 1];
13665 const Uint32 stop = replicaPtr.p->logStopGci[noNodes - 1];
13666
13667 for(Uint32 i = noNodes; i < 4 && (stop - start) > 0; i++){
13668 replicaPtr.p->noLogNodes++;
13669 replicaPtr.p->logStopGci[i - 1] = start;
13670
13671 replicaPtr.p->logNodeId[i] = replicaPtr.p->logNodeId[i-1];
13672 replicaPtr.p->logStartGci[i] = start + 1;
13673 replicaPtr.p->logStopGci[i] = stop;
13674 start += 1;
13675 }
13676 }
13677
13678 startFragReq->noOfLogNodes = replicaPtr.p->noLogNodes;
13679
13680 for (Uint32 i = 0; i < 4 ; i++) {
13681 startFragReq->lqhLogNode[i] = replicaPtr.p->logNodeId[i];
13682 startFragReq->startGci[i] = replicaPtr.p->logStartGci[i];
13683 startFragReq->lastGci[i] = replicaPtr.p->logStopGci[i];
13684 }//for
13685
13686 sendSignal(ref, GSN_START_FRAGREQ, signal,
13687 StartFragReq::SignalLength, JBB);
13688 }//for
13689 }//Dbdih::sendStartFragreq()
13690
13691 /*************************************************************************/
13692 /* SET THE INITIAL ACTIVE STATUS ON ALL NODES AND PUT INTO LISTS. */
13693 /*************************************************************************/
setInitialActiveStatus()13694 void Dbdih::setInitialActiveStatus()
13695 {
13696 NodeRecordPtr siaNodeptr;
13697 Uint32 tsiaNoActiveNodes;
13698
13699 tsiaNoActiveNodes = csystemnodes - cnoHotSpare;
13700 for(Uint32 i = 0; i<Sysfile::NODE_STATUS_SIZE; i++)
13701 SYSFILE->nodeStatus[i] = 0;
13702 for (siaNodeptr.i = 1; siaNodeptr.i < MAX_NDB_NODES; siaNodeptr.i++) {
13703 ptrAss(siaNodeptr, nodeRecord);
13704 switch(siaNodeptr.p->nodeStatus){
13705 case NodeRecord::ALIVE:
13706 case NodeRecord::DEAD:
13707 if (tsiaNoActiveNodes == 0) {
13708 jam();
13709 siaNodeptr.p->activeStatus = Sysfile::NS_HotSpare;
13710 } else {
13711 jam();
13712 tsiaNoActiveNodes = tsiaNoActiveNodes - 1;
13713 if (siaNodeptr.p->nodeStatus == NodeRecord::ALIVE)
13714 {
13715 jam();
13716 siaNodeptr.p->activeStatus = Sysfile::NS_Active;
13717 }
13718 else
13719 {
13720 siaNodeptr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
13721 }
13722 }
13723 break;
13724 default:
13725 jam();
13726 siaNodeptr.p->activeStatus = Sysfile::NS_NotDefined;
13727 break;
13728 }//if
13729 Sysfile::setNodeStatus(siaNodeptr.i,
13730 SYSFILE->nodeStatus,
13731 siaNodeptr.p->activeStatus);
13732 }//for
13733 }//Dbdih::setInitialActiveStatus()
13734
13735 /*************************************************************************/
13736 /* SET LCP ACTIVE STATUS AT THE END OF A LOCAL CHECKPOINT. */
13737 /*************************************************************************/
setLcpActiveStatusEnd()13738 void Dbdih::setLcpActiveStatusEnd()
13739 {
13740 NodeRecordPtr nodePtr;
13741
13742 for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
13743 jam();
13744 ptrAss(nodePtr, nodeRecord);
13745 if (c_lcpState.m_participatingLQH.get(nodePtr.i)){
13746 switch (nodePtr.p->activeStatus) {
13747 case Sysfile::NS_Active:
13748 case Sysfile::NS_ActiveMissed_1:
13749 case Sysfile::NS_ActiveMissed_2:
13750 jam();
13751 /*-------------------------------------------------------------------*/
13752 /* THE NODE PARTICIPATED IN THIS CHECKPOINT.
13753 * WE CAN SET ITS STATUS TO ACTIVE */
13754 /*-------------------------------------------------------------------*/
13755 nodePtr.p->activeStatus = Sysfile::NS_Active;
13756 takeOverCompleted(nodePtr.i);
13757 break;
13758 case Sysfile::NS_TakeOver:
13759 jam();
13760 /*-------------------------------------------------------------------*/
13761 /* THE NODE HAS COMPLETED A CHECKPOINT AFTER TAKE OVER. WE CAN NOW */
13762 /* SET ITS STATUS TO ACTIVE. WE CAN ALSO COMPLETE THE TAKE OVER */
13763 /* AND ALSO WE CLEAR THE TAKE OVER NODE IN THE RESTART INFO. */
13764 /*-------------------------------------------------------------------*/
13765 nodePtr.p->activeStatus = Sysfile::NS_Active;
13766 takeOverCompleted(nodePtr.i);
13767 break;
13768 default:
13769 ndbrequire(false);
13770 return;
13771 break;
13772 }//switch
13773 }//if
13774 }//for
13775
13776 if(getNodeState().getNodeRestartInProgress()){
13777 jam();
13778 if(c_lcpState.m_participatingLQH.get(getOwnNodeId())){
13779 nodePtr.i = getOwnNodeId();
13780 ptrAss(nodePtr, nodeRecord);
13781 ndbrequire(nodePtr.p->activeStatus == Sysfile::NS_Active);
13782 g_eventLogger.info("NR: setLcpActiveStatusEnd - m_participatingLQH");
13783 } else {
13784 g_eventLogger.info("NR: setLcpActiveStatusEnd - !m_participatingLQH");
13785 }
13786 }
13787
13788 c_lcpState.m_participatingDIH.clear();
13789 c_lcpState.m_participatingLQH.clear();
13790 if (isMaster()) {
13791 jam();
13792 setNodeRestartInfoBits();
13793 }//if
13794 }//Dbdih::setLcpActiveStatusEnd()
13795
takeOverCompleted(Uint32 aNodeId)13796 void Dbdih::takeOverCompleted(Uint32 aNodeId)
13797 {
13798 TakeOverRecordPtr takeOverPtr;
13799 takeOverPtr.i = findTakeOver(aNodeId);
13800 if (takeOverPtr.i != RNIL) {
13801 jam();
13802 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
13803 if (takeOverPtr.p->toMasterStatus != TakeOverRecord::WAIT_LCP) {
13804 jam();
13805 ndbrequire(!isMaster());
13806 return;
13807 }//if
13808 ndbrequire(isMaster());
13809 Sysfile::setTakeOverNode(aNodeId, SYSFILE->takeOver, 0);
13810 takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_END_COPY;
13811 cstartGcpNow = true;
13812 }//if
13813 }//Dbdih::takeOverCompleted()
13814
13815 /*************************************************************************/
13816 /* SET LCP ACTIVE STATUS BEFORE STARTING A LOCAL CHECKPOINT. */
13817 /*************************************************************************/
setLcpActiveStatusStart(Signal * signal)13818 void Dbdih::setLcpActiveStatusStart(Signal* signal)
13819 {
13820 NodeRecordPtr nodePtr;
13821
13822 c_lcpState.m_participatingLQH.clear();
13823 c_lcpState.m_participatingDIH.clear();
13824
13825 for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
13826 ptrAss(nodePtr, nodeRecord);
13827 #if 0
13828 if(nodePtr.p->nodeStatus != NodeRecord::NOT_IN_CLUSTER){
13829 infoEvent("Node %d nodeStatus=%d activeStatus=%d copyCompleted=%d lcp=%d",
13830 nodePtr.i,
13831 nodePtr.p->nodeStatus,
13832 nodePtr.p->activeStatus,
13833 nodePtr.p->copyCompleted,
13834 nodePtr.p->m_inclDihLcp);
13835 }
13836 #endif
13837 if(nodePtr.p->nodeStatus == NodeRecord::ALIVE && nodePtr.p->m_inclDihLcp){
13838 jam();
13839 c_lcpState.m_participatingDIH.set(nodePtr.i);
13840 }
13841
13842 if ((nodePtr.p->nodeStatus == NodeRecord::ALIVE) &&
13843 (nodePtr.p->copyCompleted)) {
13844 switch (nodePtr.p->activeStatus) {
13845 case Sysfile::NS_Active:
13846 jam();
13847 /*-------------------------------------------------------------------*/
13848 // The normal case. Starting a LCP for a started node which hasn't
13849 // missed the previous LCP.
13850 /*-------------------------------------------------------------------*/
13851 c_lcpState.m_participatingLQH.set(nodePtr.i);
13852 break;
13853 case Sysfile::NS_ActiveMissed_1:
13854 jam();
13855 /*-------------------------------------------------------------------*/
13856 // The node is starting up and is participating in a local checkpoint
13857 // as the final phase of the start-up. We can still use the checkpoints
13858 // on the node after a system restart.
13859 /*-------------------------------------------------------------------*/
13860 c_lcpState.m_participatingLQH.set(nodePtr.i);
13861 break;
13862 case Sysfile::NS_ActiveMissed_2:
13863 jam();
13864 /*-------------------------------------------------------------------*/
13865 // The node is starting up and is participating in a local checkpoint
13866 // as the final phase of the start-up. We have missed so
13867 // many checkpoints that we no longer can use this node to
13868 // recreate fragments from disk.
13869 // It must be taken over with the copy fragment process after a system
13870 // crash. We indicate this by setting the active status to TAKE_OVER.
13871 /*-------------------------------------------------------------------*/
13872 c_lcpState.m_participatingLQH.set(nodePtr.i);
13873 nodePtr.p->activeStatus = Sysfile::NS_TakeOver;
13874 //break; // Fall through
13875 case Sysfile::NS_TakeOver:{
13876 TakeOverRecordPtr takeOverPtr;
13877 jam();
13878 /*-------------------------------------------------------------------*/
13879 /* THIS NODE IS CURRENTLY TAKING OVER A FAILED NODE. */
13880 /*-------------------------------------------------------------------*/
13881 takeOverPtr.i = findTakeOver(nodePtr.i);
13882 if (takeOverPtr.i != RNIL) {
13883 jam();
13884 ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
13885 if (takeOverPtr.p->toMasterStatus == TakeOverRecord::WAIT_LCP) {
13886 jam();
13887 /*---------------------------------------------------------------
13888 * ALL THE INFORMATION HAVE BEEN REPLICATED TO THE NEW
13889 * NODE AND WE ARE ONLY WAITING FOR A LOCAL CHECKPOINT TO BE
13890 * PERFORMED ON THE NODE TO SET ITS STATUS TO ACTIVE.
13891 */
13892 infoEvent("Node %d is WAIT_LCP including in LCP", nodePtr.i);
13893 c_lcpState.m_participatingLQH.set(nodePtr.i);
13894 }//if
13895 }//if
13896 break;
13897 }
13898 default:
13899 jam();
13900 /*empty*/;
13901 break;
13902 }//switch
13903 } else {
13904 switch (nodePtr.p->activeStatus) {
13905 case Sysfile::NS_Active:
13906 jam();
13907 nodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
13908 break;
13909 case Sysfile::NS_ActiveMissed_1:
13910 jam();
13911 nodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_2;
13912 break;
13913 case Sysfile::NS_ActiveMissed_2:
13914 jam();
13915 CRASH_INSERTION(7192);
13916 if ((nodePtr.p->nodeStatus == NodeRecord::ALIVE) &&
13917 (!nodePtr.p->copyCompleted)) {
13918 jam();
13919 /*-----------------------------------------------------------------*/
13920 // The node is currently starting up and has not completed the
13921 // copy phase.
13922 // It will thus be in the TAKE_OVER state.
13923 /*-----------------------------------------------------------------*/
13924 ndbrequire(findTakeOver(nodePtr.i) != RNIL);
13925 nodePtr.p->activeStatus = Sysfile::NS_TakeOver;
13926 } else {
13927 jam();
13928 /*-----------------------------------------------------------------*/
13929 /* THE NODE IS ACTIVE AND HAS NOT COMPLETED ANY OF THE LAST 3
13930 * CHECKPOINTS */
13931 /* WE MUST TAKE IT OUT OF ACTION AND START A NEW NODE TO TAKE OVER.*/
13932 /*-----------------------------------------------------------------*/
13933 nodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
13934 }//if
13935 break;
13936 case Sysfile::NS_TakeOver:
13937 jam();
13938 break;
13939 default:
13940 jam();
13941 /*empty*/;
13942 break;
13943 }//switch
13944 }//if
13945 }//for
13946 if (isMaster()) {
13947 jam();
13948 checkStartTakeOver(signal);
13949 setNodeRestartInfoBits();
13950 }//if
13951 }//Dbdih::setLcpActiveStatusStart()
13952
13953 /*************************************************************************/
13954 /* SET NODE ACTIVE STATUS AT SYSTEM RESTART AND WHEN UPDATED BY MASTER */
13955 /*************************************************************************/
setNodeActiveStatus()13956 void Dbdih::setNodeActiveStatus()
13957 {
13958 NodeRecordPtr snaNodeptr;
13959
13960 for (snaNodeptr.i = 1; snaNodeptr.i < MAX_NDB_NODES; snaNodeptr.i++) {
13961 ptrAss(snaNodeptr, nodeRecord);
13962 const Uint32 tsnaNodeBits = Sysfile::getNodeStatus(snaNodeptr.i,
13963 SYSFILE->nodeStatus);
13964 switch (tsnaNodeBits) {
13965 case Sysfile::NS_Active:
13966 jam();
13967 snaNodeptr.p->activeStatus = Sysfile::NS_Active;
13968 break;
13969 case Sysfile::NS_ActiveMissed_1:
13970 jam();
13971 snaNodeptr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
13972 break;
13973 case Sysfile::NS_ActiveMissed_2:
13974 jam();
13975 snaNodeptr.p->activeStatus = Sysfile::NS_ActiveMissed_2;
13976 break;
13977 case Sysfile::NS_TakeOver:
13978 jam();
13979 snaNodeptr.p->activeStatus = Sysfile::NS_TakeOver;
13980 break;
13981 case Sysfile::NS_HotSpare:
13982 jam();
13983 snaNodeptr.p->activeStatus = Sysfile::NS_HotSpare;
13984 break;
13985 case Sysfile::NS_NotActive_NotTakenOver:
13986 jam();
13987 snaNodeptr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
13988 break;
13989 case Sysfile::NS_NotDefined:
13990 jam();
13991 snaNodeptr.p->activeStatus = Sysfile::NS_NotDefined;
13992 break;
13993 default:
13994 ndbrequire(false);
13995 break;
13996 }//switch
13997 }//for
13998 }//Dbdih::setNodeActiveStatus()
13999
14000 /***************************************************************************/
14001 /* SET THE NODE GROUP BASED ON THE RESTART INFORMATION OR AS SET BY MASTER */
14002 /***************************************************************************/
setNodeGroups()14003 void Dbdih::setNodeGroups()
14004 {
14005 NodeGroupRecordPtr NGPtr;
14006 NodeRecordPtr sngNodeptr;
14007 Uint32 Ti;
14008
14009 for (Ti = 0; Ti < MAX_NDB_NODES; Ti++) {
14010 NGPtr.i = Ti;
14011 ptrAss(NGPtr, nodeGroupRecord);
14012 NGPtr.p->nodeCount = 0;
14013 }//for
14014 for (sngNodeptr.i = 1; sngNodeptr.i < MAX_NDB_NODES; sngNodeptr.i++) {
14015 ptrAss(sngNodeptr, nodeRecord);
14016 Sysfile::ActiveStatus s =
14017 (Sysfile::ActiveStatus)Sysfile::getNodeStatus(sngNodeptr.i,
14018 SYSFILE->nodeStatus);
14019 switch (s){
14020 case Sysfile::NS_Active:
14021 case Sysfile::NS_ActiveMissed_1:
14022 case Sysfile::NS_ActiveMissed_2:
14023 case Sysfile::NS_NotActive_NotTakenOver:
14024 case Sysfile::NS_TakeOver:
14025 jam();
14026 sngNodeptr.p->nodeGroup = Sysfile::getNodeGroup(sngNodeptr.i,
14027 SYSFILE->nodeGroups);
14028 NGPtr.i = sngNodeptr.p->nodeGroup;
14029 ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
14030 NGPtr.p->nodesInGroup[NGPtr.p->nodeCount] = sngNodeptr.i;
14031 NGPtr.p->nodeCount++;
14032 break;
14033 case Sysfile::NS_HotSpare:
14034 case Sysfile::NS_NotDefined:
14035 jam();
14036 sngNodeptr.p->nodeGroup = ZNIL;
14037 break;
14038 default:
14039 ndbrequire(false);
14040 return;
14041 break;
14042 }//switch
14043 }//for
14044 cnoOfNodeGroups = 0;
14045 for (Ti = 0; Ti < MAX_NDB_NODES; Ti++) {
14046 jam();
14047 NGPtr.i = Ti;
14048 ptrAss(NGPtr, nodeGroupRecord);
14049 if (NGPtr.p->nodeCount != 0) {
14050 jam();
14051 cnoOfNodeGroups++;
14052 }//if
14053 }//for
14054 cnoHotSpare = csystemnodes - (cnoOfNodeGroups * cnoReplicas);
14055 }//Dbdih::setNodeGroups()
14056
14057 /*************************************************************************/
14058 /* SET NODE INFORMATION AFTER RECEIVING RESTART INFORMATION FROM MASTER. */
14059 /* WE TAKE THE OPPORTUNITY TO SYNCHRONISE OUR DATA WITH THE MASTER. IT */
14060 /* IS ONLY THE MASTER THAT WILL ACT ON THIS DATA. WE WILL KEEP THEM */
14061 /* UPDATED FOR THE CASE WHEN WE HAVE TO BECOME MASTER. */
14062 /*************************************************************************/
setNodeInfo(Signal * signal)14063 void Dbdih::setNodeInfo(Signal* signal)
14064 {
14065 setNodeActiveStatus();
14066 setNodeGroups();
14067 sendHOT_SPAREREP(signal);
14068 }//Dbdih::setNodeInfo()
14069
14070 /*************************************************************************/
14071 // Keep also DBDICT informed about the Hot Spare situation in the cluster.
14072 /*************************************************************************/
sendHOT_SPAREREP(Signal * signal)14073 void Dbdih::sendHOT_SPAREREP(Signal* signal)
14074 {
14075 NodeRecordPtr locNodeptr;
14076 Uint32 Ti = 0;
14077 HotSpareRep * const hotSpare = (HotSpareRep*)&signal->theData[0];
14078 NodeBitmask::clear(hotSpare->theHotSpareNodes);
14079 for (locNodeptr.i = 1; locNodeptr.i < MAX_NDB_NODES; locNodeptr.i++) {
14080 ptrAss(locNodeptr, nodeRecord);
14081 switch (locNodeptr.p->activeStatus) {
14082 case Sysfile::NS_HotSpare:
14083 jam();
14084 NodeBitmask::set(hotSpare->theHotSpareNodes, locNodeptr.i);
14085 Ti++;
14086 break;
14087 default:
14088 jam();
14089 break;
14090 }//switch
14091 }//for
14092 hotSpare->noHotSpareNodes = Ti;
14093 sendSignal(DBDICT_REF, GSN_HOT_SPAREREP,
14094 signal, HotSpareRep::SignalLength, JBB);
14095 }//Dbdih::sendHOT_SPAREREP()
14096
14097 /*************************************************************************/
14098 /* SET LCP ACTIVE STATUS FOR ALL NODES BASED ON THE INFORMATION IN */
14099 /* THE RESTART INFORMATION. */
14100 /*************************************************************************/
14101 #if 0
14102 void Dbdih::setNodeLcpActiveStatus()
14103 {
14104 c_lcpState.m_lcpActiveStatus.clear();
14105 for (Uint32 i = 1; i < MAX_NDB_NODES; i++) {
14106 if (NodeBitmask::get(SYSFILE->lcpActive, i)) {
14107 jam();
14108 c_lcpState.m_lcpActiveStatus.set(i);
14109 }//if
14110 }//for
14111 }//Dbdih::setNodeLcpActiveStatus()
14112 #endif
14113
14114 /*************************************************************************/
14115 /* SET THE RESTART INFO BITS BASED ON THE NODES ACTIVE STATUS. */
14116 /*************************************************************************/
setNodeRestartInfoBits()14117 void Dbdih::setNodeRestartInfoBits()
14118 {
14119 NodeRecordPtr nodePtr;
14120 Uint32 tsnrNodeGroup;
14121 Uint32 tsnrNodeActiveStatus;
14122 Uint32 i;
14123 for(i = 1; i < MAX_NDB_NODES; i++){
14124 Sysfile::setNodeStatus(i, SYSFILE->nodeStatus, Sysfile::NS_Active);
14125 }//for
14126 for(i = 1; i < Sysfile::NODE_GROUPS_SIZE; i++){
14127 SYSFILE->nodeGroups[i] = 0;
14128 }//for
14129 NdbNodeBitmask::clear(SYSFILE->lcpActive);
14130
14131 for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
14132 ptrAss(nodePtr, nodeRecord);
14133 switch (nodePtr.p->activeStatus) {
14134 case Sysfile::NS_Active:
14135 jam();
14136 tsnrNodeActiveStatus = Sysfile::NS_Active;
14137 break;
14138 case Sysfile::NS_ActiveMissed_1:
14139 jam();
14140 tsnrNodeActiveStatus = Sysfile::NS_ActiveMissed_1;
14141 break;
14142 case Sysfile::NS_ActiveMissed_2:
14143 jam();
14144 tsnrNodeActiveStatus = Sysfile::NS_ActiveMissed_2;
14145 break;
14146 case Sysfile::NS_HotSpare:
14147 jam();
14148 tsnrNodeActiveStatus = Sysfile::NS_HotSpare;
14149 break;
14150 case Sysfile::NS_TakeOver:
14151 jam();
14152 tsnrNodeActiveStatus = Sysfile::NS_TakeOver;
14153 break;
14154 case Sysfile::NS_NotActive_NotTakenOver:
14155 jam();
14156 tsnrNodeActiveStatus = Sysfile::NS_NotActive_NotTakenOver;
14157 break;
14158 case Sysfile::NS_NotDefined:
14159 jam();
14160 tsnrNodeActiveStatus = Sysfile::NS_NotDefined;
14161 break;
14162 default:
14163 ndbrequire(false);
14164 tsnrNodeActiveStatus = Sysfile::NS_NotDefined; // remove warning
14165 break;
14166 }//switch
14167 Sysfile::setNodeStatus(nodePtr.i, SYSFILE->nodeStatus,
14168 tsnrNodeActiveStatus);
14169 if (nodePtr.p->nodeGroup == ZNIL) {
14170 jam();
14171 tsnrNodeGroup = NO_NODE_GROUP_ID;
14172 } else {
14173 jam();
14174 tsnrNodeGroup = nodePtr.p->nodeGroup;
14175 }//if
14176 Sysfile::setNodeGroup(nodePtr.i, SYSFILE->nodeGroups, tsnrNodeGroup);
14177 if (c_lcpState.m_participatingLQH.get(nodePtr.i)){
14178 jam();
14179 NodeBitmask::set(SYSFILE->lcpActive, nodePtr.i);
14180 }//if
14181 }//for
14182 }//Dbdih::setNodeRestartInfoBits()
14183
14184 /*************************************************************************/
14185 /* START THE GLOBAL CHECKPOINT PROTOCOL IN MASTER AT START-UP */
14186 /*************************************************************************/
startGcp(Signal * signal)14187 void Dbdih::startGcp(Signal* signal)
14188 {
14189 cgcpStatus = GCP_READY;
14190 coldGcpStatus = cgcpStatus;
14191 coldGcpId = cnewgcp;
14192 cgcpSameCounter = 0;
14193 signal->theData[0] = DihContinueB::ZSTART_GCP;
14194 signal->theData[1] = 0;
14195 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
14196 signal->theData[0] = DihContinueB::ZCHECK_GCP_STOP;
14197 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
14198 }//Dbdih::startGcp()
14199
updateNodeInfo(FragmentstorePtr fragPtr)14200 void Dbdih::updateNodeInfo(FragmentstorePtr fragPtr)
14201 {
14202 ReplicaRecordPtr replicatePtr;
14203 Uint32 index = 0;
14204 replicatePtr.i = fragPtr.p->storedReplicas;
14205 do {
14206 jam();
14207 ptrCheckGuard(replicatePtr, creplicaFileSize, replicaRecord);
14208 ndbrequire(index < MAX_REPLICAS);
14209 fragPtr.p->activeNodes[index] = replicatePtr.p->procNode;
14210 index++;
14211 replicatePtr.i = replicatePtr.p->nextReplica;
14212 } while (replicatePtr.i != RNIL);
14213 fragPtr.p->fragReplicas = index;
14214
14215 /* ----------------------------------------------------------------------- */
14216 // We switch primary to the preferred primary if the preferred primary is
14217 // in the list.
14218 /* ----------------------------------------------------------------------- */
14219 const Uint32 prefPrim = fragPtr.p->preferredPrimary;
14220 for (Uint32 i = 1; i < index; i++) {
14221 jam();
14222 ndbrequire(i < MAX_REPLICAS);
14223 if (fragPtr.p->activeNodes[i] == prefPrim){
14224 jam();
14225 Uint32 switchNode = fragPtr.p->activeNodes[0];
14226 fragPtr.p->activeNodes[0] = prefPrim;
14227 fragPtr.p->activeNodes[i] = switchNode;
14228 break;
14229 }//if
14230 }//for
14231 }//Dbdih::updateNodeInfo()
14232
writeFragment(RWFragment * wf,FragmentstorePtr fragPtr)14233 void Dbdih::writeFragment(RWFragment* wf, FragmentstorePtr fragPtr)
14234 {
14235 writePageWord(wf, wf->fragId);
14236 writePageWord(wf, fragPtr.p->preferredPrimary);
14237 writePageWord(wf, fragPtr.p->noStoredReplicas);
14238 writePageWord(wf, fragPtr.p->noOldStoredReplicas);
14239 writePageWord(wf, fragPtr.p->distributionKey);
14240 writePageWord(wf, fragPtr.p->m_log_part_id);
14241 }//Dbdih::writeFragment()
14242
writePageWord(RWFragment * wf,Uint32 dataWord)14243 void Dbdih::writePageWord(RWFragment* wf, Uint32 dataWord)
14244 {
14245 if (wf->wordIndex >= 2048) {
14246 jam();
14247 ndbrequire(wf->wordIndex == 2048);
14248 allocpage(wf->rwfPageptr);
14249 wf->wordIndex = 32;
14250 wf->pageIndex++;
14251 ndbrequire(wf->pageIndex < 8);
14252 wf->rwfTabPtr.p->pageRef[wf->pageIndex] = wf->rwfPageptr.i;
14253 wf->rwfTabPtr.p->noPages++;
14254 }//if
14255 wf->rwfPageptr.p->word[wf->wordIndex] = dataWord;
14256 wf->wordIndex++;
14257 }//Dbdih::writePageWord()
14258
writeReplicas(RWFragment * wf,Uint32 replicaStartIndex)14259 void Dbdih::writeReplicas(RWFragment* wf, Uint32 replicaStartIndex)
14260 {
14261 ReplicaRecordPtr wfReplicaPtr;
14262 wfReplicaPtr.i = replicaStartIndex;
14263 while (wfReplicaPtr.i != RNIL) {
14264 jam();
14265 ptrCheckGuard(wfReplicaPtr, creplicaFileSize, replicaRecord);
14266 writePageWord(wf, wfReplicaPtr.p->procNode);
14267 writePageWord(wf, wfReplicaPtr.p->initialGci);
14268 writePageWord(wf, wfReplicaPtr.p->noCrashedReplicas);
14269 writePageWord(wf, wfReplicaPtr.p->nextLcp);
14270 Uint32 i;
14271 for (i = 0; i < MAX_LCP_STORED; i++) {
14272 writePageWord(wf, wfReplicaPtr.p->maxGciCompleted[i]);
14273 writePageWord(wf, wfReplicaPtr.p->maxGciStarted[i]);
14274 writePageWord(wf, wfReplicaPtr.p->lcpId[i]);
14275 writePageWord(wf, wfReplicaPtr.p->lcpStatus[i]);
14276 }//if
14277 for (i = 0; i < 8; i++) {
14278 writePageWord(wf, wfReplicaPtr.p->createGci[i]);
14279 writePageWord(wf, wfReplicaPtr.p->replicaLastGci[i]);
14280 }//if
14281
14282 wfReplicaPtr.i = wfReplicaPtr.p->nextReplica;
14283 }//while
14284 }//Dbdih::writeReplicas()
14285
writeRestorableGci(Signal * signal,FileRecordPtr filePtr)14286 void Dbdih::writeRestorableGci(Signal* signal, FileRecordPtr filePtr)
14287 {
14288 for (Uint32 i = 0; i < Sysfile::SYSFILE_SIZE32; i++) {
14289 sysfileDataToFile[i] = sysfileData[i];
14290 }//for
14291 signal->theData[0] = filePtr.p->fileRef;
14292 signal->theData[1] = reference();
14293 signal->theData[2] = filePtr.i;
14294 signal->theData[3] = ZLIST_OF_PAIRS_SYNCH;
14295 signal->theData[4] = ZVAR_NO_CRESTART_INFO_TO_FILE;
14296 signal->theData[5] = 1; /* AMOUNT OF PAGES */
14297 signal->theData[6] = 0; /* MEMORY PAGE = 0 SINCE COMMON STORED VARIABLE */
14298 signal->theData[7] = 0;
14299 sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
14300 }//Dbdih::writeRestorableGci()
14301
writeTabfile(Signal * signal,TabRecord * tab,FileRecordPtr filePtr)14302 void Dbdih::writeTabfile(Signal* signal, TabRecord* tab, FileRecordPtr filePtr)
14303 {
14304 signal->theData[0] = filePtr.p->fileRef;
14305 signal->theData[1] = reference();
14306 signal->theData[2] = filePtr.i;
14307 signal->theData[3] = ZLIST_OF_PAIRS_SYNCH;
14308 signal->theData[4] = ZVAR_NO_WORD;
14309 signal->theData[5] = tab->noPages;
14310 for (Uint32 i = 0; i < tab->noPages; i++) {
14311 jam();
14312 signal->theData[6 + (2 * i)] = tab->pageRef[i];
14313 signal->theData[7 + (2 * i)] = i;
14314 }//for
14315 Uint32 length = 6 + (2 * tab->noPages);
14316 sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, length, JBA);
14317 }//Dbdih::writeTabfile()
14318
execDEBUG_SIG(Signal * signal)14319 void Dbdih::execDEBUG_SIG(Signal* signal)
14320 {
14321 signal = signal; //Avoid compiler warnings
14322 }//Dbdih::execDEBUG_SIG()
14323
14324 void
execDUMP_STATE_ORD(Signal * signal)14325 Dbdih::execDUMP_STATE_ORD(Signal* signal)
14326 {
14327 DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0];
14328 Uint32 arg = dumpState->args[0];
14329 if (arg == DumpStateOrd::DihDumpNodeRestartInfo) {
14330 infoEvent("c_nodeStartMaster.blockLcp = %d, c_nodeStartMaster.blockGcp = %d, c_nodeStartMaster.wait = %d",
14331 c_nodeStartMaster.blockLcp, c_nodeStartMaster.blockGcp, c_nodeStartMaster.wait);
14332 infoEvent("cstartGcpNow = %d, cgcpStatus = %d",
14333 cstartGcpNow, cgcpStatus);
14334 infoEvent("cfirstVerifyQueue = %d, cverifyQueueCounter = %d",
14335 cfirstVerifyQueue, cverifyQueueCounter);
14336 infoEvent("cgcpOrderBlocked = %d, cgcpStartCounter = %d",
14337 cgcpOrderBlocked, cgcpStartCounter);
14338 }//if
14339 if (arg == DumpStateOrd::DihDumpNodeStatusInfo) {
14340 NodeRecordPtr localNodePtr;
14341 infoEvent("Printing nodeStatus of all nodes");
14342 for (localNodePtr.i = 1; localNodePtr.i < MAX_NDB_NODES; localNodePtr.i++) {
14343 ptrAss(localNodePtr, nodeRecord);
14344 if (localNodePtr.p->nodeStatus != NodeRecord::NOT_IN_CLUSTER) {
14345 infoEvent("Node = %d has status = %d",
14346 localNodePtr.i, localNodePtr.p->nodeStatus);
14347 }//if
14348 }//for
14349 }//if
14350
14351 if (arg == DumpStateOrd::DihPrintFragmentation){
14352 infoEvent("Printing fragmentation of all tables --");
14353 for(Uint32 i = 0; i<ctabFileSize; i++){
14354 TabRecordPtr tabPtr;
14355 tabPtr.i = i;
14356 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
14357
14358 if(tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
14359 continue;
14360
14361 for(Uint32 j = 0; j < tabPtr.p->totalfragments; j++){
14362 FragmentstorePtr fragPtr;
14363 getFragstore(tabPtr.p, j, fragPtr);
14364
14365 Uint32 nodeOrder[MAX_REPLICAS];
14366 const Uint32 noOfReplicas = extractNodeInfo(fragPtr.p, nodeOrder);
14367 char buf[100];
14368 BaseString::snprintf(buf, sizeof(buf), " Table %d Fragment %d - ", tabPtr.i, j);
14369 for(Uint32 k = 0; k < noOfReplicas; k++){
14370 char tmp[100];
14371 BaseString::snprintf(tmp, sizeof(tmp), "%d ", nodeOrder[k]);
14372 strcat(buf, tmp);
14373 }
14374 infoEvent(buf);
14375 }
14376 }
14377 }
14378
14379 if (signal->theData[0] == 7000) {
14380 infoEvent("ctimer = %d, cgcpParticipantState = %d, cgcpStatus = %d",
14381 c_lcpState.ctimer, cgcpParticipantState, cgcpStatus);
14382 infoEvent("coldGcpStatus = %d, coldGcpId = %d, cmasterState = %d",
14383 coldGcpStatus, coldGcpId, cmasterState);
14384 infoEvent("cmasterTakeOverNode = %d, ctcCounter = %d",
14385 cmasterTakeOverNode, c_lcpState.ctcCounter);
14386 }//if
14387 if (signal->theData[0] == 7001) {
14388 infoEvent("c_lcpState.keepGci = %d",
14389 c_lcpState.keepGci);
14390 infoEvent("c_lcpState.lcpStatus = %d, clcpStopGcp = %d",
14391 c_lcpState.lcpStatus,
14392 c_lcpState.lcpStopGcp);
14393 infoEvent("cgcpStartCounter = %d, cimmediateLcpStart = %d",
14394 cgcpStartCounter, c_lcpState.immediateLcpStart);
14395 }//if
14396 if (signal->theData[0] == 7002) {
14397 infoEvent("cnoOfActiveTables = %d, cgcpDelay = %d",
14398 cnoOfActiveTables, cgcpDelay);
14399 infoEvent("cdictblockref = %d, cfailurenr = %d",
14400 cdictblockref, cfailurenr);
14401 infoEvent("con_lineNodes = %d, reference() = %d, creceivedfrag = %d",
14402 con_lineNodes, reference(), creceivedfrag);
14403 }//if
14404 if (signal->theData[0] == 7003) {
14405 infoEvent("cfirstAliveNode = %d, cgckptflag = %d",
14406 cfirstAliveNode, cgckptflag);
14407 infoEvent("clocallqhblockref = %d, clocaltcblockref = %d, cgcpOrderBlocked = %d",
14408 clocallqhblockref, clocaltcblockref, cgcpOrderBlocked);
14409 infoEvent("cstarttype = %d, csystemnodes = %d, currentgcp = %d",
14410 cstarttype, csystemnodes, currentgcp);
14411 }//if
14412 if (signal->theData[0] == 7004) {
14413 infoEvent("cmasterdihref = %d, cownNodeId = %d, cnewgcp = %d",
14414 cmasterdihref, cownNodeId, cnewgcp);
14415 infoEvent("cndbStartReqBlockref = %d, cremainingfrags = %d",
14416 cndbStartReqBlockref, cremainingfrags);
14417 infoEvent("cntrlblockref = %d, cgcpSameCounter = %d, coldgcp = %d",
14418 cntrlblockref, cgcpSameCounter, coldgcp);
14419 }//if
14420 if (signal->theData[0] == 7005) {
14421 infoEvent("crestartGci = %d",
14422 crestartGci);
14423 }//if
14424 if (signal->theData[0] == 7006) {
14425 infoEvent("clcpDelay = %d, cgcpMasterTakeOverState = %d",
14426 c_lcpState.clcpDelay, cgcpMasterTakeOverState);
14427 infoEvent("cmasterNodeId = %d", cmasterNodeId);
14428 infoEvent("cnoHotSpare = %d, c_nodeStartMaster.startNode = %d, c_nodeStartMaster.wait = %d",
14429 cnoHotSpare, c_nodeStartMaster.startNode, c_nodeStartMaster.wait);
14430 }//if
14431 if (signal->theData[0] == 7007) {
14432 infoEvent("c_nodeStartMaster.failNr = %d", c_nodeStartMaster.failNr);
14433 infoEvent("c_nodeStartMaster.startInfoErrorCode = %d",
14434 c_nodeStartMaster.startInfoErrorCode);
14435 infoEvent("c_nodeStartMaster.blockLcp = %d, c_nodeStartMaster.blockGcp = %d",
14436 c_nodeStartMaster.blockLcp, c_nodeStartMaster.blockGcp);
14437 }//if
14438 if (signal->theData[0] == 7008) {
14439 infoEvent("cfirstDeadNode = %d, cstartPhase = %d, cnoReplicas = %d",
14440 cfirstDeadNode, cstartPhase, cnoReplicas);
14441 infoEvent("cwaitLcpSr = %d",cwaitLcpSr);
14442 }//if
14443 if (signal->theData[0] == 7009) {
14444 infoEvent("ccalcOldestRestorableGci = %d, cnoOfNodeGroups = %d",
14445 c_lcpState.oldestRestorableGci, cnoOfNodeGroups);
14446 infoEvent("cstartGcpNow = %d",
14447 cstartGcpNow);
14448 infoEvent("crestartGci = %d",
14449 crestartGci);
14450 }//if
14451 if (signal->theData[0] == 7010) {
14452 infoEvent("cminHotSpareNodes = %d, c_lcpState.lcpStatusUpdatedPlace = %d, cLcpStart = %d",
14453 cminHotSpareNodes, c_lcpState.lcpStatusUpdatedPlace, c_lcpState.lcpStart);
14454 infoEvent("c_blockCommit = %d, c_blockCommitNo = %d",
14455 c_blockCommit, c_blockCommitNo);
14456 }//if
14457 if (signal->theData[0] == 7011){
14458 infoEvent("c_COPY_GCIREQ_Counter = %s",
14459 c_COPY_GCIREQ_Counter.getText());
14460 infoEvent("c_COPY_TABREQ_Counter = %s",
14461 c_COPY_TABREQ_Counter.getText());
14462 infoEvent("c_CREATE_FRAGREQ_Counter = %s",
14463 c_CREATE_FRAGREQ_Counter.getText());
14464 infoEvent("c_DIH_SWITCH_REPLICA_REQ_Counter = %s",
14465 c_DIH_SWITCH_REPLICA_REQ_Counter.getText());
14466 infoEvent("c_EMPTY_LCP_REQ_Counter = %s",c_EMPTY_LCP_REQ_Counter.getText());
14467 infoEvent("c_END_TOREQ_Counter = %s", c_END_TOREQ_Counter.getText());
14468 infoEvent("c_GCP_COMMIT_Counter = %s", c_GCP_COMMIT_Counter.getText());
14469 infoEvent("c_GCP_PREPARE_Counter = %s", c_GCP_PREPARE_Counter.getText());
14470 infoEvent("c_GCP_SAVEREQ_Counter = %s", c_GCP_SAVEREQ_Counter.getText());
14471 infoEvent("c_INCL_NODEREQ_Counter = %s", c_INCL_NODEREQ_Counter.getText());
14472 infoEvent("c_MASTER_GCPREQ_Counter = %s",
14473 c_MASTER_GCPREQ_Counter.getText());
14474 infoEvent("c_MASTER_LCPREQ_Counter = %s",
14475 c_MASTER_LCPREQ_Counter.getText());
14476 infoEvent("c_START_INFOREQ_Counter = %s",
14477 c_START_INFOREQ_Counter.getText());
14478 infoEvent("c_START_RECREQ_Counter = %s", c_START_RECREQ_Counter.getText());
14479 infoEvent("c_START_TOREQ_Counter = %s", c_START_TOREQ_Counter.getText());
14480 infoEvent("c_STOP_ME_REQ_Counter = %s", c_STOP_ME_REQ_Counter.getText());
14481 infoEvent("c_TC_CLOPSIZEREQ_Counter = %s",
14482 c_TC_CLOPSIZEREQ_Counter.getText());
14483 infoEvent("c_TCGETOPSIZEREQ_Counter = %s",
14484 c_TCGETOPSIZEREQ_Counter.getText());
14485 infoEvent("c_UPDATE_TOREQ_Counter = %s", c_UPDATE_TOREQ_Counter.getText());
14486 }
14487
14488 if(signal->theData[0] == 7012){
14489 char buf[8*_NDB_NODE_BITMASK_SIZE+1];
14490 infoEvent("ParticipatingDIH = %s", c_lcpState.m_participatingDIH.getText(buf));
14491 infoEvent("ParticipatingLQH = %s", c_lcpState.m_participatingLQH.getText(buf));
14492 infoEvent("m_LCP_COMPLETE_REP_Counter_DIH = %s",
14493 c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.getText());
14494 infoEvent("m_LCP_COMPLETE_REP_Counter_LQH = %s",
14495 c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.getText());
14496 infoEvent("m_LAST_LCP_FRAG_ORD = %s",
14497 c_lcpState.m_LAST_LCP_FRAG_ORD.getText());
14498 infoEvent("m_LCP_COMPLETE_REP_From_Master_Received = %d",
14499 c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received);
14500
14501 NodeRecordPtr nodePtr;
14502 for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
14503 jam();
14504 ptrAss(nodePtr, nodeRecord);
14505 if(nodePtr.p->nodeStatus == NodeRecord::ALIVE){
14506 Uint32 i;
14507 for(i = 0; i<nodePtr.p->noOfStartedChkpt; i++){
14508 infoEvent("Node %d: started: table=%d fragment=%d replica=%d",
14509 nodePtr.i,
14510 nodePtr.p->startedChkpt[i].tableId,
14511 nodePtr.p->startedChkpt[i].fragId,
14512 nodePtr.p->startedChkpt[i].replicaPtr);
14513 }
14514
14515 for(i = 0; i<nodePtr.p->noOfQueuedChkpt; i++){
14516 infoEvent("Node %d: queued: table=%d fragment=%d replica=%d",
14517 nodePtr.i,
14518 nodePtr.p->queuedChkpt[i].tableId,
14519 nodePtr.p->queuedChkpt[i].fragId,
14520 nodePtr.p->queuedChkpt[i].replicaPtr);
14521 }
14522 }
14523 }
14524 }
14525
14526 if(arg == 7019 && signal->getLength() == 2)
14527 {
14528 char buf2[8+1];
14529 NodeRecordPtr nodePtr;
14530 nodePtr.i = signal->theData[1];
14531 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
14532 infoEvent("NF Node %d tc: %d lqh: %d dih: %d dict: %d recNODE_FAILREP: %d",
14533 nodePtr.i,
14534 nodePtr.p->dbtcFailCompleted,
14535 nodePtr.p->dblqhFailCompleted,
14536 nodePtr.p->dbdihFailCompleted,
14537 nodePtr.p->dbdictFailCompleted,
14538 nodePtr.p->recNODE_FAILREP);
14539 infoEvent(" m_NF_COMPLETE_REP: %s m_nodefailSteps: %s",
14540 nodePtr.p->m_NF_COMPLETE_REP.getText(),
14541 nodePtr.p->m_nodefailSteps.getText(buf2));
14542 }
14543
14544 if(arg == 7020 && signal->getLength() > 3)
14545 {
14546 Uint32 gsn= signal->theData[1];
14547 Uint32 block= signal->theData[2];
14548 Uint32 length= signal->length() - 3;
14549 memmove(signal->theData, signal->theData+3, 4*length);
14550 sendSignal(numberToRef(block, getOwnNodeId()), gsn, signal, length, JBB);
14551
14552 warningEvent("-- SENDING CUSTOM SIGNAL --");
14553 char buf[100], buf2[100];
14554 buf2[0]= 0;
14555 for(Uint32 i = 0; i<length; i++)
14556 {
14557 snprintf(buf, 100, "%s %.8x", buf2, signal->theData[i]);
14558 snprintf(buf2, 100, "%s", buf);
14559 }
14560 warningEvent("gsn: %d block: %s, length: %d theData: %s",
14561 gsn, getBlockName(block, "UNKNOWN"), length, buf);
14562
14563 g_eventLogger.warning("-- SENDING CUSTOM SIGNAL --");
14564 g_eventLogger.warning("gsn: %d block: %s, length: %d theData: %s",
14565 gsn, getBlockName(block, "UNKNOWN"), length, buf);
14566 }
14567
14568 if(arg == DumpStateOrd::DihDumpLCPState){
14569 infoEvent("-- Node %d LCP STATE --", getOwnNodeId());
14570 infoEvent("lcpStatus = %d (update place = %d) ",
14571 c_lcpState.lcpStatus, c_lcpState.lcpStatusUpdatedPlace);
14572 infoEvent
14573 ("lcpStart = %d lcpStopGcp = %d keepGci = %d oldestRestorable = %d",
14574 c_lcpState.lcpStart, c_lcpState.lcpStopGcp,
14575 c_lcpState.keepGci, c_lcpState.oldestRestorableGci);
14576
14577 infoEvent
14578 ("immediateLcpStart = %d masterLcpNodeId = %d",
14579 c_lcpState.immediateLcpStart,
14580 refToNode(c_lcpState.m_masterLcpDihRef));
14581
14582 for (Uint32 i = 0; i<10; i++)
14583 {
14584 infoEvent("%u : status: %u place: %u", i,
14585 c_lcpState.m_saveState[i].m_status,
14586 c_lcpState.m_saveState[i].m_place);
14587 }
14588
14589 infoEvent("-- Node %d LCP STATE --", getOwnNodeId());
14590 }
14591
14592 if(arg == DumpStateOrd::DihDumpLCPMasterTakeOver){
14593 infoEvent("-- Node %d LCP MASTER TAKE OVER STATE --", getOwnNodeId());
14594 infoEvent
14595 ("c_lcpMasterTakeOverState.state = %d updatePlace = %d failedNodeId = %d",
14596 c_lcpMasterTakeOverState.state,
14597 c_lcpMasterTakeOverState.updatePlace,
14598 c_lcpMasterTakeOverState.failedNodeId);
14599
14600 infoEvent("c_lcpMasterTakeOverState.minTableId = %u minFragId = %u",
14601 c_lcpMasterTakeOverState.minTableId,
14602 c_lcpMasterTakeOverState.minFragId);
14603
14604 infoEvent("-- Node %d LCP MASTER TAKE OVER STATE --", getOwnNodeId());
14605 }
14606
14607 if (signal->theData[0] == 7015)
14608 {
14609 if (signal->getLength() == 1)
14610 {
14611 signal->theData[1] = 0;
14612 }
14613
14614 Uint32 tableId = signal->theData[1];
14615 if (tableId < ctabFileSize)
14616 {
14617 signal->theData[0] = 7021;
14618 execDUMP_STATE_ORD(signal);
14619 signal->theData[0] = 7015;
14620 signal->theData[1] = tableId + 1;
14621 sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 2, JBB);
14622 }
14623 }
14624
14625 if(arg == DumpStateOrd::EnableUndoDelayDataWrite){
14626 g_eventLogger.info("Dbdih:: delay write of datapages for table = %d",
14627 dumpState->args[1]);
14628 // Send this dump to ACC and TUP
14629 EXECUTE_DIRECT(DBACC, GSN_DUMP_STATE_ORD, signal, 2);
14630 EXECUTE_DIRECT(DBTUP, GSN_DUMP_STATE_ORD, signal, 2);
14631
14632 // Start immediate LCP
14633 c_lcpState.ctimer += (1 << c_lcpState.clcpDelay);
14634 return;
14635 }
14636
14637 if (signal->theData[0] == DumpStateOrd::DihAllAllowNodeStart) {
14638 for (Uint32 i = 1; i < MAX_NDB_NODES; i++)
14639 setAllowNodeStart(i, true);
14640 return;
14641 }//if
14642 if (signal->theData[0] == DumpStateOrd::DihMinTimeBetweenLCP) {
14643 // Set time between LCP to min value
14644 g_eventLogger.info("Set time between LCP to min value");
14645 c_lcpState.clcpDelay = 0; // TimeBetweenLocalCheckpoints.min
14646 return;
14647 }
14648 if (signal->theData[0] == DumpStateOrd::DihMaxTimeBetweenLCP) {
14649 // Set time between LCP to max value
14650 g_eventLogger.info("Set time between LCP to max value");
14651 c_lcpState.clcpDelay = 31; // TimeBetweenLocalCheckpoints.max
14652 return;
14653 }
14654
14655 if(arg == 7098){
14656 if(signal->length() == 3){
14657 jam();
14658 infoEvent("startLcpRoundLoopLab(tabel=%d, fragment=%d)",
14659 signal->theData[1], signal->theData[2]);
14660 startLcpRoundLoopLab(signal, signal->theData[1], signal->theData[2]);
14661 return;
14662 } else {
14663 infoEvent("Invalid no of arguments to 7098 - startLcpRoundLoopLab -"
14664 " expected 2 (tableId, fragmentId)");
14665 }
14666 }
14667
14668 if(arg == DumpStateOrd::DihStartLcpImmediately){
14669 c_lcpState.ctimer += (1 << c_lcpState.clcpDelay);
14670 return;
14671 }
14672
14673 if (arg == DumpStateOrd::DihSetTimeBetweenGcp)
14674 {
14675 if (signal->getLength() == 1)
14676 {
14677 const ndb_mgm_configuration_iterator * p =
14678 m_ctx.m_config.getOwnConfigIterator();
14679 ndbrequire(p != 0);
14680 ndb_mgm_get_int_parameter(p, CFG_DB_GCP_INTERVAL, &cgcpDelay);
14681 }
14682 else
14683 {
14684 cgcpDelay = signal->theData[1];
14685 }
14686 g_eventLogger.info("Setting time between gcp : %d", cgcpDelay);
14687 }
14688
14689 if (arg == 7021 && signal->getLength() == 2)
14690 {
14691 TabRecordPtr tabPtr;
14692 tabPtr.i = signal->theData[1];
14693 if (tabPtr.i >= ctabFileSize)
14694 return;
14695
14696 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
14697
14698 if(tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
14699 return;
14700
14701 infoEvent
14702 ("Table %d: TabCopyStatus: %d TabUpdateStatus: %d TabLcpStatus: %d",
14703 tabPtr.i,
14704 tabPtr.p->tabCopyStatus,
14705 tabPtr.p->tabUpdateState,
14706 tabPtr.p->tabLcpStatus);
14707
14708 FragmentstorePtr fragPtr;
14709 for (Uint32 fid = 0; fid < tabPtr.p->totalfragments; fid++) {
14710 jam();
14711 getFragstore(tabPtr.p, fid, fragPtr);
14712
14713 char buf[100], buf2[100];
14714 BaseString::snprintf(buf, sizeof(buf), " Fragment %d: noLcpReplicas==%d ",
14715 fid, fragPtr.p->noLcpReplicas);
14716
14717 Uint32 num=0;
14718 ReplicaRecordPtr replicaPtr;
14719 replicaPtr.i = fragPtr.p->storedReplicas;
14720 do {
14721 ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
14722 BaseString::snprintf(buf2, sizeof(buf2), "%s %d(on %d)=%d(%s)",
14723 buf, num,
14724 replicaPtr.p->procNode,
14725 replicaPtr.p->lcpIdStarted,
14726 replicaPtr.p->lcpOngoingFlag ? "Ongoing" : "Idle");
14727 BaseString::snprintf(buf, sizeof(buf), "%s", buf2);
14728
14729 num++;
14730 replicaPtr.i = replicaPtr.p->nextReplica;
14731 } while (replicaPtr.i != RNIL);
14732 infoEvent(buf);
14733 }
14734 }
14735
14736 if (arg == 7022)
14737 {
14738 jam();
14739 crashSystemAtGcpStop(signal, true);
14740 }
14741 }//Dbdih::execDUMP_STATE_ORD()
14742
14743 void
execPREP_DROP_TAB_REQ(Signal * signal)14744 Dbdih::execPREP_DROP_TAB_REQ(Signal* signal){
14745 jamEntry();
14746
14747 PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
14748
14749 TabRecordPtr tabPtr;
14750 tabPtr.i = req->tableId;
14751 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
14752
14753 Uint32 senderRef = req->senderRef;
14754 Uint32 senderData = req->senderData;
14755
14756 PrepDropTabRef::ErrorCode err = PrepDropTabRef::OK;
14757 { /**
14758 * Check table state
14759 */
14760 bool ok = false;
14761 switch(tabPtr.p->tabStatus){
14762 case TabRecord::TS_IDLE:
14763 ok = true;
14764 jam();
14765 err = PrepDropTabRef::NoSuchTable;
14766 break;
14767 case TabRecord::TS_DROPPING:
14768 ok = true;
14769 jam();
14770 err = PrepDropTabRef::PrepDropInProgress;
14771 break;
14772 case TabRecord::TS_CREATING:
14773 jam();
14774 ok = true;
14775 break;
14776 case TabRecord::TS_ACTIVE:
14777 ok = true;
14778 jam();
14779 break;
14780 }
14781 ndbrequire(ok);
14782 }
14783
14784 if(err != PrepDropTabRef::OK){
14785 jam();
14786 PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
14787 ref->senderRef = reference();
14788 ref->senderData = senderData;
14789 ref->tableId = tabPtr.i;
14790 ref->errorCode = err;
14791 sendSignal(senderRef, GSN_PREP_DROP_TAB_REF, signal,
14792 PrepDropTabRef::SignalLength, JBB);
14793 return;
14794 }
14795
14796 tabPtr.p->tabStatus = TabRecord::TS_DROPPING;
14797 tabPtr.p->m_prepDropTab.senderRef = senderRef;
14798 tabPtr.p->m_prepDropTab.senderData = senderData;
14799
14800 if(isMaster()){
14801 /**
14802 * Remove from queue
14803 */
14804 NodeRecordPtr nodePtr;
14805 for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
14806 jam();
14807 ptrAss(nodePtr, nodeRecord);
14808 if (c_lcpState.m_participatingLQH.get(nodePtr.i)){
14809
14810 Uint32 index = 0;
14811 Uint32 count = nodePtr.p->noOfQueuedChkpt;
14812 while(index < count){
14813 if(nodePtr.p->queuedChkpt[index].tableId == tabPtr.i){
14814 jam();
14815 // g_eventLogger.info("Unqueuing %d", index);
14816
14817 count--;
14818 for(Uint32 i = index; i<count; i++){
14819 jam();
14820 nodePtr.p->queuedChkpt[i] = nodePtr.p->queuedChkpt[i + 1];
14821 }
14822 } else {
14823 index++;
14824 }
14825 }
14826 nodePtr.p->noOfQueuedChkpt = count;
14827 }
14828 }
14829 }
14830
14831 { /**
14832 * Check table lcp state
14833 */
14834
14835 bool ok = false;
14836 switch(tabPtr.p->tabLcpStatus){
14837 case TabRecord::TLS_COMPLETED:
14838 case TabRecord::TLS_WRITING_TO_FILE:
14839 ok = true;
14840 jam();
14841 break;
14842 return;
14843 case TabRecord::TLS_ACTIVE:
14844 ok = true;
14845 jam();
14846
14847 tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
14848
14849 /**
14850 * First check if all fragments are done
14851 */
14852 if(checkLcpAllTablesDoneInLqh()){
14853 jam();
14854
14855 g_eventLogger.info("This is the last table");
14856
14857 /**
14858 * Then check if saving of tab info is done for all tables
14859 */
14860 LcpStatus a = c_lcpState.lcpStatus;
14861 checkLcpCompletedLab(signal);
14862
14863 if(a != c_lcpState.lcpStatus){
14864 g_eventLogger.info("And all tables are written to already written disk");
14865 }
14866 }
14867 break;
14868 }
14869 ndbrequire(ok);
14870 }
14871
14872 { /**
14873 * Send WaitDropTabReq to all LQH
14874 */
14875 WaitDropTabReq * req = (WaitDropTabReq*)signal->getDataPtrSend();
14876 req->tableId = tabPtr.i;
14877 req->senderRef = reference();
14878
14879 NodeRecordPtr nodePtr;
14880 nodePtr.i = cfirstAliveNode;
14881 tabPtr.p->m_prepDropTab.waitDropTabCount.clearWaitingFor();
14882 while(nodePtr.i != RNIL){
14883 jam();
14884 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
14885
14886 tabPtr.p->m_prepDropTab.waitDropTabCount.setWaitingFor(nodePtr.i);
14887 sendSignal(calcLqhBlockRef(nodePtr.i), GSN_WAIT_DROP_TAB_REQ,
14888 signal, WaitDropTabReq::SignalLength, JBB);
14889
14890 nodePtr.i = nodePtr.p->nextNode;
14891 }
14892 }
14893
14894 waitDropTabWritingToFile(signal, tabPtr);
14895 }
14896
14897 void
waitDropTabWritingToFile(Signal * signal,TabRecordPtr tabPtr)14898 Dbdih::waitDropTabWritingToFile(Signal* signal, TabRecordPtr tabPtr){
14899
14900 if(tabPtr.p->tabLcpStatus == TabRecord::TLS_WRITING_TO_FILE){
14901 jam();
14902 signal->theData[0] = DihContinueB::WAIT_DROP_TAB_WRITING_TO_FILE;
14903 signal->theData[1] = tabPtr.i;
14904 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
14905 return;
14906 }
14907
14908 ndbrequire(tabPtr.p->tabLcpStatus == TabRecord::TLS_COMPLETED);
14909 checkPrepDropTabComplete(signal, tabPtr);
14910 }
14911
14912 void
checkPrepDropTabComplete(Signal * signal,TabRecordPtr tabPtr)14913 Dbdih::checkPrepDropTabComplete(Signal* signal, TabRecordPtr tabPtr){
14914
14915 if(tabPtr.p->tabLcpStatus != TabRecord::TLS_COMPLETED){
14916 jam();
14917 return;
14918 }
14919
14920 if(!tabPtr.p->m_prepDropTab.waitDropTabCount.done()){
14921 jam();
14922 return;
14923 }
14924
14925 const Uint32 ref = tabPtr.p->m_prepDropTab.senderRef;
14926 if(ref != 0){
14927 PrepDropTabConf* conf = (PrepDropTabConf*)signal->getDataPtrSend();
14928 conf->tableId = tabPtr.i;
14929 conf->senderRef = reference();
14930 conf->senderData = tabPtr.p->m_prepDropTab.senderData;
14931 sendSignal(tabPtr.p->m_prepDropTab.senderRef, GSN_PREP_DROP_TAB_CONF,
14932 signal, PrepDropTabConf::SignalLength, JBB);
14933 tabPtr.p->m_prepDropTab.senderRef = 0;
14934 }
14935 }
14936
14937 void
execWAIT_DROP_TAB_REF(Signal * signal)14938 Dbdih::execWAIT_DROP_TAB_REF(Signal* signal){
14939 jamEntry();
14940 WaitDropTabRef * ref = (WaitDropTabRef*)signal->getDataPtr();
14941
14942 TabRecordPtr tabPtr;
14943 tabPtr.i = ref->tableId;
14944 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
14945
14946 ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_DROPPING);
14947 Uint32 nodeId = refToNode(ref->senderRef);
14948
14949 ndbrequire(ref->errorCode == WaitDropTabRef::NoSuchTable ||
14950 ref->errorCode == WaitDropTabRef::NF_FakeErrorREF);
14951
14952 tabPtr.p->m_prepDropTab.waitDropTabCount.clearWaitingFor(nodeId);
14953 checkPrepDropTabComplete(signal, tabPtr);
14954 }
14955
14956 void
execWAIT_DROP_TAB_CONF(Signal * signal)14957 Dbdih::execWAIT_DROP_TAB_CONF(Signal* signal){
14958 jamEntry();
14959 WaitDropTabConf * conf = (WaitDropTabConf*)signal->getDataPtr();
14960
14961 TabRecordPtr tabPtr;
14962 tabPtr.i = conf->tableId;
14963 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
14964
14965 ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_DROPPING);
14966 Uint32 nodeId = refToNode(conf->senderRef);
14967 tabPtr.p->m_prepDropTab.waitDropTabCount.clearWaitingFor(nodeId);
14968 checkPrepDropTabComplete(signal, tabPtr);
14969 }
14970
14971 void
checkWaitDropTabFailedLqh(Signal * signal,Uint32 nodeId,Uint32 tableId)14972 Dbdih::checkWaitDropTabFailedLqh(Signal* signal, Uint32 nodeId, Uint32 tableId){
14973
14974 TabRecordPtr tabPtr;
14975 tabPtr.i = tableId;
14976
14977 WaitDropTabConf * conf = (WaitDropTabConf*)signal->getDataPtr();
14978 conf->tableId = tableId;
14979
14980 const Uint32 RT_BREAK = 16;
14981 for(Uint32 i = 0; i<RT_BREAK && tabPtr.i < ctabFileSize; i++, tabPtr.i++){
14982 ptrAss(tabPtr, tabRecord);
14983 if(tabPtr.p->tabStatus == TabRecord::TS_DROPPING){
14984 if(tabPtr.p->m_prepDropTab.waitDropTabCount.isWaitingFor(nodeId)){
14985 conf->senderRef = calcLqhBlockRef(nodeId);
14986 execWAIT_DROP_TAB_CONF(signal);
14987 tabPtr.i++;
14988 break;
14989 }
14990 }
14991 }
14992
14993 if(tabPtr.i == ctabFileSize){
14994 /**
14995 * Finished
14996 */
14997 jam();
14998 return;
14999 }
15000
15001 signal->theData[0] = DihContinueB::CHECK_WAIT_DROP_TAB_FAILED_LQH;
15002 signal->theData[1] = nodeId;
15003 signal->theData[2] = tabPtr.i;
15004 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
15005 }
15006
15007
15008 void
execNDB_TAMPER(Signal * signal)15009 Dbdih::execNDB_TAMPER(Signal* signal)
15010 {
15011 if ((ERROR_INSERTED(7011)) &&
15012 (signal->theData[0] == 7012)) {
15013 CLEAR_ERROR_INSERT_VALUE;
15014 calculateKeepGciLab(signal, 0, 0);
15015 return;
15016 }//if
15017 SET_ERROR_INSERT_VALUE(signal->theData[0]);
15018 return;
15019 }//Dbdih::execNDB_TAMPER()
15020
execBLOCK_COMMIT_ORD(Signal * signal)15021 void Dbdih::execBLOCK_COMMIT_ORD(Signal* signal){
15022 BlockCommitOrd* const block = (BlockCommitOrd *)&signal->theData[0];
15023
15024 jamEntry();
15025 #if 0
15026 ndbrequire(c_blockCommit == false ||
15027 c_blockCommitNo == block->failNo);
15028 #else
15029 if(!(c_blockCommit == false || c_blockCommitNo == block->failNo)){
15030 infoEvent("Possible bug in Dbdih::execBLOCK_COMMIT_ORD c_blockCommit = %d c_blockCommitNo = %d"
15031 " sig->failNo = %d", c_blockCommit, c_blockCommitNo, block->failNo);
15032 }
15033 #endif
15034 c_blockCommit = true;
15035 c_blockCommitNo = block->failNo;
15036 }
15037
execUNBLOCK_COMMIT_ORD(Signal * signal)15038 void Dbdih::execUNBLOCK_COMMIT_ORD(Signal* signal){
15039 UnblockCommitOrd* const unblock = (UnblockCommitOrd *)&signal->theData[0];
15040 (void)unblock;
15041
15042 jamEntry();
15043
15044 if(c_blockCommit == true){
15045 jam();
15046 // ndbrequire(c_blockCommitNo == unblock->failNo);
15047
15048 c_blockCommit = false;
15049 emptyverificbuffer(signal, true);
15050 }
15051 }
15052
execSTOP_PERM_REQ(Signal * signal)15053 void Dbdih::execSTOP_PERM_REQ(Signal* signal){
15054
15055 jamEntry();
15056
15057 StopPermReq* const req = (StopPermReq*)&signal->theData[0];
15058 StopPermRef* const ref = (StopPermRef*)&signal->theData[0];
15059
15060 const Uint32 senderData = req->senderData;
15061 const BlockReference senderRef = req->senderRef;
15062 const NodeId nodeId = refToNode(senderRef);
15063
15064 if (isMaster()) {
15065 /**
15066 * Master
15067 */
15068 jam();
15069 CRASH_INSERTION(7065);
15070 if (c_stopPermMaster.clientRef != 0) {
15071 jam();
15072
15073 ref->senderData = senderData;
15074 ref->errorCode = StopPermRef::NodeShutdownInProgress;
15075 sendSignal(senderRef, GSN_STOP_PERM_REF, signal,
15076 StopPermRef::SignalLength, JBB);
15077 return;
15078 }//if
15079
15080 if (c_nodeStartMaster.activeState) {
15081 jam();
15082 ref->senderData = senderData;
15083 ref->errorCode = StopPermRef::NodeStartInProgress;
15084 sendSignal(senderRef, GSN_STOP_PERM_REF, signal,
15085 StopPermRef::SignalLength, JBB);
15086 return;
15087 }//if
15088
15089 /**
15090 * Lock
15091 */
15092 c_nodeStartMaster.activeState = true;
15093 c_stopPermMaster.clientRef = senderRef;
15094
15095 c_stopPermMaster.clientData = senderData;
15096 c_stopPermMaster.returnValue = 0;
15097 c_switchReplicas.clear();
15098
15099 Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
15100 Callback c = { safe_cast(&Dbdih::switch_primary_stop_node), nodeId };
15101 ndbrequire(mutex.lock(c));
15102 } else {
15103 /**
15104 * Proxy part
15105 */
15106 jam();
15107 CRASH_INSERTION(7066);
15108 if(c_stopPermProxy.clientRef != 0){
15109 jam();
15110 ref->senderData = senderData;
15111 ref->errorCode = StopPermRef::NodeShutdownInProgress;
15112 sendSignal(senderRef, GSN_STOP_PERM_REF, signal, 2, JBB);
15113 return;
15114 }//if
15115
15116 c_stopPermProxy.clientRef = senderRef;
15117 c_stopPermProxy.masterRef = cmasterdihref;
15118 c_stopPermProxy.clientData = senderData;
15119
15120 req->senderRef = reference();
15121 req->senderData = senderData;
15122 sendSignal(cmasterdihref, GSN_STOP_PERM_REQ, signal,
15123 StopPermReq::SignalLength, JBB);
15124 }//if
15125 }//Dbdih::execSTOP_PERM_REQ()
15126
15127 void
switch_primary_stop_node(Signal * signal,Uint32 node_id,Uint32 ret_val)15128 Dbdih::switch_primary_stop_node(Signal* signal, Uint32 node_id, Uint32 ret_val)
15129 {
15130 ndbrequire(ret_val == 0);
15131 signal->theData[0] = DihContinueB::SwitchReplica;
15132 signal->theData[1] = node_id;
15133 signal->theData[2] = 0; // table id
15134 signal->theData[3] = 0; // fragment id
15135 sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
15136 }
15137
execSTOP_PERM_REF(Signal * signal)15138 void Dbdih::execSTOP_PERM_REF(Signal* signal)
15139 {
15140 jamEntry();
15141 ndbrequire(c_stopPermProxy.clientRef != 0);
15142 ndbrequire(c_stopPermProxy.masterRef == signal->senderBlockRef());
15143 sendSignal(c_stopPermProxy.clientRef, GSN_STOP_PERM_REF, signal, 2, JBB);
15144 c_stopPermProxy.clientRef = 0;
15145 }//Dbdih::execSTOP_PERM_REF()
15146
execSTOP_PERM_CONF(Signal * signal)15147 void Dbdih::execSTOP_PERM_CONF(Signal* signal)
15148 {
15149 jamEntry();
15150 ndbrequire(c_stopPermProxy.clientRef != 0);
15151 ndbrequire(c_stopPermProxy.masterRef == signal->senderBlockRef());
15152 sendSignal(c_stopPermProxy.clientRef, GSN_STOP_PERM_CONF, signal, 1, JBB);
15153 c_stopPermProxy.clientRef = 0;
15154 }//Dbdih::execSTOP_PERM_CONF()
15155
execDIH_SWITCH_REPLICA_REQ(Signal * signal)15156 void Dbdih::execDIH_SWITCH_REPLICA_REQ(Signal* signal)
15157 {
15158 jamEntry();
15159 DihSwitchReplicaReq* const req = (DihSwitchReplicaReq*)&signal->theData[0];
15160 const Uint32 tableId = req->tableId;
15161 const Uint32 fragNo = req->fragNo;
15162 const BlockReference senderRef = req->senderRef;
15163
15164 CRASH_INSERTION(7067);
15165 TabRecordPtr tabPtr;
15166 tabPtr.i = tableId;
15167 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
15168
15169 ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
15170 if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
15171 jam();
15172 sendSignal(reference(), GSN_DIH_SWITCH_REPLICA_REQ, signal,
15173 DihSwitchReplicaReq::SignalLength, JBB);
15174 return;
15175 }//if
15176 FragmentstorePtr fragPtr;
15177 getFragstore(tabPtr.p, fragNo, fragPtr);
15178
15179 /**
15180 * Do funky stuff
15181 */
15182 Uint32 oldOrder[MAX_REPLICAS];
15183 const Uint32 noOfReplicas = extractNodeInfo(fragPtr.p, oldOrder);
15184
15185 if (noOfReplicas < req->noOfReplicas) {
15186 jam();
15187 //---------------------------------------------------------------------
15188 // A crash occurred in the middle of our switch handling.
15189 //---------------------------------------------------------------------
15190 DihSwitchReplicaRef* const ref = (DihSwitchReplicaRef*)&signal->theData[0];
15191 ref->senderNode = cownNodeId;
15192 ref->errorCode = StopPermRef::NF_CausedAbortOfStopProcedure;
15193 sendSignal(senderRef, GSN_DIH_SWITCH_REPLICA_REF, signal,
15194 DihSwitchReplicaRef::SignalLength, JBB);
15195 }//if
15196 for (Uint32 i = 0; i < noOfReplicas; i++) {
15197 jam();
15198 ndbrequire(i < MAX_REPLICAS);
15199 fragPtr.p->activeNodes[i] = req->newNodeOrder[i];
15200 }//for
15201 /**
15202 * Reply
15203 */
15204 DihSwitchReplicaConf* const conf = (DihSwitchReplicaConf*)&signal->theData[0];
15205 conf->senderNode = cownNodeId;
15206 sendSignal(senderRef, GSN_DIH_SWITCH_REPLICA_CONF, signal,
15207 DihSwitchReplicaConf::SignalLength, JBB);
15208 }//Dbdih::execDIH_SWITCH_REPLICA_REQ()
15209
execDIH_SWITCH_REPLICA_CONF(Signal * signal)15210 void Dbdih::execDIH_SWITCH_REPLICA_CONF(Signal* signal)
15211 {
15212 jamEntry();
15213 /**
15214 * Response to master
15215 */
15216 CRASH_INSERTION(7068);
15217 DihSwitchReplicaConf* const conf = (DihSwitchReplicaConf*)&signal->theData[0];
15218 switchReplicaReply(signal, conf->senderNode);
15219 }//Dbdih::execDIH_SWITCH_REPLICA_CONF()
15220
execDIH_SWITCH_REPLICA_REF(Signal * signal)15221 void Dbdih::execDIH_SWITCH_REPLICA_REF(Signal* signal)
15222 {
15223 jamEntry();
15224 DihSwitchReplicaRef* const ref = (DihSwitchReplicaRef*)&signal->theData[0];
15225 if(c_stopPermMaster.returnValue == 0){
15226 jam();
15227 c_stopPermMaster.returnValue = ref->errorCode;
15228 }//if
15229 switchReplicaReply(signal, ref->senderNode);
15230 }//Dbdih::execDIH_SWITCH_REPLICA_REF()
15231
switchReplicaReply(Signal * signal,NodeId nodeId)15232 void Dbdih::switchReplicaReply(Signal* signal,
15233 NodeId nodeId){
15234 jam();
15235 receiveLoopMacro(DIH_SWITCH_REPLICA_REQ, nodeId);
15236 //------------------------------------------------------
15237 // We have received all responses from the nodes. Thus
15238 // we have completed switching replica roles. Continue
15239 // with the next fragment.
15240 //------------------------------------------------------
15241 if(c_stopPermMaster.returnValue != 0){
15242 jam();
15243 c_switchReplicas.tableId = ctabFileSize + 1;
15244 }//if
15245 c_switchReplicas.fragNo++;
15246
15247 signal->theData[0] = DihContinueB::SwitchReplica;
15248 signal->theData[1] = c_switchReplicas.nodeId;
15249 signal->theData[2] = c_switchReplicas.tableId;
15250 signal->theData[3] = c_switchReplicas.fragNo;
15251 sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
15252 }//Dbdih::switchReplicaReply()
15253
15254 void
switchReplica(Signal * signal,Uint32 nodeId,Uint32 tableId,Uint32 fragNo)15255 Dbdih::switchReplica(Signal* signal,
15256 Uint32 nodeId,
15257 Uint32 tableId,
15258 Uint32 fragNo){
15259 jam();
15260 DihSwitchReplicaReq* const req = (DihSwitchReplicaReq*)&signal->theData[0];
15261
15262 const Uint32 RT_BREAK = 64;
15263
15264 for (Uint32 i = 0; i < RT_BREAK; i++) {
15265 jam();
15266 if (tableId >= ctabFileSize) {
15267 jam();
15268 StopPermConf* const conf = (StopPermConf*)&signal->theData[0];
15269 StopPermRef* const ref = (StopPermRef*)&signal->theData[0];
15270 /**
15271 * Finished with all tables
15272 */
15273 if(c_stopPermMaster.returnValue == 0) {
15274 jam();
15275 conf->senderData = c_stopPermMaster.clientData;
15276 sendSignal(c_stopPermMaster.clientRef, GSN_STOP_PERM_CONF,
15277 signal, 1, JBB);
15278 } else {
15279 jam();
15280 ref->senderData = c_stopPermMaster.clientData;
15281 ref->errorCode = c_stopPermMaster.returnValue;
15282 sendSignal(c_stopPermMaster.clientRef, GSN_STOP_PERM_REF, signal, 2,JBB);
15283 }//if
15284
15285 /**
15286 * UnLock
15287 */
15288 c_nodeStartMaster.activeState = false;
15289 c_stopPermMaster.clientRef = 0;
15290 c_stopPermMaster.clientData = 0;
15291 c_stopPermMaster.returnValue = 0;
15292 Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
15293 mutex.unlock(); // ignore result
15294 return;
15295 }//if
15296
15297 TabRecordPtr tabPtr;
15298 tabPtr.i = tableId;
15299 ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
15300
15301 if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE) {
15302 jam();
15303 tableId++;
15304 fragNo = 0;
15305 continue;
15306 }//if
15307 if (fragNo >= tabPtr.p->totalfragments) {
15308 jam();
15309 tableId++;
15310 fragNo = 0;
15311 continue;
15312 }//if
15313 FragmentstorePtr fragPtr;
15314 getFragstore(tabPtr.p, fragNo, fragPtr);
15315
15316 Uint32 oldOrder[MAX_REPLICAS];
15317 const Uint32 noOfReplicas = extractNodeInfo(fragPtr.p, oldOrder);
15318
15319 if(oldOrder[0] != nodeId) {
15320 jam();
15321 fragNo++;
15322 continue;
15323 }//if
15324 req->tableId = tableId;
15325 req->fragNo = fragNo;
15326 req->noOfReplicas = noOfReplicas;
15327 for (Uint32 i = 0; i < (noOfReplicas - 1); i++) {
15328 req->newNodeOrder[i] = oldOrder[i+1];
15329 }//for
15330 req->newNodeOrder[noOfReplicas-1] = nodeId;
15331 req->senderRef = reference();
15332
15333 /**
15334 * Initialize struct
15335 */
15336 c_switchReplicas.tableId = tableId;
15337 c_switchReplicas.fragNo = fragNo;
15338 c_switchReplicas.nodeId = nodeId;
15339
15340 sendLoopMacro(DIH_SWITCH_REPLICA_REQ, sendDIH_SWITCH_REPLICA_REQ);
15341 return;
15342 }//for
15343
15344 signal->theData[0] = DihContinueB::SwitchReplica;
15345 signal->theData[1] = nodeId;
15346 signal->theData[2] = tableId;
15347 signal->theData[3] = fragNo;
15348 sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
15349 }//Dbdih::switchReplica()
15350
execSTOP_ME_REQ(Signal * signal)15351 void Dbdih::execSTOP_ME_REQ(Signal* signal)
15352 {
15353 jamEntry();
15354 StopMeReq* const req = (StopMeReq*)&signal->theData[0];
15355 const BlockReference senderRef = req->senderRef;
15356 const Uint32 senderData = req->senderData;
15357 const Uint32 nodeId = refToNode(senderRef);
15358 {
15359 /**
15360 * Set node dead (remove from operations)
15361 */
15362 NodeRecordPtr nodePtr;
15363 nodePtr.i = nodeId;
15364 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15365 nodePtr.p->useInTransactions = false;
15366 }
15367 if (nodeId != getOwnNodeId()) {
15368 jam();
15369 StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
15370 stopMeConf->senderData = senderData;
15371 stopMeConf->senderRef = reference();
15372 sendSignal(senderRef, GSN_STOP_ME_CONF, signal,
15373 StopMeConf::SignalLength, JBB);
15374 return;
15375 }//if
15376
15377 /**
15378 * Local signal
15379 */
15380 jam();
15381 ndbrequire(c_stopMe.clientRef == 0);
15382
15383 c_stopMe.clientData = senderData;
15384 c_stopMe.clientRef = senderRef;
15385
15386 req->senderData = senderData;
15387 req->senderRef = reference();
15388
15389 sendLoopMacro(STOP_ME_REQ, sendSTOP_ME_REQ);
15390
15391 /**
15392 * Send conf to self
15393 */
15394 StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
15395 stopMeConf->senderData = senderData;
15396 stopMeConf->senderRef = reference();
15397 sendSignal(reference(), GSN_STOP_ME_CONF, signal,
15398 StopMeConf::SignalLength, JBB);
15399 }//Dbdih::execSTOP_ME_REQ()
15400
execSTOP_ME_REF(Signal * signal)15401 void Dbdih::execSTOP_ME_REF(Signal* signal)
15402 {
15403 ndbrequire(false);
15404 }
15405
execSTOP_ME_CONF(Signal * signal)15406 void Dbdih::execSTOP_ME_CONF(Signal* signal)
15407 {
15408 jamEntry();
15409 StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
15410
15411 const Uint32 senderRef = stopMeConf->senderRef;
15412 const Uint32 senderData = stopMeConf->senderData;
15413 const Uint32 nodeId = refToNode(senderRef);
15414
15415 ndbrequire(c_stopMe.clientRef != 0);
15416 ndbrequire(c_stopMe.clientData == senderData);
15417
15418 receiveLoopMacro(STOP_ME_REQ, nodeId);
15419 //---------------------------------------------------------
15420 // All STOP_ME_REQ have been received. We will send the
15421 // confirmation back to the requesting block.
15422 //---------------------------------------------------------
15423
15424 stopMeConf->senderRef = reference();
15425 stopMeConf->senderData = c_stopMe.clientData;
15426 sendSignal(c_stopMe.clientRef, GSN_STOP_ME_CONF, signal,
15427 StopMeConf::SignalLength, JBB);
15428 c_stopMe.clientRef = 0;
15429 }//Dbdih::execSTOP_ME_CONF()
15430
execWAIT_GCP_REQ(Signal * signal)15431 void Dbdih::execWAIT_GCP_REQ(Signal* signal)
15432 {
15433 jamEntry();
15434 WaitGCPReq* const req = (WaitGCPReq*)&signal->theData[0];
15435 WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
15436 WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
15437 const Uint32 senderData = req->senderData;
15438 const BlockReference senderRef = req->senderRef;
15439 const Uint32 requestType = req->requestType;
15440
15441 if(requestType == WaitGCPReq::CurrentGCI) {
15442 jam();
15443 conf->senderData = senderData;
15444 conf->gcp = cnewgcp;
15445 conf->blockStatus = cgcpOrderBlocked;
15446 sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal,
15447 WaitGCPConf::SignalLength, JBB);
15448 return;
15449 }//if
15450
15451 if (requestType == WaitGCPReq::BlockStartGcp)
15452 {
15453 jam();
15454 conf->senderData = senderData;
15455 conf->gcp = cnewgcp;
15456 conf->blockStatus = cgcpOrderBlocked;
15457 sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal,
15458 WaitGCPConf::SignalLength, JBB);
15459 cgcpOrderBlocked = 1;
15460 return;
15461 }
15462
15463 if (requestType == WaitGCPReq::UnblockStartGcp)
15464 {
15465 jam();
15466 conf->senderData = senderData;
15467 conf->gcp = cnewgcp;
15468 conf->blockStatus = cgcpOrderBlocked;
15469 sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal,
15470 WaitGCPConf::SignalLength, JBB);
15471 cgcpOrderBlocked = 0;
15472 return;
15473 }
15474
15475 if(isMaster()) {
15476 /**
15477 * Master
15478 */
15479 jam();
15480
15481 if((requestType == WaitGCPReq::CompleteIfRunning) &&
15482 (cgcpStatus == GCP_READY)) {
15483 jam();
15484 conf->senderData = senderData;
15485 conf->gcp = coldgcp;
15486 conf->blockStatus = cgcpOrderBlocked;
15487 sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal,
15488 WaitGCPConf::SignalLength, JBB);
15489 return;
15490 }//if
15491
15492 WaitGCPMasterPtr ptr;
15493 if(c_waitGCPMasterList.seize(ptr) == false){
15494 jam();
15495 ref->senderData = senderData;
15496 ref->errorCode = WaitGCPRef::NoWaitGCPRecords;
15497 sendSignal(senderRef, GSN_WAIT_GCP_REF, signal,
15498 WaitGCPRef::SignalLength, JBB);
15499 return;
15500 }//if
15501 ptr.p->clientRef = senderRef;
15502 ptr.p->clientData = senderData;
15503
15504 if((requestType == WaitGCPReq::CompleteForceStart) &&
15505 (cgcpStatus == GCP_READY)) {
15506 jam();
15507 cstartGcpNow = true;
15508 }//if
15509 return;
15510 } else {
15511 /**
15512 * Proxy part
15513 */
15514 jam();
15515 WaitGCPProxyPtr ptr;
15516 if (c_waitGCPProxyList.seize(ptr) == false) {
15517 jam();
15518 ref->senderData = senderData;
15519 ref->errorCode = WaitGCPRef::NoWaitGCPRecords;
15520 sendSignal(senderRef, GSN_WAIT_GCP_REF, signal,
15521 WaitGCPRef::SignalLength, JBB);
15522 return;
15523 }//if
15524 ptr.p->clientRef = senderRef;
15525 ptr.p->clientData = senderData;
15526 ptr.p->masterRef = cmasterdihref;
15527
15528 req->senderData = ptr.i;
15529 req->senderRef = reference();
15530 req->requestType = requestType;
15531
15532 sendSignal(cmasterdihref, GSN_WAIT_GCP_REQ, signal,
15533 WaitGCPReq::SignalLength, JBB);
15534 return;
15535 }//if
15536 }//Dbdih::execWAIT_GCP_REQ()
15537
execWAIT_GCP_REF(Signal * signal)15538 void Dbdih::execWAIT_GCP_REF(Signal* signal)
15539 {
15540 jamEntry();
15541 ndbrequire(!isMaster());
15542 WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
15543
15544 const Uint32 proxyPtr = ref->senderData;
15545 const Uint32 errorCode = ref->errorCode;
15546
15547 WaitGCPProxyPtr ptr;
15548 ptr.i = proxyPtr;
15549 c_waitGCPProxyList.getPtr(ptr);
15550
15551 ref->senderData = ptr.p->clientData;
15552 ref->errorCode = errorCode;
15553 sendSignal(ptr.p->clientRef, GSN_WAIT_GCP_REF, signal,
15554 WaitGCPRef::SignalLength, JBB);
15555
15556 c_waitGCPProxyList.release(ptr);
15557 }//Dbdih::execWAIT_GCP_REF()
15558
execWAIT_GCP_CONF(Signal * signal)15559 void Dbdih::execWAIT_GCP_CONF(Signal* signal)
15560 {
15561 jamEntry();
15562 ndbrequire(!isMaster());
15563 WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
15564 const Uint32 proxyPtr = conf->senderData;
15565 const Uint32 gcp = conf->gcp;
15566 WaitGCPProxyPtr ptr;
15567
15568 ptr.i = proxyPtr;
15569 c_waitGCPProxyList.getPtr(ptr);
15570
15571 conf->senderData = ptr.p->clientData;
15572 conf->gcp = gcp;
15573 conf->blockStatus = cgcpOrderBlocked;
15574 sendSignal(ptr.p->clientRef, GSN_WAIT_GCP_CONF, signal,
15575 WaitGCPConf::SignalLength, JBB);
15576
15577 c_waitGCPProxyList.release(ptr);
15578 }//Dbdih::execWAIT_GCP_CONF()
15579
checkWaitGCPProxy(Signal * signal,NodeId failedNodeId)15580 void Dbdih::checkWaitGCPProxy(Signal* signal, NodeId failedNodeId)
15581 {
15582 jam();
15583 WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
15584 ref->errorCode = WaitGCPRef::NF_CausedAbortOfProcedure;
15585
15586 WaitGCPProxyPtr ptr;
15587 c_waitGCPProxyList.first(ptr);
15588 while(ptr.i != RNIL) {
15589 jam();
15590 const Uint32 i = ptr.i;
15591 const Uint32 clientData = ptr.p->clientData;
15592 const BlockReference clientRef = ptr.p->clientRef;
15593 const BlockReference masterRef = ptr.p->masterRef;
15594
15595 c_waitGCPProxyList.next(ptr);
15596 if(refToNode(masterRef) == failedNodeId) {
15597 jam();
15598 c_waitGCPProxyList.release(i);
15599 ref->senderData = clientData;
15600 sendSignal(clientRef, GSN_WAIT_GCP_REF, signal,
15601 WaitGCPRef::SignalLength, JBB);
15602 }//if
15603 }//while
15604 }//Dbdih::checkWaitGCPProxy()
15605
checkWaitGCPMaster(Signal * signal,NodeId failedNodeId)15606 void Dbdih::checkWaitGCPMaster(Signal* signal, NodeId failedNodeId)
15607 {
15608 jam();
15609 WaitGCPMasterPtr ptr;
15610 c_waitGCPMasterList.first(ptr);
15611
15612 while (ptr.i != RNIL) {
15613 jam();
15614 const Uint32 i = ptr.i;
15615 const NodeId nodeId = refToNode(ptr.p->clientRef);
15616
15617 c_waitGCPMasterList.next(ptr);
15618 if (nodeId == failedNodeId) {
15619 jam()
15620 c_waitGCPMasterList.release(i);
15621 }//if
15622 }//while
15623 }//Dbdih::checkWaitGCPMaster()
15624
emptyWaitGCPMasterQueue(Signal * signal)15625 void Dbdih::emptyWaitGCPMasterQueue(Signal* signal)
15626 {
15627 jam();
15628 WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
15629 conf->gcp = coldgcp;
15630
15631 WaitGCPMasterPtr ptr;
15632 c_waitGCPMasterList.first(ptr);
15633 while(ptr.i != RNIL) {
15634 jam();
15635 const Uint32 i = ptr.i;
15636 const Uint32 clientData = ptr.p->clientData;
15637 const BlockReference clientRef = ptr.p->clientRef;
15638
15639 c_waitGCPMasterList.next(ptr);
15640 conf->senderData = clientData;
15641 conf->blockStatus = cgcpOrderBlocked;
15642 sendSignal(clientRef, GSN_WAIT_GCP_CONF, signal,
15643 WaitGCPConf::SignalLength, JBB);
15644
15645 c_waitGCPMasterList.release(i);
15646 }//while
15647 }//Dbdih::emptyWaitGCPMasterQueue()
15648
setNodeStatus(Uint32 nodeId,NodeRecord::NodeStatus newStatus)15649 void Dbdih::setNodeStatus(Uint32 nodeId, NodeRecord::NodeStatus newStatus)
15650 {
15651 NodeRecordPtr nodePtr;
15652 nodePtr.i = nodeId;
15653 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15654 nodePtr.p->nodeStatus = newStatus;
15655 }//Dbdih::setNodeStatus()
15656
getNodeStatus(Uint32 nodeId)15657 Dbdih::NodeRecord::NodeStatus Dbdih::getNodeStatus(Uint32 nodeId)
15658 {
15659 NodeRecordPtr nodePtr;
15660 nodePtr.i = nodeId;
15661 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15662 return nodePtr.p->nodeStatus;
15663 }//Dbdih::getNodeStatus()
15664
15665 Sysfile::ActiveStatus
getNodeActiveStatus(Uint32 nodeId)15666 Dbdih::getNodeActiveStatus(Uint32 nodeId)
15667 {
15668 NodeRecordPtr nodePtr;
15669 nodePtr.i = nodeId;
15670 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15671 return nodePtr.p->activeStatus;
15672 }//Dbdih::getNodeActiveStatus()
15673
15674
15675 void
setNodeActiveStatus(Uint32 nodeId,Sysfile::ActiveStatus newStatus)15676 Dbdih::setNodeActiveStatus(Uint32 nodeId, Sysfile::ActiveStatus newStatus)
15677 {
15678 NodeRecordPtr nodePtr;
15679 nodePtr.i = nodeId;
15680 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15681 nodePtr.p->activeStatus = newStatus;
15682 }//Dbdih::setNodeActiveStatus()
15683
setAllowNodeStart(Uint32 nodeId,bool newState)15684 void Dbdih::setAllowNodeStart(Uint32 nodeId, bool newState)
15685 {
15686 NodeRecordPtr nodePtr;
15687 nodePtr.i = nodeId;
15688 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15689 nodePtr.p->allowNodeStart = newState;
15690 }//Dbdih::setAllowNodeStart()
15691
setNodeCopyCompleted(Uint32 nodeId,bool newState)15692 void Dbdih::setNodeCopyCompleted(Uint32 nodeId, bool newState)
15693 {
15694 NodeRecordPtr nodePtr;
15695 nodePtr.i = nodeId;
15696 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15697 nodePtr.p->copyCompleted = newState;
15698 }//Dbdih::setNodeCopyCompleted()
15699
getAllowNodeStart(Uint32 nodeId)15700 bool Dbdih::getAllowNodeStart(Uint32 nodeId)
15701 {
15702 NodeRecordPtr nodePtr;
15703 nodePtr.i = nodeId;
15704 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15705 return nodePtr.p->allowNodeStart;
15706 }//Dbdih::getAllowNodeStart()
15707
getNodeCopyCompleted(Uint32 nodeId)15708 bool Dbdih::getNodeCopyCompleted(Uint32 nodeId)
15709 {
15710 NodeRecordPtr nodePtr;
15711 nodePtr.i = nodeId;
15712 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15713 return nodePtr.p->copyCompleted;
15714 }//Dbdih::getNodeCopyCompleted()
15715
checkNodeAlive(Uint32 nodeId)15716 bool Dbdih::checkNodeAlive(Uint32 nodeId)
15717 {
15718 NodeRecordPtr nodePtr;
15719 nodePtr.i = nodeId;
15720 ndbrequire(nodeId > 0);
15721 ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
15722 if (nodePtr.p->nodeStatus != NodeRecord::ALIVE) {
15723 return false;
15724 } else {
15725 return true;
15726 }//if
15727 }//Dbdih::checkNodeAlive()
15728
isMaster()15729 bool Dbdih::isMaster()
15730 {
15731 return (reference() == cmasterdihref);
15732 }//Dbdih::isMaster()
15733
isActiveMaster()15734 bool Dbdih::isActiveMaster()
15735 {
15736 return ((reference() == cmasterdihref) && (cmasterState == MASTER_ACTIVE));
15737 }//Dbdih::isActiveMaster()
15738
NodeRecord()15739 Dbdih::NodeRecord::NodeRecord(){
15740 m_nodefailSteps.clear();
15741 gcpstate = NodeRecord::READY;
15742
15743 activeStatus = Sysfile::NS_NotDefined;
15744 recNODE_FAILREP = ZFALSE;
15745 nodeGroup = ZNIL;
15746 dbtcFailCompleted = ZTRUE;
15747 dbdictFailCompleted = ZTRUE;
15748 dbdihFailCompleted = ZTRUE;
15749 dblqhFailCompleted = ZTRUE;
15750 noOfStartedChkpt = 0;
15751 noOfQueuedChkpt = 0;
15752 lcpStateAtTakeOver = (MasterLCPConf::State)255;
15753
15754 activeTabptr = RNIL;
15755 nodeStatus = NodeRecord::NOT_IN_CLUSTER;
15756 useInTransactions = false;
15757 copyCompleted = false;
15758 allowNodeStart = true;
15759 }
15760
15761 // DICT lock slave
15762
15763 void
sendDictLockReq(Signal * signal,Uint32 lockType,Callback c)15764 Dbdih::sendDictLockReq(Signal* signal, Uint32 lockType, Callback c)
15765 {
15766 DictLockReq* req = (DictLockReq*)&signal->theData[0];
15767 DictLockSlavePtr lockPtr;
15768
15769 c_dictLockSlavePool.seize(lockPtr);
15770 ndbrequire(lockPtr.i != RNIL);
15771
15772 req->userPtr = lockPtr.i;
15773 req->lockType = lockType;
15774 req->userRef = reference();
15775
15776 lockPtr.p->lockPtr = RNIL;
15777 lockPtr.p->lockType = lockType;
15778 lockPtr.p->locked = false;
15779 lockPtr.p->callback = c;
15780
15781 // handle rolling upgrade
15782 {
15783 Uint32 masterVersion = getNodeInfo(cmasterNodeId).m_version;
15784
15785 const unsigned int get_major = getMajor(masterVersion);
15786 const unsigned int get_minor = getMinor(masterVersion);
15787 const unsigned int get_build = getBuild(masterVersion);
15788 ndbrequire(get_major >= 4);
15789
15790 if (masterVersion < NDBD_DICT_LOCK_VERSION_5 ||
15791 masterVersion < NDBD_DICT_LOCK_VERSION_5_1 &&
15792 get_major == 5 && get_minor == 1 ||
15793 ERROR_INSERTED(7176)) {
15794 jam();
15795
15796 infoEvent("DIH: detect upgrade: master node %u old version %u.%u.%u",
15797 (unsigned int)cmasterNodeId, get_major, get_minor, get_build);
15798
15799 DictLockConf* conf = (DictLockConf*)&signal->theData[0];
15800 conf->userPtr = lockPtr.i;
15801 conf->lockType = lockType;
15802 conf->lockPtr = ZNIL;
15803
15804 sendSignal(reference(), GSN_DICT_LOCK_CONF, signal,
15805 DictLockConf::SignalLength, JBB);
15806 return;
15807 }
15808 }
15809
15810 BlockReference dictMasterRef = calcDictBlockRef(cmasterNodeId);
15811 sendSignal(dictMasterRef, GSN_DICT_LOCK_REQ, signal,
15812 DictLockReq::SignalLength, JBB);
15813 }
15814
15815 void
execDICT_LOCK_CONF(Signal * signal)15816 Dbdih::execDICT_LOCK_CONF(Signal* signal)
15817 {
15818 jamEntry();
15819 recvDictLockConf(signal);
15820 }
15821
15822 void
execDICT_LOCK_REF(Signal * signal)15823 Dbdih::execDICT_LOCK_REF(Signal* signal)
15824 {
15825 jamEntry();
15826 ndbrequire(false);
15827 }
15828
15829 void
recvDictLockConf(Signal * signal)15830 Dbdih::recvDictLockConf(Signal* signal)
15831 {
15832 const DictLockConf* conf = (const DictLockConf*)&signal->theData[0];
15833
15834 DictLockSlavePtr lockPtr;
15835 c_dictLockSlavePool.getPtr(lockPtr, conf->userPtr);
15836
15837 lockPtr.p->lockPtr = conf->lockPtr;
15838 ndbrequire(lockPtr.p->lockType == conf->lockType);
15839 ndbrequire(lockPtr.p->locked == false);
15840 lockPtr.p->locked = true;
15841
15842 lockPtr.p->callback.m_callbackData = lockPtr.i;
15843 execute(signal, lockPtr.p->callback, 0);
15844 }
15845
15846 void
sendDictUnlockOrd(Signal * signal,Uint32 lockSlavePtrI)15847 Dbdih::sendDictUnlockOrd(Signal* signal, Uint32 lockSlavePtrI)
15848 {
15849 DictUnlockOrd* ord = (DictUnlockOrd*)&signal->theData[0];
15850
15851 DictLockSlavePtr lockPtr;
15852 c_dictLockSlavePool.getPtr(lockPtr, lockSlavePtrI);
15853
15854 ord->lockPtr = lockPtr.p->lockPtr;
15855 ord->lockType = lockPtr.p->lockType;
15856
15857 c_dictLockSlavePool.release(lockPtr);
15858
15859 // handle rolling upgrade
15860 {
15861 Uint32 masterVersion = getNodeInfo(cmasterNodeId).m_version;
15862
15863 const unsigned int get_major = getMajor(masterVersion);
15864 const unsigned int get_minor = getMinor(masterVersion);
15865 ndbrequire(get_major >= 4);
15866
15867 if (masterVersion < NDBD_DICT_LOCK_VERSION_5 ||
15868 masterVersion < NDBD_DICT_LOCK_VERSION_5_1 &&
15869 get_major == 5 && get_minor == 1 ||
15870 ERROR_INSERTED(7176)) {
15871 return;
15872 }
15873 }
15874
15875 BlockReference dictMasterRef = calcDictBlockRef(cmasterNodeId);
15876 sendSignal(dictMasterRef, GSN_DICT_UNLOCK_ORD, signal,
15877 DictUnlockOrd::SignalLength, JBB);
15878 }
15879