From 886150e1e64137f2f897cf012a145941ba45d568 Mon Sep 17 00:00:00 2001 From: Yikun Jiang Date: Fri, 29 Dec 2017 10:26:27 +0800 Subject: [PATCH] Add index(instance_uuid, updated_at) on instance_actions table A database index is added on the ``(instance_uuid, updated_at)`` columns in the ``nova.instance_actions`` table to improve the performance of filtering instance actions by the 'changes-since' parameter. Change-Id: Id79aa297c3248002a271e905dccd2c3ba27848c7 Implement: blueprint pagination-add-changes-since-for-instance-action-list --- ...8_add_instance_actions_updated_at_index.py | 46 +++++++++++++++++++ nova/db/sqlalchemy/models.py | 4 +- nova/tests/unit/db/test_migrations.py | 6 +++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/378_add_instance_actions_updated_at_index.py diff --git a/nova/db/sqlalchemy/migrate_repo/versions/378_add_instance_actions_updated_at_index.py b/nova/db/sqlalchemy/migrate_repo/versions/378_add_instance_actions_updated_at_index.py new file mode 100644 index 000000000000..9e30a6e4f39f --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/378_add_instance_actions_updated_at_index.py @@ -0,0 +1,46 @@ +# Copyright 2017 Huawei Technologies Co.,LTD. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +from oslo_log import log as logging +from sqlalchemy import MetaData, Table, Index + +LOG = logging.getLogger(__name__) + +INDEX_COLUMNS = ['instance_uuid', 'updated_at'] +INDEX_NAME = 'instance_actions_instance_uuid_updated_at_idx' +TABLE_NAME = 'instance_actions' + + +def _get_table_index(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + table = Table(TABLE_NAME, meta, autoload=True) + for idx in table.indexes: + if idx.columns.keys() == INDEX_COLUMNS: + break + else: + idx = None + return table, idx + + +def upgrade(migrate_engine): + table, index = _get_table_index(migrate_engine) + if index: + LOG.info('Skipped adding %s because an equivalent index' + ' already exists.', INDEX_NAME) + return + columns = [getattr(table.c, col_name) for col_name in INDEX_COLUMNS] + index = Index(INDEX_NAME, *columns) + index.create(migrate_engine) diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index fb4222eb7032..55b70fae78f5 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -1287,7 +1287,9 @@ class InstanceAction(BASE, NovaBase, models.SoftDeleteMixin): __tablename__ = 'instance_actions' __table_args__ = ( Index('instance_uuid_idx', 'instance_uuid'), - Index('request_id_idx', 'request_id') + Index('request_id_idx', 'request_id'), + Index('instance_actions_instance_uuid_updated_at_idx', + 'instance_uuid', 'updated_at') ) id = Column(Integer, primary_key=True, nullable=False, autoincrement=True) diff --git a/nova/tests/unit/db/test_migrations.py b/nova/tests/unit/db/test_migrations.py index f4bd57fe1228..15c00ff89cfa 100644 --- a/nova/tests/unit/db/test_migrations.py +++ b/nova/tests/unit/db/test_migrations.py @@ -991,6 +991,12 @@ class NovaMigrationsCheckers(test_migrations.ModelsMigrationsSync, self.assertIndexMembers(engine, 'migrations', 'migrations_updated_at_idx', ['updated_at']) + def _check_378(self, engine, data): + self.assertIndexMembers( + engine, 'instance_actions', + 'instance_actions_instance_uuid_updated_at_idx', + ['instance_uuid', 'updated_at']) + class TestNovaMigrationsSQLite(NovaMigrationsCheckers, test_base.DbTestCase,