Do not delete layers beyand cutoff LSN (#1128)

* Do not delete layers beyand cutoff LSN

* Update pageserver/src/layered_repository/layer_map.rs

Co-authored-by: Heikki Linnakangas <heikki.linnakangas@iki.fi>

Co-authored-by: Heikki Linnakangas <heikki.linnakangas@iki.fi>
This commit is contained in:
Konstantin Knizhnik
2022-01-24 10:42:40 +03:00
committed by GitHub
parent 65290b2e96
commit e209764877
2 changed files with 17 additions and 6 deletions

View File

@@ -651,7 +651,6 @@ impl LayeredRepository {
timeline.checkpoint(CheckpointConfig::Forced)?;
info!("timeline {} checkpoint_before_gc done", timelineid);
}
let result = timeline.gc_timeline(branchpoints, cutoff)?;
totals += result;
@@ -1633,6 +1632,7 @@ impl LayeredTimeline {
pub fn gc_timeline(&self, retain_lsns: Vec<Lsn>, cutoff: Lsn) -> Result<GcResult> {
let now = Instant::now();
let mut result: GcResult = Default::default();
let disk_consistent_lsn = self.get_disk_consistent_lsn();
let _enter = info_span!("garbage collection", timeline = %self.timelineid, tenant = %self.tenantid, cutoff = %cutoff).entered();
@@ -1718,7 +1718,12 @@ impl LayeredTimeline {
}
// 3. Is there a later on-disk layer for this relation?
if !l.is_dropped() && !layers.newer_image_layer_exists(l.get_seg_tag(), l.get_end_lsn())
if !l.is_dropped()
&& !layers.newer_image_layer_exists(
l.get_seg_tag(),
l.get_end_lsn(),
disk_consistent_lsn,
)
{
info!(
"keeping {} {}-{} because it is the latest layer",

View File

@@ -191,9 +191,15 @@ impl LayerMap {
///
/// This is used for garbage collection, to determine if an old layer can
/// be deleted.
pub fn newer_image_layer_exists(&self, seg: SegmentTag, lsn: Lsn) -> bool {
/// We ignore segments newer than disk_consistent_lsn because they will be removed at restart
pub fn newer_image_layer_exists(
&self,
seg: SegmentTag,
lsn: Lsn,
disk_consistent_lsn: Lsn,
) -> bool {
if let Some(segentry) = self.segs.get(&seg) {
segentry.newer_image_layer_exists(lsn)
segentry.newer_image_layer_exists(lsn, disk_consistent_lsn)
} else {
false
}
@@ -311,13 +317,13 @@ impl SegEntry {
self.historic.search(lsn)
}
pub fn newer_image_layer_exists(&self, lsn: Lsn) -> bool {
pub fn newer_image_layer_exists(&self, lsn: Lsn, disk_consistent_lsn: Lsn) -> bool {
// We only check on-disk layers, because
// in-memory layers are not durable
self.historic
.iter_newer(lsn)
.any(|layer| !layer.is_incremental())
.any(|layer| !layer.is_incremental() && layer.get_end_lsn() <= disk_consistent_lsn)
}
// Set new open layer for a SegEntry.