diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c index a3e51922d85..c2eadf58f87 100644 --- a/src/backend/access/heap/pruneheap.c +++ b/src/backend/access/heap/pruneheap.c @@ -20,6 +20,7 @@ #include "access/htup_details.h" #include "access/xlog.h" #include "catalog/catalog.h" +#include "commands/cluster.h" #include "miscadmin.h" #include "pgstat.h" #include "storage/bufmgr.h" @@ -84,6 +85,9 @@ heap_page_prune_opt(Relation relation, Buffer buffer) if (RecoveryInProgress()) return; + if (is_inside_rebuild_relation()) + return; + /* * Use the appropriate xmin horizon for this relation. If it's a proper * catalog relation or a user defined, additional, catalog relation, we diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index 3e2a807640f..0493d748dc8 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -561,6 +561,8 @@ mark_index_clustered(Relation rel, Oid indexOid, bool is_internal) table_close(pg_index, RowExclusiveLock); } +bool inside_rebuild_relation = false; + /* * rebuild_relation: rebuild an existing relation in index or physical order * @@ -581,36 +583,52 @@ rebuild_relation(Relation OldHeap, Oid indexOid, bool verbose) TransactionId frozenXid; MultiXactId cutoffMulti; - /* Mark the correct index as clustered */ - if (OidIsValid(indexOid)) - mark_index_clustered(OldHeap, indexOid, true); + PG_TRY(); + { + inside_rebuild_relation = true; - /* Remember info about rel before closing OldHeap */ - relpersistence = OldHeap->rd_rel->relpersistence; - is_system_catalog = IsSystemRelation(OldHeap); + /* Mark the correct index as clustered */ + if (OidIsValid(indexOid)) + mark_index_clustered(OldHeap, indexOid, true); - /* Close relcache entry, but keep lock until transaction commit */ - table_close(OldHeap, NoLock); + /* Remember info about rel before closing OldHeap */ + relpersistence = OldHeap->rd_rel->relpersistence; + is_system_catalog = IsSystemRelation(OldHeap); - /* Create the transient table that will receive the re-ordered data */ - OIDNewHeap = make_new_heap(tableOid, tableSpace, - relpersistence, - AccessExclusiveLock); + /* Close relcache entry, but keep lock until transaction commit */ + table_close(OldHeap, NoLock); - /* Copy the heap data into the new table in the desired order */ - copy_heap_data(OIDNewHeap, tableOid, indexOid, verbose, - &swap_toast_by_content, &frozenXid, &cutoffMulti); + /* Create the transient table that will receive the re-ordered data */ + OIDNewHeap = make_new_heap(tableOid, tableSpace, + relpersistence, + AccessExclusiveLock); - /* - * 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, true, - frozenXid, cutoffMulti, - relpersistence); + /* Copy the heap data into the new table in the desired order */ + copy_heap_data(OIDNewHeap, tableOid, indexOid, verbose, + &swap_toast_by_content, &frozenXid, &cutoffMulti); + + /* + * 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, true, + frozenXid, cutoffMulti, + relpersistence); + } + PG_CATCH(); + { + inside_rebuild_relation = false; + PG_RE_THROW(); + } + PG_END_TRY(); } +bool +is_inside_rebuild_relation() +{ + return inside_rebuild_relation; +} /* * Create the transient table that will be filled with new data during diff --git a/src/include/commands/cluster.h b/src/include/commands/cluster.h index d30e9c66dae..ab2ee8046d8 100644 --- a/src/include/commands/cluster.h +++ b/src/include/commands/cluster.h @@ -34,5 +34,6 @@ extern void finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, TransactionId frozenXid, MultiXactId minMulti, char newrelpersistence); +extern bool is_inside_rebuild_relation(void); #endif /* CLUSTER_H */