From 33ee5b6ba017d3aabe0e540e07e3bb1eaefa7e39 Mon Sep 17 00:00:00 2001 From: Konstantin Knizhnik Date: Sat, 17 Apr 2021 15:54:57 +0300 Subject: [PATCH] Skip truncate records when calculating relation size --- pageserver/src/page_cache.rs | 47 +++++++++++++++++++++++++---------- pageserver/src/waldecoder.rs | 2 +- pageserver/src/walreceiver.rs | 2 ++ vendor/postgres | 2 +- 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/pageserver/src/page_cache.rs b/pageserver/src/page_cache.rs index 5bd24e4e22..3e463e5a09 100644 --- a/pageserver/src/page_cache.rs +++ b/pageserver/src/page_cache.rs @@ -310,6 +310,7 @@ impl BufferTag { pub struct WALRecord { pub lsn: u64, // LSN at the *end* of the record pub will_init: bool, + pub truncate: bool, pub rec: Bytes, } @@ -317,17 +318,20 @@ impl WALRecord { pub fn pack(&self, buf: &mut BytesMut) { buf.put_u64(self.lsn); buf.put_u8(self.will_init as u8); + buf.put_u8(self.truncate as u8); buf.put_u32(self.rec.len() as u32); buf.put_slice(&self.rec[..]); } pub fn unpack(buf: &mut BytesMut) -> WALRecord { let lsn = buf.get_u64(); let will_init = buf.get_u8() != 0; + let truncate = buf.get_u8() != 0; let mut dst = vec![0u8; buf.get_u32() as usize]; buf.copy_to_slice(&mut dst); WALRecord { lsn, will_init, + truncate, rec: Bytes::from(dst), } } @@ -576,7 +580,7 @@ impl PageCache { .unwrap() .relsize_cache .insert(tag.rel, tag.blknum); - + info!("Truncate relation {:?}", tag); let mut key_buf = BytesMut::new(); let mut val_buf = BytesMut::new(); content.pack(&mut val_buf); @@ -711,7 +715,7 @@ impl PageCache { if let Some(relsize) = shared.relsize_cache.get(rel) { return *relsize; } - let key = CacheKey { + let mut key = CacheKey { tag: BufferTag { rel: *rel, blknum: u32::MAX, @@ -719,19 +723,36 @@ impl PageCache { lsn: u64::MAX, }; let mut buf = BytesMut::new(); - key.pack(&mut buf); - let mut iter = self - .db - .iterator(IteratorMode::From(&buf[..], Direction::Reverse)); - if let Some((k, _v)) = iter.next() { + + loop { buf.clear(); - buf.extend_from_slice(&k); - let tag = BufferTag::unpack(&mut buf); - if tag.rel == *rel { - let relsize = tag.blknum + 1; - shared.relsize_cache.insert(*rel, relsize); - return relsize; + key.pack(&mut buf); + let mut iter = self + .db + .iterator(IteratorMode::From(&buf[..], Direction::Reverse)); + if let Some((k, v)) = iter.next() { + buf.clear(); + buf.extend_from_slice(&k); + let tag = BufferTag::unpack(&mut buf); + if tag.rel == *rel { + buf.clear(); + buf.extend_from_slice(&v); + let content = CacheEntryContent::unpack(&mut buf); + if let Some(rec) = &content.wal_record { + if rec.truncate { + if tag.blknum > 0 { + key.tag.blknum = tag.blknum - 1; + continue; + } + break; + } + } + let relsize = tag.blknum + 1; + shared.relsize_cache.insert(*rel, relsize); + return relsize; + } } + break; } return 0; } diff --git a/pageserver/src/waldecoder.rs b/pageserver/src/waldecoder.rs index 828ad7b59f..fa79403563 100644 --- a/pageserver/src/waldecoder.rs +++ b/pageserver/src/waldecoder.rs @@ -347,7 +347,7 @@ pub struct XlSmgrTruncate { pub fn decode_truncate_record(decoded: &DecodedWALRecord) -> XlSmgrTruncate { let mut buf = decoded.record.clone(); - buf.advance((SizeOfXLogRecord+2) as usize); + buf.advance((SizeOfXLogRecord + 2) as usize); XlSmgrTruncate { blkno: buf.get_u32_le(), rnode: RelFileNode { diff --git a/pageserver/src/walreceiver.rs b/pageserver/src/walreceiver.rs index c8a5fa612c..129a80dd32 100644 --- a/pageserver/src/walreceiver.rs +++ b/pageserver/src/walreceiver.rs @@ -153,6 +153,7 @@ async fn walreceiver_main( let rec = page_cache::WALRecord { lsn: lsn, will_init: blk.will_init || blk.apply_image, + truncate: false, rec: recdata.clone(), }; @@ -176,6 +177,7 @@ async fn walreceiver_main( let rec = page_cache::WALRecord { lsn: lsn, will_init: false, + truncate: true, rec: recdata.clone(), }; pcache.put_rel_wal_record(tag, rec); diff --git a/vendor/postgres b/vendor/postgres index 5717bc00cb..32cc0a1c3a 160000 --- a/vendor/postgres +++ b/vendor/postgres @@ -1 +1 @@ -Subproject commit 5717bc00cbb95bc07f6f436fd747b74ac61179b6 +Subproject commit 32cc0a1c3a5406c13403b170548f7cd9f0b053bf