aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/storage/buffer/bufmgr.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 8341a25e055..4d2c869860f 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.197 2005/10/15 02:49:24 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.198 2005/10/27 17:07:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -85,7 +85,8 @@ static volatile BufferDesc *PinCountWaitBuf = NULL;
static bool PinBuffer(volatile BufferDesc *buf);
static void PinBuffer_Locked(volatile BufferDesc *buf);
-static void UnpinBuffer(volatile BufferDesc *buf, bool fixOwner, bool trashOK);
+static void UnpinBuffer(volatile BufferDesc *buf,
+ bool fixOwner, bool normalAccess);
static bool SyncOneBuffer(int buf_id, bool skip_pinned);
static void WaitIO(volatile BufferDesc *buf);
static bool StartBufferIO(volatile BufferDesc *buf, bool forInput);
@@ -780,12 +781,18 @@ PinBuffer_Locked(volatile BufferDesc *buf)
* This should be applied only to shared buffers, never local ones.
*
* Most but not all callers want CurrentResourceOwner to be adjusted.
+ * Those that don't should pass fixOwner = FALSE.
+ *
+ * normalAccess indicates that we are finishing a "normal" page access,
+ * that is, one requested by something outside the buffer subsystem.
+ * Passing FALSE means it's an internal access that should not update the
+ * buffer's usage count nor cause a change in the freelist.
*
* If we are releasing a buffer during VACUUM, and it's not been otherwise
- * used recently, and trashOK is true, send the buffer to the freelist.
+ * used recently, and normalAccess is true, we send the buffer to the freelist.
*/
static void
-UnpinBuffer(volatile BufferDesc *buf, bool fixOwner, bool trashOK)
+UnpinBuffer(volatile BufferDesc *buf, bool fixOwner, bool normalAccess)
{
int b = buf->buf_id;
@@ -797,7 +804,7 @@ UnpinBuffer(volatile BufferDesc *buf, bool fixOwner, bool trashOK)
PrivateRefCount[b]--;
if (PrivateRefCount[b] == 0)
{
- bool trash_buffer = false;
+ bool immed_free_buffer = false;
/* I'd better not still hold any locks on the buffer */
Assert(!LWLockHeldByMe(buf->content_lock));
@@ -810,16 +817,21 @@ UnpinBuffer(volatile BufferDesc *buf, bool fixOwner, bool trashOK)
Assert(buf->refcount > 0);
buf->refcount--;
- /* Mark the buffer recently used, unless we are in VACUUM */
- if (!strategy_hint_vacuum)
+ /* Update buffer usage info, unless this is an internal access */
+ if (normalAccess)
{
- if (buf->usage_count < BM_MAX_USAGE_COUNT)
- buf->usage_count++;
+ if (!strategy_hint_vacuum)
+ {
+ if (buf->usage_count < BM_MAX_USAGE_COUNT)
+ buf->usage_count++;
+ }
+ else
+ {
+ /* VACUUM accesses don't bump usage count, instead... */
+ if (buf->refcount == 0 && buf->usage_count == 0)
+ immed_free_buffer = true;
+ }
}
- else if (trashOK &&
- buf->refcount == 0 &&
- buf->usage_count == 0)
- trash_buffer = true;
if ((buf->flags & BM_PIN_COUNT_WAITER) &&
buf->refcount == 1)
@@ -839,7 +851,7 @@ UnpinBuffer(volatile BufferDesc *buf, bool fixOwner, bool trashOK)
* freelist for near-term reuse. We put it at the tail so that it
* won't be used before any invalid buffers that may exist.
*/
- if (trash_buffer)
+ if (immed_free_buffer)
StrategyFreeBuffer(buf, false);
}
}