00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "Backup.hpp"
00018
00019 #include <ndb_version.h>
00020
00021 #include <NdbTCP.h>
00022 #include <Bitmask.hpp>
00023
00024 #include <signaldata/NodeFailRep.hpp>
00025 #include <signaldata/ReadNodesConf.hpp>
00026
00027 #include <signaldata/ScanFrag.hpp>
00028
00029 #include <signaldata/GetTabInfo.hpp>
00030 #include <signaldata/DictTabInfo.hpp>
00031 #include <signaldata/ListTables.hpp>
00032
00033 #include <signaldata/FsOpenReq.hpp>
00034 #include <signaldata/FsAppendReq.hpp>
00035 #include <signaldata/FsCloseReq.hpp>
00036 #include <signaldata/FsConf.hpp>
00037 #include <signaldata/FsRef.hpp>
00038 #include <signaldata/FsRemoveReq.hpp>
00039
00040 #include <signaldata/BackupImpl.hpp>
00041 #include <signaldata/BackupSignalData.hpp>
00042 #include <signaldata/BackupContinueB.hpp>
00043 #include <signaldata/EventReport.hpp>
00044
00045 #include <signaldata/UtilSequence.hpp>
00046
00047 #include <signaldata/CreateTrig.hpp>
00048 #include <signaldata/AlterTrig.hpp>
00049 #include <signaldata/DropTrig.hpp>
00050 #include <signaldata/FireTrigOrd.hpp>
00051 #include <signaldata/TrigAttrInfo.hpp>
00052 #include <AttributeHeader.hpp>
00053
00054 #include <signaldata/WaitGCP.hpp>
00055
00056 #include <NdbTick.h>
00057
00058 static NDB_TICKS startTime;
00059
00060 static const Uint32 BACKUP_SEQUENCE = 0x1F000000;
00061
00062 #ifdef VM_TRACE
00063 #define DEBUG_OUT(x) ndbout << x << endl
00064 #else
00065 #define DEBUG_OUT(x)
00066 #endif
00067
00068
00069
00070 static Uint32 g_TypeOfStart = NodeState::ST_ILLEGAL_TYPE;
00071
00072 void
00073 Backup::execSTTOR(Signal* signal)
00074 {
00075 jamEntry();
00076
00077 const Uint32 startphase = signal->theData[1];
00078 const Uint32 typeOfStart = signal->theData[7];
00079
00080 if (startphase == 3) {
00081 jam();
00082 g_TypeOfStart = typeOfStart;
00083 signal->theData[0] = reference();
00084 sendSignal(NDBCNTR_REF, GSN_READ_NODESREQ, signal, 1, JBB);
00085 return;
00086 }
00087
00088 if(startphase == 7 && g_TypeOfStart == NodeState::ST_INITIAL_START &&
00089 c_masterNodeId == getOwnNodeId()){
00090 jam();
00091 createSequence(signal);
00092 return;
00093 }
00094
00095 sendSTTORRY(signal);
00096 return;
00097 }
00098
00099 void
00100 Backup::execREAD_NODESCONF(Signal* signal)
00101 {
00102 jamEntry();
00103 ReadNodesConf * conf = (ReadNodesConf *)signal->getDataPtr();
00104
00105 c_aliveNodes.clear();
00106
00107 Uint32 count = 0;
00108 for (Uint32 i = 0; i<MAX_NDB_NODES; i++) {
00109 jam();
00110 if(NodeBitmask::get(conf->allNodes, i)){
00111 jam();
00112 count++;
00113
00114 NodePtr node;
00115 ndbrequire(c_nodes.seize(node));
00116
00117 node.p->nodeId = i;
00118 if(NodeBitmask::get(conf->inactiveNodes, i)) {
00119 jam();
00120 node.p->alive = 0;
00121 } else {
00122 jam();
00123 node.p->alive = 1;
00124 c_aliveNodes.set(i);
00125 }
00126 }
00127 }
00128 c_masterNodeId = conf->masterNodeId;
00129 ndbrequire(count == conf->noOfNodes);
00130 sendSTTORRY(signal);
00131 }
00132
00133 void
00134 Backup::sendSTTORRY(Signal* signal)
00135 {
00136 signal->theData[0] = 0;
00137 signal->theData[3] = 1;
00138 signal->theData[4] = 3;
00139 signal->theData[5] = 7;
00140 signal->theData[6] = 255;
00141 sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 7, JBB);
00142 }
00143
00144 void
00145 Backup::createSequence(Signal* signal)
00146 {
00147 UtilSequenceReq * req = (UtilSequenceReq*)signal->getDataPtrSend();
00148
00149 req->senderData = RNIL;
00150 req->sequenceId = BACKUP_SEQUENCE;
00151 req->requestType = UtilSequenceReq::Create;
00152
00153 sendSignal(DBUTIL_REF, GSN_UTIL_SEQUENCE_REQ,
00154 signal, UtilSequenceReq::SignalLength, JBB);
00155 }
00156
00157 void
00158 Backup::execCONTINUEB(Signal* signal)
00159 {
00160 jamEntry();
00161 const Uint32 Tdata0 = signal->theData[0];
00162 const Uint32 Tdata1 = signal->theData[1];
00163 const Uint32 Tdata2 = signal->theData[2];
00164
00165 switch(Tdata0) {
00166 case BackupContinueB::START_FILE_THREAD:
00167 case BackupContinueB::BUFFER_UNDERFLOW:
00168 {
00169 jam();
00170 BackupFilePtr filePtr;
00171 c_backupFilePool.getPtr(filePtr, Tdata1);
00172 checkFile(signal, filePtr);
00173 return;
00174 }
00175 break;
00176 case BackupContinueB::BUFFER_FULL_SCAN:
00177 {
00178 jam();
00179 BackupFilePtr filePtr;
00180 c_backupFilePool.getPtr(filePtr, Tdata1);
00181 checkScan(signal, filePtr);
00182 return;
00183 }
00184 break;
00185 case BackupContinueB::BUFFER_FULL_FRAG_COMPLETE:
00186 {
00187 jam();
00188 BackupFilePtr filePtr;
00189 c_backupFilePool.getPtr(filePtr, Tdata1);
00190 fragmentCompleted(signal, filePtr);
00191 return;
00192 }
00193 break;
00194 case BackupContinueB::BUFFER_FULL_META:
00195 {
00196 jam();
00197 BackupRecordPtr ptr;
00198 c_backupPool.getPtr(ptr, Tdata1);
00199
00200 BackupFilePtr filePtr;
00201 ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
00202 FsBuffer & buf = filePtr.p->operation.dataBuffer;
00203
00204 if(buf.getFreeSize() + buf.getMinRead() < buf.getUsableSize()) {
00205 jam();
00206 TablePtr tabPtr;
00207 c_tablePool.getPtr(tabPtr, Tdata2);
00208
00209 DEBUG_OUT("Backup - Buffer full - " << buf.getFreeSize()
00210 << " + " << buf.getMinRead()
00211 << " < " << buf.getUsableSize()
00212 << " - tableId = " << tabPtr.p->tableId);
00213
00214 signal->theData[0] = BackupContinueB::BUFFER_FULL_META;
00215 signal->theData[1] = Tdata1;
00216 signal->theData[2] = Tdata2;
00217 sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 100, 3);
00218 return;
00219 }
00220
00221 TablePtr tabPtr;
00222 c_tablePool.getPtr(tabPtr, Tdata2);
00223 GetTabInfoReq * req = (GetTabInfoReq *)signal->getDataPtrSend();
00224 req->senderRef = reference();
00225 req->senderData = ptr.i;
00226 req->requestType = GetTabInfoReq::RequestById |
00227 GetTabInfoReq::LongSignalConf;
00228 req->tableId = tabPtr.p->tableId;
00229 sendSignal(DBDICT_REF, GSN_GET_TABINFOREQ, signal,
00230 GetTabInfoReq::SignalLength, JBB);
00231 return;
00232 }
00233 default:
00234 ndbrequire(0);
00235 }
00236 }
00237
00238 void
00239 Backup::execDUMP_STATE_ORD(Signal* signal)
00240 {
00241 jamEntry();
00242
00243 if(signal->theData[0] == 20){
00244 if(signal->length() > 1){
00245 c_defaults.m_dataBufferSize = (signal->theData[1] * 1024 * 1024);
00246 }
00247 if(signal->length() > 2){
00248 c_defaults.m_logBufferSize = (signal->theData[2] * 1024 * 1024);
00249 }
00250 if(signal->length() > 3){
00251 c_defaults.m_minWriteSize = signal->theData[3] * 1024;
00252 }
00253 if(signal->length() > 4){
00254 c_defaults.m_maxWriteSize = signal->theData[4] * 1024;
00255 }
00256
00257 infoEvent("Backup: data: %d log: %d min: %d max: %d",
00258 c_defaults.m_dataBufferSize,
00259 c_defaults.m_logBufferSize,
00260 c_defaults.m_minWriteSize,
00261 c_defaults.m_maxWriteSize);
00262 return;
00263 }
00264 if(signal->theData[0] == 21){
00265 BackupReq * req = (BackupReq*)signal->getDataPtrSend();
00266 req->senderData = 23;
00267 req->backupDataLen = 0;
00268 sendSignal(BACKUP_REF, GSN_BACKUP_REQ,signal,BackupReq::SignalLength, JBB);
00269 startTime = NdbTick_CurrentMillisecond();
00270 return;
00271 }
00272
00273 if(signal->theData[0] == 22){
00274 const Uint32 seq = signal->theData[1];
00275 FsRemoveReq * req = (FsRemoveReq *)signal->getDataPtrSend();
00276 req->userReference = reference();
00277 req->userPointer = 23;
00278 req->directory = 1;
00279 req->ownDirectory = 1;
00280 FsOpenReq::setVersion(req->fileNumber, 2);
00281 FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_CTL);
00282 FsOpenReq::v2_setSequence(req->fileNumber, seq);
00283 FsOpenReq::v2_setNodeId(req->fileNumber, getOwnNodeId());
00284 sendSignal(NDBFS_REF, GSN_FSREMOVEREQ, signal,
00285 FsRemoveReq::SignalLength, JBA);
00286 return;
00287 }
00288
00289 if(signal->theData[0] == 23){
00293 BackupRecordPtr ptr;
00294 for(c_backups.first(ptr); ptr.i != RNIL; c_backups.next(ptr)){
00295 infoEvent("BackupRecord %d: BackupId: %d MasterRef: %x ClientRef: %x",
00296 ptr.i, ptr.p->backupId, ptr.p->masterRef, ptr.p->clientRef);
00297 infoEvent(" State: %d", ptr.p->slaveState.getState());
00298 BackupFilePtr filePtr;
00299 for(ptr.p->files.first(filePtr); filePtr.i != RNIL;
00300 ptr.p->files.next(filePtr)){
00301 jam();
00302 infoEvent(" file %d: type: %d open: %d running: %d done: %d scan: %d",
00303 filePtr.i, filePtr.p->fileType, filePtr.p->fileOpened,
00304 filePtr.p->fileRunning,
00305 filePtr.p->fileClosing, filePtr.p->scanRunning);
00306 }
00307 }
00308 }
00309 if(signal->theData[0] == 24){
00313 infoEvent("Backup - dump pool sizes");
00314 infoEvent("BackupPool: %d BackupFilePool: %d TablePool: %d",
00315 c_backupPool.getSize(), c_backupFilePool.getSize(),
00316 c_tablePool.getSize());
00317 infoEvent("AttrPool: %d TriggerPool: %d FragmentPool: %d",
00318 c_backupPool.getSize(), c_backupFilePool.getSize(),
00319 c_tablePool.getSize());
00320 infoEvent("PagePool: %d",
00321 c_pagePool.getSize());
00322
00323
00324 if(signal->getLength() == 2 && signal->theData[1] == 2424)
00325 {
00326 ndbrequire(c_tablePool.getSize() == c_tablePool.getNoOfFree());
00327 ndbrequire(c_attributePool.getSize() == c_attributePool.getNoOfFree());
00328 ndbrequire(c_backupPool.getSize() == c_backupPool.getNoOfFree());
00329 ndbrequire(c_backupFilePool.getSize() == c_backupFilePool.getNoOfFree());
00330 ndbrequire(c_pagePool.getSize() == c_pagePool.getNoOfFree());
00331 ndbrequire(c_fragmentPool.getSize() == c_fragmentPool.getNoOfFree());
00332 ndbrequire(c_triggerPool.getSize() == c_triggerPool.getNoOfFree());
00333 }
00334 }
00335 }
00336
00337 bool
00338 Backup::findTable(const BackupRecordPtr & ptr,
00339 TablePtr & tabPtr, Uint32 tableId) const
00340 {
00341 for(ptr.p->tables.first(tabPtr);
00342 tabPtr.i != RNIL;
00343 ptr.p->tables.next(tabPtr)) {
00344 jam();
00345 if(tabPtr.p->tableId == tableId){
00346 jam();
00347 return true;
00348 }
00349 }
00350 tabPtr.i = RNIL;
00351 tabPtr.p = 0;
00352 return false;
00353 }
00354
00355 static Uint32 xps(Uint32 x, Uint64 ms)
00356 {
00357 float fx = x;
00358 float fs = ms;
00359
00360 if(ms == 0 || x == 0) {
00361 jam();
00362 return 0;
00363 }
00364 jam();
00365 return ((Uint32)(1000.0f * (fx + fs/2.1f))) / ((Uint32)fs);
00366 }
00367
00368 struct Number {
00369 Number(Uint32 r) { val = r;}
00370 Number & operator=(Uint32 r) { val = r; return * this; }
00371 Uint32 val;
00372 };
00373
00374 NdbOut &
00375 operator<< (NdbOut & out, const Number & val){
00376 char p = 0;
00377 Uint32 loop = 1;
00378 while(val.val > loop){
00379 loop *= 1000;
00380 p += 3;
00381 }
00382 if(loop != 1){
00383 p -= 3;
00384 loop /= 1000;
00385 }
00386
00387 switch(p){
00388 case 0:
00389 break;
00390 case 3:
00391 p = 'k';
00392 break;
00393 case 6:
00394 p = 'M';
00395 break;
00396 case 9:
00397 p = 'G';
00398 break;
00399 default:
00400 p = 0;
00401 }
00402 char str[2];
00403 str[0] = p;
00404 str[1] = 0;
00405 Uint32 tmp = (val.val + (loop >> 1)) / loop;
00406 #if 1
00407 if(p > 0)
00408 out << tmp << str;
00409 else
00410 out << tmp;
00411 #else
00412 out << val.val;
00413 #endif
00414
00415 return out;
00416 }
00417
00418 void
00419 Backup::execBACKUP_CONF(Signal* signal)
00420 {
00421 jamEntry();
00422 BackupConf * conf = (BackupConf*)signal->getDataPtr();
00423
00424 ndbout_c("Backup %d has started", conf->backupId);
00425 }
00426
00427 void
00428 Backup::execBACKUP_REF(Signal* signal)
00429 {
00430 jamEntry();
00431 BackupRef * ref = (BackupRef*)signal->getDataPtr();
00432
00433 ndbout_c("Backup (%d) has NOT started %d", ref->senderData, ref->errorCode);
00434 }
00435
00436 void
00437 Backup::execBACKUP_COMPLETE_REP(Signal* signal)
00438 {
00439 jamEntry();
00440 BackupCompleteRep* rep = (BackupCompleteRep*)signal->getDataPtr();
00441
00442 startTime = NdbTick_CurrentMillisecond() - startTime;
00443
00444 ndbout_c("Backup %d has completed", rep->backupId);
00445 const Uint32 bytes = rep->noOfBytes;
00446 const Uint32 records = rep->noOfRecords;
00447
00448 Number rps = xps(records, startTime);
00449 Number bps = xps(bytes, startTime);
00450
00451 ndbout << " Data [ "
00452 << Number(records) << " rows "
00453 << Number(bytes) << " bytes " << startTime << " ms ] "
00454 << " => "
00455 << rps << " row/s & " << bps << "b/s" << endl;
00456
00457 bps = xps(rep->noOfLogBytes, startTime);
00458 rps = xps(rep->noOfLogRecords, startTime);
00459
00460 ndbout << " Log [ "
00461 << Number(rep->noOfLogRecords) << " log records "
00462 << Number(rep->noOfLogBytes) << " bytes " << startTime << " ms ] "
00463 << " => "
00464 << rps << " records/s & " << bps << "b/s" << endl;
00465
00466 }
00467
00468 void
00469 Backup::execBACKUP_ABORT_REP(Signal* signal)
00470 {
00471 jamEntry();
00472 BackupAbortRep* rep = (BackupAbortRep*)signal->getDataPtr();
00473
00474 ndbout_c("Backup %d has been aborted %d", rep->backupId, rep->reason);
00475 }
00476
00477 const TriggerEvent::Value triggerEventValues[] = {
00478 TriggerEvent::TE_INSERT,
00479 TriggerEvent::TE_UPDATE,
00480 TriggerEvent::TE_DELETE
00481 };
00482
00483 const char* triggerNameFormat[] = {
00484 "NDB$BACKUP_%d_%d_INSERT",
00485 "NDB$BACKUP_%d_%d_UPDATE",
00486 "NDB$BACKUP_%d_%d_DELETE"
00487 };
00488
00489 const Backup::State
00490 Backup::validSlaveTransitions[] = {
00491 INITIAL, DEFINING,
00492 DEFINING, DEFINED,
00493 DEFINED, STARTED,
00494 STARTED, STARTED,
00495 STARTED, SCANNING,
00496 SCANNING, STARTED,
00497 STARTED, STOPPING,
00498 STOPPING, CLEANING,
00499 CLEANING, INITIAL,
00500
00501 INITIAL, ABORTING,
00502 DEFINING, ABORTING,
00503 DEFINED, ABORTING,
00504 STARTED, ABORTING,
00505 SCANNING, ABORTING,
00506 STOPPING, ABORTING,
00507 CLEANING, ABORTING,
00508 ABORTING, ABORTING,
00509
00510 ABORTING, INITIAL,
00511 INITIAL, INITIAL
00512 };
00513
00514 const Uint32
00515 Backup::validSlaveTransitionsCount =
00516 sizeof(Backup::validSlaveTransitions) / sizeof(Backup::State);
00517
00518 void
00519 Backup::CompoundState::setState(State newState){
00520 bool found = false;
00521 const State currState = state;
00522 for(unsigned i = 0; i<noOfValidTransitions; i+= 2) {
00523 jam();
00524 if(validTransitions[i] == currState &&
00525 validTransitions[i+1] == newState){
00526 jam();
00527 found = true;
00528 break;
00529 }
00530 }
00531
00532
00533
00534 if (newState == INITIAL)
00535 abortState = INITIAL;
00536 if(newState == ABORTING && currState != ABORTING) {
00537 jam();
00538 abortState = currState;
00539 }
00540 state = newState;
00541 #ifdef DEBUG_ABORT
00542 if (newState != currState) {
00543 ndbout_c("%u: Old state = %u, new state = %u, abort state = %u",
00544 id, currState, newState, abortState);
00545 }
00546 #endif
00547 }
00548
00549 void
00550 Backup::CompoundState::forceState(State newState)
00551 {
00552 const State currState = state;
00553 if (newState == INITIAL)
00554 abortState = INITIAL;
00555 if(newState == ABORTING && currState != ABORTING) {
00556 jam();
00557 abortState = currState;
00558 }
00559 state = newState;
00560 #ifdef DEBUG_ABORT
00561 if (newState != currState) {
00562 ndbout_c("%u: FORCE: Old state = %u, new state = %u, abort state = %u",
00563 id, currState, newState, abortState);
00564 }
00565 #endif
00566 }
00567
00568 Backup::Table::Table(ArrayPool<Attribute> & ah,
00569 ArrayPool<Fragment> & fh)
00570 : attributes(ah), fragments(fh)
00571 {
00572 triggerIds[0] = ILLEGAL_TRIGGER_ID;
00573 triggerIds[1] = ILLEGAL_TRIGGER_ID;
00574 triggerIds[2] = ILLEGAL_TRIGGER_ID;
00575 triggerAllocated[0] = false;
00576 triggerAllocated[1] = false;
00577 triggerAllocated[2] = false;
00578 }
00579
00580
00581
00582
00583
00584
00585 void
00586 Backup::execNODE_FAILREP(Signal* signal)
00587 {
00588 jamEntry();
00589
00590 NodeFailRep * rep = (NodeFailRep*)signal->getDataPtr();
00591
00592 bool doStuff = false;
00593
00594
00595
00596
00597 NodeId new_master_node_id = rep->masterNodeId;
00598 Uint32 theFailedNodes[NodeBitmask::Size];
00599 for (Uint32 i = 0; i < NodeBitmask::Size; i++)
00600 theFailedNodes[i] = rep->theNodes[i];
00601
00602 c_masterNodeId = new_master_node_id;
00603
00604 NodePtr nodePtr;
00605 for(c_nodes.first(nodePtr); nodePtr.i != RNIL; c_nodes.next(nodePtr)) {
00606 jam();
00607 if(NodeBitmask::get(theFailedNodes, nodePtr.p->nodeId)){
00608 if(nodePtr.p->alive){
00609 jam();
00610 ndbrequire(c_aliveNodes.get(nodePtr.p->nodeId));
00611 doStuff = true;
00612 } else {
00613 jam();
00614 ndbrequire(!c_aliveNodes.get(nodePtr.p->nodeId));
00615 }
00616 nodePtr.p->alive = 0;
00617 c_aliveNodes.clear(nodePtr.p->nodeId);
00618 }
00619 }
00620
00621 if(!doStuff){
00622 jam();
00623 return;
00624 }
00625
00626 #ifdef DEBUG_ABORT
00627 ndbout_c("****************** Node fail rep ******************");
00628 #endif
00629
00630 NodeId newCoordinator = c_masterNodeId;
00631 BackupRecordPtr ptr;
00632 for(c_backups.first(ptr); ptr.i != RNIL; c_backups.next(ptr)) {
00633 jam();
00634 checkNodeFail(signal, ptr, newCoordinator, theFailedNodes);
00635 }
00636 }
00637
00638 bool
00639 Backup::verifyNodesAlive(BackupRecordPtr ptr,
00640 const NdbNodeBitmask& aNodeBitMask)
00641 {
00642 Uint32 version = getNodeInfo(getOwnNodeId()).m_version;
00643 for (Uint32 i = 0; i < MAX_NDB_NODES; i++) {
00644 jam();
00645 if(aNodeBitMask.get(i)) {
00646 if(!c_aliveNodes.get(i)){
00647 jam();
00648 ptr.p->setErrorCode(AbortBackupOrd::BackupFailureDueToNodeFail);
00649 return false;
00650 }
00651 if(getNodeInfo(i).m_version != version)
00652 {
00653 jam();
00654 ptr.p->setErrorCode(AbortBackupOrd::IncompatibleVersions);
00655 return false;
00656 }
00657 }
00658 }
00659 return true;
00660 }
00661
00662 void
00663 Backup::checkNodeFail(Signal* signal,
00664 BackupRecordPtr ptr,
00665 NodeId newCoord,
00666 Uint32 theFailedNodes[NodeBitmask::Size])
00667 {
00668 NdbNodeBitmask mask;
00669 mask.assign(2, theFailedNodes);
00670
00671
00672
00673 NodePtr nodePtr;
00674 bool found = false;
00675 for(c_nodes.first(nodePtr); nodePtr.i != RNIL; c_nodes.next(nodePtr)) {
00676 jam();
00677 if(NodeBitmask::get(theFailedNodes, nodePtr.p->nodeId)) {
00678 jam();
00679 if (ptr.p->nodes.get(nodePtr.p->nodeId)) {
00680 jam();
00681 ptr.p->nodes.clear(nodePtr.p->nodeId);
00682 found = true;
00683 }
00684 }
00685 }
00686
00687 if(!found) {
00688 jam();
00689 return;
00690 }
00691
00692 if(mask.get(refToNode(ptr.p->masterRef)))
00693 {
00697 ptr.p->masterRef = reference();
00698 ptr.p->nodes.clear();
00699 ptr.p->nodes.set(getOwnNodeId());
00700 ptr.p->setErrorCode(AbortBackupOrd::BackupFailureDueToNodeFail);
00701 switch(ptr.p->m_gsn){
00702 case GSN_DEFINE_BACKUP_REQ:
00703 case GSN_START_BACKUP_REQ:
00704 case GSN_BACKUP_FRAGMENT_REQ:
00705 case GSN_STOP_BACKUP_REQ:
00706
00707 ptr.p->masterData.gsn = ptr.p->m_gsn;
00708 ptr.p->masterData.sendCounter = ptr.p->nodes;
00709 return;
00710 case GSN_DEFINE_BACKUP_REF:
00711 case GSN_DEFINE_BACKUP_CONF:
00712 case GSN_START_BACKUP_REF:
00713 case GSN_START_BACKUP_CONF:
00714 case GSN_BACKUP_FRAGMENT_REF:
00715 case GSN_BACKUP_FRAGMENT_CONF:
00716 case GSN_STOP_BACKUP_REF:
00717 case GSN_STOP_BACKUP_CONF:
00718 ptr.p->masterData.gsn = GSN_DEFINE_BACKUP_REQ;
00719 masterAbort(signal, ptr);
00720 return;
00721 case GSN_ABORT_BACKUP_ORD:
00722
00723 return;
00724 }
00725 }
00726 else if (newCoord == getOwnNodeId())
00727 {
00731 jam();
00732 CRASH_INSERTION((10001));
00733 #ifdef DEBUG_ABORT
00734 ndbout_c("**** Master: Node failed: Master id = %u",
00735 refToNode(ptr.p->masterRef));
00736 #endif
00737
00738 Uint32 gsn, len, pos;
00739 ptr.p->nodes.bitANDC(mask);
00740 switch(ptr.p->masterData.gsn){
00741 case GSN_DEFINE_BACKUP_REQ:
00742 {
00743 DefineBackupRef * ref = (DefineBackupRef*)signal->getDataPtr();
00744 ref->backupPtr = ptr.i;
00745 ref->backupId = ptr.p->backupId;
00746 ref->errorCode = AbortBackupOrd::BackupFailureDueToNodeFail;
00747 gsn= GSN_DEFINE_BACKUP_REF;
00748 len= DefineBackupRef::SignalLength;
00749 pos= &ref->nodeId - signal->getDataPtr();
00750 break;
00751 }
00752 case GSN_START_BACKUP_REQ:
00753 {
00754 StartBackupRef * ref = (StartBackupRef*)signal->getDataPtr();
00755 ref->backupPtr = ptr.i;
00756 ref->backupId = ptr.p->backupId;
00757 ref->errorCode = AbortBackupOrd::BackupFailureDueToNodeFail;
00758 ref->signalNo = ptr.p->masterData.startBackup.signalNo;
00759 gsn= GSN_START_BACKUP_REF;
00760 len= StartBackupRef::SignalLength;
00761 pos= &ref->nodeId - signal->getDataPtr();
00762 break;
00763 }
00764 case GSN_BACKUP_FRAGMENT_REQ:
00765 {
00766 BackupFragmentRef * ref = (BackupFragmentRef*)signal->getDataPtr();
00767 ref->backupPtr = ptr.i;
00768 ref->backupId = ptr.p->backupId;
00769 ref->errorCode = AbortBackupOrd::BackupFailureDueToNodeFail;
00770 gsn= GSN_BACKUP_FRAGMENT_REF;
00771 len= BackupFragmentRef::SignalLength;
00772 pos= &ref->nodeId - signal->getDataPtr();
00773 break;
00774 }
00775 case GSN_STOP_BACKUP_REQ:
00776 {
00777 StopBackupRef * ref = (StopBackupRef*)signal->getDataPtr();
00778 ref->backupPtr = ptr.i;
00779 ref->backupId = ptr.p->backupId;
00780 ref->errorCode = AbortBackupOrd::BackupFailureDueToNodeFail;
00781 gsn= GSN_STOP_BACKUP_REF;
00782 len= StopBackupRef::SignalLength;
00783 pos= &ref->nodeId - signal->getDataPtr();
00784 break;
00785 }
00786 case GSN_CREATE_TRIG_REQ:
00787 case GSN_ALTER_TRIG_REQ:
00788 case GSN_WAIT_GCP_REQ:
00789 case GSN_UTIL_SEQUENCE_REQ:
00790 case GSN_UTIL_LOCK_REQ:
00791 case GSN_DROP_TRIG_REQ:
00792 return;
00793 }
00794
00795 for(Uint32 i = 0; (i = mask.find(i+1)) != NdbNodeBitmask::NotFound; )
00796 {
00797 signal->theData[pos] = i;
00798 sendSignal(reference(), gsn, signal, len, JBB);
00799 #ifdef DEBUG_ABORT
00800 ndbout_c("sending %d to self from %d", gsn, i);
00801 #endif
00802 }
00803 return;
00804 }
00805
00809 CRASH_INSERTION((10021));
00810 }
00811
00812 void
00813 Backup::execINCL_NODEREQ(Signal* signal)
00814 {
00815 jamEntry();
00816
00817 const Uint32 senderRef = signal->theData[0];
00818 const Uint32 inclNode = signal->theData[1];
00819
00820 NodePtr node;
00821 for(c_nodes.first(node); node.i != RNIL; c_nodes.next(node)) {
00822 jam();
00823 const Uint32 nodeId = node.p->nodeId;
00824 if(inclNode == nodeId){
00825 jam();
00826
00827 ndbrequire(node.p->alive == 0);
00828 ndbrequire(!c_aliveNodes.get(nodeId));
00829
00830 node.p->alive = 1;
00831 c_aliveNodes.set(nodeId);
00832
00833 break;
00834 }
00835 }
00836 signal->theData[0] = reference();
00837 sendSignal(senderRef, GSN_INCL_NODECONF, signal, 1, JBB);
00838 }
00839
00840
00841
00842
00843
00844
00845
00846 void
00847 Backup::execBACKUP_REQ(Signal* signal)
00848 {
00849 jamEntry();
00850 BackupReq * req = (BackupReq*)signal->getDataPtr();
00851
00852 const Uint32 senderData = req->senderData;
00853 const BlockReference senderRef = signal->senderBlockRef();
00854 const Uint32 dataLen32 = req->backupDataLen;
00855
00856 if(getOwnNodeId() != getMasterNodeId()) {
00857 jam();
00858 sendBackupRef(senderRef, signal, senderData, BackupRef::IAmNotMaster);
00859 return;
00860 }
00861
00862 if (m_diskless)
00863 {
00864 sendBackupRef(senderRef, signal, senderData,
00865 BackupRef::CannotBackupDiskless);
00866 return;
00867 }
00868
00869 if(dataLen32 != 0) {
00870 jam();
00871 sendBackupRef(senderRef, signal, senderData,
00872 BackupRef::BackupDefinitionNotImplemented);
00873 return;
00874 }
00875
00876 #ifdef DEBUG_ABORT
00877 dumpUsedResources();
00878 #endif
00879
00882 BackupRecordPtr ptr;
00883 c_backups.seize(ptr);
00884 if(ptr.i == RNIL) {
00885 jam();
00886 sendBackupRef(senderRef, signal, senderData, BackupRef::OutOfBackupRecord);
00887 return;
00888 }
00889
00890 ndbrequire(ptr.p->pages.empty());
00891 ndbrequire(ptr.p->tables.isEmpty());
00892
00893 ptr.p->m_gsn = 0;
00894 ptr.p->errorCode = 0;
00895 ptr.p->clientRef = senderRef;
00896 ptr.p->clientData = senderData;
00897 ptr.p->masterRef = reference();
00898 ptr.p->nodes = c_aliveNodes;
00899 ptr.p->backupId = 0;
00900 ptr.p->backupKey[0] = 0;
00901 ptr.p->backupKey[1] = 0;
00902 ptr.p->backupDataLen = 0;
00903 ptr.p->masterData.errorCode = 0;
00904 ptr.p->masterData.dropTrig.tableId = RNIL;
00905 ptr.p->masterData.alterTrig.tableId = RNIL;
00906
00907 UtilSequenceReq * utilReq = (UtilSequenceReq*)signal->getDataPtrSend();
00908
00909 ptr.p->masterData.gsn = GSN_UTIL_SEQUENCE_REQ;
00910 utilReq->senderData = ptr.i;
00911 utilReq->sequenceId = BACKUP_SEQUENCE;
00912 utilReq->requestType = UtilSequenceReq::NextVal;
00913 sendSignal(DBUTIL_REF, GSN_UTIL_SEQUENCE_REQ,
00914 signal, UtilSequenceReq::SignalLength, JBB);
00915 }
00916
00917 void
00918 Backup::execUTIL_SEQUENCE_REF(Signal* signal)
00919 {
00920 BackupRecordPtr ptr;
00921 jamEntry();
00922 UtilSequenceRef * utilRef = (UtilSequenceRef*)signal->getDataPtr();
00923 ptr.i = utilRef->senderData;
00924 ndbrequire(ptr.i == RNIL);
00925 c_backupPool.getPtr(ptr);
00926 ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_SEQUENCE_REQ);
00927 sendBackupRef(signal, ptr, BackupRef::SequenceFailure);
00928 }
00929
00930
00931 void
00932 Backup::sendBackupRef(Signal* signal, BackupRecordPtr ptr, Uint32 errorCode)
00933 {
00934 jam();
00935 sendBackupRef(ptr.p->clientRef, signal, ptr.p->clientData, errorCode);
00936 cleanup(signal, ptr);
00937 }
00938
00939 void
00940 Backup::sendBackupRef(BlockReference senderRef, Signal *signal,
00941 Uint32 senderData, Uint32 errorCode)
00942 {
00943 jam();
00944 BackupRef* ref = (BackupRef*)signal->getDataPtrSend();
00945 ref->senderData = senderData;
00946 ref->errorCode = errorCode;
00947 ref->masterRef = numberToRef(BACKUP, getMasterNodeId());
00948 sendSignal(senderRef, GSN_BACKUP_REF, signal, BackupRef::SignalLength, JBB);
00949
00950 if(errorCode != BackupRef::IAmNotMaster){
00951 signal->theData[0] = NDB_LE_BackupFailedToStart;
00952 signal->theData[1] = senderRef;
00953 signal->theData[2] = errorCode;
00954 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
00955 }
00956 }
00957
00958 void
00959 Backup::execUTIL_SEQUENCE_CONF(Signal* signal)
00960 {
00961 jamEntry();
00962
00963 UtilSequenceConf * conf = (UtilSequenceConf*)signal->getDataPtr();
00964
00965 if(conf->requestType == UtilSequenceReq::Create)
00966 {
00967 jam();
00968 sendSTTORRY(signal);
00969 return;
00970 }
00971
00972 BackupRecordPtr ptr;
00973 ptr.i = conf->senderData;
00974 c_backupPool.getPtr(ptr);
00975
00976 ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_SEQUENCE_REQ);
00977
00978 if (ptr.p->checkError())
00979 {
00980 jam();
00981 sendBackupRef(signal, ptr, ptr.p->errorCode);
00982 return;
00983 }
00984
00985 if (ERROR_INSERTED(10023))
00986 {
00987 sendBackupRef(signal, ptr, 323);
00988 return;
00989 }
00990
00991
00992 {
00993 Uint64 backupId;
00994 memcpy(&backupId,conf->sequenceValue,8);
00995 ptr.p->backupId= (Uint32)backupId;
00996 }
00997 ptr.p->backupKey[0] = (getOwnNodeId() << 16) | (ptr.p->backupId & 0xFFFF);
00998 ptr.p->backupKey[1] = NdbTick_CurrentMillisecond();
00999
01000 ptr.p->masterData.gsn = GSN_UTIL_LOCK_REQ;
01001 Mutex mutex(signal, c_mutexMgr, ptr.p->masterData.m_defineBackupMutex);
01002 Callback c = { safe_cast(&Backup::defineBackupMutex_locked), ptr.i };
01003 ndbrequire(mutex.lock(c));
01004
01005 return;
01006 }
01007
01008 void
01009 Backup::defineBackupMutex_locked(Signal* signal, Uint32 ptrI, Uint32 retVal){
01010 jamEntry();
01011 ndbrequire(retVal == 0);
01012
01013 BackupRecordPtr ptr;
01014 ptr.i = ptrI;
01015 c_backupPool.getPtr(ptr);
01016
01017 ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_LOCK_REQ);
01018
01019 ptr.p->masterData.gsn = GSN_UTIL_LOCK_REQ;
01020 Mutex mutex(signal, c_mutexMgr, ptr.p->masterData.m_dictCommitTableMutex);
01021 Callback c = { safe_cast(&Backup::dictCommitTableMutex_locked), ptr.i };
01022 ndbrequire(mutex.lock(c));
01023 }
01024
01025 void
01026 Backup::dictCommitTableMutex_locked(Signal* signal, Uint32 ptrI,Uint32 retVal)
01027 {
01028 jamEntry();
01029 ndbrequire(retVal == 0);
01030
01034 BackupRecordPtr ptr;
01035 ptr.i = ptrI;
01036 c_backupPool.getPtr(ptr);
01037
01038 ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_LOCK_REQ);
01039
01040 if (ERROR_INSERTED(10031)) {
01041 ptr.p->setErrorCode(331);
01042 }
01043
01044 if (ptr.p->checkError())
01045 {
01046 jam();
01047
01051 jam();
01052 Mutex mutex1(signal, c_mutexMgr, ptr.p->masterData.m_dictCommitTableMutex);
01053 jam();
01054 mutex1.unlock();
01055
01056 jam();
01057 Mutex mutex2(signal, c_mutexMgr, ptr.p->masterData.m_defineBackupMutex);
01058 jam();
01059 mutex2.unlock();
01060
01061 sendBackupRef(signal, ptr, ptr.p->errorCode);
01062 return;
01063 }
01064
01065 sendDefineBackupReq(signal, ptr);
01066 }
01067
01068
01069
01070
01071
01072
01073
01074 bool
01075 Backup::haveAllSignals(BackupRecordPtr ptr, Uint32 gsn, Uint32 nodeId)
01076 {
01077 ndbrequire(ptr.p->masterRef == reference());
01078 ndbrequire(ptr.p->masterData.gsn == gsn);
01079 ndbrequire(!ptr.p->masterData.sendCounter.done());
01080 ndbrequire(ptr.p->masterData.sendCounter.isWaitingFor(nodeId));
01081
01082 ptr.p->masterData.sendCounter.clearWaitingFor(nodeId);
01083 return ptr.p->masterData.sendCounter.done();
01084 }
01085
01086 void
01087 Backup::sendDefineBackupReq(Signal *signal, BackupRecordPtr ptr)
01088 {
01092 DefineBackupReq * req = (DefineBackupReq*)signal->getDataPtrSend();
01093 req->backupId = ptr.p->backupId;
01094 req->clientRef = ptr.p->clientRef;
01095 req->clientData = ptr.p->clientData;
01096 req->senderRef = reference();
01097 req->backupPtr = ptr.i;
01098 req->backupKey[0] = ptr.p->backupKey[0];
01099 req->backupKey[1] = ptr.p->backupKey[1];
01100 req->nodes = ptr.p->nodes;
01101 req->backupDataLen = ptr.p->backupDataLen;
01102
01103 ptr.p->masterData.gsn = GSN_DEFINE_BACKUP_REQ;
01104 ptr.p->masterData.sendCounter = ptr.p->nodes;
01105 NodeReceiverGroup rg(BACKUP, ptr.p->nodes);
01106 sendSignal(rg, GSN_DEFINE_BACKUP_REQ, signal,
01107 DefineBackupReq::SignalLength, JBB);
01108
01112 const Uint32 len = ptr.p->backupDataLen;
01113 if(len == 0){
01117 jam();
01118 return;
01119 }
01120
01124 ndbrequire(0);
01125 }
01126
01127 void
01128 Backup::execDEFINE_BACKUP_REF(Signal* signal)
01129 {
01130 jamEntry();
01131
01132 DefineBackupRef* ref = (DefineBackupRef*)signal->getDataPtr();
01133
01134 const Uint32 ptrI = ref->backupPtr;
01135
01136 const Uint32 nodeId = ref->nodeId;
01137
01138 BackupRecordPtr ptr;
01139 c_backupPool.getPtr(ptr, ptrI);
01140
01141 ptr.p->setErrorCode(ref->errorCode);
01142 defineBackupReply(signal, ptr, nodeId);
01143 }
01144
01145 void
01146 Backup::execDEFINE_BACKUP_CONF(Signal* signal)
01147 {
01148 jamEntry();
01149
01150 DefineBackupConf* conf = (DefineBackupConf*)signal->getDataPtr();
01151 const Uint32 ptrI = conf->backupPtr;
01152
01153 const Uint32 nodeId = refToNode(signal->senderBlockRef());
01154
01155 BackupRecordPtr ptr;
01156 c_backupPool.getPtr(ptr, ptrI);
01157
01158 if (ERROR_INSERTED(10024))
01159 {
01160 ptr.p->setErrorCode(324);
01161 }
01162
01163 defineBackupReply(signal, ptr, nodeId);
01164 }
01165
01166 void
01167 Backup::defineBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId)
01168 {
01169 if (!haveAllSignals(ptr, GSN_DEFINE_BACKUP_REQ, nodeId)) {
01170 jam();
01171 return;
01172 }
01173
01177 jam();
01178 Mutex mutex1(signal, c_mutexMgr, ptr.p->masterData.m_dictCommitTableMutex);
01179 jam();
01180 mutex1.unlock();
01181
01182 jam();
01183 Mutex mutex2(signal, c_mutexMgr, ptr.p->masterData.m_defineBackupMutex);
01184 jam();
01185 mutex2.unlock();
01186
01187 if(ptr.p->checkError())
01188 {
01189 jam();
01190 masterAbort(signal, ptr);
01191 return;
01192 }
01193
01197 BackupConf * conf = (BackupConf*)signal->getDataPtrSend();
01198 conf->backupId = ptr.p->backupId;
01199 conf->senderData = ptr.p->clientData;
01200 conf->nodes = ptr.p->nodes;
01201 sendSignal(ptr.p->clientRef, GSN_BACKUP_CONF, signal,
01202 BackupConf::SignalLength, JBB);
01203
01204 signal->theData[0] = NDB_LE_BackupStarted;
01205 signal->theData[1] = ptr.p->clientRef;
01206 signal->theData[2] = ptr.p->backupId;
01207 ptr.p->nodes.copyto(NdbNodeBitmask::Size, signal->theData+3);
01208 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3+NdbNodeBitmask::Size, JBB);
01209
01213 TablePtr tabPtr;
01214 ndbrequire(ptr.p->tables.first(tabPtr));
01215 sendCreateTrig(signal, ptr, tabPtr);
01216 }
01217
01218
01219
01220
01221
01222
01223 void
01224 Backup::createAttributeMask(TablePtr tabPtr,
01225 Bitmask<MAXNROFATTRIBUTESINWORDS> & mask)
01226 {
01227 mask.clear();
01228 Table & table = * tabPtr.p;
01229 for(Uint32 i = 0; i<table.noOfAttributes; i++) {
01230 jam();
01231 AttributePtr attr;
01232 table.attributes.getPtr(attr, i);
01233 mask.set(i);
01234 }
01235 }
01236
01237 void
01238 Backup::sendCreateTrig(Signal* signal,
01239 BackupRecordPtr ptr, TablePtr tabPtr)
01240 {
01241 CreateTrigReq * req =(CreateTrigReq *)signal->getDataPtrSend();
01242
01243 ptr.p->masterData.gsn = GSN_CREATE_TRIG_REQ;
01244 ptr.p->masterData.sendCounter = 3;
01245 ptr.p->masterData.createTrig.tableId = tabPtr.p->tableId;
01246
01247 req->setUserRef(reference());
01248 req->setConnectionPtr(ptr.i);
01249 req->setRequestType(CreateTrigReq::RT_USER);
01250
01251 Bitmask<MAXNROFATTRIBUTESINWORDS> attrMask;
01252 createAttributeMask(tabPtr, attrMask);
01253 req->setAttributeMask(attrMask);
01254 req->setTableId(tabPtr.p->tableId);
01255 req->setIndexId(RNIL);
01256 req->setTriggerId(RNIL);
01257 req->setTriggerType(TriggerType::SUBSCRIPTION);
01258 req->setTriggerActionTime(TriggerActionTime::TA_DETACHED);
01259 req->setMonitorReplicas(true);
01260 req->setMonitorAllAttributes(false);
01261 req->setOnline(false);
01262
01263 char triggerName[MAX_TAB_NAME_SIZE];
01264 Uint32 nameBuffer[2 + ((MAX_TAB_NAME_SIZE + 3) >> 2)];
01265 LinearWriter w(nameBuffer, sizeof(nameBuffer) >> 2);
01266 LinearSectionPtr lsPtr[3];
01267
01268 for (int i=0; i < 3; i++) {
01269 req->setTriggerEvent(triggerEventValues[i]);
01270 BaseString::snprintf(triggerName, sizeof(triggerName), triggerNameFormat[i],
01271 ptr.p->backupId, tabPtr.p->tableId);
01272 w.reset();
01273 w.add(CreateTrigReq::TriggerNameKey, triggerName);
01274 lsPtr[0].p = nameBuffer;
01275 lsPtr[0].sz = w.getWordsUsed();
01276 sendSignal(DBDICT_REF, GSN_CREATE_TRIG_REQ,
01277 signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
01278 }
01279 }
01280
01281 void
01282 Backup::execCREATE_TRIG_CONF(Signal* signal)
01283 {
01284 jamEntry();
01285 CreateTrigConf * conf = (CreateTrigConf*)signal->getDataPtr();
01286
01287 const Uint32 ptrI = conf->getConnectionPtr();
01288 const Uint32 tableId = conf->getTableId();
01289 const TriggerEvent::Value type = conf->getTriggerEvent();
01290 const Uint32 triggerId = conf->getTriggerId();
01291
01292 BackupRecordPtr ptr;
01293 c_backupPool.getPtr(ptr, ptrI);
01294
01298 ndbrequire(ptr.p->masterRef == reference());
01299 ndbrequire(ptr.p->masterData.gsn == GSN_CREATE_TRIG_REQ);
01300 ndbrequire(ptr.p->masterData.sendCounter.done() == false);
01301 ndbrequire(ptr.p->masterData.createTrig.tableId == tableId);
01302
01303 TablePtr tabPtr;
01304 ndbrequire(findTable(ptr, tabPtr, tableId));
01305 ndbrequire(type < 3);
01306
01307 ndbrequire(tabPtr.p->triggerIds[type] == ILLEGAL_TRIGGER_ID);
01308 tabPtr.p->triggerIds[type] = triggerId;
01309
01310 createTrigReply(signal, ptr);
01311 }
01312
01313 void
01314 Backup::execCREATE_TRIG_REF(Signal* signal)
01315 {
01316 CreateTrigRef* ref = (CreateTrigRef*)signal->getDataPtr();
01317
01318 const Uint32 ptrI = ref->getConnectionPtr();
01319 const Uint32 tableId = ref->getTableId();
01320
01321 BackupRecordPtr ptr;
01322 c_backupPool.getPtr(ptr, ptrI);
01323
01327 ndbrequire(ptr.p->masterRef == reference());
01328 ndbrequire(ptr.p->masterData.gsn == GSN_CREATE_TRIG_REQ);
01329 ndbrequire(ptr.p->masterData.sendCounter.done() == false);
01330 ndbrequire(ptr.p->masterData.createTrig.tableId == tableId);
01331
01332 ptr.p->setErrorCode(ref->getErrorCode());
01333
01334 createTrigReply(signal, ptr);
01335 }
01336
01337 void
01338 Backup::createTrigReply(Signal* signal, BackupRecordPtr ptr)
01339 {
01340 CRASH_INSERTION(10003);
01341
01345 ptr.p->masterData.sendCounter--;
01346 if(ptr.p->masterData.sendCounter.done() == false){
01347 jam();
01348 return;
01349 }
01350
01351 if (ERROR_INSERTED(10025))
01352 {
01353 ptr.p->errorCode = 325;
01354 }
01355
01356 if(ptr.p->checkError()) {
01357 jam();
01358 masterAbort(signal, ptr);
01359 return;
01360 }
01361
01362 TablePtr tabPtr;
01363 ndbrequire(findTable(ptr, tabPtr, ptr.p->masterData.createTrig.tableId));
01364
01368 ptr.p->tables.next(tabPtr);
01369 if(tabPtr.i != RNIL){
01370 jam();
01371 sendCreateTrig(signal, ptr, tabPtr);
01372 return;
01373 }
01374
01378 ptr.p->tables.first(tabPtr);
01379 ptr.p->masterData.startBackup.signalNo = 0;
01380 ptr.p->masterData.startBackup.noOfSignals =
01381 (ptr.p->tables.noOfElements() + StartBackupReq::MaxTableTriggers - 1) /
01382 StartBackupReq::MaxTableTriggers;
01383 sendStartBackup(signal, ptr, tabPtr);
01384 }
01385
01386
01387
01388
01389
01390
01391 void
01392 Backup::sendStartBackup(Signal* signal, BackupRecordPtr ptr, TablePtr tabPtr)
01393 {
01394
01395 ptr.p->masterData.startBackup.tablePtr = tabPtr.i;
01396
01397 StartBackupReq* req = (StartBackupReq*)signal->getDataPtrSend();
01398 req->backupId = ptr.p->backupId;
01399 req->backupPtr = ptr.i;
01400 req->signalNo = ptr.p->masterData.startBackup.signalNo;
01401 req->noOfSignals = ptr.p->masterData.startBackup.noOfSignals;
01402 Uint32 i;
01403 for(i = 0; i<StartBackupReq::MaxTableTriggers; i++) {
01404 jam();
01405 req->tableTriggers[i].tableId = tabPtr.p->tableId;
01406 req->tableTriggers[i].triggerIds[0] = tabPtr.p->triggerIds[0];
01407 req->tableTriggers[i].triggerIds[1] = tabPtr.p->triggerIds[1];
01408 req->tableTriggers[i].triggerIds[2] = tabPtr.p->triggerIds[2];
01409 if(!ptr.p->tables.next(tabPtr)){
01410 jam();
01411 i++;
01412 break;
01413 }
01414 }
01415 req->noOfTableTriggers = i;
01416
01417 ptr.p->masterData.gsn = GSN_START_BACKUP_REQ;
01418 ptr.p->masterData.sendCounter = ptr.p->nodes;
01419 NodeReceiverGroup rg(BACKUP, ptr.p->nodes);
01420 sendSignal(rg, GSN_START_BACKUP_REQ, signal,
01421 StartBackupReq::HeaderLength +
01422 (i * StartBackupReq::TableTriggerLength), JBB);
01423 }
01424
01425 void
01426 Backup::execSTART_BACKUP_REF(Signal* signal)
01427 {
01428 jamEntry();
01429
01430 StartBackupRef* ref = (StartBackupRef*)signal->getDataPtr();
01431 const Uint32 ptrI = ref->backupPtr;
01432
01433 const Uint32 signalNo = ref->signalNo;
01434 const Uint32 nodeId = ref->nodeId;
01435
01436 BackupRecordPtr ptr;
01437 c_backupPool.getPtr(ptr, ptrI);
01438
01439 ptr.p->setErrorCode(ref->errorCode);
01440 startBackupReply(signal, ptr, nodeId, signalNo);
01441 }
01442
01443 void
01444 Backup::execSTART_BACKUP_CONF(Signal* signal)
01445 {
01446 jamEntry();
01447
01448 StartBackupConf* conf = (StartBackupConf*)signal->getDataPtr();
01449 const Uint32 ptrI = conf->backupPtr;
01450
01451 const Uint32 signalNo = conf->signalNo;
01452 const Uint32 nodeId = refToNode(signal->senderBlockRef());
01453
01454 BackupRecordPtr ptr;
01455 c_backupPool.getPtr(ptr, ptrI);
01456
01457 startBackupReply(signal, ptr, nodeId, signalNo);
01458 }
01459
01460 void
01461 Backup::startBackupReply(Signal* signal, BackupRecordPtr ptr,
01462 Uint32 nodeId, Uint32 signalNo)
01463 {
01464
01465 CRASH_INSERTION((10004));
01466
01467 ndbrequire(ptr.p->masterData.startBackup.signalNo == signalNo);
01468 if (!haveAllSignals(ptr, GSN_START_BACKUP_REQ, nodeId)) {
01469 jam();
01470 return;
01471 }
01472
01473 if (ERROR_INSERTED(10026))
01474 {
01475 ptr.p->errorCode = 326;
01476 }
01477
01478 if(ptr.p->checkError()){
01479 jam();
01480 masterAbort(signal, ptr);
01481 return;
01482 }
01483
01484 TablePtr tabPtr;
01485 c_tablePool.getPtr(tabPtr, ptr.p->masterData.startBackup.tablePtr);
01486 for(Uint32 i = 0; i<StartBackupReq::MaxTableTriggers; i++) {
01487 jam();
01488 if(!ptr.p->tables.next(tabPtr)) {
01489 jam();
01490 break;
01491 }
01492 }
01493
01494 if(tabPtr.i != RNIL) {
01495 jam();
01496 ptr.p->masterData.startBackup.signalNo++;
01497 sendStartBackup(signal, ptr, tabPtr);
01498 return;
01499 }
01500
01501 sendAlterTrig(signal, ptr);
01502 }
01503
01504
01505
01506
01507
01508
01509 void
01510 Backup::sendAlterTrig(Signal* signal, BackupRecordPtr ptr)
01511 {
01512 AlterTrigReq * req =(AlterTrigReq *)signal->getDataPtrSend();
01513
01514 ptr.p->masterData.gsn = GSN_ALTER_TRIG_REQ;
01515 ptr.p->masterData.sendCounter = 0;
01516
01517 req->setUserRef(reference());
01518 req->setConnectionPtr(ptr.i);
01519 req->setRequestType(AlterTrigReq::RT_USER);
01520 req->setTriggerInfo(0);
01521 req->setOnline(true);
01522 req->setReceiverRef(reference());
01523
01524 TablePtr tabPtr;
01525
01526 if (ptr.p->masterData.alterTrig.tableId == RNIL) {
01527 jam();
01528 ptr.p->tables.first(tabPtr);
01529 } else {
01530 jam();
01531 ndbrequire(findTable(ptr, tabPtr, ptr.p->masterData.alterTrig.tableId));
01532 ptr.p->tables.next(tabPtr);
01533 }
01534 if (tabPtr.i != RNIL) {
01535 jam();
01536 ptr.p->masterData.alterTrig.tableId = tabPtr.p->tableId;
01537 req->setTableId(tabPtr.p->tableId);
01538
01539 req->setTriggerId(tabPtr.p->triggerIds[0]);
01540 sendSignal(DBDICT_REF, GSN_ALTER_TRIG_REQ,
01541 signal, AlterTrigReq::SignalLength, JBB);
01542
01543 req->setTriggerId(tabPtr.p->triggerIds[1]);
01544 sendSignal(DBDICT_REF, GSN_ALTER_TRIG_REQ,
01545 signal, AlterTrigReq::SignalLength, JBB);
01546
01547 req->setTriggerId(tabPtr.p->triggerIds[2]);
01548 sendSignal(DBDICT_REF, GSN_ALTER_TRIG_REQ,
01549 signal, AlterTrigReq::SignalLength, JBB);
01550
01551 ptr.p->masterData.sendCounter += 3;
01552 return;
01553 }
01554 ptr.p->masterData.alterTrig.tableId = RNIL;
01555
01559 ptr.p->masterData.gsn = GSN_WAIT_GCP_REQ;
01560 ptr.p->masterData.waitGCP.startBackup = true;
01561
01562 WaitGCPReq * waitGCPReq = (WaitGCPReq*)signal->getDataPtrSend();
01563 waitGCPReq->senderRef = reference();
01564 waitGCPReq->senderData = ptr.i;
01565 waitGCPReq->requestType = WaitGCPReq::CompleteForceStart;
01566 sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
01567 WaitGCPReq::SignalLength,JBB);
01568 }
01569
01570 void
01571 Backup::execALTER_TRIG_CONF(Signal* signal)
01572 {
01573 jamEntry();
01574
01575 AlterTrigConf* conf = (AlterTrigConf*)signal->getDataPtr();
01576 const Uint32 ptrI = conf->getConnectionPtr();
01577
01578 BackupRecordPtr ptr;
01579 c_backupPool.getPtr(ptr, ptrI);
01580
01581 alterTrigReply(signal, ptr);
01582 }
01583
01584 void
01585 Backup::execALTER_TRIG_REF(Signal* signal)
01586 {
01587 jamEntry();
01588
01589 AlterTrigRef* ref = (AlterTrigRef*)signal->getDataPtr();
01590 const Uint32 ptrI = ref->getConnectionPtr();
01591
01592 BackupRecordPtr ptr;
01593 c_backupPool.getPtr(ptr, ptrI);
01594
01595 ptr.p->setErrorCode(ref->getErrorCode());
01596
01597 alterTrigReply(signal, ptr);
01598 }
01599
01600 void
01601 Backup::alterTrigReply(Signal* signal, BackupRecordPtr ptr)
01602 {
01603
01604 CRASH_INSERTION((10005));
01605
01606 ndbrequire(ptr.p->masterRef == reference());
01607 ndbrequire(ptr.p->masterData.gsn == GSN_ALTER_TRIG_REQ);
01608 ndbrequire(ptr.p->masterData.sendCounter.done() == false);
01609
01610 ptr.p->masterData.sendCounter--;
01611
01612 if(ptr.p->masterData.sendCounter.done() == false){
01613 jam();
01614 return;
01615 }
01616
01617 if(ptr.p->checkError()){
01618 jam();
01619 masterAbort(signal, ptr);
01620 return;
01621 }
01622
01623 sendAlterTrig(signal, ptr);
01624 }
01625
01626 void
01627 Backup::execWAIT_GCP_REF(Signal* signal)
01628 {
01629 jamEntry();
01630
01631 CRASH_INSERTION((10006));
01632
01633 WaitGCPRef * ref = (WaitGCPRef*)signal->getDataPtr();
01634 const Uint32 ptrI = ref->senderData;
01635
01636 BackupRecordPtr ptr;
01637 c_backupPool.getPtr(ptr, ptrI);
01638
01639 ndbrequire(ptr.p->masterRef == reference());
01640 ndbrequire(ptr.p->masterData.gsn == GSN_WAIT_GCP_REQ);
01641
01642 WaitGCPReq * req = (WaitGCPReq*)signal->getDataPtrSend();
01643 req->senderRef = reference();
01644 req->senderData = ptr.i;
01645 req->requestType = WaitGCPReq::CompleteForceStart;
01646 sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
01647 WaitGCPReq::SignalLength,JBB);
01648 }
01649
01650 void
01651 Backup::execWAIT_GCP_CONF(Signal* signal){
01652 jamEntry();
01653
01654 CRASH_INSERTION((10007));
01655
01656 WaitGCPConf * conf = (WaitGCPConf*)signal->getDataPtr();
01657 const Uint32 ptrI = conf->senderData;
01658 const Uint32 gcp = conf->gcp;
01659
01660 BackupRecordPtr ptr;
01661 c_backupPool.getPtr(ptr, ptrI);
01662
01663 ndbrequire(ptr.p->masterRef == reference());
01664 ndbrequire(ptr.p->masterData.gsn == GSN_WAIT_GCP_REQ);
01665
01666 if(ptr.p->checkError()) {
01667 jam();
01668 masterAbort(signal, ptr);
01669 return;
01670 }
01671
01672 if(ptr.p->masterData.waitGCP.startBackup) {
01673 jam();
01674 CRASH_INSERTION((10008));
01675 ptr.p->startGCP = gcp;
01676 ptr.p->masterData.sendCounter= 0;
01677 ptr.p->masterData.gsn = GSN_BACKUP_FRAGMENT_REQ;
01678 nextFragment(signal, ptr);
01679 return;
01680 } else {
01681 jam();
01682 if(gcp >= ptr.p->startGCP + 3)
01683 {
01684 CRASH_INSERTION((10009));
01685 ptr.p->stopGCP = gcp;
01686 sendDropTrig(signal, ptr);
01687 return;
01688 }
01689
01693 WaitGCPReq * req = (WaitGCPReq*)signal->getDataPtrSend();
01694 req->senderRef = reference();
01695 req->senderData = ptr.i;
01696 req->requestType = WaitGCPReq::CompleteForceStart;
01697 sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
01698 WaitGCPReq::SignalLength,JBB);
01699 return;
01700 }
01701 }
01702
01703
01704
01705
01706
01707
01708 void
01709 Backup::nextFragment(Signal* signal, BackupRecordPtr ptr)
01710 {
01711 jam();
01712
01713 BackupFragmentReq* req = (BackupFragmentReq*)signal->getDataPtrSend();
01714 req->backupPtr = ptr.i;
01715 req->backupId = ptr.p->backupId;
01716
01717 NodeBitmask nodes = ptr.p->nodes;
01718 Uint32 idleNodes = nodes.count();
01719 Uint32 saveIdleNodes = idleNodes;
01720 ndbrequire(idleNodes > 0);
01721
01722 TablePtr tabPtr;
01723 ptr.p->tables.first(tabPtr);
01724 for(; tabPtr.i != RNIL && idleNodes > 0; ptr.p->tables.next(tabPtr)) {
01725 jam();
01726 FragmentPtr fragPtr;
01727 Array<Fragment> & frags = tabPtr.p->fragments;
01728 const Uint32 fragCount = frags.getSize();
01729
01730 for(Uint32 i = 0; i<fragCount && idleNodes > 0; i++) {
01731 jam();
01732 tabPtr.p->fragments.getPtr(fragPtr, i);
01733 const Uint32 nodeId = fragPtr.p->node;
01734 if(fragPtr.p->scanning != 0) {
01735 jam();
01736 ndbrequire(nodes.get(nodeId));
01737 nodes.clear(nodeId);
01738 idleNodes--;
01739 } else if(fragPtr.p->scanned == 0 && nodes.get(nodeId)){
01740 jam();
01741 fragPtr.p->scanning = 1;
01742 nodes.clear(nodeId);
01743 idleNodes--;
01744
01745 req->tableId = tabPtr.p->tableId;
01746 req->fragmentNo = i;
01747 req->count = 0;
01748
01749 ptr.p->masterData.sendCounter++;
01750 const BlockReference ref = numberToRef(BACKUP, nodeId);
01751 sendSignal(ref, GSN_BACKUP_FRAGMENT_REQ, signal,
01752 BackupFragmentReq::SignalLength, JBB);
01753 }
01754 }
01755 }
01756
01757 if(idleNodes != saveIdleNodes){
01758 jam();
01759 return;
01760 }
01761
01765 {
01766 ptr.p->masterData.gsn = GSN_WAIT_GCP_REQ;
01767 ptr.p->masterData.waitGCP.startBackup = false;
01768
01769 WaitGCPReq * req = (WaitGCPReq*)signal->getDataPtrSend();
01770 req->senderRef = reference();
01771 req->senderData = ptr.i;
01772 req->requestType = WaitGCPReq::CompleteForceStart;
01773 sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
01774 WaitGCPReq::SignalLength, JBB);
01775 }
01776 }
01777
01778 void
01779 Backup::execBACKUP_FRAGMENT_CONF(Signal* signal)
01780 {
01781 jamEntry();
01782
01783 CRASH_INSERTION((10010));
01784
01785 BackupFragmentConf * conf = (BackupFragmentConf*)signal->getDataPtr();
01786 const Uint32 ptrI = conf->backupPtr;
01787
01788 const Uint32 tableId = conf->tableId;
01789 const Uint32 fragmentNo = conf->fragmentNo;
01790 const Uint32 nodeId = refToNode(signal->senderBlockRef());
01791 const Uint32 noOfBytes = conf->noOfBytes;
01792 const Uint32 noOfRecords = conf->noOfRecords;
01793
01794 BackupRecordPtr ptr;
01795 c_backupPool.getPtr(ptr, ptrI);
01796
01797 ptr.p->noOfBytes += noOfBytes;
01798 ptr.p->noOfRecords += noOfRecords;
01799 ptr.p->masterData.sendCounter--;
01800
01801 TablePtr tabPtr;
01802 ndbrequire(findTable(ptr, tabPtr, tableId));
01803
01804 FragmentPtr fragPtr;
01805 tabPtr.p->fragments.getPtr(fragPtr, fragmentNo);
01806
01807 ndbrequire(fragPtr.p->scanned == 0);
01808 ndbrequire(fragPtr.p->scanning == 1);
01809 ndbrequire(fragPtr.p->node == nodeId);
01810
01811 fragPtr.p->scanned = 1;
01812 fragPtr.p->scanning = 0;
01813
01814 if (ERROR_INSERTED(10028))
01815 {
01816 ptr.p->errorCode = 328;
01817 }
01818
01819 if(ptr.p->checkError())
01820 {
01821 if(ptr.p->masterData.sendCounter.done())
01822 {
01823 jam();
01824 masterAbort(signal, ptr);
01825 return;
01826 }
01827 }
01828 else
01829 {
01830 nextFragment(signal, ptr);
01831 }
01832 }
01833
01834 void
01835 Backup::execBACKUP_FRAGMENT_REF(Signal* signal)
01836 {
01837 jamEntry();
01838
01839 CRASH_INSERTION((10011));
01840
01841 BackupFragmentRef * ref = (BackupFragmentRef*)signal->getDataPtr();
01842 const Uint32 ptrI = ref->backupPtr;
01843
01844 const Uint32 nodeId = ref->nodeId;
01845
01846 BackupRecordPtr ptr;
01847 c_backupPool.getPtr(ptr, ptrI);
01848
01849 TablePtr tabPtr;
01850 ptr.p->tables.first(tabPtr);
01851 for(; tabPtr.i != RNIL; ptr.p->tables.next(tabPtr)) {
01852 jam();
01853 FragmentPtr fragPtr;
01854 Array<Fragment> & frags = tabPtr.p->fragments;
01855 const Uint32 fragCount = frags.getSize();
01856
01857 for(Uint32 i = 0; i<fragCount; i++) {
01858 jam();
01859 tabPtr.p->fragments.getPtr(fragPtr, i);
01860 if(fragPtr.p->scanning != 0 && nodeId == fragPtr.p->node)
01861 {
01862 jam();
01863 ndbrequire(fragPtr.p->scanned == 0);
01864 fragPtr.p->scanned = 1;
01865 fragPtr.p->scanning = 0;
01866 goto done;
01867 }
01868 }
01869 }
01870 ndbrequire(false);
01871
01872 done:
01873 ptr.p->masterData.sendCounter--;
01874 ptr.p->setErrorCode(ref->errorCode);
01875
01876 if(ptr.p->masterData.sendCounter.done())
01877 {
01878 jam();
01879 masterAbort(signal, ptr);
01880 return;
01881 }
01882
01883 AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
01884 ord->backupId = ptr.p->backupId;
01885 ord->backupPtr = ptr.i;
01886 ord->requestType = AbortBackupOrd::LogBufferFull;
01887 ord->senderData= ptr.i;
01888 execABORT_BACKUP_ORD(signal);
01889 }
01890
01891
01892
01893
01894
01895
01896
01897 void
01898 Backup::sendDropTrig(Signal* signal, BackupRecordPtr ptr)
01899 {
01900 TablePtr tabPtr;
01901 if (ptr.p->masterData.dropTrig.tableId == RNIL) {
01902 jam();
01903 ptr.p->tables.first(tabPtr);
01904 } else {
01905 jam();
01906 ndbrequire(findTable(ptr, tabPtr, ptr.p->masterData.dropTrig.tableId));
01907 ptr.p->tables.next(tabPtr);
01908 }
01909 if (tabPtr.i != RNIL) {
01910 jam();
01911 sendDropTrig(signal, ptr, tabPtr);
01912 } else {
01913 jam();
01914 ptr.p->masterData.dropTrig.tableId = RNIL;
01915
01916 sendStopBackup(signal, ptr);
01917 }
01918 }
01919
01920 void
01921 Backup::sendDropTrig(Signal* signal, BackupRecordPtr ptr, TablePtr tabPtr)
01922 {
01923 jam();
01924 DropTrigReq * req = (DropTrigReq *)signal->getDataPtrSend();
01925
01926 ptr.p->masterData.gsn = GSN_DROP_TRIG_REQ;
01927 ptr.p->masterData.sendCounter = 0;
01928
01929 req->setConnectionPtr(ptr.i);
01930 req->setUserRef(reference());
01931 req->setRequestType(DropTrigReq::RT_USER);
01932 req->setIndexId(RNIL);
01933 req->setTriggerInfo(0);
01934
01935 char triggerName[MAX_TAB_NAME_SIZE];
01936 Uint32 nameBuffer[2 + ((MAX_TAB_NAME_SIZE + 3) >> 2)];
01937 LinearWriter w(nameBuffer, sizeof(nameBuffer) >> 2);
01938 LinearSectionPtr lsPtr[3];
01939
01940 ptr.p->masterData.dropTrig.tableId = tabPtr.p->tableId;
01941 req->setTableId(tabPtr.p->tableId);
01942
01943 for (int i = 0; i < 3; i++) {
01944 Uint32 id = tabPtr.p->triggerIds[i];
01945 req->setTriggerId(id);
01946 if (id != ILLEGAL_TRIGGER_ID) {
01947 sendSignal(DBDICT_REF, GSN_DROP_TRIG_REQ,
01948 signal, DropTrigReq::SignalLength, JBB);
01949 } else {
01950 BaseString::snprintf(triggerName, sizeof(triggerName), triggerNameFormat[i],
01951 ptr.p->backupId, tabPtr.p->tableId);
01952 w.reset();
01953 w.add(CreateTrigReq::TriggerNameKey, triggerName);
01954 lsPtr[0].p = nameBuffer;
01955 lsPtr[0].sz = w.getWordsUsed();
01956 sendSignal(DBDICT_REF, GSN_DROP_TRIG_REQ,
01957 signal, DropTrigReq::SignalLength, JBB, lsPtr, 1);
01958 }
01959 ptr.p->masterData.sendCounter ++;
01960 }
01961 }
01962
01963 void
01964 Backup::execDROP_TRIG_REF(Signal* signal)
01965 {
01966 jamEntry();
01967
01968 DropTrigRef* ref = (DropTrigRef*)signal->getDataPtr();
01969 const Uint32 ptrI = ref->getConnectionPtr();
01970
01971 BackupRecordPtr ptr;
01972 c_backupPool.getPtr(ptr, ptrI);
01973
01974
01975 dropTrigReply(signal, ptr);
01976 }
01977
01978 void
01979 Backup::execDROP_TRIG_CONF(Signal* signal)
01980 {
01981 jamEntry();
01982
01983 DropTrigConf* conf = (DropTrigConf*)signal->getDataPtr();
01984 const Uint32 ptrI = conf->getConnectionPtr();
01985
01986 BackupRecordPtr ptr;
01987 c_backupPool.getPtr(ptr, ptrI);
01988
01989 dropTrigReply(signal, ptr);
01990 }
01991
01992 void
01993 Backup::dropTrigReply(Signal* signal, BackupRecordPtr ptr)
01994 {
01995
01996 CRASH_INSERTION((10012));
01997
01998 ndbrequire(ptr.p->masterRef == reference());
01999 ndbrequire(ptr.p->masterData.gsn == GSN_DROP_TRIG_REQ);
02000 ndbrequire(ptr.p->masterData.sendCounter.done() == false);
02001
02002 ptr.p->masterData.sendCounter--;
02003 if(ptr.p->masterData.sendCounter.done() == false){
02004 jam();
02005 return;
02006 }
02007
02008 sendDropTrig(signal, ptr);
02009 }
02010
02011
02012
02013
02014
02015
02016 void
02017 Backup::execSTOP_BACKUP_REF(Signal* signal)
02018 {
02019 jamEntry();
02020
02021 StopBackupRef* ref = (StopBackupRef*)signal->getDataPtr();
02022 const Uint32 ptrI = ref->backupPtr;
02023
02024 const Uint32 nodeId = ref->nodeId;
02025
02026 BackupRecordPtr ptr;
02027 c_backupPool.getPtr(ptr, ptrI);
02028
02029 ptr.p->setErrorCode(ref->errorCode);
02030 stopBackupReply(signal, ptr, nodeId);
02031 }
02032
02033 void
02034 Backup::sendStopBackup(Signal* signal, BackupRecordPtr ptr)
02035 {
02036 jam();
02037
02038 StopBackupReq* stop = (StopBackupReq*)signal->getDataPtrSend();
02039 stop->backupPtr = ptr.i;
02040 stop->backupId = ptr.p->backupId;
02041 stop->startGCP = ptr.p->startGCP;
02042 stop->stopGCP = ptr.p->stopGCP;
02043
02044 ptr.p->masterData.gsn = GSN_STOP_BACKUP_REQ;
02045 ptr.p->masterData.sendCounter = ptr.p->nodes;
02046 NodeReceiverGroup rg(BACKUP, ptr.p->nodes);
02047 sendSignal(rg, GSN_STOP_BACKUP_REQ, signal,
02048 StopBackupReq::SignalLength, JBB);
02049 }
02050
02051 void
02052 Backup::execSTOP_BACKUP_CONF(Signal* signal)
02053 {
02054 jamEntry();
02055
02056 StopBackupConf* conf = (StopBackupConf*)signal->getDataPtr();
02057 const Uint32 ptrI = conf->backupPtr;
02058
02059 const Uint32 nodeId = refToNode(signal->senderBlockRef());
02060
02061 BackupRecordPtr ptr;
02062 c_backupPool.getPtr(ptr, ptrI);
02063
02064 ptr.p->noOfLogBytes += conf->noOfLogBytes;
02065 ptr.p->noOfLogRecords += conf->noOfLogRecords;
02066
02067 stopBackupReply(signal, ptr, nodeId);
02068 }
02069
02070 void
02071 Backup::stopBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId)
02072 {
02073 CRASH_INSERTION((10013));
02074
02075 if (!haveAllSignals(ptr, GSN_STOP_BACKUP_REQ, nodeId)) {
02076 jam();
02077 return;
02078 }
02079
02080 sendAbortBackupOrd(signal, ptr, AbortBackupOrd::BackupComplete);
02081
02082 if(!ptr.p->checkError())
02083 {
02084 BackupCompleteRep * rep = (BackupCompleteRep*)signal->getDataPtrSend();
02085 rep->backupId = ptr.p->backupId;
02086 rep->senderData = ptr.p->clientData;
02087 rep->startGCP = ptr.p->startGCP;
02088 rep->stopGCP = ptr.p->stopGCP;
02089 rep->noOfBytes = ptr.p->noOfBytes;
02090 rep->noOfRecords = ptr.p->noOfRecords;
02091 rep->noOfLogBytes = ptr.p->noOfLogBytes;
02092 rep->noOfLogRecords = ptr.p->noOfLogRecords;
02093 rep->nodes = ptr.p->nodes;
02094 sendSignal(ptr.p->clientRef, GSN_BACKUP_COMPLETE_REP, signal,
02095 BackupCompleteRep::SignalLength, JBB);
02096
02097 signal->theData[0] = NDB_LE_BackupCompleted;
02098 signal->theData[1] = ptr.p->clientRef;
02099 signal->theData[2] = ptr.p->backupId;
02100 signal->theData[3] = ptr.p->startGCP;
02101 signal->theData[4] = ptr.p->stopGCP;
02102 signal->theData[5] = ptr.p->noOfBytes;
02103 signal->theData[6] = ptr.p->noOfRecords;
02104 signal->theData[7] = ptr.p->noOfLogBytes;
02105 signal->theData[8] = ptr.p->noOfLogRecords;
02106 ptr.p->nodes.copyto(NdbNodeBitmask::Size, signal->theData+9);
02107 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 9+NdbNodeBitmask::Size, JBB);
02108 }
02109 else
02110 {
02111 masterAbort(signal, ptr);
02112 }
02113 }
02114
02115
02116
02117
02118
02119
02120 void
02121 Backup::masterAbort(Signal* signal, BackupRecordPtr ptr)
02122 {
02123 jam();
02124 #ifdef DEBUG_ABORT
02125 ndbout_c("************ masterAbort");
02126 #endif
02127 if(ptr.p->masterData.errorCode != 0)
02128 {
02129 jam();
02130 return;
02131 }
02132
02133 BackupAbortRep* rep = (BackupAbortRep*)signal->getDataPtrSend();
02134 rep->backupId = ptr.p->backupId;
02135 rep->senderData = ptr.p->clientData;
02136 rep->reason = ptr.p->errorCode;
02137 sendSignal(ptr.p->clientRef, GSN_BACKUP_ABORT_REP, signal,
02138 BackupAbortRep::SignalLength, JBB);
02139
02140 signal->theData[0] = NDB_LE_BackupAborted;
02141 signal->theData[1] = ptr.p->clientRef;
02142 signal->theData[2] = ptr.p->backupId;
02143 signal->theData[3] = ptr.p->errorCode;
02144 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
02145
02146 ndbrequire(ptr.p->errorCode);
02147 ptr.p->masterData.errorCode = ptr.p->errorCode;
02148
02149 AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
02150 ord->backupId = ptr.p->backupId;
02151 ord->backupPtr = ptr.i;
02152 ord->senderData= ptr.i;
02153 NodeReceiverGroup rg(BACKUP, ptr.p->nodes);
02154
02155 switch(ptr.p->masterData.gsn){
02156 case GSN_DEFINE_BACKUP_REQ:
02157 ord->requestType = AbortBackupOrd::BackupFailure;
02158 sendSignal(rg, GSN_ABORT_BACKUP_ORD, signal,
02159 AbortBackupOrd::SignalLength, JBB);
02160 return;
02161 case GSN_CREATE_TRIG_REQ:
02162 case GSN_START_BACKUP_REQ:
02163 case GSN_ALTER_TRIG_REQ:
02164 case GSN_WAIT_GCP_REQ:
02165 case GSN_BACKUP_FRAGMENT_REQ:
02166 jam();
02167 ptr.p->stopGCP= ptr.p->startGCP + 1;
02168 sendDropTrig(signal, ptr);
02169 return;
02170 case GSN_UTIL_SEQUENCE_REQ:
02171 case GSN_UTIL_LOCK_REQ:
02172 case GSN_DROP_TRIG_REQ:
02173 ndbrequire(false);
02174 return;
02175 case GSN_STOP_BACKUP_REQ:
02176 return;
02177 }
02178 }
02179
02180 void
02181 Backup::abort_scan(Signal * signal, BackupRecordPtr ptr)
02182 {
02183 AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
02184 ord->backupId = ptr.p->backupId;
02185 ord->backupPtr = ptr.i;
02186 ord->senderData= ptr.i;
02187 ord->requestType = AbortBackupOrd::AbortScan;
02188
02189 TablePtr tabPtr;
02190 ptr.p->tables.first(tabPtr);
02191 for(; tabPtr.i != RNIL; ptr.p->tables.next(tabPtr)) {
02192 jam();
02193 FragmentPtr fragPtr;
02194 Array<Fragment> & frags = tabPtr.p->fragments;
02195 const Uint32 fragCount = frags.getSize();
02196
02197 for(Uint32 i = 0; i<fragCount; i++) {
02198 jam();
02199 tabPtr.p->fragments.getPtr(fragPtr, i);
02200 const Uint32 nodeId = fragPtr.p->node;
02201 if(fragPtr.p->scanning != 0 && ptr.p->nodes.get(nodeId)) {
02202 jam();
02203
02204 const BlockReference ref = numberToRef(BACKUP, nodeId);
02205 sendSignal(ref, GSN_ABORT_BACKUP_ORD, signal,
02206 AbortBackupOrd::SignalLength, JBB);
02207
02208 }
02209 }
02210 }
02211 }
02212
02213
02214
02215
02216
02217
02218 void
02219 Backup::defineBackupRef(Signal* signal, BackupRecordPtr ptr, Uint32 errCode)
02220 {
02221 ptr.p->m_gsn = GSN_DEFINE_BACKUP_REF;
02222 ptr.p->setErrorCode(errCode);
02223 ndbrequire(ptr.p->errorCode != 0);
02224
02225 DefineBackupRef* ref = (DefineBackupRef*)signal->getDataPtrSend();
02226 ref->backupId = ptr.p->backupId;
02227 ref->backupPtr = ptr.i;
02228 ref->errorCode = ptr.p->errorCode;
02229 ref->nodeId = getOwnNodeId();
02230 sendSignal(ptr.p->masterRef, GSN_DEFINE_BACKUP_REF, signal,
02231 DefineBackupRef::SignalLength, JBB);
02232 }
02233
02234 void
02235 Backup::execDEFINE_BACKUP_REQ(Signal* signal)
02236 {
02237 jamEntry();
02238
02239 DefineBackupReq* req = (DefineBackupReq*)signal->getDataPtr();
02240
02241 BackupRecordPtr ptr;
02242 const Uint32 ptrI = req->backupPtr;
02243 const Uint32 backupId = req->backupId;
02244 const BlockReference senderRef = req->senderRef;
02245
02246 if(senderRef == reference()){
02250 jam();
02251 c_backupPool.getPtr(ptr, ptrI);
02252 } else {
02253 jam();
02254 #ifdef DEBUG_ABORT
02255 dumpUsedResources();
02256 #endif
02257 if(!c_backups.seizeId(ptr, ptrI)) {
02258 jam();
02259 ndbrequire(false);
02260 }
02261 }
02262
02263 CRASH_INSERTION((10014));
02264
02265 ptr.p->m_gsn = GSN_DEFINE_BACKUP_REQ;
02266 ptr.p->slaveState.forceState(INITIAL);
02267 ptr.p->slaveState.setState(DEFINING);
02268 ptr.p->errorCode = 0;
02269 ptr.p->clientRef = req->clientRef;
02270 ptr.p->clientData = req->clientData;
02271 ptr.p->masterRef = senderRef;
02272 ptr.p->nodes = req->nodes;
02273 ptr.p->backupId = backupId;
02274 ptr.p->backupKey[0] = req->backupKey[0];
02275 ptr.p->backupKey[1] = req->backupKey[1];
02276 ptr.p->backupDataLen = req->backupDataLen;
02277 ptr.p->masterData.dropTrig.tableId = RNIL;
02278 ptr.p->masterData.alterTrig.tableId = RNIL;
02279 ptr.p->masterData.errorCode = 0;
02280 ptr.p->noOfBytes = 0;
02281 ptr.p->noOfRecords = 0;
02282 ptr.p->noOfLogBytes = 0;
02283 ptr.p->noOfLogRecords = 0;
02284 ptr.p->currGCP = 0;
02285
02289 BackupFilePtr files[3];
02290 Uint32 noOfPages[] = {
02291 NO_OF_PAGES_META_FILE,
02292 2,
02293 0
02294 };
02295 const Uint32 maxInsert[] = {
02296 2048,
02297
02298 2048,
02299 16*3000,
02300 };
02301 Uint32 minWrite[] = {
02302 8192,
02303 8192,
02304 32768
02305 };
02306 Uint32 maxWrite[] = {
02307 8192,
02308 8192,
02309 32768
02310 };
02311
02312 minWrite[1] = c_defaults.m_minWriteSize;
02313 maxWrite[1] = c_defaults.m_maxWriteSize;
02314 noOfPages[1] = (c_defaults.m_logBufferSize + sizeof(Page32) - 1) /
02315 sizeof(Page32);
02316 minWrite[2] = c_defaults.m_minWriteSize;
02317 maxWrite[2] = c_defaults.m_maxWriteSize;
02318 noOfPages[2] = (c_defaults.m_dataBufferSize + sizeof(Page32) - 1) /
02319 sizeof(Page32);
02320
02321 for(Uint32 i = 0; i<3; i++) {
02322 jam();
02323 if(!ptr.p->files.seize(files[i])) {
02324 jam();
02325 defineBackupRef(signal, ptr,
02326 DefineBackupRef::FailedToAllocateFileRecord);
02327 return;
02328 }
02329
02330 files[i].p->tableId = RNIL;
02331 files[i].p->backupPtr = ptr.i;
02332 files[i].p->filePointer = RNIL;
02333 files[i].p->fileClosing = 0;
02334 files[i].p->fileOpened = 0;
02335 files[i].p->fileRunning = 0;
02336 files[i].p->scanRunning = 0;
02337 files[i].p->errorCode = 0;
02338
02339 if(files[i].p->pages.seize(noOfPages[i]) == false) {
02340 jam();
02341 DEBUG_OUT("Failed to seize " << noOfPages[i] << " pages");
02342 defineBackupRef(signal, ptr, DefineBackupRef::FailedToAllocateBuffers);
02343 return;
02344 }
02345 Page32Ptr pagePtr;
02346 files[i].p->pages.getPtr(pagePtr, 0);
02347
02348 const char * msg = files[i].p->
02349 operation.dataBuffer.setup((Uint32*)pagePtr.p,
02350 noOfPages[i] * (sizeof(Page32) >> 2),
02351 128,
02352 minWrite[i] >> 2,
02353 maxWrite[i] >> 2,
02354 maxInsert[i]);
02355 if(msg != 0) {
02356 jam();
02357 defineBackupRef(signal, ptr, DefineBackupRef::FailedToSetupFsBuffers);
02358 return;
02359 }
02360 }
02361 files[0].p->fileType = BackupFormat::CTL_FILE;
02362 files[1].p->fileType = BackupFormat::LOG_FILE;
02363 files[2].p->fileType = BackupFormat::DATA_FILE;
02364
02365 ptr.p->ctlFilePtr = files[0].i;
02366 ptr.p->logFilePtr = files[1].i;
02367 ptr.p->dataFilePtr = files[2].i;
02368
02369 if (!verifyNodesAlive(ptr, ptr.p->nodes)) {
02370 jam();
02371 defineBackupRef(signal, ptr, DefineBackupRef::Undefined);
02372 return;
02373 }
02374 if (ERROR_INSERTED(10027)) {
02375 jam();
02376 defineBackupRef(signal, ptr, 327);
02377 return;
02378 }
02379
02380 if(ptr.p->backupDataLen == 0) {
02381 jam();
02382 backupAllData(signal, ptr);
02383 return;
02384 }
02385
02389 ndbrequire(0);
02390 }
02391
02392 void
02393 Backup::backupAllData(Signal* signal, BackupRecordPtr ptr)
02394 {
02398 ListTablesReq * req = (ListTablesReq*)signal->getDataPtrSend();
02399 req->senderRef = reference();
02400 req->senderData = ptr.i;
02401 req->requestData = 0;
02402 sendSignal(DBDICT_REF, GSN_LIST_TABLES_REQ, signal,
02403 ListTablesReq::SignalLength, JBB);
02404 }
02405
02406 void
02407 Backup::execLIST_TABLES_CONF(Signal* signal)
02408 {
02409 jamEntry();
02410
02411 ListTablesConf* conf = (ListTablesConf*)signal->getDataPtr();
02412
02413 BackupRecordPtr ptr;
02414 c_backupPool.getPtr(ptr, conf->senderData);
02415
02416 const Uint32 len = signal->length() - ListTablesConf::HeaderLength;
02417 for(unsigned int i = 0; i<len; i++) {
02418 jam();
02419 Uint32 tableId = ListTablesConf::getTableId(conf->tableData[i]);
02420 Uint32 tableType = ListTablesConf::getTableType(conf->tableData[i]);
02421 if (!DictTabInfo::isTable(tableType) && !DictTabInfo::isIndex(tableType)){
02422 jam();
02423 continue;
02424 }
02425 TablePtr tabPtr;
02426 ptr.p->tables.seize(tabPtr);
02427 if(tabPtr.i == RNIL) {
02428 jam();
02429 defineBackupRef(signal, ptr, DefineBackupRef::FailedToAllocateTables);
02430 return;
02431 }
02432 tabPtr.p->tableId = tableId;
02433 tabPtr.p->tableType = tableType;
02434 }
02435
02436 if(len == ListTablesConf::DataLength) {
02437 jam();
02441 return;
02442 }
02443
02447 openFiles(signal, ptr);
02448 }
02449
02450 void
02451 Backup::openFiles(Signal* signal, BackupRecordPtr ptr)
02452 {
02453 jam();
02454
02455 BackupFilePtr filePtr;
02456
02457 FsOpenReq * req = (FsOpenReq *)signal->getDataPtrSend();
02458 req->userReference = reference();
02459 req->fileFlags =
02460 FsOpenReq::OM_WRITEONLY |
02461 FsOpenReq::OM_TRUNCATE |
02462 FsOpenReq::OM_CREATE |
02463 FsOpenReq::OM_APPEND |
02464 FsOpenReq::OM_SYNC;
02465 FsOpenReq::v2_setCount(req->fileNumber, 0xFFFFFFFF);
02466
02470 c_backupFilePool.getPtr(filePtr, ptr.p->ctlFilePtr);
02471 ndbrequire(filePtr.p->fileRunning == 0);
02472 filePtr.p->fileRunning = 1;
02473
02474 req->userPointer = filePtr.i;
02475 FsOpenReq::setVersion(req->fileNumber, 2);
02476 FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_CTL);
02477 FsOpenReq::v2_setSequence(req->fileNumber, ptr.p->backupId);
02478 FsOpenReq::v2_setNodeId(req->fileNumber, getOwnNodeId());
02479 sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
02480
02484 c_backupFilePool.getPtr(filePtr, ptr.p->logFilePtr);
02485 ndbrequire(filePtr.p->fileRunning == 0);
02486 filePtr.p->fileRunning = 1;
02487
02488 req->userPointer = filePtr.i;
02489 FsOpenReq::setVersion(req->fileNumber, 2);
02490 FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_LOG);
02491 FsOpenReq::v2_setSequence(req->fileNumber, ptr.p->backupId);
02492 FsOpenReq::v2_setNodeId(req->fileNumber, getOwnNodeId());
02493 sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
02494
02498 c_backupFilePool.getPtr(filePtr, ptr.p->dataFilePtr);
02499 ndbrequire(filePtr.p->fileRunning == 0);
02500 filePtr.p->fileRunning = 1;
02501
02502 req->userPointer = filePtr.i;
02503 FsOpenReq::setVersion(req->fileNumber, 2);
02504 FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_DATA);
02505 FsOpenReq::v2_setSequence(req->fileNumber, ptr.p->backupId);
02506 FsOpenReq::v2_setNodeId(req->fileNumber, getOwnNodeId());
02507 FsOpenReq::v2_setCount(req->fileNumber, 0);
02508 sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
02509 }
02510
02511 void
02512 Backup::execFSOPENREF(Signal* signal)
02513 {
02514 jamEntry();
02515
02516 FsRef * ref = (FsRef *)signal->getDataPtr();
02517
02518 const Uint32 userPtr = ref->userPointer;
02519
02520 BackupFilePtr filePtr;
02521 c_backupFilePool.getPtr(filePtr, userPtr);
02522
02523 BackupRecordPtr ptr;
02524 c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
02525 ptr.p->setErrorCode(ref->errorCode);
02526 openFilesReply(signal, ptr, filePtr);
02527 }
02528
02529 void
02530 Backup::execFSOPENCONF(Signal* signal)
02531 {
02532 jamEntry();
02533
02534 FsConf * conf = (FsConf *)signal->getDataPtr();
02535
02536 const Uint32 userPtr = conf->userPointer;
02537 const Uint32 filePointer = conf->filePointer;
02538
02539 BackupFilePtr filePtr;
02540 c_backupFilePool.getPtr(filePtr, userPtr);
02541 filePtr.p->filePointer = filePointer;
02542
02543 BackupRecordPtr ptr;
02544 c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
02545
02546 ndbrequire(filePtr.p->fileOpened == 0);
02547 filePtr.p->fileOpened = 1;
02548 openFilesReply(signal, ptr, filePtr);
02549 }
02550
02551 void
02552 Backup::openFilesReply(Signal* signal,
02553 BackupRecordPtr ptr, BackupFilePtr filePtr)
02554 {
02555 jam();
02556
02560 ndbrequire(filePtr.p->fileRunning == 1);
02561 filePtr.p->fileRunning = 0;
02562
02566 for(ptr.p->files.first(filePtr); filePtr.i!=RNIL;ptr.p->files.next(filePtr))
02567 {
02568 jam();
02569 if(filePtr.p->fileRunning == 1) {
02570 jam();
02571 return;
02572 }
02573 }
02574
02578 if(ptr.p->checkError()) {
02579 jam();
02580 defineBackupRef(signal, ptr);
02581 return;
02582 }
02583
02587 ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
02588 if(!insertFileHeader(BackupFormat::CTL_FILE, ptr.p, filePtr.p)) {
02589 jam();
02590 defineBackupRef(signal, ptr, DefineBackupRef::FailedInsertFileHeader);
02591 return;
02592 }
02593
02594 ptr.p->files.getPtr(filePtr, ptr.p->logFilePtr);
02595 if(!insertFileHeader(BackupFormat::LOG_FILE, ptr.p, filePtr.p)) {
02596 jam();
02597 defineBackupRef(signal, ptr, DefineBackupRef::FailedInsertFileHeader);
02598 return;
02599 }
02600
02601 ptr.p->files.getPtr(filePtr, ptr.p->dataFilePtr);
02602 if(!insertFileHeader(BackupFormat::DATA_FILE, ptr.p, filePtr.p)) {
02603 jam();
02604 defineBackupRef(signal, ptr, DefineBackupRef::FailedInsertFileHeader);
02605 return;
02606 }
02607
02611 ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
02612 filePtr.p->fileRunning = 1;
02613
02614 signal->theData[0] = BackupContinueB::START_FILE_THREAD;
02615 signal->theData[1] = ptr.p->ctlFilePtr;
02616 sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 100, 2);
02617
02621 FsBuffer & buf = filePtr.p->operation.dataBuffer;
02622
02623 const Uint32 sz =
02624 (sizeof(BackupFormat::CtlFile::TableList) >> 2) +
02625 ptr.p->tables.noOfElements() - 1;
02626
02627 Uint32 * dst;
02628 ndbrequire(sz < buf.getMaxWrite());
02629 if(!buf.getWritePtr(&dst, sz)) {
02630 jam();
02631 defineBackupRef(signal, ptr, DefineBackupRef::FailedInsertTableList);
02632 return;
02633 }
02634
02635 BackupFormat::CtlFile::TableList* tl =
02636 (BackupFormat::CtlFile::TableList*)dst;
02637 tl->SectionType = htonl(BackupFormat::TABLE_LIST);
02638 tl->SectionLength = htonl(sz);
02639
02640 TablePtr tabPtr;
02641 Uint32 count = 0;
02642 for(ptr.p->tables.first(tabPtr);
02643 tabPtr.i != RNIL;
02644 ptr.p->tables.next(tabPtr)){
02645 jam();
02646 tl->TableIds[count] = htonl(tabPtr.p->tableId);
02647 count++;
02648 }
02649
02650 buf.updateWritePtr(sz);
02651
02655 ndbrequire(ptr.p->tables.first(tabPtr));
02656
02657 signal->theData[0] = BackupContinueB::BUFFER_FULL_META;
02658 signal->theData[1] = ptr.i;
02659 signal->theData[2] = tabPtr.i;
02660 sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 100, 3);
02661 return;
02662 }
02663
02664 bool
02665 Backup::insertFileHeader(BackupFormat::FileType ft,
02666 BackupRecord * ptrP,
02667 BackupFile * filePtrP){
02668 FsBuffer & buf = filePtrP->operation.dataBuffer;
02669
02670 const Uint32 sz = sizeof(BackupFormat::FileHeader) >> 2;
02671
02672 Uint32 * dst;
02673 ndbrequire(sz < buf.getMaxWrite());
02674 if(!buf.getWritePtr(&dst, sz)) {
02675 jam();
02676 return false;
02677 }
02678
02679 BackupFormat::FileHeader* header = (BackupFormat::FileHeader*)dst;
02680 ndbrequire(sizeof(header->Magic) == sizeof(BACKUP_MAGIC));
02681 memcpy(header->Magic, BACKUP_MAGIC, sizeof(BACKUP_MAGIC));
02682 header->NdbVersion = htonl(NDB_VERSION);
02683 header->SectionType = htonl(BackupFormat::FILE_HEADER);
02684 header->SectionLength = htonl(sz - 3);
02685 header->FileType = htonl(ft);
02686 header->BackupId = htonl(ptrP->backupId);
02687 header->BackupKey_0 = htonl(ptrP->backupKey[0]);
02688 header->BackupKey_1 = htonl(ptrP->backupKey[1]);
02689 header->ByteOrder = 0x12345678;
02690
02691 buf.updateWritePtr(sz);
02692 return true;
02693 }
02694
02695 void
02696 Backup::execGET_TABINFOREF(Signal* signal)
02697 {
02698 GetTabInfoRef * ref = (GetTabInfoRef*)signal->getDataPtr();
02699
02700 const Uint32 senderData = ref->senderData;
02701 BackupRecordPtr ptr;
02702 c_backupPool.getPtr(ptr, senderData);
02703
02704 defineBackupRef(signal, ptr, ref->errorCode);
02705 }
02706
02707 void
02708 Backup::execGET_TABINFO_CONF(Signal* signal)
02709 {
02710 jamEntry();
02711
02712 if(!assembleFragments(signal)) {
02713 jam();
02714 return;
02715 }
02716
02717 GetTabInfoConf * const conf = (GetTabInfoConf*)signal->getDataPtr();
02718
02719 const Uint32 len = conf->totalLen;
02720 const Uint32 senderData = conf->senderData;
02721
02722 BackupRecordPtr ptr;
02723 c_backupPool.getPtr(ptr, senderData);
02724
02725 SegmentedSectionPtr dictTabInfoPtr;
02726 signal->getSection(dictTabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
02727 ndbrequire(dictTabInfoPtr.sz == len);
02728
02732 const Uint32 noPages = (len + sizeof(Page32) - 1) / sizeof(Page32);
02733 if(ptr.p->pages.getSize() < noPages) {
02734 jam();
02735 ptr.p->pages.release();
02736 if(ptr.p->pages.seize(noPages) == false) {
02737 jam();
02738 ptr.p->setErrorCode(DefineBackupRef::FailedAllocateTableMem);
02739 ndbrequire(false);
02740 releaseSections(signal);
02741 defineBackupRef(signal, ptr);
02742 return;
02743 }
02744 }
02745
02746 BackupFilePtr filePtr;
02747 ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
02748 FsBuffer & buf = filePtr.p->operation.dataBuffer;
02749 {
02750 Uint32* dst, dstLen = len + 2;
02751 if(!buf.getWritePtr(&dst, dstLen)) {
02752 jam();
02753 ndbrequire(false);
02754 ptr.p->setErrorCode(DefineBackupRef::FailedAllocateTableMem);
02755 releaseSections(signal);
02756 defineBackupRef(signal, ptr);
02757 return;
02758 }
02759 if(dst != 0) {
02760 jam();
02761
02762 BackupFormat::CtlFile::TableDescription * desc =
02763 (BackupFormat::CtlFile::TableDescription*)dst;
02764 desc->SectionType = htonl(BackupFormat::TABLE_DESCRIPTION);
02765 desc->SectionLength = htonl(len + 2);
02766 dst += 2;
02767
02768 copy(dst, dictTabInfoPtr);
02769 buf.updateWritePtr(dstLen);
02770 }
02771 }
02772
02773 ndbrequire(ptr.p->pages.getSize() >= noPages);
02774 Page32Ptr pagePtr;
02775 ptr.p->pages.getPtr(pagePtr, 0);
02776 copy(&pagePtr.p->data[0], dictTabInfoPtr);
02777 releaseSections(signal);
02778
02779 if(ptr.p->checkError()) {
02780 jam();
02781 defineBackupRef(signal, ptr);
02782 return;
02783 }
02784
02785 TablePtr tabPtr = parseTableDescription(signal, ptr, len);
02786 if(tabPtr.i == RNIL) {
02787 jam();
02788 defineBackupRef(signal, ptr);
02789 return;
02790 }
02791
02792 TablePtr tmp = tabPtr;
02793 ptr.p->tables.next(tabPtr);
02794 if(DictTabInfo::isIndex(tmp.p->tableType)){
02795 ptr.p->tables.release(tmp);
02796 }
02797
02798 if(tabPtr.i == RNIL) {
02799 jam();
02800
02801 ptr.p->pages.release();
02802
02803 ndbrequire(ptr.p->tables.first(tabPtr));
02804 signal->theData[0] = RNIL;
02805 signal->theData[1] = tabPtr.p->tableId;
02806 signal->theData[2] = ptr.i;
02807 sendSignal(DBDIH_REF, GSN_DI_FCOUNTREQ, signal, 3, JBB);
02808 return;
02809 }
02810
02811 signal->theData[0] = BackupContinueB::BUFFER_FULL_META;
02812 signal->theData[1] = ptr.i;
02813 signal->theData[2] = tabPtr.i;
02814 sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 100, 3);
02815 return;
02816 }
02817
02818 Backup::TablePtr
02819 Backup::parseTableDescription(Signal* signal, BackupRecordPtr ptr, Uint32 len)
02820 {
02821
02822 Page32Ptr pagePtr;
02823 ptr.p->pages.getPtr(pagePtr, 0);
02824
02825 SimplePropertiesLinearReader it(&pagePtr.p->data[0], len);
02826
02827 it.first();
02828
02829 DictTabInfo::Table tmpTab; tmpTab.init();
02830 SimpleProperties::UnpackStatus stat;
02831 stat = SimpleProperties::unpack(it, &tmpTab,
02832 DictTabInfo::TableMapping,
02833 DictTabInfo::TableMappingSize,
02834 true, true);
02835 ndbrequire(stat == SimpleProperties::Break);
02836
02837 TablePtr tabPtr;
02838 ndbrequire(findTable(ptr, tabPtr, tmpTab.TableId));
02839 if(DictTabInfo::isIndex(tabPtr.p->tableType)){
02840 jam();
02841 return tabPtr;
02842 }
02843
02847 tabPtr.p->frag_mask = RNIL;
02848
02849 tabPtr.p->schemaVersion = tmpTab.TableVersion;
02850 tabPtr.p->noOfAttributes = tmpTab.NoOfAttributes;
02851 tabPtr.p->noOfNull = 0;
02852 tabPtr.p->noOfVariable = 0;
02853 tabPtr.p->sz_FixedAttributes = 0;
02854 tabPtr.p->triggerIds[0] = ILLEGAL_TRIGGER_ID;
02855 tabPtr.p->triggerIds[1] = ILLEGAL_TRIGGER_ID;
02856 tabPtr.p->triggerIds[2] = ILLEGAL_TRIGGER_ID;
02857 tabPtr.p->triggerAllocated[0] = false;
02858 tabPtr.p->triggerAllocated[1] = false;
02859 tabPtr.p->triggerAllocated[2] = false;
02860
02861 if(tabPtr.p->attributes.seize(tabPtr.p->noOfAttributes) == false) {
02862 jam();
02863 ptr.p->setErrorCode(DefineBackupRef::FailedToAllocateAttributeRecord);
02864 tabPtr.i = RNIL;
02865 return tabPtr;
02866 }
02867
02868 const Uint32 count = tabPtr.p->noOfAttributes;
02869 for(Uint32 i = 0; i<count; i++) {
02870 jam();
02871 DictTabInfo::Attribute tmp; tmp.init();
02872 stat = SimpleProperties::unpack(it, &tmp,
02873 DictTabInfo::AttributeMapping,
02874 DictTabInfo::AttributeMappingSize,
02875 true, true);
02876
02877 ndbrequire(stat == SimpleProperties::Break);
02878
02879 const Uint32 arr = tmp.AttributeArraySize;
02880 const Uint32 sz = 1 << tmp.AttributeSize;
02881 const Uint32 sz32 = (sz * arr + 31) >> 5;
02882
02883 AttributePtr attrPtr;
02884 tabPtr.p->attributes.getPtr(attrPtr, tmp.AttributeId);
02885
02886 attrPtr.p->data.nullable = tmp.AttributeNullableFlag;
02887 attrPtr.p->data.fixed = (tmp.AttributeArraySize != 0);
02888 attrPtr.p->data.sz32 = sz32;
02889
02896 if(attrPtr.p->data.fixed == true && attrPtr.p->data.nullable == false) {
02897 jam();
02898 attrPtr.p->data.offset = tabPtr.p->sz_FixedAttributes;
02899 tabPtr.p->sz_FixedAttributes += sz32;
02900 }
02901
02902 if(attrPtr.p->data.fixed == true && attrPtr.p->data.nullable == true) {
02903 jam();
02904 attrPtr.p->data.offset = 0;
02905
02906 attrPtr.p->data.offsetNull = tabPtr.p->noOfNull;
02907 tabPtr.p->noOfNull++;
02908 tabPtr.p->noOfVariable++;
02909 }
02910
02911 if(attrPtr.p->data.fixed == false) {
02912 jam();
02913 tabPtr.p->noOfVariable++;
02914 ndbrequire(0);
02915 }
02916
02917 it.next();
02918 }
02919 return tabPtr;
02920 }
02921
02922 void
02923 Backup::execDI_FCOUNTCONF(Signal* signal)
02924 {
02925 jamEntry();
02926
02927 const Uint32 userPtr = signal->theData[0];
02928 const Uint32 fragCount = signal->theData[1];
02929 const Uint32 tableId = signal->theData[2];
02930 const Uint32 senderData = signal->theData[3];
02931
02932 ndbrequire(userPtr == RNIL && signal->length() == 5);
02933
02934 BackupRecordPtr ptr;
02935 c_backupPool.getPtr(ptr, senderData);
02936
02937 TablePtr tabPtr;
02938 ndbrequire(findTable(ptr, tabPtr, tableId));
02939
02940 ndbrequire(tabPtr.p->fragments.seize(fragCount) != false);
02941 tabPtr.p->frag_mask = calculate_frag_mask(fragCount);
02942 for(Uint32 i = 0; i<fragCount; i++) {
02943 jam();
02944 FragmentPtr fragPtr;
02945 tabPtr.p->fragments.getPtr(fragPtr, i);
02946 fragPtr.p->scanned = 0;
02947 fragPtr.p->scanning = 0;
02948 fragPtr.p->tableId = tableId;
02949 fragPtr.p->node = RNIL;
02950 }
02951
02955 if(ptr.p->tables.next(tabPtr)) {
02956 jam();
02957 signal->theData[0] = RNIL;
02958 signal->theData[1] = tabPtr.p->tableId;
02959 signal->theData[2] = ptr.i;
02960 sendSignal(DBDIH_REF, GSN_DI_FCOUNTREQ, signal, 3, JBB);
02961 return;
02962 }
02963
02964 ptr.p->tables.first(tabPtr);
02965 getFragmentInfo(signal, ptr, tabPtr, 0);
02966 }
02967
02968 void
02969 Backup::getFragmentInfo(Signal* signal,
02970 BackupRecordPtr ptr, TablePtr tabPtr, Uint32 fragNo)
02971 {
02972 jam();
02973
02974 for(; tabPtr.i != RNIL; ptr.p->tables.next(tabPtr)) {
02975 jam();
02976 const Uint32 fragCount = tabPtr.p->fragments.getSize();
02977 for(; fragNo < fragCount; fragNo ++) {
02978 jam();
02979 FragmentPtr fragPtr;
02980 tabPtr.p->fragments.getPtr(fragPtr, fragNo);
02981
02982 if(fragPtr.p->scanned == 0 && fragPtr.p->scanning == 0) {
02983 jam();
02984 signal->theData[0] = RNIL;
02985 signal->theData[1] = ptr.i;
02986 signal->theData[2] = tabPtr.p->tableId;
02987 signal->theData[3] = fragNo;
02988 sendSignal(DBDIH_REF, GSN_DIGETPRIMREQ, signal, 4, JBB);
02989 return;
02990 }
02991 }
02992 fragNo = 0;
02993 }
02994
02995 getFragmentInfoDone(signal, ptr);
02996 }
02997
02998 void
02999 Backup::execDIGETPRIMCONF(Signal* signal)
03000 {
03001 jamEntry();
03002
03003 const Uint32 userPtr = signal->theData[0];
03004 const Uint32 senderData = signal->theData[1];
03005 const Uint32 nodeCount = signal->theData[6];
03006 const Uint32 tableId = signal->theData[7];
03007 const Uint32 fragNo = signal->theData[8];
03008
03009 ndbrequire(userPtr == RNIL && signal->length() == 9);
03010 ndbrequire(nodeCount > 0 && nodeCount <= MAX_REPLICAS);
03011
03012 BackupRecordPtr ptr;
03013 c_backupPool.getPtr(ptr, senderData);
03014
03015 TablePtr tabPtr;
03016 ndbrequire(findTable(ptr, tabPtr, tableId));
03017
03018 FragmentPtr fragPtr;
03019 tabPtr.p->fragments.getPtr(fragPtr, fragNo);
03020
03021 fragPtr.p->node = signal->theData[2];
03022
03023 getFragmentInfo(signal, ptr, tabPtr, fragNo + 1);
03024 }
03025
03026 void
03027 Backup::getFragmentInfoDone(Signal* signal, BackupRecordPtr ptr)
03028 {
03029 ptr.p->m_gsn = GSN_DEFINE_BACKUP_CONF;
03030 ptr.p->slaveState.setState(DEFINED);
03031 DefineBackupConf * conf = (DefineBackupConf*)signal->getDataPtr();
03032 conf->backupPtr = ptr.i;
03033 conf->backupId = ptr.p->backupId;
03034 sendSignal(ptr.p->masterRef, GSN_DEFINE_BACKUP_CONF, signal,
03035 DefineBackupConf::SignalLength, JBB);
03036 }
03037
03038
03039
03040
03041
03042
03043
03044 void
03045 Backup::execSTART_BACKUP_REQ(Signal* signal)
03046 {
03047 jamEntry();
03048
03049 CRASH_INSERTION((10015));
03050
03051 StartBackupReq* req = (StartBackupReq*)signal->getDataPtr();
03052 const Uint32 ptrI = req->backupPtr;
03053
03054 const Uint32 signalNo = req->signalNo;
03055
03056 BackupRecordPtr ptr;
03057 c_backupPool.getPtr(ptr, ptrI);
03058
03059 ptr.p->slaveState.setState(STARTED);
03060 ptr.p->m_gsn = GSN_START_BACKUP_REQ;
03061
03062 for(Uint32 i = 0; i<req->noOfTableTriggers; i++) {
03063 jam();
03064 TablePtr tabPtr;
03065 ndbrequire(findTable(ptr, tabPtr, req->tableTriggers[i].tableId));
03066 for(Uint32 j = 0; j<3; j++) {
03067 jam();
03068 const Uint32 triggerId = req->tableTriggers[i].triggerIds[j];
03069 tabPtr.p->triggerIds[j] = triggerId;
03070
03071 TriggerPtr trigPtr;
03072 if(!ptr.p->triggers.seizeId(trigPtr, triggerId)) {
03073 jam();
03074 ptr.p->m_gsn = GSN_START_BACKUP_REF;
03075 StartBackupRef* ref = (StartBackupRef*)signal->getDataPtrSend();
03076 ref->backupPtr = ptr.i;
03077 ref->backupId = ptr.p->backupId;
03078 ref->signalNo = signalNo;
03079 ref->errorCode = StartBackupRef::FailedToAllocateTriggerRecord;
03080 ref->nodeId = getOwnNodeId();
03081 sendSignal(ptr.p->masterRef, GSN_START_BACKUP_REF, signal,
03082 StartBackupRef::SignalLength, JBB);
03083 return;
03084 }
03085
03086 tabPtr.p->triggerAllocated[j] = true;
03087 trigPtr.p->backupPtr = ptr.i;
03088 trigPtr.p->tableId = tabPtr.p->tableId;
03089 trigPtr.p->tab_ptr_i = tabPtr.i;
03090 trigPtr.p->logEntry = 0;
03091 trigPtr.p->event = j;
03092 trigPtr.p->maxRecordSize = 2048;
03093 trigPtr.p->operation =
03094 &ptr.p->files.getPtr(ptr.p->logFilePtr)->operation;
03095 trigPtr.p->operation->noOfBytes = 0;
03096 trigPtr.p->operation->noOfRecords = 0;
03097 trigPtr.p->errorCode = 0;
03098 }
03099 }
03100
03104 BackupFilePtr filePtr;
03105 for(ptr.p->files.first(filePtr);
03106 filePtr.i!=RNIL;
03107 ptr.p->files.next(filePtr)){
03108 jam();
03109 if(filePtr.p->fileRunning == 0) {
03110 jam();
03111 filePtr.p->fileRunning = 1;
03112 signal->theData[0] = BackupContinueB::START_FILE_THREAD;
03113 signal->theData[1] = filePtr.i;
03114 sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 100, 2);
03115 }
03116 }
03117
03118 ptr.p->m_gsn = GSN_START_BACKUP_CONF;
03119 StartBackupConf* conf = (StartBackupConf*)signal->getDataPtrSend();
03120 conf->backupPtr = ptr.i;
03121 conf->backupId = ptr.p->backupId;
03122 conf->signalNo = signalNo;
03123 sendSignal(ptr.p->masterRef, GSN_START_BACKUP_CONF, signal,
03124 StartBackupConf::SignalLength, JBB);
03125 }
03126
03127
03128
03129
03130
03131
03132 void
03133 Backup::execBACKUP_FRAGMENT_REQ(Signal* signal)
03134 {
03135 jamEntry();
03136 BackupFragmentReq* req = (BackupFragmentReq*)signal->getDataPtr();
03137
03138 CRASH_INSERTION((10016));
03139
03140 const Uint32 ptrI = req->backupPtr;
03141
03142 const Uint32 tableId = req->tableId;
03143 const Uint32 fragNo = req->fragmentNo;
03144 const Uint32 count = req->count;
03145
03149 BackupRecordPtr ptr;
03150 c_backupPool.getPtr(ptr, ptrI);
03151
03152 ptr.p->slaveState.setState(SCANNING);
03153 ptr.p->m_gsn = GSN_BACKUP_FRAGMENT_REQ;
03154
03158 BackupFilePtr filePtr;
03159 c_backupFilePool.getPtr(filePtr, ptr.p->dataFilePtr);
03160
03161 ndbrequire(filePtr.p->backupPtr == ptrI);
03162 ndbrequire(filePtr.p->fileOpened == 1);
03163 ndbrequire(filePtr.p->fileRunning == 1);
03164 ndbrequire(filePtr.p->scanRunning == 0);
03165 ndbrequire(filePtr.p->fileClosing == 0);
03166
03170 TablePtr tabPtr;
03171 ndbrequire(findTable(ptr, tabPtr, tableId));
03172
03176 FragmentPtr fragPtr;
03177 tabPtr.p->fragments.getPtr(fragPtr, fragNo);
03178
03179 ndbrequire(fragPtr.p->scanned == 0);
03180 ndbrequire(fragPtr.p->scanning == 0 ||
03181 refToNode(ptr.p->masterRef) == getOwnNodeId());
03182
03186 if(filePtr.p->tableId != tableId) {
03187 jam();
03188 filePtr.p->operation.init(tabPtr);
03189 filePtr.p->tableId = tableId;
03190 }
03191
03195 if(!filePtr.p->operation.newFragment(tableId, fragNo)) {
03196 jam();
03197 req->count = count + 1;
03198 sendSignalWithDelay(BACKUP_REF, GSN_BACKUP_FRAGMENT_REQ, signal, 50,
03199 signal->length());
03200 ptr.p->slaveState.setState(STARTED);
03201 return;
03202 }
03203
03207 fragPtr.p->scanning = 1;
03208 filePtr.p->fragmentNo = fragNo;
03209
03213 {
03214 filePtr.p->scanRunning = 1;
03215
03216 Table & table = * tabPtr.p;
03217 ScanFragReq * req = (ScanFragReq *)signal->getDataPtrSend();
03218 const Uint32 parallelism = 16;
03219 const Uint32 attrLen = 5 + table.noOfAttributes;
03220
03221 req->senderData = filePtr.i;
03222 req->resultRef = reference();
03223 req->schemaVersion = table.schemaVersion;
03224 req->fragmentNoKeyLen = fragNo;
03225 req->requestInfo = 0;
03226 req->savePointId = 0;
03227 req->tableId = table.tableId;
03228 ScanFragReq::setLockMode(req->requestInfo, 0);
03229 ScanFragReq::setHoldLockFlag(req->requestInfo, 0);
03230 ScanFragReq::setKeyinfoFlag(req->requestInfo, 0);
03231 ScanFragReq::setAttrLen(req->requestInfo,attrLen);
03232 req->transId1 = 0;
03233 req->transId2 = (BACKUP << 20) + (getOwnNodeId() << 8);
03234 req->clientOpPtr= filePtr.i;
03235 req->batch_size_rows= parallelism;
03236 req->batch_size_bytes= 0;
03237 sendSignal(DBLQH_REF, GSN_SCAN_FRAGREQ, signal,
03238 ScanFragReq::SignalLength, JBB);
03239
03240 signal->theData[0] = filePtr.i;
03241 signal->theData[1] = 0;
03242 signal->theData[2] = (BACKUP << 20) + (getOwnNodeId() << 8);
03243
03244
03245 signal->theData[3] = table.noOfAttributes;
03246 signal->theData[4] = 0;
03247 signal->theData[5] = 0;
03248 signal->theData[6] = 0;
03249 signal->theData[7] = 0;
03250
03251 Uint32 dataPos = 8;
03252 Uint32 i;
03253 for(i = 0; i<table.noOfAttributes; i++) {
03254 jam();
03255 AttributePtr attr;
03256 table.attributes.getPtr(attr, i);
03257
03258 AttributeHeader::init(&signal->theData[dataPos], i, 0);
03259 dataPos++;
03260 if(dataPos == 25) {
03261 jam();
03262 sendSignal(DBLQH_REF, GSN_ATTRINFO, signal, 25, JBB);
03263 dataPos = 3;
03264 }
03265 }
03266 if(dataPos != 3) {
03267 jam();
03268 sendSignal(DBLQH_REF, GSN_ATTRINFO, signal, dataPos, JBB);
03269 }
03270 }
03271 }
03272
03273 void
03274 Backup::execSCAN_HBREP(Signal* signal)
03275 {
03276 jamEntry();
03277 }
03278
03279 void
03280 Backup::execTRANSID_AI(Signal* signal)
03281 {
03282 jamEntry();
03283
03284 const Uint32 filePtrI = signal->theData[0];
03285
03286
03287 const Uint32 dataLen = signal->length() - 3;
03288
03289 BackupFilePtr filePtr;
03290 c_backupFilePool.getPtr(filePtr, filePtrI);
03291
03292 OperationRecord & op = filePtr.p->operation;
03293
03294 TablePtr tabPtr;
03295 c_tablePool.getPtr(tabPtr, op.tablePtr);
03296
03297 Table & table = * tabPtr.p;
03298
03302 op.attrSzTotal += dataLen;
03303
03304 Uint32 srcSz = dataLen;
03305 const Uint32 * src = &signal->theData[3];
03306
03307 Uint32 * dst = op.dst;
03308 Uint32 dstSz = op.attrSzLeft;
03309
03310 while(srcSz > 0) {
03311 jam();
03312
03313 if(dstSz == 0) {
03314 jam();
03315
03319 const AttributeHeader attrHead(* src);
03320 const Uint32 attrId = attrHead.getAttributeId();
03321 const bool null = attrHead.isNULL();
03322 const Attribute::Data attr = table.attributes.getPtr(attrId)->data;
03323
03324 srcSz -= attrHead.getHeaderSize();
03325 src += attrHead.getHeaderSize();
03326
03327 if(null) {
03328 jam();
03329 ndbrequire(attr.nullable);
03330 op.nullAttribute(attr.offsetNull);
03331 dstSz = 0;
03332 continue;
03333 }
03334
03335 dstSz = attrHead.getDataSize();
03336 ndbrequire(dstSz == attr.sz32);
03337 if(attr.fixed && ! attr.nullable) {
03338 jam();
03339 dst = op.newAttrib(attr.offset, dstSz);
03340 } else if (attr.fixed && attr.nullable) {
03341 jam();
03342 dst = op.newNullable(attrId, dstSz);
03343 } else {
03344 ndbrequire(false);
03345
03346 }
03347 }
03348
03349 const Uint32 szCopy = (dstSz > srcSz) ? srcSz : dstSz;
03350 memcpy(dst, src, (szCopy << 2));
03351
03352 srcSz -= szCopy;
03353 dstSz -= szCopy;
03354 src += szCopy;
03355 dst += szCopy;
03356 }
03357 op.dst = dst;
03358 op.attrSzLeft = dstSz;
03359
03360 if(op.finished()){
03361 jam();
03362 op.newRecord(op.dst);
03363 }
03364 }
03365
03366 void
03367 Backup::OperationRecord::init(const TablePtr & ptr)
03368 {
03369
03370 tablePtr = ptr.i;
03371 noOfAttributes = ptr.p->noOfAttributes;
03372
03373 sz_Bitmask = (ptr.p->noOfNull + 31) >> 5;
03374 sz_FixedAttribs = ptr.p->sz_FixedAttributes;
03375
03376 if(ptr.p->noOfVariable == 0) {
03377 jam();
03378 maxRecordSize = 1 + sz_Bitmask + sz_FixedAttribs;
03379 } else {
03380 jam();
03381 maxRecordSize =
03382 1 + sz_Bitmask + 2048 + 2 * ptr.p->noOfVariable;
03383 }
03384 }
03385
03386 bool
03387 Backup::OperationRecord::newFragment(Uint32 tableId, Uint32 fragNo)
03388 {
03389 Uint32 * tmp;
03390 const Uint32 headSz = (sizeof(BackupFormat::DataFile::FragmentHeader) >> 2);
03391 const Uint32 sz = headSz + 16 * maxRecordSize;
03392
03393 ndbrequire(sz < dataBuffer.getMaxWrite());
03394 if(dataBuffer.getWritePtr(&tmp, sz)) {
03395 jam();
03396 BackupFormat::DataFile::FragmentHeader * head =
03397 (BackupFormat::DataFile::FragmentHeader*)tmp;
03398
03399 head->SectionType = htonl(BackupFormat::FRAGMENT_HEADER);
03400 head->SectionLength = htonl(headSz);
03401 head->TableId = htonl(tableId);
03402 head->FragmentNo = htonl(fragNo);
03403 head->ChecksumType = htonl(0);
03404
03405 opNoDone = opNoConf = opLen = 0;
03406 newRecord(tmp + headSz);
03407 scanStart = tmp;
03408 scanStop = (tmp + headSz);
03409
03410 noOfRecords = 0;
03411 noOfBytes = 0;
03412 return true;
03413 }
03414 return false;
03415 }
03416
03417 bool
03418 Backup::OperationRecord::fragComplete(Uint32 tableId, Uint32 fragNo)
03419 {
03420 Uint32 * tmp;
03421 const Uint32 footSz = sizeof(BackupFormat::DataFile::FragmentFooter) >> 2;
03422
03423 if(dataBuffer.getWritePtr(&tmp, footSz + 1)) {
03424 jam();
03425 * tmp = 0;
03426 tmp++;
03427 BackupFormat::DataFile::FragmentFooter * foot =
03428 (BackupFormat::DataFile::FragmentFooter*)tmp;
03429 foot->SectionType = htonl(BackupFormat::FRAGMENT_FOOTER);
03430 foot->SectionLength = htonl(footSz);
03431 foot->TableId = htonl(tableId);
03432 foot->FragmentNo = htonl(fragNo);
03433 foot->NoOfRecords = htonl(noOfRecords);
03434 foot->Checksum = htonl(0);
03435 dataBuffer.updateWritePtr(footSz + 1);
03436 return true;
03437 }
03438 return false;
03439 }
03440
03441 bool
03442 Backup::OperationRecord::newScan()
03443 {
03444 Uint32 * tmp;
03445 ndbrequire(16 * maxRecordSize < dataBuffer.getMaxWrite());
03446 if(dataBuffer.getWritePtr(&tmp, 16 * maxRecordSize)) {
03447 jam();
03448 opNoDone = opNoConf = opLen = 0;
03449 newRecord(tmp);
03450 scanStart = tmp;
03451 scanStop = tmp;
03452 return true;
03453 }
03454 return false;
03455 }
03456
03457 bool
03458 Backup::OperationRecord::closeScan()
03459 {
03460 opNoDone = opNoConf = opLen = 0;
03461 return true;
03462 }
03463
03464 bool
03465 Backup::OperationRecord::scanConf(Uint32 noOfOps, Uint32 total_len)
03466 {
03467 const Uint32 done = opNoDone-opNoConf;
03468
03469 ndbrequire(noOfOps == done);
03470 ndbrequire(opLen == total_len);
03471 opNoConf = opNoDone;
03472
03473 const Uint32 len = (scanStop - scanStart);
03474 ndbrequire(len < dataBuffer.getMaxWrite());
03475 dataBuffer.updateWritePtr(len);
03476 noOfBytes += (len << 2);
03477 return true;
03478 }
03479
03480 void
03481 Backup::execSCAN_FRAGREF(Signal* signal)
03482 {
03483 jamEntry();
03484
03485 ScanFragRef * ref = (ScanFragRef*)signal->getDataPtr();
03486
03487 const Uint32 filePtrI = ref->senderData;
03488 BackupFilePtr filePtr;
03489 c_backupFilePool.getPtr(filePtr, filePtrI);
03490
03491 filePtr.p->errorCode = ref->errorCode;
03492 filePtr.p->scanRunning = 0;
03493
03494 backupFragmentRef(signal, filePtr);
03495 }
03496
03497 void
03498 Backup::execSCAN_FRAGCONF(Signal* signal)
03499 {
03500 jamEntry();
03501
03502 CRASH_INSERTION((10017));
03503
03504 ScanFragConf * conf = (ScanFragConf*)signal->getDataPtr();
03505
03506 const Uint32 filePtrI = conf->senderData;
03507 BackupFilePtr filePtr;
03508 c_backupFilePool.getPtr(filePtr, filePtrI);
03509
03510 OperationRecord & op = filePtr.p->operation;
03511
03512 op.scanConf(conf->completedOps, conf->total_len);
03513 const Uint32 completed = conf->fragmentCompleted;
03514 if(completed != 2) {
03515 jam();
03516
03517 checkScan(signal, filePtr);
03518 return;
03519 }
03520
03521 fragmentCompleted(signal, filePtr);
03522 }
03523
03524 void
03525 Backup::fragmentCompleted(Signal* signal, BackupFilePtr filePtr)
03526 {
03527 jam();
03528
03529 if(filePtr.p->errorCode != 0)
03530 {
03531 jam();
03532 filePtr.p->scanRunning = 0;
03533 backupFragmentRef(signal, filePtr);
03534 return;
03535 }
03536
03537 OperationRecord & op = filePtr.p->operation;
03538 if(!op.fragComplete(filePtr.p->tableId, filePtr.p->fragmentNo)) {
03539 jam();
03540 signal->theData[0] = BackupContinueB::BUFFER_FULL_FRAG_COMPLETE;
03541 signal->theData[1] = filePtr.i;
03542 sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 50, 2);
03543 return;
03544 }
03545
03546 filePtr.p->scanRunning = 0;
03547
03548 BackupRecordPtr ptr;
03549 c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
03550
03551 BackupFragmentConf * conf = (BackupFragmentConf*)signal->getDataPtrSend();
03552 conf->backupId = ptr.p->backupId;
03553 conf->backupPtr = ptr.i;
03554 conf->tableId = filePtr.p->tableId;
03555 conf->fragmentNo = filePtr.p->fragmentNo;
03556 conf->noOfRecords = op.noOfRecords;
03557 conf->noOfBytes = op.noOfBytes;
03558 sendSignal(ptr.p->masterRef, GSN_BACKUP_FRAGMENT_CONF, signal,
03559 BackupFragmentConf::SignalLength, JBB);
03560
03561 ptr.p->m_gsn = GSN_BACKUP_FRAGMENT_CONF;
03562 ptr.p->slaveState.setState(STARTED);
03563 return;
03564 }
03565
03566 void
03567 Backup::backupFragmentRef(Signal * signal, BackupFilePtr filePtr)
03568 {
03569 BackupRecordPtr ptr;
03570 c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
03571
03572 ptr.p->m_gsn = GSN_BACKUP_FRAGMENT_REF;
03573
03574 BackupFragmentRef * ref = (BackupFragmentRef*)signal->getDataPtrSend();
03575 ref->backupId = ptr.p->backupId;
03576 ref->backupPtr = ptr.i;
03577 ref->nodeId = getOwnNodeId();
03578 ref->errorCode = ptr.p->errorCode;
03579 sendSignal(ptr.p->masterRef, GSN_BACKUP_FRAGMENT_REF, signal,
03580 BackupFragmentRef::SignalLength, JBB);
03581 }
03582
03583 void
03584 Backup::checkScan(Signal* signal, BackupFilePtr filePtr)
03585 {
03586 OperationRecord & op = filePtr.p->operation;
03587
03588 if(filePtr.p->errorCode != 0)
03589 {
03590 jam();
03591
03595 op.closeScan();
03596 ScanFragNextReq * req = (ScanFragNextReq *)signal->getDataPtrSend();
03597 req->senderData = filePtr.i;
03598 req->closeFlag = 1;
03599 req->transId1 = 0;
03600 req->transId2 = (BACKUP << 20) + (getOwnNodeId() << 8);
03601 sendSignal(DBLQH_REF, GSN_SCAN_NEXTREQ, signal,
03602 ScanFragNextReq::SignalLength, JBB);
03603 return;
03604 }
03605
03606 if(op.newScan()) {
03607 jam();
03608
03609 ScanFragNextReq * req = (ScanFragNextReq *)signal->getDataPtrSend();
03610 req->senderData = filePtr.i;
03611 req->closeFlag = 0;
03612 req->transId1 = 0;
03613 req->transId2 = (BACKUP << 20) + (getOwnNodeId() << 8);
03614 req->batch_size_rows= 16;
03615 req->batch_size_bytes= 0;
03616 if(ERROR_INSERTED(10032))
03617 sendSignalWithDelay(DBLQH_REF, GSN_SCAN_NEXTREQ, signal,
03618 100, ScanFragNextReq::SignalLength);
03619 else if(ERROR_INSERTED(10033))
03620 {
03621 SET_ERROR_INSERT_VALUE(10032);
03622 sendSignalWithDelay(DBLQH_REF, GSN_SCAN_NEXTREQ, signal,
03623 10000, ScanFragNextReq::SignalLength);
03624
03625 BackupRecordPtr ptr;
03626 c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
03627 AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
03628 ord->backupId = ptr.p->backupId;
03629 ord->backupPtr = ptr.i;
03630 ord->requestType = AbortBackupOrd::FileOrScanError;
03631 ord->senderData= ptr.i;
03632 sendSignal(ptr.p->masterRef, GSN_ABORT_BACKUP_ORD, signal,
03633 AbortBackupOrd::SignalLength, JBB);
03634 }
03635 else
03636 sendSignal(DBLQH_REF, GSN_SCAN_NEXTREQ, signal,
03637 ScanFragNextReq::SignalLength, JBB);
03638 return;
03639 }
03640
03641 signal->theData[0] = BackupContinueB::BUFFER_FULL_SCAN;
03642 signal->theData[1] = filePtr.i;
03643 sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 50, 2);
03644 }
03645
03646 void
03647 Backup::execFSAPPENDREF(Signal* signal)
03648 {
03649 jamEntry();
03650
03651 FsRef * ref = (FsRef *)signal->getDataPtr();
03652
03653 const Uint32 filePtrI = ref->userPointer;
03654 const Uint32 errCode = ref->errorCode;
03655
03656 BackupFilePtr filePtr;
03657 c_backupFilePool.getPtr(filePtr, filePtrI);
03658
03659 filePtr.p->fileRunning = 0;
03660 filePtr.p->errorCode = errCode;
03661
03662 checkFile(signal, filePtr);
03663 }
03664
03665 void
03666 Backup::execFSAPPENDCONF(Signal* signal)
03667 {
03668 jamEntry();
03669
03670 CRASH_INSERTION((10018));
03671
03672
03673 const Uint32 filePtrI = signal->theData[0];
03674 const Uint32 bytes = signal->theData[1];
03675
03676 BackupFilePtr filePtr;
03677 c_backupFilePool.getPtr(filePtr, filePtrI);
03678
03679 OperationRecord & op = filePtr.p->operation;
03680
03681 op.dataBuffer.updateReadPtr(bytes >> 2);
03682
03683 checkFile(signal, filePtr);
03684 }
03685
03686 void
03687 Backup::checkFile(Signal* signal, BackupFilePtr filePtr)
03688 {
03689
03690 #ifdef DEBUG_ABORT
03691
03692 #endif
03693
03694 OperationRecord & op = filePtr.p->operation;
03695
03696 Uint32 * tmp, sz; bool eof;
03697 if(op.dataBuffer.getReadPtr(&tmp, &sz, &eof))
03698 {
03699 jam();
03700
03701 jam();
03702 FsAppendReq * req = (FsAppendReq *)signal->getDataPtrSend();
03703 req->filePointer = filePtr.p->filePointer;
03704 req->userPointer = filePtr.i;
03705 req->userReference = reference();
03706 req->varIndex = 0;
03707 req->offset = tmp - c_startOfPages;
03708 req->size = sz;
03709
03710 sendSignal(NDBFS_REF, GSN_FSAPPENDREQ, signal,
03711 FsAppendReq::SignalLength, JBA);
03712 return;
03713 }
03714
03715 if(!eof) {
03716 jam();
03717 signal->theData[0] = BackupContinueB::BUFFER_UNDERFLOW;
03718 signal->theData[1] = filePtr.i;
03719 sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 50, 2);
03720 return;
03721 }
03722
03723 if(sz > 0) {
03724 jam();
03725 FsAppendReq * req = (FsAppendReq *)signal->getDataPtrSend();
03726 req->filePointer = filePtr.p->filePointer;
03727 req->userPointer = filePtr.i;
03728 req->userReference = reference();
03729 req->varIndex = 0;
03730 req->offset = tmp - c_startOfPages;
03731 req->size = sz;
03732
03733 sendSignal(NDBFS_REF, GSN_FSAPPENDREQ, signal,
03734 FsAppendReq::SignalLength, JBA);
03735 return;
03736 }
03737
03738 filePtr.p->fileRunning = 0;
03739 filePtr.p->fileClosing = 1;
03740
03741 FsCloseReq * req = (FsCloseReq *)signal->getDataPtrSend();
03742 req->filePointer = filePtr.p->filePointer;
03743 req->userPointer = filePtr.i;
03744 req->userReference = reference();
03745 req->fileFlag = 0;
03746 #ifdef DEBUG_ABORT
03747 ndbout_c("***** a FSCLOSEREQ filePtr.i = %u", filePtr.i);
03748 #endif
03749 sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, FsCloseReq::SignalLength, JBA);
03750 }
03751
03752
03753
03754
03755
03756
03757
03758 Uint32
03759 Backup::calculate_frag_mask(Uint32 count)
03760 {
03761 Uint32 mask = 1;
03762 while (mask < count) mask <<= 1;
03763 mask -= 1;
03764 return mask;
03765 }
03766
03767 void
03768 Backup::execBACKUP_TRIG_REQ(Signal* signal)
03769 {
03770
03771
03772
03773 TriggerPtr trigPtr;
03774 TablePtr tabPtr;
03775 FragmentPtr fragPtr;
03776 Uint32 trigger_id = signal->theData[0];
03777 Uint32 frag_id = signal->theData[1];
03778 Uint32 result;
03779
03780 jamEntry();
03781 c_triggerPool.getPtr(trigPtr, trigger_id);
03782 c_tablePool.getPtr(tabPtr, trigPtr.p->tab_ptr_i);
03783 frag_id = frag_id & tabPtr.p->frag_mask;
03784
03785
03786
03787
03788
03789
03790
03791 tabPtr.p->fragments.getPtr(fragPtr, frag_id);
03792 if (fragPtr.p->node != getOwnNodeId()) {
03793 jam();
03794 result = ZFALSE;
03795 } else {
03796 jam();
03797 result = ZTRUE;
03798 }
03799 signal->theData[0] = result;
03800 }
03801
03802 void
03803 Backup::execTRIG_ATTRINFO(Signal* signal) {
03804 jamEntry();
03805
03806 CRASH_INSERTION((10019));
03807
03808 TrigAttrInfo * trg = (TrigAttrInfo*)signal->getDataPtr();
03809
03810 TriggerPtr trigPtr;
03811 c_triggerPool.getPtr(trigPtr, trg->getTriggerId());
03812 ndbrequire(trigPtr.p->event != ILLEGAL_TRIGGER_ID);
03813
03814 if(trigPtr.p->errorCode != 0) {
03815 jam();
03816 return;
03817 }
03818
03819 if(trg->getAttrInfoType() == TrigAttrInfo::BEFORE_VALUES) {
03820 jam();
03824 return;
03825 }
03826
03827 BackupFormat::LogFile::LogEntry * logEntry = trigPtr.p->logEntry;
03828 if(logEntry == 0)
03829 {
03830 jam();
03831 Uint32 * dst;
03832 FsBuffer & buf = trigPtr.p->operation->dataBuffer;
03833 ndbrequire(trigPtr.p->maxRecordSize <= buf.getMaxWrite());
03834
03835 if(ERROR_INSERTED(10030) ||
03836 !buf.getWritePtr(&dst, trigPtr.p->maxRecordSize))
03837 {
03838 jam();
03839 BackupRecordPtr ptr;
03840 c_backupPool.getPtr(ptr, trigPtr.p->backupPtr);
03841 trigPtr.p->errorCode = AbortBackupOrd::LogBufferFull;
03842 AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
03843 ord->backupId = ptr.p->backupId;
03844 ord->backupPtr = ptr.i;
03845 ord->requestType = AbortBackupOrd::LogBufferFull;
03846 ord->senderData= ptr.i;
03847 sendSignal(ptr.p->masterRef, GSN_ABORT_BACKUP_ORD, signal,
03848 AbortBackupOrd::SignalLength, JBB);
03849 return;
03850 }
03851
03852 logEntry = (BackupFormat::LogFile::LogEntry *)dst;
03853 trigPtr.p->logEntry = logEntry;
03854 logEntry->Length = 0;
03855 logEntry->TableId = htonl(trigPtr.p->tableId);
03856 logEntry->TriggerEvent = htonl(trigPtr.p->event);
03857 } else {
03858 ndbrequire(logEntry->TableId == htonl(trigPtr.p->tableId));
03859 ndbrequire(logEntry->TriggerEvent == htonl(trigPtr.p->event));
03860 }
03861
03862 const Uint32 pos = logEntry->Length;
03863 const Uint32 dataLen = signal->length() - TrigAttrInfo::StaticLength;
03864 memcpy(&logEntry->Data[pos], trg->getData(), dataLen << 2);
03865
03866 logEntry->Length = pos + dataLen;
03867 }
03868
03869 void
03870 Backup::execFIRE_TRIG_ORD(Signal* signal)
03871 {
03872 jamEntry();
03873 FireTrigOrd* trg = (FireTrigOrd*)signal->getDataPtr();
03874
03875 const Uint32 gci = trg->getGCI();
03876 const Uint32 trI = trg->getTriggerId();
03877
03878 TriggerPtr trigPtr;
03879 c_triggerPool.getPtr(trigPtr, trI);
03880
03881 ndbrequire(trigPtr.p->event != ILLEGAL_TRIGGER_ID);
03882
03883 if(trigPtr.p->errorCode != 0) {
03884 jam();
03885 return;
03886 }
03887
03888 ndbrequire(trigPtr.p->logEntry != 0);
03889 Uint32 len = trigPtr.p->logEntry->Length;
03890
03891 BackupRecordPtr ptr;
03892 c_backupPool.getPtr(ptr, trigPtr.p->backupPtr);
03893 if(gci != ptr.p->currGCP)
03894 {
03895 jam();
03896
03897 trigPtr.p->logEntry->TriggerEvent = htonl(trigPtr.p->event | 0x10000);
03898 trigPtr.p->logEntry->Data[len] = htonl(gci);
03899 len ++;
03900 ptr.p->currGCP = gci;
03901 }
03902
03903 len += (sizeof(BackupFormat::LogFile::LogEntry) >> 2) - 2;
03904 trigPtr.p->logEntry->Length = htonl(len);
03905
03906 ndbrequire(len + 1 <= trigPtr.p->operation->dataBuffer.getMaxWrite());
03907 trigPtr.p->operation->dataBuffer.updateWritePtr(len + 1);
03908 trigPtr.p->logEntry = 0;
03909
03910 trigPtr.p->operation->noOfBytes += (len + 1) << 2;
03911 trigPtr.p->operation->noOfRecords += 1;
03912 }
03913
03914 void
03915 Backup::sendAbortBackupOrd(Signal* signal, BackupRecordPtr ptr,
03916 Uint32 requestType)
03917 {
03918 jam();
03919 AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
03920 ord->backupId = ptr.p->backupId;
03921 ord->backupPtr = ptr.i;
03922 ord->requestType = requestType;
03923 ord->senderData= ptr.i;
03924 NodePtr node;
03925 for(c_nodes.first(node); node.i != RNIL; c_nodes.next(node)) {
03926 jam();
03927 const Uint32 nodeId = node.p->nodeId;
03928 if(node.p->alive && ptr.p->nodes.get(nodeId)) {
03929 jam();
03930 sendSignal(numberToRef(BACKUP, nodeId), GSN_ABORT_BACKUP_ORD, signal,
03931 AbortBackupOrd::SignalLength, JBB);
03932 }
03933 }
03934 }
03935
03936
03937
03938
03939
03940
03941 void
03942 Backup::execSTOP_BACKUP_REQ(Signal* signal)
03943 {
03944 jamEntry();
03945 StopBackupReq * req = (StopBackupReq*)signal->getDataPtr();
03946
03947 CRASH_INSERTION((10020));
03948
03949 const Uint32 ptrI = req->backupPtr;
03950
03951 const Uint32 startGCP = req->startGCP;
03952 const Uint32 stopGCP = req->stopGCP;
03953
03957 ndbrequire(stopGCP > startGCP);
03958
03962 BackupRecordPtr ptr;
03963 c_backupPool.getPtr(ptr, ptrI);
03964
03965 ptr.p->slaveState.setState(STOPPING);
03966 ptr.p->m_gsn = GSN_STOP_BACKUP_REQ;
03967
03971 {
03972 BackupFilePtr filePtr;
03973 ptr.p->files.getPtr(filePtr, ptr.p->logFilePtr);
03974 Uint32 * dst;
03975 ndbrequire(filePtr.p->operation.dataBuffer.getWritePtr(&dst, 1));
03976 * dst = 0;
03977 filePtr.p->operation.dataBuffer.updateWritePtr(1);
03978 }
03979
03980 {
03981 BackupFilePtr filePtr;
03982 ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
03983
03984 const Uint32 gcpSz = sizeof(BackupFormat::CtlFile::GCPEntry) >> 2;
03985
03986 Uint32 * dst;
03987 ndbrequire(filePtr.p->operation.dataBuffer.getWritePtr(&dst, gcpSz));
03988
03989 BackupFormat::CtlFile::GCPEntry * gcp =
03990 (BackupFormat::CtlFile::GCPEntry*)dst;
03991
03992 gcp->SectionType = htonl(BackupFormat::GCP_ENTRY);
03993 gcp->SectionLength = htonl(gcpSz);
03994 gcp->StartGCP = htonl(startGCP);
03995 gcp->StopGCP = htonl(stopGCP - 1);
03996 filePtr.p->operation.dataBuffer.updateWritePtr(gcpSz);
03997 }
03998
03999 closeFiles(signal, ptr);
04000 }
04001
04002 void
04003 Backup::closeFiles(Signal* sig, BackupRecordPtr ptr)
04004 {
04008 BackupFilePtr filePtr;
04009 int openCount = 0;
04010 for(ptr.p->files.first(filePtr); filePtr.i!=RNIL; ptr.p->files.next(filePtr))
04011 {
04012 if(filePtr.p->fileOpened == 0) {
04013 jam();
04014 continue;
04015 }
04016
04017 jam();
04018 openCount++;
04019
04020 if(filePtr.p->fileClosing == 1){
04021 jam();
04022 continue;
04023 }
04024
04025 filePtr.p->fileClosing = 1;
04026
04027 if(filePtr.p->fileRunning == 1){
04028 jam();
04029 #ifdef DEBUG_ABORT
04030 ndbout_c("Close files fileRunning == 1, filePtr.i=%u", filePtr.i);
04031 #endif
04032 filePtr.p->operation.dataBuffer.eof();
04033 } else {
04034 jam();
04035
04036 FsCloseReq * req = (FsCloseReq *)sig->getDataPtrSend();
04037 req->filePointer = filePtr.p->filePointer;
04038 req->userPointer = filePtr.i;
04039 req->userReference = reference();
04040 req->fileFlag = 0;
04041 #ifdef DEBUG_ABORT
04042 ndbout_c("***** b FSCLOSEREQ filePtr.i = %u", filePtr.i);
04043 #endif
04044 sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, sig,
04045 FsCloseReq::SignalLength, JBA);
04046 }
04047 }
04048
04049 if(openCount == 0){
04050 jam();
04051 closeFilesDone(sig, ptr);
04052 }
04053 }
04054
04055 void
04056 Backup::execFSCLOSEREF(Signal* signal)
04057 {
04058 jamEntry();
04059
04060 FsRef * ref = (FsRef*)signal->getDataPtr();
04061 const Uint32 filePtrI = ref->userPointer;
04062
04063 BackupFilePtr filePtr;
04064 c_backupFilePool.getPtr(filePtr, filePtrI);
04065
04066 BackupRecordPtr ptr;
04067 c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
04068
04069 filePtr.p->fileOpened = 1;
04070 FsConf * conf = (FsConf*)signal->getDataPtr();
04071 conf->userPointer = filePtrI;
04072
04073 execFSCLOSECONF(signal);
04074 }
04075
04076 void
04077 Backup::execFSCLOSECONF(Signal* signal)
04078 {
04079 jamEntry();
04080
04081 FsConf * conf = (FsConf*)signal->getDataPtr();
04082 const Uint32 filePtrI = conf->userPointer;
04083
04084 BackupFilePtr filePtr;
04085 c_backupFilePool.getPtr(filePtr, filePtrI);
04086
04087 #ifdef DEBUG_ABORT
04088 ndbout_c("***** FSCLOSECONF filePtrI = %u", filePtrI);
04089 #endif
04090
04091 ndbrequire(filePtr.p->fileClosing == 1);
04092 ndbrequire(filePtr.p->fileOpened == 1);
04093 ndbrequire(filePtr.p->fileRunning == 0);
04094 ndbrequire(filePtr.p->scanRunning == 0);
04095
04096 filePtr.p->fileOpened = 0;
04097
04098 BackupRecordPtr ptr;
04099 c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
04100 for(ptr.p->files.first(filePtr); filePtr.i!=RNIL;ptr.p->files.next(filePtr))
04101 {
04102 jam();
04103 if(filePtr.p->fileOpened == 1) {
04104 jam();
04105 #ifdef DEBUG_ABORT
04106 ndbout_c("waiting for more FSCLOSECONF's filePtr.i = %u", filePtr.i);
04107 #endif
04108 return;
04109 }
04110 }
04111 closeFilesDone(signal, ptr);
04112 }
04113
04114 void
04115 Backup::closeFilesDone(Signal* signal, BackupRecordPtr ptr)
04116 {
04117 jam();
04118
04119 jam();
04120 BackupFilePtr filePtr;
04121 ptr.p->files.getPtr(filePtr, ptr.p->logFilePtr);
04122
04123 StopBackupConf* conf = (StopBackupConf*)signal->getDataPtrSend();
04124 conf->backupId = ptr.p->backupId;
04125 conf->backupPtr = ptr.i;
04126 conf->noOfLogBytes = filePtr.p->operation.noOfBytes;
04127 conf->noOfLogRecords = filePtr.p->operation.noOfRecords;
04128 sendSignal(ptr.p->masterRef, GSN_STOP_BACKUP_CONF, signal,
04129 StopBackupConf::SignalLength, JBB);
04130
04131 ptr.p->m_gsn = GSN_STOP_BACKUP_CONF;
04132 ptr.p->slaveState.setState(CLEANING);
04133 }
04134
04135
04136
04137
04138
04139
04140
04141
04142
04143
04144
04145 void
04146 Backup::execABORT_BACKUP_ORD(Signal* signal)
04147 {
04148 jamEntry();
04149 AbortBackupOrd* ord = (AbortBackupOrd*)signal->getDataPtr();
04150
04151 const Uint32 backupId = ord->backupId;
04152 const AbortBackupOrd::RequestType requestType =
04153 (AbortBackupOrd::RequestType)ord->requestType;
04154 const Uint32 senderData = ord->senderData;
04155
04156 #ifdef DEBUG_ABORT
04157 ndbout_c("******** ABORT_BACKUP_ORD ********* nodeId = %u",
04158 refToNode(signal->getSendersBlockRef()));
04159 ndbout_c("backupId = %u, requestType = %u, senderData = %u, ",
04160 backupId, requestType, senderData);
04161 dumpUsedResources();
04162 #endif
04163
04164 BackupRecordPtr ptr;
04165 if(requestType == AbortBackupOrd::ClientAbort) {
04166 if (getOwnNodeId() != getMasterNodeId()) {
04167 jam();
04168
04169 #ifdef DEBUG_ABORT
04170 ndbout_c("---- Forward to master nodeId = %u", getMasterNodeId());
04171 #endif
04172 sendSignal(calcBackupBlockRef(getMasterNodeId()), GSN_ABORT_BACKUP_ORD,
04173 signal, AbortBackupOrd::SignalLength, JBB);
04174 return;
04175 }
04176 jam();
04177 for(c_backups.first(ptr); ptr.i != RNIL; c_backups.next(ptr)) {
04178 jam();
04179 if(ptr.p->backupId == backupId && ptr.p->clientData == senderData) {
04180 jam();
04181 break;
04182 }
04183 }
04184 if(ptr.i == RNIL) {
04185 jam();
04186 return;
04187 }
04188 } else {
04189 if (c_backupPool.findId(senderData)) {
04190 jam();
04191 c_backupPool.getPtr(ptr, senderData);
04192 } else {
04193 jam();
04194 #ifdef DEBUG_ABORT
04195 ndbout_c("Backup: abort request type=%u on id=%u,%u not found",
04196 requestType, backupId, senderData);
04197 #endif
04198 return;
04199 }
04200 }
04201
04202 ptr.p->m_gsn = GSN_ABORT_BACKUP_ORD;
04203 const bool isCoordinator = (ptr.p->masterRef == reference());
04204
04205 bool ok = false;
04206 switch(requestType){
04207
04211 case AbortBackupOrd::ClientAbort:
04212 jam();
04213
04214 case AbortBackupOrd::LogBufferFull:
04215 jam();
04216
04217 case AbortBackupOrd::FileOrScanError:
04218 jam();
04219 ndbrequire(isCoordinator);
04220 ptr.p->setErrorCode(requestType);
04221 if(ptr.p->masterData.gsn == GSN_BACKUP_FRAGMENT_REQ)
04222 {
04226 abort_scan(signal, ptr);
04227 }
04228 return;
04229
04233 case AbortBackupOrd::AbortScan:
04234 jam();
04235 ptr.p->setErrorCode(requestType);
04236 return;
04237
04238 case AbortBackupOrd::BackupComplete:
04239 jam();
04240 cleanup(signal, ptr);
04241 return;
04242 case AbortBackupOrd::BackupFailure:
04243 case AbortBackupOrd::BackupFailureDueToNodeFail:
04244 case AbortBackupOrd::OkToClean:
04245 case AbortBackupOrd::IncompatibleVersions:
04246 #ifndef VM_TRACE
04247 default:
04248 #endif
04249 ptr.p->setErrorCode(requestType);
04250 ok= true;
04251 }
04252 ndbrequire(ok);
04253
04254 Uint32 ref= ptr.p->masterRef;
04255 ptr.p->masterRef = reference();
04256 ptr.p->nodes.clear();
04257 ptr.p->nodes.set(getOwnNodeId());
04258
04259 if(ref == reference())
04260 {
04261 ptr.p->stopGCP= ptr.p->startGCP + 1;
04262 sendDropTrig(signal, ptr);
04263 }
04264 else
04265 {
04266 ptr.p->masterData.gsn = GSN_STOP_BACKUP_REQ;
04267 ptr.p->masterData.sendCounter.clearWaitingFor();
04268 ptr.p->masterData.sendCounter.setWaitingFor(getOwnNodeId());
04269 closeFiles(signal, ptr);
04270 }
04271 }
04272
04273
04274 void
04275 Backup::dumpUsedResources()
04276 {
04277 jam();
04278 BackupRecordPtr ptr;
04279
04280 for(c_backups.first(ptr); ptr.i != RNIL; c_backups.next(ptr)) {
04281 ndbout_c("Backup id=%u, slaveState.getState = %u, errorCode=%u",
04282 ptr.p->backupId,
04283 ptr.p->slaveState.getState(),
04284 ptr.p->errorCode);
04285
04286 TablePtr tabPtr;
04287 for(ptr.p->tables.first(tabPtr);
04288 tabPtr.i != RNIL;
04289 ptr.p->tables.next(tabPtr)) {
04290 jam();
04291 for(Uint32 j = 0; j<3; j++) {
04292 jam();
04293 TriggerPtr trigPtr;
04294 if(tabPtr.p->triggerAllocated[j]) {
04295 jam();
04296 c_triggerPool.getPtr(trigPtr, tabPtr.p->triggerIds[j]);
04297 ndbout_c("Allocated[%u] Triggerid = %u, event = %u",
04298 j,
04299 tabPtr.p->triggerIds[j],
04300 trigPtr.p->event);
04301 }
04302 }
04303 }
04304
04305 BackupFilePtr filePtr;
04306 for(ptr.p->files.first(filePtr);
04307 filePtr.i != RNIL;
04308 ptr.p->files.next(filePtr)) {
04309 jam();
04310 ndbout_c("filePtr.i = %u, filePtr.p->fileOpened=%u fileRunning=%u "
04311 "scanRunning=%u",
04312 filePtr.i,
04313 filePtr.p->fileOpened,
04314 filePtr.p->fileRunning,
04315 filePtr.p->scanRunning);
04316 }
04317 }
04318 }
04319
04320 void
04321 Backup::cleanup(Signal* signal, BackupRecordPtr ptr)
04322 {
04323
04324 TablePtr tabPtr;
04325 for(ptr.p->tables.first(tabPtr); tabPtr.i != RNIL;ptr.p->tables.next(tabPtr))
04326 {
04327 jam();
04328 tabPtr.p->attributes.release();
04329 tabPtr.p->fragments.release();
04330 for(Uint32 j = 0; j<3; j++) {
04331 jam();
04332 TriggerPtr trigPtr;
04333 if(tabPtr.p->triggerAllocated[j]) {
04334 jam();
04335 c_triggerPool.getPtr(trigPtr, tabPtr.p->triggerIds[j]);
04336 trigPtr.p->event = ILLEGAL_TRIGGER_ID;
04337 tabPtr.p->triggerAllocated[j] = false;
04338 }
04339 tabPtr.p->triggerIds[j] = ILLEGAL_TRIGGER_ID;
04340 }
04341 }
04342
04343 BackupFilePtr filePtr;
04344 for(ptr.p->files.first(filePtr);
04345 filePtr.i != RNIL;
04346 ptr.p->files.next(filePtr)) {
04347 jam();
04348 ndbrequire(filePtr.p->fileOpened == 0);
04349 ndbrequire(filePtr.p->fileRunning == 0);
04350 ndbrequire(filePtr.p->scanRunning == 0);
04351 filePtr.p->pages.release();
04352 }
04353
04354 ptr.p->files.release();
04355 ptr.p->tables.release();
04356 ptr.p->triggers.release();
04357
04358 ptr.p->tables.release();
04359 ptr.p->triggers.release();
04360 ptr.p->pages.release();
04361 ptr.p->backupId = ~0;
04362
04363 if(ptr.p->checkError())
04364 removeBackup(signal, ptr);
04365 else
04366 c_backups.release(ptr);
04367 }
04368
04369
04370 void
04371 Backup::removeBackup(Signal* signal, BackupRecordPtr ptr)
04372 {
04373 jam();
04374
04375 FsRemoveReq * req = (FsRemoveReq *)signal->getDataPtrSend();
04376 req->userReference = reference();
04377 req->userPointer = ptr.i;
04378 req->directory = 1;
04379 req->ownDirectory = 1;
04380 FsOpenReq::setVersion(req->fileNumber, 2);
04381 FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_CTL);
04382 FsOpenReq::v2_setSequence(req->fileNumber, ptr.p->backupId);
04383 FsOpenReq::v2_setNodeId(req->fileNumber, getOwnNodeId());
04384 sendSignal(NDBFS_REF, GSN_FSREMOVEREQ, signal,
04385 FsRemoveReq::SignalLength, JBA);
04386 }
04387
04388 void
04389 Backup::execFSREMOVEREF(Signal* signal)
04390 {
04391 jamEntry();
04392 FsRef * ref = (FsRef*)signal->getDataPtr();
04393 const Uint32 ptrI = ref->userPointer;
04394
04395 FsConf * conf = (FsConf*)signal->getDataPtr();
04396 conf->userPointer = ptrI;
04397 execFSREMOVECONF(signal);
04398 }
04399
04400 void
04401 Backup::execFSREMOVECONF(Signal* signal){
04402 jamEntry();
04403
04404 FsConf * conf = (FsConf*)signal->getDataPtr();
04405 const Uint32 ptrI = conf->userPointer;
04406
04410 BackupRecordPtr ptr;
04411 c_backupPool.getPtr(ptr, ptrI);
04412 c_backups.release(ptr);
04413 }
04414