* Bruce Momjian wrote: > I think what you are seeing is that the getaddrinfo memory is placed in > the PGconn structure that isn't freed until PQclear is called. Does > your test call PQclear()?
s/PQclear/PQfinish/ It does call PQclear on the result, and PQfinish on the connection. The code is attached. With postgres doing the dns lookup: fubar:~# while true; do ps aux|grep -v grep|grep test; sleep 30; done root 3245 3.6 0.2 4056 1352 pts/3 S+ 10:37 0:01 ./test root 3245 3.6 0.3 4056 1456 pts/3 S+ 10:37 0:02 ./test root 3245 3.7 0.3 4184 1560 pts/3 S+ 10:37 0:03 ./test root 3245 3.7 0.3 4312 1668 pts/3 R+ 10:37 0:04 ./test root 3245 3.6 0.3 4440 1760 pts/3 S+ 10:37 0:05 ./test with an output of: called PQconnectdb: 0x804a008 called PQexec: 0x80dcbe0 calling PQclear: 0x80dcbe0 calling PQfinish: 0x804a008 ... called PQconnectdb: 0x804a008 called PQexec: 0x80dcea0 calling PQclear: 0x80dcea0 calling PQfinish: 0x804a008 ... called PQconnectdb: 0x804a008 called PQexec: 0x80dd620 calling PQclear: 0x80dd620 calling PQfinish: 0x804a008 ... and valgrind complaining about lost blocks: ==3290== 35224 bytes in 1258 blocks are definitely lost in loss record 8 of 8 ==3290== at 0x1B90459D: malloc (vg_replace_malloc.c:130) ==3290== by 0x1BC38E3B: (within /lib/tls/i686/cmov/libresolv-2.3.2.so) ==3290== by 0x1BC37B92: __libc_res_nquery (in /lib/tls/i686/cmov/libresolv-2.3.2.so) ==3290== by 0x1BC38289: (within /lib/tls/i686/cmov/libresolv-2.3.2.so) ==3290== by 0x1BC37E8F: __libc_res_nsearch (in /lib/tls/i686/cmov/libresolv-2.3.2.so) ==3290== by 0x1BDA307D: ??? ==3290== by 0x1B9EFA65: (within /lib/tls/i686/cmov/libc-2.3.2.so) ==3290== by 0x1B9F0673: getaddrinfo (in /lib/tls/i686/cmov/libc-2.3.2.so) ==3290== by 0x1B925701: getaddrinfo_all (in /usr/lib/libpq.so.3.1) ==3290== by 0x1B916F0B: (within /usr/lib/libpq.so.3.1) ==3290== by 0x1B9164B9: PQconnectStart (in /usr/lib/libpq.so.3.1) ==3290== by 0x1B916441: PQconnectdb (in /usr/lib/libpq.so.3.1) With the IP in the host field: fubar:~# while true; do ps aux|grep -v grep|grep test; sleep 30; done root 3312 1.4 0.2 3872 1092 pts/3 S+ 10:42 0:00 ./test root 3312 1.6 0.2 3872 1092 pts/3 S+ 10:42 0:00 ./test root 3312 1.9 0.2 3872 1092 pts/3 S+ 10:42 0:01 ./test root 3312 2.0 0.2 3872 1092 pts/3 S+ 10:42 0:01 ./test root 3312 2.0 0.2 3872 1092 pts/3 S+ 10:42 0:02 ./test output: called PQconnectdb: 0x804a008 called PQexec: 0x80525b8 calling PQclear: 0x80525b8 calling PQfinish: 0x804a008 ... called PQconnectdb: 0x804a008 called PQexec: 0x80525b8 calling PQclear: 0x80525b8 calling PQfinish: 0x804a008 ... called PQconnectdb: 0x804a008 called PQexec: 0x80525b8 calling PQclear: 0x80525b8 calling PQfinish: 0x804a008 ... and no leaking output from valgrind. Best regards, Karsten Desler
#include <postgresql/libpq-fe.h> #include <stdio.h> // gcc -lpq -o test test.c static const char *conninfo = "host=xxx.xxx.xx.xx port=5432 dbname=xxx user=xxx password=xxx connect_timeout=30"; // static const char *conninfo = "host=db.xxx.de port=5432 dbname=xxx user=xxx password=xxx connect_timeout=30"; static int fetch_from_database(void) { PGconn *conn; PGresult *res; char sql[32768]; int c_username, c_ip; int ret = -1; unsigned int max, i; conn = PQconnectdb(conninfo); printf("called PQconnectdb: %p\n", conn); if (!conn) { printf("connection failed\n"); goto out_finish; } snprintf(sql, sizeof(sql), "SELECT username,ip FROM extras WHERE server=(SELECT id FROM servers WHERE IP='xxx.xxx.xx.xx') ORDER BY username"); res = PQexec(conn, sql); printf("called PQexec: %p\n", res); if (PQresultStatus(res) != PGRES_TUPLES_OK) { printf("couldn't get data\n"); goto out; } max = (unsigned int)PQntuples(res); if (max == 0) { ret = 0; goto out; } if (max > 64) { printf("too many results\n"); goto out; } c_username = PQfnumber(res, "username"); c_ip = PQfnumber(res, "ip"); if (c_username == -1 || c_ip == -1) { printf("weird table structure found\n"); goto out; } for (i = 0; i < max; i++) { (void)PQgetvalue(res, i, c_username); (void)PQgetvalue(res, i, c_ip); } ret = 0; out: printf("calling PQclear: %p\n", res); PQclear(res); out_finish: printf("calling PQfinish: %p\n", conn); PQfinish(conn); res = NULL; conn = NULL; return ret; } int main(void) { while(fetch_from_database() == 0); return 0; }
---------------------------(end of broadcast)--------------------------- TIP 9: In versions below 8.0, the planner will ignore your desire to choose an index scan if your joining column's datatypes do not match