Commit f374a9da authored by Peter Eisentraut's avatar Peter Eisentraut

Change clusterdb and vacuumdb into C programs.

parent eab5d643
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/maintenance.sgml,v 1.22 2003/03/25 16:15:37 petere Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/maintenance.sgml,v 1.23 2003/06/18 12:19:11 petere Exp $
--> -->
<chapter id="maintenance"> <chapter id="maintenance">
...@@ -136,7 +136,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/maintenance.sgml,v 1.22 2003/03/25 16:15:37 ...@@ -136,7 +136,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/maintenance.sgml,v 1.22 2003/03/25 16:15:37
<command>VACUUM</> once a day at a low-usage time of day, supplemented <command>VACUUM</> once a day at a low-usage time of day, supplemented
by more frequent vacuuming of heavily-updated tables if necessary. by more frequent vacuuming of heavily-updated tables if necessary.
(If you have multiple databases in a cluster, don't forget to (If you have multiple databases in a cluster, don't forget to
vacuum each one; the <filename>vacuumdb</> script may be helpful.) vacuum each one; the program <filename>vacuumdb</> may be helpful.)
Use plain <command>VACUUM</>, not <command>VACUUM FULL</>, for routine Use plain <command>VACUUM</>, not <command>VACUUM FULL</>, for routine
vacuuming for space recovery. vacuuming for space recovery.
</para> </para>
......
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/clusterdb.sgml,v 1.9 2003/03/24 14:32:51 petere Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/clusterdb.sgml,v 1.10 2003/06/18 12:19:11 petere Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -41,16 +41,13 @@ PostgreSQL documentation ...@@ -41,16 +41,13 @@ PostgreSQL documentation
</para> </para>
<para> <para>
<application>clusterdb</application> is a shell script wrapper around the <application>clusterdb</application> is a wrapper around the SQL
backend command command <xref linkend="SQL-CLUSTER" endterm="sql-cluster-title">.
<xref linkend="SQL-CLUSTER" endterm="sql-cluster-title"> via There is no effective difference between clustering databases via
the <productname>PostgreSQL</productname> interactive terminal this or other methods. The database server must be running at the
<xref linkend="APP-PSQL">. There is no effective targeted host. Also, any default settings and environment
difference between clustering databases via this or other methods. variables used by the <application>libpq</application> front-end
<application>psql</application> must be found by the script and library will apply.
a database server must be running at the targeted host. Also, any default
settings and environment variables available to <application>psql</application>
and the <application>libpq</application> front-end library do apply.
</para> </para>
</refsect1> </refsect1>
......
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/dropuser.sgml,v 1.25 2003/05/26 17:50:09 momjian Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/dropuser.sgml,v 1.26 2003/06/18 12:19:11 petere Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -37,13 +37,13 @@ PostgreSQL documentation ...@@ -37,13 +37,13 @@ PostgreSQL documentation
</para> </para>
<para> <para>
<application>dropuser</application> is a shell script wrapper <application>dropuser</application> is a wrapper around the
around the <acronym>SQL</acronym> command <xref <acronym>SQL</acronym> command <xref linkend="SQL-DROPUSER"
linkend="SQL-DROPUSER" endterm="SQL-DROPUSER-title">. The database endterm="SQL-DROPUSER-title">. The database server must be running
server must be running on the targeted host. There on the targeted host. There is nothing special about removing
is nothing special about removing users via this or other users via this or other methods. Also, any default settings and
methods. Also, any default settings and environment variables environment variables used by the <application>libpq</application>
used by the <application>libpq</application> front-end library will apply. front-end library will apply.
</para> </para>
</refsect1> </refsect1>
......
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/vacuumdb.sgml,v 1.28 2003/03/24 14:32:51 petere Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/vacuumdb.sgml,v 1.29 2003/06/18 12:19:11 petere Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -48,16 +48,13 @@ PostgreSQL documentation ...@@ -48,16 +48,13 @@ PostgreSQL documentation
</para> </para>
<para> <para>
<application>vacuumdb</application> is a shell script wrapper around the <application>vacuumdb</application> is a wrapper around the SQL
backend command command <xref linkend="SQL-VACUUM" endterm="SQL-VACUUM-title">.
<xref linkend="SQL-VACUUM" endterm="SQL-VACUUM-title"> via There is no effective difference between vacuuming databases via
the <productname>PostgreSQL</productname> interactive terminal this or other methods. The database server must be running at the
<xref linkend="APP-PSQL">. There is no effective targeted host. Also, any default settings and environment
difference between vacuuming databases via this or other methods. variables used by the <application>libpq</application> front-end
<application>psql</application> must be found by the script and library will apply.
a database server must be running at the targeted host. Also, any default
settings and environment variables available to <application>psql</application>
and the <application>libpq</application> front-end library do apply.
</para> </para>
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group # Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California # Portions Copyright (c) 1994, Regents of the University of California
# #
# $Header: /cvsroot/pgsql/src/bin/scripts/Makefile,v 1.20 2003/04/16 05:23:55 tgl Exp $ # $Header: /cvsroot/pgsql/src/bin/scripts/Makefile,v 1.21 2003/06/18 12:19:11 petere Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
...@@ -13,8 +13,7 @@ subdir = src/bin/scripts ...@@ -13,8 +13,7 @@ subdir = src/bin/scripts
top_builddir = ../../.. top_builddir = ../../..
include $(top_builddir)/src/Makefile.global include $(top_builddir)/src/Makefile.global
SCRIPTS := vacuumdb clusterdb PROGRAMS = createdb createlang createuser dropdb droplang dropuser clusterdb vacuumdb
PROGRAMS = createdb createlang createuser dropdb droplang dropuser
override CPPFLAGS := -I$(top_srcdir)/src/bin/pg_dump -I$(top_srcdir)/src/bin/psql -I$(libpq_srcdir) $(CPPFLAGS) override CPPFLAGS := -I$(top_srcdir)/src/bin/pg_dump -I$(top_srcdir)/src/bin/psql -I$(libpq_srcdir) $(CPPFLAGS)
...@@ -30,6 +29,8 @@ createuser: createuser.o common.o dumputils.o sprompt.o $(top_builddir)/src/back ...@@ -30,6 +29,8 @@ createuser: createuser.o common.o dumputils.o sprompt.o $(top_builddir)/src/back
dropdb: dropdb.o common.o dumputils.o sprompt.o $(top_builddir)/src/backend/parser/keywords.o dropdb: dropdb.o common.o dumputils.o sprompt.o $(top_builddir)/src/backend/parser/keywords.o
droplang: droplang.o common.o sprompt.o print.o mbprint.o droplang: droplang.o common.o sprompt.o print.o mbprint.o
dropuser: dropuser.o common.o dumputils.o sprompt.o $(top_builddir)/src/backend/parser/keywords.o dropuser: dropuser.o common.o dumputils.o sprompt.o $(top_builddir)/src/backend/parser/keywords.o
clusterdb: clusterdb.o common.o dumputils.o sprompt.o $(top_builddir)/src/backend/parser/keywords.o
vacuumdb: vacuumdb.o common.o sprompt.o
dumputils.c sprompt.c : % : $(top_srcdir)/src/bin/pg_dump/% dumputils.c sprompt.c : % : $(top_srcdir)/src/bin/pg_dump/%
rm -f $@ && $(LN_S) $< . rm -f $@ && $(LN_S) $< .
...@@ -49,14 +50,14 @@ install: all installdirs ...@@ -49,14 +50,14 @@ install: all installdirs
$(INSTALL_PROGRAM) droplang$(X) $(DESTDIR)$(bindir)/droplang$(X) $(INSTALL_PROGRAM) droplang$(X) $(DESTDIR)$(bindir)/droplang$(X)
$(INSTALL_PROGRAM) createuser$(X) $(DESTDIR)$(bindir)/createuser$(X) $(INSTALL_PROGRAM) createuser$(X) $(DESTDIR)$(bindir)/createuser$(X)
$(INSTALL_PROGRAM) dropuser$(X) $(DESTDIR)$(bindir)/dropuser$(X) $(INSTALL_PROGRAM) dropuser$(X) $(DESTDIR)$(bindir)/dropuser$(X)
$(INSTALL_SCRIPT) $(srcdir)/clusterdb $(DESTDIR)$(bindir)/clusterdb $(INSTALL_PROGRAM) clusterdb$(X) $(DESTDIR)$(bindir)/clusterdb$(X)
$(INSTALL_SCRIPT) $(srcdir)/vacuumdb $(DESTDIR)$(bindir)/vacuumdb $(INSTALL_PROGRAM) vacuumdb$(X) $(DESTDIR)$(bindir)/vacuumdb$(X)
installdirs: installdirs:
$(mkinstalldirs) $(DESTDIR)$(bindir) $(mkinstalldirs) $(DESTDIR)$(bindir)
uninstall: uninstall:
rm -f $(addprefix $(DESTDIR)$(bindir)/, $(SCRIPTS) $(addsuffix $(X), $(PROGRAMS))) rm -f $(addprefix $(DESTDIR)$(bindir)/, $(addsuffix $(X), $(PROGRAMS)))
clean distclean maintainer-clean: clean distclean maintainer-clean:
......
#!/bin/sh
#-------------------------------------------------------------------------
#
# clusterdb--
# cluster a postgres database
#
# This script runs psql with the "-c" option to cluster
# the requested database.
#
# Copyright (c) 2002, PostgreSQL Global Development Group
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/clusterdb,v 1.12 2003/06/11 05:13:12 momjian Exp $
#
#-------------------------------------------------------------------------
CMDNAME=`basename "$0"`
PATHNAME=`echo "$0" | sed "s,$CMDNAME\$,,"`
PSQLOPT=
table=
dbname=
alldb=
quiet=0
while [ "$#" -gt 0 ]
do
case "$1" in
--help|-\?)
usage=t
break
;;
# options passed on to psql
--host|-h)
PSQLOPT="$PSQLOPT -h $2"
shift;;
-h*)
PSQLOPT="$PSQLOPT $1"
;;
--host=*)
PSQLOPT="$PSQLOPT -h `echo \"$1\" | sed 's/^--host=//'`"
;;
--port|-p)
PSQLOPT="$PSQLOPT -p $2"
shift;;
-p*)
PSQLOPT="$PSQLOPT $1"
;;
--port=*)
PSQLOPT="$PSQLOPT -p `echo \"$1\" | sed 's/^--port=//'`"
;;
--username|-U)
PSQLOPT="$PSQLOPT -U $2"
shift;;
-U*)
PSQLOPT="$PSQLOPT $1"
;;
--username=*)
PSQLOPT="$PSQLOPT -U `echo \"$1\" | sed 's/^--username=//'`"
;;
--password|-W)
PSQLOPT="$PSQLOPT -W"
;;
--echo|-e)
ECHOOPT="-e"
;;
--quiet|-q)
ECHOOPT="$ECHOOPT -o /dev/null"
quiet=1
;;
--dbname|-d)
dbname="$2"
shift;;
-d*)
dbname=`echo $1 | sed 's/^-d//'`
;;
--dbname=*)
dbname=`echo $1 | sed 's/^--dbname=//'`
;;
-a|--alldb)
alldb=1
;;
# options converted into SQL command
--table|-t)
table="$2"
shift;;
-t*)
table=`echo $1 | sed 's/^-t//'`
;;
--table=*)
table=`echo $1 | sed 's/^--table=//'`
;;
-*)
echo "$CMDNAME: invalid option: $1" 1>&2
echo "Try '$CMDNAME --help' for more information." 1>&2
exit 1
;;
*)
dbname="$1"
if [ "$#" -ne 1 ]; then
echo "$CMDNAME: invalid option: $2" 1>&2
echo "Try '$CMDNAME --help' for more information." 1>&2
exit 1
fi
;;
esac
shift
done
if [ "$usage" ]; then
echo "$CMDNAME cluster all previously clustered tables in a database."
echo
echo "Usage:"
echo " $CMDNAME [OPTION]... [DBNAME]"
echo
echo "Options:"
echo " -a, --all cluster all databases"
echo " -d, --dbname=DBNAME database to cluster"
echo " -t, --table='TABLE' cluster specific table only"
echo " -e, --echo show the commands sent to the backend"
echo " -q, --quiet don't write any output"
echo " --help show this help, then exit"
echo
echo "Connection options:"
echo " -h, --host=HOSTNAME database server host or socket directory"
echo " -p, --port=PORT database server port"
echo " -U, --username=USERNAME user name to connect as"
echo " -W, --password prompt for password"
echo
echo "Read the description of the SQL command CLUSTER for details."
echo
echo "Report bugs to <pgsql-bugs@postgresql.org>."
exit 0
fi
if [ "$alldb" ]; then
if [ "$dbname" -o "$table" ]; then
echo "$CMDNAME: cannot cluster all databases and a specific one at the same time" 1>&2
exit 1
fi
dbname=`${PATHNAME}psql $PSQLOPT -q -t -A -d template1 -c 'SELECT datname FROM pg_database WHERE datallowconn'`
[ "$?" -ne 0 ] && exit 1
elif [ -z "$dbname" ]; then
if [ "$PGDATABASE" ]; then
dbname="$PGDATABASE"
elif [ "$PGUSER" ]; then
dbname="$PGUSER"
else
dbname=`${PATHNAME}pg_id -u -n`
fi
[ "$?" -ne 0 ] && exit 1
fi
for db in $dbname
do
[ "$alldb" ] && echo "Clustering $db"
if [ -z "$table" ]; then
${PATHNAME}psql $PSQLOPT $ECHOOPT -c "CLUSTER" -d $db
[ "$?" -ne 0 ] && exit 1
else
${PATHNAME}psql $PSQLOPT $ECHOOPT -c "CLUSTER $table" -d $db
[ "$?" -ne 0 ] && exit 1
fi
done
exit 0
/*-------------------------------------------------------------------------
*
* clusterdb
*
* Portions Copyright (c) 2002-2003, PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/scripts/clusterdb.c,v 1.1 2003/06/18 12:19:11 petere Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres_fe.h"
#include "common.h"
#include "dumputils.h"
static
void cluster_one_database(const char *dbname, const char *table,
const char *host, const char *port, const char *username, bool password,
const char *progname, bool echo, bool quiet);
static
void cluster_all_databases(const char *host, const char *port, const char *username, bool password,
const char *progname, bool echo, bool quiet);
static void help(const char *progname);
int
main(int argc, char *argv[])
{
static struct option long_options[] = {
{"host", required_argument, NULL, 'h'},
{"port", required_argument, NULL, 'p'},
{"username", required_argument, NULL, 'U'},
{"password", no_argument, NULL, 'W'},
{"echo", no_argument, NULL, 'e'},
{"quiet", no_argument, NULL, 'q'},
{"dbname", required_argument, NULL, 'd'},
{"all", no_argument, NULL, 'a'},
{"table", required_argument, NULL, 't'},
{NULL, 0, NULL, 0}
};
char *progname;
int optindex;
int c;
const char *dbname = NULL;
char *host = NULL;
char *port = NULL;
char *username = NULL;
bool password = false;
bool echo = false;
bool quiet = false;
bool alldb = false;
char *table = NULL;
progname = get_progname(argv[0]);
init_nls();
handle_help_version_opts(argc, argv, "clusterdb", help);
while ((c = getopt_long(argc, argv, "h:p:U:Weqd:at:", long_options, &optindex)) != -1)
{
switch (c)
{
case 'h':
host = optarg;
break;
case 'p':
port = optarg;
break;
case 'U':
username = optarg;
break;
case 'W':
password = true;
break;
case 'e':
echo = true;
break;
case 'q':
quiet = true;
break;
case 'd':
dbname = optarg;
break;
case 'a':
alldb = true;
break;
case 't':
table = optarg;
break;
default:
fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
exit(1);
}
}
switch (argc - optind)
{
case 0:
break;
case 1:
dbname = argv[optind];
break;
default:
fprintf(stderr, _("%s: too many command-line arguments (first is '%s')\n"),
progname, argv[optind + 1]);
fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
exit(1);
}
if (alldb)
{
if (dbname)
{
fprintf(stderr, _("%s: cannot cluster all databases and a specific one at the same time\n"),
progname);
exit(1);
}
if (table)
{
fprintf(stderr, _("%s: cannot cluster a specific table in all databases\n"),
progname);
exit(1);
}
cluster_all_databases(host, port, username, password,
progname, echo, quiet);
}
else
{
if (dbname == NULL)
{
if (getenv("PGDATABASE"))
dbname = getenv("PGDATABASE");
else if (getenv("PGUSER"))
dbname = getenv("PGUSER");
else
dbname = get_user_name(progname);
}
cluster_one_database(dbname, table,
host, port, username, password,
progname, echo, quiet);
}
exit(0);
}
static
void cluster_one_database(const char *dbname, const char *table,
const char *host, const char *port, const char *username, bool password,
const char *progname, bool echo, bool quiet)
{
PQExpBufferData sql;
PGconn *conn;
PGresult *result;
initPQExpBuffer(&sql);
appendPQExpBuffer(&sql, "CLUSTER");
if (table)
appendPQExpBuffer(&sql, " %s", fmtId(table));
appendPQExpBuffer(&sql, ";\n");
conn = connectDatabase(dbname, host, port, username, password, progname);
if (echo)
printf("%s", sql.data);
result = PQexec(conn, sql.data);
if (PQresultStatus(result) != PGRES_COMMAND_OK)
{
if (table)
fprintf(stderr, _("%s: clustering of table \"%s\" in database \"%s\" failed: %s"),
progname, table, dbname, PQerrorMessage(conn));
else
fprintf(stderr, _("%s: clustering of database \"%s\" failed: %s"),
progname, dbname, PQerrorMessage(conn));
PQfinish(conn);
exit(1);
}
PQclear(result);
PQfinish(conn);
termPQExpBuffer(&sql);
if (!quiet)
puts("CLUSTER");
}
static
void cluster_all_databases(const char *host, const char *port, const char *username, bool password,
const char *progname, bool echo, bool quiet)
{
PGconn *conn;
PGresult *result;
int i;
conn = connectDatabase("template1", host, port, username, password, progname);
result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn;", progname, echo);
PQfinish(conn);
for (i = 0; i < PQntuples(result); i++)
{
char *dbname = PQgetvalue(result, i, 0);
if (!quiet)
fprintf(stderr, _("%s: clustering database \"%s\"\n"), progname, dbname);
cluster_one_database(dbname, NULL,
host, port, username, password,
progname, echo, quiet);
}
PQclear(result);
}
static void
help(const char *progname)
{
printf(_("%s clusters all previously clustered tables in a database.\n"), progname);
printf(_("Usage:\n"));
printf(_(" %s [OPTION]... [DBNAME]\n"), progname);
printf(_("\nOptions:\n"));
printf(_(" -a, --all cluster all databases\n"));
printf(_(" -d, --dbname=DBNAME database to cluster\n"));
printf(_(" -t, --table=TABLE cluster specific table only"));
printf(_(" -e, --echo show the commands being sent to the server\n"));
printf(_(" -q, --quiet don't write any messages\n"));
printf(_(" --help show this help, then exit\n"));
printf(_(" --version output version information, then exit\n"));
printf(_("\nConnection options:\n"));
printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
printf(_(" -p, --port=PORT database server port\n"));
printf(_(" -U, --username=USERNAME user name to connect as\n"));
printf(_(" -W, --password prompt for password\n"));
printf(_("\nRead the description of the SQL command CLUSTER for details.\n"));
printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
}
# $Header: /cvsroot/pgsql/src/bin/scripts/nls.mk,v 1.1 2003/03/18 22:19:47 petere Exp $ # $Header: /cvsroot/pgsql/src/bin/scripts/nls.mk,v 1.2 2003/06/18 12:19:11 petere Exp $
CATALOG_NAME := pgscripts CATALOG_NAME := pgscripts
AVAIL_LANGUAGES := AVAIL_LANGUAGES :=
GETTEXT_FILES := createdb.c createlang.c createuser.c \ GETTEXT_FILES := createdb.c createlang.c createuser.c \
dropdb.c droplang.c dropuser.c \ dropdb.c droplang.c dropuser.c \
clusterdb.c vacuumdb.c \
common.c common.c
GETTEXT_TRIGGERS:= _ simple_prompt GETTEXT_TRIGGERS:= _ simple_prompt
#!/bin/sh
#-------------------------------------------------------------------------
#
# vacuumdb--
# vacuum a postgres database
#
# This script runs psql with the "-c" option to vacuum
# the requested database.
#
# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/vacuumdb,v 1.28 2003/06/11 05:13:12 momjian Exp $
#
#-------------------------------------------------------------------------
CMDNAME=`basename "$0"`
PATHNAME=`echo "$0" | sed "s,$CMDNAME\$,,"`
PSQLOPT=
full=
verbose=
analyze=
table=
dbname=
alldb=
quiet=0
while [ "$#" -gt 0 ]
do
case "$1" in
--help|-\?)
usage=t
break
;;
# options passed on to psql
--host|-h)
PSQLOPT="$PSQLOPT -h $2"
shift;;
-h*)
PSQLOPT="$PSQLOPT $1"
;;
--host=*)
PSQLOPT="$PSQLOPT -h `echo \"$1\" | sed 's/^--host=//'`"
;;
--port|-p)
PSQLOPT="$PSQLOPT -p $2"
shift;;
-p*)
PSQLOPT="$PSQLOPT $1"
;;
--port=*)
PSQLOPT="$PSQLOPT -p `echo \"$1\" | sed 's/^--port=//'`"
;;
--username|-U)
PSQLOPT="$PSQLOPT -U $2"
shift;;
-U*)
PSQLOPT="$PSQLOPT $1"
;;
--username=*)
PSQLOPT="$PSQLOPT -U `echo \"$1\" | sed 's/^--username=//'`"
;;
--password|-W)
PSQLOPT="$PSQLOPT -W"
;;
--echo|-e)
ECHOOPT="-e"
;;
--quiet|-q)
ECHOOPT="$ECHOOPT -o /dev/null"
quiet=1
;;
--dbname|-d)
dbname="$2"
shift;;
-d*)
dbname=`echo $1 | sed 's/^-d//'`
;;
--dbname=*)
dbname=`echo $1 | sed 's/^--dbname=//'`
;;
# options converted into SQL command
--analyze|-z)
analyze="ANALYZE"
;;
--all|-a)
alldb=Y
;;
--table|-t)
table="$2"
shift;;
-t*)
table=`echo $1 | sed 's/^-t//'`
;;
--table=*)
table=`echo $1 | sed 's/^--table=//'`
;;
--full|-f)
full="FULL"
;;
--verbose|-v)
verbose="VERBOSE"
;;
-*)
echo "$CMDNAME: invalid option: $1" 1>&2
echo "Try '$CMDNAME --help' for more information." 1>&2
exit 1
;;
*)
dbname="$1"
if [ "$#" -ne 1 ]; then
echo "$CMDNAME: invalid option: $2" 1>&2
echo "Try '$CMDNAME --help' for more information." 1>&2
exit 1
fi
;;
esac
shift
done
if [ "$usage" ]; then
echo "$CMDNAME cleans and analyzes a PostgreSQL database."
echo
echo "Usage:"
echo " $CMDNAME [OPTION]... [DBNAME]"
echo
echo "Options:"
echo " -a, --all vacuum all databases"
echo " -d, --dbname=DBNAME database to vacuum"
echo " -t, --table='TABLE[(columns)]' vacuum specific table only"
echo " -f, --full do full vacuuming"
echo " -z, --analyze update optimizer hints"
echo " -e, --echo show the command being sent to the backend"
echo " -q, --quiet don't write any output"
echo " -v, --verbose write a lot of output"
echo " --help show this help, then exit"
echo
echo "Connection options:"
echo " -h, --host=HOSTNAME database server host or socket directory"
echo " -p, --port=PORT database server port"
echo " -U, --username=USERNAME user name to connect as"
echo " -W, --password prompt for password"
echo
echo "Read the description of the SQL command VACUUM for details."
echo
echo "Report bugs to <pgsql-bugs@postgresql.org>."
exit 0
fi
if [ "$alldb" ]; then
if [ "$dbname" -o "$table" ]; then
echo "$CMDNAME: cannot vacuum all databases and a specific one at the same time" 1>&2
exit 1
fi
dbname=`${PATHNAME}psql $PSQLOPT -q -t -A -d template1 -c 'SELECT datname FROM pg_database WHERE datallowconn'`
elif [ -z "$dbname" ]; then
if [ "$PGDATABASE" ]; then
dbname="$PGDATABASE"
elif [ "$PGUSER" ]; then
dbname="$PGUSER"
else
dbname=`${PATHNAME}pg_id -u -n`
fi
[ "$?" -ne 0 ] && exit 1
fi
for db in $dbname
do
[ "$alldb" -a "$quiet" -ne 1 ] && echo "Vacuuming $db"
${PATHNAME}psql $PSQLOPT $ECHOOPT -c "VACUUM $full $verbose $analyze $table" -d $db
if [ "$?" -ne 0 ]; then
echo "$CMDNAME: vacuum $table $db failed" 1>&2
exit 1
fi
done
exit 0
/*-------------------------------------------------------------------------
*
* vacuumdb
*
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Header: /cvsroot/pgsql/src/bin/scripts/vacuumdb.c,v 1.1 2003/06/18 12:19:11 petere Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres_fe.h"
#include "common.h"
static
void vacuum_one_database(const char *dbname, bool full, bool verbose, bool analyze, const char *table,
const char *host, const char *port, const char *username, bool password,
const char *progname, bool echo, bool quiet);
static
void vacuum_all_databases(bool full, bool verbose, bool analyze,
const char *host, const char *port, const char *username, bool password,
const char *progname, bool echo, bool quiet);
static void help(const char *progname);
int
main(int argc, char *argv[])
{
static struct option long_options[] = {
{"host", required_argument, NULL, 'h'},
{"port", required_argument, NULL, 'p'},
{"username", required_argument, NULL, 'U'},
{"password", no_argument, NULL, 'W'},
{"echo", no_argument, NULL, 'e'},
{"quiet", no_argument, NULL, 'q'},
{"dbname", required_argument, NULL, 'd'},
{"analyze", no_argument, NULL, 'z'},
{"all", no_argument, NULL, 'a'},
{"table", required_argument, NULL, 't'},
{"full", no_argument, NULL, 'f'},
{"verbose", no_argument, NULL, 'v'},
{NULL, 0, NULL, 0}
};
char *progname;
int optindex;
int c;
const char *dbname = NULL;
char *host = NULL;
char *port = NULL;
char *username = NULL;
bool password = false;
bool echo = false;
bool quiet = false;
bool analyze = false;
bool alldb = false;
char *table = NULL;
bool full = false;
bool verbose = false;
progname = get_progname(argv[0]);
init_nls();
handle_help_version_opts(argc, argv, "vacuumdb", help);
while ((c = getopt_long(argc, argv, "h:p:U:Weqd:zat:fv", long_options, &optindex)) != -1)
{
switch (c)
{
case 'h':
host = optarg;
break;
case 'p':
port = optarg;
break;
case 'U':
username = optarg;
break;
case 'W':
password = true;
break;
case 'e':
echo = true;
break;
case 'q':
quiet = true;
break;
case 'd':
dbname = optarg;
break;
case 'z':
analyze = true;
break;
case 'a':
alldb = true;
break;
case 't':
table = optarg;
break;
case 'f':
full = true;
break;
case 'v':
verbose = true;
break;
default:
fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
exit(1);
}
}
switch (argc - optind)
{
case 0:
break;
case 1:
dbname = argv[optind];
break;
default:
fprintf(stderr, _("%s: too many command-line arguments (first is '%s')\n"),
progname, argv[optind + 1]);
fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
exit(1);
}
if (alldb)
{
if (dbname)
{
fprintf(stderr, _("%s: cannot vacuum all databases and a specific one at the same time\n"),
progname);
exit(1);
}
if (table)
{
fprintf(stderr, _("%s: cannot vacuum a specific table in all databases\n"),
progname);
exit(1);
}
vacuum_all_databases(full, verbose, analyze,
host, port, username, password,
progname, echo, quiet);
}
else
{
if (dbname == NULL)
{
if (getenv("PGDATABASE"))
dbname = getenv("PGDATABASE");
else if (getenv("PGUSER"))
dbname = getenv("PGUSER");
else
dbname = get_user_name(progname);
}
vacuum_one_database(dbname, full, verbose, analyze, table,
host, port, username, password,
progname, echo, quiet);
}
exit(0);
}
static
void vacuum_one_database(const char *dbname, bool full, bool verbose, bool analyze, const char *table,
const char *host, const char *port, const char *username, bool password,
const char *progname, bool echo, bool quiet)
{
PQExpBufferData sql;
PGconn *conn;
PGresult *result;
initPQExpBuffer(&sql);
appendPQExpBuffer(&sql, "VACUUM");
if (full)
appendPQExpBuffer(&sql, " FULL");
if (verbose)
appendPQExpBuffer(&sql, " VERBOSE");
if (analyze)
appendPQExpBuffer(&sql, " ANALYZE");
if (table)
appendPQExpBuffer(&sql, " %s", table);
appendPQExpBuffer(&sql, ";\n");
conn = connectDatabase(dbname, host, port, username, password, progname);
if (echo)
printf("%s", sql.data);
result = PQexec(conn, sql.data);
if (PQresultStatus(result) != PGRES_COMMAND_OK)
{
if (table)
fprintf(stderr, _("%s: vacuuming of table \"%s\" in database \"%s\" failed: %s"),
progname, table, dbname, PQerrorMessage(conn));
else
fprintf(stderr, _("%s: vacuuming of database \"%s\" failed: %s"),
progname, dbname, PQerrorMessage(conn));
PQfinish(conn);
exit(1);
}
PQclear(result);
PQfinish(conn);
termPQExpBuffer(&sql);
if (!quiet)
puts("VACUUM");
}
static
void vacuum_all_databases(bool full, bool verbose, bool analyze,
const char *host, const char *port, const char *username, bool password,
const char *progname, bool echo, bool quiet)
{
PGconn *conn;
PGresult *result;
int i;
conn = connectDatabase("template1", host, port, username, password, progname);
result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn;", progname, echo);
PQfinish(conn);
for (i = 0; i < PQntuples(result); i++)
{
char *dbname = PQgetvalue(result, i, 0);
if (!quiet)
fprintf(stderr, _("%s: vacuuming database \"%s\"\n"), progname, dbname);
vacuum_one_database(dbname, full, verbose, analyze, NULL,
host, port, username, password,
progname, echo, quiet);
}
PQclear(result);
}
static void
help(const char *progname)
{
printf(_("%s cleans and analyzes a PostgreSQL database.\n\n"), progname);
printf(_("Usage:\n"));
printf(_(" %s [OPTION]... [DBNAME]\n"), progname);
printf(_("\nOptions:\n"));
printf(_(" -a, --all vacuum all databases\n"));
printf(_(" -d, --dbname=DBNAME database to vacuum\n"));
printf(_(" -t, --table='TABLE[(COLUMNS)]' vacuum specific table only\n"));
printf(_(" -f, --full do full vacuuming\n"));
printf(_(" -z, --analyze update optimizer hints\n"));
printf(_(" -e, --echo show the commands being sent to the server\n"));
printf(_(" -q, --quiet don't write any messages\n"));
printf(_(" -v, --verbose write a lot of output\n"));
printf(_(" --help show this help, then exit\n"));
printf(_(" --version output version information, then exit\n"));
printf(_("\nConnection options:\n"));
printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
printf(_(" -p, --port=PORT database server port\n"));
printf(_(" -U, --username=USERNAME user name to connect as\n"));
printf(_(" -W, --password prompt for password\n"));
printf(_("\nRead the description of the SQL command VACUUM for details.\n"));
printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment