aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/cache/relcache.c
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2024-10-31 10:02:58 +0200
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2024-10-31 10:02:58 +0200
commit8e2e2662214a0a6d0fb23a070ea78d691d8ced43 (patch)
tree9873173c41f983dadc00e7f7e628fef233b58cce /src/backend/utils/cache/relcache.c
parent3974bc319639ad7da5934ba8d04d474a6f7fdee6 (diff)
downloadpostgresql-8e2e2662214a0a6d0fb23a070ea78d691d8ced43.tar.gz
postgresql-8e2e2662214a0a6d0fb23a070ea78d691d8ced43.zip
Simplify call to rebuild relcache entry for indexes
RelationClearRelation(rebuild == true) calls RelationReloadIndexInfo() for indexes. We can rely on that in RelationIdGetRelation(), instead of calling RelationReloadIndexInfo() directly. That simplifies the code a little. In the passing, add a comment in RelationBuildLocalRelation() explaining why it doesn't call RelationInitIndexAccessInfo(). It's because at index creation, it's called before the pg_index row has been created. That's also the reason that RelationClearRelation() still needs a special case to go through the full-blown rebuild if the index support information in the relcache entry hasn't been populated yet. Reviewed-by: jian he <jian.universality@gmail.com> Discussion: https://www.postgresql.org/message-id/9c9e8908-7b3e-4ce7-85a8-00c0e165a3d6%40iki.fi
Diffstat (limited to 'src/backend/utils/cache/relcache.c')
-rw-r--r--src/backend/utils/cache/relcache.c41
1 files changed, 17 insertions, 24 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index c326f687eb4..8143f080433 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -2083,16 +2083,7 @@ RelationIdGetRelation(Oid relationId)
/* revalidate cache entry if necessary */
if (!rd->rd_isvalid)
{
- /*
- * Indexes only have a limited number of possible schema changes,
- * and we don't want to use the full-blown procedure because it's
- * a headache for indexes that reload itself depends on.
- */
- if (rd->rd_rel->relkind == RELKIND_INDEX ||
- rd->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
- RelationReloadIndexInfo(rd);
- else
- RelationClearRelation(rd, true);
+ RelationClearRelation(rd, true);
/*
* Normally entries need to be valid here, but before the relcache
@@ -2264,14 +2255,6 @@ RelationReloadIndexInfo(Relation relation)
!relation->rd_isvalid &&
relation->rd_droppedSubid == InvalidSubTransactionId);
- /* Ensure it's closed at smgr level */
- RelationCloseSmgr(relation);
-
- /* Must free any AM cached data upon relcache flush */
- if (relation->rd_amcache)
- pfree(relation->rd_amcache);
- relation->rd_amcache = NULL;
-
/*
* If it's a shared index, we might be called before backend startup has
* finished selecting a database, in which case we have no way to read
@@ -2600,15 +2583,19 @@ RelationClearRelation(Relation relation, bool rebuild)
return;
/*
- * Even non-system indexes should not be blown away if they are open and
- * have valid index support information. This avoids problems with active
- * use of the index support information. As with nailed indexes, we
- * re-read the pg_class row to handle possible physical relocation of the
- * index, and we check for pg_index updates too.
+ * Indexes only have a limited number of possible schema changes, and we
+ * don't want to use the full-blown procedure because it's a headache for
+ * indexes that reload itself depends on.
+ *
+ * As an exception, use the full procedure if the index access info hasn't
+ * been initialized yet. Index creation relies on that: it first builds
+ * the relcache entry with RelationBuildLocalRelation(), creates the
+ * pg_index tuple only after that, and then relies on
+ * CommandCounterIncrement to load the pg_index contents.
*/
if ((relation->rd_rel->relkind == RELKIND_INDEX ||
relation->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) &&
- relation->rd_refcnt > 0 &&
+ rebuild &&
relation->rd_indexcxt != NULL)
{
if (IsTransactionState())
@@ -3721,6 +3708,12 @@ RelationBuildLocalRelation(const char *relname,
RelationInitTableAccessMethod(rel);
/*
+ * Leave index access method uninitialized, because the pg_index row has
+ * not been inserted at this stage of index creation yet. The cache
+ * invalidation after pg_index row has been inserted will initialize it.
+ */
+
+ /*
* Okay to insert into the relcache hash table.
*
* Ordinarily, there should certainly not be an existing hash entry for