From 4a154164dafa35011a3c292b97effe2ebf0cf089 Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Wed, 7 Oct 2015 09:33:05 -0700 Subject: [PATCH] Log DBReferenceError in archive_deleted_rows_for_table We should add the foreign key constraint integrity error to the warning since it includes detailed information about the reference table that caused the constraint failure, which is useful for knowing things are out of order without having to check your database. You get something like this now: 2015-10-07 15:29:38.238 WARNING nova.db.sqlalchemy.api [req-6115aef5-2a82-4d42-bf67-eaab2e8eee63 None None] IntegrityError detected when archiving table instances: (pymysql.err.IntegrityError) (1451, u'Cannot delete or update a parent row: a foreign key constraint fails (`nova`.`instance_actions`, CONSTRAINT `fk_instance_actions_instance_uuid` FOREIGN KEY (`instance_uuid`) REFERENCES `instances` (`uuid`))') [SQL: u'DELETE FROM instances WHERE instances.id in (SELECT T1.id FROM (SELECT instances.id \nFROM instances \nWHERE instances.deleted != %s ORDER BY instances.id \n LIMIT %s) as T1)'] [parameters: (0, 10)] Related-Bug: #1183523 Change-Id: I41b10898c6e9cc48da58c4d2daf7df362fc9fc36 --- nova/db/sqlalchemy/api.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index bb40f9efd..58da040a8 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -6017,12 +6017,13 @@ def archive_deleted_rows_for_table(context, tablename, max_rows): with conn.begin(): conn.execute(insert) result_delete = conn.execute(delete_statement) - except db_exc.DBReferenceError: + except db_exc.DBReferenceError as ex: # A foreign key constraint keeps us from deleting some of # these rows until we clean up a dependent table. Just # skip this table for now; we'll come back to it later. - msg = _("IntegrityError detected when archiving table %s") % tablename - LOG.warn(msg) + LOG.warn(_LW("IntegrityError detected when archiving table " + "%(tablename)s: %(error)s"), + {'tablename': tablename, 'error': six.text_type(ex)}) return rows_archived rows_archived = result_delete.rowcount