MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Backup.cpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #include <my_global.h>
19 #include "Backup.hpp"
20 
21 #include <ndb_version.h>
22 
23 #include <NdbTCP.h>
24 #include <Bitmask.hpp>
25 
26 #include <signaldata/NodeFailRep.hpp>
27 #include <signaldata/ReadNodesConf.hpp>
28 
29 #include <signaldata/DihScanTab.hpp>
30 #include <signaldata/ScanFrag.hpp>
31 
32 #include <signaldata/GetTabInfo.hpp>
33 #include <signaldata/DictTabInfo.hpp>
34 #include <signaldata/ListTables.hpp>
35 
36 #include <signaldata/FsOpenReq.hpp>
37 #include <signaldata/FsAppendReq.hpp>
38 #include <signaldata/FsCloseReq.hpp>
39 #include <signaldata/FsConf.hpp>
40 #include <signaldata/FsRef.hpp>
41 #include <signaldata/FsRemoveReq.hpp>
42 
43 #include <signaldata/BackupImpl.hpp>
44 #include <signaldata/BackupSignalData.hpp>
45 #include <signaldata/BackupContinueB.hpp>
46 #include <signaldata/EventReport.hpp>
47 
48 #include <signaldata/UtilSequence.hpp>
49 
50 #include <signaldata/CreateTrigImpl.hpp>
51 #include <signaldata/DropTrigImpl.hpp>
52 #include <signaldata/FireTrigOrd.hpp>
53 #include <signaldata/TrigAttrInfo.hpp>
54 #include <AttributeHeader.hpp>
55 
56 #include <signaldata/WaitGCP.hpp>
57 #include <signaldata/LCP.hpp>
58 #include <signaldata/BackupLockTab.hpp>
59 #include <signaldata/DumpStateOrd.hpp>
60 
61 #include <signaldata/DumpStateOrd.hpp>
62 
63 #include <signaldata/DbinfoScan.hpp>
64 #include <signaldata/TransIdAI.hpp>
65 
66 #include <NdbTick.h>
67 #include <dbtup/Dbtup.hpp>
68 
69 static NDB_TICKS startTime;
70 
71 #ifdef VM_TRACE
72 #define DEBUG_OUT(x) ndbout << x << endl
73 #else
74 #define DEBUG_OUT(x)
75 #endif
76 
77 //#define DEBUG_ABORT
78 //#define dbg globalSignalLoggers.log
79 
80 static Uint32 g_TypeOfStart = NodeState::ST_ILLEGAL_TYPE;
81 
82 #define SEND_BACKUP_STARTED_FLAG(A) (((A) & 0x3) > 0)
83 #define SEND_BACKUP_COMPLETED_FLAG(A) (((A) & 0x3) > 1)
84 
85 void
86 Backup::execSTTOR(Signal* signal)
87 {
88  jamEntry();
89 
90  const Uint32 startphase = signal->theData[1];
91  const Uint32 typeOfStart = signal->theData[7];
92 
93  if (startphase == 1)
94  {
95  m_curr_disk_write_speed = c_defaults.m_disk_write_speed_sr;
96  m_overflow_disk_write = 0;
97  m_reset_disk_speed_time = NdbTick_CurrentMillisecond();
98  m_reset_delay_used = Backup::DISK_SPEED_CHECK_DELAY;
99  signal->theData[0] = BackupContinueB::RESET_DISK_SPEED_COUNTER;
100  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal,
101  Backup::DISK_SPEED_CHECK_DELAY, 1);
102  }
103  if (startphase == 3) {
104  jam();
105  g_TypeOfStart = typeOfStart;
106  signal->theData[0] = reference();
107  sendSignal(NDBCNTR_REF, GSN_READ_NODESREQ, signal, 1, JBB);
108  return;
109  }//if
110 
111  if (startphase == 7)
112  {
113  m_curr_disk_write_speed = c_defaults.m_disk_write_speed;
114  }
115 
116  if(startphase == 7 && g_TypeOfStart == NodeState::ST_INITIAL_START &&
117  c_masterNodeId == getOwnNodeId() && !isNdbMtLqh()){
118  jam();
119  createSequence(signal);
120  return;
121  }//if
122 
123  sendSTTORRY(signal);
124  return;
125 }//Dbdict::execSTTOR()
126 
127 void
128 Backup::execREAD_NODESCONF(Signal* signal)
129 {
130  jamEntry();
131  ReadNodesConf * conf = (ReadNodesConf *)signal->getDataPtr();
132 
133  c_aliveNodes.clear();
134 
135  Uint32 count = 0;
136  for (Uint32 i = 0; i<MAX_NDB_NODES; i++) {
137  jam();
138  if(NdbNodeBitmask::get(conf->allNodes, i)){
139  jam();
140  count++;
141 
142  NodePtr node;
143  ndbrequire(c_nodes.seize(node));
144 
145  node.p->nodeId = i;
146  if(NdbNodeBitmask::get(conf->inactiveNodes, i)) {
147  jam();
148  node.p->alive = 0;
149  } else {
150  jam();
151  node.p->alive = 1;
152  c_aliveNodes.set(i);
153  }//if
154  }//if
155  }//for
156  c_masterNodeId = conf->masterNodeId;
157  ndbrequire(count == conf->noOfNodes);
158  sendSTTORRY(signal);
159 }
160 
161 void
162 Backup::sendSTTORRY(Signal* signal)
163 {
164  signal->theData[0] = 0;
165  signal->theData[3] = 1;
166  signal->theData[4] = 3;
167  signal->theData[5] = 7;
168  signal->theData[6] = 255; // No more start phases from missra
169  BlockReference cntrRef = !isNdbMtLqh() ? NDBCNTR_REF : BACKUP_REF;
170  sendSignal(cntrRef, GSN_STTORRY, signal, 7, JBB);
171 }
172 
173 void
174 Backup::createSequence(Signal* signal)
175 {
176  UtilSequenceReq * req = (UtilSequenceReq*)signal->getDataPtrSend();
177 
178  req->senderData = RNIL;
179  req->sequenceId = NDB_BACKUP_SEQUENCE;
180  req->requestType = UtilSequenceReq::Create;
181 
182  sendSignal(DBUTIL_REF, GSN_UTIL_SEQUENCE_REQ,
183  signal, UtilSequenceReq::SignalLength, JBB);
184 }
185 
186 void
187 Backup::execCONTINUEB(Signal* signal)
188 {
189  jamEntry();
190  const Uint32 Tdata0 = signal->theData[0];
191  const Uint32 Tdata1 = signal->theData[1];
192  const Uint32 Tdata2 = signal->theData[2];
193 
194  switch(Tdata0) {
195  case BackupContinueB::RESET_DISK_SPEED_COUNTER:
196  {
197  /*
198  Adjust for upto 10 millisecond delay of this signal. Longer
199  delays will not be handled, in this case the system is most
200  likely under too high load and it won't matter very much that
201  we decrease the speed of checkpoints.
202 
203  We use a technique where we allow an overflow write in one
204  period. This overflow will be removed from the next period
205  such that the load will at average be as specified.
206  */
207  int delay_time = m_reset_delay_used;
208  NDB_TICKS curr_time = NdbTick_CurrentMillisecond();
209  int sig_delay = int(curr_time - m_reset_disk_speed_time);
210 
211  m_words_written_this_period = m_overflow_disk_write;
212  m_overflow_disk_write = 0;
213  m_reset_disk_speed_time = curr_time;
214 
215  if (sig_delay > delay_time + 10)
216  delay_time = Backup::DISK_SPEED_CHECK_DELAY - 10;
217  else if (sig_delay < delay_time - 10)
218  delay_time = Backup::DISK_SPEED_CHECK_DELAY + 10;
219  else
220  delay_time = Backup::DISK_SPEED_CHECK_DELAY - (sig_delay - delay_time);
221  m_reset_delay_used= delay_time;
222  signal->theData[0] = BackupContinueB::RESET_DISK_SPEED_COUNTER;
223  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, delay_time, 1);
224 #if 0
225  ndbout << "Signal delay was = " << sig_delay;
226  ndbout << " Current time = " << curr_time << endl;
227  ndbout << " Delay time will be = " << delay_time << endl << endl;
228 #endif
229  break;
230  }
231  case BackupContinueB::BACKUP_FRAGMENT_INFO:
232  {
233  jam();
234  const Uint32 ptr_I = Tdata1;
235  Uint32 tabPtr_I = Tdata2;
236  Uint32 fragPtr_I = signal->theData[3];
237 
238  BackupRecordPtr ptr LINT_SET_PTR;
239  c_backupPool.getPtr(ptr, ptr_I);
240  TablePtr tabPtr;
241  ptr.p->tables.getPtr(tabPtr, tabPtr_I);
242 
243  if (fragPtr_I != tabPtr.p->fragments.getSize())
244  {
245  jam();
246  FragmentPtr fragPtr;
247  tabPtr.p->fragments.getPtr(fragPtr, fragPtr_I);
248 
249  BackupFilePtr filePtr LINT_SET_PTR;
250  ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
251 
252  const Uint32 sz = sizeof(BackupFormat::CtlFile::FragmentInfo) >> 2;
253  Uint32 * dst;
254  if (!filePtr.p->operation.dataBuffer.getWritePtr(&dst, sz))
255  {
256  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 4);
257  return;
258  }
259 
262  fragInfo->SectionType = htonl(BackupFormat::FRAGMENT_INFO);
263  fragInfo->SectionLength = htonl(sz);
264  fragInfo->TableId = htonl(fragPtr.p->tableId);
265  fragInfo->FragmentNo = htonl(fragPtr_I);
266  fragInfo->NoOfRecordsLow = htonl((Uint32)(fragPtr.p->noOfRecords & 0xFFFFFFFF));
267  fragInfo->NoOfRecordsHigh = htonl((Uint32)(fragPtr.p->noOfRecords >> 32));
268  fragInfo->FilePosLow = htonl(0);
269  fragInfo->FilePosHigh = htonl(0);
270 
271  filePtr.p->operation.dataBuffer.updateWritePtr(sz);
272 
273  fragPtr_I++;
274  }
275 
276  if (fragPtr_I == tabPtr.p->fragments.getSize())
277  {
278  BackupLockTab *req = (BackupLockTab *)signal->getDataPtrSend();
279  req->m_senderRef = reference();
280  req->m_tableId = tabPtr.p->tableId;
281  req->m_lock_unlock = BackupLockTab::UNLOCK_TABLE;
282  req->m_backup_state = BackupLockTab::BACKUP_FRAGMENT_INFO;
283  req->m_backupRecordPtr_I = ptr_I;
284  req->m_tablePtr_I = tabPtr_I;
285  sendSignal(DBDICT_REF, GSN_BACKUP_LOCK_TAB_REQ, signal,
286  BackupLockTab::SignalLength, JBB);
287  return;
288  }
289 
290  signal->theData[0] = BackupContinueB::BACKUP_FRAGMENT_INFO;
291  signal->theData[1] = ptr_I;
292  signal->theData[2] = tabPtr_I;
293  signal->theData[3] = fragPtr_I;
294  sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
295  return;
296  }
297  case BackupContinueB::START_FILE_THREAD:
298  case BackupContinueB::BUFFER_UNDERFLOW:
299  {
300  jam();
301  BackupFilePtr filePtr LINT_SET_PTR;
302  c_backupFilePool.getPtr(filePtr, Tdata1);
303  checkFile(signal, filePtr);
304  return;
305  }
306  break;
307  case BackupContinueB::BUFFER_FULL_SCAN:
308  {
309  jam();
310  BackupFilePtr filePtr LINT_SET_PTR;
311  c_backupFilePool.getPtr(filePtr, Tdata1);
312  checkScan(signal, filePtr);
313  return;
314  }
315  break;
316  case BackupContinueB::BUFFER_FULL_FRAG_COMPLETE:
317  {
318  jam();
319  BackupFilePtr filePtr LINT_SET_PTR;
320  c_backupFilePool.getPtr(filePtr, Tdata1);
321  fragmentCompleted(signal, filePtr);
322  return;
323  }
324  break;
325  case BackupContinueB::BUFFER_FULL_META:
326  {
327  jam();
328  BackupRecordPtr ptr LINT_SET_PTR;
329  c_backupPool.getPtr(ptr, Tdata1);
330 
331  BackupFilePtr filePtr LINT_SET_PTR;
332  ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
333  FsBuffer & buf = filePtr.p->operation.dataBuffer;
334 
335  if(buf.getFreeSize() < buf.getMaxWrite()) {
336  jam();
337  TablePtr tabPtr LINT_SET_PTR;
338  c_tablePool.getPtr(tabPtr, Tdata2);
339 
340  DEBUG_OUT("Backup - Buffer full - "
341  << buf.getFreeSize()
342  << " < " << buf.getMaxWrite()
343  << " (sz: " << buf.getUsableSize()
344  << " getMinRead: " << buf.getMinRead()
345  << ") - tableId = " << tabPtr.p->tableId);
346 
347  signal->theData[0] = BackupContinueB::BUFFER_FULL_META;
348  signal->theData[1] = Tdata1;
349  signal->theData[2] = Tdata2;
350  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 3);
351  return;
352  }//if
353 
354  TablePtr tabPtr LINT_SET_PTR;
355  c_tablePool.getPtr(tabPtr, Tdata2);
356  GetTabInfoReq * req = (GetTabInfoReq *)signal->getDataPtrSend();
357  req->senderRef = reference();
358  req->senderData = ptr.i;
359  req->requestType = GetTabInfoReq::RequestById |
360  GetTabInfoReq::LongSignalConf;
361  req->tableId = tabPtr.p->tableId;
362  req->schemaTransId = 0;
363  sendSignal(DBDICT_REF, GSN_GET_TABINFOREQ, signal,
364  GetTabInfoReq::SignalLength, JBB);
365  return;
366  }
367  case BackupContinueB::ZDELAY_SCAN_NEXT:
368  if (ERROR_INSERTED(10039))
369  {
370  jam();
371  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 300,
372  signal->getLength());
373  return;
374  }
375  else
376  {
377  jam();
378  CLEAR_ERROR_INSERT_VALUE;
379  ndbout_c("Resuming backup");
380 
381  Uint32 filePtr_I = Tdata1;
382  BackupFilePtr filePtr;
383  c_backupFilePool.getPtr(filePtr, filePtr_I);
384  BackupRecordPtr ptr;
385  c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
386  TablePtr tabPtr;
387  findTable(ptr, tabPtr, filePtr.p->tableId);
388  FragmentPtr fragPtr;
389  tabPtr.p->fragments.getPtr(fragPtr, filePtr.p->fragmentNo);
390 
391  BlockReference lqhRef = 0;
392  if (ptr.p->is_lcp()) {
393  lqhRef = calcInstanceBlockRef(DBLQH);
394  } else {
395  const Uint32 instanceKey = fragPtr.p->lqhInstanceKey;
396  ndbrequire(instanceKey != 0);
397  lqhRef = numberToRef(DBLQH, instanceKey, getOwnNodeId());
398  }
399 
400  memmove(signal->theData, signal->theData + 2,
401  4*ScanFragNextReq::SignalLength);
402 
403  sendSignal(lqhRef, GSN_SCAN_NEXTREQ, signal,
404  ScanFragNextReq::SignalLength, JBB);
405  return ;
406  }
407  default:
408  ndbrequire(0);
409  }//switch
410 }
411 
412 void
413 Backup::execBACKUP_LOCK_TAB_CONF(Signal *signal)
414 {
415  jamEntry();
416  const BackupLockTab *conf = (const BackupLockTab *)signal->getDataPtrSend();
417  BackupRecordPtr ptr LINT_SET_PTR;
418  c_backupPool.getPtr(ptr, conf->m_backupRecordPtr_I);
419  TablePtr tabPtr;
420  ptr.p->tables.getPtr(tabPtr, conf->m_tablePtr_I);
421 
422  switch(conf->m_backup_state) {
423  case BackupLockTab::BACKUP_FRAGMENT_INFO:
424  {
425  jam();
426  ptr.p->tables.next(tabPtr);
427  if (tabPtr.i == RNIL)
428  {
429  jam();
430  closeFiles(signal, ptr);
431  return;
432  }
433 
434  signal->theData[0] = BackupContinueB::BACKUP_FRAGMENT_INFO;
435  signal->theData[1] = ptr.i;
436  signal->theData[2] = tabPtr.i;
437  signal->theData[3] = 0; // Start from first fragment of next table
438  sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
439  return;
440  }
441  case BackupLockTab::GET_TABINFO_CONF:
442  {
443  jam();
444  if (conf->errorCode)
445  {
446  jam();
447  defineBackupRef(signal, ptr, conf->errorCode);
448  return;
449  }
450 
451  ptr.p->tables.next(tabPtr);
452  afterGetTabinfoLockTab(signal, ptr, tabPtr);
453  return;
454  }
455  case BackupLockTab::CLEANUP:
456  {
457  jam();
458  ptr.p->tables.next(tabPtr);
459  cleanupNextTable(signal, ptr, tabPtr);
460  return;
461  }
462  default:
463  ndbrequire(false);
464  }
465 }
466 
467 void
468 Backup::execBACKUP_LOCK_TAB_REF(Signal *signal)
469 {
470  jamEntry();
471  ndbrequire(false /* Not currently possible. */);
472 }
473 
474 void
476 {
477  jamEntry();
478 
479  /* Dump commands used in public interfaces */
480  switch (signal->theData[0]) {
481  case DumpStateOrd::BackupStatus:
482  {
483  BlockReference result_ref = CMVMI_REF;
484  if (signal->length() == 2)
485  result_ref = signal->theData[1];
486 
487  BackupRecordPtr ptr;
488  int reported = 0;
489  for(c_backups.first(ptr); ptr.i != RNIL; c_backups.next(ptr))
490  {
491  if (!ptr.p->is_lcp())
492  {
493  reportStatus(signal, ptr, result_ref);
494  reported++;
495  }
496  }
497  if (!reported)
498  reportStatus(signal, ptr, result_ref);
499  return;
500  }
501  default:
502  /* continue to debug section */
503  break;
504  }
505 
506  /* Debugging or unclassified section */
507 
508  if(signal->theData[0] == 20){
509  if(signal->length() > 1){
510  c_defaults.m_dataBufferSize = (signal->theData[1] * 1024 * 1024);
511  }
512  if(signal->length() > 2){
513  c_defaults.m_logBufferSize = (signal->theData[2] * 1024 * 1024);
514  }
515  if(signal->length() > 3){
516  c_defaults.m_minWriteSize = signal->theData[3] * 1024;
517  }
518  if(signal->length() > 4){
519  c_defaults.m_maxWriteSize = signal->theData[4] * 1024;
520  }
521 
522  infoEvent("Backup: data: %d log: %d min: %d max: %d",
523  c_defaults.m_dataBufferSize,
524  c_defaults.m_logBufferSize,
525  c_defaults.m_minWriteSize,
526  c_defaults.m_maxWriteSize);
527  return;
528  }
529  if(signal->theData[0] == 21){
530  BackupReq * req = (BackupReq*)signal->getDataPtrSend();
531  req->senderData = 23;
532  req->backupDataLen = 0;
533  sendSignal(reference(), GSN_BACKUP_REQ,signal,BackupReq::SignalLength, JBB);
534  startTime = NdbTick_CurrentMillisecond();
535  return;
536  }
537 
538  if(signal->theData[0] == 22){
539  const Uint32 seq = signal->theData[1];
540  FsRemoveReq * req = (FsRemoveReq *)signal->getDataPtrSend();
541  req->userReference = reference();
542  req->userPointer = 23;
543  req->directory = 1;
544  req->ownDirectory = 1;
545  FsOpenReq::setVersion(req->fileNumber, 2);
546  FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_CTL);
547  FsOpenReq::v2_setSequence(req->fileNumber, seq);
548  FsOpenReq::v2_setNodeId(req->fileNumber, getOwnNodeId());
549  sendSignal(NDBFS_REF, GSN_FSREMOVEREQ, signal,
550  FsRemoveReq::SignalLength, JBA);
551  return;
552  }
553 
554  if(signal->theData[0] == 23){
558  BackupRecordPtr ptr LINT_SET_PTR;
559  for(c_backups.first(ptr); ptr.i != RNIL; c_backups.next(ptr)){
560  infoEvent("BackupRecord %d: BackupId: %u MasterRef: %x ClientRef: %x",
561  ptr.i, ptr.p->backupId, ptr.p->masterRef, ptr.p->clientRef);
562  infoEvent(" State: %d", ptr.p->slaveState.getState());
563  BackupFilePtr filePtr;
564  for(ptr.p->files.first(filePtr); filePtr.i != RNIL;
565  ptr.p->files.next(filePtr)){
566  jam();
567  infoEvent(" file %d: type: %d flags: H'%x",
568  filePtr.i, filePtr.p->fileType,
569  filePtr.p->m_flags);
570  }
571  }
572 
573  ndbout_c("m_curr_disk_write_speed: %u m_words_written_this_period: %u m_overflow_disk_write: %u",
574  m_curr_disk_write_speed, m_words_written_this_period, m_overflow_disk_write);
575  ndbout_c("m_reset_delay_used: %u m_reset_disk_speed_time: %llu",
576  m_reset_delay_used, (Uint64)m_reset_disk_speed_time);
577  for(c_backups.first(ptr); ptr.i != RNIL; c_backups.next(ptr))
578  {
579  ndbout_c("BackupRecord %u: BackupId: %u MasterRef: %x ClientRef: %x",
580  ptr.i, ptr.p->backupId, ptr.p->masterRef, ptr.p->clientRef);
581  ndbout_c(" State: %u", ptr.p->slaveState.getState());
582  ndbout_c(" noOfByte: %llu noOfRecords: %llu",
583  ptr.p->noOfBytes, ptr.p->noOfRecords);
584  ndbout_c(" noOfLogBytes: %llu noOfLogRecords: %llu",
585  ptr.p->noOfLogBytes, ptr.p->noOfLogRecords);
586  ndbout_c(" errorCode: %u", ptr.p->errorCode);
587  BackupFilePtr filePtr;
588  for(ptr.p->files.first(filePtr); filePtr.i != RNIL;
589  ptr.p->files.next(filePtr))
590  {
591  ndbout_c(" file %u: type: %u flags: H'%x tableId: %u fragmentId: %u",
592  filePtr.i, filePtr.p->fileType, filePtr.p->m_flags,
593  filePtr.p->tableId, filePtr.p->fragmentNo);
594  }
595  if (ptr.p->slaveState.getState() == SCANNING && ptr.p->dataFilePtr != RNIL)
596  {
597  c_backupFilePool.getPtr(filePtr, ptr.p->dataFilePtr);
598  OperationRecord & op = filePtr.p->operation;
599  Uint32 *tmp = NULL;
600  Uint32 sz = 0;
601  bool eof = FALSE;
602  bool ready = op.dataBuffer.getReadPtr(&tmp, &sz, &eof);
603  ndbout_c("ready: %s eof: %s", ready ? "TRUE" : "FALSE", eof ? "TRUE" : "FALSE");
604  }
605  }
606  return;
607  }
608  if(signal->theData[0] == 24){
612  infoEvent("Backup - dump pool sizes");
613  infoEvent("BackupPool: %d BackupFilePool: %d TablePool: %d",
614  c_backupPool.getSize(), c_backupFilePool.getSize(),
615  c_tablePool.getSize());
616  infoEvent("AttrPool: %d TriggerPool: %d FragmentPool: %d",
617  c_backupPool.getSize(), c_backupFilePool.getSize(),
618  c_tablePool.getSize());
619  infoEvent("PagePool: %d",
620  c_pagePool.getSize());
621 
622 
623  if(signal->getLength() == 2 && signal->theData[1] == 2424)
624  {
628  BackupRecordPtr lcp;
629  ndbrequire(c_backups.first(lcp));
630 
631  ndbrequire(c_backupPool.getSize() == c_backupPool.getNoOfFree() + 1);
632  if(lcp.p->tables.isEmpty())
633  {
634  ndbrequire(c_tablePool.getSize() == c_tablePool.getNoOfFree());
635  ndbrequire(c_fragmentPool.getSize() == c_fragmentPool.getNoOfFree());
636  ndbrequire(c_triggerPool.getSize() == c_triggerPool.getNoOfFree());
637  }
638  ndbrequire(c_backupFilePool.getSize() == c_backupFilePool.getNoOfFree() + 1);
639  BackupFilePtr lcp_file;
640  c_backupFilePool.getPtr(lcp_file, lcp.p->dataFilePtr);
641  ndbrequire(c_pagePool.getSize() ==
642  c_pagePool.getNoOfFree() +
643  lcp_file.p->pages.getSize());
644  }
645  }
646 
647  if(signal->theData[0] == DumpStateOrd::DumpBackup)
648  {
649  /* Display a bunch of stuff about Backup defaults */
650  infoEvent("Compressed Backup: %d", c_defaults.m_compressed_backup);
651  infoEvent("Compressed LCP: %d", c_defaults.m_compressed_lcp);
652  }
653 
654  if(signal->theData[0] == DumpStateOrd::DumpBackupSetCompressed)
655  {
656  c_defaults.m_compressed_backup= signal->theData[1];
657  infoEvent("Compressed Backup: %d", c_defaults.m_compressed_backup);
658  }
659 
660  if(signal->theData[0] == DumpStateOrd::DumpBackupSetCompressedLCP)
661  {
662  c_defaults.m_compressed_lcp= signal->theData[1];
663  infoEvent("Compressed LCP: %d", c_defaults.m_compressed_lcp);
664  }
665 
666  if (signal->theData[0] == DumpStateOrd::BackupErrorInsert)
667  {
668  if (signal->getLength() == 1)
669  ndbout_c("BACKUP: setting error %u", signal->theData[1]);
670  else
671  ndbout_c("BACKUP: setting error %u, %u",
672  signal->theData[1], signal->theData[2]);
673  SET_ERROR_INSERT_VALUE2(signal->theData[1], signal->theData[2]);
674  }
675 }
676 
677 void Backup::execDBINFO_SCANREQ(Signal *signal)
678 {
679  jamEntry();
680  DbinfoScanReq req= *(DbinfoScanReq*)signal->theData;
681  const Ndbinfo::ScanCursor* cursor =
682  CAST_CONSTPTR(Ndbinfo::ScanCursor, DbinfoScan::getCursorPtr(&req));
683 
685 
686  switch(req.tableId){
687  case Ndbinfo::POOLS_TABLEID:
688  {
689  Ndbinfo::pool_entry pools[] =
690  {
691  { "Backup Record",
692  c_backupPool.getUsed(),
693  c_backupPool.getSize(),
694  c_backupPool.getEntrySize(),
695  c_backupPool.getUsedHi(),
696  { CFG_DB_PARALLEL_BACKUPS,0,0,0 }},
697  { "Backup File",
698  c_backupFilePool.getUsed(),
699  c_backupFilePool.getSize(),
700  c_backupFilePool.getEntrySize(),
701  c_backupFilePool.getUsedHi(),
702  { CFG_DB_PARALLEL_BACKUPS,0,0,0 }},
703  { "Table",
704  c_tablePool.getUsed(),
705  c_tablePool.getSize(),
706  c_tablePool.getEntrySize(),
707  c_tablePool.getUsedHi(),
708  { CFG_DB_PARALLEL_BACKUPS,
709  CFG_DB_NO_TABLES,
710  CFG_DB_NO_ORDERED_INDEXES,
711  CFG_DB_NO_UNIQUE_HASH_INDEXES }},
712  { "Trigger",
713  c_triggerPool.getUsed(),
714  c_triggerPool.getSize(),
715  c_triggerPool.getEntrySize(),
716  c_triggerPool.getUsedHi(),
717  { CFG_DB_PARALLEL_BACKUPS,
718  CFG_DB_NO_TABLES,
719  CFG_DB_NO_ORDERED_INDEXES,
720  CFG_DB_NO_UNIQUE_HASH_INDEXES }},
721  { "Fragment",
722  c_fragmentPool.getUsed(),
723  c_fragmentPool.getSize(),
724  c_fragmentPool.getEntrySize(),
725  c_fragmentPool.getUsedHi(),
726  { CFG_DB_NO_TABLES,
727  CFG_DB_NO_ORDERED_INDEXES,
728  CFG_DB_NO_UNIQUE_HASH_INDEXES,0 }},
729  { "Page",
730  c_pagePool.getUsed(),
731  c_pagePool.getSize(),
732  c_pagePool.getEntrySize(),
733  c_pagePool.getUsedHi(),
734  { CFG_DB_BACKUP_MEM,
735  CFG_DB_BACKUP_DATA_BUFFER_MEM,0,0 }},
736  { NULL, 0,0,0,0, { 0,0,0,0 }}
737  };
738 
739  const size_t num_config_params =
740  sizeof(pools[0].config_params) / sizeof(pools[0].config_params[0]);
741  Uint32 pool = cursor->data[0];
742  BlockNumber bn = blockToMain(number());
743  while(pools[pool].poolname)
744  {
745  jam();
746  Ndbinfo::Row row(signal, req);
747  row.write_uint32(getOwnNodeId());
748  row.write_uint32(bn); // block number
749  row.write_uint32(instance()); // block instance
750  row.write_string(pools[pool].poolname);
751 
752  row.write_uint64(pools[pool].used);
753  row.write_uint64(pools[pool].total);
754  row.write_uint64(pools[pool].used_hi);
755  row.write_uint64(pools[pool].entry_size);
756  for (size_t i = 0; i < num_config_params; i++)
757  row.write_uint32(pools[pool].config_params[i]);
758  ndbinfo_send_row(signal, req, row, rl);
759  pool++;
760  if (rl.need_break(req))
761  {
762  jam();
763  ndbinfo_send_scan_break(signal, req, rl, pool);
764  return;
765  }
766  }
767  break;
768  }
769  default:
770  break;
771  }
772 
773  ndbinfo_send_scan_conf(signal, req, rl);
774 }
775 
776 bool
777 Backup::findTable(const BackupRecordPtr & ptr,
778  TablePtr & tabPtr, Uint32 tableId) const
779 {
780  for(ptr.p->tables.first(tabPtr);
781  tabPtr.i != RNIL;
782  ptr.p->tables.next(tabPtr)) {
783  jam();
784  if(tabPtr.p->tableId == tableId){
785  jam();
786  return true;
787  }//if
788  }//for
789  tabPtr.i = RNIL;
790  tabPtr.p = 0;
791  return false;
792 }
793 
794 static Uint32 xps(Uint64 x, Uint64 ms)
795 {
796  float fx = float(x);
797  float fs = float(ms);
798 
799  if(ms == 0 || x == 0) {
800  jamNoBlock();
801  return 0;
802  }//if
803  jamNoBlock();
804  return ((Uint32)(1000.0f * (fx + fs/2.1f))) / ((Uint32)fs);
805 }
806 
807 struct Number {
808  Number(Uint64 r) { val = r;}
809  Number & operator=(Uint64 r) { val = r; return * this; }
810  Uint64 val;
811 };
812 
813 NdbOut &
814 operator<< (NdbOut & out, const Number & val){
815  char p = 0;
816  Uint32 loop = 1;
817  while(val.val > loop){
818  loop *= 1000;
819  p += 3;
820  }
821  if(loop != 1){
822  p -= 3;
823  loop /= 1000;
824  }
825 
826  switch(p){
827  case 0:
828  break;
829  case 3:
830  p = 'k';
831  break;
832  case 6:
833  p = 'M';
834  break;
835  case 9:
836  p = 'G';
837  break;
838  default:
839  p = 0;
840  }
841  char str[2];
842  str[0] = p;
843  str[1] = 0;
844  Uint32 tmp = (Uint32)((val.val + (loop >> 1)) / loop);
845 #if 1
846  if(p > 0)
847  out << tmp << str;
848  else
849  out << tmp;
850 #else
851  out << val.val;
852 #endif
853 
854  return out;
855 }
856 
857 void
858 Backup::execBACKUP_CONF(Signal* signal)
859 {
860  jamEntry();
861  BackupConf * conf = (BackupConf*)signal->getDataPtr();
862 
863  ndbout_c("Backup %u has started", conf->backupId);
864 }
865 
866 void
868 {
869  jamEntry();
870  BackupRef * ref = (BackupRef*)signal->getDataPtr();
871 
872  ndbout_c("Backup (%u) has NOT started %d", ref->senderData, ref->errorCode);
873 }
874 
875 void
876 Backup::execBACKUP_COMPLETE_REP(Signal* signal)
877 {
878  jamEntry();
879  BackupCompleteRep* rep = (BackupCompleteRep*)signal->getDataPtr();
880 
881  startTime = NdbTick_CurrentMillisecond() - startTime;
882 
883  ndbout_c("Backup %u has completed", rep->backupId);
884  const Uint64 bytes =
885  rep->noOfBytesLow + (((Uint64)rep->noOfBytesHigh) << 32);
886  const Uint64 records =
887  rep->noOfRecordsLow + (((Uint64)rep->noOfRecordsHigh) << 32);
888 
889  Number rps = xps(records, startTime);
890  Number bps = xps(bytes, startTime);
891 
892  ndbout << " Data [ "
893  << Number(records) << " rows "
894  << Number(bytes) << " bytes " << startTime << " ms ] "
895  << " => "
896  << rps << " row/s & " << bps << "b/s" << endl;
897 
898  bps = xps(rep->noOfLogBytes, startTime);
899  rps = xps(rep->noOfLogRecords, startTime);
900 
901  ndbout << " Log [ "
902  << Number(rep->noOfLogRecords) << " log records "
903  << Number(rep->noOfLogBytes) << " bytes " << startTime << " ms ] "
904  << " => "
905  << rps << " records/s & " << bps << "b/s" << endl;
906 
907 }
908 
909 void
910 Backup::execBACKUP_ABORT_REP(Signal* signal)
911 {
912  jamEntry();
913  BackupAbortRep* rep = (BackupAbortRep*)signal->getDataPtr();
914 
915  ndbout_c("Backup %u has been aborted %d", rep->backupId, rep->reason);
916 }
917 
918 const TriggerEvent::Value triggerEventValues[] = {
919  TriggerEvent::TE_INSERT,
920  TriggerEvent::TE_UPDATE,
921  TriggerEvent::TE_DELETE
922 };
923 
924 const Backup::State
925 Backup::validSlaveTransitions[] = {
926  INITIAL, DEFINING,
927  DEFINING, DEFINED,
928  DEFINED, STARTED,
929  STARTED, STARTED, // Several START_BACKUP_REQ is sent
930  STARTED, SCANNING,
931  SCANNING, STARTED,
932  STARTED, STOPPING,
933  STOPPING, CLEANING,
934  CLEANING, INITIAL,
935 
936  INITIAL, ABORTING, // Node fail
937  DEFINING, ABORTING,
938  DEFINED, ABORTING,
939  STARTED, ABORTING,
940  SCANNING, ABORTING,
941  STOPPING, ABORTING,
942  CLEANING, ABORTING, // Node fail w/ master takeover
943  ABORTING, ABORTING, // Slave who initiates ABORT should have this transition
944 
945  ABORTING, INITIAL,
946  INITIAL, INITIAL
947 };
948 
949 const Uint32
950 Backup::validSlaveTransitionsCount =
951 sizeof(Backup::validSlaveTransitions) / sizeof(Backup::State);
952 
953 void
954 Backup::CompoundState::setState(State newState){
955  bool found = false;
956  const State currState = state;
957  for(unsigned i = 0; i<noOfValidTransitions; i+= 2) {
958  jam();
959  if(validTransitions[i] == currState &&
960  validTransitions[i+1] == newState){
961  jam();
962  found = true;
963  break;
964  }
965  }
966 
967  //ndbrequire(found);
968 
969  if (newState == INITIAL)
970  abortState = INITIAL;
971  if(newState == ABORTING && currState != ABORTING) {
972  jam();
973  abortState = currState;
974  }
975  state = newState;
976 #ifdef DEBUG_ABORT
977  if (newState != currState) {
978  ndbout_c("%u: Old state = %u, new state = %u, abort state = %u",
979  id, currState, newState, abortState);
980  }
981 #endif
982 }
983 
984 void
985 Backup::CompoundState::forceState(State newState)
986 {
987  const State currState = state;
988  if (newState == INITIAL)
989  abortState = INITIAL;
990  if(newState == ABORTING && currState != ABORTING) {
991  jam();
992  abortState = currState;
993  }
994  state = newState;
995 #ifdef DEBUG_ABORT
996  if (newState != currState) {
997  ndbout_c("%u: FORCE: Old state = %u, new state = %u, abort state = %u",
998  id, currState, newState, abortState);
999  }
1000 #endif
1001 }
1002 
1003 Backup::Table::Table(ArrayPool<Fragment> & fh)
1004  : fragments(fh)
1005 {
1006  triggerIds[0] = ILLEGAL_TRIGGER_ID;
1007  triggerIds[1] = ILLEGAL_TRIGGER_ID;
1008  triggerIds[2] = ILLEGAL_TRIGGER_ID;
1009  triggerAllocated[0] = false;
1010  triggerAllocated[1] = false;
1011  triggerAllocated[2] = false;
1012 }
1013 
1014 /*****************************************************************************
1015  *
1016  * Node state handling
1017  *
1018  *****************************************************************************/
1019 void
1020 Backup::execNODE_FAILREP(Signal* signal)
1021 {
1022  jamEntry();
1023 
1024  NodeFailRep * rep = (NodeFailRep*)signal->getDataPtr();
1025 
1026  bool doStuff = false;
1027  /*
1028  Start by saving important signal data which will be destroyed before the
1029  process is completed.
1030  */
1031  NodeId new_master_node_id = rep->masterNodeId;
1032  Uint32 theFailedNodes[NdbNodeBitmask::Size];
1033  for (Uint32 i = 0; i < NdbNodeBitmask::Size; i++)
1034  theFailedNodes[i] = rep->theNodes[i];
1035 
1036  c_masterNodeId = new_master_node_id;
1037 
1038  NodePtr nodePtr;
1039  for(c_nodes.first(nodePtr); nodePtr.i != RNIL; c_nodes.next(nodePtr)) {
1040  jam();
1041  if(NdbNodeBitmask::get(theFailedNodes, nodePtr.p->nodeId)){
1042  if(nodePtr.p->alive){
1043  jam();
1044  ndbrequire(c_aliveNodes.get(nodePtr.p->nodeId));
1045  doStuff = true;
1046  } else {
1047  jam();
1048  ndbrequire(!c_aliveNodes.get(nodePtr.p->nodeId));
1049  }//if
1050  nodePtr.p->alive = 0;
1051  c_aliveNodes.clear(nodePtr.p->nodeId);
1052  }//if
1053  }//for
1054 
1055  if(!doStuff){
1056  jam();
1057  return;
1058  }//if
1059 
1060 #ifdef DEBUG_ABORT
1061  ndbout_c("****************** Node fail rep ******************");
1062 #endif
1063 
1064  NodeId newCoordinator = c_masterNodeId;
1065  BackupRecordPtr ptr;
1066  for(c_backups.first(ptr); ptr.i != RNIL; c_backups.next(ptr)) {
1067  jam();
1068  checkNodeFail(signal, ptr, newCoordinator, theFailedNodes);
1069  }
1070 
1071  /* Block level cleanup */
1072  for(unsigned i = 1; i < MAX_NDB_NODES; i++) {
1073  jam();
1074  if(NdbNodeBitmask::get(theFailedNodes, i))
1075  {
1076  jam();
1077  Uint32 elementsCleaned = simBlockNodeFailure(signal, i); // No callback
1078  ndbassert(elementsCleaned == 0); // Backup should have no distributed frag signals
1079  (void) elementsCleaned; // Remove compiler warning
1080  }//if
1081  }//for
1082 }
1083 
1084 bool
1085 Backup::verifyNodesAlive(BackupRecordPtr ptr,
1086  const NdbNodeBitmask& aNodeBitMask)
1087 {
1088  Uint32 version = getNodeInfo(getOwnNodeId()).m_version;
1089  for (Uint32 i = 0; i < MAX_NDB_NODES; i++) {
1090  jam();
1091  if(aNodeBitMask.get(i)) {
1092  if(!c_aliveNodes.get(i)){
1093  jam();
1094  ptr.p->setErrorCode(AbortBackupOrd::BackupFailureDueToNodeFail);
1095  return false;
1096  }//if
1097  if(getNodeInfo(i).m_version != version)
1098  {
1099  jam();
1100  ptr.p->setErrorCode(AbortBackupOrd::IncompatibleVersions);
1101  return false;
1102  }
1103  }//if
1104  }//for
1105  return true;
1106 }
1107 
1108 void
1110  BackupRecordPtr ptr,
1111  NodeId newCoord,
1112  Uint32 theFailedNodes[NdbNodeBitmask::Size])
1113 {
1114  NdbNodeBitmask mask;
1115  mask.assign(2, theFailedNodes);
1116 
1117  /* Update ptr.p->nodes to be up to date with current alive nodes
1118  */
1119  NodePtr nodePtr;
1120  bool found = false;
1121  for(c_nodes.first(nodePtr); nodePtr.i != RNIL; c_nodes.next(nodePtr)) {
1122  jam();
1123  if(NdbNodeBitmask::get(theFailedNodes, nodePtr.p->nodeId)) {
1124  jam();
1125  if (ptr.p->nodes.get(nodePtr.p->nodeId)) {
1126  jam();
1127  ptr.p->nodes.clear(nodePtr.p->nodeId);
1128  found = true;
1129  }
1130  }//if
1131  }//for
1132 
1133  if(!found) {
1134  jam();
1135  return; // failed node is not part of backup process, safe to continue
1136  }
1137 
1138  if(mask.get(refToNode(ptr.p->masterRef)))
1139  {
1143  ptr.p->masterRef = reference();
1144  ptr.p->nodes.clear();
1145  ptr.p->nodes.set(getOwnNodeId());
1146  ptr.p->setErrorCode(AbortBackupOrd::BackupFailureDueToNodeFail);
1147  switch(ptr.p->m_gsn){
1148  case GSN_DEFINE_BACKUP_REQ:
1149  case GSN_START_BACKUP_REQ:
1150  case GSN_BACKUP_FRAGMENT_REQ:
1151  case GSN_STOP_BACKUP_REQ:
1152  // I'm currently processing...reply to self and abort...
1153  ptr.p->masterData.gsn = ptr.p->m_gsn;
1154  ptr.p->masterData.sendCounter = ptr.p->nodes;
1155  return;
1156  case GSN_DEFINE_BACKUP_REF:
1157  case GSN_DEFINE_BACKUP_CONF:
1158  case GSN_START_BACKUP_REF:
1159  case GSN_START_BACKUP_CONF:
1160  case GSN_BACKUP_FRAGMENT_REF:
1161  case GSN_BACKUP_FRAGMENT_CONF:
1162  case GSN_STOP_BACKUP_REF:
1163  case GSN_STOP_BACKUP_CONF:
1164  ptr.p->masterData.gsn = GSN_DEFINE_BACKUP_REQ;
1165  masterAbort(signal, ptr);
1166  return;
1167  case GSN_ABORT_BACKUP_ORD:
1168  // Already aborting
1169  return;
1170  }
1171  }
1172  else if (newCoord == getOwnNodeId())
1173  {
1177  jam();
1178  CRASH_INSERTION((10001));
1179 #ifdef DEBUG_ABORT
1180  ndbout_c("**** Master: Node failed: Master id = %u",
1181  refToNode(ptr.p->masterRef));
1182 #endif
1183 
1184  Uint32 gsn, len, pos;
1185  LINT_INIT(gsn);
1186  LINT_INIT(len);
1187  LINT_INIT(pos);
1188  ptr.p->nodes.bitANDC(mask);
1189  switch(ptr.p->masterData.gsn){
1190  case GSN_DEFINE_BACKUP_REQ:
1191  {
1192  DefineBackupRef * ref = (DefineBackupRef*)signal->getDataPtr();
1193  ref->backupPtr = ptr.i;
1194  ref->backupId = ptr.p->backupId;
1195  ref->errorCode = AbortBackupOrd::BackupFailureDueToNodeFail;
1196  gsn= GSN_DEFINE_BACKUP_REF;
1197  len= DefineBackupRef::SignalLength;
1198  pos= Uint32(&ref->nodeId - signal->getDataPtr());
1199  break;
1200  }
1201  case GSN_START_BACKUP_REQ:
1202  {
1203  StartBackupRef * ref = (StartBackupRef*)signal->getDataPtr();
1204  ref->backupPtr = ptr.i;
1205  ref->backupId = ptr.p->backupId;
1206  ref->errorCode = AbortBackupOrd::BackupFailureDueToNodeFail;
1207  gsn= GSN_START_BACKUP_REF;
1208  len= StartBackupRef::SignalLength;
1209  pos= Uint32(&ref->nodeId - signal->getDataPtr());
1210  break;
1211  }
1212  case GSN_BACKUP_FRAGMENT_REQ:
1213  {
1214  BackupFragmentRef * ref = (BackupFragmentRef*)signal->getDataPtr();
1215  ref->backupPtr = ptr.i;
1216  ref->backupId = ptr.p->backupId;
1217  ref->errorCode = AbortBackupOrd::BackupFailureDueToNodeFail;
1218  gsn= GSN_BACKUP_FRAGMENT_REF;
1219  len= BackupFragmentRef::SignalLength;
1220  pos= Uint32(&ref->nodeId - signal->getDataPtr());
1221  break;
1222  }
1223  case GSN_STOP_BACKUP_REQ:
1224  {
1225  StopBackupRef * ref = (StopBackupRef*)signal->getDataPtr();
1226  ref->backupPtr = ptr.i;
1227  ref->backupId = ptr.p->backupId;
1228  ref->errorCode = AbortBackupOrd::BackupFailureDueToNodeFail;
1229  ref->nodeId = getOwnNodeId();
1230  gsn= GSN_STOP_BACKUP_REF;
1231  len= StopBackupRef::SignalLength;
1232  pos= Uint32(&ref->nodeId - signal->getDataPtr());
1233  break;
1234  }
1235  case GSN_WAIT_GCP_REQ:
1236  case GSN_DROP_TRIG_IMPL_REQ:
1237  case GSN_CREATE_TRIG_IMPL_REQ:
1238  case GSN_ALTER_TRIG_IMPL_REQ:
1239  ptr.p->setErrorCode(AbortBackupOrd::BackupFailureDueToNodeFail);
1240  return;
1241  case GSN_UTIL_SEQUENCE_REQ:
1242  case GSN_UTIL_LOCK_REQ:
1243  return;
1244  default:
1245  ndbrequire(false);
1246  }
1247 
1248  for(Uint32 i = 0; (i = mask.find(i+1)) != NdbNodeBitmask::NotFound; )
1249  {
1250  signal->theData[pos] = i;
1251  sendSignal(reference(), gsn, signal, len, JBB);
1252 #ifdef DEBUG_ABORT
1253  ndbout_c("sending %d to self from %d", gsn, i);
1254 #endif
1255  }
1256  return;
1257  }//if
1258 
1262  CRASH_INSERTION((10021));
1263 }
1264 
1265 void
1266 Backup::execINCL_NODEREQ(Signal* signal)
1267 {
1268  jamEntry();
1269 
1270  const Uint32 senderRef = signal->theData[0];
1271  const Uint32 inclNode = signal->theData[1];
1272 
1273  NodePtr node;
1274  for(c_nodes.first(node); node.i != RNIL; c_nodes.next(node)) {
1275  jam();
1276  const Uint32 nodeId = node.p->nodeId;
1277  if(inclNode == nodeId){
1278  jam();
1279 
1280  ndbrequire(node.p->alive == 0);
1281  ndbrequire(!c_aliveNodes.get(nodeId));
1282 
1283  node.p->alive = 1;
1284  c_aliveNodes.set(nodeId);
1285 
1286  break;
1287  }//if
1288  }//for
1289  signal->theData[0] = inclNode;
1290  signal->theData[1] = reference();
1291  sendSignal(senderRef, GSN_INCL_NODECONF, signal, 2, JBB);
1292 }
1293 
1294 /*****************************************************************************
1295  *
1296  * Master functionallity - Define backup
1297  *
1298  *****************************************************************************/
1299 
1300 void
1302 {
1303  jamEntry();
1304  BackupReq * req = (BackupReq*)signal->getDataPtr();
1305 
1306  const Uint32 senderData = req->senderData;
1307  const BlockReference senderRef = signal->senderBlockRef();
1308  const Uint32 dataLen32 = req->backupDataLen; // In 32 bit words
1309  const Uint32 flags = signal->getLength() > 2 ? req->flags : 2;
1310  const Uint32 input_backupId = signal->getLength() > 3 ? req->inputBackupId : 0;
1311 
1312  if (getOwnNodeId() != getMasterNodeId())
1313  {
1314  jam();
1315  sendBackupRef(senderRef, flags, signal, senderData,
1316  BackupRef::IAmNotMaster);
1317  return;
1318  }//if
1319 
1320  if (c_defaults.m_diskless)
1321  {
1322  jam();
1323  sendBackupRef(senderRef, flags, signal, senderData,
1324  BackupRef::CannotBackupDiskless);
1325  return;
1326  }
1327 
1328  if (dataLen32 != 0)
1329  {
1330  jam();
1331  sendBackupRef(senderRef, flags, signal, senderData,
1332  BackupRef::BackupDefinitionNotImplemented);
1333  return;
1334  }//if
1335 
1336 #ifdef DEBUG_ABORT
1337  dumpUsedResources();
1338 #endif
1339 
1342  BackupRecordPtr ptr;
1343  c_backups.seize(ptr);
1344  if (ptr.i == RNIL)
1345  {
1346  jam();
1347  sendBackupRef(senderRef, flags, signal, senderData,
1348  BackupRef::OutOfBackupRecord);
1349  return;
1350  }//if
1351 
1352  ndbrequire(ptr.p->tables.isEmpty());
1353 
1354  ptr.p->m_gsn = 0;
1355  ptr.p->errorCode = 0;
1356  ptr.p->clientRef = senderRef;
1357  ptr.p->clientData = senderData;
1358  ptr.p->flags = flags;
1359  ptr.p->masterRef = reference();
1360  ptr.p->nodes = c_aliveNodes;
1361  if (input_backupId)
1362  {
1363  jam();
1364  ptr.p->backupId = input_backupId;
1365  }
1366  else
1367  {
1368  jam();
1369  ptr.p->backupId = 0;
1370  }
1371  ptr.p->backupKey[0] = 0;
1372  ptr.p->backupKey[1] = 0;
1373  ptr.p->backupDataLen = 0;
1374  ptr.p->masterData.errorCode = 0;
1375 
1376  ptr.p->masterData.sequence.retriesLeft = 3;
1377  sendUtilSequenceReq(signal, ptr);
1378 }
1379 
1380 void
1381 Backup::sendUtilSequenceReq(Signal* signal, BackupRecordPtr ptr, Uint32 delay)
1382 {
1383  jam();
1384 
1385  UtilSequenceReq * utilReq = (UtilSequenceReq*)signal->getDataPtrSend();
1386  ptr.p->masterData.gsn = GSN_UTIL_SEQUENCE_REQ;
1387  utilReq->senderData = ptr.i;
1388  utilReq->sequenceId = NDB_BACKUP_SEQUENCE;
1389 
1390  if (ptr.p->backupId)
1391  {
1392  jam();
1393  utilReq->requestType = UtilSequenceReq::SetVal;
1394  utilReq->value = ptr.p->backupId;
1395  }
1396  else
1397  {
1398  jam();
1399  utilReq->requestType = UtilSequenceReq::NextVal;
1400  }
1401 
1402  if (delay == 0)
1403  {
1404  jam();
1405  sendSignal(DBUTIL_REF, GSN_UTIL_SEQUENCE_REQ,
1406  signal, UtilSequenceReq::SignalLength, JBB);
1407  }
1408  else
1409  {
1410  jam();
1411  sendSignalWithDelay(DBUTIL_REF, GSN_UTIL_SEQUENCE_REQ,
1412  signal, delay, UtilSequenceReq::SignalLength);
1413  }
1414 }
1415 
1416 void
1417 Backup::execUTIL_SEQUENCE_REF(Signal* signal)
1418 {
1419  jamEntry();
1420  BackupRecordPtr ptr LINT_SET_PTR;
1421  UtilSequenceRef * utilRef = (UtilSequenceRef*)signal->getDataPtr();
1422  ptr.i = utilRef->senderData;
1423  c_backupPool.getPtr(ptr);
1424  ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_SEQUENCE_REQ);
1425 
1426  if (utilRef->errorCode == UtilSequenceRef::TCError)
1427  {
1428  jam();
1429  if (ptr.p->masterData.sequence.retriesLeft > 0)
1430  {
1431  jam();
1432  infoEvent("BACKUP: retrying sequence on error %u",
1433  utilRef->TCErrorCode);
1434  ptr.p->masterData.sequence.retriesLeft--;
1435  sendUtilSequenceReq(signal, ptr, 300);
1436  return;
1437  }
1438  }
1439  warningEvent("BACKUP: aborting due to sequence error (%u, %u)",
1440  utilRef->errorCode,
1441  utilRef->TCErrorCode);
1442 
1443  sendBackupRef(signal, ptr, BackupRef::SequenceFailure);
1444 }//execUTIL_SEQUENCE_REF()
1445 
1446 void
1447 Backup::sendBackupRef(Signal* signal, BackupRecordPtr ptr, Uint32 errorCode)
1448 {
1449  jam();
1450  sendBackupRef(ptr.p->clientRef, ptr.p->flags, signal,
1451  ptr.p->clientData, errorCode);
1452  cleanup(signal, ptr);
1453 }
1454 
1455 void
1456 Backup::sendBackupRef(BlockReference senderRef, Uint32 flags, Signal *signal,
1457  Uint32 senderData, Uint32 errorCode)
1458 {
1459  jam();
1460  if (SEND_BACKUP_STARTED_FLAG(flags))
1461  {
1462  jam();
1463  BackupRef* ref = (BackupRef*)signal->getDataPtrSend();
1464  ref->senderData = senderData;
1465  ref->errorCode = errorCode;
1466  ref->masterRef = numberToRef(BACKUP, getMasterNodeId());
1467  sendSignal(senderRef, GSN_BACKUP_REF, signal, BackupRef::SignalLength, JBB);
1468  }
1469 
1470  if (errorCode != BackupRef::IAmNotMaster)
1471  {
1472  jam();
1473  signal->theData[0] = NDB_LE_BackupFailedToStart;
1474  signal->theData[1] = senderRef;
1475  signal->theData[2] = errorCode;
1476  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
1477  }
1478 }
1479 
1480 void
1481 Backup::execUTIL_SEQUENCE_CONF(Signal* signal)
1482 {
1483  jamEntry();
1484 
1485  UtilSequenceConf * conf = (UtilSequenceConf*)signal->getDataPtr();
1486 
1487  if(conf->requestType == UtilSequenceReq::Create)
1488  {
1489  jam();
1490  sendSTTORRY(signal); // At startup in NDB
1491  return;
1492  }
1493 
1494  BackupRecordPtr ptr LINT_SET_PTR;
1495  ptr.i = conf->senderData;
1496  c_backupPool.getPtr(ptr);
1497 
1498  ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_SEQUENCE_REQ);
1499 
1500  if (ptr.p->checkError())
1501  {
1502  jam();
1503  sendBackupRef(signal, ptr, ptr.p->errorCode);
1504  return;
1505  }//if
1506 
1507  if (ERROR_INSERTED(10023))
1508  {
1509  sendBackupRef(signal, ptr, 323);
1510  return;
1511  }//if
1512 
1513 
1514  if(!ptr.p->backupId && conf->requestType != UtilSequenceReq::SetVal)
1515  {
1516  Uint64 backupId;
1517  memcpy(&backupId,conf->sequenceValue,8);
1518  ptr.p->backupId= (Uint32)backupId;
1519  }
1520 
1521  ptr.p->backupKey[0] = (getOwnNodeId() << 16) | (ptr.p->backupId & 0xFFFF);
1522  ptr.p->backupKey[1] = Uint32(NdbTick_CurrentMillisecond());
1523 
1524  ptr.p->masterData.gsn = GSN_UTIL_LOCK_REQ;
1525  Mutex mutex(signal, c_mutexMgr, ptr.p->masterData.m_defineBackupMutex);
1526  Callback c = { safe_cast(&Backup::defineBackupMutex_locked), ptr.i };
1527  ndbrequire(mutex.lock(c));
1528 
1529  return;
1530 }
1531 
1532 void
1533 Backup::defineBackupMutex_locked(Signal* signal, Uint32 ptrI, Uint32 retVal){
1534  jamEntry();
1535  ndbrequire(retVal == 0);
1536 
1537  BackupRecordPtr ptr LINT_SET_PTR;
1538  ptr.i = ptrI;
1539  c_backupPool.getPtr(ptr);
1540 
1541  ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_LOCK_REQ);
1542 
1543  ptr.p->masterData.gsn = GSN_UTIL_LOCK_REQ;
1544  Mutex mutex(signal, c_mutexMgr, ptr.p->masterData.m_dictCommitTableMutex);
1545  Callback c = { safe_cast(&Backup::dictCommitTableMutex_locked), ptr.i };
1546  ndbrequire(mutex.lock(c));
1547 }
1548 
1549 void
1550 Backup::dictCommitTableMutex_locked(Signal* signal, Uint32 ptrI,Uint32 retVal)
1551 {
1552  jamEntry();
1553  ndbrequire(retVal == 0);
1554 
1558  BackupRecordPtr ptr LINT_SET_PTR;
1559  ptr.i = ptrI;
1560  c_backupPool.getPtr(ptr);
1561 
1562  ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_LOCK_REQ);
1563 
1564  if (ERROR_INSERTED(10031)) {
1565  ptr.p->setErrorCode(331);
1566  }//if
1567 
1568  if (ptr.p->checkError())
1569  {
1570  jam();
1571 
1575  jam();
1576  Mutex mutex1(signal, c_mutexMgr, ptr.p->masterData.m_dictCommitTableMutex);
1577  jam();
1578  mutex1.unlock(); // ignore response
1579 
1580  jam();
1581  Mutex mutex2(signal, c_mutexMgr, ptr.p->masterData.m_defineBackupMutex);
1582  jam();
1583  mutex2.unlock(); // ignore response
1584 
1585  sendBackupRef(signal, ptr, ptr.p->errorCode);
1586  return;
1587  }//if
1588 
1589  sendDefineBackupReq(signal, ptr);
1590 }
1591 
1592 /*****************************************************************************
1593  *
1594  * Master functionallity - Define backup cont'd (from now on all slaves are in)
1595  *
1596  *****************************************************************************/
1597 
1598 bool
1599 Backup::haveAllSignals(BackupRecordPtr ptr, Uint32 gsn, Uint32 nodeId)
1600 {
1601  ndbrequire(ptr.p->masterRef == reference());
1602  ndbrequire(ptr.p->masterData.gsn == gsn);
1603  ndbrequire(!ptr.p->masterData.sendCounter.done());
1604  ndbrequire(ptr.p->masterData.sendCounter.isWaitingFor(nodeId));
1605 
1606  ptr.p->masterData.sendCounter.clearWaitingFor(nodeId);
1607  return ptr.p->masterData.sendCounter.done();
1608 }
1609 
1610 void
1612 {
1616  DefineBackupReq * req = (DefineBackupReq*)signal->getDataPtrSend();
1617  req->backupId = ptr.p->backupId;
1618  req->clientRef = ptr.p->clientRef;
1619  req->clientData = ptr.p->clientData;
1620  req->senderRef = reference();
1621  req->backupPtr = ptr.i;
1622  req->backupKey[0] = ptr.p->backupKey[0];
1623  req->backupKey[1] = ptr.p->backupKey[1];
1624  req->nodes = ptr.p->nodes;
1625  req->backupDataLen = ptr.p->backupDataLen;
1626  req->flags = ptr.p->flags;
1627 
1628  ptr.p->masterData.gsn = GSN_DEFINE_BACKUP_REQ;
1629  ptr.p->masterData.sendCounter = ptr.p->nodes;
1630  BlockNumber backupBlockNo = numberToBlock(BACKUP, instanceKey(ptr));
1631  NodeReceiverGroup rg(backupBlockNo, ptr.p->nodes);
1632  sendSignal(rg, GSN_DEFINE_BACKUP_REQ, signal,
1633  DefineBackupReq::SignalLength, JBB);
1634 
1638  const Uint32 len = ptr.p->backupDataLen;
1639  if(len == 0){
1643  jam();
1644  return;
1645  }//if
1646 
1650  ndbrequire(0);
1651 }
1652 
1653 void
1654 Backup::execDEFINE_BACKUP_REF(Signal* signal)
1655 {
1656  jamEntry();
1657 
1658  DefineBackupRef* ref = (DefineBackupRef*)signal->getDataPtr();
1659 
1660  const Uint32 ptrI = ref->backupPtr;
1661  //const Uint32 backupId = ref->backupId;
1662  const Uint32 nodeId = ref->nodeId;
1663 
1664  BackupRecordPtr ptr LINT_SET_PTR;
1665  c_backupPool.getPtr(ptr, ptrI);
1666 
1667  ptr.p->setErrorCode(ref->errorCode);
1668  defineBackupReply(signal, ptr, nodeId);
1669 }
1670 
1671 void
1672 Backup::execDEFINE_BACKUP_CONF(Signal* signal)
1673 {
1674  jamEntry();
1675 
1676  DefineBackupConf* conf = (DefineBackupConf*)signal->getDataPtr();
1677  const Uint32 ptrI = conf->backupPtr;
1678  //const Uint32 backupId = conf->backupId;
1679  const Uint32 nodeId = refToNode(signal->senderBlockRef());
1680 
1681  BackupRecordPtr ptr LINT_SET_PTR;
1682  c_backupPool.getPtr(ptr, ptrI);
1683 
1684  if (ERROR_INSERTED(10024))
1685  {
1686  ptr.p->setErrorCode(324);
1687  }
1688 
1689  defineBackupReply(signal, ptr, nodeId);
1690 }
1691 
1692 void
1694 {
1695  if (!haveAllSignals(ptr, GSN_DEFINE_BACKUP_REQ, nodeId)) {
1696  jam();
1697  return;
1698  }
1699 
1703  jam();
1704  Mutex mutex1(signal, c_mutexMgr, ptr.p->masterData.m_dictCommitTableMutex);
1705  jam();
1706  mutex1.unlock(); // ignore response
1707 
1708  jam();
1709  Mutex mutex2(signal, c_mutexMgr, ptr.p->masterData.m_defineBackupMutex);
1710  jam();
1711  mutex2.unlock(); // ignore response
1712 
1713  if(ptr.p->checkError())
1714  {
1715  jam();
1716  masterAbort(signal, ptr);
1717  return;
1718  }
1719 
1720  CRASH_INSERTION((10034));
1721 
1729  TablePtr tabPtr;
1730  ptr.p->tables.first(tabPtr);
1731 
1732  sendStartBackup(signal, ptr, tabPtr);
1733 }
1734 
1735 /*****************************************************************************
1736  *
1737  * Master functionallity - Prepare triggers
1738  *
1739  *****************************************************************************/
1740 void
1741 Backup::createAttributeMask(TablePtr tabPtr,
1743 {
1744  mask.clear();
1745  for (Uint32 i = 0; i<tabPtr.p->noOfAttributes; i++)
1746  mask.set(i);
1747 }
1748 
1749 void
1750 Backup::sendCreateTrig(Signal* signal,
1751  BackupRecordPtr ptr, TablePtr tabPtr)
1752 {
1753  CreateTrigImplReq* req = (CreateTrigImplReq*)signal->getDataPtrSend();
1754 
1755  /*
1756  * First, setup the structures
1757  */
1758  for(Uint32 j=0; j<3; j++) {
1759  jam();
1760 
1761  TriggerPtr trigPtr;
1762  if(!ptr.p->triggers.seize(trigPtr)) {
1763  jam();
1764  ptr.p->m_gsn = GSN_START_BACKUP_REF;
1765  StartBackupRef* ref = (StartBackupRef*)signal->getDataPtrSend();
1766  ref->backupPtr = ptr.i;
1767  ref->backupId = ptr.p->backupId;
1768  ref->errorCode = StartBackupRef::FailedToAllocateTriggerRecord;
1769  ref->nodeId = getOwnNodeId();
1770  sendSignal(ptr.p->masterRef, GSN_START_BACKUP_REF, signal,
1771  StartBackupRef::SignalLength, JBB);
1772  return;
1773  } // if
1774 
1775  const Uint32 triggerId= trigPtr.i;
1776  tabPtr.p->triggerIds[j] = triggerId;
1777  tabPtr.p->triggerAllocated[j] = true;
1778  trigPtr.p->backupPtr = ptr.i;
1779  trigPtr.p->tableId = tabPtr.p->tableId;
1780  trigPtr.p->tab_ptr_i = tabPtr.i;
1781  trigPtr.p->logEntry = 0;
1782  trigPtr.p->event = j;
1783  trigPtr.p->maxRecordSize = 4096;
1784  trigPtr.p->operation =
1785  &ptr.p->files.getPtr(ptr.p->logFilePtr)->operation;
1786  trigPtr.p->operation->noOfBytes = 0;
1787  trigPtr.p->operation->noOfRecords = 0;
1788  trigPtr.p->errorCode = 0;
1789  } // for
1790 
1791  /*
1792  * now ask DBTUP to create
1793  */
1794  ptr.p->slaveData.gsn = GSN_CREATE_TRIG_IMPL_REQ;
1795  ptr.p->slaveData.trigSendCounter = 3;
1796  ptr.p->slaveData.createTrig.tableId = tabPtr.p->tableId;
1797 
1798  req->senderRef = reference();
1799  req->receiverRef = reference();
1800  req->senderData = ptr.i;
1801  req->requestType = 0;
1802 
1804  createAttributeMask(tabPtr, attrMask);
1805 
1806  req->tableId = tabPtr.p->tableId;
1807  req->tableVersion = 0;
1808  req->indexId = RNIL;
1809  req->indexVersion = 0;
1810 
1811  Uint32 ti = 0;
1812  /*
1813  * We always send PK for any operations and any triggertypes.
1814  * For SUBSCRIPTION_BEFORE
1815  * We send after image for INSERT.
1816  * We send before image for DELETE.
1817  * We send before+after image for UPDATE.
1818  * For SUBSCRIPTION
1819  * We send after image for INSERT.
1820  * We send only PK for DELETE.
1821  * We send after image for UPDATE.
1822  */
1823  if(ptr.p->flags & BackupReq::USE_UNDO_LOG)
1824  TriggerInfo::setTriggerType(ti, TriggerType::SUBSCRIPTION_BEFORE);
1825  else
1826  TriggerInfo::setTriggerType(ti, TriggerType::SUBSCRIPTION);
1827  TriggerInfo::setTriggerActionTime(ti, TriggerActionTime::TA_DETACHED);
1828  TriggerInfo::setMonitorReplicas(ti, true);
1829  TriggerInfo::setMonitorAllAttributes(ti, false);
1830 
1831  for (int i=0; i < 3; i++) {
1832  req->triggerId = tabPtr.p->triggerIds[i];
1833 
1834  Uint32 ti2 = ti;
1835  TriggerInfo::setTriggerEvent(ti2, triggerEventValues[i]);
1836  req->triggerInfo = ti2;
1837 
1838  LinearSectionPtr ptr[3];
1839  ptr[0].p = attrMask.rep.data;
1840  ptr[0].sz = attrMask.getSizeInWords();
1841 
1842  sendSignal(DBTUP_REF, GSN_CREATE_TRIG_IMPL_REQ,
1843  signal, CreateTrigImplReq::SignalLength, JBB, ptr ,1);
1844  }
1845 }
1846 
1847 void
1849 {
1850  jamEntry();
1851  const CreateTrigImplConf* conf =
1852  (const CreateTrigImplConf*)signal->getDataPtr();
1853 
1854  const Uint32 ptrI = conf->senderData;
1855  const Uint32 tableId = conf->tableId;
1856  const TriggerEvent::Value type =
1857  TriggerInfo::getTriggerEvent(conf->triggerInfo);
1858 
1859  BackupRecordPtr ptr LINT_SET_PTR;
1860  c_backupPool.getPtr(ptr, ptrI);
1861 
1868  ndbrequire(ptr.p->slaveData.gsn == GSN_CREATE_TRIG_IMPL_REQ);
1869  ndbrequire(ptr.p->slaveData.trigSendCounter.done() == false);
1870  ndbrequire(ptr.p->slaveData.createTrig.tableId == tableId);
1871 
1872  TablePtr tabPtr;
1873  ndbrequire(findTable(ptr, tabPtr, tableId));
1874  ndbrequire(type < 3); // if some decides to change the enums
1875 
1876  createTrigReply(signal, ptr);
1877 }
1878 
1879 void
1881 {
1882  jamEntry();
1883  const CreateTrigImplRef* ref =
1884  (const CreateTrigImplRef*)signal->getDataPtr();
1885 
1886  const Uint32 ptrI = ref->senderData;
1887  const Uint32 tableId = ref->tableId;
1888 
1889  BackupRecordPtr ptr LINT_SET_PTR;
1890  c_backupPool.getPtr(ptr, ptrI);
1891 
1898  ndbrequire(ptr.p->slaveData.gsn == GSN_CREATE_TRIG_IMPL_REQ);
1899  ndbrequire(ptr.p->slaveData.trigSendCounter.done() == false);
1900  ndbrequire(ptr.p->slaveData.createTrig.tableId == tableId);
1901 
1902  ptr.p->setErrorCode(ref->errorCode);
1903 
1904  createTrigReply(signal, ptr);
1905 }
1906 
1907 void
1909 {
1910  CRASH_INSERTION(10003);
1911 
1915  ptr.p->slaveData.trigSendCounter--;
1916  if(ptr.p->slaveData.trigSendCounter.done() == false){
1917  jam();
1918  return;
1919  }//if
1920 
1921  if (ERROR_INSERTED(10025))
1922  {
1923  ptr.p->errorCode = 325;
1924  }
1925 
1926  if(ptr.p->checkError()) {
1927  jam();
1928  ptr.p->m_gsn = GSN_START_BACKUP_REF;
1929  StartBackupRef* ref = (StartBackupRef*)signal->getDataPtrSend();
1930  ref->backupPtr = ptr.i;
1931  ref->backupId = ptr.p->backupId;
1932  ref->errorCode = ptr.p->errorCode;
1933  ref->nodeId = getOwnNodeId();
1934  sendSignal(ptr.p->masterRef, GSN_START_BACKUP_REF, signal,
1935  StartBackupRef::SignalLength, JBB);
1936  return;
1937  }//if
1938 
1939  TablePtr tabPtr;
1940  ndbrequire(findTable(ptr, tabPtr, ptr.p->slaveData.createTrig.tableId));
1941 
1945  ptr.p->tables.next(tabPtr);
1946  if(tabPtr.i != RNIL){
1947  jam();
1948  sendCreateTrig(signal, ptr, tabPtr);
1949  return;
1950  }//if
1951 
1957  ptr.p->m_gsn = GSN_START_BACKUP_CONF;
1958  StartBackupConf* conf = (StartBackupConf*)signal->getDataPtrSend();
1959  conf->backupPtr = ptr.i;
1960  conf->backupId = ptr.p->backupId;
1961  sendSignal(ptr.p->masterRef, GSN_START_BACKUP_CONF, signal,
1962  StartBackupConf::SignalLength, JBB);
1963 }
1964 
1965 /*****************************************************************************
1966  *
1967  * Master functionallity - Start backup
1968  *
1969  *****************************************************************************/
1970 void
1972 {
1973 
1974  ptr.p->masterData.startBackup.tablePtr = tabPtr.i;
1975 
1976  StartBackupReq* req = (StartBackupReq*)signal->getDataPtrSend();
1977  req->backupId = ptr.p->backupId;
1978  req->backupPtr = ptr.i;
1979 
1987  ptr.p->masterData.gsn = GSN_START_BACKUP_REQ;
1988  ptr.p->masterData.sendCounter = ptr.p->nodes;
1989  BlockNumber backupBlockNo = numberToBlock(BACKUP, instanceKey(ptr));
1990  NodeReceiverGroup rg(backupBlockNo, ptr.p->nodes);
1991  sendSignal(rg, GSN_START_BACKUP_REQ, signal,
1992  StartBackupReq::SignalLength, JBB);
1993 }
1994 
1995 void
1996 Backup::execSTART_BACKUP_REF(Signal* signal)
1997 {
1998  jamEntry();
1999 
2000  StartBackupRef* ref = (StartBackupRef*)signal->getDataPtr();
2001  const Uint32 ptrI = ref->backupPtr;
2002  //const Uint32 backupId = ref->backupId;
2003  const Uint32 nodeId = ref->nodeId;
2004 
2005  BackupRecordPtr ptr LINT_SET_PTR;
2006  c_backupPool.getPtr(ptr, ptrI);
2007 
2008  ptr.p->setErrorCode(ref->errorCode);
2009  startBackupReply(signal, ptr, nodeId);
2010 }
2011 
2012 void
2013 Backup::execSTART_BACKUP_CONF(Signal* signal)
2014 {
2015  jamEntry();
2016 
2017  StartBackupConf* conf = (StartBackupConf*)signal->getDataPtr();
2018  const Uint32 ptrI = conf->backupPtr;
2019  //const Uint32 backupId = conf->backupId;
2020  const Uint32 nodeId = refToNode(signal->senderBlockRef());
2021 
2022  BackupRecordPtr ptr LINT_SET_PTR;
2023  c_backupPool.getPtr(ptr, ptrI);
2024 
2025  startBackupReply(signal, ptr, nodeId);
2026 }
2027 
2028 void
2030 {
2031 
2032  CRASH_INSERTION((10004));
2033 
2034  if (!haveAllSignals(ptr, GSN_START_BACKUP_REQ, nodeId)) {
2035  jam();
2036  return;
2037  }
2038 
2039  if (ERROR_INSERTED(10026))
2040  {
2041  ptr.p->errorCode = 326;
2042  }
2043 
2044  if(ptr.p->checkError()){
2045  jam();
2046  masterAbort(signal, ptr);
2047  return;
2048  }
2049 
2050  /*
2051  * We reply to client after create trigger
2052  */
2053  if (SEND_BACKUP_STARTED_FLAG(ptr.p->flags))
2054  {
2055  BackupConf * conf = (BackupConf*)signal->getDataPtrSend();
2056  conf->backupId = ptr.p->backupId;
2057  conf->senderData = ptr.p->clientData;
2058  conf->nodes = ptr.p->nodes;
2059  sendSignal(ptr.p->clientRef, GSN_BACKUP_CONF, signal,
2060  BackupConf::SignalLength, JBB);
2061  }
2062 
2063  signal->theData[0] = NDB_LE_BackupStarted;
2064  signal->theData[1] = ptr.p->clientRef;
2065  signal->theData[2] = ptr.p->backupId;
2066  ptr.p->nodes.copyto(NdbNodeBitmask::Size, signal->theData+3);
2067  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3+NdbNodeBitmask::Size, JBB);
2068 
2072  ptr.p->masterData.gsn = GSN_WAIT_GCP_REQ;
2073  ptr.p->masterData.waitGCP.startBackup = true;
2074 
2075  WaitGCPReq * waitGCPReq = (WaitGCPReq*)signal->getDataPtrSend();
2076  waitGCPReq->senderRef = reference();
2077  waitGCPReq->senderData = ptr.i;
2078  waitGCPReq->requestType = WaitGCPReq::CompleteForceStart;
2079  //we delay 10 seconds for testcases to generate events to be recorded in the UNDO log
2080  if (ERROR_INSERTED(10041))
2081  {
2082  sendSignalWithDelay(DBDIH_REF, GSN_WAIT_GCP_REQ, signal, 10*1000, WaitGCPReq::SignalLength);
2083  }
2084  else
2085  sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
2086  WaitGCPReq::SignalLength,JBB);
2087 }
2088 
2089 void
2090 Backup::execWAIT_GCP_REF(Signal* signal)
2091 {
2092  jamEntry();
2093 
2094  CRASH_INSERTION((10006));
2095 
2096  WaitGCPRef * ref = (WaitGCPRef*)signal->getDataPtr();
2097  const Uint32 ptrI = ref->senderData;
2098 
2099  BackupRecordPtr ptr LINT_SET_PTR;
2100  c_backupPool.getPtr(ptr, ptrI);
2101 
2102  ndbrequire(ptr.p->masterRef == reference());
2103  ndbrequire(ptr.p->masterData.gsn == GSN_WAIT_GCP_REQ);
2104 
2105  WaitGCPReq * req = (WaitGCPReq*)signal->getDataPtrSend();
2106  req->senderRef = reference();
2107  req->senderData = ptr.i;
2108  req->requestType = WaitGCPReq::CompleteForceStart;
2109  sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
2110  WaitGCPReq::SignalLength,JBB);
2111 }
2112 
2113 void
2115  jamEntry();
2116 
2117  CRASH_INSERTION((10007));
2118 
2119  WaitGCPConf * conf = (WaitGCPConf*)signal->getDataPtr();
2120  const Uint32 ptrI = conf->senderData;
2121  const Uint32 gcp = conf->gci_hi;
2122 
2123  BackupRecordPtr ptr LINT_SET_PTR;
2124  c_backupPool.getPtr(ptr, ptrI);
2125 
2126  ndbrequire(ptr.p->masterRef == reference());
2127  ndbrequire(ptr.p->masterData.gsn == GSN_WAIT_GCP_REQ);
2128 
2129  if(ptr.p->checkError()) {
2130  jam();
2131  masterAbort(signal, ptr);
2132  return;
2133  }//if
2134 
2135  if(ptr.p->masterData.waitGCP.startBackup) {
2136  jam();
2137  CRASH_INSERTION((10008));
2138  ptr.p->startGCP = gcp;
2139  ptr.p->masterData.sendCounter= 0;
2140  ptr.p->masterData.gsn = GSN_BACKUP_FRAGMENT_REQ;
2141  nextFragment(signal, ptr);
2142  return;
2143  } else {
2144  jam();
2145  if(gcp >= ptr.p->startGCP + 3)
2146  {
2147  CRASH_INSERTION((10009));
2148  ptr.p->stopGCP = gcp;
2154  sendStopBackup(signal, ptr);
2155  return;
2156  }//if
2157 
2161  WaitGCPReq * req = (WaitGCPReq*)signal->getDataPtrSend();
2162  req->senderRef = reference();
2163  req->senderData = ptr.i;
2164  req->requestType = WaitGCPReq::CompleteForceStart;
2165  sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
2166  WaitGCPReq::SignalLength,JBB);
2167  return;
2168  }
2169 }
2170 
2171 /*****************************************************************************
2172  *
2173  * Master functionallity - Backup fragment
2174  *
2175  *****************************************************************************/
2176 void
2178 {
2179  jam();
2180 
2181  BackupFragmentReq* req = (BackupFragmentReq*)signal->getDataPtrSend();
2182  req->backupPtr = ptr.i;
2183  req->backupId = ptr.p->backupId;
2184 
2185  NdbNodeBitmask nodes = ptr.p->nodes;
2186  Uint32 idleNodes = nodes.count();
2187  Uint32 saveIdleNodes = idleNodes;
2188  ndbrequire(idleNodes > 0);
2189 
2190  TablePtr tabPtr;
2191  ptr.p->tables.first(tabPtr);
2192  for(; tabPtr.i != RNIL && idleNodes > 0; ptr.p->tables.next(tabPtr)) {
2193  jam();
2194  FragmentPtr fragPtr;
2195  Array<Fragment> & frags = tabPtr.p->fragments;
2196  const Uint32 fragCount = frags.getSize();
2197 
2198  for(Uint32 i = 0; i<fragCount && idleNodes > 0; i++) {
2199  jam();
2200  tabPtr.p->fragments.getPtr(fragPtr, i);
2201  const Uint32 nodeId = fragPtr.p->node;
2202  if(fragPtr.p->scanning != 0) {
2203  jam();
2204  ndbrequire(nodes.get(nodeId));
2205  nodes.clear(nodeId);
2206  idleNodes--;
2207  } else if(fragPtr.p->scanned == 0 && nodes.get(nodeId)){
2208  jam();
2209  fragPtr.p->scanning = 1;
2210  nodes.clear(nodeId);
2211  idleNodes--;
2212 
2213  req->tableId = tabPtr.p->tableId;
2214  req->fragmentNo = i;
2215  req->count = 0;
2216 
2217  ptr.p->masterData.sendCounter++;
2218  BlockReference ref = numberToRef(BACKUP, instanceKey(ptr), nodeId);
2219  sendSignal(ref, GSN_BACKUP_FRAGMENT_REQ, signal,
2220  BackupFragmentReq::SignalLength, JBB);
2221  }//if
2222  }//for
2223  }//for
2224 
2225  if(idleNodes != saveIdleNodes){
2226  jam();
2227  return;
2228  }//if
2229 
2233  {
2234  ptr.p->masterData.gsn = GSN_WAIT_GCP_REQ;
2235  ptr.p->masterData.waitGCP.startBackup = false;
2236 
2237  WaitGCPReq * req = (WaitGCPReq*)signal->getDataPtrSend();
2238  req->senderRef = reference();
2239  req->senderData = ptr.i;
2240  req->requestType = WaitGCPReq::CompleteForceStart;
2241  sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
2242  WaitGCPReq::SignalLength, JBB);
2243  }
2244 }
2245 
2246 void
2247 Backup::execBACKUP_FRAGMENT_CONF(Signal* signal)
2248 {
2249  jamEntry();
2250 
2251  CRASH_INSERTION((10010));
2252 
2253  BackupFragmentConf * conf = (BackupFragmentConf*)signal->getDataPtr();
2254  const Uint32 ptrI = conf->backupPtr;
2255  //const Uint32 backupId = conf->backupId;
2256  const Uint32 tableId = conf->tableId;
2257  const Uint32 fragmentNo = conf->fragmentNo;
2258  const Uint32 nodeId = refToNode(signal->senderBlockRef());
2259  const Uint64 noOfBytes =
2260  conf->noOfBytesLow + (((Uint64)conf->noOfBytesHigh) << 32);
2261  const Uint64 noOfRecords =
2262  conf->noOfRecordsLow + (((Uint64)conf->noOfRecordsHigh) << 32);
2263 
2264  BackupRecordPtr ptr LINT_SET_PTR;
2265  c_backupPool.getPtr(ptr, ptrI);
2266 
2267  ptr.p->noOfBytes += noOfBytes;
2268  ptr.p->noOfRecords += noOfRecords;
2269  ptr.p->masterData.sendCounter--;
2270 
2271  TablePtr tabPtr;
2272  ndbrequire(findTable(ptr, tabPtr, tableId));
2273 
2274  tabPtr.p->noOfRecords += noOfRecords;
2275 
2276  FragmentPtr fragPtr;
2277  tabPtr.p->fragments.getPtr(fragPtr, fragmentNo);
2278 
2279  fragPtr.p->noOfRecords = noOfRecords;
2280 
2281  ndbrequire(fragPtr.p->scanned == 0);
2282  ndbrequire(fragPtr.p->scanning == 1);
2283  ndbrequire(fragPtr.p->node == nodeId);
2284 
2285  fragPtr.p->scanned = 1;
2286  fragPtr.p->scanning = 0;
2287 
2288  if (ERROR_INSERTED(10028))
2289  {
2290  ptr.p->errorCode = 328;
2291  }
2292 
2293  if(ptr.p->checkError())
2294  {
2295  if(ptr.p->masterData.sendCounter.done())
2296  {
2297  jam();
2298  masterAbort(signal, ptr);
2299  return;
2300  }//if
2301  }
2302  else
2303  {
2304  NdbNodeBitmask nodes = ptr.p->nodes;
2305  nodes.clear(getOwnNodeId());
2306  if (!nodes.isclear())
2307  {
2309  (BackupFragmentCompleteRep*)signal->getDataPtrSend();
2310  rep->backupId = ptr.p->backupId;
2311  rep->backupPtr = ptr.i;
2312  rep->tableId = tableId;
2313  rep->fragmentNo = fragmentNo;
2314  rep->noOfTableRowsLow = (Uint32)(tabPtr.p->noOfRecords & 0xFFFFFFFF);
2315  rep->noOfTableRowsHigh = (Uint32)(tabPtr.p->noOfRecords >> 32);
2316  rep->noOfFragmentRowsLow = (Uint32)(noOfRecords & 0xFFFFFFFF);
2317  rep->noOfFragmentRowsHigh = (Uint32)(noOfRecords >> 32);
2318  BlockNumber backupBlockNo = numberToBlock(BACKUP, instanceKey(ptr));
2319  NodeReceiverGroup rg(backupBlockNo, ptr.p->nodes);
2320  sendSignal(rg, GSN_BACKUP_FRAGMENT_COMPLETE_REP, signal,
2321  BackupFragmentCompleteRep::SignalLength, JBB);
2322  }
2323  nextFragment(signal, ptr);
2324  }
2325 }
2326 
2327 void
2328 Backup::execBACKUP_FRAGMENT_REF(Signal* signal)
2329 {
2330  jamEntry();
2331 
2332  CRASH_INSERTION((10011));
2333 
2334  BackupFragmentRef * ref = (BackupFragmentRef*)signal->getDataPtr();
2335  const Uint32 ptrI = ref->backupPtr;
2336  //const Uint32 backupId = ref->backupId;
2337  const Uint32 nodeId = ref->nodeId;
2338 
2339  BackupRecordPtr ptr LINT_SET_PTR;
2340  c_backupPool.getPtr(ptr, ptrI);
2341 
2342  TablePtr tabPtr;
2343  ptr.p->tables.first(tabPtr);
2344  for(; tabPtr.i != RNIL; ptr.p->tables.next(tabPtr)) {
2345  jam();
2346  FragmentPtr fragPtr;
2347  Array<Fragment> & frags = tabPtr.p->fragments;
2348  const Uint32 fragCount = frags.getSize();
2349 
2350  for(Uint32 i = 0; i<fragCount; i++) {
2351  jam();
2352  tabPtr.p->fragments.getPtr(fragPtr, i);
2353  if(fragPtr.p->scanning != 0 && nodeId == fragPtr.p->node)
2354  {
2355  jam();
2356  ndbrequire(fragPtr.p->scanned == 0);
2357  fragPtr.p->scanned = 1;
2358  fragPtr.p->scanning = 0;
2359  goto done;
2360  }
2361  }
2362  }
2363  goto err;
2364 
2365 done:
2366  ptr.p->masterData.sendCounter--;
2367  ptr.p->setErrorCode(ref->errorCode);
2368 
2369  if(ptr.p->masterData.sendCounter.done())
2370  {
2371  jam();
2372  masterAbort(signal, ptr);
2373  return;
2374  }//if
2375 
2376 err:
2377  AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
2378  ord->backupId = ptr.p->backupId;
2379  ord->backupPtr = ptr.i;
2380  ord->requestType = AbortBackupOrd::LogBufferFull;
2381  ord->senderData= ptr.i;
2382  execABORT_BACKUP_ORD(signal);
2383 }
2384 
2385 void
2386 Backup::execBACKUP_FRAGMENT_COMPLETE_REP(Signal* signal)
2387 {
2388  jamEntry();
2390  (BackupFragmentCompleteRep*)signal->getDataPtr();
2391 
2392  BackupRecordPtr ptr LINT_SET_PTR;
2393  c_backupPool.getPtr(ptr, rep->backupPtr);
2394 
2395  TablePtr tabPtr;
2396  ndbrequire(findTable(ptr, tabPtr, rep->tableId));
2397 
2398  tabPtr.p->noOfRecords =
2399  rep->noOfTableRowsLow + (((Uint64)rep->noOfTableRowsHigh) << 32);
2400 
2401  FragmentPtr fragPtr;
2402  tabPtr.p->fragments.getPtr(fragPtr, rep->fragmentNo);
2403 
2404  fragPtr.p->noOfRecords =
2405  rep->noOfFragmentRowsLow + (((Uint64)rep->noOfFragmentRowsHigh) << 32);
2406 }
2407 
2408 /*****************************************************************************
2409  *
2410  * Slave functionallity - Drop triggers
2411  *
2412  *****************************************************************************/
2413 
2414 void
2416 {
2417  TablePtr tabPtr;
2418  ptr.p->slaveData.gsn = GSN_DROP_TRIG_IMPL_REQ;
2419 
2420  if (ptr.p->slaveData.dropTrig.tableId == RNIL) {
2421  jam();
2422  if(ptr.p->tables.count())
2423  ptr.p->tables.first(tabPtr);
2424  else
2425  {
2426  // Early abort, go to close files
2427  jam();
2428  closeFiles(signal, ptr);
2429  return;
2430  }
2431  } else {
2432  jam();
2433  ndbrequire(findTable(ptr, tabPtr, ptr.p->slaveData.dropTrig.tableId));
2434  ptr.p->tables.next(tabPtr);
2435  }//if
2436  if (tabPtr.i != RNIL) {
2437  jam();
2438  sendDropTrig(signal, ptr, tabPtr);
2439  } else {
2443  //if backup error, we needn't insert footers
2444  if(ptr.p->checkError())
2445  {
2446  jam();
2447  closeFiles(signal, ptr);
2448  ptr.p->errorCode = 0;
2449  return;
2450  }
2451 
2452  {
2453  BackupFilePtr filePtr LINT_SET_PTR;
2454  ptr.p->files.getPtr(filePtr, ptr.p->logFilePtr);
2455  Uint32 * dst;
2456  LINT_INIT(dst);
2457  ndbrequire(filePtr.p->operation.dataBuffer.getWritePtr(&dst, 1));
2458  * dst = 0;
2459  filePtr.p->operation.dataBuffer.updateWritePtr(1);
2460  }
2461 
2462  {
2463  BackupFilePtr filePtr LINT_SET_PTR;
2464  ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
2465 
2466  const Uint32 gcpSz = sizeof(BackupFormat::CtlFile::GCPEntry) >> 2;
2467 
2468  Uint32 * dst;
2469  LINT_INIT(dst);
2470  ndbrequire(filePtr.p->operation.dataBuffer.getWritePtr(&dst, gcpSz));
2471 
2474 
2475  gcp->SectionType = htonl(BackupFormat::GCP_ENTRY);
2476  gcp->SectionLength = htonl(gcpSz);
2477  gcp->StartGCP = htonl(ptr.p->startGCP);
2478  gcp->StopGCP = htonl(ptr.p->stopGCP - 1);
2479  filePtr.p->operation.dataBuffer.updateWritePtr(gcpSz);
2480 
2481  {
2482  TablePtr tabPtr;
2483  if (ptr.p->tables.first(tabPtr))
2484  {
2485  jam();
2486  signal->theData[0] = BackupContinueB::BACKUP_FRAGMENT_INFO;
2487  signal->theData[1] = ptr.i;
2488  signal->theData[2] = tabPtr.i;
2489  signal->theData[3] = 0;
2490  sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
2491  }
2492  else
2493  {
2494  jam();
2495  closeFiles(signal, ptr);
2496  }
2497  }
2498  }
2499  }
2500 }
2501 
2502 void
2503 Backup::sendDropTrig(Signal* signal, BackupRecordPtr ptr, TablePtr tabPtr)
2504 {
2505  jam();
2506  DropTrigImplReq* req = (DropTrigImplReq*)signal->getDataPtrSend();
2507 
2508  ptr.p->slaveData.gsn = GSN_DROP_TRIG_IMPL_REQ;
2509  ptr.p->slaveData.trigSendCounter = 0;
2510  req->senderRef = reference(); // Sending to myself
2511  req->senderData = ptr.i;
2512  req->requestType = 0;
2513  req->tableId = tabPtr.p->tableId;
2514  req->tableVersion = 0;
2515  req->indexId = RNIL;
2516  req->indexVersion = 0;
2517  req->receiverRef = reference();
2518 
2519  // TUP needs some triggerInfo to find right list
2520  Uint32 ti = 0;
2521  if(ptr.p->flags & BackupReq::USE_UNDO_LOG)
2522  TriggerInfo::setTriggerType(ti, TriggerType::SUBSCRIPTION_BEFORE);
2523  else
2524  TriggerInfo::setTriggerType(ti, TriggerType::SUBSCRIPTION);
2525  TriggerInfo::setTriggerActionTime(ti, TriggerActionTime::TA_DETACHED);
2526  TriggerInfo::setMonitorReplicas(ti, true);
2527  TriggerInfo::setMonitorAllAttributes(ti, false);
2528 
2529  ptr.p->slaveData.dropTrig.tableId = tabPtr.p->tableId;
2530  req->tableId = tabPtr.p->tableId;
2531 
2532  for (int i = 0; i < 3; i++) {
2533  Uint32 id = tabPtr.p->triggerIds[i];
2534  req->triggerId = id;
2535 
2536  Uint32 ti2 = ti;
2537  TriggerInfo::setTriggerEvent(ti2, triggerEventValues[i]);
2538  req->triggerInfo = ti2;
2539 
2540  sendSignal(DBTUP_REF, GSN_DROP_TRIG_IMPL_REQ,
2541  signal, DropTrigImplReq::SignalLength, JBB);
2542  ptr.p->slaveData.trigSendCounter ++;
2543  }
2544 }
2545 
2546 void
2547 Backup::execDROP_TRIG_IMPL_REF(Signal* signal)
2548 {
2549  jamEntry();
2550 
2551  const DropTrigImplRef* ref = (const DropTrigImplRef*)signal->getDataPtr();
2552  const Uint32 ptrI = ref->senderData;
2553 
2554  BackupRecordPtr ptr LINT_SET_PTR;
2555  c_backupPool.getPtr(ptr, ptrI);
2556 
2557  if(ref->triggerId != ~(Uint32) 0)
2558  {
2559  ndbout << "ERROR DROPPING TRIGGER: " << ref->triggerId;
2560  ndbout << " Err: " << ref->errorCode << endl << endl;
2561  }
2562 
2563  dropTrigReply(signal, ptr);
2564 }
2565 
2566 void
2567 Backup::execDROP_TRIG_IMPL_CONF(Signal* signal)
2568 {
2569  jamEntry();
2570 
2571  const DropTrigImplConf* conf = (const DropTrigImplConf*)signal->getDataPtr();
2572  const Uint32 ptrI = conf->senderData;
2573 
2574  BackupRecordPtr ptr LINT_SET_PTR;
2575  c_backupPool.getPtr(ptr, ptrI);
2576 
2577  dropTrigReply(signal, ptr);
2578 }
2579 
2580 void
2581 Backup::dropTrigReply(Signal* signal, BackupRecordPtr ptr)
2582 {
2583  CRASH_INSERTION((10012));
2584 
2585  ndbrequire(ptr.p->slaveData.gsn == GSN_DROP_TRIG_IMPL_REQ);
2586  ndbrequire(ptr.p->slaveData.trigSendCounter.done() == false);
2587 
2588  // move from .masterData to .slaveData
2589  ptr.p->slaveData.trigSendCounter--;
2590  if(ptr.p->slaveData.trigSendCounter.done() == false){
2591  jam();
2592  return;
2593  }//if
2594 
2595  sendDropTrig(signal, ptr); // recursive next
2596 }
2597 
2598 /*****************************************************************************
2599  *
2600  * Master functionallity - Stop backup
2601  *
2602  *****************************************************************************/
2603 void
2604 Backup::execSTOP_BACKUP_REF(Signal* signal)
2605 {
2606  jamEntry();
2607 
2608  StopBackupRef* ref = (StopBackupRef*)signal->getDataPtr();
2609  const Uint32 ptrI = ref->backupPtr;
2610  //const Uint32 backupId = ref->backupId;
2611  const Uint32 nodeId = ref->nodeId;
2612 
2613  BackupRecordPtr ptr LINT_SET_PTR;
2614  c_backupPool.getPtr(ptr, ptrI);
2615 
2616  ptr.p->setErrorCode(ref->errorCode);
2617  stopBackupReply(signal, ptr, nodeId);
2618 }
2619 
2620 void
2621 Backup::sendStopBackup(Signal* signal, BackupRecordPtr ptr)
2622 {
2623  jam();
2624 
2625  StopBackupReq* stop = (StopBackupReq*)signal->getDataPtrSend();
2626  stop->backupPtr = ptr.i;
2627  stop->backupId = ptr.p->backupId;
2628  stop->startGCP = ptr.p->startGCP;
2629  stop->stopGCP = ptr.p->stopGCP;
2630 
2631  ptr.p->masterData.gsn = GSN_STOP_BACKUP_REQ;
2632  ptr.p->masterData.sendCounter = ptr.p->nodes;
2633  BlockNumber backupBlockNo = numberToBlock(BACKUP, instanceKey(ptr));
2634  NodeReceiverGroup rg(backupBlockNo, ptr.p->nodes);
2635  sendSignal(rg, GSN_STOP_BACKUP_REQ, signal,
2636  StopBackupReq::SignalLength, JBB);
2637 }
2638 
2639 void
2640 Backup::execSTOP_BACKUP_CONF(Signal* signal)
2641 {
2642  jamEntry();
2643 
2644  StopBackupConf* conf = (StopBackupConf*)signal->getDataPtr();
2645  const Uint32 ptrI = conf->backupPtr;
2646  //const Uint32 backupId = conf->backupId;
2647  const Uint32 nodeId = refToNode(signal->senderBlockRef());
2648 
2649  BackupRecordPtr ptr LINT_SET_PTR;
2650  c_backupPool.getPtr(ptr, ptrI);
2651 
2652  ptr.p->noOfLogBytes += conf->noOfLogBytes;
2653  ptr.p->noOfLogRecords += conf->noOfLogRecords;
2654 
2655  stopBackupReply(signal, ptr, nodeId);
2656 }
2657 
2658 void
2659 Backup::stopBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId)
2660 {
2661  CRASH_INSERTION((10013));
2662 
2663  if (!haveAllSignals(ptr, GSN_STOP_BACKUP_REQ, nodeId)) {
2664  jam();
2665  return;
2666  }
2667 
2668  sendAbortBackupOrd(signal, ptr, AbortBackupOrd::BackupComplete);
2669 
2670  if(!ptr.p->checkError() && ptr.p->masterData.errorCode == 0)
2671  {
2672  if (SEND_BACKUP_COMPLETED_FLAG(ptr.p->flags))
2673  {
2674  BackupCompleteRep * rep = (BackupCompleteRep*)signal->getDataPtrSend();
2675  rep->backupId = ptr.p->backupId;
2676  rep->senderData = ptr.p->clientData;
2677  rep->startGCP = ptr.p->startGCP;
2678  rep->stopGCP = ptr.p->stopGCP;
2679  rep->noOfBytesLow = (Uint32)(ptr.p->noOfBytes & 0xFFFFFFFF);
2680  rep->noOfRecordsLow = (Uint32)(ptr.p->noOfRecords & 0xFFFFFFFF);
2681  rep->noOfBytesHigh = (Uint32)(ptr.p->noOfBytes >> 32);
2682  rep->noOfRecordsHigh = (Uint32)(ptr.p->noOfRecords >> 32);
2683  rep->noOfLogBytes = Uint32(ptr.p->noOfLogBytes); // TODO 64-bit log-bytes
2684  rep->noOfLogRecords = Uint32(ptr.p->noOfLogRecords); // TODO ^^
2685  rep->nodes = ptr.p->nodes;
2686  sendSignal(ptr.p->clientRef, GSN_BACKUP_COMPLETE_REP, signal,
2687  BackupCompleteRep::SignalLength, JBB);
2688  }
2689 
2690  signal->theData[0] = NDB_LE_BackupCompleted;
2691  signal->theData[1] = ptr.p->clientRef;
2692  signal->theData[2] = ptr.p->backupId;
2693  signal->theData[3] = ptr.p->startGCP;
2694  signal->theData[4] = ptr.p->stopGCP;
2695  signal->theData[5] = (Uint32)(ptr.p->noOfBytes & 0xFFFFFFFF);
2696  signal->theData[6] = (Uint32)(ptr.p->noOfRecords & 0xFFFFFFFF);
2697  signal->theData[7] = (Uint32)(ptr.p->noOfLogBytes & 0xFFFFFFFF);
2698  signal->theData[8] = (Uint32)(ptr.p->noOfLogRecords & 0xFFFFFFFF);
2699  ptr.p->nodes.copyto(NdbNodeBitmask::Size, signal->theData+9);
2700  signal->theData[9+NdbNodeBitmask::Size] = (Uint32)(ptr.p->noOfBytes >> 32);
2701  signal->theData[10+NdbNodeBitmask::Size] = (Uint32)(ptr.p->noOfRecords >> 32);
2702  signal->theData[11+NdbNodeBitmask::Size] = (Uint32)(ptr.p->noOfLogBytes >> 32);
2703  signal->theData[12+NdbNodeBitmask::Size] = (Uint32)(ptr.p->noOfLogRecords >> 32);
2704  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 13+NdbNodeBitmask::Size, JBB);
2705  }
2706  else
2707  {
2708  masterAbort(signal, ptr);
2709  }
2710 }
2711 
2712 void
2713 Backup::initReportStatus(Signal *signal, BackupRecordPtr ptr)
2714 {
2715  Uint64 now = NdbTick_CurrentMillisecond() / 1000;
2716  ptr.p->m_next_report = now + m_backup_report_frequency;
2717 }
2718 
2719 void
2720 Backup::checkReportStatus(Signal *signal, BackupRecordPtr ptr)
2721 {
2722  if (m_backup_report_frequency == 0)
2723  return;
2724 
2725  Uint64 now = NdbTick_CurrentMillisecond() / 1000;
2726  if (now > ptr.p->m_next_report)
2727  {
2728  reportStatus(signal, ptr);
2729  ptr.p->m_next_report = now + m_backup_report_frequency;
2730  }
2731 }
2732 
2733 void
2734 Backup::reportStatus(Signal* signal, BackupRecordPtr ptr,
2735  BlockReference ref)
2736 {
2737  const int signal_length = 11;
2738 
2739  signal->theData[0] = NDB_LE_BackupStatus;
2740  for (int i= 1; i < signal_length; i++)
2741  signal->theData[i] = 0;
2742 
2743  if (ptr.i == RNIL ||
2744  (ptr.p->m_gsn == 0 &&
2745  ptr.p->masterData.gsn == 0))
2746  {
2747  sendSignal(ref, GSN_EVENT_REP, signal, signal_length, JBB);
2748  return;
2749  }
2750  signal->theData[1] = ptr.p->clientRef;
2751  signal->theData[2] = ptr.p->backupId;
2752 
2753  if (ptr.p->dataFilePtr == RNIL)
2754  {
2755  sendSignal(ref, GSN_EVENT_REP, signal, signal_length, JBB);
2756  return;
2757  }
2758 
2759  BackupFilePtr dataFilePtr LINT_SET_PTR;
2760  ptr.p->files.getPtr(dataFilePtr, ptr.p->dataFilePtr);
2761  signal->theData[3] = (Uint32)(dataFilePtr.p->operation.m_bytes_total & 0xFFFFFFFF);
2762  signal->theData[4] = (Uint32)(dataFilePtr.p->operation.m_bytes_total >> 32);
2763  signal->theData[5] = (Uint32)(dataFilePtr.p->operation.m_records_total & 0xFFFFFFFF);
2764  signal->theData[6] = (Uint32)(dataFilePtr.p->operation.m_records_total >> 32);
2765 
2766  if (ptr.p->logFilePtr == RNIL)
2767  {
2768  sendSignal(ref, GSN_EVENT_REP, signal, signal_length, JBB);
2769  return;
2770  }
2771 
2772  BackupFilePtr logFilePtr LINT_SET_PTR;
2773  ptr.p->files.getPtr(logFilePtr, ptr.p->logFilePtr);
2774  signal->theData[7] = (Uint32)(logFilePtr.p->operation.m_bytes_total & 0xFFFFFFFF);
2775  signal->theData[8] = (Uint32)(logFilePtr.p->operation.m_bytes_total >> 32);
2776  signal->theData[9] = (Uint32)(logFilePtr.p->operation.m_records_total & 0xFFFFFFFF);
2777  signal->theData[10]= (Uint32)(logFilePtr.p->operation.m_records_total >> 32);
2778 
2779  sendSignal(ref, GSN_EVENT_REP, signal, signal_length, JBB);
2780 }
2781 
2782 /*****************************************************************************
2783  *
2784  * Master functionallity - Abort backup
2785  *
2786  *****************************************************************************/
2787 void
2788 Backup::masterAbort(Signal* signal, BackupRecordPtr ptr)
2789 {
2790  jam();
2791 #ifdef DEBUG_ABORT
2792  ndbout_c("************ masterAbort");
2793 #endif
2794 
2795  ndbassert(ptr.p->masterRef == reference());
2796 
2797  if(ptr.p->masterData.errorCode != 0)
2798  {
2799  jam();
2800  return;
2801  }
2802 
2803  if (SEND_BACKUP_COMPLETED_FLAG(ptr.p->flags))
2804  {
2805  BackupAbortRep* rep = (BackupAbortRep*)signal->getDataPtrSend();
2806  rep->backupId = ptr.p->backupId;
2807  rep->senderData = ptr.p->clientData;
2808  rep->reason = ptr.p->errorCode;
2809  sendSignal(ptr.p->clientRef, GSN_BACKUP_ABORT_REP, signal,
2810  BackupAbortRep::SignalLength, JBB);
2811  }
2812  signal->theData[0] = NDB_LE_BackupAborted;
2813  signal->theData[1] = ptr.p->clientRef;
2814  signal->theData[2] = ptr.p->backupId;
2815  signal->theData[3] = ptr.p->errorCode;
2816  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
2817 
2818  ndbrequire(ptr.p->errorCode);
2819  ptr.p->masterData.errorCode = ptr.p->errorCode;
2820 
2821  AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
2822  ord->backupId = ptr.p->backupId;
2823  ord->backupPtr = ptr.i;
2824  ord->senderData= ptr.i;
2825  BlockNumber backupBlockNo = numberToBlock(BACKUP, instanceKey(ptr));
2826  NodeReceiverGroup rg(backupBlockNo, ptr.p->nodes);
2827 
2828  switch(ptr.p->masterData.gsn){
2829  case GSN_DEFINE_BACKUP_REQ:
2830  ord->requestType = AbortBackupOrd::BackupFailure;
2831  sendSignal(rg, GSN_ABORT_BACKUP_ORD, signal,
2832  AbortBackupOrd::SignalLength, JBB);
2833  return;
2834  case GSN_CREATE_TRIG_IMPL_REQ:
2835  case GSN_START_BACKUP_REQ:
2836  case GSN_ALTER_TRIG_REQ:
2837  case GSN_WAIT_GCP_REQ:
2838  case GSN_BACKUP_FRAGMENT_REQ:
2839  jam();
2840  ptr.p->stopGCP= ptr.p->startGCP + 1;
2841  sendStopBackup(signal, ptr); // dropping due to error
2842  return;
2843  case GSN_UTIL_SEQUENCE_REQ:
2844  case GSN_UTIL_LOCK_REQ:
2845  ndbrequire(false);
2846  return;
2847  case GSN_DROP_TRIG_IMPL_REQ:
2848  case GSN_STOP_BACKUP_REQ:
2849  return;
2850  }
2851 }
2852 
2853 void
2854 Backup::abort_scan(Signal * signal, BackupRecordPtr ptr)
2855 {
2856  AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
2857  ord->backupId = ptr.p->backupId;
2858  ord->backupPtr = ptr.i;
2859  ord->senderData= ptr.i;
2860  ord->requestType = AbortBackupOrd::AbortScan;
2861 
2862  TablePtr tabPtr;
2863  ptr.p->tables.first(tabPtr);
2864  for(; tabPtr.i != RNIL; ptr.p->tables.next(tabPtr)) {
2865  jam();
2866  FragmentPtr fragPtr;
2867  Array<Fragment> & frags = tabPtr.p->fragments;
2868  const Uint32 fragCount = frags.getSize();
2869 
2870  for(Uint32 i = 0; i<fragCount; i++) {
2871  jam();
2872  tabPtr.p->fragments.getPtr(fragPtr, i);
2873  const Uint32 nodeId = fragPtr.p->node;
2874  if(fragPtr.p->scanning != 0 && ptr.p->nodes.get(nodeId)) {
2875  jam();
2876 
2877  BlockReference ref = numberToRef(BACKUP, instanceKey(ptr), nodeId);
2878  sendSignal(ref, GSN_ABORT_BACKUP_ORD, signal,
2879  AbortBackupOrd::SignalLength, JBB);
2880 
2881  }
2882  }
2883  }
2884 }
2885 
2886 /*****************************************************************************
2887  *
2888  * Slave functionallity: Define Backup
2889  *
2890  *****************************************************************************/
2891 void
2892 Backup::defineBackupRef(Signal* signal, BackupRecordPtr ptr, Uint32 errCode)
2893 {
2894  jam();
2895  ptr.p->setErrorCode(errCode);
2896  if(ptr.p->is_lcp())
2897  {
2898  jam();
2899  if (ptr.p->ctlFilePtr == RNIL) {
2900  ptr.p->m_gsn = GSN_DEFINE_BACKUP_REF;
2901  ndbrequire(ptr.p->errorCode != 0);
2902  DefineBackupRef* ref = (DefineBackupRef*)signal->getDataPtrSend();
2903  ref->backupId = ptr.p->backupId;
2904  ref->backupPtr = ptr.i;
2905  ref->errorCode = ptr.p->errorCode;
2906  ref->nodeId = getOwnNodeId();
2907  sendSignal(ptr.p->masterRef, GSN_DEFINE_BACKUP_REF, signal,
2908  DefineBackupRef::SignalLength, JBB);
2909  return;
2910  }
2911 
2912  BackupFilePtr filePtr LINT_SET_PTR;
2913  ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
2914  if (filePtr.p->m_flags & BackupFile::BF_LCP_META)
2915  {
2916  jam();
2917  ndbrequire(! (filePtr.p->m_flags & BackupFile::BF_FILE_THREAD));
2918  filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_LCP_META;
2919  if (filePtr.p->m_flags & BackupFile::BF_OPEN)
2920  {
2921  closeFile(signal, ptr, filePtr);
2922  return;
2923  }
2924  }
2925 
2926  ndbrequire(filePtr.p->m_flags == 0);
2927 
2928  TablePtr tabPtr;
2929  FragmentPtr fragPtr;
2930 
2931  ndbrequire(ptr.p->tables.first(tabPtr));
2932  tabPtr.p->fragments.getPtr(fragPtr, 0);
2933 
2934  LcpPrepareRef* ref= (LcpPrepareRef*)signal->getDataPtrSend();
2935  ref->senderData = ptr.p->clientData;
2936  ref->senderRef = reference();
2937  ref->tableId = tabPtr.p->tableId;
2938  ref->fragmentId = fragPtr.p->fragmentId;
2939  ref->errorCode = errCode;
2940  sendSignal(ptr.p->masterRef, GSN_LCP_PREPARE_REF,
2941  signal, LcpPrepareRef::SignalLength, JBB);
2942  return;
2943  }
2944 
2945  ptr.p->m_gsn = GSN_DEFINE_BACKUP_REF;
2946  ndbrequire(ptr.p->errorCode != 0);
2947 
2948  DefineBackupRef* ref = (DefineBackupRef*)signal->getDataPtrSend();
2949  ref->backupId = ptr.p->backupId;
2950  ref->backupPtr = ptr.i;
2951  ref->errorCode = ptr.p->errorCode;
2952  ref->nodeId = getOwnNodeId();
2953  sendSignal(ptr.p->masterRef, GSN_DEFINE_BACKUP_REF, signal,
2954  DefineBackupRef::SignalLength, JBB);
2955 }
2956 
2957 void
2959 {
2960  jamEntry();
2961 
2962  DefineBackupReq* req = (DefineBackupReq*)signal->getDataPtr();
2963 
2964  BackupRecordPtr ptr LINT_SET_PTR;
2965  const Uint32 ptrI = req->backupPtr;
2966  const Uint32 backupId = req->backupId;
2967  const BlockReference senderRef = req->senderRef;
2968 
2969  if(senderRef == reference()){
2973  jam();
2974  c_backupPool.getPtr(ptr, ptrI);
2975  } else { // from other node
2976  jam();
2977 #ifdef DEBUG_ABORT
2978  dumpUsedResources();
2979 #endif
2980  if(!c_backups.seizeId(ptr, ptrI)) {
2981  jam();
2982  ndbrequire(false); // If master has succeeded slave should succed
2983  }//if
2984  }//if
2985 
2986  CRASH_INSERTION((10014));
2987 
2988  ptr.p->m_gsn = GSN_DEFINE_BACKUP_REQ;
2989  ptr.p->slaveState.forceState(INITIAL);
2990  ptr.p->slaveState.setState(DEFINING);
2991  ptr.p->slaveData.dropTrig.tableId = RNIL;
2992  ptr.p->errorCode = 0;
2993  ptr.p->clientRef = req->clientRef;
2994  ptr.p->clientData = req->clientData;
2995  if(senderRef == reference())
2996  ptr.p->flags = req->flags;
2997  else
2998  ptr.p->flags = req->flags & ~((Uint32)BackupReq::WAITCOMPLETED); /* remove waitCompleted flags
2999  * as non master should never
3000  * reply
3001  */
3002  ptr.p->masterRef = senderRef;
3003  ptr.p->nodes = req->nodes;
3004  ptr.p->backupId = backupId;
3005  ptr.p->backupKey[0] = req->backupKey[0];
3006  ptr.p->backupKey[1] = req->backupKey[1];
3007  ptr.p->backupDataLen = req->backupDataLen;
3008  ptr.p->masterData.errorCode = 0;
3009  ptr.p->noOfBytes = 0;
3010  ptr.p->noOfRecords = 0;
3011  ptr.p->noOfLogBytes = 0;
3012  ptr.p->noOfLogRecords = 0;
3013  ptr.p->currGCP = 0;
3014  ptr.p->startGCP = 0;
3015  ptr.p->stopGCP = 0;
3016 
3020  BackupFilePtr files[3];
3021  Uint32 noOfPages[] = {
3022  NO_OF_PAGES_META_FILE,
3023  2, // 32k
3024  0 // 3M
3025  };
3026  const Uint32 maxInsert[] = {
3027  MAX_WORDS_META_FILE,
3028  4096, // 16k
3029  16 * (MAX_TUPLE_SIZE_IN_WORDS + 128 /* safety */), // Max 16 tuples
3030  };
3031  Uint32 minWrite[] = {
3032  8192,
3033  8192,
3034  32768
3035  };
3036  Uint32 maxWrite[] = {
3037  8192,
3038  8192,
3039  32768
3040  };
3041 
3042  minWrite[1] = c_defaults.m_minWriteSize;
3043  maxWrite[1] = c_defaults.m_maxWriteSize;
3044  noOfPages[1] = (c_defaults.m_logBufferSize + sizeof(Page32) - 1) /
3045  sizeof(Page32);
3046  minWrite[2] = c_defaults.m_minWriteSize;
3047  maxWrite[2] = c_defaults.m_maxWriteSize;
3048  noOfPages[2] = (c_defaults.m_dataBufferSize + sizeof(Page32) - 1) /
3049  sizeof(Page32);
3050 
3051  if (ptr.p->is_lcp())
3052  {
3053  noOfPages[2] = (c_defaults.m_lcp_buffer_size + sizeof(Page32) - 1) /
3054  sizeof(Page32);
3055  }
3056 
3057  ptr.p->ctlFilePtr = ptr.p->logFilePtr = ptr.p->dataFilePtr = RNIL;
3058 
3059  for(Uint32 i = 0; i<3; i++) {
3060  jam();
3061  if(ptr.p->is_lcp() && i != 2)
3062  {
3063  files[i].i = RNIL;
3064  continue;
3065  }
3066  if(!ptr.p->files.seize(files[i])) {
3067  jam();
3068  defineBackupRef(signal, ptr,
3069  DefineBackupRef::FailedToAllocateFileRecord);
3070  return;
3071  }//if
3072 
3073  files[i].p->tableId = RNIL;
3074  files[i].p->backupPtr = ptr.i;
3075  files[i].p->filePointer = RNIL;
3076  files[i].p->m_flags = 0;
3077  files[i].p->errorCode = 0;
3078 
3079  if(ERROR_INSERTED(10035) || files[i].p->pages.seize(noOfPages[i]) == false)
3080  {
3081  jam();
3082  DEBUG_OUT("Failed to seize " << noOfPages[i] << " pages");
3083  defineBackupRef(signal, ptr, DefineBackupRef::FailedToAllocateBuffers);
3084  return;
3085  }//if
3086  Page32Ptr pagePtr;
3087  files[i].p->pages.getPtr(pagePtr, 0);
3088 
3089  const char * msg = files[i].p->
3090  operation.dataBuffer.setup((Uint32*)pagePtr.p,
3091  noOfPages[i] * (sizeof(Page32) >> 2),
3092  128,
3093  minWrite[i] >> 2,
3094  maxWrite[i] >> 2,
3095  maxInsert[i]);
3096  if(msg != 0) {
3097  jam();
3098  defineBackupRef(signal, ptr, DefineBackupRef::FailedToSetupFsBuffers);
3099  return;
3100  }//if
3101 
3102  switch(i){
3103  case 0:
3104  files[i].p->fileType = BackupFormat::CTL_FILE;
3105  ptr.p->ctlFilePtr = files[i].i;
3106  break;
3107  case 1:
3108  if(ptr.p->flags & BackupReq::USE_UNDO_LOG)
3109  files[i].p->fileType = BackupFormat::UNDO_FILE;
3110  else
3111  files[i].p->fileType = BackupFormat::LOG_FILE;
3112  ptr.p->logFilePtr = files[i].i;
3113  break;
3114  case 2:
3115  files[i].p->fileType = BackupFormat::DATA_FILE;
3116  ptr.p->dataFilePtr = files[i].i;
3117  }
3118  files[i].p->operation.m_bytes_total = 0;
3119  files[i].p->operation.m_records_total = 0;
3120  }//for
3121 
3122  initReportStatus(signal, ptr);
3123 
3124  if (!verifyNodesAlive(ptr, ptr.p->nodes)) {
3125  jam();
3126  defineBackupRef(signal, ptr, DefineBackupRef::Undefined);
3127  return;
3128  }//if
3129  if (ERROR_INSERTED(10027)) {
3130  jam();
3131  defineBackupRef(signal, ptr, 327);
3132  return;
3133  }//if
3134 
3135  if(ptr.p->backupDataLen == 0) {
3136  jam();
3137  backupAllData(signal, ptr);
3138  return;
3139  }//if
3140 
3141  if(ptr.p->is_lcp())
3142  {
3143  jam();
3144  getFragmentInfoDone(signal, ptr);
3145  return;
3146  }
3147 
3151  ndbrequire(0);
3152 }
3153 
3154 void
3156 {
3160  ListTablesReq * req = (ListTablesReq*)signal->getDataPtrSend();
3161  req->init();
3162  req->senderRef = reference();
3163  req->senderData = ptr.i;
3164  req->setTableId(0);
3165  req->setTableType(0);
3166  sendSignal(DBDICT_REF, GSN_LIST_TABLES_REQ, signal,
3167  ListTablesReq::SignalLength, JBB);
3168 }
3169 
3170 void
3172 {
3173  jamEntry();
3174  Uint32 fragInfo = signal->header.m_fragmentInfo;
3175  ListTablesConf* conf = (ListTablesConf*)signal->getDataPtr();
3176  Uint32 noOfTables = conf->noOfTables;
3177 
3178  BackupRecordPtr ptr LINT_SET_PTR;
3179  c_backupPool.getPtr(ptr, conf->senderData);
3180 
3181  SectionHandle handle (this, signal);
3182  signal->header.m_fragmentInfo = 0;
3183  if (noOfTables > 0)
3184  {
3185  ListTablesData ltd;
3186  const Uint32 listTablesDataSizeInWords = (sizeof(ListTablesData) + 3) / 4;
3187  SegmentedSectionPtr tableDataPtr;
3188  handle.getSection(tableDataPtr, ListTablesConf::TABLE_DATA);
3190  tableDataReader(tableDataPtr, getSectionSegmentPool());
3191 
3192  tableDataReader.reset();
3193  for(unsigned int i = 0; i<noOfTables; i++) {
3194  jam();
3195  tableDataReader.getWords((Uint32 *)&ltd, listTablesDataSizeInWords);
3196  Uint32 tableId = ltd.getTableId();
3197  Uint32 tableType = ltd.getTableType();
3198  Uint32 state= ltd.getTableState();
3199 
3200  if (! (DictTabInfo::isTable(tableType) ||
3201  DictTabInfo::isIndex(tableType) ||
3202  DictTabInfo::isFilegroup(tableType) ||
3203  DictTabInfo::isFile(tableType)
3204  || DictTabInfo::isHashMap(tableType)
3205  ))
3206  {
3207  jam();
3208  continue;
3209  }
3210 
3211  if (state != DictTabInfo::StateOnline)
3212  {
3213  jam();
3214  continue;
3215  }
3216 
3217  TablePtr tabPtr;
3218  ptr.p->tables.seize(tabPtr);
3219  if(tabPtr.i == RNIL) {
3220  jam();
3221  defineBackupRef(signal, ptr, DefineBackupRef::FailedToAllocateTables);
3222  releaseSections(handle);
3223  return;
3224  }//if
3225  tabPtr.p->tableId = tableId;
3226  tabPtr.p->tableType = tableType;
3227  }//for
3228  }
3229 
3230  releaseSections(handle);
3231 
3232  /*
3233  If first or not last signal
3234  then keep accumulating table data
3235  */
3236  if ((fragInfo == 1) || (fragInfo == 2))
3237  {
3238  return;
3239  }
3240  openFiles(signal, ptr);
3241 }
3242 
3243 void
3245 {
3246  jam();
3247 
3248  BackupFilePtr filePtr LINT_SET_PTR;
3249 
3250  FsOpenReq * req = (FsOpenReq *)signal->getDataPtrSend();
3251  req->userReference = reference();
3252  req->fileFlags =
3253  FsOpenReq::OM_WRITEONLY |
3254  FsOpenReq::OM_CREATE_IF_NONE |
3255  FsOpenReq::OM_APPEND |
3256  FsOpenReq::OM_AUTOSYNC;
3257 
3258  if (c_defaults.m_compressed_backup)
3259  req->fileFlags |= FsOpenReq::OM_GZ;
3260 
3261  FsOpenReq::v2_setCount(req->fileNumber, 0xFFFFFFFF);
3262  req->auto_sync_size = c_defaults.m_disk_synch_size;
3266  c_backupFilePool.getPtr(filePtr, ptr.p->ctlFilePtr);
3267  filePtr.p->m_flags |= BackupFile::BF_OPENING;
3268 
3269  req->userPointer = filePtr.i;
3270  FsOpenReq::setVersion(req->fileNumber, 2);
3271  FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_CTL);
3272  FsOpenReq::v2_setSequence(req->fileNumber, ptr.p->backupId);
3273  FsOpenReq::v2_setNodeId(req->fileNumber, getOwnNodeId());
3274  sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
3275 
3279  c_backupFilePool.getPtr(filePtr, ptr.p->logFilePtr);
3280  filePtr.p->m_flags |= BackupFile::BF_OPENING;
3281 
3282  //write uncompressed log file when enable undo log,since log file is read from back to front.
3283  if(ptr.p->flags & BackupReq::USE_UNDO_LOG)
3284  req->fileFlags &= ~FsOpenReq::OM_GZ;
3285 
3286  req->userPointer = filePtr.i;
3287  FsOpenReq::setVersion(req->fileNumber, 2);
3288  FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_LOG);
3289  FsOpenReq::v2_setSequence(req->fileNumber, ptr.p->backupId);
3290  FsOpenReq::v2_setNodeId(req->fileNumber, getOwnNodeId());
3291  sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
3292 
3296  c_backupFilePool.getPtr(filePtr, ptr.p->dataFilePtr);
3297  filePtr.p->m_flags |= BackupFile::BF_OPENING;
3298 
3299  if (c_defaults.m_o_direct)
3300  req->fileFlags |= FsOpenReq::OM_DIRECT;
3301  if (c_defaults.m_compressed_backup)
3302  req->fileFlags |= FsOpenReq::OM_GZ;
3303  req->userPointer = filePtr.i;
3304  FsOpenReq::setVersion(req->fileNumber, 2);
3305  FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_DATA);
3306  FsOpenReq::v2_setSequence(req->fileNumber, ptr.p->backupId);
3307  FsOpenReq::v2_setNodeId(req->fileNumber, getOwnNodeId());
3308  FsOpenReq::v2_setCount(req->fileNumber, 0);
3309  sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
3310 }
3311 
3312 void
3314 {
3315  jamEntry();
3316 
3317  FsRef * ref = (FsRef *)signal->getDataPtr();
3318 
3319  const Uint32 userPtr = ref->userPointer;
3320 
3321  BackupFilePtr filePtr LINT_SET_PTR;
3322  c_backupFilePool.getPtr(filePtr, userPtr);
3323 
3324  BackupRecordPtr ptr LINT_SET_PTR;
3325  c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
3326  ptr.p->setErrorCode(ref->errorCode);
3327  openFilesReply(signal, ptr, filePtr);
3328 }
3329 
3330 void
3331 Backup::execFSOPENCONF(Signal* signal)
3332 {
3333  jamEntry();
3334 
3335  FsConf * conf = (FsConf *)signal->getDataPtr();
3336 
3337  const Uint32 userPtr = conf->userPointer;
3338  const Uint32 filePointer = conf->filePointer;
3339 
3340  BackupFilePtr filePtr LINT_SET_PTR;
3341  c_backupFilePool.getPtr(filePtr, userPtr);
3342  filePtr.p->filePointer = filePointer;
3343 
3344  BackupRecordPtr ptr LINT_SET_PTR;
3345  c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
3346 
3347  ndbrequire(! (filePtr.p->m_flags & BackupFile::BF_OPEN));
3348  filePtr.p->m_flags |= BackupFile::BF_OPEN;
3349  openFilesReply(signal, ptr, filePtr);
3350 }
3351 
3352 void
3354  BackupRecordPtr ptr, BackupFilePtr filePtr)
3355 {
3356  jam();
3357 
3361  ndbrequire(filePtr.p->m_flags & BackupFile::BF_OPENING);
3362  filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_OPENING;
3363  filePtr.p->m_flags |= BackupFile::BF_OPEN;
3367  for(ptr.p->files.first(filePtr); filePtr.i!=RNIL;ptr.p->files.next(filePtr))
3368  {
3369  jam();
3370  if(filePtr.p->m_flags & BackupFile::BF_OPENING) {
3371  jam();
3372  return;
3373  }//if
3374  }//for
3375 
3376  if (ERROR_INSERTED(10037)) {
3377  jam();
3382  ptr.p->errorCode = DefineBackupRef::FailedInsertFileHeader;
3383  defineBackupRef(signal, ptr);
3384  return;
3385  }
3389  if(ptr.p->checkError())
3390  {
3391  jam();
3392  if(ptr.p->errorCode == FsRef::fsErrFileExists)
3393  {
3394  jam();
3395  ptr.p->errorCode = DefineBackupRef::FailedForBackupFilesAleadyExist;
3396  }
3397  defineBackupRef(signal, ptr);
3398  return;
3399  }//if
3400 
3401  if(!ptr.p->is_lcp())
3402  {
3406  ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
3407  if(!insertFileHeader(BackupFormat::CTL_FILE, ptr.p, filePtr.p)) {
3408  jam();
3409  defineBackupRef(signal, ptr, DefineBackupRef::FailedInsertFileHeader);
3410  return;
3411  }//if
3412 
3413  BackupFormat::FileType logfiletype;
3414  if(ptr.p->flags & BackupReq::USE_UNDO_LOG)
3415  logfiletype = BackupFormat::UNDO_FILE;
3416  else
3417  logfiletype = BackupFormat::LOG_FILE;
3418 
3419  ptr.p->files.getPtr(filePtr, ptr.p->logFilePtr);
3420  if(!insertFileHeader(logfiletype, ptr.p, filePtr.p)) {
3421  jam();
3422  defineBackupRef(signal, ptr, DefineBackupRef::FailedInsertFileHeader);
3423  return;
3424  }//if
3425 
3426  ptr.p->files.getPtr(filePtr, ptr.p->dataFilePtr);
3427  if(!insertFileHeader(BackupFormat::DATA_FILE, ptr.p, filePtr.p)) {
3428  jam();
3429  defineBackupRef(signal, ptr, DefineBackupRef::FailedInsertFileHeader);
3430  return;
3431  }//if
3432  }
3433  else
3434  {
3435  ptr.p->files.getPtr(filePtr, ptr.p->dataFilePtr);
3436  if(!insertFileHeader(BackupFormat::LCP_FILE, ptr.p, filePtr.p)) {
3437  jam();
3438  defineBackupRef(signal, ptr, DefineBackupRef::FailedInsertFileHeader);
3439  return;
3440  }//if
3441 
3442  ptr.p->ctlFilePtr = ptr.p->dataFilePtr;
3443  }
3444 
3448  if (!ptr.p->is_lcp())
3449  {
3450  jam();
3451  ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
3452  filePtr.p->m_flags |= BackupFile::BF_FILE_THREAD;
3453 
3454  signal->theData[0] = BackupContinueB::START_FILE_THREAD;
3455  signal->theData[1] = filePtr.i;
3456  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
3457  }
3458  else
3459  {
3460  jam();
3461  filePtr.p->m_flags |= BackupFile::BF_LCP_META;
3462  }
3463 
3467  FsBuffer & buf = filePtr.p->operation.dataBuffer;
3468 
3469  const Uint32 sz =
3470  (sizeof(BackupFormat::CtlFile::TableList) >> 2) +
3471  ptr.p->tables.count() - 1;
3472 
3473  Uint32 * dst;
3474  ndbrequire(sz < buf.getMaxWrite());
3475  if(!buf.getWritePtr(&dst, sz)) {
3476  jam();
3477  defineBackupRef(signal, ptr, DefineBackupRef::FailedInsertTableList);
3478  return;
3479  }//if
3480 
3483  tl->SectionType = htonl(BackupFormat::TABLE_LIST);
3484  tl->SectionLength = htonl(sz);
3485 
3486  TablePtr tabPtr;
3487  Uint32 count = 0;
3488  for(ptr.p->tables.first(tabPtr);
3489  tabPtr.i != RNIL;
3490  ptr.p->tables.next(tabPtr)){
3491  jam();
3492  tl->TableIds[count] = htonl(tabPtr.p->tableId);
3493  count++;
3494  }//for
3495 
3496  buf.updateWritePtr(sz);
3497 
3501  ndbrequire(ptr.p->tables.first(tabPtr));
3502 
3503  signal->theData[0] = BackupContinueB::BUFFER_FULL_META;
3504  signal->theData[1] = ptr.i;
3505  signal->theData[2] = tabPtr.i;
3506  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 3);
3507  return;
3508 }
3509 
3510 bool
3511 Backup::insertFileHeader(BackupFormat::FileType ft,
3512  BackupRecord * ptrP,
3513  BackupFile * filePtrP){
3514  FsBuffer & buf = filePtrP->operation.dataBuffer;
3515 
3516  const Uint32 sz = sizeof(BackupFormat::FileHeader) >> 2;
3517 
3518  Uint32 * dst;
3519  ndbrequire(sz < buf.getMaxWrite());
3520  if(!buf.getWritePtr(&dst, sz)) {
3521  jam();
3522  return false;
3523  }//if
3524 
3526  ndbrequire(sizeof(header->Magic) == sizeof(BACKUP_MAGIC));
3527  memcpy(header->Magic, BACKUP_MAGIC, sizeof(BACKUP_MAGIC));
3528  header->BackupVersion = htonl(NDB_BACKUP_VERSION);
3529  header->SectionType = htonl(BackupFormat::FILE_HEADER);
3530  header->SectionLength = htonl(sz - 3);
3531  header->FileType = htonl(ft);
3532  header->BackupId = htonl(ptrP->backupId);
3533  header->BackupKey_0 = htonl(ptrP->backupKey[0]);
3534  header->BackupKey_1 = htonl(ptrP->backupKey[1]);
3535  header->ByteOrder = 0x12345678;
3536  header->NdbVersion = htonl(NDB_VERSION_D);
3537  header->MySQLVersion = htonl(NDB_MYSQL_VERSION_D);
3538 
3539  buf.updateWritePtr(sz);
3540  return true;
3541 }
3542 
3543 void
3544 Backup::execGET_TABINFOREF(Signal* signal)
3545 {
3546  GetTabInfoRef * ref = (GetTabInfoRef*)signal->getDataPtr();
3547 
3548  const Uint32 senderData = ref->senderData;
3549  BackupRecordPtr ptr LINT_SET_PTR;
3550  c_backupPool.getPtr(ptr, senderData);
3551 
3552  defineBackupRef(signal, ptr, ref->errorCode);
3553 }
3554 
3555 void
3556 Backup::execGET_TABINFO_CONF(Signal* signal)
3557 {
3558  jamEntry();
3559 
3560  if(!assembleFragments(signal)) {
3561  jam();
3562  return;
3563  }//if
3564 
3565  GetTabInfoConf * const conf = (GetTabInfoConf*)signal->getDataPtr();
3566  //const Uint32 senderRef = info->senderRef;
3567  const Uint32 len = conf->totalLen;
3568  const Uint32 senderData = conf->senderData;
3569  const Uint32 tableType = conf->tableType;
3570  const Uint32 tableId = conf->tableId;
3571 
3572  BackupRecordPtr ptr LINT_SET_PTR;
3573  c_backupPool.getPtr(ptr, senderData);
3574 
3575  SectionHandle handle(this, signal);
3576  SegmentedSectionPtr dictTabInfoPtr;
3577  handle.getSection(dictTabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
3578  ndbrequire(dictTabInfoPtr.sz == len);
3579 
3580  TablePtr tabPtr ;
3581  ndbrequire(findTable(ptr, tabPtr, tableId));
3582 
3583  BackupFilePtr filePtr LINT_SET_PTR;
3584  ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
3585  FsBuffer & buf = filePtr.p->operation.dataBuffer;
3586  Uint32* dst = 0;
3587  { // Write into ctl file
3588  Uint32 dstLen = len + 3;
3589  if(!buf.getWritePtr(&dst, dstLen)) {
3590  jam();
3591  ndbrequire(false);
3592  ptr.p->setErrorCode(DefineBackupRef::FailedAllocateTableMem);
3593  releaseSections(handle);
3594  defineBackupRef(signal, ptr);
3595  return;
3596  }//if
3597  if(dst != 0) {
3598  jam();
3599 
3602  desc->SectionType = htonl(BackupFormat::TABLE_DESCRIPTION);
3603  desc->SectionLength = htonl(len + 3);
3604  desc->TableType = htonl(tableType);
3605  dst += 3;
3606 
3607  copy(dst, dictTabInfoPtr);
3608  buf.updateWritePtr(dstLen);
3609  }//if
3610  }
3611 
3612  releaseSections(handle);
3613 
3614  if(ptr.p->checkError()) {
3615  jam();
3616  defineBackupRef(signal, ptr);
3617  return;
3618  }//if
3619 
3620  if (!DictTabInfo::isTable(tabPtr.p->tableType))
3621  {
3622  jam();
3623 
3624  TablePtr tmp = tabPtr;
3625  ptr.p->tables.next(tabPtr);
3626  ptr.p->tables.release(tmp);
3627  afterGetTabinfoLockTab(signal, ptr, tabPtr);
3628  return;
3629  }
3630 
3631  if (!parseTableDescription(signal, ptr, tabPtr, dst, len))
3632  {
3633  jam();
3634  defineBackupRef(signal, ptr);
3635  return;
3636  }
3637 
3638  if(!ptr.p->is_lcp())
3639  {
3640  jam();
3641  BackupLockTab *req = (BackupLockTab *)signal->getDataPtrSend();
3642  req->m_senderRef = reference();
3643  req->m_tableId = tabPtr.p->tableId;
3644  req->m_lock_unlock = BackupLockTab::LOCK_TABLE;
3645  req->m_backup_state = BackupLockTab::GET_TABINFO_CONF;
3646  req->m_backupRecordPtr_I = ptr.i;
3647  req->m_tablePtr_I = tabPtr.i;
3648  sendSignal(DBDICT_REF, GSN_BACKUP_LOCK_TAB_REQ, signal,
3649  BackupLockTab::SignalLength, JBB);
3650  if (ERROR_INSERTED(10038))
3651  {
3652  /* Test */
3653  AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
3654  ord->backupId = ptr.p->backupId;
3655  ord->backupPtr = ptr.i;
3656  ord->requestType = AbortBackupOrd::ClientAbort;
3657  ord->senderData= ptr.p->clientData;
3658  sendSignal(ptr.p->masterRef, GSN_ABORT_BACKUP_ORD, signal,
3659  AbortBackupOrd::SignalLength, JBB);
3660  }
3661  return;
3662  }
3663 
3664  ptr.p->tables.next(tabPtr);
3665  afterGetTabinfoLockTab(signal, ptr, tabPtr);
3666 }
3667 
3668 void
3670  BackupRecordPtr ptr, TablePtr tabPtr)
3671 {
3672  if(tabPtr.i == RNIL)
3673  {
3677  jam();
3678 
3679  if(ptr.p->is_lcp())
3680  {
3681  jam();
3682  lcp_open_file_done(signal, ptr);
3683  return;
3684  }
3685 
3686  ndbrequire(ptr.p->tables.first(tabPtr));
3687  DihScanTabReq * req = (DihScanTabReq*)signal->getDataPtrSend();
3688  req->senderRef = reference();
3689  req->senderData = ptr.i;
3690  req->tableId = tabPtr.p->tableId;
3691  req->schemaTransId = 0;
3692  sendSignal(DBDIH_REF, GSN_DIH_SCAN_TAB_REQ, signal,
3693  DihScanTabReq::SignalLength, JBB);
3694  return;
3695  }//if
3696 
3700  signal->theData[0] = BackupContinueB::BUFFER_FULL_META;
3701  signal->theData[1] = ptr.i;
3702  signal->theData[2] = tabPtr.i;
3703  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 3);
3704  return;
3705 }
3706 
3707 bool
3709  BackupRecordPtr ptr,
3710  TablePtr tabPtr,
3711  const Uint32 * tabdescptr,
3712  Uint32 len)
3713 {
3714  SimplePropertiesLinearReader it(tabdescptr, len);
3715 
3716  it.first();
3717 
3718  DictTabInfo::Table tmpTab; tmpTab.init();
3720  stat = SimpleProperties::unpack(it, &tmpTab,
3721  DictTabInfo::TableMapping,
3722  DictTabInfo::TableMappingSize,
3723  true, true);
3724  ndbrequire(stat == SimpleProperties::Break);
3725 
3726  bool lcp = ptr.p->is_lcp();
3727 
3728  ndbrequire(tabPtr.p->tableId == tmpTab.TableId);
3729  ndbrequire(lcp || (tabPtr.p->tableType == tmpTab.TableType));
3730 
3738  tabPtr.p->noOfRecords = 0;
3739  tabPtr.p->schemaVersion = tmpTab.TableVersion;
3740  tabPtr.p->triggerIds[0] = ILLEGAL_TRIGGER_ID;
3741  tabPtr.p->triggerIds[1] = ILLEGAL_TRIGGER_ID;
3742  tabPtr.p->triggerIds[2] = ILLEGAL_TRIGGER_ID;
3743  tabPtr.p->triggerAllocated[0] = false;
3744  tabPtr.p->triggerAllocated[1] = false;
3745  tabPtr.p->triggerAllocated[2] = false;
3746 
3747  tabPtr.p->noOfAttributes = tmpTab.NoOfAttributes;
3748  tabPtr.p->maxRecordSize = 1; // LEN word
3749  bzero(tabPtr.p->attrInfo, sizeof(tabPtr.p->attrInfo));
3750 
3751  Uint32 *list = tabPtr.p->attrInfo + 1;
3752 
3753  if (lcp)
3754  {
3755  jam();
3756  AttributeHeader::init(tabPtr.p->attrInfo, AttributeHeader::READ_LCP, 0);
3757  }
3758  else
3759  {
3760  jam();
3761  AttributeHeader::init(tabPtr.p->attrInfo, AttributeHeader::READ_ALL,
3762  tmpTab.NoOfAttributes);
3763  }
3764 
3765  Uint32 varsize = 0;
3766  Uint32 disk = 0;
3767  Uint32 null = 0;
3768  for(Uint32 i = 0; i<tmpTab.NoOfAttributes; i++) {
3769  jam();
3770  DictTabInfo::Attribute tmp; tmp.init();
3771  stat = SimpleProperties::unpack(it, &tmp,
3772  DictTabInfo::AttributeMapping,
3773  DictTabInfo::AttributeMappingSize,
3774  true, true);
3775 
3776  ndbrequire(stat == SimpleProperties::Break);
3777  it.next(); // Move Past EndOfAttribute
3778 
3779  if(lcp && tmp.AttributeStorageType == NDB_STORAGETYPE_DISK)
3780  {
3781  disk++;
3782  continue;
3783  }
3784 
3785  if (tmp.AttributeArrayType != NDB_ARRAYTYPE_FIXED)
3786  varsize++;
3787 
3788  if (tmp.AttributeNullableFlag)
3789  null++;
3790 
3791  if (tmp.AttributeSize == 0)
3792  {
3793  tabPtr.p->maxRecordSize += (tmp.AttributeArraySize + 31) >> 5;
3794  }
3795  else
3796  {
3797  const Uint32 arr = tmp.AttributeArraySize;
3798  const Uint32 sz = 1 << tmp.AttributeSize;
3799  const Uint32 sz32 = (sz * arr + 31) >> 5;
3800 
3801  tabPtr.p->maxRecordSize += sz32;
3802  }
3803  }
3804 
3805  tabPtr.p->attrInfoLen = Uint32(list - tabPtr.p->attrInfo);
3806 
3807  if (lcp)
3808  {
3809  Dbtup* tup = (Dbtup*)globalData.getBlock(DBTUP, instance());
3810  tabPtr.p->maxRecordSize = 1 + tup->get_max_lcp_record_size(tmpTab.TableId);
3811  }
3812  else
3813  {
3814  // mask
3815  tabPtr.p->maxRecordSize += 1 + ((tmpTab.NoOfAttributes + null + 31) >> 5);
3816  tabPtr.p->maxRecordSize += (2 * varsize + 3) / 4;
3817  }
3818 
3819  return true;
3820 }
3821 
3822 void
3824 {
3825  jamEntry();
3826  DihScanTabConf * conf = (DihScanTabConf*)signal->getDataPtr();
3827  const Uint32 fragCount = conf->fragmentCount;
3828  const Uint32 tableId = conf->tableId;
3829  const Uint32 senderData = conf->senderData;
3830  const Uint32 scanCookie = conf->scanCookie;
3831  ndbrequire(conf->reorgFlag == 0); // no backup during table reorg
3832 
3833  BackupRecordPtr ptr LINT_SET_PTR;
3834  c_backupPool.getPtr(ptr, senderData);
3835 
3836  TablePtr tabPtr;
3837  ndbrequire(findTable(ptr, tabPtr, tableId));
3838 
3839  tabPtr.p->m_scan_cookie = scanCookie;
3840  ndbrequire(tabPtr.p->fragments.seize(fragCount) != false);
3841  for(Uint32 i = 0; i<fragCount; i++) {
3842  jam();
3843  FragmentPtr fragPtr;
3844  tabPtr.p->fragments.getPtr(fragPtr, i);
3845  fragPtr.p->scanned = 0;
3846  fragPtr.p->scanning = 0;
3847  fragPtr.p->tableId = tableId;
3848  fragPtr.p->fragmentId = i;
3849  fragPtr.p->lqhInstanceKey = 0;
3850  fragPtr.p->node = 0;
3851  }//for
3852 
3856  if(ptr.p->tables.next(tabPtr)) {
3857  jam();
3858  DihScanTabReq * req = (DihScanTabReq*)signal->getDataPtrSend();
3859  req->senderRef = reference();
3860  req->senderData = ptr.i;
3861  req->tableId = tabPtr.p->tableId;
3862  req->schemaTransId = 0;
3863  sendSignal(DBDIH_REF, GSN_DIH_SCAN_TAB_REQ, signal,
3864  DihScanTabReq::SignalLength, JBB);
3865  return;
3866  }//if
3867 
3868  ptr.p->tables.first(tabPtr);
3869  getFragmentInfo(signal, ptr, tabPtr, 0);
3870 }
3871 
3872 void
3873 Backup::getFragmentInfo(Signal* signal,
3874  BackupRecordPtr ptr, TablePtr tabPtr, Uint32 fragNo)
3875 {
3876  jam();
3877 
3878  for(; tabPtr.i != RNIL; ptr.p->tables.next(tabPtr)) {
3879  jam();
3880  const Uint32 fragCount = tabPtr.p->fragments.getSize();
3881  for(; fragNo < fragCount; fragNo ++) {
3882  jam();
3883  FragmentPtr fragPtr;
3884  tabPtr.p->fragments.getPtr(fragPtr, fragNo);
3885 
3886  if(fragPtr.p->scanned == 0 && fragPtr.p->scanning == 0) {
3887  jam();
3888  DihScanGetNodesReq* req = (DihScanGetNodesReq*)signal->getDataPtrSend();
3889  req->senderRef = reference();
3890  req->senderData = ptr.i;
3891  req->tableId = tabPtr.p->tableId;
3892  req->fragId = fragNo;
3893  req->scanCookie = tabPtr.p->m_scan_cookie;
3894  sendSignal(DBDIH_REF, GSN_DIH_SCAN_GET_NODES_REQ, signal,
3895  DihScanGetNodesReq::SignalLength, JBB);
3896  return;
3897  }//if
3898  }//for
3899 
3900  DihScanTabCompleteRep*rep= (DihScanTabCompleteRep*)signal->getDataPtrSend();
3901  rep->tableId = tabPtr.p->tableId;
3902  rep->scanCookie = tabPtr.p->m_scan_cookie;
3903  sendSignal(DBDIH_REF, GSN_DIH_SCAN_TAB_COMPLETE_REP, signal,
3904  DihScanTabCompleteRep::SignalLength, JBB);
3905 
3906  fragNo = 0;
3907  }//for
3908 
3909 
3910  getFragmentInfoDone(signal, ptr);
3911 }
3912 
3913 void
3914 Backup::execDIH_SCAN_GET_NODES_CONF(Signal* signal)
3915 {
3916  jamEntry();
3917 
3918  DihScanGetNodesConf* conf = (DihScanGetNodesConf*)signal->getDataPtrSend();
3919  const Uint32 senderData = conf->senderData;
3920  const Uint32 nodeCount = conf->count;
3921  const Uint32 tableId = conf->tableId;
3922  const Uint32 fragNo = conf->fragId;
3923  const Uint32 instanceKey = conf->instanceKey;
3924 
3925  ndbrequire(nodeCount > 0 && nodeCount <= MAX_REPLICAS);
3926 
3927  BackupRecordPtr ptr LINT_SET_PTR;
3928  c_backupPool.getPtr(ptr, senderData);
3929 
3930  TablePtr tabPtr;
3931  ndbrequire(findTable(ptr, tabPtr, tableId));
3932 
3933  FragmentPtr fragPtr;
3934  tabPtr.p->fragments.getPtr(fragPtr, fragNo);
3935  fragPtr.p->lqhInstanceKey = instanceKey;
3936 
3937  fragPtr.p->node = conf->nodes[0];
3938 
3939  getFragmentInfo(signal, ptr, tabPtr, fragNo + 1);
3940 }
3941 
3942 void
3943 Backup::getFragmentInfoDone(Signal* signal, BackupRecordPtr ptr)
3944 {
3945  ptr.p->m_gsn = GSN_DEFINE_BACKUP_CONF;
3946  ptr.p->slaveState.setState(DEFINED);
3947  DefineBackupConf * conf = (DefineBackupConf*)signal->getDataPtr();
3948  conf->backupPtr = ptr.i;
3949  conf->backupId = ptr.p->backupId;
3950  sendSignal(ptr.p->masterRef, GSN_DEFINE_BACKUP_CONF, signal,
3951  DefineBackupConf::SignalLength, JBB);
3952 }
3953 
3954 
3955 /*****************************************************************************
3956  *
3957  * Slave functionallity: Start backup
3958  *
3959  *****************************************************************************/
3960 void
3962 {
3963  jamEntry();
3964 
3965  CRASH_INSERTION((10015));
3966 
3967  StartBackupReq* req = (StartBackupReq*)signal->getDataPtr();
3968  const Uint32 ptrI = req->backupPtr;
3969 
3970  BackupRecordPtr ptr LINT_SET_PTR;
3971  c_backupPool.getPtr(ptr, ptrI);
3972 
3973  ptr.p->slaveState.setState(STARTED);
3974  ptr.p->m_gsn = GSN_START_BACKUP_REQ;
3975 
3979  BackupFilePtr filePtr;
3980  for(ptr.p->files.first(filePtr); filePtr.i!=RNIL;ptr.p->files.next(filePtr))
3981  {
3982  jam();
3983  if(! (filePtr.p->m_flags & BackupFile::BF_FILE_THREAD))
3984  {
3985  jam();
3986  filePtr.p->m_flags |= BackupFile::BF_FILE_THREAD;
3987  signal->theData[0] = BackupContinueB::START_FILE_THREAD;
3988  signal->theData[1] = filePtr.i;
3989  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
3990  }//if
3991  }//for
3992 
3996  TablePtr tabPtr;
3997  ndbrequire(ptr.p->tables.first(tabPtr));
3998  sendCreateTrig(signal, ptr, tabPtr);
3999 }
4000 
4001 /*****************************************************************************
4002  *
4003  * Slave functionallity: Backup fragment
4004  *
4005  *****************************************************************************/
4006 void
4008 {
4009  jamEntry();
4010  BackupFragmentReq* req = (BackupFragmentReq*)signal->getDataPtr();
4011 
4012  CRASH_INSERTION((10016));
4013 
4014  const Uint32 ptrI = req->backupPtr;
4015  //const Uint32 backupId = req->backupId;
4016  const Uint32 tableId = req->tableId;
4017  const Uint32 fragNo = req->fragmentNo;
4018  const Uint32 count = req->count;
4019 
4023  BackupRecordPtr ptr LINT_SET_PTR;
4024  c_backupPool.getPtr(ptr, ptrI);
4025 
4026  ptr.p->slaveState.setState(SCANNING);
4027  ptr.p->m_gsn = GSN_BACKUP_FRAGMENT_REQ;
4028 
4032  BackupFilePtr filePtr LINT_SET_PTR;
4033  c_backupFilePool.getPtr(filePtr, ptr.p->dataFilePtr);
4034 
4035  ndbrequire(filePtr.p->backupPtr == ptrI);
4036  ndbrequire(filePtr.p->m_flags ==
4037  (BackupFile::BF_OPEN | BackupFile::BF_FILE_THREAD));
4038 
4042  TablePtr tabPtr;
4043  ndbrequire(findTable(ptr, tabPtr, tableId));
4044 
4048  FragmentPtr fragPtr;
4049  tabPtr.p->fragments.getPtr(fragPtr, fragNo);
4050 
4051  ndbrequire(fragPtr.p->scanned == 0);
4052  ndbrequire(fragPtr.p->scanning == 0 ||
4053  refToNode(ptr.p->masterRef) == getOwnNodeId());
4054 
4058  if(filePtr.p->tableId != tableId) {
4059  jam();
4060  filePtr.p->operation.init(tabPtr);
4061  filePtr.p->tableId = tableId;
4062  }//if
4063 
4067  if(!filePtr.p->operation.newFragment(tableId, fragPtr.p->fragmentId)) {
4068  jam();
4069  req->count = count + 1;
4070  sendSignalWithDelay(reference(), GSN_BACKUP_FRAGMENT_REQ, signal, 50,
4071  signal->length());
4072  ptr.p->slaveState.setState(STARTED);
4073  return;
4074  }//if
4075 
4079  fragPtr.p->scanning = 1;
4080  filePtr.p->fragmentNo = fragPtr.p->fragmentId;
4081  filePtr.p->m_retry_count = 0;
4082 
4083  sendScanFragReq(signal, ptr, filePtr, tabPtr, fragPtr, 0);
4084 }
4085 
4086 void
4088  Ptr<BackupRecord> ptr,
4089  Ptr<BackupFile> filePtr,
4090  Ptr<Table> tabPtr,
4091  Ptr<Fragment> fragPtr,
4092  Uint32 delay)
4093 {
4097  {
4098  filePtr.p->m_flags |= BackupFile::BF_SCAN_THREAD;
4099 
4100  Table & table = * tabPtr.p;
4101  ScanFragReq * req = (ScanFragReq *)signal->getDataPtrSend();
4102  const Uint32 parallelism = 16;
4103 
4104  req->senderData = filePtr.i;
4105  req->resultRef = reference();
4106  req->schemaVersion = table.schemaVersion;
4107  req->fragmentNoKeyLen = fragPtr.p->fragmentId;
4108  req->requestInfo = 0;
4109  req->savePointId = 0;
4110  req->tableId = table.tableId;
4111  ScanFragReq::setReadCommittedFlag(req->requestInfo, 1);
4112  ScanFragReq::setLockMode(req->requestInfo, 0);
4113  ScanFragReq::setHoldLockFlag(req->requestInfo, 0);
4114  ScanFragReq::setKeyinfoFlag(req->requestInfo, 0);
4115  ScanFragReq::setTupScanFlag(req->requestInfo, 1);
4116  if (ptr.p->is_lcp())
4117  {
4118  ScanFragReq::setScanPrio(req->requestInfo, 1);
4119  ScanFragReq::setNoDiskFlag(req->requestInfo, 1);
4120  ScanFragReq::setLcpScanFlag(req->requestInfo, 1);
4121  }
4122  req->transId1 = 0;
4123  req->transId2 = (BACKUP << 20) + (getOwnNodeId() << 8);
4124  req->clientOpPtr= filePtr.i;
4125  req->batch_size_rows= parallelism;
4126  req->batch_size_bytes= 0;
4127  BlockReference lqhRef = 0;
4128  if (ptr.p->is_lcp()) {
4129  lqhRef = calcInstanceBlockRef(DBLQH);
4130  } else {
4131  const Uint32 instanceKey = fragPtr.p->lqhInstanceKey;
4132  ndbrequire(instanceKey != 0);
4133  lqhRef = numberToRef(DBLQH, instanceKey, getOwnNodeId());
4134  }
4135 
4136  Uint32 attrInfo[25];
4137  attrInfo[0] = table.attrInfoLen;
4138  attrInfo[1] = 0;
4139  attrInfo[2] = 0;
4140  attrInfo[3] = 0;
4141  attrInfo[4] = 0;
4142  memcpy(attrInfo + 5, table.attrInfo, 4*table.attrInfoLen);
4143  LinearSectionPtr ptr[3];
4144  ptr[0].p = attrInfo;
4145  ptr[0].sz = 5 + table.attrInfoLen;
4146  if (delay == 0)
4147  {
4148  jam();
4149  sendSignal(lqhRef, GSN_SCAN_FRAGREQ, signal,
4150  ScanFragReq::SignalLength, JBB, ptr, 1);
4151  }
4152  else
4153  {
4154  jam();
4155  SectionHandle handle(this);
4156  ndbrequire(import(handle.m_ptr[0], ptr[0].p, ptr[0].sz));
4157  handle.m_cnt = 1;
4158  sendSignalWithDelay(lqhRef, GSN_SCAN_FRAGREQ, signal,
4159  delay, ScanFragReq::SignalLength, &handle);
4160  }
4161  }
4162 }
4163 
4164 void
4166 {
4167  jamEntry();
4168 }
4169 
4170 void
4172 {
4173  jamEntry();
4174 
4175  const Uint32 filePtrI = signal->theData[0];
4176  //const Uint32 transId1 = signal->theData[1];
4177  //const Uint32 transId2 = signal->theData[2];
4178  Uint32 dataLen = signal->length() - 3;
4179 
4180  BackupFilePtr filePtr LINT_SET_PTR;
4181  c_backupFilePool.getPtr(filePtr, filePtrI);
4182 
4183  OperationRecord & op = filePtr.p->operation;
4184 
4188  Uint32 * dst = op.dst;
4189  if (signal->getNoOfSections() == 0)
4190  {
4191  jam();
4192  const Uint32 * src = &signal->theData[3];
4193  * dst = htonl(dataLen);
4194  memcpy(dst + 1, src, 4*dataLen);
4195  }
4196  else
4197  {
4198  jam();
4199  SectionHandle handle(this, signal);
4200  SegmentedSectionPtr dataPtr;
4201  handle.getSection(dataPtr, 0);
4202  dataLen = dataPtr.sz;
4203 
4204  * dst = htonl(dataLen);
4205  copy(dst + 1, dataPtr);
4206  releaseSections(handle);
4207  }
4208 
4209  op.attrSzTotal += dataLen;
4210  ndbrequire(dataLen < op.maxRecordSize);
4211 
4212  op.finished(dataLen);
4213 
4214  op.newRecord(dst + dataLen + 1);
4215 }
4216 
4217 void
4219 {
4220  tablePtr = ptr.i;
4221  maxRecordSize = ptr.p->maxRecordSize;
4222 }
4223 
4224 bool
4225 Backup::OperationRecord::newFragment(Uint32 tableId, Uint32 fragNo)
4226 {
4227  Uint32 * tmp;
4228  const Uint32 headSz = (sizeof(BackupFormat::DataFile::FragmentHeader) >> 2);
4229  const Uint32 sz = headSz + 16 * maxRecordSize;
4230 
4231  ndbrequire(sz < dataBuffer.getMaxWrite());
4232  if(dataBuffer.getWritePtr(&tmp, sz)) {
4233  jam();
4236 
4237  head->SectionType = htonl(BackupFormat::FRAGMENT_HEADER);
4238  head->SectionLength = htonl(headSz);
4239  head->TableId = htonl(tableId);
4240  head->FragmentNo = htonl(fragNo);
4241  head->ChecksumType = htonl(0);
4242 
4243  opNoDone = opNoConf = opLen = 0;
4244  newRecord(tmp + headSz);
4245  scanStart = tmp;
4246  scanStop = (tmp + headSz);
4247 
4248  noOfRecords = 0;
4249  noOfBytes = 0;
4250  return true;
4251  }//if
4252  return false;
4253 }
4254 
4255 bool
4256 Backup::OperationRecord::fragComplete(Uint32 tableId, Uint32 fragNo, bool fill_record)
4257 {
4258  Uint32 * tmp;
4259  const Uint32 footSz = sizeof(BackupFormat::DataFile::FragmentFooter) >> 2;
4260  Uint32 sz = footSz + 1;
4261 
4262  if (fill_record)
4263  {
4264  Uint32 * new_tmp;
4265  if (!dataBuffer.getWritePtr(&tmp, sz))
4266  return false;
4267  new_tmp = tmp + sz;
4268 
4269  if ((UintPtr)new_tmp & (sizeof(Page32)-1))
4270  {
4271  /* padding is needed to get full write */
4272  new_tmp += 2 /* to fit empty header minimum 2 words*/;
4273  new_tmp = (Uint32 *)(((UintPtr)new_tmp + sizeof(Page32)-1) &
4274  ~(UintPtr)(sizeof(Page32)-1));
4275  /* new write sz */
4276  sz = Uint32(new_tmp - tmp);
4277  }
4278  }
4279 
4280  if(dataBuffer.getWritePtr(&tmp, sz)) {
4281  jam();
4282  * tmp = 0; // Finish record stream
4283  tmp++;
4286  foot->SectionType = htonl(BackupFormat::FRAGMENT_FOOTER);
4287  foot->SectionLength = htonl(footSz);
4288  foot->TableId = htonl(tableId);
4289  foot->FragmentNo = htonl(fragNo);
4290  foot->NoOfRecords = htonl(Uint32(noOfRecords)); // TODO
4291  foot->Checksum = htonl(0);
4292 
4293  if (sz != footSz + 1)
4294  {
4295  tmp += footSz;
4296  memset(tmp, 0, (sz - footSz - 1) * 4);
4297  *tmp = htonl(BackupFormat::EMPTY_ENTRY);
4298  tmp++;
4299  *tmp = htonl(sz - footSz - 1);
4300  }
4301 
4302  dataBuffer.updateWritePtr(sz);
4303  return true;
4304  }//if
4305  return false;
4306 }
4307 
4308 bool
4310 {
4311  Uint32 * tmp;
4312  ndbrequire(16 * maxRecordSize < dataBuffer.getMaxWrite());
4313  if(dataBuffer.getWritePtr(&tmp, 16 * maxRecordSize))
4314  {
4315  jam();
4316  opNoDone = opNoConf = opLen = 0;
4317  newRecord(tmp);
4318  scanStart = tmp;
4319  scanStop = tmp;
4320  return true;
4321  }//if
4322  return false;
4323 }
4324 
4325 bool
4326 Backup::OperationRecord::closeScan()
4327 {
4328  opNoDone = opNoConf = opLen = 0;
4329  return true;
4330 }
4331 
4332 bool
4333 Backup::OperationRecord::scanConf(Uint32 noOfOps, Uint32 total_len)
4334 {
4335  const Uint32 done = Uint32(opNoDone-opNoConf);
4336 
4337  ndbrequire(noOfOps == done);
4338  ndbrequire(opLen == total_len);
4339  opNoConf = opNoDone;
4340 
4341  const Uint32 len = Uint32(scanStop - scanStart);
4342  ndbrequire(len < dataBuffer.getMaxWrite());
4343  dataBuffer.updateWritePtr(len);
4344  noOfBytes += (len << 2);
4345  m_bytes_total += (len << 2);
4346  return true;
4347 }
4348 
4349 void
4350 Backup::execSCAN_FRAGREF(Signal* signal)
4351 {
4352  jamEntry();
4353 
4354  ScanFragRef * ref = (ScanFragRef*)signal->getDataPtr();
4355 
4356  const Uint32 filePtrI = ref->senderData;
4357  BackupFilePtr filePtr LINT_SET_PTR;
4358  c_backupFilePool.getPtr(filePtr, filePtrI);
4359 
4360  Uint32 errCode = ref->errorCode;
4361  if (filePtr.p->errorCode == 0)
4362  {
4363  // check for transient errors
4364  switch(errCode){
4365  case ScanFragRef::ZSCAN_BOOK_ACC_OP_ERROR:
4366  case ScanFragRef::NO_TC_CONNECT_ERROR:
4367  case ScanFragRef::ZTOO_MANY_ACTIVE_SCAN_ERROR:
4368  jam();
4369  break;
4370  default:
4371  jam();
4372  filePtr.p->errorCode = errCode;
4373  }
4374  }
4375 
4376  if (filePtr.p->errorCode == 0)
4377  {
4378  jam();
4379  filePtr.p->m_retry_count++;
4380  if (filePtr.p->m_retry_count == 10)
4381  {
4382  jam();
4383  filePtr.p->errorCode = errCode;
4384  }
4385  }
4386 
4387  if (filePtr.p->errorCode != 0)
4388  {
4389  jam();
4390  filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_SCAN_THREAD;
4391  backupFragmentRef(signal, filePtr);
4392  }
4393  else
4394  {
4395  jam();
4396 
4397  // retry
4398 
4399  BackupRecordPtr ptr;
4400  c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
4401  TablePtr tabPtr;
4402  ndbrequire(findTable(ptr, tabPtr, filePtr.p->tableId));
4403  FragmentPtr fragPtr;
4404  tabPtr.p->fragments.getPtr(fragPtr, filePtr.p->fragmentNo);
4405  sendScanFragReq(signal, ptr, filePtr, tabPtr, fragPtr, 100);
4406  }
4407 }
4408 
4409 void
4410 Backup::execSCAN_FRAGCONF(Signal* signal)
4411 {
4412  jamEntry();
4413 
4414  CRASH_INSERTION((10017));
4415 
4416  ScanFragConf * conf = (ScanFragConf*)signal->getDataPtr();
4417 
4418  const Uint32 filePtrI = conf->senderData;
4419  BackupFilePtr filePtr LINT_SET_PTR;
4420  c_backupFilePool.getPtr(filePtr, filePtrI);
4421 
4422  OperationRecord & op = filePtr.p->operation;
4423 
4424  op.scanConf(conf->completedOps, conf->total_len);
4425  const Uint32 completed = conf->fragmentCompleted;
4426  if(completed != 2) {
4427  jam();
4428 
4429  checkScan(signal, filePtr);
4430  return;
4431  }//if
4432 
4433  fragmentCompleted(signal, filePtr);
4434 }
4435 
4436 void
4437 Backup::fragmentCompleted(Signal* signal, BackupFilePtr filePtr)
4438 {
4439  jam();
4440 
4441  if(filePtr.p->errorCode != 0)
4442  {
4443  jam();
4444  filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_SCAN_THREAD;
4445  backupFragmentRef(signal, filePtr); // Scan completed
4446  return;
4447  }//if
4448 
4449  BackupRecordPtr ptr LINT_SET_PTR;
4450  c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
4451 
4452  OperationRecord & op = filePtr.p->operation;
4453  if(!op.fragComplete(filePtr.p->tableId, filePtr.p->fragmentNo,
4454  c_defaults.m_o_direct))
4455  {
4456  jam();
4457  signal->theData[0] = BackupContinueB::BUFFER_FULL_FRAG_COMPLETE;
4458  signal->theData[1] = filePtr.i;
4459  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 50, 2);
4460  return;
4461  }//if
4462 
4463  filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_SCAN_THREAD;
4464 
4465  if (ptr.p->is_lcp())
4466  {
4467  ptr.p->slaveState.setState(STOPPING);
4468  filePtr.p->operation.dataBuffer.eof();
4469  }
4470  else
4471  {
4472  BackupFragmentConf * conf = (BackupFragmentConf*)signal->getDataPtrSend();
4473  conf->backupId = ptr.p->backupId;
4474  conf->backupPtr = ptr.i;
4475  conf->tableId = filePtr.p->tableId;
4476  conf->fragmentNo = filePtr.p->fragmentNo;
4477  conf->noOfRecordsLow = (Uint32)(op.noOfRecords & 0xFFFFFFFF);
4478  conf->noOfRecordsHigh = (Uint32)(op.noOfRecords >> 32);
4479  conf->noOfBytesLow = (Uint32)(op.noOfBytes & 0xFFFFFFFF);
4480  conf->noOfBytesHigh = (Uint32)(op.noOfBytes >> 32);
4481  sendSignal(ptr.p->masterRef, GSN_BACKUP_FRAGMENT_CONF, signal,
4482  BackupFragmentConf::SignalLength, JBB);
4483 
4484  ptr.p->m_gsn = GSN_BACKUP_FRAGMENT_CONF;
4485  ptr.p->slaveState.setState(STARTED);
4486  }
4487  return;
4488 }
4489 
4490 void
4491 Backup::backupFragmentRef(Signal * signal, BackupFilePtr filePtr)
4492 {
4493  BackupRecordPtr ptr LINT_SET_PTR;
4494  c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
4495 
4496  ptr.p->m_gsn = GSN_BACKUP_FRAGMENT_REF;
4497 
4498  BackupFragmentRef * ref = (BackupFragmentRef*)signal->getDataPtrSend();
4499  ref->backupId = ptr.p->backupId;
4500  ref->backupPtr = ptr.i;
4501  ref->nodeId = getOwnNodeId();
4502  ref->errorCode = filePtr.p->errorCode;
4503  sendSignal(ptr.p->masterRef, GSN_BACKUP_FRAGMENT_REF, signal,
4504  BackupFragmentRef::SignalLength, JBB);
4505 }
4506 
4507 void
4509 {
4510  OperationRecord & op = filePtr.p->operation;
4511  BlockReference lqhRef = 0;
4512  {
4513  BackupRecordPtr ptr LINT_SET_PTR;
4514  c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
4515  if (ptr.p->is_lcp()) {
4516  lqhRef = calcInstanceBlockRef(DBLQH);
4517  } else {
4518  TablePtr tabPtr;
4519  ndbrequire(findTable(ptr, tabPtr, filePtr.p->tableId));
4520  FragmentPtr fragPtr;
4521  tabPtr.p->fragments.getPtr(fragPtr, filePtr.p->fragmentNo);
4522  const Uint32 instanceKey = fragPtr.p->lqhInstanceKey;
4523  lqhRef = numberToRef(DBLQH, instanceKey, getOwnNodeId());
4524  }
4525  }
4526 
4527  if(filePtr.p->errorCode != 0)
4528  {
4529  jam();
4530 
4534  op.closeScan();
4535  ScanFragNextReq * req = (ScanFragNextReq *)signal->getDataPtrSend();
4536  req->senderData = filePtr.i;
4537  req->requestInfo = ScanFragNextReq::ZCLOSE;
4538  req->transId1 = 0;
4539  req->transId2 = (BACKUP << 20) + (getOwnNodeId() << 8);
4540  sendSignal(lqhRef, GSN_SCAN_NEXTREQ, signal,
4541  ScanFragNextReq::SignalLength, JBB);
4542  return;
4543  }//if
4544 
4545  if(op.newScan()) {
4546  jam();
4547 
4548  ScanFragNextReq * req = (ScanFragNextReq *)signal->getDataPtrSend();
4549  req->senderData = filePtr.i;
4550  req->requestInfo = 0;
4551  req->transId1 = 0;
4552  req->transId2 = (BACKUP << 20) + (getOwnNodeId() << 8);
4553  req->batch_size_rows= 16;
4554  req->batch_size_bytes= 0;
4555 
4556  if (ERROR_INSERTED(10039) &&
4557  filePtr.p->tableId >= 2 &&
4558  filePtr.p->operation.noOfRecords > 0)
4559  {
4560  ndbout_c("halting backup for table %d fragment: %d after %llu records",
4561  filePtr.p->tableId,
4562  filePtr.p->fragmentNo,
4563  filePtr.p->operation.noOfRecords);
4564  memmove(signal->theData+2, signal->theData,
4565  4*ScanFragNextReq::SignalLength);
4566  signal->theData[0] = BackupContinueB::ZDELAY_SCAN_NEXT;
4567  signal->theData[1] = filePtr.i;
4568  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal,
4569  300, 2+ScanFragNextReq::SignalLength);
4570  return;
4571  }
4572  if(ERROR_INSERTED(10032))
4573  sendSignalWithDelay(lqhRef, GSN_SCAN_NEXTREQ, signal,
4574  100, ScanFragNextReq::SignalLength);
4575  else if(ERROR_INSERTED(10033))
4576  {
4577  SET_ERROR_INSERT_VALUE(10032);
4578  sendSignalWithDelay(lqhRef, GSN_SCAN_NEXTREQ, signal,
4579  10000, ScanFragNextReq::SignalLength);
4580 
4581  BackupRecordPtr ptr LINT_SET_PTR;
4582  c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
4583  AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
4584  ord->backupId = ptr.p->backupId;
4585  ord->backupPtr = ptr.i;
4586  ord->requestType = AbortBackupOrd::FileOrScanError;
4587  ord->senderData= ptr.i;
4588  sendSignal(ptr.p->masterRef, GSN_ABORT_BACKUP_ORD, signal,
4589  AbortBackupOrd::SignalLength, JBB);
4590  }
4591 #ifdef ERROR_INSERT
4592  else if (ERROR_INSERTED(10042) && filePtr.p->tableId ==c_error_insert_extra)
4593  {
4594  sendSignalWithDelay(lqhRef, GSN_SCAN_NEXTREQ, signal,
4595  10, ScanFragNextReq::SignalLength);
4596  }
4597 #endif
4598  else
4599  {
4600  sendSignal(lqhRef, GSN_SCAN_NEXTREQ, signal,
4601  ScanFragNextReq::SignalLength, JBB);
4602 
4603  /*
4604  check if it is time to report backup status
4605  */
4606  BackupRecordPtr ptr LINT_SET_PTR;
4607  c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
4608  if (!ptr.p->is_lcp())
4609  checkReportStatus(signal, ptr);
4610  }
4611  return;
4612  }//if
4613 
4614  signal->theData[0] = BackupContinueB::BUFFER_FULL_SCAN;
4615  signal->theData[1] = filePtr.i;
4616  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 50, 2);
4617 }
4618 
4619 void
4620 Backup::execFSAPPENDREF(Signal* signal)
4621 {
4622  jamEntry();
4623 
4624  FsRef * ref = (FsRef *)signal->getDataPtr();
4625 
4626  const Uint32 filePtrI = ref->userPointer;
4627  const Uint32 errCode = ref->errorCode;
4628 
4629  BackupFilePtr filePtr LINT_SET_PTR;
4630  c_backupFilePool.getPtr(filePtr, filePtrI);
4631 
4632  filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_FILE_THREAD;
4633  filePtr.p->errorCode = errCode;
4634 
4635  checkFile(signal, filePtr);
4636 }
4637 
4638 void
4639 Backup::execFSAPPENDCONF(Signal* signal)
4640 {
4641  jamEntry();
4642 
4643  CRASH_INSERTION((10018));
4644 
4645  //FsConf * conf = (FsConf*)signal->getDataPtr();
4646  const Uint32 filePtrI = signal->theData[0]; //conf->userPointer;
4647  const Uint32 bytes = signal->theData[1]; //conf->bytes;
4648 
4649  BackupFilePtr filePtr LINT_SET_PTR;
4650  c_backupFilePool.getPtr(filePtr, filePtrI);
4651 
4652  OperationRecord & op = filePtr.p->operation;
4653 
4654  op.dataBuffer.updateReadPtr(bytes >> 2);
4655 
4656  checkFile(signal, filePtr);
4657 }
4658 
4659 /*
4660  This routine handles two problems with writing to disk during local
4661  checkpoints and backups. The first problem is that we need to limit
4662  the writing to ensure that we don't use too much CPU and disk resources
4663  for backups and checkpoints. The perfect solution to this is to use
4664  a dynamic algorithm that adapts to the environment. Until we have
4665  implemented this we can satisfy ourselves with an algorithm that
4666  uses a configurable limit.
4667 
4668  The second problem is that in Linux we can get severe problems if we
4669  write very much to the disk without synching. In the worst case we
4670  can have Gigabytes of data in the Linux page cache before we reach
4671  the limit of how much we can write. If this happens the performance
4672  will drop significantly when we reach this limit since the Linux flush
4673  daemon will spend a few minutes on writing out the page cache to disk.
4674  To avoid this we ensure that a file never have more than a certain
4675  amount of data outstanding before synch. This variable is also
4676  configurable.
4677 */
4678 bool
4679 Backup::ready_to_write(bool ready, Uint32 sz, bool eof, BackupFile *fileP)
4680 {
4681 #if 0
4682  ndbout << "ready_to_write: ready = " << ready << " eof = " << eof;
4683  ndbout << " sz = " << sz << endl;
4684  ndbout << "words this period = " << m_words_written_this_period;
4685  ndbout << endl << "overflow disk write = " << m_overflow_disk_write;
4686  ndbout << endl << "Current Millisecond is = ";
4687  ndbout << NdbTick_CurrentMillisecond() << endl;
4688 #endif
4689  if ((ready || eof) &&
4690  m_words_written_this_period <= m_curr_disk_write_speed)
4691  {
4692  /*
4693  We have a buffer ready to write or we have reached end of
4694  file and thus we must write the last before closing the
4695  file.
4696  We have already check that we are allowed to write at this
4697  moment. We only worry about history of last 100 milliseconds.
4698  What happened before that is of no interest since a disk
4699  write that was issued more than 100 milliseconds should be
4700  completed by now.
4701  */
4702  int overflow;
4703  m_words_written_this_period += sz;
4704  overflow = m_words_written_this_period - m_curr_disk_write_speed;
4705  if (overflow > 0)
4706  m_overflow_disk_write = overflow;
4707 #if 0
4708  ndbout << "Will write with " << endl;
4709  ndbout << endl;
4710 #endif
4711  return true;
4712  }
4713  else
4714  {
4715 #if 0
4716  ndbout << "Will not write now" << endl << endl;
4717 #endif
4718  return false;
4719  }
4720 }
4721 
4722 void
4723 Backup::checkFile(Signal* signal, BackupFilePtr filePtr)
4724 {
4725 
4726 #ifdef DEBUG_ABORT
4727  // ndbout_c("---- check file filePtr.i = %u", filePtr.i);
4728 #endif
4729 
4730  OperationRecord & op = filePtr.p->operation;
4731  Uint32 *tmp = NULL;
4732  Uint32 sz = 0;
4733  bool eof = FALSE;
4734  bool ready = op.dataBuffer.getReadPtr(&tmp, &sz, &eof);
4735 #if 0
4736  ndbout << "Ptr to data = " << hex << tmp << endl;
4737 #endif
4738  BackupRecordPtr ptr LINT_SET_PTR;
4739  c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
4740 
4741  if (ERROR_INSERTED(10036))
4742  {
4743  jam();
4744  filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_FILE_THREAD;
4745  filePtr.p->errorCode = 2810;
4746  ptr.p->setErrorCode(2810);
4747 
4748  if(ptr.p->m_gsn == GSN_STOP_BACKUP_REQ)
4749  {
4750  jam();
4751  closeFile(signal, ptr, filePtr);
4752  }
4753  return;
4754  }
4755 
4756  if(filePtr.p->errorCode != 0)
4757  {
4758  jam();
4759  ptr.p->setErrorCode(filePtr.p->errorCode);
4760 
4761  if(ptr.p->m_gsn == GSN_STOP_BACKUP_REQ)
4762  {
4763  jam();
4764  closeFile(signal, ptr, filePtr);
4765  }
4766  return;
4767  }
4768 
4769  if (!ready_to_write(ready, sz, eof, filePtr.p))
4770  {
4771  jam();
4772  signal->theData[0] = BackupContinueB::BUFFER_UNDERFLOW;
4773  signal->theData[1] = filePtr.i;
4774  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 20, 2);
4775  return;
4776  }
4777  else if (sz > 0)
4778  {
4779  jam();
4780  ndbassert((Uint64(tmp - c_startOfPages) >> 32) == 0); // 4Gb buffers!
4781  FsAppendReq * req = (FsAppendReq *)signal->getDataPtrSend();
4782  req->filePointer = filePtr.p->filePointer;
4783  req->userPointer = filePtr.i;
4784  req->userReference = reference();
4785  req->varIndex = 0;
4786  req->offset = Uint32(tmp - c_startOfPages); // 4Gb buffers!
4787  req->size = sz;
4788  req->synch_flag = 0;
4789 
4790  sendSignal(NDBFS_REF, GSN_FSAPPENDREQ, signal,
4791  FsAppendReq::SignalLength, JBA);
4792  return;
4793  }
4794 
4795  Uint32 flags = filePtr.p->m_flags;
4796  filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_FILE_THREAD;
4797 
4798  ndbrequire(flags & BackupFile::BF_OPEN);
4799  ndbrequire(flags & BackupFile::BF_FILE_THREAD);
4800 
4801  closeFile(signal, ptr, filePtr);
4802 }
4803 
4804 
4805 /****************************************************************************
4806  *
4807  * Slave functionallity: Perform logging
4808  *
4809  ****************************************************************************/
4810 void
4812 {
4813  /*
4814  TUP asks if this trigger is to be fired on this node.
4815  */
4816  TriggerPtr trigPtr LINT_SET_PTR;
4817  TablePtr tabPtr LINT_SET_PTR;
4818  FragmentPtr fragPtr;
4819  Uint32 trigger_id = signal->theData[0];
4820  Uint32 frag_id = signal->theData[1];
4821  Uint32 result;
4822 
4823  jamEntry();
4824 
4825  c_triggerPool.getPtr(trigPtr, trigger_id);
4826 
4827  c_tablePool.getPtr(tabPtr, trigPtr.p->tab_ptr_i);
4828  tabPtr.p->fragments.getPtr(fragPtr, frag_id);
4829  if (fragPtr.p->node != getOwnNodeId()) {
4830 
4831  jam();
4832  result = ZFALSE;
4833  } else {
4834  jam();
4835  result = ZTRUE;
4836  }//if
4837  signal->theData[0] = result;
4838 }
4839 
4841 Backup::get_log_buffer(Signal* signal,
4842  TriggerPtr trigPtr, Uint32 sz)
4843 {
4844  Uint32 * dst;
4845  if(ERROR_INSERTED(10030))
4846  {
4847  jam();
4848  dst = 0;
4849  }
4850  else
4851  {
4852  jam();
4853  FsBuffer & buf = trigPtr.p->operation->dataBuffer;
4854  ndbrequire(sz <= buf.getMaxWrite());
4855  if (unlikely(!buf.getWritePtr(&dst, sz)))
4856  {
4857  jam();
4858  dst = 0;
4859  }
4860  }
4861 
4862  if (unlikely(dst == 0))
4863  {
4864  Uint32 save[TrigAttrInfo::StaticLength];
4865  memcpy(save, signal->getDataPtr(), 4*TrigAttrInfo::StaticLength);
4866  BackupRecordPtr ptr LINT_SET_PTR;
4867  c_backupPool.getPtr(ptr, trigPtr.p->backupPtr);
4868  trigPtr.p->errorCode = AbortBackupOrd::LogBufferFull;
4869  AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
4870  ord->backupId = ptr.p->backupId;
4871  ord->backupPtr = ptr.i;
4872  ord->requestType = AbortBackupOrd::LogBufferFull;
4873  ord->senderData= ptr.i;
4874  sendSignal(ptr.p->masterRef, GSN_ABORT_BACKUP_ORD, signal,
4875  AbortBackupOrd::SignalLength, JBB);
4876 
4877  memcpy(signal->getDataPtrSend(), save, 4*TrigAttrInfo::StaticLength);
4878  return 0;
4879  }//if
4880 
4881  BackupFormat::LogFile::LogEntry * logEntry =
4883  logEntry->Length = 0;
4884  logEntry->TableId = htonl(trigPtr.p->tableId);
4885 
4886  if(trigPtr.p->event==0)
4887  logEntry->TriggerEvent= htonl(TriggerEvent::TE_INSERT);
4888  else if(trigPtr.p->event==1)
4889  logEntry->TriggerEvent= htonl(TriggerEvent::TE_UPDATE);
4890  else if(trigPtr.p->event==2)
4891  logEntry->TriggerEvent= htonl(TriggerEvent::TE_DELETE);
4892  else {
4893  ndbout << "Bad Event: " << trigPtr.p->event << endl;
4894  ndbrequire(false);
4895  }
4896 
4897  return logEntry;
4898 }
4899 
4900 void
4902  jamEntry();
4903 
4904  CRASH_INSERTION((10019));
4905 
4906  TrigAttrInfo * trg = (TrigAttrInfo*)signal->getDataPtr();
4907 
4908  TriggerPtr trigPtr LINT_SET_PTR;
4909  c_triggerPool.getPtr(trigPtr, trg->getTriggerId());
4910  ndbrequire(trigPtr.p->event != ILLEGAL_TRIGGER_ID); // Online...
4911 
4912  if(trigPtr.p->errorCode != 0) {
4913  jam();
4914  return;
4915  }//if
4916 
4917  BackupRecordPtr ptr LINT_SET_PTR;
4918  c_backupPool.getPtr(ptr, trigPtr.p->backupPtr);
4919 
4920  if(ptr.p->flags & BackupReq::USE_UNDO_LOG) {
4921  if(trg->getAttrInfoType() == TrigAttrInfo::AFTER_VALUES) {
4922  jam();
4926  return;
4927  }//if
4928  }
4929  else {
4930  if(trg->getAttrInfoType() == TrigAttrInfo::BEFORE_VALUES) {
4931  jam();
4935  return;
4936  }//if
4937  }
4938 
4939  BackupFormat::LogFile::LogEntry * logEntry = trigPtr.p->logEntry;
4940  if(logEntry == 0)
4941  {
4942  jam();
4943  Uint32 sz = trigPtr.p->maxRecordSize;
4944  logEntry = trigPtr.p->logEntry = get_log_buffer(signal, trigPtr, sz);
4945  if (unlikely(logEntry == 0))
4946  {
4947  jam();
4948  return;
4949  }
4950  } else {
4951  ndbrequire(logEntry->TableId == htonl(trigPtr.p->tableId));
4952 // ndbrequire(logEntry->TriggerEvent == htonl(trigPtr.p->event));
4953  }//if
4954 
4955  const Uint32 pos = logEntry->Length;
4956  const Uint32 dataLen = signal->length() - TrigAttrInfo::StaticLength;
4957  memcpy(&logEntry->Data[pos], trg->getData(), dataLen << 2);
4958 
4959  logEntry->Length = pos + dataLen;
4960 }
4961 
4962 void
4964 {
4965  jamEntry();
4966  FireTrigOrd* trg = (FireTrigOrd*)signal->getDataPtr();
4967 
4968  const Uint32 gci = trg->getGCI();
4969  const Uint32 trI = trg->getTriggerId();
4970  const Uint32 fragId = trg->fragId;
4971 
4972  TriggerPtr trigPtr LINT_SET_PTR;
4973  c_triggerPool.getPtr(trigPtr, trI);
4974 
4975  ndbrequire(trigPtr.p->event != ILLEGAL_TRIGGER_ID);
4976 
4977  BackupRecordPtr ptr LINT_SET_PTR;
4978  c_backupPool.getPtr(ptr, trigPtr.p->backupPtr);
4979 
4980  if(trigPtr.p->errorCode != 0) {
4981  jam();
4982  SectionHandle handle(this, signal);
4983  releaseSections(handle);
4984  return;
4985  }//if
4986 
4987  if (signal->getNoOfSections())
4988  {
4989  jam();
4990  SectionHandle handle(this, signal);
4991  TablePtr tabPtr;
4992  c_tablePool.getPtr(tabPtr, trigPtr.p->tab_ptr_i);
4993  FragmentPtr fragPtr;
4994  tabPtr.p->fragments.getPtr(fragPtr, fragId);
4995  if (fragPtr.p->node != getOwnNodeId())
4996  {
4997  jam();
4998  trigPtr.p->logEntry = 0;
4999  releaseSections(handle);
5000  return;
5001  }
5002 
5003  SegmentedSectionPtr dataPtr[3];
5004  handle.getSection(dataPtr[0], 0);
5005  handle.getSection(dataPtr[1], 1);
5006  handle.getSection(dataPtr[2], 2);
5013  /* Backup is doing UNDO logging and need before values
5014  * Add 2 extra words to get_log_buffer for potential gci and logEntry length info stored at end.
5015  */
5016  if(ptr.p->flags & BackupReq::USE_UNDO_LOG) {
5017  trigPtr.p->logEntry = get_log_buffer(signal,
5018  trigPtr, dataPtr[0].sz + dataPtr[1].sz + 2);
5019  if (unlikely(trigPtr.p->logEntry == 0))
5020  {
5021  jam();
5022  releaseSections(handle);
5023  return;
5024  }
5025  copy(trigPtr.p->logEntry->Data, dataPtr[0]);
5026  copy(trigPtr.p->logEntry->Data+dataPtr[0].sz, dataPtr[1]);
5027  trigPtr.p->logEntry->Length = dataPtr[0].sz + dataPtr[1].sz;
5028  }
5029  // Backup is doing REDO logging and need after values
5030  else {
5031  trigPtr.p->logEntry = get_log_buffer(signal,
5032  trigPtr, dataPtr[0].sz + dataPtr[2].sz + 1);
5033  if (unlikely(trigPtr.p->logEntry == 0))
5034  {
5035  jam();
5036  releaseSections(handle);
5037  return;
5038  }
5039  copy(trigPtr.p->logEntry->Data, dataPtr[0]);
5040  copy(trigPtr.p->logEntry->Data+dataPtr[0].sz, dataPtr[2]);
5041  trigPtr.p->logEntry->Length = dataPtr[0].sz + dataPtr[2].sz;
5042  }
5043 
5044  releaseSections(handle);
5045  }
5046 
5047  ndbrequire(trigPtr.p->logEntry != 0);
5048  Uint32 len = trigPtr.p->logEntry->Length;
5049  trigPtr.p->logEntry->FragId = htonl(fragId);
5050 
5051  if(gci != ptr.p->currGCP)
5052  {
5053  jam();
5054  trigPtr.p->logEntry->TriggerEvent|= htonl(0x10000);
5055  trigPtr.p->logEntry->Data[len] = htonl(gci);
5056  len++;
5057  ptr.p->currGCP = gci;
5058  }
5059 
5060  Uint32 datalen = len;
5061  len += (sizeof(BackupFormat::LogFile::LogEntry) >> 2) - 2;
5062  trigPtr.p->logEntry->Length = htonl(len);
5063 
5064  if(ptr.p->flags & BackupReq::USE_UNDO_LOG)
5065  {
5066  /* keep the length at both the end of logEntry and ->logEntry variable
5067  The total length of logEntry is len + 2
5068  */
5069  trigPtr.p->logEntry->Data[datalen] = htonl(len);
5070  }
5071 
5072  Uint32 entryLength = len +1;
5073  if(ptr.p->flags & BackupReq::USE_UNDO_LOG)
5074  entryLength ++;
5075 
5076  ndbrequire(entryLength <= trigPtr.p->operation->dataBuffer.getMaxWrite());
5077  trigPtr.p->operation->dataBuffer.updateWritePtr(entryLength);
5078  trigPtr.p->logEntry = 0;
5079 
5080  {
5081  const Uint32 entryByteLength = entryLength << 2;
5082  trigPtr.p->operation->noOfBytes += entryByteLength;
5083  trigPtr.p->operation->m_bytes_total += entryByteLength;
5084  trigPtr.p->operation->noOfRecords += 1;
5085  trigPtr.p->operation->m_records_total += 1;
5086  }
5087 }
5088 
5089 void
5090 Backup::sendAbortBackupOrd(Signal* signal, BackupRecordPtr ptr,
5091  Uint32 requestType)
5092 {
5093  jam();
5094  AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
5095  ord->backupId = ptr.p->backupId;
5096  ord->backupPtr = ptr.i;
5097  ord->requestType = requestType;
5098  ord->senderData= ptr.i;
5099  NodePtr node;
5100  for(c_nodes.first(node); node.i != RNIL; c_nodes.next(node)) {
5101  jam();
5102  const Uint32 nodeId = node.p->nodeId;
5103  if(node.p->alive && ptr.p->nodes.get(nodeId)) {
5104  jam();
5105  BlockReference ref = numberToRef(BACKUP, instanceKey(ptr), nodeId);
5106  sendSignal(ref, GSN_ABORT_BACKUP_ORD, signal,
5107  AbortBackupOrd::SignalLength, JBB);
5108  }//if
5109  }//for
5110 }
5111 
5112 /*****************************************************************************
5113  *
5114  * Slave functionallity: Stop backup
5115  *
5116  *****************************************************************************/
5117 void
5119 {
5120  jamEntry();
5121  StopBackupReq * req = (StopBackupReq*)signal->getDataPtr();
5122 
5123  CRASH_INSERTION((10020));
5124 
5125  const Uint32 ptrI = req->backupPtr;
5126  //const Uint32 backupId = req->backupId;
5127  const Uint32 startGCP = req->startGCP;
5128  const Uint32 stopGCP = req->stopGCP;
5129 
5133  ndbrequire(stopGCP > startGCP);
5134 
5138  BackupRecordPtr ptr LINT_SET_PTR;
5139  c_backupPool.getPtr(ptr, ptrI);
5140 
5141  ptr.p->slaveState.setState(STOPPING);
5142  ptr.p->m_gsn = GSN_STOP_BACKUP_REQ;
5143  ptr.p->startGCP= startGCP;
5144  ptr.p->stopGCP= stopGCP;
5145 
5149  sendDropTrig(signal, ptr);
5150 }
5151 
5152 void
5154 {
5158  BackupFilePtr filePtr;
5159  int openCount = 0;
5160  for(ptr.p->files.first(filePtr); filePtr.i!=RNIL; ptr.p->files.next(filePtr))
5161  {
5162  if(! (filePtr.p->m_flags & BackupFile::BF_OPEN))
5163  {
5164  jam();
5165  continue;
5166  }
5167 
5168  jam();
5169  openCount++;
5170 
5171  if(filePtr.p->m_flags & BackupFile::BF_CLOSING)
5172  {
5173  jam();
5174  continue;
5175  }//if
5176 
5177  filePtr.p->operation.dataBuffer.eof();
5178  if(filePtr.p->m_flags & BackupFile::BF_FILE_THREAD)
5179  {
5180  jam();
5181 #ifdef DEBUG_ABORT
5182  ndbout_c("Close files fileRunning == 1, filePtr.i=%u", filePtr.i);
5183 #endif
5184  }
5185  else
5186  {
5187  jam();
5188  closeFile(sig, ptr, filePtr);
5189  }
5190  }
5191 
5192  if(openCount == 0){
5193  jam();
5194  closeFilesDone(sig, ptr);
5195  }//if
5196 }
5197 
5198 void
5199 Backup::closeFile(Signal* signal, BackupRecordPtr ptr, BackupFilePtr filePtr)
5200 {
5201  ndbrequire(filePtr.p->m_flags & BackupFile::BF_OPEN);
5202  ndbrequire(! (filePtr.p->m_flags & BackupFile::BF_OPENING));
5203  ndbrequire(! (filePtr.p->m_flags & BackupFile::BF_CLOSING));
5204  filePtr.p->m_flags |= BackupFile::BF_CLOSING;
5205 
5206  FsCloseReq * req = (FsCloseReq *)signal->getDataPtrSend();
5207  req->filePointer = filePtr.p->filePointer;
5208  req->userPointer = filePtr.i;
5209  req->userReference = reference();
5210  req->fileFlag = 0;
5211 
5212  if (ptr.p->errorCode)
5213  {
5214  FsCloseReq::setRemoveFileFlag(req->fileFlag, 1);
5215  }
5216 
5217 #ifdef DEBUG_ABORT
5218  ndbout_c("***** a FSCLOSEREQ filePtr.i = %u flags: %x",
5219  filePtr.i, filePtr.p->m_flags);
5220 #endif
5221  sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, FsCloseReq::SignalLength, JBA);
5222 
5223 }
5224 
5225 void
5226 Backup::execFSCLOSEREF(Signal* signal)
5227 {
5228  jamEntry();
5229 
5230  FsRef * ref = (FsRef*)signal->getDataPtr();
5231  const Uint32 filePtrI = ref->userPointer;
5232 
5233  BackupFilePtr filePtr LINT_SET_PTR;
5234  c_backupFilePool.getPtr(filePtr, filePtrI);
5235 
5236  BackupRecordPtr ptr LINT_SET_PTR;
5237  c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
5238 
5239  FsConf * conf = (FsConf*)signal->getDataPtr();
5240  conf->userPointer = filePtrI;
5241 
5242  execFSCLOSECONF(signal);
5243 }
5244 
5245 void
5246 Backup::execFSCLOSECONF(Signal* signal)
5247 {
5248  jamEntry();
5249 
5250  FsConf * conf = (FsConf*)signal->getDataPtr();
5251  const Uint32 filePtrI = conf->userPointer;
5252 
5253  BackupFilePtr filePtr LINT_SET_PTR;
5254  c_backupFilePool.getPtr(filePtr, filePtrI);
5255 
5256 #ifdef DEBUG_ABORT
5257  ndbout_c("***** FSCLOSECONF filePtrI = %u", filePtrI);
5258 #endif
5259 
5260  ndbrequire(filePtr.p->m_flags == (BackupFile::BF_OPEN |
5261  BackupFile::BF_CLOSING));
5262 
5263 
5264  filePtr.p->m_flags &= ~(Uint32)(BackupFile::BF_OPEN |BackupFile::BF_CLOSING);
5265  filePtr.p->operation.dataBuffer.reset();
5266 
5267  BackupRecordPtr ptr LINT_SET_PTR;
5268  c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
5269  closeFiles(signal, ptr);
5270 }
5271 
5272 void
5273 Backup::closeFilesDone(Signal* signal, BackupRecordPtr ptr)
5274 {
5275  jam();
5276 
5277  if(ptr.p->is_lcp())
5278  {
5279  lcp_close_file_conf(signal, ptr);
5280  return;
5281  }
5282 
5283  jam();
5284 
5285  //error when do insert footer or close file
5286  if(ptr.p->checkError())
5287  {
5288  StopBackupRef * ref = (StopBackupRef*)signal->getDataPtr();
5289  ref->backupPtr = ptr.i;
5290  ref->backupId = ptr.p->backupId;
5291  ref->errorCode = ptr.p->errorCode;
5292  ref->nodeId = getOwnNodeId();
5293  sendSignal(ptr.p->masterRef, GSN_STOP_BACKUP_REF, signal,
5294  StopBackupConf::SignalLength, JBB);
5295 
5296  ptr.p->m_gsn = GSN_STOP_BACKUP_REF;
5297  ptr.p->slaveState.setState(CLEANING);
5298  return;
5299  }
5300 
5301  StopBackupConf* conf = (StopBackupConf*)signal->getDataPtrSend();
5302  conf->backupId = ptr.p->backupId;
5303  conf->backupPtr = ptr.i;
5304 
5305  BackupFilePtr filePtr LINT_SET_PTR;
5306  if(ptr.p->logFilePtr != RNIL)
5307  {
5308  ptr.p->files.getPtr(filePtr, ptr.p->logFilePtr);
5309  conf->noOfLogBytes= Uint32(filePtr.p->operation.noOfBytes); // TODO
5310  conf->noOfLogRecords= Uint32(filePtr.p->operation.noOfRecords); // TODO
5311  }
5312  else
5313  {
5314  conf->noOfLogBytes= 0;
5315  conf->noOfLogRecords= 0;
5316  }
5317 
5318  sendSignal(ptr.p->masterRef, GSN_STOP_BACKUP_CONF, signal,
5319  StopBackupConf::SignalLength, JBB);
5320 
5321  ptr.p->m_gsn = GSN_STOP_BACKUP_CONF;
5322  ptr.p->slaveState.setState(CLEANING);
5323 }
5324 
5325 /*****************************************************************************
5326  *
5327  * Slave functionallity: Abort backup
5328  *
5329  *****************************************************************************/
5330 /*****************************************************************************
5331  *
5332  * Slave functionallity: Abort backup
5333  *
5334  *****************************************************************************/
5335 void
5337 {
5338  jamEntry();
5339  AbortBackupOrd* ord = (AbortBackupOrd*)signal->getDataPtr();
5340 
5341  const Uint32 backupId = ord->backupId;
5342  const AbortBackupOrd::RequestType requestType =
5343  (AbortBackupOrd::RequestType)ord->requestType;
5344  const Uint32 senderData = ord->senderData;
5345 
5346 #ifdef DEBUG_ABORT
5347  ndbout_c("******** ABORT_BACKUP_ORD ********* nodeId = %u",
5348  refToNode(signal->getSendersBlockRef()));
5349  ndbout_c("backupId = %u, requestType = %u, senderData = %u, ",
5350  backupId, requestType, senderData);
5351  dumpUsedResources();
5352 #endif
5353 
5354  BackupRecordPtr ptr LINT_SET_PTR;
5355  if(requestType == AbortBackupOrd::ClientAbort) {
5356  if (getOwnNodeId() != getMasterNodeId()) {
5357  jam();
5358  // forward to master
5359 #ifdef DEBUG_ABORT
5360  ndbout_c("---- Forward to master nodeId = %u", getMasterNodeId());
5361 #endif
5362  BlockReference ref = numberToRef(BACKUP, UserBackupInstanceKey,
5363  getMasterNodeId());
5364  sendSignal(ref, GSN_ABORT_BACKUP_ORD,
5365  signal, AbortBackupOrd::SignalLength, JBB);
5366  return;
5367  }
5368  jam();
5369  for(c_backups.first(ptr); ptr.i != RNIL; c_backups.next(ptr)) {
5370  jam();
5371  if(ptr.p->backupId == backupId && ptr.p->clientData == senderData) {
5372  jam();
5373  break;
5374  }//if
5375  }//for
5376  if(ptr.i == RNIL) {
5377  jam();
5378  return;
5379  }//if
5380  } else {
5381  if (c_backupPool.findId(senderData)) {
5382  jam();
5383  c_backupPool.getPtr(ptr, senderData);
5384  } else {
5385  jam();
5386 #ifdef DEBUG_ABORT
5387  ndbout_c("Backup: abort request type=%u on id=%u,%u not found",
5388  requestType, backupId, senderData);
5389 #endif
5390  return;
5391  }
5392  }//if
5393 
5394  ptr.p->m_gsn = GSN_ABORT_BACKUP_ORD;
5395  const bool isCoordinator = (ptr.p->masterRef == reference());
5396 
5397  bool ok = false;
5398  switch(requestType){
5399 
5403  case AbortBackupOrd::ClientAbort:
5404  jam();
5405  // fall through
5406  case AbortBackupOrd::LogBufferFull:
5407  jam();
5408  // fall through
5409  case AbortBackupOrd::FileOrScanError:
5410  jam();
5411  ndbrequire(isCoordinator);
5412  ptr.p->setErrorCode(requestType);
5413  if(ptr.p->masterData.gsn == GSN_BACKUP_FRAGMENT_REQ)
5414  {
5418  abort_scan(signal, ptr);
5419  }
5420  return;
5421 
5425  case AbortBackupOrd::AbortScan:
5426  jam();
5427  ptr.p->setErrorCode(requestType);
5428  return;
5429 
5430  case AbortBackupOrd::BackupComplete:
5431  jam();
5432  cleanup(signal, ptr);
5433  return;
5434  case AbortBackupOrd::BackupFailure:
5435  case AbortBackupOrd::BackupFailureDueToNodeFail:
5436  case AbortBackupOrd::OkToClean:
5437  case AbortBackupOrd::IncompatibleVersions:
5438 #ifndef VM_TRACE
5439  default:
5440 #endif
5441  ptr.p->setErrorCode(requestType);
5442  ptr.p->masterData.errorCode = requestType;
5443  ok= true;
5444  }
5445  ndbrequire(ok);
5446 
5447  ptr.p->masterRef = reference();
5448  ptr.p->nodes.clear();
5449  ptr.p->nodes.set(getOwnNodeId());
5450 
5451 
5452  ptr.p->stopGCP= ptr.p->startGCP + 1;
5453  sendStopBackup(signal, ptr);
5454 }
5455 
5456 
5457 void
5458 Backup::dumpUsedResources()
5459 {
5460  jam();
5461  BackupRecordPtr ptr;
5462 
5463  for(c_backups.first(ptr); ptr.i != RNIL; c_backups.next(ptr)) {
5464  ndbout_c("Backup id=%u, slaveState.getState = %u, errorCode=%u",
5465  ptr.p->backupId,
5466  ptr.p->slaveState.getState(),
5467  ptr.p->errorCode);
5468 
5469  TablePtr tabPtr;
5470  for(ptr.p->tables.first(tabPtr);
5471  tabPtr.i != RNIL;
5472  ptr.p->tables.next(tabPtr)) {
5473  jam();
5474  for(Uint32 j = 0; j<3; j++) {
5475  jam();
5476  TriggerPtr trigPtr LINT_SET_PTR;
5477  if(tabPtr.p->triggerAllocated[j]) {
5478  jam();
5479  c_triggerPool.getPtr(trigPtr, tabPtr.p->triggerIds[j]);
5480  ndbout_c("Allocated[%u] Triggerid = %u, event = %u",
5481  j,
5482  tabPtr.p->triggerIds[j],
5483  trigPtr.p->event);
5484  }//if
5485  }//for
5486  }//for
5487 
5488  BackupFilePtr filePtr;
5489  for(ptr.p->files.first(filePtr);
5490  filePtr.i != RNIL;
5491  ptr.p->files.next(filePtr)) {
5492  jam();
5493  ndbout_c("filePtr.i = %u, flags: H'%x ",
5494  filePtr.i, filePtr.p->m_flags);
5495  }//for
5496  }
5497 }
5498 
5499 void
5500 Backup::cleanup(Signal* signal, BackupRecordPtr ptr)
5501 {
5502  TablePtr tabPtr;
5503  ptr.p->tables.first(tabPtr);
5504  cleanupNextTable(signal, ptr, tabPtr);
5505 }
5506 
5507 void
5508 Backup::cleanupNextTable(Signal *signal, BackupRecordPtr ptr, TablePtr tabPtr)
5509 {
5510  if (tabPtr.i != RNIL)
5511  {
5512  jam();
5513  tabPtr.p->fragments.release();
5514  for(Uint32 j = 0; j<3; j++) {
5515  jam();
5516  TriggerPtr trigPtr LINT_SET_PTR;
5517  if(tabPtr.p->triggerAllocated[j]) {
5518  jam();
5519  c_triggerPool.getPtr(trigPtr, tabPtr.p->triggerIds[j]);
5520  trigPtr.p->event = ILLEGAL_TRIGGER_ID;
5521  tabPtr.p->triggerAllocated[j] = false;
5522  }//if
5523  tabPtr.p->triggerIds[j] = ILLEGAL_TRIGGER_ID;
5524  }//for
5525  {
5526  BackupLockTab *req = (BackupLockTab *)signal->getDataPtrSend();
5527  req->m_senderRef = reference();
5528  req->m_tableId = tabPtr.p->tableId;
5529  req->m_lock_unlock = BackupLockTab::UNLOCK_TABLE;
5530  req->m_backup_state = BackupLockTab::CLEANUP;
5531  req->m_backupRecordPtr_I = ptr.i;
5532  req->m_tablePtr_I = tabPtr.i;
5533  sendSignal(DBDICT_REF, GSN_BACKUP_LOCK_TAB_REQ, signal,
5534  BackupLockTab::SignalLength, JBB);
5535  return;
5536  }
5537  }
5538 
5539  BackupFilePtr filePtr;
5540  for(ptr.p->files.first(filePtr);filePtr.i != RNIL;ptr.p->files.next(filePtr))
5541  {
5542  jam();
5543  ndbrequire(filePtr.p->m_flags == 0);
5544  filePtr.p->pages.release();
5545  }//for
5546 
5547  ptr.p->files.release();
5548  ptr.p->tables.release();
5549  ptr.p->triggers.release();
5550  ptr.p->backupId = ~0;
5551 
5552  /*
5553  report of backup status uses these variables to keep track
5554  if files are used
5555  */
5556  ptr.p->ctlFilePtr = ptr.p->logFilePtr = ptr.p->dataFilePtr = RNIL;
5557 
5558  if(ptr.p->checkError())
5559  removeBackup(signal, ptr);
5560  else
5561  {
5562  /*
5563  report of backup status uses these variables to keep track
5564  if backup ia running and current state
5565  */
5566  ptr.p->m_gsn = 0;
5567  ptr.p->masterData.gsn = 0;
5568  c_backups.release(ptr);
5569  }
5570 }
5571 
5572 
5573 void
5574 Backup::removeBackup(Signal* signal, BackupRecordPtr ptr)
5575 {
5576  jam();
5577 
5578  FsRemoveReq * req = (FsRemoveReq *)signal->getDataPtrSend();
5579  req->userReference = reference();
5580  req->userPointer = ptr.i;
5581  req->directory = 1;
5582  req->ownDirectory = 1;
5583  FsOpenReq::setVersion(req->fileNumber, 2);
5584  FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_CTL);
5585  FsOpenReq::v2_setSequence(req->fileNumber, ptr.p->backupId);
5586  FsOpenReq::v2_setNodeId(req->fileNumber, getOwnNodeId());
5587  sendSignal(NDBFS_REF, GSN_FSREMOVEREQ, signal,
5588  FsRemoveReq::SignalLength, JBA);
5589 }
5590 
5591 void
5592 Backup::execFSREMOVEREF(Signal* signal)
5593 {
5594  jamEntry();
5595  FsRef * ref = (FsRef*)signal->getDataPtr();
5596  const Uint32 ptrI = ref->userPointer;
5597 
5598  FsConf * conf = (FsConf*)signal->getDataPtr();
5599  conf->userPointer = ptrI;
5600  execFSREMOVECONF(signal);
5601 }
5602 
5603 void
5605  jamEntry();
5606 
5607  FsConf * conf = (FsConf*)signal->getDataPtr();
5608  const Uint32 ptrI = conf->userPointer;
5609 
5613  BackupRecordPtr ptr LINT_SET_PTR;
5614  c_backupPool.getPtr(ptr, ptrI);
5615  /*
5616  report of backup status uses these variables to keep track
5617  if backup ia running and current state
5618  */
5619  ptr.p->m_gsn = 0;
5620  ptr.p->masterData.gsn = 0;
5621  c_backups.release(ptr);
5622 }
5623 
5627 void
5629 {
5630  jamEntry();
5631  LcpPrepareReq req = *(LcpPrepareReq*)signal->getDataPtr();
5632 
5633  BackupRecordPtr ptr LINT_SET_PTR;
5634  c_backupPool.getPtr(ptr, req.backupPtr);
5635 
5636  ptr.p->m_gsn = GSN_LCP_PREPARE_REQ;
5637 
5638  TablePtr tabPtr;
5639  FragmentPtr fragPtr;
5640  if (!ptr.p->tables.isEmpty())
5641  {
5642  jam();
5643  ndbrequire(ptr.p->errorCode);
5644  ptr.p->tables.first(tabPtr);
5645  if (tabPtr.p->tableId == req.tableId)
5646  {
5647  jam();
5648  ndbrequire(!tabPtr.p->fragments.empty());
5649  tabPtr.p->fragments.getPtr(fragPtr, 0);
5650  fragPtr.p->fragmentId = req.fragmentId;
5651  defineBackupRef(signal, ptr, ptr.p->errorCode);
5652  return;
5653  }
5654  else
5655  {
5656  jam();
5657  tabPtr.p->fragments.release();
5658  ptr.p->tables.release();
5659  ptr.p->errorCode = 0;
5660  // fall-through
5661  }
5662  }
5663 
5664  if(!ptr.p->tables.seize(tabPtr) || !tabPtr.p->fragments.seize(1))
5665  {
5666  if(!tabPtr.isNull())
5667  ptr.p->tables.release();
5668  ndbrequire(false); // TODO
5669  }
5670  tabPtr.p->tableId = req.tableId;
5671  tabPtr.p->fragments.getPtr(fragPtr, 0);
5672  tabPtr.p->tableType = DictTabInfo::UserTable;
5673  fragPtr.p->fragmentId = req.fragmentId;
5674  fragPtr.p->lcp_no = req.lcpNo;
5675  fragPtr.p->scanned = 0;
5676  fragPtr.p->scanning = 0;
5677  fragPtr.p->tableId = req.tableId;
5678 
5679  ptr.p->backupId= req.backupId;
5680  lcp_open_file(signal, ptr);
5681 }
5682 
5683 void
5684 Backup::lcp_close_file_conf(Signal* signal, BackupRecordPtr ptr)
5685 {
5686  jam();
5687 
5688  TablePtr tabPtr;
5689  ndbrequire(ptr.p->tables.first(tabPtr));
5690  Uint32 tableId = tabPtr.p->tableId;
5691 
5692  BackupFilePtr filePtr LINT_SET_PTR;
5693  c_backupFilePool.getPtr(filePtr, ptr.p->dataFilePtr);
5694  ndbrequire(filePtr.p->m_flags == 0);
5695 
5696  if (ptr.p->m_gsn == GSN_LCP_PREPARE_REQ)
5697  {
5698  jam();
5699  defineBackupRef(signal, ptr, ptr.p->errorCode);
5700  return;
5701  }
5702 
5703  FragmentPtr fragPtr;
5704  tabPtr.p->fragments.getPtr(fragPtr, 0);
5705  Uint32 fragmentId = fragPtr.p->fragmentId;
5706 
5707  tabPtr.p->fragments.release();
5708  ptr.p->tables.release();
5709  ptr.p->errorCode = 0;
5710 
5711  BackupFragmentConf * conf = (BackupFragmentConf*)signal->getDataPtrSend();
5712  conf->backupId = ptr.p->backupId;
5713  conf->backupPtr = ptr.i;
5714  conf->tableId = tableId;
5715  conf->fragmentNo = fragmentId;
5716  conf->noOfRecordsLow = 0;
5717  conf->noOfRecordsHigh = 0;
5718  conf->noOfBytesLow = 0;
5719  conf->noOfBytesHigh = 0;
5720  sendSignal(ptr.p->masterRef, GSN_BACKUP_FRAGMENT_CONF, signal,
5721  BackupFragmentConf::SignalLength, JBB);
5722 }
5723 
5724 void
5726 {
5727  FsOpenReq * req = (FsOpenReq *)signal->getDataPtrSend();
5728  req->userReference = reference();
5729  req->fileFlags =
5730  FsOpenReq::OM_WRITEONLY |
5731  FsOpenReq::OM_TRUNCATE |
5732  FsOpenReq::OM_CREATE |
5733  FsOpenReq::OM_APPEND |
5734  FsOpenReq::OM_AUTOSYNC;
5735 
5736  if (c_defaults.m_compressed_lcp)
5737  req->fileFlags |= FsOpenReq::OM_GZ;
5738 
5739  if (c_defaults.m_o_direct)
5740  req->fileFlags |= FsOpenReq::OM_DIRECT;
5741  FsOpenReq::v2_setCount(req->fileNumber, 0xFFFFFFFF);
5742  req->auto_sync_size = c_defaults.m_disk_synch_size;
5743 
5744  TablePtr tabPtr;
5745  FragmentPtr fragPtr;
5746 
5747  ndbrequire(ptr.p->tables.first(tabPtr));
5748  tabPtr.p->fragments.getPtr(fragPtr, 0);
5749 
5753  BackupFilePtr filePtr LINT_SET_PTR;
5754  c_backupFilePool.getPtr(filePtr, ptr.p->dataFilePtr);
5755  ndbrequire(filePtr.p->m_flags == 0);
5756  filePtr.p->m_flags |= BackupFile::BF_OPENING;
5757  filePtr.p->tableId = RNIL; // Will force init
5758  req->userPointer = filePtr.i;
5759  FsOpenReq::setVersion(req->fileNumber, 5);
5760  FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_DATA);
5761  FsOpenReq::v5_setLcpNo(req->fileNumber, fragPtr.p->lcp_no);
5762  FsOpenReq::v5_setTableId(req->fileNumber, tabPtr.p->tableId);
5763  FsOpenReq::v5_setFragmentId(req->fileNumber, fragPtr.p->fragmentId);
5764  sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
5765 }
5766 
5767 void
5769 {
5770  TablePtr tabPtr;
5771  FragmentPtr fragPtr;
5772 
5773  ndbrequire(ptr.p->tables.first(tabPtr));
5774  tabPtr.p->fragments.getPtr(fragPtr, 0);
5775 
5776  BackupFilePtr filePtr LINT_SET_PTR;
5777  c_backupFilePool.getPtr(filePtr, ptr.p->dataFilePtr);
5778  ndbrequire(filePtr.p->m_flags ==
5779  (BackupFile::BF_OPEN | BackupFile::BF_LCP_META));
5780  filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_LCP_META;
5781 
5782  ptr.p->slaveState.setState(STARTED);
5783 
5784  LcpPrepareConf* conf= (LcpPrepareConf*)signal->getDataPtrSend();
5785  conf->senderData = ptr.p->clientData;
5786  conf->senderRef = reference();
5787  conf->tableId = tabPtr.p->tableId;
5788  conf->fragmentId = fragPtr.p->fragmentId;
5789  sendSignal(ptr.p->masterRef, GSN_LCP_PREPARE_CONF,
5790  signal, LcpPrepareConf::SignalLength, JBB);
5791 
5795  filePtr.p->m_flags |= BackupFile::BF_FILE_THREAD;
5796 
5797  signal->theData[0] = BackupContinueB::START_FILE_THREAD;
5798  signal->theData[1] = filePtr.i;
5799  signal->theData[2] = __LINE__;
5800  sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 3);
5801 }
5802 
5803 void
5804 Backup::execEND_LCPREQ(Signal* signal)
5805 {
5806  EndLcpReq* req= (EndLcpReq*)signal->getDataPtr();
5807 
5808  BackupRecordPtr ptr LINT_SET_PTR;
5809  c_backupPool.getPtr(ptr, req->backupPtr);
5810  ndbrequire(ptr.p->backupId == req->backupId);
5811 
5812  BackupFilePtr filePtr LINT_SET_PTR;
5813  ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
5814  ndbrequire(filePtr.p->m_flags == 0);
5815 
5816  if (!ptr.p->tables.isEmpty())
5817  {
5818  jam();
5819  ndbrequire(ptr.p->errorCode);
5820  TablePtr tabPtr;
5821  ptr.p->tables.first(tabPtr);
5822  tabPtr.p->fragments.release();
5823  ptr.p->tables.release();
5824  ptr.p->errorCode = 0;
5825  }
5826 
5827  ptr.p->errorCode = 0;
5828  ptr.p->slaveState.setState(CLEANING);
5829  ptr.p->slaveState.setState(INITIAL);
5830  ptr.p->slaveState.setState(DEFINING);
5831  ptr.p->slaveState.setState(DEFINED);
5832 
5833  EndLcpConf* conf= (EndLcpConf*)signal->getDataPtr();
5834  conf->senderData = ptr.p->clientData;
5835  conf->senderRef = reference();
5836  sendSignal(ptr.p->masterRef, GSN_END_LCPCONF,
5837  signal, EndLcpConf::SignalLength, JBB);
5838 }