Repository: cassandra Updated Branches: refs/heads/cassandra-3.1.1 [created] 8347d3771
Fix missing row data after range tombstone in legacy data patch by blambov; reviewed by slebresne for CASSANDRA-10822 Conflicts: CHANGES.txt Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/feaed2a4 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/feaed2a4 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/feaed2a4 Branch: refs/heads/cassandra-3.1.1 Commit: feaed2a4362500f2b79fc90a728b50656338af00 Parents: e092873 Author: Branimir Lambov <branimir.lam...@datastax.com> Authored: Thu Dec 10 15:33:15 2015 +0200 Committer: T Jake Luciani <j...@apache.org> Committed: Mon Dec 14 12:19:17 2015 -0500 ---------------------------------------------------------------------- CHANGES.txt | 4 ++++ .../org/apache/cassandra/db/UnfilteredDeserializer.java | 11 +++++------ .../cassandra/db/compaction/CompactionManager.java | 5 ++++- 3 files changed, 13 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/feaed2a4/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index a2e9434..dce2a06 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,7 @@ +3.1.1 + * Fix upgrade data loss due to range tombstone deleting more data than then should + (CASSANDRA-10822) + 3.1 Merged from 3.0: * Avoid MV race during node decommission (CASSANDRA-10674) http://git-wip-us.apache.org/repos/asf/cassandra/blob/feaed2a4/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/feaed2a4/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 3ce7d2c..0deaf44 100644 --- a/src/java/org/apache/cassandra/db/compaction/CompactionManager.java +++ b/src/java/org/apache/cassandra/db/compaction/CompactionManager.java @@ -958,13 +958,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); }