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