diff --git a/pageserver/src/basebackup.rs b/pageserver/src/basebackup.rs index 1a830d2d72..1292f3f3f6 100644 --- a/pageserver/src/basebackup.rs +++ b/pageserver/src/basebackup.rs @@ -177,8 +177,7 @@ impl<'a> Basebackup<'a> { // fn add_twophase_file(&mut self, xid: TransactionId) -> anyhow::Result<()> { // Include in tarball two-phase files only of in-progress transactions - if self.timeline.get_tx_status(xid, self.lsn)? - == pg_constants::TRANSACTION_STATUS_IN_PROGRESS + if self.timeline.get_tx_is_in_progress(xid, self.lsn) { let img = self.timeline diff --git a/pageserver/src/object_repository.rs b/pageserver/src/object_repository.rs index d5c1e04a98..288ece95a8 100644 --- a/pageserver/src/object_repository.rs +++ b/pageserver/src/object_repository.rs @@ -23,7 +23,7 @@ use crate::{PageServerConf, ZTimelineId}; use anyhow::{anyhow, bail, Context, Result}; use bytes::Bytes; use log::*; -use postgres_ffi::pg_constants; + use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap, HashSet}; use std::convert::TryInto; @@ -712,9 +712,9 @@ impl Timeline for ObjectTimeline { for vers in self.obj_store.object_versions(&key, horizon)? { let lsn = vers.0; prepared_horizon = Lsn::min(lsn, prepared_horizon); - if self.get_tx_status(xid, horizon)? - != pg_constants::TRANSACTION_STATUS_IN_PROGRESS + if !self.get_tx_is_in_progress(xid, horizon) { + info!("unlink twophase_file NOT TRANSACTION_STATUS_IN_PROGRESS {}", xid); self.obj_store.unlink(&key, lsn)?; result.prep_deleted += 1; } diff --git a/pageserver/src/repository.rs b/pageserver/src/repository.rs index 0732d504ec..68ad07fdd8 100644 --- a/pageserver/src/repository.rs +++ b/pageserver/src/repository.rs @@ -157,22 +157,26 @@ pub trait Timeline: Send + Sync { /// and is st to false in GC threads which infinitely repeats GC iterations in loop. fn gc_iteration(&self, horizon: u64, compact: bool) -> Result; - // Check transaction status - fn get_tx_status(&self, xid: TransactionId, lsn: Lsn) -> anyhow::Result { + // Check if transaction is in progress + fn get_tx_is_in_progress(&self, xid: TransactionId, lsn: Lsn) -> bool { let pageno = xid / pg_constants::CLOG_XACTS_PER_PAGE; let segno = pageno / pg_constants::SLRU_PAGES_PER_SEGMENT; let rpageno = pageno % pg_constants::SLRU_PAGES_PER_SEGMENT; - let clog_page = self.get_page_at_lsn( + // Handle truncated CLOG: if no pg_xact file exists for the transaction, + // it is definitely not in progress. + if let Ok(clog_page) = self.get_page_at_lsn( RelishTag::Slru { slru: SlruKind::Clog, segno, }, rpageno, - lsn, - )?; - let status = transaction_id_get_status(xid, &clog_page[..]); - Ok(status) + lsn) + { + let status = transaction_id_get_status(xid, &clog_page[..]); + return status == pg_constants::TRANSACTION_STATUS_IN_PROGRESS + } + return false; } }