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