mirror of
https://github.com/postgres/postgres.git
synced 2025-07-03 20:02:46 +03:00
Provide a parenthesized-options syntax for VACUUM, analogous to that recently
adopted for EXPLAIN. This will allow additional options to be implemented in future without having to make them fully-reserved keywords. The old syntax remains available for existing options, however. Itagaki Takahiro
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/maintenance.sgml,v 1.96 2009/08/07 20:54:31 alvherre Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/maintenance.sgml,v 1.97 2009/11/16 21:32:06 tgl Exp $ -->
|
||||||
|
|
||||||
<chapter id="maintenance">
|
<chapter id="maintenance">
|
||||||
<title>Routine Database Maintenance Tasks</title>
|
<title>Routine Database Maintenance Tasks</title>
|
||||||
@ -502,8 +502,9 @@ SELECT datname, age(datfrozenxid) FROM pg_database;
|
|||||||
only scans pages that have been modified since the last vacuum, but
|
only scans pages that have been modified since the last vacuum, but
|
||||||
<structfield>relfrozenxid</> can only be advanced when the whole table is
|
<structfield>relfrozenxid</> can only be advanced when the whole table is
|
||||||
scanned. The whole table is scanned when <structfield>relfrozenxid</> is
|
scanned. The whole table is scanned when <structfield>relfrozenxid</> is
|
||||||
more than <varname>vacuum_freeze_table_age</> transactions old, when the
|
more than <varname>vacuum_freeze_table_age</> transactions old, when
|
||||||
<command>VACUUM FREEZE</> command is used, or when all pages happen to
|
<command>VACUUM</>'s <literal>FREEZE</> option is used, or when all pages
|
||||||
|
happen to
|
||||||
require vacuuming to remove dead row versions. When <command>VACUUM</>
|
require vacuuming to remove dead row versions. When <command>VACUUM</>
|
||||||
scans the whole table, after it's finished <literal>age(relfrozenxid)</>
|
scans the whole table, after it's finished <literal>age(relfrozenxid)</>
|
||||||
should be a little more than the <varname>vacuum_freeze_min_age</> setting
|
should be a little more than the <varname>vacuum_freeze_min_age</> setting
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/vacuum.sgml,v 1.55 2009/03/24 20:17:08 tgl Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/vacuum.sgml,v 1.56 2009/11/16 21:32:06 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -21,6 +21,7 @@ PostgreSQL documentation
|
|||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<synopsis>
|
<synopsis>
|
||||||
|
VACUUM [ ( { FULL | FREEZE | VERBOSE | ANALYZE } [, ...] ) ] [ <replaceable class="PARAMETER">table</replaceable> [ (<replaceable class="PARAMETER">column</replaceable> [, ...] ) ] ]
|
||||||
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> ]
|
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> ]
|
||||||
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable> [ (<replaceable class="PARAMETER">column</replaceable> [, ...] ) ] ]
|
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable> [ (<replaceable class="PARAMETER">column</replaceable> [, ...] ) ] ]
|
||||||
</synopsis>
|
</synopsis>
|
||||||
@ -63,6 +64,15 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">
|
|||||||
blocks. This form is much slower and requires an exclusive lock on each
|
blocks. This form is much slower and requires an exclusive lock on each
|
||||||
table while it is being processed.
|
table while it is being processed.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
When the option list is surrounded by parentheses, the options can be
|
||||||
|
written in any order. Without parentheses, options must be specified
|
||||||
|
in exactly the order shown above.
|
||||||
|
Prior to <productname>PostgreSQL</productname> 8.5, the unparenthesized
|
||||||
|
syntax was the only one supported. It is expected that all new options
|
||||||
|
will be supported only in the parenthesized syntax.
|
||||||
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
@ -127,6 +137,7 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The name of a specific column to analyze. Defaults to all columns.
|
The name of a specific column to analyze. Defaults to all columns.
|
||||||
|
If a column list is specified, <literal>ANALYZE</> is implied.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -214,7 +225,7 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">
|
|||||||
table in the regression database:
|
table in the regression database:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
regression=# VACUUM VERBOSE ANALYZE onek;
|
regression=# VACUUM (VERBOSE, ANALYZE) onek;
|
||||||
INFO: vacuuming "public.onek"
|
INFO: vacuuming "public.onek"
|
||||||
INFO: index "onek_unique1" now contains 1000 tuples in 14 pages
|
INFO: index "onek_unique1" now contains 1000 tuples in 14 pages
|
||||||
DETAIL: 3000 index tuples were removed.
|
DETAIL: 3000 index tuples were removed.
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.141 2009/08/12 18:23:49 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.142 2009/11/16 21:32:06 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -135,7 +135,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
|
|||||||
Oid save_userid;
|
Oid save_userid;
|
||||||
bool save_secdefcxt;
|
bool save_secdefcxt;
|
||||||
|
|
||||||
if (vacstmt->verbose)
|
if (vacstmt->options & VACOPT_VERBOSE)
|
||||||
elevel = INFO;
|
elevel = INFO;
|
||||||
else
|
else
|
||||||
elevel = DEBUG2;
|
elevel = DEBUG2;
|
||||||
@ -173,7 +173,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
|
|||||||
(pg_database_ownercheck(MyDatabaseId, GetUserId()) && !onerel->rd_rel->relisshared)))
|
(pg_database_ownercheck(MyDatabaseId, GetUserId()) && !onerel->rd_rel->relisshared)))
|
||||||
{
|
{
|
||||||
/* No need for a WARNING if we already complained during VACUUM */
|
/* No need for a WARNING if we already complained during VACUUM */
|
||||||
if (!vacstmt->vacuum)
|
if (!(vacstmt->options & VACOPT_VACUUM))
|
||||||
{
|
{
|
||||||
if (onerel->rd_rel->relisshared)
|
if (onerel->rd_rel->relisshared)
|
||||||
ereport(WARNING,
|
ereport(WARNING,
|
||||||
@ -199,7 +199,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
|
|||||||
if (onerel->rd_rel->relkind != RELKIND_RELATION)
|
if (onerel->rd_rel->relkind != RELKIND_RELATION)
|
||||||
{
|
{
|
||||||
/* No need for a WARNING if we already complained during VACUUM */
|
/* No need for a WARNING if we already complained during VACUUM */
|
||||||
if (!vacstmt->vacuum)
|
if (!(vacstmt->options & VACOPT_VACUUM))
|
||||||
ereport(WARNING,
|
ereport(WARNING,
|
||||||
(errmsg("skipping \"%s\" --- cannot analyze indexes, views, or special system tables",
|
(errmsg("skipping \"%s\" --- cannot analyze indexes, views, or special system tables",
|
||||||
RelationGetRelationName(onerel))));
|
RelationGetRelationName(onerel))));
|
||||||
@ -475,7 +475,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
|
|||||||
* VACUUM ANALYZE, don't overwrite the accurate count already inserted by
|
* VACUUM ANALYZE, don't overwrite the accurate count already inserted by
|
||||||
* VACUUM.
|
* VACUUM.
|
||||||
*/
|
*/
|
||||||
if (!vacstmt->vacuum)
|
if (!(vacstmt->options & VACOPT_VACUUM))
|
||||||
{
|
{
|
||||||
for (ind = 0; ind < nindexes; ind++)
|
for (ind = 0; ind < nindexes; ind++)
|
||||||
{
|
{
|
||||||
@ -493,7 +493,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
|
|||||||
cleanup:
|
cleanup:
|
||||||
|
|
||||||
/* If this isn't part of VACUUM ANALYZE, let index AMs do cleanup */
|
/* If this isn't part of VACUUM ANALYZE, let index AMs do cleanup */
|
||||||
if (!vacstmt->vacuum)
|
if (!(vacstmt->options & VACOPT_VACUUM))
|
||||||
{
|
{
|
||||||
for (ind = 0; ind < nindexes; ind++)
|
for (ind = 0; ind < nindexes; ind++)
|
||||||
{
|
{
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.395 2009/11/10 18:00:06 alvherre Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.396 2009/11/16 21:32:06 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -289,14 +289,22 @@ void
|
|||||||
vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
|
vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
|
||||||
BufferAccessStrategy bstrategy, bool for_wraparound, bool isTopLevel)
|
BufferAccessStrategy bstrategy, bool for_wraparound, bool isTopLevel)
|
||||||
{
|
{
|
||||||
const char *stmttype = vacstmt->vacuum ? "VACUUM" : "ANALYZE";
|
const char *stmttype;
|
||||||
volatile MemoryContext anl_context = NULL;
|
volatile MemoryContext anl_context = NULL;
|
||||||
volatile bool all_rels,
|
volatile bool all_rels,
|
||||||
in_outer_xact,
|
in_outer_xact,
|
||||||
use_own_xacts;
|
use_own_xacts;
|
||||||
List *relations;
|
List *relations;
|
||||||
|
|
||||||
if (vacstmt->verbose)
|
/* sanity checks on options */
|
||||||
|
Assert(vacstmt->options & (VACOPT_VACUUM | VACOPT_ANALYZE));
|
||||||
|
Assert((vacstmt->options & VACOPT_VACUUM) ||
|
||||||
|
!(vacstmt->options & (VACOPT_FULL | VACOPT_FREEZE)));
|
||||||
|
Assert((vacstmt->options & VACOPT_ANALYZE) || vacstmt->va_cols == NIL);
|
||||||
|
|
||||||
|
stmttype = (vacstmt->options & VACOPT_VACUUM) ? "VACUUM" : "ANALYZE";
|
||||||
|
|
||||||
|
if (vacstmt->options & VACOPT_VERBOSE)
|
||||||
elevel = INFO;
|
elevel = INFO;
|
||||||
else
|
else
|
||||||
elevel = DEBUG2;
|
elevel = DEBUG2;
|
||||||
@ -315,7 +323,7 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
|
|||||||
*
|
*
|
||||||
* ANALYZE (without VACUUM) can run either way.
|
* ANALYZE (without VACUUM) can run either way.
|
||||||
*/
|
*/
|
||||||
if (vacstmt->vacuum)
|
if (vacstmt->options & VACOPT_VACUUM)
|
||||||
{
|
{
|
||||||
PreventTransactionChain(isTopLevel, stmttype);
|
PreventTransactionChain(isTopLevel, stmttype);
|
||||||
in_outer_xact = false;
|
in_outer_xact = false;
|
||||||
@ -327,7 +335,7 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
|
|||||||
* Send info about dead objects to the statistics collector, unless we are
|
* Send info about dead objects to the statistics collector, unless we are
|
||||||
* in autovacuum --- autovacuum.c does this for itself.
|
* in autovacuum --- autovacuum.c does this for itself.
|
||||||
*/
|
*/
|
||||||
if (vacstmt->vacuum && !IsAutoVacuumWorkerProcess())
|
if ((vacstmt->options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess())
|
||||||
pgstat_vacuum_stat();
|
pgstat_vacuum_stat();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -378,11 +386,11 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
|
|||||||
* transaction block, and also in an autovacuum worker, use own
|
* transaction block, and also in an autovacuum worker, use own
|
||||||
* transactions so we can release locks sooner.
|
* transactions so we can release locks sooner.
|
||||||
*/
|
*/
|
||||||
if (vacstmt->vacuum)
|
if (vacstmt->options & VACOPT_VACUUM)
|
||||||
use_own_xacts = true;
|
use_own_xacts = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Assert(vacstmt->analyze);
|
Assert(vacstmt->options & VACOPT_ANALYZE);
|
||||||
if (IsAutoVacuumWorkerProcess())
|
if (IsAutoVacuumWorkerProcess())
|
||||||
use_own_xacts = true;
|
use_own_xacts = true;
|
||||||
else if (in_outer_xact)
|
else if (in_outer_xact)
|
||||||
@ -438,11 +446,11 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
|
|||||||
Oid relid = lfirst_oid(cur);
|
Oid relid = lfirst_oid(cur);
|
||||||
bool scanned_all = false;
|
bool scanned_all = false;
|
||||||
|
|
||||||
if (vacstmt->vacuum)
|
if (vacstmt->options & VACOPT_VACUUM)
|
||||||
vacuum_rel(relid, vacstmt, do_toast, for_wraparound,
|
vacuum_rel(relid, vacstmt, do_toast, for_wraparound,
|
||||||
&scanned_all);
|
&scanned_all);
|
||||||
|
|
||||||
if (vacstmt->analyze)
|
if (vacstmt->options & VACOPT_ANALYZE)
|
||||||
{
|
{
|
||||||
MemoryContext old_context = NULL;
|
MemoryContext old_context = NULL;
|
||||||
|
|
||||||
@ -502,7 +510,7 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
|
|||||||
StartTransactionCommand();
|
StartTransactionCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vacstmt->vacuum && !IsAutoVacuumWorkerProcess())
|
if ((vacstmt->options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess())
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Update pg_database.datfrozenxid, and truncate pg_clog if possible.
|
* Update pg_database.datfrozenxid, and truncate pg_clog if possible.
|
||||||
@ -1034,7 +1042,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
|
|||||||
*/
|
*/
|
||||||
PushActiveSnapshot(GetTransactionSnapshot());
|
PushActiveSnapshot(GetTransactionSnapshot());
|
||||||
|
|
||||||
if (!vacstmt->full)
|
if (!(vacstmt->options & VACOPT_FULL))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* In lazy vacuum, we can set the PROC_IN_VACUUM flag, which lets
|
* In lazy vacuum, we can set the PROC_IN_VACUUM flag, which lets
|
||||||
@ -1074,7 +1082,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
|
|||||||
* vacuum, but just ShareUpdateExclusiveLock for concurrent vacuum. Either
|
* vacuum, but just ShareUpdateExclusiveLock for concurrent vacuum. Either
|
||||||
* way, we can be sure that no other backend is vacuuming the same table.
|
* way, we can be sure that no other backend is vacuuming the same table.
|
||||||
*/
|
*/
|
||||||
lmode = vacstmt->full ? AccessExclusiveLock : ShareUpdateExclusiveLock;
|
lmode = (vacstmt->options & VACOPT_FULL) ? AccessExclusiveLock : ShareUpdateExclusiveLock;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open the relation and get the appropriate lock on it.
|
* Open the relation and get the appropriate lock on it.
|
||||||
@ -1186,7 +1194,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
|
|||||||
/*
|
/*
|
||||||
* Do the actual work --- either FULL or "lazy" vacuum
|
* Do the actual work --- either FULL or "lazy" vacuum
|
||||||
*/
|
*/
|
||||||
if (vacstmt->full)
|
if (vacstmt->options & VACOPT_FULL)
|
||||||
heldoff = full_vacuum_rel(onerel, vacstmt);
|
heldoff = full_vacuum_rel(onerel, vacstmt);
|
||||||
else
|
else
|
||||||
heldoff = lazy_vacuum_rel(onerel, vacstmt, vac_strategy, scanned_all);
|
heldoff = lazy_vacuum_rel(onerel, vacstmt, vac_strategy, scanned_all);
|
||||||
@ -1331,8 +1339,11 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
|
|||||||
vacrelstats->hasindex, FreezeLimit);
|
vacrelstats->hasindex, FreezeLimit);
|
||||||
|
|
||||||
/* report results to the stats collector, too */
|
/* report results to the stats collector, too */
|
||||||
pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared,
|
pgstat_report_vacuum(RelationGetRelid(onerel),
|
||||||
true, vacstmt->analyze, vacrelstats->rel_tuples);
|
onerel->rd_rel->relisshared,
|
||||||
|
true,
|
||||||
|
(vacstmt->options & VACOPT_ANALYZE) != 0,
|
||||||
|
vacrelstats->rel_tuples);
|
||||||
|
|
||||||
return heldoff;
|
return heldoff;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.123 2009/11/10 18:00:06 alvherre Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.124 2009/11/16 21:32:06 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -164,7 +164,7 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
|
|||||||
if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration > 0)
|
if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration > 0)
|
||||||
starttime = GetCurrentTimestamp();
|
starttime = GetCurrentTimestamp();
|
||||||
|
|
||||||
if (vacstmt->verbose)
|
if (vacstmt->options & VACOPT_VERBOSE)
|
||||||
elevel = INFO;
|
elevel = INFO;
|
||||||
else
|
else
|
||||||
elevel = DEBUG2;
|
elevel = DEBUG2;
|
||||||
@ -236,7 +236,8 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
|
|||||||
pgstat_report_vacuum(RelationGetRelid(onerel),
|
pgstat_report_vacuum(RelationGetRelid(onerel),
|
||||||
onerel->rd_rel->relisshared,
|
onerel->rd_rel->relisshared,
|
||||||
vacrelstats->scanned_all,
|
vacrelstats->scanned_all,
|
||||||
vacstmt->analyze, vacrelstats->rel_tuples);
|
(vacstmt->options & VACOPT_ANALYZE) != 0,
|
||||||
|
vacrelstats->rel_tuples);
|
||||||
|
|
||||||
/* and log the action if appropriate */
|
/* and log the action if appropriate */
|
||||||
if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0)
|
if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0)
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.450 2009/10/28 14:55:38 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.451 2009/11/16 21:32:06 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -2957,10 +2957,7 @@ _copyVacuumStmt(VacuumStmt *from)
|
|||||||
{
|
{
|
||||||
VacuumStmt *newnode = makeNode(VacuumStmt);
|
VacuumStmt *newnode = makeNode(VacuumStmt);
|
||||||
|
|
||||||
COPY_SCALAR_FIELD(vacuum);
|
COPY_SCALAR_FIELD(options);
|
||||||
COPY_SCALAR_FIELD(full);
|
|
||||||
COPY_SCALAR_FIELD(analyze);
|
|
||||||
COPY_SCALAR_FIELD(verbose);
|
|
||||||
COPY_SCALAR_FIELD(freeze_min_age);
|
COPY_SCALAR_FIELD(freeze_min_age);
|
||||||
COPY_SCALAR_FIELD(freeze_table_age);
|
COPY_SCALAR_FIELD(freeze_table_age);
|
||||||
COPY_NODE_FIELD(relation);
|
COPY_NODE_FIELD(relation);
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.372 2009/10/28 14:55:38 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.373 2009/11/16 21:32:06 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1483,10 +1483,7 @@ _equalDropdbStmt(DropdbStmt *a, DropdbStmt *b)
|
|||||||
static bool
|
static bool
|
||||||
_equalVacuumStmt(VacuumStmt *a, VacuumStmt *b)
|
_equalVacuumStmt(VacuumStmt *a, VacuumStmt *b)
|
||||||
{
|
{
|
||||||
COMPARE_SCALAR_FIELD(vacuum);
|
COMPARE_SCALAR_FIELD(options);
|
||||||
COMPARE_SCALAR_FIELD(full);
|
|
||||||
COMPARE_SCALAR_FIELD(analyze);
|
|
||||||
COMPARE_SCALAR_FIELD(verbose);
|
|
||||||
COMPARE_SCALAR_FIELD(freeze_min_age);
|
COMPARE_SCALAR_FIELD(freeze_min_age);
|
||||||
COMPARE_SCALAR_FIELD(freeze_table_age);
|
COMPARE_SCALAR_FIELD(freeze_table_age);
|
||||||
COMPARE_NODE_FIELD(relation);
|
COMPARE_NODE_FIELD(relation);
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.692 2009/11/11 20:31:26 alvherre Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.693 2009/11/16 21:32:06 tgl Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -229,6 +229,7 @@ static TypeName *TableFuncTypeName(List *columns);
|
|||||||
transaction_mode_item
|
transaction_mode_item
|
||||||
|
|
||||||
%type <ival> opt_lock lock_type cast_context
|
%type <ival> opt_lock lock_type cast_context
|
||||||
|
%type <ival> vacuum_option_list vacuum_option_elem
|
||||||
%type <boolean> opt_force opt_or_replace
|
%type <boolean> opt_force opt_or_replace
|
||||||
opt_grant_grant_option opt_grant_admin_option
|
opt_grant_grant_option opt_grant_admin_option
|
||||||
opt_nowait opt_if_exists opt_with_data
|
opt_nowait opt_if_exists opt_with_data
|
||||||
@ -6625,12 +6626,13 @@ cluster_index_specification:
|
|||||||
VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
|
VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
|
||||||
{
|
{
|
||||||
VacuumStmt *n = makeNode(VacuumStmt);
|
VacuumStmt *n = makeNode(VacuumStmt);
|
||||||
n->vacuum = true;
|
n->options = VACOPT_VACUUM;
|
||||||
n->analyze = false;
|
if ($2)
|
||||||
n->full = $2;
|
n->options |= VACOPT_FULL;
|
||||||
|
if ($4)
|
||||||
|
n->options |= VACOPT_VERBOSE;
|
||||||
n->freeze_min_age = $3 ? 0 : -1;
|
n->freeze_min_age = $3 ? 0 : -1;
|
||||||
n->freeze_table_age = $3 ? 0 : -1;
|
n->freeze_table_age = $3 ? 0 : -1;
|
||||||
n->verbose = $4;
|
|
||||||
n->relation = NULL;
|
n->relation = NULL;
|
||||||
n->va_cols = NIL;
|
n->va_cols = NIL;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
@ -6638,12 +6640,13 @@ VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
|
|||||||
| VACUUM opt_full opt_freeze opt_verbose qualified_name
|
| VACUUM opt_full opt_freeze opt_verbose qualified_name
|
||||||
{
|
{
|
||||||
VacuumStmt *n = makeNode(VacuumStmt);
|
VacuumStmt *n = makeNode(VacuumStmt);
|
||||||
n->vacuum = true;
|
n->options = VACOPT_VACUUM;
|
||||||
n->analyze = false;
|
if ($2)
|
||||||
n->full = $2;
|
n->options |= VACOPT_FULL;
|
||||||
|
if ($4)
|
||||||
|
n->options |= VACOPT_VERBOSE;
|
||||||
n->freeze_min_age = $3 ? 0 : -1;
|
n->freeze_min_age = $3 ? 0 : -1;
|
||||||
n->freeze_table_age = $3 ? 0 : -1;
|
n->freeze_table_age = $3 ? 0 : -1;
|
||||||
n->verbose = $4;
|
|
||||||
n->relation = $5;
|
n->relation = $5;
|
||||||
n->va_cols = NIL;
|
n->va_cols = NIL;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
@ -6651,25 +6654,64 @@ VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
|
|||||||
| VACUUM opt_full opt_freeze opt_verbose AnalyzeStmt
|
| VACUUM opt_full opt_freeze opt_verbose AnalyzeStmt
|
||||||
{
|
{
|
||||||
VacuumStmt *n = (VacuumStmt *) $5;
|
VacuumStmt *n = (VacuumStmt *) $5;
|
||||||
n->vacuum = true;
|
n->options |= VACOPT_VACUUM;
|
||||||
n->full = $2;
|
if ($2)
|
||||||
|
n->options |= VACOPT_FULL;
|
||||||
|
if ($4)
|
||||||
|
n->options |= VACOPT_VERBOSE;
|
||||||
n->freeze_min_age = $3 ? 0 : -1;
|
n->freeze_min_age = $3 ? 0 : -1;
|
||||||
n->freeze_table_age = $3 ? 0 : -1;
|
n->freeze_table_age = $3 ? 0 : -1;
|
||||||
n->verbose |= $4;
|
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
|
| VACUUM '(' vacuum_option_list ')'
|
||||||
|
{
|
||||||
|
VacuumStmt *n = makeNode(VacuumStmt);
|
||||||
|
n->options = VACOPT_VACUUM | $3;
|
||||||
|
if (n->options & VACOPT_FREEZE)
|
||||||
|
n->freeze_min_age = n->freeze_table_age = 0;
|
||||||
|
else
|
||||||
|
n->freeze_min_age = n->freeze_table_age = -1;
|
||||||
|
n->relation = NULL;
|
||||||
|
n->va_cols = NIL;
|
||||||
|
$$ = (Node *) n;
|
||||||
|
}
|
||||||
|
| VACUUM '(' vacuum_option_list ')' qualified_name opt_name_list
|
||||||
|
{
|
||||||
|
VacuumStmt *n = makeNode(VacuumStmt);
|
||||||
|
n->options = VACOPT_VACUUM | $3;
|
||||||
|
if (n->options & VACOPT_FREEZE)
|
||||||
|
n->freeze_min_age = n->freeze_table_age = 0;
|
||||||
|
else
|
||||||
|
n->freeze_min_age = n->freeze_table_age = -1;
|
||||||
|
n->relation = $5;
|
||||||
|
n->va_cols = $6;
|
||||||
|
if (n->va_cols != NIL) /* implies analyze */
|
||||||
|
n->options |= VACOPT_ANALYZE;
|
||||||
|
$$ = (Node *) n;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
vacuum_option_list:
|
||||||
|
vacuum_option_elem { $$ = $1; }
|
||||||
|
| vacuum_option_list ',' vacuum_option_elem { $$ = $1 | $3; }
|
||||||
|
;
|
||||||
|
|
||||||
|
vacuum_option_elem:
|
||||||
|
analyze_keyword { $$ = VACOPT_ANALYZE; }
|
||||||
|
| VERBOSE { $$ = VACOPT_VERBOSE; }
|
||||||
|
| FREEZE { $$ = VACOPT_FREEZE; }
|
||||||
|
| FULL { $$ = VACOPT_FULL; }
|
||||||
;
|
;
|
||||||
|
|
||||||
AnalyzeStmt:
|
AnalyzeStmt:
|
||||||
analyze_keyword opt_verbose
|
analyze_keyword opt_verbose
|
||||||
{
|
{
|
||||||
VacuumStmt *n = makeNode(VacuumStmt);
|
VacuumStmt *n = makeNode(VacuumStmt);
|
||||||
n->vacuum = false;
|
n->options = VACOPT_ANALYZE;
|
||||||
n->analyze = true;
|
if ($2)
|
||||||
n->full = false;
|
n->options |= VACOPT_VERBOSE;
|
||||||
n->freeze_min_age = -1;
|
n->freeze_min_age = -1;
|
||||||
n->freeze_table_age = -1;
|
n->freeze_table_age = -1;
|
||||||
n->verbose = $2;
|
|
||||||
n->relation = NULL;
|
n->relation = NULL;
|
||||||
n->va_cols = NIL;
|
n->va_cols = NIL;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
@ -6677,12 +6719,11 @@ AnalyzeStmt:
|
|||||||
| analyze_keyword opt_verbose qualified_name opt_name_list
|
| analyze_keyword opt_verbose qualified_name opt_name_list
|
||||||
{
|
{
|
||||||
VacuumStmt *n = makeNode(VacuumStmt);
|
VacuumStmt *n = makeNode(VacuumStmt);
|
||||||
n->vacuum = false;
|
n->options = VACOPT_ANALYZE;
|
||||||
n->analyze = true;
|
if ($2)
|
||||||
n->full = false;
|
n->options |= VACOPT_VERBOSE;
|
||||||
n->freeze_min_age = -1;
|
n->freeze_min_age = -1;
|
||||||
n->freeze_table_age = -1;
|
n->freeze_table_age = -1;
|
||||||
n->verbose = $2;
|
|
||||||
n->relation = $3;
|
n->relation = $3;
|
||||||
n->va_cols = $4;
|
n->va_cols = $4;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.104 2009/08/31 19:40:59 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.105 2009/11/16 21:32:06 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -2640,12 +2640,13 @@ autovacuum_do_vac_analyze(autovac_table *tab,
|
|||||||
MemSet(&vacstmt, 0, sizeof(vacstmt));
|
MemSet(&vacstmt, 0, sizeof(vacstmt));
|
||||||
|
|
||||||
vacstmt.type = T_VacuumStmt;
|
vacstmt.type = T_VacuumStmt;
|
||||||
vacstmt.vacuum = tab->at_dovacuum;
|
vacstmt.options = 0;
|
||||||
vacstmt.full = false;
|
if (tab->at_dovacuum)
|
||||||
vacstmt.analyze = tab->at_doanalyze;
|
vacstmt.options |= VACOPT_VACUUM;
|
||||||
|
if (tab->at_doanalyze)
|
||||||
|
vacstmt.options |= VACOPT_ANALYZE;
|
||||||
vacstmt.freeze_min_age = tab->at_freeze_min_age;
|
vacstmt.freeze_min_age = tab->at_freeze_min_age;
|
||||||
vacstmt.freeze_table_age = tab->at_freeze_table_age;
|
vacstmt.freeze_table_age = tab->at_freeze_table_age;
|
||||||
vacstmt.verbose = false;
|
|
||||||
vacstmt.relation = NULL; /* not used since we pass a relid */
|
vacstmt.relation = NULL; /* not used since we pass a relid */
|
||||||
vacstmt.va_cols = NIL;
|
vacstmt.va_cols = NIL;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.316 2009/10/26 02:26:40 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.317 2009/11/16 21:32:07 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1815,7 +1815,7 @@ CreateCommandTag(Node *parsetree)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case T_VacuumStmt:
|
case T_VacuumStmt:
|
||||||
if (((VacuumStmt *) parsetree)->vacuum)
|
if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
|
||||||
tag = "VACUUM";
|
tag = "VACUUM";
|
||||||
else
|
else
|
||||||
tag = "ANALYZE";
|
tag = "ANALYZE";
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.414 2009/11/13 23:44:19 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.415 2009/11/16 21:32:07 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -2209,16 +2209,25 @@ typedef struct ClusterStmt
|
|||||||
* Vacuum and Analyze Statements
|
* Vacuum and Analyze Statements
|
||||||
*
|
*
|
||||||
* Even though these are nominally two statements, it's convenient to use
|
* Even though these are nominally two statements, it's convenient to use
|
||||||
* just one node type for both.
|
* just one node type for both. Note that at least one of VACOPT_VACUUM
|
||||||
|
* and VACOPT_ANALYZE must be set in options. VACOPT_FREEZE is an internal
|
||||||
|
* convenience for the grammar and is not examined at runtime --- the
|
||||||
|
* freeze_min_age and freeze_table_age fields are what matter.
|
||||||
* ----------------------
|
* ----------------------
|
||||||
*/
|
*/
|
||||||
|
typedef enum VacuumOption
|
||||||
|
{
|
||||||
|
VACOPT_VACUUM = 1 << 0, /* do VACUUM */
|
||||||
|
VACOPT_ANALYZE = 1 << 1, /* do ANALYZE */
|
||||||
|
VACOPT_VERBOSE = 1 << 2, /* print progress info */
|
||||||
|
VACOPT_FREEZE = 1 << 3, /* FREEZE option */
|
||||||
|
VACOPT_FULL = 1 << 4 /* FULL (non-concurrent) vacuum */
|
||||||
|
} VacuumOption;
|
||||||
|
|
||||||
typedef struct VacuumStmt
|
typedef struct VacuumStmt
|
||||||
{
|
{
|
||||||
NodeTag type;
|
NodeTag type;
|
||||||
bool vacuum; /* do VACUUM step */
|
int options; /* OR of VacuumOption flags */
|
||||||
bool full; /* do FULL (non-concurrent) vacuum */
|
|
||||||
bool analyze; /* do ANALYZE step */
|
|
||||||
bool verbose; /* print progress info */
|
|
||||||
int freeze_min_age; /* min freeze age, or -1 to use default */
|
int freeze_min_age; /* min freeze age, or -1 to use default */
|
||||||
int freeze_table_age; /* age at which to scan whole table */
|
int freeze_table_age; /* age at which to scan whole table */
|
||||||
RangeVar *relation; /* single table to process, or NULL */
|
RangeVar *relation; /* single table to process, or NULL */
|
||||||
|
@ -49,11 +49,12 @@ SELECT count(*) FROM vactst;
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
DELETE FROM vactst WHERE i != 0;
|
DELETE FROM vactst WHERE i != 0;
|
||||||
VACUUM FULL vactst;
|
VACUUM (FULL) vactst;
|
||||||
DELETE FROM vactst;
|
DELETE FROM vactst;
|
||||||
SELECT * FROM vactst;
|
SELECT * FROM vactst;
|
||||||
i
|
i
|
||||||
---
|
---
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
|
VACUUM (FULL, FREEZE) vactst;
|
||||||
DROP TABLE vactst;
|
DROP TABLE vactst;
|
||||||
|
@ -35,8 +35,10 @@ INSERT INTO vactst SELECT * FROM vactst;
|
|||||||
INSERT INTO vactst VALUES (0);
|
INSERT INTO vactst VALUES (0);
|
||||||
SELECT count(*) FROM vactst;
|
SELECT count(*) FROM vactst;
|
||||||
DELETE FROM vactst WHERE i != 0;
|
DELETE FROM vactst WHERE i != 0;
|
||||||
VACUUM FULL vactst;
|
VACUUM (FULL) vactst;
|
||||||
DELETE FROM vactst;
|
DELETE FROM vactst;
|
||||||
SELECT * FROM vactst;
|
SELECT * FROM vactst;
|
||||||
|
|
||||||
|
VACUUM (FULL, FREEZE) vactst;
|
||||||
|
|
||||||
DROP TABLE vactst;
|
DROP TABLE vactst;
|
||||||
|
Reference in New Issue
Block a user