db: Drop support for MySQL 5.5

This went EOL in December 2018. We don't need this logic. A release note
is included, even though this isn't really needed (we don't formalize
our support for different MySQL versions anywhere, and are mostly
dependent on what SQLAlchemy/oslo.db support)

Change-Id: Ie78d6e7612d84c712c8dc6fb5effc2b8bd5b4b22
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
Stephen Finucane 2022-02-17 16:53:01 +00:00
parent 6d4a6aa978
commit 36c530676f
6 changed files with 8 additions and 91 deletions

View File

@ -1892,17 +1892,6 @@ def cleanup_expired_messages(context):
###################
def workers_init():
"""Check if DB supports subsecond resolution and set global flag.
MySQL 5.5 doesn't support subsecond resolution in datetime fields, so we
have to take it into account when working with the worker's table.
Once we drop support for MySQL 5.5 we can remove this method.
"""
return IMPL.workers_init()
def worker_create(context, **values):
"""Create a worker entry from optional arguments."""
return IMPL.worker_create(context, **values)

View File

@ -7272,7 +7272,9 @@ def _worker_query(context, session=None, until=None, db_filters=None,
query = model_query(context, models.Worker, session=session)
# TODO(geguileo): Once we remove support for MySQL 5.5 we can remove this
# TODO: Once we stop creating the SENTINEL entry in the database (which
# was only needed to support MySQL 5.5), we can drop this. Probably in the
# A release or later
if ignore_sentinel:
# We don't want to retrieve the workers sentinel
query = query.filter(models.Worker.resource_type != 'SENTINEL')
@ -7292,35 +7294,10 @@ def _worker_query(context, session=None, until=None, db_filters=None,
return query
DB_SUPPORTS_SUBSECOND_RESOLUTION = True
def workers_init():
"""Check if DB supports subsecond resolution and set global flag.
MySQL 5.5 doesn't support subsecond resolution in datetime fields, so we
have to take it into account when working with the worker's table.
To do this we'll have 1 row in the DB, created by the migration script,
where we have tried to set the microseconds and we'll check it.
Once we drop support for MySQL 5.5 we can remove this method.
"""
global DB_SUPPORTS_SUBSECOND_RESOLUTION
session = get_session()
query = session.query(models.Worker).filter_by(resource_type='SENTINEL')
worker = query.first()
DB_SUPPORTS_SUBSECOND_RESOLUTION = bool(worker.updated_at.microsecond)
def _worker_set_updated_at_field(values):
# TODO(geguileo): Once we drop support for MySQL 5.5 we can simplify this
# method.
updated_at = values.get('updated_at', timeutils.utcnow())
if isinstance(updated_at, str):
return
if not DB_SUPPORTS_SUBSECOND_RESOLUTION:
updated_at = updated_at.replace(microsecond=0)
values['updated_at'] = updated_at

View File

@ -318,8 +318,5 @@ class CleanableManager(object):
def init_host(self, service_id, added_to_cluster=None, **kwargs):
ctxt = context.get_admin_context()
self.service_id = service_id
# TODO(geguileo): Once we don't support MySQL 5.5 anymore we can remove
# call to workers_init.
db.workers_init()
cleanup_request = objects.CleanupRequest(service_id=service_id)
self.do_cleanup(ctxt, cleanup_request)

View File

@ -47,9 +47,8 @@ class TestCleanableManager(test.TestCase):
is_admin=True)
self.service = db.service_create(self.context, {})
@mock.patch('cinder.db.workers_init', autospec=True)
@mock.patch('cinder.manager.CleanableManager.do_cleanup', autospec=True)
def test_init_host_with_service(self, mock_cleanup, mock_workers_init):
def test_init_host_with_service(self, mock_cleanup):
mngr = FakeManager()
self.assertFalse(hasattr(mngr, 'service_id'))
mngr.init_host(service_id=self.service.id)
@ -59,7 +58,6 @@ class TestCleanableManager(test.TestCase):
clean_req = mock_cleanup.call_args[0][2]
self.assertIsInstance(clean_req, objects.CleanupRequest)
self.assertEqual(self.service.id, clean_req.service_id)
mock_workers_init.assert_called_once_with()
def test_do_cleanup(self):
"""Basic successful cleanup."""

View File

@ -15,9 +15,7 @@
"""Unit tests for cinder.db.api.Worker"""
from datetime import datetime
import time
from unittest import mock
import uuid
from oslo_db import exception as db_exception
@ -41,41 +39,12 @@ class DBAPIWorkerTestCase(test.TestCase, test.ModelsObjectComparatorMixin):
super(DBAPIWorkerTestCase, self).setUp()
self.ctxt = context.get_admin_context()
def tearDown(self):
db.sqlalchemy.api.DB_SUPPORTS_SUBSECOND_RESOLUTION = True
super(DBAPIWorkerTestCase, self).tearDown()
def test_workers_init(self):
# SQLite supports subsecond resolution so result is True
db.sqlalchemy.api.DB_SUPPORTS_SUBSECOND_RESOLUTION = None
db.workers_init()
self.assertTrue(db.sqlalchemy.api.DB_SUPPORTS_SUBSECOND_RESOLUTION)
def test_workers_init_not_supported(self):
# Fake a Db that doesn't support sub-second resolution in datetimes
db.worker_update(
self.ctxt, None,
{'resource_type': 'SENTINEL', 'ignore_sentinel': False},
updated_at=datetime.utcnow().replace(microsecond=0))
db.workers_init()
self.assertFalse(db.sqlalchemy.api.DB_SUPPORTS_SUBSECOND_RESOLUTION)
def test_worker_create_and_get(self):
"""Test basic creation of a worker record."""
worker = db.worker_create(self.ctxt, **self.worker_fields)
db_worker = db.worker_get(self.ctxt, id=worker.id)
self._assertEqualObjects(worker, db_worker)
@mock.patch('oslo_utils.timeutils.utcnow',
return_value=datetime.utcnow().replace(microsecond=123))
def test_worker_create_no_subsecond(self, mock_utcnow):
"""Test basic creation of a worker record."""
db.sqlalchemy.api.DB_SUPPORTS_SUBSECOND_RESOLUTION = False
worker = db.worker_create(self.ctxt, **self.worker_fields)
db_worker = db.worker_get(self.ctxt, id=worker.id)
self._assertEqualObjects(worker, db_worker)
self.assertEqual(0, db_worker.updated_at.microsecond)
def test_worker_create_unique_constrains(self):
"""Test when we use an already existing resource type and id."""
db.worker_create(self.ctxt, **self.worker_fields)
@ -163,23 +132,6 @@ class DBAPIWorkerTestCase(test.TestCase, test.ModelsObjectComparatorMixin):
['updated_at', 'race_preventer'])
self.assertEqual(worker.race_preventer + 1, db_worker.race_preventer)
def test_worker_update_no_subsecond(self):
"""Test basic worker update."""
db.sqlalchemy.api.DB_SUPPORTS_SUBSECOND_RESOLUTION = False
worker = self._create_workers(1)[0]
worker = db.worker_get(self.ctxt, id=worker.id)
now = datetime.utcnow().replace(microsecond=123)
with mock.patch('oslo_utils.timeutils.utcnow', return_value=now):
res = db.worker_update(self.ctxt, worker.id, service_id=1)
self.assertEqual(1, res)
worker.service_id = 1
db_worker = db.worker_get(self.ctxt, id=worker.id)
self._assertEqualObjects(worker, db_worker,
['updated_at', 'race_preventer'])
self.assertEqual(0, db_worker.updated_at.microsecond)
self.assertEqual(worker.race_preventer + 1, db_worker.race_preventer)
def test_worker_update_update_orm(self):
"""Test worker update updating the worker orm object."""
worker = self._create_workers(1)[0]

View File

@ -0,0 +1,4 @@
---
upgrade:
- |
Support for MySQL 5.5 has been dropped.