chia7712 commented on code in PR #23318:
URL: https://github.com/apache/kafka/pull/23318#discussion_r4162879220


##########
core/src/main/scala/kafka/server/AbstractFetcherThread.scala:
##########
@@ -501,25 +408,29 @@ abstract class AbstractFetcherThread(name: String,
   }
 
   /**
-   * Returns initial partition fetch state based on current state and the 
provided `initialFetchState`.
-   * From IBP 2.7 onwards, we can rely on truncation based on diverging data 
returned in fetch responses.
-   * For older versions, we can skip the truncation step iff the leader epoch 
matches the existing epoch.
+   * Returns the initial partition fetch state based on the current state and 
the provided
+   * `initialFetchState`.
+   *
+   * If the current state already has the same leader epoch, it is preserved. 
Otherwise, the
+   * partition starts from `initOffset`.
+   *
+   * When `latestEpoch` is present, the partition starts in the Fetching 
state. Any log divergence is
+   * reported by the leader as a diverging epoch in the fetch response and 
handled by
+   * `truncateOnFetchResponse`.
+   *
+   * If `latestEpoch` is empty (for example, when the log contains only 
records in a message format
+   * older than v2), the fetch request carries no last fetched epoch and the 
leader cannot report a
+   * diverging epoch. In this case, the partition starts in the Truncating 
state, so that
+   * `maybeTruncate()` truncates its log to `initOffset`, which is the high 
watermark.
    */
   private def partitionFetchState(tp: TopicPartition, initialFetchState: 
InitialFetchState, currentState: PartitionFetchState): PartitionFetchState = {
     if (currentState != null && currentState.currentLeaderEpoch == 
initialFetchState.currentLeaderEpoch) {
       currentState
-    } else if (initialFetchState.initOffset < 0) {
-      fetchOffsetAndTruncate(tp, initialFetchState.topicId, 
initialFetchState.currentLeaderEpoch)
-    } else if (leader.isTruncationOnFetchSupported) {
-      // With old message format, `latestEpoch` will be empty and we use 
Truncating state
-      // to truncate to high watermark.
+    } else {
       val lastFetchedEpoch = latestEpoch(tp)
       val state = if (lastFetchedEpoch.isPresent) ReplicaState.FETCHING else 
ReplicaState.TRUNCATING
-      new PartitionFetchState(initialFetchState.topicId.toJava, 
initialFetchState.initOffset, Optional.empty(), 
initialFetchState.currentLeaderEpoch,
-        state, lastFetchedEpoch)
-    } else {

Review Comment:
   It seems to be a bug for a future log with LEO > HWM, which is common when 
the future log has caught up but the current replica still has uncommitted 
data. The first fetch will cause the exception shown below.
   ```java
       if (fetchOffset != futureLog.logEndOffset)
         throw new IllegalStateException("Offset mismatch for the future 
replica %s: fetched offset = %d, log end offset = %d.".format(
           topicPartition, fetchOffset, futureLog.logEndOffset))
   ```
   
   It was handled by the truncating phase (`getOffsetTruncationState` overrides 
the initial offset), but that phase is now removed by this PR. I think we need 
to update `ReplicaManager` to let `InitialFetchState` use 
`initialFetchOffset(futureLog)` instead of HWM, same as the follower path.
   
   ```java
             futureReplicasAndInitialOffset.put(topicPartition, 
InitialFetchState(topicIds(topicPartition.topic), leader,
               partition.getLeaderEpoch, futureLog.highWatermark))
   
               val initialFetchState = InitialFetchState(topicId.toScala, new 
BrokerEndPoint(config.brokerId, "localhost", -1),
                 partition.getLeaderEpoch, futureLog.highWatermark)
   
   ```



##########
core/src/main/scala/kafka/server/AbstractFetcherThread.scala:
##########
@@ -144,144 +142,71 @@ abstract class AbstractFetcherThread(name: String,
   }
 
   /**
-   * Builds offset for leader epoch requests for partitions that are in the 
truncating phase based
-   * on latest epochs of the future replicas (the one that is fetching)
+   * Truncate the log of every partition in the truncating state to its fetch 
offset, which is the
+   * high watermark. A partition only enters that state when the follower has 
no leader epoch, i.e.

Review Comment:
   The empty log also enters this state, right?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to