@@ -381,26 +381,29 @@ recover_wal(Dir, #conf{system = System,
381381 end || File <- Files0 ,
382382 filename :extension (File ) == " .wal" ],
383383 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),
404407
405408 ? DEBUG (" WAL in ~ts : final writers recovered ~b " ,
406409 [System , map_size (FinalWriters )]),
@@ -781,9 +784,10 @@ dump_records(<<_:1/unsigned, 1:1/unsigned, _:22/unsigned,
781784dump_records (<<>>, Entries ) ->
782785 Entries .
783786
784- recover_wal_chunks (# conf {} = Conf , Fd , Mode ) ->
787+ recover_wal_chunks (# conf {} = Conf , Fd , Writers , Mode ) ->
785788 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 }).
787791% All zeros indicates end of a pre-allocated wal file
788792recover_records (_ , _Fd , <<0 :1 /unsigned , 0 :1 /unsigned , 0 :22 /unsigned ,
789793 IdDataLen :16 /unsigned , _ :IdDataLen /binary ,
@@ -824,10 +828,11 @@ recover_records(#conf{names = Names} = Conf, Fd,
824828 % W ->
825829 % W#{UId => {in_seq, SmallestIdx}}
826830 % 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}},
829833 recover_records (Conf , Fd , Rest , Cache ,
830- State0 # recovery {writers = Writers });
834+ State0 # recovery {writers =
835+ maps :remove (UId , Writers )});
831836 error ->
832837 System = Conf # conf .system ,
833838 ? DEBUG (" WAL in ~ts : record failed CRC check. If this is the last record"
@@ -1004,7 +1009,16 @@ recover_entry(Names, UId, {Idx, _, _} = Entry, SmallestIdx,
10041009 {ok , M } = ra_log_ets :mem_table_please (Names , UId ),
10051010 M
10061011 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+ case ra_mt :insert_sparse (Entry , PrevIdx , Mt0 ) of
10081022 {ok , Mt1 } ->
10091023 Ranges = update_ranges (Ranges0 , UId , ra_mt :tid (Mt1 ),
10101024 SmallestIdx , [Idx ]),
@@ -1014,7 +1028,8 @@ recover_entry(Names, UId, {Idx, _, _} = Entry, SmallestIdx,
10141028 {error , overwriting } ->
10151029 % % create successor memtable
10161030 {ok , Mt1 } = ra_log_ets :new_mem_table_please (Names , UId , Mt0 ),
1017- {retry , State # recovery {tables = Tables #{UId => Mt1 }}}
1031+ {retry , State # recovery {tables = Tables #{UId => Mt1 },
1032+ writers = maps :remove (UId , Writers )}}
10181033 end ;
10191034recover_entry (Names , UId , {Idx , Term , _ }, SmallestIdx ,
10201035 # recovery {mode = post_boot ,
@@ -1049,6 +1064,7 @@ handle_trunc(false, _UId, _Idx, State) ->
10491064 State ;
10501065handle_trunc (true , UId , Idx , # recovery {mode = Mode ,
10511066 ranges = Ranges0 ,
1067+ writers = Writers ,
10521068 tables = Tbls } = State ) ->
10531069 case Tbls of
10541070 #{UId := Mt0 } when Mode == initial ->
@@ -1065,9 +1081,10 @@ handle_trunc(true, UId, Idx, #recovery{mode = Mode,
10651081 end ,
10661082
10671083 State # recovery {tables = Tbls #{UId => Mt },
1084+ writers = maps :remove (UId , Writers ),
10681085 ranges = Ranges };
10691086 _ ->
1070- State
1087+ State # recovery { writers = maps : remove ( UId , Writers )}
10711088 end .
10721089
10731090named_cast (To , Msg ) when is_pid (To ) ->
0 commit comments