Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions core/src/main/scala/kafka/cluster/Partition.scala
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ class Partition(val topicPartition: TopicPartition,
newAssignedReplicas.foreach(id => getOrCreateReplica(id, partitionStateInfo.isNew))

val leaderReplica = localReplicaOrException
val leaderEpochStartOffset = leaderReplica.logEndOffset.messageOffset
val leaderEpochStartOffset = leaderReplica.logEndOffset
info(s"$topicPartition starts at Leader Epoch ${partitionStateInfo.basePartitionState.leaderEpoch} from " +
s"offset $leaderEpochStartOffset. Previous Leader Epoch was: $leaderEpoch")

Expand All @@ -399,7 +399,7 @@ class Partition(val topicPartition: TopicPartition,
}

val isNewLeader = !leaderReplicaIdOpt.contains(localBrokerId)
val curLeaderLogEndOffset = leaderReplica.logEndOffset.messageOffset
val curLeaderLogEndOffset = leaderReplica.logEndOffset
val curTimeMs = time.milliseconds
// initialize lastCaughtUpTime of replicas as well as their lastFetchTimeMs and lastFetchLeaderLogEndOffset.
(assignedReplicas - leaderReplica).foreach { replica =>
Expand Down Expand Up @@ -510,7 +510,7 @@ class Partition(val topicPartition: TopicPartition,
val fetchOffset = logReadResult.info.fetchOffsetMetadata.messageOffset
if (!inSyncReplicas.contains(replica) &&
assignedReplicas.map(_.brokerId).contains(replicaId) &&
replica.logEndOffset.offsetDiff(leaderHW) >= 0 &&
replica.logEndOffsetMetadata.offsetDiff(leaderHW) >= 0 &&
leaderEpochStartOffsetOpt.exists(fetchOffset >= _)) {
val newInSyncReplicas = inSyncReplicas + replica
info(s"Expanding ISR from ${inSyncReplicas.map(_.brokerId).mkString(",")} " +
Expand Down Expand Up @@ -542,9 +542,9 @@ class Partition(val topicPartition: TopicPartition,
val curInSyncReplicas = inSyncReplicas

if (isTraceEnabled) {
def logEndOffsetString(r: Replica) = s"broker ${r.brokerId}: ${r.logEndOffset.messageOffset}"
def logEndOffsetString(r: Replica) = s"broker ${r.brokerId}: ${r.logEndOffset}"
val (ackedReplicas, awaitingReplicas) = curInSyncReplicas.partition { replica =>
replica.logEndOffset.messageOffset >= requiredOffset
replica.logEndOffset >= requiredOffset
}
trace(s"Progress awaiting ISR acks for offset $requiredOffset: acked: ${ackedReplicas.map(logEndOffsetString)}, " +
s"awaiting ${awaitingReplicas.map(logEndOffsetString)}")
Expand Down Expand Up @@ -588,7 +588,7 @@ class Partition(val topicPartition: TopicPartition,
private def maybeIncrementLeaderHW(leaderReplica: Replica, curTime: Long = time.milliseconds): Boolean = {
val allLogEndOffsets = assignedReplicas.filter { replica =>
curTime - replica.lastCaughtUpTimeMs <= replicaLagTimeMaxMs || inSyncReplicas.contains(replica)
}.map(_.logEndOffset)
}.map(_.logEndOffsetMetadata)
val newHighWatermark = allLogEndOffsets.min(new LogOffsetMetadata.OffsetOrdering)
val oldHighWatermark = leaderReplica.highWatermark

Expand All @@ -600,7 +600,7 @@ class Partition(val topicPartition: TopicPartition,
debug(s"High watermark updated to $newHighWatermark")
true
} else {
def logEndOffsetString(r: Replica) = s"replica ${r.brokerId}: ${r.logEndOffset}"
def logEndOffsetString(r: Replica) = s"replica ${r.brokerId}: ${r.logEndOffsetMetadata}"
debug(s"Skipping update high watermark since new hw $newHighWatermark is not larger than old hw $oldHighWatermark. " +
s"All current LEOs are ${assignedReplicas.map(logEndOffsetString)}")
false
Expand Down Expand Up @@ -643,9 +643,9 @@ class Partition(val topicPartition: TopicPartition,
.format(inSyncReplicas.map(_.brokerId).mkString(","),
newInSyncReplicas.map(_.brokerId).mkString(","),
leaderReplica.highWatermark.messageOffset,
leaderReplica.logEndOffset.messageOffset,
leaderReplica.logEndOffset,
outOfSyncReplicas.map { replica =>
s"(brokerId: ${replica.brokerId}, endOffset: ${replica.logEndOffset.messageOffset})"
s"(brokerId: ${replica.brokerId}, endOffset: ${replica.logEndOffset})"
}.mkString(" ")
)
)
Expand Down Expand Up @@ -685,7 +685,7 @@ class Partition(val topicPartition: TopicPartition,
val candidateReplicas = inSyncReplicas - leaderReplica

val laggingReplicas = candidateReplicas.filter(r =>
r.logEndOffset.messageOffset != leaderReplica.logEndOffset.messageOffset && (time.milliseconds - r.lastCaughtUpTimeMs) > maxLagMs)
r.logEndOffset != leaderReplica.logEndOffset && (time.milliseconds - r.lastCaughtUpTimeMs) > maxLagMs)
if (laggingReplicas.nonEmpty)
debug("Lagging replicas are %s".format(laggingReplicas.map(_.brokerId).mkString(",")))

Expand Down Expand Up @@ -716,7 +716,7 @@ class Partition(val topicPartition: TopicPartition,
} catch {
case e: UnexpectedAppendOffsetException =>
val replica = if (isFuture) futureLocalReplicaOrException else localReplicaOrException
val logEndOffset = replica.logEndOffset.messageOffset
val logEndOffset = replica.logEndOffset
if (logEndOffset == replica.logStartOffset &&
e.firstOffset < logEndOffset && e.lastOffset >= logEndOffset) {
// This may happen if the log start offset on the leader (or current replica) falls in
Expand Down Expand Up @@ -790,7 +790,7 @@ class Partition(val topicPartition: TopicPartition,
*/
val initialHighWatermark = localReplica.highWatermark.messageOffset
val initialLogStartOffset = localReplica.logStartOffset
val initialLogEndOffset = localReplica.logEndOffset.messageOffset
val initialLogEndOffset = localReplica.logEndOffset
val initialLastStableOffset = localReplica.lastStableOffset.messageOffset

val maxOffsetOpt = fetchIsolation match {
Expand Down Expand Up @@ -827,7 +827,7 @@ class Partition(val topicPartition: TopicPartition,
val lastFetchableOffset = isolationLevel match {
case Some(IsolationLevel.READ_COMMITTED) => localReplica.lastStableOffset.messageOffset
case Some(IsolationLevel.READ_UNCOMMITTED) => localReplica.highWatermark.messageOffset
case None => localReplica.logEndOffset.messageOffset
case None => localReplica.logEndOffset
}

val epochLogString = if(currentLeaderEpoch.isPresent) {
Expand Down
19 changes: 11 additions & 8 deletions core/src/main/scala/kafka/cluster/Replica.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class Replica(val brokerId: Int,
@volatile private[this] var highWatermarkMetadata = new LogOffsetMetadata(initialHighWatermarkValue)
// the log end offset value, kept in all replicas;
// for local replica it is the log's end offset, for remote replicas its value is only updated by follower fetch
@volatile private[this] var logEndOffsetMetadata = LogOffsetMetadata.UnknownOffsetMetadata
@volatile private[this] var _logEndOffsetMetadata = LogOffsetMetadata.UnknownOffsetMetadata
// the log start offset value, kept in all replicas;
// for local replica it is the log's start offset, for remote replicas its value is only updated by follower fetch
@volatile private[this] var _logStartOffset = Log.UnknownLogStartOffset
Expand Down Expand Up @@ -76,7 +76,7 @@ class Replica(val brokerId: Int,
_lastCaughtUpTimeMs = math.max(_lastCaughtUpTimeMs, lastFetchTimeMs)

logStartOffset = logReadResult.followerLogStartOffset
logEndOffset = logReadResult.info.fetchOffsetMetadata
logEndOffsetMetadata = logReadResult.info.fetchOffsetMetadata
lastFetchLeaderLogEndOffset = logReadResult.leaderLogEndOffset
lastFetchTimeMs = logReadResult.fetchTimeMs
}
Expand All @@ -87,12 +87,12 @@ class Replica(val brokerId: Int,
_lastCaughtUpTimeMs = lastCaughtUpTimeMs
}

private def logEndOffset_=(newLogEndOffset: LogOffsetMetadata) {
private def logEndOffsetMetadata_=(newLogEndOffset: LogOffsetMetadata) {
if (isLocal) {
throw new KafkaException(s"Should not set log end offset on partition $topicPartition's local replica $brokerId")
} else {
logEndOffsetMetadata = newLogEndOffset
trace(s"Setting log end offset for replica $brokerId for partition $topicPartition to [$logEndOffsetMetadata]")
_logEndOffsetMetadata = newLogEndOffset
trace(s"Setting log end offset for replica $brokerId for partition $topicPartition to [${_logEndOffsetMetadata}]")
}
}

Expand All @@ -112,11 +112,14 @@ class Replica(val brokerId: Int,
}
}

def logEndOffset: LogOffsetMetadata =
def logEndOffsetMetadata: LogOffsetMetadata =
if (isLocal)
log.get.logEndOffsetMetadata
else
logEndOffsetMetadata
_logEndOffsetMetadata

def logEndOffset: Long =
logEndOffsetMetadata.messageOffset

/**
* Increment the log start offset if the new offset is greater than the previous log start offset. The replica
Expand Down Expand Up @@ -201,7 +204,7 @@ class Replica(val brokerId: Int,
def offsetSnapshot: LogOffsetSnapshot = {
LogOffsetSnapshot(
logStartOffset = logStartOffset,
logEndOffset = logEndOffset,
logEndOffset = logEndOffsetMetadata,
highWatermark = highWatermark,
lastStableOffset = lastStableOffset)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class ReplicaAlterLogDirsThread(name: String,
}

override protected def logEndOffset(topicPartition: TopicPartition): Long = {
replicaMgr.futureLocalReplicaOrException(topicPartition).logEndOffset.messageOffset
replicaMgr.futureLocalReplicaOrException(topicPartition).logEndOffset
}

override protected def endOffsetForEpoch(topicPartition: TopicPartition, epoch: Int): Option[OffsetAndEpoch] = {
Expand Down Expand Up @@ -103,12 +103,12 @@ class ReplicaAlterLogDirsThread(name: String,
val partition = replicaMgr.getPartition(topicPartition).get
val records = toMemoryRecords(partitionData.records)

if (fetchOffset != futureReplica.logEndOffset.messageOffset)
if (fetchOffset != futureReplica.logEndOffset)
throw new IllegalStateException("Offset mismatch for the future replica %s: fetched offset = %d, log end offset = %d.".format(
topicPartition, fetchOffset, futureReplica.logEndOffset.messageOffset))
topicPartition, fetchOffset, futureReplica.logEndOffset))

val logAppendInfo = partition.appendRecordsToFollowerOrFutureReplica(records, isFuture = true)
val futureReplicaHighWatermark = futureReplica.logEndOffset.messageOffset.min(partitionData.highWatermark)
val futureReplicaHighWatermark = futureReplica.logEndOffset.min(partitionData.highWatermark)
futureReplica.highWatermark = new LogOffsetMetadata(futureReplicaHighWatermark)
futureReplica.maybeIncrementLogStartOffset(partitionData.logStartOffset)

Expand Down
12 changes: 6 additions & 6 deletions core/src/main/scala/kafka/server/ReplicaFetcherThread.scala
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class ReplicaFetcherThread(name: String,
}

override protected def logEndOffset(topicPartition: TopicPartition): Long = {
replicaMgr.localReplicaOrException(topicPartition).logEndOffset.messageOffset
replicaMgr.localReplicaOrException(topicPartition).logEndOffset
}

override protected def endOffsetForEpoch(topicPartition: TopicPartition, epoch: Int): Option[OffsetAndEpoch] = {
Expand Down Expand Up @@ -145,21 +145,21 @@ class ReplicaFetcherThread(name: String,

maybeWarnIfOversizedRecords(records, topicPartition)

if (fetchOffset != replica.logEndOffset.messageOffset)
if (fetchOffset != replica.logEndOffset)
throw new IllegalStateException("Offset mismatch for partition %s: fetched offset = %d, log end offset = %d.".format(
topicPartition, fetchOffset, replica.logEndOffset.messageOffset))
topicPartition, fetchOffset, replica.logEndOffset))

if (isTraceEnabled)
trace("Follower has replica log end offset %d for partition %s. Received %d messages and leader hw %d"
.format(replica.logEndOffset.messageOffset, topicPartition, records.sizeInBytes, partitionData.highWatermark))
.format(replica.logEndOffset, topicPartition, records.sizeInBytes, partitionData.highWatermark))

// Append the leader's messages to the log
val logAppendInfo = partition.appendRecordsToFollowerOrFutureReplica(records, isFuture = false)

if (isTraceEnabled)
trace("Follower has replica log end offset %d after appending %d bytes of messages for partition %s"
.format(replica.logEndOffset.messageOffset, records.sizeInBytes, topicPartition))
val followerHighWatermark = replica.logEndOffset.messageOffset.min(partitionData.highWatermark)
.format(replica.logEndOffset, records.sizeInBytes, topicPartition))
val followerHighWatermark = replica.logEndOffset.min(partitionData.highWatermark)
val leaderLogStartOffset = partitionData.logStartOffset
// for the follower replica, we do not need to keep
// its segment base offset the physical position,
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/kafka/server/ReplicaManager.scala
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ class ReplicaManager(val config: KafkaConfig,
localReplica(topicPartition) match {
case Some(replica) =>
if (isFuture)
replica.logEndOffset.messageOffset - logEndOffset
replica.logEndOffset - logEndOffset
else
math.max(replica.highWatermark.messageOffset - logEndOffset, 0)
case None =>
Expand Down Expand Up @@ -1405,7 +1405,7 @@ class ReplicaManager(val config: KafkaConfig,
nonOfflinePartitionsIterator.filter(_.leaderReplicaIfLocal.isDefined)

def getLogEndOffset(topicPartition: TopicPartition): Option[Long] =
nonOfflinePartition(topicPartition).flatMap(_.leaderReplicaIfLocal.map(_.logEndOffset.messageOffset))
nonOfflinePartition(topicPartition).flatMap(_.leaderReplicaIfLocal.map(_.logEndOffset))

// Flushes the highwatermark value for all partitions to the highwatermark file
def checkpointHighWatermarks() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,7 @@ class AdminClientIntegrationTest extends IntegrationTestHarness with Logging {
}, s"Expected follower to discover new log start offset $expectedStartOffset")

TestUtils.waitUntilTrue(() => {
servers(followerIndex).replicaManager.localReplica(topicPartition).get.logEndOffset.messageOffset == expectedEndOffset
servers(followerIndex).replicaManager.localReplica(topicPartition).get.logEndOffset == expectedEndOffset
}, s"Expected follower to catch up to log end offset $expectedEndOffset")
}

Expand Down Expand Up @@ -871,7 +871,7 @@ class AdminClientIntegrationTest extends IntegrationTestHarness with Logging {
// make sure we are in the expected state after delete records
for (i <- 0 until serverCount) {
assertEquals(3, servers(i).replicaManager.localReplica(topicPartition).get.logStartOffset)
assertEquals(expectedLEO, servers(i).replicaManager.localReplica(topicPartition).get.logEndOffset.messageOffset)
assertEquals(expectedLEO, servers(i).replicaManager.localReplica(topicPartition).get.logEndOffset)
}

// we will create another dir just for one server
Expand All @@ -886,7 +886,7 @@ class AdminClientIntegrationTest extends IntegrationTestHarness with Logging {

// once replica moved, its LSO and LEO should match other replicas
assertEquals(3, servers(0).replicaManager.localReplica(topicPartition).get.logStartOffset)
assertEquals(expectedLEO, servers(0).replicaManager.localReplica(topicPartition).get.logEndOffset.messageOffset)
assertEquals(expectedLEO, servers(0).replicaManager.localReplica(topicPartition).get.logEndOffset)
}

@Test
Expand Down
Loading