On Mon, 2004-12-27 at 22:21, Bruce Momjian wrote:
> Should we consider at least adjusting the meaning of bgwriter_percent?

Yes. As things stand, this is the only change that seems safe.

Here's a very short patch that implements this change within BufferSync
in bufmgr.c 

- No algorithm changes
- No error message changes
- Only change is the call to StrategyDirtyBufferList is made using the
maximum number of buffers that will be cleaned, rather than uselessly
trawling through all of shared_buffers

This changes the meaning of bgwriter_percent from "percent of dirty
buffers" to "percent of shared_buffers". The default settings of 1% of
1000 buffers gives up to 10 dirty block writes every 250ms

Benefit: allows performance tuning by increases options for setting
bgwriter_delay which would otherwise have an ineffectually high minimum
setting

Risk: low

1-line doc patch to follow, if this is approved.

-- 
Best Regards, Simon Riggs
Index: src/backend/storage/buffer/bufmgr.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v
retrieving revision 1.182
diff -d -c -r1.182 bufmgr.c
*** src/backend/storage/buffer/bufmgr.c	24 Nov 2004 02:56:17 -0000	1.182
--- src/backend/storage/buffer/bufmgr.c	30 Dec 2004 23:52:24 -0000
***************
*** 681,686 ****
--- 681,687 ----
  {
  	BufferDesc **dirty_buffers;
  	BufferTag  *buftags;
+     int         dirty_buffers_maxlen = 1;
  	int			num_buffer_dirty;
  	int			i;
  
***************
*** 688,717 ****
  	if (percent == 0 || maxpages == 0)
  		return 0;
  
  	/*
! 	 * Get a list of all currently dirty buffers and how many there are.
  	 * We do not flush buffers that get dirtied after we started. They
! 	 * have to wait until the next checkpoint.
  	 */
! 	dirty_buffers = (BufferDesc **) palloc(NBuffers * sizeof(BufferDesc *));
! 	buftags = (BufferTag *) palloc(NBuffers * sizeof(BufferTag));
  
  	LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
- 	num_buffer_dirty = StrategyDirtyBufferList(dirty_buffers, buftags,
- 											   NBuffers);
  
! 	/*
! 	 * If called by the background writer, we are usually asked to only
! 	 * write out some portion of dirty buffers now, to prevent the IO
! 	 * storm at checkpoint time.
! 	 */
! 	if (percent > 0)
! 	{
! 		Assert(percent <= 100);
! 		num_buffer_dirty = (num_buffer_dirty * percent + 99) / 100;
! 	}
! 	if (maxpages > 0 && num_buffer_dirty > maxpages)
! 		num_buffer_dirty = maxpages;
  
  	/* Make sure we can handle the pin inside the loop */
  	ResourceOwnerEnlargeBuffers(CurrentResourceOwner);
--- 689,719 ----
  	if (percent == 0 || maxpages == 0)
  		return 0;
  
+     /* Set number of buffers we will clean at LRUs of buffer lists */
+     if (percent > 0 ) {
+     	Assert(percent <= 100);
+    	    dirty_buffers_maxlen = (NBuffers * percent + 99) / 100;
+     }
+ 	if (maxpages > 0 && dirty_buffers_maxlen > maxpages)
+     	dirty_buffers_maxlen = maxpages;
+ 
+     /* if checkpoint time */
+     if (percent == -1 && maxpages == -1)
+     	dirty_buffers_maxlen = NBuffers;
+ 
  	/*
! 	 * Get a list of dirty buffers to clean and how many there are.
  	 * We do not flush buffers that get dirtied after we started. They
! 	 * have to wait until the next call of this function
  	 */
! 	dirty_buffers = 
!          (BufferDesc **) palloc(dirty_buffers_maxlen * sizeof(BufferDesc *));
! 	buftags = (BufferTag *) palloc(dirty_buffers_maxlen * sizeof(BufferTag));
  
  	LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
  
!    	num_buffer_dirty = StrategyDirtyBufferList(dirty_buffers, buftags,
! 											   dirty_buffers_maxlen);
  
  	/* Make sure we can handle the pin inside the loop */
  	ResourceOwnerEnlargeBuffers(CurrentResourceOwner);
---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings

Reply via email to