merge from 2.1
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/c74f2252 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/c74f2252 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/c74f2252 Branch: refs/heads/trunk Commit: c74f2252201be2e55e6fc68b7dbcc520472c2b63 Parents: 23e77f1 f59df28 Author: Jonathan Ellis <jbel...@apache.org> Authored: Tue Apr 14 12:27:34 2015 -0500 Committer: Jonathan Ellis <jbel...@apache.org> Committed: Tue Apr 14 12:27:34 2015 -0500 ---------------------------------------------------------------------- CHANGES.txt | 5 + .../cassandra/service/StorageService.java | 218 ++++++++++++++++--- .../cassandra/service/StorageServiceMBean.java | 10 + .../org/apache/cassandra/tools/NodeProbe.java | 61 +++++- .../cassandra/tools/nodetool/Snapshot.java | 43 +++- 5 files changed, 288 insertions(+), 49 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/c74f2252/CHANGES.txt ---------------------------------------------------------------------- diff --cc CHANGES.txt index 9f89e3f,d64ebc5..063a39b --- a/CHANGES.txt +++ b/CHANGES.txt @@@ -1,100 -1,5 +1,105 @@@ +3.0 + * Allow cassandra config to be updated to restart daemon without unloading classes (CASSANDRA-9046) + * Don't initialize compaction writer before checking if iter is empty (CASSANDRA-9117) + * Remove line number generation from default logback.xml + * Don't execute any functions at prepare-time (CASSANDRA-9037) + * Share file handles between all instances of a SegmentedFile (CASSANDRA-8893) + * Make it possible to major compact LCS (CASSANDRA-7272) + * Make FunctionExecutionException extend RequestExecutionException + (CASSANDRA-9055) + * Add support for SELECT JSON, INSERT JSON syntax and new toJson(), fromJson() + functions (CASSANDRA-7970) + * Optimise max purgeable timestamp calculation in compaction (CASSANDRA-8920) + * Constrain internode message buffer sizes, and improve IO class hierarchy (CASSANDRA-8670) + * New tool added to validate all sstables in a node (CASSANDRA-5791) + * Push notification when tracing completes for an operation (CASSANDRA-7807) + * Delay "node up" and "node added" notifications until native protocol server is started (CASSANDRA-8236) + * Compressed Commit Log (CASSANDRA-6809) + * Optimise IntervalTree (CASSANDRA-8988) + * Add a key-value payload for third party usage (CASSANDRA-8553) + * Bump metrics-reporter-config dependency for metrics 3.0 (CASSANDRA-8149) + * Partition intra-cluster message streams by size, not type (CASSANDRA-8789) + * Add WriteFailureException to native protocol, notify coordinator of + write failures (CASSANDRA-8592) + * Convert SequentialWriter to nio (CASSANDRA-8709) + * Add role based access control (CASSANDRA-7653, 8650, 7216, 8760, 8849, 8761, 8850) + * Record client ip address in tracing sessions (CASSANDRA-8162) + * Indicate partition key columns in response metadata for prepared + statements (CASSANDRA-7660) + * Merge UUIDType and TimeUUIDType parse logic (CASSANDRA-8759) + * Avoid memory allocation when searching index summary (CASSANDRA-8793) + * Optimise (Time)?UUIDType Comparisons (CASSANDRA-8730) + * Make CRC32Ex into a separate maven dependency (CASSANDRA-8836) + * Use preloaded jemalloc w/ Unsafe (CASSANDRA-8714) + * Avoid accessing partitioner through StorageProxy (CASSANDRA-8244, 8268) + * Upgrade Metrics library and remove depricated metrics (CASSANDRA-5657) + * Serializing Row cache alternative, fully off heap (CASSANDRA-7438) + * Duplicate rows returned when in clause has repeated values (CASSANDRA-6707) + * Make CassandraException unchecked, extend RuntimeException (CASSANDRA-8560) + * Support direct buffer decompression for reads (CASSANDRA-8464) + * DirectByteBuffer compatible LZ4 methods (CASSANDRA-7039) + * Group sstables for anticompaction correctly (CASSANDRA-8578) + * Add ReadFailureException to native protocol, respond + immediately when replicas encounter errors while handling + a read request (CASSANDRA-7886) + * Switch CommitLogSegment from RandomAccessFile to nio (CASSANDRA-8308) + * Allow mixing token and partition key restrictions (CASSANDRA-7016) + * Support index key/value entries on map collections (CASSANDRA-8473) + * Modernize schema tables (CASSANDRA-8261) + * Support for user-defined aggregation functions (CASSANDRA-8053) + * Fix NPE in SelectStatement with empty IN values (CASSANDRA-8419) + * Refactor SelectStatement, return IN results in natural order instead + of IN value list order and ignore duplicate values in partition key IN restrictions (CASSANDRA-7981) + * Support UDTs, tuples, and collections in user-defined + functions (CASSANDRA-7563) + * Fix aggregate fn results on empty selection, result column name, + and cqlsh parsing (CASSANDRA-8229) + * Mark sstables as repaired after full repair (CASSANDRA-7586) + * Extend Descriptor to include a format value and refactor reader/writer + APIs (CASSANDRA-7443) + * Integrate JMH for microbenchmarks (CASSANDRA-8151) + * Keep sstable levels when bootstrapping (CASSANDRA-7460) + * Add Sigar library and perform basic OS settings check on startup (CASSANDRA-7838) + * Support for aggregation functions (CASSANDRA-4914) + * Remove cassandra-cli (CASSANDRA-7920) + * Accept dollar quoted strings in CQL (CASSANDRA-7769) + * Make assassinate a first class command (CASSANDRA-7935) + * Support IN clause on any partition key column (CASSANDRA-7855) + * Support IN clause on any clustering column (CASSANDRA-4762) + * Improve compaction logging (CASSANDRA-7818) + * Remove YamlFileNetworkTopologySnitch (CASSANDRA-7917) + * Do anticompaction in groups (CASSANDRA-6851) + * Support user-defined functions (CASSANDRA-7395, 7526, 7562, 7740, 7781, 7929, + 7924, 7812, 8063, 7813, 7708) + * Permit configurable timestamps with cassandra-stress (CASSANDRA-7416) + * Move sstable RandomAccessReader to nio2, which allows using the + FILE_SHARE_DELETE flag on Windows (CASSANDRA-4050) + * Remove CQL2 (CASSANDRA-5918) + * Add Thrift get_multi_slice call (CASSANDRA-6757) + * Optimize fetching multiple cells by name (CASSANDRA-6933) + * Allow compilation in java 8 (CASSANDRA-7028) + * Make incremental repair default (CASSANDRA-7250) + * Enable code coverage thru JaCoCo (CASSANDRA-7226) + * Switch external naming of 'column families' to 'tables' (CASSANDRA-4369) + * Shorten SSTable path (CASSANDRA-6962) + * Use unsafe mutations for most unit tests (CASSANDRA-6969) + * Fix race condition during calculation of pending ranges (CASSANDRA-7390) + * Fail on very large batch sizes (CASSANDRA-8011) + * Improve concurrency of repair (CASSANDRA-6455, 8208) + * Select optimal CRC32 implementation at runtime (CASSANDRA-8614) + * Evaluate MurmurHash of Token once per query (CASSANDRA-7096) + * Generalize progress reporting (CASSANDRA-8901) + * Resumable bootstrap streaming (CASSANDRA-8838, CASSANDRA-8942) + * Allow scrub for secondary index (CASSANDRA-5174) + * Save repair data to system table (CASSANDRA-5839) + 2.1.5 ++<<<<<<< HEAD + * Add generate-idea-files target to build.xml (CASSANDRA-9123) ++||||||| merged common ancestors ++======= + * Allow takeColumnFamilySnapshot to take a list of tables (CASSANDRA-8348) ++>>>>>>> cassandra-2.1 * Limit major sstable operations to their canonical representation (CASSANDRA-8669) * cqlsh: Add tests for INSERT and UPDATE tab completion (CASSANDRA-9125) * cqlsh: quote column names when needed in COPY FROM inserts (CASSANDRA-9080) http://git-wip-us.apache.org/repos/asf/cassandra/blob/c74f2252/src/java/org/apache/cassandra/service/StorageService.java ---------------------------------------------------------------------- diff --cc src/java/org/apache/cassandra/service/StorageService.java index 045e7ac,a5fa563..e0fb8b2 --- a/src/java/org/apache/cassandra/service/StorageService.java +++ b/src/java/org/apache/cassandra/service/StorageService.java @@@ -22,45 -27,103 +27,105 @@@ import java.lang.management.ManagementF import java.net.InetAddress; import java.net.UnknownHostException; import java.nio.ByteBuffer; - import java.util.*; - import java.util.concurrent.*; + import java.util.ArrayList; + import java.util.Arrays; + import java.util.Collection; + import java.util.Collections; + import java.util.HashMap; + import java.util.HashSet; + import java.util.Iterator; + import java.util.LinkedHashMap; + import java.util.LinkedList; + import java.util.List; + import java.util.Map; + import java.util.Map.Entry; + import java.util.Set; + import java.util.SortedMap; + import java.util.TreeMap; + import java.util.UUID; + import java.util.concurrent.CopyOnWriteArrayList; + import java.util.concurrent.ExecutionException; + import java.util.concurrent.ExecutorService; + import java.util.concurrent.Future; + import java.util.concurrent.FutureTask; + import java.util.concurrent.TimeUnit; + import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; - import javax.management.*; -import java.util.concurrent.atomic.AtomicLong; + + import javax.management.JMX; + import javax.management.MBeanServer; -import javax.management.Notification; + import javax.management.NotificationBroadcasterSupport; + import javax.management.ObjectName; import javax.management.openmbean.TabularData; import javax.management.openmbean.TabularDataSupport; - import com.google.common.annotations.VisibleForTesting; - import com.google.common.base.Predicate; - import com.google.common.collect.*; - import com.google.common.util.concurrent.*; - import org.apache.commons.lang3.StringUtils; - import org.slf4j.Logger; - import org.slf4j.LoggerFactory; - - import ch.qos.logback.classic.LoggerContext; - import ch.qos.logback.classic.jmx.JMXConfiguratorMBean; - import ch.qos.logback.classic.spi.ILoggingEvent; - import ch.qos.logback.core.Appender; -import org.apache.cassandra.auth.Auth; +import org.apache.cassandra.auth.AuthKeyspace; +import org.apache.cassandra.auth.AuthMigrationListener; - import org.apache.cassandra.concurrent.*; - import org.apache.cassandra.config.*; - import org.apache.cassandra.db.*; + import org.apache.cassandra.concurrent.ScheduledExecutors; + import org.apache.cassandra.concurrent.Stage; + import org.apache.cassandra.concurrent.StageManager; + import org.apache.cassandra.config.CFMetaData; + import org.apache.cassandra.config.DatabaseDescriptor; + import org.apache.cassandra.config.KSMetaData; + import org.apache.cassandra.config.Schema; + import org.apache.cassandra.db.BatchlogManager; + import org.apache.cassandra.db.ColumnFamilyStore; + import org.apache.cassandra.db.CounterMutationVerbHandler; + import org.apache.cassandra.db.DecoratedKey; + import org.apache.cassandra.db.DefinitionsUpdateVerbHandler; + import org.apache.cassandra.db.HintedHandOffManager; + import org.apache.cassandra.db.Keyspace; + import org.apache.cassandra.db.MigrationRequestVerbHandler; + import org.apache.cassandra.db.MutationVerbHandler; + import org.apache.cassandra.db.ReadRepairVerbHandler; + import org.apache.cassandra.db.ReadVerbHandler; + import org.apache.cassandra.db.SchemaCheckVerbHandler; + import org.apache.cassandra.db.SnapshotDetailsTabularData; + import org.apache.cassandra.db.SystemKeyspace; + import org.apache.cassandra.db.TruncateVerbHandler; import org.apache.cassandra.db.commitlog.CommitLog; import org.apache.cassandra.db.compaction.CompactionManager; --import org.apache.cassandra.db.index.SecondaryIndex; - import org.apache.cassandra.dht.*; + import org.apache.cassandra.dht.BootStrapper; + import org.apache.cassandra.dht.IPartitioner; import org.apache.cassandra.dht.Range; - import org.apache.cassandra.exceptions.*; - import org.apache.cassandra.gms.*; + import org.apache.cassandra.dht.RangeStreamer; + import org.apache.cassandra.dht.RingPosition; ++import org.apache.cassandra.dht.StreamStateStore; + import org.apache.cassandra.dht.Token; ++import org.apache.cassandra.exceptions.AlreadyExistsException; + import org.apache.cassandra.exceptions.ConfigurationException; + import org.apache.cassandra.exceptions.InvalidRequestException; + import org.apache.cassandra.exceptions.UnavailableException; + import org.apache.cassandra.gms.ApplicationState; + import org.apache.cassandra.gms.EndpointState; + import org.apache.cassandra.gms.FailureDetector; + import org.apache.cassandra.gms.GossipDigestAck2VerbHandler; + import org.apache.cassandra.gms.GossipDigestAckVerbHandler; + import org.apache.cassandra.gms.GossipDigestSynVerbHandler; + import org.apache.cassandra.gms.GossipShutdownVerbHandler; + import org.apache.cassandra.gms.Gossiper; + import org.apache.cassandra.gms.IEndpointStateChangeSubscriber; + import org.apache.cassandra.gms.IFailureDetector; + import org.apache.cassandra.gms.TokenSerializer; + import org.apache.cassandra.gms.VersionedValue; import org.apache.cassandra.io.sstable.SSTableDeletingTask; import org.apache.cassandra.io.sstable.SSTableLoader; import org.apache.cassandra.io.util.FileUtils; - import org.apache.cassandra.locator.*; + import org.apache.cassandra.locator.AbstractReplicationStrategy; + import org.apache.cassandra.locator.DynamicEndpointSnitch; + import org.apache.cassandra.locator.IEndpointSnitch; + import org.apache.cassandra.locator.LocalStrategy; + import org.apache.cassandra.locator.TokenMetadata; import org.apache.cassandra.metrics.StorageMetrics; - import org.apache.cassandra.net.*; - import org.apache.cassandra.repair.*; + import org.apache.cassandra.net.AsyncOneResponse; + import org.apache.cassandra.net.MessageOut; + import org.apache.cassandra.net.MessagingService; + import org.apache.cassandra.net.ResponseVerbHandler; -import org.apache.cassandra.repair.RepairFuture; + import org.apache.cassandra.repair.RepairMessageVerbHandler; + import org.apache.cassandra.repair.RepairParallelism; ++import org.apache.cassandra.repair.RepairRunnable; ++import org.apache.cassandra.repair.SystemDistributedKeyspace; +import org.apache.cassandra.repair.messages.RepairOption; import org.apache.cassandra.service.paxos.CommitVerbHandler; import org.apache.cassandra.service.paxos.PrepareVerbHandler; import org.apache.cassandra.service.paxos.ProposeVerbHandler; @@@ -68,13 -135,37 +137,40 @@@ import org.apache.cassandra.streaming.S import org.apache.cassandra.thrift.EndpointDetails; import org.apache.cassandra.thrift.TokenRange; import org.apache.cassandra.thrift.cassandraConstants; -import org.apache.cassandra.tracing.Tracing; +import org.apache.cassandra.tracing.TraceKeyspace; - import org.apache.cassandra.utils.*; + import org.apache.cassandra.utils.BackgroundActivityMonitor; + import org.apache.cassandra.utils.FBUtilities; + import org.apache.cassandra.utils.JVMStabilityInspector; + import org.apache.cassandra.utils.OutputHandler; + import org.apache.cassandra.utils.Pair; + import org.apache.cassandra.utils.WrappedRunnable; +import org.apache.cassandra.utils.progress.ProgressEvent; +import org.apache.cassandra.utils.progress.ProgressEventType; +import org.apache.cassandra.utils.progress.jmx.JMXProgressSupport; + import org.apache.commons.lang3.StringUtils; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; - import static java.nio.charset.StandardCharsets.ISO_8859_1; + import ch.qos.logback.classic.LoggerContext; + import ch.qos.logback.classic.jmx.JMXConfiguratorMBean; + import ch.qos.logback.classic.spi.ILoggingEvent; + import ch.qos.logback.core.Appender; + + import com.google.common.annotations.VisibleForTesting; + import com.google.common.base.Predicate; + import com.google.common.collect.ArrayListMultimap; + import com.google.common.collect.Collections2; + import com.google.common.collect.HashMultimap; + import com.google.common.collect.ImmutableSet; + import com.google.common.collect.Iterables; -import com.google.common.collect.Iterators; + import com.google.common.collect.Lists; + import com.google.common.collect.Maps; + import com.google.common.collect.Multimap; + import com.google.common.collect.Sets; + import com.google.common.util.concurrent.FutureCallback; + import com.google.common.util.concurrent.Futures; ++import com.google.common.util.concurrent.ListenableFuture; + import com.google.common.util.concurrent.Uninterruptibles; /** * This abstraction contains the token/identifier of this node @@@ -2459,6 -2381,69 +2555,70 @@@ public class StorageService extends Not columnFamilyStore.snapshot(tag); } + /** + * Takes the snapshot of a multiple column family from different keyspaces. A snapshot name must be specified. + * + * + * @param tag + * the tag given to the snapshot; may not be null or empty + * @param columnFamilyList + * list of columnfamily from different keyspace in the form of ks1.cf1 ks2.cf2 + */ + @Override + public void takeMultipleColumnFamilySnapshot(String tag, String... columnFamilyList) + throws IOException + { + Map<Keyspace, List<String>> keyspaceColumnfamily = new HashMap<Keyspace, List<String>>(); + for (String columnFamily : columnFamilyList) + { + String splittedString[] = columnFamily.split("\\."); + if (splittedString.length == 2) + { + String keyspaceName = splittedString[0]; + String columnFamilyName = splittedString[1]; + + if (keyspaceName == null) + throw new IOException("You must supply a keyspace name"); + if (operationMode.equals(Mode.JOINING)) + throw new IOException("Cannot snapshot until bootstrap completes"); ++ + if (columnFamilyName == null) + throw new IOException("You must supply a column family name"); + if (tag == null || tag.equals("")) + throw new IOException("You must supply a snapshot name."); + + Keyspace keyspace = getValidKeyspace(keyspaceName); + ColumnFamilyStore columnFamilyStore = keyspace.getColumnFamilyStore(columnFamilyName); + // As there can be multiple column family from same keyspace check if snapshot exist for that specific + // columnfamily and not for whole keyspace + + if (columnFamilyStore.snapshotExists(tag)) + throw new IOException("Snapshot " + tag + " already exists."); + if (!keyspaceColumnfamily.containsKey(keyspace)) + { + keyspaceColumnfamily.put(keyspace, new ArrayList<String>()); + } + + // Add Keyspace columnfamily to map in order to support atomicity for snapshot process. + // So no snapshot should happen if any one of the above conditions fail for any keyspace or columnfamily + keyspaceColumnfamily.get(keyspace).add(columnFamilyName); + + } + else + { + throw new IllegalArgumentException( + "Cannot take a snapshot on secondary index or invalid column family name. You must supply a column family name in the form of keyspace.columnfamily"); + } + } + + for (Entry<Keyspace, List<String>> entry : keyspaceColumnfamily.entrySet()) + { + for (String columnFamily : entry.getValue()) + entry.getKey().snapshot(tag, columnFamily); + } + + } + private Keyspace getValidKeyspace(String keyspaceName) throws IOException { if (!Schema.instance.getKeyspaces().contains(keyspaceName)) http://git-wip-us.apache.org/repos/asf/cassandra/blob/c74f2252/src/java/org/apache/cassandra/service/StorageServiceMBean.java ---------------------------------------------------------------------- diff --cc src/java/org/apache/cassandra/service/StorageServiceMBean.java index 3b7ac3e,ab34e1b..01588c6 --- a/src/java/org/apache/cassandra/service/StorageServiceMBean.java +++ b/src/java/org/apache/cassandra/service/StorageServiceMBean.java @@@ -204,6 -211,18 +204,16 @@@ public interface StorageServiceMBean ex public void takeColumnFamilySnapshot(String keyspaceName, String columnFamilyName, String tag) throws IOException; /** + * Takes the snapshot of a multiple column family from different keyspaces. A snapshot name must be specified. + * + * @param tag + * the tag given to the snapshot; may not be null or empty + * @param columnFamilyList + * list of columnfamily from different keyspace in the form of ks1.cf1 ks2.cf2 + */ + public void takeMultipleColumnFamilySnapshot(String tag, String... columnFamilyList) throws IOException; - - - ++ + /** * Remove the snapshot with the given name from the given keyspaces. * If no tag is specified we will remove all snapshots. */ http://git-wip-us.apache.org/repos/asf/cassandra/blob/c74f2252/src/java/org/apache/cassandra/tools/NodeProbe.java ---------------------------------------------------------------------- diff --cc src/java/org/apache/cassandra/tools/NodeProbe.java index ecc5f57,5b97e79..c0c60e5 --- a/src/java/org/apache/cassandra/tools/NodeProbe.java +++ b/src/java/org/apache/cassandra/tools/NodeProbe.java @@@ -25,24 -27,39 +25,32 @@@ import java.lang.management.MemoryUsage import java.lang.management.RuntimeMXBean; import java.net.InetAddress; import java.net.UnknownHostException; - import java.util.*; -import java.text.SimpleDateFormat; + import java.util.AbstractMap; + import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; + import java.util.Collections; + import java.util.Comparator; + import java.util.HashMap; + import java.util.Iterator; + import java.util.List; + import java.util.Map; import java.util.Map.Entry; + import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.concurrent.locks.Condition; - import javax.management.*; + import javax.management.JMX; + import javax.management.MBeanServerConnection; + import javax.management.MalformedObjectNameException; -import javax.management.Notification; -import javax.management.NotificationListener; + import javax.management.ObjectName; import javax.management.openmbean.CompositeData; + import javax.management.openmbean.OpenDataException; + import javax.management.openmbean.TabularData; -import javax.management.remote.JMXConnectionNotification; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; - import javax.management.openmbean.*; - - import com.google.common.base.Function; - import com.google.common.collect.*; - import com.google.common.util.concurrent.Uninterruptibles; -import org.apache.cassandra.concurrent.JMXEnabledThreadPoolExecutorMBean; +import org.apache.cassandra.concurrent.Stage; import org.apache.cassandra.db.ColumnFamilyStoreMBean; import org.apache.cassandra.db.HintedHandOffManager; import org.apache.cassandra.db.HintedHandOffManagerMBean; @@@ -50,20 -67,32 +58,31 @@@ import org.apache.cassandra.db.compacti import org.apache.cassandra.db.compaction.CompactionManagerMBean; import org.apache.cassandra.gms.FailureDetector; import org.apache.cassandra.gms.FailureDetectorMBean; +import org.apache.cassandra.gms.Gossiper; +import org.apache.cassandra.gms.GossiperMBean; import org.apache.cassandra.locator.EndpointSnitchInfoMBean; +import org.apache.cassandra.metrics.CassandraMetricsRegistry; + import org.apache.cassandra.metrics.ColumnFamilyMetrics.Sampler; +import org.apache.cassandra.metrics.StorageMetrics; +import org.apache.cassandra.metrics.ThreadPoolMetrics; import org.apache.cassandra.net.MessagingService; import org.apache.cassandra.net.MessagingServiceMBean; - import org.apache.cassandra.service.*; - import org.apache.cassandra.streaming.StreamState; -import org.apache.cassandra.repair.RepairParallelism; -import org.apache.cassandra.service.ActiveRepairService; + import org.apache.cassandra.service.CacheService; + import org.apache.cassandra.service.CacheServiceMBean; + import org.apache.cassandra.service.GCInspector; + import org.apache.cassandra.service.GCInspectorMXBean; + import org.apache.cassandra.service.StorageProxy; + import org.apache.cassandra.service.StorageProxyMBean; + import org.apache.cassandra.service.StorageServiceMBean; import org.apache.cassandra.streaming.StreamManagerMBean; + import org.apache.cassandra.streaming.StreamState; import org.apache.cassandra.streaming.management.StreamStateCompositeData; -import org.apache.cassandra.utils.EstimatedHistogram; -import org.apache.cassandra.utils.JVMStabilityInspector; -import org.apache.cassandra.utils.concurrent.SimpleCondition; - import org.apache.cassandra.metrics.ColumnFamilyMetrics.Sampler; + import com.google.common.base.Function; + import com.google.common.collect.Iterables; + import com.google.common.collect.Maps; + import com.google.common.collect.Sets; + import com.google.common.util.concurrent.Uninterruptibles; -import com.yammer.metrics.reporting.JmxReporter; /** * JMX client operations for Cassandra. http://git-wip-us.apache.org/repos/asf/cassandra/blob/c74f2252/src/java/org/apache/cassandra/tools/nodetool/Snapshot.java ---------------------------------------------------------------------- diff --cc src/java/org/apache/cassandra/tools/nodetool/Snapshot.java index 22cc775,0000000..d2eab9a mode 100644,000000..100644 --- a/src/java/org/apache/cassandra/tools/nodetool/Snapshot.java +++ b/src/java/org/apache/cassandra/tools/nodetool/Snapshot.java @@@ -1,71 -1,0 +1,94 @@@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.cassandra.tools.nodetool; + +import static com.google.common.collect.Iterables.toArray; +import static org.apache.commons.lang3.StringUtils.join; +import io.airlift.command.Arguments; +import io.airlift.command.Command; +import io.airlift.command.Option; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "snapshot", description = "Take a snapshot of specified keyspaces or a snapshot of the specified table") +public class Snapshot extends NodeToolCmd +{ + @Arguments(usage = "[<keyspaces...>]", description = "List of keyspaces. By default, all keyspaces") + private List<String> keyspaces = new ArrayList<>(); + + @Option(title = "table", name = {"-cf", "--column-family", "--table"}, description = "The table name (you must specify one and only one keyspace for using this option)") + private String columnFamily = null; + + @Option(title = "tag", name = {"-t", "--tag"}, description = "The name of the snapshot") + private String snapshotName = Long.toString(System.currentTimeMillis()); + ++ @Option(title = "kclist", name = { "-kc", "--kc-list" }, description = "The list of Keyspace.Column family to take snapshot.(you must not specify only keyspace)") ++ private String kcList = null; ++ + @Override + public void execute(NodeProbe probe) + { + try + { + StringBuilder sb = new StringBuilder(); + + sb.append("Requested creating snapshot(s) for "); - - if (keyspaces.isEmpty()) - sb.append("[all keyspaces]"); ++ // Create a separate path for kclist to avoid breaking of already existing scripts ++ if (null != kcList && !kcList.isEmpty()) ++ { ++ kcList = kcList.replace(" ", ""); ++ if (keyspaces.isEmpty() && null == columnFamily) ++ sb.append("[").append(kcList).append("]"); ++ else ++ { ++ throw new IOException( ++ "When specifying the Keyspace columfamily list for a snapshot, you should not specify columnfamily"); ++ } ++ if (!snapshotName.isEmpty()) ++ sb.append(" with snapshot name [").append(snapshotName).append("]"); ++ System.out.println(sb.toString()); ++ probe.takeMultipleColumnFamilySnapshot(snapshotName, kcList.split(",")); ++ System.out.println("Snapshot directory: " + snapshotName); ++ } + else - sb.append("[").append(join(keyspaces, ", ")).append("]"); ++ { ++ if (keyspaces.isEmpty()) ++ sb.append("[all keyspaces]"); ++ else ++ sb.append("[").append(join(keyspaces, ", ")).append("]"); + - if (!snapshotName.isEmpty()) - sb.append(" with snapshot name [").append(snapshotName).append("]"); ++ if (!snapshotName.isEmpty()) ++ sb.append(" with snapshot name [").append(snapshotName).append("]"); + - System.out.println(sb.toString()); ++ System.out.println(sb.toString()); + - probe.takeSnapshot(snapshotName, columnFamily, toArray(keyspaces, String.class)); - System.out.println("Snapshot directory: " + snapshotName); - } catch (IOException e) ++ probe.takeSnapshot(snapshotName, columnFamily, toArray(keyspaces, String.class)); ++ System.out.println("Snapshot directory: " + snapshotName); ++ } ++ } ++ catch (IOException e) + { + throw new RuntimeException("Error during taking a snapshot", e); + } + } +}