Search in sources :

Example 61 with Cluster

use of org.apache.cassandra.distributed.Cluster in project cassandra by apache.

the class PreviewRepairTest method testFinishingIncRepairDuringPreview.

/**
 * another case where the repaired datasets could mismatch is if an incremental repair finishes just as the preview
 * repair is starting up.
 *
 * This tests this case:
 * 1. we start a preview repair
 * 2. pause the validation requests from node1 -> node2
 * 3. node1 starts its validation
 * 4. run an incremental repair which completes fine
 * 5. node2 resumes its validation
 *
 * Now we will include sstables from the second incremental repair on node2 but not on node1
 * This should fail since we fail any preview repair which is ongoing when an incremental repair finishes (step 4 above)
 */
@Test
public void testFinishingIncRepairDuringPreview() throws IOException, InterruptedException, ExecutionException {
    ExecutorService es = Executors.newSingleThreadExecutor();
    try (Cluster cluster = init(Cluster.build(2).withConfig(config -> config.with(GOSSIP).with(NETWORK)).start())) {
        cluster.schemaChange("create table " + KEYSPACE + ".tbl (id int primary key, t int)");
        insert(cluster.coordinator(1), 0, 100);
        cluster.forEach((node) -> node.flush(KEYSPACE));
        cluster.get(1).callOnInstance(repair(options(false, false)));
        insert(cluster.coordinator(1), 100, 100);
        cluster.forEach((node) -> node.flush(KEYSPACE));
        Condition previewRepairStarted = newOneTimeCondition();
        Condition continuePreviewRepair = newOneTimeCondition();
        DelayFirstRepairTypeMessageFilter filter = validationRequest(previewRepairStarted, continuePreviewRepair);
        // this pauses the validation request sent from node1 to node2 until we have run a full inc repair below
        cluster.filters().outbound().verbs(VALIDATION_REQ.id).from(1).to(2).messagesMatching(filter).drop();
        Future<RepairResult> rsFuture = es.submit(() -> cluster.get(1).callOnInstance(repair(options(true, false))));
        previewRepairStarted.await();
        // this needs to finish before the preview repair is unpaused on node2
        cluster.get(1).callOnInstance(repair(options(false, false)));
        continuePreviewRepair.signalAll();
        RepairResult rs = rsFuture.get();
        // preview repair should have failed
        assertFalse(rs.success);
        // and no mismatches should have been reported
        assertFalse(rs.wasInconsistent);
    } finally {
        es.shutdown();
    }
}
Also used : Condition.newOneTimeCondition(org.apache.cassandra.utils.concurrent.Condition.newOneTimeCondition) Condition(org.apache.cassandra.utils.concurrent.Condition) ExecutorService(java.util.concurrent.ExecutorService) Cluster(org.apache.cassandra.distributed.Cluster) RepairResult(org.apache.cassandra.distributed.shared.RepairResult) Test(org.junit.Test)

Example 62 with Cluster

use of org.apache.cassandra.distributed.Cluster in project cassandra by apache.

the class ReadDigestConsistencyTest method testDigestConsistency.

@Test
public void testDigestConsistency() throws Exception {
    try (Cluster cluster = init(builder().withNodes(2).start())) {
        cluster.schemaChange(CREATE_TABLE);
        insertData(cluster.coordinator(1));
        testDigestConsistency(cluster.coordinator(1));
        testDigestConsistency(cluster.coordinator(2));
    }
}
Also used : Cluster(org.apache.cassandra.distributed.Cluster) Test(org.junit.Test)

Example 63 with Cluster

use of org.apache.cassandra.distributed.Cluster in project cassandra by apache.

the class ReadRepairTest method testRangeSliceQueryWithTombstones.

/**
 * Verify that range queries with CL>ONE don't do unnecessary read-repairs when there are tombstones.
 * <p>
 * See CASSANDRA-8989 and CASSANDRA-9502.
 * <p>
 * Migrated from Python dtest read_repair_test.py:TestReadRepair.test_range_slice_query_with_tombstones()
 */
private void testRangeSliceQueryWithTombstones(boolean flush) throws Throwable {
    try (Cluster cluster = init(Cluster.create(2))) {
        cluster.schemaChange(withKeyspace("CREATE TABLE %s.t (k int, c int, v int, PRIMARY KEY(k, c))"));
        ICoordinator coordinator = cluster.coordinator(1);
        // insert some rows in all nodes
        String insertQuery = withKeyspace("INSERT INTO %s.t (k, c, v) VALUES (?, ?, ?)");
        for (int k = 0; k < 10; k++) {
            for (int c = 0; c < 10; c++) coordinator.execute(insertQuery, ALL, k, c, k * c);
        }
        // delete a subset of the inserted partitions, plus some others that don't exist
        String deletePartitionQuery = withKeyspace("DELETE FROM %s.t WHERE k = ?");
        for (int k = 5; k < 15; k++) {
            coordinator.execute(deletePartitionQuery, ALL, k);
        }
        // delete some of the rows of some of the partitions, including deleted and not deleted partitions
        String deleteRowQuery = withKeyspace("DELETE FROM %s.t WHERE k = ? AND c = ?");
        for (int k = 2; k < 7; k++) {
            for (int c = 0; c < 5; c++) coordinator.execute(deleteRowQuery, ALL, k, c);
        }
        // delete some of the rows of some not-existent partitions, including deleted and never-written partitions
        for (int k = 12; k < 17; k++) {
            for (int c = 0; c < 5; c++) coordinator.execute(deleteRowQuery, ALL, k, c);
        }
        // flush all the nodes if specified
        if (flush) {
            for (int n = 1; n <= cluster.size(); n++) cluster.get(n).flush(KEYSPACE);
        }
        // run a bunch of queries verifying that they don't trigger read repair
        coordinator.execute(withKeyspace("SELECT * FROM %s.t LIMIT 100"), QUORUM);
        for (int k = 0; k < 15; k++) {
            coordinator.execute(withKeyspace("SELECT * FROM %s.t WHERE k=?"), QUORUM, k);
            for (int c = 0; c < 10; c++) {
                coordinator.execute(withKeyspace("SELECT * FROM %s.t WHERE k=? AND c=?"), QUORUM, k, c);
                coordinator.execute(withKeyspace("SELECT * FROM %s.t WHERE k=? AND c>?"), QUORUM, k, c);
                coordinator.execute(withKeyspace("SELECT * FROM %s.t WHERE k=? AND c<?"), QUORUM, k, c);
            }
        }
        long requests = ReadRepairTester.readRepairRequestsCount(cluster.get(1), "t");
        assertEquals("No read repair requests were expected, found " + requests, 0, requests);
    }
}
Also used : ICoordinator(org.apache.cassandra.distributed.api.ICoordinator) Cluster(org.apache.cassandra.distributed.Cluster)

Example 64 with Cluster

use of org.apache.cassandra.distributed.Cluster in project cassandra by apache.

the class ReadRepairTest method alterRFAndRunReadRepair.

/**
 * Test that there is no read repair with RF=1, and that altering it to RF>1 doesn't trigger any repair by
 * itself but following queries will use read repair accordingly with the new RF.
 */
@Test
public void alterRFAndRunReadRepair() throws Throwable {
    try (Cluster cluster = builder().withNodes(2).start()) {
        cluster.schemaChange(withKeyspace("CREATE KEYSPACE %s WITH replication = " + "{'class': 'SimpleStrategy', 'replication_factor': 1}"));
        cluster.schemaChange(withKeyspace("CREATE TABLE %s.t (k int PRIMARY KEY, a int, b int)" + " WITH read_repair='blocking'"));
        // insert a row that will only get to one node due to the RF=1
        Object[] row = row(1, 1, 1);
        cluster.get(1).executeInternal(withKeyspace("INSERT INTO %s.t (k, a, b) VALUES (?, ?, ?)"), row);
        // flush to ensure reads come from sstables
        cluster.get(1).flush(KEYSPACE);
        // at RF=1 it shouldn't matter which node we query, as the data should always come from the only replica
        String query = withKeyspace("SELECT * FROM %s.t WHERE k = 1");
        for (int i = 1; i <= cluster.size(); i++) assertRows(cluster.coordinator(i).execute(query, ALL), row);
        // at RF=1 the prevoius queries shouldn't have triggered read repair
        assertRows(cluster.get(1).executeInternal(query), row);
        assertRows(cluster.get(2).executeInternal(query));
        // alter RF
        System.setProperty(Config.PROPERTY_PREFIX + "allow_alter_rf_during_range_movement", "true");
        cluster.schemaChange(withKeyspace("ALTER KEYSPACE %s WITH replication = " + "{'class': 'SimpleStrategy', 'replication_factor': 2}"));
        // altering the RF shouldn't have triggered any read repair
        assertRows(cluster.get(1).executeInternal(query), row);
        assertRows(cluster.get(2).executeInternal(query));
        // query again at CL=ALL, this time the data should be repaired
        assertRows(cluster.coordinator(2).execute(query, ALL), row);
        assertRows(cluster.get(1).executeInternal(query), row);
        assertRows(cluster.get(2).executeInternal(query), row);
    }
}
Also used : Cluster(org.apache.cassandra.distributed.Cluster) Test(org.junit.Test)

Example 65 with Cluster

use of org.apache.cassandra.distributed.Cluster in project cassandra by apache.

the class ReadRepairTest method movingTokenReadRepairTest.

@Test
public void movingTokenReadRepairTest() throws Throwable {
    try (Cluster cluster = init(Cluster.create(4), 3)) {
        List<Token> tokens = cluster.tokens();
        cluster.schemaChange("CREATE TABLE " + KEYSPACE + ".tbl (pk int, ck int, v int, PRIMARY KEY (pk, ck)) WITH read_repair='blocking'");
        int i = 0;
        while (true) {
            Token t = Murmur3Partitioner.instance.getToken(Int32Type.instance.decompose(i));
            // the list of tokens uses zero-based numbering, whereas the cluster nodes use one-based numbering
            if (t.compareTo(tokens.get(2 - 1)) < 0 && t.compareTo(tokens.get(1 - 1)) > 0)
                break;
            ++i;
        }
        // write only to #4
        cluster.get(4).executeInternal("INSERT INTO " + KEYSPACE + ".tbl (pk, ck, v) VALUES (?, 1, 1)", i);
        // mark #2 as leaving in #4
        cluster.get(4).acceptsOnInstance((InetSocketAddress endpoint) -> {
            StorageService.instance.getTokenMetadata().addLeavingEndpoint(InetAddressAndPort.getByAddressOverrideDefaults(endpoint.getAddress(), endpoint.getPort()));
            PendingRangeCalculatorService.instance.update();
            PendingRangeCalculatorService.instance.blockUntilFinished();
        }).accept(cluster.get(2).broadcastAddress());
        // prevent #4 from reading or writing to #3, so our QUORUM must contain #2 and #4
        // since #1 is taking over the range, this means any read-repair must make it to #1 as well
        // (as a speculative repair in this case, as we prefer to send repair mutations to the initial
        // set of read replicas, which are 2 and 3 here).
        cluster.filters().verbs(READ_REQ.id).from(4).to(3).drop();
        cluster.filters().verbs(READ_REPAIR_REQ.id).from(4).to(3).drop();
        assertRows(cluster.coordinator(4).execute("SELECT * FROM " + KEYSPACE + ".tbl WHERE pk = ?", ConsistencyLevel.QUORUM, i), row(i, 1, 1));
        // verify that #1 receives the write
        assertRows(cluster.get(1).executeInternal("SELECT * FROM " + KEYSPACE + ".tbl WHERE pk = ?", i), row(i, 1, 1));
    }
}
Also used : InetSocketAddress(java.net.InetSocketAddress) Cluster(org.apache.cassandra.distributed.Cluster) Token(org.apache.cassandra.dht.Token) Test(org.junit.Test)

Aggregations

Cluster (org.apache.cassandra.distributed.Cluster)161 Test (org.junit.Test)151 IInvokableInstance (org.apache.cassandra.distributed.api.IInvokableInstance)37 Assert (org.junit.Assert)37 IOException (java.io.IOException)36 Feature (org.apache.cassandra.distributed.api.Feature)34 GOSSIP (org.apache.cassandra.distributed.api.Feature.GOSSIP)30 NETWORK (org.apache.cassandra.distributed.api.Feature.NETWORK)30 ConsistencyLevel (org.apache.cassandra.distributed.api.ConsistencyLevel)29 List (java.util.List)22 ImmutableMap (com.google.common.collect.ImmutableMap)21 InetAddress (java.net.InetAddress)20 TokenSupplier (org.apache.cassandra.distributed.api.TokenSupplier)20 StorageService (org.apache.cassandra.service.StorageService)18 Arrays (java.util.Arrays)17 Collections (java.util.Collections)17 Assertions (org.assertj.core.api.Assertions)17 Map (java.util.Map)16 TestBaseImpl (org.apache.cassandra.distributed.test.TestBaseImpl)15 ICoordinator (org.apache.cassandra.distributed.api.ICoordinator)14