def _do_block_write_master(group_id, master_uuid, update_only=False): """Block and disable write access to the current master. Note that connections are not killed and blocking the master may take some time. """ master = _server.MySQLServer.fetch(_uuid.UUID(master_uuid)) assert (master.status == _server.MySQLServer.PRIMARY) master.mode = _server.MySQLServer.READ_ONLY master.status = _server.MySQLServer.SECONDARY if not update_only: master.connect() _utils.set_read_only(master, True) # Temporarily unset the master in this group. group = _server.Group.fetch(group_id) _set_group_master_replication(group, None) # At the end, we notify that a server was demoted. # Any function that implements this event should not # run any action that updates Fabric. The event was # designed to trigger external actions such as: # # . Updating an external entity. # # . Fencing off a server. _events.trigger("SERVER_DEMOTED", set([group_id]), group_id, str(master.uuid))
def _do_block_write_master(group_id, master_uuid, update_only=False): """Block and disable write access to the current master. Note that connections are not killed and blocking the master may take some time. """ master = _server.MySQLServer.fetch(_uuid.UUID(master_uuid)) assert(master.status == _server.MySQLServer.PRIMARY) master.mode = _server.MySQLServer.READ_ONLY master.status = _server.MySQLServer.SECONDARY if not update_only: master.connect() _utils.set_read_only(master, True) _utils.set_offline_mode(master, True) # Temporarily unset the master in this group. group = _server.Group.fetch(group_id) _set_group_master_replication(group, None) # At the end, we notify that a server was demoted. # Any function that implements this event should not # run any action that updates Fabric. The event was # designed to trigger external actions such as: # # . Updating an external entity. # # . Fencing off a server. _events.trigger("SERVER_DEMOTED", set([group_id]), group_id, str(master.uuid) )
def _change_to_candidate(group_id, master_uuid, update_only=False): """Switch to candidate slave. """ forbidden_status = (_server.MySQLServer.FAULTY, ) master = _server.MySQLServer.fetch(_uuid.UUID(master_uuid)) master.mode = _server.MySQLServer.READ_WRITE master.status = _server.MySQLServer.PRIMARY if not update_only: # Prepare the server to be the master master.connect() _utils.reset_slave(master) _utils.set_read_only(master, False) group = _server.Group.fetch(group_id) _set_group_master_replication(group, master.uuid, update_only) if not update_only: # Make slaves point to the master. for server in group.servers(): if server.uuid != _uuid.UUID(master_uuid) and \ server.status not in forbidden_status: try: server.connect() _utils.switch_master(server, master) except _errors.DatabaseError as error: _LOGGER.debug( "Error configuring slave (%s).", server.uuid, exc_info=error ) # At the end, we notify that a server was promoted. _events.trigger("SERVER_PROMOTED", set([group_id]), group_id, master_uuid )
def _change_to_candidate(group_id, master_uuid, update_only=False): """Switch to candidate slave. """ forbidden_status = (_server.MySQLServer.FAULTY, ) master = _server.MySQLServer.fetch(_uuid.UUID(master_uuid)) master.mode = _server.MySQLServer.READ_WRITE master.status = _server.MySQLServer.PRIMARY if not update_only: # Prepare the server to be the master master.connect() _utils.reset_slave(master) _utils.set_read_only(master, False) group = _server.Group.fetch(group_id) _set_group_master_replication(group, master.uuid, update_only) if not update_only: # Make slaves point to the master. for server in group.servers(): if server.uuid != _uuid.UUID(master_uuid) and \ server.status not in forbidden_status: try: server.connect() _utils.switch_master(server, master) except _errors.DatabaseError as error: _LOGGER.debug("Error configuring slave (%s): %s.", server.uuid, error) # At the end, we notify that a server was promoted. _events.trigger("SERVER_PROMOTED", set([group_id]), group_id, master_uuid)
def check_properties_5(param_01, param_02): """Check properties 5. """ _events.trigger( EVENT_CHECK_PROPERTIES_2, set(["lock"]), "NEW 01", "NEW 02" ) job = _executor.ExecutorThread.executor_object().current_job checkpoint = _checkpoint.Checkpoint.fetch(job.procedure.uuid) return checkpoint
def execute(self, event, locks, *args, **kwargs): """Trigger the execution of an event. :param event: Event's identification. :type event: String :param args: Event's non-keyworded arguments. :param kwargs: Event's keyworded arguments. :return: :class:`CommandResult` instance with UUID of the procedures that were triggered. """ lockable_objects = set() for lock in locks.split(","): lockable_objects.add(lock.strip()) rset = ResultSet(names=['uuid'], types=[str]) # Trigger the event and add the UUID of all procedures queued # to the result. for proc in _events.trigger(event, lockable_objects, *args, **kwargs): rset.append_row([str(proc.uuid)]) return CommandResult(None, results=rset)
def execute(self, param, synchronous=True): """Method that is remotely executed. """ procedures = _events.trigger( NEW_PROCEDURE_GROUP_1, self.get_lockable_objects(), param ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, provider_id, username, password, url, tenant=None, provider_type="OPENSTACK", default_image=None, default_flavor=None, extra=None, synchronous=True): """Register a provider. :param provider_id: Provider's Id. :param username: User name to use during authentication. :param password: Password to use during authentication. :param url: URL that is used as an access point. :param tenant: Tenant's name, i.e. who will access resources in the cloud. :param provider_type: Provider type. :param image: Default image's name that will be used upon creating a machine if one is not provided. :param image: Default flavor's name that will be used upon creating a machine if one is not provided. :param extra: Define parameters that are specific to a provider. :param synchronous: Whether one should wait until the execution finishes or not. :return: Tuple with job's uuid and status. """ procedures = _events.trigger( REGISTER_PROVIDER, self.get_lockable_objects(), provider_id, provider_type, username, password, url, tenant, default_image, default_flavor, extra ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, shard_id, group_id, split_value=None, update_only=False, synchronous=True): """Split the shard represented by the shard_id into the destination group. :param shard_id: The shard_id of the shard that needs to be split. :param group_id: The ID of the group into which the split data needs to be moved. :param split_value: The value at which the range needs to be split. :update_only: Only update the state store and skip provisioning. :param synchronous: Whether one should wait until the execution finishes """ mysqldump_binary = _services_utils.read_config_value( self.config, 'sharding', 'mysqldump_program') mysqlclient_binary = _services_utils.read_config_value( self.config, 'sharding', 'mysqlclient_program') prune_limit = _services_utils.read_config_value( self.config, 'sharding', 'prune_limit') config_file = self.config.config_file if self.config.config_file else "" procedures = _events.trigger(CHECK_SHARD_INFORMATION, self.get_lockable_objects(), shard_id, group_id, mysqldump_binary, mysqlclient_binary, split_value, config_file, prune_limit, "SPLIT", update_only) return self.wait_for_procedures(procedures, synchronous)
def _report_failure(self, server): """Mark the server as faulty and report a failure. The thread is created to allow the built-in failure detector to continue monitoring the servers so that if the report failure hangs, it will kill all connections to faulty servers thus eventually freeing the thread. Not though that the report failure is not crash-safe so it might fail without promoting a new server to master. In the future, we will circumvent this limitation. """ try: _persistence.init_thread() server.status = MySQLServer.FAULTY self.__connection_manager.purge_connections(server) procedures = trigger( "REPORT_FAILURE", None, str(server.uuid), threading.current_thread().name, MySQLServer.FAULTY, False ) executor = _executor.Executor() for procedure in procedures: executor.wait_for_procedure(procedure) _persistence.deinit_thread() finally: self.__thread_report_failure = False
def test_properties_5(self): """5 - Within a job, triggering a set of independent jobs. """ procedures = _events.trigger( EVENT_CHECK_PROPERTIES_5, set(["lock"]), "PARAM 01", "PARAM 02" ) # Get the result (Checkpoint object) from the procedure. self.assertEqual(len(procedures), 1) result = None procedure = None for procedure in procedures: procedure.wait() result = procedure.result # Fetch and check all the properties. self.assertEqual(len(result), 1) for checkpoint in result: self.assertEqual(checkpoint.param_args, ("PARAM 01", "PARAM 02") ) self.assertEqual(checkpoint.param_kwargs, {}) self.assertNotEqual(checkpoint.started, None) self.assertEqual(checkpoint.finished, None) self.assertEqual(checkpoint.do_action, check_properties_5) # There should not be any entry for this procedure. self.assertEqual(len(_checkpoint.Checkpoint.fetch(procedure.uuid)), 0)
def execute(self, shard_id, group_id, split_value=None, update_only=False, synchronous=True): """Split the shard represented by the shard_id into the destination group. :param shard_id: The shard_id of the shard that needs to be split. :param group_id: The ID of the group into which the split data needs to be moved. :param split_value: The value at which the range needs to be split. :update_only: Only update the state store and skip provisioning. :param synchronous: Whether one should wait until the execution finishes """ mysqldump_binary = _services_utils.read_config_value( self.config, 'sharding', 'mysqldump_program' ) mysqlclient_binary = _services_utils.read_config_value( self.config, 'sharding', 'mysqlclient_program' ) prune_limit = _services_utils.read_config_value( self.config, 'sharding', 'prune_limit' ) config_file = self.config.config_file if self.config.config_file else "" procedures = _events.trigger( CHECK_SHARD_INFORMATION, self.get_lockable_objects(), shard_id, group_id, mysqldump_binary, mysqlclient_binary, split_value, config_file, prune_limit, "SPLIT", update_only) return self.wait_for_procedures(procedures, synchronous)
def execute(self, shard_id, group_id, update_only=False, synchronous=True): """Move the shard represented by the shard_id to the destination group. :param shard_id: The ID of the shard that needs to be moved. :param group_id: The ID of the group to which the shard needs to be moved. :update_only: Only update the state store and skip provisioning. :param synchronous: Whether one should wait until the execution finishes or not. """ mysqldump_binary = _services_utils.read_config_value( self.config, 'sharding', 'mysqldump_program' ) mysqlclient_binary = _services_utils.read_config_value( self.config, 'sharding', 'mysqlclient_program' ) config_file = self.config.config_file if self.config.config_file else "" procedures = _events.trigger( CHECK_SHARD_INFORMATION, self.get_lockable_objects(), shard_id, group_id, mysqldump_binary, mysqlclient_binary, None, config_file, "", "MOVE", update_only ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, provider_id, username, password, url, tenant, provider_type="OPENSTACK", default_image=None, default_flavor=None, synchronous=True): """Register a provider. :param provider_id: Provider's Id. :param username: User name to use during authentication. :param password: Password to use during authentication. :param url: URL that is used as an access point. :param tenant: Tenant's name, i.e. who will access resources in the cloud. :param provider_type: Provider type. :param image: Default image's name that will be used upon creating a machine if one is not provided. :param image: Default flavor's name that will be used upon creating a machine if one is not provided. :param synchronous: Whether one should wait until the execution finishes or not. :return: Tuple with job's uuid and status. """ procedures = _events.trigger(REGISTER_PROVIDER, self.get_lockable_objects(), provider_id, provider_type, username, password, url, tenant, default_image, default_flavor) return self.wait_for_procedures(procedures, synchronous)
def execute(self, group_id, update_only=False, synchronous=True): """Demote the current master if there is one. :param uuid: Group's id. :param update_only: Only update the state store and skip provisioning. :param synchronous: Whether one should wait until the execution finishes or not. In what follows, one will find a figure that depicts the sequence of event that happen during the demote operation. To ease the presentation some names are abbreivated: .. seqdiag:: diagram { activation = none; === Schedule "block_write" === demote --> executor [ label = "schedule(block_write)" ]; demote <-- executor; === Execute "block_write" and schedule "wait_slaves" === executor -> block_write [ label = "execute(block_write)" ]; block_write --> executor [ label = "schedule(wait_slaves)" ]; block_write <-- executor; executor <- block_write; === Execute "wait_slaves" === executor -> wait_slaves [ label = "execute(wait_slaves)" ]; wait_slaves --> executor; wait_slaves <-- executor; executor <- wait_slaves; } """ procedures = _events.trigger(BLOCK_WRITE_DEMOTE, self.get_lockable_objects(), group_id, update_only) return self.wait_for_procedures(procedures, synchronous)
def execute(self, shard_mapping_id, table_name, column_name, range_check=False, update_only=False, synchronous=True): """Add a table to a shard mapping. :param shard_mapping_id: The shard mapping id to which the input table is attached. :param table_name: The table being sharded. :param column_name: The column whose value is used in the sharding scheme being applied :param range_check: Indicates if range check should be turned on for this table. :param update_only: Only update the state store and skip adding range checks. :param synchronous: Whether one should wait until the execution finishes or not. """ procedures = _events.trigger(ADD_SHARD_MAPPING, self.get_lockable_objects(), shard_mapping_id, table_name, column_name, range_check, update_only) return self.wait_for_procedures(procedures, synchronous)
def execute(self, synchronous=True): """Method that is remotely executed. """ procedures = _events.trigger( NEW_EXECUTION_EVENT_1, self.get_lockable_objects() ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, group_id, synchronous=True): """Method that is remotely executed. """ procedures = _events.trigger( NEW_PROCEDURE_SHARD_0, self.get_lockable_objects(), group_id ) return self.wait_for_procedures(procedures, synchronous)
def _change_to_candidate(group_id, master_uuid, update_only=False): """Switch to candidate slave. """ forbidden_status = (_server.MySQLServer.FAULTY, ) master = _server.MySQLServer.fetch(_uuid.UUID(master_uuid)) master.mode = _server.MySQLServer.READ_WRITE master.status = _server.MySQLServer.PRIMARY if not update_only: # Prepare the server to be the master master.connect() _utils.reset_slave(master) _utils.set_read_only(master, False) _utils.set_offline_mode(master, False) group = _server.Group.fetch(group_id) _set_group_master_replication(group, master.uuid, update_only) if not update_only: # Make slaves point to the master. for server in group.servers(): if server.uuid != _uuid.UUID(master_uuid) and \ server.status not in forbidden_status: try: server.connect() _utils.switch_master(server, master) except _errors.DatabaseError as error: _LOGGER.debug( "Error configuring slave (%s): %s.", server.uuid, error ) ### Restore FailureDetector's status before starting failover/switchover if _detector.FailureDetector.was_active: _detector.FailureDetector.was_active = None group.status = _server.Group.ACTIVE _detector.FailureDetector.register_group(group_id) # At the end, we notify that a server was promoted. # Any function that implements this event should not # run any action that updates Fabric. The event was # designed to trigger external actions such as: # # . Updating an external entity. _events.trigger("SERVER_PROMOTED", set([group_id]), group_id, master_uuid )
def execute(self, group_id, destn_address, server_id=None, timeout=None, synchronous=True): """Clone the objects of a given server into a destination server. :param group_id: The ID of the source group. :param destn_address: The address of the destination MySQL Server. :param source_id: The address or UUID of the source MySQL Server. :param timeout: Time in seconds after which an error is reported if the destination server is unreachable. :param synchronous: Whether one should wait until the execution finishes or not. """ # If the destination server is already part of a Fabric Group, raise # an error destn_server_uuid = _lookup_uuid(destn_address, timeout) _check_server_not_in_any_group(destn_server_uuid) host, port = split_host_port( destn_address, _backup.MySQLDump.MYSQL_DEFAULT_PORT ) # Fetch information on backup and restore programs. config_file = self.config.config_file if self.config.config_file else "" mysqldump_binary = _utils.read_config_value( self.config, 'sharding', 'mysqldump_program' ) mysqlclient_binary = _utils.read_config_value( self.config, 'sharding', 'mysqlclient_program' ) if not _utils.is_valid_binary(mysqldump_binary): raise _errors.ServerError(MYSQLDUMP_NOT_FOUND % mysqldump_binary) if not _utils.is_valid_binary(mysqlclient_binary): raise _errors.ServerError(MYSQLCLIENT_NOT_FOUND % mysqlclient_binary) # Fetch a reference to source server. if server_id: server = _retrieve_server(server_id, group_id) else: group = _retrieve_group(group_id) server = _utils.fetch_backup_server(group) # Schedule the clone operation through the executor. procedures = _events.trigger( BACKUP_SERVER, self.get_lockable_objects(), str(server.uuid), host, port, mysqldump_binary, mysqlclient_binary, config_file ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, shard_id, synchronous=True): """Enable the Shard represented by the shard_id. :param shard_id: The shard ID of the shard that needs to be removed. :param synchronous: Whether one should wait until the execution finishes or not. """ procedures = _events.trigger(SHARD_ENABLE, self.get_lockable_objects(), shard_id) return self.wait_for_procedures(procedures, synchronous)
def execute(self, provider_id, synchronous=True): """Unregister a provider. :param provider_id: Provider's Id. :param synchronous: Whether one should wait until the execution finishes or not. :return: Tuple with job's uuid and status. """ procedures = _events.trigger(UNREGISTER_PROVIDER, self.get_lockable_objects(), provider_id) return self.wait_for_procedures(procedures, synchronous)
def execute(self, table_name, shard_mapping_id, shard_id, synchronous=True): """Method that is remotely executed. """ procedures = _events.trigger(NEW_PROCEDURE_SHARD_1, self.get_lockable_objects(), table_name, shard_mapping_id, shard_id) return self.wait_for_procedures(procedures, synchronous)
def execute(self, shard_id, synchronous=True): """Enable the Shard represented by the shard_id. :param shard_id: The shard ID of the shard that needs to be removed. :param synchronous: Whether one should wait until the execution finishes or not. """ procedures = _events.trigger( SHARD_ENABLE, self.get_lockable_objects(), shard_id ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, synchronous=True): """Deactivate all groups. :param synchronous: Whether one should wait until the execution finishes or not. :return: Tuple with job's uuid and status. """ procedures = _events.trigger( DEACTIVATE_ALL, self.get_lockable_objects() ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, group_id, synchronous=True): """Activate a group. :param group_id: Group's id. :param synchronous: Whether one should wait until the execution finishes or not. :return: Tuple with job's uuid and status. """ procedures = _events.trigger(ACTIVATE_GROUP, self.get_lockable_objects(), group_id) return self.wait_for_procedures(procedures, synchronous)
def execute(self, provider_id, synchronous=True): """Unregister a provider. :param provider_id: Provider's Id. :param synchronous: Whether one should wait until the execution finishes or not. :return: Tuple with job's uuid and status. """ procedures = _events.trigger( UNREGISTER_PROVIDER, self.get_lockable_objects(), provider_id ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, group_id, synchronous=True): """Activate a group. :param group_id: Group's id. :param synchronous: Whether one should wait until the execution finishes or not. :return: Tuple with job's uuid and status. """ procedures = _events.trigger( ACTIVATE_GROUP, self.get_lockable_objects(), group_id ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, shard_id, synchronous=True): """Remove the RANGE specification mapping represented by the current RANGE shard specification object. :param shard_id: The shard ID of the shard that needs to be removed. :param synchronous: Whether one should wait until the execution finishes or not. """ procedures = _events.trigger(REMOVE_SHARD, self.get_lockable_objects(), shard_id) return self.wait_for_procedures(procedures, synchronous)
def execute(self, server_id, mode, synchronous=True): """Set a server's mode. :param server_id: Servers's UUID or HOST:PORT. :param weight: Server's weight. :param synchronous: Whether one should wait until the execution finishes or not. """ procedures = _events.trigger( SET_SERVER_MODE, self.get_lockable_objects(), server_id, mode ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, group_id, description=None, synchronous=True): """Update group's description. :param group_id: Group's id. :param description: Group's description. :param synchronous: Whether one should wait until the execution finishes or not. :return: Tuple with job's uuid and status. """ procedures = _events.trigger(UPDATE_GROUP, self.get_lockable_objects(), group_id, description) return self.wait_for_procedures(procedures, synchronous)
def execute(self, group_id, destn_address, server_id=None, timeout=None, synchronous=True): """Clone the objects of a given server into a destination server. :param group_id: The ID of the source group. :param destn_address: The address of the destination MySQL Server. :param source_id: The address or UUID of the source MySQL Server. :param timeout: Time in seconds after which an error is reported if the destination server is unreachable. :param synchronous: Whether one should wait until the execution finishes or not. """ # If the destination server is already part of a Fabric Group, raise # an error destn_server_uuid = _lookup_uuid(destn_address, timeout) _check_server_not_in_any_group(destn_server_uuid) host, port = split_host_port(destn_address, _backup.MySQLDump.MYSQL_DEFAULT_PORT) # Fetch information on backup and restore programs. config_file = self.config.config_file if self.config.config_file else "" mysqldump_binary = _utils.read_config_value(self.config, 'sharding', 'mysqldump_program') mysqlclient_binary = _utils.read_config_value(self.config, 'sharding', 'mysqlclient_program') if not _utils.is_valid_binary(mysqldump_binary): raise _errors.ServerError(MYSQLDUMP_NOT_FOUND % mysqldump_binary) if not _utils.is_valid_binary(mysqlclient_binary): raise _errors.ServerError(MYSQLCLIENT_NOT_FOUND % mysqlclient_binary) # Fetch a reference to source server. if server_id: server = _retrieve_server(server_id, group_id) else: group = _retrieve_group(group_id) server = _utils.fetch_backup_server(group) # Schedule the clone operation through the executor. procedures = _events.trigger(BACKUP_SERVER, self.get_lockable_objects(), str(server.uuid), host, port, mysqldump_binary, mysqlclient_binary, config_file) return self.wait_for_procedures(procedures, synchronous)
def execute(self, group_id, description=None, synchronous=True): """Update group's description. :param group_id: Group's id. :param description: Group's description. :param synchronous: Whether one should wait until the execution finishes or not. :return: Tuple with job's uuid and status. """ procedures = _events.trigger( UPDATE_GROUP, self.get_lockable_objects(), group_id, description ) return self.wait_for_procedures(procedures, synchronous)
def _do_block_write_master(group_id, master_uuid, update_only=False): """Block and disable write access to the current master. Note that connections are not killed and blocking the master may take some time. """ master = _server.MySQLServer.fetch(_uuid.UUID(master_uuid)) assert (master.status == _server.MySQLServer.PRIMARY) master.mode = _server.MySQLServer.READ_ONLY master.status = _server.MySQLServer.SECONDARY if not update_only: master.connect() _utils.set_read_only(master, True) # Temporarily unset the master in this group. group = _server.Group.fetch(group_id) _set_group_master_replication(group, None) # At the end, we notify that a server was demoted. _events.trigger("SERVER_DEMOTED", set([group_id]), group_id, str(master.uuid))
def execute(self, group_id, force=False, synchronous=True): """Remove a group. :param group_id: Group's id. :param force: If the group is not empty, remove it serves. :param synchronous: Whether one should wait until the execution finishes or not. :return: Tuple with job's uuid and status. """ procedures = _events.trigger( DESTROY_GROUP, self.get_lockable_objects(), group_id, force ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, shard_id, synchronous=True): """Remove the RANGE specification mapping represented by the current RANGE shard specification object. :param shard_id: The shard ID of the shard that needs to be removed. :param synchronous: Whether one should wait until the execution finishes or not. """ procedures = _events.trigger( REMOVE_SHARD, self.get_lockable_objects(), shard_id ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, server_id, status, update_only=False, synchronous=True): """Set a server's status. :param server_id: Servers's UUID or HOST:PORT. :param status: Server's status. :update_only: Only update the state store and skip provisioning. :param synchronous: Whether one should wait until the execution finishes or not. """ procedures = _events.trigger(SET_SERVER_STATUS, self.get_lockable_objects(), server_id, status, update_only) return self.wait_for_procedures(procedures, synchronous)
def execute(self, group_id, server_id, synchronous=True): """Remove a server from a group. :param group_id: Group's id. :param server_id: Servers's UUID or HOST:PORT. :param synchronous: Whether one should wait until the execution finishes or not. :return: Tuple with job's uuid and status. """ procedures = _events.trigger(REMOVE_SERVER, self.get_lockable_objects(), group_id, server_id ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, type_name, group_id, synchronous=True): """Define a shard mapping. :param type_name: The type of sharding scheme - RANGE, HASH, LIST etc :param group_id: Every shard mapping is associated with a global group that stores the global updates and the schema changes for this shard mapping and dissipates these to the shards. """ procedures = _events.trigger(DEFINE_SHARD_MAPPING, self.get_lockable_objects(), type_name, group_id) return self.wait_for_procedures(procedures, synchronous)
def execute(self, table_name, synchronous=True): """Remove the shard mapping corresponding to the table passed as input. This method is exposed through the XML-RPC framework and creates a job and enqueues it in the executor. :param table_name: The name of the table whose sharding specification is being removed. :param synchronous: Whether one should wait until the execution finishes or not. """ procedures = _events.trigger(REMOVE_SHARD_MAPPING, self.get_lockable_objects(), table_name) return self.wait_for_procedures(procedures, synchronous)
def execute(self, table_name, synchronous=True): """Remove the shard mapping corresponding to the table passed as input. This method is exposed through the XML-RPC framework and creates a job and enqueues it in the executor. :param table_name: The name of the table whose sharding specification is being removed. :param synchronous: Whether one should wait until the execution finishes or not. """ procedures = _events.trigger( REMOVE_SHARD_MAPPING, self.get_lockable_objects(), table_name ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, server_id, status, update_only=False, synchronous=True): """Set a server's status. :param server_id: Servers's UUID or HOST:PORT. :param status: Server's status. :update_only: Only update the state store and skip provisioning. :param synchronous: Whether one should wait until the execution finishes or not. """ procedures = _events.trigger( SET_SERVER_STATUS, self.get_lockable_objects(), server_id, status, update_only ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, shard_mapping_id, synchronous=True): """Remove the shard mapping definition represented by the Shard Mapping ID. This method is exposed through the XML-RPC framework and creates a job and enqueues it in the executor. :param shard_mapping_id: The shard mapping ID of the shard mapping definition that needs to be removed. :param synchronous: Whether one should wait until the execution finishes or not. """ procedures = _events.trigger(REMOVE_SHARD_MAPPING_DEFN, self.get_lockable_objects(), shard_mapping_id) return self.wait_for_procedures(procedures, synchronous)
def execute(self, shard_mapping_id, synchronous=True): """Remove the shard mapping definition represented by the Shard Mapping ID. This method is exposed through the XML-RPC framework and creates a job and enqueues it in the executor. :param shard_mapping_id: The shard mapping ID of the shard mapping definition that needs to be removed. :param synchronous: Whether one should wait until the execution finishes or not. """ procedures = _events.trigger( REMOVE_SHARD_MAPPING_DEFN, self.get_lockable_objects(), shard_mapping_id ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, type_name, group_id, synchronous=True): """Define a shard mapping. :param type_name: The type of sharding scheme - RANGE, HASH, LIST etc :param group_id: Every shard mapping is associated with a global group that stores the global updates and the schema changes for this shard mapping and dissipates these to the shards. """ procedures = _events.trigger( DEFINE_SHARD_MAPPING, self.get_lockable_objects(), type_name, group_id ) return self.wait_for_procedures(procedures, synchronous)
def _do_block_write_master(group_id, master_uuid, update_only=False): """Block and disable write access to the current master. Note that connections are not killed and blocking the master may take some time. """ master = _server.MySQLServer.fetch(_uuid.UUID(master_uuid)) assert(master.status == _server.MySQLServer.PRIMARY) master.mode = _server.MySQLServer.READ_ONLY master.status = _server.MySQLServer.SECONDARY if not update_only: master.connect() _utils.set_read_only(master, True) # Temporarily unset the master in this group. group = _server.Group.fetch(group_id) _set_group_master_replication(group, None) # At the end, we notify that a server was demoted. _events.trigger("SERVER_DEMOTED", set([group_id]), group_id, str(master.uuid) )
def execute(self, table_name, synchronous=True): """Given the table name prune the tables according to the defined sharding specification for the table. The command prunes all the tables that are part of this shard. There might be multiple tables that are part of the same shard, these tables will be related together by the same sharding key. :param table_name: The table that needs to be sharded. :param synchronous: Whether one should wait until the execution finishes or not. """ procedures = _events.trigger( PRUNE_SHARD_TABLES, self.get_lockable_objects(), table_name ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, server_id, reporter="unknown", error="unknown", update_only=False, synchronous=True): """Report a server issue. :param server_id: Servers's UUID or HOST:PORT. :param reporter: Who has reported the issue, usually an IP address or a host name. :param error: Error that has been reported. :param update_only: Only update the state store and skip provisioning. """ procedures = _events.trigger( REPORT_FAILURE, self.get_lockable_objects(), server_id, reporter, error, update_only ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, event, locks, *args, **kwargs): """Trigger the execution of an event. :param event: Event's identification. :type event: String :param args: Event's non-keyworded arguments. :param kwargs: Event's keyworded arguments. :return: List of the procedures' uuids that were created. """ lockable_objects = set() for lock in locks.split(","): lockable_objects.add(lock.strip()) return [ str(proc.uuid) \ for proc in _events.trigger(event, lockable_objects, *args, **kwargs) ]
def execute(self, table_name, synchronous=True): """Given the table name prune the tables according to the defined sharding specification for the table. The command prunes all the tables that are part of this shard. There might be multiple tables that are part of the same shard, these tables will be related together by the same sharding key. :param table_name: The table that needs to be sharded. :param synchronous: Whether one should wait until the execution finishes or not. """ prune_limit = _services_utils.read_config_value( self.config, 'sharding', 'prune_limit') procedures = _events.trigger(PRUNE_SHARD_TABLES, self.get_lockable_objects(), table_name, prune_limit) return self.wait_for_procedures(procedures, synchronous)
def execute(self, server_id, reporter="unknown", error="unknown", update_only=False, synchronous=True): """Report a server issue. :param server_id: Servers's UUID or HOST:PORT. :param reporter: Who has reported the issue, usually an IP address or a host name. :param error: Error that has been reported. :param update_only: Only update the state store and skip provisioning. """ procedures = _events.trigger(REPORT_ERROR, self.get_lockable_objects(), server_id, reporter, error, update_only) return self.wait_for_procedures(procedures, synchronous)
def execute(self, shard_id, group_id, update_only=False, synchronous=True): """Move the shard represented by the shard_id to the destination group. :param shard_id: The ID of the shard that needs to be moved. :param group_id: The ID of the group to which the shard needs to be moved. :update_only: Only update the state store and skip provisioning. :param synchronous: Whether one should wait until the execution finishes or not. """ procedures = _events.trigger( CHECK_SHARD_INFORMATION, self.get_lockable_objects(), shard_id, group_id, None, "", "MOVE", update_only ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, group_id, address, timeout=None, update_only=False, synchronous=True): """Add a server into a group. :param group_id: Group's id. :param address: Server's address. :param timeout: Time in seconds after which an error is reported if one cannot access the server. :update_only: Only update the state store and skip provisioning. :param synchronous: Whether one should wait until the execution finishes or not. :return: Tuple with job's uuid and status. """ procedures = _events.trigger(ADD_SERVER, self.get_lockable_objects(), group_id, address, timeout, update_only ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, group_id, address, timeout=None, update_only=False, synchronous=True): """Add a server into a group. :param group_id: Group's id. :param address: Server's address. :param timeout: Time in seconds after which an error is reported if one cannot access the server. :update_only: Only update the state store and skip provisioning. :param synchronous: Whether one should wait until the execution finishes or not. :return: Tuple with job's uuid and status. """ _LOGGER.debug("executing group add.") procedures = _events.trigger(ADD_SERVER, self.get_lockable_objects(), group_id, address, timeout, update_only ) return self.wait_for_procedures(procedures, synchronous)
def execute(self, event, locks=None, args=None, kwargs=None): """Trigger the execution of an event. :param event: Event's identification. :type event: String :param args: Event's non-keyworded arguments. :param kwargs: Event's keyworded arguments. :return: :class:`CommandResult` instance with UUID of the procedures that were triggered. """ # Prepare lockable objects. lockable_objects = None if locks: lockable_objects = set() for lock in locks: lockable_objects.add(lock.strip()) # Prepare list arguments. param_args = [] if args is not None: param_args = args # Prepare key word arguments. param_kwargs = {} if kwargs is not None: param_kwargs = kv_to_dict(kwargs) # Define the result set format. rset = ResultSet(names=['uuid'], types=[str]) _LOGGER.debug("Triggering event (%s) with arguments: %s, %s.", event, param_args, param_kwargs) # Trigger the event and add the UUID of all procedures queued # to the result. procedures = _events.trigger(event, lockable_objects, *param_args, **param_kwargs) for procedure in procedures: rset.append_row([str(procedure.uuid)]) return CommandResult(None, results=rset)