diff --git a/src/box/alter.cc b/src/box/alter.cc
index eb548e0b10741f6a0c44aad21cda46899d388e29..7f130297e8d65fafd8b1f97daeb181c1d1963667 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -1100,7 +1100,7 @@ class ModifyIndex: public AlterSpaceOp
 	                         old_index_def->key_def->part_count) != 0) {
 	                /*
 	                 * Primary parts have been changed -
-	                 * update non-unique secondary indexes.
+	                 * update secondary indexes.
 	                 */
 	                alter->pk_def = new_index_def->key_def;
 	        }
@@ -1411,9 +1411,7 @@ alter_space_move_indexes(struct alter_space *alter, uint32_t begin,
 		struct index_def *old_def = old_index->def;
 		struct index_def *new_def;
 		uint32_t min_field_count = alter->new_min_field_count;
-		if ((old_def->opts.is_unique &&
-		     !old_def->key_def->is_nullable) ||
-		    old_def->type != TREE || alter->pk_def == NULL) {
+		if (alter->pk_def == NULL || !index_depends_on_pk(old_index)) {
 			if (is_min_field_count_changed) {
 				new_def = index_def_dup(old_def);
 				index_def_update_optionality(new_def,
@@ -1425,9 +1423,8 @@ alter_space_move_indexes(struct alter_space *alter, uint32_t begin,
 			continue;
 		}
 		/*
-		 * Rebuild non-unique secondary keys along with
-		 * the primary, since primary key parts have
-		 * changed.
+		 * Rebuild secondary indexes that depend on the
+		 * primary key since primary key parts have changed.
 		 */
 		new_def = index_def_new(old_def->space_id, old_def->iid,
 					old_def->name, strlen(old_def->name),
diff --git a/src/box/index.cc b/src/box/index.cc
index 11a6683dd388531fa86a9e7cfb4764b7e25d652f..6cd04833847ddc2bf61b97c4f23d8d7083dc5afe 100644
--- a/src/box/index.cc
+++ b/src/box/index.cc
@@ -560,6 +560,11 @@ generic_index_update_def(struct index *)
 {
 }
 
+bool generic_index_depends_on_pk(struct index *)
+{
+	return false;
+}
+
 ssize_t
 generic_index_size(struct index *index)
 {
diff --git a/src/box/index.h b/src/box/index.h
index 2e43d9991516ccdc891e0bc2fc595061a20c9aae..f19fbd167f0ad5d1039769ad359e0a53966b926b 100644
--- a/src/box/index.h
+++ b/src/box/index.h
@@ -373,6 +373,12 @@ struct index_vtab {
 	 * require index rebuild.
 	 */
 	void (*update_def)(struct index *);
+	/**
+	 * Return true if the index depends on the primary
+	 * key definition and hence needs to be updated if
+	 * the primary key is modified.
+	 */
+	bool (*depends_on_pk)(struct index *);
 
 	ssize_t (*size)(struct index *);
 	ssize_t (*bsize)(struct index *);
@@ -505,6 +511,12 @@ index_update_def(struct index *index)
 	index->vtab->update_def(index);
 }
 
+static inline bool
+index_depends_on_pk(struct index *index)
+{
+	return index->vtab->depends_on_pk(index);
+}
+
 static inline ssize_t
 index_size(struct index *index)
 {
@@ -616,6 +628,7 @@ void generic_index_abort_create(struct index *);
 void generic_index_commit_modify(struct index *, int64_t);
 void generic_index_commit_drop(struct index *);
 void generic_index_update_def(struct index *);
+bool generic_index_depends_on_pk(struct index *);
 ssize_t generic_index_size(struct index *);
 int generic_index_min(struct index *, const char *, uint32_t, struct tuple **);
 int generic_index_max(struct index *, const char *, uint32_t, struct tuple **);
diff --git a/src/box/memtx_bitset.c b/src/box/memtx_bitset.c
index 0e546217496e1a97f1f3fbb40a8b7c7c5289693c..e66247eeadeca109e17676cb0c78713a6318df59 100644
--- a/src/box/memtx_bitset.c
+++ b/src/box/memtx_bitset.c
@@ -461,6 +461,7 @@ static const struct index_vtab memtx_bitset_index_vtab = {
 	/* .commit_modify = */ generic_index_commit_modify,
 	/* .commit_drop = */ generic_index_commit_drop,
 	/* .update_def = */ generic_index_update_def,
+	/* .depends_on_pk = */ generic_index_depends_on_pk,
 	/* .size = */ memtx_bitset_index_size,
 	/* .bsize = */ memtx_bitset_index_bsize,
 	/* .min = */ generic_index_min,
diff --git a/src/box/memtx_hash.c b/src/box/memtx_hash.c
index 9c72af5dbdc06837676fe4beb24b2317c52bf018..c4081edce15a038b988495925a5e775dd303f85b 100644
--- a/src/box/memtx_hash.c
+++ b/src/box/memtx_hash.c
@@ -385,6 +385,7 @@ static const struct index_vtab memtx_hash_index_vtab = {
 	/* .commit_modify = */ generic_index_commit_modify,
 	/* .commit_drop = */ generic_index_commit_drop,
 	/* .update_def = */ memtx_hash_index_update_def,
+	/* .depends_on_pk = */ generic_index_depends_on_pk,
 	/* .size = */ memtx_hash_index_size,
 	/* .bsize = */ memtx_hash_index_bsize,
 	/* .min = */ generic_index_min,
diff --git a/src/box/memtx_rtree.c b/src/box/memtx_rtree.c
index 373d658e5acb612af01f2be8b7a8da0b2238bbb4..7cd3ac30f669c4f9e76bc08ce0e058b3d09b0bc7 100644
--- a/src/box/memtx_rtree.c
+++ b/src/box/memtx_rtree.c
@@ -299,6 +299,7 @@ static const struct index_vtab memtx_rtree_index_vtab = {
 	/* .commit_modify = */ generic_index_commit_modify,
 	/* .commit_drop = */ generic_index_commit_drop,
 	/* .update_def = */ generic_index_update_def,
+	/* .depends_on_pk = */ generic_index_depends_on_pk,
 	/* .size = */ memtx_rtree_index_size,
 	/* .bsize = */ memtx_rtree_index_bsize,
 	/* .min = */ generic_index_min,
diff --git a/src/box/memtx_tree.c b/src/box/memtx_tree.c
index 7178a4bc6efa92bc87443c5d27dc8fbd1d9a6b90..a06b590dfde9ef9cbbba319ce67ecccf6afc7a30 100644
--- a/src/box/memtx_tree.c
+++ b/src/box/memtx_tree.c
@@ -316,6 +316,14 @@ memtx_tree_index_update_def(struct index *base)
 	index->tree.arg = memtx_tree_index_cmp_def(index);
 }
 
+static bool
+memtx_tree_index_depends_on_pk(struct index *base)
+{
+	struct index_def *def = base->def;
+	/* See comment to memtx_tree_index_cmp_def(). */
+	return !def->opts.is_unique || def->key_def->is_nullable;
+}
+
 static ssize_t
 memtx_tree_index_size(struct index *base)
 {
@@ -586,6 +594,7 @@ static const struct index_vtab memtx_tree_index_vtab = {
 	/* .commit_modify = */ generic_index_commit_modify,
 	/* .commit_drop = */ generic_index_commit_drop,
 	/* .update_def = */ memtx_tree_index_update_def,
+	/* .depends_on_pk = */ memtx_tree_index_depends_on_pk,
 	/* .size = */ memtx_tree_index_size,
 	/* .bsize = */ memtx_tree_index_bsize,
 	/* .min = */ generic_index_min,
diff --git a/src/box/sysview_index.c b/src/box/sysview_index.c
index e2b2fb96b4d92260f6e3909c2297c294509f0537..729614017ae209f221c0dc0a43756c6207cde53a 100644
--- a/src/box/sysview_index.c
+++ b/src/box/sysview_index.c
@@ -165,6 +165,7 @@ static const struct index_vtab sysview_index_vtab = {
 	/* .commit_modify = */ generic_index_commit_modify,
 	/* .commit_drop = */ generic_index_commit_drop,
 	/* .update_def = */ generic_index_update_def,
+	/* .depends_on_pk = */ generic_index_depends_on_pk,
 	/* .size = */ generic_index_size,
 	/* .bsize = */ sysview_index_bsize,
 	/* .min = */ generic_index_min,
diff --git a/src/box/vinyl.c b/src/box/vinyl.c
index 226737086a34a707253493d0da6aab0d66b64c37..2e50bf48ec62b42abca7a5b2e7bd4016cd91f59a 100644
--- a/src/box/vinyl.c
+++ b/src/box/vinyl.c
@@ -906,6 +906,17 @@ vinyl_index_commit_drop(struct index *index)
 	vy_log_tx_try_commit();
 }
 
+static bool
+vinyl_index_depends_on_pk(struct index *index)
+{
+	(void)index;
+	/*
+	 * All secondary Vinyl indexes are non-clustered and hence
+	 * have to be updated if the primary key is modified.
+	 */
+	return true;
+}
+
 static void
 vinyl_init_system_space(struct space *space)
 {
@@ -3948,6 +3959,7 @@ static const struct index_vtab vinyl_index_vtab = {
 	/* .commit_modify = */ generic_index_commit_modify,
 	/* .commit_drop = */ vinyl_index_commit_drop,
 	/* .update_def = */ generic_index_update_def,
+	/* .depends_on_pk = */ vinyl_index_depends_on_pk,
 	/* .size = */ vinyl_index_size,
 	/* .bsize = */ vinyl_index_bsize,
 	/* .min = */ generic_index_min,