From ddceb9e6cd01574b4bea539ecd891d808e8650fa Mon Sep 17 00:00:00 2001 From: Joonas Koivunen Date: Wed, 11 Oct 2023 18:24:36 +0300 Subject: [PATCH] fix(branching): read last record lsn only after Tenant::gc_cs (#5535) Fixes #5531, at least the latest error of not being able to create a branch from the head under write and gc pressure. --- pageserver/src/tenant.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pageserver/src/tenant.rs b/pageserver/src/tenant.rs index 264f8a1ee0..b79169fd8e 100644 --- a/pageserver/src/tenant.rs +++ b/pageserver/src/tenant.rs @@ -209,7 +209,7 @@ pub struct Tenant { /// The remote storage generation, used to protect S3 objects from split-brain. /// Does not change over the lifetime of the [`Tenant`] object. - /// + /// /// This duplicates the generation stored in LocationConf, but that structure is mutable: /// this copy enforces the invariant that generatio doesn't change during a Tenant's lifetime. generation: Generation, @@ -2755,6 +2755,11 @@ impl Tenant { ) -> Result, CreateTimelineError> { let src_id = src_timeline.timeline_id; + // First acquire the GC lock so that another task cannot advance the GC + // cutoff in 'gc_info', and make 'start_lsn' invalid, while we are + // creating the branch. + let _gc_cs = self.gc_cs.lock().await; + // If no start LSN is specified, we branch the new timeline from the source timeline's last record LSN let start_lsn = start_lsn.unwrap_or_else(|| { let lsn = src_timeline.get_last_record_lsn(); @@ -2762,11 +2767,6 @@ impl Tenant { lsn }); - // First acquire the GC lock so that another task cannot advance the GC - // cutoff in 'gc_info', and make 'start_lsn' invalid, while we are - // creating the branch. - let _gc_cs = self.gc_cs.lock().await; - // Create a placeholder for the new branch. This will error // out if the new timeline ID is already in use. let timeline_uninit_mark = {