diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-01 18:15:00 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-01 18:15:00 +0000 |
commit | a2a2e32c02643a0cec111511220227703fda1cd5 (patch) | |
tree | 69cc2b631234c2a8e026b9cd4d72676c61c594df /client | |
parent | Releasing progress-linux version 1:10.11.8-1~progress7.99u1. (diff) | |
download | mariadb-a2a2e32c02643a0cec111511220227703fda1cd5.tar.xz mariadb-a2a2e32c02643a0cec111511220227703fda1cd5.zip |
Merging upstream version 1:11.4.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'client')
-rw-r--r-- | client/CMakeLists.txt | 2 | ||||
-rw-r--r-- | client/client_priv.h | 2 | ||||
-rw-r--r-- | client/connection_pool.cc | 264 | ||||
-rw-r--r-- | client/connection_pool.h | 125 | ||||
-rw-r--r-- | client/mariadb-conv.cc | 8 | ||||
-rw-r--r-- | client/mysql.cc | 125 | ||||
-rw-r--r-- | client/mysql_plugin.c | 11 | ||||
-rw-r--r-- | client/mysql_upgrade.c | 35 | ||||
-rw-r--r-- | client/mysqladmin.cc | 205 | ||||
-rw-r--r-- | client/mysqlbinlog.cc | 375 | ||||
-rw-r--r-- | client/mysqlcheck.c | 23 | ||||
-rw-r--r-- | client/mysqldump.cc (renamed from client/mysqldump.c) | 205 | ||||
-rw-r--r-- | client/mysqlimport.c | 31 | ||||
-rw-r--r-- | client/mysqlshow.c | 22 | ||||
-rw-r--r-- | client/mysqlslap.c | 22 | ||||
-rw-r--r-- | client/mysqltest.cc | 152 |
16 files changed, 801 insertions, 806 deletions
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index a8e80bc8..b21402ad 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -53,7 +53,7 @@ SET_TARGET_PROPERTIES(mariadb-test PROPERTIES ENABLE_EXPORTS TRUE) MYSQL_ADD_EXECUTABLE(mariadb-check mysqlcheck.c) TARGET_LINK_LIBRARIES(mariadb-check ${CLIENT_LIB}) -MYSQL_ADD_EXECUTABLE(mariadb-dump mysqldump.c ../sql-common/my_user.c) +MYSQL_ADD_EXECUTABLE(mariadb-dump mysqldump.cc ../sql-common/my_user.c connection_pool.cc) TARGET_LINK_LIBRARIES(mariadb-dump ${CLIENT_LIB}) MYSQL_ADD_EXECUTABLE(mariadb-import mysqlimport.c) diff --git a/client/client_priv.h b/client/client_priv.h index eba8a841..46c0a897 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -42,6 +42,7 @@ enum options_client OPT_TABLES, OPT_MASTER_DATA, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH, + OPT_TLS_VERSION, OPT_SSL_CIPHER, OPT_LOCAL_INFILE, OPT_COMPACT, OPT_MYSQL_PROTOCOL, @@ -70,6 +71,7 @@ enum options_client OPT_DO_DOMAIN_IDS, OPT_IGNORE_SERVER_IDS, OPT_DO_SERVER_IDS, + OPT_SSL_FP, OPT_SSL_FPLIST, OPT_MAX_CLIENT_OPTION /* should be always the last */ }; diff --git a/client/connection_pool.cc b/client/connection_pool.cc new file mode 100644 index 00000000..7f1db370 --- /dev/null +++ b/client/connection_pool.cc @@ -0,0 +1,264 @@ +/* + Copyright (c) 2023, 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 + USA +*/ + +/* + Connection pool, with parallel query execution + Does not use threads, but IO multiplexing via mysql_send_query and + poll/iocp to wait for completions +*/ +#include <my_global.h> +#ifdef _WIN32 +#include <winsock2.h> +#else +#include <poll.h> +#endif +#include "connection_pool.h" +#include <my_compiler.h> + +namespace async_pool +{ +static ATTRIBUTE_NORETURN void die(const char *format, ...) +{ + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + abort(); +} + +pooled_connection *connection_pool::get_connection() +{ + while (free_connections.empty()) + wait_for_completions(); + auto c= free_connections.front(); + free_connections.pop(); + return c; +} + +#ifdef _WIN32 +void connection_pool::add_to_pollset(pooled_connection *c) +{ + DWORD err= ERROR_SUCCESS; + static char ch; + WSABUF buf; + buf.len= 0; + buf.buf= &ch; + if (!c->is_pipe) + { + /* Do async io (sockets). */ + DWORD flags= 0; + if (WSARecv((SOCKET) c->handle, &buf, 1, 0, &flags, c, NULL)) + err= WSAGetLastError(); + } + else + { + /* Do async read (named pipe) */ + if (!ReadFile(c->handle, buf.buf, buf.len, 0, c)) + err= GetLastError(); + } + + if (err && err != ERROR_IO_PENDING) + die("%s failed: %d\n", c->is_pipe ? "ReadFile" : "WSARecv", err); +} + +/* + Wait for completions of queries.Uses IOCP on windows to wait for completions. + (ReadFile/WSARecv with 0 bytes serves as readiness notification) +*/ +void connection_pool::wait_for_completions() +{ + ULONG n; + OVERLAPPED_ENTRY events[32]; + if (!GetQueuedCompletionStatusEx(iocp, events, array_elements(events), &n, INFINITE, + FALSE)) + { + die("GetQueuedCompletionStatusEx failed: %d\n", GetLastError()); + } + + for (ULONG i= 0; i < n; i++) + { + auto c= (pooled_connection *) events[i].lpOverlapped; + if (!c) + die("GetQueuedCompletionStatusEx unexpected return"); + DBUG_ASSERT(c->mysql); + DBUG_ASSERT(!events[i].lpCompletionKey); + DBUG_ASSERT(!events[i].dwNumberOfBytesTransferred); + complete_query(c); + } +} +#else /* !_WIN32 */ +void connection_pool::add_to_pollset(pooled_connection *c) +{ + size_t idx= c - &all_connections[0]; + pollfd *pfd= &pollset[idx]; + pfd->fd= c->fd; + pfd->events= POLLIN; + pfd->revents= 0; +} + +/* something Linux-ish, can be returned for POLLIN event*/ +#ifndef POLLRDHUP +#define POLLRDHUP 0 +#endif + +void connection_pool::wait_for_completions() +{ + int n; + while ((n= poll(pollset.data(), pollset.size(), -1)) <= 0) + { + if (errno == EINTR) + continue; + die("poll failed: %d\n", errno); + } + + for (uint i= 0; n > 0 && i < pollset.size(); i++) + { + pollfd* pfd= &pollset[i]; + if (pfd->revents & + (POLLIN | POLLPRI | POLLHUP | POLLRDHUP| POLLERR | POLLNVAL)) + { + pfd->events= 0; + pfd->revents= 0; + pfd->fd= -1; + complete_query(&all_connections[i]); + n--; + } + } + if (n) + die("poll() failed to find free connection: %d\n"); +} +#endif + +void connection_pool::complete_query(pooled_connection *c) +{ + int err= mysql_read_query_result(c->mysql); + if (c->on_completion) + c->on_completion(c->mysql, c->query.c_str(), !err, c->context); + if (c->release_connection) + { + c->in_use= false; + free_connections.push(c); + } +} + +connection_pool::~connection_pool() +{ + close(); +} + +void connection_pool::init(MYSQL *con[], size_t n) +{ +#ifdef _WIN32 + iocp= CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); + if (!iocp) + die("CreateIoCompletionPort failed: %d\n", GetLastError()); +#else + pollset.resize(n); + for (auto &pfd : pollset) + pfd.fd= -1; +#endif + + + for (size_t i= 0; i < n; i++) + all_connections.emplace_back(con[i]); + + for (auto &con : all_connections) + { + free_connections.push(&con); +#ifdef _WIN32 + if (!CreateIoCompletionPort(con.handle, iocp, 0, 0)) + die("CreateIoCompletionPort failed: %d\n", GetLastError()); +#endif + } +} + +int connection_pool::execute_async(const char *query, + query_completion_handler on_completion, + void *context, bool release_connecton) +{ + auto c= get_connection(); + c->context= context; + c->on_completion= on_completion; + c->release_connection= release_connecton; + c->query= query; + + int ret= mysql_send_query(c->mysql, query, (unsigned long) c->query.size()); + if (ret) + { + free_connections.push(c); + return ret; + } + + c->in_use= true; + add_to_pollset(c); + return 0; +} + +/* + Wait until all queries are completed and all + connections are idle. +*/ +void connection_pool::wait_all() +{ + while (free_connections.size() != all_connections.size()) + wait_for_completions(); +} + +void connection_pool::for_each_connection(void(*f)(MYSQL *mysql)) +{ + for (auto &c : all_connections) + f(c.mysql); +} + +int connection_pool::close() +{ + for (auto &c : all_connections) + mysql_close(c.mysql); + + all_connections.clear(); + while (!free_connections.empty()) + free_connections.pop(); +#ifdef _WIN32 + if (iocp) + { + CloseHandle(iocp); + iocp= nullptr; + } +#endif + return 0; +} + +pooled_connection::pooled_connection(MYSQL *c) +{ + mysql= c; +#ifdef _WIN32 + OVERLAPPED *ov= static_cast<OVERLAPPED *>(this); + memset(ov, 0, sizeof(OVERLAPPED)); + mysql_protocol_type protocol; + if (c->host && !strcmp(c->host, ".")) + protocol= MYSQL_PROTOCOL_PIPE; + else + protocol= (mysql_protocol_type) c->options.protocol; + is_pipe= protocol == MYSQL_PROTOCOL_PIPE; + handle= (HANDLE) mysql_get_socket(c); +#else + fd= mysql_get_socket(c); +#endif +} + +} // namespace async_pool diff --git a/client/connection_pool.h b/client/connection_pool.h new file mode 100644 index 00000000..48639d5b --- /dev/null +++ b/client/connection_pool.h @@ -0,0 +1,125 @@ +/* + Copyright (c) 2023, 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 + USA +*/ + +#pragma once + +#include <mysql.h> +#include <vector> +#include <queue> +#include <string> +#ifdef _WIN32 +#include <windows.h> +#else +#include <poll.h> +#endif + +/* + Implementation of asynchronous mariadb connection pool. + + This pool consists of set of MYSQL* connections, created by C API + function. The intention is that all connections have the same state + same server, by the same user etc. + + The "asynchronous" means the queries are executed on the server + without waiting for the server reply. The queries are submitted + with mysql_send_query(), and completions are picked by poll/IOCP. +*/ + +namespace async_pool +{ +typedef void (*query_completion_handler)(MYSQL *mysql, const char *query, bool success, void *context); + +struct pooled_connection +#ifdef _WIN32 + : OVERLAPPED +#endif +{ + MYSQL *mysql; + query_completion_handler on_completion=NULL; + void *context=NULL; + std::string query; + bool in_use=false; + bool release_connection=false; +#ifdef _WIN32 + bool is_pipe; + HANDLE handle; +#else + int fd; +#endif + pooled_connection(MYSQL *mysql); +}; + + +struct connection_pool +{ +private: + std::vector<pooled_connection> all_connections; + std::queue<pooled_connection *> free_connections; + pooled_connection *get_connection(); + void wait_for_completions(); + void complete_query(pooled_connection *c); + void add_to_pollset(pooled_connection *c); + +#ifdef _WIN32 + HANDLE iocp=nullptr; +#else + std::vector<pollfd> pollset; +#endif +public: + ~connection_pool(); + + /** + Add connections to the connection pool + + @param con - connections + @param n_connections - number of connections + */ + void init(MYSQL *con[], size_t n_connections); + + /** + Send query to the connection pool + Executes query on a connection in the pool, using mysql_send_query + + @param query - query string + @param on_completion - callback function to be called on completion + @param context - user context that will be passed to the callback function + @param release_connecton - if true, the connection should be released to the + pool after the query is executed. If you execute another + mysql_send_query() on the same connection, set this to false. + + Note: the function will block if there are no free connections in the pool. + + @return return code of mysql_send_query + */ + int execute_async(const char *query, query_completion_handler on_completion, void *context, bool release_connecton=true); + + /** Waits for all outstanding queries to complete.*/ + void wait_all(); + + /** Execute callback for each connection in the pool. */ + void for_each_connection(void (*f)(MYSQL *mysql)); + + /** + Closes all connections in pool and frees all resources. + Does not wait for pending queries to complete + (use wait_all() for that) + */ + int close(); +}; + +} // namespace async_pool diff --git a/client/mariadb-conv.cc b/client/mariadb-conv.cc index 1774debe..0e35812d 100644 --- a/client/mariadb-conv.cc +++ b/client/mariadb-conv.cc @@ -20,13 +20,12 @@ Character set conversion utility */ +#define VER "1.0" #include "mariadb.h" #include "client_priv.h" #include "sql_string.h" #include "my_dir.h" - -#define CONV_VERSION "1.0" - +#include <welcome_copyright_notice.h> class CmdOpt { @@ -415,8 +414,7 @@ public: } void usage(void) { - printf("%s Ver %s Distrib %s for %s on %s\n", my_progname, CONV_VERSION, - MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); + print_version(); puts("Character set conversion utility for MariaDB"); puts("Usage:"); printf("%s [OPTION...] [FILE...]\n", my_progname); diff --git a/client/mysql.cc b/client/mysql.cc index d9173cf6..ca659786 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -46,7 +46,7 @@ #include <locale.h> #endif -const char *VER= "15.1"; +const char *VER= "15.2"; /* Don't try to make a nice table if the data is too big */ #define MAX_COLUMN_LENGTH 1024 @@ -246,7 +246,7 @@ static my_bool ignore_errors=0,wait_flag=0,quick=0, tty_password= 0, opt_nobeep=0, opt_reconnect=1, opt_secure_auth= 0, default_pager_set= 0, opt_sigint_ignore= 0, - auto_vertical_output= 0, + auto_vertical_output= 0, show_query_cost= 0, show_warnings= 0, executing_query= 0, ignore_spaces= 0, opt_binhex= 0, opt_progress_reports; static my_bool debug_info_flag, debug_check_flag, batch_abort_on_error; @@ -326,6 +326,7 @@ static int com_quit(String *str,char*), com_prompt(String *str, char*), com_delimiter(String *str, char*), com_warnings(String *str, char*), com_nowarnings(String *str, char*), com_sandbox(String *str, char*); +static int com_query_cost(String *str, char*); #ifdef USE_POPEN static int com_nopager(String *str, char*), com_pager(String *str, char*), @@ -400,6 +401,8 @@ static COMMANDS commands[] = { { "print", 'p', com_print, 0, "Print current command." }, { "prompt", 'R', com_prompt, 1, "Change your mysql prompt."}, { "quit", 'q', com_quit, 0, "Quit mysql." }, + { "costs", 'Q', com_query_cost, 0, + "Toggle showing query costs after each query" }, { "rehash", '#', com_rehash, 0, "Rebuild completion hash." }, { "sandbox", '-', com_sandbox, 0, "Disallow commands that access the file system (except \\P without an argument and \\e)." }, @@ -1159,6 +1162,7 @@ static void print_table_data_xml(MYSQL_RES *result); static void print_tab_data(MYSQL_RES *result); static void print_table_data_vertically(MYSQL_RES *result); static void print_warnings(void); +static void print_last_query_cost(void); static void end_timer(ulonglong start_time, char *buff); static void nice_time(double sec,char *buff,bool part_second); extern "C" sig_handler mysql_end(int sig) __attribute__ ((noreturn)); @@ -1295,6 +1299,7 @@ int main(int argc,char *argv[]) glob_buffer.realloc(512); completion_hash_init(&ht, 128); init_alloc_root(PSI_NOT_INSTRUMENTED, &hash_mem_root, 16384, 0, MYF(0)); + if (sql_connect(current_host,current_db,current_user,opt_password, opt_silent)) { @@ -1334,26 +1339,38 @@ int main(int argc,char *argv[]) initialize_readline(); if (!status.batch && !quick && !opt_html && !opt_xml) { - /* read-history from file, default ~/.mysql_history*/ - if (getenv("MYSQL_HISTFILE")) - histfile=my_strdup(PSI_NOT_INSTRUMENTED, getenv("MYSQL_HISTFILE"),MYF(MY_WME)); - else if (getenv("HOME")) + const char *home; + /* read-history from file, default ~/.mariadb_history*/ + if ((histfile= getenv("MARIADB_HISTFILE")) + || (histfile= getenv("MYSQL_HISTFILE"))) + histfile=my_strdup(PSI_NOT_INSTRUMENTED, histfile, MYF(MY_WME)); + else if ((home= getenv("HOME"))) { histfile=(char*) my_malloc(PSI_NOT_INSTRUMENTED, - strlen(getenv("HOME")) + strlen("/.mysql_history")+2, MYF(MY_WME)); + strlen(home) + strlen("/.mariadb_history")+2, MYF(MY_WME)); if (histfile) - sprintf(histfile,"%s/.mysql_history",getenv("HOME")); - char link_name[FN_REFLEN]; - if (my_readlink(link_name, histfile, 0) == 0 && - strncmp(link_name, "/dev/null", 10) == 0) { - /* The .mysql_history file is a symlink to /dev/null, don't use it */ - my_free(histfile); - histfile= 0; + sprintf(histfile,"%s/.mariadb_history", home); + if (my_access(histfile, F_OK)) + { + /* no .mariadb_history, look for historical name and use if present */ + sprintf(histfile,"%s/.mysql_history", home); + /* and go back to original if not found */ + if (my_access(histfile, F_OK)) + sprintf(histfile,"%s/.mariadb_history", home); + } + char link_name[FN_REFLEN]; + if (my_readlink(link_name, histfile, 0) == 0 && + strncmp(link_name, "/dev/null", 10) == 0) + { + /* The .mariadb_history file is a symlink to /dev/null, don't use it */ + my_free(histfile); + histfile= 0; + } } } - /* We used to suggest setting MYSQL_HISTFILE=/dev/null. */ + /* We used to suggest setting MARIADB_HISTFILE=/dev/null. */ if (histfile && strncmp(histfile, "/dev/null", 10) == 0) histfile= NULL; @@ -1487,18 +1504,7 @@ static bool do_connect(MYSQL *mysql, const char *host, const char *user, { 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 && opt_protocol <= MYSQL_PROTOCOL_SOCKET) - { - 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, MARIADB_OPT_TLS_VERSION, opt_tls_version); - } - mysql_options(mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT, - (char*)&opt_ssl_verify_server_cert); -#endif + SET_SSL_OPTS_WITH_CHECK(mysql); if (opt_protocol) mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); if (opt_plugin_dir && *opt_plugin_dir) @@ -1824,6 +1830,8 @@ static struct my_option my_long_options[] = &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ULONG_MAX, 0, 1, 0}, {"server-arg", OPT_SERVER_ARG, "Send embedded server this as a parameter.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"show-query-costs", 0, "Show query cost after every statement.", + &show_query_cost, &show_query_cost, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"show-warnings", 0, "Show warnings after every statement.", &show_warnings, &show_warnings, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"sigint-ignore", 0, "Ignore SIGINT (CTRL-C).", &opt_sigint_ignore, @@ -1869,12 +1877,12 @@ static void usage(int version) #else const char* readline= "readline"; #endif - printf("%s Ver %s Distrib %s, for %s (%s) using %s %s\n", - my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE, + printf("%s from %s, client %s for %s (%s) using %s %s\n", + my_progname, MYSQL_SERVER_VERSION, VER, SYSTEM_TYPE, MACHINE_TYPE, readline, rl_library_version); #else - printf("%s Ver %s Distrib %s, for %s (%s), source revision %s\n", my_progname, VER, - MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE,SOURCE_REVISION); + printf("%s from %s, client %s for %s (%s), source revision %s\n", my_progname, + MYSQL_SERVER_VERSION, VER, SYSTEM_TYPE, MACHINE_TYPE,SOURCE_REVISION); #endif if (version) @@ -1987,7 +1995,7 @@ get_one_option(const struct my_option *opt, const char *argument, MySQL might still have this option in their commands, and it will not work in MariaDB unless it is handled. Therefore output a warning and continue. */ - printf("WARNING: option '--enable-cleartext-plugin' is obsolete.\n"); + printf("WARNING: option --enable-cleartext-plugin is obsolete.\n"); break; case 'A': opt_rehash= 0; @@ -3588,6 +3596,8 @@ end: /* Show warnings if any or error occurred */ if (show_warnings == 1 && (warnings >= 1 || error)) print_warnings(); + if (show_query_cost) + print_last_query_cost(); if (!error && !status.batch && (mysql.server_status & SERVER_STATUS_DB_DROPPED)) @@ -4193,6 +4203,33 @@ end: } +/* print_last_query_cost */ + +static void print_last_query_cost() +{ + const char *query; + char *end; + MYSQL_RES *result; + MYSQL_ROW cur; + + query= "show status like 'last_query_cost'"; + mysql_real_query_for_lazy(query, strlen(query)); + mysql_store_result_for_lazy(&result); + if (!result) + goto end; + + cur= mysql_fetch_row(result); + if (strtod(cur[1], &end) != 0.0) + { + init_pager(); + tee_fprintf(PAGER, "%s: %s\n\n", cur[0], cur[1]); + } + +end: + mysql_free_result(result); +} + + static const char *array_value(const char **array, char key) { for (; *array; array+= 2) @@ -4763,6 +4800,18 @@ static int com_nowarnings(String *, char *) return 0; } +static int +com_query_cost(String *buffer __attribute__((unused)), + char *line __attribute__((unused))) +{ + show_query_cost= 1 - show_query_cost; + if (show_query_cost) + put_info("Last_query_cost enabled.",INFO_INFO); + else + put_info("Last_query_cost disabled.",INFO_INFO); + return 0; +} + /* Gets argument from a command on the command line. If mode is not GET_NEXT, skips the command and returns the first argument. The line is modified by @@ -5015,6 +5064,10 @@ static int com_status(String *, char *) ulonglong id; MYSQL_RES *UNINIT_VAR(result); + /* + Don't remove "limit 1", + it is protection against SQL_SELECT_LIMIT=0 + */ if (mysql_real_query_for_lazy( C_STRING_WITH_LEN("select DATABASE(), USER() limit 1"))) return 0; @@ -5022,10 +5075,6 @@ static int com_status(String *, char *) tee_puts("--------------", stdout); usage(1); /* Print version */ tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",mysql_thread_id(&mysql)); - /* - Don't remove "limit 1", - it is protection against SQL_SELECT_LIMIT=0 - */ if (!mysql_store_result_for_lazy(&result)) { MYSQL_ROW cur=mysql_fetch_row(result); @@ -5039,8 +5088,8 @@ static int com_status(String *, char *) #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) if ((status_str= mysql_get_ssl_cipher(&mysql))) - tee_fprintf(stdout, "SSL:\t\t\tCipher in use is %s\n", - status_str); + tee_fprintf(stdout, "SSL:\t\t\tCipher in use is %s, cert is %s\n", + status_str, opt_ssl_verify_server_cert ? "OK" : "UNKNOWN"); else #endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */ tee_puts("SSL:\t\t\tNot in use", stdout); diff --git a/client/mysql_plugin.c b/client/mysql_plugin.c index a96af015..44abe861 100644 --- a/client/mysql_plugin.c +++ b/client/mysql_plugin.c @@ -15,17 +15,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ +#define VER "1.0" #include <my_global.h> #include <m_string.h> #include <mysql.h> #include <my_getopt.h> #include <my_dir.h> #include <mysql_version.h> - -#define SHOW_VERSION "1.0.0" -#define PRINT_VERSION do { printf("%s Ver %s Distrib %s\n", \ - my_progname, SHOW_VERSION, MYSQL_SERVER_VERSION); \ - } while(0) +#include <welcome_copyright_notice.h> /* Global variables. */ static uint my_end_arg= 0; @@ -418,7 +415,7 @@ exit: static void usage(void) { - PRINT_VERSION; + print_version(); puts("Copyright (c) 2011, 2015, Oracle and/or its affiliates. " "All rights reserved.\n"); puts("Enable or disable plugins."); @@ -504,7 +501,7 @@ get_one_option(const struct my_option *opt, opt_verbose++; break; case 'V': - PRINT_VERSION; + print_version(); exit(0); break; case '?': diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index fd6e1abc..3f60d169 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -18,11 +18,10 @@ #include "client_priv.h" #include <sslopt-vars.h> -#include <../scripts/mysql_fix_privilege_tables_sql.c> - -#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ +#include <../scripts/mariadb_fix_privilege_tables_sql.c> #define VER "2.1" +#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> @@ -302,8 +301,7 @@ get_one_option(const struct my_option *opt, const char *argument, switch (opt->id) { case '?': - printf("%s Ver %s Distrib %s, for %s (%s)\n", - my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); + print_version(); puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000")); puts("MariaDB utility for upgrading databases to new MariaDB versions."); print_defaults("my", load_default_groups); @@ -709,7 +707,7 @@ static int get_upgrade_info_file_name(char* name) dynstr_free(&ds_datadir); - fn_format(name, "mysql_upgrade_info", name, "", MYF(0)); + fn_format(name, "mariadb_upgrade_info", name, "", MYF(0)); DBUG_PRINT("exit", ("name: %s", name)); DBUG_RETURN(0); } @@ -718,7 +716,7 @@ static char upgrade_info_file[FN_REFLEN]= {0}; /* - Open or create mysql_upgrade_info file in servers data dir. + Open or create mariadb_upgrade_info file in servers data dir. Take a lock to ensure there cannot be any other mysql_upgrades running concurrently @@ -733,10 +731,19 @@ const char *create_error_message= static void open_mysql_upgrade_file() { char errbuff[80]; + char old_upgrade_info_file[FN_REFLEN]= {0}; + size_t path_len; + if (get_upgrade_info_file_name(upgrade_info_file)) { die("Upgrade failed"); } + + // Delete old mysql_upgrade_info file + dirname_part(old_upgrade_info_file, upgrade_info_file, &path_len); + fn_format(old_upgrade_info_file, "mysql_upgrade_info", old_upgrade_info_file, "", MYF(0)); + my_delete(old_upgrade_info_file, MYF(MY_IGNORE_ENOENT)); + if ((info_file= my_create(upgrade_info_file, 0, O_RDWR | O_NOFOLLOW, MYF(0))) < 0) @@ -793,7 +800,7 @@ static int faulty_server_versions(const char *version) } /* - Read the content of mysql_upgrade_info file and + Read the content of mariadb_upgrade_info file and compare the version number form file against version number which mysql_upgrade was compiled for @@ -870,15 +877,15 @@ static int upgrade_already_done(int silent) if (!silent) { verbose("This installation of MariaDB is already upgraded to %s.\n" - "There is no need to run mysql_upgrade again for %s.", + "There is no need to run mariadb-upgrade again for %s.", upgrade_from_version, version); if (!opt_check_upgrade) - verbose("You can use --force if you still want to run mysql_upgrade"); + verbose("You can use --force if you still want to run mariadb-upgrade"); } return 0; } -static void finish_mysql_upgrade_info_file(void) +static void finish_mariadb_upgrade_info_file(void) { if (info_file < 0) return; @@ -1335,7 +1342,7 @@ static int run_sql_fix_privilege_tables(void) a forked mysql client, because the script uses session variables and prepared statements. */ - for ( query_ptr= &mysql_fix_privilege_tables[0]; + for ( query_ptr= &mariadb_fix_privilege_tables[0]; *query_ptr != NULL; query_ptr++ ) @@ -1491,7 +1498,7 @@ int main(int argc, char **argv) printf("The --upgrade-system-tables option was used, user tables won't be touched.\n"); /* - Read the mysql_upgrade_info file to check if mysql_upgrade + Read the mariadb_upgrade_info file to check if mysql_upgrade already has been run for this installation of MariaDB */ if (!opt_force && !upgrade_already_done(0)) @@ -1519,7 +1526,7 @@ int main(int argc, char **argv) verbose("OK"); /* Finish writing indicating upgrade has been performed */ - finish_mysql_upgrade_info_file(); + finish_mariadb_upgrade_info_file(); DBUG_ASSERT(phase == phases_total); diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 01b012d3..77bcdf50 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -17,6 +17,7 @@ /* maintenance of mysql databases */ +#define VER "10.0" #include "client_priv.h" #include <signal.h> #include <my_pthread.h> /* because of signal() */ @@ -28,23 +29,18 @@ #include <password.h> #include <my_sys.h> -#define ADMIN_VERSION "10.0" #define MAX_MYSQL_VAR 512 #define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */ -#define MAX_TRUNC_LENGTH 3 char *host= NULL, *user= 0, *opt_password= 0, *default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME; -char truncated_var_names[MAX_MYSQL_VAR+100][MAX_TRUNC_LENGTH]; -char ex_var_names[MAX_MYSQL_VAR+100][FN_REFLEN]; ulonglong last_values[MAX_MYSQL_VAR+100]; static int interval=0; -static my_bool option_force=0,interrupted=0,new_line=0, - opt_compress= 0, opt_local= 0, opt_relative= 0, - opt_vertical= 0, tty_password= 0, opt_nobeep, +static my_bool option_force=0,interrupted=0,new_line=0, opt_compress= 0, + opt_local= 0, opt_relative= 0, tty_password= 0, opt_nobeep, opt_shutdown_wait_for_slaves= 0, opt_not_used; static my_bool debug_info_flag= 0, debug_check_flag= 0; -static uint tcp_port = 0, option_wait = 0, option_silent=0, nr_iterations; +static uint opt_mysql_port = 0, option_wait = 0, option_silent=0, nr_iterations; static uint opt_count_iterations= 0, my_end_arg, opt_verbose= 0; static ulong opt_connect_timeout, opt_shutdown_timeout; static char * unix_port=0; @@ -54,15 +50,7 @@ static bool sql_log_bin_off= false; static uint opt_protocol=0; static myf error_flags; /* flags to pass to my_printf_error, like ME_BELL */ -/* - When using extended-status relatively, ex_val_max_len is the estimated - maximum length for any relative value printed by extended-status. The - idea is to try to keep the length of output as short as possible. -*/ - -static uint ex_val_max_len[MAX_MYSQL_VAR]; static my_bool ex_status_printed = 0; /* First output is not relative. */ -static uint ex_var_count, max_var_length, max_val_length; #include <sslopt-vars.h> @@ -80,14 +68,9 @@ static void print_header(MYSQL_RES *result); static void print_top(MYSQL_RES *result); static void print_row(MYSQL_RES *result,MYSQL_ROW cur, uint row); static void print_relative_row(MYSQL_RES *result, MYSQL_ROW cur, uint row); -static void print_relative_row_vert(MYSQL_RES *result, MYSQL_ROW cur, uint row); -static void print_relative_header(); -static void print_relative_line(); -static void truncate_names(); static my_bool get_pidfile(MYSQL *mysql, char *pidfile); static my_bool wait_pidfile(char *pidfile, time_t last_modified, struct stat *pidfile_status); -static void store_values(MYSQL_RES *result); /* The order of commands must be the same as command_names, @@ -183,7 +166,7 @@ static struct my_option my_long_options[] = "/etc/services, " #endif "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").", - &tcp_port, &tcp_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + &opt_mysql_port, &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"protocol", OPT_MYSQL_PROTOCOL, "The protocol to use for connection (tcp, socket, pipe).", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"relative", 'r', @@ -210,10 +193,6 @@ static struct my_option my_long_options[] = &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}, - {"vertical", 'E', - "Print output vertically. Is similar to --relative, but prints output vertically.", - &opt_vertical, &opt_vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0, - 0, 0, 0}, {"wait", 'w', "Wait and retry if connection is down.", 0, 0, 0, GET_UINT, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"connect_timeout", 0, "", &opt_connect_timeout, @@ -391,18 +370,9 @@ int main(int argc,char *argv[]) uint tmp=opt_connect_timeout; mysql_options(&mysql,MYSQL_OPT_CONNECT_TIMEOUT, (char*) &tmp); } -#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, MARIADB_OPT_TLS_VERSION, opt_tls_version); - } - mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT, - (char*)&opt_ssl_verify_server_cert); -#endif + + SET_SSL_OPTS_WITH_CHECK(&mysql); + if (opt_protocol) mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); if (!strcmp(default_charset,MYSQL_AUTODETECT_CHARSET_NAME)) @@ -563,7 +533,7 @@ static my_bool sql_connect(MYSQL *mysql, uint wait) for (;;) { - if (mysql_real_connect(mysql,host,user,opt_password,NullS,tcp_port, + if (mysql_real_connect(mysql,host,user,opt_password,NullS,opt_mysql_port, unix_port, CLIENT_REMEMBER_OPTIONS)) { my_bool reconnect= 1; @@ -595,9 +565,9 @@ static my_bool sql_connect(MYSQL *mysql, uint wait) { fprintf(stderr,"Check that mariadbd is running on %s",host); fprintf(stderr," and that the port is %d.\n", - tcp_port ? tcp_port: mysql_port); + opt_mysql_port ? opt_mysql_port: mysql_port); fprintf(stderr,"You can check this by doing 'telnet %s %d'\n", - host, tcp_port ? tcp_port: mysql_port); + host, opt_mysql_port ? opt_mysql_port: mysql_port); } } return 1; @@ -943,43 +913,17 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) DBUG_ASSERT(mysql_num_rows(res) < MAX_MYSQL_VAR+100); - if (!opt_vertical) - print_header(res); - else - { - if (!ex_status_printed) - { - store_values(res); - truncate_names(); /* Does some printing also */ - } - else - { - print_relative_line(); - print_relative_header(); - print_relative_line(); - } - } + print_header(res); /* void (*func) (MYSQL_RES*, MYSQL_ROW, uint); */ - if (opt_relative && !opt_vertical) - func = print_relative_row; - else if (opt_vertical) - func = print_relative_row_vert; + if (opt_relative) + func = print_relative_row; else - func = print_row; + func = print_row; while ((row = mysql_fetch_row(res))) - (*func)(res, row, rownr++); - if (opt_vertical) - { - if (ex_status_printed) - { - putchar('\n'); - print_relative_line(); - } - } - else - print_top(res); + (*func)(res, row, rownr++); + print_top(res); ex_status_printed = 1; /* From now on the output will be relative */ mysql_free_result(res); @@ -1350,13 +1294,6 @@ static char **mask_password(int argc, char ***argv) return(temp_argv); } -static void print_version(void) -{ - printf("%s Ver %s Distrib %s, for %s on %s\n",my_progname,ADMIN_VERSION, - MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE); -} - - static void usage(void) { print_version(); @@ -1547,114 +1484,6 @@ static void print_relative_row(MYSQL_RES *result, MYSQL_ROW cur, uint row) } -static void print_relative_row_vert(MYSQL_RES *result __attribute__((unused)), - MYSQL_ROW cur, - uint row __attribute__((unused))) -{ - uint length; - ulonglong tmp; - char buff[22]; - - if (!row) - putchar('|'); - - tmp = cur[1] ? strtoull(cur[1], NULL, 10) : (ulonglong) 0; - printf(" %-*s|", ex_val_max_len[row] + 1, - llstr((tmp - last_values[row]), buff)); - - /* Find the minimum row length needed to output the relative value */ - length=(uint) strlen(buff); - if (length > ex_val_max_len[row] && ex_status_printed) - ex_val_max_len[row] = length; - last_values[row] = tmp; -} - - -static void store_values(MYSQL_RES *result) -{ - uint i; - MYSQL_ROW row; - MYSQL_FIELD *field; - - field = mysql_fetch_field(result); - max_var_length = field->max_length; - field = mysql_fetch_field(result); - max_val_length = field->max_length; - - for (i = 0; (row = mysql_fetch_row(result)); i++) - { - strmov(ex_var_names[i], row[0]); - last_values[i]=strtoull(row[1],NULL,10); - ex_val_max_len[i]=2; /* Default print width for values */ - } - ex_var_count = i; - return; -} - - -static void print_relative_header() -{ - uint i; - - putchar('|'); - for (i = 0; i < ex_var_count; i++) - printf(" %-*s|", ex_val_max_len[i] + 1, truncated_var_names[i]); - putchar('\n'); -} - - -static void print_relative_line() -{ - uint i; - - putchar('+'); - for (i = 0; i < ex_var_count; i++) - { - uint j; - for (j = 0; j < ex_val_max_len[i] + 2; j++) - putchar('-'); - putchar('+'); - } - putchar('\n'); -} - - -static void truncate_names() -{ - uint i; - char *ptr,top_line[MAX_TRUNC_LENGTH+4+NAME_LEN+22+1],buff[22]; - - ptr=top_line; - *ptr++='+'; - ptr=strfill(ptr,max_var_length+2,'-'); - *ptr++='+'; - ptr=strfill(ptr,MAX_TRUNC_LENGTH+2,'-'); - *ptr++='+'; - ptr=strfill(ptr,max_val_length+2,'-'); - *ptr++='+'; - *ptr=0; - puts(top_line); - - for (i = 0 ; i < ex_var_count; i++) - { - uint sfx=1,j; - printf("| %-*s|", max_var_length + 1, ex_var_names[i]); - ptr = ex_var_names[i]; - /* Make sure no two same truncated names will become */ - for (j = 0; j < i; j++) - if (*truncated_var_names[j] == *ptr) - sfx++; - - truncated_var_names[i][0]= *ptr; /* Copy first var char */ - int10_to_str(sfx, truncated_var_names[i]+1,10); - printf(" %-*s|", MAX_TRUNC_LENGTH + 1, truncated_var_names[i]); - printf(" %-*s|\n", max_val_length + 1, llstr(last_values[i],buff)); - } - puts(top_line); - return; -} - - static my_bool get_pidfile(MYSQL *mysql, char *pidfile) { MYSQL_RES* result; diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 8caf39b2..a998fb48 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -29,6 +29,7 @@ Format_desc_of_slave, Rotate_of_master, Format_desc_of_master. */ +#define VER "3.5" #define MYSQL_CLIENT #undef MYSQL_SERVER #define TABLE TABLE_CLIENT @@ -51,6 +52,7 @@ #include "sql_string.h" // needed for Rpl_filter #include "sql_list.h" // needed for Rpl_filter #include "rpl_filter.h" +#include "charset_collations.h" #include "mysqld.h" @@ -80,7 +82,7 @@ DYNAMIC_ARRAY events_in_stmt; // Storing the events that in one statement String stop_event_string; // Storing the STOP_EVENT output string extern "C" { -char server_version[SERVER_VERSION_LENGTH]; +char server_version[SERVER_VERSION_LENGTH]="5.0.0"; } static char *server_id_str; @@ -132,13 +134,13 @@ static ulong opt_stop_never_slave_server_id= 0; static my_bool opt_verify_binlog_checksum= 1; static ulonglong offset = 0; static char* host = 0; -static int port= 0; +static int opt_mysql_port= 0; static uint my_end_arg; static const char* sock= 0; static char *opt_plugindir= 0, *opt_default_auth= 0; static char* user = 0; -static char* pass = 0; +static char* opt_password = 0; static char *charset= 0; static uint verbose= 0; @@ -274,16 +276,10 @@ class Load_log_processor When we see first event corresponding to some LOAD DATA statement in binlog, we create temporary file to store data to be loaded. We add name of this file to file_names array using its file_id as index. - If we have Create_file event (i.e. we have binary log in pre-5.0.3 - format) we also store save event object to be able which is needed to - emit LOAD DATA statement when we will meet Exec_load_data event. - If we have Begin_load_query event we simply store 0 in - File_name_record::event field. */ struct File_name_record { char *fname; - Create_file_log_event *event; }; /* @todo Should be a map (e.g., a hash map), not an array. With the @@ -353,7 +349,6 @@ public: if (ptr->fname) { my_free(ptr->fname); - delete ptr->event; bzero((char *)ptr, sizeof(File_name_record)); } } @@ -362,34 +357,6 @@ public: } /** - Obtain Create_file event for LOAD DATA statement by its file_id - and remove it from this Load_log_processor's list of events. - - Checks whether we have already seen a Create_file_log_event with - the given file_id. If yes, returns a pointer to the event and - removes the event from array describing active temporary files. - From this moment, the caller is responsible for freeing the memory - occupied by the event. - - @param[in] file_id File id identifying LOAD DATA statement. - - @return Pointer to Create_file_log_event, or NULL if we have not - seen any Create_file_log_event with this file_id. - */ - Create_file_log_event *grab_event(uint file_id) - { - File_name_record *ptr; - Create_file_log_event *res; - - if (file_id >= file_names.elements) - return 0; - ptr= dynamic_element(&file_names, file_id, File_name_record*); - if ((res= ptr->event)) - bzero((char *)ptr, sizeof(File_name_record)); - return res; - } - - /** Obtain file name of temporary file for LOAD DATA statement by its file_id and remove it from this Load_log_processor's list of events. @@ -412,125 +379,19 @@ public: if (file_id >= file_names.elements) return 0; ptr= dynamic_element(&file_names, file_id, File_name_record*); - if (!ptr->event) - { - res= ptr->fname; - bzero((char *)ptr, sizeof(File_name_record)); - } + res= ptr->fname; + bzero((char *)ptr, sizeof(File_name_record)); return res; } - Exit_status process(Create_file_log_event *ce); - Exit_status process(Begin_load_query_log_event *ce); + Exit_status process(Begin_load_query_log_event *blqe); Exit_status process(Append_block_log_event *ae); - File prepare_new_file_for_old_format(Load_log_event *le, char *filename); - Exit_status load_old_format_file(NET* net, const char *server_fname, - uint server_fname_len, File file); Exit_status process_first_event(const char *bname, size_t blen, const uchar *block, - size_t block_len, uint file_id, - Create_file_log_event *ce); + size_t block_len, uint file_id); }; /** - Creates and opens a new temporary file in the directory specified by previous call to init_by_dir_name() or init_by_cur_dir(). - - @param[in] le The basename of the created file will start with the - basename of the file pointed to by this Load_log_event. - - @param[out] filename Buffer to save the filename in. - - @return File handle >= 0 on success, -1 on error. -*/ -File Load_log_processor::prepare_new_file_for_old_format(Load_log_event *le, - char *filename) -{ - size_t len; - char *tail; - File file; - - fn_format(filename, le->fname, target_dir_name, "", MY_REPLACE_DIR); - len= strlen(filename); - tail= filename + len; - - if ((file= create_unique_file(filename,tail)) < 0) - { - error("Could not construct local filename %s.",filename); - return -1; - } - - le->set_fname_outside_temp_buf(filename,len+strlen(tail)); - - return file; -} - - -/** - Reads a file from a server and saves it locally. - - @param[in,out] net The server to read from. - - @param[in] server_fname The name of the file that the server should - read. - - @param[in] server_fname_len The length of server_fname. - - @param[in,out] file The file to write to. - - @retval ERROR_STOP An error occurred - the program should terminate. - @retval OK_CONTINUE No error, the program should continue. -*/ -Exit_status Load_log_processor::load_old_format_file(NET* net, - const char*server_fname, - uint server_fname_len, - File file) -{ - uchar buf[FN_REFLEN+1]; - buf[0] = 0; - memcpy(buf + 1, server_fname, server_fname_len + 1); - if (my_net_write(net, buf, server_fname_len +2) || net_flush(net)) - { - error("Failed requesting the remote dump of %s.", server_fname); - return ERROR_STOP; - } - - for (;;) - { - ulong packet_len = my_net_read(net); - if (packet_len == 0) - { - if (my_net_write(net, (uchar*) "", 0) || net_flush(net)) - { - error("Failed sending the ack packet."); - return ERROR_STOP; - } - /* - we just need to send something, as the server will read but - not examine the packet - this is because mysql_load() sends - an OK when it is done - */ - break; - } - else if (packet_len == packet_error) - { - error("Failed reading a packet during the dump of %s.", server_fname); - return ERROR_STOP; - } - - if (packet_len > UINT_MAX) - { - error("Illegal length of packet read from net."); - return ERROR_STOP; - } - if (my_write(file, net->read_pos, (uint) packet_len, MYF(MY_WME|MY_NABP))) - return ERROR_STOP; - } - - return OK_CONTINUE; -} - - -/** Process the first event in the sequence of events representing a LOAD DATA statement. @@ -553,8 +414,7 @@ Exit_status Load_log_processor::process_first_event(const char *bname, size_t blen, const uchar *block, size_t block_len, - uint file_id, - Create_file_log_event *ce) + uint file_id) { size_t full_len= target_dir_name_len + blen + 9 + 9 + 1; Exit_status retval= OK_CONTINUE; @@ -566,7 +426,6 @@ Exit_status Load_log_processor::process_first_event(const char *bname, if (!(fname= (char*) my_malloc(PSI_NOT_INSTRUMENTED, full_len,MYF(MY_WME)))) { error("Out of memory."); - delete ce; DBUG_RETURN(ERROR_STOP); } @@ -581,12 +440,10 @@ Exit_status Load_log_processor::process_first_event(const char *bname, error("Could not construct local filename %s%s.", target_dir_name,bname); my_free(fname); - delete ce; DBUG_RETURN(ERROR_STOP); } rec.fname= fname; - rec.event= ce; /* fname is freed in process_event() @@ -597,13 +454,9 @@ Exit_status Load_log_processor::process_first_event(const char *bname, { error("Out of memory."); my_free(fname); - delete ce; DBUG_RETURN(ERROR_STOP); } - if (ce) - ce->set_fname_outside_temp_buf(fname, strlen(fname)); - if (my_write(file, (uchar*)block, block_len, MYF(MY_WME|MY_NABP))) { error("Failed writing to file."); @@ -619,31 +472,11 @@ Exit_status Load_log_processor::process_first_event(const char *bname, /** - Process the given Create_file_log_event. - - @see Load_log_processor::process_first_event(const char*,uint,const char*,uint,uint,Create_file_log_event*) - - @param ce Create_file_log_event to process. - - @retval ERROR_STOP An error occurred - the program should terminate. - @retval OK_CONTINUE No error, the program should continue. -*/ -Exit_status Load_log_processor::process(Create_file_log_event *ce) -{ - const char *bname= ce->fname + dirname_length(ce->fname); - size_t blen= ce->fname_len - (bname-ce->fname); - - return process_first_event(bname, blen, ce->block, ce->block_len, - ce->file_id, ce); -} - - -/** Process the given Begin_load_query_log_event. @see Load_log_processor::process_first_event(const char*,uint,const char*,uint,uint,Create_file_log_event*) - @param ce Begin_load_query_log_event to process. + @param blqe Begin_load_query_log_event to process. @retval ERROR_STOP An error occurred - the program should terminate. @retval OK_CONTINUE No error, the program should continue. @@ -651,7 +484,7 @@ Exit_status Load_log_processor::process(Create_file_log_event *ce) Exit_status Load_log_processor::process(Begin_load_query_log_event *blqe) { return process_first_event("SQL_LOAD_MB", 11, blqe->block, blqe->block_len, - blqe->file_id, 0); + blqe->file_id); } @@ -1242,41 +1075,6 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, break; } - case CREATE_FILE_EVENT: - { - Create_file_log_event* ce= (Create_file_log_event*)ev; - /* - We test if this event has to be ignored. If yes, we don't save - this event; this will have the good side-effect of ignoring all - related Append_block and Exec_load. - Note that Load event from 3.23 is not tested. - */ - if (shall_skip_database(ce->db)) - goto end; // Next event - /* - We print the event, but with a leading '#': this is just to inform - the user of the original command; the command we want to execute - will be a derivation of this original command (we will change the - filename and use LOCAL), prepared in the 'case EXEC_LOAD_EVENT' - below. - */ - print_skip_replication_statement(print_event_info, ev); - if (ce->print(result_file, print_event_info, TRUE)) - goto err; - // If this binlog is not 3.23 ; why this test?? - if (glob_description_event->binlog_version >= 3) - { - /* - transfer the responsibility for destroying the event to - load_processor - */ - ev= NULL; - if ((retval= load_processor.process(ce)) != OK_CONTINUE) - goto end; - } - break; - } - case APPEND_BLOCK_EVENT: /* Append_block_log_events can safely print themselves even if @@ -1290,36 +1088,6 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, goto end; break; - case EXEC_LOAD_EVENT: - { - if (ev->print(result_file, print_event_info)) - goto err; - Execute_load_log_event *exv= (Execute_load_log_event*)ev; - Create_file_log_event *ce= load_processor.grab_event(exv->file_id); - /* - if ce is 0, it probably means that we have not seen the Create_file - event (a bad binlog, or most probably --start-position is after the - Create_file event). Print a warning comment. - */ - if (ce) - { - bool error; - /* - We must not convert earlier, since the file is used by - my_open() in Load_log_processor::append(). - */ - convert_path_to_forward_slashes((char*) ce->fname); - error= ce->print(result_file, print_event_info, TRUE); - my_free((void*)ce->fname); - delete ce; - if (error) - goto err; - } - else - warning("Ignoring Execute_load_log_event as there is no " - "Create_file event for file_id: %u", exv->file_id); - break; - } case FORMAT_DESCRIPTION_EVENT: delete glob_description_event; glob_description_event= (Format_description_log_event*) ev; @@ -1428,8 +1196,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, int tmp_sql_offset; conn = mysql_init(NULL); - if (!mysql_real_connect(conn, host, user, pass, - map->get_db_name(), port, sock, 0)) + if (!mysql_real_connect(conn, host, user, opt_password, + map->get_db_name(), opt_mysql_port, sock, 0)) { fprintf(stderr, "%s\n", mysql_error(conn)); exit(1); @@ -1576,23 +1344,14 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, destroy_evt= FALSE; break; } - case PRE_GA_WRITE_ROWS_EVENT: - case PRE_GA_DELETE_ROWS_EVENT: - case PRE_GA_UPDATE_ROWS_EVENT: - { - Old_rows_log_event *e= (Old_rows_log_event*) ev; - bool is_stmt_end= e->get_flags(Rows_log_event::STMT_END_F); - if (print_row_event(print_event_info, ev, e->get_table_id(), - e->get_flags(Old_rows_log_event::STMT_END_F))) - goto err; - DBUG_PRINT("info", ("is_stmt_end: %d", (int) is_stmt_end)); - if (!is_stmt_end && opt_flashback) - destroy_evt= FALSE; - break; - } case START_ENCRYPTION_EVENT: glob_description_event->start_decryption((Start_encryption_log_event*)ev); /* fall through */ + case PRE_GA_WRITE_ROWS_EVENT: + case PRE_GA_DELETE_ROWS_EVENT: + case PRE_GA_UPDATE_ROWS_EVENT: + case CREATE_FILE_EVENT: + case EXEC_LOAD_EVENT: default: print_skip_replication_statement(print_event_info, ev); if (ev->print(result_file, print_event_info)) @@ -1743,7 +1502,7 @@ static struct my_option my_options[] = "/etc/services, " #endif "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").", - &port, &port, 0, GET_INT, REQUIRED_ARG, + &opt_mysql_port, &opt_mysql_port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"protocol", OPT_MYSQL_PROTOCOL, "The protocol to use for connection (tcp, socket, pipe).", @@ -2010,7 +1769,7 @@ static void warning(const char *format,...) static void cleanup() { DBUG_ENTER("cleanup"); - my_free(pass); + my_free(opt_password); my_free(database); my_free(table); my_free(host); @@ -2157,12 +1916,6 @@ static void die(int err) } -static void print_version() -{ - printf("%s Ver 3.5 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE); -} - - static void usage() { print_version(); @@ -2337,9 +2090,9 @@ get_one_option(const struct my_option *opt, const char *argument, One should not really change the argument, but we make an exception for passwords */ - my_free(pass); + my_free(opt_password); char *start= (char*) argument; - pass= my_strdup(PSI_NOT_INSTRUMENTED, argument,MYF(MY_FAE)); + opt_password= my_strdup(PSI_NOT_INSTRUMENTED, argument,MYF(MY_FAE)); while (*argument) *(char*)argument++= 'x'; /* Destroy argument */ if (*start) @@ -2503,7 +2256,7 @@ get_one_option(const struct my_option *opt, const char *argument, break; } if (tty_password) - pass= my_get_tty_password(NullS); + opt_password= my_get_tty_password(NullS); return 0; } @@ -2593,18 +2346,7 @@ 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, MARIADB_OPT_TLS_VERSION, opt_tls_version); - } - mysql_options(mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT, - (char*)&opt_ssl_verify_server_cert); -#endif /*HAVE_OPENSSL*/ + SET_SSL_OPTS_WITH_CHECK(mysql); if (opt_plugindir && *opt_plugindir) mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugindir); @@ -2617,7 +2359,7 @@ static Exit_status safe_connect() 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)) + if (!mysql_real_connect(mysql, host, user, opt_password, 0, opt_mysql_port, sock, 0)) { error("Failed on connect: %s", mysql_error(mysql)); return ERROR_STOP; @@ -2791,21 +2533,10 @@ static Exit_status check_master_version() glob_description_event= NULL; switch (version) { - case 3: - glob_description_event= new Format_description_log_event(1); - break; - case 4: - glob_description_event= new Format_description_log_event(3); - break; 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. - So we first assume that this is 4.0 (which is enough to read the - Format_desc event if one comes). - */ - glob_description_event= new Format_description_log_event(3); + case 11: + glob_description_event= new Format_description_log_event(4); break; default: error("Could not find server version: " @@ -2864,8 +2595,6 @@ static Exit_status handle_event_text_mode(PRINT_EVENT_INFO *print_event_info, } Log_event_type type= ev->get_type_code(); - if (glob_description_event->binlog_version >= 3 || - (type != LOAD_EVENT && type != CREATE_FILE_EVENT)) { /* If this is a Rotate event, maybe it's the end of the requested binlog; @@ -2924,31 +2653,6 @@ static Exit_status handle_event_text_mode(PRINT_EVENT_INFO *print_event_info, if (retval != OK_CONTINUE) DBUG_RETURN(retval); } - else - { - Load_log_event *le= (Load_log_event*)ev; - const char *old_fname= le->fname; - uint old_len= le->fname_len; - File file; - Exit_status retval; - char fname[FN_REFLEN+1]; - - 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) - { - my_close(file,MYF(MY_WME)); - DBUG_RETURN(retval); - } - retval= load_processor.load_old_format_file(net,old_fname,old_len,file); - my_close(file,MYF(MY_WME)); - if (retval != OK_CONTINUE) - DBUG_RETURN(retval); - } DBUG_RETURN(OK_CONTINUE); } @@ -3221,7 +2925,7 @@ static Exit_status check_header(IO_CACHE* file, MY_STAT my_file_stat; delete glob_description_event; - if (!(glob_description_event= new Format_description_log_event(3))) + if (!(glob_description_event= new Format_description_log_event(4))) { error("Failed creating Format_description_log_event; out of memory?"); return ERROR_STOP; @@ -3293,25 +2997,7 @@ static Exit_status check_header(IO_CACHE* file, { DBUG_PRINT("info",("buf[EVENT_TYPE_OFFSET=%d]=%d", EVENT_TYPE_OFFSET, buf[EVENT_TYPE_OFFSET])); - /* always test for a Start_v3, even if no --start-position */ - if (buf[EVENT_TYPE_OFFSET] == START_EVENT_V3) - { - /* This is 3.23 or 4.x */ - if (uint4korr(buf + EVENT_LEN_OFFSET) < - (LOG_EVENT_MINIMAL_HEADER_LEN + START_V3_HEADER_LEN)) - { - /* This is 3.23 (format 1) */ - delete glob_description_event; - if (!(glob_description_event= new Format_description_log_event(1))) - { - error("Failed creating Format_description_log_event; " - "out of memory?"); - return ERROR_STOP; - } - } - break; - } - else if (tmp_pos >= start_position) + if (tmp_pos >= start_position) break; else if (buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) { @@ -3789,7 +3475,6 @@ struct encryption_service_st encryption_handler= #include "password.c" #include "log_event.cc" #include "log_event_client.cc" -#include "log_event_old.cc" #include "rpl_utility.cc" #include "sql_string.cc" #include "sql_list.cc" diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index fc93c416..aa9a78ef 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -18,7 +18,7 @@ /* By Jani Tolonen, 2001-04-20, MySQL Development Team */ -#define CHECK_VERSION "2.7.4-MariaDB" +#define VER "2.8" #include "client_priv.h" #include <m_ctype.h> @@ -228,7 +228,6 @@ static const char *load_default_groups[]= 0 }; -static void print_version(void); static void usage(void); static int get_options(int *argc, char ***argv); static int process_all_databases(); @@ -248,13 +247,6 @@ static char *fix_table_name(char *dest, char *src); int what_to_do = 0; -static void print_version(void) -{ - printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, CHECK_VERSION, - MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); -} /* print_version */ - - static void usage(void) { DBUG_ENTER("usage"); @@ -1137,18 +1129,7 @@ static int dbConnect(char *host, char *user, char *passwd) mysql_init(&mysql_connection); if (opt_compress) 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, MARIADB_OPT_TLS_VERSION, opt_tls_version); - } - mysql_options(&mysql_connection, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, - (char*)&opt_ssl_verify_server_cert); -#endif + SET_SSL_OPTS(&mysql_connection); if (opt_protocol) mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); diff --git a/client/mysqldump.c b/client/mysqldump.cc index 3ef8b1d6..e3952c27 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.cc @@ -40,7 +40,7 @@ */ /* on merge conflict, bump to a higher version again */ -#define DUMP_VERSION "10.19" +#define VER "10.19" /** First mysql version supporting sequences. @@ -61,7 +61,7 @@ #include "mysqld_error.h" #include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ - +#include "connection_pool.h" /* Exit codes */ #define EX_USAGE 1 @@ -150,7 +150,7 @@ static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0, select_field_names_inited= 0; static ulong opt_max_allowed_packet, opt_net_buffer_length; static double opt_max_statement_time= 0.0; -static MYSQL mysql_connection,*mysql=0; +static MYSQL *mysql=0; static DYNAMIC_STRING insert_pat, select_field_names, select_field_names_for_header; static char *opt_password=0,*current_user=0, *current_host=0,*path=0,*fields_terminated=0, @@ -193,7 +193,7 @@ FILE *stderror_file=0; static uint opt_protocol= 0; static char *opt_plugin_dir= 0, *opt_default_auth= 0; - +static uint opt_parallel= 0; /* Dynamic_string wrapper functions. In this file use these wrappers, they will terminate the process if there is @@ -245,6 +245,8 @@ static HASH ignore_table, ignore_data; static HASH ignore_database; +static async_pool::connection_pool connection_pool; + static struct my_option my_long_options[] = { {"all-databases", 'A', @@ -506,6 +508,8 @@ 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}, + {"parallel", 'j', "Number of dump table jobs executed in parallel (only with --tab option)", + &opt_parallel, &opt_parallel, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef _WIN32 {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -669,13 +673,6 @@ void check_io(FILE *file) die(EX_EOF, "Got errno %d on write", errno); } -static void print_version(void) -{ - printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname_short,DUMP_VERSION, - MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE); -} /* print_version */ - - static void short_usage_sub(FILE *f) { fprintf(f, "Usage: %s [OPTIONS] database [tables]\n", my_progname_short); @@ -750,10 +747,8 @@ static void write_header(FILE *sql_file, const char *db_name) fprintf(sql_file, "/*!999999\\- enable the sandbox mode */ \n"); if (!opt_compact) { - print_comment(sql_file, 0, - "-- MariaDB dump %s Distrib %s, for %s (%s)\n--\n", - DUMP_VERSION, MYSQL_SERVER_VERSION, SYSTEM_TYPE, - MACHINE_TYPE); + print_comment(sql_file, 0, "-- MariaDB dump %s-%s, for %s (%s)\n--\n", + VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); print_comment(sql_file, 0, "-- Host: %s ", fix_for_comment(current_host ? current_host : "localhost")); print_comment(sql_file, 0, "Database: %s\n", @@ -762,7 +757,7 @@ static void write_header(FILE *sql_file, const char *db_name) "-- ------------------------------------------------------\n" ); print_comment(sql_file, 0, "-- Server version\t%s\n", - mysql_get_server_info(&mysql_connection)); + mysql_get_server_info(mysql)); if (!opt_logging) fprintf(sql_file, @@ -794,7 +789,7 @@ static void write_header(FILE *sql_file, const char *db_name) } fprintf(sql_file, "/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='%s%s%s' */;\n" - "/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;\n", + "/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */;\n", path?"":"NO_AUTO_VALUE_ON_ZERO",compatible_mode_normal_str[0]==0?"":",", compatible_mode_normal_str); } @@ -832,7 +827,7 @@ static void write_footer(FILE *sql_file) "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n" "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n"); fprintf(sql_file, - "/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;\n"); + "/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */;\n"); fputs("\n", sql_file); if (opt_dump_date) @@ -1434,6 +1429,7 @@ static void maybe_die(int error_num, const char* fmt_reason, ...) static int mysql_query_with_error_report(MYSQL *mysql_con, MYSQL_RES **res, const char *query) { + DBUG_ASSERT(mysql_con); if (mysql_query(mysql_con, query) || (res && !((*res)= mysql_store_result(mysql_con)))) { @@ -1902,6 +1898,13 @@ static void free_resources() else fflush(md_result_file); } + if (first_error && mysql) + { + connection_pool.for_each_connection( + [](MYSQL *c) { mysql_kill(mysql,c->thread_id);}); + } + connection_pool.close(); + if (get_table_name_result) mysql_free_result(get_table_name_result); if (routine_res) @@ -1942,7 +1945,7 @@ static void maybe_exit(int error) if (ignore_errors) return; ignore_errors= 1; /* don't want to recurse, if something fails below */ - if (opt_slave_data) + if (opt_slave_data && mysql) do_start_slave_sql(mysql); free_resources(); exit(error); @@ -1953,49 +1956,38 @@ static void maybe_exit(int error) db_connect -- connects to the host and selects DB. */ -static int connect_to_db(char *host, char *user,char *passwd) +static MYSQL* connect_to_db(char *host, char *user,char *passwd) { char buff[20+FN_REFLEN]; my_bool reconnect; DBUG_ENTER("connect_to_db"); verbose_msg("-- Connecting to %s...\n", host ? host : "localhost"); - mysql_init(&mysql_connection); + MYSQL* con = mysql_init(NULL); if (opt_compress) - 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, MARIADB_OPT_TLS_VERSION, opt_tls_version); - } - mysql_options(&mysql_connection,MYSQL_OPT_SSL_VERIFY_SERVER_CERT, - (char*)&opt_ssl_verify_server_cert); -#endif + mysql_options(con,MYSQL_OPT_COMPRESS,NullS); + SET_SSL_OPTS_WITH_CHECK(con); if (opt_protocol) - mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); - mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset); + mysql_options(con,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); + mysql_options(con, MYSQL_SET_CHARSET_NAME, default_charset); if (opt_plugin_dir && *opt_plugin_dir) - mysql_options(&mysql_connection, MYSQL_PLUGIN_DIR, opt_plugin_dir); + mysql_options(con, MYSQL_PLUGIN_DIR, opt_plugin_dir); if (opt_default_auth && *opt_default_auth) - mysql_options(&mysql_connection, MYSQL_DEFAULT_AUTH, opt_default_auth); + mysql_options(con, 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, + mysql_options(con, MYSQL_OPT_CONNECT_ATTR_RESET, 0); + mysql_options4(con, 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, + if (!mysql_real_connect(con,host,user,passwd, NULL,opt_mysql_port,opt_mysql_unix_port, 0)) { - DB_error(&mysql_connection, "when trying to connect"); - DBUG_RETURN(1); + DB_error(con, "when trying to connect"); + goto err; } - if ((mysql_get_server_version(&mysql_connection) < 40100) || + + if ((mysql_get_server_version(con) < 40100) || (opt_compatible_mode & 3)) { /* Don't dump SET NAMES with a pre-4.1 server (bug#7997). */ @@ -2009,22 +2001,38 @@ static int connect_to_db(char *host, char *user,char *passwd) cannot reconnect. */ reconnect= 0; - mysql_options(&mysql_connection, MYSQL_OPT_RECONNECT, &reconnect); + mysql_options(con, MYSQL_OPT_RECONNECT, &reconnect); my_snprintf(buff, sizeof(buff), "/*!40100 SET @@SQL_MODE='%s' */", compatible_mode_normal_str); - if (mysql_query_with_error_report(mysql, 0, buff)) - DBUG_RETURN(1); + if (mysql_query_with_error_report(con, 0, buff)) + goto err; /* set time_zone to UTC to allow dumping date types between servers with different time zone settings */ if (opt_tz_utc) { - my_snprintf(buff, sizeof(buff), "/*!40103 SET TIME_ZONE='+00:00' */"); - if (mysql_query_with_error_report(mysql, 0, buff)) - DBUG_RETURN(1); + if (mysql_query_with_error_report(con, 0, + "/*!40103 SET TIME_ZONE='+00:00' */")) + goto err; } - DBUG_RETURN(0); + + /* Set MAX_STATEMENT_TIME to 0 unless set in client */ + my_snprintf(buff, sizeof(buff), "/*!100100 SET @@MAX_STATEMENT_TIME=%f */", + opt_max_statement_time); + if (mysql_query_with_error_report(con, 0, buff)) + goto err; + + /* Set server side timeout between client commands to server compiled-in default */ + if(mysql_query_with_error_report(con,0, "/*!100100 SET WAIT_TIMEOUT=DEFAULT */")) + goto err; + + DBUG_RETURN(con); + +err: + if (con) + mysql_close(con); + DBUG_RETURN(NULL); } /* connect_to_db */ @@ -2046,7 +2054,7 @@ static void unescape(FILE *file,char *pos, size_t length) if (!(tmp=(char*) my_malloc(PSI_NOT_INSTRUMENTED, length*2+1, MYF(MY_WME)))) die(EX_MYSQLERR, "Couldn't allocate memory"); - mysql_real_escape_string(&mysql_connection, tmp, pos, (ulong)length); + mysql_real_escape_string(mysql, tmp, pos, (ulong)length); fputc('\'', file); fputs(tmp, file); fputc('\'', file); @@ -4028,6 +4036,21 @@ static void vers_append_system_time(DYNAMIC_STRING* query_string) } } +/** + Completion handler for async queries in the pool. + Dies in case query produced an error. + + @param mysql The connection that executed the query. + @param query The query that was executed. + @param success Whether the query was successful. +*/ +static void send_query_completion_func(MYSQL* mysql, const char* query, + bool success, void*) +{ + if (!success) + maybe_die(EX_MYSQLERR, "Couldn't execute async query '%s' (%s)", query, + mysql_error(mysql)); +} /* @@ -4183,6 +4206,10 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, dynstr_append_checked(&query_string, select_field_names.str); } dynstr_append_checked(&query_string, " FROM "); + char quoted_db_buf[NAME_LEN * 2 + 3]; + char *qdatabase= quote_name(db, quoted_db_buf, opt_quoted); + dynstr_append_checked(&query_string, qdatabase); + dynstr_append_checked(&query_string, "."); dynstr_append_checked(&query_string, result_table); if (versioned) @@ -4206,8 +4233,16 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, my_free(order_by); order_by= 0; } - - if (mysql_real_query(mysql, query_string.str, (ulong)query_string.length)) + if (opt_parallel) + { + if (connection_pool.execute_async(query_string.str,send_query_completion_func,nullptr,true)) + { + dynstr_free(&query_string); + DB_error(mysql, "when executing send_query 'SELECT INTO OUTFILE'"); + DBUG_VOID_RETURN; + } + } + else if (mysql_real_query(mysql, query_string.str, (ulong)query_string.length)) { dynstr_free(&query_string); DB_error(mysql, "when executing 'SELECT INTO OUTFILE'"); @@ -4387,7 +4422,7 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, { dynstr_append_checked(&extended_row,"'"); extended_row.length += - mysql_real_escape_string(&mysql_connection, + mysql_real_escape_string(mysql, &extended_row.str[extended_row.length], row[i],length); extended_row.str[extended_row.length]='\0'; @@ -6761,7 +6796,7 @@ static char *primary_key_fields(const char *table_name) { char *end; /* result (terminating \0 is already in result_length) */ - result= my_malloc(PSI_NOT_INSTRUMENTED, result_length + 10, MYF(MY_WME)); + result= (char *)my_malloc(PSI_NOT_INSTRUMENTED, result_length + 10, MYF(MY_WME)); if (!result) { fprintf(stderr, "Error: Not enough memory to store ORDER BY clause\n"); @@ -7065,10 +7100,30 @@ static void dynstr_realloc_checked(DYNAMIC_STRING *str, ulong additional_size) die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG); } +#define MAX_POOL_CONNECTIONS 256 +static void init_connection_pool(uint n_connections) +{ + MYSQL *conn[MAX_POOL_CONNECTIONS]; + + if (n_connections > array_elements(conn)) + die(EX_USAGE, "Too many connections"); + + for (uint i= 0; i < n_connections; i++) + { + MYSQL *c= connect_to_db(current_host, current_user, opt_password); + if (!c) + { + for (uint j= 0; j < i; j++) + mysql_close(conn[j]); + die(EX_MYSQLERR, "Error during connection to DB"); + } + conn[i]= c; + } + connection_pool.init(conn, n_connections); +} int main(int argc, char **argv) { - char query[48]; char bin_log_name[FN_REFLEN]; int exit_code; int consistent_binlog_pos= 0; @@ -7102,20 +7157,24 @@ int main(int argc, char **argv) } } - if (connect_to_db(current_host, current_user, opt_password)) + mysql= connect_to_db(current_host, current_user, opt_password); + if (!mysql) { free_resources(); exit(EX_MYSQLERR); } if (!path) + { write_header(md_result_file, *argv); - - /* Set MAX_STATEMENT_TIME to 0 unless set in client */ - my_snprintf(query, sizeof(query), "/*!100100 SET @@MAX_STATEMENT_TIME=%f */", opt_max_statement_time); - mysql_query(mysql, query); - - /* Set server side timeout between client commands to server compiled-in default */ - mysql_query(mysql, "/*!100100 SET WAIT_TIMEOUT=DEFAULT */"); + if (opt_parallel) + { + verbose_msg("-- Warning: ignoring --parallel setting, it currently only " + "works together with --tab\n"); + opt_parallel= 0; + } + } + else if (opt_parallel) + init_connection_pool(opt_parallel); /* Check if the server support multi source */ if (mysql_get_server_version(mysql) >= 100000) @@ -7168,8 +7227,15 @@ int main(int argc, char **argv) goto err; } - if (opt_single_transaction && start_transaction(mysql)) - goto err; + if (opt_single_transaction) + { + if (start_transaction(mysql)) + goto err; + connection_pool.for_each_connection([](MYSQL *c) { + if (start_transaction(c)) + maybe_die(EX_MYSQLERR, "Failed to start transaction on connection ID %u", mysql->thread_id); + }); + } /* Add 'STOP SLAVE to beginning of dump */ if (opt_slave_apply && add_stop_slave()) @@ -7262,6 +7328,9 @@ int main(int argc, char **argv) if (opt_delete_master_logs && purge_bin_logs_to(mysql, bin_log_name)) goto err; + /* wait for outstanding asynchronous queries */ + connection_pool.wait_all(); + /* No reason to explicitly COMMIT the transaction, neither to explicitly UNLOCK TABLES: these will be automatically be done by the server when we diff --git a/client/mysqlimport.c b/client/mysqlimport.c index f23ba1e4..2f8a75c8 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -27,7 +27,7 @@ ** * * ** ************************* */ -#define IMPORT_VERSION "3.7" +#define VER "3.7" #include "client_priv.h" #include <my_sys.h> @@ -148,6 +148,9 @@ static struct my_option my_long_options[] = {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif + {"parallel", 'j', "Number of LOAD DATA jobs executed in parallel", + &opt_use_threads, &opt_use_threads, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, + 0, 0}, {"plugin_dir", 0, "Directory for client-side plugins.", &opt_plugin_dir, &opt_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -170,10 +173,8 @@ static struct my_option my_long_options[] = &opt_mysql_unix_port, &opt_mysql_unix_port, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #include <sslopt-longopts.h> - {"use-threads", 0, - "Load files in parallel. The argument is the number " - "of threads to use for loading data.", - &opt_use_threads, &opt_use_threads, 0, + {"use-threads", 0, "Synonym for --parallel option", + &opt_use_threads, &opt_use_threads, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifndef DONT_ALLOW_USER_CHANGE {"user", 'u', "User for login if not current user.", ¤t_user, @@ -192,13 +193,6 @@ static const char *load_default_groups[]= 0 }; -static void print_version(void) -{ - printf("%s Ver %s Distrib %s, for %s (%s)\n" ,my_progname, - IMPORT_VERSION, MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE); -} - - static void usage(void) { puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc."); @@ -467,18 +461,7 @@ static MYSQL *db_connect(char *host, char *database, if (opt_local_file) mysql_options(mysql,MYSQL_OPT_LOCAL_INFILE, (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, MARIADB_OPT_TLS_VERSION, opt_tls_version); - } - mysql_options(mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT, - (char*)&opt_ssl_verify_server_cert); -#endif + SET_SSL_OPTS(mysql); if (opt_protocol) mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 4ad31b65..7124b233 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -18,7 +18,7 @@ /* Show databases, tables or columns */ -#define SHOW_VERSION "9.10" +#define VER "9.10" #include "client_priv.h" #include <my_sys.h> @@ -120,18 +120,7 @@ int main(int argc, char **argv) mysql_init(&mysql); if (opt_compress) 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, MARIADB_OPT_TLS_VERSION, opt_tls_version); - } - mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT, - (char*)&opt_ssl_verify_server_cert); -#endif + SET_SSL_OPTS(&mysql); if (opt_protocol) mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); @@ -266,13 +255,6 @@ static struct my_option my_long_options[] = }; -static void print_version(void) -{ - printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,SHOW_VERSION, - MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE); -} - - static void usage(void) { print_version(); diff --git a/client/mysqlslap.c b/client/mysqlslap.c index 035a7f0d..a52269f8 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -67,7 +67,7 @@ TODO: */ -#define SLAP_VERSION "1.0" +#define VER "1.0" #define HUGE_STRING_LENGTH 8196 #define RAND_STRING_SIZE 126 @@ -295,18 +295,7 @@ void set_mysql_connect_options(MYSQL *mysql) { if (opt_compress) 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, MARIADB_OPT_TLS_VERSION, opt_tls_version); - } - mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, - (char*)&opt_ssl_verify_server_cert); -#endif + SET_SSL_OPTS(mysql); if (opt_protocol) mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset); @@ -706,13 +695,6 @@ static struct my_option my_long_options[] = }; -static void print_version(void) -{ - printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname, SLAP_VERSION, - MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE); -} - - static void usage(void) { print_version(); diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 46565095..c71afdc7 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -33,7 +33,7 @@ And many others */ -#define MTEST_VERSION "3.5" +#define VER "3.5" #include "client_priv.h" #include <mysql_version.h> @@ -290,6 +290,13 @@ DYNAMIC_ARRAY q_lines; #include "sslopt-vars.h" +#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) +static void set_ssl_opts(MYSQL *mysql, my_bool opt_use_ssl, char *opt_ssl_cipher) +{ + SET_SSL_OPTS(mysql); +} +#endif + struct Parser { int read_lines,current_line; @@ -362,7 +369,7 @@ enum enum_commands { Q_INC, Q_DEC, Q_SOURCE, Q_DISCONNECT, Q_LET, Q_ECHO, - Q_WHILE, Q_END_BLOCK, + Q_WHILE, Q_END_BLOCK, Q_BREAK, Q_SYSTEM, Q_RESULT, Q_REQUIRE, Q_SAVE_MASTER_POS, Q_SYNC_WITH_MASTER, @@ -433,6 +440,7 @@ const char *command_names[]= "echo", "while", "end", + "break", "system", "result", "require", @@ -4841,6 +4849,19 @@ void do_wait_for_slave_to_stop(struct st_command *c __attribute__((unused))) return; } +static const char *get_col_value(MYSQL_RES *res, MYSQL_ROW row, const char *name) +{ + uint num_fields= mysql_num_fields(res); + MYSQL_FIELD *fields= mysql_fetch_fields(res); + + for (uint i= 0; i < num_fields; i++) + { + if (strcmp(fields[i].name, name) == 0) + return row[i]; + } + return "NULL"; +} + void do_sync_with_master2(struct st_command *command, long offset, const char *connection_name) @@ -4848,7 +4869,7 @@ void do_sync_with_master2(struct st_command *command, long offset, MYSQL_RES *res; MYSQL_ROW row; MYSQL *mysql= cur_con->mysql; - char query_buf[FN_REFLEN+128]; + char query_buf[FN_REFLEN+128], query_buf2[120]; int timeout= opt_wait_for_pos_timeout; if (!master_pos.file[0]) @@ -4882,6 +4903,23 @@ void do_sync_with_master2(struct st_command *command, long offset, /* master_pos_wait returned NULL or < 0 */ fprintf(stderr, "analyze: sync_with_master\n"); + sprintf(query_buf2, "show slave \"%s\" status", connection_name); + + if (!mysql_query(mysql, query_buf2)) + { + if ((res= mysql_store_result(mysql))) + { + if ((row= mysql_fetch_row(res))) + { + fprintf(stderr, "Slave position: file: %s position: %s\n", + get_col_value(res, row, "Relay_Master_Log_File"), + get_col_value(res, row, "Read_Master_Log_Pos")); + fprintf(stderr, "Master position: file: %s position: %lld\n", + master_pos.file, (longlong) (master_pos.pos + offset)); + } + mysql_free_result(res); + } + } if (!result_str) { /* @@ -4890,10 +4928,9 @@ void do_sync_with_master2(struct st_command *command, long offset, information is not initialized, the arguments are incorrect, or an error has occurred */ - die("%.*b failed: '%s' returned NULL " \ + die("%.*b failed: '%s' returned NULL " \ "indicating slave SQL thread failure", command->first_word_len, command->query, query_buf); - } if (result == -1) @@ -6057,7 +6094,7 @@ void do_connect(struct st_command *command) int read_timeout= 0; int write_timeout= 0; int connect_timeout= 0; - char *csname=0; + char *csname=0, *rauth __attribute__((unused))= 0; struct st_connection* con_slot; my_bool default_db; @@ -6135,59 +6172,59 @@ void do_connect(struct st_command *command) while (*end && !my_isspace(charset_info, *end)) end++; length= (size_t) (end - con_options); - if (length == 3 && !strncmp(con_options, "SSL", 3)) + if (length == 3 && !strncmp(con_options, STRING_WITH_LEN("SSL"))) con_ssl= USE_SSL_REQUIRED; - else if (length == 5 && !strncmp(con_options, "NOSSL", 5)) + else if (length == 5 && !strncmp(con_options, STRING_WITH_LEN("NOSSL"))) con_ssl= USE_SSL_FORBIDDEN; else if (!strncmp(con_options, "SSL-CIPHER=", 11)) { con_ssl= USE_SSL_REQUIRED; ssl_cipher=con_options + 11; } - else if (length == 8 && !strncmp(con_options, "COMPRESS", 8)) + else if (length == 8 && !strncmp(con_options, STRING_WITH_LEN("COMPRESS"))) con_compress= 1; - else if (length == 3 && !strncmp(con_options, "TCP", 3)) + else if (length == 3 && !strncmp(con_options, STRING_WITH_LEN("TCP"))) protocol= MYSQL_PROTOCOL_TCP; - else if (length == 7 && !strncmp(con_options, "DEFAULT", 7)) + else if (length == 7 && !strncmp(con_options, STRING_WITH_LEN("DEFAULT"))) protocol= MYSQL_PROTOCOL_DEFAULT; - else if (length == 4 && !strncmp(con_options, "PIPE", 4)) + else if (length == 4 && !strncmp(con_options, STRING_WITH_LEN("PIPE"))) { #ifdef _WIN32 protocol= MYSQL_PROTOCOL_PIPE; #endif } - else if (length == 6 && !strncmp(con_options, "SOCKET", 6)) + else if (length == 6 && !strncmp(con_options, STRING_WITH_LEN("SOCKET"))) { #ifndef _WIN32 protocol= MYSQL_PROTOCOL_SOCKET; #endif } - else if (length == 6 && !strncmp(con_options, "MEMORY", 6)) + else if (length == 6 && !strncmp(con_options, STRING_WITH_LEN("MEMORY"))) { #ifdef _WIN32 protocol= MYSQL_PROTOCOL_MEMORY; #endif } - else if (strncasecmp(con_options, "read_timeout=", - sizeof("read_timeout=")-1) == 0) + else if (strncasecmp(con_options, STRING_WITH_LEN("read_timeout=")) == 0) { read_timeout= atoi(con_options + sizeof("read_timeout=")-1); } - else if (strncasecmp(con_options, "write_timeout=", - sizeof("write_timeout=")-1) == 0) + else if (strncasecmp(con_options, STRING_WITH_LEN("write_timeout=")) == 0) { write_timeout= atoi(con_options + sizeof("write_timeout=")-1); } - else if (strncasecmp(con_options, "connect_timeout=", - sizeof("connect_timeout=")-1) == 0) + else if (strncasecmp(con_options, STRING_WITH_LEN("connect_timeout=")) == 0) { connect_timeout= atoi(con_options + sizeof("connect_timeout=")-1); } - else if (strncasecmp(con_options, "CHARSET=", - sizeof("CHARSET=") - 1) == 0) + else if (strncasecmp(con_options, STRING_WITH_LEN("CHARSET=")) == 0) { csname= strdup(con_options + sizeof("CHARSET=") - 1); } + else if (strncasecmp(con_options, STRING_WITH_LEN("auth=")) == 0) + { + rauth= strdup(con_options + sizeof("auth=") - 1); + } else die("Illegal option to connect: %.*b", (int) (end - con_options), con_options); @@ -6226,21 +6263,13 @@ void do_connect(struct st_command *command) if (opt_charsets_dir) mysql_options(con_slot->mysql, MYSQL_SET_CHARSET_DIR, opt_charsets_dir); +#ifndef EMBEDDED_LIBRARY + if (rauth) + mysql_options(con_slot->mysql, MARIADB_OPT_RESTRICTED_AUTH, rauth); -#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) - if (con_ssl == USE_SSL_IF_POSSIBLE && opt_use_ssl) - con_ssl= USE_SSL_REQUIRED; - - if (con_ssl == USE_SSL_REQUIRED) - { - 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); - mysql_options(con_slot->mysql, MARIADB_OPT_TLS_VERSION, opt_tls_version); - mysql_options(con_slot->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, - &opt_ssl_verify_server_cert); - } + set_ssl_opts(con_slot->mysql, con_ssl == USE_SSL_FORBIDDEN ? 0 : + con_ssl == USE_SSL_REQUIRED ? 1 : opt_use_ssl, + ssl_cipher ? ssl_cipher : opt_ssl_cipher); #endif if (protocol) @@ -6314,6 +6343,7 @@ void do_connect(struct st_command *command) dynstr_free(&ds_options); dynstr_free(&ds_default_auth); free(csname); + free(rauth); DBUG_VOID_RETURN; } @@ -6386,6 +6416,33 @@ enum block_op find_operand(const char *start) return ILLEG_OP; } +/* + do_break + + DESCRIPTION + Instruction to stop execution of the current loop +*/ +void do_break(struct st_command* command) +{ + int depth= 0; + cur_block->ok= false; + + /* Disable every outer block until while found or block stack ends */ + while (cur_block->cmd != cmd_while && cur_block > block_stack) + { + cur_block--; + cur_block->ok= false; + depth++; + } + + /* Check if the top block is not 'while' */ + if (cur_block->cmd != cmd_while) + { + die("Stray break was found"); + } + /* Set current block back */ + cur_block+= depth; +} /* Process start of a "if" or "while" statement @@ -7291,12 +7348,6 @@ static struct my_option my_long_options[] = }; -void print_version(void) -{ - printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,MTEST_VERSION, - MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE); -} - void usage() { print_version(); @@ -8874,6 +8925,7 @@ end: var_set_errno(mysql_stmt_errno(stmt)); + display_optimizer_trace(cn, ds); revert_properties(); /* Close the statement if reconnect, need new prepare */ @@ -9335,6 +9387,7 @@ int util_query(MYSQL* org_mysql, const char* query){ /* enable local infile, in non-binary builds often disabled by default */ mysql_options(mysql, MYSQL_OPT_LOCAL_INFILE, 0); mysql_options(mysql, MYSQL_OPT_NONBLOCK, 0); + SET_SSL_OPTS(mysql); safe_connect(mysql, "util", org_mysql->host, org_mysql->user, org_mysql->passwd, org_mysql->db, org_mysql->port, org_mysql->unix_socket); @@ -10158,19 +10211,7 @@ int main(int argc, char **argv) if (opt_plugin_dir && *opt_plugin_dir) mysql_options(con->mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir); -#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) - - if (opt_use_ssl) - { - 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); - mysql_options(con->mysql, MARIADB_OPT_TLS_VERSION, opt_tls_version); - mysql_options(con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, - &opt_ssl_verify_server_cert); - } -#endif + SET_SSL_OPTS(con->mysql); if (!(con->name = my_strdup(PSI_NOT_INSTRUMENTED, "default", MYF(MY_WME)))) die("Out of memory"); @@ -10324,6 +10365,7 @@ int main(int argc, char **argv) case Q_INC: do_modify_var(command, DO_INC); break; case Q_DEC: do_modify_var(command, DO_DEC); break; case Q_ECHO: do_echo(command); command_executed++; break; + case Q_BREAK: do_break(command); break; case Q_SYSTEM: do_system(command); break; case Q_REMOVE_FILE: do_remove_file(command); break; case Q_REMOVE_FILES_WILDCARD: do_remove_files_wildcard(command); break; |