On 2013-07-16 09:50:07 -0400, Noah Misch wrote:
> With "\c", in general, you may end up executing commands under the new session
> before the old backend has finished exiting. For this test case specifically,
> the two backends' attempts to drop table "t" regularly overlap. The old
> backend would drop it within RemoveTempRelationsCallback(), and the new
> backend would cascade from "rowtype" to drop it. findDependentObjects() deals
> with concurrent deletion attempts by acquiring a lock on each object it will
> delete, then calling systable_recheck_tuple() to determine whether another
> deleter was successful while the current backend was waiting for the lock.
> systable_recheck_tuple() uses the scan snapshot, which really only works if
> that snapshot is SnapshotNow or some other that changes its decision in
> response to concurrent transaction commits. The switch to MVCC snapshots left
> this mutual exclusion protocol ineffective.
Nice catch.
I wonder though, isn't that code unsafe in other ways as well? What if
the pg_depend entry was rewritten inbetween? Consider somebody doing
something like REASSIGN OWNED concurrently with a DROP. The DROP
possibly will cascade to an entry which changed the owner already. And
the recheck will then report that the object doesn't exist anymore and
abort since it does a simple HeapTupleSatisfiesVisibility() and doesn't
follow the ctid chain if the tuple has been updated...
Greetings,
Andres Freund
-- Andres Freund http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training &
Services