Repository: cassandra Updated Branches: refs/heads/trunk 9bfe61357 -> 6bc363726
Fix missing row data after range tombstone in legacy data patch by blambov; reviewed by slebresne for CASSANDRA-10822 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/71bac92c Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/71bac92c Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/71bac92c Branch: refs/heads/trunk Commit: 71bac92cf1df08de194a8283f382a7950b3a78ed Parents: 94e8d62 Author: Branimir Lambov <branimir.lam...@datastax.com> Authored: Thu Dec 10 15:33:15 2015 +0200 Committer: Sylvain Lebresne <sylv...@datastax.com> Committed: Mon Dec 14 10:57:20 2015 +0100 ---------------------------------------------------------------------- CHANGES.txt | 2 ++ .../org/apache/cassandra/db/UnfilteredDeserializer.java | 11 +++++------ .../cassandra/db/compaction/CompactionManager.java | 5 ++++- 3 files changed, 11 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/71bac92c/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index c30d35d..a0717c6 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,6 @@ 3.0.2 + * Fix upgrade data loss due to range tombstone deleting more data than then should + (CASSANDRA-10822) Merged from 2.2 * Add property to allow listening on broadcast interface (CASSANDRA-9748) * Fix regression in split size on CqlInputFormat (CASSANDRA-10835) http://git-wip-us.apache.org/repos/asf/cassandra/blob/71bac92c/src/java/org/apache/cassandra/db/UnfilteredDeserializer.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/UnfilteredDeserializer.java b/src/java/org/apache/cassandra/db/UnfilteredDeserializer.java index 66f6b71..bf9c2b8 100644 --- a/src/java/org/apache/cassandra/db/UnfilteredDeserializer.java +++ b/src/java/org/apache/cassandra/db/UnfilteredDeserializer.java @@ -406,7 +406,7 @@ public abstract class UnfilteredDeserializer public boolean hasNext() { - // Note that we loop on next == null because TombstoneTracker.openNew() could return null below. + // Note that we loop on next == null because TombstoneTracker.openNew() could return null below or the atom might be shadowed. while (next == null) { if (atoms.hasNext()) @@ -419,7 +419,8 @@ public abstract class UnfilteredDeserializer else { LegacyLayout.LegacyAtom atom = atoms.next(); - next = isRow(atom) ? readRow(atom) : tombstoneTracker.openNew(atom.asRangeTombstone()); + if (!tombstoneTracker.isShadowed(atom)) + next = isRow(atom) ? readRow(atom) : tombstoneTracker.openNew(atom.asRangeTombstone()); } } else if (tombstoneTracker.hasOpenTombstones()) @@ -498,7 +499,7 @@ public abstract class UnfilteredDeserializer if (isDone) return false; - while (next == null) + if (next == null) { next = readAtom(); if (next == null) @@ -506,9 +507,6 @@ public abstract class UnfilteredDeserializer isDone = true; return false; } - - if (tombstoneTracker.isShadowed(next)) - next = null; } return true; } @@ -576,6 +574,7 @@ public abstract class UnfilteredDeserializer */ public boolean isShadowed(LegacyLayout.LegacyAtom atom) { + assert !hasClosingMarkerBefore(atom); long timestamp = atom.isCell() ? atom.asCell().timestamp : atom.asRangeTombstone().deletionTime.markedForDeleteAt(); if (partitionDeletion.deletes(timestamp)) http://git-wip-us.apache.org/repos/asf/cassandra/blob/71bac92c/src/java/org/apache/cassandra/db/compaction/CompactionManager.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/compaction/CompactionManager.java b/src/java/org/apache/cassandra/db/compaction/CompactionManager.java index bd950e3..2234838 100644 --- a/src/java/org/apache/cassandra/db/compaction/CompactionManager.java +++ b/src/java/org/apache/cassandra/db/compaction/CompactionManager.java @@ -959,13 +959,16 @@ public class CompactionManager implements CompactionManagerMBean LifecycleTransaction txn) { FileUtils.createDirectory(compactionFileLocation); + SerializationHeader header = sstable.header; + if (header == null) + header = SerializationHeader.make(sstable.metadata, Collections.singleton(sstable)); return SSTableWriter.create(cfs.metadata, Descriptor.fromFilename(cfs.getSSTablePath(compactionFileLocation)), expectedBloomFilterSize, repairedAt, sstable.getSSTableLevel(), - sstable.header, + header, txn); }