summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin_Zheng <zhengzhenyu@huawei.com>2015-08-17 10:32:23 +0800
committerKevin_Zheng <zhengzhenyu@huawei.com>2015-08-29 10:54:14 +0800
commit6f35a8429939ec0f80deb2a65050c4b56db79545 (patch)
tree5cc740c374b1bcf4c10b73165b6b66f0de5ed693
parente81593b8c2ecf0ad5fab92bca8ac13e6c1d09daa (diff)
downloadnova-6f35a8429939ec0f80deb2a65050c4b56db79545.tar.gz
Make query to quota usage table order preserved
Currently, the query to quota usage table is not order preserved. This might cause deadlock in large-scale deployment: different calls may lock rows in different order, and deadlock will happen. This patch adds order_by to the query and make the query to the table order preserved. Change-Id: I98f6d7c3141349326c43cb32adcc1e6485ad53a6 Closes-bug: #1485408
-rw-r--r--nova/db/sqlalchemy/api.py7
-rw-r--r--nova/tests/unit/db/test_db_api.py7
2 files changed, 11 insertions, 3 deletions
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 85dd127a77..6709d35718 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -3367,9 +3367,10 @@ def _get_project_user_quota_usages(context, session, project_id,
rows = model_query(context, models.QuotaUsage,
read_deleted="no",
session=session).\
- filter_by(project_id=project_id).\
- with_lockmode('update').\
- all()
+ filter_by(project_id=project_id).\
+ order_by(models.QuotaUsage.id.asc()).\
+ with_lockmode('update').\
+ all()
proj_result = dict()
user_result = dict()
# Get the total count of in_use,reserved
diff --git a/nova/tests/unit/db/test_db_api.py b/nova/tests/unit/db/test_db_api.py
index 7e91ed4d98..31ef62c33f 100644
--- a/nova/tests/unit/db/test_db_api.py
+++ b/nova/tests/unit/db/test_db_api.py
@@ -6718,6 +6718,13 @@ class QuotaTestCase(test.TestCase, ModelsObjectComparatorMixin):
self.assertEqual(expected, db.quota_usage_get_all_by_project_and_user(
self.ctxt, 'p1', 'u1'))
+ def test_get_project_user_quota_usages_in_order(self):
+ _quota_reserve(self.ctxt, 'p1', 'u1')
+ with mock.patch.object(query.Query, 'order_by') as order_mock:
+ sqlalchemy_api._get_project_user_quota_usages(
+ self.ctxt, None, 'p1', 'u1')
+ self.assertTrue(order_mock.called)
+
def test_quota_usage_update_nonexistent(self):
self.assertRaises(exception.QuotaUsageNotFound, db.quota_usage_update,
self.ctxt, 'p1', 'u1', 'resource', in_use=42)