KAFKA-13093: Log compaction should write new segments with record version v2 (KIP-724)#18321
Conversation
f38e108 to
d41a6e2
Compare
| } | ||
|
|
||
| @Test | ||
| def testLeaderEpochCacheCreatedAfterMessageFormatUpgrade(): Unit = { |
There was a problem hiding this comment.
This test was originally removed via #18267 - added it back and modified it to take into account that the leader epoch cache always exists now (since the configured record version is always V2).
…sion v2 (KIP-724)
… longer supported
…e it always creates it now
…'s still a useful test
| def listProducerSnapshotOffsets(logDir: File): Seq[Long] = | ||
| ProducerStateManager.listSnapshotFiles(logDir).asScala.map(_.offset).sorted.toSeq | ||
|
|
||
| def assertLeaderEpochCacheEmpty(log: UnifiedLog): Unit = { |
|
|
||
| @ParameterizedTest | ||
| @ArgumentsSource(classOf[LogCleanerParameterizedIntegrationTest.ExcludeZstd]) | ||
| def testCleanerWithMessageFormatV0V1V2(compressionType: CompressionType): Unit = { |
There was a problem hiding this comment.
The tests added in this class were originally removed via #18267 - added them back, modified them to fit the new reality and extended them to include more extensive verification of the log after compaction.
0ede54e to
a50bd5d
Compare
|
@junrao Would you be able to review this PR? I would like to include it in Apache Kafka 4.0, if possible - it completes KIP-724. |
…og-compaction-write-record-v2 * apache-github/trunk: (34 commits) MINOR: Bump year to 2025 in NOTICE file (apache#18427) KAFKA-18411 Remove ZkProducerIdManager (apache#18413) KAFKA-18408 tweak the 'tag' field for BrokerHeartbeatRequest.json, BrokerRegistrationChangeRecord.json and RegisterBrokerRecord.json (apache#18421) KAFKA-18414 Remove KRaftRegistrationResult (apache#18401) KAFKA-17921 Support SASL_PLAINTEXT protocol with java.security.auth.login.config (apache#17671) KAFKA-18384 Remove ZkAlterPartitionManager (apache#18364) KAFKA-10790: Add deadlock detection to producer#flush (apache#17946) KAFKA-18412: Remove EmbeddedZookeeper (apache#18399) MINOR : Improve Exception log in NotEnoughReplicasException(apache#12394) MINOR: Improve PlaintextAdminIntegrationTest#testConsumerGroups (apache#18409) MINOR: Remove unused local variable (apache#18410) MINOR: Remove RaftManager.maybeDeleteMetadataLogDir and AutoTopicCreationManagerTest.scala (apache#17365) KAFKA-18368 Remove TestUtils#MockZkConnect and remove zkConnect from TestUtils#createBrokerConfig (apache#18352) MINOR: Update Consumer group timeout default to 30 sec (apache#16406) MINOR: Fix typo in CommitRequestManager (apache#18407) MINOR: cleanup JavaDocs for deprecation warnings (apache#18402) KAFKA-18303; Update ShareCoordinator to use new record format (apache#18396) MINOR: Update Consumer and Producer JavaDocs for committing offsets (apache#18336) KAFKA-16446: Improve controller event duration logging (apache#15622) KAFKA-18388 test-kraft-server-start.sh should use log4j2.yaml (apache#18370) ...
…to LeaderEpochFileCache
| } | ||
|
|
||
| @Test | ||
| def testMaybeAddLogDirFetchersWithoutEpochCache(): Unit = { |
There was a problem hiding this comment.
@junrao do you agree that we don't need this test anymore? Or is there a purpose that is not made clear by the test name?
There was a problem hiding this comment.
This test is still useful. We can just leave partition.futureLog.get.leaderEpochCache unchanged. It will be initialized as empty and the fetcher thread will default to initializing the fetch offset with HWM. We probably want to adjust the test name accordingly.
|
|
||
| if (logOptional.isPresent()) { | ||
| Option<LeaderEpochFileCache> leaderEpochCache = logOptional.get().leaderEpochCache(); | ||
| if (leaderEpochCache != null && leaderEpochCache.isDefined()) { |
There was a problem hiding this comment.
@junrao It's odd that we were checking for null here - do you know if we can remove this?
There was a problem hiding this comment.
Yes, we can remove this check.
Also added @OverRide annotations to catch it at compile time in the future.
| leaderEpochCache.foreach(_.clear()) | ||
| // `renameDir` with `shouldReinitialize=false` sets this to `null` and it's usually (but not always) called before this method | ||
| if (leaderEpochCache != null) | ||
| leaderEpochCache.clear() |
There was a problem hiding this comment.
@junrao This is interesting - do you think we should be setting the cache to null here too versus calling clear on it? It's a bit odd that we take different actions to achieve a similar outcome (clearing the in-memory state) in two different (but related) methods.
There was a problem hiding this comment.
The case where we don't call renameDir before delete is during LogManager.loadLog.
if (logDir.getName.endsWith(UnifiedLog.DeleteDirSuffix)) {
addLogToBeDeleted(log)
} There was a problem hiding this comment.
Yes, I agree that we can just call clear on leaderEpochCache instead of setting it to null in renameDir.
| private def initializeLeaderEpochCache(): Unit = lock synchronized { | ||
| leaderEpochCache = UnifiedLog.maybeCreateLeaderEpochCache( | ||
| dir, topicPartition, logDirFailureChannel, logIdent, leaderEpochCache, scheduler) | ||
| leaderEpochCache = UnifiedLog.createLeaderEpochCache( |
There was a problem hiding this comment.
This is an existing issue. initializeLeaderEpochCache is better named as reinitializeLeaderEpochCache.
| leaderEpochCache.foreach(_.clear()) | ||
| // `renameDir` with `shouldReinitialize=false` sets this to `null` and it's usually (but not always) called before this method | ||
| if (leaderEpochCache != null) | ||
| leaderEpochCache.clear() |
There was a problem hiding this comment.
Yes, I agree that we can just call clear on leaderEpochCache instead of setting it to null in renameDir.
|
|
||
| if (logOptional.isPresent()) { | ||
| Option<LeaderEpochFileCache> leaderEpochCache = logOptional.get().leaderEpochCache(); | ||
| if (leaderEpochCache != null && leaderEpochCache.isDefined()) { |
There was a problem hiding this comment.
Yes, we can remove this check.
| } | ||
|
|
||
| @Test | ||
| def testMaybeAddLogDirFetchersWithoutEpochCache(): Unit = { |
There was a problem hiding this comment.
This test is still useful. We can just leave partition.futureLog.get.leaderEpochCache unchanged. It will be initialized as empty and the fetcher thread will default to initializing the fetch offset with HWM. We probably want to adjust the test name accordingly.
|
@junrao Addressed your comments and the tests are passing. |
| assertTrue(log.partitionMetadataFile.isEmpty) | ||
| assertEquals(0, log.logEndOffset) | ||
| // verify that records appending can still succeed | ||
| // even with the uninitialized leaderEpochCache and partitionMetadataFile |
There was a problem hiding this comment.
We don't support appending with the uninitialized leaderEpochCache anymore - it was questionable to support this after renameDir(reinitialize=false) since the former is invoked as part of the deletion of the log.
|
@junrao Yes, good idea. Is it ok if I do that as a follow-up? It doesn't have to go into 4.0 and there are many references. |
…sion v2 (KIP-724) (#18321) Convert v0/v1 record batches to v2 during compaction even if said record batches would be written with no change otherwise. A few important details: 1. V0 compressed record batch with multiple records is converted into single V2 record batch 2. V0 uncompressed records are converted into single record V2 record batches 3. V0 records are converted to V2 records with timestampType set to `CreateTime` and the timestamp is `-1`. 4. The `KAFKA-4298` workaround is no longer needed since the conversion to V2 fixes the issue too. 5. Removed a log warning applicable to consumers older than 0.10.1 - they are no longer supported. 6. Added back the ability to append records with v0/v1 (for testing only). 7. The creation of the leader epoch cache is no longer optional since the record version config is effectively always V2. Add integration tests, these tests existed before #18267 - restored, modified and extended them. Reviewers: Jun Rao <jun@confluent.io>
…sion v2 (KIP-724) (apache#18321) Convert v0/v1 record batches to v2 during compaction even if said record batches would be written with no change otherwise. A few important details: 1. V0 compressed record batch with multiple records is converted into single V2 record batch 2. V0 uncompressed records are converted into single record V2 record batches 3. V0 records are converted to V2 records with timestampType set to `CreateTime` and the timestamp is `-1`. 4. The `KAFKA-4298` workaround is no longer needed since the conversion to V2 fixes the issue too. 5. Removed a log warning applicable to consumers older than 0.10.1 - they are no longer supported. 6. Added back the ability to append records with v0/v1 (for testing only). 7. The creation of the leader epoch cache is no longer optional since the record version config is effectively always V2. Add integration tests, these tests existed before apache#18267 - restored, modified and extended them. Reviewers: Jun Rao <jun@confluent.io>
…sion v2 (KIP-724) (apache#18321) Convert v0/v1 record batches to v2 during compaction even if said record batches would be written with no change otherwise. A few important details: 1. V0 compressed record batch with multiple records is converted into single V2 record batch 2. V0 uncompressed records are converted into single record V2 record batches 3. V0 records are converted to V2 records with timestampType set to `CreateTime` and the timestamp is `-1`. 4. The `KAFKA-4298` workaround is no longer needed since the conversion to V2 fixes the issue too. 5. Removed a log warning applicable to consumers older than 0.10.1 - they are no longer supported. 6. Added back the ability to append records with v0/v1 (for testing only). 7. The creation of the leader epoch cache is no longer optional since the record version config is effectively always V2. Add integration tests, these tests existed before apache#18267 - restored, modified and extended them. Reviewers: Jun Rao <jun@confluent.io>
…sion v2 (KIP-724) (apache#18321) Convert v0/v1 record batches to v2 during compaction even if said record batches would be written with no change otherwise. A few important details: 1. V0 compressed record batch with multiple records is converted into single V2 record batch 2. V0 uncompressed records are converted into single record V2 record batches 3. V0 records are converted to V2 records with timestampType set to `CreateTime` and the timestamp is `-1`. 4. The `KAFKA-4298` workaround is no longer needed since the conversion to V2 fixes the issue too. 5. Removed a log warning applicable to consumers older than 0.10.1 - they are no longer supported. 6. Added back the ability to append records with v0/v1 (for testing only). 7. The creation of the leader epoch cache is no longer optional since the record version config is effectively always V2. Add integration tests, these tests existed before apache#18267 - restored, modified and extended them. Reviewers: Jun Rao <jun@confluent.io>
Convert v0/v1 record batches to v2 during compaction even if said record batches would be
written with no change otherwise. A few important details:
CreateTimeand thetimestamp is
-1.KAFKA-4298workaround is no longer needed since the conversion to V2 fixesthe issue too.
supported.
config is effectively always V2.
Add integration tests, these tests existed before #18267 - restored, modified and
extended them.
Committer Checklist (excluded from commit message)