-
Notifications
You must be signed in to change notification settings - Fork 29.3k
[SPARK-21271][SQL] Ensure Unsafe.sizeInBytes is a multiple of 8 #18503
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 9 commits
eb87c63
6cde32f
ccc820f
3bd72c9
8a7a948
7f5a269
762f02a
0159701
54be80e
cc467de
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 |
|---|---|---|
|
|
@@ -167,6 +167,7 @@ public UnsafeRow() {} | |
| */ | ||
| public void pointTo(Object baseObject, long baseOffset, int sizeInBytes) { | ||
| assert numFields >= 0 : "numFields (" + numFields + ") should >= 0"; | ||
| assert sizeInBytes % 8 == 0 : "sizeInBytes (" + sizeInBytes + ") should be a multiple of 8"; | ||
|
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 think we only need the assertion here, in
Member
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. Yes, done. |
||
| this.baseObject = baseObject; | ||
| this.baseOffset = baseOffset; | ||
| this.sizeInBytes = sizeInBytes; | ||
|
|
@@ -183,6 +184,7 @@ public void pointTo(byte[] buf, int sizeInBytes) { | |
| } | ||
|
|
||
| public void setTotalSize(int sizeInBytes) { | ||
| assert sizeInBytes % 8 == 0 : "sizeInBytes (" + sizeInBytes + ") should be a multiple of 8"; | ||
| this.sizeInBytes = sizeInBytes; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -363,7 +363,11 @@ private[state] class HDFSBackedStateStoreProvider extends StateStoreProvider wit | |
| val valueRowBuffer = new Array[Byte](valueSize) | ||
| ByteStreams.readFully(input, valueRowBuffer, 0, valueSize) | ||
| val valueRow = new UnsafeRow(valueSchema.fields.length) | ||
| valueRow.pointTo(valueRowBuffer, valueSize) | ||
| // If valueSize in existing file is not multiple of 8, floor it to multiple of 8. | ||
| // This is work around for the following. | ||
|
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. nit: |
||
| // Pre-Spark 2.3 mistakenly append 4 bytes to the value row in | ||
|
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. nit: |
||
| // `FixedLengthRowBasedKeyValueBatch`, which gets persisted into the checkpoint data | ||
|
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. and |
||
| valueRow.pointTo(valueRowBuffer, (valueSize / 8) * 8) | ||
|
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. Nit: This isnt rounding. This essentially floor to the multiple of 8.
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. yes, because the extra bytes that exceed the 8-bytes boundary in @kiszk can we add more comments to explain why this can happen? We should say that before Spark 2.3 we mistakenly append 4 bytes to the value row in aggregate buffer, which gets persisted into the checkpoint data and so on
Member
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. Sure, added more comments.
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. @cloud-fan @kiszk Just to confirm again, are we absolutely sure that the issue is that there 4 extra bytes in checkpointed rows, and therefore this truncation is safe to do?
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. yes I'm absolutely sure, as we store aggregate buffers in checkpoint files. BTW, I run this test without the workaround here, and it can still pass. Which means, after this PR, And I also run the test without the fix for |
||
| map.put(keyRow, valueRow) | ||
| } | ||
| } | ||
|
|
@@ -427,7 +431,11 @@ private[state] class HDFSBackedStateStoreProvider extends StateStoreProvider wit | |
| val valueRowBuffer = new Array[Byte](valueSize) | ||
| ByteStreams.readFully(input, valueRowBuffer, 0, valueSize) | ||
| val valueRow = new UnsafeRow(valueSchema.fields.length) | ||
| valueRow.pointTo(valueRowBuffer, valueSize) | ||
| // If valueSize in existing file is not multiple of 8, floor it to multiple of 8. | ||
| // This is work around for the following. | ||
| // Pre-Spark 2.3 mistakenly append 4 bytes to the value row in | ||
| // `FixedLengthRowBasedKeyValueBatch`, which gets persisted into the checkpoint data | ||
| valueRow.pointTo(valueRowBuffer, (valueSize / 8) * 8) | ||
| map.put(keyRow, valueRow) | ||
| } | ||
| } | ||
|
|
||
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.
I'm wondering why we did this before. Was it a mistake?
Uh oh!
There was an error while loading. Please reload this page.
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.
I have the same question.
@sameeragarwal had similar question one year ago. However, no response from @ooq
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.
I recall it being intentional.
See discussion here.
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.
@ooq thank you for pointing out interesting discussion.
This discussion seems to make sense for page management. The question of @cloud-fan and me is whether
valueRowuses onlyvlen. I think that+4is for page management.