Re: vacuumlo - use a cursor - Mailing list pgsql-hackers
From | Bruce Momjian |
---|---|
Subject | Re: vacuumlo - use a cursor |
Date | |
Msg-id | 20130629152349.GC23294@momjian.us Whole thread Raw |
In response to | vacuumlo - use a cursor (Andrew Dunstan <andrew@dunslane.net>) |
Responses |
Re: vacuumlo - use a cursor
|
List | pgsql-hackers |
Is there a reason this patch was not applied? --------------------------------------------------------------------------- On Mon, Nov 12, 2012 at 05:14:57PM -0500, Andrew Dunstan wrote: > vacuumlo is rather simpleminded about dealing with the list of LOs > to be removed - it just fetches them as a straight resultset. For > one of my our this resulted in an out of memory condition. The > attached patch tries to remedy that by using a cursor instead. If > this is wanted I will add it to the next commitfest. The actualy > changes are very small - most of the patch is indentation changes > due to the introduction of an extra loop. > > cheers > > andrew > *** a/contrib/vacuumlo/vacuumlo.c > --- b/contrib/vacuumlo/vacuumlo.c > *************** > *** 290,362 **** vacuumlo(const char *database, const struct _param * param) > PQclear(res); > > buf[0] = '\0'; > ! strcat(buf, "SELECT lo FROM vacuum_l"); > ! res = PQexec(conn, buf); > ! if (PQresultStatus(res) != PGRES_TUPLES_OK) > ! { > ! fprintf(stderr, "Failed to read temp table:\n"); > ! fprintf(stderr, "%s", PQerrorMessage(conn)); > ! PQclear(res); > PQfinish(conn); > return -1; > ! } > > - matched = PQntuples(res); > deleted = 0; > ! for (i = 0; i < matched; i++) > { > ! Oid lo = atooid(PQgetvalue(res, i, 0)); > > ! if (param->verbose) > { > ! fprintf(stdout, "\rRemoving lo %6u ", lo); > ! fflush(stdout); > } > > ! if (param->dry_run == 0) > { > ! if (lo_unlink(conn, lo) < 0) > { > ! fprintf(stderr, "\nFailed to remove lo %u: ", lo); > ! fprintf(stderr, "%s", PQerrorMessage(conn)); > ! if (PQtransactionStatus(conn) == PQTRANS_INERROR) > { > ! success = false; > ! break; > } > } > else > deleted++; > ! } > ! else > ! deleted++; > ! if (param->transaction_limit > 0 && > ! (deleted % param->transaction_limit) == 0) > ! { > ! res2 = PQexec(conn, "commit"); > ! if (PQresultStatus(res2) != PGRES_COMMAND_OK) > { > ! fprintf(stderr, "Failed to commit transaction:\n"); > ! fprintf(stderr, "%s", PQerrorMessage(conn)); > PQclear(res2); > ! PQclear(res); > ! PQfinish(conn); > ! return -1; > ! } > ! PQclear(res2); > ! res2 = PQexec(conn, "begin"); > ! if (PQresultStatus(res2) != PGRES_COMMAND_OK) > ! { > ! fprintf(stderr, "Failed to start transaction:\n"); > ! fprintf(stderr, "%s", PQerrorMessage(conn)); > PQclear(res2); > - PQclear(res); > - PQfinish(conn); > - return -1; > } > - PQclear(res2); > } > } > PQclear(res); > > /* > --- 290,389 ---- > PQclear(res); > > buf[0] = '\0'; > ! 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 " INT64_FORMAT " IN myportal", > ! param->transaction_limit > 0 ? param->transaction_limit : 1000); > > deleted = 0; > ! > ! while (1) > { > ! res = PQexec(conn, buf); > ! if (PQresultStatus(res) != PGRES_TUPLES_OK) > ! { > ! fprintf(stderr, "Failed to read temp table:\n"); > ! fprintf(stderr, "%s", PQerrorMessage(conn)); > ! PQclear(res); > ! PQfinish(conn); > ! return -1; > ! } > > ! matched = PQntuples(res); > ! > ! if (matched <= 0) > { > ! /* at end of resultset */ > ! break; > } > > ! for (i = 0; i < matched; i++) > { > ! Oid lo = atooid(PQgetvalue(res, i, 0)); > ! > ! if (param->verbose) > ! { > ! fprintf(stdout, "\rRemoving lo %6u ", lo); > ! fflush(stdout); > ! } > ! > ! if (param->dry_run == 0) > { > ! if (lo_unlink(conn, lo) < 0) > { > ! fprintf(stderr, "\nFailed to remove lo %u: ", lo); > ! fprintf(stderr, "%s", PQerrorMessage(conn)); > ! if (PQtransactionStatus(conn) == PQTRANS_INERROR) > ! { > ! success = false; > ! break; > ! } > } > + else > + deleted++; > } > else > deleted++; > ! > ! if (param->transaction_limit > 0 && > ! (deleted % param->transaction_limit) == 0) > { > ! res2 = PQexec(conn, "commit"); > ! if (PQresultStatus(res2) != PGRES_COMMAND_OK) > ! { > ! fprintf(stderr, "Failed to commit transaction:\n"); > ! fprintf(stderr, "%s", PQerrorMessage(conn)); > ! PQclear(res2); > ! PQclear(res); > ! PQfinish(conn); > ! return -1; > ! } > PQclear(res2); > ! res2 = PQexec(conn, "begin"); > ! if (PQresultStatus(res2) != PGRES_COMMAND_OK) > ! { > ! fprintf(stderr, "Failed to start transaction:\n"); > ! fprintf(stderr, "%s", PQerrorMessage(conn)); > ! PQclear(res2); > ! PQclear(res); > ! PQfinish(conn); > ! return -1; > ! } > PQclear(res2); > } > } > } > + > PQclear(res); > > /* > > -- > Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) > To make changes to your subscription: > http://www.postgresql.org/mailpref/pgsql-hackers -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. +
pgsql-hackers by date: