Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 5 additions & 24 deletions src/backend/access/aocs/aocsam_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -1462,8 +1462,6 @@ aoco_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
int natts;
Datum *values;
bool *isnull;
TransactionId FreezeXid;
MultiXactId MultiXactCutoff;
Tuplesortstate *tuplesort;
PGRUsage ru0;

Expand Down Expand Up @@ -1523,29 +1521,12 @@ aoco_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
Assert(RelationGetTargetBlock(NewHeap) == InvalidBlockNumber);

/*
* Compute sane values for FreezeXid and CutoffMulti with regular
* VACUUM machinery to avoidconfising existing CLUSTER code.
* AO/AOCO tables have no per-tuple xmin/xmax, so freeze limits don't
* apply. Return Invalid values so that relfrozenxid and relminmxid
* remain unchanged after CLUSTER.
*/
vacuum_set_xid_limits(OldHeap, 0, 0, 0, 0,
&OldestXmin, &FreezeXid, NULL, &MultiXactCutoff,
NULL);

/*
* FreezeXid will become the table's new relfrozenxid, and that mustn't go
* backwards, so take the max.
*/
if (TransactionIdPrecedes(FreezeXid, OldHeap->rd_rel->relfrozenxid))
FreezeXid = OldHeap->rd_rel->relfrozenxid;

/*
* MultiXactCutoff, similarly, shouldn't go backwards either.
*/
if (MultiXactIdPrecedes(MultiXactCutoff, OldHeap->rd_rel->relminmxid))
MultiXactCutoff = OldHeap->rd_rel->relminmxid;

/* return selected values to caller */
*xid_cutoff = FreezeXid;
*multi_cutoff = MultiXactCutoff;
*xid_cutoff = InvalidTransactionId;
*multi_cutoff = InvalidMultiXactId;

tuplesort = tuplesort_begin_cluster(oldTupDesc, OldIndex,
maintenance_work_mem, NULL, false);
Expand Down
29 changes: 5 additions & 24 deletions src/backend/access/appendonly/appendonlyam_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -1317,8 +1317,6 @@ appendonly_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
int natts;
Datum *values;
bool *isnull;
TransactionId FreezeXid;
MultiXactId MultiXactCutoff;
Tuplesortstate *tuplesort;
PGRUsage ru0;

Expand Down Expand Up @@ -1380,29 +1378,12 @@ appendonly_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
Assert(RelationGetTargetBlock(NewHeap) == InvalidBlockNumber);

/*
* Compute sane values for FreezeXid and CutoffMulti with regular
* VACUUM machinery to avoidconfising existing CLUSTER code.
* AO/AOCO tables have no per-tuple xmin/xmax, so freeze limits don't
* apply. Return Invalid values so that relfrozenxid and relminmxid
* remain unchanged after CLUSTER.
*/
vacuum_set_xid_limits(OldHeap, 0, 0, 0, 0,
&OldestXmin, &FreezeXid, NULL, &MultiXactCutoff,
NULL);

/*
* FreezeXid will become the table's new relfrozenxid, and that mustn't go
* backwards, so take the max.
*/
if (TransactionIdPrecedes(FreezeXid, OldHeap->rd_rel->relfrozenxid))
FreezeXid = OldHeap->rd_rel->relfrozenxid;

/*
* MultiXactCutoff, similarly, shouldn't go backwards either.
*/
if (MultiXactIdPrecedes(MultiXactCutoff, OldHeap->rd_rel->relminmxid))
MultiXactCutoff = OldHeap->rd_rel->relminmxid;

/* return selected values to caller */
*xid_cutoff = FreezeXid;
*multi_cutoff = MultiXactCutoff;
*xid_cutoff = InvalidTransactionId;
*multi_cutoff = InvalidMultiXactId;

tuplesort = tuplesort_begin_cluster(oldTupDesc, OldIndex,
maintenance_work_mem, NULL, false);
Expand Down
13 changes: 10 additions & 3 deletions src/backend/commands/cluster.c
Original file line number Diff line number Diff line change
Expand Up @@ -1486,17 +1486,24 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
Assert(!TransactionIdIsValid(frozenXid) ||
TransactionIdIsNormal(frozenXid));
relform1->relfrozenxid = frozenXid;
Assert(MultiXactIdIsValid(cutoffMulti));
Assert(!MultiXactIdIsValid(cutoffMulti) ||
MultiXactIdPrecedesOrEquals(FirstMultiXactId, cutoffMulti));
relform1->relminmxid = cutoffMulti;
}
/*
* Cloudberry: append-optimized tables do not have a valid relfrozenxid.
* Overwrite the entry for both relations.
* Cloudberry: append-optimized tables do not have a valid relfrozenxid
* or relminmxid. Overwrite the entry for both relations.
*/
if (relform1->relkind != RELKIND_INDEX && IsAccessMethodAO(relform1->relam))
{
relform1->relfrozenxid = InvalidTransactionId;
relform1->relminmxid = InvalidMultiXactId;
}
if (relform2->relkind != RELKIND_INDEX && IsAccessMethodAO(relform2->relam))
{
relform2->relfrozenxid = InvalidTransactionId;
relform2->relminmxid = InvalidMultiXactId;
}

/* swap size statistics too, since new rel has freshly-updated stats */
if (swap_stats)
Expand Down
199 changes: 0 additions & 199 deletions src/backend/commands/vacuum.c
Original file line number Diff line number Diff line change
Expand Up @@ -3914,202 +3914,3 @@ vac_cmp_itemptr(const void *left, const void *right)
return 0;
}


void
vacuum_set_xid_limits(Relation rel,
int freeze_min_age,
int freeze_table_age,
int multixact_freeze_min_age,
int multixact_freeze_table_age,
TransactionId *oldestXmin,
TransactionId *freezeLimit,
TransactionId *xidFullScanLimit,
MultiXactId *multiXactCutoff,
MultiXactId *mxactFullScanLimit)
{
int freezemin;
int mxid_freezemin;
int effective_multixact_freeze_max_age;
TransactionId limit;
TransactionId safeLimit;
MultiXactId oldestMxact;
MultiXactId mxactLimit;
MultiXactId safeMxactLimit;

/*
* We can always ignore processes running lazy vacuum. This is because we
* use these values only for deciding which tuples we must keep in the
* tables. Since lazy vacuum doesn't write its XID anywhere (usually no
* XID assigned), it's safe to ignore it. In theory it could be
* problematic to ignore lazy vacuums in a full vacuum, but keep in mind
* that only one vacuum process can be working on a particular table at
* any time, and that each vacuum is always an independent transaction.
*/
*oldestXmin = GetOldestNonRemovableTransactionId(rel);

if (OldSnapshotThresholdActive())
{
TransactionId limit_xmin;
TimestampTz limit_ts;

if (TransactionIdLimitedForOldSnapshots(*oldestXmin, rel,
&limit_xmin, &limit_ts))
{
/*
* TODO: We should only set the threshold if we are pruning on the
* basis of the increased limits. Not as crucial here as it is
* for opportunistic pruning (which often happens at a much higher
* frequency), but would still be a significant improvement.
*/
SetOldSnapshotThresholdTimestamp(limit_ts, limit_xmin);
*oldestXmin = limit_xmin;
}
}

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);
Assert(freezemin >= 0);

/*
* Compute the cutoff XID, being careful not to generate a "permanent" XID
*/
limit = *oldestXmin - freezemin;
if (!TransactionIdIsNormal(limit))
limit = FirstNormalTransactionId;

/*
* If oldestXmin is very far back (in practice, more than
* autovacuum_freeze_max_age / 2 XIDs old), complain and force a minimum
* freeze age of zero.
*/
safeLimit = ReadNextTransactionId() - autovacuum_freeze_max_age;
if (!TransactionIdIsNormal(safeLimit))
safeLimit = FirstNormalTransactionId;

if (TransactionIdPrecedes(limit, safeLimit))
{
ereport(WARNING,
(errmsg("oldest xmin is far in the past"),
errhint("Close open transactions soon to avoid wraparound problems.\n"
"You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
limit = *oldestXmin;
}

*freezeLimit = limit;

/*
* Compute the multixact age for which freezing is urgent. This is
* normally autovacuum_multixact_freeze_max_age, but may be less if we are
* short of multixact member space.
*/
effective_multixact_freeze_max_age = MultiXactMemberFreezeThreshold();

/*
* Determine the minimum multixact freeze age to use: as specified by
* caller, or vacuum_multixact_freeze_min_age, but in any case not more
* than half effective_multixact_freeze_max_age, so that autovacuums to
* prevent MultiXact wraparound won't occur too frequently.
*/
mxid_freezemin = multixact_freeze_min_age;
if (mxid_freezemin < 0)
mxid_freezemin = vacuum_multixact_freeze_min_age;
mxid_freezemin = Min(mxid_freezemin,
effective_multixact_freeze_max_age / 2);
Assert(mxid_freezemin >= 0);

/* compute the cutoff multi, being careful to generate a valid value */
oldestMxact = GetOldestMultiXactId();
mxactLimit = oldestMxact - mxid_freezemin;
if (mxactLimit < FirstMultiXactId)
mxactLimit = FirstMultiXactId;

safeMxactLimit =
ReadNextMultiXactId() - effective_multixact_freeze_max_age;
if (safeMxactLimit < FirstMultiXactId)
safeMxactLimit = FirstMultiXactId;

if (MultiXactIdPrecedes(mxactLimit, safeMxactLimit))
{
ereport(WARNING,
(errmsg("oldest multixact is far in the past"),
errhint("Close open transactions with multixacts soon to avoid wraparound problems.")));
/* Use the safe limit, unless an older mxact is still running */
if (MultiXactIdPrecedes(oldestMxact, safeMxactLimit))
mxactLimit = oldestMxact;
else
mxactLimit = safeMxactLimit;
}

*multiXactCutoff = mxactLimit;

if (xidFullScanLimit != NULL)
{
int freezetable;

Assert(mxactFullScanLimit != NULL);

/*
* Determine the table freeze age to use: as specified by the caller,
* or vacuum_freeze_table_age, but in any case not more than
* autovacuum_freeze_max_age * 0.95, so that if you have e.g nightly
* VACUUM schedule, the nightly VACUUM gets a chance to freeze tuples
* before anti-wraparound autovacuum is launched.
*/
freezetable = freeze_table_age;
if (freezetable < 0)
freezetable = vacuum_freeze_table_age;
freezetable = Min(freezetable, autovacuum_freeze_max_age * 0.95);
Assert(freezetable >= 0);

/*
* Compute XID limit causing a full-table vacuum, being careful not to
* generate a "permanent" XID.
*/
limit = ReadNextTransactionId() - freezetable;
if (!TransactionIdIsNormal(limit))
limit = FirstNormalTransactionId;

*xidFullScanLimit = limit;

/*
* Similar to the above, determine the table freeze age to use for
* multixacts: as specified by the caller, or
* vacuum_multixact_freeze_table_age, but in any case not more than
* autovacuum_multixact_freeze_table_age * 0.95, so that if you have
* e.g. nightly VACUUM schedule, the nightly VACUUM gets a chance to
* freeze multixacts before anti-wraparound autovacuum is launched.
*/
freezetable = multixact_freeze_table_age;
if (freezetable < 0)
freezetable = vacuum_multixact_freeze_table_age;
freezetable = Min(freezetable,
effective_multixact_freeze_max_age * 0.95);
Assert(freezetable >= 0);

/*
* Compute MultiXact limit causing a full-table vacuum, being careful
* to generate a valid MultiXact value.
*/
mxactLimit = ReadNextMultiXactId() - freezetable;
if (mxactLimit < FirstMultiXactId)
mxactLimit = FirstMultiXactId;

*mxactFullScanLimit = mxactLimit;
}
else
{
Assert(mxactFullScanLimit == NULL);
}
}


24 changes: 7 additions & 17 deletions src/backend/commands/vacuum_ao.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,6 @@ ao_vacuum_rel_post_cleanup(Relation onerel, VacuumParams *params, BufferAccessSt
BlockNumber total_file_segs;
int elevel;
int options = params->options;
TransactionId OldestXmin;
TransactionId FreezeLimit;
MultiXactId MultiXactCutoff;
TransactionId xidFullScanLimit;
MultiXactId mxactFullScanLimit;

if (options & VACOPT_VERBOSE)
elevel = INFO;
Expand Down Expand Up @@ -288,25 +283,20 @@ ao_vacuum_rel_post_cleanup(Relation onerel, VacuumParams *params, BufferAccessSt
&relhasindex,
&total_file_segs);

/* MERGE16_FIXME: How to set limits for ao */
vacuum_set_xid_limits(onerel,
params->freeze_min_age,
params->freeze_table_age,
params->multixact_freeze_min_age,
params->multixact_freeze_table_age,
&OldestXmin, &FreezeLimit, &xidFullScanLimit,
&MultiXactCutoff, &mxactFullScanLimit);

/* Causion: AO/AOCO use relallvisible to represent total segment file count */
/*
* AO/AOCO tables have no per-tuple xmin/xmax, so freeze limits don't
* apply. Pass InvalidTransactionId/InvalidMultiXactId to keep
* relfrozenxid and relminmxid unchanged.
*/
vac_update_relstats(onerel,
relpages,
reltuples,
total_file_segs, /* AO/AOCO does not currently have an equivalent to
Heap's 'all visible pages', use this field to represent
AO/AOCO's total segment file count */
relhasindex,
FreezeLimit,
MultiXactCutoff,
InvalidTransactionId,
InvalidMultiXactId,
NULL,
NULL,
false,
Expand Down
1 change: 0 additions & 1 deletion src/backend/executor/nodePartitionSelector.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ ExecInitPartitionSelector(PartitionSelector *node, EState *estate, int eflags)
outerPlanState(psstate) = ExecInitNode(outerPlan(node), estate, eflags);

/* Create the working data structure for pruning. */
/* MERGE16_FIXME: This use of ExecInitPartitionPruning may be incorrect */
psstate->prune_state = CreatePartitionPruneState(&psstate->ps, node->part_prune_info);

return psstate;
Expand Down
Loading
Loading