On Friday October 10 2003 4:46, Ed L. wrote:
> I have libpq client program that repeatedly connects to a DB, queries,
> and then disconnects. After a seemingly random number of such successful
> sessions (sometimes 30, sometimes hundreds), the backend mysteriously
> exits after the client calls PQsetdbLogin(), and the client hangs. Any
> clues? Details below...
>
> Client: C program linked with 7.2.1 libpq on HP-UX B.11.00 E 9000/803.
> Server: PostgreSQL 7.3.2 on i686-pc-linux-gnu, compiled by GCC 2.96.
Still looking for clues as to the cause of this repeatable connection
failure. Passing an explicit connection timeout to PQconnectdb() escapes
from any long hangs, but the hanging is still an issue I'd like to
understand. Attached is a small C program that reliably reproduces this
problem on the setup above. I added an explicit timeout to PQconnectdb()
to wait only 30 seconds. I'm curious to know if anyone can easily repeat
the problem (careful, it will generate a bit of traffic, cpu load, and run
forever). My last example run showed 17 timeouts seemingly randomly
dispersed among 5000 consecutive connection attempts.
The server has plenty of available memory on a dual processor machine
running Linux 2.4.18-3smp. Tried to catch snapshot data from netstat on
Recv-Q and Send-Q sizes on the server during a hang... that's a little iffy
with the timing of grepping netstat output, but seems like the server's
Recv-Q's were always zero and the Send-Q's were occasional in the tens
(bytes?).
TIA for any help.
/*
* test program to demonstrate connection hangs
*/
#include <stdio.h>
#include "libpq-fe.h"
static int tries = 0;
static int successes = 0;
void logmsg(const char *msg) {
char timestamp[256];
time_t t;
t = time(NULL);
strcpy(timestamp, asctime(localtime(&t)));
timestamp[strlen(timestamp)-1] = '\0';
fprintf(stderr,"%s [%d] %s\n", timestamp, getpid(), msg);
fflush(stderr);
}
const char* get_dbhname(PGconn *conn, char *dbhname)
{
sprintf(dbhname, "[EMAIL PROTECTED]:%s:%s:%d",
PQuser(conn), PQhost(conn), PQport(conn),
PQdb(conn), PQbackendPID(conn));
return dbhname;
}
main()
{
char msg[1024];
char dbhname[1024];
PGconn *conn;
PGresult *res;
if ( ! (getenv("PGPORT") && getenv("PGHOST") &&
getenv("PGUSER") && getenv("PGDATABASE") ) ) {
logmsg("Please export PGPORT, PGUSER, PGHOST, and PGDATABASE for me.");
exit(-1);
}
sprintf(dbhname, "[EMAIL PROTECTED]:%s:db=%s",
getenv("PGUSER"), getenv("PGHOST"),
getenv("PGPORT"), getenv("PGDATABASE"));
while ( 1 ) {
tries++;
sprintf(msg,"[%d/%d] Connecting to %s", tries, successes, dbhname);
logmsg(msg);
conn = PQconnectdb("connect_timeout=30");
if (PQstatus(conn) == CONNECTION_BAD)
{
sprintf(msg, "Connection to database '%s' failed.",
getenv("PGDATABASE"));
logmsg(msg);
sprintf(msg, "%s", PQerrorMessage(conn));
logmsg(msg);
PQfinish(conn);
return 0;
}
successes++;
res = PQexec(conn, "SELECT version()");
if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
{
sprintf(msg, "SELECT query failed");
logmsg(msg);
PQclear(res);
PQfinish(conn);
return 0;
}
PQclear(res);
sprintf(msg,"[%d/%d] Closing connection to %s",
tries, successes, get_dbhname(conn,dbhname));
logmsg(msg);
PQfinish(conn);
}
return 0;
}
---------------------------(end of broadcast)---------------------------
TIP 3: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to [EMAIL PROTECTED] so that your
message can get through to the mailing list cleanly