Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5076770

Browse files
Rename and relocate freeze plan dedup routines.
Rename the heapam.c freeze plan deduplication routines added by commit 9e54059 to names that follow conventions for functions in heapam.c. Also relocate the functions so that they're next to their caller, which runs during original execution, when FREEZE_PAGE WAL records are built. The routines were initially placed next to (and followed the naming conventions of) conceptually related REDO routine code, but that scheme turned out to be kind of jarring when considered in a wider context. Author: Peter Geoghegan <pg@bowt.ie> Reported-By: Andres Freund <andres@anarazel.de> Discussion: https://postgr.es/m/20230109214308.icz26oqvt3k2274c@awork3.anarazel.de
1 parent 1b4d280 commit 5076770

File tree

1 file changed

+147
-149
lines changed

1 file changed

+147
-149
lines changed

src/backend/access/heap/heapam.c

+147-149
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ static void compute_new_xmax_infomask(TransactionId xmax, uint16 old_infomask,
9595
static TM_Result heap_lock_updated_tuple(Relation rel, HeapTuple tuple,
9696
ItemPointer ctid, TransactionId xid,
9797
LockTupleMode mode);
98+
static int heap_log_freeze_plan(HeapTupleFreeze *tuples, int ntuples,
99+
xl_heap_freeze_plan *plans_out,
100+
OffsetNumber *offsets_out);
98101
static void GetMultiXactIdHintBits(MultiXactId multi, uint16 *new_infomask,
99102
uint16 *new_infomask2);
100103
static TransactionId MultiXactIdGetUpdateXid(TransactionId xmax,
@@ -111,9 +114,6 @@ static int bottomup_sort_and_shrink(TM_IndexDeleteOp *delstate);
111114
static XLogRecPtr log_heap_new_cid(Relation relation, HeapTuple tup);
112115
static HeapTuple ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_required,
113116
bool *copy);
114-
static int heap_xlog_freeze_plan(HeapTupleFreeze *tuples, int ntuples,
115-
xl_heap_freeze_plan *plans_out,
116-
OffsetNumber *offsets_out);
117117

118118

119119
/*
@@ -6868,7 +6868,7 @@ heap_freeze_execute_prepared(Relation rel, Buffer buffer,
68686868
XLogRecPtr recptr;
68696869

68706870
/* Prepare deduplicated representation for use in WAL record */
6871-
nplans = heap_xlog_freeze_plan(tuples, ntuples, plans, offsets);
6871+
nplans = heap_log_freeze_plan(tuples, ntuples, plans, offsets);
68726872

68736873
xlrec.snapshotConflictHorizon = snapshotConflictHorizon;
68746874
xlrec.nplans = nplans;
@@ -6895,6 +6895,144 @@ heap_freeze_execute_prepared(Relation rel, Buffer buffer,
68956895
END_CRIT_SECTION();
68966896
}
68976897

6898+
/*
6899+
* Comparator used to deduplicate XLOG_HEAP2_FREEZE_PAGE freeze plans
6900+
*/
6901+
static int
6902+
heap_log_freeze_cmp(const void *arg1, const void *arg2)
6903+
{
6904+
HeapTupleFreeze *frz1 = (HeapTupleFreeze *) arg1;
6905+
HeapTupleFreeze *frz2 = (HeapTupleFreeze *) arg2;
6906+
6907+
if (frz1->xmax < frz2->xmax)
6908+
return -1;
6909+
else if (frz1->xmax > frz2->xmax)
6910+
return 1;
6911+
6912+
if (frz1->t_infomask2 < frz2->t_infomask2)
6913+
return -1;
6914+
else if (frz1->t_infomask2 > frz2->t_infomask2)
6915+
return 1;
6916+
6917+
if (frz1->t_infomask < frz2->t_infomask)
6918+
return -1;
6919+
else if (frz1->t_infomask > frz2->t_infomask)
6920+
return 1;
6921+
6922+
if (frz1->frzflags < frz2->frzflags)
6923+
return -1;
6924+
else if (frz1->frzflags > frz2->frzflags)
6925+
return 1;
6926+
6927+
/*
6928+
* heap_log_freeze_eq would consider these tuple-wise plans to be equal.
6929+
* (So the tuples will share a single canonical freeze plan.)
6930+
*
6931+
* We tiebreak on page offset number to keep each freeze plan's page
6932+
* offset number array individually sorted. (Unnecessary, but be tidy.)
6933+
*/
6934+
if (frz1->offset < frz2->offset)
6935+
return -1;
6936+
else if (frz1->offset > frz2->offset)
6937+
return 1;
6938+
6939+
Assert(false);
6940+
return 0;
6941+
}
6942+
6943+
/*
6944+
* Compare fields that describe actions required to freeze tuple with caller's
6945+
* open plan. If everything matches then the frz tuple plan is equivalent to
6946+
* caller's plan.
6947+
*/
6948+
static inline bool
6949+
heap_log_freeze_eq(xl_heap_freeze_plan *plan, HeapTupleFreeze *frz)
6950+
{
6951+
if (plan->xmax == frz->xmax &&
6952+
plan->t_infomask2 == frz->t_infomask2 &&
6953+
plan->t_infomask == frz->t_infomask &&
6954+
plan->frzflags == frz->frzflags)
6955+
return true;
6956+
6957+
/* Caller must call heap_log_freeze_new_plan again for frz */
6958+
return false;
6959+
}
6960+
6961+
/*
6962+
* Start new plan initialized using tuple-level actions. At least one tuple
6963+
* will have steps required to freeze described by caller's plan during REDO.
6964+
*/
6965+
static inline void
6966+
heap_log_freeze_new_plan(xl_heap_freeze_plan *plan, HeapTupleFreeze *frz)
6967+
{
6968+
plan->xmax = frz->xmax;
6969+
plan->t_infomask2 = frz->t_infomask2;
6970+
plan->t_infomask = frz->t_infomask;
6971+
plan->frzflags = frz->frzflags;
6972+
plan->ntuples = 1; /* for now */
6973+
}
6974+
6975+
/*
6976+
* Deduplicate tuple-based freeze plans so that each distinct set of
6977+
* processing steps is only stored once in XLOG_HEAP2_FREEZE_PAGE records.
6978+
* Called during original execution of freezing (for logged relations).
6979+
*
6980+
* Return value is number of plans set in *plans_out for caller. Also writes
6981+
* an array of offset numbers into *offsets_out output argument for caller
6982+
* (actually there is one array per freeze plan, but that's not of immediate
6983+
* concern to our caller).
6984+
*/
6985+
static int
6986+
heap_log_freeze_plan(HeapTupleFreeze *tuples, int ntuples,
6987+
xl_heap_freeze_plan *plans_out,
6988+
OffsetNumber *offsets_out)
6989+
{
6990+
int nplans = 0;
6991+
6992+
/* Sort tuple-based freeze plans in the order required to deduplicate */
6993+
qsort(tuples, ntuples, sizeof(HeapTupleFreeze), heap_log_freeze_cmp);
6994+
6995+
for (int i = 0; i < ntuples; i++)
6996+
{
6997+
HeapTupleFreeze *frz = tuples + i;
6998+
6999+
if (i == 0)
7000+
{
7001+
/* New canonical freeze plan starting with first tup */
7002+
heap_log_freeze_new_plan(plans_out, frz);
7003+
nplans++;
7004+
}
7005+
else if (heap_log_freeze_eq(plans_out, frz))
7006+
{
7007+
/* tup matches open canonical plan -- include tup in it */
7008+
Assert(offsets_out[i - 1] < frz->offset);
7009+
plans_out->ntuples++;
7010+
}
7011+
else
7012+
{
7013+
/* Tup doesn't match current plan -- done with it now */
7014+
plans_out++;
7015+
7016+
/* New canonical freeze plan starting with this tup */
7017+
heap_log_freeze_new_plan(plans_out, frz);
7018+
nplans++;
7019+
}
7020+
7021+
/*
7022+
* Save page offset number in dedicated buffer in passing.
7023+
*
7024+
* REDO routine relies on the record's offset numbers array grouping
7025+
* offset numbers by freeze plan. The sort order within each grouping
7026+
* is ascending offset number order, just to keep things tidy.
7027+
*/
7028+
offsets_out[i] = frz->offset;
7029+
}
7030+
7031+
Assert(nplans > 0 && nplans <= ntuples);
7032+
7033+
return nplans;
7034+
}
7035+
68987036
/*
68997037
* heap_freeze_tuple
69007038
* Freeze tuple in place, without WAL logging.
@@ -9015,144 +9153,6 @@ heap_xlog_visible(XLogReaderState *record)
90159153
UnlockReleaseBuffer(vmbuffer);
90169154
}
90179155

9018-
/*
9019-
* Comparator used to deduplicate XLOG_HEAP2_FREEZE_PAGE freeze plans
9020-
*/
9021-
static int
9022-
heap_xlog_freeze_cmp(const void *arg1, const void *arg2)
9023-
{
9024-
HeapTupleFreeze *frz1 = (HeapTupleFreeze *) arg1;
9025-
HeapTupleFreeze *frz2 = (HeapTupleFreeze *) arg2;
9026-
9027-
if (frz1->xmax < frz2->xmax)
9028-
return -1;
9029-
else if (frz1->xmax > frz2->xmax)
9030-
return 1;
9031-
9032-
if (frz1->t_infomask2 < frz2->t_infomask2)
9033-
return -1;
9034-
else if (frz1->t_infomask2 > frz2->t_infomask2)
9035-
return 1;
9036-
9037-
if (frz1->t_infomask < frz2->t_infomask)
9038-
return -1;
9039-
else if (frz1->t_infomask > frz2->t_infomask)
9040-
return 1;
9041-
9042-
if (frz1->frzflags < frz2->frzflags)
9043-
return -1;
9044-
else if (frz1->frzflags > frz2->frzflags)
9045-
return 1;
9046-
9047-
/*
9048-
* heap_xlog_freeze_eq would consider these tuple-wise plans to be equal.
9049-
* (So the tuples will share a single canonical freeze plan.)
9050-
*
9051-
* We tiebreak on page offset number to keep each freeze plan's page
9052-
* offset number array individually sorted. (Unnecessary, but be tidy.)
9053-
*/
9054-
if (frz1->offset < frz2->offset)
9055-
return -1;
9056-
else if (frz1->offset > frz2->offset)
9057-
return 1;
9058-
9059-
Assert(false);
9060-
return 0;
9061-
}
9062-
9063-
/*
9064-
* Compare fields that describe actions required to freeze tuple with caller's
9065-
* open plan. If everything matches then the frz tuple plan is equivalent to
9066-
* caller's plan.
9067-
*/
9068-
static inline bool
9069-
heap_xlog_freeze_eq(xl_heap_freeze_plan *plan, HeapTupleFreeze *frz)
9070-
{
9071-
if (plan->xmax == frz->xmax &&
9072-
plan->t_infomask2 == frz->t_infomask2 &&
9073-
plan->t_infomask == frz->t_infomask &&
9074-
plan->frzflags == frz->frzflags)
9075-
return true;
9076-
9077-
/* Caller must call heap_xlog_new_freeze_plan again for frz */
9078-
return false;
9079-
}
9080-
9081-
/*
9082-
* Start new plan initialized using tuple-level actions. At least one tuple
9083-
* will have steps required to freeze described by caller's plan during REDO.
9084-
*/
9085-
static inline void
9086-
heap_xlog_new_freeze_plan(xl_heap_freeze_plan *plan, HeapTupleFreeze *frz)
9087-
{
9088-
plan->xmax = frz->xmax;
9089-
plan->t_infomask2 = frz->t_infomask2;
9090-
plan->t_infomask = frz->t_infomask;
9091-
plan->frzflags = frz->frzflags;
9092-
plan->ntuples = 1; /* for now */
9093-
}
9094-
9095-
/*
9096-
* Deduplicate tuple-based freeze plans so that each distinct set of
9097-
* processing steps is only stored once in XLOG_HEAP2_FREEZE_PAGE records.
9098-
* Called during original execution of freezing (for logged relations).
9099-
*
9100-
* Return value is number of plans set in *plans_out for caller. Also writes
9101-
* an array of offset numbers into *offsets_out output argument for caller
9102-
* (actually there is one array per freeze plan, but that's not of immediate
9103-
* concern to our caller).
9104-
*/
9105-
static int
9106-
heap_xlog_freeze_plan(HeapTupleFreeze *tuples, int ntuples,
9107-
xl_heap_freeze_plan *plans_out,
9108-
OffsetNumber *offsets_out)
9109-
{
9110-
int nplans = 0;
9111-
9112-
/* Sort tuple-based freeze plans in the order required to deduplicate */
9113-
qsort(tuples, ntuples, sizeof(HeapTupleFreeze), heap_xlog_freeze_cmp);
9114-
9115-
for (int i = 0; i < ntuples; i++)
9116-
{
9117-
HeapTupleFreeze *frz = tuples + i;
9118-
9119-
if (i == 0)
9120-
{
9121-
/* New canonical freeze plan starting with first tup */
9122-
heap_xlog_new_freeze_plan(plans_out, frz);
9123-
nplans++;
9124-
}
9125-
else if (heap_xlog_freeze_eq(plans_out, frz))
9126-
{
9127-
/* tup matches open canonical plan -- include tup in it */
9128-
Assert(offsets_out[i - 1] < frz->offset);
9129-
plans_out->ntuples++;
9130-
}
9131-
else
9132-
{
9133-
/* Tup doesn't match current plan -- done with it now */
9134-
plans_out++;
9135-
9136-
/* New canonical freeze plan starting with this tup */
9137-
heap_xlog_new_freeze_plan(plans_out, frz);
9138-
nplans++;
9139-
}
9140-
9141-
/*
9142-
* Save page offset number in dedicated buffer in passing.
9143-
*
9144-
* REDO routine relies on the record's offset numbers array grouping
9145-
* offset numbers by freeze plan. The sort order within each grouping
9146-
* is ascending offset number order, just to keep things tidy.
9147-
*/
9148-
offsets_out[i] = frz->offset;
9149-
}
9150-
9151-
Assert(nplans > 0 && nplans <= ntuples);
9152-
9153-
return nplans;
9154-
}
9155-
91569156
/*
91579157
* Replay XLOG_HEAP2_FREEZE_PAGE records
91589158
*/
@@ -9189,21 +9189,19 @@ heap_xlog_freeze_page(XLogReaderState *record)
91899189
sizeof(xl_heap_freeze_plan)));
91909190
for (int p = 0; p < xlrec->nplans; p++)
91919191
{
9192-
xl_heap_freeze_plan plan;
91939192
HeapTupleFreeze frz;
91949193

91959194
/*
91969195
* Convert freeze plan representation from WAL record into
91979196
* per-tuple format used by heap_execute_freeze_tuple
91989197
*/
9199-
memcpy(&plan, &plans[p], sizeof(xl_heap_freeze_plan));
9200-
frz.xmax = plan.xmax;
9201-
frz.t_infomask2 = plan.t_infomask2;
9202-
frz.t_infomask = plan.t_infomask;
9203-
frz.frzflags = plan.frzflags;
9198+
frz.xmax = plans[p].xmax;
9199+
frz.t_infomask2 = plans[p].t_infomask2;
9200+
frz.t_infomask = plans[p].t_infomask;
9201+
frz.frzflags = plans[p].frzflags;
92049202
frz.offset = InvalidOffsetNumber; /* unused, but be tidy */
92059203

9206-
for (int i = 0; i < plan.ntuples; i++)
9204+
for (int i = 0; i < plans[p].ntuples; i++)
92079205
{
92089206
OffsetNumber offset = offsets[curoff++];
92099207
ItemId lp;

0 commit comments

Comments
 (0)