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();