diff -cpr pgsql-orig/src/backend/postmaster/bgwriter.c pgsql/src/backend/postmaster/bgwriter.c
*** pgsql-orig/src/backend/postmaster/bgwriter.c	2006-01-10 22:03:59.000000000 +0900
--- pgsql/src/backend/postmaster/bgwriter.c	2006-01-10 22:19:50.000000000 +0900
*************** static void bg_quickdie(SIGNAL_ARGS);
*** 150,155 ****
--- 150,159 ----
  static void BgSigHupHandler(SIGNAL_ARGS);
  static void ReqCheckpointHandler(SIGNAL_ARGS);
  static void ReqShutdownHandler(SIGNAL_ARGS);
+ static int	EliminateDupRequests(BgWriterRequest *requests, int num);
+ static int	BgWriterRequestCompare(const void *v1, const void *v2);
+ static size_t unique(void *base, size_t nmemb, size_t size,
+ 			int (*compar)(const void *, const void *));
  
  
  /*
*************** RequestCheckpoint(bool waitforit, bool w
*** 628,639 ****
   *
   * If we are unable to pass over the request (at present, this can happen
   * if the shared memory queue is full), we return false.  That forces
!  * the backend to do its own fsync.  We hope that will be even more seldom.
   *
   * Note: we presently make no attempt to eliminate duplicate requests
!  * in the requests[] queue.  The bgwriter will have to eliminate dups
!  * internally anyway, so we may as well avoid holding the lock longer
!  * than we have to here.
   */
  bool
  ForwardFsyncRequest(RelFileNode rnode, BlockNumber segno)
--- 632,644 ----
   *
   * If we are unable to pass over the request (at present, this can happen
   * if the shared memory queue is full), we return false.  That forces
!  * the backend to do its own fsync.  We hope that will be even more seldom,
!  * but in such cases, we will eliminate duplicate requests.
   *
   * Note: we presently make no attempt to eliminate duplicate requests
!  * in the requests[] queue as long as it is not full.  The bgwriter will
!  * have to eliminate dups internally anyway, so we may as well avoid
!  * holding the lock longer than we have to here.
   */
  bool
  ForwardFsyncRequest(RelFileNode rnode, BlockNumber segno)
*************** ForwardFsyncRequest(RelFileNode rnode, B
*** 645,656 ****
  	Assert(BgWriterShmem != NULL);
  
  	LWLockAcquire(BgWriterCommLock, LW_EXCLUSIVE);
! 	if (BgWriterShmem->bgwriter_pid == 0 ||
! 		BgWriterShmem->num_requests >= BgWriterShmem->max_requests)
  	{
  		LWLockRelease(BgWriterCommLock);
  		return false;
  	}
  	request = &BgWriterShmem->requests[BgWriterShmem->num_requests++];
  	request->rnode = rnode;
  	request->segno = segno;
--- 650,670 ----
  	Assert(BgWriterShmem != NULL);
  
  	LWLockAcquire(BgWriterCommLock, LW_EXCLUSIVE);
! 	if (BgWriterShmem->bgwriter_pid == 0)
  	{
  		LWLockRelease(BgWriterCommLock);
  		return false;
  	}
+ 	if (BgWriterShmem->num_requests >= BgWriterShmem->max_requests)
+ 	{
+ 		BgWriterShmem->num_requests = EliminateDupRequests(
+ 			BgWriterShmem->requests, BgWriterShmem->num_requests);
+ 		if (BgWriterShmem->num_requests >= BgWriterShmem->max_requests)
+ 		{
+ 			LWLockRelease(BgWriterCommLock);
+ 			return false;
+ 		}
+ 	}
  	request = &BgWriterShmem->requests[BgWriterShmem->num_requests++];
  	request->rnode = rnode;
  	request->segno = segno;
*************** AbsorbFsyncRequests(void)
*** 710,712 ****
--- 724,778 ----
  
  	END_CRIT_SECTION();
  }
+ 
+ static int
+ BgWriterRequestCompare(const void *v1, const void *v2)
+ {
+ 	const BgWriterRequest *lhs = (const BgWriterRequest *)v1;
+ 	const BgWriterRequest *rhs = (const BgWriterRequest *)v2;
+ 
+ 	if (lhs->rnode.spcNode < rhs->rnode.spcNode) return -1;
+ 	if (lhs->rnode.spcNode > rhs->rnode.spcNode) return  1;
+ 	if (lhs->rnode.dbNode < rhs->rnode.dbNode) return -1;
+ 	if (lhs->rnode.dbNode > rhs->rnode.dbNode) return  1;
+ 	if (lhs->rnode.relNode < rhs->rnode.relNode) return -1;
+ 	if (lhs->rnode.relNode > rhs->rnode.relNode) return  1;
+ 	if (lhs->segno < rhs->segno) return -1;
+ 	if (lhs->segno > rhs->segno) return  1;
+ 	return 0;
+ }
+ 
+ static size_t
+ unique(void *base, size_t nmemb, size_t size,
+ 		int (*compar)(const void *, const void *))
+ {
+ 	char *start	= (char *) base;
+ 	char *stop	= (char *) base + (size * (nmemb - 1));
+ 	char *dst	= start;
+ 	char *p		= start;
+ 
+ 	while (p <= stop)
+ 	{
+ 		size_t	elements;
+ 		char   *q = p;
+ 
+ 		while (q < stop && compar(q, q + size) != 0)
+ 			q = q + size;
+ 
+ 		elements = ((q - p) / size) + 1;
+ 		memmove(dst, p, size * elements);
+ 		dst = dst + size * elements;
+ 
+ 		p = q + size;
+ 		while (p <= stop && compar(q, p) == 0)
+ 			p = p + size;
+ 	}
+ 	return (dst - start) / size;
+ }
+ 
+ static int
+ EliminateDupRequests(BgWriterRequest *requests, int num)
+ {
+ 	qsort(requests, num, sizeof(BgWriterRequest), BgWriterRequestCompare);
+ 	return unique(requests, num, sizeof(BgWriterRequest), BgWriterRequestCompare);
+ }
