Commit bb203c75 authored by Tom Lane's avatar Tom Lane

Come to think of it, DropBuffers() could have the same problem as

ReleaseRelationBuffers --- need to wait if anyone is trying to flush
out that buffer.
parent 6b5d8e14
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.67 1999/11/22 01:19:42 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.68 1999/11/22 02:03:21 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -831,7 +831,7 @@ FlushBuffer(Buffer buffer, bool release) ...@@ -831,7 +831,7 @@ FlushBuffer(Buffer buffer, bool release)
*/ */
if (bufHdr->flags & BM_JUST_DIRTIED) if (bufHdr->flags & BM_JUST_DIRTIED)
{ {
elog(NOTICE, "FlusfBuffer: content of block %u (%s) changed while flushing", elog(NOTICE, "FlushBuffer: content of block %u (%s) changed while flushing",
bufHdr->tag.blockNum, bufHdr->sb_relname); bufHdr->tag.blockNum, bufHdr->sb_relname);
} }
else else
...@@ -1476,9 +1476,8 @@ ReleaseRelationBuffers(Relation rel) ...@@ -1476,9 +1476,8 @@ ReleaseRelationBuffers(Relation rel)
* This function marks all the buffers in the buffer cache for a * This function marks all the buffers in the buffer cache for a
* particular database as clean. This is used when we destroy a * particular database as clean. This is used when we destroy a
* database, to avoid trying to flush data to disk when the directory * database, to avoid trying to flush data to disk when the directory
* tree no longer exists. * tree no longer exists. Implementation is pretty similar to
* * ReleaseRelationBuffers() which is for destroying just one relation.
* This is an exceedingly non-public interface.
* -------------------------------------------------------------------- * --------------------------------------------------------------------
*/ */
void void
...@@ -1491,8 +1490,30 @@ DropBuffers(Oid dbid) ...@@ -1491,8 +1490,30 @@ DropBuffers(Oid dbid)
for (i = 1; i <= NBuffers; i++) for (i = 1; i <= NBuffers; i++)
{ {
buf = &BufferDescriptors[i - 1]; buf = &BufferDescriptors[i - 1];
if ((buf->tag.relId.dbId == dbid) && (buf->flags & BM_DIRTY)) recheck:
buf->flags &= ~BM_DIRTY; if (buf->tag.relId.dbId == dbid)
{
/*
* If there is I/O in progress, better wait till it's done;
* don't want to delete the database out from under someone
* who's just trying to flush the buffer!
*/
if (buf->flags & BM_IO_IN_PROGRESS)
{
WaitIO(buf, BufMgrLock);
/* By now, the buffer very possibly belongs to some other
* DB, so check again before proceeding.
*/
goto recheck;
}
/* Now we can do what we came for */
buf->flags &= ~ ( BM_DIRTY | BM_JUST_DIRTIED);
/*
* The thing should be free, if caller has checked that
* no backends are running in that database.
*/
Assert(buf->flags & BM_FREE);
}
} }
SpinRelease(BufMgrLock); SpinRelease(BufMgrLock);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment