diff --git a/CHANGES.txt b/CHANGES.txt index 7126f53e72..1777b8dd99 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -8,6 +8,7 @@ * Make sure sstables with moved starts are removed correctly in LeveledGenerations (CASSANDRA-16552) * Upgrade jackson-databind to 2.9.10.8 (CASSANDRA-16462) Merged from 3.0: + * Clean transaction log leftovers at the beginning of sstablelevelreset and sstableofflinerelevel (CASSANDRA-12519) * CQL shell should prefer newer TLS version by default (CASSANDRA-16695) * Ensure that existing empty rows are properly returned (CASSANDRA-16671) * Invalidate prepared statements on DROP COMPACT (CASSANDRA-16712) diff --git a/src/java/org/apache/cassandra/tools/SSTableLevelResetter.java b/src/java/org/apache/cassandra/tools/SSTableLevelResetter.java index 915edf12b7..40cdd7b2e8 100644 --- a/src/java/org/apache/cassandra/tools/SSTableLevelResetter.java +++ b/src/java/org/apache/cassandra/tools/SSTableLevelResetter.java @@ -22,6 +22,7 @@ import java.util.Map; import java.util.Set; import org.apache.cassandra.config.Schema; +import org.apache.cassandra.db.lifecycle.LifecycleTransaction; import org.apache.cassandra.db.ColumnFamilyStore; import org.apache.cassandra.db.Directories; import org.apache.cassandra.db.Keyspace; @@ -75,10 +76,19 @@ public class SSTableLevelResetter System.exit(1); } + // remove any leftovers in the transaction log Keyspace keyspace = Keyspace.openWithoutSSTables(keyspaceName); ColumnFamilyStore cfs = keyspace.getColumnFamilyStore(columnfamily); + if (!LifecycleTransaction.removeUnfinishedLeftovers(cfs)) + { + throw new RuntimeException(String.format("Cannot remove temporary or obsoleted files for %s.%s " + + "due to a problem with transaction log files.", + keyspace, columnfamily)); + } + + Directories.SSTableLister lister = cfs.getDirectories().sstableLister(Directories.OnTxnErr.THROW).skipTemporary(true); boolean foundSSTable = false; - for (Map.Entry> sstable : cfs.getDirectories().sstableLister(Directories.OnTxnErr.THROW).list().entrySet()) + for (Map.Entry> sstable : lister.list().entrySet()) { if (sstable.getValue().contains(Component.STATS)) { diff --git a/src/java/org/apache/cassandra/tools/SSTableOfflineRelevel.java b/src/java/org/apache/cassandra/tools/SSTableOfflineRelevel.java index 9f0395b0fc..ae0242cfd6 100644 --- a/src/java/org/apache/cassandra/tools/SSTableOfflineRelevel.java +++ b/src/java/org/apache/cassandra/tools/SSTableOfflineRelevel.java @@ -35,6 +35,7 @@ import com.google.common.collect.Multimap; import com.google.common.collect.SetMultimap; import org.apache.cassandra.config.Schema; +import org.apache.cassandra.db.lifecycle.LifecycleTransaction; import org.apache.cassandra.db.ColumnFamilyStore; import org.apache.cassandra.db.DecoratedKey; import org.apache.cassandra.db.Directories; @@ -97,8 +98,16 @@ public class SSTableOfflineRelevel keyspace, columnfamily)); + // remove any leftovers in the transaction log Keyspace ks = Keyspace.openWithoutSSTables(keyspace); ColumnFamilyStore cfs = ks.getColumnFamilyStore(columnfamily); + if (!LifecycleTransaction.removeUnfinishedLeftovers(cfs)) + { + throw new RuntimeException(String.format("Cannot remove temporary or obsoleted files for %s.%s " + + "due to a problem with transaction log files.", + keyspace, columnfamily)); + } + Directories.SSTableLister lister = cfs.getDirectories().sstableLister(Directories.OnTxnErr.THROW).skipTemporary(true); SetMultimap sstableMultimap = HashMultimap.create(); for (Map.Entry> sstable : lister.list().entrySet())