summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeikki Linnakangas2015-07-06 13:10:58 +0000
committerHeikki Linnakangas2015-07-06 13:10:58 +0000
commit4f33621f3f50286e607a3cdcc1f7a7d51075af95 (patch)
tree5637e7449f36fdb5ead86c9d62953b778d053f43
parent906e9249494bda975914b78fdd743609e1f83016 (diff)
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
-rw-r--r--src/backend/libpq/pqcomm.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index a4b37ed5a2..9f92e4efae 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -726,6 +726,11 @@ StreamConnection(pgsocket server_fd, Port *port)
if (!IS_AF_UNIX(port->laddr.addr.ss_family))
{
int on;
+#ifdef WIN32
+ int oldopt;
+ int optlen;
+ int newopt;
+#endif
#ifdef TCP_NODELAY
on = 1;
@@ -747,16 +752,43 @@ StreamConnection(pgsocket server_fd, Port *port)
#ifdef WIN32
/*
- * This is a Win32 socket optimization. The ideal size is 32k.
- * http://support.microsoft.com/kb/823764/EN-US/
+ * This is a Win32 socket optimization. The OS send buffer should be
+ * large enough to send the whole Postgres send buffer in one go, or
+ * performance suffers. The Postgres send buffer can be enlarged if a
+ * very large message needs to be sent, but we won't attempt to
+ * enlarge the OS buffer if that happens, so somewhat arbitrarily
+ * ensure that the OS buffer is at least PQ_SEND_BUFFER_SIZE * 4.
+ * (That's 32kB with the current default).
+ *
+ * The default OS buffer size used to be 8kB in earlier Windows
+ * versions, but was raised to 64kB in Windows 2012. So it shouldn't
+ * be necessary to change it in later versions anymore. Changing it
+ * unnecessarily can even reduce performance, because setting
+ * SO_SNDBUF in the application disables the "dynamic send buffering"
+ * feature that was introduced in Windows 7. So before fiddling with
+ * SO_SNDBUF, check if the current buffer size is already large enough
+ * and only increase it if necessary.
+ *
+ * See https://support.microsoft.com/kb/823764/EN-US/ and
+ * https://msdn.microsoft.com/en-us/library/bb736549%28v=vs.85%29.aspx
*/
- on = PQ_SEND_BUFFER_SIZE * 4;
- if (setsockopt(port->sock, SOL_SOCKET, SO_SNDBUF, (char *) &on,
- sizeof(on)) < 0)
+ optlen = sizeof(oldopt);
+ if (getsockopt(server_fd, SOL_SOCKET, SO_SNDBUF, (char *) &oldopt,
+ &optlen) < 0)
{
- elog(LOG, "setsockopt(SO_SNDBUF) failed: %m");
+ elog(LOG, "getsockopt(SO_SNDBUF) failed: %m");
return STATUS_ERROR;
}
+ newopt = PQ_SEND_BUFFER_SIZE * 4;
+ if (oldopt < newopt)
+ {
+ if (setsockopt(port->sock, SOL_SOCKET, SO_SNDBUF, (char *) &newopt,
+ sizeof(newopt)) < 0)
+ {
+ elog(LOG, "setsockopt(SO_SNDBUF) failed: %m");
+ return STATUS_ERROR;
+ }
+ }
#endif
/*