diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/mysql_upgrade.c | 118 | ||||
-rw-r--r-- | client/mysqladmin.cc | 5 | ||||
-rw-r--r-- | client/mysqlbinlog.cc | 9 | ||||
-rw-r--r-- | client/mysqlcheck.c | 271 | ||||
-rw-r--r-- | client/mysqldump.c | 68 | ||||
-rw-r--r-- | client/mysqltest.cc | 53 |
6 files changed, 389 insertions, 135 deletions
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index dcfdff1a81f..ce441695d6f 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -1,6 +1,6 @@ /* Copyright (c) 2006, 2013, Oracle and/or its affiliates. - Copyright (c) 2010, 2013, Monty Program Ab. + Copyright (c) 2010, 2015, MariaDB 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 @@ -36,6 +36,8 @@ # endif #endif +static int phase = 0; +static int phases_total = 6; static char mysql_path[FN_REFLEN]; static char mysqlcheck_path[FN_REFLEN]; @@ -45,6 +47,8 @@ static my_bool opt_not_used, opt_silent; static uint my_end_arg= 0; static char *opt_user= (char*)"root"; +static my_bool upgrade_from_mysql; + static DYNAMIC_STRING ds_args; static DYNAMIC_STRING conn_args; @@ -206,12 +210,12 @@ static void die(const char *fmt, ...) } -static int verbose(const char *fmt, ...) +static void verbose(const char *fmt, ...) { va_list args; if (opt_silent) - return 0; + return; /* Print the verbose message */ va_start(args, fmt); @@ -222,7 +226,6 @@ static int verbose(const char *fmt, ...) fflush(stdout); } va_end(args); - return 0; } @@ -740,10 +743,21 @@ static void print_conn_args(const char *tool_name) in the server using "mysqlcheck --check-upgrade .." */ -static int run_mysqlcheck_upgrade(const char *arg1, const char *arg2) +static int run_mysqlcheck_upgrade(my_bool mysql_db_only) { + const char *what= mysql_db_only ? "mysql database" : "tables"; + const char *arg1= mysql_db_only ? "--databases" : "--all-databases"; + const char *arg2= mysql_db_only ? "mysql" : "--skip-database=mysql"; + int retch; + if (opt_systables_only && !mysql_db_only) + { + verbose("Phase %d/%d: Checking and upgrading %s... Skipped", + ++phase, phases_total, what); + return 0; + } + verbose("Phase %d/%d: Checking and upgrading %s", ++phase, phases_total, what); 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, @@ -757,12 +771,77 @@ static int run_mysqlcheck_upgrade(const char *arg1, const char *arg2) arg1, arg2, "2>&1", NULL); + 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="--process-views=YES"; + if (upgrade_from_mysql) + { + /* + this has to ignore opt_systables_only, because upgrade_from_mysql + is determined by analyzing systables. if we honor opt_systables_only + here, views won't be fixed by subsequent mysql_upgrade runs + */ + upgrade_views="--process-views=UPGRADE_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", ++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", "--repair", + upgrade_views, + "--skip-process-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 3/5: Fixing table and database names"); + if (opt_systables_only) + { + verbose("Phase %d/%d: Fixing table and database names ... Skipped", + ++phase, phases_total); + return 0; + } + 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 */ @@ -850,6 +929,9 @@ static int run_sql_fix_privilege_tables(void) if (init_dynamic_string(&ds_result, "", 512, 512)) die("Out of memory"); + verbose("Phase %d/%d: Running 'mysql_fix_privilege_tables'", + ++phase, phases_total); + /* Individual queries can not be executed independently by invoking a forked mysql client, because the script uses session variables @@ -1019,23 +1101,19 @@ int main(int argc, char **argv) if (opt_version_check && check_version_match()) die("Upgrade failed"); + upgrade_from_mysql= is_mysql(); + /* Run "mysqlcheck" and "mysql_fix_privilege_tables.sql" */ - verbose("Phase 1/5: Checking mysql database"); - if (run_mysqlcheck_upgrade("--databases", "mysql")) - die("Upgrade failed" ); - verbose("Phase 2/5: Running 'mysql_fix_privilege_tables'..."); - if (run_sql_fix_privilege_tables()) + if (run_mysqlcheck_upgrade(TRUE) || + run_mysqlcheck_views() || + run_sql_fix_privilege_tables() || + run_mysqlcheck_fixnames() || + run_mysqlcheck_upgrade(FALSE)) die("Upgrade failed" ); - if (!opt_systables_only && - (run_mysqlcheck_fixnames() || - verbose("Phase 4/5: Checking and upgrading tables") || - run_mysqlcheck_upgrade("--all-databases","--skip-database=mysql"))) - die("Upgrade failed" ); - - verbose("Phase 5/5: Running 'FLUSH PRIVILEGES'..."); + verbose("Phase %d/%d: Running 'FLUSH PRIVILEGES'", ++phase, phases_total); if (run_query("FLUSH PRIVILEGES", NULL, TRUE)) die("Upgrade failed" ); @@ -1044,6 +1122,8 @@ int main(int argc, char **argv) /* Create a file indicating upgrade has been performed */ create_mysql_upgrade_info_file(); + DBUG_ASSERT(phase == phases_total); + free_used_memory(); my_end(my_end_arg); exit(0); diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 88016d9563d..bc6b68c63d1 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2014, Oracle and/or its affiliates. - Copyright (c) 2010, 2014, Monty Program Ab. + Copyright (c) 2010, 2015, MariaDB 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 @@ -1249,6 +1249,9 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) static char **mask_password(int argc, char ***argv) { char **temp_argv; + if (!argc) + return NULL; + temp_argv= (char **)(my_malloc(sizeof(char *) * argc, MYF(MY_WME))); argc--; while (argc > 0) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 7c93e8d3ebd..7a54a693cb4 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -49,6 +49,8 @@ #include "mysqld.h" +#include <algorithm> + Rpl_filter *binlog_filter= 0; #define BIN_LOG_HEADER_SIZE 4 @@ -67,6 +69,7 @@ ulong server_id = 0; ulong bytes_sent = 0L, bytes_received = 0L; ulong mysqld_net_retry_count = 10L; ulong open_files_limit; +ulong opt_binlog_rows_event_max_size; uint test_flags = 0; static uint opt_protocol= 0; static FILE *result_file; @@ -1436,6 +1439,12 @@ that may lead to an endless loop.", "Used to reserve file descriptors for use by this program.", &open_files_limit, &open_files_limit, 0, GET_ULONG, REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0}, + {"binlog-row-event-max-size", 0, + "The maximum size of a row-based binary log event in bytes. Rows will be " + "grouped into events smaller than this size if possible. " + "This value must be a multiple of 256.", + &opt_binlog_rows_event_max_size, &opt_binlog_rows_event_max_size, 0, + GET_ULONG, REQUIRED_ARG, UINT_MAX, 256, ULONG_MAX, 0, 256, 0}, {"verify-binlog-checksum", 'c', "Verify checksum binlog events.", (uchar**) &opt_verify_binlog_checksum, (uchar**) &opt_verify_binlog_checksum, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 2f5ee4c82e6..ead4127dad6 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001, 2013, Oracle and/or its affiliates. - Copyright (c) 2010, 2013, Monty Program Ab. + Copyright (c) 2010, 2015, MariaDB 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 @@ -18,7 +18,7 @@ /* By Jani Tolonen, 2001-04-20, MySQL Development Team */ -#define CHECK_VERSION "2.7.3-MariaDB" +#define CHECK_VERSION "2.7.4-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_do_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; @@ -53,10 +54,21 @@ static char *opt_plugin_dir= 0, *opt_default_auth= 0; static int first_error = 0; static char *opt_skip_database; DYNAMIC_ARRAY tables4repair, tables4rebuild, alter_table_cmds; +DYNAMIC_ARRAY views4repair; static char *shared_memory_base_name=0; static uint opt_protocol=0; -enum operations { DO_CHECK=1, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE }; +enum operations { DO_CHECK=1, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_FIX_NAMES }; +const char *operation_name[]= +{ + "???", "check", "repair", "analyze", "optimize", "fix names" +}; + +typedef enum { DO_VIEWS_NO, DO_VIEWS_YES, DO_VIEWS_FROM_MYSQL } enum_do_views; +const char *do_views_opts[]= {"NO", "YES", "UPGRADE_FROM_MYSQL", NullS}; +TYPELIB do_views_typelib= { array_elements(do_views_opts) - 1, "", + do_views_opts, NULL }; +static ulong opt_do_views= DO_VIEWS_NO; static struct my_option my_long_options[] = { @@ -200,6 +212,14 @@ static struct my_option my_long_options[] = 0, 0, 0, GET_NO_ARG, 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}, + {"process-views", 0, + "Perform the requested operation (check or repair) on views. " + "One of: NO, YES (correct the checksum, if necessary, add the " + "mariadb-version field), UPGRADE_FROM_MYSQL (same as YES and toggle " + "the algorithm MERGE<->TEMPTABLE.", &opt_do_views, &opt_do_views, + &do_views_typelib, GET_ENUM, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"process-tables", 0, "Perform the requested operation on tables.", + &opt_do_tables, &opt_do_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} }; @@ -216,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, size_t 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); @@ -294,11 +314,11 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), what_to_do = DO_OPTIMIZE; break; case OPT_FIX_DB_NAMES: - what_to_do= DO_UPGRADE; + what_to_do= DO_FIX_NAMES; opt_databases= 1; break; case OPT_FIX_TABLE_NAMES: - what_to_do= DO_UPGRADE; + what_to_do= DO_FIX_NAMES; break; case 'p': if (argument == disabled_my_option) @@ -339,7 +359,9 @@ 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_MYSQL_PROTOCOL: opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, opt->name); @@ -348,7 +370,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), if (orig_what_to_do && (what_to_do != orig_what_to_do)) { - fprintf(stderr, "Error: %s doesn't support multiple contradicting commands.\n", + fprintf(stderr, "Error: %s doesn't support multiple contradicting commands.\n", my_progname); DBUG_RETURN(1); } @@ -370,6 +392,12 @@ 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_do_views && !opt_do_tables) + { + fprintf(stderr, "Error: Nothing to repair when both " + "--process-tables=NO and --process-views=NO\n"); + exit(1); + } if (!what_to_do) { size_t pnlen= strlen(my_progname); @@ -386,6 +414,13 @@ static int get_options(int *argc, char ***argv) what_to_do = DO_CHECK; } + if (opt_do_views && what_to_do != DO_REPAIR && what_to_do != DO_CHECK) + { + fprintf(stderr, "Error: %s doesn't support %s for views.\n", + my_progname, operation_name[what_to_do]); + exit(1); + } + /* If there's no --default-character-set option given with --fix-table-name or --fix-db-name set the default character set to "utf8". @@ -470,13 +505,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) +{ + char query[1024]; + MYSQL_RES *res; + MYSQL_FIELD *field; + int view; + DBUG_ENTER("is_view"); + + my_snprintf(query, sizeof(query), "SHOW CREATE TABLE %`s", table); + 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); + + 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)) DBUG_RETURN(1); - if (opt_all_in_1 && what_to_do != DO_UPGRADE) + if (opt_all_in_1 && what_to_do != DO_FIX_NAMES) { /* We need table list in form `a`, `b`, `c` @@ -487,6 +550,15 @@ static int process_selected_tables(char *db, char **table_names, int tables) size_t tot_length= 0; int i= 0; + if (opt_do_tables && opt_do_views) + { + fprintf(stderr, "Error: %s cannot process both tables and views " + "in one command (--process-tables=YES " + "--process-views=YES --all-in-1).\n", + my_progname); + DBUG_RETURN(1); + } + for (i = 0; i < tables; i++) tot_length+= fixed_name_length(*(table_names + i)) + 2; @@ -501,12 +573,20 @@ 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)); + handle_request_for_tables(table_names_comma_sep + 1, tot_length - 1, + opt_do_views != 0); 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); + if (view < 0) + continue; + handle_request_for_tables(table, table_len, (view == 1)); + } DBUG_RETURN(0); } /* process_selected_tables */ @@ -521,9 +601,6 @@ static uint fixed_name_length(const char *name) { if (*p == '`') extra_length++; - else if (*p == '.') - extra_length+= 2; - } DBUG_RETURN((uint) ((p - name) + extra_length)); } @@ -537,11 +614,6 @@ static char *fix_table_name(char *dest, char *src) for (; *src; src++) { switch (*src) { - case '.': /* add backticks around '.' */ - *dest++= '`'; - *dest++= '.'; - *dest++= '`'; - break; case '`': /* escape backtick character */ *dest++= '`'; /* fall through */ @@ -561,6 +633,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)) @@ -579,7 +652,7 @@ static int process_all_tables_in_db(char *database) num_columns= mysql_num_fields(res); - if (opt_all_in_1 && what_to_do != DO_UPGRADE) + if (opt_all_in_1 && what_to_do != DO_FIX_NAMES) { /* We need table list in form `a`, `b`, `c` @@ -590,8 +663,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_do_views) + tot_views_length+= fixed_name_length(row[0]) + 2; + else if (opt_do_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)))) @@ -599,32 +681,62 @@ 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_do_views) + continue; + views_end= fix_table_name(views_end, row[0]); + *views_end++= ','; + } + else + { + if (!opt_do_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 { while ((row = mysql_fetch_row(res))) { /* Skip views if we don't perform renaming. */ - if ((what_to_do != DO_UPGRADE) && (num_columns == 2) && (strcmp(row[1], "VIEW") == 0)) - continue; + if ((what_to_do != DO_FIX_NAMES) && (num_columns == 2) && (strcmp(row[1], "VIEW") == 0)) + { + if (!opt_do_views) + continue; + view= TRUE; + } + else + { + if (!opt_do_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); @@ -712,7 +824,7 @@ static int process_one_db(char *database) if (verbose) puts(database); - if (what_to_do == DO_UPGRADE) + if (what_to_do == DO_FIX_NAMES) { int rc= 0; if (opt_fix_db_names && !strncmp(database,"#mysql50#", 9)) @@ -751,39 +863,59 @@ static int disable_binlog() return run_query(stmt, 0); } -static int handle_request_for_tables(char *tables, uint length) +static int handle_request_for_tables(char *tables, size_t 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: op = "CHECK"; - if (opt_quick) end = strmov(end, " QUICK"); - if (opt_fast) end = strmov(end, " FAST"); - if (opt_medium_check) end = strmov(end, " MEDIUM"); /* Default */ - if (opt_extended) end = strmov(end, " EXTENDED"); - if (opt_check_only_changed) end = strmov(end, " CHANGED"); + if (view) + { + if (opt_fast || opt_check_only_changed) + DBUG_RETURN(0); + } + else + { + if (opt_quick) end = strmov(end, " QUICK"); + if (opt_fast) end = strmov(end, " FAST"); + if (opt_extended) end = strmov(end, " EXTENDED"); + if (opt_medium_check) end = strmov(end, " MEDIUM"); /* Default */ + if (opt_check_only_changed) end = strmov(end, " CHANGED"); + } if (opt_upgrade) end = strmov(end, " FOR UPGRADE"); break; case DO_REPAIR: - 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"); + op= opt_write_binlog ? "REPAIR" : "REPAIR NO_WRITE_TO_BINLOG"; + if (view) + { + if (opt_do_views == DO_VIEWS_FROM_MYSQL) end = strmov(end, " FROM MYSQL"); + } + else + { + if (opt_quick) end = strmov(end, " QUICK"); + if (opt_extended) end = strmov(end, " EXTENDED"); + if (opt_frm) end = strmov(end, " USE_FRM"); + } break; case DO_ANALYZE: + DBUG_ASSERT(!view); op= (opt_write_binlog) ? "ANALYZE" : "ANALYZE NO_WRITE_TO_BINLOG"; break; case DO_OPTIMIZE: + DBUG_ASSERT(!view); op= (opt_write_binlog) ? "OPTIMIZE" : "OPTIMIZE NO_WRITE_TO_BINLOG"; break; - case DO_UPGRADE: + case DO_FIX_NAMES: + DBUG_ASSERT(!view); DBUG_RETURN(fix_table_storage_name(tables)); } @@ -792,14 +924,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, MY_MIN((int) sizeof(table_name_buff)-1, (int) (ptr - org))); @@ -811,7 +944,7 @@ static int handle_request_for_tables(char *tables, uint length) puts(query); 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); DBerror(sock, message); my_free(query); DBUG_RETURN(1); @@ -836,13 +969,18 @@ static void print_result() { MYSQL_RES *res; MYSQL_ROW row; - char prev[(NAME_LEN+9)*2+2]; + char prev[(NAME_LEN+9)*3+2]; char prev_alter[MAX_ALTER_STR_SIZE]; + char *db_name; + uint length_of_db; uint i; my_bool found_error=0, table_rebuild=0; + DYNAMIC_ARRAY *array4repair= &tables4repair; DBUG_ENTER("print_result"); res = mysql_use_result(sock); + db_name= sock->db; + length_of_db= strlen(db_name); prev[0] = '\0'; prev_alter[0]= 0; @@ -866,11 +1004,18 @@ static void print_result() if (prev_alter[0]) insert_dynamic(&alter_table_cmds, (uchar*) prev_alter); else - insert_dynamic(&tables4rebuild, (uchar*) prev); + { + char *table_name= prev + (length_of_db+1); + insert_dynamic(&tables4rebuild, (uchar*) table_name); + } } else - insert_dynamic(&tables4repair, prev); + { + char *table_name= prev + (length_of_db+1); + insert_dynamic(array4repair, table_name); + } } + array4repair= &tables4repair; found_error=0; table_rebuild=0; prev_alter[0]= 0; @@ -886,8 +1031,11 @@ static void print_result() we have to run upgrade on it. In this case we write a nicer message than "Please do "REPAIR TABLE""... */ - if (!strcmp(row[2],"error") && strstr(row[3],"REPAIR TABLE")) + if (!strcmp(row[2],"error") && strstr(row[3],"REPAIR ")) + { printf("%-50s %s", row[0], "Needs upgrade"); + array4repair= strstr(row[3], "VIEW") ? &views4repair : &tables4repair; + } else printf("%s\n%-9s: %s", row[0], row[2], row[3]); if (opt_auto_repair && strcmp(row[2],"note")) @@ -910,10 +1058,16 @@ static void print_result() if (prev_alter[0]) insert_dynamic(&alter_table_cmds, prev_alter); else - insert_dynamic(&tables4rebuild, prev); + { + char *table_name= prev + (length_of_db+1); + insert_dynamic(&tables4rebuild, table_name); + } } else - insert_dynamic(&tables4repair, prev); + { + char *table_name= prev + (length_of_db+1); + insert_dynamic(array4repair, table_name); + } } mysql_free_result(res); DBUG_VOID_RETURN; @@ -1032,6 +1186,8 @@ int main(int argc, char **argv) if (opt_auto_repair && (my_init_dynamic_array(&tables4repair, sizeof(char)*(NAME_LEN*2+2),16, 64, MYF(0)) || + my_init_dynamic_array(&views4repair, sizeof(char)*(NAME_LEN*2+2),16, + 64, MYF(0)) || my_init_dynamic_array(&tables4rebuild, sizeof(char)*(NAME_LEN*2+2),16, 64, MYF(0)) || my_init_dynamic_array(&alter_table_cmds, MAX_ALTER_STR_SIZE, 0, 1, @@ -1056,12 +1212,19 @@ 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)); for (i = 0; i < alter_table_cmds.elements ; i++) run_query((char*) dynamic_array_ptr(&alter_table_cmds, i), 1); + if (!opt_silent && views4repair.elements) + puts("\nRepairing views"); + for (i = 0; i < views4repair.elements ; i++) + { + char *name= (char*) dynamic_array_ptr(&views4repair, i); + handle_request_for_tables(name, fixed_name_length(name), TRUE); + } } ret= MY_TEST(first_error); @@ -1069,8 +1232,10 @@ int main(int argc, char **argv) dbDisconnect(current_host); if (opt_auto_repair) { + delete_dynamic(&views4repair); delete_dynamic(&tables4repair); delete_dynamic(&tables4rebuild); + delete_dynamic(&alter_table_cmds); } end1: my_free(opt_password); diff --git a/client/mysqldump.c b/client/mysqldump.c index 3adbe87a8bb..e4683ab79c4 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -97,7 +97,7 @@ static ulong find_set(TYPELIB *lib, const char *x, uint length, static char *alloc_query_str(ulong size); static void field_escape(DYNAMIC_STRING* in, const char *from); -static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, +static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_no_data_med= 1, quick= 1, extended_insert= 1, lock_tables=1,ignore_errors=0,flush_logs=0,flush_privileges=0, opt_drop=1,opt_keywords=0,opt_lock=1,opt_compress=0, @@ -114,7 +114,6 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_slave_apply= 0, opt_include_master_host_port= 0, opt_events= 0, opt_comments_used= 0, - opt_galera_sst_mode= 0, opt_alltspcs=0, opt_notspcs= 0; static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0; static ulong opt_max_allowed_packet, opt_net_buffer_length; @@ -204,6 +203,8 @@ const char *compatible_mode_names[]= TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1, "", compatible_mode_names, NULL}; +#define MED_ENGINES "MRG_MyISAM, MRG_ISAM, CONNECT, OQGRAPH, SPIDER, VP, FEDERATED" + HASH ignore_table; static struct my_option my_long_options[] = @@ -351,14 +352,6 @@ static struct my_option my_long_options[] = {"force", 'f', "Continue even if we get an SQL error.", &ignore_errors, &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"galera-sst-mode", OPT_GALERA_SST_MODE, - "This mode should normally be used in mysqldump snapshot state transfer " - "(SST) in a Galera cluster. If enabled, mysqldump additionally dumps " - "commands to turn off binary logging and SET global gtid_binlog_state " - "with the current value. Note: RESET MASTER needs to be executed on the " - "server receiving the resulting dump.", - &opt_galera_sst_mode, &opt_galera_sst_mode, 0, GET_BOOL, NO_ARG, 0, 0, 0, - 0, 0, 0}, {"gtid", OPT_USE_GTID, "Used together with --master-data=1 or --dump-slave=1." "When enabled, the output from those options will set the GTID position " "instead of the binlog file and offset; the file/offset will appear only as " @@ -438,6 +431,9 @@ static struct my_option my_long_options[] = NO_ARG, 0, 0, 0, 0, 0, 0}, {"no-data", 'd', "No row information.", &opt_no_data, &opt_no_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"no-data-med", 0, "No row information for engines that " + "Manage External Data (" MED_ENGINES ").", &opt_no_data_med, + &opt_no_data_med, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"no-set-names", 'N', "Same as --skip-set-charset.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"opt", OPT_OPTIMIZE, @@ -4903,43 +4899,6 @@ static int dump_selected_tables(char *db, char **table_names, int tables) } /* dump_selected_tables */ -/** - Add the following statements to the generated dump: - a) SET @@session.sql_log_bin=OFF; - b) SET @@global.gtid_binlog_state='[N-N-N,...]' -*/ -static int wsrep_set_sst_cmds(MYSQL *mysql) { - MYSQL_RES *res; - MYSQL_ROW row; - - if (mysql_get_server_version(mysql) < 100005) { - /* @@gtid_binlog_state does not exist. */ - return 0; - } - - if (mysql_query_with_error_report(mysql, &res, "SELECT " - "@@global.gtid_binlog_state")) - return 1; - - if (mysql_num_rows(res) != 1) - /* No entry for @@global.gtid_binlog_state, nothing needs to be done. */ - return 0; - - if (!(row= mysql_fetch_row(res)) || !(char *)row[0]) - return 1; - - /* first, add a command to turn off binary logging, */ - fprintf(md_result_file, "SET @@session.sql_log_bin=OFF;\n"); - - /* followed by, a command to set global gtid_binlog_state. */ - fprintf(md_result_file, "SET @@global.gtid_binlog_state='%s';\n", - (char*)row[0]); - - mysql_free_result(res); - return 0; -} - - static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos, int have_mariadb_gtid, int use_gtid) { @@ -5452,12 +5411,12 @@ char check_if_ignore_table(const char *table_name, char *table_type) /* If these two types, we do want to skip dumping the table */ - if (!opt_no_data && - (!my_strcasecmp(&my_charset_latin1, table_type, "MRG_MyISAM") || - !strcmp(table_type,"MRG_ISAM") || - !strcmp(table_type,"CONNECT") || - !strcmp(table_type,"FEDERATED"))) - result= IGNORE_DATA; + if (!opt_no_data && opt_no_data_med) + { + const char *found= strstr(" " MED_ENGINES ",", table_type); + if (found && found[-1] == ' ' && found[strlen(table_type)] == ',') + result= IGNORE_DATA; + } } mysql_free_result(res); DBUG_RETURN(result); @@ -5936,9 +5895,6 @@ int main(int argc, char **argv) if (opt_slave_apply && add_stop_slave()) goto err; - if (opt_galera_sst_mode && wsrep_set_sst_cmds(mysql)) - goto err; - if (opt_master_data && do_show_master_status(mysql, consistent_binlog_pos, have_mariadb_gtid, opt_use_gtid)) goto err; diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 9b7a6e8fd19..e28d56e9187 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -839,6 +839,7 @@ static void handle_no_active_connection(struct st_command* command, #define EMB_END_CONNECTION 3 #define EMB_PREPARE_STMT 4 #define EMB_EXECUTE_STMT 5 +#define EMB_CLOSE_STMT 6 /* workaround for MySQL BUG#57491 */ #undef MY_WME @@ -887,6 +888,9 @@ pthread_handler_t connection_thread(void *arg) case EMB_EXECUTE_STMT: cn->result= mysql_stmt_execute(cn->stmt); break; + case EMB_CLOSE_STMT: + cn->result= mysql_stmt_close(cn->stmt); + break; default: DBUG_ASSERT(0); } @@ -984,6 +988,17 @@ static int do_stmt_execute(struct st_connection *cn) } +static int do_stmt_close(struct st_connection *cn) +{ + /* The cn->stmt is already set. */ + if (!cn->has_thread) + return mysql_stmt_close(cn->stmt); + signal_connection_thd(cn, EMB_CLOSE_STMT); + wait_query_thread_done(cn); + return cn->result; +} + + static void emb_close_connection(struct st_connection *cn) { if (!cn->has_thread) @@ -1019,6 +1034,7 @@ static void init_connection_thd(struct st_connection *cn) #define do_read_query_result(cn) mysql_read_query_result(cn->mysql) #define do_stmt_prepare(cn, q, q_len) mysql_stmt_prepare(cn->stmt, q, q_len) #define do_stmt_execute(cn) mysql_stmt_execute(cn->stmt) +#define do_stmt_close(cn) mysql_stmt_close(cn->stmt) #endif /*EMBEDDED_LIBRARY*/ @@ -1378,11 +1394,11 @@ void close_connections() DBUG_ENTER("close_connections"); for (--next_con; next_con >= connections; --next_con) { + if (next_con->stmt) + do_stmt_close(next_con); #ifdef EMBEDDED_LIBRARY emb_close_connection(next_con); #endif - if (next_con->stmt) - mysql_stmt_close(next_con->stmt); next_con->stmt= 0; mysql_close(next_con->mysql); next_con->mysql= 0; @@ -5635,7 +5651,11 @@ void do_close_connection(struct st_command *command) con->mysql->net.vio = 0; } } -#else +#endif /*!EMBEDDED_LIBRARY*/ + if (con->stmt) + do_stmt_close(con); + con->stmt= 0; +#ifdef EMBEDDED_LIBRARY /* As query could be still executed in a separate theread we need to check if the query's thread was finished and probably wait @@ -5643,9 +5663,6 @@ void do_close_connection(struct st_command *command) */ emb_close_connection(con); #endif /*EMBEDDED_LIBRARY*/ - if (con->stmt) - mysql_stmt_close(con->stmt); - con->stmt= 0; mysql_close(con->mysql); con->mysql= 0; @@ -5912,6 +5929,8 @@ void do_connect(struct st_command *command) my_bool con_ssl= 0, con_compress= 0; my_bool con_pipe= 0; my_bool con_shm __attribute__ ((unused))= 0; + int read_timeout= 0; + int write_timeout= 0; struct st_connection* con_slot; static DYNAMIC_STRING ds_connection_name; @@ -6008,6 +6027,16 @@ void do_connect(struct st_command *command) con_pipe= 1; else if (length == 3 && !strncmp(con_options, "SHM", 3)) con_shm= 1; + else if (strncasecmp(con_options, "read_timeout=", + sizeof("read_timeout=")-1) == 0) + { + read_timeout= atoi(con_options + sizeof("read_timeout=")-1); + } + else if (strncasecmp(con_options, "write_timeout=", + sizeof("write_timeout=")-1) == 0) + { + write_timeout= atoi(con_options + sizeof("write_timeout=")-1); + } else die("Illegal option to connect: %.*s", (int) (end - con_options), con_options); @@ -6080,6 +6109,18 @@ void do_connect(struct st_command *command) if (opt_protocol) mysql_options(con_slot->mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol); + if (read_timeout) + { + mysql_options(con_slot->mysql, MYSQL_OPT_READ_TIMEOUT, + (char*)&read_timeout); + } + + if (write_timeout) + { + mysql_options(con_slot->mysql, MYSQL_OPT_WRITE_TIMEOUT, + (char*)&write_timeout); + } + #ifdef HAVE_SMEM if (con_shm) { |