Skip to content

Comments

HBASE-29890 WAL tailing reader should resume partial cell reads instead of resetting compression#7741

Open
sidkhillon wants to merge 4 commits intoapache:masterfrom
HubSpot:reset-last-read-for-upstream
Open

HBASE-29890 WAL tailing reader should resume partial cell reads instead of resetting compression#7741
sidkhillon wants to merge 4 commits intoapache:masterfrom
HubSpot:reset-last-read-for-upstream

Conversation

@sidkhillon
Copy link
Contributor

@sidkhillon sidkhillon commented Feb 11, 2026

When the WAL tailing reader hits EOF mid-cell during WAL compression, it currently returns EOF_AND_RESET_COMPRESSION, which forces the reader to re-read the entire WAL file from the beginning to rebuild dictionary state. This is an O(n) operation that becomes increasingly expensive as the WAL grows.

The root cause is that the CompressedKvDecoder eagerly adds entries to the compression dictionaries (ROW, FAMILY, QUALIFIER, and tag dictionaries) as it reads each field of a cell. If an IOException occurs partway through reading a cell, the dictionaries are left in a partially-updated state that no longer matches the actual stream position. The reader has no choice but to throw away the entire compression context and start over.

Proposed Fix is to defer dictionary additions until a cell is fully parsed:

  • Buffer ROW/FAMILY/QUALIFIER dictionary additions in CompressedKvDecoder and only commit them after parseCellInner() succeeds. On IOException, discard the pending additions.
  • Add a similar deferred-addition mode to TagCompressionContext for tag dictionaries.
  • Reset the ValueCompressor if an IOException occurs during the value decompression phase.

With deferred additions, hitting EOF mid-cell leaves the dictionaries in the state they were after the last fully-read cell. This means the reader can return EOF_AND_RESET (a cheap seek to the saved position) instead of EOF_AND_RESET_COMPRESSION, and resume reading from where it left off once the file grows.

@sidkhillon sidkhillon changed the title [HBASE-29890] WAL tailing reader should resume partial cell reads instead of resetting compression HBASE-29890 WAL tailing reader should resume partial cell reads instead of resetting compression Feb 11, 2026
@sidkhillon
Copy link
Contributor Author

cc @Apache9, I would really appreciate any feedback you have on this PR. Thank you!

@sidkhillon sidkhillon force-pushed the reset-last-read-for-upstream branch from 9d57c06 to 874e4ff Compare February 13, 2026 19:34

private byte[] getDeferredOrDictEntry(short dictIdx) {
if (deferAdditions) {
int deferredIdx = dictIdx - deferredBaseIndex;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this algorithm always right?

The Dictionary interface does not guarantee that the newly added entry will have the current size as its index, and in the implementation, LRUDictionary may move entries when it is being accessed...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. I have created an UndoableLRUDictionary that will let us rollback changes to the dictionary, and I've added many scenarios to test it out as unit tests. Please let me know how that looks.

@sidkhillon
Copy link
Contributor Author

@Apache9 I've addressed the PR feedback you left, and I would really appreciate another review when you have the chance. Thank you!

@sidkhillon sidkhillon requested a review from Apache9 February 23, 2026 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants