Skip to content

Commit 3b0347b

Browse files
committed
Move the tuple freezing point in CLUSTER to a point further back in the past,
to avoid losing useful Xid information in not-so-old tuples. This makes CLUSTER behave the same as VACUUM as far a tuple-freezing behavior goes (though CLUSTER does not yet advance the table's relfrozenxid). While at it, move the actual freezing operation in rewriteheap.c to a more appropriate place, and document it thoroughly. This part of the patch from Tom Lane.
1 parent 90cbc63 commit 3b0347b

File tree

6 files changed

+44
-21
lines changed

6 files changed

+44
-21
lines changed

src/backend/access/heap/rewriteheap.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@
9696
* Portions Copyright (c) 1994-5, Regents of the University of California
9797
*
9898
* IDENTIFICATION
99-
* $PostgreSQL: pgsql/src/backend/access/heap/rewriteheap.c,v 1.4 2007/05/16 16:36:56 alvherre Exp $
99+
* $PostgreSQL: pgsql/src/backend/access/heap/rewriteheap.c,v 1.5 2007/05/17 15:28:29 alvherre Exp $
100100
*
101101
*-------------------------------------------------------------------------
102102
*/
@@ -123,6 +123,8 @@ typedef struct RewriteStateData
123123
bool rs_use_wal; /* must we WAL-log inserts? */
124124
TransactionId rs_oldest_xmin; /* oldest xmin used by caller to
125125
* determine tuple visibility */
126+
TransactionId rs_freeze_xid; /* Xid that will be used as freeze
127+
* cutoff point */
126128
MemoryContext rs_cxt; /* for hash tables and entries and
127129
* tuples in them */
128130
HTAB *rs_unresolved_tups; /* unmatched A tuples */
@@ -171,14 +173,15 @@ static void raw_heap_insert(RewriteState state, HeapTuple tup);
171173
*
172174
* new_heap new, locked heap relation to insert tuples to
173175
* oldest_xmin xid used by the caller to determine which tuples are dead
176+
* freeze_xid xid before which tuples will be frozen
174177
* use_wal should the inserts to the new heap be WAL-logged?
175178
*
176179
* Returns an opaque RewriteState, allocated in current memory context,
177180
* to be used in subsequent calls to the other functions.
178181
*/
179182
RewriteState
180183
begin_heap_rewrite(Relation new_heap, TransactionId oldest_xmin,
181-
bool use_wal)
184+
TransactionId freeze_xid, bool use_wal)
182185
{
183186
RewriteState state;
184187
MemoryContext rw_cxt;
@@ -206,6 +209,7 @@ begin_heap_rewrite(Relation new_heap, TransactionId oldest_xmin,
206209
state->rs_buffer_valid = false;
207210
state->rs_use_wal = use_wal;
208211
state->rs_oldest_xmin = oldest_xmin;
212+
state->rs_freeze_xid = freeze_xid;
209213
state->rs_cxt = rw_cxt;
210214

211215
/* Initialize hash tables used to track update chains */
@@ -292,7 +296,9 @@ end_heap_rewrite(RewriteState state)
292296
/*
293297
* Add a tuple to the new heap.
294298
*
295-
* Visibility information is copied from the original tuple.
299+
* Visibility information is copied from the original tuple, except that
300+
* we "freeze" very-old tuples. Note that since we scribble on new_tuple,
301+
* it had better be temp storage not a pointer to the original tuple.
296302
*
297303
* state opaque state as returned by begin_heap_rewrite
298304
* old_tuple original tuple in the old heap
@@ -323,6 +329,17 @@ rewrite_heap_tuple(RewriteState state,
323329
new_tuple->t_data->t_infomask |=
324330
old_tuple->t_data->t_infomask & HEAP_XACT_MASK;
325331

332+
/*
333+
* While we have our hands on the tuple, we may as well freeze any
334+
* very-old xmin or xmax, so that future VACUUM effort can be saved.
335+
*
336+
* Note we abuse heap_freeze_tuple() a bit here, since it's expecting
337+
* to be given a pointer to a tuple in a disk buffer. It happens
338+
* though that we can get the right things to happen by passing
339+
* InvalidBuffer for the buffer.
340+
*/
341+
heap_freeze_tuple(new_tuple->t_data, state->rs_freeze_xid, InvalidBuffer);
342+
326343
/*
327344
* Invalid ctid means that ctid should point to the tuple itself.
328345
* We'll override it later if the tuple is part of an update chain.
@@ -538,8 +555,6 @@ raw_heap_insert(RewriteState state, HeapTuple tup)
538555
OffsetNumber newoff;
539556
HeapTuple heaptup;
540557

541-
heap_freeze_tuple(tup->t_data, state->rs_oldest_xmin, InvalidBuffer);
542-
543558
/*
544559
* If the new tuple is too big for storage or contains already toasted
545560
* out-of-line attributes from some other relation, invoke the toaster.

src/backend/commands/cluster.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.159 2007/04/08 01:26:28 tgl Exp $
14+
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.160 2007/05/17 15:28:29 alvherre Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -29,6 +29,7 @@
2929
#include "catalog/namespace.h"
3030
#include "catalog/toasting.h"
3131
#include "commands/cluster.h"
32+
#include "commands/vacuum.h"
3233
#include "miscadmin.h"
3334
#include "storage/procarray.h"
3435
#include "utils/acl.h"
@@ -657,6 +658,7 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
657658
HeapTuple tuple;
658659
bool use_wal;
659660
TransactionId OldestXmin;
661+
TransactionId FreezeXid;
660662
RewriteState rwstate;
661663

662664
/*
@@ -688,11 +690,16 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
688690
/* use_wal off requires rd_targblock be initially invalid */
689691
Assert(NewHeap->rd_targblock == InvalidBlockNumber);
690692

691-
/* Get the cutoff xmin we'll use to weed out dead tuples */
692-
OldestXmin = GetOldestXmin(OldHeap->rd_rel->relisshared, true);
693+
/*
694+
* compute xids used to freeze and weed out dead tuples. We use -1
695+
* freeze_min_age to avoid having CLUSTER freeze tuples earlier than
696+
* a plain VACUUM would.
697+
*/
698+
vacuum_set_xid_limits(-1, OldHeap->rd_rel->relisshared,
699+
&OldestXmin, &FreezeXid);
693700

694701
/* Initialize the rewrite operation */
695-
rwstate = begin_heap_rewrite(NewHeap, OldestXmin, use_wal);
702+
rwstate = begin_heap_rewrite(NewHeap, OldestXmin, FreezeXid, use_wal);
696703

697704
/*
698705
* Scan through the OldHeap in OldIndex order and copy each tuple into the

src/backend/commands/vacuum.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
*
1515
* IDENTIFICATION
16-
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.350 2007/04/16 18:29:50 alvherre Exp $
16+
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.351 2007/05/17 15:28:29 alvherre Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -566,7 +566,7 @@ get_rel_oids(List *relids, const RangeVar *vacrel, const char *stmttype)
566566
* vacuum_set_xid_limits() -- compute oldest-Xmin and freeze cutoff points
567567
*/
568568
void
569-
vacuum_set_xid_limits(VacuumStmt *vacstmt, bool sharedRel,
569+
vacuum_set_xid_limits(int freeze_min_age, bool sharedRel,
570570
TransactionId *oldestXmin,
571571
TransactionId *freezeLimit)
572572
{
@@ -588,12 +588,12 @@ vacuum_set_xid_limits(VacuumStmt *vacstmt, bool sharedRel,
588588
Assert(TransactionIdIsNormal(*oldestXmin));
589589

590590
/*
591-
* Determine the minimum freeze age to use: as specified in the vacstmt,
591+
* Determine the minimum freeze age to use: as specified by the caller,
592592
* or vacuum_freeze_min_age, but in any case not more than half
593593
* autovacuum_freeze_max_age, so that autovacuums to prevent XID
594594
* wraparound won't occur too frequently.
595595
*/
596-
freezemin = vacstmt->freeze_min_age;
596+
freezemin = freeze_min_age;
597597
if (freezemin < 0)
598598
freezemin = vacuum_freeze_min_age;
599599
freezemin = Min(freezemin, autovacuum_freeze_max_age / 2);
@@ -1154,7 +1154,7 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
11541154
i;
11551155
VRelStats *vacrelstats;
11561156

1157-
vacuum_set_xid_limits(vacstmt, onerel->rd_rel->relisshared,
1157+
vacuum_set_xid_limits(vacstmt->freeze_min_age, onerel->rd_rel->relisshared,
11581158
&OldestXmin, &FreezeLimit);
11591159

11601160
/*

src/backend/commands/vacuumlazy.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
*
3737
*
3838
* IDENTIFICATION
39-
* $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.88 2007/04/30 03:23:48 tgl Exp $
39+
* $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.89 2007/05/17 15:28:29 alvherre Exp $
4040
*
4141
*-------------------------------------------------------------------------
4242
*/
@@ -158,7 +158,7 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
158158
else
159159
elevel = DEBUG2;
160160

161-
vacuum_set_xid_limits(vacstmt, onerel->rd_rel->relisshared,
161+
vacuum_set_xid_limits(vacstmt->freeze_min_age, onerel->rd_rel->relisshared,
162162
&OldestXmin, &FreezeLimit);
163163

164164
vacrelstats = (LVRelStats *) palloc0(sizeof(LVRelStats));

src/include/access/rewriteheap.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994-5, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/include/access/rewriteheap.h,v 1.1 2007/04/08 01:26:33 tgl Exp $
9+
* $PostgreSQL: pgsql/src/include/access/rewriteheap.h,v 1.2 2007/05/17 15:28:29 alvherre Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -20,10 +20,11 @@
2020
typedef struct RewriteStateData *RewriteState;
2121

2222
extern RewriteState begin_heap_rewrite(Relation NewHeap,
23-
TransactionId OldestXmin, bool use_wal);
23+
TransactionId OldestXmin, TransactionId FreezeXid,
24+
bool use_wal);
2425
extern void end_heap_rewrite(RewriteState state);
2526
extern void rewrite_heap_tuple(RewriteState state, HeapTuple oldTuple,
26-
HeapTuple newTuple);
27+
HeapTuple newTuple);
2728
extern void rewrite_heap_dead_tuple(RewriteState state, HeapTuple oldTuple);
2829

2930
#endif /* REWRITE_HEAP_H */

src/include/commands/vacuum.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.70 2007/03/13 00:33:43 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.71 2007/05/17 15:28:29 alvherre Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -119,7 +119,7 @@ extern void vac_update_relstats(Oid relid,
119119
double num_tuples,
120120
bool hasindex,
121121
TransactionId frozenxid);
122-
extern void vacuum_set_xid_limits(VacuumStmt *vacstmt, bool sharedRel,
122+
extern void vacuum_set_xid_limits(int freeze_min_age, bool sharedRel,
123123
TransactionId *oldestXmin,
124124
TransactionId *freezeLimit);
125125
extern void vac_update_datfrozenxid(void);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy