*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.198 2005/10/27 17:07:58 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.199 2005/11/17 17:42:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
BlockNumber firstDelBlock)
{
int i;
- volatile BufferDesc *bufHdr;
if (istemp)
{
- for (i = 0; i < NLocBuffer; i++)
- {
- bufHdr = &LocalBufferDescriptors[i];
- if (RelFileNodeEquals(bufHdr->tag.rnode, rnode) &&
- bufHdr->tag.blockNum >= firstDelBlock)
- {
- if (LocalRefCount[i] != 0)
- elog(ERROR, "block %u of %u/%u/%u is still referenced (local %u)",
- bufHdr->tag.blockNum,
- bufHdr->tag.rnode.spcNode,
- bufHdr->tag.rnode.dbNode,
- bufHdr->tag.rnode.relNode,
- LocalRefCount[i]);
- CLEAR_BUFFERTAG(bufHdr->tag);
- bufHdr->flags = 0;
- bufHdr->usage_count = 0;
- }
- }
+ DropRelFileNodeLocalBuffers(rnode, firstDelBlock);
return;
}
for (i = 0; i < NBuffers; i++)
{
- bufHdr = &BufferDescriptors[i];
+ volatile BufferDesc *bufHdr = &BufferDescriptors[i];
+
LockBufHdr(bufHdr);
if (RelFileNodeEquals(bufHdr->tag.rnode, rnode) &&
bufHdr->tag.blockNum >= firstDelBlock)
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.70 2005/10/15 02:49:25 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.71 2005/11/17 17:42:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
}
}
+/*
+ * DropRelFileNodeLocalBuffers
+ * This function removes from the buffer pool all the pages of the
+ * specified relation that have block numbers >= firstDelBlock.
+ * (In particular, with firstDelBlock = 0, all pages are removed.)
+ * Dirty pages are simply dropped, without bothering to write them
+ * out first. Therefore, this is NOT rollback-able, and so should be
+ * used only with extreme caution!
+ *
+ * See DropRelFileNodeBuffers in bufmgr.c for more notes.
+ */
+void
+DropRelFileNodeLocalBuffers(RelFileNode rnode, BlockNumber firstDelBlock)
+{
+ int i;
+
+ for (i = 0; i < NLocBuffer; i++)
+ {
+ BufferDesc *bufHdr = &LocalBufferDescriptors[i];
+ LocalBufferLookupEnt *hresult;
+
+ if ((bufHdr->flags & BM_TAG_VALID) &&
+ RelFileNodeEquals(bufHdr->tag.rnode, rnode) &&
+ bufHdr->tag.blockNum >= firstDelBlock)
+ {
+ if (LocalRefCount[i] != 0)
+ elog(ERROR, "block %u of %u/%u/%u is still referenced (local %u)",
+ bufHdr->tag.blockNum,
+ bufHdr->tag.rnode.spcNode,
+ bufHdr->tag.rnode.dbNode,
+ bufHdr->tag.rnode.relNode,
+ LocalRefCount[i]);
+ /* Remove entry from hashtable */
+ hresult = (LocalBufferLookupEnt *)
+ hash_search(LocalBufHash, (void *) &bufHdr->tag,
+ HASH_REMOVE, NULL);
+ if (!hresult) /* shouldn't happen */
+ elog(ERROR, "local buffer hash table corrupted");
+ /* Mark buffer invalid */
+ CLEAR_BUFFERTAG(bufHdr->tag);
+ bufHdr->flags = 0;
+ bufHdr->usage_count = 0;
+ }
+ }
+}
+
/*
* InitLocalBuffers -
* init the local buffer cache. Since most queries (esp. multi-user ones)
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/storage/buf_internals.h,v 1.81 2005/10/15 02:49:46 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/storage/buf_internals.h,v 1.82 2005/11/17 17:42:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern BufferDesc *LocalBufferAlloc(Relation reln, BlockNumber blockNum,
bool *foundPtr);
extern void WriteLocalBuffer(Buffer buffer, bool release);
+extern void DropRelFileNodeLocalBuffers(RelFileNode rnode,
+ BlockNumber firstDelBlock);
extern void AtEOXact_LocalBuffers(bool isCommit);
#endif /* BUFMGR_INTERNALS_H */