Vineet-kumar8757 opened a new pull request, #22848:
URL: https://github.com/apache/kafka/pull/22848

   ## Summary
   
   MirrorMaker 2 (MM2) can silently lose data in two operational scenarios 
because
   the replication consumer's auto.offset.reset defaults to earliest, which
   masks the underlying OffsetOutOfRangeException:
   
   1. *Silent data loss* – a retention policy purges source records before they
      are replicated; the consumer jumps forward to a later valid offset, 
leaving
      an undetected gap.
   2. *Source topic reset* – a source topic is deleted and recreated (log end
      offset back to 0); MM2 silently restarts from the earliest offset.
   
   This PR adds opt-in fail-fast detection for both cases.
   
   ## Design rationale
   
   - The Kafka consumer already detects an invalid current offset and raises
     org.apache.kafka.clients.consumer.OffsetOutOfRangeException — but only when
     auto.offset.reset=none. So the feature forces none on the replication
     consumer when enabled.
   - Because none has no fallback for partitions without a committed offset,
     initializeConsumer() explicitly seekToBeginning() for uncommitted
     partitions to preserve MM2's original first-run behavior.
   - In poll(), OffsetOutOfRangeException is caught and classified by
     inspecting each partition's earliest available offset:
     - earliest > 0 → records were purged → *DataLossException*
     - earliest == 0 → topic was deleted/recreated → *TopicResetException*
     A detailed error (topic, partition, requested offset, earliest offset) is
     logged before the task fails fast. A topic reset takes precedence when both
     conditions are present in the same batch.
   - The behavior is gated by a new connector config
     detect.offset.out.of.range.enabled (default false), so existing
     deployments are unaffected unless they opt in.
   
   ## Files changed
   
   - MirrorSourceTask.java – force auto.offset.reset=none when enabled, manual
     seek-to-beginning for uncommitted partitions, catch/classify
     OffsetOutOfRangeException via new handleOffsetOutOfRange().
   - MirrorSourceConfig.java – new detect.offset.out.of.range.enabled config +
     accessor.
   - DataLossException.java (new) – thrown on source record purge.
   - TopicResetException.java (new) – thrown on source topic reset.
   - MirrorSourceTaskTest.java – tests for data-loss detection, topic-reset
     detection, precedence, and seek-to-beginning behavior.
   - MirrorSourceConfigTest.java – tests for the new config default and toggle.
   
   ## Lifecycle integration
   
   The change lives entirely within the existing MirrorSourceTask lifecycle
   (start() → initializeConsumer() → poll()). Throwing a ConnectException
   subclass from poll() is the standard Connect mechanism for failing a task,
   so Connect stops and surfaces the task as FAILED without any new plumbing.
   
   ## Testing
   
   - ./gradlew :connect:mirror:test --tests "*MirrorSourceTaskTest" --tests 
"*MirrorSourceConfigTest"
   - ./gradlew :connect:mirror:checkstyleMain :connect:mirror:checkstyleTest 
spotlessCheck
   
   ## Backward compatibility
   
   Fully backward compatible — the feature is disabled by default. When 
disabled,
   MM2 retains its existing auto.offset.reset=earliest behavior.


-- 
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