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