mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 04:22:27 +01:00
Merge osalerma@bk-internal.mysql.com:/home/bk/mysql-5.0
into 127.(none):/home/osku/mysql-5.0
This commit is contained in:
commit
b3dcaff948
33 changed files with 256 additions and 359 deletions
|
@ -203,7 +203,7 @@ static int com_nopager(String *str, char*), com_pager(String *str, char*),
|
|||
com_edit(String *str,char*), com_shell(String *str, char *);
|
||||
#endif
|
||||
|
||||
static int read_lines(bool execute_commands);
|
||||
static int read_and_execute(bool interactive);
|
||||
static int sql_connect(char *host,char *database,char *user,char *password,
|
||||
uint silent);
|
||||
static int put_info(const char *str,INFO_TYPE info,uint error=0,
|
||||
|
@ -468,7 +468,7 @@ int main(int argc,char *argv[])
|
|||
"Type 'help [[%]function name[%]]' to get help on usage of function.\n");
|
||||
#endif
|
||||
put_info(buff,INFO_INFO);
|
||||
status.exit_status=read_lines(1); // read lines and execute them
|
||||
status.exit_status= read_and_execute(!status.batch);
|
||||
if (opt_outfile)
|
||||
end_tee();
|
||||
mysql_end(0);
|
||||
|
@ -957,7 +957,7 @@ static int get_options(int argc, char **argv)
|
|||
return(0);
|
||||
}
|
||||
|
||||
static int read_lines(bool execute_commands)
|
||||
static int read_and_execute(bool interactive)
|
||||
{
|
||||
#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
|
||||
char linebuffer[254];
|
||||
|
@ -972,7 +972,7 @@ static int read_lines(bool execute_commands)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
if (status.batch || !execute_commands)
|
||||
if (!interactive)
|
||||
{
|
||||
line=batch_readline(status.line_buff);
|
||||
line_number++;
|
||||
|
@ -1050,7 +1050,7 @@ static int read_lines(bool execute_commands)
|
|||
Check if line is a mysql command line
|
||||
(We want to allow help, print and clear anywhere at line start
|
||||
*/
|
||||
if (execute_commands && (named_cmds || glob_buffer.is_empty())
|
||||
if ((named_cmds || glob_buffer.is_empty())
|
||||
&& !in_string && (com=find_command(line,0)))
|
||||
{
|
||||
if ((*com->func)(&glob_buffer,line) > 0)
|
||||
|
@ -1058,7 +1058,7 @@ static int read_lines(bool execute_commands)
|
|||
if (glob_buffer.is_empty()) // If buffer was emptied
|
||||
in_string=0;
|
||||
#ifdef HAVE_READLINE
|
||||
if (status.add_to_history && not_in_history(line))
|
||||
if (interactive && status.add_to_history && not_in_history(line))
|
||||
add_history(line);
|
||||
#endif
|
||||
continue;
|
||||
|
@ -1068,7 +1068,7 @@ static int read_lines(bool execute_commands)
|
|||
}
|
||||
/* if in batch mode, send last query even if it doesn't end with \g or go */
|
||||
|
||||
if ((status.batch || !execute_commands) && !status.exit_status)
|
||||
if (!interactive && !status.exit_status)
|
||||
{
|
||||
remove_cntrl(glob_buffer);
|
||||
if (!glob_buffer.is_empty())
|
||||
|
@ -2783,7 +2783,7 @@ static int com_source(String *buffer, char *line)
|
|||
status.line_buff=line_buff;
|
||||
status.file_name=source_name;
|
||||
glob_buffer.length(0); // Empty command buffer
|
||||
error=read_lines(0); // Read lines from file
|
||||
error= read_and_execute(false);
|
||||
status=old_status; // Continue as before
|
||||
my_fclose(sql_file,MYF(0));
|
||||
batch_readline_end(line_buff);
|
||||
|
|
|
@ -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
|
||||
alter table t1 drop key a;
|
||||
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;
|
||||
insert into t1 values (_koi8r'ÔÅÓÔ');
|
||||
select hex(a) from t1;
|
||||
|
|
|
@ -31,6 +31,10 @@ a
|
|||
Test delimiter delimiter
|
||||
a
|
||||
1
|
||||
Tables_in_test
|
||||
t1
|
||||
t2
|
||||
t3
|
||||
|
||||
Test delimiter : from command line
|
||||
a
|
||||
|
|
|
@ -2875,6 +2875,16 @@ b a t1_val t2_val
|
|||
1 1 1 1
|
||||
1 2 2 1
|
||||
drop table t1, t2, t3;
|
||||
DO IFNULL(NULL, NULL);
|
||||
SELECT CAST(IFNULL(NULL, NULL) AS DECIMAL);
|
||||
CAST(IFNULL(NULL, NULL) AS DECIMAL)
|
||||
NULL
|
||||
SELECT ABS(IFNULL(NULL, NULL));
|
||||
ABS(IFNULL(NULL, NULL))
|
||||
NULL
|
||||
SELECT IFNULL(NULL, NULL);
|
||||
IFNULL(NULL, NULL)
|
||||
NULL
|
||||
create table t1 (a char(1));
|
||||
create table t2 (a char(1));
|
||||
insert into t1 values ('a'),('b'),('c');
|
||||
|
|
|
@ -748,6 +748,14 @@ end|
|
|||
call bug11394(2, 1)|
|
||||
ERROR HY000: Recursive stored routines are not allowed.
|
||||
drop procedure bug11394|
|
||||
CREATE PROCEDURE BUG_12490() HELP CONTENTS;
|
||||
ERROR 0A000: HELP is not allowed in stored procedures
|
||||
CREATE FUNCTION BUG_12490() RETURNS INT HELP CONTENTS;
|
||||
ERROR 0A000: HELP is not allowed in stored procedures
|
||||
CREATE TABLE t_bug_12490(a int);
|
||||
CREATE TRIGGER BUG_12490 BEFORE UPDATE ON t_bug_12490 FOR EACH ROW HELP CONTENTS;
|
||||
ERROR 0A000: HELP is not allowed in stored procedures
|
||||
DROP TABLE t_bug_12490;
|
||||
drop function if exists bug11834_1;
|
||||
drop function if exists bug11834_2;
|
||||
create function bug11834_1() returns int return 10;
|
||||
|
|
|
@ -337,6 +337,14 @@ alter table t1 drop key no_such_key;
|
|||
alter table t1 drop key a;
|
||||
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
|
||||
#
|
||||
|
|
|
@ -45,4 +45,7 @@ delimiter delimiter
|
|||
select * from t1 delimiter
|
||||
delimiter ; # Reset delimiter
|
||||
|
||||
|
||||
#
|
||||
# Bug #11523: \d works differently than delimiter
|
||||
#
|
||||
source t/mysql_delimiter_source.sql
|
||||
|
|
8
mysql-test/t/mysql_delimiter_source.sql
Normal file
8
mysql-test/t/mysql_delimiter_source.sql
Normal file
|
@ -0,0 +1,8 @@
|
|||
delimiter //
|
||||
create table t2 (a int) //
|
||||
delimiter ;
|
||||
\d //
|
||||
create table t3 (a int) //
|
||||
\d ;
|
||||
show tables;
|
||||
drop table t2, t3;
|
|
@ -2445,6 +2445,15 @@ select * from t1 natural join t3 natural join t2;
|
|||
drop table t1, t2, t3;
|
||||
|
||||
|
||||
#
|
||||
# Bug #12841: Server crash on DO IFNULL(NULL,NULL)
|
||||
#
|
||||
# (testing returning of int, decimal, real, string)
|
||||
DO IFNULL(NULL, NULL);
|
||||
SELECT CAST(IFNULL(NULL, NULL) AS DECIMAL);
|
||||
SELECT ABS(IFNULL(NULL, NULL));
|
||||
SELECT IFNULL(NULL, NULL);
|
||||
|
||||
#
|
||||
# Bug #6495 Illogical requirement for column qualification in NATURAL join
|
||||
#
|
||||
|
|
|
@ -1079,6 +1079,19 @@ call bug11394(2, 1)|
|
|||
drop procedure bug11394|
|
||||
delimiter ;|
|
||||
|
||||
|
||||
#
|
||||
# BUG 12490 (Packets out of order if calling HELP CONTENTS from Stored Procedure)
|
||||
#
|
||||
--error 1314
|
||||
CREATE PROCEDURE BUG_12490() HELP CONTENTS;
|
||||
--error 1314
|
||||
CREATE FUNCTION BUG_12490() RETURNS INT HELP CONTENTS;
|
||||
CREATE TABLE t_bug_12490(a int);
|
||||
--error 1314
|
||||
CREATE TRIGGER BUG_12490 BEFORE UPDATE ON t_bug_12490 FOR EACH ROW HELP CONTENTS;
|
||||
DROP TABLE t_bug_12490;
|
||||
|
||||
#
|
||||
# Bug#11834 "Re-execution of prepared statement with dropped function
|
||||
# crashes server". Also tests handling of prepared stmts which use
|
||||
|
|
|
@ -509,7 +509,7 @@ ALTER TABLE proc MODIFY name char(64) DEFAULT '' NOT NULL,
|
|||
'TRADITIONAL',
|
||||
'NO_AUTO_CREATE_USER',
|
||||
'HIGH_NOT_PRECEDENCE'
|
||||
) DEFAULT '' NOT NULL
|
||||
) DEFAULT '' NOT NULL,
|
||||
DEFAULT CHARACTER SET utf8;
|
||||
|
||||
# Correct the character set and collation
|
||||
|
|
|
@ -70,7 +70,6 @@ mysqlmanager_SOURCES= command.cc command.h mysqlmanager.cc \
|
|||
user_map.h user_map.cc \
|
||||
messages.h messages.cc \
|
||||
commands.h commands.cc \
|
||||
factory.h factory.cc \
|
||||
instance.h instance.cc \
|
||||
instance_map.h instance_map.cc\
|
||||
instance_options.h instance_options.cc \
|
||||
|
|
|
@ -461,7 +461,8 @@ int Show_instance_log::execute(struct st_net *net, ulong connection_id)
|
|||
/* Instance has no such log */
|
||||
if (logpath == NULL)
|
||||
return ER_NO_SUCH_LOG;
|
||||
else if (*logpath == '\0')
|
||||
|
||||
if (*logpath == '\0')
|
||||
return ER_GUESS_LOGFILE;
|
||||
|
||||
|
||||
|
@ -571,6 +572,7 @@ int Show_instance_log_files::execute(struct st_net *net, ulong connection_id)
|
|||
if ((instance= instance_map->
|
||||
find(instance_name, strlen(instance_name))) == NULL)
|
||||
goto err;
|
||||
|
||||
{
|
||||
/*
|
||||
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,
|
|||
option.
|
||||
|
||||
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
|
||||
0 - ok
|
||||
*/
|
||||
|
@ -694,22 +696,14 @@ Set_option::Set_option(Instance_map *instance_map_arg,
|
|||
int Set_option::correct_file(int skip)
|
||||
{
|
||||
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,
|
||||
option_value, instance_name, skip);
|
||||
switch (error)
|
||||
{
|
||||
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 */
|
||||
}
|
||||
DBUG_ASSERT(error >= 0 && error <= 2);
|
||||
|
||||
return 0; /* keep compiler happy */
|
||||
return mysys_to_im_error[error];
|
||||
}
|
||||
|
||||
|
||||
|
@ -725,10 +719,9 @@ int Set_option::correct_file(int skip)
|
|||
1 - error occured
|
||||
*/
|
||||
|
||||
|
||||
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 */
|
||||
instance_map->lock();
|
||||
|
@ -746,16 +739,14 @@ int Set_option::execute(struct st_net *net, ulong connection_id)
|
|||
int val;
|
||||
|
||||
val= do_command(net);
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
net_send_ok(net, connection_id, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
|||
|
||||
if (instance == 0)
|
||||
return ER_BAD_INSTANCE_NAME; /* haven't found an instance */
|
||||
else
|
||||
{
|
||||
if (!(instance->options.nonguarded))
|
||||
instance_map->guardian->
|
||||
stop_guard(instance);
|
||||
if ((err_code= instance->stop()))
|
||||
return err_code;
|
||||
net_send_ok(net, connection_id, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(instance->options.nonguarded))
|
||||
instance_map->guardian->stop_guard(instance);
|
||||
|
||||
if ((err_code= instance->stop()))
|
||||
return err_code;
|
||||
|
||||
net_send_ok(net, connection_id, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,100 +0,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);
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
#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,
|
|||
}
|
||||
else
|
||||
{
|
||||
switch (current_node->state)
|
||||
{
|
||||
switch (current_node->state) {
|
||||
case NOT_STARTED:
|
||||
instance->start();
|
||||
current_node->last_checked= current_time;
|
||||
|
@ -149,7 +148,8 @@ void Guardian_thread::process_instance(Instance *instance,
|
|||
log_info("guardian: starting instance %s",
|
||||
instance->options.instance_name);
|
||||
}
|
||||
else current_node->state= CRASHED;
|
||||
else
|
||||
current_node->state= CRASHED;
|
||||
break;
|
||||
case CRASHED: /* just regular restarts */
|
||||
if (current_time - current_node->last_checked >
|
||||
|
@ -219,7 +219,8 @@ void Guardian_thread::run()
|
|||
|
||||
/* check the loop predicate before sleeping */
|
||||
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;
|
||||
|
@ -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
|
||||
stop_instances()
|
||||
stop_instances_arg whether we should stop instances at shutdown
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
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
|
||||
the state accordingly. Otherwise we could simply delete an entry.
|
||||
NOTE: Guardian should be locked by the calling function
|
||||
the state accordingly. Otherwise we simply delete an entry.
|
||||
|
||||
NOTE
|
||||
Guardian object should be locked by the calling function.
|
||||
|
||||
RETURN
|
||||
0 - ok
|
||||
|
|
|
@ -62,8 +62,8 @@ class Guardian_thread: public Guardian_thread_args
|
|||
{
|
||||
public:
|
||||
/* states of an instance */
|
||||
enum INSTANCE_STATE { NOT_STARTED= 1, STARTING, STARTED, JUST_CRASHED,
|
||||
CRASHED, CRASHED_AND_ABANDONED, STOPPING };
|
||||
enum enum_instance_state { NOT_STARTED= 1, STARTING, STARTED, JUST_CRASHED,
|
||||
CRASHED, CRASHED_AND_ABANDONED, STOPPING };
|
||||
|
||||
/*
|
||||
The Guardian list node structure. Guardian utilizes it to store
|
||||
|
@ -74,7 +74,7 @@ public:
|
|||
{
|
||||
Instance *instance;
|
||||
/* 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) */
|
||||
int restart_counter;
|
||||
/* triggered at a crash */
|
||||
|
|
|
@ -49,12 +49,12 @@ public:
|
|||
Instance_options options;
|
||||
|
||||
private:
|
||||
int crashed;
|
||||
/*
|
||||
Mutex protecting the instance. Currently we use it to avoid the
|
||||
double start of the instance. This happens when the instance is starting
|
||||
and we issue the start command once more.
|
||||
*/
|
||||
int crashed;
|
||||
pthread_mutex_t LOCK_instance;
|
||||
/*
|
||||
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)
|
|||
if ((instance= map->find(group, strlen(group))) == NULL)
|
||||
{
|
||||
if ((instance= new Instance) == 0)
|
||||
goto err_new_instance;
|
||||
if (instance->init(group))
|
||||
goto err;
|
||||
if (map->add_instance(instance))
|
||||
goto err;
|
||||
if (instance->init(group) || map->add_instance(instance))
|
||||
goto err_instance;
|
||||
}
|
||||
|
||||
if (instance->options.add_option(option))
|
||||
goto err;
|
||||
goto err; /* the instance'll be deleted when we destroy the map */
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
err_instance:
|
||||
delete instance;
|
||||
err_new_instance:
|
||||
err:
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -122,10 +120,8 @@ mysqld_path(default_mysqld_path_arg)
|
|||
|
||||
int Instance_map::init()
|
||||
{
|
||||
if (hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
|
||||
get_instance_key, delete_instance, 0))
|
||||
return 1;
|
||||
return 0;
|
||||
return hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
|
||||
get_instance_key, delete_instance, 0);
|
||||
}
|
||||
|
||||
Instance_map::~Instance_map()
|
||||
|
@ -217,10 +213,9 @@ int Instance_map::complete_initialization()
|
|||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
return 1;
|
||||
err_instance:
|
||||
delete instance;
|
||||
err:
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,13 +51,9 @@ static inline int create_mysqld_command(Buffer *buf,
|
|||
/* here the '\0' character is copied from the option string */
|
||||
buf->append(position, option, option_len);
|
||||
|
||||
if (buf->is_error())
|
||||
return 1;
|
||||
return buf->is_error();
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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") */
|
||||
rc= parse_output_and_get_value(cmd.buffer, option_name + 2,
|
||||
result, result_len, GET_VALUE);
|
||||
|
||||
return rc;
|
||||
err:
|
||||
return 1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
@ -142,11 +136,8 @@ int Instance_options::fill_instance_version()
|
|||
result[strlen(result) - NEWLINE_LEN]= '\0';
|
||||
mysqld_version= strdup_root(&alloc, result);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
err:
|
||||
return 1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
@ -194,13 +185,15 @@ int Instance_options::fill_log_options()
|
|||
/* compute hostname and datadir for the instance */
|
||||
if (mysqld_datadir == NULL)
|
||||
{
|
||||
if (get_default_option(datadir,
|
||||
MAX_LOG_OPTION_LENGTH, "--datadir"))
|
||||
if (get_default_option(datadir, MAX_LOG_OPTION_LENGTH, "--datadir"))
|
||||
goto err;
|
||||
}
|
||||
else /* below is safe, as --datadir always has a value */
|
||||
strmake(datadir, strchr(mysqld_datadir, '=') + 1,
|
||||
MAX_LOG_OPTION_LENGTH - 1);
|
||||
else
|
||||
{
|
||||
/* 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)
|
||||
strmov(hostname, "mysql");
|
||||
|
@ -230,15 +223,12 @@ int Instance_options::fill_log_options()
|
|||
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))
|
||||
{
|
||||
strmov(full_name + strlen(full_name),
|
||||
log_files->default_suffix);
|
||||
}
|
||||
else
|
||||
goto err;
|
||||
|
||||
strmov(full_name + strlen(full_name), log_files->default_suffix);
|
||||
|
||||
/*
|
||||
If there were specified two identical logfiles options,
|
||||
we would loose some memory in MEM_ROOT here. However
|
||||
|
@ -254,8 +244,7 @@ int Instance_options::fill_log_options()
|
|||
fn_format(full_name, argv[i] +log_files->length + 1,
|
||||
datadir, "", MY_UNPACK_FILENAME | MY_SAFE_PATH);
|
||||
|
||||
if (!(*(log_files->value)=
|
||||
strdup_root(&alloc, full_name)))
|
||||
if (!(*(log_files->value)= strdup_root(&alloc, full_name)))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
@ -263,10 +252,8 @@ int Instance_options::fill_log_options()
|
|||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -294,7 +281,7 @@ int Instance_options::get_pid_filename(char *result)
|
|||
const char *pid_file= mysqld_pid_file;
|
||||
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 */
|
||||
if (get_default_option(datadir, sizeof(datadir), "--datadir"))
|
||||
|
@ -333,8 +320,7 @@ pid_t Instance_options::get_pid()
|
|||
my_fclose(pid_file_stream, MYF(0));
|
||||
return pid;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -343,11 +329,8 @@ int Instance_options::complete_initialization(const char *default_path,
|
|||
{
|
||||
const char *tmp;
|
||||
|
||||
if (!(mysqld_path))
|
||||
{
|
||||
if (!(mysqld_path= strdup_root(&alloc, default_path)))
|
||||
goto err;
|
||||
}
|
||||
if (!mysqld_path && !(mysqld_path= strdup_root(&alloc, default_path)))
|
||||
goto err;
|
||||
|
||||
mysqld_path_len= strlen(mysqld_path);
|
||||
|
||||
|
@ -395,9 +378,10 @@ int Instance_options::complete_initialization(const char *default_path,
|
|||
goto err;
|
||||
|
||||
/* we need to reserve space for the final zero + possible default options */
|
||||
if (!(argv= (char**) alloc_root(&alloc, (options_array.elements + 1
|
||||
+ MAX_NUMBER_OF_DEFAULT_OPTIONS) * sizeof(char*))))
|
||||
goto err;
|
||||
if (!(argv= (char**)
|
||||
alloc_root(&alloc, (options_array.elements + 1
|
||||
+ MAX_NUMBER_OF_DEFAULT_OPTIONS) * sizeof(char*))))
|
||||
goto err;
|
||||
|
||||
/* the path must be first in the argv */
|
||||
if (add_to_argv(mysqld_path))
|
||||
|
@ -465,8 +449,8 @@ int Instance_options::add_option(const char* option)
|
|||
|
||||
for (selected_options= options; selected_options->name; selected_options++)
|
||||
{
|
||||
if (!strncmp(tmp, selected_options->name, selected_options->length))
|
||||
switch(selected_options->type){
|
||||
if (strncmp(tmp, selected_options->name, selected_options->length) == 0)
|
||||
switch (selected_options->type) {
|
||||
case SAVE_WHOLE_AND_ADD:
|
||||
*(selected_options->value)= tmp;
|
||||
insert_dynamic(&options_array,(gptr) &tmp);
|
||||
|
@ -496,7 +480,7 @@ int Instance_options::add_to_argv(const char* option)
|
|||
{
|
||||
DBUG_ASSERT(filled_default_options < MAX_NUMBER_OF_DEFAULT_OPTIONS);
|
||||
|
||||
if ((option))
|
||||
if (option)
|
||||
argv[filled_default_options++]= (char*) option;
|
||||
return 0;
|
||||
}
|
||||
|
@ -508,9 +492,7 @@ void Instance_options::print_argv()
|
|||
int i;
|
||||
printf("printing out an instance %s argv:\n", instance_name);
|
||||
for (i=0; argv[i] != NULL; i++)
|
||||
{
|
||||
printf("argv: %s\n", argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -526,10 +508,10 @@ int Instance_options::init(const char *instance_name_arg)
|
|||
init_alloc_root(&alloc, MEM_ROOT_BLOCK_SIZE, 0);
|
||||
|
||||
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,
|
||||
instance_name_len)))
|
||||
instance_name_len)))
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -39,17 +39,14 @@ static int create_pid_file(const char *pid_file_name)
|
|||
{
|
||||
if (FILE *pid_file= my_fopen(pid_file_name,
|
||||
O_WRONLY | O_CREAT | O_BINARY, MYF(0)))
|
||||
{
|
||||
fprintf(pid_file, "%d\n", (int) getpid());
|
||||
my_fclose(pid_file, MYF(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("can't create pid file %s: errno=%d, %s",
|
||||
pid_file_name, errno, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
{
|
||||
fprintf(pid_file, "%d\n", (int) getpid());
|
||||
my_fclose(pid_file, MYF(0));
|
||||
return 0;
|
||||
}
|
||||
log_error("can't create pid file %s: errno=%d, %s",
|
||||
pid_file_name, errno, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef __WIN__
|
||||
|
@ -136,7 +133,7 @@ void manager(const Options &options)
|
|||
instance_map.guardian= &guardian_thread;
|
||||
|
||||
if (instance_map.init() || user_map.init())
|
||||
return;
|
||||
return;
|
||||
|
||||
|
||||
if (instance_map.load())
|
||||
|
@ -145,7 +142,7 @@ void manager(const Options &options)
|
|||
"the wrong config file options. For instance, missing mysqld "
|
||||
"binary. Aborting.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (user_map.load(options.password_file_name))
|
||||
return;
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include "protocol.h"
|
||||
#include "messages.h"
|
||||
#include "command.h"
|
||||
#include "factory.h"
|
||||
#include "parse.h"
|
||||
|
||||
#include <mysql.h>
|
||||
|
@ -39,8 +38,6 @@
|
|||
#include <my_sys.h>
|
||||
|
||||
|
||||
Command *parse_command(Command_factory * factory, const char *text);
|
||||
|
||||
Mysql_connection_thread_args::Mysql_connection_thread_args(
|
||||
struct st_vio *vio_arg,
|
||||
Thread_registry &thread_registry_arg,
|
||||
|
@ -336,8 +333,7 @@ int Mysql_connection_thread::dispatch_command(enum enum_server_command command,
|
|||
{
|
||||
log_info("query for connection %d : ----\n%s\n-------------------------",
|
||||
connection_id,packet);
|
||||
Command_factory commands_factory(instance_map);
|
||||
if (Command *command= parse_command(&commands_factory, packet))
|
||||
if (Command *command= parse_command(&instance_map, packet))
|
||||
{
|
||||
int res= 0;
|
||||
log_info("query for connection %d successefully parsed",connection_id);
|
||||
|
|
|
@ -244,8 +244,6 @@ C_MODE_END
|
|||
|
||||
int Options::load(int argc, char **argv)
|
||||
{
|
||||
saved_argv= argv;
|
||||
|
||||
if (argc >= 2)
|
||||
{
|
||||
if (is_prefix(argv[1], "--defaults-file="))
|
||||
|
@ -267,6 +265,8 @@ int Options::load(int argc, char **argv)
|
|||
if (setup_windows_defaults())
|
||||
goto err;
|
||||
#endif
|
||||
/* load_defaults will reset saved_argv with a new allocated list */
|
||||
saved_argv= argv;
|
||||
|
||||
/* config-file options are prepended to command-line ones */
|
||||
load_defaults(config_file, default_groups, &argc,
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "parse.h"
|
||||
#include "factory.h"
|
||||
#include "commands.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -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;
|
||||
const char *instance_name;
|
||||
|
@ -147,10 +147,10 @@ Command *parse_command(Command_factory *factory, const char *text)
|
|||
if (word_len)
|
||||
goto syntax_error;
|
||||
|
||||
command= (tok1 == TOK_START) ? (Command *)
|
||||
factory->new_Start_instance(instance_name, instance_name_len):
|
||||
(Command *)
|
||||
factory->new_Stop_instance(instance_name, instance_name_len);
|
||||
if (tok1 == TOK_START)
|
||||
command= new Start_instance(map, instance_name, instance_name_len);
|
||||
else
|
||||
command= new Stop_instance(map, instance_name, instance_name_len);
|
||||
break;
|
||||
case TOK_FLUSH:
|
||||
if (shift_token(&text, &word_len) != TOK_INSTANCES)
|
||||
|
@ -160,7 +160,7 @@ Command *parse_command(Command_factory *factory, const char *text)
|
|||
if (word_len)
|
||||
goto syntax_error;
|
||||
|
||||
command= factory->new_Flush_instances();
|
||||
command= new Flush_instances(map);
|
||||
break;
|
||||
case TOK_UNSET:
|
||||
skip= true;
|
||||
|
@ -201,13 +201,13 @@ Command *parse_command(Command_factory *factory, const char *text)
|
|||
goto syntax_error;
|
||||
|
||||
if (skip)
|
||||
command= factory->new_Unset_option(instance_name, instance_name_len,
|
||||
option, option_len, option_value,
|
||||
option_value_len);
|
||||
command= new Unset_option(map, instance_name, instance_name_len,
|
||||
option, option_len, option_value,
|
||||
option_value_len);
|
||||
else
|
||||
command= factory->new_Set_option(instance_name, instance_name_len,
|
||||
option, option_len, option_value,
|
||||
option_value_len);
|
||||
command= new Set_option(map, instance_name, instance_name_len,
|
||||
option, option_len, option_value,
|
||||
option_value_len);
|
||||
break;
|
||||
case TOK_SHOW:
|
||||
switch (shift_token(&text, &word_len)) {
|
||||
|
@ -215,7 +215,7 @@ Command *parse_command(Command_factory *factory, const char *text)
|
|||
get_word(&text, &word_len);
|
||||
if (word_len)
|
||||
goto syntax_error;
|
||||
command= factory->new_Show_instances();
|
||||
command= new Show_instances(map);
|
||||
break;
|
||||
case TOK_INSTANCE:
|
||||
switch (Token tok2= shift_token(&text, &word_len)) {
|
||||
|
@ -227,12 +227,12 @@ Command *parse_command(Command_factory *factory, const char *text)
|
|||
get_word(&text, &word_len);
|
||||
if (word_len)
|
||||
goto syntax_error;
|
||||
command= (tok2 == TOK_STATUS) ? (Command *)
|
||||
factory->new_Show_instance_status(instance_name,
|
||||
instance_name_len):
|
||||
(Command *)
|
||||
factory->new_Show_instance_options(instance_name,
|
||||
instance_name_len);
|
||||
if (tok2 == TOK_STATUS)
|
||||
command= new Show_instance_status(map, instance_name,
|
||||
instance_name_len);
|
||||
else
|
||||
command= new Show_instance_options(map, instance_name,
|
||||
instance_name_len);
|
||||
break;
|
||||
default:
|
||||
goto syntax_error;
|
||||
|
@ -252,9 +252,8 @@ Command *parse_command(Command_factory *factory, const char *text)
|
|||
/* check that this is the end of the command */
|
||||
if (word_len)
|
||||
goto syntax_error;
|
||||
command= (Command *)
|
||||
factory->new_Show_instance_log_files(instance_name,
|
||||
instance_name_len);
|
||||
command= new Show_instance_log_files(map, instance_name,
|
||||
instance_name_len);
|
||||
break;
|
||||
case TOK_ERROR:
|
||||
case TOK_GENERAL:
|
||||
|
@ -288,22 +287,16 @@ Command *parse_command(Command_factory *factory, const char *text)
|
|||
get_word(&text, &word_len);
|
||||
if (!word_len)
|
||||
goto syntax_error;
|
||||
command= (Command *)
|
||||
factory->new_Show_instance_log(instance_name,
|
||||
instance_name_len,
|
||||
log_type,
|
||||
log_size,
|
||||
text);
|
||||
command= new Show_instance_log(map, instance_name,
|
||||
instance_name_len, log_type,
|
||||
log_size, text);
|
||||
|
||||
//get_text_id(&text, &log_size_len, &log_size);
|
||||
break;
|
||||
case '\0':
|
||||
command= (Command *)
|
||||
factory->new_Show_instance_log(instance_name,
|
||||
instance_name_len,
|
||||
log_type,
|
||||
log_size,
|
||||
NULL);
|
||||
command= new Show_instance_log(map, instance_name,
|
||||
instance_name_len, log_type,
|
||||
log_size, NULL);
|
||||
break; /* this is ok */
|
||||
default:
|
||||
goto syntax_error;
|
||||
|
@ -324,7 +317,7 @@ Command *parse_command(Command_factory *factory, const char *text)
|
|||
break;
|
||||
default:
|
||||
syntax_error:
|
||||
command= factory->new_Syntax_error();
|
||||
command= new Syntax_error();
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <my_sys.h>
|
||||
|
||||
class Command;
|
||||
class Command_factory;
|
||||
class Instance_map;
|
||||
|
||||
enum Log_type
|
||||
{
|
||||
|
@ -29,7 +29,7 @@ enum Log_type
|
|||
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 */
|
||||
enum { ALPHANUM= 1, NONSPACE };
|
||||
|
@ -62,5 +62,4 @@ inline void get_word(const char **text, uint *word_len,
|
|||
*word_len= word_end - *text;
|
||||
}
|
||||
|
||||
|
||||
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_H */
|
||||
|
|
|
@ -43,8 +43,8 @@
|
|||
if flag is GET_VALUE. Return the rest of the parsed string otherwise.
|
||||
|
||||
RETURN
|
||||
0 - ok
|
||||
1 - error occured
|
||||
0 - ok, the word has been found
|
||||
1 - error occured or the word is not found
|
||||
*/
|
||||
|
||||
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 */
|
||||
enum { MAX_LINE_LEN= 512 };
|
||||
char linebuf[MAX_LINE_LEN];
|
||||
int rc= 1;
|
||||
|
||||
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")))
|
||||
goto err;
|
||||
|
||||
|
@ -95,10 +101,9 @@ int parse_output_and_get_value(const char *command, const char *word,
|
|||
strmake(result, linep, found_word_len);
|
||||
}
|
||||
else /* currently there are only two options */
|
||||
{
|
||||
strmake(result, linep, input_buffer_len - 1);
|
||||
}
|
||||
goto pclose;
|
||||
rc= 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,9 +111,7 @@ pclose:
|
|||
/* we are not interested in the termination status */
|
||||
pclose(output);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
return 1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#define SIGKILL 9
|
||||
#define SHUT_RDWR 0x2
|
||||
|
||||
//TODO: fix this
|
||||
/*TODO: fix this */
|
||||
#define DEFAULT_MONITORING_INTERVAL 20
|
||||
#define DEFAULT_PORT 2273
|
||||
#define PROTOCOL_VERSION 10
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* 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
|
||||
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)
|
|||
*/
|
||||
|
||||
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);
|
||||
*is_shutdown= shutdown_in_progress;
|
||||
if (*is_shutdown)
|
||||
if (shutdown_in_progress)
|
||||
{
|
||||
pthread_mutex_unlock(&LOCK_thread_registry);
|
||||
return 0;
|
||||
|
@ -137,7 +136,27 @@ int Thread_registry::cond_wait(Thread_info *info, pthread_cond_t *cond,
|
|||
int rc= pthread_cond_wait(cond, mutex);
|
||||
pthread_mutex_lock(&LOCK_thread_registry);
|
||||
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);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
stop all running threads, cleanup and exit.
|
||||
|
||||
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
|
||||
book 'Programming with POSIX threads', namely:
|
||||
- all user signals are handled in 'signal thread' in synchronous manner
|
||||
|
@ -94,7 +94,9 @@ public:
|
|||
void request_shutdown();
|
||||
inline bool is_shutdown();
|
||||
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:
|
||||
Thread_info head;
|
||||
bool shutdown_in_progress;
|
||||
|
|
|
@ -128,7 +128,7 @@ int User_map::load(const char *password_file_name)
|
|||
char line[USERNAME_LENGTH + SCRAMBLED_PASSWORD_CHAR_LENGTH +
|
||||
2 + /* for possible quotes */
|
||||
1 + /* for ':' */
|
||||
1 + /* for newline */
|
||||
2 + /* for newline */
|
||||
1]; /* for trailing zero */
|
||||
User *user;
|
||||
int rc= 1;
|
||||
|
|
|
@ -734,11 +734,13 @@ longlong Item_func_numhybrid::val_int()
|
|||
case STRING_RESULT:
|
||||
{
|
||||
int err_not_used;
|
||||
String *res= str_op(&str_value);
|
||||
String *res;
|
||||
if (!(res= str_op(&str_value)))
|
||||
return 0;
|
||||
|
||||
char *end= (char*) res->ptr() + res->length();
|
||||
CHARSET_INFO *cs= str_value.charset();
|
||||
return (res ? (*(cs->cset->strtoll10))(cs, res->ptr(), &end,
|
||||
&err_not_used) : 0);
|
||||
return (*(cs->cset->strtoll10))(cs, res->ptr(), &end, &err_not_used);
|
||||
}
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
|
@ -769,7 +771,10 @@ my_decimal *Item_func_numhybrid::val_decimal(my_decimal *decimal_value)
|
|||
}
|
||||
case STRING_RESULT:
|
||||
{
|
||||
String *res= str_op(&str_value);
|
||||
String *res;
|
||||
if (!(res= str_op(&str_value)))
|
||||
return NULL;
|
||||
|
||||
str2my_decimal(E_DEC_FATAL_ERROR, (char*) res->ptr(),
|
||||
res->length(), res->charset(), decimal_value);
|
||||
break;
|
||||
|
|
|
@ -2820,15 +2820,15 @@ mysql_discard_or_import_tablespace(THD *thd,
|
|||
err:
|
||||
close_thread_tables(thd);
|
||||
thd->tablespace_op=FALSE;
|
||||
|
||||
if (error == 0)
|
||||
{
|
||||
send_ok(thd);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
if (error == HA_ERR_ROW_IS_REFERENCED)
|
||||
my_error(ER_ROW_IS_REFERENCED, MYF(0));
|
||||
|
||||
table->file->print_error(error, MYF(0));
|
||||
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1020,11 +1020,19 @@ execute_var_ident: '@' ident_or_text
|
|||
/* help */
|
||||
|
||||
help:
|
||||
HELP_SYM ident_or_text
|
||||
HELP_SYM
|
||||
{
|
||||
if (Lex->sphead)
|
||||
{
|
||||
my_error(ER_SP_BADSTATEMENT, MYF(0), "HELP");
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
ident_or_text
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->sql_command= SQLCOM_HELP;
|
||||
lex->help_arg= $2.str;
|
||||
lex->help_arg= $3.str;
|
||||
};
|
||||
|
||||
/* change master */
|
||||
|
|
Loading…
Reference in a new issue