diff options
author | Sergei Golubchik <serg@mariadb.org> | 2015-04-28 21:11:49 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2015-04-28 21:11:49 +0200 |
commit | f9c02d7c29e7ddc9fa274e7fe23e5800653660f4 (patch) | |
tree | 817db8c66d7feb63147fe24f8d7474a64660451a /client | |
parent | fbab0685a7b7f39db0217823ad90dd47034eae29 (diff) | |
parent | 83ce3529b8b2ba5b8070d12aaecbb6c3e3fcaeca (diff) | |
download | mariadb-git-f9c02d7c29e7ddc9fa274e7fe23e5800653660f4.tar.gz |
Merge branch 'openquery/MDEV-6916-maria-5.5-check_view-r4408' into 5.5
Diffstat (limited to 'client')
-rw-r--r-- | client/client_priv.h | 1 | ||||
-rw-r--r-- | client/mysql_upgrade.c | 69 | ||||
-rw-r--r-- | client/mysqlcheck.c | 186 |
3 files changed, 230 insertions, 26 deletions
diff --git a/client/client_priv.h b/client/client_priv.h index e206804d057..a66c3883654 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -79,6 +79,7 @@ enum options_client OPT_SLAP_COMMIT, OPT_SLAP_DETACH, OPT_SLAP_NO_DROP, + OPT_UPGRADE_VIEWS, OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT_MODE, OPT_SERVER_ID, OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT, OPT_AUTO_VERTICAL_OUTPUT, diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 5fb3b1317d9..97e2ad92239 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -36,6 +36,8 @@ # endif #endif +static int phase = 1; +static int phases_total = 4; static char mysql_path[FN_REFLEN]; static char mysqlcheck_path[FN_REFLEN]; @@ -738,9 +740,10 @@ static void print_conn_args(const char *tool_name) static int run_mysqlcheck_upgrade(void) { - verbose("Phase 2/3: Checking and upgrading tables"); + int retch; + verbose("Phase %d/%d: Checking and upgrading tables", phase++, phases_total); print_conn_args("mysqlcheck"); - return run_tool(mysqlcheck_path, + retch= run_tool(mysqlcheck_path, NULL, /* Send output from mysqlcheck directly to screen */ "--no-defaults", ds_args.str, @@ -752,12 +755,67 @@ static int run_mysqlcheck_upgrade(void) opt_write_binlog ? "--write-binlog" : "--skip-write-binlog", "2>&1", NULL); + if (retch || opt_systables_only) + verbose("Phase %d/%d: Skipping 'mysql_fix_privilege_tables'... not needed", phase++, phases_total); + return retch; } +#define EVENTS_STRUCT_LEN 7000 + +static my_bool is_mysql() +{ + my_bool ret= TRUE; + DYNAMIC_STRING ds_events_struct; + + if (init_dynamic_string(&ds_events_struct, NULL, + EVENTS_STRUCT_LEN, EVENTS_STRUCT_LEN)) + die("Out of memory"); + + if (run_query("show create table mysql.event", + &ds_events_struct, FALSE) || + strstr(ds_events_struct.str, "IGNORE_BAD_TABLE_OPTIONS") != NULL) + ret= FALSE; + else + verbose("MySQL upgrade detected"); + + dynstr_free(&ds_events_struct); + return(ret); +} + +static int run_mysqlcheck_views(void) +{ + const char *upgrade_views="--upgrade-views=YES"; + if (is_mysql()) + { + upgrade_views="--upgrade-views=FROM_MYSQL"; + verbose("Phase %d/%d: Fixing views from mysql", phase++, phases_total); + } + else if (opt_systables_only) + { + verbose("Phase %d/%d: Fixing views - skipped - not required", phase++, phases_total); + return 0; + } + else + verbose("Phase %d/%d: Fixing views", phase++, phases_total); + + print_conn_args("mysqlcheck"); + return run_tool(mysqlcheck_path, + NULL, /* Send output from mysqlcheck directly to screen */ + "--no-defaults", + ds_args.str, + "--all-databases", + upgrade_views, + "--skip-fix-tables", + opt_verbose ? "--verbose": "", + opt_silent ? "--silent": "", + opt_write_binlog ? "--write-binlog" : "--skip-write-binlog", + "2>&1", + NULL); +} static int run_mysqlcheck_fixnames(void) { - verbose("Phase 1/3: Fixing table and database names"); + verbose("Phase %d/%d: Fixing table and database names", phase++, phases_total); print_conn_args("mysqlcheck"); return run_tool(mysqlcheck_path, NULL, /* Send output from mysqlcheck directly to screen */ @@ -838,7 +896,7 @@ static int run_sql_fix_privilege_tables(void) if (init_dynamic_string(&ds_result, "", 512, 512)) die("Out of memory"); - verbose("Phase 3/3: Running 'mysql_fix_privilege_tables'..."); + verbose("Phase %d/%d: Running 'mysql_fix_privilege_tables'...", phase++, phases_total); run_query(mysql_fix_privilege_tables, &ds_result, /* Collect result */ TRUE); @@ -1001,7 +1059,8 @@ int main(int argc, char **argv) Run "mysqlcheck" and "mysql_fix_privilege_tables.sql" */ if ((!opt_systables_only && - (run_mysqlcheck_fixnames() || run_mysqlcheck_upgrade())) || + (run_mysqlcheck_views() || + run_mysqlcheck_fixnames() || run_mysqlcheck_upgrade())) || run_sql_fix_privilege_tables()) { /* diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index a4549432c2c..43c7ff0d8a1 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -18,7 +18,7 @@ /* By Jani Tolonen, 2001-04-20, MySQL Development Team */ -#define CHECK_VERSION "2.7.1" +#define CHECK_VERSION "2.7.2-MariaDB" #include "client_priv.h" #include <m_ctype.h> @@ -42,7 +42,8 @@ static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0, opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0, opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0, tty_password= 0, opt_frm= 0, debug_info_flag= 0, debug_check_flag= 0, - opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0; + opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0, + opt_fix_tables= 1; static my_bool opt_write_binlog= 1, opt_flush_tables= 0; static uint verbose = 0, opt_mysql_port=0; static int my_end_arg; @@ -57,6 +58,20 @@ static uint opt_protocol=0; enum operations { DO_CHECK=1, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE }; +typedef enum { + UPGRADE_VIEWS_NO=0, + UPGRADE_VIEWS_YES=1, + UPGRADE_VIEWS_FROM_MYSQL=2, + UPGRADE_VIEWS_COUNT +} enum_upgrade_views; +const char *upgrade_views_opts[]= +{"NO", "YES", "FROM_MYSQL", NullS}; +TYPELIB upgrade_views_typelib= + { array_elements(upgrade_views_opts) - 1, "", + upgrade_views_opts, NULL }; +static enum_upgrade_views opt_upgrade_views= UPGRADE_VIEWS_NO; +static char *opt_upgrade_views_str= NullS; + static struct my_option my_long_options[] = { {"all-databases", 'A', @@ -196,6 +211,15 @@ static struct my_option my_long_options[] = NO_ARG, 0, 0, 0, 0, 0, 0}, {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"upgrade-views", OPT_UPGRADE_VIEWS, + "Repairs/Upgrades views. 'No' (default) doesn't do anything to views. " + "'Yes' repairs the checksum and adds a MariaDB version to the frm table defination (if missing)." + "Using 'from_mysql' will, when upgrading from MySQL, and ensure the view algorithms are the" + "same as what they where previously.", + &opt_upgrade_views_str, &opt_upgrade_views_str, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"fix-tables", 'Y', + "Fix tables. Usually the default however mysql_upgrade will run with --skip-fix-tables.", + &opt_fix_tables, &opt_fix_tables, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -212,7 +236,7 @@ static int process_selected_tables(char *db, char **table_names, int tables); static int process_all_tables_in_db(char *database); static int process_one_db(char *database); static int use_db(char *database); -static int handle_request_for_tables(char *tables, uint length); +static int handle_request_for_tables(char *tables, uint length, my_bool view); static int dbConnect(char *host, char *user,char *passwd); static void dbDisconnect(char *host); static void DBerror(MYSQL *mysql, const char *when); @@ -332,7 +356,18 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case 'v': verbose++; break; - case 'V': print_version(); exit(0); + case 'V': + print_version(); exit(0); + break; + case OPT_UPGRADE_VIEWS: + if (argument == NULL) + opt_upgrade_views= UPGRADE_VIEWS_NO; + else + { + opt_upgrade_views= (enum_upgrade_views) + (find_type_or_exit(argument, &upgrade_views_typelib, opt->name)-1); + } + break; case OPT_MYSQL_PROTOCOL: opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, opt->name); @@ -363,6 +398,23 @@ static int get_options(int *argc, char ***argv) if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) exit(ho_error); + if (what_to_do==DO_REPAIR && !(opt_upgrade_views || opt_fix_tables)) + { + fprintf(stderr, "Error: %s doesn't support repair command without either upgrade-views or fix-tables specified.\n", + my_progname); + exit(1); + } + if (opt_upgrade_views && what_to_do!=DO_REPAIR) + { + if (!what_to_do) + what_to_do= DO_REPAIR; + else + { + fprintf(stderr, "Error: %s doesn't support non-repair command with option upgrade-views.\n", + my_progname); + exit(1); + } + } if (!what_to_do) { size_t pnlen= strlen(my_progname); @@ -463,8 +515,41 @@ static int process_databases(char **db_names) } /* process_databases */ +/* returns: -1 for error, 1 for view, 0 for table */ +static int is_view(const char *table, uint length) +{ + char *query, *ptr; + MYSQL_RES *res; + MYSQL_FIELD *field; + int view; + DBUG_ENTER("is_view"); + + if (!(query =(char *) my_malloc((sizeof(char)*(length+110)), MYF(MY_WME)))) + DBUG_RETURN(-1); + ptr= strmov(query, "SHOW CREATE TABLE `"); + ptr= strxmov(ptr, table, NullS); + ptr= strxmov(ptr, "`", NullS); + if (mysql_query(sock, query)) + { + fprintf(stderr, "Failed to %s\n", query); + fprintf(stderr, "Error: %s\n", mysql_error(sock)); + my_free(query); + DBUG_RETURN(-1); + } + res= mysql_store_result(sock); + field= mysql_fetch_field(res); + view= (strcmp(field->name,"View")==0) ? 1 : 0; + mysql_free_result(res); + my_free(query); + + DBUG_RETURN(view); +} + static int process_selected_tables(char *db, char **table_names, int tables) { + int view; + char *table; + uint table_len; DBUG_ENTER("process_selected_tables"); if (use_db(db)) @@ -494,12 +579,24 @@ static int process_selected_tables(char *db, char **table_names, int tables) *end++= ','; } *--end = 0; - handle_request_for_tables(table_names_comma_sep + 1, (uint) (tot_length - 1)); + table= table_names_comma_sep + 1; + table_len= tot_length - 1; + view= is_view(table, table_len); + if (view < 0) + DBUG_RETURN(1); + handle_request_for_tables(table, table_len, (view==1)); my_free(table_names_comma_sep); } else for (; tables > 0; tables--, table_names++) - handle_request_for_tables(*table_names, fixed_name_length(*table_names)); + { + table= *table_names; + table_len= fixed_name_length(*table_names); + view= is_view(table, table_len); + if (view < 0) + continue; + handle_request_for_tables(table, table_len, (view==1)); + } DBUG_RETURN(0); } /* process_selected_tables */ @@ -546,6 +643,7 @@ static int process_all_tables_in_db(char *database) MYSQL_ROW row; uint num_columns; my_bool system_database= 0; + my_bool view= FALSE; DBUG_ENTER("process_all_tables_in_db"); if (use_db(database)) @@ -575,8 +673,17 @@ static int process_all_tables_in_db(char *database) char *tables, *end; uint tot_length = 0; + char *views, *views_end; + uint tot_views_length = 0; + while ((row = mysql_fetch_row(res))) - tot_length+= fixed_name_length(row[0]) + 2; + { + if ((num_columns == 2) && (strcmp(row[1], "VIEW") == 0) && + opt_upgrade_views) + tot_views_length+= fixed_name_length(row[0]) + 2; + else if (opt_fix_tables) + tot_length+= fixed_name_length(row[0]) + 2; + } mysql_data_seek(res, 0); if (!(tables=(char *) my_malloc(sizeof(char)*tot_length+4, MYF(MY_WME)))) @@ -584,18 +691,38 @@ static int process_all_tables_in_db(char *database) mysql_free_result(res); DBUG_RETURN(1); } - for (end = tables + 1; (row = mysql_fetch_row(res)) ;) + if (!(views=(char *) my_malloc(sizeof(char)*tot_views_length+4, MYF(MY_WME)))) { - if ((num_columns == 2) && (strcmp(row[1], "VIEW") == 0)) - continue; + my_free(tables); + mysql_free_result(res); + DBUG_RETURN(1); + } - end= fix_table_name(end, row[0]); - *end++= ','; + for (end = tables + 1, views_end= views + 1; (row = mysql_fetch_row(res)) ;) + { + if ((num_columns == 2) && (strcmp(row[1], "VIEW") == 0)) + { + if (!opt_upgrade_views) + continue; + views_end= fix_table_name(views_end, row[0]); + *views_end++= ','; + } + else + { + if (!opt_fix_tables) + continue; + end= fix_table_name(end, row[0]); + *end++= ','; + } } *--end = 0; + *--views_end = 0; if (tot_length) - handle_request_for_tables(tables + 1, tot_length - 1); + handle_request_for_tables(tables + 1, tot_length - 1, FALSE); + if (tot_views_length) + handle_request_for_tables(views + 1, tot_views_length - 1, TRUE); my_free(tables); + my_free(views); } else { @@ -603,13 +730,23 @@ static int process_all_tables_in_db(char *database) { /* Skip views if we don't perform renaming. */ if ((what_to_do != DO_UPGRADE) && (num_columns == 2) && (strcmp(row[1], "VIEW") == 0)) - continue; + { + if (!opt_upgrade_views) + continue; + view= TRUE; + } + else + { + if (!opt_fix_tables) + continue; + view= FALSE; + } if (system_database && (!strcmp(row[0], "general_log") || !strcmp(row[0], "slow_log"))) continue; /* Skip logging tables */ - handle_request_for_tables(row[0], fixed_name_length(row[0])); + handle_request_for_tables(row[0], fixed_name_length(row[0]), view); } } mysql_free_result(res); @@ -727,15 +864,17 @@ static int disable_binlog() return run_query(stmt); } -static int handle_request_for_tables(char *tables, uint length) +static int handle_request_for_tables(char *tables, uint length, my_bool view) { char *query, *end, options[100], message[100]; char table_name_buff[NAME_CHAR_LEN*2*2+1], *table_name; uint query_length= 0; const char *op = 0; + const char *tab_view; DBUG_ENTER("handle_request_for_tables"); options[0] = 0; + tab_view= view ? " VIEW " : " TABLE "; end = options; switch (what_to_do) { case DO_CHECK: @@ -748,10 +887,13 @@ static int handle_request_for_tables(char *tables, uint length) if (opt_upgrade) end = strmov(end, " FOR UPGRADE"); break; case DO_REPAIR: - op= (opt_write_binlog) ? "REPAIR" : "REPAIR NO_WRITE_TO_BINLOG"; + op= (opt_write_binlog) ? + "REPAIR" : "REPAIR NO_WRITE_TO_BINLOG"; if (opt_quick) end = strmov(end, " QUICK"); if (opt_extended) end = strmov(end, " EXTENDED"); if (opt_frm) end = strmov(end, " USE_FRM"); + if (opt_upgrade_views==UPGRADE_VIEWS_FROM_MYSQL && view) + end = strmov(end, " FROM MYSQL"); break; case DO_ANALYZE: op= (opt_write_binlog) ? "ANALYZE" : "ANALYZE NO_WRITE_TO_BINLOG"; @@ -768,14 +910,15 @@ static int handle_request_for_tables(char *tables, uint length) if (opt_all_in_1) { /* No backticks here as we added them before */ - query_length= sprintf(query, "%s TABLE %s %s", op, tables, options); + query_length= sprintf(query, "%s%s%s %s", op, + tab_view, tables, options); table_name= tables; } else { char *ptr, *org; - org= ptr= strmov(strmov(query, op), " TABLE "); + org= ptr= strmov(strmov(query, op), tab_view); ptr= fix_table_name(ptr, tables); strmake(table_name_buff, org, min((int) sizeof(table_name_buff)-1, (int) (ptr - org))); @@ -785,7 +928,8 @@ static int handle_request_for_tables(char *tables, uint length) } if (mysql_real_query(sock, query, query_length)) { - sprintf(message, "when executing '%s TABLE ... %s'", op, options); + sprintf(message, "when executing '%s%s... %s'", op, tab_view, options); + /* sprintf(message, "when executing '%s'", query); */ DBerror(sock, message); my_free(query); DBUG_RETURN(1); @@ -1055,7 +1199,7 @@ int main(int argc, char **argv) for (i = 0; i < tables4repair.elements ; i++) { char *name= (char*) dynamic_array_ptr(&tables4repair, i); - handle_request_for_tables(name, fixed_name_length(name)); + handle_request_for_tables(name, fixed_name_length(name), FALSE); } for (i = 0; i < tables4rebuild.elements ; i++) rebuild_table((char*) dynamic_array_ptr(&tables4rebuild, i)); |