diff --git a/pageserver/src/object_repository.rs b/pageserver/src/object_repository.rs index 78bf60878a..b9485300b4 100644 --- a/pageserver/src/object_repository.rs +++ b/pageserver/src/object_repository.rs @@ -290,7 +290,7 @@ impl Timeline for ObjectTimeline { // version. Otherwise we could opt to not do it, with the downside that // the next GetPage@LSN call of the same page version would have to // redo the WAL again. - self.put_page_image(tag, lsn, page_img.clone())?; + self.put_page_image(tag, lsn, page_img.clone(), false)?; } ObjectValue::SLRUTruncate => page_img = Bytes::from_static(&ZERO_PAGE), _ => bail!("Invalid object kind, expected a page entry or SRLU truncate"), @@ -469,11 +469,14 @@ impl Timeline for ObjectTimeline { /// /// Memorize a full image of a page version /// - fn put_page_image(&self, tag: ObjectTag, lsn: Lsn, img: Bytes) -> Result<()> { + fn put_page_image(&self, tag: ObjectTag, lsn: Lsn, img: Bytes, update_meta: bool) -> Result<()> { self.put_page_entry(&tag, lsn, PageEntry::Page(img))?; debug!("put_page_image rel {:?} at {}", tag, lsn); + if !update_meta { + return Ok(()); + } if let ObjectTag::RelationBuffer(tag) = tag { // Also check if this created or extended the file let old_nblocks = self.relsize_get_nowait(tag.rel, lsn)?.unwrap_or(0); @@ -684,7 +687,7 @@ impl Timeline for ObjectTimeline { if last_version { result.truncated += 1; last_version = false; - if let Some(rel_size) = self.relsize_get_nowait(tag.rel, lsn)? { + if let Some(rel_size) = self.relsize_get_nowait(tag.rel, last_lsn)? { if rel_size > tag.blknum { // preserve and materialize last version before deleting all preceeding self.get_page_at_lsn_nowait(obj, lsn)?; diff --git a/pageserver/src/page_service.rs b/pageserver/src/page_service.rs index d210b25468..dd2cc3d1e1 100644 --- a/pageserver/src/page_service.rs +++ b/pageserver/src/page_service.rs @@ -424,7 +424,7 @@ impl postgres_backend::Handler for PageServerHandler { blknum, }); - timeline.put_page_image(tag, relation_update.lsn, img)?; + timeline.put_page_image(tag, relation_update.lsn, img, true)?; } Update::WALRecord { blknum, rec } => { let tag = ObjectTag::RelationBuffer(BufferTag { diff --git a/pageserver/src/repository.rs b/pageserver/src/repository.rs index 1f3de164c1..060954c494 100644 --- a/pageserver/src/repository.rs +++ b/pageserver/src/repository.rs @@ -89,7 +89,7 @@ pub trait Timeline: Send + Sync { fn put_raw_data(&self, tag: ObjectTag, lsn: Lsn, data: &[u8]) -> Result<()>; /// Like put_wal_record, but with ready-made image of the page. - fn put_page_image(&self, tag: ObjectTag, lsn: Lsn, img: Bytes) -> Result<()>; + fn put_page_image(&self, tag: ObjectTag, lsn: Lsn, img: Bytes, update_meta: bool) -> Result<()>; /// Truncate relation fn put_truncation(&self, rel: RelTag, lsn: Lsn, nblocks: u32) -> Result<()>; @@ -367,11 +367,11 @@ mod tests { let tline = repo.create_empty_timeline(timelineid, Lsn(0))?; tline.init_valid_lsn(Lsn(1)); - tline.put_page_image(TEST_BUF(0), Lsn(2), TEST_IMG("foo blk 0 at 2"))?; - tline.put_page_image(TEST_BUF(0), Lsn(2), TEST_IMG("foo blk 0 at 2"))?; - tline.put_page_image(TEST_BUF(0), Lsn(3), TEST_IMG("foo blk 0 at 3"))?; - tline.put_page_image(TEST_BUF(1), Lsn(4), TEST_IMG("foo blk 1 at 4"))?; - tline.put_page_image(TEST_BUF(2), Lsn(5), TEST_IMG("foo blk 2 at 5"))?; + tline.put_page_image(TEST_BUF(0), Lsn(2), TEST_IMG("foo blk 0 at 2"), true)?; + tline.put_page_image(TEST_BUF(0), Lsn(2), TEST_IMG("foo blk 0 at 2"), true)?; + tline.put_page_image(TEST_BUF(0), Lsn(3), TEST_IMG("foo blk 0 at 3"), true)?; + tline.put_page_image(TEST_BUF(1), Lsn(4), TEST_IMG("foo blk 1 at 4"), true)?; + tline.put_page_image(TEST_BUF(2), Lsn(5), TEST_IMG("foo blk 2 at 5"), true)?; tline.advance_last_valid_lsn(Lsn(5)); @@ -458,7 +458,7 @@ mod tests { for i in 0..pg_constants::RELSEG_SIZE + 1 { let img = TEST_IMG(&format!("foo blk {} at {}", i, Lsn(lsn))); lsn += 1; - tline.put_page_image(TEST_BUF(i as u32), Lsn(lsn), img)?; + tline.put_page_image(TEST_BUF(i as u32), Lsn(lsn), img, true)?; } tline.advance_last_valid_lsn(Lsn(lsn)); @@ -502,7 +502,7 @@ mod tests { // add a page and advance the last valid LSN let rel = TESTREL_A; let tag = TEST_BUF(1); - tline.put_page_image(tag, Lsn(1), TEST_IMG("blk 1 @ lsn 1"))?; + tline.put_page_image(tag, Lsn(1), TEST_IMG("blk 1 @ lsn 1"), true)?; tline.advance_last_valid_lsn(Lsn(1)); let mut snapshot = tline.history()?; assert_eq!(snapshot.lsn(), Lsn(1)); diff --git a/pageserver/src/restore_local_repo.rs b/pageserver/src/restore_local_repo.rs index e519012bc6..e01d5ab861 100644 --- a/pageserver/src/restore_local_repo.rs +++ b/pageserver/src/restore_local_repo.rs @@ -203,7 +203,7 @@ fn import_relfile( }, blknum, }); - timeline.put_page_image(tag, lsn, Bytes::copy_from_slice(&buf))?; + timeline.put_page_image(tag, lsn, Bytes::copy_from_slice(&buf), true)?; } // TODO: UnexpectedEof is expected @@ -236,7 +236,7 @@ fn import_nonrel_file( // read the whole file file.read_to_end(&mut buffer)?; - timeline.put_page_image(tag, lsn, Bytes::copy_from_slice(&buffer[..]))?; + timeline.put_page_image(tag, lsn, Bytes::copy_from_slice(&buffer[..]), false)?; Ok(()) } @@ -256,7 +256,7 @@ fn import_slru_file( let r = file.read_exact(&mut buf); match r { Ok(_) => { - timeline.put_page_image(gen_tag(blknum), lsn, Bytes::copy_from_slice(&buf))?; + timeline.put_page_image(gen_tag(blknum), lsn, Bytes::copy_from_slice(&buf), false)?; } // TODO: UnexpectedEof is expected @@ -360,7 +360,7 @@ pub fn import_timeline_wal(walpath: &Path, timeline: &dyn Timeline, startpoint: } info!("reached end of WAL at {}", last_lsn); let checkpoint_bytes = checkpoint.encode(); - timeline.put_page_image(ObjectTag::Checkpoint, last_lsn, checkpoint_bytes)?; + timeline.put_page_image(ObjectTag::Checkpoint, last_lsn, checkpoint_bytes, false)?; Ok(()) } @@ -579,7 +579,7 @@ fn save_xlog_dbase_create(timeline: &dyn Timeline, lsn: Lsn, rec: &XlCreateDatab debug!("copying block {:?} to {:?}", src_key, dst_key); - timeline.put_page_image(dst_key, lsn, content)?; + timeline.put_page_image(dst_key, lsn, content, false)?; num_blocks_copied += 1; } @@ -600,7 +600,7 @@ fn save_xlog_dbase_create(timeline: &dyn Timeline, lsn: Lsn, rec: &XlCreateDatab spcnode: tablespace_id, dbnode: db_id, }); - timeline.put_page_image(new_tag, lsn, img)?; + timeline.put_page_image(new_tag, lsn, img, false)?; break; } } diff --git a/pageserver/src/walreceiver.rs b/pageserver/src/walreceiver.rs index d09d5fbec5..3a7d3bd037 100644 --- a/pageserver/src/walreceiver.rs +++ b/pageserver/src/walreceiver.rs @@ -209,6 +209,7 @@ fn walreceiver_main( ObjectTag::Checkpoint, lsn, new_checkpoint_bytes, + false, )?; } } diff --git a/vendor/postgres b/vendor/postgres index cf7f21997c..eb94b98d38 160000 --- a/vendor/postgres +++ b/vendor/postgres @@ -1 +1 @@ -Subproject commit cf7f21997c0d409e2588ae7fde128543e94c9f49 +Subproject commit eb94b98d383bcf546189d0d7c5573cff3803c94a