Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit94bb87f

Browse files
author
Peter Mount
committed
vacuumlo deals with large objects not referenced by any tables and removes them.
1 parent098e043 commit94bb87f

File tree

3 files changed

+263
-0
lines changed

3 files changed

+263
-0
lines changed

‎contrib/vacuumlo/Makefile

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# $Header: /cvsroot/pgsql/contrib/vacuumlo/Makefile,v 1.1 1999/04/10 16:48:04 peter Exp $
2+
3+
SRCDIR= ../../src
4+
5+
include$(SRCDIR)/Makefile.global
6+
7+
CONTRIBDIR=$(LIBDIR)/contrib
8+
9+
CFLAGS+= -I$(HEADERDIR)
10+
11+
TARGETS= vacuumlo
12+
CLEANFILES+=$(TARGETS)
13+
CURDIR=`pwd`
14+
15+
all::$(TARGETS)
16+
17+
$(TARGETS): vacuumlo.o
18+
$(CC) -o vacuumlo -L$(LIBDIR) -lpq -lcrypt vacuumlo.o
19+
20+
clean:
21+
rm -f$(TARGETS)*.o
22+
23+
dist:
24+
tar cf vacuumlo.tar README Makefile vacuumlo.c

‎contrib/vacuumlo/README

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
$Header: /cvsroot/pgsql/contrib/vacuumlo/Attic/README,v 1.1 1999/04/10 16:48:04 peter Exp $
2+
3+
This is a simple utility that will remove any orphaned large objects out of a
4+
PostgreSQL database.
5+
6+
Compiling
7+
--------
8+
9+
Simply run make. A single executable "vacuumlo" is created.
10+
11+
Useage
12+
------
13+
14+
vacuumlo [-v] database [db2 ... dbn]
15+
16+
The -v flag outputs some progress messages to stdout.
17+
18+
Method
19+
------
20+
21+
First, it builds a temporary table which contains all of the oid's of the
22+
large objects in that database.
23+
24+
It then scans through any columns in the database that are of type 'oid', and
25+
removes any entries from the temporary table.
26+
27+
Finally, it runs through the first table, and removes from the second table, any
28+
oid's it finds. What is left are the orphans, and these are removed.
29+
30+
I decided to place this in contrib as it needs further testing, but hopefully,
31+
this (or a variant of it) would make it into the backed as a "vacuum lo" command
32+
in a later release.
33+
34+
Peter Mount <peter@retep.org.uk>
35+
http://www.retep.org.uk
36+
March 21 1999
37+
38+
Committed April 10 1999 Peter

‎contrib/vacuumlo/vacuumlo.c

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* vacuumlo.c
4+
* This removes orphaned large objects from a database.
5+
*
6+
* Copyright (c) 1994, Regents of the University of California
7+
*
8+
*
9+
* IDENTIFICATION
10+
* $Header: /cvsroot/pgsql/contrib/vacuumlo/vacuumlo.c,v 1.1 1999/04/10 16:48:05 peter Exp $
11+
*
12+
*-------------------------------------------------------------------------
13+
*/
14+
#include<stdio.h>
15+
#include<stdlib.h>
16+
#include<strings.h>
17+
18+
#include<sys/types.h>
19+
#include<sys/stat.h>
20+
#include<fcntl.h>
21+
#include<unistd.h>
22+
23+
#include"libpq-fe.h"
24+
#include"libpq/libpq-fs.h"
25+
26+
#defineBUFSIZE1024
27+
28+
intvacuumlo(char*,int);
29+
30+
31+
/*
32+
* This vacuums a database. It returns 1 on success, -1 on failure.
33+
*/
34+
intvacuumlo(char*database,intverbose)
35+
{
36+
PGconn*conn;
37+
PGresult*res,*res2;
38+
charbuf[BUFSIZE];
39+
intmatched=0;/* Number matched per scan */
40+
inti;
41+
42+
conn=PQsetdb(NULL,NULL,NULL,NULL,database);
43+
44+
/* check to see that the backend connection was successfully made */
45+
if (PQstatus(conn)==CONNECTION_BAD)
46+
{
47+
fprintf(stderr,"Connection to database '%s' failed.\n",database);
48+
fprintf(stderr,"%s",PQerrorMessage(conn));
49+
return-1;
50+
}
51+
52+
if(verbose)
53+
fprintf(stdout,"Connected to %s\n",database);
54+
55+
/*
56+
* First we create and populate the lo temp table
57+
*/
58+
buf[0]='\0';
59+
strcat(buf,"SELECT oid AS lo ");
60+
strcat(buf,"INTO TEMP TABLE vacuum_l ");
61+
strcat(buf,"FROM pg_class ");
62+
strcat(buf,"WHERE relkind='l'");
63+
if(!(res=PQexec(conn,buf))) {
64+
fprintf(stderr,"Failed to create temp table.\n");
65+
PQfinish(conn);
66+
return-1;
67+
}
68+
PQclear(res);
69+
70+
/*
71+
* Now find any candidate tables who have columns of type oid (the column
72+
* oid is ignored, as it has attnum < 1)
73+
*/
74+
buf[0]='\0';
75+
strcat(buf,"SELECT c.relname, a.attname ");
76+
strcat(buf,"FROM pg_class c, pg_attribute a, pg_type t ");
77+
strcat(buf,"WHERE a.attnum > 0 ");
78+
strcat(buf," AND a.attrelid = c.oid ");
79+
strcat(buf," AND a.atttypid = t.oid ");
80+
strcat(buf," AND t.typname = 'oid' ");
81+
strcat(buf," AND c.relname NOT LIKE 'pg_%'");
82+
if(!(res=PQexec(conn,buf))) {
83+
fprintf(stderr,"Failed to create temp table.\n");
84+
PQfinish(conn);
85+
return-1;
86+
}
87+
for(i=0;i<PQntuples(res);i++)
88+
{
89+
char*table,*field;
90+
91+
table=PQgetvalue(res,i,0);
92+
field=PQgetvalue(res,i,1);
93+
94+
if(verbose) {
95+
fprintf(stdout,"Checking %s in %s: ",field,table);
96+
fflush(stdout);
97+
}
98+
99+
res2=PQexec(conn,"begin");
100+
PQclear(res2);
101+
102+
buf[0]='\0';
103+
strcat(buf,"DELETE FROM vacuum_l ");
104+
strcat(buf,"WHERE lo IN (");
105+
strcat(buf,"SELECT ");
106+
strcat(buf,field);
107+
strcat(buf," FROM ");
108+
strcat(buf,table);
109+
strcat(buf,");");
110+
if(!(res2=PQexec(conn,buf))) {
111+
fprintf(stderr,"Failed to check %s in table %s\n",field,table);
112+
PQclear(res);
113+
PQfinish(conn);
114+
return-1;
115+
}
116+
if(PQresultStatus(res2)!=PGRES_COMMAND_OK) {
117+
fprintf(stderr,
118+
"Failed to check %s in table %s\n%s\n",
119+
field,table,
120+
PQerrorMessage(conn)
121+
);
122+
PQclear(res2);
123+
PQclear(res);
124+
PQfinish(conn);
125+
return-1;
126+
}
127+
PQclear(res2);
128+
129+
res2=PQexec(conn,"end");
130+
PQclear(res2);
131+
132+
}
133+
PQclear(res);
134+
135+
/* Start the transaction */
136+
res=PQexec(conn,"begin");
137+
PQclear(res);
138+
139+
/*
140+
* Finally, those entries remaining in vacuum_l are orphans.
141+
*/
142+
buf[0]='\0';
143+
strcat(buf,"SELECT lo ");
144+
strcat(buf,"FROM vacuum_l");
145+
if(!(res=PQexec(conn,buf))) {
146+
fprintf(stderr,"Failed to read temp table.\n");
147+
PQfinish(conn);
148+
return-1;
149+
}
150+
matched=PQntuples(res);
151+
for(i=0;i<matched;i++)
152+
{
153+
Oidlo= (Oid)atoi(PQgetvalue(res,i,0));
154+
155+
if(verbose) {
156+
fprintf(stdout,"\rRemoving lo %6d \n",lo);
157+
fflush(stdout);
158+
}
159+
160+
if(lo_unlink(conn,lo)<0) {
161+
fprintf(stderr,"Failed to remove lo %d\n",lo);
162+
}
163+
}
164+
PQclear(res);
165+
166+
/*
167+
* That's all folks!
168+
*/
169+
res=PQexec(conn,"end");
170+
PQclear(res);
171+
PQfinish(conn);
172+
173+
if(verbose)
174+
fprintf(stdout,"\rRemoved %d large objects from %s.\n",matched,database);
175+
176+
return0;
177+
}
178+
179+
int
180+
main(intargc,char**argv)
181+
{
182+
intverbose=0;
183+
intarg;
184+
intrc=0;
185+
186+
if (argc<2)
187+
{
188+
fprintf(stderr,"Usage: %s [-v] database_name [db2 ... dbn]\n",
189+
argv[0]);
190+
exit(1);
191+
}
192+
193+
for(arg=1;arg<argc;arg++) {
194+
if(strcmp("-v",argv[arg])==0)
195+
verbose=!verbose;
196+
else
197+
rc+=vacuumlo(argv[arg],verbose);
198+
}
199+
200+
returnrc;
201+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp