|
26 | 26 |
|
27 | 27 | -include_lib("rabbit_common/include/rabbit_msg_store.hrl"). |
28 | 28 |
|
29 | | -%% We flush to disk when the write buffer gets above the max size, |
30 | | -%% or at an interval to make sure we don't keep the data in memory |
31 | | -%% too long. Confirms are sent after the data is flushed to disk. |
32 | | --define(HANDLE_CACHE_BUFFER_SIZE, 1048576). %% 1MB. |
33 | | --define(SYNC_INTERVAL, 200). %% Milliseconds. |
| 29 | +%% We flush to disk at an interval to make sure we don't keep |
| 30 | +%% the data in memory too long. Confirms are sent after the |
| 31 | +%% data is flushed to disk. |
| 32 | +-define(SYNC_INTERVAL, 200). %% Milliseconds. |
34 | 33 |
|
35 | 34 | -define(CLEAN_FILENAME, "clean.dot"). |
36 | 35 | -define(FILE_SUMMARY_FILENAME, "file_summary.ets"). |
37 | 36 |
|
38 | | --define(BINARY_MODE, [raw, binary]). |
39 | | --define(READ_MODE, [read]). |
40 | | --define(WRITE_MODE, [write]). |
41 | | - |
42 | 37 | -define(FILE_EXTENSION, ".rdq"). |
43 | | --define(FILE_EXTENSION_TMP, ".rdt"). |
44 | 38 |
|
45 | 39 | %% We keep track of flying messages for writes and removes. The idea is that |
46 | 40 | %% when a remove comes in before we could process the write, we skip the |
@@ -1575,24 +1569,19 @@ count_msg_refs(Gen, Seed, State) -> |
1575 | 1569 | case Gen(Seed) of |
1576 | 1570 | finished -> |
1577 | 1571 | ok; |
1578 | | - {_MsgId, 0, Next} -> |
| 1572 | + %% This clause is kept for v1 compatibility purposes. |
| 1573 | + %% It can be removed once we no longer support converting from v1 data. |
| 1574 | + {{MsgId, 1}, Next} -> |
| 1575 | + %% @todo Remove index_module and avoid this element/2. |
| 1576 | + _ = ets:update_counter(element(2, State#msstate.index_state), MsgId, +1, |
| 1577 | + #msg_location{msg_id=MsgId, file=undefined, ref_count=1}), |
1579 | 1578 | count_msg_refs(Gen, Next, State); |
1580 | | - {MsgId, Delta, Next} -> |
1581 | | - ok = case index_lookup(MsgId, State) of |
1582 | | - not_found -> |
1583 | | - index_insert(#msg_location { msg_id = MsgId, |
1584 | | - file = undefined, |
1585 | | - ref_count = Delta }, |
1586 | | - State); |
1587 | | - #msg_location { ref_count = RefCount } = StoreEntry -> |
1588 | | - NewRefCount = RefCount + Delta, |
1589 | | - case NewRefCount of |
1590 | | - 0 -> index_delete(MsgId, State); |
1591 | | - _ -> index_update(StoreEntry #msg_location { |
1592 | | - ref_count = NewRefCount }, |
1593 | | - State) |
1594 | | - end |
1595 | | - end, |
| 1579 | + {MsgIds, Next} -> |
| 1580 | + lists:foreach(fun(MsgId) -> |
| 1581 | + %% @todo Remove index_module and avoid this element/2. |
| 1582 | + ets:update_counter(element(2, State#msstate.index_state), MsgId, +1, |
| 1583 | + #msg_location{msg_id=MsgId, file=undefined, ref_count=1}) |
| 1584 | + end, MsgIds), |
1596 | 1585 | count_msg_refs(Gen, Next, State) |
1597 | 1586 | end. |
1598 | 1587 |
|
@@ -1621,15 +1610,15 @@ build_index_worker(Gatherer, State = #msstate { dir = Dir }, |
1621 | 1610 | FileName = filenum_to_name(File), |
1622 | 1611 | rabbit_log:debug("Rebuilding message location index from ~ts (~B file(s) remaining)", |
1623 | 1612 | [form_filename(Dir, FileName), length(Files)]), |
1624 | | - {ok, Messages0, FileSize} = |
| 1613 | + %% The scan function already dealt with duplicate messages |
| 1614 | + %% within the file. We then get messages in reverse order. |
| 1615 | + {ok, Messages, FileSize} = |
1625 | 1616 | scan_file_for_valid_messages(Dir, FileName), |
1626 | | - %% The scan gives us messages end-of-file first so we reverse the list |
1627 | | - %% in case a compaction had occurred before shutdown to not have to repeat it. |
1628 | | - Messages = lists:reverse(Messages0), |
1629 | 1617 | {ValidMessages, ValidTotalSize} = |
1630 | 1618 | lists:foldl( |
1631 | 1619 | fun (Obj = {MsgId, TotalSize, Offset}, {VMAcc, VTSAcc}) -> |
1632 | | - %% We only keep the first message in the file. Duplicates (due to compaction) get ignored. |
| 1620 | + %% Fan-out may result in the same message data in multiple |
| 1621 | + %% files so we have to guard against it. |
1633 | 1622 | case index_lookup(MsgId, State) of |
1634 | 1623 | #msg_location { file = undefined } = StoreEntry -> |
1635 | 1624 | ok = index_update(StoreEntry #msg_location { |
|
0 commit comments