Skip to content

Commit 6f93c11

Browse files
authored
Merge pull request #20 from OpenRiak/nhse-o34-d34upstream
Rename any cdb files outside of the manifest (martinsumner#486)
2 parents 37db2f2 + 161db31 commit 6f93c11

3 files changed

Lines changed: 126 additions & 36 deletions

File tree

src/leveled_inker.erl

Lines changed: 80 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@
137137
-define(WASTE_FP, "waste").
138138
-define(JOURNAL_FILEX, "cdb").
139139
-define(PENDING_FILEX, "pnd").
140+
-define(ARCHIVE_FILEX, "bak").
141+
% Note that archive means "no longer active", it is an indication of
142+
% removable waste not of backup.
140143
-define(TEST_KC, {[], infinity}).
141144
-define(SHUTDOWN_LOOPS, 10).
142145
-define(SHUTDOWN_PAUSE, 10000).
@@ -682,7 +685,7 @@ handle_call(roll, _From, State = #state{is_snapshot = Snap}) when
682685
}}
683686
end;
684687
handle_call(
685-
{backup, BackupPath}, _from, State
688+
{backup, BackupPath}, _From, State
686689
) when
687690
State#state.is_snapshot == true
688691
->
@@ -699,20 +702,21 @@ handle_call(
699702
ExtendedBaseFN = BaseFN ++ "." ++ ?JOURNAL_FILEX,
700703
BackupName = filename:join(BackupJFP, BaseFN),
701704
true = leveled_cdb:finished_rolling(PidR),
702-
case
705+
Link =
703706
file:make_link(
704707
FN ++ "." ++ ?JOURNAL_FILEX,
705708
BackupName ++ "." ++ ?JOURNAL_FILEX
706-
)
707-
of
709+
),
710+
case Link of
708711
ok ->
709712
ok;
710713
{error, eexist} ->
711714
ok
712715
end,
713-
{[{SQN, BackupName, PidR, LastKey} | ManAcc], [
714-
ExtendedBaseFN | FTRAcc
715-
]};
716+
{
717+
[{SQN, BackupName, PidR, LastKey} | ManAcc],
718+
[ExtendedBaseFN | FTRAcc]
719+
};
716720
false ->
717721
?STD_LOG(i0021, [FN, SQN, State#state.journal_sqn]),
718722
{ManAcc, FTRAcc}
@@ -1263,7 +1267,7 @@ close_allmanifest([H | ManifestT]) ->
12631267
) ->
12641268
leveled_imanifest:manifest().
12651269
%% @doc
1266-
%% Open all the files in the manifets, and updating the manifest with the PIDs
1270+
%% Open all the files in the manifest, and updating the manifest with the PIDs
12671271
%% of the opened files
12681272
open_all_manifest([], RootPath, CDBOpts) ->
12691273
?STD_LOG(i0011, []),
@@ -1273,51 +1277,93 @@ open_all_manifest([], RootPath, CDBOpts) ->
12731277
true
12741278
);
12751279
open_all_manifest(Man0, RootPath, CDBOpts) ->
1280+
OnDiskJournalSet =
1281+
sets:from_list(get_all_completejournals(RootPath), [{version, 2}]),
12761282
Man1 = leveled_imanifest:to_list(Man0),
12771283
[{HeadSQN, HeadFN, _IgnorePid, HeadLK} | ManifestTail] = Man1,
12781284
OpenJournalFun =
1279-
fun(ManEntry) ->
1285+
fun(ManEntry, Acc) ->
12801286
{LowSQN, FN, _, LK_RO} = ManEntry,
12811287
CFN = FN ++ "." ++ ?JOURNAL_FILEX,
12821288
PFN = FN ++ "." ++ ?PENDING_FILEX,
12831289
case filelib:is_file(CFN) of
12841290
true ->
12851291
{ok, Pid} =
12861292
leveled_cdb:cdb_reopen_reader(CFN, LK_RO, CDBOpts),
1287-
{LowSQN, FN, Pid, LK_RO};
1293+
{
1294+
{LowSQN, FN, Pid, LK_RO},
1295+
sets:del_element(CFN, Acc)
1296+
};
12881297
false ->
1289-
W = leveled_cdb:cdb_open_writer(PFN, CDBOpts),
1290-
{ok, Pid} = W,
1298+
{ok, Pid} = leveled_cdb:cdb_open_writer(PFN, CDBOpts),
12911299
ok = leveled_cdb:cdb_roll(Pid),
12921300
LK_WR = leveled_cdb:cdb_lastkey(Pid),
1293-
{LowSQN, FN, Pid, LK_WR}
1301+
{
1302+
{LowSQN, FN, Pid, LK_WR},
1303+
Acc
1304+
}
12941305
end
12951306
end,
1296-
OpenedTailAsList = lists:map(OpenJournalFun, ManifestTail),
1307+
{
1308+
OpenedTailAsList,
1309+
FilteredOnDiskJournalSet
1310+
} =
1311+
lists:mapfoldl(OpenJournalFun, OnDiskJournalSet, ManifestTail),
12971312
OpenedTail = leveled_imanifest:from_list(OpenedTailAsList),
12981313
CompleteHeadFN = HeadFN ++ "." ++ ?JOURNAL_FILEX,
12991314
PendingHeadFN = HeadFN ++ "." ++ ?PENDING_FILEX,
1300-
case filelib:is_file(CompleteHeadFN) of
1301-
true ->
1302-
?STD_LOG(i0012, [HeadFN]),
1303-
{ok, HeadR} = leveled_cdb:cdb_open_reader(CompleteHeadFN),
1304-
LastKey = {LastSQN, _, _} = leveled_cdb:cdb_lastkey(HeadR),
1305-
ManToHead =
1315+
StartedManifest =
1316+
case filelib:is_file(CompleteHeadFN) of
1317+
true ->
1318+
?STD_LOG(i0012, [HeadFN]),
1319+
{ok, HeadR} = leveled_cdb:cdb_open_reader(CompleteHeadFN),
1320+
LastKey = {LastSQN, _, _} = leveled_cdb:cdb_lastkey(HeadR),
1321+
ManToHead =
1322+
leveled_imanifest:add_entry(
1323+
OpenedTail,
1324+
{HeadSQN, HeadFN, HeadR, LastKey},
1325+
true
1326+
),
1327+
NewManEntry =
1328+
start_new_activejournal(LastSQN + 1, RootPath, CDBOpts),
1329+
leveled_imanifest:add_entry(ManToHead, NewManEntry, true);
1330+
false ->
1331+
{ok, HeadW} =
1332+
leveled_cdb:cdb_open_writer(PendingHeadFN, CDBOpts),
13061333
leveled_imanifest:add_entry(
1307-
OpenedTail,
1308-
{HeadSQN, HeadFN, HeadR, LastKey},
1309-
true
1310-
),
1311-
NewManEntry =
1312-
start_new_activejournal(LastSQN + 1, RootPath, CDBOpts),
1313-
leveled_imanifest:add_entry(ManToHead, NewManEntry, true);
1314-
false ->
1315-
{ok, HeadW} =
1316-
leveled_cdb:cdb_open_writer(PendingHeadFN, CDBOpts),
1317-
leveled_imanifest:add_entry(
1318-
OpenedTail, {HeadSQN, HeadFN, HeadW, HeadLK}, true
1319-
)
1320-
end.
1334+
OpenedTail, {HeadSQN, HeadFN, HeadW, HeadLK}, true
1335+
)
1336+
end,
1337+
lists:foreach(
1338+
fun(FN) ->
1339+
NewName =
1340+
filename:flatten([filename:rootname(FN), "." ++ ?ARCHIVE_FILEX]),
1341+
?STD_LOG(i0029, [FN]),
1342+
file:rename(FN, NewName)
1343+
end,
1344+
sets:to_list(
1345+
sets:del_element(CompleteHeadFN, FilteredOnDiskJournalSet)
1346+
)
1347+
),
1348+
StartedManifest.
1349+
1350+
-spec get_all_completejournals(string()) -> list(file:filename()).
1351+
get_all_completejournals(RootPath) ->
1352+
JFiles = list_dir(filepath(RootPath, journal_dir)),
1353+
CFiles = list_dir(filepath(RootPath, journal_compact_dir)),
1354+
lists:filter(
1355+
fun(FN) ->
1356+
filename:extension(FN) == ("." ++ ?JOURNAL_FILEX)
1357+
end,
1358+
JFiles ++ CFiles
1359+
).
1360+
1361+
-spec list_dir(string()) -> list(file:filename()).
1362+
list_dir(Path) ->
1363+
{ok, Files} = file:list_dir(Path),
1364+
lists:map(
1365+
fun(FN) -> filename:join(Path, FN) end, Files
1366+
).
13211367

13221368
start_new_activejournal(SQN, RootPath, CDBOpts) ->
13231369
Filename = filepath(RootPath, SQN, new_journal),

src/leveled_log.erl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,9 @@
311311
{debug, <<"Shutdown complete for cloned Inker for reason ~w">>},
312312
i0028 =>
313313
{debug, <<"Shutdown complete for Inker for reason ~w">>},
314+
i0029 =>
315+
{warning,
316+
<<"Journal with FN=~s renamed to backup as not active in manifest">>},
314317
ic001 =>
315318
{info, <<"Closed for reason ~w so maybe leaving garbage">>},
316319
ic002 =>

test/end_to_end/recovery_SUITE.erl

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -859,15 +859,56 @@ aae_missingjournal(_Config) ->
859859
{async, AllHeadF2} =
860860
leveled_bookie:book_returnfolder(
861861
Bookie2,
862-
{foldheads_allkeys, ?RIAK_TAG, FoldHeadsFun, true, true, false,
863-
false, false}
862+
{
863+
foldheads_allkeys,
864+
?RIAK_TAG,
865+
FoldHeadsFun,
866+
true,
867+
true,
868+
false,
869+
false,
870+
false
871+
}
864872
),
865873
HeadL2 = length(AllHeadF2()),
866874
io:format("Fold head returned ~w objects~n", [HeadL2]),
867875
true = HeadL2 < HeadL1,
868876
true = HeadL2 > 0,
869877

870878
ok = leveled_bookie:book_close(Bookie2),
879+
880+
% Add extra journal file - check it gets switched to .bak
881+
FNXJ = RootPath ++ "/journal/journal_files/extra_file",
882+
FNXC = RootPath ++ "/journal/journal_files/post_compact/extra_file",
883+
ok = file:write_file(FNXJ ++ ".cdb", <<"NotaCDB">>),
884+
ok = file:write_file(FNXC ++ ".cdb", <<"NotaCDB">>),
885+
{ok, _} = file:read_file_info(FNXJ ++ ".cdb"),
886+
{ok, _} = file:read_file_info(FNXC ++ ".cdb"),
887+
888+
{ok, Bookie3} = leveled_bookie:book_start(StartOpts),
889+
{async, AllHeadF3} =
890+
leveled_bookie:book_returnfolder(
891+
Bookie3,
892+
{
893+
foldheads_allkeys,
894+
?RIAK_TAG,
895+
FoldHeadsFun,
896+
true,
897+
true,
898+
false,
899+
false,
900+
false
901+
}
902+
),
903+
HeadL3 = length(AllHeadF3()),
904+
true = HeadL3 == HeadL2,
905+
906+
ok = leveled_bookie:book_close(Bookie3),
907+
908+
{error, enoent} = file:read_file_info(FNXJ ++ ".cdb"),
909+
{error, enoent} = file:read_file_info(FNXJ ++ ".cdb"),
910+
{ok, <<"NotaCDB">>} = file:read_file(FNXJ ++ ".bak"),
911+
{ok, <<"NotaCDB">>} = file:read_file(FNXC ++ ".bak"),
871912
testutil:reset_filestructure().
872913

873914
simple_cachescoring(_Config) ->

0 commit comments

Comments
 (0)