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