28 #include <my_global.h>
32 #include <sys/types.h>
37 #include <my_getopt.h>
39 #include <welcome_copyright_notice.h>
46 #include "buf0checksum.h"
54 # include "fsp0fsp.ic"
55 # include "mach0data.ic"
60 static my_bool verbose;
62 static my_bool just_count;
63 static ulong start_page;
64 static ulong end_page;
66 static my_bool use_end_page;
67 static my_bool do_one_page;
69 static ulong physical_page_size;
70 static ulong logical_page_size;
80 ulong* logical_page_size,
81 ulong* physical_page_size)
85 int bytes= fread(buf, 1, UNIV_PAGE_SIZE_MIN, f);
89 perror(
"Error reading file header");
93 if (bytes != UNIV_PAGE_SIZE_MIN)
95 fprintf(stderr,
"Error; Was not able to read the minimum page size ");
96 fprintf(stderr,
"of %d bytes. Bytes read was %d\n", UNIV_PAGE_SIZE_MIN, bytes);
109 if (*physical_page_size == 0)
110 *physical_page_size= *logical_page_size;
119 static struct my_option innochecksum_options[] =
121 {
"help",
'?',
"Displays this help and exits.",
122 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
123 {
"info",
'I',
"Synonym for --help.",
124 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
125 {
"version",
'V',
"Displays version information and exits.",
126 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
127 {
"verbose",
'v',
"Verbose (prints progress every 5 seconds).",
128 &verbose, &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
129 {
"debug",
'd',
"Debug mode (prints checksums for each page, implies verbose).",
130 &debug, &debug, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
131 {
"count",
'c',
"Print the count of pages in the file.",
132 &just_count, &just_count, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
133 {
"start_page",
's',
"Start on this page number (0 based).",
134 &start_page, &start_page, 0, GET_ULONG, REQUIRED_ARG,
135 0, 0, (longlong) 2L*1024L*1024L*1024L, 0, 1, 0},
136 {
"end_page",
'e',
"End at this page number (0 based).",
137 &end_page, &end_page, 0, GET_ULONG, REQUIRED_ARG,
138 0, 0, (longlong) 2L*1024L*1024L*1024L, 0, 1, 0},
139 {
"page",
'p',
"Check only this page (0 based).",
140 &do_page, &do_page, 0, GET_ULONG, REQUIRED_ARG,
141 0, 0, (longlong) 2L*1024L*1024L*1024L, 0, 1, 0},
143 {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
146 static void print_version(
void)
148 printf(
"%s Ver %s, for %s (%s)\n",
149 my_progname, INNODB_VERSION_STR,
150 SYSTEM_TYPE, MACHINE_TYPE);
153 static void usage(
void)
156 puts(ORACLE_WELCOME_COPYRIGHT_NOTICE(
"2000"));
157 printf(
"InnoDB offline file checksum utility.\n");
158 printf(
"Usage: %s [-c] [-s <start page>] [-e <end page>] [-p <page>] [-v] [-d] <filename>\n", my_progname);
159 my_print_help(innochecksum_options);
160 my_print_variables(innochecksum_options);
164 innochecksum_get_one_option(
167 const struct my_option *opt __attribute__((unused)),
168 char *argument __attribute__((unused)))
178 end_page= start_page= do_page;
195 static int get_options(
202 if ((ho_error=handle_options(argc, argv, innochecksum_options, innochecksum_get_one_option)))
215 int main(
int argc,
char **argv)
219 unsigned char buf[UNIV_PAGE_SIZE_MAX];
224 ulint oldcsum, oldcsumfield, csum, csumfield, crc32, logseq, logseqfield;
227 unsigned long long int size;
232 printf(
"InnoDB offline file checksum utility.\n");
238 if (get_options(&argc,&argv))
242 my_print_variables(innochecksum_options);
246 if (*filename ==
'\0')
248 fprintf(stderr,
"Error; File name missing\n");
253 if (stat(filename, &st))
255 fprintf(stderr,
"Error; %s cannot be found\n", filename);
261 f= fopen(filename,
"rb");
264 fprintf(stderr,
"Error; %s cannot be opened", filename);
269 if (!get_page_size(f, buf, &logical_page_size, &physical_page_size))
275 if (logical_page_size != physical_page_size)
277 fprintf(stderr,
"Error; This file contains compressed pages\n");
281 pages= (ulint) (size / physical_page_size);
286 printf(
"Number of pages: ");
287 printf(
"%lu\n", pages);
292 printf(
"file %s = %llu bytes (%lu pages)...\n", filename, size, pages);
294 printf(
"InnoChecksum; checking page %lu\n", do_page);
296 printf(
"InnoChecksum; checking pages in range %lu to %lu\n", start_page, use_end_page ? end_page : (pages - 1));
305 perror(
"Error; Unable to obtain file descriptor number");
309 offset= (off_t)start_page * (off_t)physical_page_size;
311 if (lseek(fd, offset, SEEK_SET) !=
offset)
313 perror(
"Error; Unable to seek to necessary offset");
323 bytes= fread(buf, 1, physical_page_size, f);
324 if (!bytes && feof(f))
329 fprintf(stderr,
"Error reading %lu bytes", physical_page_size);
333 if (bytes != physical_page_size)
335 fprintf(stderr,
"Error; bytes read (%lu) doesn't match page size (%lu)\n", bytes, physical_page_size);
343 printf(
"page %lu: log sequence number: first = %lu; second = %lu\n", ct, logseq, logseqfield);
344 if (logseq != logseqfield)
346 fprintf(stderr,
"Fail; page %lu invalid (fails log sequence number check)\n", ct);
354 printf(
"page %lu: old style: calculated = %lu; recorded = %lu\n", ct, oldcsum, oldcsumfield);
357 fprintf(stderr,
"Fail; page %lu invalid (fails old style checksum)\n", ct);
366 printf(
"page %lu: new style: calculated = %lu; crc32 = %lu; recorded = %lu\n",
367 ct, csum, crc32, csumfield);
368 if (csumfield != 0 && crc32 != csumfield && csum != csumfield)
370 fprintf(stderr,
"Fail; page %lu invalid (fails innodb and crc32 checksum)\n", ct);
375 if (use_end_page && (ct >= end_page))
385 if (!lastt) lastt= now;
386 if (now - lastt >= 1)
388 printf(
"page %lu okay: %.3f%% done\n", (ct - 1), (
float) ct / pages * 100);