summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/CMakeLists.txt10
-rw-r--r--client/client_priv.h3
-rw-r--r--client/completion_hash.cc2
-rw-r--r--client/mysql.cc99
-rw-r--r--client/mysql_plugin.c5
-rw-r--r--client/mysql_upgrade.c119
-rw-r--r--client/mysqladmin.cc67
-rw-r--r--client/mysqlbinlog.cc106
-rw-r--r--client/mysqlcheck.c98
-rw-r--r--client/mysqldump.c589
-rw-r--r--client/mysqlimport.c13
-rw-r--r--client/mysqlshow.c15
-rw-r--r--client/mysqlslap.c40
-rw-r--r--client/mysqltest.cc326
14 files changed, 1059 insertions, 433 deletions
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index e3edacc351c..e4643ad9358 100644
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -15,16 +15,20 @@
INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/include
+ ${PCRE_INCLUDES}
+ ${CMAKE_SOURCE_DIR}/mysys_ssl
${ZLIB_INCLUDE_DIR}
${SSL_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/libmysql
- ${CMAKE_SOURCE_DIR}/regex
${CMAKE_SOURCE_DIR}/sql
${CMAKE_SOURCE_DIR}/strings
${MY_READLINE_INCLUDE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
+## We will need libeay32.dll and ssleay32.dll when running client executables.
+COPY_OPENSSL_DLLS(copy_openssl_client)
+
ADD_DEFINITIONS(${SSL_DEFINES})
MYSQL_ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc
${CMAKE_SOURCE_DIR}/sql/sql_string.cc)
@@ -36,7 +40,7 @@ ENDIF(UNIX)
MYSQL_ADD_EXECUTABLE(mysqltest mysqltest.cc COMPONENT Test)
SET_SOURCE_FILES_PROPERTIES(mysqltest.cc PROPERTIES COMPILE_FLAGS "-DTHREADS")
-TARGET_LINK_LIBRARIES(mysqltest mysqlclient regex)
+TARGET_LINK_LIBRARIES(mysqltest mysqlclient pcre pcreposix)
SET_TARGET_PROPERTIES(mysqltest PROPERTIES ENABLE_EXPORTS TRUE)
@@ -79,7 +83,7 @@ ENDIF(WIN32)
ADD_EXECUTABLE(async_example async_example.c)
TARGET_LINK_LIBRARIES(async_example mysqlclient)
-SET_TARGET_PROPERTIES (mysqlcheck mysqldump mysqlimport mysql_upgrade mysqlshow mysqlslap mysql_plugin
+SET_TARGET_PROPERTIES (mysqlcheck mysqldump mysqlimport mysql_upgrade mysqlshow mysqlslap mysql_plugin async_example
PROPERTIES HAS_CXX TRUE)
ADD_DEFINITIONS(-DHAVE_DLOPEN)
diff --git a/client/client_priv.h b/client/client_priv.h
index d89ca89c405..3905f323156 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -92,6 +92,9 @@ enum options_client
OPT_REWRITE_DB,
OPT_REPORT_PROGRESS,
OPT_SKIP_ANNOTATE_ROWS_EVENTS,
+ OPT_SSL_CRL, OPT_SSL_CRLPATH,
+ OPT_USE_GTID,
+ OPT_GALERA_SST_MODE,
OPT_MAX_CLIENT_OPTION /* should be always the last */
};
diff --git a/client/completion_hash.cc b/client/completion_hash.cc
index 9ffb2082c06..c170b69de2d 100644
--- a/client/completion_hash.cc
+++ b/client/completion_hash.cc
@@ -49,7 +49,7 @@ int completion_hash_init(HashTable *ht, uint nSize)
ht->initialized = 0;
return FAILURE;
}
- init_alloc_root(&ht->mem_root, 8192, 0);
+ init_alloc_root(&ht->mem_root, 8192, 0, MYF(0));
ht->pHashFunction = hashpjw;
ht->nTableSize = nSize;
ht->initialized = 1;
diff --git a/client/mysql.cc b/client/mysql.cc
index 9d255b55430..89f9a75ec11 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -612,7 +612,6 @@ static COMMANDS commands[] = {
{ "OLD_PASSWORD", 0, 0, 0, ""},
{ "ON", 0, 0, 0, ""},
{ "ONE", 0, 0, 0, ""},
- { "ONE_SHOT", 0, 0, 0, ""},
{ "OPEN", 0, 0, 0, ""},
{ "OPTIMIZE", 0, 0, 0, ""},
{ "OPTION", 0, 0, 0, ""},
@@ -922,6 +921,7 @@ static COMMANDS commands[] = {
{ "MAKE_SET", 0, 0, 0, ""},
{ "MAKEDATE", 0, 0, 0, ""},
{ "MAKETIME", 0, 0, 0, ""},
+ { "MASTER_GTID_WAIT", 0, 0, 0, ""},
{ "MASTER_POS_WAIT", 0, 0, 0, ""},
{ "MAX", 0, 0, 0, ""},
{ "MBRCONTAINS", 0, 0, 0, ""},
@@ -1182,12 +1182,9 @@ int main(int argc,char *argv[])
exit(1);
}
defaults_argv=argv;
- if (get_options(argc, (char **) argv))
- {
- free_defaults(defaults_argv);
- my_end(0);
- exit(1);
- }
+ if ((status.exit_status= get_options(argc, (char **) argv)))
+ mysql_end(-1);
+
if (status.batch && !status.line_buff &&
!(status.line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, stdin)))
{
@@ -1207,7 +1204,7 @@ int main(int argc,char *argv[])
}
glob_buffer.realloc(512);
completion_hash_init(&ht, 128);
- init_alloc_root(&hash_mem_root, 16384, 0);
+ init_alloc_root(&hash_mem_root, 16384, 0, MYF(0));
bzero((char*) &mysql, sizeof(mysql));
if (sql_connect(current_host,current_db,current_user,opt_password,
opt_silent))
@@ -1355,6 +1352,44 @@ sig_handler mysql_end(int sig)
exit(status.exit_status);
}
+/*
+ set connection-specific options and call mysql_real_connect
+*/
+static bool do_connect(MYSQL *mysql, const char *host, const char *user,
+ const char *password, const char *database, ulong flags)
+{
+ if (opt_secure_auth)
+ mysql_options(mysql, MYSQL_SECURE_AUTH, (char *) &opt_secure_auth);
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
+ if (opt_use_ssl)
+ {
+ mysql_ssl_set(mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
+ opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
+ mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
+ }
+ mysql_options(mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
+ (char*)&opt_ssl_verify_server_cert);
+#endif
+ if (opt_protocol)
+ mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+#ifdef HAVE_SMEM
+ if (shared_memory_base_name)
+ mysql_options(mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
+#endif
+ if (opt_plugin_dir && *opt_plugin_dir)
+ mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
+
+ if (opt_default_auth && *opt_default_auth)
+ mysql_options(mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
+
+ mysql_options(mysql, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
+ mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
+ "program_name", "mysql");
+ return mysql_real_connect(mysql, host, user, password, database,
+ opt_mysql_port, opt_mysql_unix_port, flags);
+}
+
/*
This function handles sigint calls
@@ -1376,8 +1411,7 @@ sig_handler handle_sigint(int sig)
}
kill_mysql= mysql_init(kill_mysql);
- if (!mysql_real_connect(kill_mysql,current_host, current_user, opt_password,
- "", opt_mysql_port, opt_mysql_unix_port,0))
+ if (!do_connect(kill_mysql,current_host, current_user, opt_password, "", 0))
{
tee_fprintf(stdout, "Ctrl-C -- sorry, cannot connect to server to kill query, giving up ...\n");
goto err;
@@ -1890,7 +1924,7 @@ static int get_options(int argc, char **argv)
opt_net_buffer_length= *mysql_params->p_net_buffer_length;
if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
- exit(ho_error);
+ return(ho_error);
*mysql_params->p_max_allowed_packet= opt_max_allowed_packet;
*mysql_params->p_net_buffer_length= opt_net_buffer_length;
@@ -2849,7 +2883,7 @@ You can turn off this feature to get a quicker startup with -A\n\n");
mysql_free_result(fields);
break;
}
- field_names[i][num_fields*2]= '\0';
+ field_names[i][num_fields*2]= NULL;
j=0;
while ((sql_field=mysql_fetch_field(fields)))
{
@@ -3330,7 +3364,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
end:
- /* Show warnings if any or error occured */
+ /* Show warnings if any or error occurred */
if (show_warnings == 1 && (warnings >= 1 || error))
print_warnings();
@@ -3522,9 +3556,9 @@ print_table_data(MYSQL_RES *result)
{
uint length= column_names ? field->name_length : 0;
if (quick)
- length=max(length,field->length);
+ length= MY_MAX(length,field->length);
else
- length=max(length,field->max_length);
+ length= MY_MAX(length,field->max_length);
if (length < 4 && !IS_NOT_NULL(field->flags))
length=4; // Room for "NULL"
field->max_length=length;
@@ -3545,8 +3579,8 @@ print_table_data(MYSQL_RES *result)
field->name,
field->name + name_length);
uint display_length= field->max_length + name_length - numcells;
- tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
- MAX_COLUMN_LENGTH),
+ tee_fprintf(PAGER, " %-*s |",(int) MY_MIN(display_length,
+ MAX_COLUMN_LENGTH),
field->name);
}
(void) tee_fputs("\n", PAGER);
@@ -3634,9 +3668,9 @@ static int get_field_disp_length(MYSQL_FIELD *field)
uint length= column_names ? field->name_length : 0;
if (quick)
- length= max(length, field->length);
+ length= MY_MAX(length, field->length);
else
- length= max(length, field->max_length);
+ length= MY_MAX(length, field->max_length);
if (length < 4 && !IS_NOT_NULL(field->flags))
length= 4; /* Room for "NULL" */
@@ -3652,6 +3686,7 @@ static int get_field_disp_length(MYSQL_FIELD *field)
@returns The max number of characters in any row of this result
*/
+
static int get_result_width(MYSQL_RES *result)
{
unsigned int len= 0;
@@ -4585,23 +4620,8 @@ sql_real_connect(char *host,char *database,char *user,char *password,
}
if (opt_compress)
mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
- if (opt_secure_auth)
- mysql_options(&mysql, MYSQL_SECURE_AUTH, (char *) &opt_secure_auth);
if (using_opt_local_infile)
mysql_options(&mysql,MYSQL_OPT_LOCAL_INFILE, (char*) &opt_local_infile);
-#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
- if (opt_use_ssl)
- mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
- opt_ssl_capath, opt_ssl_cipher);
- mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
- (char*)&opt_ssl_verify_server_cert);
-#endif
- if (opt_protocol)
- mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
-#ifdef HAVE_SMEM
- if (shared_memory_base_name)
- mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
-#endif
if (safe_updates)
{
char init_command[100];
@@ -4613,15 +4633,8 @@ sql_real_connect(char *host,char *database,char *user,char *password,
mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
- if (opt_plugin_dir && *opt_plugin_dir)
- mysql_options(&mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
-
- if (opt_default_auth && *opt_default_auth)
- mysql_options(&mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
-
- if (!mysql_real_connect(&mysql, host, user, password,
- database, opt_mysql_port, opt_mysql_unix_port,
- connect_flag | CLIENT_MULTI_STATEMENTS))
+ if (!do_connect(&mysql, host, user, password, database,
+ connect_flag | CLIENT_MULTI_STATEMENTS))
{
if (!silent ||
(mysql_errno(&mysql) != CR_CONN_HOST_ERROR &&
diff --git a/client/mysql_plugin.c b/client/mysql_plugin.c
index bc9969c9b66..ebf04c9a8c3 100644
--- a/client/mysql_plugin.c
+++ b/client/mysql_plugin.c
@@ -15,14 +15,11 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include <my_global.h>
#include <m_string.h>
#include <mysql.h>
#include <my_getopt.h>
#include <my_dir.h>
-#include <my_global.h>
-#include <stdio.h>
-#include <string.h>
-
#define SHOW_VERSION "1.0.0"
#define PRINT_VERSION do { printf("%s Ver %s Distrib %s\n", \
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index eaa10245a94..737f9c9c8d7 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -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>
@@ -36,8 +36,8 @@
# endif
#endif
-static int phase = 1;
-static int phases_total = 4;
+static int phase = 0;
+static int phases_total = 6;
static char mysql_path[FN_REFLEN];
static char mysqlcheck_path[FN_REFLEN];
@@ -47,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;
@@ -145,22 +147,22 @@ 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},
#define USER_OPT (array_elements(my_long_options) - 6)
{"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.",
@@ -381,6 +383,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);
@@ -605,7 +610,7 @@ static int extract_variable_from_show(DYNAMIC_STRING* ds, char* value)
if ((value_end= strchr(value_start, '\n')) == NULL)
return 1; /* Unexpected result */
- len= (size_t) min(FN_REFLEN, value_end-value_start);
+ len= (size_t) MY_MIN(FN_REFLEN, value_end-value_start);
strncpy(value, value_start, len);
value[len]= '\0';
return 0;
@@ -639,7 +644,7 @@ static int get_upgrade_info_file_name(char* name)
/*
Read the content of mysql_upgrade_info file and
compare the version number form file against
- version number wich mysql_upgrade was compiled for
+ version number which mysql_upgrade was compiled for
NOTE
This is an optimization to avoid running mysql_upgrade
@@ -743,26 +748,31 @@ 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(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)
+ if (opt_systables_only && !mysql_db_only)
{
- verbose("Phase %d/%d: Checking and upgrading tables... Skipped",
- phase++, phases_total);
+ verbose("Phase %d/%d: Checking and upgrading %s... Skipped",
+ ++phase, phases_total, what);
return 0;
}
- verbose("Phase %d/%d: Checking and upgrading tables", phase++, phases_total);
+ verbose("Phase %d/%d: Checking and upgrading %s", ++phase, phases_total, what);
print_conn_args("mysqlcheck");
retch= run_tool(mysqlcheck_path,
NULL, /* Send output from mysqlcheck directly to screen */
defaults_file,
"--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);
return retch;
@@ -793,18 +803,23 @@ static my_bool is_mysql()
static int run_mysqlcheck_views(void)
{
const char *upgrade_views="--process-views=YES";
- if (is_mysql())
+ 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);
+ 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);
+ verbose("Phase %d/%d: Fixing views... Skipped", ++phase, phases_total);
return 0;
}
else
- verbose("Phase %d/%d: Fixing views", phase++, phases_total);
+ verbose("Phase %d/%d: Fixing views", ++phase, phases_total);
print_conn_args("mysqlcheck");
return run_tool(mysqlcheck_path,
@@ -825,11 +840,11 @@ static int run_mysqlcheck_fixnames(void)
if (opt_systables_only)
{
verbose("Phase %d/%d: Fixing table and database names ... Skipped",
- phase++, phases_total);
+ ++phase, phases_total);
return 0;
}
verbose("Phase %d/%d: Fixing table and database names",
- phase++, phases_total);
+ ++phase, phases_total);
print_conn_args("mysqlcheck");
return run_tool(mysqlcheck_path,
NULL, /* Send output from mysqlcheck directly to screen */
@@ -837,7 +852,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",
@@ -850,6 +867,7 @@ static const char *expected_errors[]=
"ERROR 1060", /* Duplicate column name */
"ERROR 1061", /* Duplicate key name */
"ERROR 1054", /* Unknown column */
+ "ERROR 1290", /* RR_OPTION_PREVENTS_STATEMENT */
0
};
@@ -903,15 +921,35 @@ static void print_line(char* line)
static int run_sql_fix_privilege_tables(void)
{
int found_real_errors= 0;
+ const char **query_ptr;
+ DYNAMIC_STRING ds_script;
DYNAMIC_STRING ds_result;
DBUG_ENTER("run_sql_fix_privilege_tables");
+ if (init_dynamic_string(&ds_script, "", 65536, 1024))
+ die("Out of memory");
+
if (init_dynamic_string(&ds_result, "", 512, 512))
die("Out of memory");
verbose("Phase %d/%d: Running 'mysql_fix_privilege_tables'",
- phase++, phases_total);
- run_query(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
+ and prepared statements.
+ */
+ for ( query_ptr= &mysql_fix_privilege_tables[0];
+ *query_ptr != NULL;
+ query_ptr++
+ )
+ {
+ if (strcasecmp(*query_ptr, "flush privileges;\n"))
+ dynstr_append(&ds_script, *query_ptr);
+ }
+
+ run_query(ds_script.str,
&ds_result, /* Collect result */
TRUE);
@@ -939,6 +977,7 @@ static int run_sql_fix_privilege_tables(void)
}
dynstr_free(&ds_result);
+ dynstr_free(&ds_script);
DBUG_RETURN(found_real_errors);
}
@@ -1073,23 +1112,29 @@ 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"
*/
- if (run_mysqlcheck_views() || 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
- */
+ if (run_mysqlcheck_upgrade(TRUE) ||
+ run_mysqlcheck_views() ||
+ run_sql_fix_privilege_tables() ||
+ run_mysqlcheck_fixnames() ||
+ run_mysqlcheck_upgrade(FALSE))
die("Upgrade failed" );
- }
+
+ verbose("Phase %d/%d: Running 'FLUSH PRIVILEGES'", ++phase, phases_total);
+ if (run_query("FLUSH PRIVILEGES", NULL, TRUE))
+ die("Upgrade failed" );
+
verbose("OK");
/* Create a file indicating upgrade has been performed */
create_mysql_upgrade_info_file();
+ DBUG_ASSERT(phase == phases_total);
+
end:
free_used_memory();
my_end(my_end_arg);
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index e7c6410978d..56d2784a1f5 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, 2016, Monty Program Ab.
+ Copyright (c) 2010, 2016, 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
@@ -23,9 +23,10 @@
#include <sys/stat.h>
#include <mysql.h>
#include <sql_common.h>
-#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */
+#include <welcome_copyright_notice.h>
+#include <my_rnd.h>
-#define ADMIN_VERSION "9.0"
+#define ADMIN_VERSION "9.1"
#define MAX_MYSQL_VAR 512
#define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */
#define MAX_TRUNC_LENGTH 3
@@ -100,6 +101,7 @@ enum commands {
ADMIN_FLUSH_HOSTS, ADMIN_FLUSH_TABLES, ADMIN_PASSWORD,
ADMIN_PING, ADMIN_EXTENDED_STATUS, ADMIN_FLUSH_STATUS,
ADMIN_FLUSH_PRIVILEGES, ADMIN_START_SLAVE, ADMIN_STOP_SLAVE,
+ ADMIN_START_ALL_SLAVES, ADMIN_STOP_ALL_SLAVES,
ADMIN_FLUSH_THREADS, ADMIN_OLD_PASSWORD, ADMIN_FLUSH_SLOW_LOG,
ADMIN_FLUSH_TABLE_STATISTICS, ADMIN_FLUSH_INDEX_STATISTICS,
ADMIN_FLUSH_USER_STATISTICS, ADMIN_FLUSH_CLIENT_STATISTICS,
@@ -113,6 +115,7 @@ static const char *command_names[]= {
"flush-hosts", "flush-tables", "password",
"ping", "extended-status", "flush-status",
"flush-privileges", "start-slave", "stop-slave",
+ "start-all-slaves", "stop-all-slaves",
"flush-threads", "old-password", "flush-slow-log",
"flush-table-statistics", "flush-index-statistics",
"flush-user-statistics", "flush-client-statistics",
@@ -341,8 +344,12 @@ int main(int argc,char *argv[])
}
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
+ {
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(&mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
+ mysql_options(&mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
+ }
mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
(char*)&opt_ssl_verify_server_cert);
#endif
@@ -361,6 +368,9 @@ int main(int argc,char *argv[])
if (opt_default_auth && *opt_default_auth)
mysql_options(&mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
+ mysql_options(&mysql, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
+ mysql_options4(&mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
+ "program_name", "mysqladmin");
if (sql_connect(&mysql, option_wait))
{
/*
@@ -1118,26 +1128,67 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_START_SLAVE:
- if (mysql_query(mysql, "START SLAVE"))
+ case ADMIN_START_ALL_SLAVES:
+ {
+ my_bool many_slaves= 0;
+ const char *query= "START SLAVE";
+ if (command == ADMIN_START_ALL_SLAVES && mariadb_connection(mysql) &&
+ mysql_get_server_version(mysql) >= 100000)
+ {
+ query="START ALL SLAVES";
+ many_slaves= 1;
+ }
+
+ if (mysql_query(mysql, query))
{
my_printf_error(0, "Error starting slave: %s", error_flags,
mysql_error(mysql));
return -1;
}
+ else if (!many_slaves || mysql_warning_count(mysql) > 0)
+ {
+ if (!option_silent)
+ puts("Slave('s) started");
+ }
else
- puts("Slave started");
+ {
+ if (!option_silent)
+ puts("No slaves to start");
+ }
break;
+ }
case ADMIN_STOP_SLAVE:
- if (mysql_query(mysql, "STOP SLAVE"))
+ case ADMIN_STOP_ALL_SLAVES:
+ {
+ const char *query= "STOP SLAVE";
+ my_bool many_slaves= 0;
+
+ if (command == ADMIN_STOP_ALL_SLAVES && mariadb_connection(mysql) &&
+ mysql_get_server_version(mysql) >= 100000)
+ {
+ query="STOP ALL SLAVES";
+ many_slaves= 1;
+ }
+
+ if (mysql_query(mysql, query))
{
my_printf_error(0, "Error stopping slave: %s", error_flags,
mysql_error(mysql));
return -1;
}
+ else if (!many_slaves || mysql_warning_count(mysql) > 0)
+ {
+ /* We can't detect if there was any slaves to stop with STOP SLAVE */
+ if (many_slaves && !option_silent)
+ puts("Slave('s) stopped");
+ }
else
- puts("Slave stopped");
+ {
+ if (!option_silent)
+ puts("All slaves was already stopped");
+ }
break;
-
+ }
case ADMIN_PING:
mysql->reconnect=0; /* We want to know of reconnects */
if (!mysql_ping(mysql))
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 250dc609891..4be31421f9b 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -34,9 +34,11 @@
#define TABLE TABLE_CLIENT
#include "client_priv.h"
#include <my_time.h>
+#include <sslopt-vars.h>
/* That one is necessary for defines of OPTION_NO_FOREIGN_KEY_CHECKS etc */
#include "sql_priv.h"
#include "log_event.h"
+#include "compat56.h"
#include "sql_common.h"
#include "my_dir.h"
#include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE
@@ -48,6 +50,8 @@
#include "mysqld.h"
+#include <algorithm>
+
Rpl_filter *binlog_filter= 0;
#define BIN_LOG_HEADER_SIZE 4
@@ -277,8 +281,8 @@ public:
int init()
{
- return init_dynamic_array(&file_names, sizeof(File_name_record),
- 100, 100);
+ return my_init_dynamic_array(&file_names, sizeof(File_name_record),
+ 100, 100, MYF(0));
}
void init_by_dir_name(const char *dir)
@@ -1228,6 +1232,9 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
case WRITE_ROWS_EVENT:
case DELETE_ROWS_EVENT:
case UPDATE_ROWS_EVENT:
+ case WRITE_ROWS_EVENT_V1:
+ case UPDATE_ROWS_EVENT_V1:
+ case DELETE_ROWS_EVENT_V1:
{
Rows_log_event *e= (Rows_log_event*) ev;
if (print_row_event(print_event_info, ev, e->get_table_id(),
@@ -1386,6 +1393,7 @@ static struct my_option my_options[] =
{"socket", 'S', "The socket file to use for connection.",
&sock, &sock, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
0, 0},
+#include <sslopt-longopts.h>
{"start-datetime", OPT_START_DATETIME,
"Start reading the binlog at first event having a datetime equal or "
"posterior to the argument; the argument must be a date and time "
@@ -1527,6 +1535,8 @@ static void cleanup()
my_free(host);
my_free(user);
my_free(const_cast<char*>(dirname_for_local_load));
+ my_free(start_datetime_str);
+ my_free(stop_datetime_str);
delete binlog_filter;
delete glob_description_event;
@@ -1558,13 +1568,14 @@ the mysql command line client.\n\n");
static my_time_t convert_str_to_timestamp(const char* str)
{
- int was_cut;
+ MYSQL_TIME_STATUS status;
MYSQL_TIME l_time;
long dummy_my_timezone;
uint dummy_in_dst_time_gap;
+
/* We require a total specification (date AND time) */
- if (str_to_datetime(str, (uint) strlen(str), &l_time, 0, &was_cut) !=
- MYSQL_TIMESTAMP_DATETIME || was_cut)
+ if (str_to_datetime(str, (uint) strlen(str), &l_time, 0, &status) ||
+ l_time.time_type != MYSQL_TIMESTAMP_DATETIME || status.warnings)
{
error("Incorrect date and time argument: %s", str);
exit(1);
@@ -1590,6 +1601,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
DBUG_PUSH(argument ? argument : default_dbug_option);
break;
#endif
+#include <sslopt-case.h>
case 'd':
one_database = 1;
break;
@@ -1712,7 +1724,7 @@ static int parse_args(int *argc, char*** argv)
exit(ho_error);
if (debug_info_flag)
my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
- if (debug_check_flag)
+ else if (debug_check_flag)
my_end_arg= MY_CHECK_ERROR;
return 0;
}
@@ -1739,6 +1751,18 @@ static Exit_status safe_connect()
return ERROR_STOP;
}
+#ifdef HAVE_OPENSSL
+ if (opt_use_ssl)
+ {
+ mysql_ssl_set(mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
+ opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
+ mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
+ }
+ mysql_options(mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
+ (char*)&opt_ssl_verify_server_cert);
+#endif /*HAVE_OPENSSL*/
+
if (opt_plugindir && *opt_plugindir)
mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugindir);
@@ -1752,6 +1776,9 @@ static Exit_status safe_connect()
mysql_options(mysql, MYSQL_SHARED_MEMORY_BASE_NAME,
shared_memory_base_name);
#endif
+ mysql_options(mysql, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
+ mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
+ "program_name", "mysqlbinlog");
if (!mysql_real_connect(mysql, host, user, pass, 0, port, sock, 0))
{
error("Failed on connect: %s", mysql_error(mysql));
@@ -1815,7 +1842,7 @@ static Exit_status check_master_version()
{
MYSQL_RES* res = 0;
MYSQL_ROW row;
- const char* version;
+ uint version;
if (mysql_query(mysql, "SELECT VERSION()") ||
!(res = mysql_store_result(mysql)))
@@ -1831,7 +1858,7 @@ static Exit_status check_master_version()
goto err;
}
- if (!(version = row[0]))
+ if (!(version = atoi(row[0])))
{
error("Could not find server version: "
"Master reported NULL for the version.");
@@ -1849,15 +1876,29 @@ static Exit_status check_master_version()
"Master returned '%s'", mysql_error(mysql));
goto err;
}
+
+ /*
+ Announce our capabilities to the server, so it will send us all the events
+ that we know about.
+ */
+ if (mysql_query(mysql, "SET @mariadb_slave_capability="
+ STRINGIFY_ARG(MARIA_SLAVE_CAPABILITY_MINE)))
+ {
+ error("Could not inform master about capability. Master returned '%s'",
+ mysql_error(mysql));
+ goto err;
+ }
+
delete glob_description_event;
- switch (*version) {
- case '3':
+ switch (version) {
+ case 3:
glob_description_event= new Format_description_log_event(1);
break;
- case '4':
+ case 4:
glob_description_event= new Format_description_log_event(3);
break;
- case '5':
+ case 5:
+ case 10:
/*
The server is soon going to send us its Format_description log
event, unless it is a 5.0 server with 3.23 or 4.0 binlogs.
@@ -1869,7 +1910,7 @@ static Exit_status check_master_version()
default:
glob_description_event= NULL;
error("Could not find server version: "
- "Master reported unrecognized MySQL version '%s'.", version);
+ "Master reported unrecognized MySQL version '%s'.", row[0]);
goto err;
}
if (!glob_description_event || !glob_description_event->is_valid())
@@ -2020,6 +2061,7 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info,
if ((rev->ident_len != logname_len) ||
memcmp(rev->new_log_ident, logname, logname_len))
{
+ delete ev;
DBUG_RETURN(OK_CONTINUE);
}
/*
@@ -2028,6 +2070,7 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info,
log. If we are running with to_last_remote_log, we print it,
because it serves as a useful marker between binlogs then.
*/
+ delete ev;
continue;
}
len= 1; // fake Rotate, so don't increment old_off
@@ -2058,7 +2101,9 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info,
Exit_status retval;
if ((file= load_processor.prepare_new_file_for_old_format(le,fname)) < 0)
+ {
DBUG_RETURN(ERROR_STOP);
+ }
retval= process_event(print_event_info, ev, old_off, logname);
if (retval != OK_CONTINUE)
@@ -2338,7 +2383,7 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info,
my_off_t length,tmp;
for (length= start_position_mot ; length > 0 ; length-=tmp)
{
- tmp=min(length,sizeof(buff));
+ tmp= MY_MIN(length,sizeof(buff));
if (my_b_read(file, buff, (uint) tmp))
{
error("Failed reading from file.");
@@ -2422,27 +2467,27 @@ int main(int argc, char** argv)
my_init_time(); // for time functions
tzset(); // set tzname
- init_alloc_root(&s_mem_root, 16384, 0);
+ init_alloc_root(&s_mem_root, 16384, 0, MYF(0));
if (load_defaults("my", load_groups, &argc, &argv))
exit(1);
+ defaults_argv= argv;
+
if (!(binlog_filter= new Rpl_filter))
{
error("Failed to create Rpl_filter");
- exit(1);
+ goto err;
}
- defaults_argv= argv;
parse_args(&argc, (char***)&argv);
if (!argc || opt_version)
{
if (!argc)
usage();
- cleanup();
- free_defaults(defaults_argv);
- my_end(my_end_arg);
- exit(!opt_version);
+ if (!opt_version)
+ retval= ERROR_STOP;
+ goto err;
}
if (opt_base64_output_mode == BASE64_OUTPUT_UNSPEC)
@@ -2462,12 +2507,18 @@ int main(int argc, char** argv)
if (!dirname_for_local_load)
{
if (init_tmpdir(&tmpdir, 0))
- exit(1);
+ {
+ retval= ERROR_STOP;
+ goto err;
+ }
dirname_for_local_load= my_strdup(my_tmpdir(&tmpdir), MY_WME);
}
if (load_processor.init())
- exit(1);
+ {
+ retval= ERROR_STOP;
+ goto err;
+ }
if (dirname_for_local_load)
load_processor.init_by_dir_name(dirname_for_local_load);
else
@@ -2537,12 +2588,20 @@ int main(int argc, char** argv)
free_defaults(defaults_argv);
my_free_open_file_info();
load_processor.destroy();
+ mysql_server_end();
/* We cannot free DBUG, it is used in global destructors after exit(). */
my_end(my_end_arg | MY_DONT_FREE_DBUG);
exit(retval == ERROR_STOP ? 1 : 0);
/* Keep compilers happy. */
DBUG_RETURN(retval == ERROR_STOP ? 1 : 0);
+
+err:
+ cleanup();
+ free_defaults(defaults_argv);
+ my_end(my_end_arg);
+ exit(retval == ERROR_STOP ? 1 : 0);
+ DBUG_RETURN(retval == ERROR_STOP ? 1 : 0);
}
@@ -2567,3 +2626,4 @@ void *sql_alloc(size_t size)
#include "sql_string.cc"
#include "sql_list.cc"
#include "rpl_filter.cc"
+#include "compat56.cc"
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index a07fc773726..0c34ef35966 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2001, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2001, 2013, Oracle and/or its affiliates.
Copyright (c) 2010, 2016, MariaDB
This program is free software; you can redistribute it and/or modify
@@ -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.4-MariaDB"
#include "client_priv.h"
#include <m_ctype.h>
@@ -43,7 +43,7 @@ static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 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_do_tables= 1;
+ opt_persistent_all= 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;
@@ -52,6 +52,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;
DYNAMIC_ARRAY views4repair;
static char *shared_memory_base_name=0;
@@ -159,6 +160,10 @@ static struct my_option my_long_options[] =
{"password", 'p',
"Password to use when connecting to server. If password is not given, it's solicited on the tty.",
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"persistent", 'Z',
+ "When using ANALYZE TABLE use the PERSISTENT FOR ALL option.",
+ &opt_persistent_all, &opt_persistent_all, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
#ifdef __WIN__
{"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -190,6 +195,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},
@@ -204,8 +212,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},
{"process-views", 0,
@@ -266,8 +274,11 @@ 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");
- puts("Please consult the MariaDB/MySQL knowledgebase at");
- puts("http://kb.askmonty.org/v/mysqlcheck for latest information about");
+ 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 Knowledge Base at");
+ puts("https://mariadb.com/kb/en/mysqlcheck for latest information about");
puts("this program.");
print_defaults("my", load_default_groups);
puts("");
@@ -732,8 +743,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);
@@ -755,7 +768,7 @@ static int fix_table_storage_name(const char *name)
my_snprintf(qbuf, sizeof(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);
@@ -771,7 +784,7 @@ static int fix_database_storage_name(const char *name)
DBUG_RETURN(1);
my_snprintf(qbuf, sizeof(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);
@@ -788,12 +801,16 @@ static int rebuild_table(char *name)
if (!query)
DBUG_RETURN(1);
ptr= strxmov(query, "ALTER TABLE ", name, " FORCE", NullS);
+ if (verbose >= 3)
+ puts(query);
if (mysql_real_query(sock, query, (ulong)(ptr - query)))
{
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" : "FIXED");
my_free(query);
DBUG_RETURN(rc);
}
@@ -802,6 +819,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_FIX_NAMES)
@@ -840,7 +860,7 @@ static int use_db(char *database)
static int disable_binlog()
{
const char *stmt= "SET SQL_LOG_BIN=0";
- return run_query(stmt);
+ return run_query(stmt, 0);
}
static int handle_request_for_tables(char *tables, size_t length,
@@ -890,6 +910,7 @@ static int handle_request_for_tables(char *tables, size_t length,
case DO_ANALYZE:
DBUG_ASSERT(!view);
op= (opt_write_binlog) ? "ANALYZE" : "ANALYZE NO_WRITE_TO_BINLOG";
+ if (opt_persistent_all) end = strmov(end, " PERSISTENT FOR ALL");
break;
case DO_OPTIMIZE:
DBUG_ASSERT(!view);
@@ -917,12 +938,14 @@ static int handle_request_for_tables(char *tables, size_t length,
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)));
+ strmake(table_name_buff, org, MY_MIN((int) sizeof(table_name_buff)-1,
+ (int) (ptr - org)));
table_name= table_name_buff;
ptr= strxmov(ptr, " ", options, NullS);
query_length= (size_t) (ptr - query);
}
+ if (verbose >= 3)
+ puts(query);
if (mysql_real_query(sock, query, query_length))
{
sprintf(message, "when executing '%s%s... %s'", op, tab_view, options);
@@ -1019,31 +1042,9 @@ static void print_result()
printf("%s\n%-9s: %s", row[0], row[2], row[3]);
if (opt_auto_repair && strcmp(row[2],"note"))
{
- const char *alter_txt= strstr(row[3], "ALTER TABLE");
found_error=1;
- if (alter_txt)
- {
+ if (opt_auto_repair && strstr(row[3], "ALTER TABLE") != NULL)
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
- {
- strncpy(prev_alter, alter_txt, MAX_ALTER_STR_SIZE-1);
- prev_alter[MAX_ALTER_STR_SIZE-1]= 0;
- }
- }
- }
}
}
else
@@ -1057,7 +1058,7 @@ static void print_result()
if (table_rebuild)
{
if (prev_alter[0])
- insert_dynamic(&alter_table_cmds, (uchar*) prev_alter);
+ insert_dynamic(&alter_table_cmds, prev_alter);
else
insert_table_name(&tables4rebuild, prev, length_of_db);
}
@@ -1081,8 +1082,12 @@ static int dbConnect(char *host, char *user, char *passwd)
mysql_options(&mysql_connection, MYSQL_OPT_COMPRESS, NullS);
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
+ {
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(&mysql_connection, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
+ mysql_options(&mysql_connection, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
+ }
#endif
if (opt_protocol)
mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
@@ -1096,6 +1101,9 @@ static int dbConnect(char *host, char *user, char *passwd)
mysql_options(&mysql_connection, MYSQL_DEFAULT_AUTH, opt_default_auth);
mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset);
+ mysql_options(&mysql_connection, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
+ mysql_options4(&mysql_connection, MYSQL_OPT_CONNECT_ATTR_ADD,
+ "program_name", "mysqlcheck");
if (!(sock = mysql_real_connect(&mysql_connection, host, user, passwd,
NULL, opt_mysql_port, opt_mysql_unix_port, 0)))
{
@@ -1172,10 +1180,14 @@ 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(&views4repair, 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)))
+ (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,
+ MYF(0))))
goto end;
if (opt_alldbs)
@@ -1201,7 +1213,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);
if (!opt_silent && views4repair.elements)
puts("\nRepairing views");
for (i = 0; i < views4repair.elements ; i++)
@@ -1210,7 +1222,7 @@ int main(int argc, char **argv)
handle_request_for_tables(name, fixed_name_length(name), TRUE, TRUE);
}
}
- ret= test(first_error);
+ ret= MY_TEST(first_error);
end:
dbDisconnect(current_host);
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 16b39b77cf1..153761ed510 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -39,7 +39,7 @@
** 10 Jun 2003: SET NAMES and --no-set-names by Alexander Barkov
*/
-#define DUMP_VERSION "10.14"
+#define DUMP_VERSION "10.15"
#include <my_global.h>
#include <my_sys.h>
@@ -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, size_t length,
@@ -94,7 +97,7 @@ static ulong find_set(TYPELIB *lib, const char *x, size_t 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,
@@ -134,10 +137,23 @@ 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;
+/*
+ multi_source is 0 if old server or 2 if server that support multi source
+ This is choosen this was as multi_source has 2 extra columns first in
+ SHOW ALL SLAVES STATUS.
+*/
+static uint multi_source= 0;
static DYNAMIC_STRING extended_row;
+static DYNAMIC_STRING dynamic_where;
+static MYSQL_RES *get_table_name_result= NULL;
+static MEM_ROOT glob_root;
+static MYSQL_RES *routine_res, *routine_list_res;
+
+
#include <sslopt-vars.h>
FILE *md_result_file= 0;
FILE *stderror_file=0;
@@ -193,6 +209,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[] =
@@ -226,8 +244,8 @@ static struct my_option my_long_options[] =
&opt_slave_apply, &opt_slave_apply, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
{"character-sets-dir", OPT_CHARSETS_DIR,
- "Directory for character set files.", (char**) &charsets_dir,
- (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ "Directory for character set files.", &charsets_dir,
+ &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"comments", 'i', "Write additional information.",
&opt_comments, &opt_comments, 0, GET_BOOL, NO_ARG,
1, 0, 0, 0, 0, 0},
@@ -264,8 +282,8 @@ static struct my_option my_long_options[] =
{"debug", '#', "This is a non-debug version. Catch this and exit.",
0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0},
#else
- {"debug", '#', "Output debug log.", (char**) &default_dbug_option,
- (char**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug", '#', "Output debug log.", &default_dbug_option,
+ &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
&debug_check_flag, &debug_check_flag, 0,
@@ -340,6 +358,13 @@ 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},
+ {"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 "
+ "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, "
@@ -412,6 +437,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,
@@ -866,7 +894,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
&err_ptr, &err_len);
if (err_len)
{
- strmake(buff, err_ptr, min(sizeof(buff) - 1, err_len));
+ strmake(buff, err_ptr, MY_MIN(sizeof(buff) - 1, err_len));
fprintf(stderr, "Invalid mode to --compatible: %s\n", buff);
exit(1);
}
@@ -1192,6 +1220,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,
size_t str_len,
const char *token,
@@ -1477,14 +1589,26 @@ static void free_resources()
{
if (md_result_file && md_result_file != stdout)
my_fclose(md_result_file, MYF(0));
+ if (get_table_name_result)
+ mysql_free_result(get_table_name_result);
+ if (routine_res)
+ mysql_free_result(routine_res);
+ if (routine_list_res)
+ mysql_free_result(routine_list_res);
+ if (mysql)
+ {
+ mysql_close(mysql);
+ mysql= 0;
+ }
+ my_free(order_by);
my_free(opt_password);
my_free(current_host);
+ free_root(&glob_root, MYF(0));
if (my_hash_inited(&ignore_table))
my_hash_free(&ignore_table);
- if (extended_insert)
- dynstr_free(&extended_row);
- if (insert_pat_inited)
- dynstr_free(&insert_pat);
+ dynstr_free(&extended_row);
+ dynstr_free(&dynamic_where);
+ dynstr_free(&insert_pat);
if (defaults_argv)
free_defaults(defaults_argv);
mysql_library_end();
@@ -1501,8 +1625,6 @@ static void maybe_exit(int error)
ignore_errors= 1; /* don't want to recurse, if something fails below */
if (opt_slave_data)
do_start_slave_sql(mysql);
- if (mysql)
- mysql_close(mysql);
free_resources();
exit(error);
}
@@ -1523,8 +1645,12 @@ static int connect_to_db(char *host, char *user,char *passwd)
mysql_options(&mysql_connection,MYSQL_OPT_COMPRESS,NullS);
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
+ {
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(&mysql_connection, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
+ mysql_options(&mysql_connection, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
+ }
mysql_options(&mysql_connection,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
(char*)&opt_ssl_verify_server_cert);
#endif
@@ -1542,6 +1668,9 @@ static int connect_to_db(char *host, char *user,char *passwd)
if (opt_default_auth && *opt_default_auth)
mysql_options(&mysql_connection, MYSQL_DEFAULT_AUTH, opt_default_auth);
+ mysql_options(&mysql_connection, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
+ mysql_options4(&mysql_connection, MYSQL_OPT_CONNECT_ATTR_ADD,
+ "program_name", "mysqldump");
mysql= &mysql_connection; /* So we can mysql_close() it properly */
if (!mysql_real_connect(&mysql_connection,host,user,passwd,
NULL,opt_mysql_port,opt_mysql_unix_port, 0))
@@ -1588,6 +1717,7 @@ static void dbDisconnect(char *host)
{
verbose_msg("-- Disconnecting from %s...\n", host ? host : "localhost");
mysql_close(mysql);
+ mysql= 0;
} /* dbDisconnect */
@@ -2294,7 +2424,6 @@ static uint dump_routines_for_db(char *db)
char *routine_name;
int i;
FILE *sql_file= md_result_file;
- MYSQL_RES *routine_res, *routine_list_res;
MYSQL_ROW row, routine_list_row;
char db_cl_name[MY_CS_NAME_SIZE];
@@ -2349,7 +2478,11 @@ static uint dump_routines_for_db(char *db)
routine_type[i], routine_name);
if (mysql_query_with_error_report(mysql, &routine_res, query_buff))
+ {
+ mysql_free_result(routine_list_res);
+ routine_list_res= 0;
DBUG_RETURN(1);
+ }
while ((row= mysql_fetch_row(routine_res)))
{
@@ -2367,7 +2500,8 @@ static uint dump_routines_for_db(char *db)
print_comment(sql_file, 1,
"-- does %s have permissions on mysql.proc?\n\n",
current_user);
- maybe_die(EX_MYSQLERR,"%s has insufficent privileges to %s!", current_user, query_buff);
+ maybe_die(EX_MYSQLERR,"%s has insufficent privileges to %s!",
+ current_user, query_buff);
}
else if (strlen(row[2]))
{
@@ -2390,6 +2524,9 @@ static uint dump_routines_for_db(char *db)
if (switch_db_collation(sql_file, db, ";",
db_cl_name, row[5], &db_cl_altered))
{
+ mysql_free_result(routine_res);
+ mysql_free_result(routine_list_res);
+ routine_res= routine_list_res= 0;
DBUG_RETURN(1);
}
@@ -2435,17 +2572,24 @@ static uint dump_routines_for_db(char *db)
if (db_cl_altered)
{
if (restore_db_collation(sql_file, db, ";", db_cl_name))
+ {
+ mysql_free_result(routine_res);
+ mysql_free_result(routine_list_res);
+ routine_res= routine_list_res= 0;
DBUG_RETURN(1);
+ }
}
}
}
} /* end of routine printing */
mysql_free_result(routine_res);
+ routine_res= 0;
} /* end of list of routines */
}
mysql_free_result(routine_list_res);
+ routine_list_res= 0;
} /* end of for i (0 .. 1) */
if (opt_xml)
@@ -2567,13 +2711,20 @@ static uint get_table_structure(char *table, char *db, char *table_type,
if (switch_character_set_results(mysql, "binary") ||
mysql_query_with_error_report(mysql, &result, buff) ||
switch_character_set_results(mysql, default_charset))
+ {
+ my_free(order_by);
+ order_by= 0;
DBUG_RETURN(0);
+ }
if (path)
{
if (!(sql_file= open_sql_file_for_table(table, O_WRONLY)))
+ {
+ my_free(order_by);
+ order_by= 0;
DBUG_RETURN(0);
-
+ }
write_header(sql_file, db);
}
@@ -3143,10 +3294,6 @@ static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs,
continue;
}
- query_str= cover_definer_clause(row[2], strlen(row[2]),
- C_STRING_WITH_LEN("50017"),
- C_STRING_WITH_LEN("50003"),
- C_STRING_WITH_LEN(" TRIGGER"));
if (switch_db_collation(sql_file, db_name, ";",
db_cl_name, row[5], &db_cl_altered))
DBUG_RETURN(TRUE);
@@ -3158,12 +3305,18 @@ static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs,
switch_sql_mode(sql_file, ";", row[1]);
+ query_str= cover_definer_clause(row[2], strlen(row[2]),
+ C_STRING_WITH_LEN("50017"),
+ C_STRING_WITH_LEN("50003"),
+ C_STRING_WITH_LEN(" TRIGGER"));
fprintf(sql_file,
"DELIMITER ;;\n"
"/*!50003 %s */;;\n"
"DELIMITER ;\n",
(const char *) (query_str != NULL ? query_str : row[2]));
+ my_free(query_str);
+
restore_sql_mode(sql_file, ";");
restore_cs_variables(sql_file, ";");
@@ -3172,8 +3325,6 @@ static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs,
if (restore_db_collation(sql_file, db_name, ";", db_cl_name))
DBUG_RETURN(TRUE);
}
-
- my_free(query_str);
}
DBUG_RETURN(FALSE);
@@ -3264,13 +3415,14 @@ static int dump_triggers_for_table(char *table_name, char *db_name)
{
MYSQL_RES *show_create_trigger_rs= mysql_store_result(mysql);
- if (!show_create_trigger_rs ||
- dump_trigger(sql_file, show_create_trigger_rs, db_name, db_cl_name))
- goto done;
-
+ int error= (!show_create_trigger_rs ||
+ dump_trigger(sql_file, show_create_trigger_rs, db_name,
+ db_cl_name));
mysql_free_result(show_create_trigger_rs);
+ if (error)
+ goto done;
}
-
+
}
if (opt_xml)
@@ -3517,12 +3669,14 @@ static void dump_table(char *table, char *db)
{
dynstr_append_checked(&query_string, " ORDER BY ");
dynstr_append_checked(&query_string, order_by);
+ my_free(order_by);
+ order_by= 0;
}
if (mysql_real_query(mysql, query_string.str, query_string.length))
{
- DB_error(mysql, "when executing 'SELECT INTO OUTFILE'");
dynstr_free(&query_string);
+ DB_error(mysql, "when executing 'SELECT INTO OUTFILE'");
DBUG_VOID_RETURN;
}
}
@@ -3548,6 +3702,8 @@ static void dump_table(char *table, char *db)
dynstr_append_checked(&query_string, " ORDER BY ");
dynstr_append_checked(&query_string, order_by);
+ my_free(order_by);
+ order_by= 0;
}
if (!opt_xml && !opt_compact)
@@ -3557,6 +3713,7 @@ static void dump_table(char *table, char *db)
}
if (mysql_query_with_error_report(mysql, 0, query_string.str))
{
+ dynstr_free(&query_string);
DB_error(mysql, "when retrieving data from server");
goto err;
}
@@ -3566,6 +3723,7 @@ static void dump_table(char *table, char *db)
res=mysql_store_result(mysql);
if (!res)
{
+ dynstr_free(&query_string);
DB_error(mysql, "when retrieving data from server");
goto err;
}
@@ -3881,23 +4039,22 @@ err:
static char *getTableName(int reset)
{
- static MYSQL_RES *res= NULL;
- MYSQL_ROW row;
+ MYSQL_ROW row;
- if (!res)
+ if (!get_table_name_result)
{
- if (!(res= mysql_list_tables(mysql,NullS)))
+ if (!(get_table_name_result= mysql_list_tables(mysql,NullS)))
return(NULL);
}
- if ((row= mysql_fetch_row(res)))
+ if ((row= mysql_fetch_row(get_table_name_result)))
return((char*) row[0]);
if (reset)
- mysql_data_seek(res,0); /* We want to read again */
+ mysql_data_seek(get_table_name_result,0); /* We want to read again */
else
{
- mysql_free_result(res);
- res= NULL;
+ mysql_free_result(get_table_name_result);
+ get_table_name_result= NULL;
}
return(NULL);
} /* getTableName */
@@ -3914,46 +4071,44 @@ static int dump_all_tablespaces()
static int dump_tablespaces_for_tables(char *db, char **table_names, int tables)
{
- DYNAMIC_STRING where;
int r;
int i;
char name_buff[NAME_LEN*2+3];
mysql_real_escape_string(mysql, name_buff, db, (ulong)strlen(db));
- init_dynamic_string_checked(&where, " AND TABLESPACE_NAME IN ("
+ init_dynamic_string_checked(&dynamic_where, " AND TABLESPACE_NAME IN ("
"SELECT DISTINCT TABLESPACE_NAME FROM"
" INFORMATION_SCHEMA.PARTITIONS"
" WHERE"
" TABLE_SCHEMA='", 256, 1024);
- dynstr_append_checked(&where, name_buff);
- dynstr_append_checked(&where, "' AND TABLE_NAME IN (");
+ dynstr_append_checked(&dynamic_where, name_buff);
+ dynstr_append_checked(&dynamic_where, "' AND TABLE_NAME IN (");
for (i=0 ; i<tables ; i++)
{
mysql_real_escape_string(mysql, name_buff,
table_names[i], (ulong)strlen(table_names[i]));
- dynstr_append_checked(&where, "'");
- dynstr_append_checked(&where, name_buff);
- dynstr_append_checked(&where, "',");
+ dynstr_append_checked(&dynamic_where, "'");
+ dynstr_append_checked(&dynamic_where, name_buff);
+ dynstr_append_checked(&dynamic_where, "',");
}
- dynstr_trunc(&where, 1);
- dynstr_append_checked(&where,"))");
+ dynstr_trunc(&dynamic_where, 1);
+ dynstr_append_checked(&dynamic_where,"))");
- DBUG_PRINT("info",("Dump TS for Tables where: %s",where.str));
- r= dump_tablespaces(where.str);
- dynstr_free(&where);
+ DBUG_PRINT("info",("Dump TS for Tables where: %s",dynamic_where.str));
+ r= dump_tablespaces(dynamic_where.str);
+ dynstr_free(&dynamic_where);
return r;
}
static int dump_tablespaces_for_databases(char** databases)
{
- DYNAMIC_STRING where;
int r;
int i;
- init_dynamic_string_checked(&where, " AND TABLESPACE_NAME IN ("
+ init_dynamic_string_checked(&dynamic_where, " AND TABLESPACE_NAME IN ("
"SELECT DISTINCT TABLESPACE_NAME FROM"
" INFORMATION_SCHEMA.PARTITIONS"
" WHERE"
@@ -3964,16 +4119,16 @@ static int dump_tablespaces_for_databases(char** databases)
char db_name_buff[NAME_LEN*2+3];
mysql_real_escape_string(mysql, db_name_buff,
databases[i], (ulong)strlen(databases[i]));
- dynstr_append_checked(&where, "'");
- dynstr_append_checked(&where, db_name_buff);
- dynstr_append_checked(&where, "',");
+ dynstr_append_checked(&dynamic_where, "'");
+ dynstr_append_checked(&dynamic_where, db_name_buff);
+ dynstr_append_checked(&dynamic_where, "',");
}
- dynstr_trunc(&where, 1);
- dynstr_append_checked(&where,"))");
+ dynstr_trunc(&dynamic_where, 1);
+ dynstr_append_checked(&dynamic_where,"))");
- DBUG_PRINT("info",("Dump TS for DBs where: %s",where.str));
- r= dump_tablespaces(where.str);
- dynstr_free(&where);
+ DBUG_PRINT("info",("Dump TS for DBs where: %s",dynamic_where.str));
+ r= dump_tablespaces(dynamic_where.str);
+ dynstr_free(&dynamic_where);
return r;
}
@@ -4381,9 +4536,12 @@ static int dump_all_tables_in_db(char *database)
}
}
if (numrows && mysql_real_query(mysql, query.str, query.length-1))
+ {
+ dynstr_free(&query);
DB_error(mysql, "when using LOCK TABLES");
- /* We shall continue here, if --force was given */
- dynstr_free(&query);
+ /* We shall continue here, if --force was given */
+ }
+ dynstr_free(&query); /* Safe to call twice */
}
if (flush_logs)
{
@@ -4393,6 +4551,14 @@ static int dump_all_tables_in_db(char *database)
else
verbose_msg("-- dump_all_tables_in_db : logs flushed successfully!\n");
}
+ if (opt_single_transaction && mysql_get_server_version(mysql) >= 50500)
+ {
+ verbose_msg("-- Setting savepoint...\n");
+ if (mysql_query_with_error_report(mysql, 0, "SAVEPOINT sp"))
+ {
+ DBUG_RETURN(1);
+ }
+ }
while ((table= getTableName(0)))
{
char *end= strmov(afterdot, table);
@@ -4410,6 +4576,23 @@ static int dump_all_tables_in_db(char *database)
maybe_exit(EX_MYSQLERR);
}
}
+
+ /**
+ ROLLBACK TO SAVEPOINT in --single-transaction mode to release metadata
+ lock on table which was already dumped. This allows to avoid blocking
+ concurrent DDL on this table without sacrificing correctness, as we
+ won't access table second time and dumps created by --single-transaction
+ mode have validity point at the start of transaction anyway.
+ Note that this doesn't make --single-transaction mode with concurrent
+ DDL safe in general case. It just improves situation for people for whom
+ it might be working.
+ */
+ if (opt_single_transaction && mysql_get_server_version(mysql) >= 50500)
+ {
+ verbose_msg("-- Rolling back to savepoint sp...\n");
+ if (mysql_query_with_error_report(mysql, 0, "ROLLBACK TO SAVEPOINT sp"))
+ maybe_exit(EX_MYSQLERR);
+ }
}
else
{
@@ -4432,6 +4615,14 @@ static int dump_all_tables_in_db(char *database)
}
}
}
+
+ if (opt_single_transaction && mysql_get_server_version(mysql) >= 50500)
+ {
+ verbose_msg("-- Releasing savepoint...\n");
+ if (mysql_query_with_error_report(mysql, 0, "RELEASE SAVEPOINT sp"))
+ DBUG_RETURN(1);
+ }
+
if (opt_events && mysql_get_server_version(mysql) >= 50106)
{
DBUG_PRINT("info", ("Dumping events for database %s", database));
@@ -4601,22 +4792,22 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
{
char table_buff[NAME_LEN*2+3];
DYNAMIC_STRING lock_tables_query;
- MEM_ROOT root;
char **dump_tables, **pos, **end;
DBUG_ENTER("dump_selected_tables");
if (init_dumping(db, init_dumping_tables))
DBUG_RETURN(1);
- init_alloc_root(&root, 8192, 0);
- if (!(dump_tables= pos= (char**) alloc_root(&root, tables * sizeof(char *))))
+ init_alloc_root(&glob_root, 8192, 0, MYF(0));
+ if (!(dump_tables= pos= (char**) alloc_root(&glob_root,
+ tables * sizeof(char *))))
die(EX_EOM, "alloc_root failure.");
init_dynamic_string_checked(&lock_tables_query, "LOCK TABLES ", 256, 1024);
for (; tables > 0 ; tables-- , table_names++)
{
/* the table name passed on commandline may be wrong case */
- if ((*pos= get_actual_table_name(*table_names, &root)))
+ if ((*pos= get_actual_table_name(*table_names, &glob_root)))
{
/* Add found table name to lock_tables_query */
if (lock_tables)
@@ -4631,7 +4822,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
if (!ignore_errors)
{
dynstr_free(&lock_tables_query);
- free_root(&root, MYF(0));
+ free_root(&glob_root, MYF(0));
}
maybe_die(EX_ILLEGAL_TABLE, "Couldn't find table: \"%s\"", *table_names);
/* We shall countinue here, if --force was given */
@@ -4652,7 +4843,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
if (!ignore_errors)
{
dynstr_free(&lock_tables_query);
- free_root(&root, MYF(0));
+ free_root(&glob_root, MYF(0));
}
DB_error(mysql, "when doing LOCK TABLES");
/* We shall countinue here, if --force was given */
@@ -4664,7 +4855,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
if (mysql_refresh(mysql, REFRESH_LOG))
{
if (!ignore_errors)
- free_root(&root, MYF(0));
+ free_root(&glob_root, MYF(0));
DB_error(mysql, "when doing refresh");
}
/* We shall countinue here, if --force was given */
@@ -4674,6 +4865,16 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
if (opt_xml)
print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NullS);
+ if (opt_single_transaction && mysql_get_server_version(mysql) >= 50500)
+ {
+ verbose_msg("-- Setting savepoint...\n");
+ if (mysql_query_with_error_report(mysql, 0, "SAVEPOINT sp"))
+ {
+ free_root(&glob_root, MYF(0));
+ DBUG_RETURN(1);
+ }
+ }
+
/* Dump each selected table */
for (pos= dump_tables; pos < end; pos++)
{
@@ -4686,9 +4887,42 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
{
if (path)
my_fclose(md_result_file, MYF(MY_WME));
+ if (!ignore_errors)
+ free_root(&glob_root, MYF(0));
maybe_exit(EX_MYSQLERR);
}
}
+
+ /**
+ ROLLBACK TO SAVEPOINT in --single-transaction mode to release metadata
+ lock on table which was already dumped. This allows to avoid blocking
+ concurrent DDL on this table without sacrificing correctness, as we
+ won't access table second time and dumps created by --single-transaction
+ mode have validity point at the start of transaction anyway.
+ Note that this doesn't make --single-transaction mode with concurrent
+ DDL safe in general case. It just improves situation for people for whom
+ it might be working.
+ */
+ if (opt_single_transaction && mysql_get_server_version(mysql) >= 50500)
+ {
+ verbose_msg("-- Rolling back to savepoint sp...\n");
+ if (mysql_query_with_error_report(mysql, 0, "ROLLBACK TO SAVEPOINT sp"))
+ {
+ if (!ignore_errors)
+ free_root(&glob_root, MYF(0));
+ maybe_exit(EX_MYSQLERR);
+ }
+ }
+ }
+
+ if (opt_single_transaction && mysql_get_server_version(mysql) >= 50500)
+ {
+ verbose_msg("-- Releasing savepoint...\n");
+ if (mysql_query_with_error_report(mysql, 0, "RELEASE SAVEPOINT sp"))
+ {
+ free_root(&glob_root, MYF(0));
+ DBUG_RETURN(1);
+ }
}
/* Dump each selected view */
@@ -4708,9 +4942,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
DBUG_PRINT("info", ("Dumping routines for database %s", db));
dump_routines_for_db(db);
}
- free_root(&root, MYF(0));
- my_free(order_by);
- order_by= 0;
+ free_root(&glob_root, MYF(0));
if (opt_xml)
{
fputs("</database>\n", md_result_file);
@@ -4722,12 +4954,14 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
} /* dump_selected_tables */
-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) ? "-- " : "";
@@ -4738,10 +4972,14 @@ 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
{
- if (mysql_query_with_error_report(mysql_con, &master, "SHOW MASTER STATUS"))
+ if (mysql_query_with_error_report(mysql_con, &master,
+ "SHOW MASTER STATUS"))
return 1;
row= mysql_fetch_row(master);
@@ -4766,6 +5004,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 */
@@ -4774,7 +5015,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)
@@ -4786,29 +5039,37 @@ static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos)
static int do_stop_slave_sql(MYSQL *mysql_con)
{
MYSQL_RES *slave;
- /* We need to check if the slave sql is running in the first place */
- if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
+ MYSQL_ROW row;
+
+ if (mysql_query_with_error_report(mysql_con, &slave,
+ multi_source ?
+ "SHOW ALL SLAVES STATUS" :
+ "SHOW SLAVE STATUS"))
return(1);
- else
+
+ /* Loop over all slaves */
+ while ((row= mysql_fetch_row(slave)))
{
- MYSQL_ROW row= mysql_fetch_row(slave);
- if (row && row[11])
+ if (row[11 + multi_source])
{
/* if SLAVE SQL is not running, we don't stop it */
- if (!strcmp(row[11],"No"))
+ if (strcmp(row[11 + multi_source], "No"))
{
- mysql_free_result(slave);
- /* Silently assume that they don't have the slave running */
- return(0);
+ char query[160];
+ if (multi_source)
+ sprintf(query, "STOP SLAVE '%.80s' SQL_THREAD", row[0]);
+ else
+ strmov(query, "STOP SLAVE SQL_THREAD");
+
+ if (mysql_query_with_error_report(mysql_con, 0, query))
+ {
+ mysql_free_result(slave);
+ return 1;
+ }
}
}
}
mysql_free_result(slave);
-
- /* now, stop slave if running */
- if (mysql_query_with_error_report(mysql_con, 0, "STOP SLAVE SQL_THREAD"))
- return(1);
-
return(0);
}
@@ -4817,7 +5078,10 @@ static int add_stop_slave(void)
if (opt_comments)
fprintf(md_result_file,
"\n--\n-- stop slave statement to make a recovery dump)\n--\n\n");
- fprintf(md_result_file, "STOP SLAVE;\n");
+ if (multi_source)
+ fprintf(md_result_file, "STOP ALL SLAVES;\n");
+ else
+ fprintf(md_result_file, "STOP SLAVE;\n");
return(0);
}
@@ -4826,16 +5090,28 @@ static int add_slave_statements(void)
if (opt_comments)
fprintf(md_result_file,
"\n--\n-- start slave statement to make a recovery dump)\n--\n\n");
- fprintf(md_result_file, "START SLAVE;\n");
+ if (multi_source)
+ fprintf(md_result_file, "START ALL SLAVES;\n");
+ else
+ fprintf(md_result_file, "START SLAVE;\n");
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 *slave= 0;
+ MYSQL_RES *UNINIT_VAR(slave);
+ MYSQL_ROW row;
const char *comment_prefix=
(opt_slave_data == MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : "";
- if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
+ 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 ?
+ "SHOW ALL SLAVES STATUS" :
+ "SHOW SLAVE STATUS"))
{
if (!ignore_errors)
{
@@ -4845,65 +5121,103 @@ static int do_show_slave_status(MYSQL *mysql_con)
mysql_free_result(slave);
return 1;
}
- else
+
+ while ((row= mysql_fetch_row(slave)))
{
- MYSQL_ROW row= mysql_fetch_row(slave);
- if (row && row[9] && row[21])
+ 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,
"\n--\n-- Position to start replication or point-in-time "
"recovery from (the master of this slave)\n--\n\n");
- fprintf(md_result_file, "%sCHANGE MASTER TO ", comment_prefix);
-
+ if (multi_source)
+ fprintf(md_result_file, "%sCHANGE MASTER '%.80s' TO ",
+ nogtid_comment_prefix, row[0]);
+ else
+ fprintf(md_result_file, "%sCHANGE MASTER TO ", nogtid_comment_prefix);
+
if (opt_include_master_host_port)
{
- if (row[1])
- fprintf(md_result_file, "MASTER_HOST='%s', ", row[1]);
+ if (row[1 + multi_source])
+ fprintf(md_result_file, "MASTER_HOST='%s', ", row[1 + multi_source]);
if (row[3])
- fprintf(md_result_file, "MASTER_PORT=%s, ", row[3]);
+ fprintf(md_result_file, "MASTER_PORT=%s, ", row[3 + multi_source]);
}
fprintf(md_result_file,
- "MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", row[9], row[21]);
+ "MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
+ row[9 + multi_source], row[21 + multi_source]);
check_io(md_result_file);
}
- mysql_free_result(slave);
}
+ mysql_free_result(slave);
return 0;
}
static int do_start_slave_sql(MYSQL *mysql_con)
{
MYSQL_RES *slave;
+ MYSQL_ROW row;
+ int error= 0;
+ DBUG_ENTER("do_start_slave_sql");
+
/* We need to check if the slave sql is stopped in the first place */
- if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
- return(1);
- else
+ if (mysql_query_with_error_report(mysql_con, &slave,
+ multi_source ?
+ "SHOW ALL SLAVES STATUS" :
+ "SHOW SLAVE STATUS"))
+ DBUG_RETURN(1);
+
+ while ((row= mysql_fetch_row(slave)))
{
- MYSQL_ROW row= mysql_fetch_row(slave);
- if (row && row[11])
+ DBUG_PRINT("info", ("Connection: '%s' status: '%s'",
+ multi_source ? row[0] : "", row[11 + multi_source]));
+ if (row[11 + multi_source])
{
/* if SLAVE SQL is not running, we don't start it */
- if (!strcmp(row[11],"Yes"))
+ if (strcmp(row[11 + multi_source], "Yes"))
{
- mysql_free_result(slave);
- /* Silently assume that they don't have the slave running */
- return(0);
+ char query[160];
+ if (multi_source)
+ sprintf(query, "START SLAVE '%.80s'", row[0]);
+ else
+ strmov(query, "START SLAVE");
+
+ if (mysql_query_with_error_report(mysql_con, 0, query))
+ {
+ fprintf(stderr, "%s: Error: Unable to start slave '%s'\n",
+ my_progname_short, multi_source ? row[0] : "");
+ error= 1;
+ }
}
}
}
mysql_free_result(slave);
-
- /* now, start slave if stopped */
- if (mysql_query_with_error_report(mysql_con, 0, "START SLAVE"))
- {
- fprintf(stderr, "%s: Error: Unable to start slave\n", my_progname_short);
- return 1;
- }
- return(0);
+ DBUG_RETURN(error);
}
@@ -4917,12 +5231,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") );
}
@@ -5027,7 +5342,7 @@ static ulong find_set(TYPELIB *lib, const char *x, size_t length,
for (; pos != end && *pos != ','; pos++) ;
var_len= (uint) (pos - start);
- strmake(buff, start, min(sizeof(buff) - 1, var_len));
+ strmake(buff, start, MY_MIN(sizeof(buff) - 1, var_len));
find= find_type(buff, lib, FIND_TYPE_BASIC);
if (!find)
{
@@ -5151,11 +5466,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,"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);
@@ -5542,6 +5858,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 */
@@ -5580,6 +5897,13 @@ int main(int argc, char **argv)
if (!path)
write_header(md_result_file, *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;
@@ -5625,9 +5949,12 @@ int main(int argc, char **argv)
/* Add 'STOP SLAVE to beginning of dump */
if (opt_slave_apply && add_stop_slave())
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;
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index 850a851b4aa..aee445d387d 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -442,8 +442,12 @@ static MYSQL *db_connect(char *host, char *database,
(char*) &opt_local_file);
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
+ {
mysql_ssl_set(mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
+ mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
+ }
mysql_options(mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
(char*)&opt_ssl_verify_server_cert);
#endif
@@ -461,6 +465,9 @@ static MYSQL *db_connect(char *host, char *database,
mysql_options(mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset);
+ mysql_options(mysql, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
+ mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
+ "program_name", "mysqlimport");
if (!(mysql_real_connect(mysql,host,user,passwd,
database,opt_mysql_port,opt_mysql_unix_port,
0)))
@@ -489,7 +496,6 @@ static void db_disconnect(char *host, MYSQL *mysql)
}
-
static void safe_exit(int error, MYSQL *mysql)
{
if (error && ignore_errors)
@@ -508,7 +514,10 @@ static void safe_exit(int error, MYSQL *mysql)
free_defaults(argv_to_free);
mysql_library_end();
my_free(opt_password);
- my_end(my_end_arg);
+ if (error)
+ sf_leaking_memory= 1; /* dirty exit, some threads are still running */
+ else
+ my_end(my_end_arg); /* clean exit */
exit(error);
}
diff --git a/client/mysqlshow.c b/client/mysqlshow.c
index 4349c063ee8..eec4a8d3268 100644
--- a/client/mysqlshow.c
+++ b/client/mysqlshow.c
@@ -68,10 +68,12 @@ int main(int argc, char **argv)
my_bool first_argument_uses_wildcards=0;
char *wild;
MYSQL mysql;
+ static char **defaults_argv;
MY_INIT(argv[0]);
sf_leaking_memory=1; /* don't report memory leaks on early exits */
if (load_defaults("my",load_default_groups,&argc,&argv))
exit(1);
+ defaults_argv=argv;
get_options(&argc,&argv);
@@ -118,8 +120,12 @@ int main(int argc, char **argv)
mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
+ {
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(&mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
+ mysql_options(&mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
+ }
mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
(char*)&opt_ssl_verify_server_cert);
#endif
@@ -137,13 +143,17 @@ int main(int argc, char **argv)
if (opt_default_auth && *opt_default_auth)
mysql_options(&mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
+ mysql_options(&mysql, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
+ mysql_options4(&mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
+ "program_name", "mysqlshow");
if (!(mysql_real_connect(&mysql,host,user,opt_password,
(first_argument_uses_wildcards) ? "" :
argv[0],opt_mysql_port,opt_mysql_unix_port,
0)))
{
fprintf(stderr,"%s: %s\n",my_progname,mysql_error(&mysql));
- exit(1);
+ error= 1;
+ goto error;
}
mysql.reconnect= 1;
@@ -162,11 +172,14 @@ int main(int argc, char **argv)
error=list_fields(&mysql,argv[0],argv[1],wild);
break;
}
+error:
mysql_close(&mysql); /* Close & free connection */
my_free(opt_password);
+ mysql_server_end();
#ifdef HAVE_SMEM
my_free(shared_memory_base_name);
#endif
+ free_defaults(defaults_argv);
my_end(my_end_arg);
exit(error ? 1 : 0);
return 0; /* No compiler warnings */
diff --git a/client/mysqlslap.c b/client/mysqlslap.c
index 4f6fc7d45cb..b3229980e77 100644
--- a/client/mysqlslap.c
+++ b/client/mysqlslap.c
@@ -85,9 +85,7 @@ TODO:
#include <mysqld_error.h>
#include <my_dir.h>
#include <signal.h>
-#include <stdarg.h>
#include <sslopt-vars.h>
-#include <sys/types.h>
#ifndef __WIN__
#include <sys/wait.h>
#endif
@@ -170,6 +168,7 @@ static ulonglong auto_generate_sql_number;
const char *concurrency_str= NULL;
static char *create_string;
uint *concurrency;
+static char mysql_charsets_dir[FN_REFLEN+1];
const char *default_dbug_option="d:t:o,/tmp/mysqlslap.trace";
const char *opt_csv_str;
@@ -301,8 +300,12 @@ void set_mysql_connect_options(MYSQL *mysql)
mysql_options(mysql,MYSQL_OPT_COMPRESS,NullS);
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
+ {
mysql_ssl_set(mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
+ mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
+ }
#endif
if (opt_protocol)
mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
@@ -359,6 +362,9 @@ int main(int argc, char **argv)
if (opt_default_auth && *opt_default_auth)
mysql_options(&mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
+ mysql_options(&mysql, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
+ mysql_options4(&mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
+ "program_name", "mysqlslap");
if (!opt_only_print)
{
if (!(mysql_real_connect(&mysql, host, user, opt_password,
@@ -367,6 +373,7 @@ int main(int argc, char **argv)
{
fprintf(stderr,"%s: Error when connecting to server: %s\n",
my_progname,mysql_error(&mysql));
+ mysql_close(&mysql);
free_defaults(defaults_argv);
my_end(0);
exit(1);
@@ -412,8 +419,7 @@ int main(int argc, char **argv)
pthread_mutex_destroy(&sleeper_mutex);
pthread_cond_destroy(&sleep_threshhold);
- if (!opt_only_print)
- mysql_close(&mysql); /* Close & free connection */
+ mysql_close(&mysql); /* Close & free connection */
/* now free all the strings we created */
my_free(opt_password);
@@ -580,6 +586,9 @@ static struct my_option my_long_options[] =
"Number of row inserts to perform for each thread (default is 100).",
&auto_generate_sql_number, &auto_generate_sql_number,
0, GET_ULL, REQUIRED_ARG, 100, 0, 0, 0, 0, 0},
+ {"character-sets-dir", OPT_CHARSETS_DIR,
+ "Directory for character set files.", &charsets_dir,
+ &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"commit", OPT_SLAP_COMMIT, "Commit records every X number of statements.",
&commit_rate, &commit_rate, 0, GET_UINT, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
@@ -777,6 +786,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
DBUG_PUSH(argument ? argument : default_dbug_option);
debug_check_flag= 1;
break;
+ case OPT_CHARSETS_DIR:
+ strmake_buf(mysql_charsets_dir, argument);
+ charsets_dir = mysql_charsets_dir;
+ break;
case OPT_SLAP_CSV:
if (!argument)
argument= (char *)"-"; /* use stdout */
@@ -1808,8 +1821,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);
@@ -1858,21 +1871,21 @@ pthread_handler_t run_task(void *p)
}
pthread_mutex_unlock(&sleeper_mutex);
- if (!(mysql= mysql_init(NULL)))
+ if (mysql_thread_init())
{
- fprintf(stderr,"%s: mysql_init() failed ERROR : %s\n",
- my_progname, mysql_error(mysql));
+ fprintf(stderr,"%s: mysql_thread_init() failed\n", my_progname);
exit(0);
}
- set_mysql_connect_options(mysql);
- if (mysql_thread_init())
+ if (!(mysql= mysql_init(NULL)))
{
- fprintf(stderr,"%s: mysql_thread_init() failed ERROR : %s\n",
- my_progname, mysql_error(mysql));
+ fprintf(stderr,"%s: mysql_init() failed\n", my_progname);
+ mysql_thread_end();
exit(0);
}
+ set_mysql_connect_options(mysql);
+
DBUG_PRINT("info", ("trying to connect to host %s as user %s", host, user));
if (!opt_only_print)
@@ -1990,8 +2003,7 @@ end:
if (commit_rate)
run_query(mysql, "COMMIT", strlen("COMMIT"));
- if (!opt_only_print)
- mysql_close(mysql);
+ mysql_close(mysql);
mysql_thread_end();
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 3652d1a40e2..84d5abc1a67 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -44,7 +44,8 @@
#include <hash.h>
#include <stdarg.h>
#include <violite.h>
-#include "my_regex.h" /* Our own version of regex */
+#define PCRE_STATIC 1 /* Important on Windows */
+#include "pcreposix.h" /* pcreposix regex library */
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
@@ -87,6 +88,8 @@ static my_bool non_blocking_api_enabled= 0;
#define QUERY_SEND_FLAG 1
#define QUERY_REAP_FLAG 2
+#define QUERY_PRINT_ORIGINAL_FLAG 4
+
#ifndef HAVE_SETENV
static int setenv(const char *name, const char *value, int overwrite);
#endif
@@ -248,14 +251,16 @@ static const char *opt_suite_dir, *opt_overlay_dir;
static size_t suite_dir_len, overlay_dir_len;
/* Precompiled re's */
-static my_regex_t ps_re; /* the query can be run using PS protocol */
-static my_regex_t sp_re; /* the query can be run as a SP */
-static my_regex_t view_re; /* the query can be run as a view*/
+static regex_t ps_re; /* the query can be run using PS protocol */
+static regex_t sp_re; /* the query can be run as a SP */
+static regex_t view_re; /* the query can be run as a view*/
static void init_re(void);
-static int match_re(my_regex_t *, char *);
+static int match_re(regex_t *, char *);
static void free_re(void);
+static char *get_string(char **to_ptr, char **from_ptr,
+ struct st_command *command);
static int replace(DYNAMIC_STRING *ds_str,
const char *search_str, ulong search_len,
const char *replace_str, ulong replace_len);
@@ -345,7 +350,8 @@ enum enum_commands {
Q_ERROR,
Q_SEND, Q_REAP,
Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN,
- Q_PING, Q_EVAL,
+ Q_PING, Q_EVAL,
+ Q_EVALP,
Q_EVAL_RESULT,
Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG,
Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG,
@@ -411,6 +417,7 @@ const char *command_names[]=
"replace_column",
"ping",
"eval",
+ "evalp",
"eval_result",
/* Enable/disable that the _query_ is logged to result file */
"enable_query_log",
@@ -832,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
@@ -880,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);
}
@@ -977,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)
@@ -1012,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*/
@@ -1081,7 +1104,7 @@ void do_eval(DYNAMIC_STRING *query_eval, const char *query,
Run query and dump the result to stderr in vertical format
NOTE! This function should be safe to call when an error
- has occured and thus any further errors will be ignored(although logged)
+ has occurred and thus any further errors will be ignored (although logged)
SYNOPSIS
show_query
@@ -1147,7 +1170,7 @@ static void show_query(MYSQL* mysql, const char* query)
is added to the warning stack, only print @@warning_count-1 warnings.
NOTE! This function should be safe to call when an error
- has occured and this any further errors will be ignored(although logged)
+ has occurred and this any further errors will be ignored(although logged)
SYNOPSIS
show_warnings_before_error
@@ -1371,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;
@@ -3675,7 +3698,6 @@ void do_remove_files_wildcard(struct st_command *command)
fn_format(dirname, ds_directory.str, "", "", MY_UNPACK_FILENAME);
DBUG_PRINT("info", ("listing directory: %s", dirname));
- /* Note that my_dir sorts the list if not given any flags */
if (!(dir_info= my_dir(dirname, MYF(MY_DONT_SORT | MY_WANT_STAT | MY_WME))))
{
error= 1;
@@ -3690,7 +3712,7 @@ void do_remove_files_wildcard(struct st_command *command)
/* Set default wild chars for wild_compare, is changed in embedded mode */
set_wild_chars(1);
- for (i= 0; i < (uint) dir_info->number_off_files; i++)
+ for (i= 0; i < (uint) dir_info->number_of_files; i++)
{
file= dir_info->dir_entry + i;
/* Remove only regular files, i.e. no directories etc. */
@@ -3953,17 +3975,12 @@ static int get_list_files(DYNAMIC_STRING *ds, const DYNAMIC_STRING *ds_dirname,
DBUG_ENTER("get_list_files");
DBUG_PRINT("info", ("listing directory: %s", ds_dirname->str));
- /* Note that my_dir sorts the list if not given any flags */
- if (!(dir_info= my_dir(ds_dirname->str, MYF(0))))
+ if (!(dir_info= my_dir(ds_dirname->str, MYF(MY_WANT_SORT))))
DBUG_RETURN(1);
set_wild_chars(1);
- for (i= 0; i < (uint) dir_info->number_off_files; i++)
+ for (i= 0; i < (uint) dir_info->number_of_files; i++)
{
file= dir_info->dir_entry + i;
- if (file->name[0] == '.' &&
- (file->name[1] == '\0' ||
- (file->name[1] == '.' && file->name[2] == '\0')))
- continue; /* . or .. */
if (ds_wild && ds_wild->length &&
wild_compare(file->name, ds_wild->str, 0))
continue;
@@ -4635,7 +4652,8 @@ void do_wait_for_slave_to_stop(struct st_command *c __attribute__((unused)))
}
-void do_sync_with_master2(struct st_command *command, long offset)
+void do_sync_with_master2(struct st_command *command, long offset,
+ const char *connection_name)
{
MYSQL_RES *res;
MYSQL_ROW row;
@@ -4646,8 +4664,9 @@ void do_sync_with_master2(struct st_command *command, long offset)
if (!master_pos.file[0])
die("Calling 'sync_with_master' without calling 'save_master_pos'");
- sprintf(query_buf, "select master_pos_wait('%s', %ld, %d)",
- master_pos.file, master_pos.pos + offset, timeout);
+ sprintf(query_buf, "select master_pos_wait('%s', %ld, %d, '%s')",
+ master_pos.file, master_pos.pos + offset, timeout,
+ connection_name);
if (mysql_query(mysql, query_buf))
die("failed in '%s': %d: %s", query_buf, mysql_errno(mysql),
@@ -4682,7 +4701,7 @@ void do_sync_with_master2(struct st_command *command, long offset)
master_pos_wait returned NULL. This indicates that
slave SQL thread is not started, the slave's master
information is not initialized, the arguments are
- incorrect, or an error has occured
+ incorrect, or an error has occurred
*/
die("%.*s failed: '%s' returned NULL " \
"indicating slave SQL thread failure",
@@ -4707,16 +4726,32 @@ void do_sync_with_master(struct st_command *command)
long offset= 0;
char *p= command->first_argument;
const char *offset_start= p;
+ char *start, *buff= 0;
+ start= (char*) "";
+
if (*offset_start)
{
for (; my_isdigit(charset_info, *p); p++)
offset = offset * 10 + *p - '0';
- if(*p && !my_isspace(charset_info, *p))
+ if (*p && !my_isspace(charset_info, *p) && *p != ',')
die("Invalid integer argument \"%s\"", offset_start);
+
+ while (*p && my_isspace(charset_info, *p))
+ p++;
+ if (*p == ',')
+ {
+ p++;
+ while (*p && my_isspace(charset_info, *p))
+ p++;
+ start= buff= (char*)my_malloc(strlen(p)+1,MYF(MY_WME | MY_FAE));
+ get_string(&buff, &p, command);
+ }
command->last_argument= p;
}
- do_sync_with_master2(command, offset);
+ do_sync_with_master2(command, offset, start);
+ if (buff)
+ my_free(start);
return;
}
@@ -5204,7 +5239,7 @@ typedef struct
static st_error global_error_names[] =
{
- { "<No error>", -1U, "" },
+ { "<No error>", ~0U, "" },
#include <mysqld_ername.h>
{ 0, 0, 0 }
};
@@ -5368,7 +5403,7 @@ void do_get_errcodes(struct st_command *command)
{
die("The sqlstate definition must start with an uppercase S");
}
- else if (*p == 'E' || *p == 'H')
+ else if (*p == 'E' || *p == 'W' || *p == 'H')
{
/* Error name string */
@@ -5377,9 +5412,9 @@ void do_get_errcodes(struct st_command *command)
to->type= ERR_ERRNO;
DBUG_PRINT("info", ("ERR_ERRNO: %d", to->code.errnum));
}
- else if (*p == 'e' || *p == 'h')
+ else if (*p == 'e' || *p == 'w' || *p == 'h')
{
- die("The error name definition must start with an uppercase E or H");
+ die("The error name definition must start with an uppercase E or W or H");
}
else
{
@@ -5442,8 +5477,8 @@ void do_get_errcodes(struct st_command *command)
If string is a '$variable', return the value of the variable.
*/
-char *get_string(char **to_ptr, char **from_ptr,
- struct st_command *command)
+static char *get_string(char **to_ptr, char **from_ptr,
+ struct st_command *command)
{
char c, sep;
char *to= *to_ptr, *from= *from_ptr, *start=to;
@@ -5617,7 +5652,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
@@ -5625,9 +5664,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;
@@ -5704,6 +5740,10 @@ void safe_connect(MYSQL* mysql, const char *name, const char *host,
verbose_msg("Connecting to server %s:%d (socket %s) as '%s'"
", connection '%s', attempt %d ...",
host, port, sock, user, name, failed_attempts);
+
+ mysql_options(mysql, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
+ mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
+ "program_name", "mysqltest");
while(!mysql_real_connect(mysql, host,user, pass, db, port, sock,
CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS))
{
@@ -5804,7 +5844,9 @@ int connect_n_handle_errors(struct st_command *command,
replace_dynstr_append(ds, command->query);
dynstr_append_mem(ds, ";\n", 2);
}
-
+
+ mysql_options(con, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
+ mysql_options4(con, MYSQL_OPT_CONNECT_ATTR_ADD, "program_name", "mysqltest");
while (!mysql_real_connect(con, host, user, pass, db, port, sock ? sock: 0,
CLIENT_MULTI_STATEMENTS))
{
@@ -5888,6 +5930,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;
@@ -5984,6 +6028,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);
@@ -6035,6 +6089,8 @@ void do_connect(struct st_command *command)
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
mysql_ssl_set(con_slot->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, ssl_cipher ? ssl_cipher : opt_ssl_cipher);
+ mysql_options(con_slot->mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
+ mysql_options(con_slot->mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
#if MYSQL_VERSION_ID >= 50000
/* Turn on ssl_verify_server_cert only if host is "localhost" */
opt_ssl_verify_server_cert= !strcmp(ds_host.str, "localhost");
@@ -6054,6 +6110,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)
{
@@ -6545,9 +6613,9 @@ int read_line(char *buf, int size)
}
else if ((c == '{' &&
(!my_strnncoll_simple(charset_info, (const uchar*) "while", 5,
- (uchar*) buf, min(5, p - buf), 0) ||
+ (uchar*) buf, MY_MIN(5, p - buf), 0) ||
!my_strnncoll_simple(charset_info, (const uchar*) "if", 2,
- (uchar*) buf, min(2, p - buf), 0))))
+ (uchar*) buf, MY_MIN(2, p - buf), 0))))
{
/* Only if and while commands can be terminated by { */
*p++= c;
@@ -7309,13 +7377,13 @@ void str_to_file(const char *fname, char *str, int size)
}
-void check_regerr(my_regex_t* r, int err)
+void check_regerr(regex_t* r, int err)
{
char err_buf[1024];
if (err)
{
- my_regerror(err,r,err_buf,sizeof(err_buf));
+ regerror(err,r,err_buf,sizeof(err_buf));
die("Regex error: %s\n", err_buf);
}
}
@@ -7350,7 +7418,7 @@ void init_win_path_patterns()
DBUG_ENTER("init_win_path_patterns");
- my_init_dynamic_array(&patterns, sizeof(const char*), 16, 16);
+ my_init_dynamic_array(&patterns, sizeof(const char*), 16, 16, MYF(0));
/* Loop through all paths in the array */
for (i= 0; i < num_paths; i++)
@@ -7699,6 +7767,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)))
@@ -7718,11 +7787,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);
}
@@ -8386,7 +8462,8 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
/*
Evaluate query if this is an eval command
*/
- if (command->type == Q_EVAL || command->type == Q_SEND_EVAL)
+ if (command->type == Q_EVAL || command->type == Q_SEND_EVAL ||
+ command->type == Q_EVALP)
{
if (!command->eval_query.str)
init_dynamic_string(&command->eval_query, "", command->query_len + 256,
@@ -8422,10 +8499,20 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
*/
if (!disable_query_log && (flags & QUERY_SEND_FLAG))
{
- replace_dynstr_append_mem(ds, query, query_len);
+ char *print_query= query;
+ int print_len= query_len;
+ if (flags & QUERY_PRINT_ORIGINAL_FLAG)
+ {
+ print_query= command->query;
+ print_len= command->end - command->query;
+ }
+ replace_dynstr_append_mem(ds, print_query, print_len);
dynstr_append_mem(ds, delimiter, delimiter_length);
dynstr_append_mem(ds, "\n", 1);
}
+
+ /* We're done with this flag */
+ flags &= ~QUERY_PRINT_ORIGINAL_FLAG;
/*
Write the command to the result file before we execute the query
@@ -8599,19 +8686,18 @@ char *re_eprint(int err)
{
static char epbuf[100];
size_t len __attribute__((unused))=
- my_regerror(REG_ITOA|err, (my_regex_t *)NULL, epbuf, sizeof(epbuf));
+ regerror(err, (regex_t *)NULL, epbuf, sizeof(epbuf));
assert(len <= sizeof(epbuf));
return(epbuf);
}
-void init_re_comp(my_regex_t *re, const char* str)
+void init_re_comp(regex_t *re, const char* str)
{
- int err= my_regcomp(re, str, (REG_EXTENDED | REG_ICASE | REG_NOSUB),
- &my_charset_latin1);
+ int err= regcomp(re, str, (REG_EXTENDED | REG_ICASE | REG_NOSUB | REG_DOTALL));
if (err)
{
char erbuf[100];
- int len= my_regerror(err, re, erbuf, sizeof(erbuf));
+ int len= regerror(err, re, erbuf, sizeof(erbuf));
die("error %s, %d/%d `%s'\n",
re_eprint(err), (int)len, (int)sizeof(erbuf), erbuf);
}
@@ -8656,7 +8742,7 @@ void init_re(void)
}
-int match_re(my_regex_t *re, char *str)
+int match_re(regex_t *re, char *str)
{
while (my_isspace(charset_info, *str))
str++;
@@ -8668,7 +8754,7 @@ int match_re(my_regex_t *re, char *str)
str= comm_end + 2;
}
- int err= my_regexec(re, str, (size_t)0, NULL, 0);
+ int err= regexec(re, str, (size_t)0, NULL, 0);
if (err == 0)
return 1;
@@ -8677,7 +8763,7 @@ int match_re(my_regex_t *re, char *str)
{
char erbuf[100];
- int len= my_regerror(err, re, erbuf, sizeof(erbuf));
+ int len= regerror(err, re, erbuf, sizeof(erbuf));
die("error %s, %d/%d `%s'\n",
re_eprint(err), (int)len, (int)sizeof(erbuf), erbuf);
}
@@ -8686,10 +8772,9 @@ int match_re(my_regex_t *re, char *str)
void free_re(void)
{
- my_regfree(&ps_re);
- my_regfree(&sp_re);
- my_regfree(&view_re);
- my_regex_end();
+ regfree(&ps_re);
+ regfree(&sp_re);
+ regfree(&view_re);
}
/****************************************************************************/
@@ -8955,12 +9040,16 @@ int main(int argc, char **argv)
cur_block->ok= TRUE; /* Outer block should always be executed */
cur_block->cmd= cmd_none;
- my_init_dynamic_array(&q_lines, sizeof(struct st_command*), 1024, 1024);
+ my_init_dynamic_array(&q_lines, sizeof(struct st_command*), 1024, 1024, MYF(0));
if (my_hash_init2(&var_hash, 64, charset_info,
- 128, 0, 0, get_var_key, var_free, MYF(0)))
+ 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);
@@ -8985,7 +9074,7 @@ int main(int argc, char **argv)
#endif
init_dynamic_string(&ds_res, "", 2048, 2048);
- init_alloc_root(&require_file_root, 1024, 1024);
+ init_alloc_root(&require_file_root, 1024, 1024, MYF(0));
parse_args(argc, argv);
@@ -9073,6 +9162,8 @@ int main(int argc, char **argv)
{
mysql_ssl_set(con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+ mysql_options(con->mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
+ mysql_options(con->mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
#if MYSQL_VERSION_ID >= 50000
/* Turn on ssl_verify_server_cert only if host is "localhost" */
opt_ssl_verify_server_cert= opt_host && !strcmp(opt_host, "localhost");
@@ -9284,6 +9375,7 @@ int main(int argc, char **argv)
case Q_EVAL_RESULT:
die("'eval_result' command is deprecated");
case Q_EVAL:
+ case Q_EVALP:
case Q_QUERY_VERTICAL:
case Q_QUERY_HORIZONTAL:
if (command->query == command->query_buf)
@@ -9311,6 +9403,9 @@ int main(int argc, char **argv)
flags= QUERY_REAP_FLAG;
}
+ if (command->type == Q_EVALP)
+ flags |= QUERY_PRINT_ORIGINAL_FLAG;
+
/* Check for special property for this query */
display_result_vertically|= (command->type == Q_QUERY_VERTICAL);
@@ -9380,7 +9475,7 @@ int main(int argc, char **argv)
select_connection(command);
else
select_connection_name("slave");
- do_sync_with_master2(command, 0);
+ do_sync_with_master2(command, 0, "");
break;
}
case Q_COMMENT:
@@ -9875,36 +9970,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.
@@ -9916,16 +10009,15 @@ 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 */
res=(struct st_replace_regex*)my_malloc(
sizeof(*res)+expr_len ,MYF(MY_FAE+MY_WME));
- my_init_dynamic_array(&res->regex_arr,sizeof(struct st_regex),128,128);
+ my_init_dynamic_array(&res->regex_arr,sizeof(struct st_regex), 128, 128, MYF(0));
buf= (char*)res + sizeof(*res);
expr_end= expr + expr_len;
@@ -9937,44 +10029,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 */
- reg.pattern= buf_p;
- /* Find first argument -- pattern string to be removed */
- PARSE_REGEX_ARG
-
- if (p == expr_end || ++p == expr_end)
- goto err;
+ start_re= 0;
+ reg.pattern= buf_p;
+ if (parse_re_part(&start_re, &end_re, &p, expr_end, &buf_p))
+ 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))
@@ -10122,13 +10202,13 @@ void free_replace_regex()
int reg_replace(char** buf_p, int* buf_len_p, char *pattern,
char *replace, char *string, int icase)
{
- my_regex_t r;
- my_regmatch_t *subs;
+ regex_t r;
+ regmatch_t *subs;
char *replace_end;
char *buf= *buf_p;
int len;
int buf_len, need_buf_len;
- int cflags= REG_EXTENDED;
+ int cflags= REG_EXTENDED | REG_DOTALL;
int err_code;
char *res_p,*str_p,*str_end;
@@ -10147,13 +10227,13 @@ int reg_replace(char** buf_p, int* buf_len_p, char *pattern,
if (icase)
cflags|= REG_ICASE;
- if ((err_code= my_regcomp(&r,pattern,cflags,&my_charset_latin1)))
+ if ((err_code= regcomp(&r,pattern,cflags)))
{
check_regerr(&r,err_code);
return 1;
}
- subs= (my_regmatch_t*)my_malloc(sizeof(my_regmatch_t) * (r.re_nsub+1),
+ subs= (regmatch_t*)my_malloc(sizeof(regmatch_t) * (r.re_nsub+1),
MYF(MY_WME+MY_FAE));
*res_p= 0;
@@ -10164,14 +10244,14 @@ int reg_replace(char** buf_p, int* buf_len_p, char *pattern,
while (!err_code)
{
/* find the match */
- err_code= my_regexec(&r,str_p, r.re_nsub+1, subs,
+ err_code= regexec(&r,str_p, r.re_nsub+1, subs,
(str_p == string) ? REG_NOTBOL : 0);
/* if regular expression error (eg. bad syntax, or out of memory) */
if (err_code && err_code != REG_NOMATCH)
{
check_regerr(&r,err_code);
- my_regfree(&r);
+ regfree(&r);
return 1;
}
@@ -10284,7 +10364,7 @@ int reg_replace(char** buf_p, int* buf_len_p, char *pattern,
}
}
my_free(subs);
- my_regfree(&r);
+ regfree(&r);
*res_p= 0;
*buf_p= buf;
*buf_len_p= buf_len;
@@ -10980,7 +11060,7 @@ void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input,
if (!*start)
DBUG_VOID_RETURN; /* No input */
- my_init_dynamic_array(&lines, sizeof(const char*), 32, 32);
+ my_init_dynamic_array(&lines, sizeof(const char*), 32, 32, MYF(0));
if (keep_header)
{