mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Allow pg_class xid & multixid horizons to not be set.
This allows table AMs that don't need these horizons. This was already documented in the tableam relation_set_new_filenode callback, but an assert prevented if from actually working (the test AM code contained the change itself). Defang the asserts in the general code, and move the stronger ones into heap AM. Relatedly, after CLUSTER/VACUUM, we'd always assign a relfrozenxid / relminmxid. Change the table_relation_copy_for_cluster() interface to allow the AM to overwrite the horizons that get set on the pg_class entry. This'd also in the future allow AMs like heap to compute a relfrozenxid during rewrite that's the table's actual minimum rather than a pre-determined value. Arguably it'd have been better to move the whole computation / setting of those values into the callback, but it seems likely that for other reasons it'd be better to be able to use one value to vacuum/cluster multiple tables (e.g. a toast's horizon shouldn't be different than the table's). Reported-By: Heikki Linnakangas Author: Andres Freund Discussion: https://postgr.es/m/9a7fb9cc-2419-5db7-8840-ddc10c93f122@iki.fi
This commit is contained in:
@ -870,19 +870,17 @@ copy_table_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose,
|
||||
* 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))
|
||||
if (TransactionIdIsValid(OldHeap->rd_rel->relfrozenxid) &&
|
||||
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))
|
||||
if (MultiXactIdIsValid(OldHeap->rd_rel->relminmxid) &&
|
||||
MultiXactIdPrecedes(MultiXactCutoff, OldHeap->rd_rel->relminmxid))
|
||||
MultiXactCutoff = OldHeap->rd_rel->relminmxid;
|
||||
|
||||
/* return selected values to caller */
|
||||
*pFreezeXid = FreezeXid;
|
||||
*pCutoffMulti = MultiXactCutoff;
|
||||
|
||||
/*
|
||||
* Decide whether to use an indexscan or seqscan-and-optional-sort to scan
|
||||
* the OldHeap. We know how to use a sort to duplicate the ordering of a
|
||||
@ -915,13 +913,19 @@ copy_table_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose,
|
||||
|
||||
/*
|
||||
* Hand of the actual copying to AM specific function, the generic code
|
||||
* cannot know how to deal with visibility across AMs.
|
||||
* cannot know how to deal with visibility across AMs. Note that this
|
||||
* routine is allowed to set FreezeXid / MultiXactCutoff to different
|
||||
* values (e.g. because the AM doesn't use freezing).
|
||||
*/
|
||||
table_relation_copy_for_cluster(OldHeap, NewHeap, OldIndex, use_sort,
|
||||
OldestXmin, FreezeXid, MultiXactCutoff,
|
||||
OldestXmin, &FreezeXid, &MultiXactCutoff,
|
||||
&num_tuples, &tups_vacuumed,
|
||||
&tups_recently_dead);
|
||||
|
||||
/* return selected values to caller, get set as relfrozenxid/minmxid */
|
||||
*pFreezeXid = FreezeXid;
|
||||
*pCutoffMulti = MultiXactCutoff;
|
||||
|
||||
/* Reset rd_toastoid just to be tidy --- it shouldn't be looked at again */
|
||||
NewHeap->rd_toastoid = InvalidOid;
|
||||
|
||||
@ -1118,9 +1122,9 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
|
||||
/* set rel1's frozen Xid and minimum MultiXid */
|
||||
if (relform1->relkind != RELKIND_INDEX)
|
||||
{
|
||||
Assert(TransactionIdIsNormal(frozenXid));
|
||||
Assert(!TransactionIdIsValid(frozenXid) ||
|
||||
TransactionIdIsNormal(frozenXid));
|
||||
relform1->relfrozenxid = frozenXid;
|
||||
Assert(MultiXactIdIsValid(cutoffMulti));
|
||||
relform1->relminmxid = cutoffMulti;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user