aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/vacuum.c41
-rw-r--r--src/backend/commands/vacuumlazy.c20
-rw-r--r--src/include/commands/vacuum.h4
3 files changed, 52 insertions, 13 deletions
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index e9f41eac323..f9fce596a36 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.317.2.7 2008/02/11 19:14:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.317.2.8 2009/11/10 18:01:11 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
@@ -206,10 +206,10 @@ static void vac_update_dbstats(Oid dbid,
static void vac_truncate_clog(TransactionId vacuumXID,
TransactionId frozenXID);
static bool 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,
@@ -963,6 +963,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
bool result;
Oid save_userid;
bool save_secdefcxt;
+ bool heldoff;
/* Begin a transaction for vacuuming this relation */
StartTransactionCommand();
@@ -1085,9 +1086,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);
result = true; /* did the vacuum */
@@ -1103,6 +1104,10 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
StrategyHintVacuum(false);
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
@@ -1141,8 +1146,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
@@ -1153,6 +1161,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);
@@ -1194,8 +1203,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
@@ -1218,6 +1227,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;
}
@@ -1637,8 +1648,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)
@@ -1662,6 +1676,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
vacuumed_pages;
int keep_tuples = 0;
PGRUsage ru0;
+ bool heldoff = false;
pg_rusage_init(&ru0);
@@ -2373,7 +2388,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();
}
@@ -2563,6 +2584,8 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
pfree(vacrelstats->vtlinks);
ExecContext_Finish(&ec);
+
+ return heldoff;
}
/*
diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c
index f4703ee0175..17c61484ed2 100644
--- a/src/backend/commands/vacuumlazy.c
+++ b/src/backend/commands/vacuumlazy.c
@@ -33,7 +33,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.61.2.7 2009/01/06 14:55:56 heikki Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.61.2.8 2009/11/10 18:01:11 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
@@ -134,8 +134,11 @@ static int vac_cmp_page_spaces(const void *left, const void *right);
*
* 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.
*/
-void
+bool
lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
{
LVRelStats *vacrelstats;
@@ -143,6 +146,7 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
int nindexes;
bool hasindex;
BlockNumber possibly_freeable;
+ bool heldoff = false;
if (vacstmt->verbose)
elevel = INFO;
@@ -173,12 +177,22 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
*
* Don't even think about it unless we have a shot at releasing a goodly
* number of pages. Otherwise, the time taken isn't worth it.
+ *
+ * Note that after we've truncated the heap, it's too late to abort the
+ * transaction; doing so would lose the sinval messages needed to tell
+ * the other backends about the table being shrunk. We prevent interrupts
+ * in that case; caller is responsible for re-enabling them after
+ * committing the transaction.
*/
possibly_freeable = vacrelstats->rel_pages - vacrelstats->nonempty_pages;
if (possibly_freeable > 0 &&
(possibly_freeable >= REL_TRUNCATE_MINIMUM ||
possibly_freeable >= vacrelstats->rel_pages / REL_TRUNCATE_FRACTION))
+ {
+ HOLD_INTERRUPTS();
+ heldoff = true;
lazy_truncate_heap(onerel, vacrelstats);
+ }
/* Update shared free space map with final free space info */
lazy_update_fsm(onerel, vacrelstats);
@@ -192,6 +206,8 @@ lazy_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;
}
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index 13418b018e8..2f1fc903c41 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.62 2005/10/15 02:49:44 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.62.2.1 2009/11/10 18:01:11 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
@@ -125,7 +125,7 @@ extern bool vac_is_partial_index(Relation indrel);
extern void vacuum_delay_point(void);
/* in commands/vacuumlazy.c */
-extern void lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt);
+extern bool lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt);
/* in commands/analyze.c */
extern void analyze_rel(Oid relid, VacuumStmt *vacstmt);