Add index on instances table across project_id and updated_at

We should have an index on the instances.updated_at table because
that's what's used to filter instances when using the --changes-since
filter parameter with nova list.

Closes-Bug: #1642729

Change-Id: I4c723839f36efddd95cd24d745fb71c96c75d2c1
This commit is contained in:
int32bit 2016-11-19 00:08:12 +08:00 committed by Matt Riedemann
parent 72d0c3a484
commit 887cc5243e
3 changed files with 69 additions and 0 deletions

View File

@ -0,0 +1,58 @@
# 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
from sqlalchemy.engine import reflection
from nova.i18n import _LI
LOG = logging.getLogger(__name__)
INDEX_COLUMNS_1 = ['project_id']
INDEX_NAME_1 = 'instances_project_id_idx'
INDEX_COLUMNS_2 = ['updated_at', 'project_id']
INDEX_NAME_2 = 'instances_updated_at_project_id_idx'
TABLE_NAME = 'instances'
def _get_table_index(migrate_engine, table_name, index_columns):
inspector = reflection.Inspector.from_engine(migrate_engine)
for idx in inspector.get_indexes(table_name):
if idx['column_names'] == index_columns:
break
else:
idx = None
return idx
def upgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
table = Table(TABLE_NAME, meta, autoload=True)
if _get_table_index(migrate_engine, TABLE_NAME, INDEX_COLUMNS_1):
LOG.info(_LI('Skipped adding %s because an equivalent index'
' already exists.'), INDEX_NAME_1)
else:
columns = [getattr(table.c, col_name) for col_name in INDEX_COLUMNS_1]
index = Index(INDEX_NAME_1, *columns)
index.create(migrate_engine)
if _get_table_index(migrate_engine, TABLE_NAME, INDEX_COLUMNS_2):
LOG.info(_LI('Skipped adding %s because an equivalent index'
' already exists.'), INDEX_NAME_2)
else:
columns = [getattr(table.c, col_name) for col_name in INDEX_COLUMNS_2]
index = Index(INDEX_NAME_2, *columns)
index.create(migrate_engine)

View File

@ -198,6 +198,7 @@ class Instance(BASE, NovaBase, models.SoftDeleteMixin):
__tablename__ = 'instances'
__table_args__ = (
Index('uuid', 'uuid', unique=True),
Index('instances_project_id_idx', 'project_id'),
Index('instances_project_id_deleted_idx',
'project_id', 'deleted'),
Index('instances_reservation_id_idx',
@ -214,6 +215,8 @@ class Instance(BASE, NovaBase, models.SoftDeleteMixin):
'host', 'deleted', 'cleaned'),
Index('instances_deleted_created_at_idx',
'deleted', 'created_at'),
Index('instances_updated_at_project_id_idx',
'updated_at', 'project_id'),
schema.UniqueConstraint('uuid', name='uniq_instances0uuid'),
)
injected_files = []

View File

@ -933,6 +933,14 @@ class NovaMigrationsCheckers(test_migrations.ModelsMigrationsSync,
self.assertColumnNotExists(engine, 'instances', 'scheduled_at')
self.assertColumnNotExists(engine, 'shadow_instances', 'scheduled_at')
def _check_347(self, engine, data):
self.assertIndexMembers(engine, 'instances',
'instances_project_id_idx',
['project_id'])
self.assertIndexMembers(engine, 'instances',
'instances_updated_at_project_id_idx',
['updated_at', 'project_id'])
class TestNovaMigrationsSQLite(NovaMigrationsCheckers,
test_base.DbTestCase,