Add debug logging when Instance raises OrphanedObjectError

This logging would be helpful in debugging issues when
OrphanedObjectError is raised by an instance. Currently, there is
not a way to identify which instance is attempting to lazy-load a
field while orphaned. Being able to locate the instance in the
database could also help with recovery/cleanup when a problematic
record is disrupting operation of a deployment.

Change-Id: I093de2839c1bb7c949a0812e07b63de4cc5ed167
(cherry picked from commit e0fbb6fc06)
(cherry picked from commit f32deaa617)
(cherry picked from commit 9e84562976)
(cherry picked from commit 8aa6723fa4)
This commit is contained in:
melanie witt 2023-05-17 03:04:49 +00:00
parent 00998e1b2f
commit cc75f91aac
2 changed files with 20 additions and 0 deletions

View File

@ -1088,6 +1088,11 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
def obj_load_attr(self, attrname):
# NOTE(danms): We can't lazy-load anything without a context and a uuid
if not self._context:
if 'uuid' in self:
LOG.debug(
"Lazy-load of '%s' attempted by orphaned instance",
attrname, instance=self
)
raise exception.OrphanedObjectError(method='obj_load_attr',
objtype=self.obj_name())
if 'uuid' not in self:

View File

@ -1632,6 +1632,21 @@ class TestInstanceObject(test_objects._LocalTest,
self._test_save_objectfield_fk_constraint_fails(
'other_foreign_key', db_exc.DBReferenceError)
@mock.patch('nova.objects.instance.LOG.debug')
def test_obj_load_attr_log(self, mock_log_debug):
# Instance with no UUID should not log.
instance = objects.Instance()
self.assertRaises(
exception.OrphanedObjectError, instance.obj_load_attr, 'foo')
mock_log_debug.assert_not_called()
# Instance with UUID should log.
instance = objects.Instance(
uuid='127a0d59-b88c-422b-b9a1-2dc7cc51fb9a')
self.assertRaises(
exception.OrphanedObjectError, instance.obj_load_attr, 'foo')
msg = "Lazy-load of '%s' attempted by orphaned instance"
mock_log_debug.assert_called_once_with(msg, 'foo', instance=instance)
class TestRemoteInstanceObject(test_objects._RemoteTest,
_TestInstanceObject):