Tom Lane wrote:
> Alvaro Herrera <[EMAIL PROTECTED]> writes:
> > Tom Lane wrote:
> >> Heikki Linnakangas <[EMAIL PROTECTED]> writes:
> >>> How about freezing anything older than vacuum_freeze_min_age, just like 
> >>> VACUUM does?
> >> 
> >> I suppose that'd be OK, but is it likely to be worth the trouble?
> 
> > I think so, because it means that people using CLUSTER to keep the size
> > of tables in line instead of VACUUM, would not need the otherwise
> > mandatory VACUUM.
> 
> Fair enough.  Who will fix the already-applied patch?

Here is my proposed patch.

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support
Index: src/backend/access/heap/rewriteheap.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/access/heap/rewriteheap.c,v
retrieving revision 1.4
diff -c -p -r1.4 rewriteheap.c
*** src/backend/access/heap/rewriteheap.c	16 May 2007 16:36:56 -0000	1.4
--- src/backend/access/heap/rewriteheap.c	16 May 2007 22:34:18 -0000
*************** typedef struct RewriteStateData
*** 123,128 ****
--- 123,130 ----
  	bool			rs_use_wal;			/* must we WAL-log inserts? */
  	TransactionId	rs_oldest_xmin;		/* oldest xmin used by caller to
  										 * determine tuple visibility */
+ 	TransactionId	rs_freeze_xid;		/* Xid that will be used as freeze
+ 										 * cutoff point */
  	MemoryContext	rs_cxt;				/* for hash tables and entries and
  										 * tuples in them */
  	HTAB		   *rs_unresolved_tups;	/* unmatched A tuples */
*************** static void raw_heap_insert(RewriteState
*** 171,176 ****
--- 173,179 ----
   *
   * new_heap		new, locked heap relation to insert tuples to
   * oldest_xmin	xid used by the caller to determine which tuples are dead
+  * freeze_xid	xid before which tuples will be frozen
   * use_wal		should the inserts to the new heap be WAL-logged?
   *
   * Returns an opaque RewriteState, allocated in current memory context,
*************** static void raw_heap_insert(RewriteState
*** 178,184 ****
   */
  RewriteState
  begin_heap_rewrite(Relation new_heap, TransactionId oldest_xmin,
! 				   bool use_wal)
  {
  	RewriteState state;
  	MemoryContext rw_cxt;
--- 181,187 ----
   */
  RewriteState
  begin_heap_rewrite(Relation new_heap, TransactionId oldest_xmin,
! 				   TransactionId freeze_xid, bool use_wal)
  {
  	RewriteState state;
  	MemoryContext rw_cxt;
*************** begin_heap_rewrite(Relation new_heap, Tr
*** 206,211 ****
--- 209,215 ----
  	state->rs_buffer_valid = false;
  	state->rs_use_wal = use_wal;
  	state->rs_oldest_xmin = oldest_xmin;
+ 	state->rs_freeze_xid = freeze_xid;
  	state->rs_cxt = rw_cxt;
  
  	/* Initialize hash tables used to track update chains */
*************** raw_heap_insert(RewriteState state, Heap
*** 538,544 ****
  	OffsetNumber	newoff;
  	HeapTuple		heaptup;
  
! 	heap_freeze_tuple(tup->t_data, state->rs_oldest_xmin, InvalidBuffer);
  
  	/*
  	 * If the new tuple is too big for storage or contains already toasted
--- 542,548 ----
  	OffsetNumber	newoff;
  	HeapTuple		heaptup;
  
! 	heap_freeze_tuple(tup->t_data, state->rs_freeze_xid, InvalidBuffer);
  
  	/*
  	 * If the new tuple is too big for storage or contains already toasted
Index: src/backend/commands/cluster.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/cluster.c,v
retrieving revision 1.159
diff -c -p -r1.159 cluster.c
*** src/backend/commands/cluster.c	8 Apr 2007 01:26:28 -0000	1.159
--- src/backend/commands/cluster.c	16 May 2007 22:34:24 -0000
***************
*** 29,34 ****
--- 29,35 ----
  #include "catalog/namespace.h"
  #include "catalog/toasting.h"
  #include "commands/cluster.h"
+ #include "commands/vacuum.h"
  #include "miscadmin.h"
  #include "storage/procarray.h"
  #include "utils/acl.h"
*************** copy_heap_data(Oid OIDNewHeap, Oid OIDOl
*** 657,662 ****
--- 658,664 ----
  	HeapTuple	tuple;
  	bool		use_wal;
  	TransactionId OldestXmin;
+ 	TransactionId FreezeXid;
  	RewriteState rwstate;
  
  	/*
*************** copy_heap_data(Oid OIDNewHeap, Oid OIDOl
*** 688,698 ****
  	/* use_wal off requires rd_targblock be initially invalid */
  	Assert(NewHeap->rd_targblock == InvalidBlockNumber);
  
! 	/* Get the cutoff xmin we'll use to weed out dead tuples */
! 	OldestXmin = GetOldestXmin(OldHeap->rd_rel->relisshared, true);
  
  	/* Initialize the rewrite operation */
! 	rwstate = begin_heap_rewrite(NewHeap, OldestXmin, use_wal);
  
  	/*
  	 * Scan through the OldHeap in OldIndex order and copy each tuple into the
--- 690,705 ----
  	/* use_wal off requires rd_targblock be initially invalid */
  	Assert(NewHeap->rd_targblock == InvalidBlockNumber);
  
! 	/*
! 	 * compute xids used to freeze and weed out dead tuples.  We use -1
! 	 * freeze_min_age to avoid having CLUSTER freeze tuples earlier than
! 	 * a plain VACUUM would.
! 	 */
! 	vacuum_set_xid_limits(-1, OldHeap->rd_rel->relisshared,
! 						  &OldestXmin, &FreezeXid);
  
  	/* Initialize the rewrite operation */
! 	rwstate = begin_heap_rewrite(NewHeap, OldestXmin, FreezeXid, use_wal);
  
  	/*
  	 * Scan through the OldHeap in OldIndex order and copy each tuple into the
Index: src/backend/commands/vacuum.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/vacuum.c,v
retrieving revision 1.350
diff -c -p -r1.350 vacuum.c
*** src/backend/commands/vacuum.c	16 Apr 2007 18:29:50 -0000	1.350
--- src/backend/commands/vacuum.c	16 May 2007 22:34:47 -0000
*************** get_rel_oids(List *relids, const RangeVa
*** 566,572 ****
   * vacuum_set_xid_limits() -- compute oldest-Xmin and freeze cutoff points
   */
  void
! vacuum_set_xid_limits(VacuumStmt *vacstmt, bool sharedRel,
  					  TransactionId *oldestXmin,
  					  TransactionId *freezeLimit)
  {
--- 566,572 ----
   * vacuum_set_xid_limits() -- compute oldest-Xmin and freeze cutoff points
   */
  void
! vacuum_set_xid_limits(int freeze_min_age, bool sharedRel,
  					  TransactionId *oldestXmin,
  					  TransactionId *freezeLimit)
  {
*************** vacuum_set_xid_limits(VacuumStmt *vacstm
*** 588,599 ****
  	Assert(TransactionIdIsNormal(*oldestXmin));
  
  	/*
! 	 * Determine the minimum freeze age to use: as specified in the vacstmt,
  	 * or vacuum_freeze_min_age, but in any case not more than half
  	 * autovacuum_freeze_max_age, so that autovacuums to prevent XID
  	 * wraparound won't occur too frequently.
  	 */
! 	freezemin = vacstmt->freeze_min_age;
  	if (freezemin < 0)
  		freezemin = vacuum_freeze_min_age;
  	freezemin = Min(freezemin, autovacuum_freeze_max_age / 2);
--- 588,599 ----
  	Assert(TransactionIdIsNormal(*oldestXmin));
  
  	/*
! 	 * Determine the minimum freeze age to use: as specified by the caller,
  	 * or vacuum_freeze_min_age, but in any case not more than half
  	 * autovacuum_freeze_max_age, so that autovacuums to prevent XID
  	 * wraparound won't occur too frequently.
  	 */
! 	freezemin = freeze_min_age;
  	if (freezemin < 0)
  		freezemin = vacuum_freeze_min_age;
  	freezemin = Min(freezemin, autovacuum_freeze_max_age / 2);
*************** full_vacuum_rel(Relation onerel, VacuumS
*** 1154,1160 ****
  				i;
  	VRelStats  *vacrelstats;
  
! 	vacuum_set_xid_limits(vacstmt, onerel->rd_rel->relisshared,
  						  &OldestXmin, &FreezeLimit);
  
  	/*
--- 1154,1160 ----
  				i;
  	VRelStats  *vacrelstats;
  
! 	vacuum_set_xid_limits(vacstmt->freeze_min_age, onerel->rd_rel->relisshared,
  						  &OldestXmin, &FreezeLimit);
  
  	/*
Index: src/backend/commands/vacuumlazy.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/vacuumlazy.c,v
retrieving revision 1.88
diff -c -p -r1.88 vacuumlazy.c
*** src/backend/commands/vacuumlazy.c	30 Apr 2007 03:23:48 -0000	1.88
--- src/backend/commands/vacuumlazy.c	16 May 2007 22:34:55 -0000
*************** lazy_vacuum_rel(Relation onerel, VacuumS
*** 158,164 ****
  	else
  		elevel = DEBUG2;
  
! 	vacuum_set_xid_limits(vacstmt, onerel->rd_rel->relisshared,
  						  &OldestXmin, &FreezeLimit);
  
  	vacrelstats = (LVRelStats *) palloc0(sizeof(LVRelStats));
--- 158,164 ----
  	else
  		elevel = DEBUG2;
  
! 	vacuum_set_xid_limits(vacstmt->freeze_min_age, onerel->rd_rel->relisshared,
  						  &OldestXmin, &FreezeLimit);
  
  	vacrelstats = (LVRelStats *) palloc0(sizeof(LVRelStats));
Index: src/include/access/rewriteheap.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/access/rewriteheap.h,v
retrieving revision 1.1
diff -c -p -r1.1 rewriteheap.h
*** src/include/access/rewriteheap.h	8 Apr 2007 01:26:33 -0000	1.1
--- src/include/access/rewriteheap.h	16 May 2007 22:35:05 -0000
***************
*** 20,29 ****
  typedef struct RewriteStateData *RewriteState;
  
  extern RewriteState begin_heap_rewrite(Relation NewHeap,
! 									   TransactionId OldestXmin, bool use_wal);
  extern void end_heap_rewrite(RewriteState state);
  extern void rewrite_heap_tuple(RewriteState state, HeapTuple oldTuple,
! 							   HeapTuple newTuple);
  extern void rewrite_heap_dead_tuple(RewriteState state, HeapTuple oldTuple);
  
  #endif /* REWRITE_HEAP_H */
--- 20,30 ----
  typedef struct RewriteStateData *RewriteState;
  
  extern RewriteState begin_heap_rewrite(Relation NewHeap,
! 				   TransactionId OldestXmin, TransactionId FreezeXid,
! 				   bool use_wal);
  extern void end_heap_rewrite(RewriteState state);
  extern void rewrite_heap_tuple(RewriteState state, HeapTuple oldTuple,
! 				   HeapTuple newTuple);
  extern void rewrite_heap_dead_tuple(RewriteState state, HeapTuple oldTuple);
  
  #endif /* REWRITE_HEAP_H */
Index: src/include/commands/vacuum.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/commands/vacuum.h,v
retrieving revision 1.70
diff -c -p -r1.70 vacuum.h
*** src/include/commands/vacuum.h	13 Mar 2007 00:33:43 -0000	1.70
--- src/include/commands/vacuum.h	16 May 2007 22:35:08 -0000
*************** extern void vac_update_relstats(Oid reli
*** 119,125 ****
  					double num_tuples,
  					bool hasindex,
  					TransactionId frozenxid);
! extern void vacuum_set_xid_limits(VacuumStmt *vacstmt, bool sharedRel,
  					  TransactionId *oldestXmin,
  					  TransactionId *freezeLimit);
  extern void vac_update_datfrozenxid(void);
--- 119,125 ----
  					double num_tuples,
  					bool hasindex,
  					TransactionId frozenxid);
! extern void vacuum_set_xid_limits(int freeze_min_age, bool sharedRel,
  					  TransactionId *oldestXmin,
  					  TransactionId *freezeLimit);
  extern void vac_update_datfrozenxid(void);
---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?

               http://www.postgresql.org/docs/faq

Reply via email to