Commit f479c3a4 authored by andrey@lmy004's avatar andrey@lmy004

Merge lmy004.:/work/mysql-5.0-clean into lmy004.:/work/mysql-5.0-ready5

parents 235cde55 251271f1
...@@ -523,6 +523,10 @@ alter table t1 drop key no_such_key; ...@@ -523,6 +523,10 @@ alter table t1 drop key no_such_key;
ERROR 42000: Can't DROP 'no_such_key'; check that column/key exists ERROR 42000: Can't DROP 'no_such_key'; check that column/key exists
alter table t1 drop key a; alter table t1 drop key a;
drop table t1; drop table t1;
CREATE TABLE T12207(a int) ENGINE=MYISAM;
ALTER TABLE T12207 DISCARD TABLESPACE;
ERROR HY000: Table storage engine for 'T12207' doesn't have this option
DROP TABLE T12207;
create table t1 (a text) character set koi8r; create table t1 (a text) character set koi8r;
insert into t1 values (_koi8r''); insert into t1 values (_koi8r'');
select hex(a) from t1; select hex(a) from t1;
......
...@@ -337,6 +337,14 @@ alter table t1 drop key no_such_key; ...@@ -337,6 +337,14 @@ alter table t1 drop key no_such_key;
alter table t1 drop key a; alter table t1 drop key a;
drop table t1; drop table t1;
#
# BUG 12207 alter table ... discard table space on MyISAM table causes ERROR 2013 (HY000)
#
CREATE TABLE T12207(a int) ENGINE=MYISAM;
--error 1031
ALTER TABLE T12207 DISCARD TABLESPACE;
DROP TABLE T12207;
# #
# Bug #6479 ALTER TABLE ... changing charset fails for TEXT columns # Bug #6479 ALTER TABLE ... changing charset fails for TEXT columns
# #
......
...@@ -70,7 +70,6 @@ mysqlmanager_SOURCES= command.cc command.h mysqlmanager.cc \ ...@@ -70,7 +70,6 @@ mysqlmanager_SOURCES= command.cc command.h mysqlmanager.cc \
user_map.h user_map.cc \ user_map.h user_map.cc \
messages.h messages.cc \ messages.h messages.cc \
commands.h commands.cc \ commands.h commands.cc \
factory.h factory.cc \
instance.h instance.cc \ instance.h instance.cc \
instance_map.h instance_map.cc\ instance_map.h instance_map.cc\
instance_options.h instance_options.cc \ instance_options.h instance_options.cc \
......
...@@ -461,7 +461,8 @@ int Show_instance_log::execute(struct st_net *net, ulong connection_id) ...@@ -461,7 +461,8 @@ int Show_instance_log::execute(struct st_net *net, ulong connection_id)
/* Instance has no such log */ /* Instance has no such log */
if (logpath == NULL) if (logpath == NULL)
return ER_NO_SUCH_LOG; return ER_NO_SUCH_LOG;
else if (*logpath == '\0')
if (*logpath == '\0')
return ER_GUESS_LOGFILE; return ER_GUESS_LOGFILE;
...@@ -571,6 +572,7 @@ int Show_instance_log_files::execute(struct st_net *net, ulong connection_id) ...@@ -571,6 +572,7 @@ int Show_instance_log_files::execute(struct st_net *net, ulong connection_id)
if ((instance= instance_map-> if ((instance= instance_map->
find(instance_name, strlen(instance_name))) == NULL) find(instance_name, strlen(instance_name))) == NULL)
goto err; goto err;
{ {
/* /*
We have alike structure in instance_options.cc. We use such to be able We have alike structure in instance_options.cc. We use such to be able
...@@ -686,7 +688,7 @@ Set_option::Set_option(Instance_map *instance_map_arg, ...@@ -686,7 +688,7 @@ Set_option::Set_option(Instance_map *instance_map_arg,
option. option.
RETURN RETURN
ER_BAD_INSTANCE_NAME The instance name specified is not valid ER_OUT_OF_RESOURCES out of resources
ER_ACCESS_OPTION_FILE Cannot access the option file ER_ACCESS_OPTION_FILE Cannot access the option file
0 - ok 0 - ok
*/ */
...@@ -694,22 +696,14 @@ Set_option::Set_option(Instance_map *instance_map_arg, ...@@ -694,22 +696,14 @@ Set_option::Set_option(Instance_map *instance_map_arg,
int Set_option::correct_file(int skip) int Set_option::correct_file(int skip)
{ {
int error; int error;
const static int mysys_to_im_error[]= { 0, ER_OUT_OF_RESOURCES,
ER_ACCESS_OPTION_FILE };
error= modify_defaults_file(Options::config_file, option, error= modify_defaults_file(Options::config_file, option,
option_value, instance_name, skip); option_value, instance_name, skip);
switch (error) DBUG_ASSERT(error >= 0 && error <= 2);
{
case 0:
return 0; /* everything was fine */
case 1:
return ER_OUT_OF_RESOURCES;
case 2:
return ER_ACCESS_OPTION_FILE;
default:
DBUG_ASSERT(0); /* should never get here */
}
return 0; /* keep compiler happy */ return mysys_to_im_error[error];
} }
...@@ -725,10 +719,9 @@ int Set_option::correct_file(int skip) ...@@ -725,10 +719,9 @@ int Set_option::correct_file(int skip)
1 - error occured 1 - error occured
*/ */
int Set_option::do_command(struct st_net *net) int Set_option::do_command(struct st_net *net)
{ {
int error= 0; int error;
/* we must hold the instance_map mutex while changing config file */ /* we must hold the instance_map mutex while changing config file */
instance_map->lock(); instance_map->lock();
...@@ -746,16 +739,14 @@ int Set_option::execute(struct st_net *net, ulong connection_id) ...@@ -746,16 +739,14 @@ int Set_option::execute(struct st_net *net, ulong connection_id)
int val; int val;
val= do_command(net); val= do_command(net);
if (val == 0) if (val == 0)
{
net_send_ok(net, connection_id, NULL); net_send_ok(net, connection_id, NULL);
return 0;
}
return val; return val;
} }
else
return ER_BAD_INSTANCE_NAME; return ER_BAD_INSTANCE_NAME;
} }
...@@ -785,16 +776,15 @@ int Stop_instance::execute(struct st_net *net, ulong connection_id) ...@@ -785,16 +776,15 @@ int Stop_instance::execute(struct st_net *net, ulong connection_id)
if (instance == 0) if (instance == 0)
return ER_BAD_INSTANCE_NAME; /* haven't found an instance */ return ER_BAD_INSTANCE_NAME; /* haven't found an instance */
else
{ if (!(instance->options.nonguarded))
if (!(instance->options.nonguarded)) instance_map->guardian->stop_guard(instance);
instance_map->guardian->
stop_guard(instance); if ((err_code= instance->stop()))
if ((err_code= instance->stop())) return err_code;
return err_code;
net_send_ok(net, connection_id, NULL); net_send_ok(net, connection_id, NULL);
return 0; return 0;
}
} }
......
/* Copyright (C) 2004 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "factory.h"
Show_instances *Command_factory::new_Show_instances()
{
return new Show_instances(&instance_map);
}
Flush_instances *Command_factory::new_Flush_instances()
{
return new Flush_instances(&instance_map);
}
Show_instance_status *Command_factory::
new_Show_instance_status(const char *name, uint len)
{
return new Show_instance_status(&instance_map, name, len);
}
Show_instance_options *Command_factory::
new_Show_instance_options(const char *name, uint len)
{
return new Show_instance_options(&instance_map, name, len);
}
Start_instance *Command_factory::
new_Start_instance(const char *name, uint len)
{
return new Start_instance(&instance_map, name, len);
}
Stop_instance *Command_factory::new_Stop_instance(const char *name, uint len)
{
return new Stop_instance(&instance_map, name, len);
}
Syntax_error *Command_factory::new_Syntax_error()
{
return new Syntax_error();
}
Set_option *Command_factory::
new_Set_option(const char* name, uint len,
const char *option_arg, uint option_len,
const char *option_value_arg, uint option_value_len)
{
return new Set_option(&instance_map, name, len, option_arg,
option_len, option_value_arg, option_value_len);
}
Unset_option *Command_factory::
new_Unset_option(const char* name, uint len,
const char *option_arg, uint option_len,
const char *option_value_arg, uint option_value_len)
{
return new Unset_option(&instance_map, name, len, option_arg,
option_len, option_value_arg, option_value_len);
}
Show_instance_log *Command_factory::
new_Show_instance_log(const char *name, uint len,
Log_type log_type_arg,
const char *size, const char *offset)
{
return new Show_instance_log(&instance_map, name, len,
log_type_arg, size, offset);
}
Show_instance_log_files *Command_factory::
new_Show_instance_log_files(const char *name, uint len)
{
return new Show_instance_log_files(&instance_map, name, len);
}
#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_FACTORY_H
#define INCLUDES_MYSQL_INSTANCE_MANAGER_FACTORY_H
/* Copyright (C) 2004 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "command.h"
#include "commands.h"
#include "instance_map.h"
/*
This class could be used to handle various protocols. We could pass to
the parser various derived classes. I.e Mylsq_command_factory,
Http_command_factory e.t.c. Also see comment in the instance_map.cc
*/
class Show_instances;
class Command_factory
{
public:
Command_factory(Instance_map &instance_map): instance_map(instance_map)
{}
Show_instances *new_Show_instances ();
Flush_instances *new_Flush_instances ();
Syntax_error *new_Syntax_error ();
Show_instance_status *new_Show_instance_status (const char *name, uint len);
Show_instance_options *new_Show_instance_options (const char *name, uint len);
Start_instance *new_Start_instance (const char *name, uint len);
Stop_instance *new_Stop_instance (const char *name, uint len);
Show_instance_log *new_Show_instance_log (const char *name, uint len,
Log_type log_type_arg,
const char *size,
const char *offset);
Set_option *new_Set_option (const char *name, uint len,
const char *option_arg, uint option_len,
const char *option_value_arg,
uint option_value_len);
Unset_option *new_Unset_option (const char *name, uint len,
const char *option_arg, uint option_len,
const char *option_value_arg,
uint option_value_len);
Show_instance_log_files *new_Show_instance_log_files (const char *name,
uint len);
Instance_map &instance_map;
};
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_FACTORY_H */
...@@ -122,8 +122,7 @@ void Guardian_thread::process_instance(Instance *instance, ...@@ -122,8 +122,7 @@ void Guardian_thread::process_instance(Instance *instance,
} }
else else
{ {
switch (current_node->state) switch (current_node->state) {
{
case NOT_STARTED: case NOT_STARTED:
instance->start(); instance->start();
current_node->last_checked= current_time; current_node->last_checked= current_time;
...@@ -149,7 +148,8 @@ void Guardian_thread::process_instance(Instance *instance, ...@@ -149,7 +148,8 @@ void Guardian_thread::process_instance(Instance *instance,
log_info("guardian: starting instance %s", log_info("guardian: starting instance %s",
instance->options.instance_name); instance->options.instance_name);
} }
else current_node->state= CRASHED; else
current_node->state= CRASHED;
break; break;
case CRASHED: /* just regular restarts */ case CRASHED: /* just regular restarts */
if (current_time - current_node->last_checked > if (current_time - current_node->last_checked >
...@@ -219,7 +219,8 @@ void Guardian_thread::run() ...@@ -219,7 +219,8 @@ void Guardian_thread::run()
/* check the loop predicate before sleeping */ /* check the loop predicate before sleeping */
if (!(shutdown_requested && (!(guarded_instances)))) if (!(shutdown_requested && (!(guarded_instances))))
pthread_cond_timedwait(&COND_guardian, &LOCK_guardian, &timeout); thread_registry.cond_timedwait(&thread_info, &COND_guardian,
&LOCK_guardian, &timeout);
} }
stopped= TRUE; stopped= TRUE;
...@@ -365,18 +366,20 @@ int Guardian_thread::stop_guard(Instance *instance) ...@@ -365,18 +366,20 @@ int Guardian_thread::stop_guard(Instance *instance)
} }
/* /*
Start Guardian shutdown. Attempt to start instances if requested. An internal method which is called at shutdown to unregister instances and
attempt to stop them if requested.
SYNOPSYS SYNOPSYS
stop_instances() stop_instances()
stop_instances_arg whether we should stop instances at shutdown stop_instances_arg whether we should stop instances at shutdown
DESCRIPTION DESCRIPTION
Loops through the guarded_instances list and prepares them for shutdown. Loops through the guarded_instances list and prepares them for shutdown.
If stop_instances was requested, we need to issue a stop command and change If stop_instances was requested, we need to issue a stop command and change
the state accordingly. Otherwise we could simply delete an entry. the state accordingly. Otherwise we simply delete an entry.
NOTE: Guardian should be locked by the calling function
NOTE
Guardian object should be locked by the calling function.
RETURN RETURN
0 - ok 0 - ok
......
...@@ -62,8 +62,8 @@ class Guardian_thread: public Guardian_thread_args ...@@ -62,8 +62,8 @@ class Guardian_thread: public Guardian_thread_args
{ {
public: public:
/* states of an instance */ /* states of an instance */
enum INSTANCE_STATE { NOT_STARTED= 1, STARTING, STARTED, JUST_CRASHED, enum enum_instance_state { NOT_STARTED= 1, STARTING, STARTED, JUST_CRASHED,
CRASHED, CRASHED_AND_ABANDONED, STOPPING }; CRASHED, CRASHED_AND_ABANDONED, STOPPING };
/* /*
The Guardian list node structure. Guardian utilizes it to store The Guardian list node structure. Guardian utilizes it to store
...@@ -74,7 +74,7 @@ public: ...@@ -74,7 +74,7 @@ public:
{ {
Instance *instance; Instance *instance;
/* state of an instance (i.e. STARTED, CRASHED, etc.) */ /* state of an instance (i.e. STARTED, CRASHED, etc.) */
INSTANCE_STATE state; enum_instance_state state;
/* the amount of attemts to restart instance (cleaned up at success) */ /* the amount of attemts to restart instance (cleaned up at success) */
int restart_counter; int restart_counter;
/* triggered at a crash */ /* triggered at a crash */
......
...@@ -49,12 +49,12 @@ public: ...@@ -49,12 +49,12 @@ public:
Instance_options options; Instance_options options;
private: private:
int crashed;
/* /*
Mutex protecting the instance. Currently we use it to avoid the Mutex protecting the instance. Currently we use it to avoid the
double start of the instance. This happens when the instance is starting double start of the instance. This happens when the instance is starting
and we issue the start command once more. and we issue the start command once more.
*/ */
int crashed;
pthread_mutex_t LOCK_instance; pthread_mutex_t LOCK_instance;
/* /*
This condition variable is used to wake threads waiting for instance to This condition variable is used to wake threads waiting for instance to
......
...@@ -91,22 +91,20 @@ static int process_option(void *ctx, const char *group, const char *option) ...@@ -91,22 +91,20 @@ static int process_option(void *ctx, const char *group, const char *option)
if ((instance= map->find(group, strlen(group))) == NULL) if ((instance= map->find(group, strlen(group))) == NULL)
{ {
if ((instance= new Instance) == 0) if ((instance= new Instance) == 0)
goto err_new_instance;
if (instance->init(group))
goto err;
if (map->add_instance(instance))
goto err; goto err;
if (instance->init(group) || map->add_instance(instance))
goto err_instance;
} }
if (instance->options.add_option(option)) if (instance->options.add_option(option))
goto err; goto err; /* the instance'll be deleted when we destroy the map */
} }
return 0; return 0;
err: err_instance:
delete instance; delete instance;
err_new_instance: err:
return 1; return 1;
} }
...@@ -122,10 +120,8 @@ mysqld_path(default_mysqld_path_arg) ...@@ -122,10 +120,8 @@ mysqld_path(default_mysqld_path_arg)
int Instance_map::init() int Instance_map::init()
{ {
if (hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0, return hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
get_instance_key, delete_instance, 0)) get_instance_key, delete_instance, 0);
return 1;
return 0;
} }
Instance_map::~Instance_map() Instance_map::~Instance_map()
...@@ -217,10 +213,9 @@ int Instance_map::complete_initialization() ...@@ -217,10 +213,9 @@ int Instance_map::complete_initialization()
} }
return 0; return 0;
err:
return 1;
err_instance: err_instance:
delete instance; delete instance;
err:
return 1; return 1;
} }
......
...@@ -51,13 +51,9 @@ static inline int create_mysqld_command(Buffer *buf, ...@@ -51,13 +51,9 @@ static inline int create_mysqld_command(Buffer *buf,
/* here the '\0' character is copied from the option string */ /* here the '\0' character is copied from the option string */
buf->append(position, option, option_len); buf->append(position, option, option_len);
if (buf->is_error()) return buf->is_error();
return 1;
} }
else return 1;
return 1;
return 0;
} }
...@@ -96,10 +92,8 @@ int Instance_options::get_default_option(char *result, size_t result_len, ...@@ -96,10 +92,8 @@ int Instance_options::get_default_option(char *result, size_t result_len,
/* +2 eats first "--" from the option string (E.g. "--datadir") */ /* +2 eats first "--" from the option string (E.g. "--datadir") */
rc= parse_output_and_get_value(cmd.buffer, option_name + 2, rc= parse_output_and_get_value(cmd.buffer, option_name + 2,
result, result_len, GET_VALUE); result, result_len, GET_VALUE);
return rc;
err: err:
return 1; return rc;
} }
...@@ -142,11 +136,8 @@ int Instance_options::fill_instance_version() ...@@ -142,11 +136,8 @@ int Instance_options::fill_instance_version()
result[strlen(result) - NEWLINE_LEN]= '\0'; result[strlen(result) - NEWLINE_LEN]= '\0';
mysqld_version= strdup_root(&alloc, result); mysqld_version= strdup_root(&alloc, result);
} }
return rc;
err: err:
return 1; return rc;
} }
...@@ -194,13 +185,15 @@ int Instance_options::fill_log_options() ...@@ -194,13 +185,15 @@ int Instance_options::fill_log_options()
/* compute hostname and datadir for the instance */ /* compute hostname and datadir for the instance */
if (mysqld_datadir == NULL) if (mysqld_datadir == NULL)
{ {
if (get_default_option(datadir, if (get_default_option(datadir, MAX_LOG_OPTION_LENGTH, "--datadir"))
MAX_LOG_OPTION_LENGTH, "--datadir"))
goto err; goto err;
} }
else /* below is safe, as --datadir always has a value */ else
strmake(datadir, strchr(mysqld_datadir, '=') + 1, {
MAX_LOG_OPTION_LENGTH - 1); /* below is safe, as --datadir always has a value */
strmake(datadir,
strchr(mysqld_datadir, '=') + 1, MAX_LOG_OPTION_LENGTH - 1);
}
if (gethostname(hostname,sizeof(hostname)-1) < 0) if (gethostname(hostname,sizeof(hostname)-1) < 0)
strmov(hostname, "mysql"); strmov(hostname, "mysql");
...@@ -230,15 +223,12 @@ int Instance_options::fill_log_options() ...@@ -230,15 +223,12 @@ int Instance_options::fill_log_options()
MY_UNPACK_FILENAME | MY_SAFE_PATH); MY_UNPACK_FILENAME | MY_SAFE_PATH);
if ((MAX_LOG_OPTION_LENGTH - strlen(full_name)) > if ((MAX_LOG_OPTION_LENGTH - strlen(full_name)) <=
strlen(log_files->default_suffix)) strlen(log_files->default_suffix))
{
strmov(full_name + strlen(full_name),
log_files->default_suffix);
}
else
goto err; goto err;
strmov(full_name + strlen(full_name), log_files->default_suffix);
/* /*
If there were specified two identical logfiles options, If there were specified two identical logfiles options,
we would loose some memory in MEM_ROOT here. However we would loose some memory in MEM_ROOT here. However
...@@ -254,8 +244,7 @@ int Instance_options::fill_log_options() ...@@ -254,8 +244,7 @@ int Instance_options::fill_log_options()
fn_format(full_name, argv[i] +log_files->length + 1, fn_format(full_name, argv[i] +log_files->length + 1,
datadir, "", MY_UNPACK_FILENAME | MY_SAFE_PATH); datadir, "", MY_UNPACK_FILENAME | MY_SAFE_PATH);
if (!(*(log_files->value)= if (!(*(log_files->value)= strdup_root(&alloc, full_name)))
strdup_root(&alloc, full_name)))
goto err; goto err;
} }
} }
...@@ -263,10 +252,8 @@ int Instance_options::fill_log_options() ...@@ -263,10 +252,8 @@ int Instance_options::fill_log_options()
} }
return 0; return 0;
err: err:
return 1; return 1;
} }
...@@ -294,7 +281,7 @@ int Instance_options::get_pid_filename(char *result) ...@@ -294,7 +281,7 @@ int Instance_options::get_pid_filename(char *result)
const char *pid_file= mysqld_pid_file; const char *pid_file= mysqld_pid_file;
char datadir[MAX_PATH_LEN]; char datadir[MAX_PATH_LEN];
if (!(mysqld_datadir)) if (mysqld_datadir == NULL)
{ {
/* we might get an error here if we have wrong path to the mysqld binary */ /* we might get an error here if we have wrong path to the mysqld binary */
if (get_default_option(datadir, sizeof(datadir), "--datadir")) if (get_default_option(datadir, sizeof(datadir), "--datadir"))
...@@ -333,8 +320,7 @@ pid_t Instance_options::get_pid() ...@@ -333,8 +320,7 @@ pid_t Instance_options::get_pid()
my_fclose(pid_file_stream, MYF(0)); my_fclose(pid_file_stream, MYF(0));
return pid; return pid;
} }
else return 0;
return 0;
} }
...@@ -343,11 +329,8 @@ int Instance_options::complete_initialization(const char *default_path, ...@@ -343,11 +329,8 @@ int Instance_options::complete_initialization(const char *default_path,
{ {
const char *tmp; const char *tmp;
if (!(mysqld_path)) if (!mysqld_path && !(mysqld_path= strdup_root(&alloc, default_path)))
{ goto err;
if (!(mysqld_path= strdup_root(&alloc, default_path)))
goto err;
}
mysqld_path_len= strlen(mysqld_path); mysqld_path_len= strlen(mysqld_path);
...@@ -395,9 +378,10 @@ int Instance_options::complete_initialization(const char *default_path, ...@@ -395,9 +378,10 @@ int Instance_options::complete_initialization(const char *default_path,
goto err; goto err;
/* we need to reserve space for the final zero + possible default options */ /* we need to reserve space for the final zero + possible default options */
if (!(argv= (char**) alloc_root(&alloc, (options_array.elements + 1 if (!(argv= (char**)
+ MAX_NUMBER_OF_DEFAULT_OPTIONS) * sizeof(char*)))) alloc_root(&alloc, (options_array.elements + 1
goto err; + MAX_NUMBER_OF_DEFAULT_OPTIONS) * sizeof(char*))))
goto err;
/* the path must be first in the argv */ /* the path must be first in the argv */
if (add_to_argv(mysqld_path)) if (add_to_argv(mysqld_path))
...@@ -465,8 +449,8 @@ int Instance_options::add_option(const char* option) ...@@ -465,8 +449,8 @@ int Instance_options::add_option(const char* option)
for (selected_options= options; selected_options->name; selected_options++) for (selected_options= options; selected_options->name; selected_options++)
{ {
if (!strncmp(tmp, selected_options->name, selected_options->length)) if (strncmp(tmp, selected_options->name, selected_options->length) == 0)
switch(selected_options->type){ switch (selected_options->type) {
case SAVE_WHOLE_AND_ADD: case SAVE_WHOLE_AND_ADD:
*(selected_options->value)= tmp; *(selected_options->value)= tmp;
insert_dynamic(&options_array,(gptr) &tmp); insert_dynamic(&options_array,(gptr) &tmp);
...@@ -496,7 +480,7 @@ int Instance_options::add_to_argv(const char* option) ...@@ -496,7 +480,7 @@ int Instance_options::add_to_argv(const char* option)
{ {
DBUG_ASSERT(filled_default_options < MAX_NUMBER_OF_DEFAULT_OPTIONS); DBUG_ASSERT(filled_default_options < MAX_NUMBER_OF_DEFAULT_OPTIONS);
if ((option)) if (option)
argv[filled_default_options++]= (char*) option; argv[filled_default_options++]= (char*) option;
return 0; return 0;
} }
...@@ -508,9 +492,7 @@ void Instance_options::print_argv() ...@@ -508,9 +492,7 @@ void Instance_options::print_argv()
int i; int i;
printf("printing out an instance %s argv:\n", instance_name); printf("printing out an instance %s argv:\n", instance_name);
for (i=0; argv[i] != NULL; i++) for (i=0; argv[i] != NULL; i++)
{
printf("argv: %s\n", argv[i]); printf("argv: %s\n", argv[i]);
}
} }
...@@ -526,10 +508,10 @@ int Instance_options::init(const char *instance_name_arg) ...@@ -526,10 +508,10 @@ int Instance_options::init(const char *instance_name_arg)
init_alloc_root(&alloc, MEM_ROOT_BLOCK_SIZE, 0); init_alloc_root(&alloc, MEM_ROOT_BLOCK_SIZE, 0);
if (my_init_dynamic_array(&options_array, sizeof(char*), 0, 32)) if (my_init_dynamic_array(&options_array, sizeof(char*), 0, 32))
goto err; goto err;
if (!(instance_name= strmake_root(&alloc, (char*) instance_name_arg, if (!(instance_name= strmake_root(&alloc, (char*) instance_name_arg,
instance_name_len))) instance_name_len)))
goto err; goto err;
return 0; return 0;
......
...@@ -39,17 +39,14 @@ static int create_pid_file(const char *pid_file_name) ...@@ -39,17 +39,14 @@ static int create_pid_file(const char *pid_file_name)
{ {
if (FILE *pid_file= my_fopen(pid_file_name, if (FILE *pid_file= my_fopen(pid_file_name,
O_WRONLY | O_CREAT | O_BINARY, MYF(0))) O_WRONLY | O_CREAT | O_BINARY, MYF(0)))
{ {
fprintf(pid_file, "%d\n", (int) getpid()); fprintf(pid_file, "%d\n", (int) getpid());
my_fclose(pid_file, MYF(0)); my_fclose(pid_file, MYF(0));
} return 0;
else }
{ log_error("can't create pid file %s: errno=%d, %s",
log_error("can't create pid file %s: errno=%d, %s", pid_file_name, errno, strerror(errno));
pid_file_name, errno, strerror(errno)); return 1;
return 1;
}
return 0;
} }
#ifndef __WIN__ #ifndef __WIN__
...@@ -136,7 +133,7 @@ void manager(const Options &options) ...@@ -136,7 +133,7 @@ void manager(const Options &options)
instance_map.guardian= &guardian_thread; instance_map.guardian= &guardian_thread;
if (instance_map.init() || user_map.init()) if (instance_map.init() || user_map.init())
return; return;
if (instance_map.load()) if (instance_map.load())
...@@ -145,7 +142,7 @@ void manager(const Options &options) ...@@ -145,7 +142,7 @@ void manager(const Options &options)
"the wrong config file options. For instance, missing mysqld " "the wrong config file options. For instance, missing mysqld "
"binary. Aborting."); "binary. Aborting.");
return; return;
} }
if (user_map.load(options.password_file_name)) if (user_map.load(options.password_file_name))
return; return;
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include "protocol.h" #include "protocol.h"
#include "messages.h" #include "messages.h"
#include "command.h" #include "command.h"
#include "factory.h"
#include "parse.h" #include "parse.h"
#include <mysql.h> #include <mysql.h>
...@@ -39,8 +38,6 @@ ...@@ -39,8 +38,6 @@
#include <my_sys.h> #include <my_sys.h>
Command *parse_command(Command_factory * factory, const char *text);
Mysql_connection_thread_args::Mysql_connection_thread_args( Mysql_connection_thread_args::Mysql_connection_thread_args(
struct st_vio *vio_arg, struct st_vio *vio_arg,
Thread_registry &thread_registry_arg, Thread_registry &thread_registry_arg,
...@@ -336,8 +333,7 @@ int Mysql_connection_thread::dispatch_command(enum enum_server_command command, ...@@ -336,8 +333,7 @@ int Mysql_connection_thread::dispatch_command(enum enum_server_command command,
{ {
log_info("query for connection %d : ----\n%s\n-------------------------", log_info("query for connection %d : ----\n%s\n-------------------------",
connection_id,packet); connection_id,packet);
Command_factory commands_factory(instance_map); if (Command *command= parse_command(&instance_map, packet))
if (Command *command= parse_command(&commands_factory, packet))
{ {
int res= 0; int res= 0;
log_info("query for connection %d successefully parsed",connection_id); log_info("query for connection %d successefully parsed",connection_id);
......
...@@ -244,8 +244,6 @@ C_MODE_END ...@@ -244,8 +244,6 @@ C_MODE_END
int Options::load(int argc, char **argv) int Options::load(int argc, char **argv)
{ {
saved_argv= argv;
if (argc >= 2) if (argc >= 2)
{ {
if (is_prefix(argv[1], "--defaults-file=")) if (is_prefix(argv[1], "--defaults-file="))
...@@ -267,6 +265,8 @@ int Options::load(int argc, char **argv) ...@@ -267,6 +265,8 @@ int Options::load(int argc, char **argv)
if (setup_windows_defaults()) if (setup_windows_defaults())
goto err; goto err;
#endif #endif
/* load_defaults will reset saved_argv with a new allocated list */
saved_argv= argv;
/* config-file options are prepended to command-line ones */ /* config-file options are prepended to command-line ones */
load_defaults(config_file, default_groups, &argc, load_defaults(config_file, default_groups, &argc,
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "parse.h" #include "parse.h"
#include "factory.h" #include "commands.h"
#include <string.h> #include <string.h>
...@@ -114,7 +114,7 @@ int get_text_id(const char **text, uint *word_len, const char **id) ...@@ -114,7 +114,7 @@ int get_text_id(const char **text, uint *word_len, const char **id)
} }
Command *parse_command(Command_factory *factory, const char *text) Command *parse_command(Instance_map *map, const char *text)
{ {
uint word_len; uint word_len;
const char *instance_name; const char *instance_name;
...@@ -147,10 +147,10 @@ Command *parse_command(Command_factory *factory, const char *text) ...@@ -147,10 +147,10 @@ Command *parse_command(Command_factory *factory, const char *text)
if (word_len) if (word_len)
goto syntax_error; goto syntax_error;
command= (tok1 == TOK_START) ? (Command *) if (tok1 == TOK_START)
factory->new_Start_instance(instance_name, instance_name_len): command= new Start_instance(map, instance_name, instance_name_len);
(Command *) else
factory->new_Stop_instance(instance_name, instance_name_len); command= new Stop_instance(map, instance_name, instance_name_len);
break; break;
case TOK_FLUSH: case TOK_FLUSH:
if (shift_token(&text, &word_len) != TOK_INSTANCES) if (shift_token(&text, &word_len) != TOK_INSTANCES)
...@@ -160,7 +160,7 @@ Command *parse_command(Command_factory *factory, const char *text) ...@@ -160,7 +160,7 @@ Command *parse_command(Command_factory *factory, const char *text)
if (word_len) if (word_len)
goto syntax_error; goto syntax_error;
command= factory->new_Flush_instances(); command= new Flush_instances(map);
break; break;
case TOK_UNSET: case TOK_UNSET:
skip= true; skip= true;
...@@ -201,13 +201,13 @@ Command *parse_command(Command_factory *factory, const char *text) ...@@ -201,13 +201,13 @@ Command *parse_command(Command_factory *factory, const char *text)
goto syntax_error; goto syntax_error;
if (skip) if (skip)
command= factory->new_Unset_option(instance_name, instance_name_len, command= new Unset_option(map, instance_name, instance_name_len,
option, option_len, option_value, option, option_len, option_value,
option_value_len); option_value_len);
else else
command= factory->new_Set_option(instance_name, instance_name_len, command= new Set_option(map, instance_name, instance_name_len,
option, option_len, option_value, option, option_len, option_value,
option_value_len); option_value_len);
break; break;
case TOK_SHOW: case TOK_SHOW:
switch (shift_token(&text, &word_len)) { switch (shift_token(&text, &word_len)) {
...@@ -215,7 +215,7 @@ Command *parse_command(Command_factory *factory, const char *text) ...@@ -215,7 +215,7 @@ Command *parse_command(Command_factory *factory, const char *text)
get_word(&text, &word_len); get_word(&text, &word_len);
if (word_len) if (word_len)
goto syntax_error; goto syntax_error;
command= factory->new_Show_instances(); command= new Show_instances(map);
break; break;
case TOK_INSTANCE: case TOK_INSTANCE:
switch (Token tok2= shift_token(&text, &word_len)) { switch (Token tok2= shift_token(&text, &word_len)) {
...@@ -227,12 +227,12 @@ Command *parse_command(Command_factory *factory, const char *text) ...@@ -227,12 +227,12 @@ Command *parse_command(Command_factory *factory, const char *text)
get_word(&text, &word_len); get_word(&text, &word_len);
if (word_len) if (word_len)
goto syntax_error; goto syntax_error;
command= (tok2 == TOK_STATUS) ? (Command *) if (tok2 == TOK_STATUS)
factory->new_Show_instance_status(instance_name, command= new Show_instance_status(map, instance_name,
instance_name_len): instance_name_len);
(Command *) else
factory->new_Show_instance_options(instance_name, command= new Show_instance_options(map, instance_name,
instance_name_len); instance_name_len);
break; break;
default: default:
goto syntax_error; goto syntax_error;
...@@ -252,9 +252,8 @@ Command *parse_command(Command_factory *factory, const char *text) ...@@ -252,9 +252,8 @@ Command *parse_command(Command_factory *factory, const char *text)
/* check that this is the end of the command */ /* check that this is the end of the command */
if (word_len) if (word_len)
goto syntax_error; goto syntax_error;
command= (Command *) command= new Show_instance_log_files(map, instance_name,
factory->new_Show_instance_log_files(instance_name, instance_name_len);
instance_name_len);
break; break;
case TOK_ERROR: case TOK_ERROR:
case TOK_GENERAL: case TOK_GENERAL:
...@@ -288,22 +287,16 @@ Command *parse_command(Command_factory *factory, const char *text) ...@@ -288,22 +287,16 @@ Command *parse_command(Command_factory *factory, const char *text)
get_word(&text, &word_len); get_word(&text, &word_len);
if (!word_len) if (!word_len)
goto syntax_error; goto syntax_error;
command= (Command *) command= new Show_instance_log(map, instance_name,
factory->new_Show_instance_log(instance_name, instance_name_len, log_type,
instance_name_len, log_size, text);
log_type,
log_size,
text);
//get_text_id(&text, &log_size_len, &log_size); //get_text_id(&text, &log_size_len, &log_size);
break; break;
case '\0': case '\0':
command= (Command *) command= new Show_instance_log(map, instance_name,
factory->new_Show_instance_log(instance_name, instance_name_len, log_type,
instance_name_len, log_size, NULL);
log_type,
log_size,
NULL);
break; /* this is ok */ break; /* this is ok */
default: default:
goto syntax_error; goto syntax_error;
...@@ -324,7 +317,7 @@ Command *parse_command(Command_factory *factory, const char *text) ...@@ -324,7 +317,7 @@ Command *parse_command(Command_factory *factory, const char *text)
break; break;
default: default:
syntax_error: syntax_error:
command= factory->new_Syntax_error(); command= new Syntax_error();
} }
return command; return command;
} }
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include <my_sys.h> #include <my_sys.h>
class Command; class Command;
class Command_factory; class Instance_map;
enum Log_type enum Log_type
{ {
...@@ -29,7 +29,7 @@ enum Log_type ...@@ -29,7 +29,7 @@ enum Log_type
IM_LOG_SLOW IM_LOG_SLOW
}; };
Command *parse_command(Command_factory *factory, const char *text); Command *parse_command(Instance_map *instance_map, const char *text);
/* define kinds of the word seek method */ /* define kinds of the word seek method */
enum { ALPHANUM= 1, NONSPACE }; enum { ALPHANUM= 1, NONSPACE };
...@@ -62,5 +62,4 @@ inline void get_word(const char **text, uint *word_len, ...@@ -62,5 +62,4 @@ inline void get_word(const char **text, uint *word_len,
*word_len= word_end - *text; *word_len= word_end - *text;
} }
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_H */ #endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_H */
...@@ -43,8 +43,8 @@ ...@@ -43,8 +43,8 @@
if flag is GET_VALUE. Return the rest of the parsed string otherwise. if flag is GET_VALUE. Return the rest of the parsed string otherwise.
RETURN RETURN
0 - ok 0 - ok, the word has been found
1 - error occured 1 - error occured or the word is not found
*/ */
int parse_output_and_get_value(const char *command, const char *word, int parse_output_and_get_value(const char *command, const char *word,
...@@ -56,9 +56,15 @@ int parse_output_and_get_value(const char *command, const char *word, ...@@ -56,9 +56,15 @@ int parse_output_and_get_value(const char *command, const char *word,
/* should be enough to store the string from the output */ /* should be enough to store the string from the output */
enum { MAX_LINE_LEN= 512 }; enum { MAX_LINE_LEN= 512 };
char linebuf[MAX_LINE_LEN]; char linebuf[MAX_LINE_LEN];
int rc= 1;
wordlen= strlen(word); wordlen= strlen(word);
/*
Successful return of popen does not tell us whether the command has been
executed successfully: if the command was not found, we'll get EOF
when reading the output buffer below.
*/
if (!(output= popen(command, "r"))) if (!(output= popen(command, "r")))
goto err; goto err;
...@@ -95,10 +101,9 @@ int parse_output_and_get_value(const char *command, const char *word, ...@@ -95,10 +101,9 @@ int parse_output_and_get_value(const char *command, const char *word,
strmake(result, linep, found_word_len); strmake(result, linep, found_word_len);
} }
else /* currently there are only two options */ else /* currently there are only two options */
{
strmake(result, linep, input_buffer_len - 1); strmake(result, linep, input_buffer_len - 1);
} rc= 0;
goto pclose; break;
} }
} }
...@@ -106,9 +111,7 @@ pclose: ...@@ -106,9 +111,7 @@ pclose:
/* we are not interested in the termination status */ /* we are not interested in the termination status */
pclose(output); pclose(output);
return 0;
err: err:
return 1; return rc;
} }
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#define SIGKILL 9 #define SIGKILL 9
#define SHUT_RDWR 0x2 #define SHUT_RDWR 0x2
//TODO: fix this /*TODO: fix this */
#define DEFAULT_MONITORING_INTERVAL 20 #define DEFAULT_MONITORING_INTERVAL 20
#define DEFAULT_PORT 2273 #define DEFAULT_PORT 2273
#define PROTOCOL_VERSION 10 #define PROTOCOL_VERSION 10
......
/* Copyright (C) 2003 MySQL AB & MySQL Finland AB & TCX DataKonsult AB /* cOPYRIght (C) 2003 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -122,11 +122,10 @@ void Thread_registry::unregister_thread(Thread_info *info) ...@@ -122,11 +122,10 @@ void Thread_registry::unregister_thread(Thread_info *info)
*/ */
int Thread_registry::cond_wait(Thread_info *info, pthread_cond_t *cond, int Thread_registry::cond_wait(Thread_info *info, pthread_cond_t *cond,
pthread_mutex_t *mutex, bool *is_shutdown) pthread_mutex_t *mutex)
{ {
pthread_mutex_lock(&LOCK_thread_registry); pthread_mutex_lock(&LOCK_thread_registry);
*is_shutdown= shutdown_in_progress; if (shutdown_in_progress)
if (*is_shutdown)
{ {
pthread_mutex_unlock(&LOCK_thread_registry); pthread_mutex_unlock(&LOCK_thread_registry);
return 0; return 0;
...@@ -137,7 +136,27 @@ int Thread_registry::cond_wait(Thread_info *info, pthread_cond_t *cond, ...@@ -137,7 +136,27 @@ int Thread_registry::cond_wait(Thread_info *info, pthread_cond_t *cond,
int rc= pthread_cond_wait(cond, mutex); int rc= pthread_cond_wait(cond, mutex);
pthread_mutex_lock(&LOCK_thread_registry); pthread_mutex_lock(&LOCK_thread_registry);
info->current_cond= 0; info->current_cond= 0;
*is_shutdown= shutdown_in_progress; pthread_mutex_unlock(&LOCK_thread_registry);
return rc;
}
int Thread_registry::cond_timedwait(Thread_info *info, pthread_cond_t *cond,
pthread_mutex_t *mutex,
struct timespec *wait_time)
{
pthread_mutex_lock(&LOCK_thread_registry);
if (shutdown_in_progress)
{
pthread_mutex_unlock(&LOCK_thread_registry);
return 0;
}
info->current_cond= cond;
pthread_mutex_unlock(&LOCK_thread_registry);
/* sic: race condition here, cond can be signaled in deliver_shutdown */
int rc= pthread_cond_timedwait(cond, mutex, wait_time);
pthread_mutex_lock(&LOCK_thread_registry);
info->current_cond= 0;
pthread_mutex_unlock(&LOCK_thread_registry); pthread_mutex_unlock(&LOCK_thread_registry);
return rc; return rc;
} }
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
stop all running threads, cleanup and exit. stop all running threads, cleanup and exit.
Note, that a thread can't be shut down nicely if it doesn't want to be. Note, that a thread can't be shut down nicely if it doesn't want to be.
That's why to perform clean shutdown, all threads consituting a process That's why to perform clean shutdown, all threads constituting a process
must observe certain rules. Here we use the rules, described in Butenhof must observe certain rules. Here we use the rules, described in Butenhof
book 'Programming with POSIX threads', namely: book 'Programming with POSIX threads', namely:
- all user signals are handled in 'signal thread' in synchronous manner - all user signals are handled in 'signal thread' in synchronous manner
...@@ -94,7 +94,9 @@ public: ...@@ -94,7 +94,9 @@ public:
void request_shutdown(); void request_shutdown();
inline bool is_shutdown(); inline bool is_shutdown();
int cond_wait(Thread_info *info, pthread_cond_t *cond, int cond_wait(Thread_info *info, pthread_cond_t *cond,
pthread_mutex_t *mutex, bool *is_shutdown); pthread_mutex_t *mutex);
int cond_timedwait(Thread_info *info, pthread_cond_t *cond,
pthread_mutex_t *mutex, struct timespec *wait_time);
private: private:
Thread_info head; Thread_info head;
bool shutdown_in_progress; bool shutdown_in_progress;
......
...@@ -128,7 +128,7 @@ int User_map::load(const char *password_file_name) ...@@ -128,7 +128,7 @@ int User_map::load(const char *password_file_name)
char line[USERNAME_LENGTH + SCRAMBLED_PASSWORD_CHAR_LENGTH + char line[USERNAME_LENGTH + SCRAMBLED_PASSWORD_CHAR_LENGTH +
2 + /* for possible quotes */ 2 + /* for possible quotes */
1 + /* for ':' */ 1 + /* for ':' */
1 + /* for newline */ 2 + /* for newline */
1]; /* for trailing zero */ 1]; /* for trailing zero */
User *user; User *user;
int rc= 1; int rc= 1;
......
...@@ -2820,15 +2820,15 @@ mysql_discard_or_import_tablespace(THD *thd, ...@@ -2820,15 +2820,15 @@ mysql_discard_or_import_tablespace(THD *thd,
err: err:
close_thread_tables(thd); close_thread_tables(thd);
thd->tablespace_op=FALSE; thd->tablespace_op=FALSE;
if (error == 0) if (error == 0)
{ {
send_ok(thd); send_ok(thd);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
if (error == HA_ERR_ROW_IS_REFERENCED) table->file->print_error(error, MYF(0));
my_error(ER_ROW_IS_REFERENCED, MYF(0));
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
......
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