Tweak BgBufferSync() so that a persistent write error on a dirty buffer

doesn't block the bgwriter from making progress writing out other buffers.
This was a hard problem in the context of the ARC/2Q design, but it's
trivial in the context of clock sweep ... just advance the sweep counter
before we try to write not after.
This commit is contained in:
Tom Lane 2005-08-02 20:52:08 +00:00
parent 688784f671
commit 6eac4e69cf
2 changed files with 17 additions and 11 deletions

View File

@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.17 2005/06/30 00:00:51 tgl Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.18 2005/08/02 20:52:08 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -256,8 +256,7 @@ BackgroundWriterMain(void)
/* /*
* Sleep at least 1 second after any error. A write error is * Sleep at least 1 second after any error. A write error is
* likely to be repeated, and we don't want to be filling the * likely to be repeated, and we don't want to be filling the
* error logs as fast as we can. (XXX think about ways to make * error logs as fast as we can.
* progress when the LRU dirty buffer cannot be written...)
*/ */
pg_usleep(1000000L); pg_usleep(1000000L);
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.189 2005/05/19 21:35:46 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.190 2005/08/02 20:52:08 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -903,6 +903,11 @@ BgBufferSync(void)
/* /*
* This loop runs over all buffers, including pinned ones. The * This loop runs over all buffers, including pinned ones. The
* starting point advances through the buffer pool on successive calls. * starting point advances through the buffer pool on successive calls.
*
* Note that we advance the static counter *before* trying to write.
* This ensures that, if we have a persistent write failure on a dirty
* buffer, we'll still be able to make progress writing other buffers.
* (The bgwriter will catch the error and just call us again later.)
*/ */
if (bgwriter_all_percent > 0.0 && bgwriter_all_maxpages > 0) if (bgwriter_all_percent > 0.0 && bgwriter_all_maxpages > 0)
{ {
@ -911,14 +916,15 @@ BgBufferSync(void)
while (num_to_scan-- > 0) while (num_to_scan-- > 0)
{ {
if (SyncOneBuffer(buf_id1, false))
num_written++;
if (++buf_id1 >= NBuffers) if (++buf_id1 >= NBuffers)
buf_id1 = 0; buf_id1 = 0;
if (num_written >= bgwriter_all_maxpages) if (SyncOneBuffer(buf_id1, false))
{
if (++num_written >= bgwriter_all_maxpages)
break; break;
} }
} }
}
/* /*
* This loop considers only unpinned buffers close to the clock sweep * This loop considers only unpinned buffers close to the clock sweep
@ -934,11 +940,12 @@ BgBufferSync(void)
while (num_to_scan-- > 0) while (num_to_scan-- > 0)
{ {
if (SyncOneBuffer(buf_id2, true)) if (SyncOneBuffer(buf_id2, true))
num_written++; {
if (++num_written >= bgwriter_lru_maxpages)
break;
}
if (++buf_id2 >= NBuffers) if (++buf_id2 >= NBuffers)
buf_id2 = 0; buf_id2 = 0;
if (num_written >= bgwriter_lru_maxpages)
break;
} }
} }
} }