vactrunc-nointerrupt-2-81.patch
text/x-diff
Filename: vactrunc-nointerrupt-2-81.patch
Type: text/x-diff
Part: 0
Patch
Format: context
| File | + | − |
|---|---|---|
| src/backend/commands/vacuum.c | 29 | 8 |
| src/backend/commands/vacuumlazy.c | 18 | 1 |
| src/include/commands/vacuum.h | 1 | 1 |
Index: src/backend/commands/vacuum.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/commands/vacuum.c,v
retrieving revision 1.317.2.7
diff -c -p -r1.317.2.7 vacuum.c
*** src/backend/commands/vacuum.c 11 Feb 2008 19:14:45 -0000 1.317.2.7
--- src/backend/commands/vacuum.c 6 Nov 2009 17:15:40 -0000
*************** static void vac_update_dbstats(Oid dbid,
*** 206,215 ****
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 void scan_heap(VRelStats *vacrelstats, Relation onerel,
VacPageList vacuum_pages, VacPageList fraged_pages);
! static void repair_frag(VRelStats *vacrelstats, Relation onerel,
VacPageList vacuum_pages, VacPageList fraged_pages,
int nindexes, Relation *Irel);
static void move_chain_tuple(Relation rel,
--- 206,215 ----
static void vac_truncate_clog(TransactionId vacuumXID,
TransactionId frozenXID);
static bool vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind);
! static bool full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt);
static void scan_heap(VRelStats *vacrelstats, Relation onerel,
VacPageList vacuum_pages, VacPageList fraged_pages);
! 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,
*************** vacuum_rel(Oid relid, VacuumStmt *vacstm
*** 963,968 ****
--- 963,969 ----
bool result;
Oid save_userid;
bool save_secdefcxt;
+ bool heldoff;
/* Begin a transaction for vacuuming this relation */
StartTransactionCommand();
*************** vacuum_rel(Oid relid, VacuumStmt *vacstm
*** 1085,1093 ****
* Do the actual work --- either FULL or "lazy" vacuum
*/
if (vacstmt->full)
! full_vacuum_rel(onerel, vacstmt);
else
! lazy_vacuum_rel(onerel, vacstmt);
result = true; /* did the vacuum */
--- 1086,1094 ----
* Do the actual work --- either FULL or "lazy" vacuum
*/
if (vacstmt->full)
! heldoff = full_vacuum_rel(onerel, vacstmt);
else
! heldoff = lazy_vacuum_rel(onerel, vacstmt);
result = true; /* did the vacuum */
*************** vacuum_rel(Oid relid, VacuumStmt *vacstm
*** 1103,1108 ****
--- 1104,1113 ----
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
*************** vacuum_rel(Oid relid, VacuumStmt *vacstm
*** 1141,1148 ****
*
* At entry, we have already established a transaction and opened
* and locked the relation.
*/
! static void
full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
{
VacPageListData vacuum_pages; /* List of pages to vacuum and/or
--- 1146,1157 ----
*
* 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 call RESUME_INTERRUPTS() after commit if
+ * it is true.
*/
! static bool
full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
{
VacPageListData vacuum_pages; /* List of pages to vacuum and/or
*************** full_vacuum_rel(Relation onerel, VacuumS
*** 1153,1158 ****
--- 1162,1168 ----
int nindexes,
i;
VRelStats *vacrelstats;
+ bool heldoff = false;
vacuum_set_xid_limits(vacstmt, onerel->rd_rel->relisshared,
&OldestXmin, &FreezeLimit);
*************** full_vacuum_rel(Relation onerel, VacuumS
*** 1194,1201 ****
if (fraged_pages.num_pages > 0)
{
/* Try to shrink heap */
! repair_frag(vacrelstats, onerel, &vacuum_pages, &fraged_pages,
! nindexes, Irel);
vac_close_indexes(nindexes, Irel, NoLock);
}
else
--- 1204,1211 ----
if (fraged_pages.num_pages > 0)
{
/* Try to shrink heap */
! heldoff = repair_frag(vacrelstats, onerel, &vacuum_pages, &fraged_pages,
! nindexes, Irel);
vac_close_indexes(nindexes, Irel, NoLock);
}
else
*************** full_vacuum_rel(Relation onerel, VacuumS
*** 1218,1223 ****
--- 1228,1235 ----
/* report results to the stats collector, too */
pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared,
vacstmt->analyze, vacrelstats->rel_tuples);
+
+ return heldoff;
}
*************** scan_heap(VRelStats *vacrelstats, Relati
*** 1637,1644 ****
* 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.
*/
! static void
repair_frag(VRelStats *vacrelstats, Relation onerel,
VacPageList vacuum_pages, VacPageList fraged_pages,
int nindexes, Relation *Irel)
--- 1649,1660 ----
* 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 call RESUME_INTERRUPTS() after commit if
+ * it is true.
*/
! static bool
repair_frag(VRelStats *vacrelstats, Relation onerel,
VacPageList vacuum_pages, VacPageList fraged_pages,
int nindexes, Relation *Irel)
*************** repair_frag(VRelStats *vacrelstats, Rela
*** 1662,1667 ****
--- 1678,1684 ----
vacuumed_pages;
int keep_tuples = 0;
PGRUsage ru0;
+ bool heldoff = false;
pg_rusage_init(&ru0);
*************** repair_frag(VRelStats *vacrelstats, Rela
*** 2374,2379 ****
--- 2391,2398 ----
* For now, a quick hack: record status of current transaction as
* committed, and continue.
*/
+ HOLD_INTERRUPTS();
+ heldoff = true;
RecordTransactionCommit();
}
*************** repair_frag(VRelStats *vacrelstats, Rela
*** 2563,2568 ****
--- 2582,2589 ----
pfree(vacrelstats->vtlinks);
ExecContext_Finish(&ec);
+
+ return heldoff;
}
/*
Index: src/backend/commands/vacuumlazy.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/commands/vacuumlazy.c,v
retrieving revision 1.61.2.7
diff -c -p -r1.61.2.7 vacuumlazy.c
*** src/backend/commands/vacuumlazy.c 6 Jan 2009 14:55:56 -0000 1.61.2.7
--- src/backend/commands/vacuumlazy.c 6 Nov 2009 16:03:37 -0000
*************** static int vac_cmp_page_spaces(const voi
*** 134,141 ****
*
* At entry, we have already established a transaction and opened
* and locked the relation.
*/
! void
lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
{
LVRelStats *vacrelstats;
--- 134,145 ----
*
* 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 call RESUME_INTERRUPTS() after commit if
+ * it is true.
*/
! bool
lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
{
LVRelStats *vacrelstats;
*************** lazy_vacuum_rel(Relation onerel, VacuumS
*** 143,148 ****
--- 147,153 ----
int nindexes;
bool hasindex;
BlockNumber possibly_freeable;
+ bool heldoff;
if (vacstmt->verbose)
elevel = INFO;
*************** lazy_vacuum_rel(Relation onerel, VacuumS
*** 173,184 ****
--- 178,199 ----
*
* 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 hold off interrupts
+ * in that case; the caller is responsible for releasing 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);
*************** lazy_vacuum_rel(Relation onerel, VacuumS
*** 192,197 ****
--- 207,214 ----
/* report results to the stats collector, too */
pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared,
vacstmt->analyze, vacrelstats->rel_tuples);
+
+ return heldoff;
}
Index: src/include/commands/vacuum.h
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/include/commands/vacuum.h,v
retrieving revision 1.62
diff -c -p -r1.62 vacuum.h
*** src/include/commands/vacuum.h 15 Oct 2005 02:49:44 -0000 1.62
--- src/include/commands/vacuum.h 6 Nov 2009 14:21:04 -0000
*************** extern bool vac_is_partial_index(Relatio
*** 125,131 ****
extern void vacuum_delay_point(void);
/* in commands/vacuumlazy.c */
! extern void lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt);
/* in commands/analyze.c */
extern void analyze_rel(Oid relid, VacuumStmt *vacstmt);
--- 125,131 ----
extern void vacuum_delay_point(void);
/* in commands/vacuumlazy.c */
! extern bool lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt);
/* in commands/analyze.c */
extern void analyze_rel(Oid relid, VacuumStmt *vacstmt);