Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 281a724

Browse files
committed
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.
1 parent cc87402 commit 281a724

File tree

15 files changed

+747
-656
lines changed

15 files changed

+747
-656
lines changed

src/backend/access/index/genam.c

+42-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.68 2008/04/13 19:18:14 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.69 2008/06/08 22:41:04 tgl Exp $
1212
*
1313
* NOTES
1414
* many of the old access method routines have been turned into
@@ -251,6 +251,47 @@ systable_getnext(SysScanDesc sysscan)
251251
return htup;
252252
}
253253

254+
/*
255+
* systable_recheck_tuple --- recheck visibility of most-recently-fetched tuple
256+
*
257+
* This is useful to test whether an object was deleted while we waited to
258+
* acquire lock on it.
259+
*
260+
* Note: we don't actually *need* the tuple to be passed in, but it's a
261+
* good crosscheck that the caller is interested in the right tuple.
262+
*/
263+
bool
264+
systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup)
265+
{
266+
bool result;
267+
268+
if (sysscan->irel)
269+
{
270+
IndexScanDesc scan = sysscan->iscan;
271+
272+
Assert(tup == &scan->xs_ctup);
273+
Assert(BufferIsValid(scan->xs_cbuf));
274+
/* must hold a buffer lock to call HeapTupleSatisfiesVisibility */
275+
LockBuffer(scan->xs_cbuf, BUFFER_LOCK_SHARE);
276+
result = HeapTupleSatisfiesVisibility(tup, scan->xs_snapshot,
277+
scan->xs_cbuf);
278+
LockBuffer(scan->xs_cbuf, BUFFER_LOCK_UNLOCK);
279+
}
280+
else
281+
{
282+
HeapScanDesc scan = sysscan->scan;
283+
284+
Assert(tup == &scan->rs_ctup);
285+
Assert(BufferIsValid(scan->rs_cbuf));
286+
/* must hold a buffer lock to call HeapTupleSatisfiesVisibility */
287+
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
288+
result = HeapTupleSatisfiesVisibility(tup, scan->rs_snapshot,
289+
scan->rs_cbuf);
290+
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
291+
}
292+
return result;
293+
}
294+
254295
/*
255296
* systable_endscan --- close scan, release resources
256297
*

0 commit comments

Comments
 (0)