Loading extra/innochecksum.c +200 −178 Original line number Diff line number Diff line Loading @@ -24,7 +24,7 @@ Published with a permission. */ // needed to have access to 64 bit file functions /* needed to have access to 64 bit file functions */ #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE Loading @@ -35,7 +35,7 @@ #include <sys/stat.h> #include <unistd.h> // all of these ripped from InnoDB code from MySQL 4.0.22 /* all of these ripped from InnoDB code from MySQL 4.0.22 */ #define UT_HASH_RANDOM_MASK 1463735687 #define UT_HASH_RANDOM_MASK2 1653893711 #define FIL_PAGE_LSN 16 Loading @@ -46,14 +46,15 @@ #define FIL_PAGE_SPACE_OR_CHKSUM 0 #define UNIV_PAGE_SIZE (2 * 8192) // command line argument to do page checks (that's it) // another argument to specify page ranges... seek to right spot and go from there /* command line argument to do page checks (that's it) */ /* another argument to specify page ranges... seek to right spot and go from there */ typedef unsigned long int ulint; typedef unsigned char byte; /* innodb function in name; modified slightly to not have the ASM version (lots of #ifs that didn't apply) */ ulint mach_read_from_4(byte *b) { ulint mach_read_from_4(byte *b) { return( ((ulint)(b[0]) << 24) + ((ulint)(b[1]) << 16) + ((ulint)(b[2]) << 8) Loading Loading @@ -82,7 +83,8 @@ ut_fold_binary( ulint i; ulint fold= 0; for (i = 0; i < len; i++) { for (i= 0; i < len; i++) { fold= ut_fold_ulint_pair(fold, (ulint)(*str)); str++; Loading Loading @@ -132,28 +134,31 @@ buf_calc_page_old_checksum( } int main(int argc, char **argv) { FILE *f; // our input file byte *p; // storage of pages read int bytes; // bytes read count ulint ct; // current page number (0 based) int now; // current time int lastt; // last time ulint oldcsum, oldcsumfield, csum, csumfield, logseq, logseqfield; // ulints for checksum storage struct stat st; // for stat, if you couldn't guess unsigned long long int size; // size of file (has to be 64 bits) ulint pages; // number of pages in file ulint start_page = 0, end_page = 0, use_end_page = 0; // for starting and ending at certain pages int main(int argc, char **argv) { FILE *f; /* our input file */ byte *p; /* storage of pages read */ int bytes; /* bytes read count */ ulint ct; /* current page number (0 based) */ int now; /* current time */ int lastt; /* last time */ ulint oldcsum, oldcsumfield, csum, csumfield, logseq, logseqfield; /* ulints for checksum storage */ struct stat st; /* for stat, if you couldn't guess */ unsigned long long int size; /* size of file (has to be 64 bits) */ ulint pages; /* number of pages in file */ ulint start_page= 0, end_page= 0, use_end_page= 0; /* for starting and ending at certain pages */ off_t offset= 0; int just_count = 0; // if true, just print page count int just_count= 0; /* if true, just print page count */ int verbose= 0; int debug= 0; int c; int fd; // remove arguments while ((c = getopt(argc, argv, "cvds:e:p:")) != -1) { switch (c) { /* remove arguments */ while ((c= getopt(argc, argv, "cvds:e:p:")) != -1) { switch (c) { case 'v': verbose= 1; break; Loading Loading @@ -186,11 +191,12 @@ int main(int argc, char **argv) { } } // debug implies verbose... /* debug implies verbose... */ if (debug) verbose= 1; // make sure we have the right arguments if (optind >= argc) { /* make sure we have the right arguments */ if (optind >= argc) { printf("InnoDB offline file checksum utility.\n"); printf("usage: %s [-c] [-s <start page>] [-e <end page>] [-p <page>] [-v] [-d] <filename>\n", argv[0]); printf("\t-c\tprint the count of pages in the file\n"); Loading @@ -202,99 +208,115 @@ int main(int argc, char **argv) { return 1; } // stat the file to get size and page count if (stat(argv[optind], &st)) { /* stat the file to get size and page count */ if (stat(argv[optind], &st)) { perror("error statting file"); return 1; } size= st.st_size; pages= size / UNIV_PAGE_SIZE; if (just_count) { if (just_count) { printf("%lu\n", pages); return 0; } else if (verbose) { } else if (verbose) { printf("file %s= %llu bytes (%lu pages)...\n", argv[1], size, pages); printf("checking pages in range %lu to %lu\n", start_page, use_end_page ? end_page : (pages - 1)); } // open the file for reading /* open the file for reading */ f= fopen(argv[optind], "r"); if (!f) { if (!f) { perror("error opening file"); return 1; } // seek to the necessary position if (start_page) { /* seek to the necessary position */ if (start_page) { fd= fileno(f); if (!fd) { if (!fd) { perror("unable to obtain file descriptor number"); return 1; } offset= (off_t)start_page * (off_t)UNIV_PAGE_SIZE; if (lseek(fd, offset, SEEK_SET) != offset) { if (lseek(fd, offset, SEEK_SET) != offset) { perror("unable to seek to necessary offset"); return 1; } } // allocate buffer for reading (so we don't realloc every time) /* allocate buffer for reading (so we don't realloc every time) */ p= (byte *)malloc(UNIV_PAGE_SIZE); // main checksumming loop /* main checksumming loop */ ct= start_page; lastt= 0; while (!feof(f)) { while (!feof(f)) { bytes= fread(p, 1, UNIV_PAGE_SIZE, f); if (!bytes && feof(f)) return 0; if (bytes != UNIV_PAGE_SIZE) { if (bytes != UNIV_PAGE_SIZE) { fprintf(stderr, "bytes read (%d) doesn't match universal page size (%d)\n", bytes, UNIV_PAGE_SIZE); return 1; } // check the "stored log sequence numbers" /* check the "stored log sequence numbers" */ logseq= mach_read_from_4(p + FIL_PAGE_LSN + 4); logseqfield= mach_read_from_4(p + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM + 4); if (debug) printf("page %lu: log sequence number: first = %lu; second = %lu\n", ct, logseq, logseqfield); if (logseq != logseqfield) { if (logseq != logseqfield) { fprintf(stderr, "page %lu invalid (fails log sequence number check)\n", ct); return 1; } // check old method of checksumming /* check old method of checksumming */ oldcsum= buf_calc_page_old_checksum(p); oldcsumfield= mach_read_from_4(p + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM); if (debug) printf("page %lu: old style: calculated = %lu; recorded = %lu\n", ct, oldcsum, oldcsumfield); if (oldcsumfield != mach_read_from_4(p + FIL_PAGE_LSN) && oldcsumfield != oldcsum) { if (oldcsumfield != mach_read_from_4(p + FIL_PAGE_LSN) && oldcsumfield != oldcsum) { fprintf(stderr, "page %lu invalid (fails old style checksum)\n", ct); return 1; } // now check the new method /* now check the new method */ csum= buf_calc_page_new_checksum(p); csumfield= mach_read_from_4(p + FIL_PAGE_SPACE_OR_CHKSUM); if (debug) printf("page %lu: new style: calculated = %lu; recorded = %lu\n", ct, csum, csumfield); if (csumfield != 0 && csum != csumfield) { if (csumfield != 0 && csum != csumfield) { fprintf(stderr, "page %lu invalid (fails new style checksum)\n", ct); return 1; } // end if this was the last page we were supposed to check /* end if this was the last page we were supposed to check */ if (use_end_page && (ct >= end_page)) return 0; // do counter increase and progress printing /* do counter increase and progress printing */ ct++; if (verbose) { if (ct % 64 == 0) { if (verbose) { if (ct % 64 == 0) { now= time(0); if (!lastt) lastt= now; if (now - lastt >= 1) { if (now - lastt >= 1) { printf("page %lu okay: %.3f%% done\n", (ct - 1), (float) ct / pages * 100); lastt= now; } Loading Loading
extra/innochecksum.c +200 −178 Original line number Diff line number Diff line Loading @@ -24,7 +24,7 @@ Published with a permission. */ // needed to have access to 64 bit file functions /* needed to have access to 64 bit file functions */ #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE Loading @@ -35,7 +35,7 @@ #include <sys/stat.h> #include <unistd.h> // all of these ripped from InnoDB code from MySQL 4.0.22 /* all of these ripped from InnoDB code from MySQL 4.0.22 */ #define UT_HASH_RANDOM_MASK 1463735687 #define UT_HASH_RANDOM_MASK2 1653893711 #define FIL_PAGE_LSN 16 Loading @@ -46,14 +46,15 @@ #define FIL_PAGE_SPACE_OR_CHKSUM 0 #define UNIV_PAGE_SIZE (2 * 8192) // command line argument to do page checks (that's it) // another argument to specify page ranges... seek to right spot and go from there /* command line argument to do page checks (that's it) */ /* another argument to specify page ranges... seek to right spot and go from there */ typedef unsigned long int ulint; typedef unsigned char byte; /* innodb function in name; modified slightly to not have the ASM version (lots of #ifs that didn't apply) */ ulint mach_read_from_4(byte *b) { ulint mach_read_from_4(byte *b) { return( ((ulint)(b[0]) << 24) + ((ulint)(b[1]) << 16) + ((ulint)(b[2]) << 8) Loading Loading @@ -82,7 +83,8 @@ ut_fold_binary( ulint i; ulint fold= 0; for (i = 0; i < len; i++) { for (i= 0; i < len; i++) { fold= ut_fold_ulint_pair(fold, (ulint)(*str)); str++; Loading Loading @@ -132,28 +134,31 @@ buf_calc_page_old_checksum( } int main(int argc, char **argv) { FILE *f; // our input file byte *p; // storage of pages read int bytes; // bytes read count ulint ct; // current page number (0 based) int now; // current time int lastt; // last time ulint oldcsum, oldcsumfield, csum, csumfield, logseq, logseqfield; // ulints for checksum storage struct stat st; // for stat, if you couldn't guess unsigned long long int size; // size of file (has to be 64 bits) ulint pages; // number of pages in file ulint start_page = 0, end_page = 0, use_end_page = 0; // for starting and ending at certain pages int main(int argc, char **argv) { FILE *f; /* our input file */ byte *p; /* storage of pages read */ int bytes; /* bytes read count */ ulint ct; /* current page number (0 based) */ int now; /* current time */ int lastt; /* last time */ ulint oldcsum, oldcsumfield, csum, csumfield, logseq, logseqfield; /* ulints for checksum storage */ struct stat st; /* for stat, if you couldn't guess */ unsigned long long int size; /* size of file (has to be 64 bits) */ ulint pages; /* number of pages in file */ ulint start_page= 0, end_page= 0, use_end_page= 0; /* for starting and ending at certain pages */ off_t offset= 0; int just_count = 0; // if true, just print page count int just_count= 0; /* if true, just print page count */ int verbose= 0; int debug= 0; int c; int fd; // remove arguments while ((c = getopt(argc, argv, "cvds:e:p:")) != -1) { switch (c) { /* remove arguments */ while ((c= getopt(argc, argv, "cvds:e:p:")) != -1) { switch (c) { case 'v': verbose= 1; break; Loading Loading @@ -186,11 +191,12 @@ int main(int argc, char **argv) { } } // debug implies verbose... /* debug implies verbose... */ if (debug) verbose= 1; // make sure we have the right arguments if (optind >= argc) { /* make sure we have the right arguments */ if (optind >= argc) { printf("InnoDB offline file checksum utility.\n"); printf("usage: %s [-c] [-s <start page>] [-e <end page>] [-p <page>] [-v] [-d] <filename>\n", argv[0]); printf("\t-c\tprint the count of pages in the file\n"); Loading @@ -202,99 +208,115 @@ int main(int argc, char **argv) { return 1; } // stat the file to get size and page count if (stat(argv[optind], &st)) { /* stat the file to get size and page count */ if (stat(argv[optind], &st)) { perror("error statting file"); return 1; } size= st.st_size; pages= size / UNIV_PAGE_SIZE; if (just_count) { if (just_count) { printf("%lu\n", pages); return 0; } else if (verbose) { } else if (verbose) { printf("file %s= %llu bytes (%lu pages)...\n", argv[1], size, pages); printf("checking pages in range %lu to %lu\n", start_page, use_end_page ? end_page : (pages - 1)); } // open the file for reading /* open the file for reading */ f= fopen(argv[optind], "r"); if (!f) { if (!f) { perror("error opening file"); return 1; } // seek to the necessary position if (start_page) { /* seek to the necessary position */ if (start_page) { fd= fileno(f); if (!fd) { if (!fd) { perror("unable to obtain file descriptor number"); return 1; } offset= (off_t)start_page * (off_t)UNIV_PAGE_SIZE; if (lseek(fd, offset, SEEK_SET) != offset) { if (lseek(fd, offset, SEEK_SET) != offset) { perror("unable to seek to necessary offset"); return 1; } } // allocate buffer for reading (so we don't realloc every time) /* allocate buffer for reading (so we don't realloc every time) */ p= (byte *)malloc(UNIV_PAGE_SIZE); // main checksumming loop /* main checksumming loop */ ct= start_page; lastt= 0; while (!feof(f)) { while (!feof(f)) { bytes= fread(p, 1, UNIV_PAGE_SIZE, f); if (!bytes && feof(f)) return 0; if (bytes != UNIV_PAGE_SIZE) { if (bytes != UNIV_PAGE_SIZE) { fprintf(stderr, "bytes read (%d) doesn't match universal page size (%d)\n", bytes, UNIV_PAGE_SIZE); return 1; } // check the "stored log sequence numbers" /* check the "stored log sequence numbers" */ logseq= mach_read_from_4(p + FIL_PAGE_LSN + 4); logseqfield= mach_read_from_4(p + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM + 4); if (debug) printf("page %lu: log sequence number: first = %lu; second = %lu\n", ct, logseq, logseqfield); if (logseq != logseqfield) { if (logseq != logseqfield) { fprintf(stderr, "page %lu invalid (fails log sequence number check)\n", ct); return 1; } // check old method of checksumming /* check old method of checksumming */ oldcsum= buf_calc_page_old_checksum(p); oldcsumfield= mach_read_from_4(p + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM); if (debug) printf("page %lu: old style: calculated = %lu; recorded = %lu\n", ct, oldcsum, oldcsumfield); if (oldcsumfield != mach_read_from_4(p + FIL_PAGE_LSN) && oldcsumfield != oldcsum) { if (oldcsumfield != mach_read_from_4(p + FIL_PAGE_LSN) && oldcsumfield != oldcsum) { fprintf(stderr, "page %lu invalid (fails old style checksum)\n", ct); return 1; } // now check the new method /* now check the new method */ csum= buf_calc_page_new_checksum(p); csumfield= mach_read_from_4(p + FIL_PAGE_SPACE_OR_CHKSUM); if (debug) printf("page %lu: new style: calculated = %lu; recorded = %lu\n", ct, csum, csumfield); if (csumfield != 0 && csum != csumfield) { if (csumfield != 0 && csum != csumfield) { fprintf(stderr, "page %lu invalid (fails new style checksum)\n", ct); return 1; } // end if this was the last page we were supposed to check /* end if this was the last page we were supposed to check */ if (use_end_page && (ct >= end_page)) return 0; // do counter increase and progress printing /* do counter increase and progress printing */ ct++; if (verbose) { if (ct % 64 == 0) { if (verbose) { if (ct % 64 == 0) { now= time(0); if (!lastt) lastt= now; if (now - lastt >= 1) { if (now - lastt >= 1) { printf("page %lu okay: %.3f%% done\n", (ct - 1), (float) ct / pages * 100); lastt= now; } Loading