📄 restore.cpp
字号:
/* 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 */#include "Restore.hpp"#include <NdbTCP.h>#include <OutputStream.hpp>#include <Bitmask.hpp>#include <AttributeHeader.hpp>#include <trigger_definitions.h>#include <SimpleProperties.hpp>#include <signaldata/DictTabInfo.hpp>Uint16 Twiddle16(Uint16 in); // Byte shift 16-bit dataUint32 Twiddle32(Uint32 in); // Byte shift 32-bit dataUint64 Twiddle64(Uint64 in); // Byte shift 64-bit databoolBackupFile::Twiddle(const AttributeDesc* attr_desc, AttributeData* attr_data, Uint32 arraySize){ Uint32 i; if(m_hostByteOrder) return true; if(arraySize == 0){ arraySize = attr_desc->arraySize; } switch(attr_desc->size){ case 8: return true; case 16: for(i = 0; i<arraySize; i++){ attr_data->u_int16_value[i] = Twiddle16(attr_data->u_int16_value[i]); } return true; case 32: for(i = 0; i<arraySize; i++){ attr_data->u_int32_value[i] = Twiddle32(attr_data->u_int32_value[i]); } return true; case 64: for(i = 0; i<arraySize; i++){ attr_data->u_int64_value[i] = Twiddle64(attr_data->u_int64_value[i]); } return true; default: return false; } // switch} // TwiddleFilteredNdbOut err(* new FileOutputStream(stderr), 0, 0);FilteredNdbOut info(* new FileOutputStream(stdout), 1, 1);FilteredNdbOut debug(* new FileOutputStream(stdout), 2, 0);// To decide in what byte order data isconst Uint32 magicByteOrder = 0x12345678;const Uint32 swappedMagicByteOrder = 0x78563412;RestoreMetaData::RestoreMetaData(const char* path, Uint32 nodeId, Uint32 bNo) { debug << "RestoreMetaData constructor" << endl; setCtlFile(nodeId, bNo, path);}RestoreMetaData::~RestoreMetaData(){ for(Uint32 i= 0; i < allTables.size(); i++) { TableS *table = allTables[i]; for(Uint32 j= 0; j < table->m_fragmentInfo.size(); j++) delete table->m_fragmentInfo[j]; delete table; } allTables.clear();}TableS * RestoreMetaData::getTable(Uint32 tableId) const { for(Uint32 i= 0; i < allTables.size(); i++) if(allTables[i]->getTableId() == tableId) return allTables[i]; return NULL;}Uint32RestoreMetaData::getStopGCP() const { return m_stopGCP;}intRestoreMetaData::loadContent() { Uint32 noOfTables = readMetaTableList(); if(noOfTables == 0) { return 1; } for(Uint32 i = 0; i<noOfTables; i++){ if(!readMetaTableDesc()){ return 0; } } if(!readGCPEntry()) return 0; if(!readFragmentInfo()) return 0; return 1;}Uint32RestoreMetaData::readMetaTableList() { Uint32 sectionInfo[2]; if (buffer_read(§ionInfo, sizeof(sectionInfo), 1) != 1){ err << "readMetaTableList read header error" << endl; return 0; } sectionInfo[0] = ntohl(sectionInfo[0]); sectionInfo[1] = ntohl(sectionInfo[1]); const Uint32 tabCount = sectionInfo[1] - 2; void *tmp; if (buffer_get_ptr(&tmp, 4, tabCount) != tabCount){ err << "readMetaTableList read tabCount error" << endl; return 0; } return tabCount;}boolRestoreMetaData::readMetaTableDesc() { Uint32 sectionInfo[2]; // Read section header if (buffer_read(§ionInfo, sizeof(sectionInfo), 1) != 1){ err << "readMetaTableDesc read header error" << endl; return false; } // if sectionInfo[0] = ntohl(sectionInfo[0]); sectionInfo[1] = ntohl(sectionInfo[1]); assert(sectionInfo[0] == BackupFormat::TABLE_DESCRIPTION); // Read dictTabInfo buffer const Uint32 len = (sectionInfo[1] - 2); void *ptr; if (buffer_get_ptr(&ptr, 4, len) != len){ err << "readMetaTableDesc read error" << endl; return false; } // if return parseTableDescriptor((Uint32*)ptr, len); }boolRestoreMetaData::readGCPEntry() { Uint32 data[4]; BackupFormat::CtlFile::GCPEntry * dst = (BackupFormat::CtlFile::GCPEntry *)&data[0]; if(buffer_read(dst, 4, 4) != 4){ err << "readGCPEntry read error" << endl; return false; } dst->SectionType = ntohl(dst->SectionType); dst->SectionLength = ntohl(dst->SectionLength); if(dst->SectionType != BackupFormat::GCP_ENTRY){ err << "readGCPEntry invalid format" << endl; return false; } dst->StartGCP = ntohl(dst->StartGCP); dst->StopGCP = ntohl(dst->StopGCP); m_startGCP = dst->StartGCP; m_stopGCP = dst->StopGCP; return true;}boolRestoreMetaData::readFragmentInfo(){ BackupFormat::CtlFile::FragmentInfo fragInfo; TableS * table = 0; Uint32 tableId = RNIL; while (buffer_read(&fragInfo, 4, 2) == 2) { fragInfo.SectionType = ntohl(fragInfo.SectionType); fragInfo.SectionLength = ntohl(fragInfo.SectionLength); if (fragInfo.SectionType != BackupFormat::FRAGMENT_INFO) { err << "readFragmentInfo invalid section type: " << fragInfo.SectionType << endl; return false; } if (buffer_read(&fragInfo.TableId, (fragInfo.SectionLength-2)*4, 1) != 1) { err << "readFragmentInfo invalid section length: " << fragInfo.SectionLength << endl; return false; } fragInfo.TableId = ntohl(fragInfo.TableId); if (fragInfo.TableId != tableId) { tableId = fragInfo.TableId; table = getTable(tableId); } FragmentInfo * tmp = new FragmentInfo; tmp->fragmentNo = ntohl(fragInfo.FragmentNo); tmp->noOfRecords = ntohl(fragInfo.NoOfRecordsLow) + (((Uint64)ntohl(fragInfo.NoOfRecordsHigh)) << 32); tmp->filePosLow = ntohl(fragInfo.FilePosLow); tmp->filePosHigh = ntohl(fragInfo.FilePosHigh); table->m_fragmentInfo.push_back(tmp); table->m_noOfRecords += tmp->noOfRecords; } return true;}TableS::TableS(Uint32 version, NdbTableImpl* tableImpl) : m_dictTable(tableImpl){ m_dictTable = tableImpl; m_noOfNullable = m_nullBitmaskSize = 0; m_auto_val_id= ~(Uint32)0; m_max_auto_val= 0; m_noOfRecords= 0; backupVersion = version; for (int i = 0; i < tableImpl->getNoOfColumns(); i++) createAttr(tableImpl->getColumn(i));}TableS::~TableS(){ for (Uint32 i= 0; i < allAttributesDesc.size(); i++) delete allAttributesDesc[i];}// Parse dictTabInfo buffer and pushback to to vector storage boolRestoreMetaData::parseTableDescriptor(const Uint32 * data, Uint32 len){ NdbTableImpl* tableImpl = 0; int ret = NdbDictInterface::parseTableInfo(&tableImpl, data, len, false); if (ret != 0) { err << "parseTableInfo " << " failed" << endl; return false; } if(tableImpl == 0) return false; debug << "parseTableInfo " << tableImpl->getName() << " done" << endl; TableS * table = new TableS(m_fileHeader.NdbVersion, tableImpl); if(table == NULL) { return false; } debug << "Parsed table id " << table->getTableId() << endl; debug << "Parsed table #attr " << table->getNoOfAttributes() << endl; debug << "Parsed table schema version not used " << endl; debug << "Pushing table " << table->getTableName() << endl; debug << " with " << table->getNoOfAttributes() << " attributes" << endl; allTables.push_back(table); return true;}// ConstructorRestoreDataIterator::RestoreDataIterator(const RestoreMetaData & md, void (* _free_data_callback)()) : BackupFile(_free_data_callback), m_metaData(md){ debug << "RestoreDataIterator constructor" << endl; setDataFile(md, 0);}TupleS & TupleS::operator=(const TupleS& tuple){ prepareRecord(*tuple.m_currentTable); if (allAttrData) memcpy(allAttrData, tuple.allAttrData, getNoOfAttributes()*sizeof(AttributeData)); return *this;}int TupleS::getNoOfAttributes() const { if (m_currentTable == 0) return 0; return m_currentTable->getNoOfAttributes();}TableS * TupleS::getTable() const { return m_currentTable;}const AttributeDesc * TupleS::getDesc(int i) const { return m_currentTable->allAttributesDesc[i];}AttributeData * TupleS::getData(int i) const{ return &(allAttrData[i]);}boolTupleS::prepareRecord(TableS & tab){ if (allAttrData) { if (getNoOfAttributes() == tab.getNoOfAttributes()) { m_currentTable = &tab; return true; } delete [] allAttrData; m_currentTable= 0; } allAttrData = new AttributeData[tab.getNoOfAttributes()]; if (allAttrData == 0) return false; m_currentTable = &tab; return true;}const TupleS *RestoreDataIterator::getNextTuple(int & res){ Uint32 dataLength = 0; // Read record length if (buffer_read(&dataLength, sizeof(dataLength), 1) != 1){ err << "getNextTuple:Error reading length of data part" << endl; res = -1; return NULL; } // if // Convert length from network byte order dataLength = ntohl(dataLength); const Uint32 dataLenBytes = 4 * dataLength; if (dataLength == 0) { // Zero length for last tuple // End of this data fragment debug << "End of fragment" << endl; res = 0; return NULL; } // if // Read tuple data void *_buf_ptr; if (buffer_get_ptr(&_buf_ptr, 1, dataLenBytes) != dataLenBytes) { err << "getNextTuple:Read error: " << endl; res = -1; return NULL; } Uint32 *buf_ptr = (Uint32*)_buf_ptr, *ptr = buf_ptr; ptr += m_currentTable->m_nullBitmaskSize; Uint32 i; for(i= 0; i < m_currentTable->m_fixedKeys.size(); i++){ assert(ptr < buf_ptr + dataLength); const Uint32 attrId = m_currentTable->m_fixedKeys[i]->attrId; AttributeData * attr_data = m_tuple.getData(attrId); const AttributeDesc * attr_desc = m_tuple.getDesc(attrId); const Uint32 sz = attr_desc->getSizeInWords(); attr_data->null = false; attr_data->void_value = ptr; if(!Twiddle(attr_desc, attr_data)) { res = -1; return NULL; } ptr += sz; } for(i = 0; i < m_currentTable->m_fixedAttribs.size(); i++){ assert(ptr < buf_ptr + dataLength); const Uint32 attrId = m_currentTable->m_fixedAttribs[i]->attrId; AttributeData * attr_data = m_tuple.getData(attrId); const AttributeDesc * attr_desc = m_tuple.getDesc(attrId); const Uint32 sz = attr_desc->getSizeInWords(); attr_data->null = false; attr_data->void_value = ptr; if(!Twiddle(attr_desc, attr_data)) { res = -1; return NULL; } ptr += sz; } for(i = 0; i < m_currentTable->m_variableAttribs.size(); i++){ const Uint32 attrId = m_currentTable->m_variableAttribs[i]->attrId; AttributeData * attr_data = m_tuple.getData(attrId); const AttributeDesc * attr_desc = m_tuple.getDesc(attrId); if(attr_desc->m_column->getNullable()){ const Uint32 ind = attr_desc->m_nullBitIndex; if(BitmaskImpl::get(m_currentTable->m_nullBitmaskSize, buf_ptr,ind)){ attr_data->null = true; attr_data->void_value = NULL; continue; } } assert(ptr < buf_ptr + dataLength); typedef BackupFormat::DataFile::VariableData VarData; VarData * data = (VarData *)ptr; Uint32 sz = ntohl(data->Sz); Uint32 id = ntohl(data->Id); assert(id == attrId); attr_data->null = false; attr_data->void_value = &data->Data[0]; /** * Compute array size */ const Uint32 arraySize = (4 * sz) / (attr_desc->size / 8); assert(arraySize >= attr_desc->arraySize); if(!Twiddle(attr_desc, attr_data, attr_desc->arraySize)) { res = -1; return NULL; } ptr += (sz + 2); } m_count ++; res = 0; return &m_tuple;} // RestoreDataIterator::getNextTupleBackupFile::BackupFile(void (* _free_data_callback)()) : free_data_callback(_free_data_callback){ m_file = 0; m_path[0] = 0; m_fileName[0] = 0; m_buffer_sz = 64*1024; m_buffer = malloc(m_buffer_sz); m_buffer_ptr = m_buffer; m_buffer_data_left = 0;}BackupFile::~BackupFile(){ if(m_file != 0) fclose(m_file); if(m_buffer != 0) free(m_buffer);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -