Commit 3ccde312 authored by Alvaro Herrera's avatar Alvaro Herrera

Have autovacuum consider processing TOAST tables separately from their

main tables.

This requires vacuum() to accept processing a toast table standalone, so
there's a user-visible change in that it's now possible (for a superuser) to
execute "VACUUM pg_toast.pg_toast_XXX".
parent 010eebf1
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.375 2008/06/05 15:47:32 alvherre Exp $ * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.376 2008/08/13 00:07:50 alvherre Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -213,8 +213,8 @@ static BufferAccessStrategy vac_strategy; ...@@ -213,8 +213,8 @@ static BufferAccessStrategy vac_strategy;
static List *get_rel_oids(Oid relid, const RangeVar *vacrel, static List *get_rel_oids(Oid relid, const RangeVar *vacrel,
const char *stmttype); const char *stmttype);
static void vac_truncate_clog(TransactionId frozenXID); static void vac_truncate_clog(TransactionId frozenXID);
static void vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind, static void vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast,
bool for_wraparound); bool for_wraparound);
static void full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt); static void full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt);
static void scan_heap(VRelStats *vacrelstats, Relation onerel, static void scan_heap(VRelStats *vacrelstats, Relation onerel,
VacPageList vacuum_pages, VacPageList fraged_pages); VacPageList vacuum_pages, VacPageList fraged_pages);
...@@ -268,6 +268,9 @@ static Size PageGetFreeSpaceWithFillFactor(Relation relation, Page page); ...@@ -268,6 +268,9 @@ static Size PageGetFreeSpaceWithFillFactor(Relation relation, Page page);
* OID to be processed, and vacstmt->relation is ignored. (The non-invalid * OID to be processed, and vacstmt->relation is ignored. (The non-invalid
* case is currently only used by autovacuum.) * case is currently only used by autovacuum.)
* *
* do_toast is passed as FALSE by autovacuum, because it processes TOAST
* tables separately.
*
* for_wraparound is used by autovacuum to let us know when it's forcing * for_wraparound is used by autovacuum to let us know when it's forcing
* a vacuum for wraparound, which should not be auto-cancelled. * a vacuum for wraparound, which should not be auto-cancelled.
* *
...@@ -281,7 +284,7 @@ static Size PageGetFreeSpaceWithFillFactor(Relation relation, Page page); ...@@ -281,7 +284,7 @@ static Size PageGetFreeSpaceWithFillFactor(Relation relation, Page page);
* at transaction commit. * at transaction commit.
*/ */
void void
vacuum(VacuumStmt *vacstmt, Oid relid, 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 = vacstmt->vacuum ? "VACUUM" : "ANALYZE";
...@@ -433,7 +436,7 @@ vacuum(VacuumStmt *vacstmt, Oid relid, ...@@ -433,7 +436,7 @@ vacuum(VacuumStmt *vacstmt, Oid relid,
Oid relid = lfirst_oid(cur); Oid relid = lfirst_oid(cur);
if (vacstmt->vacuum) if (vacstmt->vacuum)
vacuum_rel(relid, vacstmt, RELKIND_RELATION, for_wraparound); vacuum_rel(relid, vacstmt, do_toast, for_wraparound);
if (vacstmt->analyze) if (vacstmt->analyze)
{ {
...@@ -975,8 +978,7 @@ vac_truncate_clog(TransactionId frozenXID) ...@@ -975,8 +978,7 @@ vac_truncate_clog(TransactionId frozenXID)
* At entry and exit, we are not inside a transaction. * At entry and exit, we are not inside a transaction.
*/ */
static void static void
vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind, vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound)
bool for_wraparound)
{ {
LOCKMODE lmode; LOCKMODE lmode;
Relation onerel; Relation onerel;
...@@ -1013,8 +1015,8 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind, ...@@ -1013,8 +1015,8 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind,
* by autovacuum; it's used to avoid cancelling a vacuum that was * by autovacuum; it's used to avoid cancelling a vacuum that was
* invoked in an emergency. * invoked in an emergency.
* *
* Note: this flag remains set until CommitTransaction or * Note: these flags remain set until CommitTransaction or
* AbortTransaction. We don't want to clear it until we reset * AbortTransaction. We don't want to clear them until we reset
* MyProc->xid/xmin, else OldestXmin might appear to go backwards, * MyProc->xid/xmin, else OldestXmin might appear to go backwards,
* which is probably Not Good. * which is probably Not Good.
*/ */
...@@ -1087,10 +1089,11 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind, ...@@ -1087,10 +1089,11 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind,
} }
/* /*
* Check that it's a plain table; we used to do this in get_rel_oids() but * Check that it's a vacuumable table; we used to do this in get_rel_oids()
* seems safer to check after we've locked the relation. * but seems safer to check after we've locked the relation.
*/ */
if (onerel->rd_rel->relkind != expected_relkind) if (onerel->rd_rel->relkind != RELKIND_RELATION &&
onerel->rd_rel->relkind != RELKIND_TOASTVALUE)
{ {
ereport(WARNING, ereport(WARNING,
(errmsg("skipping \"%s\" --- cannot vacuum indexes, views, or special system tables", (errmsg("skipping \"%s\" --- cannot vacuum indexes, views, or special system tables",
...@@ -1132,9 +1135,13 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind, ...@@ -1132,9 +1135,13 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind,
LockRelationIdForSession(&onerelid, lmode); LockRelationIdForSession(&onerelid, lmode);
/* /*
* Remember the relation's TOAST relation for later * Remember the relation's TOAST relation for later, if the caller asked
* us to process it.
*/ */
toast_relid = onerel->rd_rel->reltoastrelid; if (do_toast)
toast_relid = onerel->rd_rel->reltoastrelid;
else
toast_relid = InvalidOid;
/* /*
* Switch to the table owner's userid, so that any index functions are * Switch to the table owner's userid, so that any index functions are
...@@ -1173,7 +1180,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind, ...@@ -1173,7 +1180,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind,
* totally unimportant for toast relations. * totally unimportant for toast relations.
*/ */
if (toast_relid != InvalidOid) if (toast_relid != InvalidOid)
vacuum_rel(toast_relid, vacstmt, RELKIND_TOASTVALUE, for_wraparound); vacuum_rel(toast_relid, vacstmt, false, for_wraparound);
/* /*
* Now release the session-level lock on the master table. * Now release the session-level lock on the master table.
......
This diff is collapsed.
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.295 2008/07/18 20:26:06 tgl Exp $ * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.296 2008/08/13 00:07:50 alvherre Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -836,7 +836,7 @@ ProcessUtility(Node *parsetree, ...@@ -836,7 +836,7 @@ ProcessUtility(Node *parsetree,
break; break;
case T_VacuumStmt: case T_VacuumStmt:
vacuum((VacuumStmt *) parsetree, InvalidOid, NULL, false, vacuum((VacuumStmt *) parsetree, InvalidOid, true, NULL, false,
isTopLevel); isTopLevel);
break; break;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, 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/commands/vacuum.h,v 1.79 2008/07/01 10:33:09 heikki Exp $ * $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.80 2008/08/13 00:07:50 alvherre Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -125,7 +125,7 @@ extern int vacuum_freeze_min_age; ...@@ -125,7 +125,7 @@ extern int vacuum_freeze_min_age;
/* in commands/vacuum.c */ /* in commands/vacuum.c */
extern void vacuum(VacuumStmt *vacstmt, Oid relid, extern void vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
BufferAccessStrategy bstrategy, bool for_wraparound, bool isTopLevel); BufferAccessStrategy bstrategy, bool for_wraparound, bool isTopLevel);
extern void vac_open_indexes(Relation relation, LOCKMODE lockmode, extern void vac_open_indexes(Relation relation, LOCKMODE lockmode,
int *nindexes, Relation **Irel); int *nindexes, Relation **Irel);
......
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