aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/cluster.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/cluster.c')
-rw-r--r--src/backend/commands/cluster.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index 238781b6a70..c0cb2f66545 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -17,6 +17,7 @@
*/
#include "postgres.h"
+#include "access/multixact.h"
#include "access/relscan.h"
#include "access/rewriteheap.h"
#include "access/transam.h"
@@ -65,7 +66,8 @@ static void rebuild_relation(Relation OldHeap, Oid indexOid,
int freeze_min_age, int freeze_table_age, bool verbose);
static void copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex,
int freeze_min_age, int freeze_table_age, bool verbose,
- bool *pSwapToastByContent, TransactionId *pFreezeXid);
+ bool *pSwapToastByContent, TransactionId *pFreezeXid,
+ MultiXactId *pFreezeMulti);
static List *get_tables_to_cluster(MemoryContext cluster_context);
static void reform_and_rewrite_tuple(HeapTuple tuple,
TupleDesc oldTupDesc, TupleDesc newTupDesc,
@@ -549,6 +551,7 @@ rebuild_relation(Relation OldHeap, Oid indexOid,
bool is_system_catalog;
bool swap_toast_by_content;
TransactionId frozenXid;
+ MultiXactId frozenMulti;
/* Mark the correct index as clustered */
if (OidIsValid(indexOid))
@@ -566,14 +569,14 @@ rebuild_relation(Relation OldHeap, Oid indexOid,
/* Copy the heap data into the new table in the desired order */
copy_heap_data(OIDNewHeap, tableOid, indexOid,
freeze_min_age, freeze_table_age, verbose,
- &swap_toast_by_content, &frozenXid);
+ &swap_toast_by_content, &frozenXid, &frozenMulti);
/*
* Swap the physical files of the target and transient tables, then
* rebuild the target's indexes and throw away the transient table.
*/
finish_heap_swap(tableOid, OIDNewHeap, is_system_catalog,
- swap_toast_by_content, false, frozenXid);
+ swap_toast_by_content, false, frozenXid, frozenMulti);
}
@@ -706,7 +709,8 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace)
static void
copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex,
int freeze_min_age, int freeze_table_age, bool verbose,
- bool *pSwapToastByContent, TransactionId *pFreezeXid)
+ bool *pSwapToastByContent, TransactionId *pFreezeXid,
+ MultiXactId *pFreezeMulti)
{
Relation NewHeap,
OldHeap,
@@ -722,6 +726,7 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex,
bool is_system_catalog;
TransactionId OldestXmin;
TransactionId FreezeXid;
+ MultiXactId MultiXactFrzLimit;
RewriteState rwstate;
bool use_sort;
Tuplesortstate *tuplesort;
@@ -822,7 +827,7 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex,
*/
vacuum_set_xid_limits(freeze_min_age, freeze_table_age,
OldHeap->rd_rel->relisshared,
- &OldestXmin, &FreezeXid, NULL);
+ &OldestXmin, &FreezeXid, NULL, &MultiXactFrzLimit);
/*
* FreezeXid will become the table's new relfrozenxid, and that mustn't go
@@ -831,14 +836,16 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex,
if (TransactionIdPrecedes(FreezeXid, OldHeap->rd_rel->relfrozenxid))
FreezeXid = OldHeap->rd_rel->relfrozenxid;
- /* return selected value to caller */
+ /* return selected values to caller */
*pFreezeXid = FreezeXid;
+ *pFreezeMulti = MultiXactFrzLimit;
/* Remember if it's a system catalog */
is_system_catalog = IsSystemRelation(OldHeap);
/* Initialize the rewrite operation */
- rwstate = begin_heap_rewrite(NewHeap, OldestXmin, FreezeXid, use_wal);
+ rwstate = begin_heap_rewrite(NewHeap, OldestXmin, FreezeXid,
+ MultiXactFrzLimit, use_wal);
/*
* Decide whether to use an indexscan or seqscan-and-optional-sort to scan
@@ -966,9 +973,8 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex,
/*
* Similar situation to INSERT_IN_PROGRESS case.
*/
- Assert(!(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI));
if (!is_system_catalog &&
- !TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple->t_data)))
+ !TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetUpdateXid(tuple->t_data)))
elog(WARNING, "concurrent delete in progress within table \"%s\"",
RelationGetRelationName(OldHeap));
/* treat as recently dead */
@@ -1097,6 +1103,7 @@ static void
swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
bool swap_toast_by_content,
TransactionId frozenXid,
+ MultiXactId frozenMulti,
Oid *mapped_tables)
{
Relation relRelation;
@@ -1204,11 +1211,13 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
* and then fail to commit the pg_class update.
*/
- /* set rel1's frozen Xid */
+ /* set rel1's frozen Xid and minimum MultiXid */
if (relform1->relkind != RELKIND_INDEX)
{
Assert(TransactionIdIsNormal(frozenXid));
relform1->relfrozenxid = frozenXid;
+ Assert(MultiXactIdIsValid(frozenMulti));
+ relform1->relminmxid = frozenMulti;
}
/* swap size statistics too, since new rel has freshly-updated stats */
@@ -1272,6 +1281,7 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
target_is_pg_class,
swap_toast_by_content,
frozenXid,
+ frozenMulti,
mapped_tables);
}
else
@@ -1361,6 +1371,7 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
target_is_pg_class,
swap_toast_by_content,
InvalidTransactionId,
+ InvalidMultiXactId,
mapped_tables);
/* Clean up. */
@@ -1398,7 +1409,8 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
bool is_system_catalog,
bool swap_toast_by_content,
bool check_constraints,
- TransactionId frozenXid)
+ TransactionId frozenXid,
+ MultiXactId frozenMulti)
{
ObjectAddress object;
Oid mapped_tables[4];
@@ -1414,7 +1426,8 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
*/
swap_relation_files(OIDOldHeap, OIDNewHeap,
(OIDOldHeap == RelationRelationId),
- swap_toast_by_content, frozenXid, mapped_tables);
+ swap_toast_by_content, frozenXid, frozenMulti,
+ mapped_tables);
/*
* If it's a system catalog, queue an sinval message to flush all