Restore.hpp 8.63 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#ifndef RESTORE_H
#define RESTORE_H

20
#include <ndb_global.h>
21
#include <NdbOut.hpp>
22 23
#include "../src/kernel/blocks/backup/BackupFormat.hpp"
#include "../src/ndbapi/NdbDictionaryImpl.hpp"
24 25 26 27 28
#include <NdbApi.hpp>

#include <ndb_version.h>
#include <version.h>

29 30
static const char * delimiter = ";"; // Delimiter in file dump

31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
const int FileNameLenC = 256;
const int TableNameLenC = 256;
const int AttrNameLenC = 256;
const Uint32 timeToWaitForNdbC = 10000;
const Uint32 opsDefaultC = 1000;

// Forward declarations
//class AttributeDesc;
struct AttributeDesc;
struct AttributeData;
struct AttributeS;

struct AttributeData {
  bool null;
  Uint32 size;
  union {
    Int8 * int8_value;
    Uint8 * u_int8_value;
    
    Int16 * int16_value;
    Uint16 * u_int16_value;

    Int32 * int32_value;
    Uint32 * u_int32_value;
    
    Int64 * int64_value;
    Uint64 * u_int64_value;

    char * string_value;
    
    void* void_value;
  };
};

struct AttributeDesc {
  //private:
  friend class TupleS;
  friend class TableS;
  friend class RestoreDataIterator;
  friend class RestoreMetaData;
  friend struct AttributeS;
  Uint32 size; // bits       
  Uint32 arraySize;
74 75
  Uint32 attrId;
  NdbDictionary::Column *m_column;
76 77 78 79

  Uint32 m_nullBitIndex;
public:
  
80 81
  AttributeDesc(NdbDictionary::Column *column);
  AttributeDesc();
82 83 84 85 86 87

  Uint32 getSizeInWords() const { return (size * arraySize + 31)/ 32;}
}; // AttributeDesc

struct AttributeS {
  const AttributeDesc * Desc;
unknown's avatar
unknown committed
88
  AttributeData Data;
89 90 91 92 93 94
};

class TupleS {
private:
  friend class RestoreDataIterator;
  
unknown's avatar
unknown committed
95
  class TableS *m_currentTable;
96
  AttributeData *allAttrData;
unknown's avatar
unknown committed
97
  bool prepareRecord(TableS &);
98 99
  
public:
unknown's avatar
unknown committed
100 101 102 103
  TupleS() {
    m_currentTable= 0;
    allAttrData= 0;
  };
104 105 106 107 108 109 110 111
  ~TupleS()
  {
    if (allAttrData)
      delete [] allAttrData;
  };
  TupleS(const TupleS& tuple); // disable copy constructor
  TupleS & operator=(const TupleS& tuple);
  int getNoOfAttributes() const;
unknown's avatar
unknown committed
112
  TableS * getTable() const;
113 114
  const AttributeDesc * getDesc(int i) const;
  AttributeData * getData(int i) const;
115 116 117 118 119 120 121 122 123 124
}; // class TupleS

class TableS {
  
  friend class TupleS;
  friend class RestoreMetaData;
  friend class RestoreDataIterator;
  
  Uint32 schemaVersion;
  Uint32 backupVersion;
unknown's avatar
unknown committed
125 126 127 128 129
  Vector<AttributeDesc *> allAttributesDesc;
  Vector<AttributeDesc *> m_fixedKeys;
  //Vector<AttributeDesc *> m_variableKey; 
  Vector<AttributeDesc *> m_fixedAttribs;
  Vector<AttributeDesc *> m_variableAttribs;
130 131 132 133
  
  Uint32 m_noOfNullable;
  Uint32 m_nullBitmaskSize;

unknown's avatar
unknown committed
134 135 136
  Uint32 m_auto_val_id;
  Uint64 m_max_auto_val;

137 138
  int pos;

139
  void createAttr(NdbDictionary::Column *column);
140 141 142

public:
  class NdbDictionary::Table* m_dictTable;
143
  TableS (class NdbTableImpl* dictTable);
unknown's avatar
unknown committed
144
  ~TableS();
145 146

  Uint32 getTableId() const { 
147
    return m_dictTable->getTableId(); 
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
  }
  /*
  void setMysqlTableName(char * tableName) {
    strpcpy(mysqlTableName, tableName);
  }
  
  char * 
  void setMysqlDatabaseName(char * databaseName) {
    strpcpy(mysqlDatabaseName, databaseName);
  }

  table.setMysqlDatabaseName(database);
  */
  void setBackupVersion(Uint32 version) { 
    backupVersion = version;
  }
  
  Uint32 getBackupVersion() const { 
    return backupVersion;
  }
  
  const char * getTableName() const { 
    return m_dictTable->getName();
  }
  
  int getNoOfAttributes() const { 
    return allAttributesDesc.size();
  };
  
unknown's avatar
unknown committed
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
  bool have_auto_inc() const {
    return m_auto_val_id != ~(Uint32)0;
  };

  bool have_auto_inc(Uint32 id) const {
    return m_auto_val_id == id;
  };

  Uint64 get_max_auto_val() const {
    return m_max_auto_val;
  };

  void update_max_auto_val(const char *data, int size) {
    Uint64 val= 0;
    switch(size){
    case 8:
      val= *(Uint8*)data;
      break;
    case 16:
      val= *(Uint16*)data;
      break;
    case 24:
      val= (0xffffff)&*(Uint32*)data;
      break;
    case 32:
      val= *(Uint32*)data;
      break;
    case 64:
      val= *(Uint64*)data;
      break;
    default:
      return;
    };
    if(val > m_max_auto_val)
      m_max_auto_val= val;
  };
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
  /**
   * Get attribute descriptor
   */
  const AttributeDesc * operator[](int attributeId) const { 
    return allAttributesDesc[attributeId]; 
  }

  TableS& operator=(TableS& org) ; 
}; // TableS;

class BackupFile {
protected:
  FILE * m_file;
  char m_path[PATH_MAX];
  char m_fileName[PATH_MAX];
  bool m_hostByteOrder;
  BackupFormat::FileHeader m_fileHeader;
  BackupFormat::FileHeader m_expectedFileHeader;
  
  Uint32 m_nodeId;
  
unknown's avatar
unknown committed
234 235 236 237 238 239
  void * m_buffer;
  void * m_buffer_ptr;
  Uint32 m_buffer_sz;
  Uint32 m_buffer_data_left;
  void (* free_data_callback)();

240 241 242 243 244
  bool openFile();
  void setCtlFile(Uint32 nodeId, Uint32 backupId, const char * path);
  void setDataFile(const BackupFile & bf, Uint32 no);
  void setLogFile(const BackupFile & bf, Uint32 no);
  
unknown's avatar
unknown committed
245 246 247 248 249
  Uint32 buffer_get_ptr(void **p_buf_ptr, Uint32 size, Uint32 nmemb);
  Uint32 buffer_read(void *ptr, Uint32 size, Uint32 nmemb);
  Uint32 buffer_get_ptr_ahead(void **p_buf_ptr, Uint32 size, Uint32 nmemb);
  Uint32 buffer_read_ahead(void *ptr, Uint32 size, Uint32 nmemb);

250 251
  void setName(const char * path, const char * name);

unknown's avatar
unknown committed
252
  BackupFile(void (* free_data_callback)() = 0);
253 254 255 256 257 258 259 260 261
  ~BackupFile();
public:
  bool readHeader();
  bool validateFooter();

  const char * getPath() const { return m_path;}
  const char * getFilename() const { return m_fileName;}
  Uint32 getNodeId() const { return m_nodeId;}
  const BackupFormat::FileHeader & getFileHeader() const { return m_fileHeader;}
262
  bool Twiddle(const AttributeDesc *  attr_desc, AttributeData * attr_data, Uint32 arraySize = 0);
263 264 265 266
};

class RestoreMetaData : public BackupFile {

unknown's avatar
unknown committed
267
  Vector<TableS *> allTables;
268
  bool readMetaFileHeader();
269
  bool readMetaTableDesc();
270 271 272 273 274 275 276
		
  bool readGCPEntry();
  Uint32 readMetaTableList();

  Uint32 m_startGCP;
  Uint32 m_stopGCP;
  
277
  bool parseTableDescriptor(const Uint32 * data, Uint32 len);
278 279 280

public:
  RestoreMetaData(const char * path, Uint32 nodeId, Uint32 bNo);
unknown's avatar
unknown committed
281
  virtual ~RestoreMetaData();
282
  
283
  int loadContent();
284 285 286 287
		  
  Uint32 getNoOfTables() const { return allTables.size();}
  
  const TableS * operator[](int i) const { return allTables[i];}
unknown's avatar
unknown committed
288
  TableS * getTable(Uint32 tableId) const;
289 290 291 292 293 294 295 296

  Uint32 getStopGCP() const;
}; // RestoreMetaData


class RestoreDataIterator : public BackupFile {
  const RestoreMetaData & m_metaData;
  Uint32 m_count;
unknown's avatar
unknown committed
297
  TableS* m_currentTable;
298 299
  TupleS m_tuple;

300 301 302
public:

  // Constructor
303
  RestoreDataIterator(const RestoreMetaData &, void (* free_data_callback)());
unknown's avatar
unknown committed
304
  ~RestoreDataIterator() {};
305 306 307 308
  
  // Read data file fragment header
  bool readFragmentHeader(int & res);
  bool validateFragmentFooter();
309

310 311 312 313 314 315 316 317 318 319 320
  const TupleS *getNextTuple(int & res);
};

class LogEntry {
public:
  enum EntryType {
    LE_INSERT,
    LE_DELETE,
    LE_UPDATE
  };
  EntryType m_type;
unknown's avatar
unknown committed
321
  TableS * m_table;  
unknown's avatar
unknown committed
322 323
  Vector<AttributeS*> m_values;
  Vector<AttributeS*> m_values_e;
unknown's avatar
unknown committed
324 325 326 327
  AttributeS *add_attr() {
    AttributeS * attr;
    if (m_values_e.size() > 0) {
      attr = m_values_e[m_values_e.size()-1];
unknown's avatar
unknown committed
328
      m_values_e.erase(m_values_e.size()-1);
unknown's avatar
unknown committed
329 330 331 332 333 334 335 336 337
    }
    else
    {
      attr = new AttributeS;
    }
    m_values.push_back(attr);
    return attr;
  }
  void clear() {
unknown's avatar
unknown committed
338
    for(Uint32 i= 0; i < m_values.size(); i++)
unknown's avatar
unknown committed
339 340 341 342 343
      m_values_e.push_back(m_values[i]);
    m_values.clear();
  }
  ~LogEntry()
  {
unknown's avatar
unknown committed
344 345
    Uint32 i;
    for(i= 0; i< m_values.size(); i++)
unknown's avatar
unknown committed
346
      delete m_values[i];
unknown's avatar
unknown committed
347
    for(i= 0; i< m_values_e.size(); i++)
unknown's avatar
unknown committed
348 349
      delete m_values_e[i];
  }
unknown's avatar
unknown committed
350
  Uint32 size() const { return m_values.size(); }
unknown's avatar
unknown committed
351
  const AttributeS * operator[](int i) const { return m_values[i];}
352 353 354 355 356 357 358 359 360 361
};

class RestoreLogIterator : public BackupFile {
private:
  const RestoreMetaData & m_metaData;

  Uint32 m_count;  
  LogEntry m_logEntry;
public:
  RestoreLogIterator(const RestoreMetaData &);
unknown's avatar
unknown committed
362 363
  virtual ~RestoreLogIterator() {};

364 365 366
  const LogEntry * getNextLogEntry(int & res);
};

367 368 369 370 371
NdbOut& operator<<(NdbOut& ndbout, const TableS&);
NdbOut& operator<<(NdbOut& ndbout, const TupleS&);
NdbOut& operator<<(NdbOut& ndbout, const LogEntry&);
NdbOut& operator<<(NdbOut& ndbout, const RestoreMetaData&);

372 373 374
#endif