mirror of
https://github.com/postgres/postgres.git
synced 2025-11-22 12:22:45 +03:00
Fix REINDEX CONCURRENTLY of partitions
In case of a partition index, when swapping the old and new index, we also need to attach the new index as a partition and detach the old one. Also, to handle partition indexes, we not only need to change dependencies referencing the index, but also dependencies of the index referencing something else. The previous code did this only specifically for a constraint, but we also need to do this for partitioned indexes. So instead write a generic function that does it for all dependencies. Author: Michael Paquier <michael@paquier.xyz> Author: Peter Eisentraut <peter.eisentraut@2ndquadrant.com> Discussion: https://www.postgresql.org/message-id/flat/DF4PR8401MB11964EDB77C860078C343BEBEE5A0%40DF4PR8401MB1196.NAMPRD84.PROD.OUTLOOK.COM#154df1fedb735190a773481765f7b874
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
#include "catalog/heap.h"
|
||||
#include "catalog/index.h"
|
||||
#include "catalog/objectaccess.h"
|
||||
#include "catalog/partition.h"
|
||||
#include "catalog/pg_am.h"
|
||||
#include "catalog/pg_collation.h"
|
||||
#include "catalog/pg_constraint.h"
|
||||
@@ -1263,7 +1264,13 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId, const char
|
||||
indexColNames = lappend(indexColNames, NameStr(att->attname));
|
||||
}
|
||||
|
||||
/* Now create the new index */
|
||||
/*
|
||||
* Now create the new index.
|
||||
*
|
||||
* For a partition index, we adjust the partition dependency later, to
|
||||
* ensure a consistent state at all times. That is why parentIndexRelid
|
||||
* is not set here.
|
||||
*/
|
||||
newIndexId = index_create(heapRelation,
|
||||
newName,
|
||||
InvalidOid, /* indexRelationId */
|
||||
@@ -1395,6 +1402,9 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName)
|
||||
namestrcpy(&newClassForm->relname, NameStr(oldClassForm->relname));
|
||||
namestrcpy(&oldClassForm->relname, oldName);
|
||||
|
||||
/* Copy partition flag to track inheritance properly */
|
||||
newClassForm->relispartition = oldClassForm->relispartition;
|
||||
|
||||
CatalogTupleUpdate(pg_class, &oldClassTuple->t_self, oldClassTuple);
|
||||
CatalogTupleUpdate(pg_class, &newClassTuple->t_self, newClassTuple);
|
||||
|
||||
@@ -1555,29 +1565,23 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName)
|
||||
}
|
||||
|
||||
/*
|
||||
* Move all dependencies on the old index to the new one
|
||||
* Swap inheritance relationship with parent index
|
||||
*/
|
||||
|
||||
if (OidIsValid(indexConstraintOid))
|
||||
if (get_rel_relispartition(oldIndexId))
|
||||
{
|
||||
ObjectAddress myself,
|
||||
referenced;
|
||||
List *ancestors = get_partition_ancestors(oldIndexId);
|
||||
Oid parentIndexRelid = linitial_oid(ancestors);
|
||||
|
||||
/* Change to having the new index depend on the constraint */
|
||||
deleteDependencyRecordsForClass(RelationRelationId, oldIndexId,
|
||||
ConstraintRelationId, DEPENDENCY_INTERNAL);
|
||||
DeleteInheritsTuple(oldIndexId, parentIndexRelid);
|
||||
StoreSingleInheritance(newIndexId, parentIndexRelid, 1);
|
||||
|
||||
myself.classId = RelationRelationId;
|
||||
myself.objectId = newIndexId;
|
||||
myself.objectSubId = 0;
|
||||
|
||||
referenced.classId = ConstraintRelationId;
|
||||
referenced.objectId = indexConstraintOid;
|
||||
referenced.objectSubId = 0;
|
||||
|
||||
recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
|
||||
list_free(ancestors);
|
||||
}
|
||||
|
||||
/*
|
||||
* Move all dependencies of and on the old index to the new one
|
||||
*/
|
||||
changeDependenciesOf(RelationRelationId, oldIndexId, newIndexId);
|
||||
changeDependenciesOn(RelationRelationId, oldIndexId, newIndexId);
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user