@ -16,7 +16,7 @@
@@ -16,7 +16,7 @@
*/
package kafka.raft
import kafka.log. { AppendOrigin , Defaults , UnifiedLog , LogConfig , LogOffsetSnapshot , SnapshotGenerated }
import kafka.log. { AppendOrigin , Defaults , LogConfig , LogOffsetSnapshot , SnapshotGenerated , UnifiedLog }
import kafka.server.KafkaConfig. { MetadataLogSegmentBytesProp , MetadataLogSegmentMinBytesProp }
import kafka.server. { BrokerTopicStats , FetchHighWatermark , FetchLogEnd , KafkaConfig , LogDirFailureChannel , RequestLocal }
import kafka.utils. { CoreUtils , Logging , Scheduler }
@ -26,7 +26,7 @@ import org.apache.kafka.common.record.{ControlRecordUtils, MemoryRecords, Record
@@ -26,7 +26,7 @@ import org.apache.kafka.common.record.{ControlRecordUtils, MemoryRecords, Record
import org.apache.kafka.common.utils. { BufferSupplier , Time }
import org.apache.kafka.common. { KafkaException , TopicPartition , Uuid }
import org.apache.kafka.raft. { Isolation , KafkaRaftClient , LogAppendInfo , LogFetchInfo , LogOffsetMetadata , OffsetAndEpoch , OffsetMetadata , ReplicatedLog , ValidOffsetAndEpoch }
import org.apache.kafka.snapshot. { FileRawSnapshotReader , FileRawSnapshotWriter , RawSnapshotReader , RawSnapshotWriter , Snapshots }
import org.apache.kafka.snapshot. { FileRawSnapshotReader , FileRawSnapshotWriter , RawSnapshotReader , RawSnapshotWriter , SnapshotPath , Snapshot s }
import java.io.File
import java.nio.file. { Files , NoSuchFileException , Path }
@ -546,7 +546,7 @@ case class MetadataLogConfig(logSegmentBytes: Int,
@@ -546,7 +546,7 @@ case class MetadataLogConfig(logSegmentBytes: Int,
fileDeleteDelayMs : Int ,
nodeId : Int )
object KafkaMetadataLog {
object KafkaMetadataLog extends Logging {
def apply (
topicPartition : TopicPartition ,
topicId : Uuid ,
@ -623,7 +623,9 @@ object KafkaMetadataLog {
@@ -623,7 +623,9 @@ object KafkaMetadataLog {
private def recoverSnapshots (
log : UnifiedLog
) : mutable.TreeMap [ OffsetAndEpoch , Option [ FileRawSnapshotReader ] ] = {
val snapshots = mutable . TreeMap . empty [ OffsetAndEpoch , Option [ FileRawSnapshotReader ] ]
val snapshotsToRetain = mutable . TreeMap . empty [ OffsetAndEpoch , Option [ FileRawSnapshotReader ] ]
val snapshotsToDelete = mutable . Buffer . empty [ SnapshotPath ]
// Scan the log directory ; deleting partial snapshots and older snapshot , only remembering immutable snapshots start
// from logStartOffset
val filesInDir = Files . newDirectoryStream ( log . dir . toPath )
@ -631,21 +633,40 @@ object KafkaMetadataLog {
@@ -631,21 +633,40 @@ object KafkaMetadataLog {
try {
filesInDir . forEach { path =>
Snapshots . parse ( path ) . ifPresent { snapshotPath =>
if ( snapshotPath . partial ||
snapshotPath . deleted ||
snapshotPath . snapshotId . offset < log . logStartOffset ) {
// Delete partial snapshot , deleted snapshot and older snapshot
Files . deleteIfExists ( snapshotPath . p ath)
// Collect partial snapshot , deleted snapshot and older snapshot for deletion
if ( snapshotPath . partial
|| snapshotPath . deleted
|| snapshotPath . snapshotId . offset < log . logStartOffset ) {
snapshotsToDelete . append ( snapshotP ath)
} else {
snapshots . put ( snapshotPath . snapshotId , None )
snapshotsToRetain . put ( snapshotPath . snapshotId , None )
}
}
}
// Before deleting any snapshots , we should ensure that the retained snapshots are
// consistent with the current state of the log . If the log start offset is not 0 ,
// then we must have a snapshot which covers the initial state up to the current
// log start offset .
if ( log . logStartOffset > 0 ) {
val latestSnapshotId = snapshotsToRetain . lastOption . map ( _ . _1 )
if ( ! latestSnapshotId . exists ( snapshotId => snapshotId . offset >= log . logStartOffset ) ) {
throw new IllegalStateException ( "Inconsistent snapshot state: there must be a snapshot " +
s" at an offset larger then the current log start offset ${ log . logStartOffset } , but the " +
s" latest snapshot is $latestSnapshotId " )
}
}
snapshotsToDelete . foreach { snapshotPath =>
Files . deleteIfExists ( snapshotPath . path )
info ( s" Deleted unneeded snapshot file with path $snapshotPath " )
}
} finally {
filesInDir . close ( )
}
snapshots
info ( s" Initialized snapshots with IDs ${ snapshotsToRetain . keys } from ${ log . dir } " )
snapshotsToRetain
}
private def deleteSnapshotFiles (