mirror of https://github.com/apache/cassandra
Merge branch 'cassandra-4.0' into cassandra-4.1
This commit is contained in:
commit
792e823af0
|
|
@ -5,6 +5,7 @@
|
|||
* IntrusiveStack.accumulate is not accumulating correctly (CASSANDRA-20670)
|
||||
* Add nodetool get/setguardrailsconfig commands (CASSANDRA-19552)
|
||||
Merged from 4.0:
|
||||
* Fix IndexOutOfBoundsException in sstablemetadata tool when a range tombstone is a max clustering value (CASSANDRA-20855)
|
||||
* Update Jackson to 2.19.2 (CASSANDRA-20848)
|
||||
* Update commons-lang3 to 3.18.0 (CASSANDRA-20849)
|
||||
* Add NativeTransportMaxConcurrentConnectionsPerIp to StorageProxyMBean (CASSANDRA-20642)
|
||||
|
|
|
|||
|
|
@ -356,21 +356,9 @@ public class SSTableMetadataViewer
|
|||
if (validation != null && header != null)
|
||||
printMinMaxToken(descriptor, FBUtilities.newPartitioner(descriptor), header.getKeyType());
|
||||
|
||||
if (header != null && header.getClusteringTypes().size() == stats.minClusteringValues.size())
|
||||
{
|
||||
List<AbstractType<?>> clusteringTypes = header.getClusteringTypes();
|
||||
List<ByteBuffer> minClusteringValues = stats.minClusteringValues;
|
||||
List<ByteBuffer> maxClusteringValues = stats.maxClusteringValues;
|
||||
String[] minValues = new String[clusteringTypes.size()];
|
||||
String[] maxValues = new String[clusteringTypes.size()];
|
||||
for (int i = 0; i < clusteringTypes.size(); i++)
|
||||
{
|
||||
minValues[i] = clusteringTypes.get(i).getString(minClusteringValues.get(i));
|
||||
maxValues[i] = clusteringTypes.get(i).getString(maxClusteringValues.get(i));
|
||||
}
|
||||
field("minClusteringValues", Arrays.toString(minValues));
|
||||
field("maxClusteringValues", Arrays.toString(maxValues));
|
||||
}
|
||||
printClusteringValues(header, "minClusteringValues", stats.minClusteringValues);
|
||||
printClusteringValues(header, "maxClusteringValues", stats.maxClusteringValues);
|
||||
|
||||
field("Estimated droppable tombstones",
|
||||
stats.getEstimatedDroppableTombstoneRatio((int) (currentTimeMillis() / 1000) - this.gc));
|
||||
field("SSTable Level", stats.sstableLevel);
|
||||
|
|
@ -437,6 +425,21 @@ public class SSTableMetadataViewer
|
|||
}
|
||||
}
|
||||
|
||||
private void printClusteringValues(SerializationHeader.Component header, String name, List<ByteBuffer> clusteringValues)
|
||||
{
|
||||
if (header != null && header.getClusteringTypes().size() >= clusteringValues.size())
|
||||
{
|
||||
List<AbstractType<?>> clusteringTypes = header.getClusteringTypes();
|
||||
int size = Math.min(clusteringTypes.size(), clusteringValues.size());
|
||||
String[] values = new String[size];
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
values[i] = clusteringTypes.get(i).getString(clusteringValues.get(i));
|
||||
}
|
||||
field(name, Arrays.toString(values));
|
||||
}
|
||||
}
|
||||
|
||||
private void field(String field, Object value)
|
||||
{
|
||||
field(field, value, null);
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
3617993137
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,8 @@
|
|||
Data.db
|
||||
TOC.txt
|
||||
Digest.crc32
|
||||
Summary.db
|
||||
Filter.db
|
||||
Statistics.db
|
||||
CompressionInfo.db
|
||||
Index.db
|
||||
|
|
@ -18,16 +18,23 @@
|
|||
|
||||
package org.apache.cassandra.tools;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.cassandra.SchemaLoader;
|
||||
import org.apache.cassandra.cql3.QueryProcessor;
|
||||
import org.apache.cassandra.db.Keyspace;
|
||||
import org.apache.cassandra.service.StorageService;
|
||||
import org.apache.cassandra.tools.ToolRunner.ToolResult;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
|
|
@ -225,4 +232,52 @@ public class SSTableMetadataViewerTest extends OfflineToolUtils
|
|||
assertKeyspaceNotLoaded();
|
||||
assertServerNotLoaded();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadingOfSStableWithRangeTombstoneAsMaxClustering() throws IOException
|
||||
{
|
||||
String sstableWithTombstones = copySSTables("sstable_metadata", "CASSANDRA_20855");
|
||||
ToolResult tool = ToolRunner.invokeClass(SSTableMetadataViewer.class, sstableWithTombstones);
|
||||
assertTrue(tool.getStdout(), CharMatcher.ascii().matchesAllOf(tool.getStdout()));
|
||||
Assertions.assertThat(tool.getStdout()).contains(sstableWithTombstones.replaceAll("-Data\\.db$", ""));
|
||||
Assertions.assertThat(tool.getStdout()).contains("minClusteringValues: [clust_key_1_1, clust_key_2_1]");
|
||||
// Range tombstone end as a max clustering value, only the first clustering key is stored in metadata
|
||||
Assertions.assertThat(tool.getStdout()).contains("maxClusteringValues: [clust_key_1_2]");
|
||||
assertTrue(tool.getStderr(), tool.getStderr().isEmpty());
|
||||
assertEquals(0, tool.getExitCode());
|
||||
assertGoodEnvPostTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
// the logic is used only to generate test data for testLoadingOfSStableWithRangeTombstoneAsMaxClustering
|
||||
// the result of the generation is committed to SCM
|
||||
public void generateSSTableWithRangeTombstone() throws IOException
|
||||
{
|
||||
SchemaLoader.prepareServer();
|
||||
StorageService.instance.initServer();
|
||||
Keyspace.setInitialized();
|
||||
QueryProcessor.executeInternal("CREATE KEYSPACE sstable_metadata WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}");
|
||||
QueryProcessor.executeInternal("CREATE TABLE sstable_metadata.CASSANDRA_20855 (pk text, ck_1 text, ck_2 text, val text, PRIMARY KEY (pk, ck_1, ck_2))");
|
||||
|
||||
QueryProcessor.executeInternal(String.format("INSERT INTO sstable_metadata.CASSANDRA_20855 (pk, ck_1, ck_2, val) VALUES ('%s', '%s', '%s', '%s')",
|
||||
"part_key_1", "clust_key_1_1", "clust_key_2_1", "value"));
|
||||
|
||||
QueryProcessor.executeInternal(String.format("DELETE FROM sstable_metadata.CASSANDRA_20855 WHERE pk = '%s' AND ck_1 = '%s'",
|
||||
"part_key_1", "clust_key_1_2"));
|
||||
|
||||
StorageService.instance.forceKeyspaceFlush("sstable_metadata");
|
||||
}
|
||||
|
||||
|
||||
private static String copySSTables(String keyspace, String table) throws IOException
|
||||
{
|
||||
File targetKeyspaceDir = new File("build/test/cassandra/data/", keyspace);
|
||||
targetKeyspaceDir.mkdirs();
|
||||
File targetTableDir = new File(targetKeyspaceDir, table);
|
||||
File srcKeyspaceDir = new File("test/data/" + keyspace);
|
||||
FileUtils.copyDirectory(new File(srcKeyspaceDir, table), targetTableDir);
|
||||
File[] sstableFiles = targetTableDir.listFiles((file) -> file.isFile() && file.getName().endsWith("-Data.db"));
|
||||
return sstableFiles[0].getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue