diff options
| author | Boris Pavlovic <boris@pavlovic.me> | 2013-03-04 23:31:20 +0400 |
|---|---|---|
| committer | Boris Pavlovic <boris@pavlovic.me> | 2013-03-04 23:51:26 +0400 |
| commit | be6a2cc1670bb27334609e17f0556529f0cc9462 (patch) | |
| tree | 3bdf31e0e9024898dedaadc80c6c854c77bc487f | |
| parent | bcdbe9ba881db8b38525bfc44a182e6b210459cd (diff) | |
| download | nova-be6a2cc1670bb27334609e17f0556529f0cc9462.tar.gz nova-be6a2cc1670bb27334609e17f0556529f0cc9462.tar.xz nova-be6a2cc1670bb27334609e17f0556529f0cc9462.zip | |
Imporove db.sqlalchemy.api._validate_unique_server_name method
This method is called by instance_create and instance_update.
If parameter CONF.osapi_compute_unqiue_server_name_scope is set to
'global' or 'project' then it has terrible performance.
Algorithm was next:
1) Get all instances and all connected data (5 joinloads..) in global
(or project).
2) Compare hostname with hostnames in instances (locally)
Now:
1) Get only count of instances with same hostname in global (or project).
2) If count > 0 raise Exception.
Change-Id: I35ea121c3f906b4fff11c38bafa2ab33200bd6b2
| -rw-r--r-- | nova/db/sqlalchemy/api.py | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 33261f4db..e7eb56f89 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1371,17 +1371,19 @@ def _validate_unique_server_name(context, session, name): if not CONF.osapi_compute_unique_server_name_scope: return - search_opts = {'deleted': False} + lowername = name.lower() + base_query = model_query(context, models.Instance, session=session, + read_deleted=False).\ + filter(func.lower(models.Instance.hostname) == lowername) + if CONF.osapi_compute_unique_server_name_scope == 'project': - search_opts['project_id'] = context.project_id - instance_list = instance_get_all_by_filters(context, search_opts, - 'created_at', 'desc', - session=session) + instance_with_same_name = base_query.\ + filter_by(project_id=context.project_id).\ + count() + elif CONF.osapi_compute_unique_server_name_scope == 'global': - instance_list = instance_get_all_by_filters(context.elevated(), - search_opts, - 'created_at', 'desc', - session=session) + instance_with_same_name = base_query.count() + else: msg = _('Unknown osapi_compute_unique_server_name_scope value: %s' ' Flag must be empty, "global" or' @@ -1389,10 +1391,8 @@ def _validate_unique_server_name(context, session, name): LOG.warn(msg) return - lowername = name.lower() - for instance in instance_list: - if instance['hostname'].lower() == lowername: - raise exception.InstanceExists(name=instance['hostname']) + if instance_with_same_name > 0: + raise exception.InstanceExists(name=lowername) @require_context |
