Merge 10.0.14 into 10.1

This commit is contained in:
Sergei Golubchik 2014-10-15 12:59:13 +02:00
commit f62c12b405
2115 changed files with 88123 additions and 80328 deletions

View file

@ -90,7 +90,7 @@ extern "C" {
#if defined(__WIN__)
#include <conio.h>
#else
#include <readline/readline.h>
#include <readline.h>
#define HAVE_READLINE
#define USE_POPEN
#endif

View file

@ -22,7 +22,7 @@
#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */
#define VER "1.3a"
#define VER "1.4"
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
@ -140,21 +140,21 @@ static struct my_option my_long_options[]=
#include <sslopt-longopts.h>
{"tmpdir", 't', "Directory for temporary files.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"upgrade-system-tables", 's', "Only upgrade the system tables "
"do not try to upgrade the data.",
{"upgrade-system-tables", 's', "Only upgrade the system tables in the mysql database. Tables in other databases are not checked or touched.",
&opt_systables_only, &opt_systables_only, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"user", 'u', "User for login if not current user.", &opt_user,
&opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"verbose", 'v', "Display more output about the process.",
{"verbose", 'v', "Display more output about the process; Using it twice will print connection argument; Using it 3 times will print out all CHECK, RENAME and ALTER TABLE during the check phase.",
&opt_not_used, &opt_not_used, 0, GET_BOOL, NO_ARG, 1, 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},
{"version-check", 'k', "Run this program only if its \'server version\' "
"matches the version of the server to which it's connecting, (enabled by "
"default); use --skip-version-check to avoid this check. Note: the \'server "
"version\' of the program is the version of the MySQL server with which it "
"was built/distributed.", &opt_version_check, &opt_version_check, 0,
{"version-check", 'k',
"Run this program only if its \'server version\' "
"matches the version of the server to which it's connecting. "
"Note: the \'server version\' of the program is the version of the MariaDB "
"server with which it was built/distributed.",
&opt_version_check, &opt_version_check, 0,
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
{"write-binlog", OPT_WRITE_BINLOG, "All commands including those, "
"issued by mysqlcheck, are written to the binary log.",
@ -206,12 +206,12 @@ static void die(const char *fmt, ...)
}
static void verbose(const char *fmt, ...)
static int verbose(const char *fmt, ...)
{
va_list args;
if (opt_silent)
return;
return 0;
/* Print the verbose message */
va_start(args, fmt);
@ -222,6 +222,7 @@ static void verbose(const char *fmt, ...)
fflush(stdout);
}
va_end(args);
return 0;
}
@ -370,6 +371,9 @@ static int run_command(char* cmd,
FILE *res_file;
int error;
if (opt_verbose >= 4)
puts(cmd);
if (!(res_file= popen(cmd, "r")))
die("popen(\"%s\", \"r\") failed", cmd);
@ -750,20 +754,21 @@ static void print_conn_args(const char *tool_name)
in the server using "mysqlcheck --check-upgrade .."
*/
static int run_mysqlcheck_upgrade(void)
static int run_mysqlcheck_upgrade(const char *arg1, const char *arg2)
{
verbose("Phase 2/3: Checking and upgrading tables");
print_conn_args("mysqlcheck");
return run_tool(mysqlcheck_path,
NULL, /* Send output from mysqlcheck directly to screen */
"--no-defaults",
ds_args.str,
"--check-upgrade",
"--all-databases",
"--auto-repair",
!opt_silent || opt_verbose ? "--verbose": "",
!opt_silent || opt_verbose >= 1 ? "--verbose" : "",
opt_verbose >= 2 ? "--verbose" : "",
opt_verbose >= 3 ? "--verbose" : "",
opt_silent ? "--silent": "",
opt_write_binlog ? "--write-binlog" : "--skip-write-binlog",
arg1, arg2,
"2>&1",
NULL);
}
@ -771,7 +776,7 @@ static int run_mysqlcheck_upgrade(void)
static int run_mysqlcheck_fixnames(void)
{
verbose("Phase 1/3: Fixing table and database names");
verbose("Phase 3/4: Fixing table and database names");
print_conn_args("mysqlcheck");
return run_tool(mysqlcheck_path,
NULL, /* Send output from mysqlcheck directly to screen */
@ -780,7 +785,9 @@ static int run_mysqlcheck_fixnames(void)
"--all-databases",
"--fix-db-names",
"--fix-table-names",
opt_verbose ? "--verbose": "",
opt_verbose >= 1 ? "--verbose" : "",
opt_verbose >= 2 ? "--verbose" : "",
opt_verbose >= 3 ? "--verbose" : "",
opt_silent ? "--silent": "",
opt_write_binlog ? "--write-binlog" : "--skip-write-binlog",
"2>&1",
@ -857,7 +864,6 @@ 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'...");
/*
Individual queries can not be executed independently by invoking
a forked mysql client, because the script uses session variables
@ -1004,16 +1010,12 @@ int main(int argc, char **argv)
/* Find mysql */
find_tool(mysql_path, IF_WIN("mysql.exe", "mysql"), self_name);
if (!opt_systables_only)
{
/* Find mysqlcheck */
find_tool(mysqlcheck_path, IF_WIN("mysqlcheck.exe", "mysqlcheck"), self_name);
}
else
{
if (!opt_silent)
printf("The --upgrade-system-tables option was used, databases won't be touched.\n");
}
/* Find mysqlcheck */
find_tool(mysqlcheck_path, IF_WIN("mysqlcheck.exe", "mysqlcheck"), self_name);
if (opt_systables_only && !opt_silent)
printf("The --upgrade-system-tables option was used, user tables won't be touched.\n");
/*
Read the mysql_upgrade_info file to check if mysql_upgrade
@ -1033,16 +1035,19 @@ 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_sql_fix_privilege_tables())
{
/*
The upgrade failed to complete in some way or another,
significant error message should have been printed to the screen
*/
verbose("Phase 1/4: Checking mysql database");
if (run_mysqlcheck_upgrade("--databases", "mysql"))
die("Upgrade failed" );
}
verbose("Phase 2/4: Running 'mysql_fix_privilege_tables'...");
if (run_sql_fix_privilege_tables())
die("Upgrade failed" );
if (!opt_systables_only &&
(run_mysqlcheck_fixnames() ||
verbose("Phase 4/4: Checking and upgrading tables") ||
run_mysqlcheck_upgrade("--all-databases","--skip-database=mysql")))
die("Upgrade failed" );
verbose("OK");
/* Create a file indicating upgrade has been performed */

View file

@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2012, Oracle and/or its affiliates.
Copyright (c) 2010, 2012, Monty Program Ab.
Copyright (c) 2000, 2014, Oracle and/or its affiliates.
Copyright (c) 2010, 2014, Monty Program Ab.
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
@ -71,6 +71,7 @@ extern "C" my_bool get_one_option(int optid, const struct my_option *opt,
char *argument);
static my_bool sql_connect(MYSQL *mysql, uint wait);
static int execute_commands(MYSQL *mysql,int argc, char **argv);
static char **mask_password(int argc, char ***argv);
static int drop_db(MYSQL *mysql,const char *db);
extern "C" sig_handler endprog(int signal_number);
static void nice_time(ulong sec,char *buff);
@ -306,9 +307,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
int main(int argc,char *argv[])
{
int error= 0;
int error= 0, temp_argc;
MYSQL mysql;
char **commands, **save_argv;
char **commands, **save_argv, **temp_argv;
MY_INIT(argv[0]);
mysql_init(&mysql);
@ -316,8 +317,12 @@ int main(int argc,char *argv[])
if ((error= load_defaults("my",load_default_groups,&argc,&argv)))
goto err1;
save_argv = argv; /* Save for free_defaults */
if ((error=handle_options(&argc, &argv, my_long_options, get_one_option)))
goto err2;
temp_argv= mask_password(argc, &argv);
temp_argc= argc;
if (debug_info_flag)
my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
if (debug_check_flag)
@ -328,7 +333,7 @@ int main(int argc,char *argv[])
usage();
exit(1);
}
commands = argv;
commands = temp_argv;
if (tty_password)
opt_password = get_tty_password(NullS);
@ -475,6 +480,13 @@ int main(int argc,char *argv[])
} /* got connection */
mysql_close(&mysql);
temp_argc--;
while(temp_argc >= 0)
{
my_free(temp_argv[temp_argc]);
temp_argc--;
}
my_free(temp_argv);
err2:
mysql_library_end();
my_free(opt_password);
@ -1213,6 +1225,47 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
return 0;
}
/**
@brief Masking the password if it is passed as command line argument.
@details It works in Linux and changes cmdline in ps and /proc/pid/cmdline,
but it won't work for history file of shell.
The command line arguments are copied to another array and the
password in the argv is masked. This function is called just after
"handle_options" because in "handle_options", the agrv pointers
are altered which makes freeing of dynamically allocated memory
difficult. The password masking is done before all other operations
in order to minimise the time frame of password visibility via cmdline.
@param argc command line options (count)
@param argv command line options (values)
@return temp_argv copy of argv
*/
static char **mask_password(int argc, char ***argv)
{
char **temp_argv;
temp_argv= (char **)(my_malloc(sizeof(char *) * argc, MYF(MY_WME)));
argc--;
while (argc > 0)
{
temp_argv[argc]= my_strdup((*argv)[argc], MYF(MY_FAE));
if (find_type((*argv)[argc - 1],&command_typelib, FIND_TYPE_BASIC) == ADMIN_PASSWORD ||
find_type((*argv)[argc - 1],&command_typelib, FIND_TYPE_BASIC) == ADMIN_OLD_PASSWORD)
{
char *start= (*argv)[argc];
while (*start)
*start++= 'x';
start= (*argv)[argc];
if (*start)
start[1]= 0; /* Cut length of argument */
}
argc--;
}
temp_argv[argc]= my_strdup((*argv)[argc], MYF(MY_FAE));
return(temp_argv);
}
static void print_version(void)
{

View file

@ -18,7 +18,7 @@
/* By Jani Tolonen, 2001-04-20, MySQL Development Team */
#define CHECK_VERSION "2.7.2-MariaDB"
#define CHECK_VERSION "2.7.3-MariaDB"
#include "client_priv.h"
#include <m_ctype.h>
@ -51,6 +51,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;
static char *opt_skip_database;
DYNAMIC_ARRAY tables4repair, tables4rebuild, alter_table_cmds;
static char *shared_memory_base_name=0;
static uint opt_protocol=0;
@ -178,6 +179,9 @@ static struct my_option my_long_options[] =
#endif
{"silent", 's', "Print only error messages.", &opt_silent,
&opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"skip_database", 0, "Don't process the database specified as argument",
&opt_skip_database, &opt_skip_database, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
{"socket", 'S', "The socket file to use for connection.",
&opt_mysql_unix_port, &opt_mysql_unix_port, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@ -192,8 +196,8 @@ static struct my_option my_long_options[] =
{"user", 'u', "User for login if not current user.", &current_user,
&current_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"verbose", 'v', "Print info about the various stages.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"verbose", 'v', "Print info about the various stages; Using it 3 times will print out all CHECK, RENAME and ALTER TABLE during the check phase.",
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},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
@ -246,6 +250,9 @@ static void usage(void)
puts("mysqlrepair: The default option will be -r");
puts("mysqlanalyze: The default option will be -a");
puts("mysqloptimize: The default option will be -o\n");
printf("Usage: %s [OPTIONS] database [tables]\n", my_progname);
printf("OR %s [OPTIONS] --databases DB1 [DB2 DB3...]\n",
my_progname);
puts("Please consult the MariaDB/MySQL knowledgebase at");
puts("http://kb.askmonty.org/v/mysqlcheck for latest information about");
puts("this program.");
@ -625,8 +632,10 @@ static int process_all_tables_in_db(char *database)
} /* process_all_tables_in_db */
static int run_query(const char *query)
static int run_query(const char *query, my_bool log_query)
{
if (verbose >=3 && log_query)
puts(query);
if (mysql_query(sock, query))
{
fprintf(stderr, "Failed to %s\n", query);
@ -646,7 +655,7 @@ static int fix_table_storage_name(const char *name)
if (strncmp(name, "#mysql50#", 9))
DBUG_RETURN(1);
sprintf(qbuf, "RENAME TABLE `%s` TO `%s`", name, name + 9);
rc= run_query(qbuf);
rc= run_query(qbuf, 1);
if (verbose)
printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
DBUG_RETURN(rc);
@ -661,7 +670,7 @@ static int fix_database_storage_name(const char *name)
if (strncmp(name, "#mysql50#", 9))
DBUG_RETURN(1);
sprintf(qbuf, "ALTER DATABASE `%s` UPGRADE DATA DIRECTORY NAME", name);
rc= run_query(qbuf);
rc= run_query(qbuf, 1);
if (verbose)
printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
DBUG_RETURN(rc);
@ -680,6 +689,8 @@ static int rebuild_table(char *name)
ptr= strmov(query, "ALTER TABLE ");
ptr= fix_table_name(ptr, name);
ptr= strxmov(ptr, " FORCE", NullS);
if (verbose >= 3)
puts(query);
if (mysql_real_query(sock, query, (uint)(ptr - query)))
{
fprintf(stderr, "Failed to %s\n", query);
@ -696,6 +707,9 @@ static int process_one_db(char *database)
{
DBUG_ENTER("process_one_db");
if (opt_skip_database && !strcmp(database, opt_skip_database))
DBUG_RETURN(0);
if (verbose)
puts(database);
if (what_to_do == DO_UPGRADE)
@ -735,7 +749,7 @@ static int use_db(char *database)
static int disable_binlog()
{
mysql_query(sock, "SET WSREP_ON=0"); /* ignore the error, if any */
return run_query("SET SQL_LOG_BIN=0");
return run_query("SET SQL_LOG_BIN=0", 0);
}
static int handle_request_for_tables(char *tables, uint length)
@ -794,6 +808,8 @@ static int handle_request_for_tables(char *tables, uint length)
ptr= strxmov(ptr, " ", options, NullS);
query_length= (uint) (ptr - query);
}
if (verbose >= 3)
puts(query);
if (mysql_real_query(sock, query, query_length))
{
sprintf(message, "when executing '%s TABLE ... %s'", op, options);
@ -1046,7 +1062,7 @@ 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));
run_query((char*) dynamic_array_ptr(&alter_table_cmds, i), 1);
}
ret= MY_TEST(first_error);

View file

@ -87,6 +87,9 @@
/* Chars needed to store LONGLONG, excluding trailing '\0'. */
#define LONGLONG_LEN 20
/* Max length GTID position that we will output. */
#define MAX_GTID_LENGTH 1024
static void add_load_option(DYNAMIC_STRING *str, const char *option,
const char *option_value);
static ulong find_set(TYPELIB *lib, const char *x, uint length,
@ -135,6 +138,7 @@ static ulong opt_compatible_mode= 0;
#define MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL 2
static uint opt_mysql_port= 0, opt_master_data;
static uint opt_slave_data;
static uint opt_use_gtid;
static uint my_end_arg;
static char * opt_mysql_unix_port=0;
static int first_error=0;
@ -355,6 +359,13 @@ static struct my_option my_long_options[] =
"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", 0, "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 "
"a comment. When disabled, the GTID position will still appear in the "
"output, but only commented.",
&opt_use_gtid, &opt_use_gtid, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
{"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"hex-blob", OPT_HEXBLOB, "Dump binary strings (BINARY, "
@ -1192,7 +1203,7 @@ check_consistent_binlog_pos(char *binlog_pos_file, char *binlog_pos_offset)
if (mysql_query_with_error_report(mysql, &res,
"SHOW STATUS LIKE 'binlog_snapshot_%'"))
return 1;
return 0;
found= 0;
while ((row= mysql_fetch_row(res)))
@ -1215,6 +1226,90 @@ check_consistent_binlog_pos(char *binlog_pos_file, char *binlog_pos_offset)
return (found == 2);
}
/*
Get the GTID position corresponding to a given old-style binlog position.
This uses BINLOG_GTID_POS(). The advantage is that the GTID position can
be obtained completely non-blocking in this way (without the need for
FLUSH TABLES WITH READ LOCK), as the old-style position can be obtained
with START TRANSACTION WITH CONSISTENT SNAPSHOT.
Returns 0 if ok, non-zero if error.
*/
static int
get_binlog_gtid_pos(char *binlog_pos_file, char *binlog_pos_offset,
char *out_gtid_pos)
{
DYNAMIC_STRING query;
MYSQL_RES *res;
MYSQL_ROW row;
int err;
char file_buf[FN_REFLEN*2+1], offset_buf[LONGLONG_LEN*2+1];
size_t len_pos_file= strlen(binlog_pos_file);
size_t len_pos_offset= strlen(binlog_pos_offset);
if (len_pos_file >= FN_REFLEN || len_pos_offset > LONGLONG_LEN)
return 0;
mysql_real_escape_string(mysql, file_buf, binlog_pos_file, len_pos_file);
mysql_real_escape_string(mysql, offset_buf, binlog_pos_offset, len_pos_offset);
init_dynamic_string_checked(&query, "SELECT BINLOG_GTID_POS('", 256, 1024);
dynstr_append_checked(&query, file_buf);
dynstr_append_checked(&query, "', '");
dynstr_append_checked(&query, offset_buf);
dynstr_append_checked(&query, "')");
err= mysql_query_with_error_report(mysql, &res, query.str);
dynstr_free(&query);
if (err)
return err;
err= 1;
if ((row= mysql_fetch_row(res)))
{
strmake(out_gtid_pos, row[0], MAX_GTID_LENGTH-1);
err= 0;
}
mysql_free_result(res);
return err;
}
/*
Get the GTID position on a master or slave.
The parameter MASTER is non-zero to get the position on a master
(@@gtid_binlog_pos) or zero for a slave (@@gtid_slave_pos).
This uses the @@gtid_binlog_pos or @@gtid_slave_pos, so requires FLUSH TABLES
WITH READ LOCK or similar to be consistent.
Returns 0 if ok, non-zero for error.
*/
static int
get_gtid_pos(char *out_gtid_pos, int master)
{
MYSQL_RES *res;
MYSQL_ROW row;
int found;
if (mysql_query_with_error_report(mysql, &res,
(master ?
"SELECT @@GLOBAL.gtid_binlog_pos" :
"SELECT @@GLOBAL.gtid_slave_pos")))
return 1;
found= 0;
if ((row= mysql_fetch_row(res)))
{
strmake(out_gtid_pos, row[0], MAX_GTID_LENGTH-1);
found++;
}
mysql_free_result(res);
return (found != 1);
}
static char *my_case_str(const char *str,
uint str_len,
const char *token,
@ -4850,12 +4945,15 @@ static int wsrep_set_sst_cmds(MYSQL *mysql) {
return 0;
}
static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos)
static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos,
int have_mariadb_gtid, int use_gtid)
{
MYSQL_ROW row;
MYSQL_RES *UNINIT_VAR(master);
char binlog_pos_file[FN_REFLEN];
char binlog_pos_offset[LONGLONG_LEN+1];
char gtid_pos[MAX_GTID_LENGTH];
char *file, *offset;
const char *comment_prefix=
(opt_master_data == MYSQL_OPT_MASTER_DATA_COMMENTED_SQL) ? "-- " : "";
@ -4866,6 +4964,9 @@ static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos)
return 1;
file= binlog_pos_file;
offset= binlog_pos_offset;
if (have_mariadb_gtid &&
get_binlog_gtid_pos(binlog_pos_file, binlog_pos_offset, gtid_pos))
return 1;
}
else
{
@ -4895,6 +4996,9 @@ static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos)
return 0;
}
}
if (have_mariadb_gtid && get_gtid_pos(gtid_pos, 1))
return 1;
}
/* SHOW MASTER STATUS reports file and position */
@ -4903,7 +5007,19 @@ static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos)
"recovery from\n--\n\n");
fprintf(md_result_file,
"%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
comment_prefix, file, offset);
(use_gtid ? "-- " : comment_prefix), file, offset);
if (have_mariadb_gtid)
{
print_comment(md_result_file, 0,
"\n--\n-- GTID to start replication from\n--\n\n");
if (use_gtid)
fprintf(md_result_file,
"%sCHANGE MASTER TO MASTER_USE_GTID=slave_pos;\n",
comment_prefix);
fprintf(md_result_file,
"%sSET GLOBAL gtid_slave_pos='%s';\n",
(!use_gtid ? "-- " : comment_prefix), gtid_pos);
}
check_io(md_result_file);
if (!consistent_binlog_pos)
@ -4973,12 +5089,16 @@ static int add_slave_statements(void)
return(0);
}
static int do_show_slave_status(MYSQL *mysql_con)
static int do_show_slave_status(MYSQL *mysql_con, int use_gtid,
int have_mariadb_gtid)
{
MYSQL_RES *UNINIT_VAR(slave);
MYSQL_ROW row;
const char *comment_prefix=
(opt_slave_data == MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : "";
const char *gtid_comment_prefix= (use_gtid ? comment_prefix : "-- ");
const char *nogtid_comment_prefix= (!use_gtid ? comment_prefix : "-- ");
int set_gtid_done= 0;
if (mysql_query_with_error_report(mysql_con, &slave,
multi_source ?
@ -4996,8 +5116,30 @@ static int do_show_slave_status(MYSQL *mysql_con)
while ((row= mysql_fetch_row(slave)))
{
if (multi_source && !set_gtid_done)
{
char gtid_pos[MAX_GTID_LENGTH];
if (have_mariadb_gtid && get_gtid_pos(gtid_pos, 0))
return 1;
if (opt_comments)
fprintf(md_result_file, "\n--\n-- Gtid position to start replication "
"from\n--\n\n");
fprintf(md_result_file, "%sSET GLOBAL gtid_slave_pos='%s';\n",
gtid_comment_prefix, gtid_pos);
set_gtid_done= 1;
}
if (row[9 + multi_source] && row[21 + multi_source])
{
if (use_gtid)
{
if (multi_source)
fprintf(md_result_file, "%sCHANGE MASTER '%.80s' TO "
"MASTER_USE_GTID=slave_pos;\n", gtid_comment_prefix, row[0]);
else
fprintf(md_result_file, "%sCHANGE MASTER TO "
"MASTER_USE_GTID=slave_pos;\n", gtid_comment_prefix);
}
/* SHOW MASTER STATUS reports file and position */
if (opt_comments)
fprintf(md_result_file,
@ -5006,9 +5148,9 @@ static int do_show_slave_status(MYSQL *mysql_con)
if (multi_source)
fprintf(md_result_file, "%sCHANGE MASTER '%.80s' TO ",
comment_prefix, row[0]);
nogtid_comment_prefix, row[0]);
else
fprintf(md_result_file, "%sCHANGE MASTER TO ", comment_prefix);
fprintf(md_result_file, "%sCHANGE MASTER TO ", nogtid_comment_prefix);
if (opt_include_master_host_port)
{
@ -5081,12 +5223,13 @@ static int do_flush_tables_read_lock(MYSQL *mysql_con)
FLUSH TABLES is to lower the probability of a stage where both mysqldump
and most client connections are stalled. Of course, if a second long
update starts between the two FLUSHes, we have that bad stall.
We use the LOCAL option, as we do not want the FLUSH TABLES replicated to
other servers.
*/
return
( mysql_query_with_error_report(mysql_con, 0,
((opt_master_data != 0) ?
"FLUSH /*!40101 LOCAL */ TABLES" :
"FLUSH TABLES")) ||
( mysql_query_with_error_report(mysql_con, 0,
"FLUSH /*!40101 LOCAL */ TABLES") ||
mysql_query_with_error_report(mysql_con, 0,
"FLUSH TABLES WITH READ LOCK") );
}
@ -5707,6 +5850,7 @@ int main(int argc, char **argv)
char bin_log_name[FN_REFLEN];
int exit_code;
int consistent_binlog_pos= 0;
int have_mariadb_gtid= 0;
MY_INIT(argv[0]);
sf_leaking_memory=1; /* don't report memory leaks on early exits */
@ -5747,7 +5891,10 @@ int main(int argc, char **argv)
/* Check if the server support multi source */
if (mysql_get_server_version(mysql) >= 100000)
{
multi_source= 2;
have_mariadb_gtid= 1;
}
if (opt_slave_data && do_stop_slave_sql(mysql))
goto err;
@ -5798,9 +5945,11 @@ int main(int argc, char **argv)
if (opt_galera_sst_mode && wsrep_set_sst_cmds(mysql))
goto err;
if (opt_master_data && do_show_master_status(mysql, consistent_binlog_pos))
if (opt_master_data && do_show_master_status(mysql, consistent_binlog_pos,
have_mariadb_gtid, opt_use_gtid))
goto err;
if (opt_slave_data && do_show_slave_status(mysql))
if (opt_slave_data && do_show_slave_status(mysql, opt_use_gtid,
have_mariadb_gtid))
goto err;
if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit! */
goto err;
@ -5817,19 +5966,36 @@ int main(int argc, char **argv)
dump_all_tablespaces();
dump_all_databases();
}
else if (argc > 1 && !opt_databases)
{
/* Only one database and selected table(s) */
if (!opt_alltspcs && !opt_notspcs)
dump_tablespaces_for_tables(*argv, (argv + 1), (argc -1));
dump_selected_tables(*argv, (argv + 1), (argc - 1));
}
else
{
/* One or more databases, all tables */
if (!opt_alltspcs && !opt_notspcs)
dump_tablespaces_for_databases(argv);
dump_databases(argv);
// Check all arguments meet length condition. Currently database and table
// names are limited to NAME_LEN bytes and stack-based buffers assumes
// that escaped name will be not longer than NAME_LEN*2 + 2 bytes long.
int argument;
for (argument= 0; argument < argc; argument++)
{
size_t argument_length= strlen(argv[argument]);
if (argument_length > NAME_LEN)
{
die(EX_CONSCHECK, "[ERROR] Argument '%s' is too long, it cannot be "
"name for any table or database.\n", argv[argument]);
}
}
if (argc > 1 && !opt_databases)
{
/* Only one database and selected table(s) */
if (!opt_alltspcs && !opt_notspcs)
dump_tablespaces_for_tables(*argv, (argv + 1), (argc - 1));
dump_selected_tables(*argv, (argv + 1), (argc - 1));
}
else
{
/* One or more databases, all tables */
if (!opt_alltspcs && !opt_notspcs)
dump_tablespaces_for_databases(argv);
dump_databases(argv);
}
}
/* add 'START SLAVE' to end of dump */

View file

@ -1796,8 +1796,8 @@ run_scheduler(stats *sptr, statement *stmts, uint concur, ulonglong limit)
pthread_mutex_lock(&sleeper_mutex);
master_wakeup= 0;
pthread_mutex_unlock(&sleeper_mutex);
pthread_cond_broadcast(&sleep_threshhold);
pthread_mutex_unlock(&sleeper_mutex);
gettimeofday(&start_time, NULL);

View file

@ -7577,6 +7577,7 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
{
uint count;
MYSQL_RES *warn_res;
DYNAMIC_STRING res;
DBUG_ENTER("append_warnings");
if (!(count= mysql_warning_count(mysql)))
@ -7596,11 +7597,18 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
die("Warning count is %u but didn't get any warnings",
count);
append_result(ds, warn_res);
init_dynamic_string(&res, "", 1024, 1024);
append_result(&res, warn_res);
mysql_free_result(warn_res);
DBUG_PRINT("warnings", ("%s", ds->str));
DBUG_PRINT("warnings", ("%s", res.str));
if (display_result_sorted)
dynstr_append_sorted(ds, &res, 0);
else
dynstr_append_mem(ds, res.str, res.length);
dynstr_free(&res);
DBUG_RETURN(count);
}
@ -8848,6 +8856,10 @@ int main(int argc, char **argv)
128, 0, 0, get_var_key, 0, var_free, MYF(0)))
die("Variable hash initialization failed");
{
char path_separator[]= { FN_LIBCHAR, 0 };
var_set_string("SYSTEM_PATH_SEPARATOR", path_separator);
}
var_set_string("MYSQL_SERVER_VERSION", MYSQL_SERVER_VERSION);
var_set_string("MYSQL_SYSTEM_TYPE", SYSTEM_TYPE);
var_set_string("MYSQL_MACHINE_TYPE", MACHINE_TYPE);
@ -9768,36 +9780,34 @@ struct st_regex
int reg_replace(char** buf_p, int* buf_len_p, char *pattern, char *replace,
char *string, int icase);
bool parse_re_part(char *start_re, char *end_re,
char **p, char *end, char **buf)
{
if (*start_re != *end_re)
{
switch ((*start_re= *(*p)++)) {
case '(': *end_re= ')'; break;
case '[': *end_re= ']'; break;
case '{': *end_re= '}'; break;
case '<': *end_re= '>'; break;
default: *end_re= *start_re;
}
}
while (*p < end && **p != *end_re)
{
if ((*p)[0] == '\\' && *p + 1 < end && (*p)[1] == *end_re)
(*p)++;
/*
Finds the next (non-escaped) '/' in the expression.
(If the character '/' is needed, it can be escaped using '\'.)
*/
*(*buf)++= *(*p)++;
}
*(*buf)++= 0;
(*p)++;
return *p > end;
}
#define PARSE_REGEX_ARG \
while (p < expr_end) \
{ \
char c= *p; \
if (c == '/') \
{ \
if (last_c == '\\') \
{ \
buf_p[-1]= '/'; \
} \
else \
{ \
*buf_p++ = 0; \
break; \
} \
} \
else \
*buf_p++ = c; \
\
last_c= c; \
p++; \
} \
\
/*
Initializes the regular substitution expression to be used in the
result output of test.
@ -9809,10 +9819,9 @@ struct st_replace_regex* init_replace_regex(char* expr)
{
struct st_replace_regex* res;
char* buf,*expr_end;
char* p;
char* p, start_re, end_re= 1;
char* buf_p;
uint expr_len= strlen(expr);
char last_c = 0;
struct st_regex reg;
/* my_malloc() will die on fail with MY_FAE */
@ -9830,44 +9839,32 @@ struct st_replace_regex* init_replace_regex(char* expr)
{
bzero(&reg,sizeof(reg));
/* find the start of the statement */
while (p < expr_end)
{
if (*p == '/')
break;
while (my_isspace(charset_info, *p) && p < expr_end)
p++;
}
if (p == expr_end || ++p == expr_end)
if (p >= expr_end)
{
if (res->regex_arr.elements)
break;
else
goto err;
}
/* we found the start */
start_re= 0;
reg.pattern= buf_p;
if (parse_re_part(&start_re, &end_re, &p, expr_end, &buf_p))
goto err;
/* Find first argument -- pattern string to be removed */
PARSE_REGEX_ARG
if (p == expr_end || ++p == expr_end)
goto err;
/* buf_p now points to the replacement pattern terminated with \0 */
reg.replace= buf_p;
/* Find second argument -- replace string to replace pattern */
PARSE_REGEX_ARG
if (p == expr_end)
goto err;
/* skip the ending '/' in the statement */
p++;
if (parse_re_part(&start_re, &end_re, &p, expr_end, &buf_p))
goto err;
/* Check if we should do matching case insensitive */
if (p < expr_end && *p == 'i')
{
p++;
reg.icase= 1;
}
/* done parsing the statement, now place it in regex_arr */
if (insert_dynamic(&res->regex_arr,(uchar*) &reg))