mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-05 19:09:58 +08:00
On Windows, use pgwin32_waitforsinglesocket() instead of select() to wait for
input in the stats collector. Our select() emulation is apparently buggy for UDP sockets :-(. This should resolve problems with stats collection (and hence autovacuum) failing under more than minimal load. Diagnosis and patch by Magnus Hagander. Patch probably needs to be back-ported to 8.1 and 8.0, but first let's see if it makes the buildfarm happy...
This commit is contained in:
parent
ebe2830613
commit
043fcd6616
@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.74 2006/10/06 17:13:59 petere Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.74.2.1 2007/01/26 20:07:01 tgl Exp $
|
||||
*
|
||||
* Since the server static private key ($DataDir/server.key)
|
||||
* will normally be stored unencrypted so that the database
|
||||
@ -275,7 +275,8 @@ rloop:
|
||||
#ifdef WIN32
|
||||
pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
|
||||
(err == SSL_ERROR_WANT_READ) ?
|
||||
FD_READ | FD_CLOSE : FD_WRITE | FD_CLOSE);
|
||||
FD_READ | FD_CLOSE : FD_WRITE | FD_CLOSE,
|
||||
INFINITE);
|
||||
#endif
|
||||
goto rloop;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
@ -374,7 +375,8 @@ wloop:
|
||||
#ifdef WIN32
|
||||
pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
|
||||
(err == SSL_ERROR_WANT_READ) ?
|
||||
FD_READ | FD_CLOSE : FD_WRITE | FD_CLOSE);
|
||||
FD_READ | FD_CLOSE : FD_WRITE | FD_CLOSE,
|
||||
INFINITE);
|
||||
#endif
|
||||
goto wloop;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
@ -889,7 +891,8 @@ aloop:
|
||||
#ifdef WIN32
|
||||
pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
|
||||
(err == SSL_ERROR_WANT_READ) ?
|
||||
FD_READ | FD_CLOSE | FD_ACCEPT : FD_WRITE | FD_CLOSE);
|
||||
FD_READ | FD_CLOSE | FD_ACCEPT : FD_WRITE | FD_CLOSE,
|
||||
INFINITE);
|
||||
#endif
|
||||
goto aloop;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/port/win32/socket.c,v 1.14.2.1 2006/12/04 22:24:04 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/port/win32/socket.c,v 1.14.2.2 2007/01/26 20:07:01 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -114,7 +114,7 @@ isDataGram(SOCKET s) {
|
||||
}
|
||||
|
||||
int
|
||||
pgwin32_waitforsinglesocket(SOCKET s, int what)
|
||||
pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout)
|
||||
{
|
||||
static HANDLE waitevent = INVALID_HANDLE_VALUE;
|
||||
static SOCKET current_socket = -1;
|
||||
@ -195,7 +195,7 @@ pgwin32_waitforsinglesocket(SOCKET s, int what)
|
||||
}
|
||||
}
|
||||
else
|
||||
r = WaitForMultipleObjectsEx(2, events, FALSE, INFINITE, TRUE);
|
||||
r = WaitForMultipleObjectsEx(2, events, FALSE, timeout, TRUE);
|
||||
|
||||
if (r == WAIT_OBJECT_0 || r == WAIT_IO_COMPLETION)
|
||||
{
|
||||
@ -205,6 +205,8 @@ pgwin32_waitforsinglesocket(SOCKET s, int what)
|
||||
}
|
||||
if (r == WAIT_OBJECT_0 + 1)
|
||||
return 1;
|
||||
if (r == WAIT_TIMEOUT)
|
||||
return 0;
|
||||
ereport(ERROR,
|
||||
(errmsg_internal("Bad return from WaitForMultipleObjects: %i (%i)", r, (int) GetLastError())));
|
||||
return 0;
|
||||
@ -274,7 +276,7 @@ pgwin32_connect(SOCKET s, const struct sockaddr * addr, int addrlen)
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (pgwin32_waitforsinglesocket(s, FD_CONNECT) == 0)
|
||||
while (pgwin32_waitforsinglesocket(s, FD_CONNECT, INFINITE) == 0)
|
||||
{
|
||||
/* Loop endlessly as long as we are just delivering signals */
|
||||
}
|
||||
@ -310,7 +312,8 @@ pgwin32_recv(SOCKET s, char *buf, int len, int f)
|
||||
|
||||
/* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK (<=nt4) */
|
||||
|
||||
if (pgwin32_waitforsinglesocket(s, FD_READ | FD_CLOSE | FD_ACCEPT) == 0)
|
||||
if (pgwin32_waitforsinglesocket(s, FD_READ | FD_CLOSE | FD_ACCEPT,
|
||||
INFINITE) == 0)
|
||||
return -1;
|
||||
|
||||
r = WSARecv(s, &wbuf, 1, &b, &flags, NULL, NULL);
|
||||
@ -355,7 +358,7 @@ pgwin32_send(SOCKET s, char *buf, int len, int flags)
|
||||
|
||||
/* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK (<=nt4) */
|
||||
|
||||
if (pgwin32_waitforsinglesocket(s, FD_WRITE | FD_CLOSE) == 0)
|
||||
if (pgwin32_waitforsinglesocket(s, FD_WRITE | FD_CLOSE, INFINITE) == 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
*
|
||||
* Copyright (c) 2001-2006, PostgreSQL Global Development Group
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.140.2.1 2007/01/11 23:06:09 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.140.2.2 2007/01/26 20:07:01 tgl Exp $
|
||||
* ----------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
@ -1633,11 +1633,13 @@ PgstatCollectorMain(int argc, char *argv[])
|
||||
int len;
|
||||
PgStat_Msg msg;
|
||||
|
||||
#ifndef WIN32
|
||||
#ifdef HAVE_POLL
|
||||
struct pollfd input_fd;
|
||||
#else
|
||||
struct timeval sel_timeout;
|
||||
fd_set rfds;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
IsUnderPostmaster = true; /* we are a postmaster subprocess now */
|
||||
@ -1700,7 +1702,7 @@ PgstatCollectorMain(int argc, char *argv[])
|
||||
* Setup the descriptor set for select(2). Since only one bit in the set
|
||||
* ever changes, we need not repeat FD_ZERO each time.
|
||||
*/
|
||||
#ifndef HAVE_POLL
|
||||
#if !defined(HAVE_POLL) && !defined(WIN32)
|
||||
FD_ZERO(&rfds);
|
||||
#endif
|
||||
|
||||
@ -1747,8 +1749,10 @@ PgstatCollectorMain(int argc, char *argv[])
|
||||
* poll/select call, so this also limits speed of response to SIGQUIT,
|
||||
* which is more important.)
|
||||
*
|
||||
* We use poll(2) if available, otherwise select(2)
|
||||
* We use poll(2) if available, otherwise select(2).
|
||||
* Win32 has its own implementation.
|
||||
*/
|
||||
#ifndef WIN32
|
||||
#ifdef HAVE_POLL
|
||||
input_fd.fd = pgStatSock;
|
||||
input_fd.events = POLLIN | POLLERR;
|
||||
@ -1786,6 +1790,10 @@ PgstatCollectorMain(int argc, char *argv[])
|
||||
|
||||
got_data = FD_ISSET(pgStatSock, &rfds);
|
||||
#endif /* HAVE_POLL */
|
||||
#else /* WIN32 */
|
||||
got_data = pgwin32_waitforsinglesocket(pgStatSock, FD_READ,
|
||||
PGSTAT_SELECT_TIMEOUT*1000);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If there is a message on the socket, read it and check for
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.63.2.1 2007/01/11 02:40:12 momjian Exp $ */
|
||||
/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.63.2.2 2007/01/26 20:07:01 tgl Exp $ */
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
#define WIN32_ONLY_COMPILER
|
||||
@ -250,7 +250,7 @@ int pgwin32_recv(SOCKET s, char *buf, int len, int flags);
|
||||
int pgwin32_send(SOCKET s, char *buf, int len, int flags);
|
||||
|
||||
const char *pgwin32_socket_strerror(int err);
|
||||
int pgwin32_waitforsinglesocket(SOCKET s, int what);
|
||||
int pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout);
|
||||
|
||||
/* in backend/port/win32/security.c */
|
||||
extern int pgwin32_is_admin(void);
|
||||
|
Loading…
Reference in New Issue
Block a user