summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Vaintroub <vvaintroub@mysql.com>2009-11-03 01:19:37 +0100
committerVladislav Vaintroub <vvaintroub@mysql.com>2009-11-03 01:19:37 +0100
commit2f075a1e37a483833e6f7e2de4bd3f9b1848082c (patch)
tree7efbc2b00daea46ee33727295265e0752f0385b4
parent84301e8b9d8e3e8a658ecfed9d7f1ceb7a9f05fe (diff)
downloadmariadb-git-2f075a1e37a483833e6f7e2de4bd3f9b1848082c.tar.gz
Bug #47423 mtr connects to wrong database
The reason for the bug is that mysqtest as well as other client tools running in test suite (mysqlbinlog, mysqldump) will first try to connect whatever database has created shared memory with default base name "MySQL" and use this. (Same effect could be seen on Unix if mtr would not care to calculate "port" and "socket" parameter). The fix ensures that all client tools and running in mtr use unique per-database shared memory base parameters, so there is no possibility to clash with already installed one. We use socket name for shared memory base (it's known to be unique). This shared-memory-base is written to the MTR config file to the [client] and [mysqld] sections. Fix made also made sure all client tools understand and correctly handle --shared-memory-base. Prior to this patch it was not the case for mysqltest, mysqlbinlog and mysql_client_test. All new connections done from mtr scripts via connect() will by default set shared-memory-base. And finally, there is a possibility to force shared memory or pipe connection and overwrite shared memory/pipe base name from within mtr scripts via optional PIPE or SHM modifier. This functionality was manually backported from 6.0 (original patch http://lists.mysql.com/commits/74749)
-rw-r--r--client/mysqlbinlog.cc14
-rw-r--r--client/mysqltest.cc57
-rw-r--r--mysql-test/lib/My/ConfigFactory.pm20
-rw-r--r--mysql-test/t/named_pipe.test5
-rw-r--r--tests/mysql_client_test.c94
5 files changed, 156 insertions, 34 deletions
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index ebe34231238..a5d29f92a17 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -78,6 +78,9 @@ static const char* host = 0;
static int port= 0;
static uint my_end_arg;
static const char* sock= 0;
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name= 0;
+#endif
static const char* user = 0;
static char* pass = 0;
static char *charset= 0;
@@ -1077,6 +1080,12 @@ static struct my_option my_long_options[] =
{"set-charset", OPT_SET_CHARSET,
"Add 'SET NAMES character_set' to the output.", (uchar**) &charset,
(uchar**) &charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef HAVE_SMEM
+ {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
+ "Base name of shared memory.", (uchar**) &shared_memory_base_name,
+ (uchar**) &shared_memory_base_name,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif
{"short-form", 's', "Just show regular queries: no extra info and no "
"row-based events. This is for testing only, and should not be used in "
"production systems. If you want to suppress base64-output, consider "
@@ -1379,6 +1388,11 @@ static Exit_status safe_connect()
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 (!mysql_real_connect(mysql, host, user, pass, 0, port, sock, 0))
{
error("Failed on connect: %s", mysql_error(mysql));
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index e37b7d89a93..635beb5fbda 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -81,6 +81,9 @@ enum {
static int record= 0, opt_sleep= -1;
static char *opt_db= 0, *opt_pass= 0;
const char *opt_user= 0, *opt_host= 0, *unix_sock= 0, *opt_basedir= "./";
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name=0;
+#endif
const char *opt_logdir= "";
const char *opt_include= 0, *opt_charsets_dir;
static int opt_port= 0;
@@ -4896,6 +4899,8 @@ do_handle_error:
<opts> - options to use for the connection
* SSL - use SSL if available
* COMPRESS - use compression if available
+ * SHM - use shared memory if available
+ * PIPE - use named pipe if available
*/
@@ -4904,6 +4909,7 @@ void do_connect(struct st_command *command)
int con_port= opt_port;
char *con_options;
my_bool con_ssl= 0, con_compress= 0;
+ my_bool con_pipe= 0, con_shm= 0;
struct st_connection* con_slot;
static DYNAMIC_STRING ds_connection_name;
@@ -4914,6 +4920,9 @@ void do_connect(struct st_command *command)
static DYNAMIC_STRING ds_port;
static DYNAMIC_STRING ds_sock;
static DYNAMIC_STRING ds_options;
+#ifdef HAVE_SMEM
+ static DYNAMIC_STRING ds_shm;
+#endif
const struct command_arg connect_args[] = {
{ "connection name", ARG_STRING, TRUE, &ds_connection_name, "Name of the connection" },
{ "host", ARG_STRING, TRUE, &ds_host, "Host to connect to" },
@@ -4941,6 +4950,11 @@ void do_connect(struct st_command *command)
die("Illegal argument for port: '%s'", ds_port.str);
}
+#ifdef HAVE_SMEM
+ /* Shared memory */
+ init_dynamic_string(&ds_shm, ds_sock.str, 0, 0);
+#endif
+
/* Sock */
if (ds_sock.length)
{
@@ -4979,6 +4993,10 @@ void do_connect(struct st_command *command)
con_ssl= 1;
else if (!strncmp(con_options, "COMPRESS", 8))
con_compress= 1;
+ else if (!strncmp(con_options, "PIPE", 4))
+ con_pipe= 1;
+ else if (!strncmp(con_options, "SHM", 3))
+ con_shm= 1;
else
die("Illegal option to connect: %.*s",
(int) (end - con_options), con_options);
@@ -5026,6 +5044,31 @@ void do_connect(struct st_command *command)
}
#endif
+#ifdef __WIN__
+ if (con_pipe)
+ {
+ uint protocol= MYSQL_PROTOCOL_PIPE;
+ mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, &protocol);
+ }
+#endif
+
+#ifdef HAVE_SMEM
+ if (con_shm)
+ {
+ uint protocol= MYSQL_PROTOCOL_MEMORY;
+ if (!ds_shm.length)
+ die("Missing shared memory base name");
+ mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME, ds_shm.str);
+ mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, &protocol);
+ }
+ else if(shared_memory_base_name)
+ {
+ mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME,
+ shared_memory_base_name);
+ }
+#endif
+
+
/* Use default db name */
if (ds_database.length == 0)
dynstr_set(&ds_database, opt_db);
@@ -5058,6 +5101,9 @@ void do_connect(struct st_command *command)
dynstr_free(&ds_port);
dynstr_free(&ds_sock);
dynstr_free(&ds_options);
+#ifdef HAVE_SMEM
+ dynstr_free(&ds_shm);
+#endif
DBUG_VOID_RETURN;
}
@@ -5724,6 +5770,12 @@ static struct my_option my_long_options[] =
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"server-file", 'F', "Read embedded server arguments from file.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef HAVE_SMEM
+ {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
+ "Base name of shared memory.", (uchar**) &shared_memory_base_name,
+ (uchar**) &shared_memory_base_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+#endif
{"silent", 's', "Suppress all normal output. Synonym for --quiet.",
(uchar**) &silent, (uchar**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"skip-safemalloc", OPT_SKIP_SAFEMALLOC,
@@ -7673,6 +7725,11 @@ int main(int argc, char **argv)
}
#endif
+#ifdef HAVE_SMEM
+ if (shared_memory_base_name)
+ mysql_options(&con->mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
+#endif
+
if (!(con->name = my_strdup("default", MYF(MY_WME))))
die("Out of memory");
diff --git a/mysql-test/lib/My/ConfigFactory.pm b/mysql-test/lib/My/ConfigFactory.pm
index c1e8f7cd826..c4d68e7127c 100644
--- a/mysql-test/lib/My/ConfigFactory.pm
+++ b/mysql-test/lib/My/ConfigFactory.pm
@@ -7,6 +7,7 @@ use Carp;
use My::Config;
use My::Find;
+use My::Platform;
use File::Basename;
@@ -218,7 +219,13 @@ my @mysqld_rules=
{ 'ssl-key' => \&fix_ssl_server_key },
);
-
+if (IS_WINDOWS)
+{
+ # For simplicity, we use the same names for shared memory and
+ # named pipes.
+ push(@mysqld_rules, {'shared-memory-base-name' => \&fix_socket});
+}
+
sub fix_ndb_mgmd_port {
my ($self, $config, $group_name, $group)= @_;
my $hostname= $group->value('HostName');
@@ -347,6 +354,16 @@ sub post_check_client_group {
}
$config->insert($client_group_name, $name_to, $option->value())
}
+
+ if (IS_WINDOWS)
+ {
+ # Shared memory base may or may not be defined (e.g not defined in embedded)
+ my $shm = $group_to_copy_from->option("shared-memory-base-name");
+ if (defined $shm)
+ {
+ $config->insert($client_group_name,"shared-memory-base-name", $shm->value());
+ }
+ }
}
@@ -393,6 +410,7 @@ sub post_check_embedded_group {
(
'#log-error', # Embedded server writes stderr to mysqltest's log file
'slave-net-timeout', # Embedded server are not build with replication
+ 'shared-memory-base-name', # No shared memory for embedded
);
foreach my $option ( $mysqld->options(), $first_mysqld->options() ) {
diff --git a/mysql-test/t/named_pipe.test b/mysql-test/t/named_pipe.test
index e3dfd24bb52..e88fd8e1ef8 100644
--- a/mysql-test/t/named_pipe.test
+++ b/mysql-test/t/named_pipe.test
@@ -9,6 +9,11 @@ if (`SELECT '$nmp' != 'ON'`){
skip No named pipe support;
}
+# Connect using named pipe for testing
+connect(pipe_con,localhost,root,,,,,PIPE);
+
# Source select test case
-- source include/common-tests.inc
+connection default;
+disconnect pipe_con;
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 9394b0df40b..f65e549fd96 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -46,6 +46,9 @@ static char *opt_user= 0;
static char *opt_password= 0;
static char *opt_host= 0;
static char *opt_unix_socket= 0;
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name= 0;
+#endif
static unsigned int opt_port;
static my_bool tty_password= 0, opt_silent= 0;
@@ -230,6 +233,26 @@ static void print_st_error(MYSQL_STMT *stmt, const char *msg)
}
}
+/*
+ Enhanced version of mysql_client_init(), which may also set shared memory
+ base on Windows.
+*/
+static MYSQL *mysql_client_init(MYSQL* con)
+{
+ MYSQL* res = mysql_init(con);
+#ifdef HAVE_SMEM
+ if (res && shared_memory_base_name)
+ mysql_options(res, MYSQL_SHARED_MEMORY_BASE_NAME, shared_memory_base_name);
+#endif
+ return res;
+}
+
+/*
+ Disable direct calls of mysql_init, as it disregards shared memory base.
+*/
+#define mysql_init(A) Please use mysql_client_init instead of mysql_init
+
+
/* Check if the connection has InnoDB tables */
static my_bool check_have_innodb(MYSQL *conn)
@@ -293,10 +316,10 @@ static MYSQL* client_connect(ulong flag, uint protocol, my_bool auto_reconnect)
fprintf(stdout, "\n Establishing a connection to '%s' ...",
opt_host ? opt_host : "");
- if (!(mysql= mysql_init(NULL)))
+ if (!(mysql= mysql_client_init(NULL)))
{
opt_silent= 0;
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
exit(1);
}
/* enable local infile, in non-binary builds often disabled by default */
@@ -1160,9 +1183,9 @@ static my_bool thread_query(char *query)
error= 0;
if (!opt_silent)
fprintf(stdout, "\n in thread_query(%s)", query);
- if (!(l_mysql= mysql_init(NULL)))
+ if (!(l_mysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
return 1;
}
if (!(mysql_real_connect(l_mysql, opt_host, opt_user,
@@ -2512,9 +2535,9 @@ static void test_ps_query_cache()
case TEST_QCACHE_ON_WITH_OTHER_CONN:
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- printf("mysql_init() failed");
+ printf("mysql_client_init() failed");
DIE_UNLESS(0);
}
if (!(mysql_real_connect(lmysql, opt_host, opt_user,
@@ -4960,9 +4983,9 @@ static void test_stmt_close()
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
exit(1);
}
if (!(mysql_real_connect(lmysql, opt_host, opt_user,
@@ -5851,9 +5874,9 @@ DROP TABLE IF EXISTS test_multi_tab";
rc= mysql_more_results(mysql);
DIE_UNLESS(rc == 0);
- if (!(mysql_local= mysql_init(NULL)))
+ if (!(mysql_local= mysql_client_init(NULL)))
{
- fprintf(stdout, "\n mysql_init() failed");
+ fprintf(stdout, "\n mysql_client_init() failed");
exit(1);
}
@@ -5976,9 +5999,9 @@ static void test_prepare_multi_statements()
char query[MAX_TEST_QUERY_LENGTH];
myheader("test_prepare_multi_statements");
- if (!(mysql_local= mysql_init(NULL)))
+ if (!(mysql_local= mysql_client_init(NULL)))
{
- fprintf(stderr, "\n mysql_init() failed");
+ fprintf(stderr, "\n mysql_client_init() failed");
exit(1);
}
@@ -7459,9 +7482,9 @@ static void test_prepare_grant()
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
exit(1);
}
if (!(mysql_real_connect(lmysql, opt_host, "test_grant",
@@ -7915,9 +7938,9 @@ static void test_drop_temp()
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
exit(1);
}
@@ -13159,7 +13182,7 @@ static void test_bug15518()
int rc;
myheader("test_bug15518");
- mysql1= mysql_init(NULL);
+ mysql1= mysql_client_init(NULL);
if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
opt_db ? opt_db : "test", opt_port, opt_unix_socket,
@@ -13315,9 +13338,9 @@ static void test_bug8378()
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
exit(1);
}
if (mysql_options(lmysql, MYSQL_SET_CHARSET_NAME, "gbk"))
@@ -13856,7 +13879,7 @@ static void test_bug9992()
if (!opt_silent)
printf("Establishing a connection with option CLIENT_MULTI_STATEMENTS..\n");
- mysql1= mysql_init(NULL);
+ mysql1= mysql_client_init(NULL);
if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
opt_db ? opt_db : "test", opt_port, opt_unix_socket,
@@ -14445,9 +14468,9 @@ static void test_bug12001()
myheader("test_bug12001");
- if (!(mysql_local= mysql_init(NULL)))
+ if (!(mysql_local= mysql_client_init(NULL)))
{
- fprintf(stdout, "\n mysql_init() failed");
+ fprintf(stdout, "\n mysql_client_init() failed");
exit(1);
}
@@ -15172,9 +15195,9 @@ static void test_opt_reconnect()
myheader("test_opt_reconnect");
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
exit(1);
}
@@ -15209,9 +15232,9 @@ static void test_opt_reconnect()
mysql_close(lmysql);
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
DIE_UNLESS(0);
}
@@ -15246,7 +15269,7 @@ static void test_bug12744()
int rc;
myheader("test_bug12744");
- lmysql= mysql_init(NULL);
+ lmysql= mysql_client_init(NULL);
DIE_UNLESS(lmysql);
if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password,
@@ -15819,7 +15842,7 @@ static void test_bug15752()
rc= mysql_query(mysql, "create procedure p1() select 1");
myquery(rc);
- mysql_init(&mysql_local);
+ mysql_client_init(&mysql_local);
if (! mysql_real_connect(&mysql_local, opt_host, opt_user,
opt_password, current_db, opt_port,
opt_unix_socket,
@@ -16705,7 +16728,7 @@ static void test_bug29692()
{
MYSQL* conn;
- if (!(conn= mysql_init(NULL)))
+ if (!(conn= mysql_client_init(NULL)))
{
myerror("test_bug29692 init failed");
exit(1);
@@ -16840,7 +16863,7 @@ static void test_bug30472()
/* Create a new connection. */
- DIE_UNLESS(mysql_init(&con));
+ DIE_UNLESS(mysql_client_init(&con));
DIE_UNLESS(mysql_real_connect(&con,
opt_host,
@@ -17014,7 +17037,7 @@ static void test_bug20023()
/* Create a new connection. */
- DIE_UNLESS(mysql_init(&con));
+ DIE_UNLESS(mysql_client_init(&con));
DIE_UNLESS(mysql_real_connect(&con,
opt_host,
@@ -17151,7 +17174,7 @@ static void bug31418_impl()
/* Create a new connection. */
- DIE_UNLESS(mysql_init(&con));
+ DIE_UNLESS(mysql_client_init(&con));
DIE_UNLESS(mysql_real_connect(&con,
opt_host,
@@ -18001,7 +18024,7 @@ static void test_bug44495()
"END;");
myquery(rc);
- DIE_UNLESS(mysql_init(&con));
+ DIE_UNLESS(mysql_client_init(&con));
DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
current_db, opt_port, opt_unix_socket,
@@ -18064,6 +18087,11 @@ static struct my_option client_test_long_options[] =
0, 0, 0, 0, 0, 0},
{"silent", 's', "Be more silent", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0,
0},
+#ifdef HAVE_SMEM
+ {"shared-memory-base-name", 'm', "Base name of shared memory.",
+ (uchar**) &shared_memory_base_name, (uchar**)&shared_memory_base_name, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif
{"socket", 'S', "Socket file to use for connection",
(uchar **) &opt_unix_socket, (uchar **) &opt_unix_socket, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},