vacuumlo: Use a cursor to limit client-side memory usage.

This prevents the client from gobbling up too much memory when the
number of large objects to be removed is very large.

Andrew Dunstan, reviewed by Josh Kupershmidt
This commit is contained in:
Robert Haas 2013-07-15 10:48:44 -04:00
parent 03010366b6
commit 67ccbb080d

View File

@ -290,19 +290,42 @@ vacuumlo(const char *database, const struct _param * param)
PQclear(res); PQclear(res);
buf[0] = '\0'; buf[0] = '\0';
strcat(buf, "SELECT lo FROM vacuum_l"); strcat(buf,
"DECLARE myportal CURSOR WITH HOLD FOR SELECT lo FROM vacuum_l");
res = PQexec(conn, buf);
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn));
PQclear(res);
PQfinish(conn);
return -1;
}
PQclear(res);
snprintf(buf, BUFSIZE, "FETCH FORWARD %ld IN myportal",
param->transaction_limit > 0 ? param->transaction_limit : 1000L);
deleted = 0;
while (1)
{
res = PQexec(conn, buf); res = PQexec(conn, buf);
if (PQresultStatus(res) != PGRES_TUPLES_OK) if (PQresultStatus(res) != PGRES_TUPLES_OK)
{ {
fprintf(stderr, "Failed to read temp table:\n"); fprintf(stderr, "FETCH FORWARD failed: %s", PQerrorMessage(conn));
fprintf(stderr, "%s", PQerrorMessage(conn));
PQclear(res); PQclear(res);
PQfinish(conn); PQfinish(conn);
return -1; return -1;
} }
matched = PQntuples(res); matched = PQntuples(res);
deleted = 0; if (matched <= 0)
{
/* at end of resultset */
PQclear(res);
break;
}
for (i = 0; i < matched; i++) for (i = 0; i < matched; i++)
{ {
Oid lo = atooid(PQgetvalue(res, i, 0)); Oid lo = atooid(PQgetvalue(res, i, 0));
@ -322,6 +345,7 @@ vacuumlo(const char *database, const struct _param * param)
if (PQtransactionStatus(conn) == PQTRANS_INERROR) if (PQtransactionStatus(conn) == PQTRANS_INERROR)
{ {
success = false; success = false;
PQclear(res);
break; break;
} }
} }
@ -330,6 +354,7 @@ vacuumlo(const char *database, const struct _param * param)
} }
else else
deleted++; deleted++;
if (param->transaction_limit > 0 && if (param->transaction_limit > 0 &&
(deleted % param->transaction_limit) == 0) (deleted % param->transaction_limit) == 0)
{ {
@ -357,7 +382,9 @@ vacuumlo(const char *database, const struct _param * param)
PQclear(res2); PQclear(res2);
} }
} }
PQclear(res); PQclear(res);
}
/* /*
* That's all folks! * That's all folks!