]> granicus.if.org Git - postgresql/commitdiff
Arrange to call AbsorbFsyncRequests every so often while performing a
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 3 Mar 2006 00:02:02 +0000 (00:02 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 3 Mar 2006 00:02:02 +0000 (00:02 +0000)
checkpoint in the bgwriter.  This forestalls overflow of the fsync request
queue, which is not fatal but causes considerable performance degradation
when it occurs (because backends then have to do their own fsyncs).  Per
patch from Itagaki Takahiro, modified a little bit by me.

src/backend/storage/buffer/bufmgr.c
src/backend/storage/smgr/md.c

index 11e83812d0c0712053995fd7347a04e29f7a9912..41ca4c14495f88983f344d2ae29c9a5271dfbcaf 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.202 2006/01/06 00:04:20 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.203 2006/03/03 00:02:01 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -42,6 +42,7 @@
 
 #include "lib/stringinfo.h"
 #include "miscadmin.h"
+#include "postmaster/bgwriter.h"
 #include "storage/buf_internals.h"
 #include "storage/bufmgr.h"
 #include "storage/bufpage.h"
@@ -61,6 +62,9 @@
 #define LocalBufHdrGetBlock(bufHdr) \
        LocalBufferBlockPointers[-((bufHdr)->buf_id + 2)]
 
+/* interval for calling AbsorbFsyncRequests in BufferSync */
+#define WRITES_PER_ABSORB              1000
+
 
 /* GUC variables */
 bool           zero_damaged_pages = false;
@@ -892,6 +896,7 @@ BufferSync(void)
 {
        int                     buf_id;
        int                     num_to_scan;
+       int                     absorb_counter;
 
        /*
         * Find out where to start the circular scan.
@@ -905,9 +910,23 @@ BufferSync(void)
         * Loop over all buffers.
         */
        num_to_scan = NBuffers;
+       absorb_counter = WRITES_PER_ABSORB;
        while (num_to_scan-- > 0)
        {
-               (void) SyncOneBuffer(buf_id, false);
+               if (SyncOneBuffer(buf_id, false))
+               {
+                       /*
+                        * If in bgwriter, absorb pending fsync requests after each
+                        * WRITES_PER_ABSORB write operations, to prevent overflow of
+                        * the fsync request queue.  If not in bgwriter process, this is
+                        * a no-op.
+                        */
+                       if (--absorb_counter <= 0)
+                       {
+                               AbsorbFsyncRequests();
+                               absorb_counter = WRITES_PER_ABSORB;
+                       }
+               }
                if (++buf_id >= NBuffers)
                        buf_id = 0;
        }
index f8d15ee3ff85206e1bd9349463aa114ce8c64a91..60d8a229639eb455deac2f065c64381af4f81fd4 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/storage/smgr/md.c,v 1.118 2005/10/15 02:49:26 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/storage/smgr/md.c,v 1.119 2006/03/03 00:02:02 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -28,6 +28,9 @@
 #include "utils/memutils.h"
 
 
+/* interval for calling AbsorbFsyncRequests in mdsync */
+#define FSYNCS_PER_ABSORB              10
+
 /*
  *     The magnetic disk storage manager keeps track of open file
  *     descriptors in its own descriptor pool.  This is done to make it
@@ -702,6 +705,7 @@ mdsync(void)
 {
        HASH_SEQ_STATUS hstat;
        PendingOperationEntry *entry;
+       int                     absorb_counter;
 
        if (!pendingOpsTable)
                return false;
@@ -714,6 +718,7 @@ mdsync(void)
         */
        AbsorbFsyncRequests();
 
+       absorb_counter = FSYNCS_PER_ABSORB;
        hash_seq_init(&hstat, pendingOpsTable);
        while ((entry = (PendingOperationEntry *) hash_seq_search(&hstat)) != NULL)
        {
@@ -727,6 +732,19 @@ mdsync(void)
                        SMgrRelation reln;
                        MdfdVec    *seg;
 
+                       /*
+                        * If in bgwriter, absorb pending requests every so often to
+                        * prevent overflow of the fsync request queue.  The hashtable
+                        * code does not specify whether entries added by this will be
+                        * visited by our search, but we don't really care: it's OK if
+                        * we do, and OK if we don't.
+                        */
+                       if (--absorb_counter <= 0)
+                       {
+                               AbsorbFsyncRequests();
+                               absorb_counter = FSYNCS_PER_ABSORB;
+                       }
+
                        /*
                         * Find or create an smgr hash entry for this relation. This may
                         * seem a bit unclean -- md calling smgr?  But it's really the