29 #include <ndb_global.h>
32 #include "records.hpp"
34 #define RETURN_ERROR 1
37 #define FROM_BEGINNING 0
39 void usage(
const char * prg);
40 Uint32 readFromFile(FILE * f, Uint32 *toPtr, Uint32 sizeInWords);
41 void readArguments(
int argc,
const char** argv);
46 bool theDumpFlag =
false;
47 bool thePrintFlag =
true;
48 bool theCheckFlag =
true;
49 bool onlyPageHeaders =
false;
50 bool onlyMbyteHeaders =
false;
51 bool onlyFileDesc =
false;
53 bool theTwiddle =
false;
54 Uint32 startAtMbyte = 0;
55 Uint32 startAtPage = 0;
56 Uint32 startAtPageIndex = 0;
59 unsigned NO_MBYTE_IN_FILE = 16;
61 NDB_COMMAND(redoLogFileReader,
"redoLogFileReader",
"redoLogFileReader",
"Read a redo log file", 16384) {
64 Uint32 oldWordIndex = 0;
65 Uint32 recordType = 1234567890;
77 readArguments(argc, argv);
79 f = fopen(fileName,
"rb");
81 perror(
"Error: open file");
87 my_stat(fileName, &buf, MYF(0));
88 NO_MBYTE_IN_FILE = buf.st_size / (1024 * 1024);
89 if (NO_MBYTE_IN_FILE != 16)
91 ndbout_c(
"Detected %umb files", NO_MBYTE_IN_FILE);
95 Uint32 tmpFileOffset = startAtMbyte * PAGESIZE * NO_PAGES_IN_MBYTE *
sizeof(Uint32);
96 if (fseek(f, tmpFileOffset, FROM_BEGINNING)) {
97 perror(
"Error: Move in file");
101 redoLogPage =
new Uint32[PAGESIZE*NO_PAGES_IN_MBYTE];
102 Uint32 words_from_previous_page = 0;
105 bool lastPage =
false;
106 for (Uint32 j = startAtMbyte; j < NO_MBYTE_IN_FILE && !lastPage; j++) {
108 ndbout_c(
"mb: %d", j);
109 readFromFile(f, redoLogPage, PAGESIZE*NO_PAGES_IN_MBYTE);
111 words_from_previous_page = 0;
114 for (
int i = 0;
i < NO_PAGES_IN_MBYTE;
i++)
117 thePageHeader = (
PageHeader *) &redoLogPage[
i*PAGESIZE];
119 ndbout << j <<
":" <<
i <<
":" << wordIndex << endl
120 <<
" " << j*32 +
i <<
":" << wordIndex <<
" ";
121 if (thePrintFlag) ndbout << (*thePageHeader);
124 ndbout_c(
"lap: %d maxgcicompleted: %d maxgcistarted: %d",
125 thePageHeader->m_lap,
126 thePageHeader->m_max_gci_completed,
127 thePageHeader->m_max_gci_started);
131 if(!thePageHeader->check()) {
132 ndbout <<
"Error in thePageHeader->check()" << endl;
136 Uint32 checkSum = 37;
137 for (
int ps = 1; ps < PAGESIZE; ps++)
138 checkSum = redoLogPage[
i*PAGESIZE+ps] ^ checkSum;
140 if (checkSum != redoLogPage[
i*PAGESIZE]){
141 ndbout_c(
"WRONG CHECKSUM: checksum = 0x%x expected: 0x%x",
142 redoLogPage[
i*PAGESIZE],
147 ndbout <<
"expected checksum: " << checkSum << endl;
151 lastPage =
i != 0 && thePageHeader->lastPage();
152 Uint32 lastWord = thePageHeader->lastWord();
154 if (onlyMbyteHeaders) {
159 if (onlyPageHeaders) {
165 wordIndex = thePageHeader->getLogRecordSize() - words_from_previous_page;
166 Uint32 *redoLogPagePos = redoLogPage +
i*PAGESIZE;
167 if (words_from_previous_page)
169 memmove(redoLogPagePos + wordIndex,
170 redoLogPagePos - words_from_previous_page,
171 words_from_previous_page*4);
175 if (words_from_previous_page)
178 ndbout << j <<
":" <<
i-1 <<
":" << PAGESIZE-words_from_previous_page << endl
179 << j <<
":" <<
i <<
":" << wordIndex+words_from_previous_page << endl
180 <<
" " << j*32 +
i-1 <<
":" << PAGESIZE-words_from_previous_page <<
" ";
181 words_from_previous_page = 0;
186 ndbout_c(
"mb: %u fp: %u pos: %u",
187 j, (j*32 +
i), wordIndex);
189 redoLogPagePos = redoLogPage +
i*PAGESIZE + wordIndex;
190 oldWordIndex = wordIndex;
191 recordType = *redoLogPagePos;
195 if (thePrintFlag) ndbout << (*fdRecord);
197 if(!fdRecord->check()) {
198 ndbout <<
"Error in fdRecord->check()" << endl;
203 delete [] redoLogPage;
206 wordIndex += fdRecord->getLogRecordSize();
209 case ZNEXT_LOG_RECORD_TYPE:
211 wordIndex += nlRecord->getLogRecordSize(wordIndex);
212 if (wordIndex <= PAGESIZE) {
213 if (thePrintFlag) ndbout << (*nlRecord);
215 if(!nlRecord->check()) {
216 ndbout <<
"Error in nlRecord->check()" << endl;
223 case ZCOMPLETED_GCI_TYPE:
225 wordIndex += cGCIrecord->getLogRecordSize();
226 if (wordIndex <= PAGESIZE) {
227 if (thePrintFlag) ndbout << (*cGCIrecord);
229 if(!cGCIrecord->check()) {
230 ndbout <<
"Error in cGCIrecord->check()" << endl;
239 wordIndex += poRecord->getLogRecordSize(PAGESIZE-wordIndex);
240 if (wordIndex <= PAGESIZE) {
241 if (thePrintFlag) ndbout << (*poRecord);
243 if(!poRecord->check()) {
244 ndbout <<
"Error in poRecord->check()" << endl;
253 wordIndex += ctRecord->getLogRecordSize();
254 if (wordIndex <= PAGESIZE) {
255 if (thePrintFlag) ndbout << (*ctRecord);
257 if(!ctRecord->check()) {
258 ndbout <<
"Error in ctRecord->check()" << endl;
265 case ZINVALID_COMMIT_TYPE:
267 wordIndex += ictRecord->getLogRecordSize();
268 if (wordIndex <= PAGESIZE) {
269 if (thePrintFlag) ndbout << (*ictRecord);
271 if(!ictRecord->check()) {
272 ndbout <<
"Error in ictRecord->check()" << endl;
279 case ZNEXT_MBYTE_TYPE:
281 if (thePrintFlag) ndbout << (*nmRecord);
282 i = NO_PAGES_IN_MBYTE;
287 wordIndex += atRecord->getLogRecordSize();
288 if (wordIndex <= PAGESIZE) {
289 if (thePrintFlag) ndbout << (*atRecord);
291 if(!atRecord->check()) {
292 ndbout <<
"Error in atRecord->check()" << endl;
299 case ZNEW_PREP_OP_TYPE:
300 case ZFRAG_SPLIT_TYPE:
301 ndbout << endl <<
"Record type = " << recordType <<
" not implemented." << endl;
305 ndbout <<
" ------ERROR: UNKNOWN RECORD TYPE------" << endl;
308 for (
int k = wordIndex; k < PAGESIZE; k++){
309 Uint32 unknown = redoLogPage[
i*PAGESIZE + k];
310 ndbout_c(
"%-30d%-12u%-12x", k, unknown, unknown);
319 wordIndex = lastWord;
322 }
while(wordIndex < (Int32)lastWord &&
i < NO_PAGES_IN_MBYTE);
325 if (
false && lastPage)
329 ndbout <<
" ------PAGE END: DUMPING REST OF PAGE------" << endl;
330 for (
int k = wordIndex > PAGESIZE ? oldWordIndex : wordIndex;
333 Uint32
word = redoLogPage[
i*PAGESIZE + k];
334 ndbout_c(
"%-30d%-12u%-12x", k, word, word);
339 if (wordIndex > PAGESIZE) {
340 words_from_previous_page = PAGESIZE - oldWordIndex;
341 ndbout <<
" ----------- Record continues on next page -----------" << endl;
344 words_from_previous_page = 0;
349 if (startAtMbyte != 0) {
354 delete [] redoLogPage;
360 twiddle_32(Uint32 in)
364 retVal = ((in & 0x000000FF) << 24) |
365 ((in & 0x0000FF00) << 8) |
366 ((in & 0x00FF0000) >> 8) |
367 ((in & 0xFF000000) >> 24);
376 Uint32 readFromFile(FILE * f, Uint32 *toPtr, Uint32 sizeInWords) {
377 Uint32 noOfReadWords;
378 if ( !(noOfReadWords = (Uint32)fread(toPtr,
sizeof(Uint32), sizeInWords, f))){
379 ndbout <<
"Error reading file" << endl;
385 for (Uint32
i = 0;
i<noOfReadWords;
i++)
386 toPtr[
i] = twiddle_32(toPtr[
i]);
389 return noOfReadWords;
398 void usage(
const char * prg){
399 ndbout << endl <<
"Usage: " << endl << prg
400 <<
" <Binary log file> [-noprint] [-nocheck] [-mbyte <0-15>] "
401 <<
"[-mbyteheaders] [-pageheaders] [-filedescriptors] [-page <0-31>] "
402 <<
"[-pageindex <12-8191>] -twiddle"
406 void readArguments(
int argc,
const char** argv)
408 if(argc < 2 || argc > 9){
413 strcpy(fileName, argv[1]);
419 if (strcmp(argv[i],
"-noprint") == 0) {
420 thePrintFlag =
false;
421 }
else if (strcmp(argv[i],
"-dump") == 0) {
423 }
else if (strcmp(argv[i],
"-twiddle") == 0) {
425 }
else if (strcmp(argv[i],
"-nocheck") == 0) {
426 theCheckFlag =
false;
427 }
else if (strcmp(argv[i],
"-mbyteheaders") == 0) {
428 onlyMbyteHeaders =
true;
429 }
else if (strcmp(argv[i],
"-pageheaders") == 0) {
430 onlyPageHeaders =
true;
431 }
else if (strcmp(argv[i],
"-filedescriptors") == 0) {
433 }
else if (strcmp(argv[i],
"-lap") == 0) {
434 thePrintFlag =
false;
436 }
else if (strcmp(argv[i],
"-mbyte") == 0) {
437 startAtMbyte = atoi(argv[i+1]);
440 }
else if (strcmp(argv[i],
"-page") == 0) {
441 startAtPage = atoi(argv[i+1]);
442 if (startAtPage > 31) {
448 }
else if (strcmp(argv[i],
"-pageindex") == 0) {
449 startAtPageIndex = atoi(argv[i+1]);
450 if (startAtPageIndex > 8191 || startAtPageIndex < 12) {
467 ndbout <<
"Error in redoLogReader(). Exiting!" << endl;
469 delete [] redoLogPage;