You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sa...@apache.org on 2015/10/28 18:30:42 UTC

[2/3] cassandra git commit: On CFS::reload, execute the reload task for each secondary index

On CFS::reload, execute the reload task for each secondary index

Patch by Sam Tunnicliffe; reviewed by Tyler Hobbs for CASSANDRA-10604


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/8210075c
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/8210075c
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/8210075c

Branch: refs/heads/trunk
Commit: 8210075c57af696e78000e8cd0019737b2373875
Parents: 5034f44
Author: Sam Tunnicliffe <sa...@beobal.com>
Authored: Wed Oct 28 13:16:15 2015 +0000
Committer: Sam Tunnicliffe <sa...@beobal.com>
Committed: Wed Oct 28 17:23:57 2015 +0000

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 src/java/org/apache/cassandra/index/Index.java  | 11 ++++++
 .../cassandra/index/SecondaryIndexManager.java  | 16 +++-----
 .../index/internal/CassandraIndex.java          |  1 -
 .../apache/cassandra/index/CustomIndexTest.java | 40 ++++++++++++++++++++
 .../index/internal/CassandraIndexTest.java      |  9 +++++
 6 files changed, 66 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/8210075c/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 4ead854..c945bd2 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 3.0
+ * Execute the metadata reload task of all registered indexes on CFS::reload (CASSANDRA-10604)
  * Fix thrift cas operations with defined columns (CASSANDRA-10576)
  * Fix PartitionUpdate.operationCount()for updates with static column operations (CASSANDRA-10606)
  * Fix thrift get() queries with defined columns (CASSANDRA-10586)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8210075c/src/java/org/apache/cassandra/index/Index.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/index/Index.java b/src/java/org/apache/cassandra/index/Index.java
index 0f4ecbd..b6c12a9 100644
--- a/src/java/org/apache/cassandra/index/Index.java
+++ b/src/java/org/apache/cassandra/index/Index.java
@@ -296,9 +296,20 @@ public interface Index
      * Listener for processing events emitted during a single partition update.
      * Instances of this are responsible for applying modifications to the index in response to a single update
      * operation on a particular partition of the base table.
+     *
      * That update may be generated by the normal write path, by iterating SSTables during streaming operations or when
      * building or rebuilding an index from source. Updates also occur during compaction when multiple versions of a
      * source partition from different SSTables are merged.
+     *
+     * Implementations should not make assumptions about resolution or filtering of the partition update being
+     * processed. That is to say that it is possible for an Indexer instance to receive notification of a
+     * PartitionDelete or RangeTombstones which shadow a Row it then receives via insertRow/updateRow.
+     *
+     * It is important to note that the only ordering guarantee made for the methods here is that the first call will
+     * be to begin() and the last call to finish(). The other methods may be called to process update events in any
+     * order. This can also include duplicate calls, in cases where a memtable partition is under contention from
+     * several updates. In that scenario, the same set of events may be delivered to the Indexer as memtable update
+     * which failed due to contention is re-applied.
      */
     public interface Indexer
     {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8210075c/src/java/org/apache/cassandra/index/SecondaryIndexManager.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/index/SecondaryIndexManager.java b/src/java/org/apache/cassandra/index/SecondaryIndexManager.java
index 3ed9714..92b04fe 100644
--- a/src/java/org/apache/cassandra/index/SecondaryIndexManager.java
+++ b/src/java/org/apache/cassandra/index/SecondaryIndexManager.java
@@ -142,17 +142,11 @@ public class SecondaryIndexManager implements IndexRegistry
 
     private Future<?> reloadIndex(IndexMetadata indexDef)
     {
-        // if the index metadata has changed, reload the index
-        IndexMetadata registered = indexes.get(indexDef.name).getIndexMetadata();
-        if (!registered.equals(indexDef))
-        {
-            Index index = indexes.remove(registered.name);
-            index.register(this);
-            return blockingExecutor.submit(index.getMetadataReloadTask(indexDef));
-        }
-
-        // otherwise, nothing to do
-        return Futures.immediateFuture(null);
+        Index index = indexes.get(indexDef.name);
+        Callable<?> reloadTask = index.getMetadataReloadTask(indexDef);
+        return reloadTask == null
+               ? Futures.immediateFuture(null)
+               : blockingExecutor.submit(index.getMetadataReloadTask(indexDef));
     }
 
     private Future<?> createIndex(IndexMetadata indexDef)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8210075c/src/java/org/apache/cassandra/index/internal/CassandraIndex.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/index/internal/CassandraIndex.java b/src/java/org/apache/cassandra/index/internal/CassandraIndex.java
index 5b5b7e4..674cd20 100644
--- a/src/java/org/apache/cassandra/index/internal/CassandraIndex.java
+++ b/src/java/org/apache/cassandra/index/internal/CassandraIndex.java
@@ -183,7 +183,6 @@ public abstract class CassandraIndex implements Index
 
     public Callable<?> getMetadataReloadTask(IndexMetadata indexDef)
     {
-        setMetadata(indexDef);
         return () -> {
             indexCfs.metadata.reloadIndexMetadataProperties(baseCfs.metadata);
             indexCfs.reload();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8210075c/test/unit/org/apache/cassandra/index/CustomIndexTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/index/CustomIndexTest.java b/test/unit/org/apache/cassandra/index/CustomIndexTest.java
index b2c9257..b372c59 100644
--- a/test/unit/org/apache/cassandra/index/CustomIndexTest.java
+++ b/test/unit/org/apache/cassandra/index/CustomIndexTest.java
@@ -1,6 +1,8 @@
 package org.apache.cassandra.index;
 
 import java.util.*;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
 import com.google.common.collect.ImmutableList;
@@ -452,6 +454,23 @@ public class CustomIndexTest extends CQLTester
                              "SELECT * FROM %s WHERE expr(int_index, 'foo')");
     }
 
+    @Test
+    public void reloadIndexMetadataOnBaseCfsReload() throws Throwable
+    {
+        // verify that whenever the base table CFMetadata is reloaded, a reload of the index
+        // metadata is performed
+        createTable("CREATE TABLE %s (k int, v1 int, PRIMARY KEY(k))");
+        createIndex(String.format("CREATE CUSTOM INDEX reload_counter ON %%s() USING '%s'",
+                                  CountMetadataReloadsIndex.class.getName()));
+        ColumnFamilyStore cfs = getCurrentColumnFamilyStore();
+        CountMetadataReloadsIndex index = (CountMetadataReloadsIndex)cfs.indexManager.getIndexByName("reload_counter");
+        assertEquals(0, index.reloads.get());
+
+        // reloading the CFS, even without any metadata changes invokes the index's metadata reload task
+        cfs.reload();
+        assertEquals(1, index.reloads.get());
+    }
+
     private void testCreateIndex(String indexName, String... targetColumnNames) throws Throwable
     {
         createIndex(String.format("CREATE CUSTOM INDEX %s ON %%s(%s) USING '%s'",
@@ -495,6 +514,27 @@ public class CustomIndexTest extends CQLTester
         return new IndexTarget(ColumnIdentifier.getInterned(name, true), type);
     }
 
+    public static final class CountMetadataReloadsIndex extends StubIndex
+    {
+        private final AtomicInteger reloads = new AtomicInteger(0);
+
+        public CountMetadataReloadsIndex(ColumnFamilyStore baseCfs, IndexMetadata metadata)
+        {
+            super(baseCfs, metadata);
+        }
+
+        public void reset()
+        {
+            super.reset();
+            reloads.set(0);
+        }
+
+        public Callable<?> getMetadataReloadTask(IndexMetadata indexMetadata)
+        {
+            return reloads::incrementAndGet;
+        }
+    }
+
     public static final class IndexIncludedInBuild extends StubIndex
     {
         public IndexIncludedInBuild(ColumnFamilyStore baseCfs, IndexMetadata metadata)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8210075c/test/unit/org/apache/cassandra/index/internal/CassandraIndexTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/index/internal/CassandraIndexTest.java b/test/unit/org/apache/cassandra/index/internal/CassandraIndexTest.java
index 2ca858d..934e551 100644
--- a/test/unit/org/apache/cassandra/index/internal/CassandraIndexTest.java
+++ b/test/unit/org/apache/cassandra/index/internal/CassandraIndexTest.java
@@ -639,9 +639,18 @@ public class CassandraIndexTest extends CQLTester
             assertRows(execute(selectFirstRowCql), firstRow);
             assertEmpty(execute(selectSecondRowCql));
 
+            // reload the base cfs and verify queries still work as expected
+            getCurrentColumnFamilyStore().reload();
+            assertRows(execute(selectFirstRowCql), firstRow);
+            assertEmpty(execute(selectSecondRowCql));
+
             // drop the index and assert we can no longer query using it
             execute(dropIndexCql);
             assertInvalidThrowMessage(missingIndexMessage, InvalidRequestException.class, selectFirstRowCql);
+            // reload the base cfs and verify again
+            getCurrentColumnFamilyStore().reload();
+            assertInvalidThrowMessage(missingIndexMessage, InvalidRequestException.class, selectFirstRowCql);
+
             flush();
             compact();