From 2a243f5eb341b09cbd7594dcd76bb1fe137d0692 Mon Sep 17 00:00:00 2001 From: Konstantin Knizhnik Date: Tue, 23 May 2023 21:44:15 +0300 Subject: [PATCH] Change rel_size_key prefi to separate data from metadata --- pageserver/src/pgdatadir_mapping.rs | 43 ++++++++++++++++------------- pageserver/src/tenant/metadata.rs | 6 +++- pageserver/src/tenant/timeline.rs | 2 ++ 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/pageserver/src/pgdatadir_mapping.rs b/pageserver/src/pgdatadir_mapping.rs index 67f37ee519..879c5ee851 100644 --- a/pageserver/src/pgdatadir_mapping.rs +++ b/pageserver/src/pgdatadir_mapping.rs @@ -167,7 +167,7 @@ impl Timeline { return Ok(0); } - let key = rel_size_to_key(tag); + let key = self.rel_size_to_key(tag); let mut buf = self.get(key, lsn, ctx).await?; let nblocks = buf.get_u32_le(); @@ -516,7 +516,7 @@ impl Timeline { if cancel.is_cancelled() { return Err(CalculateLogicalSizeError::Cancelled); } - let relsize_key = rel_size_to_key(rel); + let relsize_key = self.rel_size_to_key(rel); let mut buf = self .get(relsize_key, lsn, ctx) .await @@ -561,7 +561,7 @@ impl Timeline { .collect(); rels.sort_unstable(); for rel in rels { - let relsize_key = rel_size_to_key(rel); + let relsize_key = self.rel_size_to_key(rel); let mut buf = self.get(relsize_key, lsn, ctx).await?; let relsize = buf.get_u32_le(); @@ -648,6 +648,22 @@ impl Timeline { let mut rel_size_cache = self.rel_size_cache.write().unwrap(); rel_size_cache.remove(tag); } + + fn rel_size_to_key(&self, rel: RelTag) -> Key { + let field1 = if self.format_version == 4 { + 0x00u8 + } else { + 0x04u8 + }; + Key { + field1, + field2: rel.spcnode, + field3: rel.dbnode, + field4: rel.relnode, + field5: rel.forknum, + field6: 0xffffffff, + } + } } /// DatadirModification represents an operation to ingest an atomic set of @@ -890,7 +906,7 @@ impl<'a> DatadirModification<'a> { ); // Put size - let size_key = rel_size_to_key(rel); + let size_key = self.tline.rel_size_to_key(rel); let buf = nblocks.to_le_bytes(); self.put(size_key, Value::Image(Bytes::from(buf.to_vec()))); @@ -914,7 +930,7 @@ impl<'a> DatadirModification<'a> { anyhow::ensure!(rel.relnode != 0, "invalid relnode"); let last_lsn = self.tline.get_last_record_lsn(); if self.tline.get_rel_exists(rel, last_lsn, true, ctx).await? { - let size_key = rel_size_to_key(rel); + let size_key = self.tline.rel_size_to_key(rel); // Fetch the old size first let old_size = self.get(size_key, ctx).await?.get_u32_le(); @@ -945,7 +961,7 @@ impl<'a> DatadirModification<'a> { anyhow::ensure!(rel.relnode != 0, "invalid relnode"); // Put size - let size_key = rel_size_to_key(rel); + let size_key = self.tline.rel_size_to_key(rel); let old_size = self.get(size_key, ctx).await?.get_u32_le(); // only extend relation here. never decrease the size @@ -977,7 +993,7 @@ impl<'a> DatadirModification<'a> { } // update logical size - let size_key = rel_size_to_key(rel); + let size_key = self.tline.rel_size_to_key(rel); let old_size = self.get(size_key, ctx).await?.get_u32_le(); self.pending_nblocks -= old_size as i64; @@ -1291,7 +1307,7 @@ static ZERO_PAGE: Bytes = Bytes::from_static(&[0u8; BLCKSZ as usize]); // 00 SPCNODE DBNODE RELNODE FORK BLKNUM // // RelSize: -// 00 SPCNODE DBNODE RELNODE FORK FFFFFFFF +// 04 SPCNODE DBNODE RELNODE FORK FFFFFFFF // // SlruDir: // 01 kind 00000000 00000000 00 00000000 @@ -1375,17 +1391,6 @@ fn rel_block_to_key(rel: RelTag, blknum: BlockNumber) -> Key { } } -fn rel_size_to_key(rel: RelTag) -> Key { - Key { - field1: 0x00, - field2: rel.spcnode, - field3: rel.dbnode, - field4: rel.relnode, - field5: rel.forknum, - field6: 0xffffffff, - } -} - fn rel_key_range(rel: RelTag) -> Range { Key { field1: 0x00, diff --git a/pageserver/src/tenant/metadata.rs b/pageserver/src/tenant/metadata.rs index 1ea61fa26b..66a6d423e2 100644 --- a/pageserver/src/tenant/metadata.rs +++ b/pageserver/src/tenant/metadata.rs @@ -23,7 +23,7 @@ use crate::config::PageServerConf; use crate::virtual_file::VirtualFile; /// Use special format number to enable backward compatibility. -const METADATA_FORMAT_VERSION: u16 = 4; +const METADATA_FORMAT_VERSION: u16 = 5; /// Previous supported format versions. const METADATA_OLD_FORMAT_VERSION: u16 = 3; @@ -227,6 +227,10 @@ impl TimelineMetadata { pub fn pg_version(&self) -> u32 { self.body.pg_version } + + pub fn format_version(&self) -> u16 { + self.hdr.format_version + } } /// Save timeline metadata to file diff --git a/pageserver/src/tenant/timeline.rs b/pageserver/src/tenant/timeline.rs index c47f4444f5..5879f7a115 100644 --- a/pageserver/src/tenant/timeline.rs +++ b/pageserver/src/tenant/timeline.rs @@ -120,6 +120,7 @@ pub struct Timeline { pub timeline_id: TimelineId, pub pg_version: u32, + pub format_version: u16, pub(super) layers: RwLock>, @@ -1353,6 +1354,7 @@ impl Timeline { timeline_id, tenant_id, pg_version, + format_version: metadata.format_version(), layers: RwLock::new(LayerMap::default()), walredo_mgr,