MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
read.cpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
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 St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 
19 #include <ndb_global.h>
20 
21 #include <NdbTCP.h>
22 #include <NdbOut.hpp>
23 #include "BackupFormat.hpp"
24 #include <AttributeHeader.hpp>
25 #include <SimpleProperties.hpp>
26 #include <ndb_version.h>
27 #include <util/ndbzio.h>
28 
29 bool readHeader(ndbzio_stream*, BackupFormat::FileHeader *);
32 Int32 readRecord(ndbzio_stream*, Uint32 **);
33 
34 NdbOut & operator<<(NdbOut&, const BackupFormat::FileHeader &);
35 NdbOut & operator<<(NdbOut&, const BackupFormat::DataFile::FragmentHeader &);
36 NdbOut & operator<<(NdbOut&, const BackupFormat::DataFile::FragmentFooter &);
37 
38 bool readTableList(ndbzio_stream*, BackupFormat::CtlFile::TableList **);
40 bool readGCPEntry(ndbzio_stream*, BackupFormat::CtlFile::GCPEntry **);
41 
42 NdbOut & operator<<(NdbOut&, const BackupFormat::CtlFile::TableList &);
43 NdbOut & operator<<(NdbOut&, const BackupFormat::CtlFile::TableDescription &);
44 NdbOut & operator<<(NdbOut&, const BackupFormat::CtlFile::GCPEntry &);
45 
46 Int32 readLogEntry(ndbzio_stream*, Uint32**);
47 
48 static Uint32 recNo;
49 static Uint32 logEntryNo;
50 
51 int
52 main(int argc, const char * argv[]){
53 
54  ndb_init();
55  if(argc <= 1){
56  printf("Usage: %s <filename>\n", argv[0]);
57  exit(1);
58  }
59 
60  ndbzio_stream fo;
61  bzero(&fo, sizeof(fo));
62  int r= ndbzopen(&fo,argv[1], O_RDONLY);
63 
64  if(r != 1)
65  {
66  ndbout_c("Failed to open file '%s', error: %d",
67  argv[1], r);
68  exit(1);
69  }
70 
71  ndbzio_stream* f = &fo;
72 
73  BackupFormat::FileHeader fileHeader;
74  if(!readHeader(f, &fileHeader)){
75  ndbout << "Invalid file!" << endl;
76  exit(1);
77  }
78  ndbout << fileHeader << endl;
79 
80  switch(fileHeader.FileType){
81  case BackupFormat::DATA_FILE:
82  while(f->z_eof){
84  if(!readFragHeader(f, &fragHeader))
85  break;
86  ndbout << fragHeader << endl;
87 
88  Uint32 len, * data;
89  while((len = readRecord(f, &data)) > 0){
90 #if 0
91  ndbout << "-> " << hex;
92  for(Uint32 i = 0; i<len; i++){
93  ndbout << data[i] << " ";
94  }
95  ndbout << endl;
96 #endif
97  }
98 
100  if(!readFragFooter(f, &fragFooter))
101  break;
102  ndbout << fragFooter << endl;
103  }
104  break;
105  case BackupFormat::CTL_FILE:{
107  if(!readTableList(f, &tabList)){
108  ndbout << "Invalid file! No table list" << endl;
109  break;
110  }
111  ndbout << (* tabList) << endl;
112 
113  const Uint32 noOfTables = tabList->SectionLength - 2;
114  for(Uint32 i = 0; i<noOfTables; i++){
116  if(!readTableDesc(f, &tabDesc)){
117  ndbout << "Invalid file missing table description" << endl;
118  break;
119  }
120  ndbout << (* tabDesc) << endl;
121  }
122 
124  if(!readGCPEntry(f, &gcpE)){
125  ndbout << "Invalid file! GCP ENtry" << endl;
126  break;
127  }
128  ndbout << (* gcpE) << endl;
129 
130  break;
131  }
132  case BackupFormat::LOG_FILE:{
133  logEntryNo = 0;
134 
136 
137  Uint32 len, * data;
138  while((len = readLogEntry(f, &data)) > 0){
139  LogEntry * logEntry = (LogEntry *) data;
143  Uint32 event = ntohl(logEntry->TriggerEvent);
144  bool gcp = (event & 0x10000) != 0;
145  event &= 0xFFFF;
146  if(gcp)
147  len --;
148 
149  ndbout << "LogEntry Table: " << (Uint32)ntohl(logEntry->TableId)
150  << " Event: " << event
151  << " Length: " << (len - 2);
152 
153  const Uint32 dataLen = len - 2;
154 #if 0
155  Uint32 pos = 0;
156  while(pos < dataLen){
157  AttributeHeader * ah = (AttributeHeader*)&logEntry->Data[pos];
158  ndbout_c(" Attribut: %d Size: %d",
159  ah->getAttributeId(),
160  ah->getDataSize());
161  pos += ah->getDataSize() + 1;
162  }
163 #endif
164  if(gcp)
165  ndbout << " GCP: " << (Uint32)ntohl(logEntry->Data[dataLen]);
166  ndbout << endl;
167  }
168  break;
169  }
170  case BackupFormat::LCP_FILE:
171  {
173  if(!readTableList(f, &tabList)){
174  ndbout << "Invalid file! No table list" << endl;
175  break;
176  }
177  ndbout << (* tabList) << endl;
178 
179  const Uint32 noOfTables = tabList->SectionLength - 2;
180  for(Uint32 i = 0; i<noOfTables; i++){
182  if(!readTableDesc(f, &tabDesc)){
183  ndbout << "Invalid file missing table description" << endl;
184  break;
185  }
186  ndbout << (* tabDesc) << endl;
187  }
188 
189  while(!f->z_eof){
191  if(!readFragHeader(f, &fragHeader))
192  break;
193  ndbout << fragHeader << endl;
194 
195  Uint32 len, * data;
196  while((len = readRecord(f, &data)) > 0){
197 #if 0
198  ndbout << "-> " << hex;
199  for(Uint32 i = 0; i<len; i++){
200  ndbout << data[i] << " ";
201  }
202  ndbout << endl;
203 #endif
204  }
205 
207  if(!readFragFooter(f, &fragFooter))
208  break;
209  ndbout << fragFooter << endl;
210  }
211  break;
212  }
213  default:
214  ndbout << "Unsupported file type for printer: "
215  << fileHeader.FileType << endl;
216  break;
217  }
218  ndbzclose(f);
219  return 0;
220 }
221 
222 #define RETURN_FALSE() { ndbout_c("false: %d", __LINE__); abort(); return false; }
223 
224 static bool endian = false;
225 
226 static
227 inline
228 size_t
229 aread(void * buf, size_t sz, size_t n, ndbzio_stream* f)
230 {
231  int error = 0;
232  unsigned r = ndbzread(f, buf, (sz * n), &error);
233  if (error || r != (sz * n))
234  {
235  printf("Failed to read!!");
236  exit(1);
237  }
238  return r / sz;
239 }
240 
241 bool
242 readHeader(ndbzio_stream* f, BackupFormat::FileHeader * dst){
243  if(aread(dst, 4, 3, f) != 3)
244  RETURN_FALSE();
245 
246  if(memcmp(dst->Magic, BACKUP_MAGIC, sizeof(BACKUP_MAGIC)) != 0)
247  {
248  ndbout_c("Incorrect file-header!");
249  printf("Found: ");
250  for (unsigned i = 0; i<sizeof(BACKUP_MAGIC); i++)
251  printf("0x%.2x ", (Uint32)(Uint8)dst->Magic[i]);
252  printf("\n");
253  printf("Expect: ");
254  for (unsigned i = 0; i<sizeof(BACKUP_MAGIC); i++)
255  printf("0x%.2x ", (Uint32)(Uint8)BACKUP_MAGIC[i]);
256  printf("\n");
257 
258  RETURN_FALSE();
259  }
260 
261  dst->BackupVersion = ntohl(dst->BackupVersion);
262  if(dst->BackupVersion >= NDB_VERSION)
263  {
264  printf("incorrect versions, file: 0x%x expect: 0x%x\n", dst->NdbVersion, NDB_VERSION);
265  RETURN_FALSE();
266  }
267 
268  if(aread(&dst->SectionType, 4, 2, f) != 2)
269  RETURN_FALSE();
270  dst->SectionType = ntohl(dst->SectionType);
271  dst->SectionLength = ntohl(dst->SectionLength);
272 
273  if(dst->SectionType != BackupFormat::FILE_HEADER)
274  RETURN_FALSE();
275 
276  if(dst->SectionLength != ((sizeof(BackupFormat::FileHeader) - 12) >> 2))
277  RETURN_FALSE();
278 
279  if(aread(&dst->FileType, 4, dst->SectionLength - 2, f) !=
280  (dst->SectionLength - 2))
281  RETURN_FALSE();
282 
283  dst->FileType = ntohl(dst->FileType);
284  dst->BackupId = ntohl(dst->BackupId);
285  dst->BackupKey_0 = ntohl(dst->BackupKey_0);
286  dst->BackupKey_1 = ntohl(dst->BackupKey_1);
287 
288  if(dst->ByteOrder != 0x12345678)
289  endian = true;
290 
291  return true;
292 }
293 
294 bool
295 readFragHeader(ndbzio_stream* f, BackupFormat::DataFile::FragmentHeader * dst){
296  if(aread(dst, 1, sizeof(* dst), f) != sizeof(* dst))
297  return false;
298 
299  dst->SectionType = ntohl(dst->SectionType);
300  dst->SectionLength = ntohl(dst->SectionLength);
301  dst->TableId = ntohl(dst->TableId);
302  dst->FragmentNo = ntohl(dst->FragmentNo);
303  dst->ChecksumType = ntohl(dst->ChecksumType);
304 
305  if(dst->SectionLength != (sizeof(* dst) >> 2))
306  RETURN_FALSE();
307 
308  if(dst->SectionType != BackupFormat::FRAGMENT_HEADER)
309  RETURN_FALSE();
310 
311  recNo = 0;
312 
313  return true;
314 }
315 
316 bool
317 readFragFooter(ndbzio_stream* f, BackupFormat::DataFile::FragmentFooter * dst){
318  if(aread(dst, 1, sizeof(* dst), f) != sizeof(* dst))
319  RETURN_FALSE();
320 
321  dst->SectionType = ntohl(dst->SectionType);
322  dst->SectionLength = ntohl(dst->SectionLength);
323  dst->TableId = ntohl(dst->TableId);
324  dst->FragmentNo = ntohl(dst->FragmentNo);
325  dst->NoOfRecords = ntohl(dst->NoOfRecords);
326  dst->Checksum = ntohl(dst->Checksum);
327 
328  if(dst->SectionLength != (sizeof(* dst) >> 2))
329  RETURN_FALSE();
330 
331  if(dst->SectionType != BackupFormat::FRAGMENT_FOOTER)
332  RETURN_FALSE();
333  return true;
334 }
335 
336 
337 static union {
338  Uint32 buf[8192];
343 } theData;
344 
345 Int32
346 readRecord(ndbzio_stream* f, Uint32 **dst){
347  Uint32 len;
348  if(aread(&len, 1, 4, f) != 4)
349  RETURN_FALSE();
350 
351  len = ntohl(len);
352 
353  if(aread(theData.buf, 4, len, f) != len)
354  {
355  return -1;
356  }
357 
358  if(len > 0)
359  recNo++;
360  else
361  ndbout_c("Found %d records", recNo);
362 
363  * dst = &theData.buf[0];
364 
365 
366  return len;
367 }
368 
369 Int32
370 readLogEntry(ndbzio_stream* f, Uint32 **dst){
371  Uint32 len;
372  if(aread(&len, 1, 4, f) != 4)
373  RETURN_FALSE();
374 
375  len = ntohl(len);
376 
377  if(aread(&theData.buf[1], 4, len, f) != len)
378  return -1;
379 
380  theData.buf[0] = len;
381 
382  if(len > 0)
383  logEntryNo++;
384 
385  * dst = &theData.buf[0];
386 
387  return len;
388 }
389 
390 
391 NdbOut &
392 operator<<(NdbOut& ndbout, const BackupFormat::FileHeader & hf){
393 
394  char buf[9];
395  memcpy(buf, hf.Magic, sizeof(hf.Magic));
396  buf[8] = 0;
397 
398  ndbout << "-- FileHeader:" << endl;
399  ndbout << "Magic: " << buf << endl;
400  ndbout << "BackupVersion: " << hex << hf.BackupVersion << endl;
401  ndbout << "SectionType: " << hf.SectionType << endl;
402  ndbout << "SectionLength: " << hf.SectionLength << endl;
403  ndbout << "FileType: " << hf.FileType << endl;
404  ndbout << "BackupId: " << hf.BackupId << endl;
405  ndbout << "BackupKey: [ " << hex << hf.BackupKey_0
406  << " "<< hf.BackupKey_1 << " ]" << endl;
407  ndbout << "ByteOrder: " << hex << hf.ByteOrder << endl;
408  return ndbout;
409 }
410 
411 NdbOut & operator<<(NdbOut& ndbout,
413 
414  ndbout << "-- Fragment header:" << endl;
415  ndbout << "SectionType: " << hf.SectionType << endl;
416  ndbout << "SectionLength: " << hf.SectionLength << endl;
417  ndbout << "TableId: " << hf.TableId << endl;
418  ndbout << "FragmentNo: " << hf.FragmentNo << endl;
419  ndbout << "ChecksumType: " << hf.ChecksumType << endl;
420 
421  return ndbout;
422 }
423 NdbOut & operator<<(NdbOut& ndbout,
425 
426  ndbout << "-- Fragment footer:" << endl;
427  ndbout << "SectionType: " << hf.SectionType << endl;
428  ndbout << "SectionLength: " << hf.SectionLength << endl;
429  ndbout << "TableId: " << hf.TableId << endl;
430  ndbout << "FragmentNo: " << hf.FragmentNo << endl;
431  ndbout << "NoOfRecords: " << hf.NoOfRecords << endl;
432  ndbout << "Checksum: " << hf.Checksum << endl;
433 
434  return ndbout;
435 }
436 
437 bool
439  BackupFormat::CtlFile::TableList * dst = &theData.TableList;
440 
441  if(aread(dst, 4, 2, f) != 2)
442  RETURN_FALSE();
443 
444  dst->SectionType = ntohl(dst->SectionType);
445  dst->SectionLength = ntohl(dst->SectionLength);
446 
447  if(dst->SectionType != BackupFormat::TABLE_LIST)
448  RETURN_FALSE();
449 
450  const Uint32 len = dst->SectionLength - 2;
451  if(aread(&dst->TableIds[0], 4, len, f) != len)
452  RETURN_FALSE();
453 
454  for(Uint32 i = 0; i<len; i++){
455  dst->TableIds[i] = ntohl(dst->TableIds[i]);
456  }
457 
458  * ret = dst;
459 
460  return true;
461 }
462 
463 bool
465  BackupFormat::CtlFile::TableDescription * dst = &theData.TableDescription;
466 
467  if(aread(dst, 4, 3, f) != 3)
468  RETURN_FALSE();
469 
470  dst->SectionType = ntohl(dst->SectionType);
471  dst->SectionLength = ntohl(dst->SectionLength);
472  dst->TableType = ntohl(dst->TableType);
473 
474  if(dst->SectionType != BackupFormat::TABLE_DESCRIPTION)
475  RETURN_FALSE();
476 
477  const Uint32 len = dst->SectionLength - 3;
478  if(aread(&dst->DictTabInfo[0], 4, len, f) != len)
479  RETURN_FALSE();
480 
481  * ret = dst;
482 
483  return true;
484 }
485 
486 bool
487 readGCPEntry(ndbzio_stream* f, BackupFormat::CtlFile::GCPEntry **ret){
488  BackupFormat::CtlFile::GCPEntry * dst = &theData.GcpEntry;
489 
490  if(aread(dst, 4, 4, f) != 4)
491  RETURN_FALSE();
492 
493  dst->SectionType = ntohl(dst->SectionType);
494  dst->SectionLength = ntohl(dst->SectionLength);
495 
496  if(dst->SectionType != BackupFormat::GCP_ENTRY)
497  RETURN_FALSE();
498 
499  dst->StartGCP = ntohl(dst->StartGCP);
500  dst->StopGCP = ntohl(dst->StopGCP);
501 
502  * ret = dst;
503 
504  return true;
505 }
506 
507 
508 NdbOut &
509 operator<<(NdbOut& ndbout, const BackupFormat::CtlFile::TableList & hf) {
510  ndbout << "-- Table List:" << endl;
511  ndbout << "SectionType: " << hf.SectionType << endl;
512  ndbout << "SectionLength: " << hf.SectionLength << endl;
513  for(Uint32 i = 0; i < hf.SectionLength - 2; i++){
514  ndbout << hf.TableIds[i] << " ";
515  if((i + 1) % 16 == 0)
516  ndbout << endl;
517  }
518  return ndbout;
519 }
520 
521 NdbOut &
522 operator<<(NdbOut& ndbout, const BackupFormat::CtlFile::TableDescription & hf){
523  ndbout << "-- Table Description:" << endl;
524  ndbout << "SectionType: " << hf.SectionType << endl;
525  ndbout << "SectionLength: " << hf.SectionLength << endl;
526  ndbout << "TableType: " << hf.TableType << endl;
527 
528  SimplePropertiesLinearReader it(&hf.DictTabInfo[0], hf.SectionLength - 3);
529  char buf[1024];
530  for(it.first(); it.valid(); it.next()){
531  switch(it.getValueType()){
532  case SimpleProperties::Uint32Value:
533  ndbout << "Key: " << it.getKey()
534  << " value(" << it.getValueLen() << ") : "
535  << it.getUint32() << endl;
536  break;
537  case SimpleProperties::StringValue:
538  if(it.getValueLen() < sizeof(buf)){
539  it.getString(buf);
540  ndbout << "Key: " << it.getKey()
541  << " value(" << it.getValueLen() << ") : "
542  << "\"" << buf << "\"" << endl;
543  } else {
544  ndbout << "Key: " << it.getKey()
545  << " value(" << it.getValueLen() << ") : "
546  << "\"" << "<TOO LONG>" << "\"" << endl;
547 
548  }
549  break;
550  default:
551  ndbout << "Unknown type for key: " << it.getKey()
552  << " type: " << it.getValueType() << endl;
553  }
554  }
555 
556  return ndbout;
557 }
558 
559 NdbOut &
560 operator<<(NdbOut& ndbout, const BackupFormat::CtlFile::GCPEntry & hf) {
561  ndbout << "-- GCP Entry:" << endl;
562  ndbout << "SectionType: " << hf.SectionType << endl;
563  ndbout << "SectionLength: " << hf.SectionLength << endl;
564  ndbout << "Start GCP: " << hf.StartGCP << endl;
565  ndbout << "Stop GCP: " << hf.StopGCP << endl;
566 
567  return ndbout;
568 }
569