You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2011/03/09 21:52:03 UTC

svn commit: r1079989 - in /cassandra/branches/cassandra-0.7: CHANGES.txt conf/cassandra.yaml src/java/org/apache/cassandra/db/commitlog/CommitLog.java test/unit/org/apache/cassandra/db/CommitLogTest.java

Author: jbellis
Date: Wed Mar  9 20:52:03 2011
New Revision: 1079989

URL: http://svn.apache.org/viewvc?rev=1079989&view=rev
Log:
fix commitlog replaywhen flush position refers to data thatdidnt

Modified:
    cassandra/branches/cassandra-0.7/CHANGES.txt
    cassandra/branches/cassandra-0.7/conf/cassandra.yaml
    cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/commitlog/CommitLog.java
    cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/db/CommitLogTest.java

Modified: cassandra/branches/cassandra-0.7/CHANGES.txt
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/CHANGES.txt?rev=1079989&r1=1079988&r2=1079989&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/CHANGES.txt (original)
+++ cassandra/branches/cassandra-0.7/CHANGES.txt Wed Mar  9 20:52:03 2011
@@ -16,6 +16,8 @@
  * avoid writing empty rows when scrubbing tombstoned rows (CASSANDRA-2296)
  * fix assertion error in range and index scans for CL < ALL
    (CASSANDRA-2282)
+ * fix commitlog replay when flush position refers to data that didn't
+   get synced before server died (CASSANDRA-2285)
 
 
 0.7.3

Modified: cassandra/branches/cassandra-0.7/conf/cassandra.yaml
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/conf/cassandra.yaml?rev=1079989&r1=1079988&r2=1079989&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/conf/cassandra.yaml (original)
+++ cassandra/branches/cassandra-0.7/conf/cassandra.yaml Wed Mar  9 20:52:03 2011
@@ -87,7 +87,7 @@ commitlog_rotation_threshold_in_mb: 128
 # performing the sync.
 commitlog_sync: periodic
 
-# the other option is "timed," where writes may be acked immediately
+# the other option is "periodic" where writes may be acked immediately
 # and the CommitLog is simply synced every commitlog_sync_period_in_ms
 # milliseconds.
 commitlog_sync_period_in_ms: 10000

Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/commitlog/CommitLog.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/commitlog/CommitLog.java?rev=1079989&r1=1079988&r2=1079989&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/commitlog/CommitLog.java (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/commitlog/CommitLog.java Wed Mar  9 20:52:03 2011
@@ -190,11 +190,14 @@ public class CommitLog
                     logger.info(headerPath + " incomplete, missing or corrupt.  Everything is ok, don't panic.  CommitLog will be replayed from the beginning");
                     logger.debug("exception was", ioe);
                 }
-                if (replayPosition < 0)
+                if (replayPosition < 0 || replayPosition > reader.length())
                 {
+                    // replayPosition > reader.length() can happen if some data gets flushed before it is written to the commitlog
+                    // (see https://issues.apache.org/jira/browse/CASSANDRA-2285)
                     logger.debug("skipping replay of fully-flushed {}", file);
                     continue;
                 }
+
                 reader.seek(replayPosition);
 
                 if (logger.isDebugEnabled())

Modified: cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/db/CommitLogTest.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/db/CommitLogTest.java?rev=1079989&r1=1079988&r2=1079989&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/db/CommitLogTest.java (original)
+++ cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/db/CommitLogTest.java Wed Mar  9 20:52:03 2011
@@ -108,6 +108,30 @@ public class CommitLogTest extends Clean
         testRecoveryWithBadSizeArgument(-10, 10); // negative size, but no EOF
     }
 
+    @Test
+    public void testRecoveryWithHeaderPositionGreaterThanLogLength() throws Exception
+    {
+        // Note: this can actually happen (in periodic mode) when data is flushed
+        // before it had time to hit the commitlog (since the header is flushed by the system)
+        // see https://issues.apache.org/jira/browse/CASSANDRA-2285
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        DataOutputStream dos = new DataOutputStream(out);
+        Checksum checksum = new CRC32();
+
+        // write the first checksum after the fixed-size part, so we won't read garbage lastFlushedAt data.
+        dos.writeInt(1);
+        checksum.update(1);
+        dos.writeLong(checksum.getValue());
+        dos.writeInt(0);
+        checksum.update(0);
+        dos.writeInt(200);
+        checksum.update(200);
+        dos.writeLong(checksum.getValue());
+        dos.close();
+
+        testRecovery(out.toByteArray(), new byte[0]);
+    }
+
     protected void testRecoveryWithBadSizeArgument(int size, int dataSize) throws Exception
     {
         Checksum checksum = new CRC32();