@@ -381,26 +381,29 @@ recover_wal(Dir, #conf{system = System,
381
381
end || File <- Files0 ,
382
382
filename :extension (File ) == " .wal" ],
383
383
WalFiles = lists :sort (Files ),
384
- AllWriters =
385
- [begin
386
- ? DEBUG (" WAL in ~ts : recovering ~ts , Mode ~s " ,
387
- [System , F , Mode ]),
388
- Fd = open_at_first_record (filename :join (Dir , F )),
389
- {Time , # recovery {ranges = Ranges ,
390
- writers = Writers }} =
391
- timer :tc (fun () -> recover_wal_chunks (Conf , Fd , Mode ) end ),
392
-
393
- ok = ra_log_segment_writer :accept_mem_tables (SegWriter , Ranges , F ),
394
-
395
- close_existing (Fd ),
396
- ? DEBUG (" WAL in ~ts : recovered ~ts time taken ~b ms - recovered ~b writers" ,
397
- [System , F , Time div 1000 , map_size (Writers )]),
398
- Writers
399
- end || F <- WalFiles ],
400
-
401
- FinalWriters = lists :foldl (fun (New , Acc ) ->
402
- maps :merge (Acc , New )
403
- end , #{}, AllWriters ),
384
+ FinalWriters =
385
+ lists :foldl (fun (F , Writers0 ) ->
386
+ ? DEBUG (" WAL in ~ts : recovering ~ts , Mode ~s " ,
387
+ [System , F , Mode ]),
388
+ Fd = open_at_first_record (filename :join (Dir , F )),
389
+ {Time , # recovery {ranges = Ranges ,
390
+ writers = Writers }} =
391
+ timer :tc (fun () ->
392
+ recover_wal_chunks (Conf , Fd ,
393
+ Writers0 , Mode )
394
+ end ),
395
+
396
+ ok = ra_log_segment_writer :accept_mem_tables (SegWriter ,
397
+ Ranges , F ),
398
+ close_existing (Fd ),
399
+ ? DEBUG (" WAL in ~ts : recovered ~ts time taken ~b ms - recovered ~b writers" ,
400
+ [System , F , Time div 1000 , map_size (Writers )]),
401
+ Writers
402
+ end , #{}, WalFiles ),
403
+
404
+ % FinalWriters = lists:foldl(fun (New, Acc) ->
405
+ % maps:merge(Acc, New)
406
+ % end, #{}, AllWriters),
404
407
405
408
? DEBUG (" WAL in ~ts : final writers recovered ~b " ,
406
409
[System , map_size (FinalWriters )]),
@@ -781,9 +784,10 @@ dump_records(<<_:1/unsigned, 1:1/unsigned, _:22/unsigned,
781
784
dump_records (<<>>, Entries ) ->
782
785
Entries .
783
786
784
- recover_wal_chunks (# conf {} = Conf , Fd , Mode ) ->
787
+ recover_wal_chunks (# conf {} = Conf , Fd , Writers , Mode ) ->
785
788
Chunk = read_wal_chunk (Fd , Conf # conf .recovery_chunk_size ),
786
- recover_records (Conf , Fd , Chunk , #{}, # recovery {mode = Mode }).
789
+ recover_records (Conf , Fd , Chunk , #{}, # recovery {mode = Mode ,
790
+ writers = Writers }).
787
791
% All zeros indicates end of a pre-allocated wal file
788
792
recover_records (_ , _Fd , <<0 :1 /unsigned , 0 :1 /unsigned , 0 :22 /unsigned ,
789
793
IdDataLen :16 /unsigned , _ :IdDataLen /binary ,
@@ -824,10 +828,11 @@ recover_records(#conf{names = Names} = Conf, Fd,
824
828
% W ->
825
829
% W#{UId => {in_seq, SmallestIdx}}
826
830
% end,
827
- W = State0 # recovery .writers ,
828
- Writers = W #{UId => {in_seq , SmallestIdx - 1 }},
831
+ Writers = State0 # recovery .writers ,
832
+ % Writers = W#{UId => {in_seq, SmallestIdx - 1}},
829
833
recover_records (Conf , Fd , Rest , Cache ,
830
- State0 # recovery {writers = Writers });
834
+ State0 # recovery {writers =
835
+ maps :remove (UId , Writers )});
831
836
error ->
832
837
System = Conf # conf .system ,
833
838
? DEBUG (" WAL in ~ts : record failed CRC check. If this is the last record"
@@ -1004,7 +1009,17 @@ recover_entry(Names, UId, {Idx, _, _} = Entry, SmallestIdx,
1004
1009
{ok , M } = ra_log_ets :mem_table_please (Names , UId ),
1005
1010
M
1006
1011
end ,
1007
- case ra_mt :insert (Entry , Mt0 ) of
1012
+ % % always use write_sparse as there is nothing to indicate in the wal
1013
+ % % data if an entry was written as such. this way we recover all writes
1014
+ % % so should be ok for all types of writes
1015
+ PrevIdx = case Writers of
1016
+ #{UId := {in_seq , I }} ->
1017
+ I ;
1018
+ _ ->
1019
+ undefined
1020
+ end ,
1021
+ % ct:pal("ra_mt:insert_sparse ~b ~w", [Idx, PrevIdx]),
1022
+ case ra_mt :insert_sparse (Entry , PrevIdx , Mt0 ) of
1008
1023
{ok , Mt1 } ->
1009
1024
Ranges = update_ranges (Ranges0 , UId , ra_mt :tid (Mt1 ),
1010
1025
SmallestIdx , [Idx ]),
@@ -1014,7 +1029,8 @@ recover_entry(Names, UId, {Idx, _, _} = Entry, SmallestIdx,
1014
1029
{error , overwriting } ->
1015
1030
% % create successor memtable
1016
1031
{ok , Mt1 } = ra_log_ets :new_mem_table_please (Names , UId , Mt0 ),
1017
- {retry , State # recovery {tables = Tables #{UId => Mt1 }}}
1032
+ {retry , State # recovery {tables = Tables #{UId => Mt1 },
1033
+ writers = maps :remove (UId , Writers )}}
1018
1034
end ;
1019
1035
recover_entry (Names , UId , {Idx , Term , _ }, SmallestIdx ,
1020
1036
# recovery {mode = post_boot ,
@@ -1049,6 +1065,7 @@ handle_trunc(false, _UId, _Idx, State) ->
1049
1065
State ;
1050
1066
handle_trunc (true , UId , Idx , # recovery {mode = Mode ,
1051
1067
ranges = Ranges0 ,
1068
+ writers = Writers ,
1052
1069
tables = Tbls } = State ) ->
1053
1070
case Tbls of
1054
1071
#{UId := Mt0 } when Mode == initial ->
@@ -1065,9 +1082,10 @@ handle_trunc(true, UId, Idx, #recovery{mode = Mode,
1065
1082
end ,
1066
1083
1067
1084
State # recovery {tables = Tbls #{UId => Mt },
1085
+ writers = maps :remove (UId , Writers ),
1068
1086
ranges = Ranges };
1069
1087
_ ->
1070
- State
1088
+ State # recovery { writers = maps : remove ( UId , Writers )}
1071
1089
end .
1072
1090
1073
1091
named_cast (To , Msg ) when is_pid (To ) ->
0 commit comments