1 /* Copyright (c) 2003-2008 MySQL AB
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16 #include <my_config.h>
19 #include <ndb_version.h>
22 #include <Bitmask.hpp>
24 #include <signaldata/NodeFailRep.hpp>
25 #include <signaldata/ReadNodesConf.hpp>
27 #include <signaldata/DihFragCount.hpp>
28 #include <signaldata/ScanFrag.hpp>
30 #include <signaldata/GetTabInfo.hpp>
31 #include <signaldata/DictTabInfo.hpp>
32 #include <signaldata/ListTables.hpp>
34 #include <signaldata/FsOpenReq.hpp>
35 #include <signaldata/FsAppendReq.hpp>
36 #include <signaldata/FsCloseReq.hpp>
37 #include <signaldata/FsConf.hpp>
38 #include <signaldata/FsRef.hpp>
39 #include <signaldata/FsRemoveReq.hpp>
41 #include <signaldata/BackupImpl.hpp>
42 #include <signaldata/BackupSignalData.hpp>
43 #include <signaldata/BackupContinueB.hpp>
44 #include <signaldata/EventReport.hpp>
46 #include <signaldata/UtilSequence.hpp>
48 #include <signaldata/CreateTrig.hpp>
49 #include <signaldata/AlterTrig.hpp>
50 #include <signaldata/DropTrig.hpp>
51 #include <signaldata/FireTrigOrd.hpp>
52 #include <signaldata/TrigAttrInfo.hpp>
53 #include <AttributeHeader.hpp>
55 #include <signaldata/WaitGCP.hpp>
56 #include <signaldata/LCP.hpp>
60 static NDB_TICKS startTime
;
62 static const Uint32 BACKUP_SEQUENCE
= 0x1F000000;
65 #define DEBUG_OUT(x) ndbout << x << endl
71 //#define dbg globalSignalLoggers.log
73 static Uint32 g_TypeOfStart
= NodeState::ST_ILLEGAL_TYPE
;
75 #define SEND_BACKUP_STARTED_FLAG(A) (((A) & 0x3) > 0)
76 #define SEND_BACKUP_COMPLETED_FLAG(A) (((A) & 0x3) > 1)
79 Backup::execSTTOR(Signal
* signal
)
83 const Uint32 startphase
= signal
->theData
[1];
84 const Uint32 typeOfStart
= signal
->theData
[7];
88 m_curr_disk_write_speed
= c_defaults
.m_disk_write_speed_sr
;
89 m_overflow_disk_write
= 0;
90 m_reset_disk_speed_time
= NdbTick_CurrentMillisecond();
91 m_reset_delay_used
= Backup::DISK_SPEED_CHECK_DELAY
;
92 signal
->theData
[0] = BackupContinueB::RESET_DISK_SPEED_COUNTER
;
93 sendSignalWithDelay(BACKUP_REF
, GSN_CONTINUEB
, signal
,
94 Backup::DISK_SPEED_CHECK_DELAY
, 1);
96 if (startphase
== 3) {
98 g_TypeOfStart
= typeOfStart
;
99 signal
->theData
[0] = reference();
100 sendSignal(NDBCNTR_REF
, GSN_READ_NODESREQ
, signal
, 1, JBB
);
106 m_curr_disk_write_speed
= c_defaults
.m_disk_write_speed
;
109 if(startphase
== 7 && g_TypeOfStart
== NodeState::ST_INITIAL_START
&&
110 c_masterNodeId
== getOwnNodeId()){
112 createSequence(signal
);
118 }//Dbdict::execSTTOR()
121 Backup::execREAD_NODESCONF(Signal
* signal
)
124 ReadNodesConf
* conf
= (ReadNodesConf
*)signal
->getDataPtr();
126 c_aliveNodes
.clear();
129 for (Uint32 i
= 0; i
<MAX_NDB_NODES
; i
++) {
131 if(NodeBitmask::get(conf
->allNodes
, i
)){
136 ndbrequire(c_nodes
.seize(node
));
139 if(NodeBitmask::get(conf
->inactiveNodes
, i
)) {
149 c_masterNodeId
= conf
->masterNodeId
;
150 ndbrequire(count
== conf
->noOfNodes
);
155 Backup::sendSTTORRY(Signal
* signal
)
157 signal
->theData
[0] = 0;
158 signal
->theData
[3] = 1;
159 signal
->theData
[4] = 3;
160 signal
->theData
[5] = 7;
161 signal
->theData
[6] = 255; // No more start phases from missra
162 sendSignal(NDBCNTR_REF
, GSN_STTORRY
, signal
, 7, JBB
);
166 Backup::createSequence(Signal
* signal
)
168 UtilSequenceReq
* req
= (UtilSequenceReq
*)signal
->getDataPtrSend();
170 req
->senderData
= RNIL
;
171 req
->sequenceId
= BACKUP_SEQUENCE
;
172 req
->requestType
= UtilSequenceReq::Create
;
174 sendSignal(DBUTIL_REF
, GSN_UTIL_SEQUENCE_REQ
,
175 signal
, UtilSequenceReq::SignalLength
, JBB
);
179 Backup::execCONTINUEB(Signal
* signal
)
182 const Uint32 Tdata0
= signal
->theData
[0];
183 const Uint32 Tdata1
= signal
->theData
[1];
184 const Uint32 Tdata2
= signal
->theData
[2];
187 case BackupContinueB::RESET_DISK_SPEED_COUNTER
:
190 Adjust for upto 10 millisecond delay of this signal. Longer
191 delays will not be handled, in this case the system is most
192 likely under too high load and it won't matter very much that
193 we decrease the speed of checkpoints.
195 We use a technique where we allow an overflow write in one
196 period. This overflow will be removed from the next period
197 such that the load will at average be as specified.
199 int delay_time
= m_reset_delay_used
;
200 NDB_TICKS curr_time
= NdbTick_CurrentMillisecond();
201 int sig_delay
= curr_time
- m_reset_disk_speed_time
;
203 m_words_written_this_period
= m_overflow_disk_write
;
204 m_overflow_disk_write
= 0;
205 m_reset_disk_speed_time
= curr_time
;
207 if (sig_delay
> delay_time
+ 10)
208 delay_time
= Backup::DISK_SPEED_CHECK_DELAY
- 10;
209 else if (sig_delay
< delay_time
- 10)
210 delay_time
= Backup::DISK_SPEED_CHECK_DELAY
+ 10;
212 delay_time
= Backup::DISK_SPEED_CHECK_DELAY
- (sig_delay
- delay_time
);
213 m_reset_delay_used
= delay_time
;
214 signal
->theData
[0] = BackupContinueB::RESET_DISK_SPEED_COUNTER
;
215 sendSignalWithDelay(BACKUP_REF
, GSN_CONTINUEB
, signal
, delay_time
, 1);
217 ndbout
<< "Signal delay was = " << sig_delay
;
218 ndbout
<< " Current time = " << curr_time
<< endl
;
219 ndbout
<< " Delay time will be = " << delay_time
<< endl
<< endl
;
223 case BackupContinueB::BACKUP_FRAGMENT_INFO
:
226 const Uint32 ptr_I
= Tdata1
;
227 Uint32 tabPtr_I
= Tdata2
;
228 Uint32 fragPtr_I
= signal
->theData
[3];
230 BackupRecordPtr ptr LINT_SET_PTR
;
231 c_backupPool
.getPtr(ptr
, ptr_I
);
233 ptr
.p
->tables
.getPtr(tabPtr
, tabPtr_I
);
235 if (fragPtr_I
!= tabPtr
.p
->fragments
.getSize())
239 tabPtr
.p
->fragments
.getPtr(fragPtr
, fragPtr_I
);
241 BackupFilePtr filePtr LINT_SET_PTR
;
242 ptr
.p
->files
.getPtr(filePtr
, ptr
.p
->ctlFilePtr
);
244 const Uint32 sz
= sizeof(BackupFormat::CtlFile::FragmentInfo
) >> 2;
246 if (!filePtr
.p
->operation
.dataBuffer
.getWritePtr(&dst
, sz
))
248 sendSignalWithDelay(BACKUP_REF
, GSN_CONTINUEB
, signal
, 100, 4);
252 BackupFormat::CtlFile::FragmentInfo
* fragInfo
=
253 (BackupFormat::CtlFile::FragmentInfo
*)dst
;
254 fragInfo
->SectionType
= htonl(BackupFormat::FRAGMENT_INFO
);
255 fragInfo
->SectionLength
= htonl(sz
);
256 fragInfo
->TableId
= htonl(fragPtr
.p
->tableId
);
257 fragInfo
->FragmentNo
= htonl(fragPtr_I
);
258 fragInfo
->NoOfRecordsLow
= htonl(fragPtr
.p
->noOfRecords
& 0xFFFFFFFF);
259 fragInfo
->NoOfRecordsHigh
= htonl(fragPtr
.p
->noOfRecords
>> 32);
260 fragInfo
->FilePosLow
= htonl(0);
261 fragInfo
->FilePosHigh
= htonl(0);
263 filePtr
.p
->operation
.dataBuffer
.updateWritePtr(sz
);
268 if (fragPtr_I
== tabPtr
.p
->fragments
.getSize())
270 signal
->theData
[0] = tabPtr
.p
->tableId
;
271 signal
->theData
[1] = 0; // unlock
272 EXECUTE_DIRECT(DBDICT
, GSN_BACKUP_FRAGMENT_REQ
, signal
, 2);
275 ptr
.p
->tables
.next(tabPtr
);
276 if ((tabPtr_I
= tabPtr
.i
) == RNIL
)
279 closeFiles(signal
, ptr
);
284 signal
->theData
[0] = BackupContinueB::BACKUP_FRAGMENT_INFO
;
285 signal
->theData
[1] = ptr_I
;
286 signal
->theData
[2] = tabPtr_I
;
287 signal
->theData
[3] = fragPtr_I
;
288 sendSignal(BACKUP_REF
, GSN_CONTINUEB
, signal
, 4, JBB
);
291 case BackupContinueB::START_FILE_THREAD
:
292 case BackupContinueB::BUFFER_UNDERFLOW
:
295 BackupFilePtr filePtr LINT_SET_PTR
;
296 c_backupFilePool
.getPtr(filePtr
, Tdata1
);
297 checkFile(signal
, filePtr
);
301 case BackupContinueB::BUFFER_FULL_SCAN
:
304 BackupFilePtr filePtr LINT_SET_PTR
;
305 c_backupFilePool
.getPtr(filePtr
, Tdata1
);
306 checkScan(signal
, filePtr
);
310 case BackupContinueB::BUFFER_FULL_FRAG_COMPLETE
:
313 BackupFilePtr filePtr LINT_SET_PTR
;
314 c_backupFilePool
.getPtr(filePtr
, Tdata1
);
315 fragmentCompleted(signal
, filePtr
);
319 case BackupContinueB::BUFFER_FULL_META
:
322 BackupRecordPtr ptr LINT_SET_PTR
;
323 c_backupPool
.getPtr(ptr
, Tdata1
);
325 BackupFilePtr filePtr LINT_SET_PTR
;
326 ptr
.p
->files
.getPtr(filePtr
, ptr
.p
->ctlFilePtr
);
327 FsBuffer
& buf
= filePtr
.p
->operation
.dataBuffer
;
329 if(buf
.getFreeSize() < buf
.getMaxWrite()) {
331 TablePtr tabPtr LINT_SET_PTR
;
332 c_tablePool
.getPtr(tabPtr
, Tdata2
);
334 DEBUG_OUT("Backup - Buffer full - "
336 << " < " << buf
.getMaxWrite()
337 << " (sz: " << buf
.getUsableSize()
338 << " getMinRead: " << buf
.getMinRead()
339 << ") - tableId = " << tabPtr
.p
->tableId
);
341 signal
->theData
[0] = BackupContinueB::BUFFER_FULL_META
;
342 signal
->theData
[1] = Tdata1
;
343 signal
->theData
[2] = Tdata2
;
344 sendSignalWithDelay(BACKUP_REF
, GSN_CONTINUEB
, signal
, 100, 3);
348 TablePtr tabPtr LINT_SET_PTR
;
349 c_tablePool
.getPtr(tabPtr
, Tdata2
);
350 GetTabInfoReq
* req
= (GetTabInfoReq
*)signal
->getDataPtrSend();
351 req
->senderRef
= reference();
352 req
->senderData
= ptr
.i
;
353 req
->requestType
= GetTabInfoReq::RequestById
|
354 GetTabInfoReq::LongSignalConf
;
355 req
->tableId
= tabPtr
.p
->tableId
;
356 sendSignal(DBDICT_REF
, GSN_GET_TABINFOREQ
, signal
,
357 GetTabInfoReq::SignalLength
, JBB
);
360 case BackupContinueB::ZDELAY_SCAN_NEXT
:
361 if (ERROR_INSERTED(10036))
364 sendSignalWithDelay(BACKUP_REF
, GSN_CONTINUEB
, signal
, 300,
365 signal
->getLength());
371 CLEAR_ERROR_INSERT_VALUE
;
372 ndbout_c("Resuming backup");
373 memmove(signal
->theData
, signal
->theData
+ 1,
374 4*ScanFragNextReq::SignalLength
);
375 sendSignal(DBLQH_REF
, GSN_SCAN_NEXTREQ
, signal
,
376 ScanFragNextReq::SignalLength
, JBB
);
385 Backup::execDUMP_STATE_ORD(Signal
* signal
)
389 if(signal
->theData
[0] == 20){
390 if(signal
->length() > 1){
391 c_defaults
.m_dataBufferSize
= (signal
->theData
[1] * 1024 * 1024);
393 if(signal
->length() > 2){
394 c_defaults
.m_logBufferSize
= (signal
->theData
[2] * 1024 * 1024);
396 if(signal
->length() > 3){
397 c_defaults
.m_minWriteSize
= signal
->theData
[3] * 1024;
399 if(signal
->length() > 4){
400 c_defaults
.m_maxWriteSize
= signal
->theData
[4] * 1024;
403 infoEvent("Backup: data: %d log: %d min: %d max: %d",
404 c_defaults
.m_dataBufferSize
,
405 c_defaults
.m_logBufferSize
,
406 c_defaults
.m_minWriteSize
,
407 c_defaults
.m_maxWriteSize
);
410 if(signal
->theData
[0] == 21){
411 BackupReq
* req
= (BackupReq
*)signal
->getDataPtrSend();
412 req
->senderData
= 23;
413 req
->backupDataLen
= 0;
414 sendSignal(BACKUP_REF
, GSN_BACKUP_REQ
,signal
,BackupReq::SignalLength
, JBB
);
415 startTime
= NdbTick_CurrentMillisecond();
419 if(signal
->theData
[0] == 22){
420 const Uint32 seq
= signal
->theData
[1];
421 FsRemoveReq
* req
= (FsRemoveReq
*)signal
->getDataPtrSend();
422 req
->userReference
= reference();
423 req
->userPointer
= 23;
425 req
->ownDirectory
= 1;
426 FsOpenReq::setVersion(req
->fileNumber
, 2);
427 FsOpenReq::setSuffix(req
->fileNumber
, FsOpenReq::S_CTL
);
428 FsOpenReq::v2_setSequence(req
->fileNumber
, seq
);
429 FsOpenReq::v2_setNodeId(req
->fileNumber
, getOwnNodeId());
430 sendSignal(NDBFS_REF
, GSN_FSREMOVEREQ
, signal
,
431 FsRemoveReq::SignalLength
, JBA
);
435 if(signal
->theData
[0] == 23){
439 BackupRecordPtr ptr LINT_SET_PTR
;
440 for(c_backups
.first(ptr
); ptr
.i
!= RNIL
; c_backups
.next(ptr
)){
441 infoEvent("BackupRecord %d: BackupId: %d MasterRef: %x ClientRef: %x",
442 ptr
.i
, ptr
.p
->backupId
, ptr
.p
->masterRef
, ptr
.p
->clientRef
);
443 infoEvent(" State: %d", ptr
.p
->slaveState
.getState());
444 BackupFilePtr filePtr
;
445 for(ptr
.p
->files
.first(filePtr
); filePtr
.i
!= RNIL
;
446 ptr
.p
->files
.next(filePtr
)){
448 infoEvent(" file %d: type: %d flags: H'%x",
449 filePtr
.i
, filePtr
.p
->fileType
,
454 ndbout_c("m_curr_disk_write_speed: %u m_words_written_this_period: %u m_overflow_disk_write: %u",
455 m_curr_disk_write_speed
, m_words_written_this_period
, m_overflow_disk_write
);
456 ndbout_c("m_reset_delay_used: %u m_reset_disk_speed_time: %llu",
457 m_reset_delay_used
, (Uint64
)m_reset_disk_speed_time
);
458 for(c_backups
.first(ptr
); ptr
.i
!= RNIL
; c_backups
.next(ptr
))
460 ndbout_c("BackupRecord %u: BackupId: %u MasterRef: %x ClientRef: %x",
461 ptr
.i
, ptr
.p
->backupId
, ptr
.p
->masterRef
, ptr
.p
->clientRef
);
462 ndbout_c(" State: %u", ptr
.p
->slaveState
.getState());
463 ndbout_c(" noOfByte: %llu noOfRecords: %llu",
464 ptr
.p
->noOfBytes
, ptr
.p
->noOfRecords
);
465 ndbout_c(" noOfLogBytes: %llu noOfLogRecords: %llu",
466 ptr
.p
->noOfLogBytes
, ptr
.p
->noOfLogRecords
);
467 ndbout_c(" errorCode: %u", ptr
.p
->errorCode
);
468 BackupFilePtr filePtr
;
469 for(ptr
.p
->files
.first(filePtr
); filePtr
.i
!= RNIL
;
470 ptr
.p
->files
.next(filePtr
))
472 ndbout_c(" file %u: type: %u flags: H'%x tableId: %u fragmentId: %u",
473 filePtr
.i
, filePtr
.p
->fileType
, filePtr
.p
->m_flags
,
474 filePtr
.p
->tableId
, filePtr
.p
->fragmentNo
);
476 if (ptr
.p
->slaveState
.getState() == SCANNING
&& ptr
.p
->dataFilePtr
!= RNIL
)
478 c_backupFilePool
.getPtr(filePtr
, ptr
.p
->dataFilePtr
);
479 OperationRecord
& op
= filePtr
.p
->operation
;
483 bool ready
= op
.dataBuffer
.getReadPtr(&tmp
, &sz
, &eof
);
484 ndbout_c("ready: %s eof: %s", ready
? "TRUE" : "FALSE", eof
? "TRUE" : "FALSE");
489 if(signal
->theData
[0] == 24){
491 * Print size of records etc.
493 infoEvent("Backup - dump pool sizes");
494 infoEvent("BackupPool: %d BackupFilePool: %d TablePool: %d",
495 c_backupPool
.getSize(), c_backupFilePool
.getSize(),
496 c_tablePool
.getSize());
497 infoEvent("AttrPool: %d TriggerPool: %d FragmentPool: %d",
498 c_backupPool
.getSize(), c_backupFilePool
.getSize(),
499 c_tablePool
.getSize());
500 infoEvent("PagePool: %d",
501 c_pagePool
.getSize());
504 if(signal
->getLength() == 2 && signal
->theData
[1] == 2424)
510 ndbrequire(c_backups
.first(lcp
));
512 ndbrequire(c_backupPool
.getSize() == c_backupPool
.getNoOfFree() + 1);
513 if(lcp
.p
->tables
.isEmpty())
515 ndbrequire(c_tablePool
.getSize() == c_tablePool
.getNoOfFree());
516 ndbrequire(c_attributePool
.getSize() == c_attributePool
.getNoOfFree());
517 ndbrequire(c_fragmentPool
.getSize() == c_fragmentPool
.getNoOfFree());
518 ndbrequire(c_triggerPool
.getSize() == c_triggerPool
.getNoOfFree());
520 ndbrequire(c_backupFilePool
.getSize() == c_backupFilePool
.getNoOfFree() + 1);
521 BackupFilePtr lcp_file
;
522 c_backupFilePool
.getPtr(lcp_file
, lcp
.p
->dataFilePtr
);
523 ndbrequire(c_pagePool
.getSize() ==
524 c_pagePool
.getNoOfFree() +
525 lcp_file
.p
->pages
.getSize());
531 Backup::findTable(const BackupRecordPtr
& ptr
,
532 TablePtr
& tabPtr
, Uint32 tableId
) const
534 for(ptr
.p
->tables
.first(tabPtr
);
536 ptr
.p
->tables
.next(tabPtr
)) {
538 if(tabPtr
.p
->tableId
== tableId
){
548 static Uint32
xps(Uint64 x
, Uint64 ms
)
553 if(ms
== 0 || x
== 0) {
558 return ((Uint32
)(1000.0f
* (fx
+ fs
/2.1f
))) / ((Uint32
)fs
);
562 Number(Uint64 r
) { val
= r
;}
563 Number
& operator=(Uint64 r
) { val
= r
; return * this; }
568 operator<< (NdbOut
& out
, const Number
& val
){
571 while(val
.val
> loop
){
598 Uint32 tmp
= (val
.val
+ (loop
>> 1)) / loop
;
612 Backup::execBACKUP_CONF(Signal
* signal
)
615 BackupConf
* conf
= (BackupConf
*)signal
->getDataPtr();
617 ndbout_c("Backup %d has started", conf
->backupId
);
621 Backup::execBACKUP_REF(Signal
* signal
)
624 BackupRef
* ref
= (BackupRef
*)signal
->getDataPtr();
626 ndbout_c("Backup (%d) has NOT started %d", ref
->senderData
, ref
->errorCode
);
630 Backup::execBACKUP_COMPLETE_REP(Signal
* signal
)
633 BackupCompleteRep
* rep
= (BackupCompleteRep
*)signal
->getDataPtr();
635 startTime
= NdbTick_CurrentMillisecond() - startTime
;
637 ndbout_c("Backup %d has completed", rep
->backupId
);
639 rep
->noOfBytesLow
+ (((Uint64
)rep
->noOfBytesHigh
) << 32);
640 const Uint64 records
=
641 rep
->noOfRecordsLow
+ (((Uint64
)rep
->noOfRecordsHigh
) << 32);
643 Number rps
= xps(records
, startTime
);
644 Number bps
= xps(bytes
, startTime
);
647 << Number(records
) << " rows "
648 << Number(bytes
) << " bytes " << startTime
<< " ms ] "
650 << rps
<< " row/s & " << bps
<< "b/s" << endl
;
652 bps
= xps(rep
->noOfLogBytes
, startTime
);
653 rps
= xps(rep
->noOfLogRecords
, startTime
);
656 << Number(rep
->noOfLogRecords
) << " log records "
657 << Number(rep
->noOfLogBytes
) << " bytes " << startTime
<< " ms ] "
659 << rps
<< " records/s & " << bps
<< "b/s" << endl
;
664 Backup::execBACKUP_ABORT_REP(Signal
* signal
)
667 BackupAbortRep
* rep
= (BackupAbortRep
*)signal
->getDataPtr();
669 ndbout_c("Backup %d has been aborted %d", rep
->backupId
, rep
->reason
);
672 const TriggerEvent::Value triggerEventValues
[] = {
673 TriggerEvent::TE_INSERT
,
674 TriggerEvent::TE_UPDATE
,
675 TriggerEvent::TE_DELETE
679 Backup::validSlaveTransitions
[] = {
683 STARTED
, STARTED
, // Several START_BACKUP_REQ is sent
690 INITIAL
, ABORTING
, // Node fail
696 CLEANING
, ABORTING
, // Node fail w/ master takeover
697 ABORTING
, ABORTING
, // Slave who initiates ABORT should have this transition
704 Backup::validSlaveTransitionsCount
=
705 sizeof(Backup::validSlaveTransitions
) / sizeof(Backup::State
);
708 Backup::CompoundState::setState(State newState
){
710 const State currState
= state
;
711 for(unsigned i
= 0; i
<noOfValidTransitions
; i
+= 2) {
713 if(validTransitions
[i
] == currState
&&
714 validTransitions
[i
+1] == newState
){
723 if (newState
== INITIAL
)
724 abortState
= INITIAL
;
725 if(newState
== ABORTING
&& currState
!= ABORTING
) {
727 abortState
= currState
;
731 if (newState
!= currState
) {
732 ndbout_c("%u: Old state = %u, new state = %u, abort state = %u",
733 id
, currState
, newState
, abortState
);
739 Backup::CompoundState::forceState(State newState
)
741 const State currState
= state
;
742 if (newState
== INITIAL
)
743 abortState
= INITIAL
;
744 if(newState
== ABORTING
&& currState
!= ABORTING
) {
746 abortState
= currState
;
750 if (newState
!= currState
) {
751 ndbout_c("%u: FORCE: Old state = %u, new state = %u, abort state = %u",
752 id
, currState
, newState
, abortState
);
757 Backup::Table::Table(ArrayPool
<Attribute
> & ah
,
758 ArrayPool
<Fragment
> & fh
)
759 : attributes(ah
), fragments(fh
)
761 triggerIds
[0] = ILLEGAL_TRIGGER_ID
;
762 triggerIds
[1] = ILLEGAL_TRIGGER_ID
;
763 triggerIds
[2] = ILLEGAL_TRIGGER_ID
;
764 triggerAllocated
[0] = false;
765 triggerAllocated
[1] = false;
766 triggerAllocated
[2] = false;
769 /*****************************************************************************
771 * Node state handling
773 *****************************************************************************/
775 Backup::execNODE_FAILREP(Signal
* signal
)
779 NodeFailRep
* rep
= (NodeFailRep
*)signal
->getDataPtr();
781 bool doStuff
= false;
783 Start by saving important signal data which will be destroyed before the
784 process is completed.
786 NodeId new_master_node_id
= rep
->masterNodeId
;
787 Uint32 theFailedNodes
[NodeBitmask::Size
];
788 for (Uint32 i
= 0; i
< NodeBitmask::Size
; i
++)
789 theFailedNodes
[i
] = rep
->theNodes
[i
];
791 c_masterNodeId
= new_master_node_id
;
794 for(c_nodes
.first(nodePtr
); nodePtr
.i
!= RNIL
; c_nodes
.next(nodePtr
)) {
796 if(NodeBitmask::get(theFailedNodes
, nodePtr
.p
->nodeId
)){
797 if(nodePtr
.p
->alive
){
799 ndbrequire(c_aliveNodes
.get(nodePtr
.p
->nodeId
));
803 ndbrequire(!c_aliveNodes
.get(nodePtr
.p
->nodeId
));
805 nodePtr
.p
->alive
= 0;
806 c_aliveNodes
.clear(nodePtr
.p
->nodeId
);
816 ndbout_c("****************** Node fail rep ******************");
819 NodeId newCoordinator
= c_masterNodeId
;
821 for(c_backups
.first(ptr
); ptr
.i
!= RNIL
; c_backups
.next(ptr
)) {
823 checkNodeFail(signal
, ptr
, newCoordinator
, theFailedNodes
);
828 Backup::verifyNodesAlive(BackupRecordPtr ptr
,
829 const NdbNodeBitmask
& aNodeBitMask
)
831 Uint32 version
= getNodeInfo(getOwnNodeId()).m_version
;
832 for (Uint32 i
= 0; i
< MAX_NDB_NODES
; i
++) {
834 if(aNodeBitMask
.get(i
)) {
835 if(!c_aliveNodes
.get(i
)){
837 ptr
.p
->setErrorCode(AbortBackupOrd::BackupFailureDueToNodeFail
);
840 if(getNodeInfo(i
).m_version
!= version
)
843 ptr
.p
->setErrorCode(AbortBackupOrd::IncompatibleVersions
);
852 Backup::checkNodeFail(Signal
* signal
,
855 Uint32 theFailedNodes
[NodeBitmask::Size
])
858 mask
.assign(2, theFailedNodes
);
860 /* Update ptr.p->nodes to be up to date with current alive nodes
864 for(c_nodes
.first(nodePtr
); nodePtr
.i
!= RNIL
; c_nodes
.next(nodePtr
)) {
866 if(NodeBitmask::get(theFailedNodes
, nodePtr
.p
->nodeId
)) {
868 if (ptr
.p
->nodes
.get(nodePtr
.p
->nodeId
)) {
870 ptr
.p
->nodes
.clear(nodePtr
.p
->nodeId
);
878 return; // failed node is not part of backup process, safe to continue
881 if(mask
.get(refToNode(ptr
.p
->masterRef
)))
884 * Master died...abort
886 ptr
.p
->masterRef
= reference();
887 ptr
.p
->nodes
.clear();
888 ptr
.p
->nodes
.set(getOwnNodeId());
889 ptr
.p
->setErrorCode(AbortBackupOrd::BackupFailureDueToNodeFail
);
890 switch(ptr
.p
->m_gsn
){
891 case GSN_DEFINE_BACKUP_REQ
:
892 case GSN_START_BACKUP_REQ
:
893 case GSN_BACKUP_FRAGMENT_REQ
:
894 case GSN_STOP_BACKUP_REQ
:
895 // I'm currently processing...reply to self and abort...
896 ptr
.p
->masterData
.gsn
= ptr
.p
->m_gsn
;
897 ptr
.p
->masterData
.sendCounter
= ptr
.p
->nodes
;
899 case GSN_DEFINE_BACKUP_REF
:
900 case GSN_DEFINE_BACKUP_CONF
:
901 case GSN_START_BACKUP_REF
:
902 case GSN_START_BACKUP_CONF
:
903 case GSN_BACKUP_FRAGMENT_REF
:
904 case GSN_BACKUP_FRAGMENT_CONF
:
905 case GSN_STOP_BACKUP_REF
:
906 case GSN_STOP_BACKUP_CONF
:
907 ptr
.p
->masterData
.gsn
= GSN_DEFINE_BACKUP_REQ
;
908 masterAbort(signal
, ptr
);
910 case GSN_ABORT_BACKUP_ORD
:
915 else if (newCoord
== getOwnNodeId())
918 * I'm master for this backup
921 CRASH_INSERTION((10001));
923 ndbout_c("**** Master: Node failed: Master id = %u",
924 refToNode(ptr
.p
->masterRef
));
927 Uint32 gsn
, len
, pos
;
931 ptr
.p
->nodes
.bitANDC(mask
);
932 switch(ptr
.p
->masterData
.gsn
){
933 case GSN_DEFINE_BACKUP_REQ
:
935 DefineBackupRef
* ref
= (DefineBackupRef
*)signal
->getDataPtr();
936 ref
->backupPtr
= ptr
.i
;
937 ref
->backupId
= ptr
.p
->backupId
;
938 ref
->errorCode
= AbortBackupOrd::BackupFailureDueToNodeFail
;
939 gsn
= GSN_DEFINE_BACKUP_REF
;
940 len
= DefineBackupRef::SignalLength
;
941 pos
= &ref
->nodeId
- signal
->getDataPtr();
944 case GSN_START_BACKUP_REQ
:
946 StartBackupRef
* ref
= (StartBackupRef
*)signal
->getDataPtr();
947 ref
->backupPtr
= ptr
.i
;
948 ref
->backupId
= ptr
.p
->backupId
;
949 ref
->errorCode
= AbortBackupOrd::BackupFailureDueToNodeFail
;
950 gsn
= GSN_START_BACKUP_REF
;
951 len
= StartBackupRef::SignalLength
;
952 pos
= &ref
->nodeId
- signal
->getDataPtr();
955 case GSN_BACKUP_FRAGMENT_REQ
:
957 BackupFragmentRef
* ref
= (BackupFragmentRef
*)signal
->getDataPtr();
958 ref
->backupPtr
= ptr
.i
;
959 ref
->backupId
= ptr
.p
->backupId
;
960 ref
->errorCode
= AbortBackupOrd::BackupFailureDueToNodeFail
;
961 gsn
= GSN_BACKUP_FRAGMENT_REF
;
962 len
= BackupFragmentRef::SignalLength
;
963 pos
= &ref
->nodeId
- signal
->getDataPtr();
966 case GSN_STOP_BACKUP_REQ
:
968 StopBackupRef
* ref
= (StopBackupRef
*)signal
->getDataPtr();
969 ref
->backupPtr
= ptr
.i
;
970 ref
->backupId
= ptr
.p
->backupId
;
971 ref
->errorCode
= AbortBackupOrd::BackupFailureDueToNodeFail
;
972 ref
->nodeId
= getOwnNodeId();
973 gsn
= GSN_STOP_BACKUP_REF
;
974 len
= StopBackupRef::SignalLength
;
975 pos
= &ref
->nodeId
- signal
->getDataPtr();
978 case GSN_WAIT_GCP_REQ
:
979 case GSN_DROP_TRIG_REQ
:
980 case GSN_CREATE_TRIG_REQ
:
981 case GSN_ALTER_TRIG_REQ
:
982 ptr
.p
->setErrorCode(AbortBackupOrd::BackupFailureDueToNodeFail
);
984 case GSN_UTIL_SEQUENCE_REQ
:
985 case GSN_UTIL_LOCK_REQ
:
991 for(Uint32 i
= 0; (i
= mask
.find(i
+1)) != NdbNodeBitmask::NotFound
; )
993 signal
->theData
[pos
] = i
;
994 sendSignal(reference(), gsn
, signal
, len
, JBB
);
996 ndbout_c("sending %d to self from %d", gsn
, i
);
1003 * I abort myself as slave if not master
1005 CRASH_INSERTION((10021));
1009 Backup::execINCL_NODEREQ(Signal
* signal
)
1013 const Uint32 senderRef
= signal
->theData
[0];
1014 const Uint32 inclNode
= signal
->theData
[1];
1017 for(c_nodes
.first(node
); node
.i
!= RNIL
; c_nodes
.next(node
)) {
1019 const Uint32 nodeId
= node
.p
->nodeId
;
1020 if(inclNode
== nodeId
){
1023 ndbrequire(node
.p
->alive
== 0);
1024 ndbrequire(!c_aliveNodes
.get(nodeId
));
1027 c_aliveNodes
.set(nodeId
);
1032 signal
->theData
[0] = inclNode
;
1033 signal
->theData
[1] = reference();
1034 sendSignal(senderRef
, GSN_INCL_NODECONF
, signal
, 2, JBB
);
1037 /*****************************************************************************
1039 * Master functionallity - Define backup
1041 *****************************************************************************/
1044 Backup::execBACKUP_REQ(Signal
* signal
)
1047 BackupReq
* req
= (BackupReq
*)signal
->getDataPtr();
1049 const Uint32 senderData
= req
->senderData
;
1050 const BlockReference senderRef
= signal
->senderBlockRef();
1051 const Uint32 dataLen32
= req
->backupDataLen
; // In 32 bit words
1052 const Uint32 flags
= signal
->getLength() > 2 ? req
->flags
: 2;
1054 if(getOwnNodeId() != getMasterNodeId()) {
1056 sendBackupRef(senderRef
, flags
, signal
, senderData
, BackupRef::IAmNotMaster
);
1060 if (c_defaults
.m_diskless
)
1062 sendBackupRef(senderRef
, flags
, signal
, senderData
,
1063 BackupRef::CannotBackupDiskless
);
1067 if(dataLen32
!= 0) {
1069 sendBackupRef(senderRef
, flags
, signal
, senderData
,
1070 BackupRef::BackupDefinitionNotImplemented
);
1075 dumpUsedResources();
1078 * Seize a backup record
1080 BackupRecordPtr ptr
;
1081 c_backups
.seize(ptr
);
1084 sendBackupRef(senderRef
, flags
, signal
, senderData
, BackupRef::OutOfBackupRecord
);
1088 ndbrequire(ptr
.p
->tables
.isEmpty());
1091 ptr
.p
->errorCode
= 0;
1092 ptr
.p
->clientRef
= senderRef
;
1093 ptr
.p
->clientData
= senderData
;
1094 ptr
.p
->flags
= flags
;
1095 ptr
.p
->masterRef
= reference();
1096 ptr
.p
->nodes
= c_aliveNodes
;
1097 ptr
.p
->backupId
= 0;
1098 ptr
.p
->backupKey
[0] = 0;
1099 ptr
.p
->backupKey
[1] = 0;
1100 ptr
.p
->backupDataLen
= 0;
1101 ptr
.p
->masterData
.errorCode
= 0;
1103 UtilSequenceReq
* utilReq
= (UtilSequenceReq
*)signal
->getDataPtrSend();
1105 ptr
.p
->masterData
.gsn
= GSN_UTIL_SEQUENCE_REQ
;
1106 utilReq
->senderData
= ptr
.i
;
1107 utilReq
->sequenceId
= BACKUP_SEQUENCE
;
1108 utilReq
->requestType
= UtilSequenceReq::NextVal
;
1109 sendSignal(DBUTIL_REF
, GSN_UTIL_SEQUENCE_REQ
,
1110 signal
, UtilSequenceReq::SignalLength
, JBB
);
1114 Backup::execUTIL_SEQUENCE_REF(Signal
* signal
)
1116 BackupRecordPtr ptr LINT_SET_PTR
;
1118 UtilSequenceRef
* utilRef
= (UtilSequenceRef
*)signal
->getDataPtr();
1119 ptr
.i
= utilRef
->senderData
;
1120 c_backupPool
.getPtr(ptr
);
1121 ndbrequire(ptr
.p
->masterData
.gsn
== GSN_UTIL_SEQUENCE_REQ
);
1122 sendBackupRef(signal
, ptr
, BackupRef::SequenceFailure
);
1123 }//execUTIL_SEQUENCE_REF()
1127 Backup::sendBackupRef(Signal
* signal
, BackupRecordPtr ptr
, Uint32 errorCode
)
1130 sendBackupRef(ptr
.p
->clientRef
, ptr
.p
->flags
, signal
, ptr
.p
->clientData
, errorCode
);
1131 cleanup(signal
, ptr
);
1135 Backup::sendBackupRef(BlockReference senderRef
, Uint32 flags
, Signal
*signal
,
1136 Uint32 senderData
, Uint32 errorCode
)
1139 if (SEND_BACKUP_STARTED_FLAG(flags
))
1141 BackupRef
* ref
= (BackupRef
*)signal
->getDataPtrSend();
1142 ref
->senderData
= senderData
;
1143 ref
->errorCode
= errorCode
;
1144 ref
->masterRef
= numberToRef(BACKUP
, getMasterNodeId());
1145 sendSignal(senderRef
, GSN_BACKUP_REF
, signal
, BackupRef::SignalLength
, JBB
);
1148 if(errorCode
!= BackupRef::IAmNotMaster
){
1149 signal
->theData
[0] = NDB_LE_BackupFailedToStart
;
1150 signal
->theData
[1] = senderRef
;
1151 signal
->theData
[2] = errorCode
;
1152 sendSignal(CMVMI_REF
, GSN_EVENT_REP
, signal
, 3, JBB
);
1157 Backup::execUTIL_SEQUENCE_CONF(Signal
* signal
)
1161 UtilSequenceConf
* conf
= (UtilSequenceConf
*)signal
->getDataPtr();
1163 if(conf
->requestType
== UtilSequenceReq::Create
)
1166 sendSTTORRY(signal
); // At startup in NDB
1170 BackupRecordPtr ptr LINT_SET_PTR
;
1171 ptr
.i
= conf
->senderData
;
1172 c_backupPool
.getPtr(ptr
);
1174 ndbrequire(ptr
.p
->masterData
.gsn
== GSN_UTIL_SEQUENCE_REQ
);
1176 if (ptr
.p
->checkError())
1179 sendBackupRef(signal
, ptr
, ptr
.p
->errorCode
);
1183 if (ERROR_INSERTED(10023))
1185 sendBackupRef(signal
, ptr
, 323);
1192 memcpy(&backupId
,conf
->sequenceValue
,8);
1193 ptr
.p
->backupId
= (Uint32
)backupId
;
1195 ptr
.p
->backupKey
[0] = (getOwnNodeId() << 16) | (ptr
.p
->backupId
& 0xFFFF);
1196 ptr
.p
->backupKey
[1] = NdbTick_CurrentMillisecond();
1198 ptr
.p
->masterData
.gsn
= GSN_UTIL_LOCK_REQ
;
1199 Mutex
mutex(signal
, c_mutexMgr
, ptr
.p
->masterData
.m_defineBackupMutex
);
1200 Callback c
= { safe_cast(&Backup::defineBackupMutex_locked
), ptr
.i
};
1201 ndbrequire(mutex
.lock(c
));
1207 Backup::defineBackupMutex_locked(Signal
* signal
, Uint32 ptrI
, Uint32 retVal
){
1209 ndbrequire(retVal
== 0);
1211 BackupRecordPtr ptr LINT_SET_PTR
;
1213 c_backupPool
.getPtr(ptr
);
1215 ndbrequire(ptr
.p
->masterData
.gsn
== GSN_UTIL_LOCK_REQ
);
1217 ptr
.p
->masterData
.gsn
= GSN_UTIL_LOCK_REQ
;
1218 Mutex
mutex(signal
, c_mutexMgr
, ptr
.p
->masterData
.m_dictCommitTableMutex
);
1219 Callback c
= { safe_cast(&Backup::dictCommitTableMutex_locked
), ptr
.i
};
1220 ndbrequire(mutex
.lock(c
));
1224 Backup::dictCommitTableMutex_locked(Signal
* signal
, Uint32 ptrI
,Uint32 retVal
)
1227 ndbrequire(retVal
== 0);
1230 * We now have both the mutexes
1232 BackupRecordPtr ptr LINT_SET_PTR
;
1234 c_backupPool
.getPtr(ptr
);
1236 ndbrequire(ptr
.p
->masterData
.gsn
== GSN_UTIL_LOCK_REQ
);
1238 if (ERROR_INSERTED(10031)) {
1239 ptr
.p
->setErrorCode(331);
1242 if (ptr
.p
->checkError())
1250 Mutex
mutex1(signal
, c_mutexMgr
, ptr
.p
->masterData
.m_dictCommitTableMutex
);
1252 mutex1
.unlock(); // ignore response
1255 Mutex
mutex2(signal
, c_mutexMgr
, ptr
.p
->masterData
.m_defineBackupMutex
);
1257 mutex2
.unlock(); // ignore response
1259 sendBackupRef(signal
, ptr
, ptr
.p
->errorCode
);
1263 sendDefineBackupReq(signal
, ptr
);
1266 /*****************************************************************************
1268 * Master functionallity - Define backup cont'd (from now on all slaves are in)
1270 *****************************************************************************/
1273 Backup::haveAllSignals(BackupRecordPtr ptr
, Uint32 gsn
, Uint32 nodeId
)
1275 ndbrequire(ptr
.p
->masterRef
== reference());
1276 ndbrequire(ptr
.p
->masterData
.gsn
== gsn
);
1277 ndbrequire(!ptr
.p
->masterData
.sendCounter
.done());
1278 ndbrequire(ptr
.p
->masterData
.sendCounter
.isWaitingFor(nodeId
));
1280 ptr
.p
->masterData
.sendCounter
.clearWaitingFor(nodeId
);
1281 return ptr
.p
->masterData
.sendCounter
.done();
1285 Backup::sendDefineBackupReq(Signal
*signal
, BackupRecordPtr ptr
)
1288 * Sending define backup to all participants
1290 DefineBackupReq
* req
= (DefineBackupReq
*)signal
->getDataPtrSend();
1291 req
->backupId
= ptr
.p
->backupId
;
1292 req
->clientRef
= ptr
.p
->clientRef
;
1293 req
->clientData
= ptr
.p
->clientData
;
1294 req
->senderRef
= reference();
1295 req
->backupPtr
= ptr
.i
;
1296 req
->backupKey
[0] = ptr
.p
->backupKey
[0];
1297 req
->backupKey
[1] = ptr
.p
->backupKey
[1];
1298 req
->nodes
= ptr
.p
->nodes
;
1299 req
->backupDataLen
= ptr
.p
->backupDataLen
;
1300 req
->flags
= ptr
.p
->flags
;
1302 ptr
.p
->masterData
.gsn
= GSN_DEFINE_BACKUP_REQ
;
1303 ptr
.p
->masterData
.sendCounter
= ptr
.p
->nodes
;
1304 NodeReceiverGroup
rg(BACKUP
, ptr
.p
->nodes
);
1305 sendSignal(rg
, GSN_DEFINE_BACKUP_REQ
, signal
,
1306 DefineBackupReq::SignalLength
, JBB
);
1309 * Now send backup data
1311 const Uint32 len
= ptr
.p
->backupDataLen
;
1327 Backup::execDEFINE_BACKUP_REF(Signal
* signal
)
1331 DefineBackupRef
* ref
= (DefineBackupRef
*)signal
->getDataPtr();
1333 const Uint32 ptrI
= ref
->backupPtr
;
1334 //const Uint32 backupId = ref->backupId;
1335 const Uint32 nodeId
= ref
->nodeId
;
1337 BackupRecordPtr ptr LINT_SET_PTR
;
1338 c_backupPool
.getPtr(ptr
, ptrI
);
1340 ptr
.p
->setErrorCode(ref
->errorCode
);
1341 defineBackupReply(signal
, ptr
, nodeId
);
1345 Backup::execDEFINE_BACKUP_CONF(Signal
* signal
)
1349 DefineBackupConf
* conf
= (DefineBackupConf
*)signal
->getDataPtr();
1350 const Uint32 ptrI
= conf
->backupPtr
;
1351 //const Uint32 backupId = conf->backupId;
1352 const Uint32 nodeId
= refToNode(signal
->senderBlockRef());
1354 BackupRecordPtr ptr LINT_SET_PTR
;
1355 c_backupPool
.getPtr(ptr
, ptrI
);
1357 if (ERROR_INSERTED(10024))
1359 ptr
.p
->setErrorCode(324);
1362 defineBackupReply(signal
, ptr
, nodeId
);
1366 Backup::defineBackupReply(Signal
* signal
, BackupRecordPtr ptr
, Uint32 nodeId
)
1368 if (!haveAllSignals(ptr
, GSN_DEFINE_BACKUP_REQ
, nodeId
)) {
1377 Mutex
mutex1(signal
, c_mutexMgr
, ptr
.p
->masterData
.m_dictCommitTableMutex
);
1379 mutex1
.unlock(); // ignore response
1382 Mutex
mutex2(signal
, c_mutexMgr
, ptr
.p
->masterData
.m_defineBackupMutex
);
1384 mutex2
.unlock(); // ignore response
1386 if(ptr
.p
->checkError())
1389 masterAbort(signal
, ptr
);
1396 CRASH_INSERTION((10034));
1398 if (SEND_BACKUP_STARTED_FLAG(ptr
.p
->flags
))
1400 BackupConf
* conf
= (BackupConf
*)signal
->getDataPtrSend();
1401 conf
->backupId
= ptr
.p
->backupId
;
1402 conf
->senderData
= ptr
.p
->clientData
;
1403 conf
->nodes
= ptr
.p
->nodes
;
1404 sendSignal(ptr
.p
->clientRef
, GSN_BACKUP_CONF
, signal
,
1405 BackupConf::SignalLength
, JBB
);
1408 signal
->theData
[0] = NDB_LE_BackupStarted
;
1409 signal
->theData
[1] = ptr
.p
->clientRef
;
1410 signal
->theData
[2] = ptr
.p
->backupId
;
1411 ptr
.p
->nodes
.copyto(NdbNodeBitmask::Size
, signal
->theData
+3);
1412 sendSignal(CMVMI_REF
, GSN_EVENT_REP
, signal
, 3+NdbNodeBitmask::Size
, JBB
);
1415 * We've received GSN_DEFINE_BACKUP_CONF from all participants.
1417 * Our next step is to send START_BACKUP_REQ to all participants,
1418 * who will then send CREATE_TRIG_REQ for all tables to their local
1422 ptr
.p
->tables
.first(tabPtr
);
1424 sendStartBackup(signal
, ptr
, tabPtr
);
1427 /*****************************************************************************
1429 * Master functionallity - Prepare triggers
1431 *****************************************************************************/
1433 Backup::createAttributeMask(TablePtr tabPtr
,
1434 Bitmask
<MAXNROFATTRIBUTESINWORDS
> & mask
)
1437 Table
& table
= * tabPtr
.p
;
1438 Ptr
<Attribute
> attrPtr
;
1439 table
.attributes
.first(attrPtr
);
1440 for(; !attrPtr
.isNull(); table
.attributes
.next(attrPtr
))
1443 mask
.set(attrPtr
.p
->data
.attrId
);
1448 Backup::sendCreateTrig(Signal
* signal
,
1449 BackupRecordPtr ptr
, TablePtr tabPtr
)
1451 CreateTrigReq
* req
=(CreateTrigReq
*)signal
->getDataPtrSend();
1454 * First, setup the structures
1456 for(Uint32 j
=0; j
<3; j
++) {
1460 if(!ptr
.p
->triggers
.seize(trigPtr
)) {
1462 ptr
.p
->m_gsn
= GSN_START_BACKUP_REF
;
1463 StartBackupRef
* ref
= (StartBackupRef
*)signal
->getDataPtrSend();
1464 ref
->backupPtr
= ptr
.i
;
1465 ref
->backupId
= ptr
.p
->backupId
;
1466 ref
->errorCode
= StartBackupRef::FailedToAllocateTriggerRecord
;
1467 ref
->nodeId
= getOwnNodeId();
1468 sendSignal(ptr
.p
->masterRef
, GSN_START_BACKUP_REF
, signal
,
1469 StartBackupRef::SignalLength
, JBB
);
1473 const Uint32 triggerId
= trigPtr
.i
;
1474 tabPtr
.p
->triggerIds
[j
] = triggerId
;
1475 tabPtr
.p
->triggerAllocated
[j
] = true;
1476 trigPtr
.p
->backupPtr
= ptr
.i
;
1477 trigPtr
.p
->tableId
= tabPtr
.p
->tableId
;
1478 trigPtr
.p
->tab_ptr_i
= tabPtr
.i
;
1479 trigPtr
.p
->logEntry
= 0;
1480 trigPtr
.p
->event
= j
;
1481 trigPtr
.p
->maxRecordSize
= 4096;
1482 trigPtr
.p
->operation
=
1483 &ptr
.p
->files
.getPtr(ptr
.p
->logFilePtr
)->operation
;
1484 trigPtr
.p
->operation
->noOfBytes
= 0;
1485 trigPtr
.p
->operation
->noOfRecords
= 0;
1486 trigPtr
.p
->errorCode
= 0;
1490 * now ask DBTUP to create
1492 ptr
.p
->slaveData
.gsn
= GSN_CREATE_TRIG_REQ
;
1493 ptr
.p
->slaveData
.trigSendCounter
= 3;
1494 ptr
.p
->slaveData
.createTrig
.tableId
= tabPtr
.p
->tableId
;
1496 req
->setUserRef(reference());
1497 req
->setReceiverRef(reference());
1498 req
->setConnectionPtr(ptr
.i
);
1499 req
->setRequestType(CreateTrigReq::RT_USER
);
1501 Bitmask
<MAXNROFATTRIBUTESINWORDS
> attrMask
;
1502 createAttributeMask(tabPtr
, attrMask
);
1503 req
->setAttributeMask(attrMask
);
1504 req
->setTableId(tabPtr
.p
->tableId
);
1505 req
->setIndexId(RNIL
); // not used
1506 req
->setTriggerType(TriggerType::SUBSCRIPTION
);
1507 req
->setTriggerActionTime(TriggerActionTime::TA_DETACHED
);
1508 req
->setMonitorReplicas(true);
1509 req
->setMonitorAllAttributes(false);
1510 req
->setOnline(true);
1512 for (int i
=0; i
< 3; i
++) {
1513 req
->setTriggerId(tabPtr
.p
->triggerIds
[i
]);
1514 req
->setTriggerEvent(triggerEventValues
[i
]);
1516 sendSignal(DBTUP_REF
, GSN_CREATE_TRIG_REQ
,
1517 signal
, CreateTrigReq::SignalLength
, JBB
);
1522 Backup::execCREATE_TRIG_CONF(Signal
* signal
)
1525 CreateTrigConf
* conf
= (CreateTrigConf
*)signal
->getDataPtr();
1527 const Uint32 ptrI
= conf
->getConnectionPtr();
1528 const Uint32 tableId
= conf
->getTableId();
1529 const TriggerEvent::Value type
= conf
->getTriggerEvent();
1531 BackupRecordPtr ptr LINT_SET_PTR
;
1532 c_backupPool
.getPtr(ptr
, ptrI
);
1535 * Verify that I'm waiting for this conf
1537 * ptr.p->masterRef != reference()
1538 * as slaves and masters have triggers now.
1540 ndbrequire(ptr
.p
->slaveData
.gsn
== GSN_CREATE_TRIG_REQ
);
1541 ndbrequire(ptr
.p
->slaveData
.trigSendCounter
.done() == false);
1542 ndbrequire(ptr
.p
->slaveData
.createTrig
.tableId
== tableId
);
1545 ndbrequire(findTable(ptr
, tabPtr
, tableId
));
1546 ndbrequire(type
< 3); // if some decides to change the enums
1548 createTrigReply(signal
, ptr
);
1552 Backup::execCREATE_TRIG_REF(Signal
* signal
)
1555 CreateTrigRef
* ref
= (CreateTrigRef
*)signal
->getDataPtr();
1557 const Uint32 ptrI
= ref
->getConnectionPtr();
1558 const Uint32 tableId
= ref
->getTableId();
1560 BackupRecordPtr ptr LINT_SET_PTR
;
1561 c_backupPool
.getPtr(ptr
, ptrI
);
1564 * Verify that I'm waiting for this ref
1566 * ptr.p->masterRef != reference()
1567 * as slaves and masters have triggers now
1569 ndbrequire(ptr
.p
->slaveData
.gsn
== GSN_CREATE_TRIG_REQ
);
1570 ndbrequire(ptr
.p
->slaveData
.trigSendCounter
.done() == false);
1571 ndbrequire(ptr
.p
->slaveData
.createTrig
.tableId
== tableId
);
1573 ptr
.p
->setErrorCode(ref
->getErrorCode());
1575 createTrigReply(signal
, ptr
);
1579 Backup::createTrigReply(Signal
* signal
, BackupRecordPtr ptr
)
1581 CRASH_INSERTION(10003);
1584 * Check finished with table
1586 ptr
.p
->slaveData
.trigSendCounter
--;
1587 if(ptr
.p
->slaveData
.trigSendCounter
.done() == false){
1592 if (ERROR_INSERTED(10025))
1594 ptr
.p
->errorCode
= 325;
1597 if(ptr
.p
->checkError()) {
1599 ptr
.p
->m_gsn
= GSN_START_BACKUP_REF
;
1600 StartBackupRef
* ref
= (StartBackupRef
*)signal
->getDataPtrSend();
1601 ref
->backupPtr
= ptr
.i
;
1602 ref
->backupId
= ptr
.p
->backupId
;
1603 ref
->errorCode
= ptr
.p
->errorCode
;
1604 ref
->nodeId
= getOwnNodeId();
1605 sendSignal(ptr
.p
->masterRef
, GSN_START_BACKUP_REF
, signal
,
1606 StartBackupRef::SignalLength
, JBB
);
1611 ndbrequire(findTable(ptr
, tabPtr
, ptr
.p
->slaveData
.createTrig
.tableId
));
1616 ptr
.p
->tables
.next(tabPtr
);
1617 if(tabPtr
.i
!= RNIL
){
1619 sendCreateTrig(signal
, ptr
, tabPtr
);
1624 * We've finished creating triggers.
1626 * send conf and wait
1628 ptr
.p
->m_gsn
= GSN_START_BACKUP_CONF
;
1629 StartBackupConf
* conf
= (StartBackupConf
*)signal
->getDataPtrSend();
1630 conf
->backupPtr
= ptr
.i
;
1631 conf
->backupId
= ptr
.p
->backupId
;
1632 sendSignal(ptr
.p
->masterRef
, GSN_START_BACKUP_CONF
, signal
,
1633 StartBackupConf::SignalLength
, JBB
);
1636 /*****************************************************************************
1638 * Master functionallity - Start backup
1640 *****************************************************************************/
1642 Backup::sendStartBackup(Signal
* signal
, BackupRecordPtr ptr
, TablePtr tabPtr
)
1645 ptr
.p
->masterData
.startBackup
.tablePtr
= tabPtr
.i
;
1647 StartBackupReq
* req
= (StartBackupReq
*)signal
->getDataPtrSend();
1648 req
->backupId
= ptr
.p
->backupId
;
1649 req
->backupPtr
= ptr
.i
;
1652 * We use trigger Ids that are unique to BACKUP.
1653 * These don't interfere with other triggers (e.g. from DBDICT)
1654 * as there is a special case in DBTUP.
1656 * Consequently, backups during online upgrade won't work
1658 ptr
.p
->masterData
.gsn
= GSN_START_BACKUP_REQ
;
1659 ptr
.p
->masterData
.sendCounter
= ptr
.p
->nodes
;
1660 NodeReceiverGroup
rg(BACKUP
, ptr
.p
->nodes
);
1661 sendSignal(rg
, GSN_START_BACKUP_REQ
, signal
,
1662 StartBackupReq::SignalLength
, JBB
);
1666 Backup::execSTART_BACKUP_REF(Signal
* signal
)
1670 StartBackupRef
* ref
= (StartBackupRef
*)signal
->getDataPtr();
1671 const Uint32 ptrI
= ref
->backupPtr
;
1672 //const Uint32 backupId = ref->backupId;
1673 const Uint32 nodeId
= ref
->nodeId
;
1675 BackupRecordPtr ptr LINT_SET_PTR
;
1676 c_backupPool
.getPtr(ptr
, ptrI
);
1678 ptr
.p
->setErrorCode(ref
->errorCode
);
1679 startBackupReply(signal
, ptr
, nodeId
);
1683 Backup::execSTART_BACKUP_CONF(Signal
* signal
)
1687 StartBackupConf
* conf
= (StartBackupConf
*)signal
->getDataPtr();
1688 const Uint32 ptrI
= conf
->backupPtr
;
1689 //const Uint32 backupId = conf->backupId;
1690 const Uint32 nodeId
= refToNode(signal
->senderBlockRef());
1692 BackupRecordPtr ptr LINT_SET_PTR
;
1693 c_backupPool
.getPtr(ptr
, ptrI
);
1695 startBackupReply(signal
, ptr
, nodeId
);
1699 Backup::startBackupReply(Signal
* signal
, BackupRecordPtr ptr
, Uint32 nodeId
)
1702 CRASH_INSERTION((10004));
1704 if (!haveAllSignals(ptr
, GSN_START_BACKUP_REQ
, nodeId
)) {
1709 if (ERROR_INSERTED(10026))
1711 ptr
.p
->errorCode
= 326;
1714 if(ptr
.p
->checkError()){
1716 masterAbort(signal
, ptr
);
1723 ptr
.p
->masterData
.gsn
= GSN_WAIT_GCP_REQ
;
1724 ptr
.p
->masterData
.waitGCP
.startBackup
= true;
1726 WaitGCPReq
* waitGCPReq
= (WaitGCPReq
*)signal
->getDataPtrSend();
1727 waitGCPReq
->senderRef
= reference();
1728 waitGCPReq
->senderData
= ptr
.i
;
1729 waitGCPReq
->requestType
= WaitGCPReq::CompleteForceStart
;
1730 sendSignal(DBDIH_REF
, GSN_WAIT_GCP_REQ
, signal
,
1731 WaitGCPReq::SignalLength
,JBB
);
1735 Backup::execWAIT_GCP_REF(Signal
* signal
)
1739 CRASH_INSERTION((10006));
1741 WaitGCPRef
* ref
= (WaitGCPRef
*)signal
->getDataPtr();
1742 const Uint32 ptrI
= ref
->senderData
;
1744 BackupRecordPtr ptr LINT_SET_PTR
;
1745 c_backupPool
.getPtr(ptr
, ptrI
);
1747 ndbrequire(ptr
.p
->masterRef
== reference());
1748 ndbrequire(ptr
.p
->masterData
.gsn
== GSN_WAIT_GCP_REQ
);
1750 WaitGCPReq
* req
= (WaitGCPReq
*)signal
->getDataPtrSend();
1751 req
->senderRef
= reference();
1752 req
->senderData
= ptr
.i
;
1753 req
->requestType
= WaitGCPReq::CompleteForceStart
;
1754 sendSignal(DBDIH_REF
, GSN_WAIT_GCP_REQ
, signal
,
1755 WaitGCPReq::SignalLength
,JBB
);
1759 Backup::execWAIT_GCP_CONF(Signal
* signal
){
1762 CRASH_INSERTION((10007));
1764 WaitGCPConf
* conf
= (WaitGCPConf
*)signal
->getDataPtr();
1765 const Uint32 ptrI
= conf
->senderData
;
1766 const Uint32 gcp
= conf
->gcp
;
1768 BackupRecordPtr ptr LINT_SET_PTR
;
1769 c_backupPool
.getPtr(ptr
, ptrI
);
1771 ndbrequire(ptr
.p
->masterRef
== reference());
1772 ndbrequire(ptr
.p
->masterData
.gsn
== GSN_WAIT_GCP_REQ
);
1774 if(ptr
.p
->checkError()) {
1776 masterAbort(signal
, ptr
);
1780 if(ptr
.p
->masterData
.waitGCP
.startBackup
) {
1782 CRASH_INSERTION((10008));
1783 ptr
.p
->startGCP
= gcp
;
1784 ptr
.p
->masterData
.sendCounter
= 0;
1785 ptr
.p
->masterData
.gsn
= GSN_BACKUP_FRAGMENT_REQ
;
1786 nextFragment(signal
, ptr
);
1790 if(gcp
>= ptr
.p
->startGCP
+ 3)
1792 CRASH_INSERTION((10009));
1793 ptr
.p
->stopGCP
= gcp
;
1795 * Backup is complete - begin cleanup
1796 * STOP_BACKUP_REQ is sent to participants.
1797 * They then drop the local triggers
1799 sendStopBackup(signal
, ptr
);
1804 * Make sure that we got entire stopGCP
1806 WaitGCPReq
* req
= (WaitGCPReq
*)signal
->getDataPtrSend();
1807 req
->senderRef
= reference();
1808 req
->senderData
= ptr
.i
;
1809 req
->requestType
= WaitGCPReq::CompleteForceStart
;
1810 sendSignal(DBDIH_REF
, GSN_WAIT_GCP_REQ
, signal
,
1811 WaitGCPReq::SignalLength
,JBB
);
1816 /*****************************************************************************
1818 * Master functionallity - Backup fragment
1820 *****************************************************************************/
1822 Backup::nextFragment(Signal
* signal
, BackupRecordPtr ptr
)
1826 BackupFragmentReq
* req
= (BackupFragmentReq
*)signal
->getDataPtrSend();
1827 req
->backupPtr
= ptr
.i
;
1828 req
->backupId
= ptr
.p
->backupId
;
1830 NodeBitmask nodes
= ptr
.p
->nodes
;
1831 Uint32 idleNodes
= nodes
.count();
1832 Uint32 saveIdleNodes
= idleNodes
;
1833 ndbrequire(idleNodes
> 0);
1836 ptr
.p
->tables
.first(tabPtr
);
1837 for(; tabPtr
.i
!= RNIL
&& idleNodes
> 0; ptr
.p
->tables
.next(tabPtr
)) {
1839 FragmentPtr fragPtr
;
1840 Array
<Fragment
> & frags
= tabPtr
.p
->fragments
;
1841 const Uint32 fragCount
= frags
.getSize();
1843 for(Uint32 i
= 0; i
<fragCount
&& idleNodes
> 0; i
++) {
1845 tabPtr
.p
->fragments
.getPtr(fragPtr
, i
);
1846 const Uint32 nodeId
= fragPtr
.p
->node
;
1847 if(fragPtr
.p
->scanning
!= 0) {
1849 ndbrequire(nodes
.get(nodeId
));
1850 nodes
.clear(nodeId
);
1852 } else if(fragPtr
.p
->scanned
== 0 && nodes
.get(nodeId
)){
1854 fragPtr
.p
->scanning
= 1;
1855 nodes
.clear(nodeId
);
1858 req
->tableId
= tabPtr
.p
->tableId
;
1859 req
->fragmentNo
= i
;
1862 ptr
.p
->masterData
.sendCounter
++;
1863 const BlockReference ref
= numberToRef(BACKUP
, nodeId
);
1864 sendSignal(ref
, GSN_BACKUP_FRAGMENT_REQ
, signal
,
1865 BackupFragmentReq::SignalLength
, JBB
);
1870 if(idleNodes
!= saveIdleNodes
){
1876 * Finished with all tables
1879 ptr
.p
->masterData
.gsn
= GSN_WAIT_GCP_REQ
;
1880 ptr
.p
->masterData
.waitGCP
.startBackup
= false;
1882 WaitGCPReq
* req
= (WaitGCPReq
*)signal
->getDataPtrSend();
1883 req
->senderRef
= reference();
1884 req
->senderData
= ptr
.i
;
1885 req
->requestType
= WaitGCPReq::CompleteForceStart
;
1886 sendSignal(DBDIH_REF
, GSN_WAIT_GCP_REQ
, signal
,
1887 WaitGCPReq::SignalLength
, JBB
);
1892 Backup::execBACKUP_FRAGMENT_CONF(Signal
* signal
)
1896 CRASH_INSERTION((10010));
1898 BackupFragmentConf
* conf
= (BackupFragmentConf
*)signal
->getDataPtr();
1899 const Uint32 ptrI
= conf
->backupPtr
;
1900 //const Uint32 backupId = conf->backupId;
1901 const Uint32 tableId
= conf
->tableId
;
1902 const Uint32 fragmentNo
= conf
->fragmentNo
;
1903 const Uint32 nodeId
= refToNode(signal
->senderBlockRef());
1904 const Uint64 noOfBytes
=
1905 conf
->noOfBytesLow
+ (((Uint64
)conf
->noOfBytesHigh
) << 32);
1906 const Uint64 noOfRecords
=
1907 conf
->noOfRecordsLow
+ (((Uint64
)conf
->noOfRecordsHigh
) << 32);
1909 BackupRecordPtr ptr LINT_SET_PTR
;
1910 c_backupPool
.getPtr(ptr
, ptrI
);
1912 ptr
.p
->noOfBytes
+= noOfBytes
;
1913 ptr
.p
->noOfRecords
+= noOfRecords
;
1914 ptr
.p
->masterData
.sendCounter
--;
1917 ndbrequire(findTable(ptr
, tabPtr
, tableId
));
1919 tabPtr
.p
->noOfRecords
+= noOfRecords
;
1921 FragmentPtr fragPtr
;
1922 tabPtr
.p
->fragments
.getPtr(fragPtr
, fragmentNo
);
1924 fragPtr
.p
->noOfRecords
= noOfRecords
;
1926 ndbrequire(fragPtr
.p
->scanned
== 0);
1927 ndbrequire(fragPtr
.p
->scanning
== 1);
1928 ndbrequire(fragPtr
.p
->node
== nodeId
);
1930 fragPtr
.p
->scanned
= 1;
1931 fragPtr
.p
->scanning
= 0;
1933 if (ERROR_INSERTED(10028))
1935 ptr
.p
->errorCode
= 328;
1938 if(ptr
.p
->checkError())
1940 if(ptr
.p
->masterData
.sendCounter
.done())
1943 masterAbort(signal
, ptr
);
1949 NodeBitmask nodes
= ptr
.p
->nodes
;
1950 nodes
.clear(getOwnNodeId());
1951 if (!nodes
.isclear())
1953 BackupFragmentCompleteRep
*rep
=
1954 (BackupFragmentCompleteRep
*)signal
->getDataPtrSend();
1955 rep
->backupId
= ptr
.p
->backupId
;
1956 rep
->backupPtr
= ptr
.i
;
1957 rep
->tableId
= tableId
;
1958 rep
->fragmentNo
= fragmentNo
;
1959 rep
->noOfTableRowsLow
= (Uint32
)(tabPtr
.p
->noOfRecords
& 0xFFFFFFFF);
1960 rep
->noOfTableRowsHigh
= (Uint32
)(tabPtr
.p
->noOfRecords
>> 32);
1961 rep
->noOfFragmentRowsLow
= (Uint32
)(noOfRecords
& 0xFFFFFFFF);
1962 rep
->noOfFragmentRowsHigh
= (Uint32
)(noOfRecords
>> 32);
1963 NodeReceiverGroup
rg(BACKUP
, ptr
.p
->nodes
);
1964 sendSignal(rg
, GSN_BACKUP_FRAGMENT_COMPLETE_REP
, signal
,
1965 BackupFragmentCompleteRep::SignalLength
, JBB
);
1967 nextFragment(signal
, ptr
);
1972 Backup::execBACKUP_FRAGMENT_REF(Signal
* signal
)
1976 CRASH_INSERTION((10011));
1978 BackupFragmentRef
* ref
= (BackupFragmentRef
*)signal
->getDataPtr();
1979 const Uint32 ptrI
= ref
->backupPtr
;
1980 //const Uint32 backupId = ref->backupId;
1981 const Uint32 nodeId
= ref
->nodeId
;
1983 BackupRecordPtr ptr LINT_SET_PTR
;
1984 c_backupPool
.getPtr(ptr
, ptrI
);
1987 ptr
.p
->tables
.first(tabPtr
);
1988 for(; tabPtr
.i
!= RNIL
; ptr
.p
->tables
.next(tabPtr
)) {
1990 FragmentPtr fragPtr
;
1991 Array
<Fragment
> & frags
= tabPtr
.p
->fragments
;
1992 const Uint32 fragCount
= frags
.getSize();
1994 for(Uint32 i
= 0; i
<fragCount
; i
++) {
1996 tabPtr
.p
->fragments
.getPtr(fragPtr
, i
);
1997 if(fragPtr
.p
->scanning
!= 0 && nodeId
== fragPtr
.p
->node
)
2000 ndbrequire(fragPtr
.p
->scanned
== 0);
2001 fragPtr
.p
->scanned
= 1;
2002 fragPtr
.p
->scanning
= 0;
2010 ptr
.p
->masterData
.sendCounter
--;
2011 ptr
.p
->setErrorCode(ref
->errorCode
);
2013 if(ptr
.p
->masterData
.sendCounter
.done())
2016 masterAbort(signal
, ptr
);
2021 AbortBackupOrd
*ord
= (AbortBackupOrd
*)signal
->getDataPtrSend();
2022 ord
->backupId
= ptr
.p
->backupId
;
2023 ord
->backupPtr
= ptr
.i
;
2024 ord
->requestType
= AbortBackupOrd::LogBufferFull
;
2025 ord
->senderData
= ptr
.i
;
2026 execABORT_BACKUP_ORD(signal
);
2030 Backup::execBACKUP_FRAGMENT_COMPLETE_REP(Signal
* signal
)
2033 BackupFragmentCompleteRep
* rep
=
2034 (BackupFragmentCompleteRep
*)signal
->getDataPtr();
2036 BackupRecordPtr ptr LINT_SET_PTR
;
2037 c_backupPool
.getPtr(ptr
, rep
->backupPtr
);
2040 ndbrequire(findTable(ptr
, tabPtr
, rep
->tableId
));
2042 tabPtr
.p
->noOfRecords
=
2043 rep
->noOfTableRowsLow
+ (((Uint64
)rep
->noOfTableRowsHigh
) << 32);
2045 FragmentPtr fragPtr
;
2046 tabPtr
.p
->fragments
.getPtr(fragPtr
, rep
->fragmentNo
);
2048 fragPtr
.p
->noOfRecords
=
2049 rep
->noOfFragmentRowsLow
+ (((Uint64
)rep
->noOfFragmentRowsHigh
) << 32);
2052 /*****************************************************************************
2054 * Slave functionallity - Drop triggers
2056 *****************************************************************************/
2059 Backup::sendDropTrig(Signal
* signal
, BackupRecordPtr ptr
)
2062 ptr
.p
->slaveData
.gsn
= GSN_DROP_TRIG_REQ
;
2064 if (ptr
.p
->slaveData
.dropTrig
.tableId
== RNIL
) {
2066 if(ptr
.p
->tables
.count())
2067 ptr
.p
->tables
.first(tabPtr
);
2070 // Early abort, go to close files
2072 closeFiles(signal
, ptr
);
2077 ndbrequire(findTable(ptr
, tabPtr
, ptr
.p
->slaveData
.dropTrig
.tableId
));
2078 ptr
.p
->tables
.next(tabPtr
);
2080 if (tabPtr
.i
!= RNIL
) {
2082 sendDropTrig(signal
, ptr
, tabPtr
);
2087 //if backup error, we needn't insert footers
2088 if(ptr
.p
->checkError())
2091 closeFiles(signal
, ptr
);
2092 ptr
.p
->errorCode
= 0;
2097 BackupFilePtr filePtr LINT_SET_PTR
;
2098 ptr
.p
->files
.getPtr(filePtr
, ptr
.p
->logFilePtr
);
2101 ndbrequire(filePtr
.p
->operation
.dataBuffer
.getWritePtr(&dst
, 1));
2103 filePtr
.p
->operation
.dataBuffer
.updateWritePtr(1);
2107 BackupFilePtr filePtr LINT_SET_PTR
;
2108 ptr
.p
->files
.getPtr(filePtr
, ptr
.p
->ctlFilePtr
);
2110 const Uint32 gcpSz
= sizeof(BackupFormat::CtlFile::GCPEntry
) >> 2;
2114 ndbrequire(filePtr
.p
->operation
.dataBuffer
.getWritePtr(&dst
, gcpSz
));
2116 BackupFormat::CtlFile::GCPEntry
* gcp
=
2117 (BackupFormat::CtlFile::GCPEntry
*)dst
;
2119 gcp
->SectionType
= htonl(BackupFormat::GCP_ENTRY
);
2120 gcp
->SectionLength
= htonl(gcpSz
);
2121 gcp
->StartGCP
= htonl(ptr
.p
->startGCP
);
2122 gcp
->StopGCP
= htonl(ptr
.p
->stopGCP
- 1);
2123 filePtr
.p
->operation
.dataBuffer
.updateWritePtr(gcpSz
);
2127 if (ptr
.p
->tables
.first(tabPtr
))
2130 signal
->theData
[0] = BackupContinueB::BACKUP_FRAGMENT_INFO
;
2131 signal
->theData
[1] = ptr
.i
;
2132 signal
->theData
[2] = tabPtr
.i
;
2133 signal
->theData
[3] = 0;
2134 sendSignal(BACKUP_REF
, GSN_CONTINUEB
, signal
, 4, JBB
);
2139 closeFiles(signal
, ptr
);
2147 Backup::sendDropTrig(Signal
* signal
, BackupRecordPtr ptr
, TablePtr tabPtr
)
2150 DropTrigReq
* req
= (DropTrigReq
*)signal
->getDataPtrSend();
2152 ptr
.p
->slaveData
.gsn
= GSN_DROP_TRIG_REQ
;
2153 ptr
.p
->slaveData
.trigSendCounter
= 0;
2154 req
->setConnectionPtr(ptr
.i
);
2155 req
->setUserRef(reference()); // Sending to myself
2156 req
->setRequestType(DropTrigReq::RT_USER
);
2157 req
->setIndexId(RNIL
);
2158 req
->setTriggerInfo(0); // not used on DROP
2159 req
->setTriggerType(TriggerType::SUBSCRIPTION
);
2160 req
->setTriggerActionTime(TriggerActionTime::TA_DETACHED
);
2162 ptr
.p
->slaveData
.dropTrig
.tableId
= tabPtr
.p
->tableId
;
2163 req
->setTableId(tabPtr
.p
->tableId
);
2165 for (int i
= 0; i
< 3; i
++) {
2166 Uint32 id
= tabPtr
.p
->triggerIds
[i
];
2167 req
->setTriggerId(id
);
2168 req
->setTriggerEvent(triggerEventValues
[i
]);
2169 sendSignal(DBTUP_REF
, GSN_DROP_TRIG_REQ
,
2170 signal
, DropTrigReq::SignalLength
, JBB
);
2171 ptr
.p
->slaveData
.trigSendCounter
++;
2176 Backup::execDROP_TRIG_REF(Signal
* signal
)
2180 DropTrigRef
* ref
= (DropTrigRef
*)signal
->getDataPtr();
2181 const Uint32 ptrI
= ref
->getConnectionPtr();
2183 BackupRecordPtr ptr LINT_SET_PTR
;
2184 c_backupPool
.getPtr(ptr
, ptrI
);
2186 if(ref
->getConf()->getTriggerId() != ~(Uint32
) 0)
2188 ndbout
<< "ERROR DROPPING TRIGGER: " << ref
->getConf()->getTriggerId();
2189 ndbout
<< " Err: " << (Uint32
)ref
->getErrorCode() << endl
<< endl
;
2192 dropTrigReply(signal
, ptr
);
2196 Backup::execDROP_TRIG_CONF(Signal
* signal
)
2200 DropTrigConf
* conf
= (DropTrigConf
*)signal
->getDataPtr();
2201 const Uint32 ptrI
= conf
->getConnectionPtr();
2203 BackupRecordPtr ptr LINT_SET_PTR
;
2204 c_backupPool
.getPtr(ptr
, ptrI
);
2206 dropTrigReply(signal
, ptr
);
2210 Backup::dropTrigReply(Signal
* signal
, BackupRecordPtr ptr
)
2212 CRASH_INSERTION((10012));
2214 ndbrequire(ptr
.p
->slaveData
.gsn
== GSN_DROP_TRIG_REQ
);
2215 ndbrequire(ptr
.p
->slaveData
.trigSendCounter
.done() == false);
2217 // move from .masterData to .slaveData
2218 ptr
.p
->slaveData
.trigSendCounter
--;
2219 if(ptr
.p
->slaveData
.trigSendCounter
.done() == false){
2224 sendDropTrig(signal
, ptr
); // recursive next
2227 /*****************************************************************************
2229 * Master functionallity - Stop backup
2231 *****************************************************************************/
2233 Backup::execSTOP_BACKUP_REF(Signal
* signal
)
2237 StopBackupRef
* ref
= (StopBackupRef
*)signal
->getDataPtr();
2238 const Uint32 ptrI
= ref
->backupPtr
;
2239 //const Uint32 backupId = ref->backupId;
2240 const Uint32 nodeId
= ref
->nodeId
;
2242 BackupRecordPtr ptr LINT_SET_PTR
;
2243 c_backupPool
.getPtr(ptr
, ptrI
);
2245 ptr
.p
->setErrorCode(ref
->errorCode
);
2246 stopBackupReply(signal
, ptr
, nodeId
);
2250 Backup::sendStopBackup(Signal
* signal
, BackupRecordPtr ptr
)
2254 StopBackupReq
* stop
= (StopBackupReq
*)signal
->getDataPtrSend();
2255 stop
->backupPtr
= ptr
.i
;
2256 stop
->backupId
= ptr
.p
->backupId
;
2257 stop
->startGCP
= ptr
.p
->startGCP
;
2258 stop
->stopGCP
= ptr
.p
->stopGCP
;
2260 ptr
.p
->masterData
.gsn
= GSN_STOP_BACKUP_REQ
;
2261 ptr
.p
->masterData
.sendCounter
= ptr
.p
->nodes
;
2262 NodeReceiverGroup
rg(BACKUP
, ptr
.p
->nodes
);
2263 sendSignal(rg
, GSN_STOP_BACKUP_REQ
, signal
,
2264 StopBackupReq::SignalLength
, JBB
);
2268 Backup::execSTOP_BACKUP_CONF(Signal
* signal
)
2272 StopBackupConf
* conf
= (StopBackupConf
*)signal
->getDataPtr();
2273 const Uint32 ptrI
= conf
->backupPtr
;
2274 //const Uint32 backupId = conf->backupId;
2275 const Uint32 nodeId
= refToNode(signal
->senderBlockRef());
2277 BackupRecordPtr ptr LINT_SET_PTR
;
2278 c_backupPool
.getPtr(ptr
, ptrI
);
2280 ptr
.p
->noOfLogBytes
+= conf
->noOfLogBytes
;
2281 ptr
.p
->noOfLogRecords
+= conf
->noOfLogRecords
;
2283 stopBackupReply(signal
, ptr
, nodeId
);
2287 Backup::stopBackupReply(Signal
* signal
, BackupRecordPtr ptr
, Uint32 nodeId
)
2289 CRASH_INSERTION((10013));
2291 if (!haveAllSignals(ptr
, GSN_STOP_BACKUP_REQ
, nodeId
)) {
2296 sendAbortBackupOrd(signal
, ptr
, AbortBackupOrd::BackupComplete
);
2298 if(!ptr
.p
->checkError())
2300 if (SEND_BACKUP_COMPLETED_FLAG(ptr
.p
->flags
))
2302 BackupCompleteRep
* rep
= (BackupCompleteRep
*)signal
->getDataPtrSend();
2303 rep
->backupId
= ptr
.p
->backupId
;
2304 rep
->senderData
= ptr
.p
->clientData
;
2305 rep
->startGCP
= ptr
.p
->startGCP
;
2306 rep
->stopGCP
= ptr
.p
->stopGCP
;
2307 rep
->noOfBytesLow
= (Uint32
)(ptr
.p
->noOfBytes
& 0xFFFFFFFF);
2308 rep
->noOfRecordsLow
= (Uint32
)(ptr
.p
->noOfRecords
& 0xFFFFFFFF);
2309 rep
->noOfBytesHigh
= (Uint32
)(ptr
.p
->noOfBytes
>> 32);
2310 rep
->noOfRecordsHigh
= (Uint32
)(ptr
.p
->noOfRecords
>> 32);
2311 rep
->noOfLogBytes
= ptr
.p
->noOfLogBytes
;
2312 rep
->noOfLogRecords
= ptr
.p
->noOfLogRecords
;
2313 rep
->nodes
= ptr
.p
->nodes
;
2314 sendSignal(ptr
.p
->clientRef
, GSN_BACKUP_COMPLETE_REP
, signal
,
2315 BackupCompleteRep::SignalLength
, JBB
);
2318 signal
->theData
[0] = NDB_LE_BackupCompleted
;
2319 signal
->theData
[1] = ptr
.p
->clientRef
;
2320 signal
->theData
[2] = ptr
.p
->backupId
;
2321 signal
->theData
[3] = ptr
.p
->startGCP
;
2322 signal
->theData
[4] = ptr
.p
->stopGCP
;
2323 signal
->theData
[5] = (Uint32
)(ptr
.p
->noOfBytes
& 0xFFFFFFFF);
2324 signal
->theData
[6] = (Uint32
)(ptr
.p
->noOfRecords
& 0xFFFFFFFF);
2325 signal
->theData
[7] = ptr
.p
->noOfLogBytes
;
2326 signal
->theData
[8] = ptr
.p
->noOfLogRecords
;
2327 ptr
.p
->nodes
.copyto(NdbNodeBitmask::Size
, signal
->theData
+9);
2328 signal
->theData
[9+NdbNodeBitmask::Size
] = (Uint32
)(ptr
.p
->noOfBytes
>> 32);
2329 signal
->theData
[10+NdbNodeBitmask::Size
] = (Uint32
)(ptr
.p
->noOfRecords
>> 32);
2330 sendSignal(CMVMI_REF
, GSN_EVENT_REP
, signal
, 11+NdbNodeBitmask::Size
, JBB
);
2334 masterAbort(signal
, ptr
);
2338 /*****************************************************************************
2340 * Master functionallity - Abort backup
2342 *****************************************************************************/
2344 Backup::masterAbort(Signal
* signal
, BackupRecordPtr ptr
)
2348 ndbout_c("************ masterAbort");
2351 ndbassert(ptr
.p
->masterRef
== reference());
2353 if(ptr
.p
->masterData
.errorCode
!= 0)
2359 if (SEND_BACKUP_COMPLETED_FLAG(ptr
.p
->flags
))
2361 BackupAbortRep
* rep
= (BackupAbortRep
*)signal
->getDataPtrSend();
2362 rep
->backupId
= ptr
.p
->backupId
;
2363 rep
->senderData
= ptr
.p
->clientData
;
2364 rep
->reason
= ptr
.p
->errorCode
;
2365 sendSignal(ptr
.p
->clientRef
, GSN_BACKUP_ABORT_REP
, signal
,
2366 BackupAbortRep::SignalLength
, JBB
);
2368 signal
->theData
[0] = NDB_LE_BackupAborted
;
2369 signal
->theData
[1] = ptr
.p
->clientRef
;
2370 signal
->theData
[2] = ptr
.p
->backupId
;
2371 signal
->theData
[3] = ptr
.p
->errorCode
;
2372 sendSignal(CMVMI_REF
, GSN_EVENT_REP
, signal
, 4, JBB
);
2374 ndbrequire(ptr
.p
->errorCode
);
2375 ptr
.p
->masterData
.errorCode
= ptr
.p
->errorCode
;
2377 AbortBackupOrd
*ord
= (AbortBackupOrd
*)signal
->getDataPtrSend();
2378 ord
->backupId
= ptr
.p
->backupId
;
2379 ord
->backupPtr
= ptr
.i
;
2380 ord
->senderData
= ptr
.i
;
2381 NodeReceiverGroup
rg(BACKUP
, ptr
.p
->nodes
);
2383 switch(ptr
.p
->masterData
.gsn
){
2384 case GSN_DEFINE_BACKUP_REQ
:
2385 ord
->requestType
= AbortBackupOrd::BackupFailure
;
2386 sendSignal(rg
, GSN_ABORT_BACKUP_ORD
, signal
,
2387 AbortBackupOrd::SignalLength
, JBB
);
2389 case GSN_CREATE_TRIG_REQ
:
2390 case GSN_START_BACKUP_REQ
:
2391 case GSN_ALTER_TRIG_REQ
:
2392 case GSN_WAIT_GCP_REQ
:
2393 case GSN_BACKUP_FRAGMENT_REQ
:
2395 ptr
.p
->stopGCP
= ptr
.p
->startGCP
+ 1;
2396 sendStopBackup(signal
, ptr
); // dropping due to error
2398 case GSN_UTIL_SEQUENCE_REQ
:
2399 case GSN_UTIL_LOCK_REQ
:
2402 case GSN_DROP_TRIG_REQ
:
2403 case GSN_STOP_BACKUP_REQ
:
2409 Backup::abort_scan(Signal
* signal
, BackupRecordPtr ptr
)
2411 AbortBackupOrd
*ord
= (AbortBackupOrd
*)signal
->getDataPtrSend();
2412 ord
->backupId
= ptr
.p
->backupId
;
2413 ord
->backupPtr
= ptr
.i
;
2414 ord
->senderData
= ptr
.i
;
2415 ord
->requestType
= AbortBackupOrd::AbortScan
;
2418 ptr
.p
->tables
.first(tabPtr
);
2419 for(; tabPtr
.i
!= RNIL
; ptr
.p
->tables
.next(tabPtr
)) {
2421 FragmentPtr fragPtr
;
2422 Array
<Fragment
> & frags
= tabPtr
.p
->fragments
;
2423 const Uint32 fragCount
= frags
.getSize();
2425 for(Uint32 i
= 0; i
<fragCount
; i
++) {
2427 tabPtr
.p
->fragments
.getPtr(fragPtr
, i
);
2428 const Uint32 nodeId
= fragPtr
.p
->node
;
2429 if(fragPtr
.p
->scanning
!= 0 && ptr
.p
->nodes
.get(nodeId
)) {
2432 const BlockReference ref
= numberToRef(BACKUP
, nodeId
);
2433 sendSignal(ref
, GSN_ABORT_BACKUP_ORD
, signal
,
2434 AbortBackupOrd::SignalLength
, JBB
);
2441 /*****************************************************************************
2443 * Slave functionallity: Define Backup
2445 *****************************************************************************/
2447 Backup::defineBackupRef(Signal
* signal
, BackupRecordPtr ptr
, Uint32 errCode
)
2450 ptr
.p
->setErrorCode(errCode
);
2454 if (ptr
.p
->ctlFilePtr
== RNIL
) {
2455 ptr
.p
->m_gsn
= GSN_DEFINE_BACKUP_REF
;
2456 ndbrequire(ptr
.p
->errorCode
!= 0);
2457 DefineBackupRef
* ref
= (DefineBackupRef
*)signal
->getDataPtrSend();
2458 ref
->backupId
= ptr
.p
->backupId
;
2459 ref
->backupPtr
= ptr
.i
;
2460 ref
->errorCode
= ptr
.p
->errorCode
;
2461 ref
->nodeId
= getOwnNodeId();
2462 sendSignal(ptr
.p
->masterRef
, GSN_DEFINE_BACKUP_REF
, signal
,
2463 DefineBackupRef::SignalLength
, JBB
);
2467 BackupFilePtr filePtr LINT_SET_PTR
;
2468 ptr
.p
->files
.getPtr(filePtr
, ptr
.p
->ctlFilePtr
);
2469 if (filePtr
.p
->m_flags
& BackupFile::BF_LCP_META
)
2472 ndbrequire(! (filePtr
.p
->m_flags
& BackupFile::BF_FILE_THREAD
));
2473 filePtr
.p
->m_flags
&= ~(Uint32
)BackupFile::BF_LCP_META
;
2474 if (filePtr
.p
->m_flags
& BackupFile::BF_OPEN
)
2476 closeFile(signal
, ptr
, filePtr
);
2481 ndbrequire(filePtr
.p
->m_flags
== 0);
2484 FragmentPtr fragPtr
;
2486 ndbrequire(ptr
.p
->tables
.first(tabPtr
));
2487 tabPtr
.p
->fragments
.getPtr(fragPtr
, 0);
2489 LcpPrepareRef
* ref
= (LcpPrepareRef
*)signal
->getDataPtrSend();
2490 ref
->senderData
= ptr
.p
->clientData
;
2491 ref
->senderRef
= reference();
2492 ref
->tableId
= tabPtr
.p
->tableId
;
2493 ref
->fragmentId
= fragPtr
.p
->fragmentId
;
2494 ref
->errorCode
= errCode
;
2495 sendSignal(ptr
.p
->masterRef
, GSN_LCP_PREPARE_REF
,
2496 signal
, LcpPrepareRef::SignalLength
, JBB
);
2500 ptr
.p
->m_gsn
= GSN_DEFINE_BACKUP_REF
;
2501 ndbrequire(ptr
.p
->errorCode
!= 0);
2503 DefineBackupRef
* ref
= (DefineBackupRef
*)signal
->getDataPtrSend();
2504 ref
->backupId
= ptr
.p
->backupId
;
2505 ref
->backupPtr
= ptr
.i
;
2506 ref
->errorCode
= ptr
.p
->errorCode
;
2507 ref
->nodeId
= getOwnNodeId();
2508 sendSignal(ptr
.p
->masterRef
, GSN_DEFINE_BACKUP_REF
, signal
,
2509 DefineBackupRef::SignalLength
, JBB
);
2513 Backup::execDEFINE_BACKUP_REQ(Signal
* signal
)
2517 DefineBackupReq
* req
= (DefineBackupReq
*)signal
->getDataPtr();
2519 BackupRecordPtr ptr LINT_SET_PTR
;
2520 const Uint32 ptrI
= req
->backupPtr
;
2521 const Uint32 backupId
= req
->backupId
;
2522 const BlockReference senderRef
= req
->senderRef
;
2524 if(senderRef
== reference()){
2526 * Signal sent from myself -> record already seized
2529 c_backupPool
.getPtr(ptr
, ptrI
);
2530 } else { // from other node
2533 dumpUsedResources();
2535 if(!c_backups
.seizeId(ptr
, ptrI
)) {
2537 ndbrequire(false); // If master has succeeded slave should succed
2541 CRASH_INSERTION((10014));
2543 ptr
.p
->m_gsn
= GSN_DEFINE_BACKUP_REQ
;
2544 ptr
.p
->slaveState
.forceState(INITIAL
);
2545 ptr
.p
->slaveState
.setState(DEFINING
);
2546 ptr
.p
->slaveData
.dropTrig
.tableId
= RNIL
;
2547 ptr
.p
->errorCode
= 0;
2548 ptr
.p
->clientRef
= req
->clientRef
;
2549 ptr
.p
->clientData
= req
->clientData
;
2550 if(senderRef
== reference())
2551 ptr
.p
->flags
= req
->flags
;
2553 ptr
.p
->flags
= req
->flags
& ~((Uint32
)0x3); /* remove waitCompleted flags
2554 * as non master should never
2557 ptr
.p
->masterRef
= senderRef
;
2558 ptr
.p
->nodes
= req
->nodes
;
2559 ptr
.p
->backupId
= backupId
;
2560 ptr
.p
->backupKey
[0] = req
->backupKey
[0];
2561 ptr
.p
->backupKey
[1] = req
->backupKey
[1];
2562 ptr
.p
->backupDataLen
= req
->backupDataLen
;
2563 ptr
.p
->masterData
.errorCode
= 0;
2564 ptr
.p
->noOfBytes
= 0;
2565 ptr
.p
->noOfRecords
= 0;
2566 ptr
.p
->noOfLogBytes
= 0;
2567 ptr
.p
->noOfLogRecords
= 0;
2569 ptr
.p
->startGCP
= 0;
2575 BackupFilePtr files
[3];
2576 Uint32 noOfPages
[] = {
2577 NO_OF_PAGES_META_FILE
,
2581 const Uint32 maxInsert
[] = {
2582 MAX_WORDS_META_FILE
,
2584 16*3000, // Max 16 tuples
2586 Uint32 minWrite
[] = {
2591 Uint32 maxWrite
[] = {
2597 minWrite
[1] = c_defaults
.m_minWriteSize
;
2598 maxWrite
[1] = c_defaults
.m_maxWriteSize
;
2599 noOfPages
[1] = (c_defaults
.m_logBufferSize
+ sizeof(Page32
) - 1) /
2601 minWrite
[2] = c_defaults
.m_minWriteSize
;
2602 maxWrite
[2] = c_defaults
.m_maxWriteSize
;
2603 noOfPages
[2] = (c_defaults
.m_dataBufferSize
+ sizeof(Page32
) - 1) /
2606 if (ptr
.p
->is_lcp())
2608 noOfPages
[2] = (c_defaults
.m_lcp_buffer_size
+ sizeof(Page32
) - 1) /
2612 ptr
.p
->ctlFilePtr
= ptr
.p
->logFilePtr
= ptr
.p
->dataFilePtr
= RNIL
;
2614 for(Uint32 i
= 0; i
<3; i
++) {
2616 if(ptr
.p
->is_lcp() && i
!= 2)
2621 if(!ptr
.p
->files
.seize(files
[i
])) {
2623 defineBackupRef(signal
, ptr
,
2624 DefineBackupRef::FailedToAllocateFileRecord
);
2628 files
[i
].p
->tableId
= RNIL
;
2629 files
[i
].p
->backupPtr
= ptr
.i
;
2630 files
[i
].p
->filePointer
= RNIL
;
2631 files
[i
].p
->m_flags
= 0;
2632 files
[i
].p
->errorCode
= 0;
2634 if(ERROR_INSERTED(10035) || files
[i
].p
->pages
.seize(noOfPages
[i
]) == false)
2637 DEBUG_OUT("Failed to seize " << noOfPages
[i
] << " pages");
2638 defineBackupRef(signal
, ptr
, DefineBackupRef::FailedToAllocateBuffers
);
2642 files
[i
].p
->pages
.getPtr(pagePtr
, 0);
2644 const char * msg
= files
[i
].p
->
2645 operation
.dataBuffer
.setup((Uint32
*)pagePtr
.p
,
2646 noOfPages
[i
] * (sizeof(Page32
) >> 2),
2653 defineBackupRef(signal
, ptr
, DefineBackupRef::FailedToSetupFsBuffers
);
2659 files
[i
].p
->fileType
= BackupFormat::CTL_FILE
;
2660 ptr
.p
->ctlFilePtr
= files
[i
].i
;
2663 files
[i
].p
->fileType
= BackupFormat::LOG_FILE
;
2664 ptr
.p
->logFilePtr
= files
[i
].i
;
2667 files
[i
].p
->fileType
= BackupFormat::DATA_FILE
;
2668 ptr
.p
->dataFilePtr
= files
[i
].i
;
2672 if (!verifyNodesAlive(ptr
, ptr
.p
->nodes
)) {
2674 defineBackupRef(signal
, ptr
, DefineBackupRef::Undefined
);
2677 if (ERROR_INSERTED(10027)) {
2679 defineBackupRef(signal
, ptr
, 327);
2683 if(ptr
.p
->backupDataLen
== 0) {
2685 backupAllData(signal
, ptr
);
2692 getFragmentInfoDone(signal
, ptr
);
2703 Backup::backupAllData(Signal
* signal
, BackupRecordPtr ptr
)
2706 * Get all tables from dict
2708 ListTablesReq
* req
= (ListTablesReq
*)signal
->getDataPtrSend();
2709 req
->senderRef
= reference();
2710 req
->senderData
= ptr
.i
;
2711 req
->requestData
= 0;
2712 sendSignal(DBDICT_REF
, GSN_LIST_TABLES_REQ
, signal
,
2713 ListTablesReq::SignalLength
, JBB
);
2717 Backup::execLIST_TABLES_CONF(Signal
* signal
)
2721 ListTablesConf
* conf
= (ListTablesConf
*)signal
->getDataPtr();
2723 BackupRecordPtr ptr LINT_SET_PTR
;
2724 c_backupPool
.getPtr(ptr
, conf
->senderData
);
2726 const Uint32 len
= signal
->length() - ListTablesConf::HeaderLength
;
2727 for(unsigned int i
= 0; i
<len
; i
++) {
2729 Uint32 tableId
= ListTablesConf::getTableId(conf
->tableData
[i
]);
2730 Uint32 tableType
= ListTablesConf::getTableType(conf
->tableData
[i
]);
2731 Uint32 state
= ListTablesConf::getTableState(conf
->tableData
[i
]);
2733 if (! (DictTabInfo::isTable(tableType
) ||
2734 DictTabInfo::isIndex(tableType
) ||
2735 DictTabInfo::isFilegroup(tableType
) ||
2736 DictTabInfo::isFile(tableType
)))
2742 if (state
!= DictTabInfo::StateOnline
)
2749 ptr
.p
->tables
.seize(tabPtr
);
2750 if(tabPtr
.i
== RNIL
) {
2752 defineBackupRef(signal
, ptr
, DefineBackupRef::FailedToAllocateTables
);
2755 tabPtr
.p
->tableId
= tableId
;
2756 tabPtr
.p
->tableType
= tableType
;
2759 if(len
== ListTablesConf::DataLength
) {
2768 * All tables fetched
2770 openFiles(signal
, ptr
);
2774 Backup::openFiles(Signal
* signal
, BackupRecordPtr ptr
)
2778 BackupFilePtr filePtr LINT_SET_PTR
;
2780 FsOpenReq
* req
= (FsOpenReq
*)signal
->getDataPtrSend();
2781 req
->userReference
= reference();
2783 FsOpenReq::OM_WRITEONLY
|
2784 FsOpenReq::OM_TRUNCATE
|
2785 FsOpenReq::OM_CREATE
|
2786 FsOpenReq::OM_APPEND
|
2787 FsOpenReq::OM_AUTOSYNC
;
2788 FsOpenReq::v2_setCount(req
->fileNumber
, 0xFFFFFFFF);
2789 req
->auto_sync_size
= c_defaults
.m_disk_synch_size
;
2793 c_backupFilePool
.getPtr(filePtr
, ptr
.p
->ctlFilePtr
);
2794 filePtr
.p
->m_flags
|= BackupFile::BF_OPENING
;
2796 req
->userPointer
= filePtr
.i
;
2797 FsOpenReq::setVersion(req
->fileNumber
, 2);
2798 FsOpenReq::setSuffix(req
->fileNumber
, FsOpenReq::S_CTL
);
2799 FsOpenReq::v2_setSequence(req
->fileNumber
, ptr
.p
->backupId
);
2800 FsOpenReq::v2_setNodeId(req
->fileNumber
, getOwnNodeId());
2801 sendSignal(NDBFS_REF
, GSN_FSOPENREQ
, signal
, FsOpenReq::SignalLength
, JBA
);
2806 c_backupFilePool
.getPtr(filePtr
, ptr
.p
->logFilePtr
);
2807 filePtr
.p
->m_flags
|= BackupFile::BF_OPENING
;
2809 req
->userPointer
= filePtr
.i
;
2810 FsOpenReq::setVersion(req
->fileNumber
, 2);
2811 FsOpenReq::setSuffix(req
->fileNumber
, FsOpenReq::S_LOG
);
2812 FsOpenReq::v2_setSequence(req
->fileNumber
, ptr
.p
->backupId
);
2813 FsOpenReq::v2_setNodeId(req
->fileNumber
, getOwnNodeId());
2814 sendSignal(NDBFS_REF
, GSN_FSOPENREQ
, signal
, FsOpenReq::SignalLength
, JBA
);
2819 c_backupFilePool
.getPtr(filePtr
, ptr
.p
->dataFilePtr
);
2820 filePtr
.p
->m_flags
|= BackupFile::BF_OPENING
;
2822 if (c_defaults
.m_o_direct
)
2823 req
->fileFlags
|= FsOpenReq::OM_DIRECT
;
2824 req
->userPointer
= filePtr
.i
;
2825 FsOpenReq::setVersion(req
->fileNumber
, 2);
2826 FsOpenReq::setSuffix(req
->fileNumber
, FsOpenReq::S_DATA
);
2827 FsOpenReq::v2_setSequence(req
->fileNumber
, ptr
.p
->backupId
);
2828 FsOpenReq::v2_setNodeId(req
->fileNumber
, getOwnNodeId());
2829 FsOpenReq::v2_setCount(req
->fileNumber
, 0);
2830 sendSignal(NDBFS_REF
, GSN_FSOPENREQ
, signal
, FsOpenReq::SignalLength
, JBA
);
2834 Backup::execFSOPENREF(Signal
* signal
)
2838 FsRef
* ref
= (FsRef
*)signal
->getDataPtr();
2840 const Uint32 userPtr
= ref
->userPointer
;
2842 BackupFilePtr filePtr LINT_SET_PTR
;
2843 c_backupFilePool
.getPtr(filePtr
, userPtr
);
2845 BackupRecordPtr ptr LINT_SET_PTR
;
2846 c_backupPool
.getPtr(ptr
, filePtr
.p
->backupPtr
);
2847 ptr
.p
->setErrorCode(ref
->errorCode
);
2848 openFilesReply(signal
, ptr
, filePtr
);
2852 Backup::execFSOPENCONF(Signal
* signal
)
2856 FsConf
* conf
= (FsConf
*)signal
->getDataPtr();
2858 const Uint32 userPtr
= conf
->userPointer
;
2859 const Uint32 filePointer
= conf
->filePointer
;
2861 BackupFilePtr filePtr LINT_SET_PTR
;
2862 c_backupFilePool
.getPtr(filePtr
, userPtr
);
2863 filePtr
.p
->filePointer
= filePointer
;
2865 BackupRecordPtr ptr LINT_SET_PTR
;
2866 c_backupPool
.getPtr(ptr
, filePtr
.p
->backupPtr
);
2868 ndbrequire(! (filePtr
.p
->m_flags
& BackupFile::BF_OPEN
));
2869 filePtr
.p
->m_flags
|= BackupFile::BF_OPEN
;
2870 openFilesReply(signal
, ptr
, filePtr
);
2874 Backup::openFilesReply(Signal
* signal
,
2875 BackupRecordPtr ptr
, BackupFilePtr filePtr
)
2880 * Mark files as "opened"
2882 ndbrequire(filePtr
.p
->m_flags
& BackupFile::BF_OPENING
);
2883 filePtr
.p
->m_flags
&= ~(Uint32
)BackupFile::BF_OPENING
;
2884 filePtr
.p
->m_flags
|= BackupFile::BF_OPEN
;
2886 * Check if all files have recived open_reply
2888 for(ptr
.p
->files
.first(filePtr
); filePtr
.i
!=RNIL
;ptr
.p
->files
.next(filePtr
))
2891 if(filePtr
.p
->m_flags
& BackupFile::BF_OPENING
) {
2898 * Did open succeed for all files
2900 if(ptr
.p
->checkError()) {
2902 defineBackupRef(signal
, ptr
);
2906 if(!ptr
.p
->is_lcp())
2909 * Insert file headers
2911 ptr
.p
->files
.getPtr(filePtr
, ptr
.p
->ctlFilePtr
);
2912 if(!insertFileHeader(BackupFormat::CTL_FILE
, ptr
.p
, filePtr
.p
)) {
2914 defineBackupRef(signal
, ptr
, DefineBackupRef::FailedInsertFileHeader
);
2918 ptr
.p
->files
.getPtr(filePtr
, ptr
.p
->logFilePtr
);
2919 if(!insertFileHeader(BackupFormat::LOG_FILE
, ptr
.p
, filePtr
.p
)) {
2921 defineBackupRef(signal
, ptr
, DefineBackupRef::FailedInsertFileHeader
);
2925 ptr
.p
->files
.getPtr(filePtr
, ptr
.p
->dataFilePtr
);
2926 if(!insertFileHeader(BackupFormat::DATA_FILE
, ptr
.p
, filePtr
.p
)) {
2928 defineBackupRef(signal
, ptr
, DefineBackupRef::FailedInsertFileHeader
);
2934 ptr
.p
->files
.getPtr(filePtr
, ptr
.p
->dataFilePtr
);
2935 if(!insertFileHeader(BackupFormat::LCP_FILE
, ptr
.p
, filePtr
.p
)) {
2937 defineBackupRef(signal
, ptr
, DefineBackupRef::FailedInsertFileHeader
);
2941 ptr
.p
->ctlFilePtr
= ptr
.p
->dataFilePtr
;
2945 * Start CTL file thread
2947 if (!ptr
.p
->is_lcp())
2950 ptr
.p
->files
.getPtr(filePtr
, ptr
.p
->ctlFilePtr
);
2951 filePtr
.p
->m_flags
|= BackupFile::BF_FILE_THREAD
;
2953 signal
->theData
[0] = BackupContinueB::START_FILE_THREAD
;
2954 signal
->theData
[1] = filePtr
.i
;
2955 sendSignalWithDelay(BACKUP_REF
, GSN_CONTINUEB
, signal
, 100, 2);
2960 filePtr
.p
->m_flags
|= BackupFile::BF_LCP_META
;
2964 * Insert table list in ctl file
2966 FsBuffer
& buf
= filePtr
.p
->operation
.dataBuffer
;
2969 (sizeof(BackupFormat::CtlFile::TableList
) >> 2) +
2970 ptr
.p
->tables
.count() - 1;
2973 ndbrequire(sz
< buf
.getMaxWrite());
2974 if(!buf
.getWritePtr(&dst
, sz
)) {
2976 defineBackupRef(signal
, ptr
, DefineBackupRef::FailedInsertTableList
);
2980 BackupFormat::CtlFile::TableList
* tl
=
2981 (BackupFormat::CtlFile::TableList
*)dst
;
2982 tl
->SectionType
= htonl(BackupFormat::TABLE_LIST
);
2983 tl
->SectionLength
= htonl(sz
);
2987 for(ptr
.p
->tables
.first(tabPtr
);
2989 ptr
.p
->tables
.next(tabPtr
)){
2991 tl
->TableIds
[count
] = htonl(tabPtr
.p
->tableId
);
2995 buf
.updateWritePtr(sz
);
2998 * Start getting table definition data
3000 ndbrequire(ptr
.p
->tables
.first(tabPtr
));
3002 signal
->theData
[0] = BackupContinueB::BUFFER_FULL_META
;
3003 signal
->theData
[1] = ptr
.i
;
3004 signal
->theData
[2] = tabPtr
.i
;
3005 sendSignalWithDelay(BACKUP_REF
, GSN_CONTINUEB
, signal
, 100, 3);
3010 Backup::insertFileHeader(BackupFormat::FileType ft
,
3011 BackupRecord
* ptrP
,
3012 BackupFile
* filePtrP
){
3013 FsBuffer
& buf
= filePtrP
->operation
.dataBuffer
;
3015 const Uint32 sz
= sizeof(BackupFormat::FileHeader
) >> 2;
3018 ndbrequire(sz
< buf
.getMaxWrite());
3019 if(!buf
.getWritePtr(&dst
, sz
)) {
3024 BackupFormat::FileHeader
* header
= (BackupFormat::FileHeader
*)dst
;
3025 ndbrequire(sizeof(header
->Magic
) == sizeof(BACKUP_MAGIC
));
3026 memcpy(header
->Magic
, BACKUP_MAGIC
, sizeof(BACKUP_MAGIC
));
3027 header
->NdbVersion
= htonl(NDB_VERSION
);
3028 header
->SectionType
= htonl(BackupFormat::FILE_HEADER
);
3029 header
->SectionLength
= htonl(sz
- 3);
3030 header
->FileType
= htonl(ft
);
3031 header
->BackupId
= htonl(ptrP
->backupId
);
3032 header
->BackupKey_0
= htonl(ptrP
->backupKey
[0]);
3033 header
->BackupKey_1
= htonl(ptrP
->backupKey
[1]);
3034 header
->ByteOrder
= 0x12345678;
3036 buf
.updateWritePtr(sz
);
3041 Backup::execGET_TABINFOREF(Signal
* signal
)
3043 GetTabInfoRef
* ref
= (GetTabInfoRef
*)signal
->getDataPtr();
3045 const Uint32 senderData
= ref
->senderData
;
3046 BackupRecordPtr ptr LINT_SET_PTR
;
3047 c_backupPool
.getPtr(ptr
, senderData
);
3049 BackupFilePtr filePtr LINT_SET_PTR
;
3050 ptr
.p
->files
.getPtr(filePtr
, ptr
.p
->ctlFilePtr
);
3051 filePtr
.p
->m_flags
&= ~(Uint32
)BackupFile::BF_FILE_THREAD
;
3053 defineBackupRef(signal
, ptr
, ref
->errorCode
);
3057 Backup::execGET_TABINFO_CONF(Signal
* signal
)
3061 if(!assembleFragments(signal
)) {
3066 GetTabInfoConf
* const conf
= (GetTabInfoConf
*)signal
->getDataPtr();
3067 //const Uint32 senderRef = info->senderRef;
3068 const Uint32 len
= conf
->totalLen
;
3069 const Uint32 senderData
= conf
->senderData
;
3070 const Uint32 tableType
= conf
->tableType
;
3071 const Uint32 tableId
= conf
->tableId
;
3073 BackupRecordPtr ptr LINT_SET_PTR
;
3074 c_backupPool
.getPtr(ptr
, senderData
);
3076 SegmentedSectionPtr dictTabInfoPtr
;
3077 signal
->getSection(dictTabInfoPtr
, GetTabInfoConf::DICT_TAB_INFO
);
3078 ndbrequire(dictTabInfoPtr
.sz
== len
);
3081 ndbrequire(findTable(ptr
, tabPtr
, tableId
));
3083 BackupFilePtr filePtr LINT_SET_PTR
;
3084 ptr
.p
->files
.getPtr(filePtr
, ptr
.p
->ctlFilePtr
);
3085 FsBuffer
& buf
= filePtr
.p
->operation
.dataBuffer
;
3087 { // Write into ctl file
3088 Uint32 dstLen
= len
+ 3;
3089 if(!buf
.getWritePtr(&dst
, dstLen
)) {
3092 ptr
.p
->setErrorCode(DefineBackupRef::FailedAllocateTableMem
);
3093 releaseSections(signal
);
3094 defineBackupRef(signal
, ptr
);
3100 BackupFormat::CtlFile::TableDescription
* desc
=
3101 (BackupFormat::CtlFile::TableDescription
*)dst
;
3102 desc
->SectionType
= htonl(BackupFormat::TABLE_DESCRIPTION
);
3103 desc
->SectionLength
= htonl(len
+ 3);
3104 desc
->TableType
= htonl(tableType
);
3107 copy(dst
, dictTabInfoPtr
);
3108 buf
.updateWritePtr(dstLen
);
3112 releaseSections(signal
);
3114 if(ptr
.p
->checkError()) {
3116 defineBackupRef(signal
, ptr
);
3120 if (!DictTabInfo::isTable(tabPtr
.p
->tableType
))
3124 TablePtr tmp
= tabPtr
;
3125 ptr
.p
->tables
.next(tabPtr
);
3126 ptr
.p
->tables
.release(tmp
);
3130 if (!parseTableDescription(signal
, ptr
, tabPtr
, dst
, len
))
3133 defineBackupRef(signal
, ptr
);
3137 if(!ptr
.p
->is_lcp())
3140 signal
->theData
[0] = tabPtr
.p
->tableId
;
3141 signal
->theData
[1] = 1; // lock
3142 EXECUTE_DIRECT(DBDICT
, GSN_BACKUP_FRAGMENT_REQ
, signal
, 2);
3145 ptr
.p
->tables
.next(tabPtr
);
3148 if(tabPtr
.i
== RNIL
)
3151 * Done with all tables...
3157 lcp_open_file_done(signal
, ptr
);
3161 ndbrequire(ptr
.p
->tables
.first(tabPtr
));
3162 DihFragCountReq
* const req
= (DihFragCountReq
*)signal
->getDataPtrSend();
3163 req
->m_connectionData
= RNIL
;
3164 req
->m_tableRef
= tabPtr
.p
->tableId
;
3165 req
->m_senderData
= ptr
.i
;
3166 sendSignal(DBDIH_REF
, GSN_DI_FCOUNTREQ
, signal
,
3167 DihFragCountReq::SignalLength
, JBB
);
3172 * Fetch next table...
3174 signal
->theData
[0] = BackupContinueB::BUFFER_FULL_META
;
3175 signal
->theData
[1] = ptr
.i
;
3176 signal
->theData
[2] = tabPtr
.i
;
3177 sendSignalWithDelay(BACKUP_REF
, GSN_CONTINUEB
, signal
, 100, 3);
3182 Backup::parseTableDescription(Signal
* signal
,
3183 BackupRecordPtr ptr
,
3185 const Uint32
* tabdescptr
,
3188 SimplePropertiesLinearReader
it(tabdescptr
, len
);
3192 DictTabInfo::Table tmpTab
; tmpTab
.init();
3193 SimpleProperties::UnpackStatus stat
;
3194 stat
= SimpleProperties::unpack(it
, &tmpTab
,
3195 DictTabInfo::TableMapping
,
3196 DictTabInfo::TableMappingSize
,
3198 ndbrequire(stat
== SimpleProperties::Break
);
3200 bool lcp
= ptr
.p
->is_lcp();
3202 ndbrequire(tabPtr
.p
->tableId
== tmpTab
.TableId
);
3203 ndbrequire(lcp
|| (tabPtr
.p
->tableType
== tmpTab
.TableType
));
3206 * LCP should not save disk attributes but only mem attributes
3210 * Initialize table object
3212 tabPtr
.p
->noOfRecords
= 0;
3213 tabPtr
.p
->schemaVersion
= tmpTab
.TableVersion
;
3214 tabPtr
.p
->noOfAttributes
= tmpTab
.NoOfAttributes
;
3215 tabPtr
.p
->noOfNull
= 0;
3216 tabPtr
.p
->noOfVariable
= 0; // Computed while iterating over attribs
3217 tabPtr
.p
->sz_FixedAttributes
= 0; // Computed while iterating over attribs
3218 tabPtr
.p
->triggerIds
[0] = ILLEGAL_TRIGGER_ID
;
3219 tabPtr
.p
->triggerIds
[1] = ILLEGAL_TRIGGER_ID
;
3220 tabPtr
.p
->triggerIds
[2] = ILLEGAL_TRIGGER_ID
;
3221 tabPtr
.p
->triggerAllocated
[0] = false;
3222 tabPtr
.p
->triggerAllocated
[1] = false;
3223 tabPtr
.p
->triggerAllocated
[2] = false;
3226 const Uint32 count
= tabPtr
.p
->noOfAttributes
;
3227 for(Uint32 i
= 0; i
<count
; i
++) {
3229 DictTabInfo::Attribute tmp
; tmp
.init();
3230 stat
= SimpleProperties::unpack(it
, &tmp
,
3231 DictTabInfo::AttributeMapping
,
3232 DictTabInfo::AttributeMappingSize
,
3235 ndbrequire(stat
== SimpleProperties::Break
);
3236 it
.next(); // Move Past EndOfAttribute
3238 const Uint32 arr
= tmp
.AttributeArraySize
;
3239 const Uint32 sz
= 1 << tmp
.AttributeSize
;
3240 const Uint32 sz32
= (sz
* arr
+ 31) >> 5;
3242 if(lcp
&& tmp
.AttributeStorageType
== NDB_STORAGETYPE_DISK
)
3248 AttributePtr attrPtr
;
3249 if(!tabPtr
.p
->attributes
.seize(attrPtr
))
3252 ptr
.p
->setErrorCode(DefineBackupRef::FailedToAllocateAttributeRecord
);
3256 attrPtr
.p
->data
.m_flags
= 0;
3257 attrPtr
.p
->data
.attrId
= tmp
.AttributeId
;
3259 attrPtr
.p
->data
.m_flags
|=
3260 (tmp
.AttributeNullableFlag
? Attribute::COL_NULLABLE
: 0);
3261 attrPtr
.p
->data
.m_flags
|= (tmp
.AttributeArrayType
== NDB_ARRAYTYPE_FIXED
)?
3262 Attribute::COL_FIXED
: 0;
3263 attrPtr
.p
->data
.sz32
= sz32
;
3266 * 1) Fixed non-nullable
3269 if(attrPtr
.p
->data
.m_flags
& Attribute::COL_FIXED
&&
3270 !(attrPtr
.p
->data
.m_flags
& Attribute::COL_NULLABLE
)) {
3272 attrPtr
.p
->data
.offset
= tabPtr
.p
->sz_FixedAttributes
;
3273 tabPtr
.p
->sz_FixedAttributes
+= sz32
;
3275 attrPtr
.p
->data
.offset
= ~0;
3276 tabPtr
.p
->noOfVariable
++;
3286 * Remove all disk attributes
3288 tabPtr
.p
->noOfAttributes
-= disk
;
3291 AttributePtr attrPtr
;
3292 ndbrequire(tabPtr
.p
->attributes
.seize(attrPtr
));
3295 attrPtr
.p
->data
.attrId
= AttributeHeader::DISK_REF
;
3296 attrPtr
.p
->data
.m_flags
= Attribute::COL_FIXED
;
3297 attrPtr
.p
->data
.sz32
= 2;
3299 attrPtr
.p
->data
.offset
= tabPtr
.p
->sz_FixedAttributes
;
3300 tabPtr
.p
->sz_FixedAttributes
+= sz32
;
3301 tabPtr
.p
->noOfAttributes
++;
3306 AttributePtr attrPtr
;
3307 ndbrequire(tabPtr
.p
->attributes
.seize(attrPtr
));
3310 attrPtr
.p
->data
.attrId
= AttributeHeader::ROWID
;
3311 attrPtr
.p
->data
.m_flags
= Attribute::COL_FIXED
;
3312 attrPtr
.p
->data
.sz32
= 2;
3314 attrPtr
.p
->data
.offset
= tabPtr
.p
->sz_FixedAttributes
;
3315 tabPtr
.p
->sz_FixedAttributes
+= sz32
;
3316 tabPtr
.p
->noOfAttributes
++;
3319 if (tmpTab
.RowGCIFlag
)
3321 AttributePtr attrPtr
;
3322 ndbrequire(tabPtr
.p
->attributes
.seize(attrPtr
));
3325 attrPtr
.p
->data
.attrId
= AttributeHeader::ROW_GCI
;
3326 attrPtr
.p
->data
.m_flags
= Attribute::COL_FIXED
;
3327 attrPtr
.p
->data
.sz32
= 2;
3329 attrPtr
.p
->data
.offset
= tabPtr
.p
->sz_FixedAttributes
;
3330 tabPtr
.p
->sz_FixedAttributes
+= sz32
;
3331 tabPtr
.p
->noOfAttributes
++;
3338 Backup::execDI_FCOUNTCONF(Signal
* signal
)
3341 DihFragCountConf
* const conf
= (DihFragCountConf
*)signal
->getDataPtr();
3342 const Uint32 userPtr
= conf
->m_connectionData
;
3343 const Uint32 fragCount
= conf
->m_fragmentCount
;
3344 const Uint32 tableId
= conf
->m_tableRef
;
3345 const Uint32 senderData
= conf
->m_senderData
;
3347 ndbrequire(userPtr
== RNIL
&& signal
->length() == 5);
3349 BackupRecordPtr ptr LINT_SET_PTR
;
3350 c_backupPool
.getPtr(ptr
, senderData
);
3353 ndbrequire(findTable(ptr
, tabPtr
, tableId
));
3355 ndbrequire(tabPtr
.p
->fragments
.seize(fragCount
) != false);
3356 for(Uint32 i
= 0; i
<fragCount
; i
++) {
3358 FragmentPtr fragPtr
;
3359 tabPtr
.p
->fragments
.getPtr(fragPtr
, i
);
3360 fragPtr
.p
->scanned
= 0;
3361 fragPtr
.p
->scanning
= 0;
3362 fragPtr
.p
->tableId
= tableId
;
3363 fragPtr
.p
->fragmentId
= i
;
3364 fragPtr
.p
->node
= 0;
3370 if(ptr
.p
->tables
.next(tabPtr
)) {
3372 DihFragCountReq
* const req
= (DihFragCountReq
*)signal
->getDataPtrSend();
3373 req
->m_connectionData
= RNIL
;
3374 req
->m_tableRef
= tabPtr
.p
->tableId
;
3375 req
->m_senderData
= ptr
.i
;
3376 sendSignal(DBDIH_REF
, GSN_DI_FCOUNTREQ
, signal
,
3377 DihFragCountReq::SignalLength
, JBB
);
3381 ptr
.p
->tables
.first(tabPtr
);
3382 getFragmentInfo(signal
, ptr
, tabPtr
, 0);
3386 Backup::getFragmentInfo(Signal
* signal
,
3387 BackupRecordPtr ptr
, TablePtr tabPtr
, Uint32 fragNo
)
3391 for(; tabPtr
.i
!= RNIL
; ptr
.p
->tables
.next(tabPtr
)) {
3393 const Uint32 fragCount
= tabPtr
.p
->fragments
.getSize();
3394 for(; fragNo
< fragCount
; fragNo
++) {
3396 FragmentPtr fragPtr
;
3397 tabPtr
.p
->fragments
.getPtr(fragPtr
, fragNo
);
3399 if(fragPtr
.p
->scanned
== 0 && fragPtr
.p
->scanning
== 0) {
3401 signal
->theData
[0] = RNIL
;
3402 signal
->theData
[1] = ptr
.i
;
3403 signal
->theData
[2] = tabPtr
.p
->tableId
;
3404 signal
->theData
[3] = fragNo
;
3405 sendSignal(DBDIH_REF
, GSN_DIGETPRIMREQ
, signal
, 4, JBB
);
3412 getFragmentInfoDone(signal
, ptr
);
3416 Backup::execDIGETPRIMCONF(Signal
* signal
)
3420 const Uint32 userPtr
= signal
->theData
[0];
3421 const Uint32 senderData
= signal
->theData
[1];
3422 const Uint32 nodeCount
= signal
->theData
[6];
3423 const Uint32 tableId
= signal
->theData
[7];
3424 const Uint32 fragNo
= signal
->theData
[8];
3426 ndbrequire(userPtr
== RNIL
&& signal
->length() == 9);
3427 ndbrequire(nodeCount
> 0 && nodeCount
<= MAX_REPLICAS
);
3429 BackupRecordPtr ptr LINT_SET_PTR
;
3430 c_backupPool
.getPtr(ptr
, senderData
);
3433 ndbrequire(findTable(ptr
, tabPtr
, tableId
));
3435 FragmentPtr fragPtr
;
3436 tabPtr
.p
->fragments
.getPtr(fragPtr
, fragNo
);
3438 fragPtr
.p
->node
= signal
->theData
[2];
3440 getFragmentInfo(signal
, ptr
, tabPtr
, fragNo
+ 1);
3444 Backup::getFragmentInfoDone(Signal
* signal
, BackupRecordPtr ptr
)
3446 ptr
.p
->m_gsn
= GSN_DEFINE_BACKUP_CONF
;
3447 ptr
.p
->slaveState
.setState(DEFINED
);
3448 DefineBackupConf
* conf
= (DefineBackupConf
*)signal
->getDataPtr();
3449 conf
->backupPtr
= ptr
.i
;
3450 conf
->backupId
= ptr
.p
->backupId
;
3451 sendSignal(ptr
.p
->masterRef
, GSN_DEFINE_BACKUP_CONF
, signal
,
3452 DefineBackupConf::SignalLength
, JBB
);
3456 /*****************************************************************************
3458 * Slave functionallity: Start backup
3460 *****************************************************************************/
3462 Backup::execSTART_BACKUP_REQ(Signal
* signal
)
3466 CRASH_INSERTION((10015));
3468 StartBackupReq
* req
= (StartBackupReq
*)signal
->getDataPtr();
3469 const Uint32 ptrI
= req
->backupPtr
;
3471 BackupRecordPtr ptr LINT_SET_PTR
;
3472 c_backupPool
.getPtr(ptr
, ptrI
);
3474 ptr
.p
->slaveState
.setState(STARTED
);
3475 ptr
.p
->m_gsn
= GSN_START_BACKUP_REQ
;
3478 * Start file threads...
3480 BackupFilePtr filePtr
;
3481 for(ptr
.p
->files
.first(filePtr
); filePtr
.i
!=RNIL
;ptr
.p
->files
.next(filePtr
))
3484 if(! (filePtr
.p
->m_flags
& BackupFile::BF_FILE_THREAD
))
3487 filePtr
.p
->m_flags
|= BackupFile::BF_FILE_THREAD
;
3488 signal
->theData
[0] = BackupContinueB::START_FILE_THREAD
;
3489 signal
->theData
[1] = filePtr
.i
;
3490 sendSignalWithDelay(BACKUP_REF
, GSN_CONTINUEB
, signal
, 100, 2);
3495 * Tell DBTUP to create triggers
3498 ndbrequire(ptr
.p
->tables
.first(tabPtr
));
3499 sendCreateTrig(signal
, ptr
, tabPtr
);
3502 /*****************************************************************************
3504 * Slave functionallity: Backup fragment
3506 *****************************************************************************/
3508 Backup::execBACKUP_FRAGMENT_REQ(Signal
* signal
)
3511 BackupFragmentReq
* req
= (BackupFragmentReq
*)signal
->getDataPtr();
3513 CRASH_INSERTION((10016));
3515 const Uint32 ptrI
= req
->backupPtr
;
3516 //const Uint32 backupId = req->backupId;
3517 const Uint32 tableId
= req
->tableId
;
3518 const Uint32 fragNo
= req
->fragmentNo
;
3519 const Uint32 count
= req
->count
;
3524 BackupRecordPtr ptr LINT_SET_PTR
;
3525 c_backupPool
.getPtr(ptr
, ptrI
);
3527 ptr
.p
->slaveState
.setState(SCANNING
);
3528 ptr
.p
->m_gsn
= GSN_BACKUP_FRAGMENT_REQ
;
3533 BackupFilePtr filePtr LINT_SET_PTR
;
3534 c_backupFilePool
.getPtr(filePtr
, ptr
.p
->dataFilePtr
);
3536 ndbrequire(filePtr
.p
->backupPtr
== ptrI
);
3537 ndbrequire(filePtr
.p
->m_flags
==
3538 (BackupFile::BF_OPEN
| BackupFile::BF_FILE_THREAD
));
3544 ndbrequire(findTable(ptr
, tabPtr
, tableId
));
3549 FragmentPtr fragPtr
;
3550 tabPtr
.p
->fragments
.getPtr(fragPtr
, fragNo
);
3552 ndbrequire(fragPtr
.p
->scanned
== 0);
3553 ndbrequire(fragPtr
.p
->scanning
== 0 ||
3554 refToNode(ptr
.p
->masterRef
) == getOwnNodeId());
3559 if(filePtr
.p
->tableId
!= tableId
) {
3561 filePtr
.p
->operation
.init(tabPtr
);
3562 filePtr
.p
->tableId
= tableId
;
3566 * Check for space in buffer
3568 if(!filePtr
.p
->operation
.newFragment(tableId
, fragPtr
.p
->fragmentId
)) {
3570 req
->count
= count
+ 1;
3571 sendSignalWithDelay(BACKUP_REF
, GSN_BACKUP_FRAGMENT_REQ
, signal
, 50,
3573 ptr
.p
->slaveState
.setState(STARTED
);
3578 * Mark things as "in use"
3580 fragPtr
.p
->scanning
= 1;
3581 filePtr
.p
->fragmentNo
= fragPtr
.p
->fragmentId
;
3587 filePtr
.p
->m_flags
|= BackupFile::BF_SCAN_THREAD
;
3589 Table
& table
= * tabPtr
.p
;
3590 ScanFragReq
* req
= (ScanFragReq
*)signal
->getDataPtrSend();
3591 const Uint32 parallelism
= 16;
3592 const Uint32 attrLen
= 5 + table
.noOfAttributes
;
3594 req
->senderData
= filePtr
.i
;
3595 req
->resultRef
= reference();
3596 req
->schemaVersion
= table
.schemaVersion
;
3597 req
->fragmentNoKeyLen
= fragPtr
.p
->fragmentId
;
3598 req
->requestInfo
= 0;
3599 req
->savePointId
= 0;
3600 req
->tableId
= table
.tableId
;
3601 ScanFragReq::setReadCommittedFlag(req
->requestInfo
, 1);
3602 ScanFragReq::setLockMode(req
->requestInfo
, 0);
3603 ScanFragReq::setHoldLockFlag(req
->requestInfo
, 0);
3604 ScanFragReq::setKeyinfoFlag(req
->requestInfo
, 0);
3605 ScanFragReq::setAttrLen(req
->requestInfo
,attrLen
);
3606 ScanFragReq::setTupScanFlag(req
->requestInfo
, 1);
3607 if (ptr
.p
->is_lcp())
3609 ScanFragReq::setScanPrio(req
->requestInfo
, 1);
3610 ScanFragReq::setNoDiskFlag(req
->requestInfo
, 1);
3611 ScanFragReq::setLcpScanFlag(req
->requestInfo
, 1);
3614 req
->transId2
= (BACKUP
<< 20) + (getOwnNodeId() << 8);
3615 req
->clientOpPtr
= filePtr
.i
;
3616 req
->batch_size_rows
= parallelism
;
3617 req
->batch_size_bytes
= 0;
3618 sendSignal(DBLQH_REF
, GSN_SCAN_FRAGREQ
, signal
,
3619 ScanFragReq::SignalLength
, JBB
);
3621 signal
->theData
[0] = filePtr
.i
;
3622 signal
->theData
[1] = 0;
3623 signal
->theData
[2] = (BACKUP
<< 20) + (getOwnNodeId() << 8);
3626 signal
->theData
[3] = table
.noOfAttributes
;
3627 signal
->theData
[4] = 0;
3628 signal
->theData
[5] = 0;
3629 signal
->theData
[6] = 0;
3630 signal
->theData
[7] = 0;
3633 Ptr
<Attribute
> attrPtr
;
3634 table
.attributes
.first(attrPtr
);
3635 for(; !attrPtr
.isNull(); table
.attributes
.next(attrPtr
))
3640 * LCP should not save disk attributes
3642 ndbrequire(! (ptr
.p
->is_lcp() &&
3643 attrPtr
.p
->data
.m_flags
& Attribute::COL_DISK
));
3645 AttributeHeader::init(&signal
->theData
[dataPos
],
3646 attrPtr
.p
->data
.attrId
, 0);
3650 sendSignal(DBLQH_REF
, GSN_ATTRINFO
, signal
, 25, JBB
);
3656 sendSignal(DBLQH_REF
, GSN_ATTRINFO
, signal
, dataPos
, JBB
);
3662 Backup::execSCAN_HBREP(Signal
* signal
)
3668 Backup::execTRANSID_AI(Signal
* signal
)
3672 const Uint32 filePtrI
= signal
->theData
[0];
3673 //const Uint32 transId1 = signal->theData[1];
3674 //const Uint32 transId2 = signal->theData[2];
3675 const Uint32 dataLen
= signal
->length() - 3;
3677 BackupFilePtr filePtr LINT_SET_PTR
;
3678 c_backupFilePool
.getPtr(filePtr
, filePtrI
);
3680 OperationRecord
& op
= filePtr
.p
->operation
;
3682 TablePtr tabPtr LINT_SET_PTR
;
3683 c_tablePool
.getPtr(tabPtr
, op
.tablePtr
);
3685 Table
& table
= * tabPtr
.p
;
3690 op
.attrSzTotal
+= dataLen
;
3692 Uint32 srcSz
= dataLen
;
3694 const Uint32
* src
= &signal
->theData
[3];
3696 Ptr
<Attribute
> attrPtr
;
3697 table
.attributes
.first(attrPtr
);
3698 Uint32 columnNo
= 0;
3700 while (usedSz
< srcSz
)
3705 * Finished with one attribute now find next
3707 const AttributeHeader
attrHead(* src
);
3708 const Uint32 attrId
= attrHead
.getAttributeId();
3709 const bool null
= attrHead
.isNULL();
3710 const Attribute::Data attr
= attrPtr
.p
->data
;
3711 ndbrequire(attrId
== attr
.attrId
);
3713 usedSz
+= attrHead
.getHeaderSize();
3714 src
+= attrHead
.getHeaderSize();
3718 ndbrequire(attr
.m_flags
& Attribute::COL_NULLABLE
);
3722 Uint32 dstSz
= attrHead
.getDataSize();
3723 if (attr
.m_flags
& Attribute::COL_FIXED
&&
3724 ! (attr
.m_flags
& Attribute::COL_NULLABLE
)) {
3726 dst
= op
.newAttrib(attr
.offset
, dstSz
);
3727 ndbrequire(dstSz
== attr
.sz32
);
3729 dst
= op
.newVariable(columnNo
, attrHead
.getByteSize());
3730 ndbrequire(dstSz
<= attr
.sz32
);
3733 memcpy(dst
, src
, (dstSz
<< 2));
3737 table
.attributes
.next(attrPtr
);
3741 ndbrequire(usedSz
== srcSz
);
3742 ndbrequire(op
.finished());
3743 op
.newRecord(op
.dst
);
3747 Backup::OperationRecord::init(const TablePtr
& ptr
)
3751 noOfAttributes
= ptr
.p
->noOfAttributes
;
3753 sz_Bitmask
= (ptr
.p
->noOfNull
+ 31) >> 5;
3754 sz_FixedAttribs
= ptr
.p
->sz_FixedAttributes
;
3756 if(ptr
.p
->noOfVariable
== 0) {
3758 maxRecordSize
= 1 + sz_Bitmask
+ sz_FixedAttribs
;
3762 1 + sz_Bitmask
+ 2048 /* Max tuple size */ + 2 * ptr
.p
->noOfVariable
;
3767 Backup::OperationRecord::newFragment(Uint32 tableId
, Uint32 fragNo
)
3770 const Uint32 headSz
= (sizeof(BackupFormat::DataFile::FragmentHeader
) >> 2);
3771 const Uint32 sz
= headSz
+ 16 * maxRecordSize
;
3773 ndbrequire(sz
< dataBuffer
.getMaxWrite());
3774 if(dataBuffer
.getWritePtr(&tmp
, sz
)) {
3776 BackupFormat::DataFile::FragmentHeader
* head
=
3777 (BackupFormat::DataFile::FragmentHeader
*)tmp
;
3779 head
->SectionType
= htonl(BackupFormat::FRAGMENT_HEADER
);
3780 head
->SectionLength
= htonl(headSz
);
3781 head
->TableId
= htonl(tableId
);
3782 head
->FragmentNo
= htonl(fragNo
);
3783 head
->ChecksumType
= htonl(0);
3785 opNoDone
= opNoConf
= opLen
= 0;
3786 newRecord(tmp
+ headSz
);
3788 scanStop
= (tmp
+ headSz
);
3798 Backup::OperationRecord::fragComplete(Uint32 tableId
, Uint32 fragNo
, bool fill_record
)
3801 const Uint32 footSz
= sizeof(BackupFormat::DataFile::FragmentFooter
) >> 2;
3802 Uint32 sz
= footSz
+ 1;
3807 if (!dataBuffer
.getWritePtr(&tmp
, sz
))
3811 if ((UintPtr
)new_tmp
& (sizeof(Page32
)-1))
3813 /* padding is needed to get full write */
3814 new_tmp
+= 2 /* to fit empty header minimum 2 words*/;
3815 new_tmp
= (Uint32
*)(((UintPtr
)new_tmp
+ sizeof(Page32
)-1) &
3816 ~(UintPtr
)(sizeof(Page32
)-1));
3822 if(dataBuffer
.getWritePtr(&tmp
, sz
)) {
3824 * tmp
= 0; // Finish record stream
3826 BackupFormat::DataFile::FragmentFooter
* foot
=
3827 (BackupFormat::DataFile::FragmentFooter
*)tmp
;
3828 foot
->SectionType
= htonl(BackupFormat::FRAGMENT_FOOTER
);
3829 foot
->SectionLength
= htonl(footSz
);
3830 foot
->TableId
= htonl(tableId
);
3831 foot
->FragmentNo
= htonl(fragNo
);
3832 foot
->NoOfRecords
= htonl(noOfRecords
);
3833 foot
->Checksum
= htonl(0);
3835 if (sz
!= footSz
+ 1)
3838 memset(tmp
, 0, (sz
- footSz
- 1) * 4);
3839 *tmp
= htonl(BackupFormat::EMPTY_ENTRY
);
3841 *tmp
= htonl(sz
- footSz
- 1);
3844 dataBuffer
.updateWritePtr(sz
);
3851 Backup::OperationRecord::newScan()
3854 ndbrequire(16 * maxRecordSize
< dataBuffer
.getMaxWrite());
3855 if(dataBuffer
.getWritePtr(&tmp
, 16 * maxRecordSize
)) {
3857 opNoDone
= opNoConf
= opLen
= 0;
3867 Backup::OperationRecord::closeScan()
3869 opNoDone
= opNoConf
= opLen
= 0;
3874 Backup::OperationRecord::scanConf(Uint32 noOfOps
, Uint32 total_len
)
3876 const Uint32 done
= opNoDone
-opNoConf
;
3878 ndbrequire(noOfOps
== done
);
3879 ndbrequire(opLen
== total_len
);
3880 opNoConf
= opNoDone
;
3882 const Uint32 len
= (scanStop
- scanStart
);
3883 ndbrequire(len
< dataBuffer
.getMaxWrite());
3884 dataBuffer
.updateWritePtr(len
);
3885 noOfBytes
+= (len
<< 2);
3890 Backup::execSCAN_FRAGREF(Signal
* signal
)
3894 ScanFragRef
* ref
= (ScanFragRef
*)signal
->getDataPtr();
3896 const Uint32 filePtrI
= ref
->senderData
;
3897 BackupFilePtr filePtr LINT_SET_PTR
;
3898 c_backupFilePool
.getPtr(filePtr
, filePtrI
);
3900 filePtr
.p
->errorCode
= ref
->errorCode
;
3901 filePtr
.p
->m_flags
&= ~(Uint32
)BackupFile::BF_SCAN_THREAD
;
3903 backupFragmentRef(signal
, filePtr
);
3907 Backup::execSCAN_FRAGCONF(Signal
* signal
)
3911 CRASH_INSERTION((10017));
3913 ScanFragConf
* conf
= (ScanFragConf
*)signal
->getDataPtr();
3915 const Uint32 filePtrI
= conf
->senderData
;
3916 BackupFilePtr filePtr LINT_SET_PTR
;
3917 c_backupFilePool
.getPtr(filePtr
, filePtrI
);
3919 OperationRecord
& op
= filePtr
.p
->operation
;
3921 op
.scanConf(conf
->completedOps
, conf
->total_len
);
3922 const Uint32 completed
= conf
->fragmentCompleted
;
3923 if(completed
!= 2) {
3926 checkScan(signal
, filePtr
);
3930 fragmentCompleted(signal
, filePtr
);
3934 Backup::fragmentCompleted(Signal
* signal
, BackupFilePtr filePtr
)
3938 if(filePtr
.p
->errorCode
!= 0)
3941 filePtr
.p
->m_flags
&= ~(Uint32
)BackupFile::BF_SCAN_THREAD
;
3942 backupFragmentRef(signal
, filePtr
); // Scan completed
3946 BackupRecordPtr ptr LINT_SET_PTR
;
3947 c_backupPool
.getPtr(ptr
, filePtr
.p
->backupPtr
);
3949 OperationRecord
& op
= filePtr
.p
->operation
;
3950 if(!op
.fragComplete(filePtr
.p
->tableId
, filePtr
.p
->fragmentNo
,
3951 c_defaults
.m_o_direct
))
3954 signal
->theData
[0] = BackupContinueB::BUFFER_FULL_FRAG_COMPLETE
;
3955 signal
->theData
[1] = filePtr
.i
;
3956 sendSignalWithDelay(BACKUP_REF
, GSN_CONTINUEB
, signal
, 50, 2);
3960 filePtr
.p
->m_flags
&= ~(Uint32
)BackupFile::BF_SCAN_THREAD
;
3962 if (ptr
.p
->is_lcp())
3964 ptr
.p
->slaveState
.setState(STOPPING
);
3965 filePtr
.p
->operation
.dataBuffer
.eof();
3969 BackupFragmentConf
* conf
= (BackupFragmentConf
*)signal
->getDataPtrSend();
3970 conf
->backupId
= ptr
.p
->backupId
;
3971 conf
->backupPtr
= ptr
.i
;
3972 conf
->tableId
= filePtr
.p
->tableId
;
3973 conf
->fragmentNo
= filePtr
.p
->fragmentNo
;
3974 conf
->noOfRecordsLow
= (Uint32
)(op
.noOfRecords
& 0xFFFFFFFF);
3975 conf
->noOfRecordsHigh
= (Uint32
)(op
.noOfRecords
>> 32);
3976 conf
->noOfBytesLow
= (Uint32
)(op
.noOfBytes
& 0xFFFFFFFF);
3977 conf
->noOfBytesHigh
= (Uint32
)(op
.noOfBytes
>> 32);
3978 sendSignal(ptr
.p
->masterRef
, GSN_BACKUP_FRAGMENT_CONF
, signal
,
3979 BackupFragmentConf::SignalLength
, JBB
);
3981 ptr
.p
->m_gsn
= GSN_BACKUP_FRAGMENT_CONF
;
3982 ptr
.p
->slaveState
.setState(STARTED
);
3988 Backup::backupFragmentRef(Signal
* signal
, BackupFilePtr filePtr
)
3990 BackupRecordPtr ptr LINT_SET_PTR
;
3991 c_backupPool
.getPtr(ptr
, filePtr
.p
->backupPtr
);
3993 ptr
.p
->m_gsn
= GSN_BACKUP_FRAGMENT_REF
;
3995 BackupFragmentRef
* ref
= (BackupFragmentRef
*)signal
->getDataPtrSend();
3996 ref
->backupId
= ptr
.p
->backupId
;
3997 ref
->backupPtr
= ptr
.i
;
3998 ref
->nodeId
= getOwnNodeId();
3999 ref
->errorCode
= filePtr
.p
->errorCode
;
4000 sendSignal(ptr
.p
->masterRef
, GSN_BACKUP_FRAGMENT_REF
, signal
,
4001 BackupFragmentRef::SignalLength
, JBB
);
4005 Backup::checkScan(Signal
* signal
, BackupFilePtr filePtr
)
4007 OperationRecord
& op
= filePtr
.p
->operation
;
4009 if(filePtr
.p
->errorCode
!= 0)
4017 ScanFragNextReq
* req
= (ScanFragNextReq
*)signal
->getDataPtrSend();
4018 req
->senderData
= filePtr
.i
;
4021 req
->transId2
= (BACKUP
<< 20) + (getOwnNodeId() << 8);
4022 sendSignal(DBLQH_REF
, GSN_SCAN_NEXTREQ
, signal
,
4023 ScanFragNextReq::SignalLength
, JBB
);
4030 ScanFragNextReq
* req
= (ScanFragNextReq
*)signal
->getDataPtrSend();
4031 req
->senderData
= filePtr
.i
;
4034 req
->transId2
= (BACKUP
<< 20) + (getOwnNodeId() << 8);
4035 req
->batch_size_rows
= 16;
4036 req
->batch_size_bytes
= 0;
4038 if (ERROR_INSERTED(10036) &&
4039 filePtr
.p
->tableId
>= 2 &&
4040 filePtr
.p
->operation
.noOfRecords
> 0)
4042 ndbout_c("halting backup for table %d fragment: %d after %llu records",
4044 filePtr
.p
->fragmentNo
,
4045 filePtr
.p
->operation
.noOfRecords
);
4046 memmove(signal
->theData
+1, signal
->theData
,
4047 4*ScanFragNextReq::SignalLength
);
4048 signal
->theData
[0] = BackupContinueB::ZDELAY_SCAN_NEXT
;
4049 sendSignalWithDelay(BACKUP_REF
, GSN_CONTINUEB
, signal
,
4050 300, 1+ScanFragNextReq::SignalLength
);
4053 if(ERROR_INSERTED(10032))
4054 sendSignalWithDelay(DBLQH_REF
, GSN_SCAN_NEXTREQ
, signal
,
4055 100, ScanFragNextReq::SignalLength
);
4056 else if(ERROR_INSERTED(10033))
4058 SET_ERROR_INSERT_VALUE(10032);
4059 sendSignalWithDelay(DBLQH_REF
, GSN_SCAN_NEXTREQ
, signal
,
4060 10000, ScanFragNextReq::SignalLength
);
4062 BackupRecordPtr ptr LINT_SET_PTR
;
4063 c_backupPool
.getPtr(ptr
, filePtr
.p
->backupPtr
);
4064 AbortBackupOrd
*ord
= (AbortBackupOrd
*)signal
->getDataPtrSend();
4065 ord
->backupId
= ptr
.p
->backupId
;
4066 ord
->backupPtr
= ptr
.i
;
4067 ord
->requestType
= AbortBackupOrd::FileOrScanError
;
4068 ord
->senderData
= ptr
.i
;
4069 sendSignal(ptr
.p
->masterRef
, GSN_ABORT_BACKUP_ORD
, signal
,
4070 AbortBackupOrd::SignalLength
, JBB
);
4073 sendSignal(DBLQH_REF
, GSN_SCAN_NEXTREQ
, signal
,
4074 ScanFragNextReq::SignalLength
, JBB
);
4078 signal
->theData
[0] = BackupContinueB::BUFFER_FULL_SCAN
;
4079 signal
->theData
[1] = filePtr
.i
;
4080 sendSignalWithDelay(BACKUP_REF
, GSN_CONTINUEB
, signal
, 50, 2);
4084 Backup::execFSAPPENDREF(Signal
* signal
)
4088 FsRef
* ref
= (FsRef
*)signal
->getDataPtr();
4090 const Uint32 filePtrI
= ref
->userPointer
;
4091 const Uint32 errCode
= ref
->errorCode
;
4093 BackupFilePtr filePtr LINT_SET_PTR
;
4094 c_backupFilePool
.getPtr(filePtr
, filePtrI
);
4096 filePtr
.p
->m_flags
&= ~(Uint32
)BackupFile::BF_FILE_THREAD
;
4097 filePtr
.p
->errorCode
= errCode
;
4099 checkFile(signal
, filePtr
);
4103 Backup::execFSAPPENDCONF(Signal
* signal
)
4107 CRASH_INSERTION((10018));
4109 //FsConf * conf = (FsConf*)signal->getDataPtr();
4110 const Uint32 filePtrI
= signal
->theData
[0]; //conf->userPointer;
4111 const Uint32 bytes
= signal
->theData
[1]; //conf->bytes;
4113 BackupFilePtr filePtr LINT_SET_PTR
;
4114 c_backupFilePool
.getPtr(filePtr
, filePtrI
);
4116 OperationRecord
& op
= filePtr
.p
->operation
;
4118 op
.dataBuffer
.updateReadPtr(bytes
>> 2);
4120 checkFile(signal
, filePtr
);
4124 This routine handles two problems with writing to disk during local
4125 checkpoints and backups. The first problem is that we need to limit
4126 the writing to ensure that we don't use too much CPU and disk resources
4127 for backups and checkpoints. The perfect solution to this is to use
4128 a dynamic algorithm that adapts to the environment. Until we have
4129 implemented this we can satisfy ourselves with an algorithm that
4130 uses a configurable limit.
4132 The second problem is that in Linux we can get severe problems if we
4133 write very much to the disk without synching. In the worst case we
4134 can have Gigabytes of data in the Linux page cache before we reach
4135 the limit of how much we can write. If this happens the performance
4136 will drop significantly when we reach this limit since the Linux flush
4137 daemon will spend a few minutes on writing out the page cache to disk.
4138 To avoid this we ensure that a file never have more than a certain
4139 amount of data outstanding before synch. This variable is also
4143 Backup::ready_to_write(bool ready
, Uint32 sz
, bool eof
, BackupFile
*fileP
)
4146 ndbout
<< "ready_to_write: ready = " << ready
<< " eof = " << eof
;
4147 ndbout
<< " sz = " << sz
<< endl
;
4148 ndbout
<< "words this period = " << m_words_written_this_period
;
4149 ndbout
<< endl
<< "overflow disk write = " << m_overflow_disk_write
;
4150 ndbout
<< endl
<< "Current Millisecond is = ";
4151 ndbout
<< NdbTick_CurrentMillisecond() << endl
;
4153 if ((ready
|| eof
) &&
4154 m_words_written_this_period
<= m_curr_disk_write_speed
)
4157 We have a buffer ready to write or we have reached end of
4158 file and thus we must write the last before closing the
4160 We have already check that we are allowed to write at this
4161 moment. We only worry about history of last 100 milliseconds.
4162 What happened before that is of no interest since a disk
4163 write that was issued more than 100 milliseconds should be
4167 m_words_written_this_period
+= sz
;
4168 overflow
= m_words_written_this_period
- m_curr_disk_write_speed
;
4170 m_overflow_disk_write
= overflow
;
4172 ndbout
<< "Will write with " << endl
;
4180 ndbout
<< "Will not write now" << endl
<< endl
;
4187 Backup::checkFile(Signal
* signal
, BackupFilePtr filePtr
)
4191 // ndbout_c("---- check file filePtr.i = %u", filePtr.i);
4194 OperationRecord
& op
= filePtr
.p
->operation
;
4198 bool ready
= op
.dataBuffer
.getReadPtr(&tmp
, &sz
, &eof
);
4200 ndbout
<< "Ptr to data = " << hex
<< tmp
<< endl
;
4202 BackupRecordPtr ptr LINT_SET_PTR
;
4203 c_backupPool
.getPtr(ptr
, filePtr
.p
->backupPtr
);
4205 if (ERROR_INSERTED(10036))
4208 filePtr
.p
->m_flags
&= ~(Uint32
)BackupFile::BF_FILE_THREAD
;
4209 filePtr
.p
->errorCode
= 2810;
4210 ptr
.p
->setErrorCode(2810);
4212 if(ptr
.p
->m_gsn
== GSN_STOP_BACKUP_REQ
)
4215 closeFile(signal
, ptr
, filePtr
);
4220 if(filePtr
.p
->errorCode
!= 0)
4223 ptr
.p
->setErrorCode(filePtr
.p
->errorCode
);
4225 if(ptr
.p
->m_gsn
== GSN_STOP_BACKUP_REQ
)
4228 closeFile(signal
, ptr
, filePtr
);
4233 if (!ready_to_write(ready
, sz
, eof
, filePtr
.p
))
4236 signal
->theData
[0] = BackupContinueB::BUFFER_UNDERFLOW
;
4237 signal
->theData
[1] = filePtr
.i
;
4238 sendSignalWithDelay(BACKUP_REF
, GSN_CONTINUEB
, signal
, 20, 2);
4244 FsAppendReq
* req
= (FsAppendReq
*)signal
->getDataPtrSend();
4245 req
->filePointer
= filePtr
.p
->filePointer
;
4246 req
->userPointer
= filePtr
.i
;
4247 req
->userReference
= reference();
4249 req
->offset
= tmp
- c_startOfPages
;
4251 req
->synch_flag
= 0;
4253 sendSignal(NDBFS_REF
, GSN_FSAPPENDREQ
, signal
,
4254 FsAppendReq::SignalLength
, JBA
);
4258 Uint32 flags
= filePtr
.p
->m_flags
;
4259 filePtr
.p
->m_flags
&= ~(Uint32
)BackupFile::BF_FILE_THREAD
;
4261 ndbrequire(flags
& BackupFile::BF_OPEN
);
4262 ndbrequire(flags
& BackupFile::BF_FILE_THREAD
);
4264 closeFile(signal
, ptr
, filePtr
);
4268 /****************************************************************************
4270 * Slave functionallity: Perform logging
4272 ****************************************************************************/
4274 Backup::execBACKUP_TRIG_REQ(Signal
* signal
)
4277 TUP asks if this trigger is to be fired on this node.
4279 TriggerPtr trigPtr LINT_SET_PTR
;
4280 TablePtr tabPtr LINT_SET_PTR
;
4281 FragmentPtr fragPtr
;
4282 Uint32 trigger_id
= signal
->theData
[0];
4283 Uint32 frag_id
= signal
->theData
[1];
4288 c_triggerPool
.getPtr(trigPtr
, trigger_id
);
4290 c_tablePool
.getPtr(tabPtr
, trigPtr
.p
->tab_ptr_i
);
4291 tabPtr
.p
->fragments
.getPtr(fragPtr
, frag_id
);
4292 if (fragPtr
.p
->node
!= getOwnNodeId()) {
4300 signal
->theData
[0] = result
;
4304 Backup::execTRIG_ATTRINFO(Signal
* signal
) {
4307 CRASH_INSERTION((10019));
4309 TrigAttrInfo
* trg
= (TrigAttrInfo
*)signal
->getDataPtr();
4311 TriggerPtr trigPtr LINT_SET_PTR
;
4312 c_triggerPool
.getPtr(trigPtr
, trg
->getTriggerId());
4313 ndbrequire(trigPtr
.p
->event
!= ILLEGAL_TRIGGER_ID
); // Online...
4315 if(trigPtr
.p
->errorCode
!= 0) {
4320 if(trg
->getAttrInfoType() == TrigAttrInfo::BEFORE_VALUES
) {
4323 * Backup is doing REDO logging and don't need before values
4328 BackupFormat::LogFile::LogEntry
* logEntry
= trigPtr
.p
->logEntry
;
4333 FsBuffer
& buf
= trigPtr
.p
->operation
->dataBuffer
;
4334 ndbrequire(trigPtr
.p
->maxRecordSize
<= buf
.getMaxWrite());
4336 if(ERROR_INSERTED(10030) ||
4337 !buf
.getWritePtr(&dst
, trigPtr
.p
->maxRecordSize
))
4340 Uint32 save
[TrigAttrInfo::StaticLength
];
4341 memcpy(save
, signal
->getDataPtr(), 4*TrigAttrInfo::StaticLength
);
4342 BackupRecordPtr ptr LINT_SET_PTR
;
4343 c_backupPool
.getPtr(ptr
, trigPtr
.p
->backupPtr
);
4344 trigPtr
.p
->errorCode
= AbortBackupOrd::LogBufferFull
;
4345 AbortBackupOrd
*ord
= (AbortBackupOrd
*)signal
->getDataPtrSend();
4346 ord
->backupId
= ptr
.p
->backupId
;
4347 ord
->backupPtr
= ptr
.i
;
4348 ord
->requestType
= AbortBackupOrd::LogBufferFull
;
4349 ord
->senderData
= ptr
.i
;
4350 sendSignal(ptr
.p
->masterRef
, GSN_ABORT_BACKUP_ORD
, signal
,
4351 AbortBackupOrd::SignalLength
, JBB
);
4353 memcpy(signal
->getDataPtrSend(), save
, 4*TrigAttrInfo::StaticLength
);
4357 logEntry
= (BackupFormat::LogFile::LogEntry
*)dst
;
4358 trigPtr
.p
->logEntry
= logEntry
;
4359 logEntry
->Length
= 0;
4360 logEntry
->TableId
= htonl(trigPtr
.p
->tableId
);
4363 if(trigPtr
.p
->event
==0)
4364 logEntry
->TriggerEvent
= htonl(TriggerEvent::TE_INSERT
);
4365 else if(trigPtr
.p
->event
==1)
4366 logEntry
->TriggerEvent
= htonl(TriggerEvent::TE_UPDATE
);
4367 else if(trigPtr
.p
->event
==2)
4368 logEntry
->TriggerEvent
= htonl(TriggerEvent::TE_DELETE
);
4370 ndbout
<< "Bad Event: " << trigPtr
.p
->event
<< endl
;
4374 ndbrequire(logEntry
->TableId
== htonl(trigPtr
.p
->tableId
));
4375 // ndbrequire(logEntry->TriggerEvent == htonl(trigPtr.p->event));
4378 const Uint32 pos
= logEntry
->Length
;
4379 const Uint32 dataLen
= signal
->length() - TrigAttrInfo::StaticLength
;
4380 memcpy(&logEntry
->Data
[pos
], trg
->getData(), dataLen
<< 2);
4382 logEntry
->Length
= pos
+ dataLen
;
4386 Backup::execFIRE_TRIG_ORD(Signal
* signal
)
4389 FireTrigOrd
* trg
= (FireTrigOrd
*)signal
->getDataPtr();
4391 const Uint32 gci
= trg
->getGCI();
4392 const Uint32 trI
= trg
->getTriggerId();
4393 const Uint32 fragId
= trg
->fragId
;
4395 TriggerPtr trigPtr LINT_SET_PTR
;
4396 c_triggerPool
.getPtr(trigPtr
, trI
);
4398 ndbrequire(trigPtr
.p
->event
!= ILLEGAL_TRIGGER_ID
);
4400 if(trigPtr
.p
->errorCode
!= 0) {
4405 ndbrequire(trigPtr
.p
->logEntry
!= 0);
4406 Uint32 len
= trigPtr
.p
->logEntry
->Length
;
4407 trigPtr
.p
->logEntry
->FragId
= htonl(fragId
);
4409 BackupRecordPtr ptr LINT_SET_PTR
;
4410 c_backupPool
.getPtr(ptr
, trigPtr
.p
->backupPtr
);
4411 if(gci
!= ptr
.p
->currGCP
)
4414 trigPtr
.p
->logEntry
->TriggerEvent
|= htonl(0x10000);
4415 trigPtr
.p
->logEntry
->Data
[len
] = htonl(gci
);
4417 ptr
.p
->currGCP
= gci
;
4420 len
+= (sizeof(BackupFormat::LogFile::LogEntry
) >> 2) - 2;
4421 trigPtr
.p
->logEntry
->Length
= htonl(len
);
4423 ndbrequire(len
+ 1 <= trigPtr
.p
->operation
->dataBuffer
.getMaxWrite());
4424 trigPtr
.p
->operation
->dataBuffer
.updateWritePtr(len
+ 1);
4425 trigPtr
.p
->logEntry
= 0;
4427 trigPtr
.p
->operation
->noOfBytes
+= (len
+ 1) << 2;
4428 trigPtr
.p
->operation
->noOfRecords
+= 1;
4432 Backup::sendAbortBackupOrd(Signal
* signal
, BackupRecordPtr ptr
,
4436 AbortBackupOrd
*ord
= (AbortBackupOrd
*)signal
->getDataPtrSend();
4437 ord
->backupId
= ptr
.p
->backupId
;
4438 ord
->backupPtr
= ptr
.i
;
4439 ord
->requestType
= requestType
;
4440 ord
->senderData
= ptr
.i
;
4442 for(c_nodes
.first(node
); node
.i
!= RNIL
; c_nodes
.next(node
)) {
4444 const Uint32 nodeId
= node
.p
->nodeId
;
4445 if(node
.p
->alive
&& ptr
.p
->nodes
.get(nodeId
)) {
4447 sendSignal(numberToRef(BACKUP
, nodeId
), GSN_ABORT_BACKUP_ORD
, signal
,
4448 AbortBackupOrd::SignalLength
, JBB
);
4453 /*****************************************************************************
4455 * Slave functionallity: Stop backup
4457 *****************************************************************************/
4459 Backup::execSTOP_BACKUP_REQ(Signal
* signal
)
4462 StopBackupReq
* req
= (StopBackupReq
*)signal
->getDataPtr();
4464 CRASH_INSERTION((10020));
4466 const Uint32 ptrI
= req
->backupPtr
;
4467 //const Uint32 backupId = req->backupId;
4468 const Uint32 startGCP
= req
->startGCP
;
4469 const Uint32 stopGCP
= req
->stopGCP
;
4472 * At least one GCP must have passed
4474 ndbrequire(stopGCP
> startGCP
);
4479 BackupRecordPtr ptr LINT_SET_PTR
;
4480 c_backupPool
.getPtr(ptr
, ptrI
);
4482 ptr
.p
->slaveState
.setState(STOPPING
);
4483 ptr
.p
->m_gsn
= GSN_STOP_BACKUP_REQ
;
4484 ptr
.p
->startGCP
= startGCP
;
4485 ptr
.p
->stopGCP
= stopGCP
;
4488 * Destroy the triggers in local DBTUP we created
4490 sendDropTrig(signal
, ptr
);
4494 Backup::closeFiles(Signal
* sig
, BackupRecordPtr ptr
)
4499 BackupFilePtr filePtr
;
4501 for(ptr
.p
->files
.first(filePtr
); filePtr
.i
!=RNIL
; ptr
.p
->files
.next(filePtr
))
4503 if(! (filePtr
.p
->m_flags
& BackupFile::BF_OPEN
))
4512 if(filePtr
.p
->m_flags
& BackupFile::BF_CLOSING
)
4518 filePtr
.p
->operation
.dataBuffer
.eof();
4519 if(filePtr
.p
->m_flags
& BackupFile::BF_FILE_THREAD
)
4523 ndbout_c("Close files fileRunning == 1, filePtr.i=%u", filePtr
.i
);
4529 closeFile(sig
, ptr
, filePtr
);
4535 closeFilesDone(sig
, ptr
);
4540 Backup::closeFile(Signal
* signal
, BackupRecordPtr ptr
, BackupFilePtr filePtr
)
4542 ndbrequire(filePtr
.p
->m_flags
& BackupFile::BF_OPEN
);
4543 ndbrequire(! (filePtr
.p
->m_flags
& BackupFile::BF_OPENING
));
4544 ndbrequire(! (filePtr
.p
->m_flags
& BackupFile::BF_CLOSING
));
4545 filePtr
.p
->m_flags
|= BackupFile::BF_CLOSING
;
4547 FsCloseReq
* req
= (FsCloseReq
*)signal
->getDataPtrSend();
4548 req
->filePointer
= filePtr
.p
->filePointer
;
4549 req
->userPointer
= filePtr
.i
;
4550 req
->userReference
= reference();
4553 if (ptr
.p
->errorCode
)
4555 FsCloseReq::setRemoveFileFlag(req
->fileFlag
, 1);
4559 ndbout_c("***** a FSCLOSEREQ filePtr.i = %u flags: %x",
4560 filePtr
.i
, filePtr
.p
->m_flags
);
4562 sendSignal(NDBFS_REF
, GSN_FSCLOSEREQ
, signal
, FsCloseReq::SignalLength
, JBA
);
4567 Backup::execFSCLOSEREF(Signal
* signal
)
4571 FsRef
* ref
= (FsRef
*)signal
->getDataPtr();
4572 const Uint32 filePtrI
= ref
->userPointer
;
4574 BackupFilePtr filePtr LINT_SET_PTR
;
4575 c_backupFilePool
.getPtr(filePtr
, filePtrI
);
4577 BackupRecordPtr ptr LINT_SET_PTR
;
4578 c_backupPool
.getPtr(ptr
, filePtr
.p
->backupPtr
);
4580 FsConf
* conf
= (FsConf
*)signal
->getDataPtr();
4581 conf
->userPointer
= filePtrI
;
4583 execFSCLOSECONF(signal
);
4587 Backup::execFSCLOSECONF(Signal
* signal
)
4591 FsConf
* conf
= (FsConf
*)signal
->getDataPtr();
4592 const Uint32 filePtrI
= conf
->userPointer
;
4594 BackupFilePtr filePtr LINT_SET_PTR
;
4595 c_backupFilePool
.getPtr(filePtr
, filePtrI
);
4598 ndbout_c("***** FSCLOSECONF filePtrI = %u", filePtrI
);
4601 ndbrequire(filePtr
.p
->m_flags
== (BackupFile::BF_OPEN
|
4602 BackupFile::BF_CLOSING
));
4605 filePtr
.p
->m_flags
&= ~(Uint32
)(BackupFile::BF_OPEN
|BackupFile::BF_CLOSING
);
4606 filePtr
.p
->operation
.dataBuffer
.reset();
4608 BackupRecordPtr ptr LINT_SET_PTR
;
4609 c_backupPool
.getPtr(ptr
, filePtr
.p
->backupPtr
);
4610 closeFiles(signal
, ptr
);
4614 Backup::closeFilesDone(Signal
* signal
, BackupRecordPtr ptr
)
4620 lcp_close_file_conf(signal
, ptr
);
4626 //error when do insert footer or close file
4627 if(ptr
.p
->checkError())
4629 StopBackupRef
* ref
= (StopBackupRef
*)signal
->getDataPtr();
4630 ref
->backupPtr
= ptr
.i
;
4631 ref
->backupId
= ptr
.p
->backupId
;
4632 ref
->errorCode
= ptr
.p
->errorCode
;
4633 ref
->nodeId
= getOwnNodeId();
4634 sendSignal(ptr
.p
->masterRef
, GSN_STOP_BACKUP_REF
, signal
,
4635 StopBackupConf::SignalLength
, JBB
);
4637 ptr
.p
->m_gsn
= GSN_STOP_BACKUP_REF
;
4638 ptr
.p
->slaveState
.setState(CLEANING
);
4642 StopBackupConf
* conf
= (StopBackupConf
*)signal
->getDataPtrSend();
4643 conf
->backupId
= ptr
.p
->backupId
;
4644 conf
->backupPtr
= ptr
.i
;
4646 BackupFilePtr filePtr LINT_SET_PTR
;
4647 if(ptr
.p
->logFilePtr
!= RNIL
)
4649 ptr
.p
->files
.getPtr(filePtr
, ptr
.p
->logFilePtr
);
4650 conf
->noOfLogBytes
= filePtr
.p
->operation
.noOfBytes
;
4651 conf
->noOfLogRecords
= filePtr
.p
->operation
.noOfRecords
;
4655 conf
->noOfLogBytes
= 0;
4656 conf
->noOfLogRecords
= 0;
4659 sendSignal(ptr
.p
->masterRef
, GSN_STOP_BACKUP_CONF
, signal
,
4660 StopBackupConf::SignalLength
, JBB
);
4662 ptr
.p
->m_gsn
= GSN_STOP_BACKUP_CONF
;
4663 ptr
.p
->slaveState
.setState(CLEANING
);
4666 /*****************************************************************************
4668 * Slave functionallity: Abort backup
4670 *****************************************************************************/
4671 /*****************************************************************************
4673 * Slave functionallity: Abort backup
4675 *****************************************************************************/
4677 Backup::execABORT_BACKUP_ORD(Signal
* signal
)
4680 AbortBackupOrd
* ord
= (AbortBackupOrd
*)signal
->getDataPtr();
4682 const Uint32 backupId
= ord
->backupId
;
4683 const AbortBackupOrd::RequestType requestType
=
4684 (AbortBackupOrd::RequestType
)ord
->requestType
;
4685 const Uint32 senderData
= ord
->senderData
;
4688 ndbout_c("******** ABORT_BACKUP_ORD ********* nodeId = %u",
4689 refToNode(signal
->getSendersBlockRef()));
4690 ndbout_c("backupId = %u, requestType = %u, senderData = %u, ",
4691 backupId
, requestType
, senderData
);
4692 dumpUsedResources();
4695 BackupRecordPtr ptr LINT_SET_PTR
;
4696 if(requestType
== AbortBackupOrd::ClientAbort
) {
4697 if (getOwnNodeId() != getMasterNodeId()) {
4699 // forward to master
4701 ndbout_c("---- Forward to master nodeId = %u", getMasterNodeId());
4703 sendSignal(calcBackupBlockRef(getMasterNodeId()), GSN_ABORT_BACKUP_ORD
,
4704 signal
, AbortBackupOrd::SignalLength
, JBB
);
4708 for(c_backups
.first(ptr
); ptr
.i
!= RNIL
; c_backups
.next(ptr
)) {
4710 if(ptr
.p
->backupId
== backupId
&& ptr
.p
->clientData
== senderData
) {
4720 if (c_backupPool
.findId(senderData
)) {
4722 c_backupPool
.getPtr(ptr
, senderData
);
4726 ndbout_c("Backup: abort request type=%u on id=%u,%u not found",
4727 requestType
, backupId
, senderData
);
4733 ptr
.p
->m_gsn
= GSN_ABORT_BACKUP_ORD
;
4734 const bool isCoordinator
= (ptr
.p
->masterRef
== reference());
4737 switch(requestType
){
4740 * Requests sent to master
4742 case AbortBackupOrd::ClientAbort
:
4745 case AbortBackupOrd::LogBufferFull
:
4748 case AbortBackupOrd::FileOrScanError
:
4750 ndbrequire(isCoordinator
);
4751 ptr
.p
->setErrorCode(requestType
);
4752 if(ptr
.p
->masterData
.gsn
== GSN_BACKUP_FRAGMENT_REQ
)
4755 * Only scans are actively aborted
4757 abort_scan(signal
, ptr
);
4762 * Requests sent to slave
4764 case AbortBackupOrd::AbortScan
:
4766 ptr
.p
->setErrorCode(requestType
);
4769 case AbortBackupOrd::BackupComplete
:
4771 cleanup(signal
, ptr
);
4773 case AbortBackupOrd::BackupFailure
:
4774 case AbortBackupOrd::BackupFailureDueToNodeFail
:
4775 case AbortBackupOrd::OkToClean
:
4776 case AbortBackupOrd::IncompatibleVersions
:
4780 ptr
.p
->setErrorCode(requestType
);
4785 ptr
.p
->masterRef
= reference();
4786 ptr
.p
->nodes
.clear();
4787 ptr
.p
->nodes
.set(getOwnNodeId());
4790 ptr
.p
->stopGCP
= ptr
.p
->startGCP
+ 1;
4791 sendStopBackup(signal
, ptr
);
4796 Backup::dumpUsedResources()
4799 BackupRecordPtr ptr
;
4801 for(c_backups
.first(ptr
); ptr
.i
!= RNIL
; c_backups
.next(ptr
)) {
4802 ndbout_c("Backup id=%u, slaveState.getState = %u, errorCode=%u",
4804 ptr
.p
->slaveState
.getState(),
4808 for(ptr
.p
->tables
.first(tabPtr
);
4810 ptr
.p
->tables
.next(tabPtr
)) {
4812 for(Uint32 j
= 0; j
<3; j
++) {
4814 TriggerPtr trigPtr LINT_SET_PTR
;
4815 if(tabPtr
.p
->triggerAllocated
[j
]) {
4817 c_triggerPool
.getPtr(trigPtr
, tabPtr
.p
->triggerIds
[j
]);
4818 ndbout_c("Allocated[%u] Triggerid = %u, event = %u",
4820 tabPtr
.p
->triggerIds
[j
],
4826 BackupFilePtr filePtr
;
4827 for(ptr
.p
->files
.first(filePtr
);
4829 ptr
.p
->files
.next(filePtr
)) {
4831 ndbout_c("filePtr.i = %u, flags: H'%x ",
4832 filePtr
.i
, filePtr
.p
->m_flags
);
4838 Backup::cleanup(Signal
* signal
, BackupRecordPtr ptr
)
4842 for(ptr
.p
->tables
.first(tabPtr
); tabPtr
.i
!= RNIL
;ptr
.p
->tables
.next(tabPtr
))
4845 tabPtr
.p
->attributes
.release();
4846 tabPtr
.p
->fragments
.release();
4847 for(Uint32 j
= 0; j
<3; j
++) {
4849 TriggerPtr trigPtr LINT_SET_PTR
;
4850 if(tabPtr
.p
->triggerAllocated
[j
]) {
4852 c_triggerPool
.getPtr(trigPtr
, tabPtr
.p
->triggerIds
[j
]);
4853 trigPtr
.p
->event
= ILLEGAL_TRIGGER_ID
;
4854 tabPtr
.p
->triggerAllocated
[j
] = false;
4856 tabPtr
.p
->triggerIds
[j
] = ILLEGAL_TRIGGER_ID
;
4859 signal
->theData
[0] = tabPtr
.p
->tableId
;
4860 signal
->theData
[1] = 0; // unlock
4861 EXECUTE_DIRECT(DBDICT
, GSN_BACKUP_FRAGMENT_REQ
, signal
, 2);
4865 BackupFilePtr filePtr
;
4866 for(ptr
.p
->files
.first(filePtr
);filePtr
.i
!= RNIL
;ptr
.p
->files
.next(filePtr
))
4869 ndbrequire(filePtr
.p
->m_flags
== 0);
4870 filePtr
.p
->pages
.release();
4873 ptr
.p
->files
.release();
4874 ptr
.p
->tables
.release();
4875 ptr
.p
->triggers
.release();
4876 ptr
.p
->backupId
= ~0;
4878 if(ptr
.p
->checkError())
4879 removeBackup(signal
, ptr
);
4881 c_backups
.release(ptr
);
4886 Backup::removeBackup(Signal
* signal
, BackupRecordPtr ptr
)
4890 FsRemoveReq
* req
= (FsRemoveReq
*)signal
->getDataPtrSend();
4891 req
->userReference
= reference();
4892 req
->userPointer
= ptr
.i
;
4894 req
->ownDirectory
= 1;
4895 FsOpenReq::setVersion(req
->fileNumber
, 2);
4896 FsOpenReq::setSuffix(req
->fileNumber
, FsOpenReq::S_CTL
);
4897 FsOpenReq::v2_setSequence(req
->fileNumber
, ptr
.p
->backupId
);
4898 FsOpenReq::v2_setNodeId(req
->fileNumber
, getOwnNodeId());
4899 sendSignal(NDBFS_REF
, GSN_FSREMOVEREQ
, signal
,
4900 FsRemoveReq::SignalLength
, JBA
);
4904 Backup::execFSREMOVEREF(Signal
* signal
)
4907 FsRef
* ref
= (FsRef
*)signal
->getDataPtr();
4908 const Uint32 ptrI
= ref
->userPointer
;
4910 FsConf
* conf
= (FsConf
*)signal
->getDataPtr();
4911 conf
->userPointer
= ptrI
;
4912 execFSREMOVECONF(signal
);
4916 Backup::execFSREMOVECONF(Signal
* signal
){
4919 FsConf
* conf
= (FsConf
*)signal
->getDataPtr();
4920 const Uint32 ptrI
= conf
->userPointer
;
4925 BackupRecordPtr ptr LINT_SET_PTR
;
4926 c_backupPool
.getPtr(ptr
, ptrI
);
4927 c_backups
.release(ptr
);
4934 Backup::execLCP_PREPARE_REQ(Signal
* signal
)
4937 LcpPrepareReq req
= *(LcpPrepareReq
*)signal
->getDataPtr();
4939 BackupRecordPtr ptr LINT_SET_PTR
;
4940 c_backupPool
.getPtr(ptr
, req
.backupPtr
);
4942 ptr
.p
->m_gsn
= GSN_LCP_PREPARE_REQ
;
4945 FragmentPtr fragPtr
;
4946 if (!ptr
.p
->tables
.isEmpty())
4949 ndbrequire(ptr
.p
->errorCode
);
4950 ptr
.p
->tables
.first(tabPtr
);
4951 if (tabPtr
.p
->tableId
== req
.tableId
)
4954 ndbrequire(!tabPtr
.p
->fragments
.empty());
4955 tabPtr
.p
->fragments
.getPtr(fragPtr
, 0);
4956 fragPtr
.p
->fragmentId
= req
.fragmentId
;
4957 defineBackupRef(signal
, ptr
, ptr
.p
->errorCode
);
4963 tabPtr
.p
->attributes
.release();
4964 tabPtr
.p
->fragments
.release();
4965 ptr
.p
->tables
.release();
4966 ptr
.p
->errorCode
= 0;
4971 if(!ptr
.p
->tables
.seize(tabPtr
) || !tabPtr
.p
->fragments
.seize(1))
4973 if(!tabPtr
.isNull())
4974 ptr
.p
->tables
.release();
4975 ndbrequire(false); // TODO
4977 tabPtr
.p
->tableId
= req
.tableId
;
4978 tabPtr
.p
->fragments
.getPtr(fragPtr
, 0);
4979 tabPtr
.p
->tableType
= DictTabInfo::UserTable
;
4980 fragPtr
.p
->fragmentId
= req
.fragmentId
;
4981 fragPtr
.p
->lcp_no
= req
.lcpNo
;
4982 fragPtr
.p
->scanned
= 0;
4983 fragPtr
.p
->scanning
= 0;
4984 fragPtr
.p
->tableId
= req
.tableId
;
4986 ptr
.p
->backupId
= req
.backupId
;
4987 lcp_open_file(signal
, ptr
);
4991 Backup::lcp_close_file_conf(Signal
* signal
, BackupRecordPtr ptr
)
4996 ndbrequire(ptr
.p
->tables
.first(tabPtr
));
4997 Uint32 tableId
= tabPtr
.p
->tableId
;
4999 BackupFilePtr filePtr LINT_SET_PTR
;
5000 c_backupFilePool
.getPtr(filePtr
, ptr
.p
->dataFilePtr
);
5001 ndbrequire(filePtr
.p
->m_flags
== 0);
5003 if (ptr
.p
->m_gsn
== GSN_LCP_PREPARE_REQ
)
5006 defineBackupRef(signal
, ptr
, ptr
.p
->errorCode
);
5010 FragmentPtr fragPtr
;
5011 tabPtr
.p
->fragments
.getPtr(fragPtr
, 0);
5012 Uint32 fragmentId
= fragPtr
.p
->fragmentId
;
5014 tabPtr
.p
->attributes
.release();
5015 tabPtr
.p
->fragments
.release();
5016 ptr
.p
->tables
.release();
5017 ptr
.p
->errorCode
= 0;
5019 BackupFragmentConf
* conf
= (BackupFragmentConf
*)signal
->getDataPtrSend();
5020 conf
->backupId
= ptr
.p
->backupId
;
5021 conf
->backupPtr
= ptr
.i
;
5022 conf
->tableId
= tableId
;
5023 conf
->fragmentNo
= fragmentId
;
5024 conf
->noOfRecordsLow
= 0;
5025 conf
->noOfRecordsHigh
= 0;
5026 conf
->noOfBytesLow
= 0;
5027 conf
->noOfBytesHigh
= 0;
5028 sendSignal(ptr
.p
->masterRef
, GSN_BACKUP_FRAGMENT_CONF
, signal
,
5029 BackupFragmentConf::SignalLength
, JBB
);
5033 Backup::lcp_open_file(Signal
* signal
, BackupRecordPtr ptr
)
5035 FsOpenReq
* req
= (FsOpenReq
*)signal
->getDataPtrSend();
5036 req
->userReference
= reference();
5038 FsOpenReq::OM_WRITEONLY
|
5039 FsOpenReq::OM_TRUNCATE
|
5040 FsOpenReq::OM_CREATE
|
5041 FsOpenReq::OM_APPEND
|
5042 FsOpenReq::OM_AUTOSYNC
;
5043 if (c_defaults
.m_o_direct
)
5044 req
->fileFlags
|= FsOpenReq::OM_DIRECT
;
5045 FsOpenReq::v2_setCount(req
->fileNumber
, 0xFFFFFFFF);
5046 req
->auto_sync_size
= c_defaults
.m_disk_synch_size
;
5049 FragmentPtr fragPtr
;
5051 ndbrequire(ptr
.p
->tables
.first(tabPtr
));
5052 tabPtr
.p
->fragments
.getPtr(fragPtr
, 0);
5057 BackupFilePtr filePtr LINT_SET_PTR
;
5058 c_backupFilePool
.getPtr(filePtr
, ptr
.p
->dataFilePtr
);
5059 ndbrequire(filePtr
.p
->m_flags
== 0);
5060 filePtr
.p
->m_flags
|= BackupFile::BF_OPENING
;
5061 filePtr
.p
->tableId
= RNIL
; // Will force init
5062 req
->userPointer
= filePtr
.i
;
5063 FsOpenReq::setVersion(req
->fileNumber
, 5);
5064 FsOpenReq::setSuffix(req
->fileNumber
, FsOpenReq::S_DATA
);
5065 FsOpenReq::v5_setLcpNo(req
->fileNumber
, fragPtr
.p
->lcp_no
);
5066 FsOpenReq::v5_setTableId(req
->fileNumber
, tabPtr
.p
->tableId
);
5067 FsOpenReq::v5_setFragmentId(req
->fileNumber
, fragPtr
.p
->fragmentId
);
5068 sendSignal(NDBFS_REF
, GSN_FSOPENREQ
, signal
, FsOpenReq::SignalLength
, JBA
);
5072 Backup::lcp_open_file_done(Signal
* signal
, BackupRecordPtr ptr
)
5075 FragmentPtr fragPtr
;
5077 ndbrequire(ptr
.p
->tables
.first(tabPtr
));
5078 tabPtr
.p
->fragments
.getPtr(fragPtr
, 0);
5080 BackupFilePtr filePtr LINT_SET_PTR
;
5081 c_backupFilePool
.getPtr(filePtr
, ptr
.p
->dataFilePtr
);
5082 ndbrequire(filePtr
.p
->m_flags
==
5083 (BackupFile::BF_OPEN
| BackupFile::BF_LCP_META
));
5084 filePtr
.p
->m_flags
&= ~(Uint32
)BackupFile::BF_LCP_META
;
5086 ptr
.p
->slaveState
.setState(STARTED
);
5088 LcpPrepareConf
* conf
= (LcpPrepareConf
*)signal
->getDataPtrSend();
5089 conf
->senderData
= ptr
.p
->clientData
;
5090 conf
->senderRef
= reference();
5091 conf
->tableId
= tabPtr
.p
->tableId
;
5092 conf
->fragmentId
= fragPtr
.p
->fragmentId
;
5093 sendSignal(ptr
.p
->masterRef
, GSN_LCP_PREPARE_CONF
,
5094 signal
, LcpPrepareConf::SignalLength
, JBB
);
5099 filePtr
.p
->m_flags
|= BackupFile::BF_FILE_THREAD
;
5101 signal
->theData
[0] = BackupContinueB::START_FILE_THREAD
;
5102 signal
->theData
[1] = filePtr
.i
;
5103 signal
->theData
[2] = __LINE__
;
5104 sendSignalWithDelay(BACKUP_REF
, GSN_CONTINUEB
, signal
, 100, 3);
5108 Backup::execEND_LCPREQ(Signal
* signal
)
5110 EndLcpReq
* req
= (EndLcpReq
*)signal
->getDataPtr();
5112 BackupRecordPtr ptr LINT_SET_PTR
;
5113 c_backupPool
.getPtr(ptr
, req
->backupPtr
);
5114 ndbrequire(ptr
.p
->backupId
== req
->backupId
);
5116 BackupFilePtr filePtr LINT_SET_PTR
;
5117 ptr
.p
->files
.getPtr(filePtr
, ptr
.p
->ctlFilePtr
);
5118 ndbrequire(filePtr
.p
->m_flags
== 0);
5120 if (!ptr
.p
->tables
.isEmpty())
5123 ndbrequire(ptr
.p
->errorCode
);
5125 ptr
.p
->tables
.first(tabPtr
);
5126 tabPtr
.p
->attributes
.release();
5127 tabPtr
.p
->fragments
.release();
5128 ptr
.p
->tables
.release();
5129 ptr
.p
->errorCode
= 0;
5132 ptr
.p
->errorCode
= 0;
5133 ptr
.p
->slaveState
.setState(CLEANING
);
5134 ptr
.p
->slaveState
.setState(INITIAL
);
5135 ptr
.p
->slaveState
.setState(DEFINING
);
5136 ptr
.p
->slaveState
.setState(DEFINED
);
5138 EndLcpConf
* conf
= (EndLcpConf
*)signal
->getDataPtr();
5139 conf
->senderData
= ptr
.p
->clientData
;
5140 conf
->senderRef
= reference();
5141 sendSignal(ptr
.p
->masterRef
, GSN_END_LCPCONF
,
5142 signal
, EndLcpConf::SignalLength
, JBB
);