[ 
https://issues.apache.org/jira/browse/HADOOP-3821?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12616731#action_12616731
 ] 

Hadoop QA commented on HADOOP-3821:
-----------------------------------

-1 overall.  Here are the results of testing the latest attachment 
  
http://issues.apache.org/jira/secure/attachment/12386788/HADOOP-3821_0_20080724.patch
  against trunk revision 679601.

    +1 @author.  The patch does not contain any @author tags.

    -1 tests included.  The patch doesn't appear to include any new or modified 
tests.
                        Please justify why no tests are needed for this patch.

    +1 javadoc.  The javadoc tool did not generate any warning messages.

    +1 javac.  The applied patch does not increase the total number of javac 
compiler warnings.

    +1 findbugs.  The patch does not introduce any new Findbugs warnings.

    +1 release audit.  The applied patch does not increase the total number of 
release audit warnings.

    +1 core tests.  The patch passed core unit tests.

    +1 contrib tests.  The patch passed contrib unit tests.

Test results: 
http://hudson.zones.apache.org/hudson/job/Hadoop-Patch/2943/testReport/
Findbugs warnings: 
http://hudson.zones.apache.org/hudson/job/Hadoop-Patch/2943/artifact/trunk/build/test/findbugs/newPatchFindbugsWarnings.html
Checkstyle results: 
http://hudson.zones.apache.org/hudson/job/Hadoop-Patch/2943/artifact/trunk/build/test/checkstyle-errors.html
Console output: 
http://hudson.zones.apache.org/hudson/job/Hadoop-Patch/2943/console

This message is automatically generated.

> SequenceFile's Reader.decompressorPool or Writer.decompressorPool gets into 
> an inconsistent state when calling close() more than once
> -------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: HADOOP-3821
>                 URL: https://issues.apache.org/jira/browse/HADOOP-3821
>             Project: Hadoop Core
>          Issue Type: Bug
>          Components: io
>    Affects Versions: 0.17.0, 0.17.1, 0.18.0, 0.19.0
>            Reporter: Peter Voss
>            Assignee: Arun C Murthy
>             Fix For: 0.19.0
>
>         Attachments: HADOOP-3821_0_20080724.patch
>
>
> SequenceFile.Reader uses a decompressorPool to reuse Decompressor instances. 
> The Reader obtains such an instance from the pool on object creation and 
> returns it back to the pool it when {{close()}} is called.
> SequenceFile.Reader implements the {{java.io.Closable}} interface and it's 
> spec on the {{close()}} method says:
> {quote}
> Closes this stream and releases any system resources associated 
> with it. If the stream is already closed then invoking this 
> method has no effect.
> {quote}
> This spec is violated by the Reader implementation, because calling 
> {{close()}} multiple times has really bad implications. 
> When you call {{close()}} twice, one and the same Decompressor instances will 
> be returned to the pool two times and the pool would now maintain duplicated 
> references to the same Decompressor instances. When other Readers now request 
> instances from the pool it might happen that two Readers get the same 
> Decompressor instance.
> The correct behavior would be to just ignore a second call to {{close()}}.
> The exact same issue applies to the SequenceFile.Writer as well.
> We were having big trouble with this, because we were observing sporadic 
> exceptions from merge operations. The strange thing was that executing the 
> same merge again usually succeeded. But sometimes it took multiple attempts 
> to complete a merge successfully. It was very hard to debug that the root 
> cause was some duplicated Decompressor references in the decompressorPool.
> Exceptions that we observed in production looked like this (we were using 
> hadoop 0.17.0):
> {noformat}
> java.io.IOException: unknown compression method
> at 
> org.apache.hadoop.io.compress.zlib.BuiltInZlibInflater.decompress(BuiltInZlibInflater.java:47)
> at 
> org.apache.hadoop.io.compress.DecompressorStream.decompress(DecompressorStream.java:80)
> at 
> org.apache.hadoop.io.compress.DecompressorStream.read(DecompressorStream.java:74)
> at java.io.DataInputStream.readFully(DataInputStream.java:178)
> at 
> org.apache.hadoop.io.DataOutputBuffer$Buffer.write(DataOutputBuffer.java:56)
> at org.apache.hadoop.io.DataOutputBuffer.write(DataOutputBuffer.java:90)
> at org.apache.hadoop.io.SequenceFile$Reader.nextRawKey(SequenceFile.java:1995)
> at 
> org.apache.hadoop.io.SequenceFile$Sorter$SegmentDescriptor.nextRawKey(SequenceFile.java:3002)
> at 
> org.apache.hadoop.io.SequenceFile$Sorter$MergeQueue.next(SequenceFile.java:2760)
> at org.apache.hadoop.io.SequenceFile$Sorter.writeFile(SequenceFile.java:2625)
> at org.apache.hadoop.io.SequenceFile$Sorter.merge(SequenceFile.java:2644)
> {noformat}
> or 
> {noformat}
> java.io.IOException: zero length keys not allowed
> at 
> org.apache.hadoop.io.SequenceFile$BlockCompressWriter.appendRaw(SequenceFile.java:1340)
> at org.apache.hadoop.io.SequenceFile$Sorter.writeFile(SequenceFile.java:2626)
> at org.apache.hadoop.io.SequenceFile$Sorter.merge(SequenceFile.java:2644)
> {noformat}
> The following snippet reproduces the problem:
> {code:java}
>     public void testCodecPool() throws IOException {
>         Configuration conf = new Configuration();
>         LocalFileSystem fs = new LocalFileSystem();
>         fs.setConf(conf);
>         fs.getRawFileSystem().setConf(conf);
>         // create a sequence file
>         Path path = new Path("target/seqFile");
>         SequenceFile.Writer writer = SequenceFile.createWriter(fs, conf, 
> path, Text.class, NullWritable.class, CompressionType.BLOCK);
>         writer.append(new Text("key1"), NullWritable.get());
>         writer.append(new Text("key2"), NullWritable.get());
>         writer.close();
>         // Create a reader which uses 4 BuiltInZLibInflater instances
>         SequenceFile.Reader reader = new SequenceFile.Reader(fs, path, conf);
>         // Returns the 4 BuiltInZLibInflater instances to the CodecPool
>         reader.close();
>         // The second close erroneously returns the same 4 
> BuiltInZLibInflater instances to the CodecPool again
>         reader.close();
>         // The first reader gets 4 BuiltInZLibInflater instances from the 
> CodecPool
>         SequenceFile.Reader reader1 = new SequenceFile.Reader(fs, path, conf);
>         // read first value from reader1
>         Text text = new Text();
>         reader1.next(text);
>         assertEquals("key1", text.toString());
>         // The second reader gets the same 4 BuiltInZLibInflater instances 
> from the CodePool as reader1
>         SequenceFile.Reader reader2 = new SequenceFile.Reader(fs, path, conf);
>         // read first value from reader2
>         reader2.next(text);
>         assertEquals("key1", text.toString());
>         // read second value from reader1
>         reader1.next(text);
>         assertEquals("key2", text.toString());
>         // read second value from reader2 (this throws an exception)
>         reader2.next(text);
>         assertEquals("key2", text.toString());
>         
>         assertFalse(reader1.next(text));
>         assertFalse(reader2.next(text));
>     }
> {code}
> It fails with the exception:
> {noformat}
> java.io.EOFException
>       at java.io.DataInputStream.readByte(DataInputStream.java:243)
>       at org.apache.hadoop.io.WritableUtils.readVLong(WritableUtils.java:324)
>       at org.apache.hadoop.io.WritableUtils.readVInt(WritableUtils.java:345)
>       at org.apache.hadoop.io.SequenceFile$Reader.next(SequenceFile.java:1835)
>       at CodecPoolTest.testCodecPool(CodecPoolTest.java:56)
> {noformat}
> But this is just a very simple test that shows the problem. Much more weired 
> things can happen when running in a complex production environment. Esp. 
> heavy concurrency makes the behavior much more exciting. ;-)

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to