diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2005-11-17 17:42:02 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2005-11-17 17:42:02 +0000 |
commit | c859308aba7edef428994e6de90ff35f35a328c5 (patch) | |
tree | 14940f255a6c69d44a41f1211d6c8787524abd5e /src/backend/storage/buffer/localbuf.c | |
parent | 84bb3876bc6efad2c6b36198d6562797af6b0549 (diff) | |
download | postgresql-c859308aba7edef428994e6de90ff35f35a328c5.tar.gz postgresql-c859308aba7edef428994e6de90ff35f35a328c5.zip |
DropRelFileNodeBuffers failed to fix the state of the lookup hash table
that was added to localbuf.c in 8.1; therefore, applying it to a temp table
left corrupt lookup state in memory. The only case where this had a
significant chance of causing problems was an ON COMMIT DELETE ROWS temp
table; the other possible paths left bogus state that was unlikely to
be used again. Per report from Csaba Nagy.
Diffstat (limited to 'src/backend/storage/buffer/localbuf.c')
-rw-r--r-- | src/backend/storage/buffer/localbuf.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/src/backend/storage/buffer/localbuf.c b/src/backend/storage/buffer/localbuf.c index ca80255e15e..acaf4b9b6e2 100644 --- a/src/backend/storage/buffer/localbuf.c +++ b/src/backend/storage/buffer/localbuf.c @@ -9,7 +9,7 @@ * * * 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 $ * *------------------------------------------------------------------------- */ @@ -242,6 +242,52 @@ WriteLocalBuffer(Buffer buffer, bool release) } /* + * 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) * don't involve local buffers, we delay allocating actual memory for the |