diff --git a/pageserver/src/basebackup.rs b/pageserver/src/basebackup.rs index 975318419f..cae0ffb980 100644 --- a/pageserver/src/basebackup.rs +++ b/pageserver/src/basebackup.rs @@ -59,6 +59,7 @@ pub async fn send_basebackup_tarball<'a, W>( req_lsn: Option, prev_lsn: Option, full_backup: bool, + replica: bool, ctx: &'a RequestContext, ) -> Result<(), BasebackupError> where @@ -110,8 +111,8 @@ where }; info!( - "taking basebackup lsn={}, prev_lsn={} (full_backup={})", - backup_lsn, prev_lsn, full_backup + "taking basebackup lsn={}, prev_lsn={} (full_backup={}, replica={})", + backup_lsn, prev_lsn, full_backup, replica ); let basebackup = Basebackup { @@ -120,6 +121,7 @@ where lsn: backup_lsn, prev_record_lsn: prev_lsn, full_backup, + replica, ctx, }; basebackup @@ -140,6 +142,7 @@ where lsn: Lsn, prev_record_lsn: Lsn, full_backup: bool, + replica: bool, ctx: &'a RequestContext, } @@ -372,6 +375,10 @@ where for (path, content) in aux_files { if path.starts_with("pg_replslot") { + // Do not create LR slots at standby because they are not used but prevent WAL truncation + if self.replica { + continue; + } let offs = pg_constants::REPL_SLOT_ON_DISK_OFFSETOF_RESTART_LSN; let restart_lsn = Lsn(u64::from_le_bytes( content[offs..offs + 8].try_into().unwrap(), diff --git a/pageserver/src/page_service.rs b/pageserver/src/page_service.rs index 62b14cb83e..aed8a87851 100644 --- a/pageserver/src/page_service.rs +++ b/pageserver/src/page_service.rs @@ -1080,6 +1080,7 @@ impl PageServerHandler { prev_lsn: Option, full_backup: bool, gzip: bool, + replica: bool, ctx: &RequestContext, ) -> Result<(), QueryError> where @@ -1132,6 +1133,7 @@ impl PageServerHandler { lsn, prev_lsn, full_backup, + replica, ctx, ) .await @@ -1154,6 +1156,7 @@ impl PageServerHandler { lsn, prev_lsn, full_backup, + replica, ctx, ) .await @@ -1170,6 +1173,7 @@ impl PageServerHandler { lsn, prev_lsn, full_backup, + replica, ctx, ) .await @@ -1326,24 +1330,27 @@ where .for_command(ComputeCommandKind::Basebackup) .inc(); - let (lsn, gzip) = match (params.get(2), params.get(3)) { - (None, _) => (None, false), - (Some(&"--gzip"), _) => (None, true), - (Some(lsn_str), gzip_str_opt) => { - let lsn = Lsn::from_str(lsn_str) - .with_context(|| format!("Failed to parse Lsn from {lsn_str}"))?; - let gzip = match gzip_str_opt { - Some(&"--gzip") => true, - None => false, - Some(third_param) => { + let mut lsn = None; + let mut replica = false; + let mut gzip = false; + for param in ¶ms[2..] { + if param.starts_with("--") { + match *param { + "--gzip" => gzip = true, + "--replica" => replica = true, + _ => { return Err(QueryError::Other(anyhow::anyhow!( - "Parameter in position 3 unknown {third_param}", + "Unknown parameter {param}", ))) } - }; - (Some(lsn), gzip) + } + } else { + lsn = Some( + Lsn::from_str(param) + .with_context(|| format!("Failed to parse Lsn from {param}"))?, + ); } - }; + } let metric_recording = metrics::BASEBACKUP_QUERY_TIME.start_recording(&ctx); let res = async { @@ -1355,6 +1362,7 @@ where None, false, gzip, + replica, &ctx, ) .await?; @@ -1415,6 +1423,7 @@ where prev_lsn, true, false, + false, &ctx, ) .await?;