Tweak BgBufferSync() so that a persistent write error on a dirty buffer
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 2 Aug 2005 20:52:08 +0000 (20:52 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 2 Aug 2005 20:52:08 +0000 (20:52 +0000)
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.

src/backend/postmaster/bgwriter.c
src/backend/storage/buffer/bufmgr.c

index d826a6190de11ae2bee605d23c91ffaa1befac01..f4158fc89a50269042f78d2bb3e6456c821985af 100644 (file)
@@ -37,7 +37,7 @@
  *
  *
  * 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
                 * 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
-                * progress when the LRU dirty buffer cannot be written...)
+                * error logs as fast as we can.
                 */
                pg_usleep(1000000L);
        }
index 1fe681e1aba9c25635024f902168b91536b36d05..4fb16eb6145eae239f1396bb2171f9c1f2c72abf 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * 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
         * 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)
        {
@@ -911,12 +916,13 @@ BgBufferSync(void)
 
                while (num_to_scan-- > 0)
                {
-                       if (SyncOneBuffer(buf_id1, false))
-                               num_written++;
                        if (++buf_id1 >= NBuffers)
                                buf_id1 = 0;
-                       if (num_written >= bgwriter_all_maxpages)
-                               break;
+                       if (SyncOneBuffer(buf_id1, false))
+                       {
+                               if (++num_written >= bgwriter_all_maxpages)
+                                       break;
+                       }
                }
        }
 
@@ -934,11 +940,12 @@ BgBufferSync(void)
                while (num_to_scan-- > 0)
                {
                        if (SyncOneBuffer(buf_id2, true))
-                               num_written++;
+                       {
+                               if (++num_written >= bgwriter_lru_maxpages)
+                                       break;
+                       }
                        if (++buf_id2 >= NBuffers)
                                buf_id2 = 0;
-                       if (num_written >= bgwriter_lru_maxpages)
-                               break;
                }
        }
 }