88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.197 2005/10/15 02:49:24 momjian Exp $
11+ * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.198 2005/10/27 17:07:58 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -85,7 +85,8 @@ static volatile BufferDesc *PinCountWaitBuf = NULL;
8585
8686static bool PinBuffer (volatile BufferDesc * buf );
8787static void PinBuffer_Locked (volatile BufferDesc * buf );
88- static void UnpinBuffer (volatile BufferDesc * buf ,bool fixOwner ,bool trashOK );
88+ static void UnpinBuffer (volatile BufferDesc * buf ,
89+ bool fixOwner ,bool normalAccess );
8990static bool SyncOneBuffer (int buf_id ,bool skip_pinned );
9091static void WaitIO (volatile BufferDesc * buf );
9192static bool StartBufferIO (volatile BufferDesc * buf ,bool forInput );
@@ -780,12 +781,18 @@ PinBuffer_Locked(volatile BufferDesc *buf)
780781 * This should be applied only to shared buffers, never local ones.
781782 *
782783 * Most but not all callers want CurrentResourceOwner to be adjusted.
784+ * Those that don't should pass fixOwner = FALSE.
785+ *
786+ * normalAccess indicates that we are finishing a "normal" page access,
787+ * that is, one requested by something outside the buffer subsystem.
788+ * Passing FALSE means it's an internal access that should not update the
789+ * buffer's usage count nor cause a change in the freelist.
783790 *
784791 * If we are releasing a buffer during VACUUM, and it's not been otherwise
785- * used recently, andtrashOK is true, send the buffer to the freelist.
792+ * used recently, andnormalAccess is true, we send the buffer to the freelist.
786793 */
787794static void
788- UnpinBuffer (volatile BufferDesc * buf ,bool fixOwner ,bool trashOK )
795+ UnpinBuffer (volatile BufferDesc * buf ,bool fixOwner ,bool normalAccess )
789796{
790797int b = buf -> buf_id ;
791798
@@ -797,7 +804,7 @@ UnpinBuffer(volatile BufferDesc *buf, bool fixOwner, bool trashOK)
797804PrivateRefCount [b ]-- ;
798805if (PrivateRefCount [b ]== 0 )
799806{
800- bool trash_buffer = false;
807+ bool immed_free_buffer = false;
801808
802809/* I'd better not still hold any locks on the buffer */
803810Assert (!LWLockHeldByMe (buf -> content_lock ));
@@ -810,16 +817,21 @@ UnpinBuffer(volatile BufferDesc *buf, bool fixOwner, bool trashOK)
810817Assert (buf -> refcount > 0 );
811818buf -> refcount -- ;
812819
813- /*Mark the bufferrecently used , unlesswe are in VACUUM */
814- if (! strategy_hint_vacuum )
820+ /*Update bufferusage info , unlessthis is an internal access */
821+ if (normalAccess )
815822{
816- if (buf -> usage_count < BM_MAX_USAGE_COUNT )
817- buf -> usage_count ++ ;
823+ if (!strategy_hint_vacuum )
824+ {
825+ if (buf -> usage_count < BM_MAX_USAGE_COUNT )
826+ buf -> usage_count ++ ;
827+ }
828+ else
829+ {
830+ /* VACUUM accesses don't bump usage count, instead... */
831+ if (buf -> refcount == 0 && buf -> usage_count == 0 )
832+ immed_free_buffer = true;
833+ }
818834}
819- else if (trashOK &&
820- buf -> refcount == 0 &&
821- buf -> usage_count == 0 )
822- trash_buffer = true;
823835
824836if ((buf -> flags & BM_PIN_COUNT_WAITER )&&
825837buf -> refcount == 1 )
@@ -839,7 +851,7 @@ UnpinBuffer(volatile BufferDesc *buf, bool fixOwner, bool trashOK)
839851 * freelist for near-term reuse. We put it at the tail so that it
840852 * won't be used before any invalid buffers that may exist.
841853 */
842- if (trash_buffer )
854+ if (immed_free_buffer )
843855StrategyFreeBuffer (buf , false);
844856}
845857}