-
Notifications
You must be signed in to change notification settings - Fork 3.4k
HBASE-28390 WAL value compression fails for cells with large values #5696
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,6 +18,7 @@ | |
| package org.apache.hadoop.hbase.regionserver.wal; | ||
|
|
||
| import java.io.ByteArrayOutputStream; | ||
| import java.io.EOFException; | ||
| import java.io.IOException; | ||
| import java.io.InputStream; | ||
| import java.io.OutputStream; | ||
|
|
@@ -129,9 +130,25 @@ public void decompress(InputStream in, int inLength, byte[] outArray, int outOff | |
| } else { | ||
| lowerIn.reset(in, inLength); | ||
| IOUtils.readFully(compressedIn, outArray, outOffset, outLength); | ||
| // if the uncompressed size was larger than the configured buffer size for the codec, | ||
| // the BlockCompressorStream will have left an extra 4 bytes hanging. This represents a size | ||
| // for the next segment, and it should be 0. See HBASE-28390 | ||
| if (lowerIn.available() == 4) { | ||
| int remaining = rawReadInt(lowerIn); | ||
| assert remaining == 0; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private int rawReadInt(InputStream in) throws IOException { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm surprised commons-io or our own util code doesn't have something like this already.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried looking and couldn't find one. I'll try looking again
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Woops I think IOUtils.readInt should work. Any other comments/concerns other than that?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Left an approving review with the rest. Thanks!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, there is no IOUtils.readInt in commons-io. I realized that the IOUtils I was referring to (while on mobile) was a different library that we don't have a dependency on. We have a variety of methods for reading ints from byte[] or ByteBuffer, but not for InputStream that I can find. I could read the bytes into a byte[4] and use one of the utils, but I'd rather not allocate an unnecessary byte array. I'm going to leave this alone for now. |
||
| int b1 = in.read(); | ||
| int b2 = in.read(); | ||
| int b3 = in.read(); | ||
| int b4 = in.read(); | ||
| if ((b1 | b2 | b3 | b4) < 0) throw new EOFException(); | ||
| return ((b1 << 24) + (b2 << 16) + (b3 << 8) + (b4 << 0)); | ||
| } | ||
|
|
||
| public void clear() { | ||
| if (compressedOut != null) { | ||
| try { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part is ugly but I don't have an alternative suggestion. At least we know both in the WAL read and HFile read cases we won't be contending with a short read, so available is going to be either 0 or 4 and otherwise we'd have had an EOFException thrown.