Michael Semb Wever created CASSANDRA-21620:
----------------------------------------------

             Summary: Stats metadata over-sizes the legacy minimum and maximum 
clustering values
                 Key: CASSANDRA-21620
                 URL: https://issues.apache.org/jira/browse/CASSANDRA-21620
             Project: Apache Cassandra
          Issue Type: Bug
          Components: Local/SSTable
            Reporter: Michael Semb Wever


For an sstable version that still carries the legacy minimum and maximum 
clustering values, {{StatsMetadata.StatsMetadataSerializer.serialize}} writes 
the components of each bound up to the first null one, and writes that count:

{code:java}
out.writeInt(countUntilNull(minClusteringValues.getBufferArray()));
for (ByteBuffer value : minClusteringValues.getBufferArray())
{
    if (value == null)
        break;
    ByteBufferUtil.writeWithShortLength(value, out);
}
{code}

{{serializedSize}} charges two length bytes for every component the bound 
holds, null ones included:

{code:java}
size += minClusteringValues.size() * 2 /* short length */ + 
minClusteringValues.dataSize();
{code}

A bound that {{MetadataCollector}} builds holds one entry per clustering 
column, so a covered clustering that stops short of the last column makes the 
two disagree. {{dataSize()}} already counts a null component as zero bytes, so 
the difference is the two length bytes alone.

{{MetadataSerializer.serialize}} derives the table-of-contents offset of each 
component from the returned size, and writes the whole backing array of a 
buffer allocated to that size. The STATS component therefore ends with two 
unused bytes per absent component. The file stays readable: the reader takes 
the length of each component from the offsets and stops once it has read the 
recorded count.

No production write reaches the disagreement today, which is why the ticket is 
Low. A writer uses the latest version of its format, where 
{{hasLegacyMinMax()}} is false, and a metadata mutation on an older sstable 
rebuilds the bounds from disk, where they carry exactly the components that 
were written and no nulls. The legacy branch is deprecated and due for removal 
after {{oa}}; until then the two halves of the serializer must agree, because 
the offset arithmetic depends on it.

The patch sizes both bounds with {{countUntilNull}}, the same count the writer 
uses.

Patch: 
[mck/upstream/stats-metadata-legacy-min-max-size/trunk|https://github.com/thelastpickle/cassandra/tree/mck/upstream/stats-metadata-legacy-min-max-size/trunk]
Provenance: 
[f57af096a0|https://github.com/datastax/cassandra/commit/f57af096a0a9b5225d46dc860ab683d26156a013]
 by Jacek Lewandowski. That commit repairs the size computation only; the 
writer already counts to the first null upstream.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to