Search in sources :

Example 16 with AllocationId

use of org.elasticsearch.cluster.routing.AllocationId in project crate by crate.

the class ReplicationTrackerRetentionLeaseTests method testPersistRetentionLeasesUnderConcurrency.

/**
 * Test that we correctly synchronize writing the retention lease state file in {@link ReplicationTracker#persistRetentionLeases(Path)}.
 * This test can fail without the synchronization block in that method.
 *
 * @throws IOException if an I/O exception occurs loading the retention lease state file
 */
@Test
public void testPersistRetentionLeasesUnderConcurrency() throws IOException {
    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 int length = randomIntBetween(0, 8);
    for (int i = 0; i < length; i++) {
        if (rarely() && primaryTerm < Long.MAX_VALUE) {
            primaryTerm = randomLongBetween(primaryTerm + 1, Long.MAX_VALUE);
            replicationTracker.setOperationPrimaryTerm(primaryTerm);
        }
        final long retainingSequenceNumber = randomLongBetween(SequenceNumbers.NO_OPS_PERFORMED, Long.MAX_VALUE);
        replicationTracker.addRetentionLease(Integer.toString(i), retainingSequenceNumber, "test-" + i, ActionListener.wrap(() -> {
        }));
    }
    final Path path = createTempDir();
    final int numberOfThreads = randomIntBetween(1, 2 * Runtime.getRuntime().availableProcessors());
    final CyclicBarrier barrier = new CyclicBarrier(1 + numberOfThreads);
    final Thread[] threads = new Thread[numberOfThreads];
    for (int i = 0; i < numberOfThreads; i++) {
        final String id = Integer.toString(length + i);
        threads[i] = new Thread(() -> {
            try {
                barrier.await();
                final long retainingSequenceNumber = randomLongBetween(SequenceNumbers.NO_OPS_PERFORMED, Long.MAX_VALUE);
                replicationTracker.addRetentionLease(id, retainingSequenceNumber, "test-" + id, ActionListener.wrap(() -> {
                }));
                replicationTracker.persistRetentionLeases(path);
                barrier.await();
            } catch (final BrokenBarrierException | InterruptedException | WriteStateException e) {
                throw new AssertionError(e);
            }
        });
        threads[i].start();
    }
    try {
        // synchronize the threads invoking ReplicationTracker#persistRetentionLeases(Path path)
        barrier.await();
        // wait for all the threads to finish
        barrier.await();
        for (int i = 0; i < numberOfThreads; i++) {
            threads[i].join();
        }
    } catch (final BrokenBarrierException | InterruptedException e) {
        throw new AssertionError(e);
    }
    assertThat(replicationTracker.loadRetentionLeases(path), equalTo(replicationTracker.getRetentionLeases()));
}
Also used : Path(java.nio.file.Path) BrokenBarrierException(java.util.concurrent.BrokenBarrierException) AllocationId(org.elasticsearch.cluster.routing.AllocationId) Matchers.hasToString(org.hamcrest.Matchers.hasToString) Matchers.containsString(org.hamcrest.Matchers.containsString) CyclicBarrier(java.util.concurrent.CyclicBarrier) ShardId(org.elasticsearch.index.shard.ShardId) Test(org.junit.Test)

Example 17 with AllocationId

use of org.elasticsearch.cluster.routing.AllocationId in project crate by crate.

the class ReplicationTrackerRetentionLeaseTests method testLoadAndPersistRetentionLeases.

@Test
public void testLoadAndPersistRetentionLeases() throws IOException {
    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 int length = randomIntBetween(0, 8);
    for (int i = 0; i < length; i++) {
        if (rarely() && primaryTerm < Long.MAX_VALUE) {
            primaryTerm = randomLongBetween(primaryTerm + 1, Long.MAX_VALUE);
            replicationTracker.setOperationPrimaryTerm(primaryTerm);
        }
        final long retainingSequenceNumber = randomLongBetween(SequenceNumbers.NO_OPS_PERFORMED, Long.MAX_VALUE);
        replicationTracker.addRetentionLease(Integer.toString(i), retainingSequenceNumber, "test-" + i, ActionListener.wrap(() -> {
        }));
    }
    final Path path = createTempDir();
    replicationTracker.persistRetentionLeases(path);
    assertThat(replicationTracker.loadRetentionLeases(path), equalTo(replicationTracker.getRetentionLeases()));
}
Also used : ShardId(org.elasticsearch.index.shard.ShardId) Path(java.nio.file.Path) AllocationId(org.elasticsearch.cluster.routing.AllocationId) Test(org.junit.Test)

Example 18 with AllocationId

use of org.elasticsearch.cluster.routing.AllocationId in project crate by crate.

the class ReplicationTrackerRetentionLeaseTests method testCloneNonexistentRetentionLease.

@Test
public void testCloneNonexistentRetentionLease() {
    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);
    assertThat(expectThrows(RetentionLeaseNotFoundException.class, () -> replicationTracker.cloneRetentionLease("nonexistent-lease-id", "target", ActionListener.wrap(() -> {
    }))).getMessage(), equalTo("retention lease with ID [nonexistent-lease-id] not found"));
}
Also used : ShardId(org.elasticsearch.index.shard.ShardId) AllocationId(org.elasticsearch.cluster.routing.AllocationId) Test(org.junit.Test)

Example 19 with AllocationId

use of org.elasticsearch.cluster.routing.AllocationId in project crate by crate.

the class ReplicationTrackerRetentionLeaseTests method testRemoveRetentionLeaseCausesRetentionLeaseSync.

@Test
public void testRemoveRetentionLeaseCausesRetentionLeaseSync() {
    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.builder().put(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), true).build()), 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 removing the lease
        invoked.set(false);
        retainingSequenceNumbers.remove(id);
        replicationTracker.removeRetentionLease(id, ActionListener.wrap(() -> {
        }));
        assertTrue(invoked.get());
    }
}
Also used : HashMap(java.util.HashMap) AllocationId(org.elasticsearch.cluster.routing.AllocationId) AtomicReference(java.util.concurrent.atomic.AtomicReference) Matchers.hasToString(org.hamcrest.Matchers.hasToString) Matchers.containsString(org.hamcrest.Matchers.containsString) ShardId(org.elasticsearch.index.shard.ShardId) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicLong(java.util.concurrent.atomic.AtomicLong) Test(org.junit.Test)

Example 20 with AllocationId

use of org.elasticsearch.cluster.routing.AllocationId in project crate by crate.

the class ReplicationTrackerRetentionLeaseTests method testRenewLeaseWithLowerRetainingSequenceNumber.

@Test
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.elasticsearch.index.shard.ShardId) AllocationId(org.elasticsearch.cluster.routing.AllocationId) Matchers.hasToString(org.hamcrest.Matchers.hasToString) Matchers.containsString(org.hamcrest.Matchers.containsString) Test(org.junit.Test)

Aggregations

AllocationId (org.elasticsearch.cluster.routing.AllocationId)24 ShardId (org.elasticsearch.index.shard.ShardId)22 Test (org.junit.Test)16 IndexShardRoutingTable (org.elasticsearch.cluster.routing.IndexShardRoutingTable)7 Matchers.containsString (org.hamcrest.Matchers.containsString)7 Matchers.hasToString (org.hamcrest.Matchers.hasToString)7 AtomicLong (java.util.concurrent.atomic.AtomicLong)6 ClusterState (org.elasticsearch.cluster.ClusterState)5 DiscoveryNode (org.elasticsearch.cluster.node.DiscoveryNode)4 IndexRoutingTable (org.elasticsearch.cluster.routing.IndexRoutingTable)4 RoutingTable (org.elasticsearch.cluster.routing.RoutingTable)4 Path (java.nio.file.Path)3 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)3 IndexMetadata (org.elasticsearch.cluster.metadata.IndexMetadata)3 BalancedShardsAllocator (org.elasticsearch.cluster.routing.allocation.allocator.BalancedShardsAllocator)3 AllocationDeciders (org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders)3 NodeVersionAllocationDecider (org.elasticsearch.cluster.routing.allocation.decider.NodeVersionAllocationDecider)3 TestGatewayAllocator (org.elasticsearch.test.gateway.TestGatewayAllocator)3 HashMap (java.util.HashMap)2