Search in sources :

Example 1 with SSTableAddedNotification

use of org.apache.cassandra.notifications.SSTableAddedNotification in project cassandra by apache.

the class LeveledCompactionStrategyTest method testNewRepairedSSTable.

@Test
public void testNewRepairedSSTable() throws Exception {
    byte[] b = new byte[100 * 1024];
    new Random().nextBytes(b);
    // 100 KiB value, make it easy to have multiple files
    ByteBuffer value = ByteBuffer.wrap(b);
    // Enough data to have a level 1 and 2
    int rows = 40;
    int columns = 20;
    // Adds enough data to trigger multiple sstable per level
    for (int r = 0; r < rows; r++) {
        UpdateBuilder update = UpdateBuilder.create(cfs.metadata(), String.valueOf(r));
        for (int c = 0; c < columns; c++) update.newRow("column" + c).add("val", value);
        update.applyUnsafe();
        cfs.forceBlockingFlush();
    }
    waitForLeveling(cfs);
    cfs.disableAutoCompaction();
    while (CompactionManager.instance.isCompacting(Arrays.asList(cfs), (sstable) -> true)) Thread.sleep(100);
    CompactionStrategyManager manager = cfs.getCompactionStrategyManager();
    List<List<AbstractCompactionStrategy>> strategies = manager.getStrategies();
    LeveledCompactionStrategy repaired = (LeveledCompactionStrategy) strategies.get(0).get(0);
    LeveledCompactionStrategy unrepaired = (LeveledCompactionStrategy) strategies.get(1).get(0);
    assertEquals(0, repaired.manifest.getLevelCount());
    assertEquals(2, unrepaired.manifest.getLevelCount());
    assertTrue(manager.getSSTableCountPerLevel()[1] > 0);
    assertTrue(manager.getSSTableCountPerLevel()[2] > 0);
    for (SSTableReader sstable : cfs.getLiveSSTables()) assertFalse(sstable.isRepaired());
    int sstableCount = unrepaired.manifest.getSSTables().size();
    // we only have unrepaired sstables:
    assertEquals(sstableCount, cfs.getLiveSSTables().size());
    SSTableReader sstable1 = unrepaired.manifest.getLevel(2).iterator().next();
    SSTableReader sstable2 = unrepaired.manifest.getLevel(1).iterator().next();
    sstable1.descriptor.getMetadataSerializer().mutateRepairMetadata(sstable1.descriptor, System.currentTimeMillis(), null, false);
    sstable1.reloadSSTableMetadata();
    assertTrue(sstable1.isRepaired());
    manager.handleNotification(new SSTableRepairStatusChanged(Arrays.asList(sstable1)), this);
    int repairedSSTableCount = repaired.manifest.getSSTables().size();
    assertEquals(1, repairedSSTableCount);
    // make sure the repaired sstable ends up in the same level in the repaired manifest:
    assertTrue(repaired.manifest.getLevel(2).contains(sstable1));
    // and that it is gone from unrepaired
    assertFalse(unrepaired.manifest.getLevel(2).contains(sstable1));
    unrepaired.removeSSTable(sstable2);
    manager.handleNotification(new SSTableAddedNotification(singleton(sstable2), null), this);
    assertTrue(unrepaired.manifest.getLevel(1).contains(sstable2));
    assertFalse(repaired.manifest.getLevel(1).contains(sstable2));
}
Also used : SSTableReader(org.apache.cassandra.io.sstable.format.SSTableReader) SSTableRepairStatusChanged(org.apache.cassandra.notifications.SSTableRepairStatusChanged) Random(java.util.Random) UpdateBuilder(org.apache.cassandra.UpdateBuilder) List(java.util.List) ArrayList(java.util.ArrayList) SSTableAddedNotification(org.apache.cassandra.notifications.SSTableAddedNotification) ByteBuffer(java.nio.ByteBuffer) Test(org.junit.Test)

Example 2 with SSTableAddedNotification

use of org.apache.cassandra.notifications.SSTableAddedNotification in project cassandra by apache.

the class SecondaryIndexManagerTest method addingSSTablesMarksTheIndexAsBuilt.

@Test
public void addingSSTablesMarksTheIndexAsBuilt() throws Throwable {
    String tableName = createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
    String indexName = createIndex("CREATE INDEX ON %s(c)");
    waitForIndex(KEYSPACE, tableName, indexName);
    assertMarkedAsBuilt(indexName);
    ColumnFamilyStore cfs = getCurrentColumnFamilyStore();
    cfs.indexManager.markAllIndexesRemoved();
    assertNotMarkedAsBuilt(indexName);
    try (Refs<SSTableReader> sstables = Refs.ref(cfs.getSSTables(SSTableSet.CANONICAL))) {
        cfs.indexManager.handleNotification(new SSTableAddedNotification(sstables, null), cfs.getTracker());
        assertMarkedAsBuilt(indexName);
    }
}
Also used : SSTableReader(org.apache.cassandra.io.sstable.format.SSTableReader) ColumnFamilyStore(org.apache.cassandra.db.ColumnFamilyStore) SSTableAddedNotification(org.apache.cassandra.notifications.SSTableAddedNotification) Test(org.junit.Test)

Example 3 with SSTableAddedNotification

use of org.apache.cassandra.notifications.SSTableAddedNotification in project cassandra by apache.

the class SecondaryIndexManagerTest method cannotRebuildWhileAnSSTableBuildIsInProgress.

@Test
public void cannotRebuildWhileAnSSTableBuildIsInProgress() throws Throwable {
    final String tableName = createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
    final String indexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
    final AtomicBoolean error = new AtomicBoolean();
    // wait for index initialization and verify it's built:
    waitForIndex(KEYSPACE, tableName, indexName);
    assertMarkedAsBuilt(indexName);
    // add sstables in another thread, but make it block:
    TestingIndex.blockBuild();
    Thread asyncBuild = new Thread(() -> {
        ColumnFamilyStore cfs = getCurrentColumnFamilyStore();
        try (Refs<SSTableReader> sstables = Refs.ref(cfs.getSSTables(SSTableSet.CANONICAL))) {
            cfs.indexManager.handleNotification(new SSTableAddedNotification(sstables, null), cfs.getTracker());
        } catch (Throwable ex) {
            error.set(true);
        }
    });
    asyncBuild.start();
    // wait for the build to block, so that we can proceed unblocking all further operations:
    TestingIndex.waitBlockedOnBuild();
    // do not block further builds:
    TestingIndex.shouldBlockBuild = false;
    // verify rebuilding the index before the previous index build task has finished fails
    assertFalse(tryRebuild(indexName, false));
    assertNotMarkedAsBuilt(indexName);
    // check that the index is marked as built when the build finishes
    TestingIndex.unblockBuild();
    asyncBuild.join();
    assertMarkedAsBuilt(indexName);
    // now verify you can rebuild
    assertTrue(tryRebuild(indexName, false));
    assertMarkedAsBuilt(indexName);
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) SSTableReader(org.apache.cassandra.io.sstable.format.SSTableReader) ColumnFamilyStore(org.apache.cassandra.db.ColumnFamilyStore) SSTableAddedNotification(org.apache.cassandra.notifications.SSTableAddedNotification) Test(org.junit.Test)

Example 4 with SSTableAddedNotification

use of org.apache.cassandra.notifications.SSTableAddedNotification in project cassandra by apache.

the class SecondaryIndexManagerTest method initializingIndexNotQueryableButMaybeNotWritableAfterPartialRebuild.

@Test
public void initializingIndexNotQueryableButMaybeNotWritableAfterPartialRebuild() throws Throwable {
    TestingIndex.blockCreate();
    String tableName = createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
    String defaultIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
    String readOnlyIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", ReadOnlyOnFailureIndex.class.getName()));
    String writeOnlyIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", WriteOnlyOnFailureIndex.class.getName()));
    // the index should never be queryable while the initialization hasn't finished
    assertFalse(isQueryable(defaultIndexName));
    assertFalse(isQueryable(readOnlyIndexName));
    assertFalse(isQueryable(writeOnlyIndexName));
    // the index should always we writable while the initialization hasn't finished
    assertTrue(isWritable(defaultIndexName));
    assertTrue(isWritable(readOnlyIndexName));
    assertTrue(isWritable(writeOnlyIndexName));
    // a failing partial build doesn't set the index as queryable, but might set it as not writable
    TestingIndex.shouldFailBuild = true;
    ColumnFamilyStore cfs = getCurrentColumnFamilyStore();
    try {
        cfs.indexManager.handleNotification(new SSTableAddedNotification(cfs.getLiveSSTables(), null), this);
        fail("Should have failed!");
    } catch (Throwable ex) {
        assertTrue(ex.getMessage().contains("configured to fail"));
    }
    assertFalse(isQueryable(defaultIndexName));
    assertFalse(isQueryable(readOnlyIndexName));
    assertFalse(isQueryable(writeOnlyIndexName));
    assertTrue(isWritable(defaultIndexName));
    assertFalse(isWritable(readOnlyIndexName));
    assertTrue(isWritable(writeOnlyIndexName));
    // a successful partial build doesn't set the index as queryable nor writable
    TestingIndex.shouldFailBuild = false;
    cfs.indexManager.handleNotification(new SSTableAddedNotification(cfs.getLiveSSTables(), null), this);
    assertFalse(isQueryable(defaultIndexName));
    assertFalse(isQueryable(readOnlyIndexName));
    assertFalse(isQueryable(writeOnlyIndexName));
    assertTrue(isWritable(defaultIndexName));
    assertFalse(isWritable(readOnlyIndexName));
    assertTrue(isWritable(writeOnlyIndexName));
    // the index should be queryable once the initialization has finished
    TestingIndex.unblockCreate();
    waitForIndex(KEYSPACE, tableName, defaultIndexName);
    assertTrue(isQueryable(defaultIndexName));
    assertTrue(isQueryable(readOnlyIndexName));
    assertTrue(isQueryable(writeOnlyIndexName));
    assertTrue(isWritable(defaultIndexName));
    assertTrue(isWritable(readOnlyIndexName));
    assertTrue(isWritable(writeOnlyIndexName));
}
Also used : ColumnFamilyStore(org.apache.cassandra.db.ColumnFamilyStore) SSTableAddedNotification(org.apache.cassandra.notifications.SSTableAddedNotification) Test(org.junit.Test)

Example 5 with SSTableAddedNotification

use of org.apache.cassandra.notifications.SSTableAddedNotification in project cassandra by apache.

the class SecondaryIndexManagerTest method addingSSTableWithBuildFailureWhileRebuildIsInProgress.

@Test
public void addingSSTableWithBuildFailureWhileRebuildIsInProgress() throws Throwable {
    final String tableName = createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
    final String indexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
    final AtomicBoolean error = new AtomicBoolean();
    // wait for index initialization and verify it's built:
    waitForIndex(KEYSPACE, tableName, indexName);
    assertMarkedAsBuilt(indexName);
    // rebuild the index in another thread, but make it block:
    TestingIndex.blockBuild();
    Thread asyncBuild = new Thread(() -> {
        try {
            tryRebuild(indexName, false);
        } catch (Throwable ex) {
            error.set(true);
        }
    });
    asyncBuild.start();
    // wait for the rebuild to block, so that we can proceed unblocking all further operations:
    TestingIndex.waitBlockedOnBuild();
    // do not block further builds:
    TestingIndex.shouldBlockBuild = false;
    // try adding sstables but make the build fail:
    TestingIndex.shouldFailBuild = true;
    ColumnFamilyStore cfs = getCurrentColumnFamilyStore();
    try (Refs<SSTableReader> sstables = Refs.ref(cfs.getSSTables(SSTableSet.CANONICAL))) {
        cfs.indexManager.handleNotification(new SSTableAddedNotification(sstables, null), cfs.getTracker());
        fail("Should have failed!");
    } catch (Throwable ex) {
        assertTrue(ex.getMessage().contains("configured to fail"));
    }
    // disable failures:
    TestingIndex.shouldFailBuild = false;
    // unblock the pending build:
    TestingIndex.unblockBuild();
    asyncBuild.join();
    // verify the index is *not* built due to the failing sstable build:
    assertNotMarkedAsBuilt(indexName);
    assertFalse(error.get());
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) SSTableReader(org.apache.cassandra.io.sstable.format.SSTableReader) ColumnFamilyStore(org.apache.cassandra.db.ColumnFamilyStore) SSTableAddedNotification(org.apache.cassandra.notifications.SSTableAddedNotification) Test(org.junit.Test)

Aggregations

SSTableAddedNotification (org.apache.cassandra.notifications.SSTableAddedNotification)18 Test (org.junit.Test)14 SSTableReader (org.apache.cassandra.io.sstable.format.SSTableReader)13 UUID (java.util.UUID)7 ColumnFamilyStore (org.apache.cassandra.db.ColumnFamilyStore)6 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)3 SSTableDeletingNotification (org.apache.cassandra.notifications.SSTableDeletingNotification)3 List (java.util.List)2 SSTableListChangedNotification (org.apache.cassandra.notifications.SSTableListChangedNotification)2 SSTableRepairStatusChanged (org.apache.cassandra.notifications.SSTableRepairStatusChanged)2 ByteBuffer (java.nio.ByteBuffer)1 ArrayList (java.util.ArrayList)1 Random (java.util.Random)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 UpdateBuilder (org.apache.cassandra.UpdateBuilder)1 INotification (org.apache.cassandra.notifications.INotification)1 INotificationConsumer (org.apache.cassandra.notifications.INotificationConsumer)1 SSTableMetadataChanged (org.apache.cassandra.notifications.SSTableMetadataChanged)1