Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4f33621

Browse files
committed
Don't set SO_SNDBUF on recent Windows versions that have a bigger default.
It's unnecessary to set it if the default is higher in the first place. Furthermore, setting SO_SNDBUF disables the so-called "dynamic send buffering" feature, which hurts performance further. This can be seen especially when the network between the client and the server has high latency. Chen Huajun
1 parent 906e924 commit 4f33621

File tree

1 file changed

+38
-6
lines changed

1 file changed

+38
-6
lines changed

src/backend/libpq/pqcomm.c

+38-6
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,11 @@ StreamConnection(pgsocket server_fd, Port *port)
726726
if (!IS_AF_UNIX(port->laddr.addr.ss_family))
727727
{
728728
int on;
729+
#ifdef WIN32
730+
int oldopt;
731+
int optlen;
732+
int newopt;
733+
#endif
729734

730735
#ifdef TCP_NODELAY
731736
on = 1;
@@ -747,16 +752,43 @@ StreamConnection(pgsocket server_fd, Port *port)
747752
#ifdef WIN32
748753

749754
/*
750-
* This is a Win32 socket optimization. The ideal size is 32k.
751-
* http://support.microsoft.com/kb/823764/EN-US/
755+
* This is a Win32 socket optimization. The OS send buffer should be
756+
* large enough to send the whole Postgres send buffer in one go, or
757+
* performance suffers. The Postgres send buffer can be enlarged if a
758+
* very large message needs to be sent, but we won't attempt to
759+
* enlarge the OS buffer if that happens, so somewhat arbitrarily
760+
* ensure that the OS buffer is at least PQ_SEND_BUFFER_SIZE * 4.
761+
* (That's 32kB with the current default).
762+
*
763+
* The default OS buffer size used to be 8kB in earlier Windows
764+
* versions, but was raised to 64kB in Windows 2012. So it shouldn't
765+
* be necessary to change it in later versions anymore. Changing it
766+
* unnecessarily can even reduce performance, because setting
767+
* SO_SNDBUF in the application disables the "dynamic send buffering"
768+
* feature that was introduced in Windows 7. So before fiddling with
769+
* SO_SNDBUF, check if the current buffer size is already large enough
770+
* and only increase it if necessary.
771+
*
772+
* See https://support.microsoft.com/kb/823764/EN-US/ and
773+
* https://msdn.microsoft.com/en-us/library/bb736549%28v=vs.85%29.aspx
752774
*/
753-
on = PQ_SEND_BUFFER_SIZE * 4;
754-
if (setsockopt(port->sock, SOL_SOCKET, SO_SNDBUF, (char *) &on,
755-
sizeof(on)) < 0)
775+
optlen = sizeof(oldopt);
776+
if (getsockopt(server_fd, SOL_SOCKET, SO_SNDBUF, (char *) &oldopt,
777+
&optlen) < 0)
756778
{
757-
elog(LOG, "setsockopt(SO_SNDBUF) failed: %m");
779+
elog(LOG, "getsockopt(SO_SNDBUF) failed: %m");
758780
return STATUS_ERROR;
759781
}
782+
newopt = PQ_SEND_BUFFER_SIZE * 4;
783+
if (oldopt < newopt)
784+
{
785+
if (setsockopt(port->sock, SOL_SOCKET, SO_SNDBUF, (char *) &newopt,
786+
sizeof(newopt)) < 0)
787+
{
788+
elog(LOG, "setsockopt(SO_SNDBUF) failed: %m");
789+
return STATUS_ERROR;
790+
}
791+
}
760792
#endif
761793

762794
/*

0 commit comments

Comments
 (0)