Browse Source

Resize replicas (volume) together with primary

When resizing volume for an instance which is the primary of a
replication, cluster, Trove also resizes the volume for all the replicas
automatically.

Change-Id: I2e719772fe7abc719255ea2a705d9ec342aced2a
changes/22/743422/1
Lingxian Kong 1 week ago
parent
commit
8e48d757e6
4 changed files with 39 additions and 19 deletions
  1. +3
    -0
      api-ref/source/instance-actions.inc
  2. +4
    -0
      releasenotes/notes/victoria-resize-vollume-for-replication.yaml
  3. +30
    -17
      trove/instance/models.py
  4. +2
    -2
      trove/quota/quota.py

+ 3
- 0
api-ref/source/instance-actions.inc View File

@@ -82,6 +82,9 @@ size. A valid volume size is an integer value in gigabytes (GB).
You cannot increase the volume to a size that is larger than the
API volume size limit.

For replication cluster, resizing volume of the primary will also resize
replicas automatically.

Normal response codes: 202

Request


+ 4
- 0
releasenotes/notes/victoria-resize-vollume-for-replication.yaml View File

@@ -0,0 +1,4 @@
---
features:
- When resizing volume for an instance which is the primary of a replication
cluster, Trove also resizes the volume for all the replicas automatically.

+ 30
- 17
trove/instance/models.py View File

@@ -1353,28 +1353,41 @@ class Instance(BuiltInstance):
new_flavor)

def resize_volume(self, new_size):
def _resize_resources():
self.validate_can_perform_action()
LOG.info("Resizing volume of instance %s.", self.id)
if self.db_info.cluster_id is not None:
raise exception.ClusterInstanceOperationNotSupported()
old_size = self.volume_size
if int(new_size) <= old_size:
raise exception.BadRequest(_("The new volume 'size' must be "
"larger than the current volume "
"size of '%s'.") % old_size)
# Set the task to Resizing before sending off to the taskmanager
self.update_db(task_status=InstanceTasks.RESIZING)
task_api.API(self.context).resize_volume(new_size, self.id)
"""Resize instance volume.

If the instance is primary in a replication cluster, volumes of all the
replicas are also resized.
"""

def _resize_resources(instance):
LOG.info("Resizing volume of instance %s.", instance.id)
instance.update_db(task_status=InstanceTasks.RESIZING)
task_api.API(self.context).resize_volume(new_size, instance.id)

new_size_l = int(new_size)

if self.db_info.cluster_id is not None:
raise exception.ClusterInstanceOperationNotSupported()
if not self.volume_size:
raise exception.BadRequest(_("Instance %s has no volume.")
% self.id)
new_size_l = int(new_size)
if new_size_l <= self.volume_size:
raise exception.BadRequest(_("The new volume 'size' must be "
"larger than the current volume "
"size of '%s'.") % self.volume_size)
validate_volume_size(new_size_l)
return run_with_quotas(self.tenant_id,
{'volumes': new_size_l - self.volume_size},
_resize_resources)
self.validate_can_perform_action()

instances = [self]
for dbinfo in self.slaves:
replica = Instance.load(self.context, dbinfo.id, needs_server=True)
replica.validate_can_perform_action()
instances.append(replica)

for instance in instances:
run_with_quotas(
self.tenant_id, {'volumes': new_size_l - self.volume_size},
_resize_resources, instance)

def reboot(self):
LOG.info("Rebooting instance %s.", self.id)


+ 2
- 2
trove/quota/quota.py View File

@@ -356,13 +356,13 @@ resources = [Resource(Resource.INSTANCES, 'max_instances_per_tenant'),
QUOTAS.register_resources(resources)


def run_with_quotas(tenant_id, deltas, f):
def run_with_quotas(tenant_id, deltas, f, *args, **kwargs):
"""Quota wrapper."""

reservations = QUOTAS.reserve(tenant_id, **deltas)
result = None
try:
result = f()
result = f(*args, **kwargs)
except Exception:
QUOTAS.rollback(reservations)
raise


Loading…
Cancel
Save