def shrink(self, instance_ids): self.validate_cluster_available() context = self.context db_info = self.db_info datastore_version = self.ds_version for db_instance in self.db_instances: if db_instance.type == 'master': if db_instance.id in instance_ids: raise exception.ClusterShrinkInstanceInUse( id=db_instance.id, reason="Cannot remove master node.") all_instance_ids = [ db_instance.id for db_instance in self.db_instances ] left_instances = [ instance_id for instance_id in all_instance_ids if instance_id not in instance_ids ] k = self.k_safety(len(left_instances)) vertica_conf = CONF.get(datastore_version.manager) if k < vertica_conf.min_ksafety: raise exception.ClusterNumInstancesBelowSafetyThreshold() db_info.update(task_status=ClusterTasks.SHRINKING_CLUSTER) task_api.load(context, datastore_version.manager).shrink_cluster( self.db_info.id, instance_ids) return VerticaCluster(self.context, db_info, self.ds, self.ds_version)
def shrink(self, removal_ids): LOG.debug("Shrinking cluster %s.", self.id) self.validate_cluster_available() cluster_info = self.db_info cluster_info.update(task_status=ClusterTasks.SHRINKING_CLUSTER) try: removal_insts = [ inst_models.Instance.load(self.context, inst_id) for inst_id in removal_ids ] node_ids = [] error_ids = [] for instance in removal_insts: node_id = Cluster.get_guest(instance).get_node_id_for_removal() if node_id: node_ids.append(node_id) else: error_ids.append(instance.id) if error_ids: raise exception.ClusterShrinkInstanceInUse( id=error_ids, reason="Nodes cannot be removed. Check slots.") all_instances = (inst_models.DBInstance.find_all( cluster_id=self.id, deleted=False).all()) remain_insts = [ inst_models.Instance.load(self.context, inst.id) for inst in all_instances if inst.id not in removal_ids ] for inst in remain_insts: guest = Cluster.get_guest(inst) guest.remove_nodes(node_ids) for inst in removal_insts: inst.update_db(cluster_id=None) for inst in removal_insts: inst_models.Instance.delete(inst) return RedisCluster(self.context, cluster_info, self.ds, self.ds_version) finally: cluster_info.update(task_status=ClusterTasks.NONE)
def shrink(self, instance_ids): """Removes instances from a cluster. Currently only supports removing entire replica sets from the cluster. """ if not len(instance_ids) > 0: raise exception.TroveError( _('No instances specified for shrink operation.')) self._prep_resize() all_member_ids = set([member.id for member in self.members]) all_query_router_ids = set( [query_router.id for query_router in self.query_routers]) target_ids = set(instance_ids) target_member_ids = target_ids.intersection(all_member_ids) target_query_router_ids = target_ids.intersection(all_query_router_ids) target_configsvr_ids = target_ids.difference( target_member_ids.union(target_query_router_ids)) if target_configsvr_ids: raise exception.ClusterShrinkInstanceInUse( id=list(target_configsvr_ids), reason="Cannot remove config servers.") remaining_query_router_ids = all_query_router_ids.difference( target_query_router_ids) if len(remaining_query_router_ids) < 1: raise exception.ClusterShrinkInstanceInUse( id=list(target_query_router_ids), reason="Cannot remove all remaining query routers. At least " "one query router must be available in the cluster.") if target_member_ids: target_members = [ member for member in self.members if member.id in target_member_ids ] target_shards = {} for member in target_members: if member.shard_id in target_shards: target_shards[member.shard_id].append(member.id) else: target_shards[member.shard_id] = [member.id] for target_shard_id in target_shards.keys(): # check the whole shard is being deleted target_shard_member_ids = [ member.id for member in target_members if member.shard_id == target_shard_id ] all_shard_member_ids = [ member.id for member in self.members if member.shard_id == target_shard_id ] if set(target_shard_member_ids) != set(all_shard_member_ids): raise exception.TroveError( _('MongoDB cluster shrink only supports removing an ' 'entire shard. Shard %(shard)s has members: ' '%(instances)s') % { 'shard': target_shard_id, 'instances': all_shard_member_ids }) self._check_shard_status(target_shard_member_ids[0]) # all checks are done by now self.update_db(task_status=ClusterTasks.SHRINKING_CLUSTER) for instance_id in instance_ids: instance = inst_models.load_any_instance(self.context, instance_id) instance.delete() self.manager.shrink_cluster(self.id, instance_ids)