From be2e54604c8c1e7a3b0da6134964fb8f19b8c567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20G=C3=B6m=C3=B6ri?= Date: Sun, 30 Apr 2023 13:15:13 +0200 Subject: [PATCH] Handle missing delivery marker in CQ v1 index This can happen when a classic queue has messages published on a pre-3.10 RabbitMQ version, but still present after an upgrade to 3.10+. Fixes #7904 --- deps/rabbit/src/rabbit_queue_index.erl | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/deps/rabbit/src/rabbit_queue_index.erl b/deps/rabbit/src/rabbit_queue_index.erl index 3333ecab50..e75d2c9151 100644 --- a/deps/rabbit/src/rabbit_queue_index.erl +++ b/deps/rabbit/src/rabbit_queue_index.erl @@ -952,6 +952,10 @@ action_to_entry(RelSeq, Action, JEntries) -> ({no_pub, del, no_ack}) when Action == ack -> {set, {no_pub, del, ack}}; ({?PUB, del, no_ack}) when Action == ack -> + {reset, none}; + %% Special case, missing del + %% See journal_minus_segment1/2 + ({?PUB, no_del, no_ack}) when Action == ack -> {reset, none} end. @@ -1342,6 +1346,11 @@ segment_plus_journal1({?PUB = Pub, no_del, no_ack}, {no_pub, del, no_ack}) -> segment_plus_journal1({?PUB, no_del, no_ack}, {no_pub, del, ack}) -> {undefined, -1}; segment_plus_journal1({?PUB, del, no_ack}, {no_pub, no_del, ack}) -> + {undefined, -1}; + +%% Special case, missing del +%% See journal_minus_segment1/2 +segment_plus_journal1({?PUB, no_del, no_ack}, {no_pub, no_del, ack}) -> {undefined, -1}. %% Remove from the journal entries for a segment, items that are @@ -1413,6 +1422,16 @@ journal_minus_segment1({no_pub, no_del, ack}, {?PUB, del, no_ack}) -> journal_minus_segment1({no_pub, no_del, ack}, {?PUB, del, ack}) -> {undefined, -1}; +%% Just ack in journal, missing del +%% Since 3.10 message delivery is tracked per-queue, not per-message, +%% but to keep queue index v1 format messages are always marked as +%% delivered on publish. But for a message that was published before +%% 3.10 this is not the case and the delivery marker can be missing. +%% As a workaround we add the del marker because if a message is acked +%% it must have been delivered as well. +journal_minus_segment1({no_pub, no_del, ack}, {?PUB, no_del, no_ack}) -> + {{no_pub, del, ack}, 0}; + %% Deliver and ack in journal journal_minus_segment1({no_pub, del, ack}, {?PUB, no_del, no_ack}) -> {keep, 0};