Search in sources :

Example 11 with AllocationId

use of org.opensearch.cluster.routing.AllocationId in project OpenSearch by opensearch-project.

the class ReplicationTrackerTests method testGlobalCheckpointUpdate.

public void testGlobalCheckpointUpdate() {
    final long initialClusterStateVersion = randomNonNegativeLong();
    Map<AllocationId, Long> allocations = new HashMap<>();
    Map<AllocationId, Long> activeWithCheckpoints = randomAllocationsWithLocalCheckpoints(1, 5);
    Set<AllocationId> active = new HashSet<>(activeWithCheckpoints.keySet());
    allocations.putAll(activeWithCheckpoints);
    Map<AllocationId, Long> initializingWithCheckpoints = randomAllocationsWithLocalCheckpoints(0, 5);
    Set<AllocationId> initializing = new HashSet<>(initializingWithCheckpoints.keySet());
    allocations.putAll(initializingWithCheckpoints);
    assertThat(allocations.size(), equalTo(active.size() + initializing.size()));
    // note: allocations can never be empty in practice as we always have at least one primary shard active/in sync
    // it is however nice not to assume this on this level and check we do the right thing.
    final long minLocalCheckpoint = allocations.values().stream().min(Long::compare).orElse(UNASSIGNED_SEQ_NO);
    final AllocationId primaryId = active.iterator().next();
    final ReplicationTracker tracker = newTracker(primaryId);
    assertThat(tracker.getGlobalCheckpoint(), equalTo(UNASSIGNED_SEQ_NO));
    logger.info("--> using allocations");
    allocations.keySet().forEach(aId -> {
        final String type;
        if (active.contains(aId)) {
            type = "active";
        } else if (initializing.contains(aId)) {
            type = "init";
        } else {
            throw new IllegalStateException(aId + " not found in any map");
        }
        logger.info("  - [{}], local checkpoint [{}], [{}]", aId, allocations.get(aId), type);
    });
    tracker.updateFromMaster(initialClusterStateVersion, ids(active), routingTable(initializing, primaryId));
    tracker.activatePrimaryMode(NO_OPS_PERFORMED);
    assertThat(tracker.getReplicationGroup().getReplicationTargets().size(), equalTo(1));
    initializing.forEach(aId -> markAsTrackingAndInSyncQuietly(tracker, aId.getId(), NO_OPS_PERFORMED));
    assertThat(tracker.getReplicationGroup().getReplicationTargets().size(), equalTo(1 + initializing.size()));
    allocations.keySet().forEach(aId -> updateLocalCheckpoint(tracker, aId.getId(), allocations.get(aId)));
    assertThat(tracker.getGlobalCheckpoint(), equalTo(minLocalCheckpoint));
    // increment checkpoints
    active.forEach(aId -> allocations.put(aId, allocations.get(aId) + 1 + randomInt(4)));
    initializing.forEach(aId -> allocations.put(aId, allocations.get(aId) + 1 + randomInt(4)));
    allocations.keySet().forEach(aId -> updateLocalCheckpoint(tracker, aId.getId(), allocations.get(aId)));
    final long minLocalCheckpointAfterUpdates = allocations.entrySet().stream().map(Map.Entry::getValue).min(Long::compareTo).orElse(UNASSIGNED_SEQ_NO);
    // now insert an unknown active/insync id , the checkpoint shouldn't change but a refresh should be requested.
    final AllocationId extraId = AllocationId.newInitializing();
    // first check that adding it without the master blessing doesn't change anything.
    updateLocalCheckpoint(tracker, extraId.getId(), minLocalCheckpointAfterUpdates + 1 + randomInt(4));
    assertNull(tracker.checkpoints.get(extraId.getId()));
    expectThrows(IllegalStateException.class, () -> tracker.initiateTracking(extraId.getId()));
    Set<AllocationId> newInitializing = new HashSet<>(initializing);
    newInitializing.add(extraId);
    tracker.updateFromMaster(initialClusterStateVersion + 1, ids(active), routingTable(newInitializing, primaryId));
    addPeerRecoveryRetentionLease(tracker, extraId);
    tracker.initiateTracking(extraId.getId());
    // now notify for the new id
    if (randomBoolean()) {
        updateLocalCheckpoint(tracker, extraId.getId(), minLocalCheckpointAfterUpdates + 1 + randomInt(4));
        markAsTrackingAndInSyncQuietly(tracker, extraId.getId(), randomInt((int) minLocalCheckpointAfterUpdates));
    } else {
        markAsTrackingAndInSyncQuietly(tracker, extraId.getId(), minLocalCheckpointAfterUpdates + 1 + randomInt(4));
    }
    // now it should be incremented
    assertThat(tracker.getGlobalCheckpoint(), greaterThan(minLocalCheckpoint));
}
Also used : HashMap(java.util.HashMap) AllocationId(org.opensearch.cluster.routing.AllocationId) AtomicLong(java.util.concurrent.atomic.AtomicLong) HashSet(java.util.HashSet)

Example 12 with AllocationId

use of org.opensearch.cluster.routing.AllocationId in project OpenSearch by opensearch-project.

the class ReplicationTrackerRetentionLeaseTests method testAddRetentionLeaseCausesRetentionLeaseSync.

public void testAddRetentionLeaseCausesRetentionLeaseSync() {
    final AllocationId allocationId = AllocationId.newInitializing();
    final Map<String, Long> retainingSequenceNumbers = new HashMap<>();
    final AtomicBoolean invoked = new AtomicBoolean();
    final AtomicReference<ReplicationTracker> reference = new AtomicReference<>();
    final ReplicationTracker replicationTracker = new ReplicationTracker(new ShardId("test", "_na", 0), allocationId.getId(), IndexSettingsModule.newIndexSettings("test", Settings.EMPTY), randomNonNegativeLong(), UNASSIGNED_SEQ_NO, value -> {
    }, () -> 0L, (leases, listener) -> {
        // we do not want to hold a lock on the replication tracker in the callback!
        assertFalse(Thread.holdsLock(reference.get()));
        invoked.set(true);
        assertThat(leases.leases().stream().collect(Collectors.toMap(RetentionLease::id, RetentionLease::retainingSequenceNumber)), equalTo(retainingSequenceNumbers));
    }, OPS_BASED_RECOVERY_ALWAYS_REASONABLE);
    reference.set(replicationTracker);
    replicationTracker.updateFromMaster(randomNonNegativeLong(), Collections.singleton(allocationId.getId()), routingTable(Collections.emptySet(), allocationId));
    replicationTracker.activatePrimaryMode(SequenceNumbers.NO_OPS_PERFORMED);
    retainingSequenceNumbers.put(ReplicationTracker.getPeerRecoveryRetentionLeaseId(nodeIdFromAllocationId(allocationId)), 0L);
    final int length = randomIntBetween(0, 8);
    for (int i = 0; i < length; i++) {
        final String id = randomAlphaOfLength(8);
        final long retainingSequenceNumber = randomLongBetween(SequenceNumbers.NO_OPS_PERFORMED, Long.MAX_VALUE);
        retainingSequenceNumbers.put(id, retainingSequenceNumber);
        replicationTracker.addRetentionLease(id, retainingSequenceNumber, "test", ActionListener.wrap(() -> {
        }));
        // assert that the new retention lease callback was invoked
        assertTrue(invoked.get());
        // reset the invocation marker so that we can assert the callback was not invoked when renewing the lease
        invoked.set(false);
        replicationTracker.renewRetentionLease(id, retainingSequenceNumber, "test");
        assertFalse(invoked.get());
    }
}
Also used : HashMap(java.util.HashMap) AllocationId(org.opensearch.cluster.routing.AllocationId) AtomicReference(java.util.concurrent.atomic.AtomicReference) Matchers.hasToString(org.hamcrest.Matchers.hasToString) Matchers.containsString(org.hamcrest.Matchers.containsString) ShardId(org.opensearch.index.shard.ShardId) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicLong(java.util.concurrent.atomic.AtomicLong)

Example 13 with AllocationId

use of org.opensearch.cluster.routing.AllocationId in project OpenSearch by opensearch-project.

the class ReplicationTrackerRetentionLeaseTests method testCloneDuplicateRetentionLease.

public void testCloneDuplicateRetentionLease() {
    final AllocationId allocationId = AllocationId.newInitializing();
    final ReplicationTracker replicationTracker = new ReplicationTracker(new ShardId("test", "_na", 0), allocationId.getId(), IndexSettingsModule.newIndexSettings("test", Settings.EMPTY), randomLongBetween(1, Long.MAX_VALUE), UNASSIGNED_SEQ_NO, value -> {
    }, () -> 0L, (leases, listener) -> {
    }, OPS_BASED_RECOVERY_ALWAYS_REASONABLE);
    replicationTracker.updateFromMaster(randomNonNegativeLong(), Collections.singleton(allocationId.getId()), routingTable(Collections.emptySet(), allocationId));
    replicationTracker.activatePrimaryMode(SequenceNumbers.NO_OPS_PERFORMED);
    replicationTracker.addRetentionLease("source", randomLongBetween(0L, Long.MAX_VALUE), "test-source", ActionListener.wrap(() -> {
    }));
    replicationTracker.addRetentionLease("exists", randomLongBetween(0L, Long.MAX_VALUE), "test-source", ActionListener.wrap(() -> {
    }));
    assertThat(expectThrows(RetentionLeaseAlreadyExistsException.class, () -> replicationTracker.cloneRetentionLease("source", "exists", ActionListener.wrap(() -> {
    }))).getMessage(), equalTo("retention lease with ID [exists] already exists"));
}
Also used : ShardId(org.opensearch.index.shard.ShardId) AllocationId(org.opensearch.cluster.routing.AllocationId)

Example 14 with AllocationId

use of org.opensearch.cluster.routing.AllocationId in project OpenSearch by opensearch-project.

the class ReplicationTrackerRetentionLeaseTests method testRenewLeaseWithLowerRetainingSequenceNumber.

public void testRenewLeaseWithLowerRetainingSequenceNumber() throws Exception {
    final AllocationId allocationId = AllocationId.newInitializing();
    long primaryTerm = randomLongBetween(1, Long.MAX_VALUE);
    final ReplicationTracker replicationTracker = new ReplicationTracker(new ShardId("test", "_na", 0), allocationId.getId(), IndexSettingsModule.newIndexSettings("test", Settings.EMPTY), primaryTerm, UNASSIGNED_SEQ_NO, value -> {
    }, () -> 0L, (leases, listener) -> {
    }, OPS_BASED_RECOVERY_ALWAYS_REASONABLE);
    replicationTracker.updateFromMaster(randomNonNegativeLong(), Collections.singleton(allocationId.getId()), routingTable(Collections.emptySet(), allocationId));
    replicationTracker.activatePrimaryMode(SequenceNumbers.NO_OPS_PERFORMED);
    final String id = randomAlphaOfLength(8);
    final long retainingSequenceNumber = randomNonNegativeLong();
    final String source = randomAlphaOfLength(8);
    replicationTracker.addRetentionLease(id, retainingSequenceNumber, source, ActionListener.wrap(() -> {
    }));
    final long lowerRetainingSequenceNumber = randomLongBetween(SequenceNumbers.NO_OPS_PERFORMED, retainingSequenceNumber - 1);
    final RetentionLeaseInvalidRetainingSeqNoException e = expectThrows(RetentionLeaseInvalidRetainingSeqNoException.class, () -> replicationTracker.renewRetentionLease(id, lowerRetainingSequenceNumber, source));
    assertThat(e, hasToString(containsString("the current retention lease with [" + id + "]" + " is retaining a higher sequence number [" + retainingSequenceNumber + "]" + " than the new retaining sequence number [" + lowerRetainingSequenceNumber + "] from [" + source + "]")));
}
Also used : ShardId(org.opensearch.index.shard.ShardId) AllocationId(org.opensearch.cluster.routing.AllocationId) Matchers.hasToString(org.hamcrest.Matchers.hasToString) Matchers.containsString(org.hamcrest.Matchers.containsString)

Example 15 with AllocationId

use of org.opensearch.cluster.routing.AllocationId in project OpenSearch by opensearch-project.

the class ReplicationTrackerRetentionLeaseTests method testAddDuplicateRetentionLease.

public void testAddDuplicateRetentionLease() {
    final AllocationId allocationId = AllocationId.newInitializing();
    long primaryTerm = randomLongBetween(1, Long.MAX_VALUE);
    final ReplicationTracker replicationTracker = new ReplicationTracker(new ShardId("test", "_na", 0), allocationId.getId(), IndexSettingsModule.newIndexSettings("test", Settings.EMPTY), primaryTerm, UNASSIGNED_SEQ_NO, value -> {
    }, () -> 0L, (leases, listener) -> {
    }, OPS_BASED_RECOVERY_ALWAYS_REASONABLE);
    replicationTracker.updateFromMaster(randomNonNegativeLong(), Collections.singleton(allocationId.getId()), routingTable(Collections.emptySet(), allocationId));
    replicationTracker.activatePrimaryMode(SequenceNumbers.NO_OPS_PERFORMED);
    final String id = randomAlphaOfLength(8);
    final long retainingSequenceNumber = randomNonNegativeLong();
    final String source = randomAlphaOfLength(8);
    replicationTracker.addRetentionLease(id, retainingSequenceNumber, source, ActionListener.wrap(() -> {
    }));
    final long nextRetaininSequenceNumber = randomLongBetween(retainingSequenceNumber, Long.MAX_VALUE);
    final RetentionLeaseAlreadyExistsException e = expectThrows(RetentionLeaseAlreadyExistsException.class, () -> replicationTracker.addRetentionLease(id, nextRetaininSequenceNumber, source, ActionListener.wrap(() -> {
    })));
    assertThat(e, hasToString(containsString("retention lease with ID [" + id + "] already exists")));
}
Also used : ShardId(org.opensearch.index.shard.ShardId) AllocationId(org.opensearch.cluster.routing.AllocationId) Matchers.hasToString(org.hamcrest.Matchers.hasToString) Matchers.containsString(org.hamcrest.Matchers.containsString)

Aggregations

AllocationId (org.opensearch.cluster.routing.AllocationId)47 ShardId (org.opensearch.index.shard.ShardId)29 AtomicLong (java.util.concurrent.atomic.AtomicLong)21 IndexShardRoutingTable (org.opensearch.cluster.routing.IndexShardRoutingTable)17 HashSet (java.util.HashSet)16 BrokenBarrierException (java.util.concurrent.BrokenBarrierException)16 CyclicBarrier (java.util.concurrent.CyclicBarrier)16 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)16 ShardRouting (org.opensearch.cluster.routing.ShardRouting)16 TestShardRouting (org.opensearch.cluster.routing.TestShardRouting)14 ArrayList (java.util.ArrayList)13 Set (java.util.Set)13 Matchers.containsString (org.hamcrest.Matchers.containsString)13 Matchers.hasToString (org.hamcrest.Matchers.hasToString)13 ShardRoutingState (org.opensearch.cluster.routing.ShardRoutingState)13 Settings (org.opensearch.common.settings.Settings)13 IndexSettings (org.opensearch.index.IndexSettings)13 IOException (java.io.IOException)12 Collections (java.util.Collections)12 Collections.emptySet (java.util.Collections.emptySet)12