Merge bk-internal:/home/bk/mysql-5.0
into mysql.com:/home/jimw/my/mysql-5.0-clean
This commit is contained in:
commit
b50eb4cd42
@ -24,7 +24,7 @@
|
|||||||
Published with a permission.
|
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 _LARGEFILE_SOURCE
|
||||||
#define _LARGEFILE64_SOURCE
|
#define _LARGEFILE64_SOURCE
|
||||||
|
|
||||||
@ -35,7 +35,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.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_MASK 1463735687
|
||||||
#define UT_HASH_RANDOM_MASK2 1653893711
|
#define UT_HASH_RANDOM_MASK2 1653893711
|
||||||
#define FIL_PAGE_LSN 16
|
#define FIL_PAGE_LSN 16
|
||||||
@ -46,18 +46,19 @@
|
|||||||
#define FIL_PAGE_SPACE_OR_CHKSUM 0
|
#define FIL_PAGE_SPACE_OR_CHKSUM 0
|
||||||
#define UNIV_PAGE_SIZE (2 * 8192)
|
#define UNIV_PAGE_SIZE (2 * 8192)
|
||||||
|
|
||||||
// command line argument to do page checks (that's it)
|
/* command line argument to do page checks (that's it) */
|
||||||
// another argument to specify page ranges... seek to right spot and go from there
|
/* another argument to specify page ranges... seek to right spot and go from there */
|
||||||
|
|
||||||
typedef unsigned long int ulint;
|
typedef unsigned long int ulint;
|
||||||
typedef unsigned char byte;
|
typedef unsigned char byte;
|
||||||
|
|
||||||
/* innodb function in name; modified slightly to not have the ASM version (lots of #ifs that didn't apply) */
|
/* 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)
|
return( ((ulint)(b[0]) << 24)
|
||||||
+ ((ulint)(b[2]) << 8)
|
+ ((ulint)(b[1]) << 16)
|
||||||
+ (ulint)(b[3])
|
+ ((ulint)(b[2]) << 8)
|
||||||
|
+ (ulint)(b[3])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,12 +81,13 @@ ut_fold_binary(
|
|||||||
ulint len) /* in: length */
|
ulint len) /* in: length */
|
||||||
{
|
{
|
||||||
ulint i;
|
ulint i;
|
||||||
ulint fold = 0;
|
ulint fold= 0;
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i= 0; i < len; i++)
|
||||||
fold = ut_fold_ulint_pair(fold, (ulint)(*str));
|
{
|
||||||
|
fold= ut_fold_ulint_pair(fold, (ulint)(*str));
|
||||||
|
|
||||||
str++;
|
str++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(fold);
|
return(fold);
|
||||||
@ -106,12 +108,12 @@ buf_calc_page_new_checksum(
|
|||||||
checksum is stored, and also the last 8 bytes of page because
|
checksum is stored, and also the last 8 bytes of page because
|
||||||
there we store the old formula checksum. */
|
there we store the old formula checksum. */
|
||||||
|
|
||||||
checksum = ut_fold_binary(page + FIL_PAGE_OFFSET,
|
checksum= ut_fold_binary(page + FIL_PAGE_OFFSET,
|
||||||
FIL_PAGE_FILE_FLUSH_LSN - FIL_PAGE_OFFSET)
|
FIL_PAGE_FILE_FLUSH_LSN - FIL_PAGE_OFFSET)
|
||||||
+ ut_fold_binary(page + FIL_PAGE_DATA,
|
+ ut_fold_binary(page + FIL_PAGE_DATA,
|
||||||
UNIV_PAGE_SIZE - FIL_PAGE_DATA
|
UNIV_PAGE_SIZE - FIL_PAGE_DATA
|
||||||
- FIL_PAGE_END_LSN_OLD_CHKSUM);
|
- FIL_PAGE_END_LSN_OLD_CHKSUM);
|
||||||
checksum = checksum & 0xFFFFFFFF;
|
checksum= checksum & 0xFFFFFFFF;
|
||||||
|
|
||||||
return(checksum);
|
return(checksum);
|
||||||
}
|
}
|
||||||
@ -124,183 +126,203 @@ buf_calc_page_old_checksum(
|
|||||||
{
|
{
|
||||||
ulint checksum;
|
ulint checksum;
|
||||||
|
|
||||||
checksum = ut_fold_binary(page, FIL_PAGE_FILE_FLUSH_LSN);
|
checksum= ut_fold_binary(page, FIL_PAGE_FILE_FLUSH_LSN);
|
||||||
|
|
||||||
checksum = checksum & 0xFFFFFFFF;
|
checksum= checksum & 0xFFFFFFFF;
|
||||||
|
|
||||||
return(checksum);
|
return(checksum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv)
|
||||||
FILE *f; // our input file
|
{
|
||||||
byte *p; // storage of pages read
|
FILE *f; /* our input file */
|
||||||
int bytes; // bytes read count
|
byte *p; /* storage of pages read */
|
||||||
ulint ct; // current page number (0 based)
|
int bytes; /* bytes read count */
|
||||||
int now; // current time
|
ulint ct; /* current page number (0 based) */
|
||||||
int lastt; // last time
|
int now; /* current time */
|
||||||
ulint oldcsum, oldcsumfield, csum, csumfield, logseq, logseqfield; // ulints for checksum storage
|
int lastt; /* last time */
|
||||||
struct stat st; // for stat, if you couldn't guess
|
ulint oldcsum, oldcsumfield, csum, csumfield, logseq, logseqfield; /* ulints for checksum storage */
|
||||||
unsigned long long int size; // size of file (has to be 64 bits)
|
struct stat st; /* for stat, if you couldn't guess */
|
||||||
ulint pages; // number of pages in file
|
unsigned long long int size; /* size of file (has to be 64 bits) */
|
||||||
ulint start_page = 0, end_page = 0, use_end_page = 0; // for starting and ending at certain pages
|
ulint pages; /* number of pages in file */
|
||||||
off_t offset = 0;
|
ulint start_page= 0, end_page= 0, use_end_page= 0; /* for starting and ending at certain pages */
|
||||||
int just_count = 0; // if true, just print page count
|
off_t offset= 0;
|
||||||
int verbose = 0;
|
int just_count= 0; /* if true, just print page count */
|
||||||
int debug = 0;
|
int verbose= 0;
|
||||||
int c;
|
int debug= 0;
|
||||||
int fd;
|
int c;
|
||||||
|
int fd;
|
||||||
|
|
||||||
// remove arguments
|
/* remove arguments */
|
||||||
while ((c = getopt(argc, argv, "cvds:e:p:")) != -1) {
|
while ((c= getopt(argc, argv, "cvds:e:p:")) != -1)
|
||||||
switch (c) {
|
{
|
||||||
case 'v':
|
switch (c)
|
||||||
verbose = 1;
|
{
|
||||||
break;
|
case 'v':
|
||||||
case 'c':
|
verbose= 1;
|
||||||
just_count = 1;
|
break;
|
||||||
break;
|
case 'c':
|
||||||
case 's':
|
just_count= 1;
|
||||||
start_page = atoi(optarg);
|
break;
|
||||||
break;
|
case 's':
|
||||||
case 'e':
|
start_page= atoi(optarg);
|
||||||
end_page = atoi(optarg);
|
break;
|
||||||
use_end_page = 1;
|
case 'e':
|
||||||
break;
|
end_page= atoi(optarg);
|
||||||
case 'p':
|
use_end_page= 1;
|
||||||
start_page = atoi(optarg);
|
break;
|
||||||
end_page = atoi(optarg);
|
case 'p':
|
||||||
use_end_page = 1;
|
start_page= atoi(optarg);
|
||||||
break;
|
end_page= atoi(optarg);
|
||||||
case 'd':
|
use_end_page= 1;
|
||||||
debug = 1;
|
break;
|
||||||
break;
|
case 'd':
|
||||||
case ':':
|
debug= 1;
|
||||||
fprintf(stderr, "option -%c requires an argument\n", optopt);
|
break;
|
||||||
return 1;
|
case ':':
|
||||||
break;
|
fprintf(stderr, "option -%c requires an argument\n", optopt);
|
||||||
case '?':
|
return 1;
|
||||||
fprintf(stderr, "unrecognized option: -%c\n", optopt);
|
break;
|
||||||
return 1;
|
case '?':
|
||||||
break;
|
fprintf(stderr, "unrecognized option: -%c\n", optopt);
|
||||||
}
|
return 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// debug implies verbose...
|
/* debug implies verbose... */
|
||||||
if (debug) verbose = 1;
|
if (debug) verbose= 1;
|
||||||
|
|
||||||
// make sure we have the right arguments
|
/* make sure we have the right arguments */
|
||||||
if (optind >= argc) {
|
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("InnoDB offline file checksum utility.\n");
|
||||||
printf("\t-c\tprint the count of pages in the file\n");
|
printf("usage: %s [-c] [-s <start page>] [-e <end page>] [-p <page>] [-v] [-d] <filename>\n", argv[0]);
|
||||||
printf("\t-s n\tstart on this page number (0 based)\n");
|
printf("\t-c\tprint the count of pages in the file\n");
|
||||||
printf("\t-e n\tend at this page number (0 based)\n");
|
printf("\t-s n\tstart on this page number (0 based)\n");
|
||||||
printf("\t-p n\tcheck only this page (0 based)\n");
|
printf("\t-e n\tend at this page number (0 based)\n");
|
||||||
printf("\t-v\tverbose (prints progress every 5 seconds)\n");
|
printf("\t-p n\tcheck only this page (0 based)\n");
|
||||||
printf("\t-d\tdebug mode (prints checksums for each page)\n");
|
printf("\t-v\tverbose (prints progress every 5 seconds)\n");
|
||||||
return 1;
|
printf("\t-d\tdebug mode (prints checksums for each page)\n");
|
||||||
}
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// stat the file to get size and page count
|
/* stat the file to get size and page count */
|
||||||
if (stat(argv[optind], &st)) {
|
if (stat(argv[optind], &st))
|
||||||
perror("error statting file");
|
{
|
||||||
return 1;
|
perror("error statting file");
|
||||||
}
|
return 1;
|
||||||
size = st.st_size;
|
}
|
||||||
pages = size / UNIV_PAGE_SIZE;
|
size= st.st_size;
|
||||||
if (just_count) {
|
pages= size / UNIV_PAGE_SIZE;
|
||||||
printf("%lu\n", pages);
|
if (just_count)
|
||||||
return 0;
|
{
|
||||||
} else if (verbose) {
|
printf("%lu\n", pages);
|
||||||
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
|
|
||||||
f = fopen(argv[optind], "r");
|
|
||||||
if (!f) {
|
|
||||||
perror("error opening file");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// seek to the necessary position
|
|
||||||
if (start_page) {
|
|
||||||
fd = fileno(f);
|
|
||||||
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) {
|
|
||||||
perror("unable to seek to necessary offset");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate buffer for reading (so we don't realloc every time)
|
|
||||||
p = (byte *)malloc(UNIV_PAGE_SIZE);
|
|
||||||
|
|
||||||
// main checksumming loop
|
|
||||||
ct = start_page;
|
|
||||||
lastt = 0;
|
|
||||||
while (!feof(f)) {
|
|
||||||
bytes = fread(p, 1, UNIV_PAGE_SIZE, f);
|
|
||||||
if (!bytes && feof(f)) return 0;
|
|
||||||
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"
|
|
||||||
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) {
|
|
||||||
fprintf(stderr, "page %lu invalid (fails log sequence number check)\n", ct);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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) {
|
|
||||||
fprintf(stderr, "page %lu invalid (fails old style checksum)\n", ct);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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) {
|
|
||||||
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
|
|
||||||
if (use_end_page && (ct >= end_page))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// do counter increase and progress printing
|
|
||||||
ct++;
|
|
||||||
if (verbose) {
|
|
||||||
if (ct % 64 == 0) {
|
|
||||||
now = time(0);
|
|
||||||
if (!lastt) lastt = now;
|
|
||||||
if (now - lastt >= 1) {
|
|
||||||
printf("page %lu okay: %.3f%% done\n", (ct - 1), (float) ct / pages * 100);
|
|
||||||
lastt = now;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
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 */
|
||||||
|
f= fopen(argv[optind], "r");
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
perror("error opening file");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* seek to the necessary position */
|
||||||
|
if (start_page)
|
||||||
|
{
|
||||||
|
fd= fileno(f);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
perror("unable to seek to necessary offset");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate buffer for reading (so we don't realloc every time) */
|
||||||
|
p= (byte *)malloc(UNIV_PAGE_SIZE);
|
||||||
|
|
||||||
|
/* main checksumming loop */
|
||||||
|
ct= start_page;
|
||||||
|
lastt= 0;
|
||||||
|
while (!feof(f))
|
||||||
|
{
|
||||||
|
bytes= fread(p, 1, UNIV_PAGE_SIZE, f);
|
||||||
|
if (!bytes && feof(f)) return 0;
|
||||||
|
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" */
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "page %lu invalid (fails log sequence number check)\n", ct);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "page %lu invalid (fails old style checksum)\n", ct);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
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 */
|
||||||
|
if (use_end_page && (ct >= end_page))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* do counter increase and progress printing */
|
||||||
|
ct++;
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
|
if (ct % 64 == 0)
|
||||||
|
{
|
||||||
|
now= time(0);
|
||||||
|
if (!lastt) lastt= now;
|
||||||
|
if (now - lastt >= 1)
|
||||||
|
{
|
||||||
|
printf("page %lu okay: %.3f%% done\n", (ct - 1), (float) ct / pages * 100);
|
||||||
|
lastt= now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user