*** pgsql/src/backend/commands/vacuum.c 2008/02/11 19:14:53 1.299.4.4 --- pgsql/src/backend/commands/vacuum.c 2009/11/10 18:01:26 1.299.4.5 *************** *** 13,19 **** * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.299.4.3 2008/01/03 21:25:00 tgl Exp $ * *------------------------------------------------------------------------- */ --- 13,19 ---- * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.299.4.4 2008/02/11 19:14:53 tgl Exp $ * *------------------------------------------------------------------------- */ *************** static void vac_update_dbstats(Oid dbid, *** 176,185 **** 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, --- 176,185 ---- 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 *** 885,890 **** --- 885,891 ---- bool result; AclId save_userid; bool save_secdefcxt; + bool heldoff; /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); *************** vacuum_rel(Oid relid, VacuumStmt *vacstm *** 1011,1019 **** * 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 */ --- 1012,1020 ---- * 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 *** 1029,1034 **** --- 1030,1039 ---- 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 *** 1067,1074 **** * * 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 --- 1072,1082 ---- * * 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 bool full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt) { VacPageListData vacuum_pages; /* List of pages to vacuum and/or *************** full_vacuum_rel(Relation onerel, VacuumS *** 1079,1084 **** --- 1087,1093 ---- 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 *** 1120,1127 **** 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 --- 1129,1136 ---- 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 *** 1150,1155 **** --- 1159,1166 ---- /* update statistics in pg_class */ vac_update_relstats(RelationGetRelid(onerel), vacrelstats->rel_pages, vacrelstats->rel_tuples, vacrelstats->hasindex); + + return heldoff; } *************** scan_heap(VRelStats *vacrelstats, Relati *** 1563,1570 **** * 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) --- 1574,1584 ---- * 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 bool repair_frag(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages, VacPageList fraged_pages, int nindexes, Relation *Irel) *************** repair_frag(VRelStats *vacrelstats, Rela *** 1588,1593 **** --- 1602,1608 ---- vacuumed_pages; int keep_tuples = 0; VacRUsage ru0; + bool heldoff = false; vac_init_rusage(&ru0); *************** repair_frag(VRelStats *vacrelstats, Rela *** 2292,2298 **** --- 2307,2319 ---- * a 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(); } *************** repair_frag(VRelStats *vacrelstats, Rela *** 2491,2496 **** --- 2512,2519 ---- pfree(vacrelstats->vtlinks); ExecContext_Finish(&ec); + + return heldoff; } /*