Fix infinite loop in looking up predecessor layer

Commit 960c7d69a8 changed the LSN returned in the Continue case in
InMemoryLayer::get_page_reconstruct_data(), but neglected to make the
same change in DeltaLayer.

Also add an escape hatch to the loop in materialize_page() to avoid
getting stuck in an infinite loop, if a bug like this reoccurs.
This commit is contained in:
Heikki Linnakangas
2021-11-04 16:07:12 +02:00
parent c75bc9b8b0
commit 6d742719a1
2 changed files with 10 additions and 1 deletions

View File

@@ -1534,6 +1534,15 @@ impl LayeredTimeline {
PageReconstructResult::Continue(cont_lsn) => {
// Fetch base image / more WAL from the returned predecessor layer
if let Some((cont_layer, cont_lsn)) = self.get_layer_for_read(seg, cont_lsn)? {
if cont_lsn == curr_lsn {
// We landed on the same layer again. Shouldn't happen, but if it does,
// don't get stuck in an infinite loop.
bail!(
"could not find predecessor layer of segment {} at {}",
seg.rel,
cont_lsn
);
}
layer_arc = cont_layer;
layer_ref = &*layer_arc;
curr_lsn = cont_lsn;

View File

@@ -230,7 +230,7 @@ impl Layer for DeltaLayer {
// If an older page image is needed to reconstruct the page, let the
// caller know.
if need_image {
Ok(PageReconstructResult::Continue(self.start_lsn))
Ok(PageReconstructResult::Continue(Lsn(self.start_lsn.0 - 1)))
} else {
Ok(PageReconstructResult::Complete)
}