1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-26 12:21:12 +03:00

Make bgwriter sleep longer when it has no work to do, to save electricity.

To make it wake up promptly when activity starts again, backends nudge it
by setting a latch in MarkBufferDirty(). The latch is kept set while
bgwriter is active, so there is very little overhead from that when the
system is busy. It is only armed before going into longer sleep.

Peter Geoghegan, with some changes by me.
This commit is contained in:
Heikki Linnakangas
2012-01-26 18:19:48 +02:00
parent 467ff207f5
commit 6d90eaaa89
4 changed files with 165 additions and 28 deletions

View File

@ -953,6 +953,7 @@ void
MarkBufferDirty(Buffer buffer)
{
volatile BufferDesc *bufHdr;
bool dirtied = false;
if (!BufferIsValid(buffer))
elog(ERROR, "bad buffer ID: %d", buffer);
@ -973,19 +974,25 @@ MarkBufferDirty(Buffer buffer)
Assert(bufHdr->refcount > 0);
/*
* If the buffer was not dirty already, do vacuum accounting.
*/
if (!(bufHdr->flags & BM_DIRTY))
{
VacuumPageDirty++;
if (VacuumCostActive)
VacuumCostBalance += VacuumCostPageDirty;
}
dirtied = true;
bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
UnlockBufHdr(bufHdr);
/*
* If the buffer was not dirty already, do vacuum accounting, and
* nudge bgwriter.
*/
if (dirtied)
{
VacuumPageDirty++;
if (VacuumCostActive)
VacuumCostBalance += VacuumCostPageDirty;
if (ProcGlobal->bgwriterLatch)
SetLatch(ProcGlobal->bgwriterLatch);
}
}
/*
@ -1307,8 +1314,12 @@ BufferSync(int flags)
* BgBufferSync -- Write out some dirty buffers in the pool.
*
* This is called periodically by the background writer process.
*
* Returns true if the clocksweep has been "lapped", so that there's nothing
* to do. Also returns true if there's nothing to do because bgwriter was
* effectively disabled by setting bgwriter_lru_maxpages to 0.
*/
void
bool
BgBufferSync(void)
{
/* info obtained from freelist.c */
@ -1365,7 +1376,7 @@ BgBufferSync(void)
if (bgwriter_lru_maxpages <= 0)
{
saved_info_valid = false;
return;
return true;
}
/*
@ -1584,6 +1595,8 @@ BgBufferSync(void)
recent_alloc, strategy_delta, scans_per_alloc, smoothed_density);
#endif
}
return (bufs_to_lap == 0);
}
/*
@ -2341,16 +2354,24 @@ SetBufferCommitInfoNeedsSave(Buffer buffer)
if ((bufHdr->flags & (BM_DIRTY | BM_JUST_DIRTIED)) !=
(BM_DIRTY | BM_JUST_DIRTIED))
{
bool dirtied = false;
LockBufHdr(bufHdr);
Assert(bufHdr->refcount > 0);
if (!(bufHdr->flags & BM_DIRTY))
dirtied = true;
bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
UnlockBufHdr(bufHdr);
if (dirtied)
{
VacuumPageDirty++;
if (VacuumCostActive)
VacuumCostBalance += VacuumCostPageDirty;
/* The bgwriter may need to be woken. */
if (ProcGlobal->bgwriterLatch)
SetLatch(ProcGlobal->bgwriterLatch);
}
bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
UnlockBufHdr(bufHdr);
}
}