@@ -334,14 +334,31 @@ where
334334 let _t = StopWatch :: new ( & * ENGINE_READ_ENTRY_DURATION_HISTOGRAM ) ;
335335 if let Some ( memtable) = self . memtables . get ( region_id) {
336336 let mut ents_idx: Vec < EntryIndex > = Vec :: with_capacity ( ( end - begin) as usize ) ;
337- // Ensure that the corresponding memtable is locked with a read lock before
338- // completing the fetching of entries from the raft logs. This
339- // prevents the scenario where the index could become stale while
340- // being concurrently updated by the `rewrite` operation.
341- let immutable = memtable. read ( ) ;
342- immutable. fetch_entries_to ( begin, end, max_size, & mut ents_idx) ?;
337+ memtable
338+ . read ( )
339+ . fetch_entries_to ( begin, end, max_size, & mut ents_idx) ?;
343340 for i in ents_idx. iter ( ) {
344- vec. push ( read_entry_from_file :: < M , _ > ( self . pipe_log . as_ref ( ) , i) ?) ;
341+ vec. push ( {
342+ match read_entry_from_file :: < M , _ > ( self . pipe_log . as_ref ( ) , i) {
343+ Ok ( entry) => entry,
344+ Err ( e) => {
345+ // The index is not found in the file, it means the entry is already
346+ // stale by `compact` or `rewrite`. Retry to read the entry from the
347+ // memtable.
348+ let immutable = memtable. read ( ) ;
349+ // Ensure that the corresponding memtable is locked with a read lock
350+ // before completing the fetching of entries
351+ // from the raft logs. This prevents the
352+ // scenario where the index could become stale while
353+ // being concurrently updated by the `rewrite` operation.
354+ if let Some ( idx) = immutable. get_entry ( i. index ) {
355+ read_entry_from_file :: < M , _ > ( self . pipe_log . as_ref ( ) , & idx) ?
356+ } else {
357+ return Err ( e) ;
358+ }
359+ }
360+ }
361+ } ) ;
345362 }
346363 ENGINE_READ_ENTRY_COUNT_HISTOGRAM . observe ( ents_idx. len ( ) as f64 ) ;
347364 return Ok ( ents_idx. len ( ) ) ;
0 commit comments