Skip to content

Commit b69f2e3

Browse files
committed
Teach vacuumlo to limit number of removals, via new -l option.
Also, handle failure better: don't just blindly keep trying to delete stuff after the transaction has already failed. Tim Lewis, reviewed by Josh Kupershmidt, with further hacking by me.
1 parent f54e373 commit b69f2e3

File tree

2 files changed

+47
-6
lines changed

2 files changed

+47
-6
lines changed

contrib/vacuumlo/vacuumlo.c

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ struct _param
4848
char *pg_host;
4949
int verbose;
5050
int dry_run;
51+
long transaction_limit;
5152
};
5253

5354
int vacuumlo(char *, struct _param *);
@@ -65,11 +66,12 @@ vacuumlo(char *database, struct _param * param)
6566
PGresult *res,
6667
*res2;
6768
char buf[BUFSIZE];
68-
int matched;
69-
int deleted;
69+
long matched;
70+
long deleted;
7071
int i;
7172
static char *password = NULL;
7273
bool new_pass;
74+
bool success = true;
7375

7476
if (param->pg_prompt == TRI_YES && password == NULL)
7577
password = simple_prompt("Password: ", 100, false);
@@ -280,12 +282,19 @@ vacuumlo(char *database, struct _param * param)
280282
{
281283
fprintf(stderr, "\nFailed to remove lo %u: ", lo);
282284
fprintf(stderr, "%s", PQerrorMessage(conn));
285+
if (PQtransactionStatus(conn) == PQTRANS_INERROR)
286+
{
287+
success = false;
288+
break;
289+
}
283290
}
284291
else
285292
deleted++;
286293
}
287294
else
288295
deleted++;
296+
if (param->transaction_limit != 0 && deleted >= param->transaction_limit)
297+
break;
289298
}
290299
PQclear(res);
291300

@@ -298,10 +307,20 @@ vacuumlo(char *database, struct _param * param)
298307
PQfinish(conn);
299308

300309
if (param->verbose)
301-
fprintf(stdout, "\r%s %d large objects from %s.\n",
302-
(param->dry_run ? "Would remove" : "Removed"), deleted, database);
310+
{
311+
if (param->dry_run)
312+
fprintf(stdout, "\rWould remove %ld large objects from %s.\n",
313+
deleted, database);
314+
else if (success)
315+
fprintf(stdout,
316+
"\rSuccessfully removed %ld large objects from %s.\n",
317+
deleted, database);
318+
else
319+
fprintf(stdout, "\rRemoval from %s failed at object %ld of %ld.\n",
320+
database, deleted, matched);
321+
}
303322

304-
return 0;
323+
return ((param->dry_run || success) ? 0 : -1);
305324
}
306325

307326
void
@@ -311,6 +330,7 @@ usage(const char *progname)
311330
printf("Usage:\n %s [OPTION]... DBNAME...\n\n", progname);
312331
printf("Options:\n");
313332
printf(" -h HOSTNAME database server host or socket directory\n");
333+
printf(" -l LIMIT stop after removing LIMIT large objects\n");
314334
printf(" -n don't remove large objects, just show what would be done\n");
315335
printf(" -p PORT database server port\n");
316336
printf(" -U USERNAME user name to connect as\n");
@@ -342,6 +362,7 @@ main(int argc, char **argv)
342362
param.pg_port = NULL;
343363
param.verbose = 0;
344364
param.dry_run = 0;
365+
param.transaction_limit = 0;
345366

346367
if (argc > 1)
347368
{
@@ -359,7 +380,7 @@ main(int argc, char **argv)
359380

360381
while (1)
361382
{
362-
c = getopt(argc, argv, "h:U:p:vnwW");
383+
c = getopt(argc, argv, "h:l:U:p:vnwW");
363384
if (c == -1)
364385
break;
365386

@@ -395,6 +416,16 @@ main(int argc, char **argv)
395416
}
396417
param.pg_port = strdup(optarg);
397418
break;
419+
case 'l':
420+
param.transaction_limit = strtol(optarg, NULL, 10);
421+
if (param.transaction_limit < 0)
422+
{
423+
fprintf(stderr,
424+
"%s: transaction limit must not be negative (0 disables)\n",
425+
progname);
426+
exit(1);
427+
}
428+
break;
398429
case 'h':
399430
param.pg_host = strdup(optarg);
400431
break;

doc/src/sgml/vacuumlo.sgml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@ vacuumlo [options] database [database2 ... databaseN]
5656
</listitem>
5757
</varlistentry>
5858

59+
<varlistentry>
60+
<term><option>-l</option> <replaceable>limit</></term>
61+
<listitem>
62+
<para>
63+
Stop after removing LIMIT large objects. Useful to avoid
64+
exceeding <xref linkend="guc-max-locks-per-transaction">.
65+
</para>
66+
</listitem>
67+
</varlistentry>
68+
5969
<varlistentry>
6070
<term><option>-w</></term>
6171
<term><option>--no-password</></term>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy