Skip orphan multi/exec keys in SaveIndexExtension instead of aborting - #1361
mohanrajendran wants to merge 5 commits into
Conversation
4f1273d to
a514ea7
Compare
55080be to
7f1312b
Compare
A key can appear in the multi/exec queue (multi_mutations_keys_) without a corresponding entry in the mutation map (tracked_mutated_records_); the two are maintained by different threads at different times and their consistency is not guaranteed across a fork/save boundary. SaveIndexExtension asserted deque subset of map with a fatal CHECK, which aborted the forked RDB writer and truncated the stream, blocking every full sync (and, once persisted, re-crashing on load). Skip such orphan keys instead of aborting, writing the adjusted count so the RDB stays self-consistent. A skipped key's index membership is rebuilt from the key list / backfill on load. The load side does not assert the invariant, so no read-side change is needed. Add IndexSchemaFriendTest.OrphanMultiKeySkippedOnSave (verified to abort on the pre-fix code) and OrphanMultiKeySkipped_RoundTrip (save/load round trip). Signed-off-by: Mohan Rajendran <mohrjen@amazon.com>
7f1312b to
2b18768
Compare
Signed-off-by: Mohan Rajendran <mohrjen@amazon.com>
Signed-off-by: Mohan Rajendran <mohrjen@amazon.com>
Signed-off-by: Mohan Rajendran <mohrjen@amazon.com>
Signed-off-by: Mohan Rajendran <mohrjen@amazon.com>
|
Reviewers for this PR
Assigned automatically to the least-assigned members of the reviewer pools in |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (4)
Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review. 📝 WalkthroughWalkthroughThe RDB save path now skips orphaned multi/exec keys instead of aborting. It records skipped keys, serializes live entries, and adds unit and integration tests for save, restore, readability, and searchability. ChangesOrphaned multi/exec save handling
Suggested reviewers: Priority: ⬇️ Low Merge Risk: ⚪ Minimal · up to RDB saves now tolerate consumed multi/exec queue keys without aborting, while preserving readable snapshots and searchable records. No current merge-blocking risk remains. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
/label bug |
Problem
IndexSchema::SaveIndexExtensionassumes every key inmulti_mutations_keys_also exists intracked_mutated_records_. That assumption is not guaranteed at an RDB save boundary: the main thread updates the queue while writer threads consume the mutation map.This patch addresses a production ElastiCache crash where a forked RDB writer aborted during replication full sync. The primary process stayed up, but repeated child aborts caused full-sync failures. The initial failure can occur at the first save boundary; a save/reload/save cycle is not required.
sequenceDiagram participant M as Main thread participant Q as Multi exec queue participant MAP as Mutation map participant W as Writer thread participant S as RDB save M->>MAP: Normal write K M->>W: Schedule K Note over W: Writer is paused M->>Q: MULTI EXEC write K M->>MAP: Merge K Note over Q: Queue length is below threshold W->>MAP: Consume K Note over Q,MAP: Queue has K and map has no K S->>Q: Walk queued K S->>MAP: Check K S-->>S: RDB writer abortsFix
Skip queued keys that no longer have a mutation-map entry, and write the retained-key count so the RDB stream remains self-consistent. A skipped key's index membership is re-derived from the serialized key list or backfill on load; the load path needs no change.
Tests
IndexSchemaFriendTest.OrphanMultiKeySkippedOnSaveverifies thatSaveIndexExtensionsucceeds when the queue contains a map-less key.TestMutationQueue.test_multi_exec_orphan_key_saved_on_first_savereproduces the production runtime sequence without a reload and verifies that the firstSAVEsucceeds.TestMutationQueue.test_multi_exec_orphan_key_skipped_still_searchablecovers the save/reload/save path and verifies that the data remains searchable after another restart.Note
Draining the multi/exec queue in the pre-fork callback could reduce the chance of forming this inconsistency at snapshot time. The save-time guard is still required for an RDB that already contains the inconsistency.