diff options
Diffstat (limited to 'src/backend/commands/vacuum.c')
-rw-r--r-- | src/backend/commands/vacuum.c | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 6e58d561e89..ffa986c0538 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -13,7 +13,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.342.2.6 2008/09/11 14:01:16 alvherre Exp $ + * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.342.2.7 2009/11/10 18:00:57 alvherre Exp $ * *------------------------------------------------------------------------- */ @@ -204,10 +204,10 @@ static List *get_rel_oids(List *relids, const RangeVar *vacrel, const char *stmttype); static void vac_truncate_clog(TransactionId frozenXID); static void vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind); -static void full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt); +static bool full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt); static void scan_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages, VacPageList fraged_pages); -static void repair_frag(VRelStats *vacrelstats, Relation onerel, +static bool repair_frag(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages, VacPageList fraged_pages, int nindexes, Relation *Irel); static void move_chain_tuple(Relation rel, @@ -959,6 +959,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind) Oid toast_relid; Oid save_userid; bool save_secdefcxt; + bool heldoff; /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); @@ -1102,9 +1103,9 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind) * Do the actual work --- either FULL or "lazy" vacuum */ if (vacstmt->full) - full_vacuum_rel(onerel, vacstmt); + heldoff = full_vacuum_rel(onerel, vacstmt); else - lazy_vacuum_rel(onerel, vacstmt); + heldoff = lazy_vacuum_rel(onerel, vacstmt); StrategyHintVacuum(false); @@ -1119,6 +1120,10 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind) */ CommitTransactionCommand(); + /* now we can allow interrupts again, if disabled */ + if (heldoff) + RESUME_INTERRUPTS(); + /* * If the relation has a secondary toast rel, vacuum that too while we * still hold the session lock on the master table. Note however that @@ -1152,8 +1157,11 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind) * * At entry, we have already established a transaction and opened * and locked the relation. + * + * The return value indicates whether this function has held off + * interrupts -- caller must RESUME_INTERRUPTS() after commit if true. */ -static void +static bool full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt) { VacPageListData vacuum_pages; /* List of pages to vacuum and/or @@ -1164,6 +1172,7 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt) int nindexes, i; VRelStats *vacrelstats; + bool heldoff = false; vacuum_set_xid_limits(vacstmt, onerel->rd_rel->relisshared, &OldestXmin, &FreezeLimit); @@ -1205,8 +1214,8 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt) if (fraged_pages.num_pages > 0) { /* Try to shrink heap */ - repair_frag(vacrelstats, onerel, &vacuum_pages, &fraged_pages, - nindexes, Irel); + heldoff = repair_frag(vacrelstats, onerel, &vacuum_pages, &fraged_pages, + nindexes, Irel); vac_close_indexes(nindexes, Irel, NoLock); } else @@ -1230,6 +1239,8 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt) /* report results to the stats collector, too */ pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared, vacstmt->analyze, vacrelstats->rel_tuples); + + return heldoff; } @@ -1655,8 +1666,11 @@ scan_heap(VRelStats *vacrelstats, Relation onerel, * for them after committing (in hack-manner - without losing locks * and freeing memory!) current transaction. It truncates relation * if some end-blocks are gone away. + * + * The return value indicates whether this function has held off + * interrupts -- caller must RESUME_INTERRUPTS() after commit if true. */ -static void +static bool repair_frag(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages, VacPageList fraged_pages, int nindexes, Relation *Irel) @@ -1680,6 +1694,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel, vacuumed_pages; int keep_tuples = 0; PGRUsage ru0; + bool heldoff = false; pg_rusage_init(&ru0); @@ -2380,7 +2395,13 @@ repair_frag(VRelStats *vacrelstats, Relation onerel, * lot of extra code to close and re-open the relation, indexes, etc. * For now, a quick hack: record status of current transaction as * committed, and continue. + * + * We prevent cancel interrupts after this point to mitigate the + * problem that you can't abort the transaction now; caller is + * responsible for re-enabling them after committing the transaction. */ + HOLD_INTERRUPTS(); + heldoff = true; RecordTransactionCommit(); } @@ -2570,6 +2591,8 @@ repair_frag(VRelStats *vacrelstats, Relation onerel, pfree(vacrelstats->vtlinks); ExecContext_Finish(&ec); + + return heldoff; } /* |