1
/* Copyright (C) 2003 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
19
#include <ndb_limits.h>
20
#include <SimulatedBlock.hpp>
22
#include "FsBuffer.hpp"
23
#include "BackupFormat.hpp"
25
#include <NodeBitmask.hpp>
26
#include <SimpleProperties.hpp>
29
#include <DLFifoList.hpp>
30
#include <DLCFifoList.hpp>
31
#include <SignalCounter.hpp>
32
#include <blocks/mutexes.hpp>
39
* Backup - This block manages database backup and restore
41
class Backup : public SimulatedBlock
44
Backup(Block_context& ctx);
46
BLOCK_DEFINES(Backup);
50
void execSTTOR(Signal* signal);
51
void execREAD_CONFIG_REQ(Signal* signal);
52
void execDUMP_STATE_ORD(Signal* signal);
53
void execREAD_NODESCONF(Signal* signal);
54
void execNODE_FAILREP(Signal* signal);
55
void execINCL_NODEREQ(Signal* signal);
56
void execCONTINUEB(Signal* signal);
61
void execBACKUP_REF(Signal* signal);
62
void execBACKUP_CONF(Signal* signal);
63
void execBACKUP_ABORT_REP(Signal* signal);
64
void execBACKUP_COMPLETE_REP(Signal* signal);
67
* Signals sent from master
69
void execDEFINE_BACKUP_REQ(Signal* signal);
70
void execBACKUP_DATA(Signal* signal);
71
void execSTART_BACKUP_REQ(Signal* signal);
72
void execBACKUP_FRAGMENT_REQ(Signal* signal);
73
void execBACKUP_FRAGMENT_COMPLETE_REP(Signal* signal);
74
void execSTOP_BACKUP_REQ(Signal* signal);
75
void execBACKUP_STATUS_REQ(Signal* signal);
76
void execABORT_BACKUP_ORD(Signal* signal);
81
void execSCAN_HBREP(Signal* signal);
82
void execTRANSID_AI(Signal* signal);
83
void execSCAN_FRAGREF(Signal* signal);
84
void execSCAN_FRAGCONF(Signal* signal);
89
void execBACKUP_TRIG_REQ(Signal* signal);
90
void execTRIG_ATTRINFO(Signal* signal);
91
void execFIRE_TRIG_ORD(Signal* signal);
96
void execLIST_TABLES_CONF(Signal* signal);
97
void execGET_TABINFOREF(Signal* signal);
98
void execGET_TABINFO_CONF(Signal* signal);
99
void execCREATE_TRIG_REF(Signal* signal);
100
void execCREATE_TRIG_CONF(Signal* signal);
101
void execDROP_TRIG_REF(Signal* signal);
102
void execDROP_TRIG_CONF(Signal* signal);
107
void execDI_FCOUNTCONF(Signal* signal);
108
void execDIGETPRIMCONF(Signal* signal);
113
void execFSOPENREF(Signal* signal);
114
void execFSOPENCONF(Signal* signal);
116
void execFSCLOSEREF(Signal* signal);
117
void execFSCLOSECONF(Signal* signal);
119
void execFSAPPENDREF(Signal* signal);
120
void execFSAPPENDCONF(Signal* signal);
122
void execFSREMOVEREF(Signal* signal);
123
void execFSREMOVECONF(Signal* signal);
126
* Master functinallity
128
void execBACKUP_REQ(Signal* signal);
129
void execABORT_BACKUP_REQ(Signal* signal);
131
void execDEFINE_BACKUP_REF(Signal* signal);
132
void execDEFINE_BACKUP_CONF(Signal* signal);
134
void execSTART_BACKUP_REF(Signal* signal);
135
void execSTART_BACKUP_CONF(Signal* signal);
137
void execBACKUP_FRAGMENT_REF(Signal* signal);
138
void execBACKUP_FRAGMENT_CONF(Signal* signal);
140
void execSTOP_BACKUP_REF(Signal* signal);
141
void execSTOP_BACKUP_CONF(Signal* signal);
143
void execBACKUP_STATUS_CONF(Signal* signal);
145
void execUTIL_SEQUENCE_REF(Signal* signal);
146
void execUTIL_SEQUENCE_CONF(Signal* signal);
148
void execWAIT_GCP_REF(Signal* signal);
149
void execWAIT_GCP_CONF(Signal* signal);
151
void execLCP_PREPARE_REQ(Signal* signal);
152
void execLCP_FRAGMENT_REQ(Signal*);
153
void execEND_LCPREQ(Signal* signal);
155
void defineBackupMutex_locked(Signal* signal, Uint32 ptrI,Uint32 retVal);
156
void dictCommitTableMutex_locked(Signal* signal, Uint32 ptrI,Uint32 retVal);
163
union { Uint32 prevList; Uint32 nextPool; };
165
typedef Ptr<Node> NodePtr;
167
#define BACKUP_WORDS_PER_PAGE 8191
169
Uint32 data[BACKUP_WORDS_PER_PAGE];
172
typedef Ptr<Page32> Page32Ptr;
183
Uint32 sz32; // No of 32 bit words
184
Uint32 offset; // Relative DataFixedAttributes/DataFixedKeys
185
Uint32 offsetNull; // In NullBitmask
193
typedef Ptr<Attribute> AttributePtr;
200
Uint8 scanned; // 0 = not scanned x = scanned by node x
201
Uint8 scanning; // 0 = not scanning x = scanning on node x
205
typedef Ptr<Fragment> FragmentPtr;
208
Table(ArrayPool<Attribute> &, ArrayPool<Fragment> &);
213
Uint32 schemaVersion;
216
Uint32 noOfAttributes;
218
Uint32 sz_FixedAttributes;
219
Uint32 triggerIds[3];
220
bool triggerAllocated[3];
222
DLFifoList<Attribute> attributes;
223
Array<Fragment> fragments;
226
union { Uint32 nextPool; Uint32 prevList; };
228
typedef Ptr<Table> TablePtr;
230
struct OperationRecord {
232
OperationRecord(Backup & b) : backup(b) {}
237
void init(const TablePtr & ptr);
242
bool newFragment(Uint32 tableId, Uint32 fragNo);
243
bool fragComplete(Uint32 tableId, Uint32 fragNo, bool fill_record);
246
* Once per scan frag (next) req/conf
249
bool scanConf(Uint32 noOfOps, Uint32 opLen);
255
void newRecord(Uint32 * base);
262
void nullAttribute(Uint32 nullOffset);
263
Uint32 * newNullable(Uint32 attrId, Uint32 sz);
264
Uint32 * newAttrib(Uint32 offset, Uint32 sz);
265
Uint32 * newVariable(Uint32 id, Uint32 sz);
271
Uint32* dst_FixedAttribs;
272
BackupFormat::DataFile::VariableData* dst_VariableData;
274
Uint32 noOfAttributes; // No of Attributes
275
Uint32 attrLeft; // No of attributes left
283
Uint32 attrSzTotal; // No of AI words received
284
Uint32 tablePtr; // Ptr.i to current table
289
Uint32 maxRecordSize;
299
Uint32 sz_FixedAttribs;
302
union { Uint32 nextPool; Uint32 nextList; };
307
BlockNumber number() const { return backup.number(); }
308
void progError(int line, int cause, const char * extra) {
309
backup.progError(line, cause, extra);
312
friend struct OperationRecord;
314
struct TriggerRecord {
315
TriggerRecord() { event = ~0;}
316
OperationRecord * operation;
317
BackupFormat::LogFile::LogEntry * logEntry;
318
Uint32 maxRecordSize;
324
union { Uint32 nextPool; Uint32 nextList; };
326
typedef Ptr<TriggerRecord> TriggerPtr;
329
* BackupFile - At least 3 per backup
332
BackupFile(Backup & backup, ArrayPool<Page32> & pp)
333
: operation(backup), pages(pp) {}
335
Uint32 backupPtr; // Pointer to backup record
340
BackupFormat::FileType fileType;
341
OperationRecord operation;
345
union { Uint32 prevList; Uint32 nextPool; };
351
,BF_FILE_THREAD = 0x8
352
,BF_SCAN_THREAD = 0x10
358
typedef Ptr<BackupFile> BackupFilePtr;
362
* State for BackupRecord
366
DEFINING = 1, // Defining backup content and parameters
367
DEFINED = 2, // DEFINE_BACKUP_CONF sent in slave, received all in master
368
STARTED = 3, // Creating triggers
369
SCANNING = 4, // Scanning fragments
370
STOPPING = 5, // Closing files
371
CLEANING = 6, // Cleaning resources
372
ABORTING = 7 // Aborting backup
375
static const Uint32 validSlaveTransitionsCount;
376
static const Uint32 validMasterTransitionsCount;
377
static const State validSlaveTransitions[];
378
static const State validMasterTransitions[];
380
class CompoundState {
382
CompoundState(Backup & b,
384
Uint32 count, Uint32 _id)
386
, validTransitions(valid),
387
noOfValidTransitions(count), id(_id)
393
void setState(State s);
394
State getState() const { return state;}
395
State getAbortState() const { return abortState;}
397
void forceState(State s);
399
BlockNumber number() const { return backup.number(); }
400
void progError(int line, int cause, const char * extra) {
401
backup.progError(line, cause, extra);
406
State abortState; /**
407
When state == ABORTING, this contains the state
408
when the abort started
410
const State * validTransitions;
411
const Uint32 noOfValidTransitions;
414
friend class CompoundState;
419
* One record per backup
421
struct BackupRecord {
422
BackupRecord(Backup& b,
423
ArrayPool<Table> & tp,
424
ArrayPool<BackupFile> & bp,
425
ArrayPool<TriggerRecord> & trp)
426
: slaveState(b, validSlaveTransitions, validSlaveTransitionsCount,1)
427
, tables(tp), triggers(trp), files(bp)
428
, ctlFilePtr(RNIL), logFilePtr(RNIL), dataFilePtr(RNIL)
429
, masterData(b), backup(b)
435
CompoundState slaveState;
445
NdbNodeBitmask nodes;
450
Uint64 noOfLogRecords;
455
DLCFifoList<Table> tables;
456
SLList<TriggerRecord> triggers;
458
SLList<BackupFile> files;
459
Uint32 ctlFilePtr; // Ptr.i to ctl-file
460
Uint32 logFilePtr; // Ptr.i to log-file
461
Uint32 dataFilePtr; // Ptr.i to first data-file
463
Uint32 backupDataLen; // Used for (un)packing backup request
464
SimpleProperties props;// Used for (un)packing backup request
467
SignalCounter trigSendCounter;
478
MasterData(Backup & b)
481
MutexHandle2<BACKUP_DEFINE_MUTEX> m_defineBackupMutex;
482
MutexHandle2<DICT_COMMIT_TABLE_MUTEX> m_dictCommitTableMutex;
485
SignalCounter sendCounter;
503
union { Uint32 prevList; Uint32 nextPool; };
505
void setErrorCode(Uint32 errCode){
510
bool checkError() const {
511
return errorCode != 0;
514
bool is_lcp() const {
515
return backupDataLen == ~(Uint32)0;
519
BlockNumber number() const { return backup.number(); }
520
void progError(int line, int cause, const char * extra) {
521
backup.progError(line, cause, extra);
524
friend struct BackupRecord;
525
typedef Ptr<BackupRecord> BackupRecordPtr;
528
Uint32 m_dataBufferSize;
529
Uint32 m_logBufferSize;
530
Uint32 m_minWriteSize;
531
Uint32 m_maxWriteSize;
532
Uint32 m_lcp_buffer_size;
534
Uint32 m_disk_write_speed_sr;
535
Uint32 m_disk_write_speed;
536
Uint32 m_disk_synch_size;
544
Uint32 * c_startOfPages;
545
NodeId c_masterNodeId;
546
SLList<Node> c_nodes;
547
NdbNodeBitmask c_aliveNodes;
548
DLList<BackupRecord> c_backups;
552
Variables that control checkpoint to disk speed
554
Uint32 m_curr_disk_write_speed;
555
Uint32 m_words_written_this_period;
556
Uint32 m_overflow_disk_write;
557
Uint32 m_reset_delay_used;
558
NDB_TICKS m_reset_disk_speed_time;
559
static const int DISK_SPEED_CHECK_DELAY = 100;
561
STATIC_CONST(NO_OF_PAGES_META_FILE =
562
(2*MAX_WORDS_META_FILE + BACKUP_WORDS_PER_PAGE - 1) /
563
BACKUP_WORDS_PER_PAGE);
568
ArrayPool<Table> c_tablePool;
569
ArrayPool<Attribute> c_attributePool;
570
ArrayPool<BackupRecord> c_backupPool;
571
ArrayPool<BackupFile> c_backupFilePool;
572
ArrayPool<Page32> c_pagePool;
573
ArrayPool<Fragment> c_fragmentPool;
574
ArrayPool<Node> c_nodePool;
575
ArrayPool<TriggerRecord> c_triggerPool;
577
void checkFile(Signal*, BackupFilePtr);
578
void checkScan(Signal*, BackupFilePtr);
579
void fragmentCompleted(Signal*, BackupFilePtr);
581
void backupAllData(Signal* signal, BackupRecordPtr);
583
void getFragmentInfo(Signal*, BackupRecordPtr, TablePtr, Uint32 fragNo);
584
void getFragmentInfoDone(Signal*, BackupRecordPtr);
586
void openFiles(Signal* signal, BackupRecordPtr ptr);
587
void openFilesReply(Signal*, BackupRecordPtr ptr, BackupFilePtr);
588
void closeFiles(Signal*, BackupRecordPtr ptr);
589
void closeFile(Signal*, BackupRecordPtr, BackupFilePtr);
590
void closeFilesDone(Signal*, BackupRecordPtr ptr);
592
void sendDefineBackupReq(Signal *signal, BackupRecordPtr ptr);
594
void defineBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId);
595
void createTrigReply(Signal* signal, BackupRecordPtr ptr);
596
void alterTrigReply(Signal* signal, BackupRecordPtr ptr);
597
void startBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32);
598
void stopBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId);
600
void defineBackupRef(Signal*, BackupRecordPtr, Uint32 errCode = 0);
601
void backupFragmentRef(Signal * signal, BackupFilePtr filePtr);
603
void nextFragment(Signal*, BackupRecordPtr);
605
void sendCreateTrig(Signal*, BackupRecordPtr ptr, TablePtr tabPtr);
606
void createAttributeMask(TablePtr tab, Bitmask<MAXNROFATTRIBUTESINWORDS>&);
607
void sendStartBackup(Signal*, BackupRecordPtr, TablePtr);
608
void sendAlterTrig(Signal*, BackupRecordPtr ptr);
610
void sendDropTrig(Signal*, BackupRecordPtr ptr);
611
void sendDropTrig(Signal* signal, BackupRecordPtr ptr, TablePtr tabPtr);
612
void dropTrigReply(Signal*, BackupRecordPtr ptr);
614
void sendSignalAllWait(BackupRecordPtr ptr, Uint32 gsn, Signal *signal,
616
bool executeDirect = false);
617
bool haveAllSignals(BackupRecordPtr ptr, Uint32 gsn, Uint32 nodeId);
619
void sendStopBackup(Signal*, BackupRecordPtr ptr);
620
void sendAbortBackupOrd(Signal* signal, BackupRecordPtr ptr, Uint32 errCode);
621
void sendAbortBackupOrdSlave(Signal* signal, BackupRecordPtr ptr,
623
void masterAbort(Signal*, BackupRecordPtr ptr);
624
void masterSendAbortBackup(Signal*, BackupRecordPtr ptr);
625
void slaveAbort(Signal*, BackupRecordPtr ptr);
627
void abortFile(Signal* signal, BackupRecordPtr ptr, BackupFilePtr filePtr);
628
void abortFileHook(Signal* signal, BackupFilePtr filePtr, bool scanDone);
630
bool verifyNodesAlive(BackupRecordPtr, const NdbNodeBitmask& aNodeBitMask);
631
bool checkAbort(BackupRecordPtr ptr);
632
void checkNodeFail(Signal* signal,
635
Uint32 theFailedNodes[NodeBitmask::Size]);
636
void masterTakeOver(Signal* signal, BackupRecordPtr ptr);
639
NodeId getMasterNodeId() const { return c_masterNodeId; }
640
bool findTable(const BackupRecordPtr &, TablePtr &, Uint32 tableId) const;
641
bool parseTableDescription(Signal*, BackupRecordPtr ptr, TablePtr, const Uint32*, Uint32);
643
bool insertFileHeader(BackupFormat::FileType, BackupRecord*, BackupFile*);
644
void sendBackupRef(Signal* signal, BackupRecordPtr ptr, Uint32 errorCode);
645
void sendBackupRef(BlockReference ref, Uint32 flags, Signal *signal,
646
Uint32 senderData, Uint32 errorCode);
647
void dumpUsedResources();
648
void cleanup(Signal*, BackupRecordPtr ptr);
649
void abort_scan(Signal*, BackupRecordPtr ptr);
650
void removeBackup(Signal*, BackupRecordPtr ptr);
652
void sendSTTORRY(Signal*);
653
void createSequence(Signal* signal);
654
void createSequenceReply(Signal*, class UtilSequenceConf *);
656
void lcp_open_file(Signal* signal, BackupRecordPtr ptr);
657
void lcp_open_file_done(Signal*, BackupRecordPtr);
658
void lcp_close_file_conf(Signal* signal, BackupRecordPtr);
660
bool ready_to_write(bool ready, Uint32 sz, bool eof, BackupFile *fileP);
665
Backup::OperationRecord::newRecord(Uint32 * p){
667
dst_Length = p; p += 1;
668
dst_Bitmask = p; p += sz_Bitmask;
669
dst_FixedAttribs = p; p += sz_FixedAttribs;
670
dst_VariableData = (BackupFormat::DataFile::VariableData*)p;
671
BitmaskImpl::clear(sz_Bitmask, dst_Bitmask);
672
attrLeft = noOfAttributes;
678
Backup::OperationRecord::newAttrib(Uint32 offset, Uint32 sz){
680
dst = dst_FixedAttribs + offset;
686
Backup::OperationRecord::nullAttribute(Uint32 offsetNull){
688
BitmaskImpl::set(sz_Bitmask, dst_Bitmask, offsetNull);
693
Backup::OperationRecord::nullVariable()
700
Backup::OperationRecord::newNullable(Uint32 id, Uint32 sz){
701
Uint32 sz32 = (sz + 3) >> 2;
705
dst = &dst_VariableData->Data[0];
706
dst_VariableData->Sz = htonl(sz);
707
dst_VariableData->Id = htonl(id);
709
dst_VariableData = (BackupFormat::DataFile::VariableData *)(dst + sz32);
711
// Clear all bits on newRecord -> dont need to clear this
712
// BitmaskImpl::clear(sz_Bitmask, dst_Bitmask, offsetNull);
718
Backup::OperationRecord::newVariable(Uint32 id, Uint32 sz){
719
Uint32 sz32 = (sz + 3) >> 2;
723
dst = &dst_VariableData->Data[0];
724
dst_VariableData->Sz = htonl(sz);
725
dst_VariableData->Id = htonl(id);
727
dst_VariableData = (BackupFormat::DataFile::VariableData *)(dst + sz32);
733
Backup::OperationRecord::finished(){
738
opLen += attrSzTotal;
741
scanStop = dst = (Uint32 *)dst_VariableData;
743
const Uint32 len = (dst - base - 1);
744
* dst_Length = htonl(len);