diff options
Diffstat (limited to 'client/mysqlcheck.c')
-rw-r--r-- | client/mysqlcheck.c | 90 |
1 files changed, 62 insertions, 28 deletions
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 8a9711fffae..6487259adc1 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,7 +15,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#define CHECK_VERSION "2.5.0" +#define CHECK_VERSION "2.5.1" #include "client_priv.h" #include <m_ctype.h> @@ -29,6 +29,10 @@ #define EX_USAGE 1 #define EX_MYSQLERR 2 +/* ALTER instead of repair. */ +#define MAX_ALTER_STR_SIZE 128 * 1024 +#define KEY_PARTITIONING_CHANGED_STR "KEY () partitioning changed" + static MYSQL mysql_connection, *sock = 0; static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0, opt_compress = 0, opt_databases = 0, opt_fast = 0, @@ -44,7 +48,7 @@ static char *opt_password = 0, *current_user = 0, *default_charset= 0, *current_host= 0; static char *opt_plugin_dir= 0, *opt_default_auth= 0; static int first_error = 0; -DYNAMIC_ARRAY tables4repair, tables4rebuild; +DYNAMIC_ARRAY tables4repair, tables4rebuild, alter_table_cmds; #ifdef HAVE_SMEM static char *shared_memory_base_name=0; #endif @@ -591,6 +595,17 @@ static int process_all_tables_in_db(char *database) } /* process_all_tables_in_db */ +static int run_query(const char *query) +{ + if (mysql_query(sock, query)) + { + fprintf(stderr, "Failed to %s\n", query); + fprintf(stderr, "Error: %s\n", mysql_error(sock)); + return 1; + } + return 0; +} + static int fix_table_storage_name(const char *name) { @@ -599,12 +614,7 @@ static int fix_table_storage_name(const char *name) if (strncmp(name, "#mysql50#", 9)) return 1; sprintf(qbuf, "RENAME TABLE `%s` TO `%s`", name, name + 9); - if (mysql_query(sock, qbuf)) - { - fprintf(stderr, "Failed to %s\n", qbuf); - fprintf(stderr, "Error: %s\n", mysql_error(sock)); - rc= 1; - } + rc= run_query(qbuf); if (verbose) printf("%-50s %s\n", name, rc ? "FAILED" : "OK"); return rc; @@ -617,12 +627,7 @@ static int fix_database_storage_name(const char *name) if (strncmp(name, "#mysql50#", 9)) return 1; sprintf(qbuf, "ALTER DATABASE `%s` UPGRADE DATA DIRECTORY NAME", name); - if (mysql_query(sock, qbuf)) - { - fprintf(stderr, "Failed to %s\n", qbuf); - fprintf(stderr, "Error: %s\n", mysql_error(sock)); - rc= 1; - } + rc= run_query(qbuf); if (verbose) printf("%-50s %s\n", name, rc ? "FAILED" : "OK"); return rc; @@ -685,13 +690,7 @@ static int use_db(char *database) static int disable_binlog() { const char *stmt= "SET SQL_LOG_BIN=0"; - if (mysql_query(sock, stmt)) - { - fprintf(stderr, "Failed to %s\n", stmt); - fprintf(stderr, "Error: %s\n", mysql_error(sock)); - return 1; - } - return 0; + return run_query(stmt); } static int handle_request_for_tables(char *tables, uint length) @@ -761,12 +760,14 @@ static void print_result() MYSQL_RES *res; MYSQL_ROW row; char prev[NAME_LEN*2+2]; + char prev_alter[MAX_ALTER_STR_SIZE]; uint i; my_bool found_error=0, table_rebuild=0; res = mysql_use_result(sock); prev[0] = '\0'; + prev_alter[0]= 0; for (i = 0; (row = mysql_fetch_row(res)); i++) { int changed = strcmp(prev, row[0]); @@ -783,12 +784,18 @@ static void print_result() strcmp(row[3],"OK")) { if (table_rebuild) - insert_dynamic(&tables4rebuild, (uchar*) prev); + { + if (prev_alter[0]) + insert_dynamic(&alter_table_cmds, (uchar*) prev_alter); + else + insert_dynamic(&tables4rebuild, (uchar*) prev); + } else insert_dynamic(&tables4repair, (uchar*) prev); } found_error=0; table_rebuild=0; + prev_alter[0]= 0; if (opt_silent) continue; } @@ -797,11 +804,30 @@ static void print_result() else if (!status && changed) { printf("%s\n%-9s: %s", row[0], row[2], row[3]); - if (strcmp(row[2],"note")) + if (opt_auto_repair && strcmp(row[2],"note")) { - found_error=1; - if (opt_auto_repair && strstr(row[3], "ALTER TABLE") != NULL) + const char *alter_txt= strstr(row[3], "ALTER TABLE"); + found_error=1; + if (alter_txt) + { table_rebuild=1; + if (!strncmp(row[3], KEY_PARTITIONING_CHANGED_STR, + strlen(KEY_PARTITIONING_CHANGED_STR)) && + strstr(alter_txt, "PARTITION BY")) + { + if (strlen(alter_txt) >= MAX_ALTER_STR_SIZE) + { + printf("Error: Alter command too long (>= %d)," + " please do \"%s\" or dump/reload to fix it!\n", + MAX_ALTER_STR_SIZE, + alter_txt); + table_rebuild= 0; + prev_alter[0]= 0; + } + else + strcpy(prev_alter, alter_txt); + } + } } } else @@ -813,7 +839,12 @@ static void print_result() if (found_error && opt_auto_repair && what_to_do != DO_REPAIR) { if (table_rebuild) - insert_dynamic(&tables4rebuild, (uchar*) prev); + { + if (prev_alter[0]) + insert_dynamic(&alter_table_cmds, (uchar*) prev_alter); + else + insert_dynamic(&tables4rebuild, (uchar*) prev); + } else insert_dynamic(&tables4repair, (uchar*) prev); } @@ -915,7 +946,8 @@ int main(int argc, char **argv) if (opt_auto_repair && (my_init_dynamic_array(&tables4repair, sizeof(char)*(NAME_LEN*2+2),16,64) || - my_init_dynamic_array(&tables4rebuild, sizeof(char)*(NAME_LEN*2+2),16,64))) + my_init_dynamic_array(&tables4rebuild, sizeof(char)*(NAME_LEN*2+2),16,64) || + my_init_dynamic_array(&alter_table_cmds, MAX_ALTER_STR_SIZE, 0, 1))) { first_error = 1; goto end; @@ -943,6 +975,8 @@ int main(int argc, char **argv) } for (i = 0; i < tables4rebuild.elements ; i++) rebuild_table((char*) dynamic_array_ptr(&tables4rebuild, i)); + for (i = 0; i < alter_table_cmds.elements ; i++) + run_query((char*) dynamic_array_ptr(&alter_table_cmds, i)); } end: dbDisconnect(current_host); |