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

Commit bb203c7

Browse files
committed
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.
1 parent 6b5d8e1 commit bb203c7

File tree

1 file changed

+28
-7
lines changed

1 file changed

+28
-7
lines changed

src/backend/storage/buffer/bufmgr.c

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.67 1999/11/22 01:19:42 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.68 1999/11/22 02:03:21 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -831,7 +831,7 @@ FlushBuffer(Buffer buffer, bool release)
831831
*/
832832
if (bufHdr->flags & BM_JUST_DIRTIED)
833833
{
834-
elog(NOTICE, "FlusfBuffer: content of block %u (%s) changed while flushing",
834+
elog(NOTICE, "FlushBuffer: content of block %u (%s) changed while flushing",
835835
bufHdr->tag.blockNum, bufHdr->sb_relname);
836836
}
837837
else
@@ -1476,9 +1476,8 @@ ReleaseRelationBuffers(Relation rel)
14761476
* This function marks all the buffers in the buffer cache for a
14771477
* particular database as clean. This is used when we destroy a
14781478
* database, to avoid trying to flush data to disk when the directory
1479-
* tree no longer exists.
1480-
*
1481-
* This is an exceedingly non-public interface.
1479+
* tree no longer exists. Implementation is pretty similar to
1480+
* ReleaseRelationBuffers() which is for destroying just one relation.
14821481
* --------------------------------------------------------------------
14831482
*/
14841483
void
@@ -1491,8 +1490,30 @@ DropBuffers(Oid dbid)
14911490
for (i = 1; i <= NBuffers; i++)
14921491
{
14931492
buf = &BufferDescriptors[i - 1];
1494-
if ((buf->tag.relId.dbId == dbid) && (buf->flags & BM_DIRTY))
1495-
buf->flags &= ~BM_DIRTY;
1493+
recheck:
1494+
if (buf->tag.relId.dbId == dbid)
1495+
{
1496+
/*
1497+
* If there is I/O in progress, better wait till it's done;
1498+
* don't want to delete the database out from under someone
1499+
* who's just trying to flush the buffer!
1500+
*/
1501+
if (buf->flags & BM_IO_IN_PROGRESS)
1502+
{
1503+
WaitIO(buf, BufMgrLock);
1504+
/* By now, the buffer very possibly belongs to some other
1505+
* DB, so check again before proceeding.
1506+
*/
1507+
goto recheck;
1508+
}
1509+
/* Now we can do what we came for */
1510+
buf->flags &= ~ ( BM_DIRTY | BM_JUST_DIRTIED);
1511+
/*
1512+
* The thing should be free, if caller has checked that
1513+
* no backends are running in that database.
1514+
*/
1515+
Assert(buf->flags & BM_FREE);
1516+
}
14961517
}
14971518
SpinRelease(BufMgrLock);
14981519
}

0 commit comments

Comments
 (0)