1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-07 19:06:32 +03:00

Rewrite DROP's dependency traversal algorithm into an honest two-pass

algorithm, replacing the original intention of a one-pass search, which
had been hacked up over time to be partially two-pass in hopes of handling
various corner cases better.  It still wasn't quite there, especially as
regards emitting unwanted NOTICE messages.  More importantly, this approach
lets us fix a number of open bugs concerning concurrent DROP scenarios,
because we can take locks during the first pass and avoid traversing to
dependent objects that were just deleted by someone else.

There is more that can be done here, but I'll go ahead and commit the
base patch before working on the options.
This commit is contained in:
Tom Lane
2008-06-08 22:41:04 +00:00
parent cc87402d6e
commit 281a724d5c
15 changed files with 757 additions and 666 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.68 2008/04/13 19:18:14 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.69 2008/06/08 22:41:04 tgl Exp $
*
* NOTES
* many of the old access method routines have been turned into
@@ -251,6 +251,47 @@ systable_getnext(SysScanDesc sysscan)
return htup;
}
/*
* systable_recheck_tuple --- recheck visibility of most-recently-fetched tuple
*
* This is useful to test whether an object was deleted while we waited to
* acquire lock on it.
*
* Note: we don't actually *need* the tuple to be passed in, but it's a
* good crosscheck that the caller is interested in the right tuple.
*/
bool
systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup)
{
bool result;
if (sysscan->irel)
{
IndexScanDesc scan = sysscan->iscan;
Assert(tup == &scan->xs_ctup);
Assert(BufferIsValid(scan->xs_cbuf));
/* must hold a buffer lock to call HeapTupleSatisfiesVisibility */
LockBuffer(scan->xs_cbuf, BUFFER_LOCK_SHARE);
result = HeapTupleSatisfiesVisibility(tup, scan->xs_snapshot,
scan->xs_cbuf);
LockBuffer(scan->xs_cbuf, BUFFER_LOCK_UNLOCK);
}
else
{
HeapScanDesc scan = sysscan->scan;
Assert(tup == &scan->rs_ctup);
Assert(BufferIsValid(scan->rs_cbuf));
/* must hold a buffer lock to call HeapTupleSatisfiesVisibility */
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
result = HeapTupleSatisfiesVisibility(tup, scan->rs_snapshot,
scan->rs_cbuf);
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
}
return result;
}
/*
* systable_endscan --- close scan, release resources
*