CCR: Do not follow if leader does not have soft-deletes (#34767)

We should not create a follower index and abort a follow request if the
leader does not have soft-deletes. Moreover, we also should not
auto-follow an index if it does not have soft-deletes.
This commit is contained in:
Nhat Nguyen 2018-10-24 11:19:39 -04:00 committed by GitHub
parent 0a85997cb0
commit d73768f812
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 14 deletions

View File

@ -26,6 +26,7 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.concurrent.AtomicArray; import org.elasticsearch.common.util.concurrent.AtomicArray;
import org.elasticsearch.common.util.concurrent.CountDown; import org.elasticsearch.common.util.concurrent.CountDown;
import org.elasticsearch.index.Index; import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.license.LicenseUtils; import org.elasticsearch.license.LicenseUtils;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.xpack.ccr.CcrLicenseChecker; import org.elasticsearch.xpack.ccr.CcrLicenseChecker;
@ -370,7 +371,9 @@ public class AutoFollowCoordinator implements ClusterStateApplier {
// has a leader index uuid custom metadata entry that matches with uuid of leaderIndexMetaData variable // has a leader index uuid custom metadata entry that matches with uuid of leaderIndexMetaData variable
// If so then handle it differently: not follow it, but just add an entry to // If so then handle it differently: not follow it, but just add an entry to
// AutoFollowMetadata#followedLeaderIndexUUIDs // AutoFollowMetadata#followedLeaderIndexUUIDs
leaderIndicesToFollow.add(leaderIndexMetaData.getIndex()); if (leaderIndexMetaData.getSettings().getAsBoolean(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), false)) {
leaderIndicesToFollow.add(leaderIndexMetaData.getIndex());
}
} }
} }
} }

View File

@ -125,6 +125,10 @@ public final class TransportPutFollowAction
listener.onFailure(new IllegalArgumentException("leader index [" + request.getLeaderIndex() + "] does not exist")); listener.onFailure(new IllegalArgumentException("leader index [" + request.getLeaderIndex() + "] does not exist"));
return; return;
} }
if (leaderIndexMetaData.getSettings().getAsBoolean(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), false) == false) {
listener.onFailure(
new IllegalArgumentException("leader index [" + request.getLeaderIndex() + "] does not have soft deletes enabled"));
}
ActionListener<Boolean> handler = ActionListener.wrap( ActionListener<Boolean> handler = ActionListener.wrap(
result -> { result -> {

View File

@ -67,6 +67,21 @@ public class LocalIndexFollowingIT extends CcrSingleNodeTestCase {
}); });
} }
public void testDoNotCreateFollowerIfLeaderDoesNotHaveSoftDeletes() throws Exception {
final String leaderIndexSettings = getIndexSettings(2, 0,
singletonMap(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), "false"));
assertAcked(client().admin().indices().prepareCreate("leader-index").setSource(leaderIndexSettings, XContentType.JSON));
ResumeFollowAction.Request followRequest = getResumeFollowRequest();
followRequest.setFollowerIndex("follower-index");
PutFollowAction.Request putFollowRequest = getPutFollowRequest();
putFollowRequest.setLeaderIndex("leader-index");
putFollowRequest.setFollowRequest(followRequest);
IllegalArgumentException error = expectThrows(IllegalArgumentException.class,
() -> client().execute(PutFollowAction.INSTANCE, putFollowRequest).actionGet());
assertThat(error.getMessage(), equalTo("leader index [leader-index] does not have soft deletes enabled"));
assertThat(client().admin().indices().prepareExists("follower-index").get().isExists(), equalTo(false));
}
private String getIndexSettings(final int numberOfShards, final int numberOfReplicas, private String getIndexSettings(final int numberOfShards, final int numberOfReplicas,
final Map<String, String> additionalIndexSettings) throws IOException { final Map<String, String> additionalIndexSettings) throws IOException {
final String settings; final String settings;

View File

@ -15,6 +15,7 @@ import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.Index; import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.ccr.CcrLicenseChecker; import org.elasticsearch.xpack.ccr.CcrLicenseChecker;
import org.elasticsearch.xpack.ccr.action.AutoFollowCoordinator.AutoFollower; import org.elasticsearch.xpack.ccr.action.AutoFollowCoordinator.AutoFollower;
@ -50,7 +51,7 @@ public class AutoFollowCoordinatorTests extends ESTestCase {
ClusterState leaderState = ClusterState.builder(new ClusterName("remote")) ClusterState leaderState = ClusterState.builder(new ClusterName("remote"))
.metaData(MetaData.builder().put(IndexMetaData.builder("logs-20190101") .metaData(MetaData.builder().put(IndexMetaData.builder("logs-20190101")
.settings(settings(Version.CURRENT)) .settings(settings(Version.CURRENT).put(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), true))
.numberOfShards(1) .numberOfShards(1)
.numberOfReplicas(0))) .numberOfReplicas(0)))
.build(); .build();
@ -172,7 +173,7 @@ public class AutoFollowCoordinatorTests extends ESTestCase {
ClusterState leaderState = ClusterState.builder(new ClusterName("remote")) ClusterState leaderState = ClusterState.builder(new ClusterName("remote"))
.metaData(MetaData.builder().put(IndexMetaData.builder("logs-20190101") .metaData(MetaData.builder().put(IndexMetaData.builder("logs-20190101")
.settings(settings(Version.CURRENT)) .settings(settings(Version.CURRENT).put(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), true))
.numberOfShards(1) .numberOfShards(1)
.numberOfReplicas(0))) .numberOfReplicas(0)))
.build(); .build();
@ -235,7 +236,7 @@ public class AutoFollowCoordinatorTests extends ESTestCase {
ClusterState leaderState = ClusterState.builder(new ClusterName("remote")) ClusterState leaderState = ClusterState.builder(new ClusterName("remote"))
.metaData(MetaData.builder().put(IndexMetaData.builder("logs-20190101") .metaData(MetaData.builder().put(IndexMetaData.builder("logs-20190101")
.settings(settings(Version.CURRENT)) .settings(settings(Version.CURRENT).put(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), true))
.numberOfShards(1) .numberOfShards(1)
.numberOfReplicas(0))) .numberOfReplicas(0)))
.build(); .build();
@ -306,7 +307,8 @@ public class AutoFollowCoordinatorTests extends ESTestCase {
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
Settings.Builder builder = Settings.builder() Settings.Builder builder = Settings.builder()
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT) .put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)
.put(IndexMetaData.SETTING_INDEX_UUID, "metrics-" + i); .put(IndexMetaData.SETTING_INDEX_UUID, "metrics-" + i)
.put(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), i % 2 == 0);
imdBuilder.put(IndexMetaData.builder("metrics-" + i) imdBuilder.put(IndexMetaData.builder("metrics-" + i)
.settings(builder) .settings(builder)
.numberOfShards(1) .numberOfShards(1)
@ -324,21 +326,17 @@ public class AutoFollowCoordinatorTests extends ESTestCase {
List<Index> result = AutoFollower.getLeaderIndicesToFollow("remote", autoFollowPattern, leaderState, followerState, List<Index> result = AutoFollower.getLeaderIndicesToFollow("remote", autoFollowPattern, leaderState, followerState,
Collections.emptyList()); Collections.emptyList());
result.sort(Comparator.comparing(Index::getName)); result.sort(Comparator.comparing(Index::getName));
assertThat(result.size(), equalTo(5)); assertThat(result.size(), equalTo(3));
assertThat(result.get(0).getName(), equalTo("metrics-0")); assertThat(result.get(0).getName(), equalTo("metrics-0"));
assertThat(result.get(1).getName(), equalTo("metrics-1")); assertThat(result.get(1).getName(), equalTo("metrics-2"));
assertThat(result.get(2).getName(), equalTo("metrics-2")); assertThat(result.get(2).getName(), equalTo("metrics-4"));
assertThat(result.get(3).getName(), equalTo("metrics-3"));
assertThat(result.get(4).getName(), equalTo("metrics-4"));
List<String> followedIndexUUIDs = Collections.singletonList(leaderState.metaData().index("metrics-2").getIndexUUID()); List<String> followedIndexUUIDs = Collections.singletonList(leaderState.metaData().index("metrics-2").getIndexUUID());
result = AutoFollower.getLeaderIndicesToFollow("remote", autoFollowPattern, leaderState, followerState, followedIndexUUIDs); result = AutoFollower.getLeaderIndicesToFollow("remote", autoFollowPattern, leaderState, followerState, followedIndexUUIDs);
result.sort(Comparator.comparing(Index::getName)); result.sort(Comparator.comparing(Index::getName));
assertThat(result.size(), equalTo(4)); assertThat(result.size(), equalTo(2));
assertThat(result.get(0).getName(), equalTo("metrics-0")); assertThat(result.get(0).getName(), equalTo("metrics-0"));
assertThat(result.get(1).getName(), equalTo("metrics-1")); assertThat(result.get(1).getName(), equalTo("metrics-4"));
assertThat(result.get(2).getName(), equalTo("metrics-3"));
assertThat(result.get(3).getName(), equalTo("metrics-4"));
} }
public void testGetFollowerIndexName() { public void testGetFollowerIndexName() {