From ff4941c738a5429db57aa13cacc0e126d90ee185 Mon Sep 17 00:00:00 2001 From: Alexey Kondratov Date: Wed, 23 Sep 2020 18:21:16 +0300 Subject: [PATCH 2/4] Refactor and reuse set_rel_tablespace() --- src/backend/catalog/index.c | 70 +++++++++++++++++++++----------- src/backend/commands/indexcmds.c | 35 ---------------- src/include/catalog/index.h | 2 + 3 files changed, 49 insertions(+), 58 deletions(-) diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9aa9fdf291..f652459d83 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3722,24 +3722,11 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, params->tablespaceOid = InvalidOid; /* - * Set the new tablespace for the relation. Do that only in the - * case where the reindex caller wishes to enforce a new tablespace. + * Set the new tablespace for the relation if requested. */ if (set_tablespace && - params->tablespaceOid != iRel->rd_rel->reltablespace) + set_rel_tablespace(indexId, params->tablespaceOid)) { - Relation pg_class; - Form_pg_class rd_rel; - HeapTuple tuple; - - /* First get a modifiable copy of the relation's pg_class row */ - pg_class = table_open(RelationRelationId, RowExclusiveLock); - - tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(indexId)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", indexId); - rd_rel = (Form_pg_class) GETSTRUCT(tuple); - /* * Mark the relation as ready to be dropped at transaction commit, * before making visible the new tablespace change so as this won't @@ -3747,14 +3734,6 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, */ RelationDropStorage(iRel); - /* Update the pg_class row */ - rd_rel->reltablespace = params->tablespaceOid; - CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); - - heap_freetuple(tuple); - - table_close(pg_class, RowExclusiveLock); - RelationAssumeNewRelfilenode(iRel); /* Make sure the reltablespace change is visible */ @@ -4063,6 +4042,51 @@ reindex_relation(Oid relid, int flags, ReindexParams *params) return result; } +/* + * set_rel_tablespace - modify relation tablespace in the pg_class entry. + * + * 'reloid' is an Oid of relation to be modified. + * 'tablespaceOid' is an Oid of new tablespace. + * + * Catalog modification is done only if tablespaceOid is different from + * the currently set. Returned bool value is indicating whether any changes + * were made or not. + */ +bool +set_rel_tablespace(Oid reloid, Oid tablespaceOid) +{ + Relation pg_class; + HeapTuple tuple; + Form_pg_class rd_rel; + bool changed = false; + Oid oldTablespaceOid; + + /* Get a modifiable copy of the relation's pg_class row. */ + pg_class = table_open(RelationRelationId, RowExclusiveLock); + + tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(reloid)); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for relation %u", reloid); + rd_rel = (Form_pg_class) GETSTRUCT(tuple); + + /* No work if no change in tablespace. */ + oldTablespaceOid = rd_rel->reltablespace; + if (tablespaceOid != oldTablespaceOid || + (tablespaceOid == MyDatabaseTableSpace && OidIsValid(oldTablespaceOid))) + { + /* Update the pg_class row. */ + rd_rel->reltablespace = (tablespaceOid == MyDatabaseTableSpace) ? + InvalidOid : tablespaceOid; + CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); + + changed = true; + } + + heap_freetuple(tuple); + table_close(pg_class, RowExclusiveLock); + + return changed; +} /* ---------------------------------------------------------------- * System index reindexing support diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 4dd54079a2..efcfc2b844 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -2942,41 +2942,6 @@ reindex_error_callback(void *arg) errinfo->relnamespace, errinfo->relname); } -/* - * This is mostly duplicating ATExecSetTableSpaceNoStorage, - * which should maybe be factored out to a library function. - */ -static void -set_rel_tablespace(Oid reloid, Oid tablespaceOid) -{ - Relation pg_class; - HeapTuple tuple; - Form_pg_class rd_rel; - Oid oldTablespaceOid; - - /* Get a modifiable copy of the relation's pg_class row */ - pg_class = table_open(RelationRelationId, RowExclusiveLock); - - tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(reloid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", reloid); - rd_rel = (Form_pg_class) GETSTRUCT(tuple); - - /* No work if no change in tablespace. */ - oldTablespaceOid = rd_rel->reltablespace; - if (tablespaceOid != oldTablespaceOid || - (tablespaceOid == MyDatabaseTableSpace && OidIsValid(oldTablespaceOid))) - { - /* Update the pg_class row */ - rd_rel->reltablespace = (tablespaceOid == MyDatabaseTableSpace) ? - InvalidOid : tablespaceOid; - CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); - } - - heap_freetuple(tuple); - table_close(pg_class, RowExclusiveLock); -} - /* * ReindexPartitions * diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h index 56e403ac61..30cfd1877f 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.h @@ -153,6 +153,8 @@ extern Oid IndexGetRelation(Oid indexId, bool missing_ok); extern void reindex_index(Oid indexId, bool skip_constraint_checks, char relpersistence, ReindexParams *params); +extern bool set_rel_tablespace(Oid reloid, Oid tablespaceOid); + /* Flag bits for reindex_relation(): */ #define REINDEX_REL_PROCESS_TOAST 0x01 #define REINDEX_REL_SUPPRESS_INDEX_USE 0x02 -- 2.17.0