Index: src/backend/commands/vacuum.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/commands/vacuum.c,v
retrieving revision 1.389.2.1
diff -c -p -r1.389.2.1 vacuum.c
*** src/backend/commands/vacuum.c	24 Aug 2009 02:18:40 -0000	1.389.2.1
--- src/backend/commands/vacuum.c	6 Nov 2009 14:01:04 -0000
*************** vacuum_rel(Oid relid, VacuumStmt *vacstm
*** 1023,1028 ****
--- 1023,1029 ----
  	Oid			toast_relid;
  	Oid			save_userid;
  	bool		save_secdefcxt;
+ 	bool		heldoff;
  
  	if (scanned_all)
  		*scanned_all = false;
*************** vacuum_rel(Oid relid, VacuumStmt *vacstm
*** 1189,1197 ****
  	 * Do the actual work --- either FULL or "lazy" vacuum
  	 */
  	if (vacstmt->full)
  		full_vacuum_rel(onerel, vacstmt);
  	else
! 		lazy_vacuum_rel(onerel, vacstmt, vac_strategy, scanned_all);
  
  	/* Restore userid */
  	SetUserIdAndContext(save_userid, save_secdefcxt);
--- 1190,1201 ----
  	 * Do the actual work --- either FULL or "lazy" vacuum
  	 */
  	if (vacstmt->full)
+ 	{
  		full_vacuum_rel(onerel, vacstmt);
+ 		heldoff = false;
+ 	}
  	else
! 		heldoff = lazy_vacuum_rel(onerel, vacstmt, vac_strategy, scanned_all);
  
  	/* Restore userid */
  	SetUserIdAndContext(save_userid, save_secdefcxt);
*************** vacuum_rel(Oid relid, VacuumStmt *vacstm
*** 1205,1210 ****
--- 1209,1218 ----
  	PopActiveSnapshot();
  	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
Index: src/backend/commands/vacuumlazy.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/commands/vacuumlazy.c,v
retrieving revision 1.121.2.1
diff -c -p -r1.121.2.1 vacuumlazy.c
*** src/backend/commands/vacuumlazy.c	24 Aug 2009 02:18:40 -0000	1.121.2.1
--- src/backend/commands/vacuumlazy.c	6 Nov 2009 14:00:11 -0000
*************** static int	vac_cmp_itemptr(const void *l
*** 140,147 ****
   *
   *		At entry, we have already established a transaction and opened
   *		and locked the relation.
   */
! void
  lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
  				BufferAccessStrategy bstrategy, bool *scanned_all)
  {
--- 140,151 ----
   *
   *		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,
  				BufferAccessStrategy bstrategy, bool *scanned_all)
  {
*************** lazy_vacuum_rel(Relation onerel, VacuumS
*** 153,158 ****
--- 157,163 ----
  	TimestampTz starttime = 0;
  	bool		scan_all;
  	TransactionId freezeTableLimit;
+ 	bool		heldoff;
  
  	pg_rusage_init(&ru0);
  
*************** lazy_vacuum_rel(Relation onerel, VacuumS
*** 194,205 ****
--- 199,220 ----
  	 *
  	 * 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);
+ 	}
  
  	/* Vacuum the Free Space Map */
  	FreeSpaceMapVacuum(onerel);
*************** lazy_vacuum_rel(Relation onerel, VacuumS
*** 246,251 ****
--- 261,268 ----
  
  	if (scanned_all)
  		*scanned_all = vacrelstats->scanned_all;
+ 
+ 	return heldoff;
  }
  
  
Index: src/include/commands/vacuum.h
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/include/commands/vacuum.h,v
retrieving revision 1.85
diff -c -p -r1.85 vacuum.h
*** src/include/commands/vacuum.h	11 Jun 2009 14:49:11 -0000	1.85
--- src/include/commands/vacuum.h	6 Nov 2009 13:54:43 -0000
*************** extern bool vac_is_partial_index(Relatio
*** 146,152 ****
  extern void vacuum_delay_point(void);
  
  /* in commands/vacuumlazy.c */
! extern void lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
  				BufferAccessStrategy bstrategy, bool *scanned_all);
  
  /* in commands/analyze.c */
--- 146,152 ----
  extern void vacuum_delay_point(void);
  
  /* in commands/vacuumlazy.c */
! extern bool lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
  				BufferAccessStrategy bstrategy, bool *scanned_all);
  
  /* in commands/analyze.c */
