mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
Merge mysql.com:/home/cps/mysql/devel/im/5.0-im-fix-race
into mysql.com:/home/cps/mysql/trees/5.1/5.1-virgin-no-debug mysql-test/r/subselect.result: Auto merged sql/sql_select.cc: Auto merged
This commit is contained in:
commit
1b6e7fdf55
6 changed files with 93 additions and 39 deletions
|
@ -256,7 +256,6 @@ int Guardian_thread::init()
|
|||
Instance *instance;
|
||||
Instance_map::Iterator iterator(instance_map);
|
||||
|
||||
instance_map->lock();
|
||||
/* clear the list of guarded instances */
|
||||
free_root(&alloc, MYF(0));
|
||||
init_alloc_root(&alloc, MEM_ROOT_BLOCK_SIZE, 0);
|
||||
|
@ -272,7 +271,6 @@ int Guardian_thread::init()
|
|||
}
|
||||
}
|
||||
|
||||
instance_map->unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,19 +80,44 @@ static void delete_instance(void *u)
|
|||
static int process_option(void *ctx, const char *group, const char *option)
|
||||
{
|
||||
Instance_map *map= NULL;
|
||||
|
||||
map = (Instance_map*) ctx;
|
||||
return map->process_one_option(group, option);
|
||||
}
|
||||
|
||||
C_MODE_END
|
||||
|
||||
|
||||
/*
|
||||
Process one option from the configuration file.
|
||||
|
||||
SYNOPSIS
|
||||
Instance_map::process_one_option()
|
||||
group group name
|
||||
option option string (e.g. "--name=value")
|
||||
|
||||
DESCRIPTION
|
||||
This is an auxiliary function and should not be used externally.
|
||||
It is used only by flush_instances(), which pass it to
|
||||
process_option(). The caller ensures proper locking
|
||||
of the instance map object.
|
||||
*/
|
||||
|
||||
int Instance_map::process_one_option(const char *group, const char *option)
|
||||
{
|
||||
Instance *instance= NULL;
|
||||
static const char prefix[]= { 'm', 'y', 's', 'q', 'l', 'd' };
|
||||
|
||||
map = (Instance_map*) ctx;
|
||||
if (strncmp(group, prefix, sizeof prefix) == 0 &&
|
||||
((my_isdigit(default_charset_info, group[sizeof prefix]))
|
||||
|| group[sizeof(prefix)] == '\0'))
|
||||
{
|
||||
if ((instance= map->find(group, strlen(group))) == NULL)
|
||||
if (!(instance= (Instance *) hash_search(&hash, (byte *) group,
|
||||
strlen(group))))
|
||||
{
|
||||
if ((instance= new Instance) == 0)
|
||||
if (!(instance= new Instance))
|
||||
goto err;
|
||||
if (instance->init(group) || map->add_instance(instance))
|
||||
if (instance->init(group) || my_hash_insert(&hash, (byte *) instance))
|
||||
goto err_instance;
|
||||
}
|
||||
|
||||
|
@ -108,8 +133,6 @@ err:
|
|||
return 1;
|
||||
}
|
||||
|
||||
C_MODE_END
|
||||
|
||||
|
||||
Instance_map::Instance_map(const char *default_mysqld_path_arg):
|
||||
mysqld_path(default_mysqld_path_arg)
|
||||
|
@ -144,30 +167,61 @@ void Instance_map::unlock()
|
|||
pthread_mutex_unlock(&LOCK_instance_map);
|
||||
}
|
||||
|
||||
/*
|
||||
Re-read instance configuration file.
|
||||
|
||||
SYNOPSIS
|
||||
Instance_map::flush_instances()
|
||||
|
||||
DESCRIPTION
|
||||
This function will:
|
||||
- clear the current list of instances. This removes both
|
||||
running and stopped instances.
|
||||
- load a new instance configuration from the file.
|
||||
- pass on the new map to the guardian thread: it will start
|
||||
all instances that are marked `guarded' and not yet started.
|
||||
Note, as the check whether an instance is started is currently
|
||||
very simple (returns true if there is a MySQL server running
|
||||
at the given port), this function has some peculiar
|
||||
side-effects:
|
||||
* if the port number of a running instance was changed, the
|
||||
old instance is forgotten, even if it was running. The new
|
||||
instance will be started at the new port.
|
||||
* if the configuration was changed in a way that two
|
||||
instances swapped their port numbers, the guardian thread
|
||||
will not notice that and simply report that both instances
|
||||
are configured successfully and running.
|
||||
In order to avoid such side effects one should never call
|
||||
FLUSH INSTANCES without prior stop of all running instances.
|
||||
|
||||
TODO
|
||||
FLUSH INSTANCES should return an error if it's called
|
||||
while there is a running instance.
|
||||
*/
|
||||
|
||||
int Instance_map::flush_instances()
|
||||
{
|
||||
int rc;
|
||||
|
||||
/*
|
||||
Guardian thread relies on the instance map repository for guarding
|
||||
instances. This is why refreshing instance map, we need (1) to stop
|
||||
guardian (2) reload the instance map (3) reinitialize the guardian
|
||||
with new instances.
|
||||
*/
|
||||
guardian->lock();
|
||||
pthread_mutex_lock(&LOCK_instance_map);
|
||||
hash_free(&hash);
|
||||
hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
|
||||
get_instance_key, delete_instance, 0);
|
||||
pthread_mutex_unlock(&LOCK_instance_map);
|
||||
rc= load();
|
||||
guardian->init();
|
||||
pthread_mutex_unlock(&LOCK_instance_map);
|
||||
guardian->unlock();
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int Instance_map::add_instance(Instance *instance)
|
||||
{
|
||||
return my_hash_insert(&hash, (byte *) instance);
|
||||
}
|
||||
|
||||
|
||||
Instance *
|
||||
Instance_map::find(const char *name, uint name_len)
|
||||
{
|
||||
|
@ -190,10 +244,9 @@ int Instance_map::complete_initialization()
|
|||
if ((instance= new Instance) == 0)
|
||||
goto err;
|
||||
|
||||
if (instance->init("mysqld") || add_instance(instance))
|
||||
if (instance->init("mysqld") || my_hash_insert(&hash, (byte *) instance))
|
||||
goto err_instance;
|
||||
|
||||
|
||||
/*
|
||||
After an instance have been added to the instance_map,
|
||||
hash_free should handle it's deletion => goto err, not
|
||||
|
|
|
@ -63,21 +63,24 @@ public:
|
|||
void lock();
|
||||
void unlock();
|
||||
int init();
|
||||
/*
|
||||
Process a given option and assign it to appropricate instance. This is
|
||||
required for the option handler, passed to my_search_option_files().
|
||||
*/
|
||||
int process_one_option(const char *group, const char *option);
|
||||
|
||||
Instance_map(const char *default_mysqld_path_arg);
|
||||
~Instance_map();
|
||||
|
||||
/* loads options from config files */
|
||||
int load();
|
||||
/* adds instance to internal hash */
|
||||
int add_instance(Instance *instance);
|
||||
/* inits instances argv's after all options have been loaded */
|
||||
int complete_initialization();
|
||||
|
||||
public:
|
||||
const char *mysqld_path;
|
||||
Guardian_thread *guardian;
|
||||
|
||||
private:
|
||||
/* loads options from config files */
|
||||
int load();
|
||||
/* inits instances argv's after all options have been loaded */
|
||||
int complete_initialization();
|
||||
private:
|
||||
enum { START_HASH_SIZE = 16 };
|
||||
pthread_mutex_t LOCK_instance_map;
|
||||
|
|
|
@ -135,15 +135,6 @@ void manager(const Options &options)
|
|||
if (instance_map.init() || user_map.init())
|
||||
return;
|
||||
|
||||
|
||||
if (instance_map.load())
|
||||
{
|
||||
log_error("Cannot init instances repository. This might be caused by "
|
||||
"the wrong config file options. For instance, missing mysqld "
|
||||
"binary. Aborting.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (user_map.load(options.password_file_name))
|
||||
return;
|
||||
|
||||
|
@ -207,12 +198,13 @@ void manager(const Options &options)
|
|||
|
||||
shutdown_complete= FALSE;
|
||||
|
||||
/* init list of guarded instances */
|
||||
guardian_thread.lock();
|
||||
|
||||
guardian_thread.init();
|
||||
|
||||
guardian_thread.unlock();
|
||||
if (instance_map.flush_instances())
|
||||
{
|
||||
log_error("Cannot init instances repository. This might be caused by "
|
||||
"the wrong config file options. For instance, missing mysqld "
|
||||
"binary. Aborting.");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
After the list of guarded instances have been initialized,
|
||||
|
|
|
@ -79,6 +79,7 @@ enum options {
|
|||
#endif
|
||||
OPT_MONITORING_INTERVAL,
|
||||
OPT_PORT,
|
||||
OPT_WAIT_TIMEOUT,
|
||||
OPT_BIND_ADDRESS
|
||||
};
|
||||
|
||||
|
@ -151,6 +152,11 @@ static struct my_option my_long_options[] =
|
|||
{ "version", 'V', "Output version information and exit.", 0, 0, 0,
|
||||
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
|
||||
{ "wait-timeout", OPT_WAIT_TIMEOUT, "The number of seconds IM waits "
|
||||
"for activity on a connection before closing it.",
|
||||
(gptr *) &net_read_timeout, (gptr *) &net_read_timeout, 0, GET_ULONG,
|
||||
REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0 },
|
||||
|
||||
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#define SERVER_DEFAULT_PORT 3306
|
||||
#define DEFAULT_MONITORING_INTERVAL 20
|
||||
#define DEFAULT_PORT 2273
|
||||
/* three-week timeout should be enough */
|
||||
#define LONG_TIMEOUT ((ulong) 3600L*24L*21L)
|
||||
|
||||
/* the pid of the manager process (of the signal thread on the LinuxThreads) */
|
||||
extern pid_t manager_pid;
|
||||
|
|
Loading…
Reference in a new issue