|
23 | 23 | client_ref/1, close_all_indicated/1, |
24 | 24 | write/3, write_flow/3, read/2, contains/2, remove/2]). |
25 | 25 |
|
26 | | --export([set_maximum_since_use/2, has_readers/2, combine_files/3, |
| 26 | +-export([set_maximum_since_use/2, combine_files/3, |
27 | 27 | delete_file/2]). %% internal |
28 | 28 |
|
29 | 29 | -export([transform_dir/3, force_recovery/2]). %% upgrade |
|
192 | 192 | -spec remove([rabbit_types:msg_id()], client_msstate()) -> 'ok'. |
193 | 193 |
|
194 | 194 | -spec set_maximum_since_use(server(), non_neg_integer()) -> 'ok'. |
195 | | --spec has_readers(non_neg_integer(), gc_state()) -> boolean(). |
196 | | --spec combine_files(non_neg_integer(), non_neg_integer(), gc_state()) -> |
197 | | - deletion_thunk(). |
198 | | --spec delete_file(non_neg_integer(), gc_state()) -> deletion_thunk(). |
| 195 | + |
199 | 196 | -spec force_recovery(file:filename(), server()) -> 'ok'. |
200 | 197 | -spec transform_dir(file:filename(), server(), |
201 | 198 | fun ((any()) -> (rabbit_types:ok_or_error2(msg(), any())))) -> 'ok'. |
@@ -1965,28 +1962,48 @@ cleanup_after_file_deletion(File, |
1965 | 1962 | %% garbage collection / compaction / aggregation -- external |
1966 | 1963 | %%---------------------------------------------------------------------------- |
1967 | 1964 |
|
1968 | | -has_readers(File, #gc_state { file_summary_ets = FileSummaryEts }) -> |
1969 | | - [#file_summary { locked = true, readers = Count }] = |
1970 | | - ets:lookup(FileSummaryEts, File), |
1971 | | - Count /= 0. |
| 1965 | +-spec combine_files(non_neg_integer(), non_neg_integer(), gc_state()) -> |
| 1966 | + {ok, deletion_thunk()} | {defer, non_neg_integer()}. |
1972 | 1967 |
|
1973 | 1968 | combine_files(Source, Destination, |
1974 | | - State = #gc_state { file_summary_ets = FileSummaryEts, |
1975 | | - file_handles_ets = FileHandlesEts, |
1976 | | - dir = Dir, |
1977 | | - msg_store = Server }) -> |
1978 | | - [#file_summary { |
| 1969 | + State = #gc_state { file_summary_ets = FileSummaryEts }) -> |
| 1970 | + [#file_summary{locked = true} = SourceSummary] = |
| 1971 | + ets:lookup(FileSummaryEts, Source), |
| 1972 | + |
| 1973 | + [#file_summary{locked = true} = DestinationSummary] = |
| 1974 | + ets:lookup(FileSummaryEts, Destination), |
| 1975 | + |
| 1976 | + case {SourceSummary, DestinationSummary} of |
| 1977 | + {#file_summary{readers = 0}, #file_summary{readers = 0}} -> |
| 1978 | + {ok, do_combine_files(SourceSummary, DestinationSummary, |
| 1979 | + Source, Destination, State)}; |
| 1980 | + _ -> |
| 1981 | + rabbit_log:debug("Asked to combine files ~p and ~p but they have active readers. Deferring.", |
| 1982 | + [Source, Destination]), |
| 1983 | + DeferredFiles = [FileSummary#file_summary.file |
| 1984 | + || FileSummary <- [SourceSummary, DestinationSummary], |
| 1985 | + FileSummary#file_summary.readers /= 0], |
| 1986 | + {defer, DeferredFiles} |
| 1987 | + end. |
| 1988 | + |
| 1989 | +do_combine_files(SourceSummary, DestinationSummary, |
| 1990 | + Source, Destination, |
| 1991 | + State = #gc_state { file_summary_ets = FileSummaryEts, |
| 1992 | + file_handles_ets = FileHandlesEts, |
| 1993 | + dir = Dir, |
| 1994 | + msg_store = Server }) -> |
| 1995 | + #file_summary { |
1979 | 1996 | readers = 0, |
1980 | 1997 | left = Destination, |
1981 | 1998 | valid_total_size = SourceValid, |
1982 | 1999 | file_size = SourceFileSize, |
1983 | | - locked = true }] = ets:lookup(FileSummaryEts, Source), |
1984 | | - [#file_summary { |
| 2000 | + locked = true } = SourceSummary, |
| 2001 | + #file_summary { |
1985 | 2002 | readers = 0, |
1986 | 2003 | right = Source, |
1987 | 2004 | valid_total_size = DestinationValid, |
1988 | 2005 | file_size = DestinationFileSize, |
1989 | | - locked = true }] = ets:lookup(FileSummaryEts, Destination), |
| 2006 | + locked = true } = DestinationSummary, |
1990 | 2007 |
|
1991 | 2008 | SourceName = filenum_to_name(Source), |
1992 | 2009 | DestinationName = filenum_to_name(Destination), |
@@ -2043,20 +2060,30 @@ combine_files(Source, Destination, |
2043 | 2060 | {#file_summary.file_size, TotalValidData}]), |
2044 | 2061 |
|
2045 | 2062 | Reclaimed = SourceFileSize + DestinationFileSize - TotalValidData, |
| 2063 | + rabbit_log:debug("Combined segment files number ~p (source) and ~p (destination), reclaimed ~p bytes", |
| 2064 | + [Source, Destination, Reclaimed]), |
2046 | 2065 | gen_server2:cast(Server, {combine_files, Source, Destination, Reclaimed}), |
2047 | 2066 | safe_file_delete_fun(Source, Dir, FileHandlesEts). |
2048 | 2067 |
|
| 2068 | +-spec delete_file(non_neg_integer(), gc_state()) -> {ok, deletion_thunk()} | {defer, non_neg_integer()}. |
| 2069 | + |
2049 | 2070 | delete_file(File, State = #gc_state { file_summary_ets = FileSummaryEts, |
2050 | 2071 | file_handles_ets = FileHandlesEts, |
2051 | 2072 | dir = Dir, |
2052 | 2073 | msg_store = Server }) -> |
2053 | | - [#file_summary { valid_total_size = 0, |
2054 | | - locked = true, |
2055 | | - file_size = FileSize, |
2056 | | - readers = 0 }] = ets:lookup(FileSummaryEts, File), |
2057 | | - {[], 0} = load_and_vacuum_message_file(File, State), |
2058 | | - gen_server2:cast(Server, {delete_file, File, FileSize}), |
2059 | | - safe_file_delete_fun(File, Dir, FileHandlesEts). |
| 2074 | + case ets:lookup(FileSummaryEts, File) of |
| 2075 | + [#file_summary { valid_total_size = 0, |
| 2076 | + locked = true, |
| 2077 | + file_size = FileSize, |
| 2078 | + readers = 0 }] -> |
| 2079 | + {[], 0} = load_and_vacuum_message_file(File, State), |
| 2080 | + gen_server2:cast(Server, {delete_file, File, FileSize}), |
| 2081 | + {ok, safe_file_delete_fun(File, Dir, FileHandlesEts)}; |
| 2082 | + [#file_summary{readers = Readers}] when Readers > 0 -> |
| 2083 | + rabbit_log:debug("Asked to delete file ~p but it has active readers. Deferring.", |
| 2084 | + [File]), |
| 2085 | + {defer, [File]} |
| 2086 | + end. |
2060 | 2087 |
|
2061 | 2088 | load_and_vacuum_message_file(File, State = #gc_state { dir = Dir }) -> |
2062 | 2089 | %% Messages here will be end-of-file at start-of-list |
|
0 commit comments