Preserve routing in Translog.Delete for CDC-based replication - #22584
Preserve routing in Translog.Delete for CDC-based replication#22584arpitsingla96 wants to merge 4 commits into
Conversation
PR Reviewer Guide 🔍(Review updated until commit 802edd2)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to 802edd2
Previous suggestionsSuggestions up to commit 6dccd00
|
a611666 to
b19fbbb
Compare
Thread routing values end-to-end through the delete path so that Translog.Delete carries the routing key, mirroring how Translog.Index already preserves routing. This enables CDC-based replication tools (e.g. AOSC) to correctly replay deletes for documents with custom routing to a different target index. Changes: - Engine.Delete: add nullable routing field and getter - Translog.Delete: add routing field with FORMAT_ROUTING serialization bump (backward-compatible: old entries deserialize with routing=null) - DocumentMapper: add RoutingFieldMapper to delete tombstone metadata fields and overload createDeleteTombstoneDoc with routing parameter - IndexShard: thread routing through applyDeleteOperationOnPrimary, applyDeleteOperationOnReplica, applyDeleteOperation, prepareDelete - TransportShardBulkAction: pass request.routing() to both primary and replica delete paths - InternalEngine/IngestionEngine: pass delete.routing() to tombstone - LuceneChangesSnapshot: read fields.routing() from tombstone into Translog.Delete for Lucene-based snapshot recovery - EngineConfig.TombstoneDocSupplier: add default method with routing - Engine/EngineBackedIndexer/IndexerEngineOperations: add prepareDelete overload with routing parameter Signed-off-by: Arpit Singla <asingla2@atlassian.com> Signed-off-by: Arpit Singla <arpitsingla96@gmail.com>
Address review findings for the delete routing preservation feature: 1. CRITICAL: Add version gate (V_3_6_0) in Translog.Delete.write() to prevent old nodes from encountering unrecognized routing bytes during rolling upgrades. Without this, mixed-version clusters would hit TranslogCorruptedException when old nodes read FORMAT_ROUTING entries. 2. Add testDeleteRoutingBackwardCompatibility: verifies that routing is dropped when serialized with pre-3.6.0 wire version and preserved when serialized with current version. 3. Add testDeleteRoutingTranslogRoundTrip: writes deletes with and without routing to a real translog file, reads them back by location and via snapshot, verifying end-to-end persistence. 4. Update testTranslogOpSerialization to include routing when wire version supports it. 5. Add TODO comment on MessageProcessorRunnable noting the missing routing in polling ingest delete path. 6. Add CHANGELOG entry for the feature. Signed-off-by: Arpit Singla <asingla2@atlassian.com> Signed-off-by: Arpit Singla <arpitsingla96@gmail.com>
- Make IndexerEngineOperations.prepareDelete(routing) a default method delegating to the no-routing overload, fixing japicmp breakage - Add deprecated overloads for IndexShard.applyDeleteOperationOnPrimary and applyDeleteOperationOnReplica without routing parameter - Fix misleading TombstoneDocSupplier javadoc on default method - Use static import for hamcrest not() in LuceneChangesSnapshotTests Signed-off-by: Arpit Singla <arpitsingla96@gmail.com>
V_3_6_0 and V_3_7_0 are already released without routing support. Using V_3_6_0 would cause TranslogCorruptedException on 3.6/3.7 nodes in mixed-version clusters. Gate on V_3_8_0 (Version.CURRENT) which is the first version that will ship with this feature. Signed-off-by: Arpit Singla <arpitsingla96@gmail.com>
b19fbbb to
802edd2
Compare
|
Persistent review updated to latest commit 802edd2 |
|
❌ Gradle check result for 802edd2: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
Summary
Preserve routing in
Translog.Deleteoperations so that CDC-based replication tools (e.g. AOSC) can correctly replay deletes for documents with custom routing against target indices with different shard configurations.Resolves #20907
Changes
routingfield toTranslog.Deletewith new serialization formatFORMAT_ROUTING = 8V_3_8_0) for safe rolling upgrades — older nodes never see routing bytesRoutingFieldMapperindeleteTombstoneMetadataFieldMappersLuceneChangesSnapshotEngine.Delete,IndexShard,TransportShardBulkAction, and allIndexerEngineOperationsimplementorsIndexShard.applyDeleteOperationOnPrimary/OnReplica, default method forIndexerEngineOperations.prepareDeletewith routingWire compatibility
The version gate selects the serialization format based on the receiving node's version (
StreamOutput.getVersion()). Nodes < 3.8.0 receiveFORMAT_NO_DOC_TYPE(no routing bytes). Local translog always usesVersion.CURRENT, so on-disk format is upgraded transparently on the writing node.Null routing
When routing is null (the common case), no routing bytes are written to the tombstone or translog — fully backward compatible with existing data and code paths.
Test plan
LocalTranslogTests.testDeleteRoutingTranslogRoundTrip— write/read routing through real translog fileLocalTranslogTests.testDeleteRoutingBackwardCompatibility— old wire version drops routing, new version preserves itLocalTranslogTests.testTranslogOpSerialization— version-gated round-trip with random wire versionsLuceneChangesSnapshotTests.testDeleteRoutingSerialization— Engine.Delete → Translog.Delete routing round-trip