|
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 |
@@ -1970,33 +1970,48 @@ cleanup_after_file_deletion(File, |
1970 | 1970 | %% garbage collection / compaction / aggregation -- external |
1971 | 1971 | %%---------------------------------------------------------------------------- |
1972 | 1972 |
|
1973 | | --spec has_readers(non_neg_integer(), gc_state()) -> boolean(). |
1974 | | - |
1975 | | -has_readers(File, #gc_state { file_summary_ets = FileSummaryEts }) -> |
1976 | | - [#file_summary { locked = true, readers = Count }] = |
1977 | | - ets:lookup(FileSummaryEts, File), |
1978 | | - Count /= 0. |
1979 | | - |
1980 | 1973 | -spec combine_files(non_neg_integer(), non_neg_integer(), gc_state()) -> |
1981 | | - deletion_thunk(). |
| 1974 | + {ok, deletion_thunk()} | {defer, non_neg_integer()}. |
1982 | 1975 |
|
1983 | 1976 | combine_files(Source, Destination, |
1984 | | - State = #gc_state { file_summary_ets = FileSummaryEts, |
1985 | | - file_handles_ets = FileHandlesEts, |
1986 | | - dir = Dir, |
1987 | | - msg_store = Server }) -> |
1988 | | - [#file_summary { |
| 1977 | + State = #gc_state { file_summary_ets = FileSummaryEts }) -> |
| 1978 | + [#file_summary{locked = true} = SourceSummary] = |
| 1979 | + ets:lookup(FileSummaryEts, Source), |
| 1980 | + |
| 1981 | + [#file_summary{locked = true} = DestinationSummary] = |
| 1982 | + ets:lookup(FileSummaryEts, Destination), |
| 1983 | + |
| 1984 | + case {SourceSummary, DestinationSummary} of |
| 1985 | + {#file_summary{readers = 0}, #file_summary{readers = 0}} -> |
| 1986 | + {ok, do_combine_files(SourceSummary, DestinationSummary, |
| 1987 | + Source, Destination, State)}; |
| 1988 | + _ -> |
| 1989 | + rabbit_log:debug("Asked to combine files ~p and ~p but they have active readers. Deferring.", |
| 1990 | + [Source, Destination]), |
| 1991 | + DeferredFiles = [FileSummary#file_summary.file |
| 1992 | + || FileSummary <- [SourceSummary, DestinationSummary], |
| 1993 | + FileSummary#file_summary.readers /= 0], |
| 1994 | + {defer, DeferredFiles} |
| 1995 | + end. |
| 1996 | + |
| 1997 | +do_combine_files(SourceSummary, DestinationSummary, |
| 1998 | + Source, Destination, |
| 1999 | + State = #gc_state { file_summary_ets = FileSummaryEts, |
| 2000 | + file_handles_ets = FileHandlesEts, |
| 2001 | + dir = Dir, |
| 2002 | + msg_store = Server }) -> |
| 2003 | + #file_summary { |
1989 | 2004 | readers = 0, |
1990 | 2005 | left = Destination, |
1991 | 2006 | valid_total_size = SourceValid, |
1992 | 2007 | file_size = SourceFileSize, |
1993 | | - locked = true }] = ets:lookup(FileSummaryEts, Source), |
1994 | | - [#file_summary { |
| 2008 | + locked = true } = SourceSummary, |
| 2009 | + #file_summary { |
1995 | 2010 | readers = 0, |
1996 | 2011 | right = Source, |
1997 | 2012 | valid_total_size = DestinationValid, |
1998 | 2013 | file_size = DestinationFileSize, |
1999 | | - locked = true }] = ets:lookup(FileSummaryEts, Destination), |
| 2014 | + locked = true } = DestinationSummary, |
2000 | 2015 |
|
2001 | 2016 | SourceName = filenum_to_name(Source), |
2002 | 2017 | DestinationName = filenum_to_name(Destination), |
@@ -2053,22 +2068,30 @@ combine_files(Source, Destination, |
2053 | 2068 | {#file_summary.file_size, TotalValidData}]), |
2054 | 2069 |
|
2055 | 2070 | Reclaimed = SourceFileSize + DestinationFileSize - TotalValidData, |
| 2071 | + rabbit_log:debug("Combined segment files number ~p (source) and ~p (destination), reclaimed ~p bytes", |
| 2072 | + [Source, Destination, Reclaimed]), |
2056 | 2073 | gen_server2:cast(Server, {combine_files, Source, Destination, Reclaimed}), |
2057 | 2074 | safe_file_delete_fun(Source, Dir, FileHandlesEts). |
2058 | 2075 |
|
2059 | | --spec delete_file(non_neg_integer(), gc_state()) -> deletion_thunk(). |
| 2076 | +-spec delete_file(non_neg_integer(), gc_state()) -> {ok, deletion_thunk()} | {defer, non_neg_integer()}. |
2060 | 2077 |
|
2061 | 2078 | delete_file(File, State = #gc_state { file_summary_ets = FileSummaryEts, |
2062 | 2079 | file_handles_ets = FileHandlesEts, |
2063 | 2080 | dir = Dir, |
2064 | 2081 | msg_store = Server }) -> |
2065 | | - [#file_summary { valid_total_size = 0, |
2066 | | - locked = true, |
2067 | | - file_size = FileSize, |
2068 | | - readers = 0 }] = ets:lookup(FileSummaryEts, File), |
2069 | | - {[], 0} = load_and_vacuum_message_file(File, State), |
2070 | | - gen_server2:cast(Server, {delete_file, File, FileSize}), |
2071 | | - safe_file_delete_fun(File, Dir, FileHandlesEts). |
| 2082 | + case ets:lookup(FileSummaryEts, File) of |
| 2083 | + [#file_summary { valid_total_size = 0, |
| 2084 | + locked = true, |
| 2085 | + file_size = FileSize, |
| 2086 | + readers = 0 }] -> |
| 2087 | + {[], 0} = load_and_vacuum_message_file(File, State), |
| 2088 | + gen_server2:cast(Server, {delete_file, File, FileSize}), |
| 2089 | + {ok, safe_file_delete_fun(File, Dir, FileHandlesEts)}; |
| 2090 | + [#file_summary{readers = Readers}] when Readers > 0 -> |
| 2091 | + rabbit_log:debug("Asked to delete file ~p but it has active readers. Deferring.", |
| 2092 | + [File]), |
| 2093 | + {defer, [File]} |
| 2094 | + end. |
2072 | 2095 |
|
2073 | 2096 | load_and_vacuum_message_file(File, State = #gc_state { dir = Dir }) -> |
2074 | 2097 | %% Messages here will be end-of-file at start-of-list |
|
0 commit comments