diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 11e83812d0c0712053995fd7347a04e29f7a9912..41ca4c14495f88983f344d2ae29c9a5271dfbcaf 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -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; } diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index f8d15ee3ff85206e1bd9349463aa114ce8c64a91..60d8a229639eb455deac2f065c64381af4f81fd4 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -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