Commit 2f075a1e authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

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)
parent 84301e8b
......@@ -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));
......
......@@ -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");
......
......@@ -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() ) {
......
......@@ -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;
......@@ -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},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment