From 8921a470ee797cd75def387ce184ee0ffaae6517 Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Fri, 3 May 2019 15:40:30 -0400 Subject: [PATCH] Avoid unnecessary joins in delete_resource_provider If cascade=True, we're getting all of the instances on the compute node just to use the uuid, which will by default join on the info_cache and security_groups for the instances. This is a simple optimization to avoid those unnecessary joins. A TODO is left to further optimize this with a new InstanceList query method to just get the instance uuids on a given host/node combo, but that requires an RPC change which we can't backport. Change-Id: Ie121210456a240c257979d3269db115ddae2d23b Related-Bug: #1811726 Related-Bug: #1756179 --- nova/scheduler/client/report.py | 8 ++++++-- nova/tests/unit/scheduler/client/test_report.py | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/nova/scheduler/client/report.py b/nova/scheduler/client/report.py index b81d7de40ee2..1cfaa9a0b58b 100644 --- a/nova/scheduler/client/report.py +++ b/nova/scheduler/client/report.py @@ -2169,8 +2169,12 @@ class SchedulerReportClient(object): # Delete any allocations for this resource provider. # Since allocations are by consumer, we get the consumers on this # host, which are its instances. - instances = objects.InstanceList.get_by_host_and_node(context, - host, nodename) + # TODO(mriedem): Optimize this up by adding an + # InstanceList.get_uuids_by_host_and_node method. + # Pass expected_attrs=[] to avoid joining on extra columns we + # don't use. + instances = objects.InstanceList.get_by_host_and_node( + context, host, nodename, expected_attrs=[]) for instance in instances: self.delete_allocation_for_instance(context, instance.uuid) try: diff --git a/nova/tests/unit/scheduler/client/test_report.py b/nova/tests/unit/scheduler/client/test_report.py index 654f096b954c..17682db49237 100644 --- a/nova/tests/unit/scheduler/client/test_report.py +++ b/nova/tests/unit/scheduler/client/test_report.py @@ -3201,6 +3201,8 @@ class TestAllocations(SchedulerReportClientTestCase): resp_mock = mock.Mock(status_code=204) mock_delete.return_value = resp_mock self.client.delete_resource_provider(self.context, cn, cascade=True) + mock_by_host.assert_called_once_with( + self.context, cn.host, cn.hypervisor_hostname, expected_attrs=[]) self.assertEqual(2, mock_del_alloc.call_count) exp_url = "/resource_providers/%s" % uuids.cn mock_delete.assert_called_once_with(