Use live sstables in snapshot repair if possible

patch by Jimmy Mårdell; reviewed by yukim for CASSANDRA-8312
This commit is contained in:
Jimmy Mårdell 2014-12-04 09:59:34 -06:00 committed by Yuki Morishita
parent 4030088ec1
commit ceed3a20ef
3 changed files with 38 additions and 12 deletions

View File

@ -30,6 +30,7 @@
* Fix totalDiskSpaceUsed calculation (CASSANDRA-8205)
* Add DC-aware sequential repair (CASSANDRA-8193)
* Improve JBOD disk utilization (CASSANDRA-7386)
* Use live sstables in snapshot repair if possible (CASSANDRA-8312)
2.0.11:

View File

@ -1840,10 +1840,40 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean
public List<SSTableReader> getSnapshotSSTableReader(String tag) throws IOException
{
Map<Integer, SSTableReader> active = new HashMap<>();
for (SSTableReader sstable : data.getView().sstables)
active.put(sstable.descriptor.generation, sstable);
Map<Descriptor, Set<Component>> snapshots = directories.sstableLister().snapshots(tag).list();
List<SSTableReader> readers = new ArrayList<SSTableReader>(snapshots.size());
for (Map.Entry<Descriptor, Set<Component>> entries : snapshots.entrySet())
readers.add(SSTableReader.open(entries.getKey(), entries.getValue(), metadata, partitioner));
List<SSTableReader> readers = new ArrayList<>(snapshots.size());
try
{
for (Map.Entry<Descriptor, Set<Component>> entries : snapshots.entrySet())
{
// Try acquire reference to an active sstable instead of snapshot if it exists,
// to avoid opening new sstables. If it fails, use the snapshot reference instead.
SSTableReader sstable = active.get(entries.getKey().generation);
if (sstable == null || !sstable.acquireReference())
{
if (logger.isDebugEnabled())
logger.debug("using snapshot sstable " + entries.getKey());
sstable = SSTableReader.open(entries.getKey(), entries.getValue(), metadata, partitioner);
// This is technically not necessary since it's a snapshot but makes things easier
sstable.acquireReference();
}
else if (logger.isDebugEnabled())
{
logger.debug("using active sstable " + entries.getKey());
}
readers.add(sstable);
}
}
catch (IOException | RuntimeException e)
{
// In case one of the snapshot sstables fails to open,
// we must release the references to the ones we opened so far
SSTableReader.releaseReferences(readers);
throw e;
}
return readers;
}

View File

@ -765,8 +765,8 @@ public class CompactionManager implements CompactionManagerMBean
sstables = cfs.getSnapshotSSTableReader(snapshotName);
// Computing gcbefore based on the current time wouldn't be very good because we know each replica will execute
// this at a different time (that's the whole purpose of repair with snaphsot). So instead we take the creation
// time of the snapshot, which should give us roughtly the same time on each replica (roughtly being in that case
// this at a different time (that's the whole purpose of repair with snapshot). So instead we take the creation
// time of the snapshot, which should give us roughly the same time on each replica (roughly being in that case
// 'as good as in the non-snapshot' case)
gcBefore = cfs.gcBefore(cfs.getSnapshotCreationTime(snapshotName));
}
@ -803,16 +803,11 @@ public class CompactionManager implements CompactionManagerMBean
finally
{
iter.close();
SSTableReader.releaseReferences(sstables);
if (isSnapshotValidation)
{
for (SSTableReader sstable : sstables)
FileUtils.closeQuietly(sstable);
cfs.clearSnapshot(snapshotName);
}
else
{
SSTableReader.releaseReferences(sstables);
}
metrics.finishCompaction(ci);
}
@ -956,7 +951,7 @@ public class CompactionManager implements CompactionManagerMBean
public void afterExecute(Runnable r, Throwable t)
{
DebuggableThreadPoolExecutor.maybeResetTraceSessionWrapper(r);
if (t == null)
t = DebuggableThreadPoolExecutor.extractThrowable(r);