summaryrefslogtreecommitdiff
path: root/storage/ndb/src/kernel/blocks/backup/read.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'storage/ndb/src/kernel/blocks/backup/read.cpp')
-rw-r--r--storage/ndb/src/kernel/blocks/backup/read.cpp478
1 files changed, 478 insertions, 0 deletions
diff --git a/storage/ndb/src/kernel/blocks/backup/read.cpp b/storage/ndb/src/kernel/blocks/backup/read.cpp
new file mode 100644
index 00000000000..89cc08ee9de
--- /dev/null
+++ b/storage/ndb/src/kernel/blocks/backup/read.cpp
@@ -0,0 +1,478 @@
+/* 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 <ndb_global.h>
+
+#include <NdbTCP.h>
+#include <NdbOut.hpp>
+#include "BackupFormat.hpp"
+#include <AttributeHeader.hpp>
+#include <SimpleProperties.hpp>
+
+bool readHeader(FILE*, BackupFormat::FileHeader *);
+bool readFragHeader(FILE*, BackupFormat::DataFile::FragmentHeader *);
+bool readFragFooter(FILE*, BackupFormat::DataFile::FragmentFooter *);
+Int32 readRecord(FILE*, Uint32 **);
+
+NdbOut & operator<<(NdbOut&, const BackupFormat::FileHeader &);
+NdbOut & operator<<(NdbOut&, const BackupFormat::DataFile::FragmentHeader &);
+NdbOut & operator<<(NdbOut&, const BackupFormat::DataFile::FragmentFooter &);
+
+bool readTableList(FILE*, BackupFormat::CtlFile::TableList **);
+bool readTableDesc(FILE*, BackupFormat::CtlFile::TableDescription **);
+bool readGCPEntry(FILE*, BackupFormat::CtlFile::GCPEntry **);
+
+NdbOut & operator<<(NdbOut&, const BackupFormat::CtlFile::TableList &);
+NdbOut & operator<<(NdbOut&, const BackupFormat::CtlFile::TableDescription &);
+NdbOut & operator<<(NdbOut&, const BackupFormat::CtlFile::GCPEntry &);
+
+Int32 readLogEntry(FILE*, Uint32**);
+
+static Uint32 recNo;
+static Uint32 logEntryNo;
+
+int
+main(int argc, const char * argv[]){
+
+ ndb_init();
+ if(argc <= 1){
+ printf("Usage: %s <filename>", argv[0]);
+ exit(1);
+ }
+ FILE * f = fopen(argv[1], "rb");
+ if(!f){
+ ndbout << "No such file!" << endl;
+ exit(1);
+ }
+
+ BackupFormat::FileHeader fileHeader;
+ if(!readHeader(f, &fileHeader)){
+ ndbout << "Invalid file!" << endl;
+ exit(1);
+ }
+ ndbout << fileHeader << endl;
+
+ switch(fileHeader.FileType){
+ case BackupFormat::DATA_FILE:
+ while(!feof(f)){
+ BackupFormat::DataFile::FragmentHeader fragHeader;
+ if(!readFragHeader(f, &fragHeader))
+ break;
+ ndbout << fragHeader << endl;
+
+ Uint32 len, * data;
+ while((len = readRecord(f, &data)) > 0){
+#if 0
+ ndbout << "-> " << hex;
+ for(Uint32 i = 0; i<len; i++){
+ ndbout << data[i] << " ";
+ }
+ ndbout << endl;
+#endif
+ }
+
+ BackupFormat::DataFile::FragmentFooter fragFooter;
+ if(!readFragFooter(f, &fragFooter))
+ break;
+ ndbout << fragFooter << endl;
+ }
+ break;
+ case BackupFormat::CTL_FILE:{
+ BackupFormat::CtlFile::TableList * tabList;
+ if(!readTableList(f, &tabList)){
+ ndbout << "Invalid file! No table list" << endl;
+ break;
+ }
+ ndbout << (* tabList) << endl;
+
+ const Uint32 noOfTables = tabList->SectionLength - 2;
+ for(Uint32 i = 0; i<noOfTables; i++){
+ BackupFormat::CtlFile::TableDescription * tabDesc;
+ if(!readTableDesc(f, &tabDesc)){
+ ndbout << "Invalid file missing table description" << endl;
+ break;
+ }
+ ndbout << (* tabDesc) << endl;
+ }
+
+ BackupFormat::CtlFile::GCPEntry * gcpE;
+ if(!readGCPEntry(f, &gcpE)){
+ ndbout << "Invalid file! GCP ENtry" << endl;
+ break;
+ }
+ ndbout << (* gcpE) << endl;
+
+ break;
+ }
+ case BackupFormat::LOG_FILE:{
+ logEntryNo = 0;
+
+ typedef BackupFormat::LogFile::LogEntry LogEntry;
+
+ Uint32 len, * data;
+ while((len = readLogEntry(f, &data)) > 0){
+ LogEntry * logEntry = (LogEntry *) data;
+ /**
+ * Log Entry
+ */
+ Uint32 event = ntohl(logEntry->TriggerEvent);
+ bool gcp = (event & 0x10000) != 0;
+ event &= 0xFFFF;
+ if(gcp)
+ len --;
+
+ ndbout << "LogEntry Table: " << (Uint32)ntohl(logEntry->TableId)
+ << " Event: " << event
+ << " Length: " << (len - 2);
+
+ const Uint32 dataLen = len - 2;
+#if 0
+ Uint32 pos = 0;
+ while(pos < dataLen){
+ AttributeHeader * ah = (AttributeHeader*)&logEntry->Data[pos];
+ ndbout_c(" Attribut: %d Size: %d",
+ ah->getAttributeId(),
+ ah->getDataSize());
+ pos += ah->getDataSize() + 1;
+ }
+#endif
+ if(gcp)
+ ndbout << " GCP: " << (Uint32)ntohl(logEntry->Data[dataLen]);
+ ndbout << endl;
+ }
+ break;
+ }
+ default:
+ ndbout << "Unsupported file type for printer: "
+ << fileHeader.FileType << endl;
+ break;
+ }
+ fclose(f);
+ return 0;
+}
+
+#define RETURN_FALSE() { ndbout_c("false: %d", __LINE__); abort(); return false; }
+
+static bool endian = false;
+
+bool
+readHeader(FILE* f, BackupFormat::FileHeader * dst){
+ if(fread(dst, 4, 3, f) != 3)
+ RETURN_FALSE();
+
+ if(memcmp(dst->Magic, BACKUP_MAGIC, sizeof(BACKUP_MAGIC)) != 0)
+ RETURN_FALSE();
+
+ dst->NdbVersion = ntohl(dst->NdbVersion);
+ if(dst->NdbVersion != 210)
+ RETURN_FALSE();
+
+ if(fread(&dst->SectionType, 4, 2, f) != 2)
+ RETURN_FALSE();
+ dst->SectionType = ntohl(dst->SectionType);
+ dst->SectionLength = ntohl(dst->SectionLength);
+
+ if(dst->SectionType != BackupFormat::FILE_HEADER)
+ RETURN_FALSE();
+
+ if(dst->SectionLength != ((sizeof(BackupFormat::FileHeader) - 12) >> 2))
+ RETURN_FALSE();
+
+ if(fread(&dst->FileType, 4, dst->SectionLength - 2, f) !=
+ (dst->SectionLength - 2))
+ RETURN_FALSE();
+
+ dst->FileType = ntohl(dst->FileType);
+ dst->BackupId = ntohl(dst->BackupId);
+ dst->BackupKey_0 = ntohl(dst->BackupKey_0);
+ dst->BackupKey_1 = ntohl(dst->BackupKey_1);
+
+ if(dst->FileType < BackupFormat::CTL_FILE ||
+ dst->FileType > BackupFormat::DATA_FILE)
+ RETURN_FALSE();
+
+ if(dst->ByteOrder != 0x12345678)
+ endian = true;
+
+ return true;
+}
+
+bool
+readFragHeader(FILE* f, BackupFormat::DataFile::FragmentHeader * dst){
+ if(fread(dst, 1, sizeof(* dst), f) != sizeof(* dst))
+ return false;
+
+ dst->SectionType = ntohl(dst->SectionType);
+ dst->SectionLength = ntohl(dst->SectionLength);
+ dst->TableId = ntohl(dst->TableId);
+ dst->FragmentNo = ntohl(dst->FragmentNo);
+ dst->ChecksumType = ntohl(dst->ChecksumType);
+
+ if(dst->SectionLength != (sizeof(* dst) >> 2))
+ RETURN_FALSE();
+
+ if(dst->SectionType != BackupFormat::FRAGMENT_HEADER)
+ RETURN_FALSE();
+
+ recNo = 0;
+
+ return true;
+}
+
+bool
+readFragFooter(FILE* f, BackupFormat::DataFile::FragmentFooter * dst){
+ if(fread(dst, 1, sizeof(* dst), f) != sizeof(* dst))
+ RETURN_FALSE();
+
+ dst->SectionType = ntohl(dst->SectionType);
+ dst->SectionLength = ntohl(dst->SectionLength);
+ dst->TableId = ntohl(dst->TableId);
+ dst->FragmentNo = ntohl(dst->FragmentNo);
+ dst->NoOfRecords = ntohl(dst->NoOfRecords);
+ dst->Checksum = ntohl(dst->Checksum);
+
+ if(dst->SectionLength != (sizeof(* dst) >> 2))
+ RETURN_FALSE();
+
+ if(dst->SectionType != BackupFormat::FRAGMENT_FOOTER)
+ RETURN_FALSE();
+ return true;
+}
+
+static Uint32 buf[8192];
+
+Int32
+readRecord(FILE* f, Uint32 **dst){
+ Uint32 len;
+ if(fread(&len, 1, 4, f) != 4)
+ RETURN_FALSE();
+
+ len = ntohl(len);
+
+ if(fread(buf, 4, len, f) != len)
+ return -1;
+
+ if(len > 0)
+ recNo++;
+
+ * dst = &buf[0];
+
+ return len;
+}
+
+Int32
+readLogEntry(FILE* f, Uint32 **dst){
+ Uint32 len;
+ if(fread(&len, 1, 4, f) != 4)
+ RETURN_FALSE();
+
+ len = ntohl(len);
+
+ if(fread(&buf[1], 4, len, f) != len)
+ return -1;
+
+ buf[0] = len;
+
+ if(len > 0)
+ logEntryNo++;
+
+ * dst = &buf[0];
+
+ return len;
+}
+
+
+NdbOut &
+operator<<(NdbOut& ndbout, const BackupFormat::FileHeader & hf){
+
+ char buf[9];
+ memcpy(buf, hf.Magic, sizeof(hf.Magic));
+ buf[8] = 0;
+
+ ndbout << "-- FileHeader:" << endl;
+ ndbout << "Magic: " << buf << endl;
+ ndbout << "NdbVersion: " << hf.NdbVersion << endl;
+ ndbout << "SectionType: " << hf.SectionType << endl;
+ ndbout << "SectionLength: " << hf.SectionLength << endl;
+ ndbout << "FileType: " << hf.FileType << endl;
+ ndbout << "BackupId: " << hf.BackupId << endl;
+ ndbout << "BackupKey: [ " << hex << hf.BackupKey_0
+ << " "<< hf.BackupKey_1 << " ]" << endl;
+ ndbout << "ByteOrder: " << hex << hf.ByteOrder << endl;
+ return ndbout;
+}
+
+NdbOut & operator<<(NdbOut& ndbout,
+ const BackupFormat::DataFile::FragmentHeader & hf){
+
+ ndbout << "-- Fragment header:" << endl;
+ ndbout << "SectionType: " << hf.SectionType << endl;
+ ndbout << "SectionLength: " << hf.SectionLength << endl;
+ ndbout << "TableId: " << hf.TableId << endl;
+ ndbout << "FragmentNo: " << hf.FragmentNo << endl;
+ ndbout << "ChecksumType: " << hf.ChecksumType << endl;
+
+ return ndbout;
+}
+NdbOut & operator<<(NdbOut& ndbout,
+ const BackupFormat::DataFile::FragmentFooter & hf){
+
+ ndbout << "-- Fragment footer:" << endl;
+ ndbout << "SectionType: " << hf.SectionType << endl;
+ ndbout << "SectionLength: " << hf.SectionLength << endl;
+ ndbout << "TableId: " << hf.TableId << endl;
+ ndbout << "FragmentNo: " << hf.FragmentNo << endl;
+ ndbout << "NoOfRecords: " << hf.NoOfRecords << endl;
+ ndbout << "Checksum: " << hf.Checksum << endl;
+
+ return ndbout;
+}
+
+bool
+readTableList(FILE* f, BackupFormat::CtlFile::TableList **ret){
+ BackupFormat::CtlFile::TableList * dst =
+ (BackupFormat::CtlFile::TableList *)&buf[0];
+
+ if(fread(dst, 4, 2, f) != 2)
+ RETURN_FALSE();
+
+ dst->SectionType = ntohl(dst->SectionType);
+ dst->SectionLength = ntohl(dst->SectionLength);
+
+ if(dst->SectionType != BackupFormat::TABLE_LIST)
+ RETURN_FALSE();
+
+ const Uint32 len = dst->SectionLength - 2;
+ if(fread(&dst->TableIds[0], 4, len, f) != len)
+ RETURN_FALSE();
+
+ for(Uint32 i = 0; i<len; i++){
+ dst->TableIds[i] = ntohl(dst->TableIds[i]);
+ }
+
+ * ret = dst;
+
+ return true;
+}
+
+bool
+readTableDesc(FILE* f, BackupFormat::CtlFile::TableDescription **ret){
+ BackupFormat::CtlFile::TableDescription * dst =
+ (BackupFormat::CtlFile::TableDescription *)&buf[0];
+
+ if(fread(dst, 4, 2, f) != 2)
+ RETURN_FALSE();
+
+ dst->SectionType = ntohl(dst->SectionType);
+ dst->SectionLength = ntohl(dst->SectionLength);
+
+ if(dst->SectionType != BackupFormat::TABLE_DESCRIPTION)
+ RETURN_FALSE();
+
+ const Uint32 len = dst->SectionLength - 2;
+ if(fread(&dst->DictTabInfo[0], 4, len, f) != len)
+ RETURN_FALSE();
+
+ * ret = dst;
+
+ return true;
+}
+
+bool
+readGCPEntry(FILE* f, BackupFormat::CtlFile::GCPEntry **ret){
+ BackupFormat::CtlFile::GCPEntry * dst =
+ (BackupFormat::CtlFile::GCPEntry *)&buf[0];
+
+ if(fread(dst, 4, 4, f) != 4)
+ RETURN_FALSE();
+
+ dst->SectionType = ntohl(dst->SectionType);
+ dst->SectionLength = ntohl(dst->SectionLength);
+
+ if(dst->SectionType != BackupFormat::GCP_ENTRY)
+ RETURN_FALSE();
+
+ dst->StartGCP = ntohl(dst->StartGCP);
+ dst->StopGCP = ntohl(dst->StopGCP);
+
+ * ret = dst;
+
+ return true;
+}
+
+
+NdbOut &
+operator<<(NdbOut& ndbout, const BackupFormat::CtlFile::TableList & hf) {
+ ndbout << "-- Table List:" << endl;
+ ndbout << "SectionType: " << hf.SectionType << endl;
+ ndbout << "SectionLength: " << hf.SectionLength << endl;
+ for(Uint32 i = 0; i < hf.SectionLength - 2; i++){
+ ndbout << hf.TableIds[i] << " ";
+ if((i + 1) % 16 == 0)
+ ndbout << endl;
+ }
+ return ndbout;
+}
+
+NdbOut &
+operator<<(NdbOut& ndbout, const BackupFormat::CtlFile::TableDescription & hf){
+ ndbout << "-- Table Description:" << endl;
+ ndbout << "SectionType: " << hf.SectionType << endl;
+ ndbout << "SectionLength: " << hf.SectionLength << endl;
+
+ SimplePropertiesLinearReader it(&hf.DictTabInfo[0], hf.SectionLength - 2);
+ char buf[1024];
+ for(it.first(); it.valid(); it.next()){
+ switch(it.getValueType()){
+ case SimpleProperties::Uint32Value:
+ ndbout << "Key: " << it.getKey()
+ << " value(" << it.getValueLen() << ") : "
+ << it.getUint32() << endl;
+ break;
+ case SimpleProperties::StringValue:
+ if(it.getValueLen() < sizeof(buf)){
+ it.getString(buf);
+ ndbout << "Key: " << it.getKey()
+ << " value(" << it.getValueLen() << ") : "
+ << "\"" << buf << "\"" << endl;
+ } else {
+ ndbout << "Key: " << it.getKey()
+ << " value(" << it.getValueLen() << ") : "
+ << "\"" << "<TOO LONG>" << "\"" << endl;
+
+ }
+ break;
+ default:
+ ndbout << "Unknown type for key: " << it.getKey()
+ << " type: " << it.getValueType() << endl;
+ }
+ }
+
+ return ndbout;
+}
+
+NdbOut &
+operator<<(NdbOut& ndbout, const BackupFormat::CtlFile::GCPEntry & hf) {
+ ndbout << "-- GCP Entry:" << endl;
+ ndbout << "SectionType: " << hf.SectionType << endl;
+ ndbout << "SectionLength: " << hf.SectionLength << endl;
+ ndbout << "Start GCP: " << hf.StartGCP << endl;
+ ndbout << "Stop GCP: " << hf.StopGCP << endl;
+
+ return ndbout;
+}
+