I wrote:
> I propose that it'd be a good idea to try to set the stats socket's
> receive buffer size to be a minimum of, say, 100K on all platforms.
> Code for this would be analogous to what we already have in pqcomm.c
> (circa line 760) for forcing up the send buffer size, but SO_RCVBUF
> not SO_SNDBUF.

I experimented with the attached patch.  Modern platforms such as
recent Linux and macOS seem to have default receive buffer sizes
in the 100K-200K range.  The default is less in older systems, but
even my very oldest dinosaurs will let you set it to at least 256K.
(Don't have Windows to try, though.)

I propose committing this (less the debug logging part) to HEAD
once the beta is out, and then back-patching if it doesn't break
anything and seems to improve matters on frogmouth.

                        regards, tom lane

diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index d4feed1..d868976 100644
*** a/src/backend/postmaster/pgstat.c
--- b/src/backend/postmaster/pgstat.c
***************
*** 93,98 ****
--- 93,101 ----
  #define PGSTAT_POLL_LOOP_COUNT	(PGSTAT_MAX_WAIT_TIME / PGSTAT_RETRY_DELAY)
  #define PGSTAT_INQ_LOOP_COUNT	(PGSTAT_INQ_INTERVAL / PGSTAT_RETRY_DELAY)
  
+ /* Minimum receive buffer size for the collector's socket. */
+ #define PGSTAT_MIN_RCVBUF		(100 * 1024)
+ 
  
  /* ----------
   * The initial size hints for the hash tables used in the collector.
*************** retry2:
*** 574,579 ****
--- 577,620 ----
  		goto startup_failed;
  	}
  
+ 	/*
+ 	 * Try to ensure that the socket's receive buffer is at least
+ 	 * PGSTAT_MIN_RCVBUF bytes, so that it won't easily overflow and lose
+ 	 * data.  Use of UDP protocol means that we are willing to lose data under
+ 	 * heavy load, but we don't want it to happen just because of ridiculously
+ 	 * small default buffer sizes (such as 8KB on older Windows versions).
+ 	 */
+ 	{
+ 		int			old_rcvbuf;
+ 		int			new_rcvbuf;
+ 		ACCEPT_TYPE_ARG3 rcvbufsize = sizeof(old_rcvbuf);
+ 
+ 		if (getsockopt(pgStatSock, SOL_SOCKET, SO_RCVBUF,
+ 					   (char *) &old_rcvbuf, &rcvbufsize) < 0)
+ 		{
+ 			elog(LOG, "getsockopt(SO_RCVBUF) failed: %m");
+ 			/* if we can't get existing size, always try to set it */
+ 			old_rcvbuf = 0;
+ 		}
+ 
+ 		new_rcvbuf = PGSTAT_MIN_RCVBUF;
+ 		if (old_rcvbuf < new_rcvbuf)
+ 		{
+ 			if (setsockopt(pgStatSock, SOL_SOCKET, SO_RCVBUF,
+ 						   (char *) &new_rcvbuf, sizeof(new_rcvbuf)) < 0)
+ 				elog(LOG, "setsockopt(SO_RCVBUF) failed: %m");
+ 		}
+ 
+ 		/* this part is just for debugging, not needed at commit: */
+ 		rcvbufsize = sizeof(new_rcvbuf);
+ 		if (getsockopt(pgStatSock, SOL_SOCKET, SO_RCVBUF,
+ 					   (char *) &new_rcvbuf, &rcvbufsize) < 0)
+ 			elog(LOG, "getsockopt(SO_RCVBUF) failed: %m");
+ 		else
+ 			elog(LOG, "getsockopt(SO_RCVBUF) was %d, now %d",
+ 				 old_rcvbuf, new_rcvbuf);
+ 	}
+ 
  	pg_freeaddrinfo_all(hints.ai_family, addrs);
  
  	return;
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to