aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/cluster.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2014-03-04 11:08:18 -0500
committerRobert Haas <rhaas@postgresql.org>2014-03-04 11:08:18 -0500
commitaf2543e884db06c0beb75010218cd88680203b86 (patch)
tree665b63ed893ce6378e63b5f1504ec89f45a9e17c /src/backend/commands/cluster.c
parent7e8db2dc420099df3fa73987cf2d2d6d1a609d86 (diff)
downloadpostgresql-af2543e884db06c0beb75010218cd88680203b86.tar.gz
postgresql-af2543e884db06c0beb75010218cd88680203b86.zip
Allow VACUUM FULL/CLUSTER to bump freeze horizons even for pg_class.
pg_class is a special case for CLUSTER and VACUUM FULL, so although commit 3cff1879f8d03cb729368722ca823a4bf74c0cac caused these operations to advance relfrozenxid and relminmxid for all other tables, it did not provide the same benefit for pg_class. This plugs that gap. Andres Freund
Diffstat (limited to 'src/backend/commands/cluster.c')
-rw-r--r--src/backend/commands/cluster.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index b6b40e724e7..620f071aafb 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -1269,7 +1269,8 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
* changes because we'd be updating the old data that we're about to throw
* away. Because the real work being done here for a mapped relation is
* just to change the relation map settings, it's all right to not update
- * the pg_class rows in this case.
+ * the pg_class rows in this case. The most important changes will instead
+ * performed later, in finish_heap_swap() itself.
*/
if (!target_is_pg_class)
{
@@ -1504,6 +1505,40 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
reindex_flags |= REINDEX_REL_CHECK_CONSTRAINTS;
reindex_relation(OIDOldHeap, reindex_flags);
+ /*
+ * If the relation being rebuild is pg_class, swap_relation_files()
+ * couldn't update pg_class's own pg_class entry (check comments in
+ * swap_relation_files()), thus relfrozenxid was not updated. That's
+ * annoying because a potential reason for doing a VACUUM FULL is a
+ * imminent or actual anti-wraparound shutdown. So, now that we can
+ * access the new relation using it's indices, update
+ * relfrozenxid. pg_class doesn't have a toast relation, so we don't need
+ * to update the corresponding toast relation. Not that there's little
+ * point moving all relfrozenxid updates here since swap_relation_files()
+ * needs to write to pg_class for non-mapped relations anyway.
+ */
+ if (OIDOldHeap == RelationRelationId)
+ {
+ Relation relRelation;
+ HeapTuple reltup;
+ Form_pg_class relform;
+
+ relRelation = heap_open(RelationRelationId, RowExclusiveLock);
+
+ reltup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(OIDOldHeap));
+ if (!HeapTupleIsValid(reltup))
+ elog(ERROR, "cache lookup failed for relation %u", OIDOldHeap);
+ relform = (Form_pg_class) GETSTRUCT(reltup);
+
+ relform->relfrozenxid = frozenXid;
+ relform->relminmxid = cutoffMulti;
+
+ simple_heap_update(relRelation, &reltup->t_self, reltup);
+ CatalogUpdateIndexes(relRelation, reltup);
+
+ heap_close(relRelation, RowExclusiveLock);
+ }
+
/* Destroy new heap with old filenode */
object.classId = RelationRelationId;
object.objectId = OIDNewHeap;