diff options
Diffstat (limited to 'server-tools/instance-manager/instance_map.cc')
-rw-r--r-- | server-tools/instance-manager/instance_map.cc | 217 |
1 files changed, 120 insertions, 97 deletions
diff --git a/server-tools/instance-manager/instance_map.cc b/server-tools/instance-manager/instance_map.cc index 204064233eb..5d492fe5c11 100644 --- a/server-tools/instance-manager/instance_map.cc +++ b/server-tools/instance-manager/instance_map.cc @@ -24,26 +24,18 @@ #include <mysql_com.h> #include "buffer.h" -#include "guardian.h" #include "instance.h" #include "log.h" -#include "manager.h" #include "mysqld_error.h" #include "mysql_manager_error.h" #include "options.h" #include "priv.h" -/* - Note: As we are going to suppost different types of connections, - we shouldn't have connection-specific functions. To avoid it we could - put such functions to the Command-derived class instead. - The command could be easily constructed for a specific connection if - we would provide a special factory for each connection. -*/ - C_MODE_START -/* Procedure needed for HASH initialization */ +/** + HASH-routines: get key of instance for storing in hash. +*/ static byte* get_instance_key(const byte* u, uint* len, my_bool __attribute__((unused)) t) @@ -53,14 +45,18 @@ static byte* get_instance_key(const byte* u, uint* len, return (byte *) instance->options.instance_name.str; } +/** + HASH-routines: cleanup handler. +*/ + static void delete_instance(void *u) { Instance *instance= (Instance *) u; delete instance; } -/* - The option handler to pass to the process_default_option_files finction. +/** + The option handler to pass to the process_default_option_files function. SYNOPSIS process_option() @@ -95,8 +91,8 @@ static int process_option(void *ctx, const char *group, const char *option) C_MODE_END -/* - Parse option string. +/** + Parse option string. SYNOPSIS parse_option() @@ -136,7 +132,7 @@ static void parse_option(const char *option_str, } -/* +/** Process one option from the configuration file. SYNOPSIS @@ -150,6 +146,10 @@ static void parse_option(const char *option_str, process_option(). The caller ensures proper locking of the instance map object. */ + /* + Process a given option and assign it to appropricate instance. This is + required for the option handler, passed to my_search_option_files(). + */ int Instance_map::process_one_option(const LEX_STRING *group, const char *option) @@ -212,92 +212,97 @@ int Instance_map::process_one_option(const LEX_STRING *group, } +/** + Instance_map constructor. +*/ + Instance_map::Instance_map() { pthread_mutex_init(&LOCK_instance_map, 0); } +/** + Initialize Instance_map internals. +*/ + bool Instance_map::init() { return hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0, get_instance_key, delete_instance, 0); } + +/** + Reset Instance_map data. +*/ + +bool Instance_map::reset() +{ + hash_free(&hash); + return init(); +} + + +/** + Instance_map destructor. +*/ + Instance_map::~Instance_map() { - pthread_mutex_lock(&LOCK_instance_map); + lock(); + + /* + NOTE: it's necessary to synchronize on each instance before removal, + because Instance-monitoring thread can be still alive an hold the mutex + (because it is detached and we have no control over it). + */ + + while (true) + { + Iterator it(this); + Instance *instance= it.next(); + + if (!instance) + break; + + instance->lock(); + instance->unlock(); + + remove_instance(instance); + } + hash_free(&hash); - pthread_mutex_unlock(&LOCK_instance_map); + unlock(); + pthread_mutex_destroy(&LOCK_instance_map); } +/** + Lock Instance_map. +*/ + void Instance_map::lock() { pthread_mutex_lock(&LOCK_instance_map); } +/** + Unlock Instance_map. +*/ + 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. - - NOTE: The operation should be invoked with the following locks acquired: - - Guardian; - - Instance_map; +/** + Check if there is an active instance or not. */ -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. - */ - hash_free(&hash); - hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0, - get_instance_key, delete_instance, 0); - - rc= load(); - /* don't init guardian if we failed to load instances */ - if (!rc) - guardian->init(); // TODO: check error status. - return rc; -} - - bool Instance_map::is_there_active_instance() { Instance *instance; @@ -305,29 +310,50 @@ bool Instance_map::is_there_active_instance() while ((instance= iterator.next())) { - if (guardian->find_instance_node(instance) != NULL || - instance->is_mysqld_running()) - { + bool active_instance_found; + + instance->lock(); + active_instance_found= instance->is_active(); + instance->unlock(); + + if (active_instance_found) return TRUE; - } } return FALSE; } +/** + Add an instance into the internal hash. + + MT-NOTE: Instance Map must be locked before calling the operation. +*/ + int Instance_map::add_instance(Instance *instance) { return my_hash_insert(&hash, (byte *) instance); } +/** + Remove instance from the internal hash. + + MT-NOTE: Instance Map must be locked before calling the operation. +*/ + int Instance_map::remove_instance(Instance *instance) { return hash_delete(&hash, (byte *) instance); } +/** + Create a new instance and register it in the internal hash. + + MT-NOTE: Instance Map must be locked before calling the operation. +*/ + int Instance_map::create_instance(const LEX_STRING *instance_name, const Named_value_arr *options) { @@ -391,12 +417,22 @@ int Instance_map::create_instance(const LEX_STRING *instance_name, } +/** + Return a pointer to the instance or NULL, if there is no such instance. + + MT-NOTE: Instance Map must be locked before calling the operation. +*/ + Instance * Instance_map::find(const LEX_STRING *name) { return (Instance *) hash_search(&hash, (byte *) name->str, name->length); } +/** + Init instances command line arguments after all options have been loaded. +*/ + bool Instance_map::complete_initialization() { bool mysqld_found; @@ -454,7 +490,10 @@ bool Instance_map::complete_initialization() } -/* load options from config files and create appropriate instance structures */ +/** + Load options from config files and create appropriate instance + structures. +*/ int Instance_map::load() { @@ -504,8 +543,9 @@ int Instance_map::load() } -/*--- Implementaton of the Instance map iterator class ---*/ - +/************************************************************************* + {{{ Instance_map::Iterator implementation. +*************************************************************************/ void Instance_map::Iterator::go_to_first() { @@ -521,29 +561,12 @@ Instance *Instance_map::Iterator::next() return NULL; } - -const char *Instance_map::get_instance_state_name(Instance *instance) -{ - LIST *instance_node; - - if (!instance->is_configured()) - return "misconfigured"; - - if ((instance_node= guardian->find_instance_node(instance)) != NULL) - { - /* The instance is managed by Guardian: we can report precise state. */ - - return Guardian::get_instance_state_name( - guardian->get_instance_state(instance_node)); - } - - /* The instance is not managed by Guardian: we can report status only. */ - - return instance->is_mysqld_running() ? "online" : "offline"; -} +/************************************************************************* + }}} +*************************************************************************/ -/* +/** Create a new configuration section for mysqld-instance in the config file. SYNOPSIS |