On Fri, Aug 22, 2014 at 5:23 PM, Alvaro Herrera <alvhe...@2ndquadrant.com>
wrote:
>
> Fabrízio de Royes Mello wrote:
> > On Fri, Aug 22, 2014 at 4:45 PM, Alvaro Herrera <
alvhe...@2ndquadrant.com>
> > wrote:
>
> > > I pointed out, in the email just before pushing the patch, that
perhaps
> > > we should pass down the new relpersistence flag into finish_heap_swap,
> > > and from there we could pass it down to reindex_index() which is where
> > > it would be needed.  I'm not sure it's worth the trouble, but I think
we
> > > can still ask Fabrizio to rework that part.
>
> > I can rework this part if it's a real concern.
>
> I guess we can make a better assessment by seeing what it would take.
> I'm afraid it will turn out to be really ugly.
>
> Now, there's some desire to have unlogged indexes on logged tables; I
> guess if we have that, then eventually there will also be a desire to
> swap individual indexes from logged to unlogged.  Perhaps whatever fix
> we come up with here would pave the road for that future feature.
>

Álvaro,

I did a refactoring to pass down the relpersistence to "finish_heap_swap"
and then change the catalog inside the "reindex_index" instead of in the
rewrite table phase.

That way we can get rid the function ATChangeIndexesPersistence in the
src/backend/commands/tablecmds.c.

Thoughts?

--
Fabrízio de Royes Mello
Consultoria/Coaching PostgreSQL
>> Timbira: http://www.timbira.com.br
>> Blog: http://fabriziomello.github.io
>> Linkedin: http://br.linkedin.com/in/fabriziomello
>> Twitter: http://twitter.com/fabriziomello
>> Github: http://github.com/fabriziomello
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index ee10594..173f412 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1973,7 +1973,7 @@ index_build(Relation heapRelation,
 	 * created it, or truncated twice in a subsequent transaction, the
 	 * relfilenode won't change, and nothing needs to be done here.
 	 */
-	if (heapRelation->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED &&
+	if (indexRelation->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED &&
 		!smgrexists(indexRelation->rd_smgr, INIT_FORKNUM))
 	{
 		RegProcedure ambuildempty = indexRelation->rd_am->ambuildempty;
@@ -3099,7 +3099,7 @@ IndexGetRelation(Oid indexId, bool missing_ok)
  * reindex_index - This routine is used to recreate a single index
  */
 void
-reindex_index(Oid indexId, bool skip_constraint_checks)
+reindex_index(Oid indexId, bool skip_constraint_checks, char relpersistence)
 {
 	Relation	iRel,
 				heapRelation;
@@ -3160,6 +3160,12 @@ reindex_index(Oid indexId, bool skip_constraint_checks)
 			indexInfo->ii_ExclusionStrats = NULL;
 		}
 
+		/*
+		 * Check if need to set the new relpersistence
+		 */
+		if (iRel->rd_rel->relpersistence != relpersistence)
+			iRel->rd_rel->relpersistence = relpersistence;
+
 		/* We'll build a new physical relation for the index */
 		RelationSetNewRelfilenode(iRel, InvalidTransactionId,
 								  InvalidMultiXactId);
@@ -3358,11 +3364,19 @@ reindex_relation(Oid relid, int flags)
 		foreach(indexId, indexIds)
 		{
 			Oid			indexOid = lfirst_oid(indexId);
+			char		relpersistence = rel->rd_rel->relpersistence;
 
 			if (is_pg_class)
 				RelationSetIndexList(rel, doneIndexes, InvalidOid);
 
-			reindex_index(indexOid, !(flags & REINDEX_REL_CHECK_CONSTRAINTS));
+			/* Check for flags to force UNLOGGED or PERMANENT persistence */
+			if (flags & REINDEX_REL_FORCE_UNLOGGED)
+				relpersistence = RELPERSISTENCE_UNLOGGED;
+			else if (flags & REINDEX_REL_FORCE_PERMANENT)
+				relpersistence = RELPERSISTENCE_PERMANENT;
+
+			reindex_index(indexOid, !(flags & REINDEX_REL_CHECK_CONSTRAINTS),
+						  relpersistence);
 
 			CommandCounterIncrement();
 
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index ff80b09..f285026 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -588,7 +588,8 @@ rebuild_relation(Relation OldHeap, Oid indexOid, bool verbose)
 	 */
 	finish_heap_swap(tableOid, OIDNewHeap, is_system_catalog,
 					 swap_toast_by_content, false, true,
-					 frozenXid, cutoffMulti);
+					 frozenXid, cutoffMulti,
+					 OldHeap->rd_rel->relpersistence);
 }
 
 
@@ -1474,7 +1475,8 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
 				 bool check_constraints,
 				 bool is_internal,
 				 TransactionId frozenXid,
-				 MultiXactId cutoffMulti)
+				 MultiXactId cutoffMulti,
+				 char newrelpersistence)
 {
 	ObjectAddress object;
 	Oid			mapped_tables[4];
@@ -1518,6 +1520,12 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
 	reindex_flags = REINDEX_REL_SUPPRESS_INDEX_USE;
 	if (check_constraints)
 		reindex_flags |= REINDEX_REL_CHECK_CONSTRAINTS;
+
+	if (newrelpersistence == RELPERSISTENCE_UNLOGGED)
+		reindex_flags |= REINDEX_REL_FORCE_UNLOGGED;
+	else if (newrelpersistence == RELPERSISTENCE_PERMANENT)
+		reindex_flags |= REINDEX_REL_FORCE_PERMANENT;
+
 	reindex_relation(OIDOldHeap, reindex_flags);
 
 	/*
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index fdfa6ca..6156fcc 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -1678,7 +1678,7 @@ ReindexIndex(RangeVar *indexRelation)
 									  RangeVarCallbackForReindexIndex,
 									  (void *) &heapOid);
 
-	reindex_index(indOid, false);
+	reindex_index(indOid, false, indexRelation->relpersistence);
 
 	return indOid;
 }
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index d8d3c08..b2c0fc9 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -65,7 +65,7 @@ static char *make_temptable_name_n(char *tempname, int n);
 static void mv_GenerateOper(StringInfo buf, Oid opoid);
 
 static void refresh_by_match_merge(Oid matviewOid, Oid tempOid);
-static void refresh_by_heap_swap(Oid matviewOid, Oid OIDNewHeap);
+static void refresh_by_heap_swap(Oid matviewOid, Oid OIDNewHeap, char relpersistence);
 
 static void OpenMatViewIncrementalMaintenance(void);
 static void CloseMatViewIncrementalMaintenance(void);
@@ -280,7 +280,7 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
 		Assert(matview_maintenance_depth == old_depth);
 	}
 	else
-		refresh_by_heap_swap(matviewOid, OIDNewHeap);
+		refresh_by_heap_swap(matviewOid, OIDNewHeap, relpersistence);
 
 	return matviewOid;
 }
@@ -761,10 +761,10 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid)
  * swapping is handled by the called function, so it is not needed here.
  */
 static void
-refresh_by_heap_swap(Oid matviewOid, Oid OIDNewHeap)
+refresh_by_heap_swap(Oid matviewOid, Oid OIDNewHeap, char relpersistence)
 {
 	finish_heap_swap(matviewOid, OIDNewHeap, false, false, true, true,
-					 RecentXmin, ReadNextMultiXactId());
+					 RecentXmin, ReadNextMultiXactId(), relpersistence);
 }
 
 
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 3720a0f..0802d1e 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -389,7 +389,6 @@ static void ATExecClusterOn(Relation rel, const char *indexName,
 				LOCKMODE lockmode);
 static void ATExecDropCluster(Relation rel, LOCKMODE lockmode);
 static bool ATPrepChangePersistence(Relation rel, bool toLogged);
-static void ATChangeIndexesPersistence(Oid relid, char relpersistence);
 static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
 					char *tablespacename, LOCKMODE lockmode);
 static void ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode);
@@ -3710,16 +3709,6 @@ ATRewriteTables(List **wqueue, LOCKMODE lockmode)
 			ATRewriteTable(tab, OIDNewHeap, lockmode);
 
 			/*
-			 * Change the persistence marking of indexes, if necessary.  This
-			 * is so that the new copies are built with the right persistence
-			 * in the reindex step below.  Note we cannot do this earlier,
-			 * because the rewrite step might read the indexes, and that would
-			 * cause buffers for them to have the wrong setting.
-			 */
-			if (tab->chgPersistence)
-				ATChangeIndexesPersistence(tab->relid, tab->newrelpersistence);
-
-			/*
 			 * Swap the physical files of the old and new heaps, then rebuild
 			 * indexes and discard the old heap.  We can use RecentXmin for
 			 * the table's new relfrozenxid because we rewrote all the tuples
@@ -3731,7 +3720,8 @@ ATRewriteTables(List **wqueue, LOCKMODE lockmode)
 							 false, false, true,
 							 !OidIsValid(tab->newTableSpace),
 							 RecentXmin,
-							 ReadNextMultiXactId());
+							 ReadNextMultiXactId(),
+							 persistence);
 		}
 		else
 		{
@@ -10799,48 +10789,6 @@ ATPrepChangePersistence(Relation rel, bool toLogged)
 }
 
 /*
- * Update the pg_class entry of each index for the given relation to the
- * given persistence.
- */
-static void
-ATChangeIndexesPersistence(Oid relid, char relpersistence)
-{
-	Relation	rel;
-	Relation	pg_class;
-	List	   *indexes;
-	ListCell   *cell;
-
-	pg_class = heap_open(RelationRelationId, RowExclusiveLock);
-
-	/* We already have a lock on the table */
-	rel = relation_open(relid, NoLock);
-	indexes = RelationGetIndexList(rel);
-	foreach(cell, indexes)
-	{
-		Oid			indexid = lfirst_oid(cell);
-		HeapTuple	tuple;
-		Form_pg_class pg_class_form;
-
-		tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(indexid));
-		if (!HeapTupleIsValid(tuple))
-			elog(ERROR, "cache lookup failed for relation %u",
-				 indexid);
-
-		pg_class_form = (Form_pg_class) GETSTRUCT(tuple);
-		pg_class_form->relpersistence = relpersistence;
-		simple_heap_update(pg_class, &tuple->t_self, tuple);
-
-		/* keep catalog indexes current */
-		CatalogUpdateIndexes(pg_class, tuple);
-
-		heap_freetuple(tuple);
-	}
-
-	heap_close(pg_class, RowExclusiveLock);
-	heap_close(rel, NoLock);
-}
-
-/*
  * Execute ALTER TABLE SET SCHEMA
  */
 Oid
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index b6f03df..8b1d30a 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -2983,6 +2983,7 @@ RelationSetNewRelfilenode(Relation relation, TransactionId freezeXid,
 	}
 	classform->relfrozenxid = freezeXid;
 	classform->relminmxid = minmulti;
+	classform->relpersistence = relation->rd_rel->relpersistence;
 
 	simple_heap_update(pg_class, &tuple->t_self, tuple);
 	CatalogUpdateIndexes(pg_class, tuple);
diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h
index 006b180..74111b6 100644
--- a/src/include/catalog/index.h
+++ b/src/include/catalog/index.h
@@ -102,12 +102,15 @@ extern void validate_index(Oid heapId, Oid indexId, Snapshot snapshot);
 
 extern void index_set_state_flags(Oid indexId, IndexStateFlagsAction action);
 
-extern void reindex_index(Oid indexId, bool skip_constraint_checks);
+extern void reindex_index(Oid indexId, bool skip_constraint_checks,
+						  char relpersistence);
 
 /* Flag bits for reindex_relation(): */
 #define REINDEX_REL_PROCESS_TOAST		0x01
 #define REINDEX_REL_SUPPRESS_INDEX_USE	0x02
 #define REINDEX_REL_CHECK_CONSTRAINTS	0x04
+#define REINDEX_REL_FORCE_UNLOGGED		0x08
+#define REINDEX_REL_FORCE_PERMANENT		0x10
 
 extern bool reindex_relation(Oid relid, int flags);
 
diff --git a/src/include/commands/cluster.h b/src/include/commands/cluster.h
index f7730a9..0b7e877 100644
--- a/src/include/commands/cluster.h
+++ b/src/include/commands/cluster.h
@@ -33,6 +33,7 @@ extern void finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
 				 bool check_constraints,
 				 bool is_internal,
 				 TransactionId frozenXid,
-				 MultiXactId minMulti);
+				 MultiXactId minMulti,
+				 char newrelpersistence);
 
 #endif   /* CLUSTER_H */
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to