1 /* Copyright (c) 2003-2007 MySQL AB
2    Use is subject to license terms
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 Street, Fifth Floor, Boston, MA  02110-1301, USA */
16 
17 #ifndef RESTORE_H
18 #define RESTORE_H
19 
20 #include <ndb_global.h>
21 #include <NdbOut.hpp>
22 #include "../src/kernel/blocks/backup/BackupFormat.hpp"
23 #include "../src/ndbapi/NdbDictionaryImpl.hpp"
24 #include <NdbApi.hpp>
25 
26 #include <ndb_version.h>
27 #include <version.h>
28 
29 const int FileNameLenC = 256;
30 const int TableNameLenC = 256;
31 const int AttrNameLenC = 256;
32 const Uint32 timeToWaitForNdbC = 10000;
33 const Uint32 opsDefaultC = 1000;
34 
35 // Forward declarations
36 //class AttributeDesc;
37 struct AttributeDesc;
38 struct AttributeData;
39 struct AttributeS;
40 
41 struct AttributeData {
42   bool null;
43   Uint32 size;
44   union {
45     Int8 * int8_value;
46     Uint8 * u_int8_value;
47 
48     Int16 * int16_value;
49     Uint16 * u_int16_value;
50 
51     Int32 * int32_value;
52     Uint32 * u_int32_value;
53 
54     Int64 * int64_value;
55     Uint64 * u_int64_value;
56 
57     char * string_value;
58 
59     void* void_value;
60   };
61 };
62 
63 struct AttributeDesc {
64   //private:
65   friend class TupleS;
66   friend class TableS;
67   friend class RestoreDataIterator;
68   friend class RestoreMetaData;
69   friend struct AttributeS;
70   Uint32 size; // bits
71   Uint32 arraySize;
72   Uint32 attrId;
73   NdbDictionary::Column *m_column;
74 
75   Uint32 m_nullBitIndex;
76 public:
77 
78   AttributeDesc(NdbDictionary::Column *column);
79   AttributeDesc();
80 
getSizeInWordsAttributeDesc81   Uint32 getSizeInWords() const { return (size * arraySize + 31)/ 32;}
82 }; // AttributeDesc
83 
84 struct AttributeS {
85   const AttributeDesc * Desc;
86   AttributeData Data;
87 };
88 
89 class TupleS {
90 private:
91   friend class RestoreDataIterator;
92 
93   class TableS *m_currentTable;
94   AttributeData *allAttrData;
95   bool prepareRecord(TableS &);
96 
97 public:
TupleS()98   TupleS() {
99     m_currentTable= 0;
100     allAttrData= 0;
101   };
~TupleS()102   ~TupleS()
103   {
104     if (allAttrData)
105       delete [] allAttrData;
106   };
107   TupleS(const TupleS& tuple); // disable copy constructor
108   TupleS & operator=(const TupleS& tuple);
109   int getNoOfAttributes() const;
110   TableS * getTable() const;
111   const AttributeDesc * getDesc(int i) const;
112   AttributeData * getData(int i) const;
113 }; // class TupleS
114 
115 struct FragmentInfo
116 {
117   Uint32 fragmentNo;
118   Uint64 noOfRecords;
119   Uint32 filePosLow;
120   Uint32 filePosHigh;
121 };
122 
123 class TableS {
124 
125   friend class TupleS;
126   friend class RestoreMetaData;
127   friend class RestoreDataIterator;
128 
129   Uint32 schemaVersion;
130   Uint32 backupVersion;
131   Vector<AttributeDesc *> allAttributesDesc;
132   Vector<AttributeDesc *> m_fixedKeys;
133   //Vector<AttributeDesc *> m_variableKey;
134   Vector<AttributeDesc *> m_fixedAttribs;
135   Vector<AttributeDesc *> m_variableAttribs;
136 
137   Uint32 m_noOfNullable;
138   Uint32 m_nullBitmaskSize;
139 
140   Uint32 m_auto_val_id;
141   Uint64 m_max_auto_val;
142 
143   bool isSysTable;
144   TableS *m_main_table;
145   Uint32 m_local_id;
146 
147   Uint64 m_noOfRecords;
148   Vector<FragmentInfo *> m_fragmentInfo;
149 
150   void createAttr(NdbDictionary::Column *column);
151 
152 public:
153   class NdbDictionary::Table* m_dictTable;
154   TableS (Uint32 version, class NdbTableImpl* dictTable);
155   ~TableS();
156 
getTableId() const157   Uint32 getTableId() const {
158     return m_dictTable->getTableId();
159   }
getLocalId() const160   Uint32 getLocalId() const {
161     return m_local_id;
162   }
getNoOfRecords() const163   Uint32 getNoOfRecords() const {
164     return m_noOfRecords;
165   }
166   /*
167   void setMysqlTableName(char * tableName) {
168     strpcpy(mysqlTableName, tableName);
169   }
170 
171   char *
172   void setMysqlDatabaseName(char * databaseName) {
173     strpcpy(mysqlDatabaseName, databaseName);
174   }
175 
176   table.setMysqlDatabaseName(database);
177   */
setBackupVersion(Uint32 version)178   void setBackupVersion(Uint32 version) {
179     backupVersion = version;
180   }
181 
getBackupVersion() const182   Uint32 getBackupVersion() const {
183     return backupVersion;
184   }
185 
getTableName() const186   const char * getTableName() const {
187     return m_dictTable->getName();
188   }
189 
getNoOfAttributes() const190   int getNoOfAttributes() const {
191     return allAttributesDesc.size();
192   };
193 
have_auto_inc() const194   bool have_auto_inc() const {
195     return m_auto_val_id != ~(Uint32)0;
196   };
197 
have_auto_inc(Uint32 id) const198   bool have_auto_inc(Uint32 id) const {
199     return m_auto_val_id == id;
200   };
201 
get_max_auto_val() const202   Uint64 get_max_auto_val() const {
203     return m_max_auto_val;
204   };
205 
update_max_auto_val(const char * data,int size)206   void update_max_auto_val(const char *data, int size) {
207     union {
208       Uint8  u8;
209       Uint16 u16;
210       Uint32 u32;
211     } val;
212     Uint64 v;
213     switch(size){
214     case 64:
215       memcpy(&v,data,8);
216       break;
217     case 32:
218       memcpy(&val.u32,data,4);
219       v= val.u32;
220       break;
221     case 24:
222       v= uint3korr((unsigned char*)data);
223       break;
224     case 16:
225       memcpy(&val.u16,data,2);
226       v= val.u16;
227       break;
228     case 8:
229       memcpy(&val.u8,data,1);
230       v= val.u8;
231       break;
232     default:
233       return;
234     };
235     if(v > m_max_auto_val)
236       m_max_auto_val= v;
237   };
238   /**
239    * Get attribute descriptor
240    */
operator [](int attributeId) const241   const AttributeDesc * operator[](int attributeId) const {
242     return allAttributesDesc[attributeId];
243   }
244 
getSysTable() const245   bool getSysTable() const {
246     return isSysTable;
247   }
248 
getMainTable() const249   const TableS *getMainTable() const {
250     return m_main_table;
251   }
252 
253   TableS& operator=(TableS& org) ;
254 }; // TableS;
255 
256 class RestoreLogIterator;
257 
258 class BackupFile {
259 protected:
260   FILE * m_file;
261   char m_path[PATH_MAX];
262   char m_fileName[PATH_MAX];
263   bool m_hostByteOrder;
264   BackupFormat::FileHeader m_fileHeader;
265   BackupFormat::FileHeader m_expectedFileHeader;
266 
267   Uint32 m_nodeId;
268 
269   void * m_buffer;
270   void * m_buffer_ptr;
271   Uint32 m_buffer_sz;
272   Uint32 m_buffer_data_left;
273   void (* free_data_callback)();
274 
275   bool openFile();
276   void setCtlFile(Uint32 nodeId, Uint32 backupId, const char * path);
277   void setDataFile(const BackupFile & bf, Uint32 no);
278   void setLogFile(const BackupFile & bf, Uint32 no);
279 
280   Uint32 buffer_get_ptr(void **p_buf_ptr, Uint32 size, Uint32 nmemb);
281   Uint32 buffer_read(void *ptr, Uint32 size, Uint32 nmemb);
282   Uint32 buffer_get_ptr_ahead(void **p_buf_ptr, Uint32 size, Uint32 nmemb);
283   Uint32 buffer_read_ahead(void *ptr, Uint32 size, Uint32 nmemb);
284 
285   void setName(const char * path, const char * name);
286 
287   BackupFile(void (* free_data_callback)() = 0);
288   ~BackupFile();
289 public:
290   bool readHeader();
291   bool validateFooter();
292 
getPath() const293   const char * getPath() const { return m_path;}
getFilename() const294   const char * getFilename() const { return m_fileName;}
getNodeId() const295   Uint32 getNodeId() const { return m_nodeId;}
getFileHeader() const296   const BackupFormat::FileHeader & getFileHeader() const { return m_fileHeader;}
297   bool Twiddle(const AttributeDesc *  attr_desc, AttributeData * attr_data, Uint32 arraySize = 0);
298 };
299 
300 struct DictObject {
301   Uint32 m_objType;
302   void * m_objPtr;
303 };
304 
305 class RestoreMetaData : public BackupFile {
306 
307   Vector<TableS *> allTables;
308   bool readMetaFileHeader();
309   bool readMetaTableDesc();
310   bool markSysTables();
311 
312   bool readGCPEntry();
313   bool readFragmentInfo();
314   Uint32 readMetaTableList();
315 
316   Uint32 m_startGCP;
317   Uint32 m_stopGCP;
318 
319   bool parseTableDescriptor(const Uint32 * data, Uint32 len);
320 
321   Vector<DictObject> m_objects;
322 
323 public:
324   RestoreMetaData(const char * path, Uint32 nodeId, Uint32 bNo);
325   virtual ~RestoreMetaData();
326 
327   int loadContent();
328 
getNoOfTables() const329   Uint32 getNoOfTables() const { return allTables.size();}
330 
operator [](int i) const331   const TableS * operator[](int i) const { return allTables[i];}
332   TableS * getTable(Uint32 tableId) const;
333 
getNoOfObjects() const334   Uint32 getNoOfObjects() const { return m_objects.size();}
getObjType(Uint32 i) const335   Uint32 getObjType(Uint32 i) const { return m_objects[i].m_objType; }
getObjPtr(Uint32 i) const336   void* getObjPtr(Uint32 i) const { return m_objects[i].m_objPtr; }
337 
338   Uint32 getStopGCP() const;
339 }; // RestoreMetaData
340 
341 
342 class RestoreDataIterator : public BackupFile {
343   const RestoreMetaData & m_metaData;
344   Uint32 m_count;
345   TableS* m_currentTable;
346   TupleS m_tuple;
347 
348 public:
349 
350   // Constructor
351   RestoreDataIterator(const RestoreMetaData &, void (* free_data_callback)());
~RestoreDataIterator()352   ~RestoreDataIterator() {};
353 
354   // Read data file fragment header
355   bool readFragmentHeader(int & res, Uint32 *fragmentId);
356   bool validateFragmentFooter();
357 
358   const TupleS *getNextTuple(int & res);
359 
360 private:
361 
362   int readTupleData(Uint32 *buf_ptr, Uint32 *ptr, Uint32 dataLength);
363 };
364 
365 class LogEntry {
366 public:
367   enum EntryType {
368     LE_INSERT,
369     LE_DELETE,
370     LE_UPDATE
371   };
372   Uint32 m_frag_id;
373   EntryType m_type;
374   TableS * m_table;
375   Vector<AttributeS*> m_values;
376   Vector<AttributeS*> m_values_e;
add_attr()377   AttributeS *add_attr() {
378     AttributeS * attr;
379     if (m_values_e.size() > 0) {
380       attr = m_values_e[m_values_e.size()-1];
381       m_values_e.erase(m_values_e.size()-1);
382     }
383     else
384     {
385       attr = new AttributeS;
386     }
387     m_values.push_back(attr);
388     return attr;
389   }
clear()390   void clear() {
391     for(Uint32 i= 0; i < m_values.size(); i++)
392       m_values_e.push_back(m_values[i]);
393     m_values.clear();
394   }
LogEntry()395   LogEntry() {}
~LogEntry()396   ~LogEntry()
397   {
398     Uint32 i;
399     for(i= 0; i< m_values.size(); i++)
400       delete m_values[i];
401     for(i= 0; i< m_values_e.size(); i++)
402       delete m_values_e[i];
403   }
size() const404   Uint32 size() const { return m_values.size(); }
operator [](int i) const405   const AttributeS * operator[](int i) const { return m_values[i];}
406 };
407 
408 class RestoreLogIterator : public BackupFile {
409 private:
410   const RestoreMetaData & m_metaData;
411 
412   Uint32 m_count;
413   Uint32 m_last_gci;
414   LogEntry m_logEntry;
415 public:
416   RestoreLogIterator(const RestoreMetaData &);
~RestoreLogIterator()417   virtual ~RestoreLogIterator() {};
418 
419   const LogEntry * getNextLogEntry(int & res);
420 };
421 
422 NdbOut& operator<<(NdbOut& ndbout, const TableS&);
423 NdbOut& operator<<(NdbOut& ndbout, const TupleS&);
424 NdbOut& operator<<(NdbOut& ndbout, const LogEntry&);
425 NdbOut& operator<<(NdbOut& ndbout, const RestoreMetaData&);
426 
427 #endif
428 
429 
430