23 #include <my_getopt.h>
24 #include <mysql_version.h>
26 #define BUFFER_LEN 1024
27 #define ARCHIVE_ROW_HEADER_SIZE 4
29 #define SHOW_VERSION "0.1"
31 static void get_options(
int *argc,
char * * *argv);
32 static void print_version(
void);
33 static void usage(
void);
34 static const char *opt_tmpdir;
35 static const char *new_auto_increment;
36 unsigned long long new_auto_increment_value;
37 static const char *load_default_groups[]= {
"archive_reader", 0 };
38 static char **default_argv;
39 int opt_check, opt_force, opt_quiet, opt_backup= 0, opt_extract_frm;
40 int opt_autoincrement;
42 int main(
int argc,
char *argv[])
48 get_options(&argc, &argv);
52 printf(
"No file specified. \n");
56 if (!(ret= azopen(&reader_handle, argv[0], O_RDONLY|O_BINARY)))
58 printf(
"Could not open Archive file\n");
62 if (opt_autoincrement)
66 if (new_auto_increment_value)
68 if (reader_handle.auto_increment >= new_auto_increment_value)
70 printf(
"Value is lower then current value\n");
76 new_auto_increment_value= reader_handle.auto_increment + 1;
79 if (!(ret= azopen(&writer_handle, argv[0], O_CREAT|O_RDWR|O_BINARY)))
81 printf(
"Could not open file for update: %s\n", argv[0]);
85 writer_handle.auto_increment= new_auto_increment_value;
87 azclose(&writer_handle);
88 azflush(&reader_handle, Z_SYNC_FLUSH);
91 printf(
"Version %u\n", reader_handle.version);
92 if (reader_handle.version > 2)
94 printf(
"\tMinor version %u\n", reader_handle.minor_version);
95 printf(
"\tStart position %llu\n", (
unsigned long long)reader_handle.start);
96 printf(
"\tBlock size %u\n", reader_handle.block_size);
97 printf(
"\tRows %llu\n", reader_handle.rows);
98 printf(
"\tAutoincrement %llu\n", reader_handle.auto_increment);
99 printf(
"\tCheck Point %llu\n", reader_handle.check_point);
100 printf(
"\tForced Flushes %llu\n", reader_handle.forced_flushes);
101 printf(
"\tLongest Row %u\n", reader_handle.longest_row);
102 printf(
"\tShortest Row %u\n", reader_handle.shortest_row);
103 printf(
"\tState %s\n", ( reader_handle.dirty ?
"dirty" :
"clean"));
104 printf(
"\tFRM stored at %u\n", reader_handle.frm_start_pos);
105 printf(
"\tComment stored at %u\n", reader_handle.comment_start_pos);
106 printf(
"\tData starts at %u\n", (
unsigned int)reader_handle.start);
107 if (reader_handle.frm_start_pos)
108 printf(
"\tFRM length %u\n", reader_handle.frm_length);
109 if (reader_handle.comment_start_pos)
112 (
char *) malloc(
sizeof(
char) * reader_handle.comment_length);
113 azread_comment(&reader_handle, comment);
114 printf(
"\tComment length %u\n\t\t%.*s\n", reader_handle.comment_length,
115 reader_handle.comment_length, comment);
128 uchar size_buffer[ARCHIVE_ROW_HEADER_SIZE];
132 unsigned int row_len;
133 unsigned long long row_count= 0;
136 while ((read= azread(&reader_handle, (uchar *)size_buffer,
137 ARCHIVE_ROW_HEADER_SIZE, &error)))
139 if (error == Z_STREAM_ERROR || (read && read < ARCHIVE_ROW_HEADER_SIZE))
141 printf(
"Table is damaged\n");
146 if (read == 0 || read != ARCHIVE_ROW_HEADER_SIZE)
149 row_len= uint4korr(size_buffer);
152 if (row_len > reader_handle.longest_row)
154 printf(
"Table is damaged, row %llu is invalid\n",
160 for (read= x= 0; x < row_len ; x++)
162 read+= (
unsigned int)azread(&reader_handle, &buffer,
sizeof(
char), &error);
170 printf(
"Row length did not match row (at %llu). %u != %u \n",
171 row_count, row_len, read);
178 printf(
"Table is damaged\n");
183 printf(
"Found %llu rows\n", row_count);
189 uchar size_buffer[ARCHIVE_ROW_HEADER_SIZE];
192 unsigned int row_len;
193 unsigned long long row_count= 0;
198 buffer= (
char *)malloc(reader_handle.longest_row);
201 printf(
"Could not allocate memory for row %llu\n", row_count);
206 if (!(ret= azopen(&writer_handle, argv[1], O_CREAT|O_RDWR|O_BINARY)))
208 printf(
"Could not open file for backup: %s\n", argv[1]);
212 writer_handle.auto_increment= reader_handle.auto_increment;
213 if (reader_handle.frm_length)
216 ptr= (
char *)my_malloc(
sizeof(
char) * reader_handle.frm_length, MYF(0));
217 azread_frm(&reader_handle, ptr);
218 azwrite_frm(&writer_handle, ptr, reader_handle.frm_length);
222 if (reader_handle.comment_length)
225 ptr= (
char *)my_malloc(
sizeof(
char) * reader_handle.comment_length, MYF(0));
226 azread_comment(&reader_handle, ptr);
227 azwrite_comment(&writer_handle, ptr, reader_handle.comment_length);
231 while ((read= azread(&reader_handle, (uchar *)size_buffer,
232 ARCHIVE_ROW_HEADER_SIZE, &error)))
234 if (error == Z_STREAM_ERROR || (read && read < ARCHIVE_ROW_HEADER_SIZE))
236 printf(
"Table is damaged\n");
241 if (read == 0 || read != ARCHIVE_ROW_HEADER_SIZE)
244 row_len= uint4korr(size_buffer);
248 memcpy(buffer, size_buffer, ARCHIVE_ROW_HEADER_SIZE);
250 read= (
unsigned int)azread(&reader_handle, buffer + ARCHIVE_ROW_HEADER_SIZE,
253 DBUG_ASSERT(read == row_len);
255 azwrite(&writer_handle, buffer, row_len + ARCHIVE_ROW_HEADER_SIZE);
260 printf(
"Row length did not match row (at %llu). %u != %u \n",
261 row_count, row_len, read);
265 if (reader_handle.rows == writer_handle.rows)
271 azclose(&writer_handle);
278 frm_file= my_open(argv[1], O_CREAT|O_RDWR|O_BINARY, MYF(0));
279 ptr= (
char *)my_malloc(
sizeof(
char) * reader_handle.frm_length, MYF(0));
280 azread_frm(&reader_handle, ptr);
281 my_write(frm_file, (uchar*) ptr, reader_handle.frm_length, MYF(0));
282 my_close(frm_file, MYF(0));
288 azclose(&reader_handle);
294 get_one_option(
int optid,
295 const struct my_option *opt __attribute__((unused)),
310 printf(
"Not implemented yet\n");
314 printf(
"Not implemented yet\n");
320 printf(
"Not implemented yet\n");
323 opt_autoincrement= 1;
325 new_auto_increment_value= strtoull(argument, NULL, 0);
327 new_auto_increment_value= 0;
333 if (argument == disabled_my_option)
339 DBUG_PUSH(argument ? argument :
"d:t:o,/tmp/archive_reader.trace");
346 static struct my_option my_long_options[] =
349 "Make a backup of an archive table.",
350 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
351 {
"check",
'c',
"Check table for errors.",
352 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
355 "Output debug log. Often this is 'd:t:o,filename'.",
356 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
359 "Extract the frm file.",
360 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
362 "Restart with -r if there are any errors in the table.",
363 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
365 "Display this help and exit.",
366 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
367 {
"quick",
'q',
"Faster repair by not modifying the data file.",
368 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
369 {
"repair",
'r',
"Repair a damaged Archive version 3 or above file.",
370 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
371 {
"set-auto-increment",
'A',
372 "Force auto_increment to start at this or higher value. If no value is given, then sets the next auto_increment value to the highest used value for the auto key + 1.",
373 &new_auto_increment, &new_auto_increment,
374 0, GET_ULL, OPT_ARG, 0, 0, 0, 0, 0, 0},
376 "Only print errors. One can use two -s to make archive_reader very silent.",
377 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
379 "Path for temporary files.",
381 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
383 "Print version and exit.",
384 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
385 { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
388 static void usage(
void)
391 puts(
"Copyright 2007-2008 MySQL AB, 2008 Sun Microsystems, Inc.");
392 puts(
"This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
393 puts(
"Read and modify Archive files directly\n");
394 printf(
"Usage: %s [OPTIONS] file_to_be_looked_at [file_for_backup]\n", my_progname);
395 print_defaults(
"my", load_default_groups);
396 my_print_help(my_long_options);
399 static void print_version(
void)
401 printf(
"%s Ver %s Distrib %s, for %s (%s)\n", my_progname, SHOW_VERSION,
402 MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
405 static void get_options(
int *argc,
char ***argv)
407 if (load_defaults(
"my", load_default_groups, argc, argv))
411 handle_options(argc, argv, my_long_options, get_one_option);