18 #include "Restore.hpp"
21 #include <OutputStream.hpp>
22 #include <Bitmask.hpp>
24 #include <AttributeHeader.hpp>
25 #include <trigger_definitions.h>
26 #include <SimpleProperties.hpp>
27 #include <signaldata/DictTabInfo.hpp>
28 #include <ndb_limits.h>
29 #include <NdbAutoPtr.hpp>
30 #include "../src/ndbapi/NdbDictionaryImpl.hpp"
32 #include "../../../../sql/ha_ndbcluster_tables.h"
34 extern bool ga_skip_unknown_objects;
35 extern bool ga_skip_broken_objects;
37 Uint16 Twiddle16(Uint16 in);
38 Uint32 Twiddle32(Uint32 in);
39 Uint64 Twiddle64(Uint64 in);
51 Uint32 m_twiddle_size;
52 Uint32 m_twiddle_array_size;
61 switch(attribute_type){
64 assert(attr_desc->size == 8);
65 assert(attr_desc->arraySize == 8);
67 m_twiddle_array_size = 1;
72 assert(attr_desc->size == 8);
73 assert(attr_desc->arraySize == 4);
75 m_twiddle_array_size = 1;
80 if (attr_desc->m_column->getArrayType() ==
81 NdbDictionary::Column::ArrayTypeFixed)
85 assert(attr_desc->size == 8);
86 assert(attr_desc->arraySize > 8);
88 m_twiddle_array_size = 1;
95 m_twiddle_size = attr_desc->size;
96 m_twiddle_array_size = attr_desc->arraySize;
100 assert(m_twiddle_array_size);
101 assert(m_twiddle_size);
104 bool is_aligned (
void* data_ptr)
const {
105 switch (m_twiddle_size){
111 return ((((
size_t)data_ptr) & 1) == 0);
114 return ((((
size_t)data_ptr) & 3) == 0);
117 return ((((
size_t)data_ptr) & 7) == 0);
126 void twiddle_aligned(
void*
const data_ptr)
const {
128 assert(is_aligned(data_ptr));
130 switch(m_twiddle_size){
136 Uint16* ptr = (Uint16*)data_ptr;
137 for (Uint32
i = 0;
i < m_twiddle_array_size;
i++){
138 *ptr = Twiddle16(*ptr);
145 Uint32* ptr = (Uint32*)data_ptr;
146 for (Uint32
i = 0;
i < m_twiddle_array_size;
i++){
147 *ptr = Twiddle32(*ptr);
154 Uint64* ptr = (Uint64*)data_ptr;
155 for (Uint32
i = 0;
i < m_twiddle_array_size;
i++){
156 *ptr = Twiddle64(*ptr);
177 BackupFile::twiddle_atribute(
const AttributeDesc *
const attr_desc,
183 void* data_ptr = (
char*)attr_data->void_value;
184 Uint32 data_sz = attr_desc->getSizeInBytes();
185 bool aligned= map.is_aligned(data_ptr);
190 m_twiddle_buffer.assign(data_ptr, data_sz);
191 data_ptr = m_twiddle_buffer.get_data();
195 map.twiddle_aligned(data_ptr);
200 memcpy(attr_data->void_value,
201 m_twiddle_buffer.get_data(),
224 assert(!attr_data->null);
225 assert(attr_data->void_value);
227 if(unlikely(!m_hostByteOrder))
231 twiddle_atribute(attr_desc, attr_data);
238 twiddle_atribute(attr_desc, attr_data);
239 twiddle_atribute(attr_desc, attr_data);
252 const Uint32 magicByteOrder = 0x12345678;
253 const Uint32 swappedMagicByteOrder = 0x78563412;
255 RestoreMetaData::RestoreMetaData(
const char* path, Uint32 nodeId, Uint32 bNo) {
257 debug <<
"RestoreMetaData constructor" << endl;
258 setCtlFile(nodeId, bNo, path);
261 RestoreMetaData::~RestoreMetaData(){
262 for(Uint32
i= 0;
i < allTables.size();
i++)
265 for(Uint32 j= 0; j < table->m_fragmentInfo.size(); j++)
266 delete table->m_fragmentInfo[j];
273 RestoreMetaData::getTable(Uint32 tableId)
const {
274 for(Uint32
i= 0;
i < allTables.size();
i++)
275 if(allTables[
i]->getTableId() == tableId)
281 RestoreMetaData::getStopGCP()
const {
286 RestoreMetaData::loadContent()
288 Uint32 noOfTables = readMetaTableList();
289 if(noOfTables == 0) {
292 for(Uint32
i = 0;
i<noOfTables;
i++){
293 if(!readMetaTableDesc()){
297 if (!markSysTables())
304 if(!readFragmentInfo())
310 RestoreMetaData::readMetaTableList() {
312 Uint32 sectionInfo[2];
314 if (buffer_read(§ionInfo,
sizeof(sectionInfo), 1) != 1){
315 err <<
"readMetaTableList read header error" << endl;
318 sectionInfo[0] = ntohl(sectionInfo[0]);
319 sectionInfo[1] = ntohl(sectionInfo[1]);
321 const Uint32 tabCount = sectionInfo[1] - 2;
324 if (buffer_get_ptr(&tmp, 4, tabCount) != tabCount){
325 err <<
"readMetaTableList read tabCount error" << endl;
333 RestoreMetaData::readMetaTableDesc() {
335 Uint32 sectionInfo[3];
338 Uint32 sz =
sizeof(sectionInfo) >> 2;
339 if (m_fileHeader.NdbVersion < NDBD_ROWID_VERSION ||
340 isDrop6(m_fileHeader.NdbVersion))
343 sectionInfo[2] = htonl(DictTabInfo::UserTable);
345 if (buffer_read(§ionInfo, 4*sz, 1) != 1){
346 err <<
"readMetaTableDesc read header error" << endl;
349 sectionInfo[0] = ntohl(sectionInfo[0]);
350 sectionInfo[1] = ntohl(sectionInfo[1]);
351 sectionInfo[2] = ntohl(sectionInfo[2]);
353 assert(sectionInfo[0] == BackupFormat::TABLE_DESCRIPTION);
356 const Uint32 len = (sectionInfo[1] - sz);
358 if (buffer_get_ptr(&ptr, 4, len) != len){
359 err <<
"readMetaTableDesc read error" << endl;
365 switch(obj.m_objType){
366 case DictTabInfo::SystemTable:
367 case DictTabInfo::UserTable:
368 case DictTabInfo::UniqueHashIndex:
369 case DictTabInfo::OrderedIndex:
370 return parseTableDescriptor((Uint32*)ptr, len);
376 NdbDictInterface::parseFilegroupInfo(NdbTablespaceImpl::getImpl(* dst),
381 debug << hex << obj.m_objPtr <<
" "
382 << dec << dst->
getObjectId() <<
" " << dst->getName() << endl;
389 NdbDictInterface::parseFilegroupInfo(NdbLogfileGroupImpl::getImpl(* dst),
394 debug << hex << obj.m_objPtr <<
" "
395 << dec << dst->
getObjectId() <<
" " << dst->getName() << endl;
402 NdbDictInterface::parseFileInfo(NdbDatafileImpl::getImpl(* dst),
407 debug << hex << obj.m_objPtr <<
" "
408 << dec << dst->
getObjectId() <<
" " << dst->getPath() << endl;
415 NdbDictInterface::parseFileInfo(NdbUndofileImpl::getImpl(* dst),
420 debug << hex << obj.m_objPtr <<
" "
421 << dec << dst->
getObjectId() <<
" " << dst->getPath() << endl;
424 case DictTabInfo::HashMap:
434 if (!m_hostByteOrder)
440 Uint32 len = dst->getMapLen();
442 values.fill(len - 1, zero);
443 dst->getMapValues(values.getBase(), values.size());
444 for (Uint32
i = 0;
i<len;
i++)
446 values[
i] = Twiddle16(values[
i]);
448 dst->setMap(values.getBase(), values.size());
451 m_objects.push(obj, 0);
456 if (ga_skip_unknown_objects)
458 info <<
"Skipping schema object with unknown table type "
459 << sectionInfo[2] << endl;
464 err <<
"Unsupported table type!! " << sectionInfo[2] << endl;
470 err <<
"Unable to parse dict info..."
471 << sectionInfo[2] <<
" " << errcode << endl;
478 for(Uint32
i = 0;
i<m_objects.size();
i++)
480 switch(sectionInfo[2]){
482 if (DictTabInfo::isFile(m_objects[
i].m_objType))
484 m_objects.push(obj,
i);
490 if (DictTabInfo::isFile(m_objects[
i].m_objType) ||
493 m_objects.push(obj,
i);
499 m_objects.push_back(obj);
503 m_objects.push_back(obj);
509 #define OLD_NDB_REP_DB "cluster"
510 #define OLD_NDB_APPLY_TABLE "apply_status"
511 #define OLD_NDB_SCHEMA_TABLE "schema"
514 RestoreMetaData::markSysTables()
517 for (i = 0; i < getNoOfTables(); i++) {
519 table->m_local_id =
i;
520 const char* tableName = table->getTableName();
522 strcmp(tableName,
"SYSTAB_0") == 0 ||
523 strcmp(tableName,
"NDB$EVENTS_0") == 0 ||
524 strcmp(tableName,
"sys/def/SYSTAB_0") == 0 ||
525 strcmp(tableName,
"sys/def/NDB$EVENTS_0") == 0 ||
527 strncmp(tableName, NDB_INDEX_STAT_PREFIX,
528 sizeof(NDB_INDEX_STAT_PREFIX)-1) == 0 ||
529 strstr(tableName,
"/" NDB_INDEX_STAT_PREFIX) != 0 ||
535 strcmp(tableName,
"cluster_replication/def/" OLD_NDB_APPLY_TABLE) == 0 ||
536 strcmp(tableName, OLD_NDB_REP_DB
"/def/" OLD_NDB_APPLY_TABLE) == 0 ||
537 strcmp(tableName, OLD_NDB_REP_DB
"/def/" OLD_NDB_SCHEMA_TABLE) == 0 ||
538 strcmp(tableName, NDB_REP_DB
"/def/" NDB_APPLY_TABLE) == 0 ||
539 strcmp(tableName, NDB_REP_DB
"/def/" NDB_SCHEMA_TABLE)== 0 )
541 table->m_isSysTable =
true;
542 if (strcmp(tableName,
"SYSTAB_0") == 0 ||
543 strcmp(tableName,
"sys/def/SYSTAB_0") == 0)
544 table->m_isSYSTAB_0 =
true;
547 for (i = 0; i < getNoOfTables(); i++) {
548 TableS* blobTable = allTables[
i];
549 const char* blobTableName = blobTable->getTableName();
553 cnt = sscanf(blobTableName,
"%[^/]/%[^/]/NDB$BLOB_%d_%d",
554 buf, buf, &id1, &id2);
557 for (j = 0; j < getNoOfTables(); j++) {
558 TableS* table = allTables[j];
559 if (table->getTableId() == (Uint32) id1) {
560 if (table->m_isSysTable)
561 blobTable->m_isSysTable =
true;
562 blobTable->m_main_table =
table;
563 blobTable->m_main_column_id = id2;
567 if (j == getNoOfTables()) {
568 err <<
"Restore: Bad primary table id in " << blobTableName << endl;
577 RestoreMetaData::fixBlobs()
580 for (i = 0; i < getNoOfTables(); i++) {
582 assert(table->m_dictTable != NULL);
583 NdbTableImpl& t = NdbTableImpl::getImpl(*table->m_dictTable);
584 const Uint32 noOfBlobs = t.m_noOfBlobs;
589 for (j = 0; n < noOfBlobs; j++) {
592 if (!c->getBlobType())
600 for (k = 0; k < getNoOfTables(); k++) {
601 TableS* tmp = allTables[k];
602 if (tmp->m_main_table == table &&
603 tmp->m_main_column_id == j) {
608 if (blobTable == NULL)
610 table->m_broken =
true;
612 err <<
"Table " << table->m_dictTable->
getName()
613 <<
" has blob column " << j <<
" ("
615 <<
") with missing parts table in backup."
617 if (ga_skip_broken_objects)
626 assert(blobTable->m_dictTable != NULL);
627 NdbTableImpl& bt = NdbTableImpl::getImpl(*blobTable->m_dictTable);
628 const char* colName = c->m_blobVersion == 1 ?
"DATA" :
"NDB$DATA";
631 assert(c->m_storageType == NDB_STORAGETYPE_MEMORY);
632 c->m_storageType = bc->m_storageType;
639 RestoreMetaData::readGCPEntry() {
643 if(buffer_read(&dst, 1,
sizeof(dst)) !=
sizeof(dst)){
644 err <<
"readGCPEntry read error" << endl;
648 dst.SectionType = ntohl(dst.SectionType);
649 dst.SectionLength = ntohl(dst.SectionLength);
651 if(dst.SectionType != BackupFormat::GCP_ENTRY){
652 err <<
"readGCPEntry invalid format" << endl;
656 dst.StartGCP = ntohl(dst.StartGCP);
657 dst.StopGCP = ntohl(dst.StopGCP);
659 m_startGCP = dst.StartGCP;
660 m_stopGCP = dst.StopGCP;
665 RestoreMetaData::readFragmentInfo()
669 Uint32 tableId = RNIL;
671 while (buffer_read(&fragInfo, 4, 2) == 2)
673 fragInfo.SectionType = ntohl(fragInfo.SectionType);
674 fragInfo.SectionLength = ntohl(fragInfo.SectionLength);
676 if (fragInfo.SectionType != BackupFormat::FRAGMENT_INFO)
678 err <<
"readFragmentInfo invalid section type: " <<
679 fragInfo.SectionType << endl;
683 if (buffer_read(&fragInfo.TableId, (fragInfo.SectionLength-2)*4, 1) != 1)
685 err <<
"readFragmentInfo invalid section length: " <<
686 fragInfo.SectionLength << endl;
690 fragInfo.TableId = ntohl(fragInfo.TableId);
691 if (fragInfo.TableId != tableId)
693 tableId = fragInfo.TableId;
694 table = getTable(tableId);
698 tmp->fragmentNo = ntohl(fragInfo.FragmentNo);
699 tmp->noOfRecords = ntohl(fragInfo.NoOfRecordsLow) +
700 (((Uint64)ntohl(fragInfo.NoOfRecordsHigh)) << 32);
701 tmp->filePosLow = ntohl(fragInfo.FilePosLow);
702 tmp->filePosHigh = ntohl(fragInfo.FilePosHigh);
704 table->m_fragmentInfo.push_back(tmp);
705 table->m_noOfRecords += tmp->noOfRecords;
711 : m_dictTable(tableImpl)
713 m_dictTable = tableImpl;
714 m_noOfNullable = m_nullBitmaskSize = 0;
715 m_auto_val_attrib = 0;
718 backupVersion = version;
719 m_isSysTable =
false;
720 m_isSYSTAB_0 =
false;
723 m_main_column_id = ~(Uint32)0;
726 createAttr(tableImpl->getColumn(i));
731 for (Uint32 i= 0; i < allAttributesDesc.size(); i++)
733 if (allAttributesDesc[i]->parameter)
734 free(allAttributesDesc[i]->parameter);
735 delete allAttributesDesc[
i];
742 RestoreMetaData::parseTableDescriptor(
const Uint32 * data, Uint32 len)
746 (&tableImpl, data, len,
false,
747 isDrop6(m_fileHeader.NdbVersion) ? MAKE_VERSION(5,1,2) :
748 m_fileHeader.NdbVersion);
751 err <<
"parseTableInfo " <<
" failed" << endl;
757 debug <<
"parseTableInfo " << tableImpl->
getName() <<
" done" << endl;
758 TableS * table =
new TableS(m_fileHeader.NdbVersion, tableImpl);
763 debug <<
"Parsed table id " << table->getTableId() << endl;
764 debug <<
"Parsed table #attr " << table->getNoOfAttributes() << endl;
765 debug <<
"Parsed table schema version not used " << endl;
767 debug <<
"Pushing table " << table->getTableName() << endl;
768 debug <<
" with " << table->getNoOfAttributes() <<
" attributes" << endl;
770 allTables.push_back(table);
776 RestoreDataIterator::RestoreDataIterator(
const RestoreMetaData & md,
void (* _free_data_callback)())
777 :
BackupFile(_free_data_callback), m_metaData(md)
779 debug <<
"RestoreDataIterator constructor" << endl;
782 m_bitfield_storage_len = 8192;
783 m_bitfield_storage_ptr = (Uint32*)malloc(4*m_bitfield_storage_len);
784 m_bitfield_storage_curr_ptr = m_bitfield_storage_ptr;
785 m_row_bitfield_len = 0;
788 RestoreDataIterator::~RestoreDataIterator()
790 free_bitfield_storage();
805 m_row_bitfield_len = len;
809 RestoreDataIterator::reset_bitfield_storage()
811 m_bitfield_storage_curr_ptr = m_bitfield_storage_ptr;
815 RestoreDataIterator::free_bitfield_storage()
817 if (m_bitfield_storage_ptr)
818 free(m_bitfield_storage_ptr);
819 m_bitfield_storage_ptr = 0;
820 m_bitfield_storage_curr_ptr = 0;
821 m_bitfield_storage_len = 0;
825 RestoreDataIterator::get_free_bitfield_storage()
const
828 return Uint32((m_bitfield_storage_ptr + m_bitfield_storage_len) -
829 m_bitfield_storage_curr_ptr);
833 RestoreDataIterator::get_bitfield_storage(Uint32 len)
835 Uint32 * currptr = m_bitfield_storage_curr_ptr;
836 Uint32 * nextptr = currptr + len;
837 Uint32 * endptr = m_bitfield_storage_ptr + m_bitfield_storage_len;
839 if (nextptr <= endptr)
841 m_bitfield_storage_curr_ptr = nextptr;
851 prepareRecord(*tuple.m_currentTable);
854 memcpy(allAttrData, tuple.allAttrData, getNoOfAttributes()*
sizeof(
AttributeData));
858 int TupleS::getNoOfAttributes()
const {
859 if (m_currentTable == 0)
861 return m_currentTable->getNoOfAttributes();
864 TableS * TupleS::getTable()
const {
865 return m_currentTable;
869 return m_currentTable->allAttributesDesc[
i];
873 return &(allAttrData[
i]);
877 TupleS::prepareRecord(
TableS & tab){
879 if (getNoOfAttributes() == tab.getNoOfAttributes())
881 m_currentTable = &tab;
884 delete [] allAttrData;
889 if (allAttrData == 0)
892 m_currentTable = &tab;
900 pad(Uint8* src, Uint32 align, Uint32 bitPos)
902 UintPtr ptr = UintPtr(src);
904 case DictTabInfo::aBit:
905 case DictTabInfo::a32Bit:
906 case DictTabInfo::a64Bit:
907 case DictTabInfo::a128Bit:
908 return (Uint8*)(((ptr + 3) & ~(UintPtr)3) + 4 * ((bitPos + 31) >> 5));
910 case DictTabInfo::an8Bit:
911 case DictTabInfo::a16Bit:
912 return src + 4 * ((bitPos + 31) >> 5);
924 if (m_currentTable->backupVersion >= NDBD_RAW_LCP)
926 if (m_row_bitfield_len >= get_free_bitfield_storage())
933 if (free_data_callback)
934 (*free_data_callback)();
935 reset_bitfield_storage();
939 Uint32 dataLength = 0;
941 if (buffer_read(&dataLength,
sizeof(dataLength), 1) != 1){
942 err <<
"getNextTuple:Error reading length of data part" << endl;
948 dataLength = ntohl(dataLength);
949 const Uint32 dataLenBytes = 4 * dataLength;
951 if (dataLength == 0) {
954 debug <<
"End of fragment" << endl;
961 if (buffer_get_ptr(&_buf_ptr, 1, dataLenBytes) != dataLenBytes) {
962 err <<
"getNextTuple:Read error: " << endl;
967 Uint32 *buf_ptr = (Uint32*)_buf_ptr;
968 if (m_currentTable->backupVersion >= NDBD_RAW_LCP)
974 res = readTupleData_old(buf_ptr, dataLength);
988 RestoreDataIterator::getCurrentTable()
990 return m_currentTable;
997 Uint32 * ptr = buf_ptr;
1002 if(unlikely(!m_hostByteOrder))
1007 Uint32 bmlen = ah.getByteSize();
1008 assert((bmlen & 3) == 0);
1009 Uint32 bmlen32 = bmlen / 4;
1014 if (!m_hostByteOrder)
1016 for (Uint32 i = 0; i < 1 + bmlen32; i++)
1018 ptr[
i] = Twiddle32(ptr[i]);
1030 const Uint32 * bmptr = ptr + 1;
1031 Uint8* src = (Uint8*)(bmptr + bmlen32);
1034 for (Uint32 i = 0; i < (Uint32)tab->
getNoOfColumns(); i++, bmpos++)
1046 attr_data->null =
true;
1047 attr_data->void_value = NULL;
1052 attr_data->null =
false;
1058 Uint32 attrSize = col.m_attrSize;
1059 Uint32 array = col.m_arraySize;
1060 Uint32 len = col.m_length;
1061 Uint32 sz = attrSize * array;
1062 Uint32 arrayType = col.m_arrayType;
1065 case DictTabInfo::aBit:{
1066 src = pad(src, 0, 0);
1067 Uint32* src32 = (Uint32*)src;
1069 Uint32 len32 = (len + 31) >> 5;
1070 Uint32* tmp = get_bitfield_storage(len32);
1071 attr_data->null =
false;
1072 attr_data->void_value = tmp;
1073 attr_data->size = 4*len32;
1075 if (m_hostByteOrder)
1082 for (ii = 0; ii< (1 + len32); ii++)
1083 src32[ii] = Twiddle32(src32[ii]);
1085 for (ii = 0; ii< (1 + len32); ii++)
1086 src32[ii] = Twiddle32(src32[ii]);
1089 src += 4 * ((bitPos + len) >> 5);
1090 bitPos = (bitPos + len) & 31;
1094 src = pad(src, align, bitPos);
1097 case NDB_ARRAYTYPE_FIXED:
1099 case NDB_ARRAYTYPE_SHORT_VAR:
1102 case NDB_ARRAYTYPE_MEDIUM_VAR:
1103 sz = 2 + src[0] + 256 * src[1];
1109 attr_data->void_value = src;
1110 attr_data->size = sz;
1112 if(!Twiddle(attr_desc, attr_data))
1129 RestoreDataIterator::readTupleData_old(Uint32 *buf_ptr,
1132 Uint32 * ptr = buf_ptr;
1133 ptr += m_currentTable->m_nullBitmaskSize;
1135 for(i= 0; i < m_currentTable->m_fixedKeys.size(); i++){
1136 assert(ptr < buf_ptr + dataLength);
1138 const Uint32 attrId = m_currentTable->m_fixedKeys[
i]->attrId;
1143 const Uint32 sz = attr_desc->getSizeInWords();
1145 attr_data->null =
false;
1146 attr_data->void_value = ptr;
1147 attr_data->size = 4*sz;
1149 if(!Twiddle(attr_desc, attr_data))
1156 for(i = 0; i < m_currentTable->m_fixedAttribs.size(); i++){
1157 assert(ptr < buf_ptr + dataLength);
1159 const Uint32 attrId = m_currentTable->m_fixedAttribs[
i]->attrId;
1164 const Uint32 sz = attr_desc->getSizeInWords();
1166 attr_data->null =
false;
1167 attr_data->void_value = ptr;
1168 attr_data->size = 4*sz;
1170 if(!Twiddle(attr_desc, attr_data))
1179 for(i = 0; i < m_currentTable->m_variableAttribs.size(); i++){
1180 const Uint32 attrId = m_currentTable->m_variableAttribs[
i]->attrId;
1184 attr_data->null =
true;
1185 attr_data->void_value = NULL;
1189 if (!isDrop6(m_currentTable->backupVersion))
1191 if ((res = readVarData(buf_ptr, ptr, dataLength)))
1196 if ((res = readVarData_drop6(buf_ptr, ptr, dataLength)))
1204 RestoreDataIterator::readVarData(Uint32 *buf_ptr, Uint32 *ptr,
1207 while (ptr + 2 < buf_ptr + dataLength)
1210 VarData * data = (VarData *)ptr;
1211 Uint32 sz = ntohl(data->Sz);
1212 Uint32 attrId = ntohl(data->Id);
1218 if (m_currentTable->backupVersion < MAKE_VERSION(5,1,3) &&
1221 const Uint32 ind = attr_desc->m_nullBitIndex;
1225 attr_data->null =
true;
1226 attr_data->void_value = NULL;
1231 if (m_currentTable->backupVersion < MAKE_VERSION(5,1,3))
1236 attr_data->null =
false;
1237 attr_data->void_value = &data->Data[0];
1238 attr_data->size = sz;
1241 if(!Twiddle(attr_desc, attr_data))
1246 ptr += ((sz + 3) >> 2) + 2;
1249 assert(ptr == buf_ptr + dataLength);
1256 RestoreDataIterator::readVarData_drop6(Uint32 *buf_ptr, Uint32 *ptr,
1260 for (i = 0; i < m_currentTable->m_variableAttribs.size(); i++)
1262 const Uint32 attrId = m_currentTable->m_variableAttribs[
i]->attrId;
1269 const Uint32 ind = attr_desc->m_nullBitIndex;
1273 attr_data->null =
true;
1274 attr_data->void_value = NULL;
1279 assert(ptr < buf_ptr + dataLength);
1282 VarData * data = (VarData *)ptr;
1283 Uint32 sz = ntohl(data->Sz);
1284 Uint32
id = ntohl(data->Id);
1285 assert(
id == attrId);
1287 attr_data->null =
false;
1288 attr_data->void_value = &data->Data[0];
1290 if (!Twiddle(attr_desc, attr_data))
1296 assert(ptr == buf_ptr + dataLength);
1300 BackupFile::BackupFile(
void (* _free_data_callback)())
1301 : free_data_callback(_free_data_callback)
1303 memset(&m_file,0,
sizeof(m_file));
1307 m_buffer_sz = 64*1024;
1308 m_buffer = malloc(m_buffer_sz);
1309 m_buffer_ptr = m_buffer;
1310 m_buffer_data_left = 0;
1314 m_is_undolog =
false;
1317 BackupFile::~BackupFile()
1319 (void)ndbzclose(&m_file);
1326 BackupFile::openFile(){
1327 (void)ndbzclose(&m_file);
1332 info <<
"Opening file '" << m_fileName <<
"'\n";
1333 int r= ndbzopen(&m_file, m_fileName, O_RDONLY);
1339 if (ndbz_file_size(&m_file, &size) == 0)
1341 m_file_size = (Uint64)size;
1342 info <<
"File size " << m_file_size <<
" bytes\n";
1346 info <<
"Progress reporting degraded output since fstat failed,"
1347 <<
"errno: " << errno << endl;
1354 Uint32 BackupFile::buffer_get_ptr_ahead(
void **p_buf_ptr, Uint32 size, Uint32 nmemb)
1356 Uint32 sz = size*nmemb;
1357 if (sz > m_buffer_data_left) {
1359 if (free_data_callback)
1360 (*free_data_callback)();
1374 Uint64 file_left_entry_data = 0;
1375 Uint32 buffer_free_space = m_buffer_sz - m_buffer_data_left;
1376 void * buffer_end = (
char *)m_buffer + m_buffer_sz;
1377 void * buffer_data_start = (
char *)m_buffer_ptr - m_buffer_data_left;
1379 memmove((
char *)buffer_end - m_buffer_data_left, buffer_data_start, m_buffer_data_left);
1380 buffer_data_start = (
char *)buffer_end - m_buffer_data_left;
1395 if (m_file_pos >
sizeof(m_fileHeader))
1411 file_left_entry_data = m_file_pos -
sizeof(m_fileHeader);
1412 if (file_left_entry_data <= buffer_free_space)
1418 ndbzseek(&m_file,
sizeof(m_fileHeader), SEEK_SET);
1419 r = ndbzread(&m_file,
1420 (
char *)buffer_data_start - file_left_entry_data,
1421 Uint32(file_left_entry_data),
1424 ndbzseek(&m_file,
sizeof(m_fileHeader), SEEK_SET);
1429 ndbzseek(&m_file, m_file_pos-buffer_free_space, SEEK_SET);
1430 r = ndbzread(&m_file, ((
char *)m_buffer), buffer_free_space, &error);
1431 ndbzseek(&m_file, m_file_pos-buffer_free_space, SEEK_SET);
1435 m_buffer_data_left += (Uint32)r;
1437 m_buffer_ptr = buffer_end;
1441 memmove(m_buffer, m_buffer_ptr, m_buffer_data_left);
1443 Uint32 r = ndbzread(&m_file,
1444 ((
char *)m_buffer) + m_buffer_data_left,
1445 m_buffer_sz - m_buffer_data_left, &error);
1447 m_buffer_data_left += r;
1448 m_buffer_ptr = m_buffer;
1451 if (sz > m_buffer_data_left)
1452 sz = size * (m_buffer_data_left /
size);
1461 *p_buf_ptr = (
char *)m_buffer_ptr - sz;
1463 *p_buf_ptr = m_buffer_ptr;
1467 Uint32 BackupFile::buffer_get_ptr(
void **p_buf_ptr, Uint32 size, Uint32 nmemb)
1469 Uint32 r = buffer_get_ptr_ahead(p_buf_ptr, size, nmemb);
1476 m_buffer_ptr = ((
char*)m_buffer_ptr)-(r*
size);
1477 m_buffer_data_left -= (r*
size);
1481 m_buffer_ptr = ((
char*)m_buffer_ptr)+(r*
size);
1482 m_buffer_data_left -= (r*
size);
1488 Uint32 BackupFile::buffer_read_ahead(
void *ptr, Uint32 size, Uint32 nmemb)
1491 Uint32 r = buffer_get_ptr_ahead(&buf_ptr, size, nmemb);
1492 memcpy(ptr, buf_ptr, r*size);
1497 Uint32 BackupFile::buffer_read(
void *ptr, Uint32 size, Uint32 nmemb)
1500 Uint32 r = buffer_get_ptr(&buf_ptr, size, nmemb);
1501 memcpy(ptr, buf_ptr, r*size);
1507 BackupFile::setCtlFile(Uint32 nodeId, Uint32 backupId,
const char * path){
1509 m_expectedFileHeader.BackupId = backupId;
1510 m_expectedFileHeader.FileType = BackupFormat::CTL_FILE;
1512 char name[PATH_MAX];
const Uint32 sz =
sizeof(
name);
1514 setName(path, name);
1518 BackupFile::setDataFile(
const BackupFile & bf, Uint32 no){
1519 m_nodeId = bf.m_nodeId;
1520 m_expectedFileHeader = bf.m_fileHeader;
1521 m_expectedFileHeader.FileType = BackupFormat::DATA_FILE;
1523 char name[PATH_MAX];
const Uint32 sz =
sizeof(
name);
1525 m_expectedFileHeader.BackupId, no, m_nodeId);
1526 setName(bf.m_path, name);
1530 BackupFile::setLogFile(
const BackupFile & bf, Uint32 no){
1531 m_nodeId = bf.m_nodeId;
1532 m_expectedFileHeader = bf.m_fileHeader;
1533 m_expectedFileHeader.FileType = BackupFormat::LOG_FILE;
1535 char name[PATH_MAX];
const Uint32 sz =
sizeof(
name);
1537 m_expectedFileHeader.BackupId, m_nodeId);
1538 setName(bf.m_path, name);
1542 BackupFile::setName(
const char * p,
const char * n){
1543 const Uint32 sz =
sizeof(m_path);
1544 if(p != 0 && strlen(p) > 0){
1545 if(p[strlen(p)-1] == DIR_SEPARATOR[0]){
1555 debug <<
"Filename = " << m_fileName << endl;
1559 BackupFile::readHeader(){
1565 if(buffer_read(&m_fileHeader, oldsz, 1) != 1){
1566 err <<
"readDataFileHeader: Error reading header" << endl;
1577 Uint32 backup_version = ntohl(m_fileHeader.BackupVersion);
1578 m_fileHeader.BackupVersion = backup_version;
1579 m_fileHeader.SectionType = ntohl(m_fileHeader.SectionType);
1580 m_fileHeader.SectionLength = ntohl(m_fileHeader.SectionLength);
1581 m_fileHeader.FileType = ntohl(m_fileHeader.FileType);
1582 m_fileHeader.BackupId = ntohl(m_fileHeader.BackupId);
1583 m_fileHeader.BackupKey_0 = ntohl(m_fileHeader.BackupKey_0);
1584 m_fileHeader.BackupKey_1 = ntohl(m_fileHeader.BackupKey_1);
1586 if (backup_version >= NDBD_RAW_LCP)
1588 if (buffer_read(&m_fileHeader.NdbVersion,
1589 sizeof(m_fileHeader) - oldsz, 1) != 1)
1591 err <<
"readDataFileHeader: Error reading header" << endl;
1595 m_fileHeader.NdbVersion = ntohl(m_fileHeader.NdbVersion);
1596 m_fileHeader.MySQLVersion = ntohl(m_fileHeader.MySQLVersion);
1600 m_fileHeader.NdbVersion = m_fileHeader.BackupVersion;
1601 m_fileHeader.MySQLVersion = 0;
1604 debug <<
"FileHeader: " << m_fileHeader.Magic <<
" " <<
1605 m_fileHeader.BackupVersion <<
" " <<
1606 m_fileHeader.SectionType <<
" " <<
1607 m_fileHeader.SectionLength <<
" " <<
1608 m_fileHeader.FileType <<
" " <<
1609 m_fileHeader.BackupId <<
" " <<
1610 m_fileHeader.BackupKey_0 <<
" " <<
1611 m_fileHeader.BackupKey_1 <<
" " <<
1612 m_fileHeader.ByteOrder << endl;
1614 debug <<
"ByteOrder is " << m_fileHeader.ByteOrder << endl;
1615 debug <<
"magicByteOrder is " << magicByteOrder << endl;
1618 if (m_fileHeader.FileType != m_expectedFileHeader.FileType &&
1619 !(m_expectedFileHeader.FileType == BackupFormat::LOG_FILE &&
1620 m_fileHeader.FileType == BackupFormat::UNDO_FILE)){
1625 if(m_fileHeader.FileType == BackupFormat::UNDO_FILE){
1626 m_is_undolog =
true;
1633 if (ndbz_file_size(&m_file, &size) == 0)
1634 m_file_size = (Uint64)size;
1635 ndbzseek(&m_file, 4, SEEK_END);
1636 m_file_pos = m_file_size - 4;
1637 m_buffer_data_left = 0;
1638 m_buffer_ptr = m_buffer;
1642 if (m_fileHeader.ByteOrder == magicByteOrder) {
1643 m_hostByteOrder =
true;
1644 }
else if (m_fileHeader.ByteOrder == swappedMagicByteOrder){
1645 m_hostByteOrder =
false;
1654 BackupFile::validateFooter(){
1658 bool RestoreDataIterator::readFragmentHeader(
int & ret, Uint32 *fragmentId)
1662 debug <<
"RestoreDataIterator::getNextFragment" << endl;
1667 if (buffer_read(&Header, 8, 1) != 1)
1674 Header.SectionType = ntohl(Header.SectionType);
1675 Header.SectionLength = ntohl(Header.SectionLength);
1676 if (Header.SectionType == BackupFormat::EMPTY_ENTRY)
1679 if (Header.SectionLength < 2)
1681 err <<
"getFragmentFooter:Error reading fragment footer" << endl;
1684 if (Header.SectionLength > 2)
1685 buffer_get_ptr(&tmp, Header.SectionLength*4-8, 1);
1691 if (buffer_read(((
char*)&Header)+8, Header.SectionLength*4-8, 1) != 1)
1696 Header.TableId = ntohl(Header.TableId);
1697 Header.FragmentNo = ntohl(Header.FragmentNo);
1698 Header.ChecksumType = ntohl(Header.ChecksumType);
1700 debug <<
"FragmentHeader: " << Header.SectionType
1701 <<
" " << Header.SectionLength
1702 <<
" " << Header.TableId
1703 <<
" " << Header.FragmentNo
1704 <<
" " << Header.ChecksumType << endl;
1706 m_currentTable = m_metaData.getTable(Header.TableId);
1707 if(m_currentTable == 0){
1712 if(!m_tuple.prepareRecord(*m_currentTable))
1718 init_bitfield_storage(m_currentTable->m_dictTable);
1721 info <<
"_____________________________________________________" << endl
1722 <<
"Processing data in table: " << m_currentTable->getTableName()
1723 <<
"(" << Header.TableId <<
") fragment "
1724 << Header.FragmentNo << endl;
1728 *fragmentId = Header.FragmentNo;
1734 RestoreDataIterator::validateFragmentFooter() {
1737 if (buffer_read(&footer,
sizeof(footer), 1) != 1){
1738 err <<
"getFragmentFooter:Error reading fragment footer" << endl;
1743 footer.SectionType = ntohl(footer.SectionType);
1744 footer.SectionLength = ntohl(footer.SectionLength);
1745 footer.TableId = ntohl(footer.TableId);
1746 footer.FragmentNo = ntohl(footer.FragmentNo);
1747 footer.NoOfRecords = ntohl(footer.NoOfRecords);
1748 footer.Checksum = ntohl(footer.Checksum);
1750 assert(m_count == footer.NoOfRecords);
1756 : m_column(c), truncation_detected(false)
1758 size = 8*NdbColumnImpl::getImpl(* c).m_attrSize;
1759 arraySize = NdbColumnImpl::getImpl(* c).m_arraySize;
1766 ndbout_c(
"Restore: Failed to allocate memory");
1769 d->attrId = allAttributesDesc.size();
1770 d->convertFunc = NULL;
1771 d->parameter = NULL;
1772 d->m_exclude =
false;
1773 allAttributesDesc.push_back(d);
1775 if (d->m_column->getAutoIncrement())
1776 m_auto_val_attrib = d;
1778 if(d->m_column->
getPrimaryKey() && backupVersion <= MAKE_VERSION(4,1,7))
1780 m_fixedKeys.push_back(d);
1784 if (d->m_column->getArrayType() == NDB_ARRAYTYPE_FIXED &&
1787 m_fixedAttribs.push_back(d);
1792 if (backupVersion < MAKE_VERSION(5,1,3) || isDrop6(backupVersion))
1794 d->m_nullBitIndex = m_noOfNullable;
1796 m_nullBitmaskSize = (m_noOfNullable + 31) / 32;
1798 m_variableAttribs.push_back(d);
1802 TableS::get_auto_data(
const TupleS & tuple, Uint32 * syskey, Uint64 * nextid)
const
1817 const AttributeS attr1 = {attr_desc, *attr_data};
1818 memcpy(syskey ,attr1.Data.u_int32_value,
sizeof(Uint32));
1819 attr_data = tuple.getData(1);
1820 attr_desc = tuple.getDesc(1);
1821 const AttributeS attr2 = {attr_desc, *attr_data};
1822 memcpy(nextid, attr2.Data.u_int64_value,
sizeof(Uint64));
1823 if (*syskey < 0x10000000)
1830 Uint16 Twiddle16(Uint16 in)
1834 retVal = ((in & 0xFF00) >> 8) |
1835 ((in & 0x00FF) << 8);
1840 Uint32 Twiddle32(Uint32 in)
1844 retVal = ((in & 0x000000FF) << 24) |
1845 ((in & 0x0000FF00) << 8) |
1846 ((in & 0x00FF0000) >> 8) |
1847 ((in & 0xFF000000) >> 24);
1852 Uint64 Twiddle64(Uint64 in)
1857 ((in & (Uint64)0x00000000000000FFLL) << 56) |
1858 ((in & (Uint64)0x000000000000FF00LL) << 40) |
1859 ((in & (Uint64)0x0000000000FF0000LL) << 24) |
1860 ((in & (Uint64)0x00000000FF000000LL) << 8) |
1861 ((in & (Uint64)0x000000FF00000000LL) >> 8) |
1862 ((in & (Uint64)0x0000FF0000000000LL) >> 24) |
1863 ((in & (Uint64)0x00FF000000000000LL) >> 40) |
1864 ((in & (Uint64)0xFF00000000000000LL) >> 56);
1873 debug <<
"RestoreLog constructor" << endl;
1881 RestoreLogIterator::getNextLogEntry(
int & res) {
1883 const Uint32 stopGCP = m_metaData.getStopGCP();
1885 Uint32 triggerEvent;
1888 Uint32 attr_data_len;
1891 Uint32 *logEntryPtr;
1893 int read_result = 0;
1894 read_result = buffer_read(&len,
sizeof(Uint32), 1);
1896 if (read_result == 0 ) {
1900 if (read_result != 1) {
1906 if (buffer_read_ahead(&len,
sizeof(Uint32), 1) != 1){
1913 Uint32 data_len =
sizeof(Uint32) + len*4;
1914 if (buffer_get_ptr((
void **)(&logEntryPtr), 1, data_len) != data_len) {
1924 if (unlikely(m_metaData.getFileHeader().NdbVersion < NDBD_FRAGID_VERSION ||
1925 isDrop6(m_metaData.getFileHeader().NdbVersion)))
1935 LogE_no_fragid * logE_no_fragid= (LogE_no_fragid *)logEntryPtr;
1936 tableId= ntohl(logE_no_fragid->TableId);
1937 triggerEvent= ntohl(logE_no_fragid->TriggerEvent);
1939 attr_data= &logE_no_fragid->Data[0];
1940 attr_data_len= len - ((offsetof(LogE_no_fragid,
Data) >> 2) - 1);
1945 LogE * logE= (LogE *)logEntryPtr;
1946 tableId= ntohl(logE->TableId);
1947 triggerEvent= ntohl(logE->TriggerEvent);
1948 frag_id= ntohl(logE->FragId);
1949 attr_data= &logE->Data[0];
1950 attr_data_len= len - ((offsetof(LogE,
Data) >> 2) - 1);
1953 const bool hasGcp= (triggerEvent & 0x10000) != 0;
1954 triggerEvent &= 0xFFFF;
1959 m_last_gci = ntohl(*(attr_data + attr_data_len));
1961 }
while(m_last_gci > stopGCP + 1);
1963 m_logEntry.m_table = m_metaData.getTable(tableId);
1970 switch(triggerEvent){
1971 case TriggerEvent::TE_INSERT:
1973 m_logEntry.m_type = LogEntry::LE_DELETE;
1975 m_logEntry.m_type = LogEntry::LE_INSERT;
1977 case TriggerEvent::TE_UPDATE:
1978 m_logEntry.m_type = LogEntry::LE_UPDATE;
1980 case TriggerEvent::TE_DELETE:
1982 m_logEntry.m_type = LogEntry::LE_INSERT;
1984 m_logEntry.m_type = LogEntry::LE_DELETE;
1991 const TableS * tab = m_logEntry.m_table;
1997 m_logEntry.m_frag_id = frag_id;
1999 attr = m_logEntry.add_attr();
2001 ndbout_c(
"Restore: Failed to allocate memory");
2006 if(unlikely(!m_hostByteOrder))
2007 *(Uint32*)ah = Twiddle32(*(Uint32*)ah);
2010 assert(attr->Desc != 0);
2012 const Uint32 sz = ah->getDataSize();
2014 attr->Data.null =
true;
2015 attr->Data.void_value = NULL;
2017 attr->Data.null =
false;
2019 Twiddle(attr->Desc, &(attr->Data));
2032 operator<<(NdbOut& ndbout,
const AttributeS& attr){
2038 ndbout << g_ndbrecord_print_format.null_string;
2043 tmprec.setup(desc.m_column, 0);
2044 Uint32 length = (desc.size)/8 * (desc.arraySize);
2045 tmprec.receive_data((Uint32*)data.void_value, length);
2047 ndbrecattr_print_formatted(ndbout, tmprec, g_ndbrecord_print_format);
2054 operator<<(NdbOut& ndbout,
const TupleS& tuple)
2056 for (
int i = 0; i < tuple.getNoOfAttributes(); i++)
2059 ndbout << g_ndbrecord_print_format.fields_terminated_by;
2062 const AttributeS attr = {attr_desc, *attr_data};
2063 debug << i <<
" " << attr_desc->m_column->
getName();
2071 operator<<(NdbOut& ndbout,
const LogEntry& logE)
2075 case LogEntry::LE_INSERT:
2076 ndbout <<
"INSERT " << logE.m_table->getTableName() <<
" ";
2078 case LogEntry::LE_DELETE:
2079 ndbout <<
"DELETE " << logE.m_table->getTableName() <<
" ";
2081 case LogEntry::LE_UPDATE:
2082 ndbout <<
"UPDATE " << logE.m_table->getTableName() <<
" ";
2085 ndbout <<
"Unknown log entry type (not insert, delete or update)" ;
2088 for (Uint32 i= 0; i < logE.size();i++)
2091 ndbout << attr->Desc->m_column->
getName() <<
"=";
2093 if (i < (logE.size() - 1))
2102 operator<<(NdbOut& ndbout,
const TableS & table){
2104 ndbout << (* (
NDBT_Table*)table.m_dictTable) << endl;