MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Backup.hpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #ifndef BACKUP_H
19 #define BACKUP_H
20 
21 #include <ndb_limits.h>
22 #include <SimulatedBlock.hpp>
23 
24 #include "FsBuffer.hpp"
25 #include "BackupFormat.hpp"
26 
27 #include <NodeBitmask.hpp>
28 #include <SimpleProperties.hpp>
29 
30 #include <SLList.hpp>
31 #include <DLFifoList.hpp>
32 #include <DLCFifoList.hpp>
33 #include <SignalCounter.hpp>
34 #include <blocks/mutexes.hpp>
35 
36 #include <NdbTCP.h>
37 #include <NdbTick.h>
38 #include <Array.hpp>
39 
43 class Backup : public SimulatedBlock
44 {
45  friend class BackupProxy;
46 
47 public:
48  Backup(Block_context& ctx, Uint32 instanceNumber = 0);
49  virtual ~Backup();
50  BLOCK_DEFINES(Backup);
51 
52 protected:
53 
54  void execSTTOR(Signal* signal);
55  void execREAD_CONFIG_REQ(Signal* signal);
56  void execDUMP_STATE_ORD(Signal* signal);
57  void execREAD_NODESCONF(Signal* signal);
58  void execNODE_FAILREP(Signal* signal);
59  void execINCL_NODEREQ(Signal* signal);
60  void execCONTINUEB(Signal* signal);
61 
65  void execBACKUP_REF(Signal* signal);
66  void execBACKUP_CONF(Signal* signal);
67  void execBACKUP_ABORT_REP(Signal* signal);
68  void execBACKUP_COMPLETE_REP(Signal* signal);
69 
73  void execDEFINE_BACKUP_REQ(Signal* signal);
74  void execBACKUP_DATA(Signal* signal);
75  void execSTART_BACKUP_REQ(Signal* signal);
76  void execBACKUP_FRAGMENT_REQ(Signal* signal);
77  void execBACKUP_FRAGMENT_COMPLETE_REP(Signal* signal);
78  void execSTOP_BACKUP_REQ(Signal* signal);
79  void execBACKUP_STATUS_REQ(Signal* signal);
80  void execABORT_BACKUP_ORD(Signal* signal);
81 
85  void execSCAN_HBREP(Signal* signal);
86  void execTRANSID_AI(Signal* signal);
87  void execSCAN_FRAGREF(Signal* signal);
88  void execSCAN_FRAGCONF(Signal* signal);
89 
93  void execBACKUP_TRIG_REQ(Signal* signal);
94  void execTRIG_ATTRINFO(Signal* signal);
95  void execFIRE_TRIG_ORD(Signal* signal);
96 
100  void execLIST_TABLES_CONF(Signal* signal);
101  void execGET_TABINFOREF(Signal* signal);
102  void execGET_TABINFO_CONF(Signal* signal);
103  void execCREATE_TRIG_IMPL_REF(Signal* signal);
104  void execCREATE_TRIG_IMPL_CONF(Signal* signal);
105  void execDROP_TRIG_IMPL_REF(Signal* signal);
106  void execDROP_TRIG_IMPL_CONF(Signal* signal);
107 
111  void execDIH_SCAN_TAB_CONF(Signal* signal);
112  void execDIH_SCAN_GET_NODES_CONF(Signal* signal);
113 
117  void execFSOPENREF(Signal* signal);
118  void execFSOPENCONF(Signal* signal);
119 
120  void execFSCLOSEREF(Signal* signal);
121  void execFSCLOSECONF(Signal* signal);
122 
123  void execFSAPPENDREF(Signal* signal);
124  void execFSAPPENDCONF(Signal* signal);
125 
126  void execFSREMOVEREF(Signal* signal);
127  void execFSREMOVECONF(Signal* signal);
128 
132  void execBACKUP_REQ(Signal* signal);
133  void execABORT_BACKUP_REQ(Signal* signal);
134 
135  void execDEFINE_BACKUP_REF(Signal* signal);
136  void execDEFINE_BACKUP_CONF(Signal* signal);
137 
138  void execSTART_BACKUP_REF(Signal* signal);
139  void execSTART_BACKUP_CONF(Signal* signal);
140 
141  void execBACKUP_FRAGMENT_REF(Signal* signal);
142  void execBACKUP_FRAGMENT_CONF(Signal* signal);
143 
144  void execSTOP_BACKUP_REF(Signal* signal);
145  void execSTOP_BACKUP_CONF(Signal* signal);
146 
147  void execBACKUP_STATUS_CONF(Signal* signal);
148 
149  void execUTIL_SEQUENCE_REF(Signal* signal);
150  void execUTIL_SEQUENCE_CONF(Signal* signal);
151 
152  void execWAIT_GCP_REF(Signal* signal);
153  void execWAIT_GCP_CONF(Signal* signal);
154  void execBACKUP_LOCK_TAB_CONF(Signal *signal);
155  void execBACKUP_LOCK_TAB_REF(Signal *signal);
156 
157  void execLCP_PREPARE_REQ(Signal* signal);
158  void execLCP_FRAGMENT_REQ(Signal*);
159  void execEND_LCPREQ(Signal* signal);
160 
161  void execDBINFO_SCANREQ(Signal *signal);
162 
163 private:
164  void defineBackupMutex_locked(Signal* signal, Uint32 ptrI,Uint32 retVal);
165  void dictCommitTableMutex_locked(Signal* signal, Uint32 ptrI,Uint32 retVal);
166 
167 public:
168  struct Node {
169  Uint32 nodeId;
170  Uint32 alive;
171  Uint32 nextList;
172  union { Uint32 prevList; Uint32 nextPool; };
173  };
174  typedef Ptr<Node> NodePtr;
175 
176 #define BACKUP_WORDS_PER_PAGE 8191
177  struct Page32 {
178  union {
179  Uint32 data[BACKUP_WORDS_PER_PAGE];
180  Uint32 chunkSize;
181  Uint32 nextChunk;
182  Uint32 lastChunk;
183  };
184  Uint32 nextPool;
185  };
186  typedef Ptr<Page32> Page32Ptr;
187 
188  struct Fragment {
189  Uint64 noOfRecords;
190  Uint32 tableId;
191  Uint16 node;
192  Uint16 fragmentId;
193  Uint8 lqhInstanceKey;
194  Uint8 scanned; // 0 = not scanned x = scanned by node x
195  Uint8 scanning; // 0 = not scanning x = scanning on node x
196  Uint8 lcp_no;
197  union {
198  Uint32 nextPool;
199  Uint32 chunkSize;
200  Uint32 nextChunk;
201  Uint32 lastChunk;
202  };
203  };
204  typedef Ptr<Fragment> FragmentPtr;
205 
206  struct Table {
208 
209  Uint64 noOfRecords;
210 
211  Uint32 tableId;
212  Uint32 schemaVersion;
213  Uint32 tableType;
214  Uint32 m_scan_cookie;
215  Uint32 triggerIds[3];
216  bool triggerAllocated[3];
217  Uint32 maxRecordSize;
218  Uint32 attrInfoLen;
219  Uint32 noOfAttributes;
223  Uint32 attrInfo[1+MAXNROFATTRIBUTESINWORDS+3];
224 
225  Array<Fragment> fragments;
226 
227  Uint32 nextList;
228  union { Uint32 nextPool; Uint32 prevList; };
229  };
230  typedef Ptr<Table> TablePtr;
231 
233  public:
234  OperationRecord(Backup & b) : backup(b) {}
235 
239  void init(const TablePtr & ptr);
240 
244  bool newFragment(Uint32 tableId, Uint32 fragNo);
245  bool fragComplete(Uint32 tableId, Uint32 fragNo, bool fill_record);
246 
250  bool newScan();
251  bool scanConf(Uint32 noOfOps, Uint32 opLen);
252  bool closeScan();
253 
257  void newRecord(Uint32 * base);
258  void finished(Uint32 len);
259 
260  private:
261  Uint32* base;
262  Uint32 opNoDone;
263  Uint32 opNoConf;
264  Uint32 opLen;
265 
266  public:
267  Uint32* dst;
268  Uint32 attrSzTotal; // No of AI words received
269  Uint32 tablePtr; // Ptr.i to current table
270 
271  FsBuffer dataBuffer;
272  Uint64 noOfRecords;
273  Uint64 noOfBytes;
274  Uint32 maxRecordSize;
275 
276  /*
277  keeps track of total written into backup file to be able to show
278  backup status
279  */
280  Uint64 m_records_total;
281  Uint64 m_bytes_total;
282 
283  private:
284  Uint32* scanStart;
285  Uint32* scanStop;
286 
287  public:
288  union { Uint32 nextPool; Uint32 nextList; };
289  Uint32 prevList;
290  private:
291 
292  Backup & backup;
293  BlockNumber number() const { return backup.number(); }
294  EmulatedJamBuffer *jamBuffer() const { return backup.jamBuffer(); }
295  void progError(int line, int cause, const char * extra) {
296  backup.progError(line, cause, extra);
297  }
298  };
299  friend struct OperationRecord;
300 
301  struct TriggerRecord {
302  TriggerRecord() { event = ~0;}
303  OperationRecord * operation;
305  Uint32 maxRecordSize;
306  Uint32 tableId;
307  Uint32 tab_ptr_i;
308  Uint32 event;
309  Uint32 backupPtr;
310  Uint32 errorCode;
311  union { Uint32 nextPool; Uint32 nextList; };
312  };
314 
318  struct BackupFile {
319  BackupFile(Backup & backup, ArrayPool<Page32> & pp)
320  : operation(backup), pages(pp) { m_retry_count = 0; }
321 
322  Uint32 backupPtr; // Pointer to backup record
323  Uint32 tableId;
324  Uint32 fragmentNo;
325  Uint32 filePointer;
326  Uint32 m_retry_count;
327  Uint32 errorCode;
328  BackupFormat::FileType fileType;
329  OperationRecord operation;
330 
331  Array<Page32> pages;
332  Uint32 nextList;
333  union { Uint32 prevList; Uint32 nextPool; };
334 
335  enum {
336  BF_OPEN = 0x1
337  ,BF_OPENING = 0x2
338  ,BF_CLOSING = 0x4
339  ,BF_FILE_THREAD = 0x8
340  ,BF_SCAN_THREAD = 0x10
341  ,BF_LCP_META = 0x20
342  };
343  Uint32 m_flags;
344  Uint32 m_pos;
345  };
347 
348 
352  enum State {
353  INITIAL = 0,
354  DEFINING = 1, // Defining backup content and parameters
355  DEFINED = 2, // DEFINE_BACKUP_CONF sent in slave, received all in master
356  STARTED = 3, // Creating triggers
357  SCANNING = 4, // Scanning fragments
358  STOPPING = 5, // Closing files
359  CLEANING = 6, // Cleaning resources
360  ABORTING = 7 // Aborting backup
361  };
362 
363  static const Uint32 validSlaveTransitionsCount;
364  static const Uint32 validMasterTransitionsCount;
365  static const State validSlaveTransitions[];
366  static const State validMasterTransitions[];
367 
369  public:
370  CompoundState(Backup & b,
371  const State valid[],
372  Uint32 count, Uint32 _id)
373  : backup(b)
374  , validTransitions(valid),
375  noOfValidTransitions(count), id(_id)
376  {
377  state = INITIAL;
378  abortState = state;
379  }
380 
381  void setState(State s);
382  State getState() const { return state;}
383  State getAbortState() const { return abortState;}
384 
385  void forceState(State s);
386 
387  BlockNumber number() const { return backup.number(); }
388  EmulatedJamBuffer *jamBuffer() const { return backup.jamBuffer(); }
389  void progError(int line, int cause, const char * extra) {
390  backup.progError(line, cause, extra);
391  }
392  private:
393  Backup & backup;
394  State state;
395  State abortState;
399  const State * validTransitions;
400  const Uint32 noOfValidTransitions;
401  const Uint32 id;
402  };
403  friend class CompoundState;
404 
410  struct BackupRecord {
411  BackupRecord(Backup& b,
412  ArrayPool<Table> & tp,
415  : slaveState(b, validSlaveTransitions, validSlaveTransitionsCount,1)
416  , tables(tp), triggers(trp), files(bp)
417  , ctlFilePtr(RNIL), logFilePtr(RNIL), dataFilePtr(RNIL)
418  , masterData(b), backup(b)
419 
420  {
421  /*
422  report of backup status uses these variables to keep track
423  if backup ia running and current state
424  */
425  m_gsn = 0;
426  masterData.gsn = 0;
427  }
428 
429  /* next time to report backup status */
430  Uint64 m_next_report;
431 
432  Uint32 m_gsn;
433  CompoundState slaveState;
434 
435  Uint32 clientRef;
436  Uint32 clientData;
437  Uint32 flags;
438  Uint32 signalNo;
439  Uint32 backupId;
440  Uint32 backupKey[2];
441  Uint32 masterRef;
442  Uint32 errorCode;
443  NdbNodeBitmask nodes;
444 
445  Uint64 noOfBytes;
446  Uint64 noOfRecords;
447  Uint64 noOfLogBytes;
448  Uint64 noOfLogRecords;
449 
450  Uint32 startGCP;
451  Uint32 currGCP;
452  Uint32 stopGCP;
453  DLCFifoList<Table> tables;
454  SLList<TriggerRecord> triggers;
455 
456  SLList<BackupFile> files;
457  Uint32 ctlFilePtr; // Ptr.i to ctl-file
458  Uint32 logFilePtr; // Ptr.i to log-file
459  Uint32 dataFilePtr; // Ptr.i to first data-file
460 
461  Uint32 backupDataLen; // Used for (un)packing backup request
462  SimpleProperties props;// Used for (un)packing backup request
463 
464  struct SlaveData {
465  SignalCounter trigSendCounter;
466  Uint32 gsn;
467  struct {
468  Uint32 tableId;
469  } createTrig;
470  struct {
471  Uint32 tableId;
472  } dropTrig;
473  } slaveData;
474 
475  struct MasterData {
476  MasterData(Backup & b)
477  {
478  }
479  MutexHandle2<BACKUP_DEFINE_MUTEX> m_defineBackupMutex;
480  MutexHandle2<DICT_COMMIT_TABLE_MUTEX> m_dictCommitTableMutex;
481 
482  Uint32 gsn;
483  SignalCounter sendCounter;
484  Uint32 errorCode;
485  union {
486  struct {
487  Uint32 retriesLeft;
488  } sequence;
489  struct {
490  Uint32 startBackup;
491  } waitGCP;
492  struct {
493  Uint32 signalNo;
494  Uint32 noOfSignals;
495  Uint32 tablePtr;
496  } startBackup;
497  struct {
498  Uint32 dummy;
499  } stopBackup;
500  };
501  } masterData;
502 
503  Uint32 nextList;
504  union { Uint32 prevList; Uint32 nextPool; };
505 
506  void setErrorCode(Uint32 errCode){
507  if(errorCode == 0)
508  errorCode = errCode;
509  }
510 
511  bool checkError() const {
512  return errorCode != 0;
513  }
514 
515  bool is_lcp() const {
516  return backupDataLen == ~(Uint32)0;
517  }
518 
519  Backup & backup;
520  BlockNumber number() const { return backup.number(); }
521  EmulatedJamBuffer *jamBuffer() const { return backup.jamBuffer(); }
522  void progError(int line, int cause, const char * extra) {
523  backup.progError(line, cause, extra);
524  }
525  };
526  friend struct BackupRecord;
527  typedef Ptr<BackupRecord> BackupRecordPtr;
528 
529  struct Config {
530  Uint32 m_dataBufferSize;
531  Uint32 m_logBufferSize;
532  Uint32 m_minWriteSize;
533  Uint32 m_maxWriteSize;
534  Uint32 m_lcp_buffer_size;
535 
536  Uint32 m_disk_write_speed_sr;
537  Uint32 m_disk_write_speed;
538  Uint32 m_disk_synch_size;
539  Uint32 m_diskless;
540  Uint32 m_o_direct;
541  Uint32 m_compressed_backup;
542  Uint32 m_compressed_lcp;
543  };
544 
548  Uint32 * c_startOfPages;
549  NodeId c_masterNodeId;
550  SLList<Node> c_nodes;
551  NdbNodeBitmask c_aliveNodes;
552  DLList<BackupRecord> c_backups;
553  Config c_defaults;
554 
555  /*
556  Variables that control checkpoint to disk speed
557  */
558  Uint32 m_curr_disk_write_speed;
559  Uint32 m_words_written_this_period;
560  Uint32 m_overflow_disk_write;
561  Uint32 m_reset_delay_used;
562  NDB_TICKS m_reset_disk_speed_time;
563  static const int DISK_SPEED_CHECK_DELAY = 100;
564 
565  STATIC_CONST(NO_OF_PAGES_META_FILE =
566  (2*MAX_WORDS_META_FILE + BACKUP_WORDS_PER_PAGE - 1) /
567  BACKUP_WORDS_PER_PAGE);
568 
569  Uint32 m_backup_report_frequency;
570 
575  ArrayPool<BackupRecord> c_backupPool;
576  ArrayPool<BackupFile> c_backupFilePool;
577  ArrayPool<Page32> c_pagePool;
578  ArrayPool<Fragment> c_fragmentPool;
579  ArrayPool<Node> c_nodePool;
580  ArrayPool<TriggerRecord> c_triggerPool;
581 
582  void checkFile(Signal*, BackupFilePtr);
584  void fragmentCompleted(Signal*, BackupFilePtr);
585 
586  void backupAllData(Signal* signal, BackupRecordPtr);
587 
588  void getFragmentInfo(Signal*, BackupRecordPtr, TablePtr, Uint32 fragNo);
589  void getFragmentInfoDone(Signal*, BackupRecordPtr);
590 
591  void openFiles(Signal* signal, BackupRecordPtr ptr);
593  void closeFiles(Signal*, BackupRecordPtr ptr);
594  void closeFile(Signal*, BackupRecordPtr, BackupFilePtr);
595  void closeFilesDone(Signal*, BackupRecordPtr ptr);
596 
597  void sendDefineBackupReq(Signal *signal, BackupRecordPtr ptr);
598 
599  void defineBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId);
600  void createTrigReply(Signal* signal, BackupRecordPtr ptr);
601  void alterTrigReply(Signal* signal, BackupRecordPtr ptr);
602  void startBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32);
603  void stopBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId);
604 
605  void defineBackupRef(Signal*, BackupRecordPtr, Uint32 errCode = 0);
606  void backupFragmentRef(Signal * signal, BackupFilePtr filePtr);
607 
609 
610  void sendCreateTrig(Signal*, BackupRecordPtr ptr, TablePtr tabPtr);
611  void createAttributeMask(TablePtr tab, Bitmask<MAXNROFATTRIBUTESINWORDS>&);
613  void sendAlterTrig(Signal*, BackupRecordPtr ptr);
614 
615  void sendScanFragReq(Signal*,
618  TablePtr,
619  FragmentPtr,
620  Uint32 delay);
621 
622  void sendDropTrig(Signal*, BackupRecordPtr ptr);
623  void sendDropTrig(Signal* signal, BackupRecordPtr ptr, TablePtr tabPtr);
624  void dropTrigReply(Signal*, BackupRecordPtr ptr);
625 
626  void sendSignalAllWait(BackupRecordPtr ptr, Uint32 gsn, Signal *signal,
627  Uint32 signalLength,
628  bool executeDirect = false);
629  bool haveAllSignals(BackupRecordPtr ptr, Uint32 gsn, Uint32 nodeId);
630 
631  void sendStopBackup(Signal*, BackupRecordPtr ptr);
632  void sendAbortBackupOrd(Signal* signal, BackupRecordPtr ptr, Uint32 errCode);
633  void sendAbortBackupOrdSlave(Signal* signal, BackupRecordPtr ptr,
634  Uint32 errCode);
635  void masterAbort(Signal*, BackupRecordPtr ptr);
636  void masterSendAbortBackup(Signal*, BackupRecordPtr ptr);
637  void slaveAbort(Signal*, BackupRecordPtr ptr);
638 
639  void abortFile(Signal* signal, BackupRecordPtr ptr, BackupFilePtr filePtr);
640  void abortFileHook(Signal* signal, BackupFilePtr filePtr, bool scanDone);
641 
642  bool verifyNodesAlive(BackupRecordPtr, const NdbNodeBitmask& aNodeBitMask);
643  bool checkAbort(BackupRecordPtr ptr);
644  void checkNodeFail(Signal* signal,
645  BackupRecordPtr ptr,
646  NodeId newCoord,
647  Uint32 theFailedNodes[NdbNodeBitmask::Size]);
648  void masterTakeOver(Signal* signal, BackupRecordPtr ptr);
649 
650 
651  NodeId getMasterNodeId() const { return c_masterNodeId; }
652  bool findTable(const BackupRecordPtr &, TablePtr &, Uint32 tableId) const;
653  bool parseTableDescription(Signal*, BackupRecordPtr ptr, TablePtr, const Uint32*, Uint32);
654 
655  bool insertFileHeader(BackupFormat::FileType, BackupRecord*, BackupFile*);
656  void sendBackupRef(Signal* signal, BackupRecordPtr ptr, Uint32 errorCode);
657  void sendBackupRef(BlockReference ref, Uint32 flags, Signal *signal,
658  Uint32 senderData, Uint32 errorCode);
659  void dumpUsedResources();
660  void cleanup(Signal*, BackupRecordPtr ptr);
661  void abort_scan(Signal*, BackupRecordPtr ptr);
662  void removeBackup(Signal*, BackupRecordPtr ptr);
663 
664  void sendUtilSequenceReq(Signal*, BackupRecordPtr ptr, Uint32 delay = 0);
665 
666  /*
667  For periodic backup status reporting and explicit backup status reporting
668  */
669  /* Init at start of backup, timers etc... */
670  void initReportStatus(Signal* signal, BackupRecordPtr ptr);
671  /* Sheck timers for reporting at certain points */
672  void checkReportStatus(Signal* signal, BackupRecordPtr ptr);
673  /* Send backup status, invoked either periodically, or explicitly */
674  void reportStatus(Signal* signal, BackupRecordPtr ptr,
675  BlockReference ref = CMVMI_REF);
676 
677  void sendSTTORRY(Signal*);
678  void createSequence(Signal* signal);
679  void createSequenceReply(Signal*, class UtilSequenceConf *);
680 
681  void lcp_open_file(Signal* signal, BackupRecordPtr ptr);
682  void lcp_open_file_done(Signal*, BackupRecordPtr);
683  void lcp_close_file_conf(Signal* signal, BackupRecordPtr);
684  void read_lcp_descriptor(Signal*, BackupRecordPtr, TablePtr);
685 
686  bool ready_to_write(bool ready, Uint32 sz, bool eof, BackupFile *fileP);
687 
688  void afterGetTabinfoLockTab(Signal *signal,
689  BackupRecordPtr ptr, TablePtr tabPtr);
690  void cleanupNextTable(Signal *signal, BackupRecordPtr ptr, TablePtr tabPtr);
691 
692  BackupFormat::LogFile::LogEntry* get_log_buffer(Signal*,TriggerPtr, Uint32);
693 
694  /*
695  * MT LQH. LCP runs separately in each instance number.
696  * BACKUP uses instance key 1 (real instance 0 or 1).
697  */
698  STATIC_CONST( UserBackupInstanceKey = 1 );
699  Uint32 instanceKey(BackupRecordPtr ptr) {
700  return ptr.p->is_lcp() ? instance() : UserBackupInstanceKey;
701  }
702 };
703 
704 inline
705 void
707 {
708  dst = p;
709  scanStop = p;
710 }
711 
712 inline
713 void
714 Backup::OperationRecord::finished(Uint32 len)
715 {
716  opLen += len;
717  opNoDone++;
718  noOfRecords++;
719 }
720 
721 #endif