Repository: cassandra Updated Branches: refs/heads/trunk 5f37e9fa5 -> feb30e21c
Fix saving caches when a table is dropped patch by Aleksey Yeschenko; reviewed by Benedict Elliott Smith for CASSANDRA-7784 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/e25d94e6 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/e25d94e6 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/e25d94e6 Branch: refs/heads/trunk Commit: e25d94e6e9f2f18efa7cfb8c7ed02e826b413984 Parents: 4efb6dc Author: Aleksey Yeschenko <alek...@apache.org> Authored: Tue Sep 16 00:30:21 2014 -0700 Committer: Aleksey Yeschenko <alek...@apache.org> Committed: Tue Sep 16 00:34:01 2014 -0700 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../apache/cassandra/cache/AutoSavingCache.java | 37 ++++++++++++------- .../org/apache/cassandra/cache/CacheKey.java | 38 ++------------------ .../apache/cassandra/cache/CounterCacheKey.java | 6 ++-- .../org/apache/cassandra/cache/KeyCacheKey.java | 4 +-- .../org/apache/cassandra/cache/RowCacheKey.java | 7 ++-- .../org/apache/cassandra/config/Schema.java | 9 +++++ 7 files changed, 43 insertions(+), 59 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/e25d94e6/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 8fe4253..f89cc6d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 2.1.1 + * Fix saving caches when a table is dropped (CASSANDRA-7784) * Add better error checking of new stress profile (CASSANDRA-7716) * Use ThreadLocalRandom and remove FBUtilities.threadLocalRandom (CASSANDRA-7934) * Prevent operator mistakes due to simultaneous bootstrap (CASSANDRA-7069) http://git-wip-us.apache.org/repos/asf/cassandra/blob/e25d94e6/src/java/org/apache/cassandra/cache/AutoSavingCache.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cache/AutoSavingCache.java b/src/java/org/apache/cassandra/cache/AutoSavingCache.java index affd69b..d8fd5e0 100644 --- a/src/java/org/apache/cassandra/cache/AutoSavingCache.java +++ b/src/java/org/apache/cassandra/cache/AutoSavingCache.java @@ -29,6 +29,7 @@ import org.slf4j.LoggerFactory; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.DatabaseDescriptor; +import org.apache.cassandra.config.Schema; import org.apache.cassandra.db.compaction.CompactionInfo; import org.apache.cassandra.db.compaction.CompactionManager; import org.apache.cassandra.db.compaction.OperationType; @@ -64,11 +65,18 @@ public class AutoSavingCache<K extends CacheKey, V> extends InstrumentingCache<K this.cacheLoader = cacheloader; } + @Deprecated public File getCachePath(String ksName, String cfName, UUID cfId, String version) { return DatabaseDescriptor.getSerializedCachePath(ksName, cfName, cfId, cacheType, version); } + public File getCachePath(UUID cfId, String version) + { + Pair<String, String> names = Schema.instance.getCF(cfId); + return DatabaseDescriptor.getSerializedCachePath(names.left, names.right, cfId, cacheType, version); + } + public Writer getWriter(int keysToSave) { return new Writer(keysToSave); @@ -103,7 +111,7 @@ public class AutoSavingCache<K extends CacheKey, V> extends InstrumentingCache<K long start = System.nanoTime(); // modern format, allows both key and value (so key cache load can be purely sequential) - File path = getCachePath(cfs.keyspace.getName(), cfs.name, cfs.metadata.cfId, CURRENT_VERSION); + File path = getCachePath(cfs.metadata.cfId, CURRENT_VERSION); // if path does not exist, try without cfId (assuming saved cache is created with current CF) if (!path.exists()) path = getCachePath(cfs.keyspace.getName(), cfs.name, null, CURRENT_VERSION); @@ -206,18 +214,21 @@ public class AutoSavingCache<K extends CacheKey, V> extends InstrumentingCache<K long start = System.nanoTime(); - HashMap<CacheKey.PathInfo, SequentialWriter> writers = new HashMap<>(); + HashMap<UUID, SequentialWriter> writers = new HashMap<>(); try { for (K key : keys) { - CacheKey.PathInfo path = key.getPathInfo(); - SequentialWriter writer = writers.get(path); + UUID cfId = key.getCFId(); + if (!Schema.instance.hasCF(key.getCFId())) + continue; // the table has been dropped. + + SequentialWriter writer = writers.get(cfId); if (writer == null) { - writer = tempCacheFile(path); - writers.put(path, writer); + writer = tempCacheFile(cfId); + writers.put(cfId, writer); } try @@ -238,13 +249,13 @@ public class AutoSavingCache<K extends CacheKey, V> extends InstrumentingCache<K FileUtils.closeQuietly(writer); } - for (Map.Entry<CacheKey.PathInfo, SequentialWriter> info : writers.entrySet()) + for (Map.Entry<UUID, SequentialWriter> entry : writers.entrySet()) { - CacheKey.PathInfo path = info.getKey(); - SequentialWriter writer = info.getValue(); + UUID cfId = entry.getKey(); + SequentialWriter writer = entry.getValue(); File tmpFile = new File(writer.getPath()); - File cacheFile = getCachePath(path.keyspace, path.columnFamily, path.cfId, CURRENT_VERSION); + File cacheFile = getCachePath(cfId, CURRENT_VERSION); cacheFile.delete(); // ignore error if it didn't exist if (!tmpFile.renameTo(cacheFile)) @@ -254,9 +265,9 @@ public class AutoSavingCache<K extends CacheKey, V> extends InstrumentingCache<K logger.info("Saved {} ({} items) in {} ms", cacheType, keys.size(), TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)); } - private SequentialWriter tempCacheFile(CacheKey.PathInfo pathInfo) + private SequentialWriter tempCacheFile(UUID cfId) { - File path = getCachePath(pathInfo.keyspace, pathInfo.columnFamily, pathInfo.cfId, CURRENT_VERSION); + File path = getCachePath(cfId, CURRENT_VERSION); File tmpFile = FileUtils.createTempFile(path.getName(), null, path.getParentFile()); return SequentialWriter.open(tmpFile); } @@ -282,7 +293,9 @@ public class AutoSavingCache<K extends CacheKey, V> extends InstrumentingCache<K } } else + { logger.warn("Could not list files in {}", savedCachesDir); + } } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/e25d94e6/src/java/org/apache/cassandra/cache/CacheKey.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cache/CacheKey.java b/src/java/org/apache/cassandra/cache/CacheKey.java index b4e6c22..44fead0 100644 --- a/src/java/org/apache/cassandra/cache/CacheKey.java +++ b/src/java/org/apache/cassandra/cache/CacheKey.java @@ -22,41 +22,7 @@ import java.util.UUID; public interface CacheKey extends IMeasurableMemory { /** - * @return The keyspace and ColumnFamily names to which this key belongs + * @return The cf id of the cache key. */ - public PathInfo getPathInfo(); - - public static class PathInfo - { - public final String keyspace; - public final String columnFamily; - public final UUID cfId; - - public PathInfo(String keyspace, String columnFamily, UUID cfId) - { - this.keyspace = keyspace; - this.columnFamily = columnFamily; - this.cfId = cfId; - } - - @Override - public boolean equals(Object o) - { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - PathInfo pathInfo = (PathInfo) o; - - return (cfId != null ? cfId.equals(pathInfo.cfId) : pathInfo.cfId == null) && columnFamily.equals(pathInfo.columnFamily) && keyspace.equals(pathInfo.keyspace); - } - - @Override - public int hashCode() - { - int result = keyspace.hashCode(); - result = 31 * result + columnFamily.hashCode(); - result = 31 * result + (cfId != null ? cfId.hashCode() : 0); - return result; - } - } + public UUID getCFId(); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/e25d94e6/src/java/org/apache/cassandra/cache/CounterCacheKey.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cache/CounterCacheKey.java b/src/java/org/apache/cassandra/cache/CounterCacheKey.java index da12dd4..60247c5 100644 --- a/src/java/org/apache/cassandra/cache/CounterCacheKey.java +++ b/src/java/org/apache/cassandra/cache/CounterCacheKey.java @@ -21,7 +21,6 @@ import java.nio.ByteBuffer; import java.util.Arrays; import java.util.UUID; -import org.apache.cassandra.config.Schema; import org.apache.cassandra.db.composites.CellName; import org.apache.cassandra.db.composites.CellNames; import org.apache.cassandra.utils.*; @@ -47,10 +46,9 @@ public class CounterCacheKey implements CacheKey return new CounterCacheKey(cfId, partitionKey, cellName); } - public PathInfo getPathInfo() + public UUID getCFId() { - Pair<String, String> cf = Schema.instance.getCF(cfId); - return new PathInfo(cf.left, cf.right, cfId); + return cfId; } public long unsharedHeapSize() http://git-wip-us.apache.org/repos/asf/cassandra/blob/e25d94e6/src/java/org/apache/cassandra/cache/KeyCacheKey.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cache/KeyCacheKey.java b/src/java/org/apache/cassandra/cache/KeyCacheKey.java index 5624133..cef37ce 100644 --- a/src/java/org/apache/cassandra/cache/KeyCacheKey.java +++ b/src/java/org/apache/cassandra/cache/KeyCacheKey.java @@ -44,9 +44,9 @@ public class KeyCacheKey implements CacheKey assert this.key != null; } - public PathInfo getPathInfo() + public UUID getCFId() { - return new PathInfo(desc.ksname, desc.cfname, cfId); + return cfId; } public String toString() http://git-wip-us.apache.org/repos/asf/cassandra/blob/e25d94e6/src/java/org/apache/cassandra/cache/RowCacheKey.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cache/RowCacheKey.java b/src/java/org/apache/cassandra/cache/RowCacheKey.java index aebb129..af2d4d4 100644 --- a/src/java/org/apache/cassandra/cache/RowCacheKey.java +++ b/src/java/org/apache/cassandra/cache/RowCacheKey.java @@ -21,12 +21,10 @@ import java.nio.ByteBuffer; import java.util.Arrays; import java.util.UUID; -import org.apache.cassandra.config.Schema; import org.apache.cassandra.db.DecoratedKey; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.ObjectSizes; -import org.apache.cassandra.utils.Pair; public class RowCacheKey implements CacheKey, Comparable<RowCacheKey> { @@ -47,10 +45,9 @@ public class RowCacheKey implements CacheKey, Comparable<RowCacheKey> assert this.key != null; } - public PathInfo getPathInfo() + public UUID getCFId() { - Pair<String, String> cf = Schema.instance.getCF(cfId); - return new PathInfo(cf.left, cf.right, cfId); + return cfId; } public long unsharedHeapSize() http://git-wip-us.apache.org/repos/asf/cassandra/blob/e25d94e6/src/java/org/apache/cassandra/config/Schema.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/config/Schema.java b/src/java/org/apache/cassandra/config/Schema.java index 106ad9b..8e9802f 100644 --- a/src/java/org/apache/cassandra/config/Schema.java +++ b/src/java/org/apache/cassandra/config/Schema.java @@ -302,6 +302,15 @@ public class Schema } /** + * @param cfId The identifier of the ColumnFamily to lookup + * @return true if the CF id is a known one, false otherwise. + */ + public boolean hasCF(UUID cfId) + { + return cfIdMap.containsValue(cfId); + } + + /** * Lookup keyspace/ColumnFamily identifier * * @param ksName The keyspace name