Hello hackers find_all_inheritors() with NoLock doesn't lock anything below the given relation, but it still calls find_inheritance_children() on every relation it found, which starts with has_subclass(), and that errors out if the pg_class row is gone:
ERROR: cache lookup failed for relation 16398 This needs a sub-partitioned table below the first level (root -> p1 -> p2, we hold a lock on root only, DROP TABLE p2 only locks p1 and p2) to be dropped after it was found, but before it is expanded. There are 5 callers using NoLock: VACUUM, ANALYZE, REPACK/CLUSTER and LOCK TABLE on a partitioned table, and pg_get_publication_tables(). Dropping old sub-partitions while something vacuums the root seems like a realistic way to hit it, the window grows with the number of partitions. The attached patch makes find_inheritance_children_extended() return an empty list if the relation is gone, instead of erroring out. It also adds an injection point before the pg_inherits scan, and a TAP test which fails without the fix. Found while working on the REPACK foreign partition warning patch [1]. [1]: https://www.postgresql.org/message-id/CAN4CZFM1g0oDs5Ee_5OWzf3YF-01rQDAak6ut_OWxEJJ%2BUmnXA%40mail.gmail.com
v1-0001-Fix-find_all_inheritors-with-NoLock-against-concu.patch
Description: Binary data
