Each merge log details of the level below

Help with troubleshooting memory problems, and potential issues with GC
This commit is contained in:
Martin Sumner 2019-06-13 11:50:02 +01:00
parent da59901890
commit c3a4f5118d
3 changed files with 65 additions and 1 deletions

View file

@ -222,6 +222,9 @@
{info, "Prompting deletions at ManifestSQN=~w"}}, {info, "Prompting deletions at ManifestSQN=~w"}},
{"PC022", {"PC022",
{info, "Storing reference to deletions at ManifestSQN=~w"}}, {info, "Storing reference to deletions at ManifestSQN=~w"}},
{"PC023",
{info, "At level=~w file_count=~w avg_mem=~w "
++ "file with most memory fn=~s p=~w mem=~w"}},
{"PM002", {"PM002",
{info, "Completed dump of L0 cache to list of l0cache_size=~w"}}, {info, "Completed dump of L0 cache to list of l0cache_size=~w"}},

View file

@ -176,6 +176,13 @@ handle_work({SrcLevel, Manifest}, State) ->
{leveled_pmanifest:get_manifest_sqn(UpdManifest), EntriesToDelete}. {leveled_pmanifest:get_manifest_sqn(UpdManifest), EntriesToDelete}.
merge(SrcLevel, Manifest, RootPath, OptsSST) -> merge(SrcLevel, Manifest, RootPath, OptsSST) ->
case leveled_pmanifest:report_manifest_level(Manifest, SrcLevel + 1) of
{0, 0, undefined} ->
ok;
{FCnt, AvgMem, {MaxFN, MaxP, MaxMem}} ->
leveled_log:log("PC023",
[SrcLevel + 1, FCnt, AvgMem, MaxFN, MaxP, MaxMem])
end,
Src = leveled_pmanifest:mergefile_selector(Manifest, SrcLevel), Src = leveled_pmanifest:mergefile_selector(Manifest, SrcLevel),
NewSQN = leveled_pmanifest:get_manifest_sqn(Manifest) + 1, NewSQN = leveled_pmanifest:get_manifest_sqn(Manifest) + 1,
SinkList = leveled_pmanifest:merge_lookup(Manifest, SinkList = leveled_pmanifest:merge_lookup(Manifest,

View file

@ -42,7 +42,8 @@
check_for_work/2, check_for_work/2,
is_basement/2, is_basement/2,
levelzero_present/1, levelzero_present/1,
check_bloom/3 check_bloom/3,
report_manifest_level/2
]). ]).
-export([ -export([
@ -225,6 +226,50 @@ remove_manifest(RootPath, GC_SQN) ->
end. end.
-spec report_manifest_level(manifest(), non_neg_integer()) ->
{non_neg_integer(),
non_neg_integer(),
{string(), pid(), non_neg_integer()} |
undefined}.
%% @doc
%% Report on a level in the manifest
%% - How many files in the level
%% - The average size of the memory occupied by a files in the level
%% - The file with the largest memory footprint {Filename, Pid, Memory}
report_manifest_level(Manifest, LevelIdx) ->
Levels = Manifest#manifest.levels,
Level = array:get(LevelIdx, Levels),
{LevelSize, LevelList} =
case is_list(Level) of
true ->
{length(Level), Level};
_ ->
{leveled_tree:tsize(Level), leveled_tree:to_list(Level)}
end,
AccMemFun =
fun(MaybeME, {MemAcc, Max}) ->
ME = get_manifest_entry(MaybeME),
P = ME#manifest_entry.owner,
{memory, PM} = process_info(P, memory),
UpdMax =
case Max of
{_MaxFN, _MaxP, MaxPM} when MaxPM > PM ->
Max;
_ ->
{ME#manifest_entry.filename, P, PM}
end,
{MemAcc + PM, UpdMax}
end,
case LevelSize of
0 ->
{0, 0, undefined};
_ ->
{TotalMem, BiggestMem} =
lists:foldl(AccMemFun, {0, undefined}, LevelList),
{LevelSize, TotalMem div LevelSize, BiggestMem}
end.
-spec replace_manifest_entry(manifest(), integer(), integer(), -spec replace_manifest_entry(manifest(), integer(), integer(),
list()|manifest_entry(), list()|manifest_entry(),
list()|manifest_entry()) -> manifest(). list()|manifest_entry()) -> manifest().
@ -555,6 +600,15 @@ check_bloom(Manifest, FP, Hash) ->
%%% Internal Functions %%% Internal Functions
%%%============================================================================ %%%============================================================================
-spec get_manifest_entry({tuple(), manifest_entry()}|manifest_entry())
-> manifest_entry().
%% @doc
%% Manifest levels can have entries of two forms, use this if only interested
%% in the latter form
get_manifest_entry({_EndKey, ManifestEntry}) ->
ManifestEntry;
get_manifest_entry(ManifestEntry) ->
ManifestEntry.
%% All these internal functions that work on a level are also passed LeveIdx %% All these internal functions that work on a level are also passed LeveIdx
%% even if this is not presently relevant. Currnetly levels are lists, but %% even if this is not presently relevant. Currnetly levels are lists, but