From 94bb87f94b181898c2833a628744c67035bfb628 Mon Sep 17 00:00:00 2001 From: Peter Mount Date: Sat, 10 Apr 1999 16:48:05 +0000 Subject: [PATCH] vacuumlo deals with large objects not referenced by any tables and removes them. --- contrib/vacuumlo/Makefile | 24 +++++ contrib/vacuumlo/README | 38 +++++++ contrib/vacuumlo/vacuumlo.c | 201 ++++++++++++++++++++++++++++++++++++ 3 files changed, 263 insertions(+) create mode 100644 contrib/vacuumlo/Makefile create mode 100644 contrib/vacuumlo/README create mode 100644 contrib/vacuumlo/vacuumlo.c diff --git a/contrib/vacuumlo/Makefile b/contrib/vacuumlo/Makefile new file mode 100644 index 0000000000..95214acb98 --- /dev/null +++ b/contrib/vacuumlo/Makefile @@ -0,0 +1,24 @@ +# $Header: /cvsroot/pgsql/contrib/vacuumlo/Makefile,v 1.1 1999/04/10 16:48:04 peter Exp $ + +SRCDIR= ../../src + +include $(SRCDIR)/Makefile.global + +CONTRIBDIR=$(LIBDIR)/contrib + +CFLAGS+= -I$(HEADERDIR) + +TARGETS= vacuumlo +CLEANFILES+= $(TARGETS) +CURDIR=`pwd` + +all:: $(TARGETS) + +$(TARGETS): vacuumlo.o + $(CC) -o vacuumlo -L $(LIBDIR) -lpq -lcrypt vacuumlo.o + +clean: + rm -f $(TARGETS) *.o + +dist: + tar cf vacuumlo.tar README Makefile vacuumlo.c diff --git a/contrib/vacuumlo/README b/contrib/vacuumlo/README new file mode 100644 index 0000000000..2c3c93de15 --- /dev/null +++ b/contrib/vacuumlo/README @@ -0,0 +1,38 @@ +$Header: /cvsroot/pgsql/contrib/vacuumlo/Attic/README,v 1.1 1999/04/10 16:48:04 peter Exp $ + +This is a simple utility that will remove any orphaned large objects out of a +PostgreSQL database. + +Compiling +-------- + +Simply run make. A single executable "vacuumlo" is created. + +Useage +------ + +vacuumlo [-v] database [db2 ... dbn] + +The -v flag outputs some progress messages to stdout. + +Method +------ + +First, it builds a temporary table which contains all of the oid's of the +large objects in that database. + +It then scans through any columns in the database that are of type 'oid', and +removes any entries from the temporary table. + +Finally, it runs through the first table, and removes from the second table, any +oid's it finds. What is left are the orphans, and these are removed. + +I decided to place this in contrib as it needs further testing, but hopefully, +this (or a variant of it) would make it into the backed as a "vacuum lo" command +in a later release. + +Peter Mount +http://www.retep.org.uk +March 21 1999 + +Committed April 10 1999 Peter diff --git a/contrib/vacuumlo/vacuumlo.c b/contrib/vacuumlo/vacuumlo.c new file mode 100644 index 0000000000..8b893f26e2 --- /dev/null +++ b/contrib/vacuumlo/vacuumlo.c @@ -0,0 +1,201 @@ +/*------------------------------------------------------------------------- + * + * vacuumlo.c + * This removes orphaned large objects from a database. + * + * Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * $Header: /cvsroot/pgsql/contrib/vacuumlo/vacuumlo.c,v 1.1 1999/04/10 16:48:05 peter Exp $ + * + *------------------------------------------------------------------------- + */ +#include +#include +#include + +#include +#include +#include +#include + +#include "libpq-fe.h" +#include "libpq/libpq-fs.h" + +#define BUFSIZE 1024 + +int vacuumlo(char *,int); + + +/* + * This vacuums a database. It returns 1 on success, -1 on failure. + */ +int vacuumlo(char *database,int verbose) +{ + PGconn *conn; + PGresult *res, *res2; + char buf[BUFSIZE]; + int matched=0; /* Number matched per scan */ + int i; + + conn = PQsetdb(NULL, NULL, NULL, NULL, database); + + /* check to see that the backend connection was successfully made */ + if (PQstatus(conn) == CONNECTION_BAD) + { + fprintf(stderr, "Connection to database '%s' failed.\n", database); + fprintf(stderr, "%s", PQerrorMessage(conn)); + return -1; + } + + if(verbose) + fprintf(stdout,"Connected to %s\n",database); + + /* + * First we create and populate the lo temp table + */ + buf[0]='\0'; + strcat(buf,"SELECT oid AS lo "); + strcat(buf,"INTO TEMP TABLE vacuum_l "); + strcat(buf,"FROM pg_class "); + strcat(buf,"WHERE relkind='l'"); + if(!(res = PQexec(conn,buf))) { + fprintf(stderr,"Failed to create temp table.\n"); + PQfinish(conn); + return -1; + } + PQclear(res); + + /* + * Now find any candidate tables who have columns of type oid (the column + * oid is ignored, as it has attnum < 1) + */ + buf[0]='\0'; + strcat(buf,"SELECT c.relname, a.attname "); + strcat(buf,"FROM pg_class c, pg_attribute a, pg_type t "); + strcat(buf,"WHERE a.attnum > 0 "); + strcat(buf," AND a.attrelid = c.oid "); + strcat(buf," AND a.atttypid = t.oid "); + strcat(buf," AND t.typname = 'oid' "); + strcat(buf," AND c.relname NOT LIKE 'pg_%'"); + if(!(res = PQexec(conn,buf))) { + fprintf(stderr,"Failed to create temp table.\n"); + PQfinish(conn); + return -1; + } + for(i=0;i