HBASE-27691 Prevent filters from seeing synthetic scan start cells - #8485
HBASE-27691 Prevent filters from seeing synthetic scan start cells#8485noslowerdna wants to merge 2 commits into
Conversation
|
@apurtell @virajjasani @Apache9 Would appreciate a review when you have a moment. |
|
@junegunn Would appreciate a review when you have a moment. Thanks! |
|
I could reproduce the problem locally: java_import org.apache.hadoop.hbase.CompareOperator
java_import org.apache.hadoop.hbase.filter.BinaryComparator
java_import org.apache.hadoop.hbase.filter.RowFilter
java_import org.apache.hadoop.hbase.filter.WhileMatchFilter
create 't', 'd'
put 't', 'row1', 'd:foo', 'bar'
put 't', 'row2', 'd:foo', 'bar'
put 't', 'row3', 'd:foo', 'bar'
flush 't'
# 3 rows
scan 't', FILTER => WhileMatchFilter.new(RowFilter.new(CompareOperator::NOT_EQUAL,
BinaryComparator.new(''.to_java_bytes)))
# no rows
scan 't', FILTER => WhileMatchFilter.new(RowFilter.new(CompareOperator::NOT_EQUAL,
BinaryComparator.new(''.to_java_bytes))),
COLUMNS => ['d:foo']The history behind this issue is quite involved, so I don't feel confident making a judgment call on my own. From what I understand, this patch was first suggested by Lars Hofhansl in early 2013: He raised a concern about the performance impact of eager seeks, but the question was never answered. Adding So the question still remains. Do you have a view on the performance impact? The eager seek is once per scanner open rather than per row, and scans without explicit columns already take that path, so it may well be fine. But it applies to every filtered explicit-column non-Get scan, so we should understand the cost before making it the default. To be clear, I am not suggesting we leave the bug unfixed. Correctness should take priority over performance. I would just like to understand the cost before we commit. |
HBASE-27691
What changes were proposed in this pull request?
This patch disables
StoreScanner's initial lazy seek for filtered non-Get scans. Doing so prevents synthetic lazy-seek Cells from being exposed to server-side Filters and Comparators, while retaining lazy seeking for unfiltered Scans and Gets.Why are the changes needed?
A region start boundary is not guaranteed to be a valid application row key. Passing its synthetic Cell to a
RowFiltercomparator violates the Filter contract thatfilterRowKeyreceives the first actual Cell of a row and can result in unexpected exceptions when Filter / Comparator code attempts to parse a seemingly truncated or otherwise malformed row key.In our case that manifested like this:
This change reinstates the protection intended by HBASE-6562, using its later proposed (unmerged) eager initial seek patch.
How was this patch tested?
A ROWCOL Bloom regression test verifies that a Comparator sees only the persisted row, not a synthetic region-boundary Cell. Focused tests also cover each lazy-seek decision branch.
mvn -ntp -pl hbase-server -am \ -Dtest=TestScanner \ -Dsurefire.failIfNoSpecifiedTests=false \ test