On Mon, 2007-03-12 at 09:14 +0000, Simon Riggs wrote:
> On Mon, 2007-03-12 at 16:21 +0900, ITAGAKI Takahiro wrote:

> > With the default
> > value of scan_recycle_buffers(=0), VACUUM seems to use all of buffers in 
> > pool,
> > just like existing sequential scans. Is this intended?
> 
> Yes, but its not very useful for testing to have done that. I'll do
> another version within the hour that sets N=0 (only) back to current
> behaviour for VACUUM.

New test version enclosed, where scan_recycle_buffers = 0 doesn't change
existing VACUUM behaviour.

-- 
  Simon Riggs             
  EnterpriseDB   http://www.enterprisedb.com

? .swo
? .swp
? GNUmakefile
? RUIP-Oct12.patch
? UIP-datetime.patch
? WAL_notes.txt
? autovac.patch
? backup_minor_changes.patch
? backup_single_transaction.patch
? backup_typo.patch
? bufmgr_cyclic_reuse.v1.patch
? bufmgr_cyclic_reuse.v2.patch
? bufmgr_cyclic_reuse.v3.patch
? c2
? cache_option.sql
? cacheinval.v1.patch
? check
? check2
? checl
? commit_nowait.wip1.patch
? commit_nowait.wip2.patch
? commit_options.wip.v1.patch
? commitsiblings.v1.patch
? config.log
? config.status
? copy_noWAL.patch
? copy_noWAL2.patch
? copy_nowal.v1.patch
? copy_nowal.v2.patch
? copy_nowal_prep.sql
? copy_nowal_test.sql
? crc
? d.out
? datatype_frequency.sql
? dbtValidate.sql
? ddl_caveats.patch
? deadlock.patch
? edbDataValidation.sql
? error.sql
? executestricttest
? explain_analyze_timer.v1.patch
? f.sql
? faq.patch
? faq_tab.patch
? fast_cluster.v1.patch
? fast_cluster.v2.patch
? fastcopytest.sql
? funcs
? heap_diag_funcs.v1.patch
? heap_page_func.v1.patch
? hot
? iub_doc.patch
? iubackup.patch
? keepcache.patch
? last_restart_point.v1.patch
? last_restart_point.v2.patch
? log_autovacuum.v1.patch
? log_autovacuum.v2.patch
? log_lock_waits.v1.patch
? logfile
? makefile.custom
? mi
? mj.sql
? mj_circular.v1.patch
? mj_circular.v2.patch
? mj_circular.v3.patch
? mk.out
? mk.tmp
? mki.out
? mkinfo
? mkt.tmp
? mlog
? notintransblock.patch
? num_commits++
? on.sql
? perf_doc.v1.patch
? pg_dump_analyze.v1.patch
? pg_dump_analyze.v1a.patch
? pg_standby.v2.tar
? pg_standby.v3.tar
? pg_standby.v4.tar
? pg_standby.v5.tar
? pg_standby.v6.tar
? pgbenchValidate.sql
? pgre.tar
? pgs.tar
? pgtrace_idle.REL8_3-20070104.v1.patch
? pgtrace_newprobes.REL8_3-20070104.v1.patch
? pgtrace_newprobes.v2.patch
? pitr_cleanup.patch
? portals_per_user.v1.patch
? ps.txt
? raw_page_funcs.v1.patch
? raw_page_funcs.v2.patch
? relationkeepcache.patch
? relopt
? restartablerecovery_docs.patch
? ri_initial_check.sql
? scan_recycle_buffers.v1.patch
? scan_recycle_buffers.v2.patch
? scan_recycle_buffers.v3.patch
? sel.patch
? singletransdocpatch.patch
? sss
? table_options.patch
? test_warm_standby.tar
? testcrc
? toast_options.sql
? toast_relopts.pgsql.v2.patch
? toast_relopts.v1.patch
? toast_tuning_ideas.patch
? toast_tuple_threshold_fixed.patch
? toastcache.patch
? trace_wal_flush.v1.patch
? tracedocs.patch
? transaction_guarantee.v1.patch
? transaction_guarantee.v2.patch
? transaction_guarantee.v3.patch
? transaction_guarantee.v4.patch
? transaction_guarantee.v5.patch
? transaction_guarantee.v6.patch
? uip_both.patch
? unlink_pg_internal_at_startup.patch
? vac_full_reindex.v1.patch
? vac_hint.v1.patch
? vac_hint.v2.patch
? vacstrategy.v1.patch
? vacstrategy.v2.patch
? vacstrategy_simple.v1.patch
? wal_checksum.v1.patch
? wal_checksum.v2.patch
? wrap_limit.patch
? xlog_clog_truncate.patch
? xlog_relcache.patch
? xlogswitchtuning.patch
? xlogswitchtuning2.patch
? xlogviewer.tar
? contrib/pg_relation_extend
? contrib/pgbench/.runtest.sh.swp
? contrib/pgbench/tpc_b.sql
? contrib/pgbench/truckin.pgb
? contrib/pgstattuple/pgstatheap.c
? doc/src/sgml/check
? doc/src/sgml/trace.sgml
? src/Makefile.global
? src/backend/postgres
? src/backend/access/common/rawpage.c
? src/backend/access/nbtree/nbttuple.c
? src/backend/catalog/.catalog.c.swp
? src/backend/catalog/postgres.bki
? src/backend/catalog/postgres.description
? src/backend/catalog/postgres.shdescription
? src/backend/commands/.tablespace.c.swp
? src/backend/postmaster/walwriter.c
? src/backend/storage/lmgr/.deadlock.c.swp
? src/backend/utils/mb/conversion_procs/conversion_create.sql
? src/backend/utils/mb/conversion_procs/ascii_and_mic/libascii_and_mic.so.0.0
? src/backend/utils/mb/conversion_procs/cyrillic_and_mic/libcyrillic_and_mic.so.0.0
? src/backend/utils/mb/conversion_procs/euc_cn_and_mic/libeuc_cn_and_mic.so.0.0
? src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/libeuc_jp_and_sjis.so.0.0
? src/backend/utils/mb/conversion_procs/euc_kr_and_mic/libeuc_kr_and_mic.so.0.0
? src/backend/utils/mb/conversion_procs/euc_tw_and_big5/libeuc_tw_and_big5.so.0.0
? src/backend/utils/mb/conversion_procs/latin2_and_win1250/liblatin2_and_win1250.so.0.0
? src/backend/utils/mb/conversion_procs/latin_and_mic/liblatin_and_mic.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_ascii/libutf8_and_ascii.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_big5/libutf8_and_big5.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_cyrillic/libutf8_and_cyrillic.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_euc_cn/libutf8_and_euc_cn.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_euc_jp/libutf8_and_euc_jp.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_euc_kr/libutf8_and_euc_kr.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_euc_tw/libutf8_and_euc_tw.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_gb18030/libutf8_and_gb18030.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_gbk/libutf8_and_gbk.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_iso8859/libutf8_and_iso8859.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/libutf8_and_iso8859_1.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_johab/libutf8_and_johab.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_sjis/libutf8_and_sjis.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_uhc/libutf8_and_uhc.so.0.0
? src/backend/utils/mb/conversion_procs/utf8_and_win/libutf8_and_win.so.0.0
? src/backend/utils/sort/tuplestore_mod.c
? src/bin/initdb/initdb
? src/bin/ipcclean/ipcclean
? src/bin/pg_config/pg_config
? src/bin/pg_controldata/pg_controldata
? src/bin/pg_ctl/pg_ctl
? src/bin/pg_dump/pg_dump
? src/bin/pg_dump/pg_dumpall
? src/bin/pg_dump/pg_restore
? src/bin/pg_resetxlog/pg_resetxlog
? src/bin/psql/psql
? src/bin/scripts/clusterdb
? src/bin/scripts/createdb
? src/bin/scripts/createlang
? src/bin/scripts/createuser
? src/bin/scripts/dropdb
? src/bin/scripts/droplang
? src/bin/scripts/dropuser
? src/bin/scripts/reindexdb
? src/bin/scripts/vacuumdb
? src/include/pg_config.h
? src/include/stamp-h
? src/include/access/rawpage.h
? src/include/postmaster/walwriter.h
? src/interfaces/ecpg/compatlib/libecpg_compat.so.2.2
? src/interfaces/ecpg/compatlib/libecpg_compat.so.2.3
? src/interfaces/ecpg/ecpglib/libecpg.so.5.2
? src/interfaces/ecpg/ecpglib/libecpg.so.5.3
? src/interfaces/ecpg/include/ecpg_config.h
? src/interfaces/ecpg/pgtypeslib/libpgtypes.so.2.2
? src/interfaces/ecpg/pgtypeslib/libpgtypes.so.2.3
? src/interfaces/ecpg/preproc/ecpg
? src/interfaces/ecpg/test/complex/test1
? src/interfaces/ecpg/test/complex/test1.c
? src/interfaces/ecpg/test/complex/test2
? src/interfaces/ecpg/test/complex/test2.c
? src/interfaces/ecpg/test/complex/test3
? src/interfaces/ecpg/test/complex/test3.c
? src/interfaces/libpq/exports.list
? src/interfaces/libpq/libpq.so.5.0
? src/interfaces/libpq/libpq.so.5.1
? src/pl/plpgsql/src/libplpgsql.so.1.0
? src/port/pg_config_paths.h
? src/test/regress/libregress.so.0.0
? src/test/regress/pg_regress
? src/test/regress/results
? src/test/regress/testtablespace
? src/test/regress/expected/btree_insert.out
? src/test/regress/expected/btree_misc.out
? src/test/regress/expected/btree_search.out
? src/test/regress/expected/btree_unique.out
? src/test/regress/expected/btree_vacuum.out
? src/test/regress/expected/constraints.out
? src/test/regress/expected/copy.out
? src/test/regress/expected/create_function_1.out
? src/test/regress/expected/create_function_2.out
? src/test/regress/expected/largeobject.out
? src/test/regress/expected/largeobject_1.out
? src/test/regress/expected/misc.out
? src/test/regress/expected/tablespace.out
? src/test/regress/sql/btree_insert.sql
? src/test/regress/sql/btree_misc.sql
? src/test/regress/sql/btree_search.sql
? src/test/regress/sql/btree_unique.sql
? src/test/regress/sql/btree_vacuum.sql
? src/test/regress/sql/constraints.sql
? src/test/regress/sql/copy.sql
? src/test/regress/sql/create_function_1.sql
? src/test/regress/sql/create_function_2.sql
? src/test/regress/sql/largeobject.sql
? src/test/regress/sql/misc.sql
? src/test/regress/sql/tablespace.sql
? src/timezone/zic
Index: contrib/pgstattuple/Makefile
===================================================================
RCS file: /projects/cvsroot/pgsql/contrib/pgstattuple/Makefile,v
retrieving revision 1.7
diff -c -r1.7 Makefile
*** contrib/pgstattuple/Makefile	19 Oct 2006 17:40:03 -0000	1.7
--- contrib/pgstattuple/Makefile	12 Mar 2007 10:07:28 -0000
***************
*** 7,13 ****
  #-------------------------------------------------------------------------
  
  MODULE_big	= pgstattuple
! OBJS		= pgstattuple.o pgstatindex.o
  DOCS		= README.pgstattuple README.pgstattuple.euc_jp
  DATA_built	= pgstattuple.sql
  DATA      	= uninstall_pgstattuple.sql
--- 7,13 ----
  #-------------------------------------------------------------------------
  
  MODULE_big	= pgstattuple
! OBJS		= pgstattuple.o pgstatindex.o pgstatheap.o
  DOCS		= README.pgstattuple README.pgstattuple.euc_jp
  DATA_built	= pgstattuple.sql
  DATA      	= uninstall_pgstattuple.sql
Index: contrib/pgstattuple/pgstattuple.sql.in
===================================================================
RCS file: /projects/cvsroot/pgsql/contrib/pgstattuple/pgstattuple.sql.in,v
retrieving revision 1.12
diff -c -r1.12 pgstattuple.sql.in
*** contrib/pgstattuple/pgstattuple.sql.in	4 Sep 2006 02:03:04 -0000	1.12
--- contrib/pgstattuple/pgstattuple.sql.in	12 Mar 2007 10:07:28 -0000
***************
*** 107,109 ****
--- 107,118 ----
  RETURNS int
  AS 'MODULE_PATHNAME', 'pg_relpages'
  LANGUAGE 'C' STRICT;
+ 
+ --
+ -- heap_block_get_raw_page()
+ --
+ CREATE OR REPLACE FUNCTION heap_block_get_raw_page(text, int4)
+ RETURNS bytea
+ AS 'MODULE_PATHNAME', 'heap_block_get_raw_page'
+ LANGUAGE 'C' STRICT;
+ 
Index: src/backend/commands/copy.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/copy.c,v
retrieving revision 1.277
diff -c -r1.277 copy.c
*** src/backend/commands/copy.c	3 Mar 2007 19:32:54 -0000	1.277
--- src/backend/commands/copy.c	12 Mar 2007 10:07:46 -0000
***************
*** 1865,1870 ****
--- 1865,1872 ----
  		&& !XLogArchivingActive())
  		use_wal = false;
  
+ 	StrategyHintRecycleBuffers(NScanRecycleBuffers);
+ 
  	/* Initialize state variables */
  	cstate->fe_eof = false;
  	cstate->eol_type = EOL_UNKNOWN;
***************
*** 2115,2120 ****
--- 2117,2124 ----
  		}
  	}
  
+ 	StrategyHintRecycleBuffers(0);
+ 
  	/* 
  	 * If we skipped writing WAL for heaps, then we need to sync
  	 */
Index: src/backend/executor/nodeSeqscan.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/executor/nodeSeqscan.c,v
retrieving revision 1.63
diff -c -r1.63 nodeSeqscan.c
*** src/backend/executor/nodeSeqscan.c	5 Jan 2007 22:19:28 -0000	1.63
--- src/backend/executor/nodeSeqscan.c	12 Mar 2007 10:07:46 -0000
***************
*** 24,29 ****
--- 24,30 ----
   */
  #include "postgres.h"
  
+ #include "miscadmin.h"
  #include "access/heapam.h"
  #include "executor/execdebug.h"
  #include "executor/nodeSeqscan.h"
***************
*** 154,159 ****
--- 155,166 ----
  									 estate->es_snapshot,
  									 0,
  									 NULL);
+ 	/*
+ 	 * For scans larger than shared buffer cache enable
+ 	 * buffer recycling, if the user has requested it
+ 	 */
+ 	if (currentScanDesc->rs_nblocks > NBuffers && NScanRecycleBuffers > 0)
+ 		StrategyHintRecycleBuffers(NScanRecycleBuffers);
  
  	node->ss_currentRelation = currentRelation;
  	node->ss_currentScanDesc = currentScanDesc;
***************
*** 272,277 ****
--- 279,286 ----
  	 * close the heap relation.
  	 */
  	ExecCloseScanRelation(relation);
+ 
+ 	StrategyHintRecycleBuffers(0);
  }
  
  /* ----------------------------------------------------------------
Index: src/backend/storage/buffer/bufmgr.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v
retrieving revision 1.215
diff -c -r1.215 bufmgr.c
*** src/backend/storage/buffer/bufmgr.c	1 Feb 2007 19:10:27 -0000	1.215
--- src/backend/storage/buffer/bufmgr.c	12 Mar 2007 10:07:56 -0000
***************
*** 320,325 ****
--- 320,326 ----
  	int			buf_id;
  	volatile BufferDesc *buf;
  	bool		valid;
+ 	bool		lock_held = false;
  
  	/* create a tag so we can lookup the buffer */
  	INIT_BUFFERTAG(newTag, reln, blockNum);
***************
*** 384,390 ****
  		 * it would be bad to hold the spinlock while possibly waking up other
  		 * processes.
  		 */
! 		buf = StrategyGetBuffer();
  
  		Assert(buf->refcount == 0);
  
--- 385,391 ----
  		 * it would be bad to hold the spinlock while possibly waking up other
  		 * processes.
  		 */
! 		buf = StrategyGetBuffer(&lock_held);
  
  		Assert(buf->refcount == 0);
  
***************
*** 395,401 ****
  		PinBuffer_Locked(buf);
  
  		/* Now it's safe to release the freelist lock */
! 		LWLockRelease(BufFreelistLock);
  
  		/*
  		 * If the buffer was dirty, try to write it out.  There is a race
--- 396,403 ----
  		PinBuffer_Locked(buf);
  
  		/* Now it's safe to release the freelist lock */
! 		if (lock_held)
! 			LWLockRelease(BufFreelistLock);
  
  		/*
  		 * If the buffer was dirty, try to write it out.  There is a race
***************
*** 907,913 ****
  			else
  			{
  				/* VACUUM accesses don't bump usage count, instead... */
! 				if (buf->refcount == 0 && buf->usage_count == 0)
  					immed_free_buffer = true;
  			}
  		}
--- 909,916 ----
  			else
  			{
  				/* VACUUM accesses don't bump usage count, instead... */
! 				if (buf->refcount == 0 && buf->usage_count == 0 && 
! 					!strategy_hint_recycle)
  					immed_free_buffer = true;
  			}
  		}
Index: src/backend/storage/buffer/freelist.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/storage/buffer/freelist.c,v
retrieving revision 1.58
diff -c -r1.58 freelist.c
*** src/backend/storage/buffer/freelist.c	5 Jan 2007 22:19:37 -0000	1.58
--- src/backend/storage/buffer/freelist.c	12 Mar 2007 10:07:56 -0000
***************
*** 39,47 ****
  /* Pointers to shared state */
  static BufferStrategyControl *StrategyControl = NULL;
  
  /* Backend-local state about whether currently vacuuming */
  bool		strategy_hint_vacuum = false;
! 
  
  /*
   * StrategyGetBuffer
--- 39,57 ----
  /* Pointers to shared state */
  static BufferStrategyControl *StrategyControl = NULL;
  
+ /* Buffer Recycling */
+ #define MAX_RECYCLE_BUF_IDS		128
+ static volatile int LocalRecycleBufIds[MAX_RECYCLE_BUF_IDS];
+ 
+ #define BUF_ID_NOT_SET 	-1
+ int nextVictimRecycleBufId = BUF_ID_NOT_SET;
+ 
+ int NScanRecycleBuffers = 0;
+ int ThisScanRecycleBuffers = 0;
+ 
  /* Backend-local state about whether currently vacuuming */
  bool		strategy_hint_vacuum = false;
! bool		strategy_hint_recycle = false;
  
  /*
   * StrategyGetBuffer
***************
*** 56,66 ****
   *	the caller must release that lock once the spinlock is dropped.
   */
  volatile BufferDesc *
! StrategyGetBuffer(void)
  {
  	volatile BufferDesc *buf;
  	int			trycounter;
  
  	LWLockAcquire(BufFreelistLock, LW_EXCLUSIVE);
  
  	/*
--- 66,118 ----
   *	the caller must release that lock once the spinlock is dropped.
   */
  volatile BufferDesc *
! StrategyGetBuffer(bool *lock_held)
  {
  	volatile BufferDesc *buf;
  	int			trycounter;
  
+ 	if (strategy_hint_recycle)
+ 	{
+ 		/*
+ 		 * Get the next buffer from our local cyclic cache.
+ 		 * Note that we don't need to hold the BufFreelistLock
+ 		 * to get this buffer, because we aren't accessing any
+ 		 * shared memory.
+ 		 *
+ 		 * Run private "clock cycle"
+ 		 */
+ 		if (++nextVictimRecycleBufId >= ThisScanRecycleBuffers)
+ 			nextVictimRecycleBufId = 0;
+ 
+ 		/*
+ 		 * If that slot hasn't been filled yet, use a new buffer
+ 		 * allocated via the main shared buffer allocation strategy
+ 		 */
+ 		if (LocalRecycleBufIds[nextVictimRecycleBufId] != BUF_ID_NOT_SET)
+ 		{
+ 			buf = &BufferDescriptors[LocalRecycleBufIds[nextVictimRecycleBufId]];
+ 			/*
+ 			 * If the buffer is pinned we cannot use it in any circumstance.
+ 			 * If usage_count == 0 then the buffer is fair game. 
+ 			 *
+ 			 * We also choose this buffer if usage_count == 1. Strictly, this
+ 			 * might sometimes be the wrong thing to do, but we rely on the
+ 			 * high probability that it was this process that last touched 
+ 			 * the buffer. We do have to pick a victim, so it may as well be
+ 			 * this one as any of the seldom touched blocks in the buffer pool.
+ 			 */
+ 			*lock_held = false;
+ 			LockBufHdr(buf);
+ 			if (buf->refcount == 0 && buf->usage_count <= 1)
+ 				return buf;
+ 			UnlockBufHdr(buf);
+ 		}
+ 	}
+ 
+ 	/*
+ 	 * If our selected buffer wasn't available, pick another...
+ 	 */
+ 	*lock_held = true;
  	LWLockAcquire(BufFreelistLock, LW_EXCLUSIVE);
  
  	/*
***************
*** 86,96 ****
  		 */
  		LockBufHdr(buf);
  		if (buf->refcount == 0 && buf->usage_count == 0)
  			return buf;
  		UnlockBufHdr(buf);
  	}
  
! 	/* Nothing on the freelist, so run the "clock sweep" algorithm */
  	trycounter = NBuffers;
  	for (;;)
  	{
--- 138,152 ----
  		 */
  		LockBufHdr(buf);
  		if (buf->refcount == 0 && buf->usage_count == 0)
+ 		{
+ 			if (strategy_hint_recycle)
+ 				LocalRecycleBufIds[nextVictimRecycleBufId] = buf->buf_id;
  			return buf;
+ 		}
  		UnlockBufHdr(buf);
  	}
  
! 	/* Nothing on the freelist, so run the shared "clock sweep" algorithm */
  	trycounter = NBuffers;
  	for (;;)
  	{
***************
*** 105,111 ****
--- 161,171 ----
  		 */
  		LockBufHdr(buf);
  		if (buf->refcount == 0 && buf->usage_count == 0)
+ 		{
+ 			if (strategy_hint_recycle)
+ 				LocalRecycleBufIds[nextVictimRecycleBufId] = buf->buf_id;
  			return buf;
+ 		}
  		if (buf->usage_count > 0)
  		{
  			buf->usage_count--;
***************
*** 197,204 ****
--- 257,309 ----
  StrategyHintVacuum(bool vacuum_active)
  {
  	strategy_hint_vacuum = vacuum_active;
+ 	if (vacuum_active)
+ 		StrategyHintRecycleBuffers(NScanRecycleBuffers);
+ 	else
+ 		StrategyHintRecycleBuffers(0);
  }
  
+ /*
+  * StrategyHintRecycleOwnBuffers -- tell us whether to recycle buffers 
+  * originally filled by this process. This is intended for use by
+  * callers who access blocks in a sequential pattern. Non-sequential
+  * access patterns could be disrupted severely by using this hint.
+  *
+  * Initial data suggests	
+  * 		nRecycleBuffers = 16 for read-only scans (Mark Kirkwood)
+  *		nRecycleBuffers = 32 for VACUUMs		 (Itagaki Takahiro)
+  * probably
+  *		nRecycleBuffers >=128 for normal write-intensive tasks
+  *								to allow for bgwriter activity
+  */
+ void
+ StrategyHintRecycleBuffers(int nRecycleBuffers)
+ {
+ 	int	i;
+ 
+ 	if (nRecycleBuffers < 0 || nRecycleBuffers > NBuffers 
+ 							|| nRecycleBuffers > NScanRecycleBuffers)
+ 		nRecycleBuffers = 0;
+ 
+ 	if (nRecycleBuffers > NScanRecycleBuffers)
+ 		ThisScanRecycleBuffers = NScanRecycleBuffers;
+ 	else
+ 		ThisScanRecycleBuffers = nRecycleBuffers;
+ 
+ 	if (ThisScanRecycleBuffers > 0)
+ 	{
+ 		strategy_hint_recycle = true;
+ 
+ 		/* just before 1st element, to allow for preincrement */
+ 		nextVictimRecycleBufId = -1;
+ 
+ 		/* prepare the cyclic buffer */
+ 		for (i = 0; i < MAX_RECYCLE_BUF_IDS; i++)
+ 			LocalRecycleBufIds[i] = BUF_ID_NOT_SET;
+ 	}
+ 	else
+ 		strategy_hint_recycle = false;
+ }
  
  /*
   * StrategyShmemSize
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/misc/guc.c,v
retrieving revision 1.379
diff -c -r1.379 guc.c
*** src/backend/utils/misc/guc.c	6 Mar 2007 02:06:14 -0000	1.379
--- src/backend/utils/misc/guc.c	12 Mar 2007 10:08:06 -0000
***************
*** 1184,1189 ****
--- 1184,1199 ----
  	},
  
  	{
+ 		{"scan_recycle_buffers", PGC_USERSET, RESOURCES_MEM,
+ 			gettext_noop("Sets the number of buffers to recycle during scans"),
+ 			NULL,
+ 			GUC_UNIT_BLOCKS
+ 		},
+ 		&NScanRecycleBuffers,
+ 		0, 0, 128, NULL, NULL
+ 	},
+ 
+ 	{
  		{"port", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
  			gettext_noop("Sets the TCP port the server listens on."),
  			NULL
Index: src/include/miscadmin.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/miscadmin.h,v
retrieving revision 1.193
diff -c -r1.193 miscadmin.h
*** src/include/miscadmin.h	1 Mar 2007 14:52:04 -0000	1.193
--- src/include/miscadmin.h	12 Mar 2007 10:08:07 -0000
***************
*** 128,133 ****
--- 128,134 ----
  extern DLLIMPORT char *DataDir;
  
  extern DLLIMPORT int NBuffers;
+ extern DLLIMPORT int NScanRecycleBuffers;
  extern int	MaxBackends;
  
  extern DLLIMPORT int MyProcPid;
Index: src/include/storage/buf_internals.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/storage/buf_internals.h,v
retrieving revision 1.89
diff -c -r1.89 buf_internals.h
*** src/include/storage/buf_internals.h	5 Jan 2007 22:19:57 -0000	1.89
--- src/include/storage/buf_internals.h	12 Mar 2007 10:08:08 -0000
***************
*** 169,174 ****
--- 169,175 ----
  
  /* in freelist.c */
  extern bool strategy_hint_vacuum;
+ extern bool strategy_hint_recycle;
  
  /* event counters in buf_init.c */
  extern long int ReadBufferCount;
***************
*** 184,190 ****
   */
  
  /* freelist.c */
! extern volatile BufferDesc *StrategyGetBuffer(void);
  extern void StrategyFreeBuffer(volatile BufferDesc *buf, bool at_head);
  extern int	StrategySyncStart(void);
  extern Size StrategyShmemSize(void);
--- 185,191 ----
   */
  
  /* freelist.c */
! extern volatile BufferDesc *StrategyGetBuffer(bool *lock_held);
  extern void StrategyFreeBuffer(volatile BufferDesc *buf, bool at_head);
  extern int	StrategySyncStart(void);
  extern Size StrategyShmemSize(void);
Index: src/include/storage/bufmgr.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/storage/bufmgr.h,v
retrieving revision 1.102
diff -c -r1.102 bufmgr.h
*** src/include/storage/bufmgr.h	5 Jan 2007 22:19:57 -0000	1.102
--- src/include/storage/bufmgr.h	12 Mar 2007 10:08:08 -0000
***************
*** 133,138 ****
--- 133,140 ----
  extern void DropRelFileNodeBuffers(RelFileNode rnode, bool istemp,
  					   BlockNumber firstDelBlock);
  extern void DropDatabaseBuffers(Oid dbid);
+ extern void DropAllSharedBuffers(void);
+ 
  
  #ifdef NOT_USED
  extern void PrintPinnedBufs(void);
***************
*** 157,161 ****
--- 159,164 ----
  
  /* in freelist.c */
  extern void StrategyHintVacuum(bool vacuum_active);
+ extern void StrategyHintRecycleBuffers(int nRecycleBuffers);
  
  #endif
? contrib/xlogviewer/libxlogviewer.so.0.0
? contrib/xlogviewer/xlogviewer.sql
---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?

               http://www.postgresql.org/docs/faq

Reply via email to