summaryrefslogtreecommitdiff
path: root/client/mysqlcheck.c
diff options
context:
space:
mode:
Diffstat (limited to 'client/mysqlcheck.c')
-rw-r--r--client/mysqlcheck.c210
1 files changed, 151 insertions, 59 deletions
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index ec9ee50868b..e84cbdefbbc 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -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,
@@ -42,14 +46,15 @@ static int my_end_arg;
static char * opt_mysql_unix_port = 0;
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;
+DYNAMIC_ARRAY tables4repair, tables4rebuild, alter_table_cmds;
#ifdef HAVE_SMEM
static char *shared_memory_base_name=0;
#endif
static uint opt_protocol=0;
-enum operations { DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE };
+enum operations { DO_CHECK=1, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE };
static struct my_option my_long_options[] =
{
@@ -63,10 +68,6 @@ static struct my_option my_long_options[] =
"Instead of issuing one query for each table, use one query per database, naming all tables in the database in a comma-separated list.",
&opt_all_in_1, &opt_all_in_1, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
-#ifdef __NETWARE__
- {"autoclose", OPT_AUTO_CLOSE, "Automatically close the screen on exit for Netware.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-#endif
{"auto-repair", OPT_AUTO_REPAIR,
"If a checked table is corrupted, automatically fix it. Repairing will be done after all tables have been checked, if corrupted ones were found.",
&opt_auto_repair, &opt_auto_repair, 0, GET_BOOL, NO_ARG, 0,
@@ -105,6 +106,10 @@ static struct my_option my_long_options[] =
{"default-character-set", OPT_DEFAULT_CHARSET,
"Set the default character set.", &default_charset,
&default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"default_auth", OPT_DEFAULT_AUTH,
+ "Default authentication client-side plugin to use.",
+ &opt_default_auth, &opt_default_auth, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"fast",'F', "Check only tables that haven't been closed properly.",
&opt_fast, &opt_fast, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
0},
@@ -129,7 +134,8 @@ static struct my_option my_long_options[] =
"Faster than extended-check, but only finds 99.99 percent of all errors. Should be good enough for most cases.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"write-binlog", OPT_WRITE_BINLOG,
- "Log ANALYZE, OPTIMIZE and REPAIR TABLE commands. Enabled by default; use --skip-write-binlog when commands should not be sent to replication slaves.",
+ "Log ANALYZE, OPTIMIZE and REPAIR TABLE commands. Use --skip-write-binlog "
+ "when commands should not be sent to replication slaves.",
&opt_write_binlog, &opt_write_binlog, 0, GET_BOOL, NO_ARG,
1, 0, 0, 0, 0, 0},
{"optimize", 'o', "Optimize table.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
@@ -141,14 +147,16 @@ static struct my_option my_long_options[] =
{"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
+ {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
+ &opt_plugin_dir, &opt_plugin_dir, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"port", 'P', "Port number to use for connection or 0 for default to, in "
"order of preference, my.cnf, $MYSQL_TCP_PORT, "
#if MYSQL_PORT_DEFAULT == 0
"/etc/services, "
#endif
"built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
- &opt_mysql_port,
- &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
+ &opt_mysql_port, &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
0},
{"protocol", OPT_MYSQL_PROTOCOL, "The protocol to use for connection (tcp, socket, pipe, memory).",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -209,13 +217,11 @@ static uint fixed_name_length(const char *name);
static char *fix_table_name(char *dest, char *src);
int what_to_do = 0;
-#include <help_start.h>
static void print_version(void)
{
printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, CHECK_VERSION,
MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
- NETWARE_SET_SCREEN_MODE(1);
} /* print_version */
@@ -244,18 +250,14 @@ static void usage(void)
my_print_variables(my_long_options);
} /* usage */
-#include <help_end.h>
static my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
char *argument)
{
+ int orig_what_to_do= what_to_do;
+
switch(optid) {
-#ifdef __NETWARE__
- case OPT_AUTO_CLOSE:
- setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
- break;
-#endif
case 'a':
what_to_do = DO_ANALYZE;
break;
@@ -290,7 +292,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
if (argument)
{
char *start = argument;
- my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_password);
opt_password = my_strdup(argument, MYF(MY_FAE));
while (*argument) *argument++= 'x'; /* Destroy argument */
if (*start)
@@ -329,6 +331,13 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
opt->name);
break;
}
+
+ if (orig_what_to_do && (what_to_do != orig_what_to_do))
+ {
+ fprintf(stderr, "Error: %s doesn't support multiple contradicting commands.\n",
+ my_progname);
+ return 1;
+ }
return 0;
}
@@ -343,9 +352,8 @@ static int get_options(int *argc, char ***argv)
exit(0);
}
- load_defaults("my", load_default_groups, argc, argv);
-
- if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ if ((ho_error= load_defaults("my", load_default_groups, argc, argv)) ||
+ (ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
exit(ho_error);
if (!what_to_do)
@@ -368,12 +376,15 @@ static int get_options(int *argc, char ***argv)
If there's no --default-character-set option given with
--fix-table-name or --fix-db-name set the default character set to "utf8".
*/
- if (!default_charset && (opt_fix_db_names || opt_fix_table_names))
+ if (!default_charset)
{
- default_charset= (char*) "utf8";
+ if (opt_fix_db_names || opt_fix_table_names)
+ default_charset= (char*) "utf8";
+ else
+ default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME;
}
- if (default_charset && !get_charset_by_csname(default_charset, MY_CS_PRIMARY,
- MYF(MY_WME)))
+ if (strcmp(default_charset, MYSQL_AUTODETECT_CHARSET_NAME) &&
+ !get_charset_by_csname(default_charset, MY_CS_PRIMARY, MYF(MY_WME)))
{
printf("Unsupported character set: %s\n", default_charset);
return 1;
@@ -467,7 +478,7 @@ static int process_selected_tables(char *db, char **table_names, int tables)
}
*--end = 0;
handle_request_for_tables(table_names_comma_sep + 1, (uint) (tot_length - 1));
- my_free(table_names_comma_sep, MYF(0));
+ my_free(table_names_comma_sep);
}
else
for (; tables > 0; tables--, table_names++)
@@ -566,7 +577,7 @@ static int process_all_tables_in_db(char *database)
*--end = 0;
if (tot_length)
handle_request_for_tables(tables + 1, tot_length - 1);
- my_free(tables, MYF(0));
+ my_free(tables);
}
else
{
@@ -584,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)
{
@@ -592,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;
@@ -610,14 +627,30 @@ 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))
+ rc= run_query(qbuf);
+ if (verbose)
+ printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
+ return rc;
+}
+
+static int rebuild_table(char *name)
+{
+ char *query, *ptr;
+ int rc= 0;
+ query= (char*)my_malloc(sizeof(char) * (12 + fixed_name_length(name) + 6 + 1),
+ MYF(MY_WME));
+ if (!query)
+ return 1;
+ ptr= strmov(query, "ALTER TABLE ");
+ ptr= fix_table_name(ptr, name);
+ ptr= strxmov(ptr, " FORCE", NullS);
+ if (mysql_real_query(sock, query, (uint)(ptr - query)))
{
- fprintf(stderr, "Failed to %s\n", qbuf);
+ fprintf(stderr, "Failed to %s\n", query);
fprintf(stderr, "Error: %s\n", mysql_error(sock));
rc= 1;
}
- if (verbose)
- printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
+ my_free(query);
return rc;
}
@@ -640,8 +673,11 @@ static int process_one_db(char *database)
static int use_db(char *database)
{
- if (mysql_get_server_version(sock) >= 50003 &&
- !my_strcasecmp(&my_charset_latin1, database, "information_schema"))
+ if (mysql_get_server_version(sock) >= FIRST_INFORMATION_SCHEMA_VERSION &&
+ !my_strcasecmp(&my_charset_latin1, database, INFORMATION_SCHEMA_DB_NAME))
+ return 1;
+ if (mysql_get_server_version(sock) >= FIRST_PERFORMANCE_SCHEMA_VERSION &&
+ !my_strcasecmp(&my_charset_latin1, database, PERFORMANCE_SCHEMA_DB_NAME))
return 1;
if (mysql_select_db(sock, database))
{
@@ -654,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)
@@ -720,7 +750,7 @@ static int handle_request_for_tables(char *tables, uint length)
return 1;
}
print_result();
- my_free(query, MYF(0));
+ my_free(query);
return 0;
}
@@ -730,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;
+ 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]);
@@ -750,8 +782,20 @@ static void print_result()
*/
if (found_error && opt_auto_repair && what_to_do != DO_REPAIR &&
strcmp(row[3],"OK"))
- insert_dynamic(&tables4repair, (uchar*) prev);
+ {
+ if (table_rebuild)
+ {
+ 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;
}
@@ -760,8 +804,31 @@ static void print_result()
else if (!status && changed)
{
printf("%s\n%-9s: %s", row[0], row[2], row[3]);
- if (strcmp(row[2],"note"))
- found_error=1;
+ if (opt_auto_repair && strcmp(row[2],"note"))
+ {
+ 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
printf("%-9s: %s", row[2], row[3]);
@@ -770,7 +837,17 @@ static void print_result()
}
/* add the last table to be repaired to the list */
if (found_error && opt_auto_repair && what_to_do != DO_REPAIR)
- insert_dynamic(&tables4repair, (uchar*) prev);
+ {
+ if (table_rebuild)
+ {
+ if (prev_alter[0])
+ insert_dynamic(&alter_table_cmds, (uchar*) prev_alter);
+ else
+ insert_dynamic(&tables4rebuild, (uchar*) prev);
+ }
+ else
+ insert_dynamic(&tables4repair, (uchar*) prev);
+ }
mysql_free_result(res);
}
@@ -796,8 +873,14 @@ static int dbConnect(char *host, char *user, char *passwd)
if (shared_memory_base_name)
mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
#endif
- if (default_charset)
- mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset);
+
+ if (opt_plugin_dir && *opt_plugin_dir)
+ mysql_options(&mysql_connection, MYSQL_PLUGIN_DIR, opt_plugin_dir);
+
+ if (opt_default_auth && *opt_default_auth)
+ mysql_options(&mysql_connection, MYSQL_DEFAULT_AUTH, opt_default_auth);
+
+ mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset);
if (!(sock = mysql_real_connect(&mysql_connection, host, user, passwd,
NULL, opt_mysql_port, opt_mysql_unix_port, 0)))
{
@@ -862,7 +945,9 @@ 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(&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(&alter_table_cmds, MAX_ALTER_STR_SIZE, 0, 1)))
{
first_error = 1;
goto end;
@@ -880,7 +965,7 @@ int main(int argc, char **argv)
{
uint i;
- if (!opt_silent && tables4repair.elements)
+ if (!opt_silent && (tables4repair.elements || tables4rebuild.elements))
puts("\nRepairing tables");
what_to_do = DO_REPAIR;
for (i = 0; i < tables4repair.elements ; i++)
@@ -888,14 +973,21 @@ int main(int argc, char **argv)
char *name= (char*) dynamic_array_ptr(&tables4repair, i);
handle_request_for_tables(name, fixed_name_length(name));
}
+ 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);
if (opt_auto_repair)
+ {
delete_dynamic(&tables4repair);
- my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
+ delete_dynamic(&tables4rebuild);
+ }
+ my_free(opt_password);
#ifdef HAVE_SMEM
- my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(shared_memory_base_name);
#endif
my_end(my_end_arg);
return(first_error!=0);