http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/GetLoggingLevels.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/GetLoggingLevels.java b/src/java/org/apache/cassandra/tools/nodetool/GetLoggingLevels.java new file mode 100644 index 0000000..7ce0017 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/GetLoggingLevels.java @@ -0,0 +1,38 @@ +/* + * 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 io.airlift.command.Command; + +import java.util.Map; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "getlogginglevels", description = "Get the runtime logging levels") +public class GetLoggingLevels extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + // what if some one set a very long logger name? 50 space may not be enough... + System.out.printf("%n%-50s%10s%n", "Logger Name", "Log Level"); + for (Map.Entry<String, String> entry : probe.getLoggingLevels().entrySet()) + System.out.printf("%-50s%10s%n", entry.getKey(), entry.getValue()); + } +} \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/GetSSTables.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/GetSSTables.java b/src/java/org/apache/cassandra/tools/nodetool/GetSSTables.java new file mode 100644 index 0000000..2c5d46b --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/GetSSTables.java @@ -0,0 +1,50 @@ +/* + * 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.base.Preconditions.checkArgument; +import io.airlift.command.Arguments; +import io.airlift.command.Command; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "getsstables", description = "Print the sstable filenames that own the key") +public class GetSSTables extends NodeToolCmd +{ + @Arguments(usage = "<keyspace> <table> <key>", description = "The keyspace, the table, and the key") + private List<String> args = new ArrayList<>(); + + @Override + public void execute(NodeProbe probe) + { + checkArgument(args.size() == 3, "getsstables requires ks, cf and key args"); + String ks = args.get(0); + String cf = args.get(1); + String key = args.get(2); + + List<String> sstables = probe.getSSTables(ks, cf, key); + for (String sstable : sstables) + { + System.out.println(sstable); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/GetStreamThroughput.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/GetStreamThroughput.java b/src/java/org/apache/cassandra/tools/nodetool/GetStreamThroughput.java new file mode 100644 index 0000000..437eb54 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/GetStreamThroughput.java @@ -0,0 +1,33 @@ +/* + * 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 io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "getstreamthroughput", description = "Print the Mb/s throughput cap for streaming in the system") +public class GetStreamThroughput extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + System.out.println("Current stream throughput: " + probe.getStreamThroughput() + " Mb/s"); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/GossipInfo.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/GossipInfo.java b/src/java/org/apache/cassandra/tools/nodetool/GossipInfo.java new file mode 100644 index 0000000..2acfcf1 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/GossipInfo.java @@ -0,0 +1,33 @@ +/* + * 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 io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "gossipinfo", description = "Shows the gossip information for the cluster") +public class GossipInfo extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + System.out.println(probe.getGossipInfo()); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/HostStat.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/HostStat.java b/src/java/org/apache/cassandra/tools/nodetool/HostStat.java new file mode 100644 index 0000000..19c0448 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/HostStat.java @@ -0,0 +1,41 @@ +/* + * 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 java.net.InetAddress; + +public class HostStat +{ + public final InetAddress endpoint; + public final boolean resolveIp; + public final Float owns; + public final String token; + + public HostStat(String token, InetAddress endpoint, boolean resolveIp, Float owns) + { + this.token = token; + this.endpoint = endpoint; + this.resolveIp = resolveIp; + this.owns = owns; + } + + public String ipOrDns() + { + return resolveIp ? endpoint.getHostName() : endpoint.getHostAddress(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Info.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/Info.java b/src/java/org/apache/cassandra/tools/nodetool/Info.java new file mode 100644 index 0000000..5852fc7 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/Info.java @@ -0,0 +1,153 @@ +/* + * 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 io.airlift.command.Command; +import io.airlift.command.Option; + +import java.lang.management.MemoryUsage; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.management.InstanceNotFoundException; + +import org.apache.cassandra.db.ColumnFamilyStoreMBean; +import org.apache.cassandra.io.util.FileUtils; +import org.apache.cassandra.service.CacheServiceMBean; +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "info", description = "Print node information (uptime, load, ...)") +public class Info extends NodeToolCmd +{ + @Option(name = {"-T", "--tokens"}, description = "Display all tokens") + private boolean tokens = false; + + @Override + public void execute(NodeProbe probe) + { + boolean gossipInitialized = probe.isInitialized(); + + System.out.printf("%-23s: %s%n", "ID", probe.getLocalHostId()); + System.out.printf("%-23s: %s%n", "Gossip active", gossipInitialized); + System.out.printf("%-23s: %s%n", "Thrift active", probe.isThriftServerRunning()); + System.out.printf("%-23s: %s%n", "Native Transport active", probe.isNativeTransportRunning()); + System.out.printf("%-23s: %s%n", "Load", probe.getLoadString()); + if (gossipInitialized) + System.out.printf("%-23s: %s%n", "Generation No", probe.getCurrentGenerationNumber()); + else + System.out.printf("%-23s: %s%n", "Generation No", 0); + + // Uptime + long secondsUp = probe.getUptime() / 1000; + System.out.printf("%-23s: %d%n", "Uptime (seconds)", secondsUp); + + // Memory usage + MemoryUsage heapUsage = probe.getHeapMemoryUsage(); + double memUsed = (double) heapUsage.getUsed() / (1024 * 1024); + double memMax = (double) heapUsage.getMax() / (1024 * 1024); + System.out.printf("%-23s: %.2f / %.2f%n", "Heap Memory (MB)", memUsed, memMax); + try + { + System.out.printf("%-23s: %.2f%n", "Off Heap Memory (MB)", getOffHeapMemoryUsed(probe)); + } + catch (RuntimeException e) + { + // offheap-metrics introduced in 2.1.3 - older versions do not have the appropriate mbeans + if (!(e.getCause() instanceof InstanceNotFoundException)) + throw e; + } + + // Data Center/Rack + System.out.printf("%-23s: %s%n", "Data Center", probe.getDataCenter()); + System.out.printf("%-23s: %s%n", "Rack", probe.getRack()); + + // Exceptions + System.out.printf("%-23s: %s%n", "Exceptions", probe.getStorageMetric("Exceptions")); + + CacheServiceMBean cacheService = probe.getCacheServiceMBean(); + + // Key Cache: Hits, Requests, RecentHitRate, SavePeriodInSeconds + System.out.printf("%-23s: entries %d, size %s, capacity %s, %d hits, %d requests, %.3f recent hit rate, %d save period in seconds%n", + "Key Cache", + probe.getCacheMetric("KeyCache", "Entries"), + FileUtils.stringifyFileSize((long) probe.getCacheMetric("KeyCache", "Size")), + FileUtils.stringifyFileSize((long) probe.getCacheMetric("KeyCache", "Capacity")), + probe.getCacheMetric("KeyCache", "Hits"), + probe.getCacheMetric("KeyCache", "Requests"), + probe.getCacheMetric("KeyCache", "HitRate"), + cacheService.getKeyCacheSavePeriodInSeconds()); + + // Row Cache: Hits, Requests, RecentHitRate, SavePeriodInSeconds + System.out.printf("%-23s: entries %d, size %s, capacity %s, %d hits, %d requests, %.3f recent hit rate, %d save period in seconds%n", + "Row Cache", + probe.getCacheMetric("RowCache", "Entries"), + FileUtils.stringifyFileSize((long) probe.getCacheMetric("RowCache", "Size")), + FileUtils.stringifyFileSize((long) probe.getCacheMetric("RowCache", "Capacity")), + probe.getCacheMetric("RowCache", "Hits"), + probe.getCacheMetric("RowCache", "Requests"), + probe.getCacheMetric("RowCache", "HitRate"), + cacheService.getRowCacheSavePeriodInSeconds()); + + // Counter Cache: Hits, Requests, RecentHitRate, SavePeriodInSeconds + System.out.printf("%-23s: entries %d, size %s, capacity %s, %d hits, %d requests, %.3f recent hit rate, %d save period in seconds%n", + "Counter Cache", + probe.getCacheMetric("CounterCache", "Entries"), + FileUtils.stringifyFileSize((long) probe.getCacheMetric("CounterCache", "Size")), + FileUtils.stringifyFileSize((long) probe.getCacheMetric("CounterCache", "Capacity")), + probe.getCacheMetric("CounterCache", "Hits"), + probe.getCacheMetric("CounterCache", "Requests"), + probe.getCacheMetric("CounterCache", "HitRate"), + cacheService.getCounterCacheSavePeriodInSeconds()); + + // Tokens + List<String> tokens = probe.getTokens(); + if (tokens.size() == 1 || this.tokens) + for (String token : tokens) + System.out.printf("%-23s: %s%n", "Token", token); + else + System.out.printf("%-23s: (invoke with -T/--tokens to see all %d tokens)%n", "Token", tokens.size()); + } + + /** + * Returns the total off heap memory used in MB. + * @return the total off heap memory used in MB. + */ + private static double getOffHeapMemoryUsed(NodeProbe probe) + { + long offHeapMemUsedInBytes = 0; + // get a list of column family stores + Iterator<Map.Entry<String, ColumnFamilyStoreMBean>> cfamilies = probe.getColumnFamilyStoreMBeanProxies(); + + while (cfamilies.hasNext()) + { + Entry<String, ColumnFamilyStoreMBean> entry = cfamilies.next(); + String keyspaceName = entry.getKey(); + String cfName = entry.getValue().getColumnFamilyName(); + + offHeapMemUsedInBytes += (Long) probe.getColumnFamilyMetric(keyspaceName, cfName, "MemtableOffHeapSize"); + offHeapMemUsedInBytes += (Long) probe.getColumnFamilyMetric(keyspaceName, cfName, "BloomFilterOffHeapMemoryUsed"); + offHeapMemUsedInBytes += (Long) probe.getColumnFamilyMetric(keyspaceName, cfName, "IndexSummaryOffHeapMemoryUsed"); + offHeapMemUsedInBytes += (Long) probe.getColumnFamilyMetric(keyspaceName, cfName, "CompressionMetadataOffHeapMemoryUsed"); + } + + return offHeapMemUsedInBytes / (1024d * 1024); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/InvalidateCounterCache.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/InvalidateCounterCache.java b/src/java/org/apache/cassandra/tools/nodetool/InvalidateCounterCache.java new file mode 100644 index 0000000..a5f0ebc --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/InvalidateCounterCache.java @@ -0,0 +1,33 @@ +/* + * 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 io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "invalidatecountercache", description = "Invalidate the counter cache") +public class InvalidateCounterCache extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + probe.invalidateCounterCache(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/InvalidateKeyCache.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/InvalidateKeyCache.java b/src/java/org/apache/cassandra/tools/nodetool/InvalidateKeyCache.java new file mode 100644 index 0000000..70abd53 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/InvalidateKeyCache.java @@ -0,0 +1,33 @@ +/* + * 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 io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "invalidatekeycache", description = "Invalidate the key cache") +public class InvalidateKeyCache extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + probe.invalidateKeyCache(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/InvalidateRowCache.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/InvalidateRowCache.java b/src/java/org/apache/cassandra/tools/nodetool/InvalidateRowCache.java new file mode 100644 index 0000000..149f80b --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/InvalidateRowCache.java @@ -0,0 +1,33 @@ +/* + * 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 io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "invalidaterowcache", description = "Invalidate the row cache") +public class InvalidateRowCache extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + probe.invalidateRowCache(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Join.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/Join.java b/src/java/org/apache/cassandra/tools/nodetool/Join.java new file mode 100644 index 0000000..5815591 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/Join.java @@ -0,0 +1,44 @@ +/* + * 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.base.Preconditions.checkState; +import io.airlift.command.Command; + +import java.io.IOException; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "join", description = "Join the ring") +public class Join extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + checkState(!probe.isJoined(), "This node has already joined the ring."); + + try + { + probe.joinRing(); + } catch (IOException e) + { + throw new RuntimeException("Error during joining the ring", e); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/ListSnapshots.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/ListSnapshots.java b/src/java/org/apache/cassandra/tools/nodetool/ListSnapshots.java new file mode 100644 index 0000000..ee7bf34 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/ListSnapshots.java @@ -0,0 +1,72 @@ +/* + * 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 io.airlift.command.Command; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.management.openmbean.TabularData; + +import org.apache.cassandra.io.util.FileUtils; +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "listsnapshots", description = "Lists all the snapshots along with the size on disk and true size.") +public class ListSnapshots extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + try + { + System.out.println("Snapshot Details: "); + + final Map<String,TabularData> snapshotDetails = probe.getSnapshotDetails(); + if (snapshotDetails.isEmpty()) + { + System.out.printf("There are no snapshots"); + return; + } + + final long trueSnapshotsSize = probe.trueSnapshotsSize(); + final String format = "%-20s%-29s%-29s%-19s%-19s%n"; + // display column names only once + final List<String> indexNames = snapshotDetails.entrySet().iterator().next().getValue().getTabularType().getIndexNames(); + System.out.printf(format, (Object[]) indexNames.toArray(new String[indexNames.size()])); + + for (final Map.Entry<String, TabularData> snapshotDetail : snapshotDetails.entrySet()) + { + Set<?> values = snapshotDetail.getValue().keySet(); + for (Object eachValue : values) + { + final List<?> value = (List<?>) eachValue; + System.out.printf(format, value.toArray(new Object[value.size()])); + } + } + + System.out.println("\nTotal TrueDiskSpaceUsed: " + FileUtils.stringifyFileSize(trueSnapshotsSize) + "\n"); + } + catch (Exception e) + { + throw new RuntimeException("Error during list snapshot", e); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Move.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/Move.java b/src/java/org/apache/cassandra/tools/nodetool/Move.java new file mode 100644 index 0000000..fc6b1bf --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/Move.java @@ -0,0 +1,46 @@ +/* + * 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 org.apache.commons.lang3.StringUtils.EMPTY; +import io.airlift.command.Arguments; +import io.airlift.command.Command; + +import java.io.IOException; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "move", description = "Move node on the token ring to a new token") +public class Move extends NodeToolCmd +{ + @Arguments(usage = "<new token>", description = "The new token.", required = true) + private String newToken = EMPTY; + + @Override + public void execute(NodeProbe probe) + { + try + { + probe.move(newToken); + } catch (IOException e) + { + throw new RuntimeException("Error during moving node", e); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/NetStats.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/NetStats.java b/src/java/org/apache/cassandra/tools/nodetool/NetStats.java new file mode 100644 index 0000000..cd2f1a2 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/NetStats.java @@ -0,0 +1,115 @@ +/* + * 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 io.airlift.command.Command; +import io.airlift.command.Option; + +import java.util.Set; + +import org.apache.cassandra.io.util.FileUtils; +import org.apache.cassandra.net.MessagingServiceMBean; +import org.apache.cassandra.streaming.ProgressInfo; +import org.apache.cassandra.streaming.SessionInfo; +import org.apache.cassandra.streaming.StreamState; +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "netstats", description = "Print network information on provided host (connecting node by default)") +public class NetStats extends NodeToolCmd +{ + @Option(title = "human_readable", + name = {"-H", "--human-readable"}, + description = "Display bytes in human readable form, i.e. KB, MB, GB, TB") + private boolean humanReadable = false; + + @Override + public void execute(NodeProbe probe) + { + System.out.printf("Mode: %s%n", probe.getOperationMode()); + Set<StreamState> statuses = probe.getStreamStatus(); + if (statuses.isEmpty()) + System.out.println("Not sending any streams."); + for (StreamState status : statuses) + { + System.out.printf("%s %s%n", status.description, status.planId.toString()); + for (SessionInfo info : status.sessions) + { + System.out.printf(" %s", info.peer.toString()); + // print private IP when it is used + if (!info.peer.equals(info.connecting)) + { + System.out.printf(" (using %s)", info.connecting.toString()); + } + System.out.printf("%n"); + if (!info.receivingSummaries.isEmpty()) + { + if (humanReadable) + System.out.printf(" Receiving %d files, %s total. Already received %d files, %s total%n", info.getTotalFilesToReceive(), FileUtils.stringifyFileSize(info.getTotalSizeToReceive()), info.getTotalFilesReceived(), FileUtils.stringifyFileSize(info.getTotalSizeReceived())); + else + System.out.printf(" Receiving %d files, %d bytes total. Already received %d files, %d bytes total%n", info.getTotalFilesToReceive(), info.getTotalSizeToReceive(), info.getTotalFilesReceived(), info.getTotalSizeReceived()); + for (ProgressInfo progress : info.getReceivingFiles()) + { + System.out.printf(" %s%n", progress.toString()); + } + } + if (!info.sendingSummaries.isEmpty()) + { + if (humanReadable) + System.out.printf(" Sending %d files, %s total. Already sent %d files, %s total%n", info.getTotalFilesToSend(), FileUtils.stringifyFileSize(info.getTotalSizeToSend()), info.getTotalFilesSent(), FileUtils.stringifyFileSize(info.getTotalSizeSent())); + else + System.out.printf(" Sending %d files, %d bytes total. Already sent %d files, %d bytes total%n", info.getTotalFilesToSend(), info.getTotalSizeToSend(), info.getTotalFilesSent(), info.getTotalSizeSent()); + for (ProgressInfo progress : info.getSendingFiles()) + { + System.out.printf(" %s%n", progress.toString()); + } + } + } + } + + if (!probe.isStarting()) + { + System.out.printf("Read Repair Statistics:%nAttempted: %d%nMismatch (Blocking): %d%nMismatch (Background): %d%n", probe.getReadRepairAttempted(), probe.getReadRepairRepairedBlocking(), probe.getReadRepairRepairedBackground()); + + MessagingServiceMBean ms = probe.msProxy; + System.out.printf("%-25s", "Pool Name"); + System.out.printf("%10s", "Active"); + System.out.printf("%10s", "Pending"); + System.out.printf("%15s%n", "Completed"); + + int pending; + long completed; + + pending = 0; + for (int n : ms.getLargeMessagePendingTasks().values()) + pending += n; + completed = 0; + for (long n : ms.getLargeMessageCompletedTasks().values()) + completed += n; + System.out.printf("%-25s%10s%10s%15s%n", "Large messages", "n/a", pending, completed); + + pending = 0; + for (int n : ms.getSmallMessagePendingTasks().values()) + pending += n; + completed = 0; + for (long n : ms.getSmallMessageCompletedTasks().values()) + completed += n; + System.out.printf("%-25s%10s%10s%15s%n", "Small messages", "n/a", pending, completed); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/PauseHandoff.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/PauseHandoff.java b/src/java/org/apache/cassandra/tools/nodetool/PauseHandoff.java new file mode 100644 index 0000000..ed1f655 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/PauseHandoff.java @@ -0,0 +1,33 @@ +/* + * 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 io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "pausehandoff", description = "Pause hints delivery process") +public class PauseHandoff extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + probe.pauseHintsDelivery(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/ProxyHistograms.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/ProxyHistograms.java b/src/java/org/apache/cassandra/tools/nodetool/ProxyHistograms.java new file mode 100644 index 0000000..2a2851d --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/ProxyHistograms.java @@ -0,0 +1,52 @@ +/* + * 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 java.lang.String.format; +import io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "proxyhistograms", description = "Print statistic histograms for network operations") +public class ProxyHistograms extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + String[] percentiles = new String[]{"50%", "75%", "95%", "98%", "99%", "Min", "Max"}; + double[] readLatency = probe.metricPercentilesAsArray(probe.getProxyMetric("Read")); + double[] writeLatency = probe.metricPercentilesAsArray(probe.getProxyMetric("Write")); + double[] rangeLatency = probe.metricPercentilesAsArray(probe.getProxyMetric("RangeSlice")); + + System.out.println("proxy histograms"); + System.out.println(format("%-10s%18s%18s%18s", + "Percentile", "Read Latency", "Write Latency", "Range Latency")); + System.out.println(format("%-10s%18s%18s%18s", + "", "(micros)", "(micros)", "(micros)")); + for (int i = 0; i < percentiles.length; i++) + { + System.out.println(format("%-10s%18.2f%18.2f%18.2f", + percentiles[i], + readLatency[i], + writeLatency[i], + rangeLatency[i])); + } + System.out.println(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/RangeKeySample.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/RangeKeySample.java b/src/java/org/apache/cassandra/tools/nodetool/RangeKeySample.java new file mode 100644 index 0000000..e079a4b --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/RangeKeySample.java @@ -0,0 +1,40 @@ +/* + * 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 io.airlift.command.Command; + +import java.util.List; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "rangekeysample", description = "Shows the sampled keys held across all keyspaces") +public class RangeKeySample extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + System.out.println("RangeKeySample: "); + List<String> tokenStrings = probe.sampleKeyRange(); + for (String tokenString : tokenStrings) + { + System.out.println("\t" + tokenString); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Rebuild.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/Rebuild.java b/src/java/org/apache/cassandra/tools/nodetool/Rebuild.java new file mode 100644 index 0000000..8a6dbf1 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/Rebuild.java @@ -0,0 +1,37 @@ +/* + * 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 io.airlift.command.Arguments; +import io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "rebuild", description = "Rebuild data by streaming from other nodes (similarly to bootstrap)") +public class Rebuild extends NodeToolCmd +{ + @Arguments(usage = "<src-dc-name>", description = "Name of DC from which to select sources for streaming. By default, pick any DC") + private String sourceDataCenterName = null; + + @Override + public void execute(NodeProbe probe) + { + probe.rebuild(sourceDataCenterName); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/RebuildIndex.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/RebuildIndex.java b/src/java/org/apache/cassandra/tools/nodetool/RebuildIndex.java new file mode 100644 index 0000000..9985b2b --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/RebuildIndex.java @@ -0,0 +1,43 @@ +/* + * 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.base.Preconditions.checkArgument; +import static com.google.common.collect.Iterables.toArray; +import io.airlift.command.Arguments; +import io.airlift.command.Command; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "rebuild_index", description = "A full rebuild of native secondary indexes for a given table") +public class RebuildIndex extends NodeToolCmd +{ + @Arguments(usage = "<keyspace> <table> <indexName...>", description = "The keyspace and table name followed by a list of index names (IndexNameExample: Standard3.IdxName Standard3.IdxName1)") + List<String> args = new ArrayList<>(); + + @Override + public void execute(NodeProbe probe) + { + checkArgument(args.size() >= 3, "rebuild_index requires ks, cf and idx args"); + probe.rebuildIndex(args.get(0), args.get(1), toArray(args.subList(2, args.size()), String.class)); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Refresh.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/Refresh.java b/src/java/org/apache/cassandra/tools/nodetool/Refresh.java new file mode 100644 index 0000000..153255c --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/Refresh.java @@ -0,0 +1,42 @@ +/* + * 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.base.Preconditions.checkArgument; +import io.airlift.command.Arguments; +import io.airlift.command.Command; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "refresh", description = "Load newly placed SSTables to the system without restart") +public class Refresh extends NodeToolCmd +{ + @Arguments(usage = "<keyspace> <table>", description = "The keyspace and table name") + private List<String> args = new ArrayList<>(); + + @Override + public void execute(NodeProbe probe) + { + checkArgument(args.size() == 2, "refresh requires ks and cf args"); + probe.loadNewSSTables(args.get(0), args.get(1)); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/ReloadTriggers.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/ReloadTriggers.java b/src/java/org/apache/cassandra/tools/nodetool/ReloadTriggers.java new file mode 100644 index 0000000..416aff0 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/ReloadTriggers.java @@ -0,0 +1,33 @@ +/* + * 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 io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "reloadtriggers", description = "Reload trigger classes") +public class ReloadTriggers extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + probe.reloadTriggers(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/RemoveNode.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/RemoveNode.java b/src/java/org/apache/cassandra/tools/nodetool/RemoveNode.java new file mode 100644 index 0000000..848049e --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/RemoveNode.java @@ -0,0 +1,50 @@ +/* + * 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 org.apache.commons.lang3.StringUtils.EMPTY; +import io.airlift.command.Arguments; +import io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "removenode", description = "Show status of current node removal, force completion of pending removal or remove provided ID") +public class RemoveNode extends NodeToolCmd +{ + @Arguments(title = "remove_operation", usage = "<status>|<force>|<ID>", description = "Show status of current node removal, force completion of pending removal, or remove provided ID", required = true) + private String removeOperation = EMPTY; + + @Override + public void execute(NodeProbe probe) + { + switch (removeOperation) + { + case "status": + System.out.println("RemovalStatus: " + probe.getRemovalStatus()); + break; + case "force": + System.out.println("RemovalStatus: " + probe.getRemovalStatus()); + probe.forceRemoveCompletion(); + break; + default: + probe.removeNode(removeOperation); + break; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Repair.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/Repair.java b/src/java/org/apache/cassandra/tools/nodetool/Repair.java new file mode 100644 index 0000000..45b3d98 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/Repair.java @@ -0,0 +1,123 @@ +/* + * 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.Lists.newArrayList; +import static org.apache.commons.lang3.StringUtils.EMPTY; +import io.airlift.command.Arguments; +import io.airlift.command.Command; +import io.airlift.command.Option; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.cassandra.repair.RepairParallelism; +import org.apache.cassandra.repair.messages.RepairOption; +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; +import org.apache.commons.lang3.StringUtils; + +@Command(name = "repair", description = "Repair one or more tables") +public class Repair extends NodeToolCmd +{ + @Arguments(usage = "[<keyspace> <tables>...]", description = "The keyspace followed by one or many tables") + private List<String> args = new ArrayList<>(); + + @Option(title = "seqential", name = {"-seq", "--sequential"}, description = "Use -seq to carry out a sequential repair") + private boolean sequential = false; + + @Option(title = "dc parallel", name = {"-dcpar", "--dc-parallel"}, description = "Use -dcpar to repair data centers in parallel.") + private boolean dcParallel = false; + + @Option(title = "local_dc", name = {"-local", "--in-local-dc"}, description = "Use -local to only repair against nodes in the same datacenter") + private boolean localDC = false; + + @Option(title = "specific_dc", name = {"-dc", "--in-dc"}, description = "Use -dc to repair specific datacenters") + private List<String> specificDataCenters = new ArrayList<>(); + + @Option(title = "specific_host", name = {"-hosts", "--in-hosts"}, description = "Use -hosts to repair specific hosts") + private List<String> specificHosts = new ArrayList<>(); + + @Option(title = "start_token", name = {"-st", "--start-token"}, description = "Use -st to specify a token at which the repair range starts") + private String startToken = EMPTY; + + @Option(title = "end_token", name = {"-et", "--end-token"}, description = "Use -et to specify a token at which repair range ends") + private String endToken = EMPTY; + + @Option(title = "primary_range", name = {"-pr", "--partitioner-range"}, description = "Use -pr to repair only the first range returned by the partitioner") + private boolean primaryRange = false; + + @Option(title = "full", name = {"-full", "--full"}, description = "Use -full to issue a full repair.") + private boolean fullRepair = false; + + @Option(title = "job_threads", name = {"-j", "--job-threads"}, description = "Number of threads to run repair jobs. " + + "Usually this means number of CFs to repair concurrently. " + + "WARNING: increasing this puts more load on repairing nodes, so be careful. (default: 1, max: 4)") + private int numJobThreads = 1; + + @Option(title = "trace_repair", name = {"-tr", "--trace"}, description = "Use -tr to trace the repair. Traces are logged to system_traces.events.") + private boolean trace = false; + + @Override + public void execute(NodeProbe probe) + { + List<String> keyspaces = parseOptionalKeyspace(args, probe); + String[] cfnames = parseOptionalColumnFamilies(args); + + if (primaryRange && (!specificDataCenters.isEmpty() || !specificHosts.isEmpty())) + throw new RuntimeException("Primary range repair should be performed on all nodes in the cluster."); + + for (String keyspace : keyspaces) + { + Map<String, String> options = new HashMap<>(); + RepairParallelism parallelismDegree = RepairParallelism.PARALLEL; + if (sequential) + parallelismDegree = RepairParallelism.SEQUENTIAL; + else if (dcParallel) + parallelismDegree = RepairParallelism.DATACENTER_AWARE; + options.put(RepairOption.PARALLELISM_KEY, parallelismDegree.getName()); + options.put(RepairOption.PRIMARY_RANGE_KEY, Boolean.toString(primaryRange)); + options.put(RepairOption.INCREMENTAL_KEY, Boolean.toString(!fullRepair)); + options.put(RepairOption.JOB_THREADS_KEY, Integer.toString(numJobThreads)); + options.put(RepairOption.TRACE_KEY, Boolean.toString(trace)); + options.put(RepairOption.COLUMNFAMILIES_KEY, StringUtils.join(cfnames, ",")); + if (!startToken.isEmpty() || !endToken.isEmpty()) + { + options.put(RepairOption.RANGES_KEY, startToken + ":" + endToken); + } + if (localDC) + { + options.put(RepairOption.DATACENTERS_KEY, StringUtils.join(newArrayList(probe.getDataCenter()), ",")); + } + else + { + options.put(RepairOption.DATACENTERS_KEY, StringUtils.join(specificDataCenters, ",")); + } + options.put(RepairOption.HOSTS_KEY, StringUtils.join(specificHosts, ",")); + try + { + probe.repairAsync(System.out, keyspace, options); + } catch (Exception e) + { + throw new RuntimeException("Error occurred during repair", e); + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/ResetLocalSchema.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/ResetLocalSchema.java b/src/java/org/apache/cassandra/tools/nodetool/ResetLocalSchema.java new file mode 100644 index 0000000..43280ab --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/ResetLocalSchema.java @@ -0,0 +1,41 @@ +/* + * 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 io.airlift.command.Command; + +import java.io.IOException; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "resetlocalschema", description = "Reset node's local schema and resync") +public class ResetLocalSchema extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + try + { + probe.resetLocalSchema(); + } catch (IOException e) + { + throw new RuntimeException(e); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/ResumeHandoff.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/ResumeHandoff.java b/src/java/org/apache/cassandra/tools/nodetool/ResumeHandoff.java new file mode 100644 index 0000000..584ab64 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/ResumeHandoff.java @@ -0,0 +1,33 @@ +/* + * 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 io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "resumehandoff", description = "Resume hints delivery process") +public class ResumeHandoff extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + probe.resumeHintsDelivery(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Ring.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/Ring.java b/src/java/org/apache/cassandra/tools/nodetool/Ring.java new file mode 100644 index 0000000..5102029 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/Ring.java @@ -0,0 +1,177 @@ +/* + * 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 java.lang.String.format; +import io.airlift.command.Arguments; +import io.airlift.command.Command; +import io.airlift.command.Option; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +import com.google.common.collect.LinkedHashMultimap; + +@Command(name = "ring", description = "Print information about the token ring") +public class Ring extends NodeToolCmd +{ + @Arguments(description = "Specify a keyspace for accurate ownership information (topology awareness)") + private String keyspace = null; + + @Option(title = "resolve_ip", name = {"-r", "--resolve-ip"}, description = "Show node domain names instead of IPs") + private boolean resolveIp = false; + + @Override + public void execute(NodeProbe probe) + { + Map<String, String> tokensToEndpoints = probe.getTokenToEndpointMap(); + LinkedHashMultimap<String, String> endpointsToTokens = LinkedHashMultimap.create(); + boolean haveVnodes = false; + for (Map.Entry<String, String> entry : tokensToEndpoints.entrySet()) + { + haveVnodes |= endpointsToTokens.containsKey(entry.getValue()); + endpointsToTokens.put(entry.getValue(), entry.getKey()); + } + + int maxAddressLength = Collections.max(endpointsToTokens.keys(), new Comparator<String>() + { + @Override + public int compare(String first, String second) + { + return ((Integer) first.length()).compareTo(second.length()); + } + }).length(); + + String formatPlaceholder = "%%-%ds %%-12s%%-7s%%-8s%%-16s%%-20s%%-44s%%n"; + String format = format(formatPlaceholder, maxAddressLength); + + StringBuffer errors = new StringBuffer(); + boolean showEffectiveOwnership = true; + // Calculate per-token ownership of the ring + Map<InetAddress, Float> ownerships; + try + { + ownerships = probe.effectiveOwnership(keyspace); + } + catch (IllegalStateException ex) + { + ownerships = probe.getOwnership(); + errors.append("Note: " + ex.getMessage() + "%n"); + showEffectiveOwnership = false; + } + catch (IllegalArgumentException ex) + { + System.out.printf("%nError: " + ex.getMessage() + "%n"); + return; + } + + + System.out.println(); + for (Entry<String, SetHostStat> entry : NodeTool.getOwnershipByDc(probe, resolveIp, tokensToEndpoints, ownerships).entrySet()) + printDc(probe, format, entry.getKey(), endpointsToTokens, entry.getValue(),showEffectiveOwnership); + + if (haveVnodes) + { + System.out.println(" Warning: \"nodetool ring\" is used to output all the tokens of a node."); + System.out.println(" To view status related info of a node use \"nodetool status\" instead.\n"); + } + + System.out.printf("%n " + errors.toString()); + } + + private void printDc(NodeProbe probe, String format, + String dc, + LinkedHashMultimap<String, String> endpointsToTokens, + SetHostStat hoststats,boolean showEffectiveOwnership) + { + Collection<String> liveNodes = probe.getLiveNodes(); + Collection<String> deadNodes = probe.getUnreachableNodes(); + Collection<String> joiningNodes = probe.getJoiningNodes(); + Collection<String> leavingNodes = probe.getLeavingNodes(); + Collection<String> movingNodes = probe.getMovingNodes(); + Map<String, String> loadMap = probe.getLoadMap(); + + System.out.println("Datacenter: " + dc); + System.out.println("=========="); + + // get the total amount of replicas for this dc and the last token in this dc's ring + List<String> tokens = new ArrayList<>(); + String lastToken = ""; + + for (HostStat stat : hoststats) + { + tokens.addAll(endpointsToTokens.get(stat.endpoint.getHostAddress())); + lastToken = tokens.get(tokens.size() - 1); + } + + System.out.printf(format, "Address", "Rack", "Status", "State", "Load", "Owns", "Token"); + + if (hoststats.size() > 1) + System.out.printf(format, "", "", "", "", "", "", lastToken); + else + System.out.println(); + + for (HostStat stat : hoststats) + { + String endpoint = stat.endpoint.getHostAddress(); + String rack; + try + { + rack = probe.getEndpointSnitchInfoProxy().getRack(endpoint); + } + catch (UnknownHostException e) + { + rack = "Unknown"; + } + + String status = liveNodes.contains(endpoint) + ? "Up" + : deadNodes.contains(endpoint) + ? "Down" + : "?"; + + String state = "Normal"; + + if (joiningNodes.contains(endpoint)) + state = "Joining"; + else if (leavingNodes.contains(endpoint)) + state = "Leaving"; + else if (movingNodes.contains(endpoint)) + state = "Moving"; + + String load = loadMap.containsKey(endpoint) + ? loadMap.get(endpoint) + : "?"; + String owns = stat.owns != null && showEffectiveOwnership? new DecimalFormat("##0.00%").format(stat.owns) : "?"; + System.out.printf(format, stat.ipOrDns(), rack, status, state, load, owns, stat.token); + } + System.out.println(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Scrub.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/Scrub.java b/src/java/org/apache/cassandra/tools/nodetool/Scrub.java new file mode 100644 index 0000000..8064b8e --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/Scrub.java @@ -0,0 +1,66 @@ +/* + * 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 io.airlift.command.Arguments; +import io.airlift.command.Command; +import io.airlift.command.Option; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "scrub", description = "Scrub (rebuild sstables for) one or more tables") +public class Scrub extends NodeToolCmd +{ + @Arguments(usage = "[<keyspace> <tables>...]", description = "The keyspace followed by one or many tables") + private List<String> args = new ArrayList<>(); + + @Option(title = "disable_snapshot", + name = {"-ns", "--no-snapshot"}, + description = "Scrubbed CFs will be snapshotted first, if disableSnapshot is false. (default false)") + private boolean disableSnapshot = false; + + @Option(title = "skip_corrupted", + name = {"-s", "--skip-corrupted"}, + description = "Skip corrupted partitions even when scrubbing counter tables. (default false)") + private boolean skipCorrupted = false; + + @Override + public void execute(NodeProbe probe) + { + List<String> keyspaces = parseOptionalKeyspace(args, probe); + String[] cfnames = parseOptionalColumnFamilies(args); + + for (String keyspace : keyspaces) + { + try + { + probe.scrub(System.out, disableSnapshot, skipCorrupted, keyspace, cfnames); + } catch (IllegalArgumentException e) + { + throw e; + } catch (Exception e) + { + throw new RuntimeException("Error occurred during scrubbing", e); + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/SetCacheCapacity.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/SetCacheCapacity.java b/src/java/org/apache/cassandra/tools/nodetool/SetCacheCapacity.java new file mode 100644 index 0000000..6c280d8 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/SetCacheCapacity.java @@ -0,0 +1,45 @@ +/* + * 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.base.Preconditions.checkArgument; +import io.airlift.command.Arguments; +import io.airlift.command.Command; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "setcachecapacity", description = "Set global key, row, and counter cache capacities (in MB units)") +public class SetCacheCapacity extends NodeToolCmd +{ + @Arguments(title = "<key-cache-capacity> <row-cache-capacity> <counter-cache-capacity>", + usage = "<key-cache-capacity> <row-cache-capacity> <counter-cache-capacity>", + description = "Key cache, row cache, and counter cache (in MB)", + required = true) + private List<Integer> args = new ArrayList<>(); + + @Override + public void execute(NodeProbe probe) + { + checkArgument(args.size() == 3, "setcachecapacity requires key-cache-capacity, row-cache-capacity, and counter-cache-capacity args."); + probe.setCacheCapacities(args.get(0), args.get(1), args.get(2)); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/SetCacheKeysToSave.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/SetCacheKeysToSave.java b/src/java/org/apache/cassandra/tools/nodetool/SetCacheKeysToSave.java new file mode 100644 index 0000000..12a4570 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/SetCacheKeysToSave.java @@ -0,0 +1,45 @@ +/* + * 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.base.Preconditions.checkArgument; +import io.airlift.command.Arguments; +import io.airlift.command.Command; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "setcachekeystosave", description = "Set number of keys saved by each cache for faster post-restart warmup. 0 to disable") +public class SetCacheKeysToSave extends NodeToolCmd +{ + @Arguments(title = "<key-cache-keys-to-save> <row-cache-keys-to-save> <counter-cache-keys-to-save>", + usage = "<key-cache-keys-to-save> <row-cache-keys-to-save> <counter-cache-keys-to-save>", + description = "The number of keys saved by each cache. 0 to disable", + required = true) + private List<Integer> args = new ArrayList<>(); + + @Override + public void execute(NodeProbe probe) + { + checkArgument(args.size() == 3, "setcachekeystosave requires key-cache-keys-to-save, row-cache-keys-to-save, and counter-cache-keys-to-save args."); + probe.setCacheKeysToSave(args.get(0), args.get(1), args.get(2)); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/SetCompactionThreshold.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/SetCompactionThreshold.java b/src/java/org/apache/cassandra/tools/nodetool/SetCompactionThreshold.java new file mode 100644 index 0000000..304f2b7 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/SetCompactionThreshold.java @@ -0,0 +1,50 @@ +/* + * 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.base.Preconditions.checkArgument; +import static java.lang.Integer.parseInt; +import io.airlift.command.Arguments; +import io.airlift.command.Command; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "setcompactionthreshold", description = "Set min and max compaction thresholds for a given table") +public class SetCompactionThreshold extends NodeToolCmd +{ + @Arguments(title = "<keyspace> <table> <minthreshold> <maxthreshold>", usage = "<keyspace> <table> <minthreshold> <maxthreshold>", description = "The keyspace, the table, min and max threshold", required = true) + private List<String> args = new ArrayList<>(); + + @Override + public void execute(NodeProbe probe) + { + checkArgument(args.size() == 4, "setcompactionthreshold requires ks, cf, min, and max threshold args."); + + int minthreshold = parseInt(args.get(2)); + int maxthreshold = parseInt(args.get(3)); + checkArgument(minthreshold >= 0 && maxthreshold >= 0, "Thresholds must be positive integers"); + checkArgument(minthreshold <= maxthreshold, "Min threshold cannot be greater than max."); + checkArgument(minthreshold >= 2 || maxthreshold == 0, "Min threshold must be at least 2"); + + probe.setCompactionThreshold(args.get(0), args.get(1), minthreshold, maxthreshold); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/SetCompactionThroughput.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/SetCompactionThroughput.java b/src/java/org/apache/cassandra/tools/nodetool/SetCompactionThroughput.java new file mode 100644 index 0000000..0111a20 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/SetCompactionThroughput.java @@ -0,0 +1,37 @@ +/* + * 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 io.airlift.command.Arguments; +import io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "setcompactionthroughput", description = "Set the MB/s throughput cap for compaction in the system, or 0 to disable throttling") +public class SetCompactionThroughput extends NodeToolCmd +{ + @Arguments(title = "compaction_throughput", usage = "<value_in_mb>", description = "Value in MB, 0 to disable throttling", required = true) + private Integer compactionThroughput = null; + + @Override + public void execute(NodeProbe probe) + { + probe.setCompactionThroughput(compactionThroughput); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/SetHintedHandoffThrottleInKB.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/SetHintedHandoffThrottleInKB.java b/src/java/org/apache/cassandra/tools/nodetool/SetHintedHandoffThrottleInKB.java new file mode 100644 index 0000000..d20ff3f --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/SetHintedHandoffThrottleInKB.java @@ -0,0 +1,37 @@ +/* + * 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 io.airlift.command.Arguments; +import io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "sethintedhandoffthrottlekb", description = "Set hinted handoff throttle in kb per second, per delivery thread.") +public class SetHintedHandoffThrottleInKB extends NodeToolCmd +{ + @Arguments(title = "throttle_in_kb", usage = "<value_in_kb_per_sec>", description = "Value in KB per second", required = true) + private Integer throttleInKB = null; + + @Override + public void execute(NodeProbe probe) + { + probe.setHintedHandoffThrottleInKB(throttleInKB); + } +} \ No newline at end of file
