-
Notifications
You must be signed in to change notification settings - Fork 15.4k
KAFKA-9491; Increment high watermark after full log truncation #8037
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 |
|---|---|---|
|
|
@@ -301,7 +301,7 @@ class Log(@volatile var dir: File, | |
|
|
||
| leaderEpochCache.foreach(_.truncateFromEnd(nextOffsetMetadata.messageOffset)) | ||
|
|
||
| logStartOffset = math.max(logStartOffset, segments.firstEntry.getValue.baseOffset) | ||
| updateLogStartOffset(math.max(logStartOffset, segments.firstEntry.getValue.baseOffset)) | ||
|
|
||
| // The earliest leader epoch may not be flushed during a hard failure. Recover it here. | ||
| leaderEpochCache.foreach(_.truncateFromStart(logStartOffset)) | ||
|
|
@@ -721,14 +721,30 @@ class Log(@volatile var dir: File, | |
| } | ||
| } | ||
|
|
||
| private def updateLogEndOffset(messageOffset: Long): Unit = { | ||
| nextOffsetMetadata = LogOffsetMetadata(messageOffset, activeSegment.baseOffset, activeSegment.size) | ||
| private def updateLogEndOffset(offset: Long): Unit = { | ||
| nextOffsetMetadata = LogOffsetMetadata(offset, activeSegment.baseOffset, activeSegment.size) | ||
|
|
||
| // Update the high watermark in case it has gotten ahead of the log end offset following a truncation | ||
| // or if a new segment has been rolled and the offset metadata needs to be updated. | ||
| if (highWatermark >= messageOffset) { | ||
| if (highWatermark >= offset) { | ||
| updateHighWatermarkMetadata(nextOffsetMetadata) | ||
| } | ||
|
|
||
| if (this.recoveryPoint > offset) { | ||
| this.recoveryPoint = offset | ||
| } | ||
| } | ||
|
|
||
| private def updateLogStartOffset(offset: Long): Unit = { | ||
| logStartOffset = offset | ||
|
|
||
| if (highWatermark < offset) { | ||
| updateHighWatermark(offset) | ||
| } | ||
|
|
||
| if (this.recoveryPoint < offset) { | ||
|
Member
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. Is there a case that recoveryPoint gets smaller than logStartOffset? If yes, is it ok to just move the recoveryPoint without flush? If not, is it worthy to throw exception or log this weird case?
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. Is a recovery point lower than the log start offset useful? All data below the log start offset is subject to deletion.
Member
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. U are right :) |
||
| this.recoveryPoint = offset | ||
| } | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -1242,7 +1258,7 @@ class Log(@volatile var dir: File, | |
| checkIfMemoryMappedBufferClosed() | ||
| if (newLogStartOffset > logStartOffset) { | ||
| info(s"Incrementing log start offset to $newLogStartOffset") | ||
| logStartOffset = newLogStartOffset | ||
| updateLogStartOffset(newLogStartOffset) | ||
| leaderEpochCache.foreach(_.truncateFromStart(logStartOffset)) | ||
| producerStateManager.truncateHead(newLogStartOffset) | ||
| maybeIncrementFirstUnstableOffset() | ||
|
|
@@ -2046,8 +2062,7 @@ class Log(@volatile var dir: File, | |
| removeAndDeleteSegments(deletable, asyncDelete = true) | ||
| activeSegment.truncateTo(targetOffset) | ||
| updateLogEndOffset(targetOffset) | ||
| this.recoveryPoint = math.min(targetOffset, this.recoveryPoint) | ||
| this.logStartOffset = math.min(targetOffset, this.logStartOffset) | ||
| updateLogStartOffset(math.min(targetOffset, this.logStartOffset)) | ||
| leaderEpochCache.foreach(_.truncateFromEnd(targetOffset)) | ||
| loadProducerState(targetOffset, reloadFromCleanShutdown = false) | ||
| } | ||
|
|
@@ -2081,9 +2096,7 @@ class Log(@volatile var dir: File, | |
| producerStateManager.truncate() | ||
| producerStateManager.updateMapEndOffset(newOffset) | ||
| maybeIncrementFirstUnstableOffset() | ||
|
|
||
| this.recoveryPoint = math.min(newOffset, this.recoveryPoint) | ||
| this.logStartOffset = newOffset | ||
| updateLogStartOffset(newOffset) | ||
|
Member
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. Previous behavior is which is equal to
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 have also updated
Member
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. Thanks for the explanation! |
||
| } | ||
| } | ||
| } | ||
|
|
||
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.
resetLastCaughtUpTimetakescurLeaderLogEndOffset, but we are now passingleaderEpochStartOffset. Do we need to update the parameter name of that method?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.
They are the same thing. I just got rid of a redundant variable.
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.
Ok, I see.