)]}'
{"id":"openstack%2Fnova~785075","triplet_id":"openstack%2Fnova~stable%2Ftrain~Ie653e5ec69d16ae469f1f8171fee85aea754edff","project":"openstack/nova","branch":"stable/train","topic":"bug/1837995","hashtags":[],"change_id":"Ie653e5ec69d16ae469f1f8171fee85aea754edff","subject":"Dynamically archive FK related records in archive_deleted_rows","status":"ABANDONED","created":"2021-04-06 23:10:05.000000000","updated":"2023-09-01 17:02:54.000000000","total_comment_count":3,"unresolved_comment_count":1,"has_review_started":true,"meta_rev_id":"2cdfe85b081e35e2e62312d7c1d01b19d2fb0824","_number":785075,"virtual_id_number":785075,"owner":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"actions":{},"labels":{"Verified":{"disliked":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"all":[{"tag":"autogenerated:zuul:check","value":-1,"date":"2021-04-07 18:22:45.000000000","permitted_voting_range":{"min":-2,"max":2},"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"}],"values":{"-2":"Fails","-1":"Doesn\u0027t seem to work"," 0":"No score","+1":"Works for me","+2":"Verified"},"description":"","value":-1,"default_value":0,"optional":true},"Code-Review":{"all":[{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},{"value":0,"permitted_voting_range":{"min":-2,"max":2},"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"}],"values":{"-2":"Do not merge","-1":"This patch needs further work before it can be merged"," 0":"No score","+1":"Looks good to me, but someone else must approve","+2":"Looks good to me (core reviewer)"},"description":"","default_value":0,"optional":true},"Workflow":{"rejected":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"all":[{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},{"value":-1,"date":"2021-04-07 19:02:25.000000000","permitted_voting_range":{"min":-1,"max":1},"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"}],"values":{"-1":"Work in progress"," 0":"Ready for reviews","+1":"Approved"},"description":"","default_value":0,"optional":true},"Review-Priority":{"all":[{"value":0,"permitted_voting_range":{"min":0,"max":1},"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},{"value":0,"permitted_voting_range":{"min":0,"max":2},"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"}],"values":{" 0":"Default Priority","+1":"Contributor Review Promise","+2":"Core Review Promise"},"description":"","default_value":0,"optional":true}},"removable_reviewers":[],"reviewers":{"CC":[{"_account_id":10118,"name":"IBM PowerKVM CI","email":"kvmpower@linux.vnet.ibm.com","username":"powerkvm","tags":["SERVICE_USER"]},{"_account_id":26515,"name":"Cloudbase Nova Hyper-V CI","email":"nova_hyperv_ci@cloudbasesolutions.com","username":"nova_hyperv_ci"}],"REVIEWER":[{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]}]},"pending_reviewers":{},"reviewer_updates":[{"updated":"2021-04-07 01:06:19.000000000","updated_by":{"_account_id":10118,"name":"IBM PowerKVM CI","email":"kvmpower@linux.vnet.ibm.com","username":"powerkvm","tags":["SERVICE_USER"]},"reviewer":{"_account_id":10118,"name":"IBM PowerKVM CI","email":"kvmpower@linux.vnet.ibm.com","username":"powerkvm","tags":["SERVICE_USER"]},"state":"CC"},{"updated":"2021-04-07 01:11:51.000000000","updated_by":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"reviewer":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"state":"REVIEWER"},{"updated":"2021-04-07 04:16:41.000000000","updated_by":{"_account_id":26515,"name":"Cloudbase Nova Hyper-V CI","email":"nova_hyperv_ci@cloudbasesolutions.com","username":"nova_hyperv_ci"},"reviewer":{"_account_id":26515,"name":"Cloudbase Nova Hyper-V CI","email":"nova_hyperv_ci@cloudbasesolutions.com","username":"nova_hyperv_ci"},"state":"CC"}],"messages":[{"id":"f4749fd820b4f5a06ce7ba378baf307f0fa49165","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"date":"2021-04-06 23:10:05.000000000","message":"Uploaded patch set 1.","accounts_in_message":[],"_revision_number":1},{"id":"931385547af84e67d3277a26d65dee1fdcbace13","author":{"_account_id":10118,"name":"IBM PowerKVM CI","email":"kvmpower@linux.vnet.ibm.com","username":"powerkvm","tags":["SERVICE_USER"]},"date":"2021-04-07 01:06:19.000000000","message":"Patch Set 1:\n\nBuild succeeded. Test completed on IBM PowerKVM platform. For rechecking only on the IBM PowerKVM CI, add a review comment with pkvm- recheck. For contact and more information, see https://wiki.openstack.org/wiki/PowerKVM\n\n- tempest-dsvm-full-bionic-py3 https://oplab9.parqtec.unicamp.br/pub/ppc64el/openstack/nova/75/785075/1/check/tempest-dsvm-full-bionic-py3/a614cbf/ : SUCCESS in 1h 29m 26s","accounts_in_message":[],"_revision_number":1},{"id":"d90e1a7af51e3890375b33eb586bf4d048015025","tag":"autogenerated:zuul:check","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2021-04-07 01:11:51.000000000","message":"Patch Set 1: Verified-1\n\n(2 comments)\n\nBuild failed (check pipeline).  For information on how to proceed, see\nhttps://docs.opendev.org/opendev/infra-manual/latest/developers.html#automated-testing\n\n\n- tempest-integrated-compute https://zuul.opendev.org/t/openstack/build/be5d2df40d4d44f882000745b5e19b00 : SUCCESS in 1h 20m 55s\n- openstack-tox-cover https://zuul.opendev.org/t/openstack/build/9b76e5de680e4e11b2f82adb60e48194 : FAILURE in 14m 24s\n- openstack-tox-lower-constraints https://zuul.opendev.org/t/openstack/build/5da1e68447b644e9a552c94f84c7afda : FAILURE in 14m 15s\n- openstack-tox-pep8 https://zuul.opendev.org/t/openstack/build/b9658818d684471cb2e26dcc7e22bfdd : FAILURE in 11m 03s\n- openstack-tox-py27 https://zuul.opendev.org/t/openstack/build/b7ab62261e944e2c981558d96db61e1a : FAILURE in 14m 29s\n- openstack-tox-py36 https://zuul.opendev.org/t/openstack/build/3ae87c97139840afb6dad5ceb749b6e0 : FAILURE in 11m 31s\n- openstack-tox-py37 https://zuul.opendev.org/t/openstack/build/9d6763d2347b4753ba11fddcdf3eff8b : FAILURE in 12m 41s\n- openstack-tox-docs https://zuul.opendev.org/t/openstack/build/5b52c41022294ab6a3400b1b4a7c8a19 : SUCCESS in 10m 03s\n- ironic-tempest-ipa-wholedisk-bios-agent_ipmitool-tinyipa https://zuul.opendev.org/t/openstack/build/462ea181b6c549068d2599485407a6e5 : SUCCESS in 1h 11m 15s (non-voting)\n- devstack-plugin-ceph-tempest https://zuul.opendev.org/t/openstack/build/2835cdd567f449739281a6c9e0430516 : SUCCESS in 1h 14m 40s (non-voting)\n- neutron-grenade-multinode https://zuul.opendev.org/t/openstack/build/16d345605dd74d6d85c9941f6f709345 : SUCCESS in 1h 04m 08s\n- nova-grenade-multinode https://zuul.opendev.org/t/openstack/build/43ad38a2f9b14745a29d3b2769362df3 : SUCCESS in 1h 05m 26s\n- nova-live-migration https://zuul.opendev.org/t/openstack/build/241a28851e1b4c67a5003abc2ae5de80 : SUCCESS in 46m 28s\n- nova-multi-cell https://zuul.opendev.org/t/openstack/build/e394db5c1e8e4a0fa2bbc572c89fc56c : SUCCESS in 1h 22m 06s\n- nova-next https://zuul.opendev.org/t/openstack/build/efc4162f53b04e2aaafca5dfe8221f70 : POST_FAILURE in 1h 14m 04s\n- nova-tox-functional https://zuul.opendev.org/t/openstack/build/be31cbfd87654f46b7d728135270c715 : FAILURE in 9m 54s\n- nova-tox-functional-py36 https://zuul.opendev.org/t/openstack/build/5bcdaefb12f0447b8bdf66e5dc1ffa07 : FAILURE in 8m 46s\n- tempest-slow-py3 https://zuul.opendev.org/t/openstack/build/ad59298c3f9b4a57bd0d2e43c04df1de : SUCCESS in 1h 56m 55s\n- grenade-py3 https://zuul.opendev.org/t/openstack/build/6eb2b566915749b6b027c3ac2ab94f5b : SUCCESS in 57m 41s\n- tempest-ipv6-only https://zuul.opendev.org/t/openstack/build/12887222a97844df9a6cc5a23a261ebf : SUCCESS in 50m 47s","accounts_in_message":[],"_revision_number":1},{"id":"28c618d10a04681ad3eca88441b6f8da8d899704","author":{"_account_id":26515,"name":"Cloudbase Nova Hyper-V CI","email":"nova_hyperv_ci@cloudbasesolutions.com","username":"nova_hyperv_ci"},"date":"2021-04-07 04:16:41.000000000","message":"Patch Set 1:\n\nBuild succeeded. For checking Nova with Ceph, add a comment with run-Cloudbase Nova Ceph Hyper-V CI\n\n- nova http://cloudbase-ci.com/nova/785075/1/iscsi : SUCCESS in 2h 35m 04s","accounts_in_message":[],"_revision_number":1},{"id":"d967e7cf368b40daef8bd6d544e4c2706b318969","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"date":"2021-04-07 16:02:04.000000000","message":"Uploaded patch set 2.","accounts_in_message":[],"_revision_number":2},{"id":"95348cb0ca48786401d8c838b2cb7c011bac6e84","author":{"_account_id":10118,"name":"IBM PowerKVM CI","email":"kvmpower@linux.vnet.ibm.com","username":"powerkvm","tags":["SERVICE_USER"]},"date":"2021-04-07 18:18:11.000000000","message":"Patch Set 2:\n\nBuild succeeded. Test completed on IBM PowerKVM platform. For rechecking only on the IBM PowerKVM CI, add a review comment with pkvm- recheck. For contact and more information, see https://wiki.openstack.org/wiki/PowerKVM\n\n- tempest-dsvm-full-bionic-py3 https://oplab9.parqtec.unicamp.br/pub/ppc64el/openstack/nova/75/785075/2/check/tempest-dsvm-full-bionic-py3/8bed26a/ : SUCCESS in 1h 54m 27s","accounts_in_message":[],"_revision_number":2},{"id":"08fd0b2ebf111f9c3763feaa0cbc3fff5533b4a3","tag":"autogenerated:zuul:check","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2021-04-07 18:22:45.000000000","message":"Patch Set 2: Verified-1\n\nBuild failed (check pipeline).  For information on how to proceed, see\nhttps://docs.opendev.org/opendev/infra-manual/latest/developers.html#automated-testing\n\n\n- tempest-integrated-compute https://zuul.opendev.org/t/openstack/build/4535f22b8e8544fc923a67d3ba8a4c20 : SUCCESS in 1h 26m 22s\n- openstack-tox-cover https://zuul.opendev.org/t/openstack/build/da80286f9ebe4410ac7a1fab5691b5cc : FAILURE in 16m 29s\n- openstack-tox-lower-constraints https://zuul.opendev.org/t/openstack/build/251597eb137242ee843b00d31395e222 : FAILURE in 15m 12s\n- openstack-tox-pep8 https://zuul.opendev.org/t/openstack/build/2708713c6c994f2a9c1d759c5d55b443 : FAILURE in 11m 20s\n- openstack-tox-py27 https://zuul.opendev.org/t/openstack/build/7ce2d65e4ab3492f897c8568e940bc09 : FAILURE in 14m 09s\n- openstack-tox-py36 https://zuul.opendev.org/t/openstack/build/127656d007a14a6bb57506d0c758dbd5 : FAILURE in 17m 37s\n- openstack-tox-py37 https://zuul.opendev.org/t/openstack/build/16451a901cb64b7798a74cf85074ed42 : FAILURE in 17m 41s\n- openstack-tox-docs https://zuul.opendev.org/t/openstack/build/1c09df75ad394d9eaf751c553f357a6b : SUCCESS in 12m 22s\n- ironic-tempest-ipa-wholedisk-bios-agent_ipmitool-tinyipa https://zuul.opendev.org/t/openstack/build/15a81009605a40f4a3eeff2c62b96be3 : SUCCESS in 1h 15m 05s (non-voting)\n- devstack-plugin-ceph-tempest https://zuul.opendev.org/t/openstack/build/8cb4880c719d48e9ac7cd19b9e52ba8f : SUCCESS in 1h 12m 03s (non-voting)\n- neutron-grenade-multinode https://zuul.opendev.org/t/openstack/build/ce76daa1732b4950b8923ebce7b79026 : SUCCESS in 1h 10m 46s\n- nova-grenade-multinode https://zuul.opendev.org/t/openstack/build/d1a29adaa1194815ab6bfe47e2b32d46 : SUCCESS in 1h 10m 44s\n- nova-live-migration https://zuul.opendev.org/t/openstack/build/0ee7a97a945f44b4a5634410818df768 : SUCCESS in 55m 14s\n- nova-multi-cell https://zuul.opendev.org/t/openstack/build/c02d95c2e1904247b87503039bcfb577 : SUCCESS in 1h 16m 59s\n- nova-next https://zuul.opendev.org/t/openstack/build/d379cedf38624a4c8e8e8f113b2a3a14 : SUCCESS in 1h 16m 06s\n- nova-tox-functional https://zuul.opendev.org/t/openstack/build/780165afce3144e89b2e2b3a6bc20551 : FAILURE in 10m 12s\n- nova-tox-functional-py36 https://zuul.opendev.org/t/openstack/build/f3a35c89cc1e45f8b2764eb69fe7ad72 : FAILURE in 9m 50s\n- tempest-slow-py3 https://zuul.opendev.org/t/openstack/build/3c6d6331371d46bea27c6bb84022e353 : SUCCESS in 2h 10m 26s\n- grenade-py3 https://zuul.opendev.org/t/openstack/build/cb5d48e8359a427b929e0aef61c72d6a : SUCCESS in 1h 03m 19s\n- tempest-ipv6-only https://zuul.opendev.org/t/openstack/build/796b23eb085b4855b3caf6a5981fe8ff : SUCCESS in 53m 53s","accounts_in_message":[],"_revision_number":2},{"id":"f5d4873042ceb433c485ddc5c27c553b74ca40dc","author":{"_account_id":26515,"name":"Cloudbase Nova Hyper-V CI","email":"nova_hyperv_ci@cloudbasesolutions.com","username":"nova_hyperv_ci"},"date":"2021-04-07 18:45:48.000000000","message":"Patch Set 2:\n\nBuild succeeded. For checking Nova with Ceph, add a comment with run-Cloudbase Nova Ceph Hyper-V CI\n\n- nova http://cloudbase-ci.com/nova/785075/2/iscsi : SUCCESS in 2h 40m 15s","accounts_in_message":[],"_revision_number":2},{"id":"6f08f8566b692ed55fb1607ff00b839d996bb81d","author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"date":"2021-04-07 19:02:25.000000000","message":"Patch Set 2: Workflow-1\n\n(1 comment)","accounts_in_message":[],"_revision_number":2},{"id":"2cdfe85b081e35e2e62312d7c1d01b19d2fb0824","tag":"autogenerated:gerrit:abandon","author":{"_account_id":17685,"name":"Elod Illes","email":"elod.illes@est.tech","username":"elod.illes"},"date":"2023-09-01 17:02:54.000000000","message":"Abandoned\n\nstable/train branch of nova projects\u0027 have been tagged as End of Life. All open patches have to be abandoned in order to be able to delete the branch.","accounts_in_message":[],"_revision_number":2}],"current_revision_number":2,"current_revision":"0743eb227cf6114f00ba2be94dabff6e24ca1f24","revisions":{"b1bf80455c3d0464bab6928377bf5955311bd865":{"kind":"REWORK","_number":1,"created":"2021-04-06 23:10:05.000000000","uploader":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"ref":"refs/changes/75/785075/1","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/nova","ref":"refs/changes/75/785075/1","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/nova refs/changes/75/785075/1 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/nova refs/changes/75/785075/1 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/nova refs/changes/75/785075/1 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/nova refs/changes/75/785075/1"}}},"commit":{"parents":[{"commit":"6cda0f5e31df7ef802c087cacf60974b374b852c","subject":"Add functional test for bug 1837995","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/nova/commit/6cda0f5e31df7ef802c087cacf60974b374b852c"}]}],"author":{"name":"melanie witt","email":"melwittt@gmail.com","date":"2021-01-27 22:49:19.000000000","tz":0},"committer":{"name":"melanie witt","email":"melwittt@gmail.com","date":"2021-04-06 23:09:51.000000000","tz":0},"subject":"Dynamically archive FK related records in archive_deleted_rows","message":"Dynamically archive FK related records in archive_deleted_rows\n\nCurrently, it is possible to \"partially archive\" the database by\nrunning \u0027nova-manage db archive_deleted_rows\u0027 with --max_rows or by\ninterrupting the archive process in any way. When this happens, it is\npossible to have archived a record with a foreign key relationship to a\nparent record (example: \u0027instance_extra\u0027 table record is archived while\nthe \u0027instances\u0027 table record remains).\n\nWhen an instance\u0027s records become \"split\" in this way, any API request\nthat can (1) access the deleted instance and (2) tries to access data\nthat should be in a child table (example: the embedded flavor for an\ninstance) will fail with an OrphanedObjectError and HTTP 500 to the\nuser. Examples of APIs that are affected by this are the tenant usage\nAPIs and listing of deleted instances as admin.\n\nIn the tenant usage example, the API looks at deleted instances to\ncalculate usage over a time period. It pulls deleted and non-deleted\ninstances and does instance.get_flavor() to calculate their usage. The\nflavor data is expected to be present because\nexpecteds_attrs\u003d[\u0027flavor\u0027] is used to do a join with the\n\u0027instance_extra\u0027 table and populate the instance object\u0027s flavor data.\nWhen get_flavor() is called, it tries to access the instance.flavor\nattribute (which hasn\u0027t been populated because the \u0027instance_extra\u0027\nrecord is gone). That triggers a lazy-load of the flavor which loads\nthe instance from the database again with expected_attrs\u003d[\u0027flavor\u0027]\nagain which doesn\u0027t populate instance.flavor (again) because the\n\u0027instance_extra\u0027 record is gone. Then the Instance._load_flavor code\nintentionally orphans the instance record to avoid triggering\nlazy-loads while it attempts to populate instance.flavor,\ninstance.new_flavor, and instance.old_flavor. Finally, another\nlazy-load is triggered (because instance.flavor is still not populated)\nand fails with OrphanedObjectError.\n\nOne way to solve this problem is to make it impossible for\narchive_deleted_records to orphan records that are related by foreign\nkey relationships. The approach is to process parent tables first\n(opposite of today where we process child tables first) and find all of\nthe tables that refer to it by foreign keys, create and collect\ninsert/delete statements for those child records, and then put them all\ntogether in a single database transaction to archive all related\nrecords \"atomically\". The idea is that if anything were to interrupt\nthe transaction (errors or other) it would roll back and keep all the\nrelated records together. Either all or archived or none are archived.\n\nThis changes the logic of the per table archive to discover tables that\nrefer to the table by foreign keys and generates insert/delete query\nstatements to execute in the same database transaction as the table\narchive itself. The extra records archived along with the table are\nadded to the rows_archived result. The existing code for \"archiving\nrecords if instance is deleted\" also has to be removed along with this\nbecause the new logic does the same thing dynamically and makes it\nobsolete. Finally, some assertions in the unit tests need to be changed\nor removed because they were assuming certain types of archiving\nfailures due to foreign key constraint violations that can no longer\noccur with the new dynamic logic for archiving child records.\n\nCloses-Bug: #1837995\n\nChange-Id: Ie653e5ec69d16ae469f1f8171fee85aea754edff\n(cherry picked from commit becb94ae643ab4863daa564783646921b4a2b372)\n(cherry picked from commit 513ed1dd3c60954dc467a64fdfd849a989cae56c)\n(cherry picked from commit ac89b8fbe524f333b8bb8531f5be0a7f03c5289d)\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/nova/commit/b1bf80455c3d0464bab6928377bf5955311bd865"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/nova/commit/b1bf80455c3d0464bab6928377bf5955311bd865"}]},"branch":"refs/heads/stable/train"},"0743eb227cf6114f00ba2be94dabff6e24ca1f24":{"kind":"REWORK","_number":2,"created":"2021-04-07 16:02:04.000000000","uploader":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"ref":"refs/changes/75/785075/2","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/nova","ref":"refs/changes/75/785075/2","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/nova refs/changes/75/785075/2 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/nova refs/changes/75/785075/2 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/nova refs/changes/75/785075/2 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/nova refs/changes/75/785075/2"}}},"commit":{"parents":[{"commit":"6cda0f5e31df7ef802c087cacf60974b374b852c","subject":"Add functional test for bug 1837995","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/nova/commit/6cda0f5e31df7ef802c087cacf60974b374b852c"}]}],"author":{"name":"melanie witt","email":"melwittt@gmail.com","date":"2021-01-27 22:49:19.000000000","tz":0},"committer":{"name":"melanie witt","email":"melwittt@gmail.com","date":"2021-04-07 16:01:47.000000000","tz":0},"subject":"Dynamically archive FK related records in archive_deleted_rows","message":"Dynamically archive FK related records in archive_deleted_rows\n\nCurrently, it is possible to \"partially archive\" the database by\nrunning \u0027nova-manage db archive_deleted_rows\u0027 with --max_rows or by\ninterrupting the archive process in any way. When this happens, it is\npossible to have archived a record with a foreign key relationship to a\nparent record (example: \u0027instance_extra\u0027 table record is archived while\nthe \u0027instances\u0027 table record remains).\n\nWhen an instance\u0027s records become \"split\" in this way, any API request\nthat can (1) access the deleted instance and (2) tries to access data\nthat should be in a child table (example: the embedded flavor for an\ninstance) will fail with an OrphanedObjectError and HTTP 500 to the\nuser. Examples of APIs that are affected by this are the tenant usage\nAPIs and listing of deleted instances as admin.\n\nIn the tenant usage example, the API looks at deleted instances to\ncalculate usage over a time period. It pulls deleted and non-deleted\ninstances and does instance.get_flavor() to calculate their usage. The\nflavor data is expected to be present because\nexpecteds_attrs\u003d[\u0027flavor\u0027] is used to do a join with the\n\u0027instance_extra\u0027 table and populate the instance object\u0027s flavor data.\nWhen get_flavor() is called, it tries to access the instance.flavor\nattribute (which hasn\u0027t been populated because the \u0027instance_extra\u0027\nrecord is gone). That triggers a lazy-load of the flavor which loads\nthe instance from the database again with expected_attrs\u003d[\u0027flavor\u0027]\nagain which doesn\u0027t populate instance.flavor (again) because the\n\u0027instance_extra\u0027 record is gone. Then the Instance._load_flavor code\nintentionally orphans the instance record to avoid triggering\nlazy-loads while it attempts to populate instance.flavor,\ninstance.new_flavor, and instance.old_flavor. Finally, another\nlazy-load is triggered (because instance.flavor is still not populated)\nand fails with OrphanedObjectError.\n\nOne way to solve this problem is to make it impossible for\narchive_deleted_records to orphan records that are related by foreign\nkey relationships. The approach is to process parent tables first\n(opposite of today where we process child tables first) and find all of\nthe tables that refer to it by foreign keys, create and collect\ninsert/delete statements for those child records, and then put them all\ntogether in a single database transaction to archive all related\nrecords \"atomically\". The idea is that if anything were to interrupt\nthe transaction (errors or other) it would roll back and keep all the\nrelated records together. Either all or archived or none are archived.\n\nThis changes the logic of the per table archive to discover tables that\nrefer to the table by foreign keys and generates insert/delete query\nstatements to execute in the same database transaction as the table\narchive itself. The extra records archived along with the table are\nadded to the rows_archived result. The existing code for \"archiving\nrecords if instance is deleted\" also has to be removed along with this\nbecause the new logic does the same thing dynamically and makes it\nobsolete. Finally, some assertions in the unit tests need to be changed\nor removed because they were assuming certain types of archiving\nfailures due to foreign key constraint violations that can no longer\noccur with the new dynamic logic for archiving child records.\n\nCloses-Bug: #1837995\n\nChange-Id: Ie653e5ec69d16ae469f1f8171fee85aea754edff\n(cherry picked from commit becb94ae643ab4863daa564783646921b4a2b372)\n(cherry picked from commit 7b4f4796478941eafa9c0997f7ef03293c442d94)\n(cherry picked from commit 8a858eca55544f25427c3762f14523b1507261ee)\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/nova/commit/0743eb227cf6114f00ba2be94dabff6e24ca1f24"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/nova/commit/0743eb227cf6114f00ba2be94dabff6e24ca1f24"}]},"branch":"refs/heads/stable/train"}},"requirements":[],"submit_records":[],"submit_requirements":[{"name":"Verified","description":"Verified in gate by CI","status":"UNSATISFIED","is_legacy":false,"submittability_expression_result":{"expression":"label:Verified\u003dMAX AND -label:Verified\u003dMIN","fulfilled":false,"status":"FAIL","passing_atoms":[],"failing_atoms":["label:Verified\u003dMAX","label:Verified\u003dMIN"],"atom_explanations":{}}},{"name":"Code-Review","description":"Code reviewed by core reviewer","status":"UNSATISFIED","is_legacy":false,"submittability_expression_result":{"expression":"label:Code-Review\u003dMAX AND -label:Code-Review\u003dMIN","fulfilled":false,"status":"FAIL","passing_atoms":[],"failing_atoms":["label:Code-Review\u003dMAX","label:Code-Review\u003dMIN"],"atom_explanations":{}}},{"name":"Review-Priority","description":"Review Priority","status":"NOT_APPLICABLE","is_legacy":false,"applicability_expression_result":{"fulfilled":false,"status":"FAIL"},"submittability_expression_result":{"expression":"is:true","fulfilled":true,"status":"NOT_EVALUATED","passing_atoms":[],"failing_atoms":[],"atom_explanations":{}}},{"name":"Workflow","description":"Approved for gate by core reviewer","status":"UNSATISFIED","is_legacy":false,"submittability_expression_result":{"expression":"label:Workflow\u003dMAX AND -label:Workflow\u003dMIN","fulfilled":false,"status":"FAIL","passing_atoms":["label:Workflow\u003dMIN"],"failing_atoms":["label:Workflow\u003dMAX"],"atom_explanations":{}}}]}
