From cfa429a46ea6a29561f970494f4de671a2dcdf2e Mon Sep 17 00:00:00 2001 From: Artur Zakirov Date: Tue, 21 May 2024 18:31:09 +0900 Subject: [PATCH] Fix swap of relfrozenxid, relfrozenxid and relallvisible (#377) This PR is follow up of #157. - Fixed the typo: https://github.com/reorg/pg_repack/pull/157#issuecomment-1519195513 - Removed `PG_VERSION_NUM >= 90300` check since we don't support such old versions anyway - Added check `relform1->relkind != RELKIND_INDEX` since `relfrozenxid` and `relminmxid` is non-zero only for tables --------- Co-authored-by: Alexey Bashtanov --- lib/repack.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/lib/repack.c b/lib/repack.c index ff60df8..26a937d 100644 --- a/lib/repack.c +++ b/lib/repack.c @@ -1225,20 +1225,28 @@ swap_heap_or_index_files(Oid r1, Oid r2) relform1->reltoastrelid = relform2->reltoastrelid; relform2->reltoastrelid = swaptemp; - /* set rel1's frozen Xid to larger one */ - if (TransactionIdIsNormal(relform1->relfrozenxid)) + /* + * Swap relfrozenxid and relminmxid, as they must be consistent with the data + */ + if (relform1->relkind != RELKIND_INDEX) { - if (TransactionIdFollows(relform1->relfrozenxid, - relform2->relfrozenxid)) - relform1->relfrozenxid = relform2->relfrozenxid; - else - relform2->relfrozenxid = relform1->relfrozenxid; + TransactionId frozenxid; + MultiXactId minmxid; + + frozenxid = relform1->relfrozenxid; + relform1->relfrozenxid = relform2->relfrozenxid; + relform2->relfrozenxid = frozenxid; + + minmxid = relform1->relminmxid; + relform1->relminmxid = relform2->relminmxid; + relform2->relminmxid = minmxid; } /* swap size statistics too, since new rel has freshly-updated stats */ { int32 swap_pages; float4 swap_tuples; + int32 swap_allvisible; swap_pages = relform1->relpages; relform1->relpages = relform2->relpages; @@ -1247,6 +1255,10 @@ swap_heap_or_index_files(Oid r1, Oid r2) swap_tuples = relform1->reltuples; relform1->reltuples = relform2->reltuples; relform2->reltuples = swap_tuples; + + swap_allvisible = relform1->relallvisible; + relform1->relallvisible = relform2->relallvisible; + relform2->relallvisible = swap_allvisible; } indstate = CatalogOpenIndexes(relRelation);