Fix marking an SSTable as suspected and BufferPool leakage in case of a corrupted SSTable read during a compaction

Patch by Dmitry Konstantinov; reviewed by Branimir Lambov for CASSANDRA-20396
This commit is contained in:
Dmitry Konstantinov 2025-03-07 23:24:22 +03:00 committed by Jordan West
parent f327b63db0
commit 17cb89208c
3 changed files with 72 additions and 12 deletions

View File

@ -162,8 +162,16 @@ public class ChunkCache
{
ByteBuffer buffer = bufferPool.get(key.file.chunkSize(), key.file.preferredBufferType());
assert buffer != null;
key.file.readChunk(key.position, buffer);
return new Buffer(buffer, key.position);
try
{
key.file.readChunk(key.position, buffer);
return new Buffer(buffer, key.position);
}
catch (Throwable t)
{
bufferPool.put(buffer);
throw t;
}
}
@Override

View File

@ -76,6 +76,11 @@ public class SSTableIdentityIterator implements Comparable<SSTableIdentityIterat
sstable.markSuspect();
throw new CorruptSSTableException(e, file.getPath());
}
catch (CorruptSSTableException e) // to ensure that we marked the sstable as suspected if CorruptSSTableException is thrown from lower levels
{
sstable.markSuspect();
throw e;
}
}
public static SSTableIdentityIterator create(SSTableReader sstable, FileDataInput dfile, long dataPosition, DecoratedKey key, boolean tombstoneOnly)
@ -99,6 +104,11 @@ public class SSTableIdentityIterator implements Comparable<SSTableIdentityIterat
sstable.markSuspect();
throw new CorruptSSTableException(e, dfile.getPath());
}
catch (CorruptSSTableException e) // to ensure that we marked the sstable as suspected if CorruptSSTableException is thrown from lower levels
{
sstable.markSuspect();
throw e;
}
}
public static SSTableIdentityIterator create(SSTableReader sstable, FileDataInput dfile, boolean tombstoneOnly)
@ -121,6 +131,11 @@ public class SSTableIdentityIterator implements Comparable<SSTableIdentityIterat
sstable.markSuspect();
throw new CorruptSSTableException(e, dfile.getPath());
}
catch (CorruptSSTableException e) // to ensure that we marked the sstable as suspected if CorruptSSTableException is thrown from lower levels
{
sstable.markSuspect();
throw e;
}
}
public TableMetadata metadata()
@ -164,6 +179,11 @@ public class SSTableIdentityIterator implements Comparable<SSTableIdentityIterat
sstable.markSuspect();
throw new CorruptSSTableException(e, filename);
}
catch (CorruptSSTableException e) // to ensure that we marked the sstable as suspected if CorruptSSTableException is thrown from lower levels
{
sstable.markSuspect();
throw e;
}
catch (IOError e)
{
if (e.getCause() instanceof IOException)
@ -192,6 +212,11 @@ public class SSTableIdentityIterator implements Comparable<SSTableIdentityIterat
sstable.markSuspect();
throw new CorruptSSTableException(e, filename);
}
catch (CorruptSSTableException e) // to ensure that we marked the sstable as suspected if CorruptSSTableException is thrown from lower levels
{
sstable.markSuspect();
throw e;
}
catch (IOError e)
{
if (e.getCause() instanceof IOException)
@ -240,6 +265,11 @@ public class SSTableIdentityIterator implements Comparable<SSTableIdentityIterat
sstable.markSuspect();
throw new CorruptSSTableException(e, filename);
}
catch (CorruptSSTableException e) // to ensure that we marked the sstable as suspected if CorruptSSTableException is thrown from lower levels
{
sstable.markSuspect();
throw e;
}
catch (IOError e)
{
if (e.getCause() instanceof IOException)

View File

@ -17,6 +17,8 @@
*/
package org.apache.cassandra.io.sstable.format;
import java.io.IOError;
import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
@ -148,19 +150,39 @@ implements ISSTableScanner
boolean advanceRange()
{
if (!rangeIterator.hasNext())
return false;
try
{
if (!rangeIterator.hasNext())
return false;
bytesScannedInPreviousRanges += currentEndPosition - currentStartPosition;
bytesScannedInPreviousRanges += currentEndPosition - currentStartPosition;
PartitionPositionBounds nextRange = rangeIterator.next();
if (currentEndPosition > nextRange.lowerPosition)
throw new IllegalArgumentException("Ranges supplied to SSTableSimpleScanner must be non-overlapping and in ascending order.");
PartitionPositionBounds nextRange = rangeIterator.next();
if (currentEndPosition > nextRange.lowerPosition)
throw new IllegalArgumentException("Ranges supplied to SSTableSimpleScanner must be non-overlapping and in ascending order.");
currentEndPosition = nextRange.upperPosition;
currentStartPosition = nextRange.lowerPosition;
dfile.seek(currentStartPosition);
return true;
currentEndPosition = nextRange.upperPosition;
currentStartPosition = nextRange.lowerPosition;
dfile.seek(currentStartPosition);
return true;
}
catch (CorruptSSTableException e)
{
sstable.markSuspect();
throw e;
}
catch (IOError e)
{
if (e.getCause() instanceof IOException)
{
sstable.markSuspect();
throw new CorruptSSTableException((Exception)e.getCause(), sstable.getFilename());
}
else
{
throw e;
}
}
}
public UnfilteredRowIterator next()