mirror of
https://github.com/neondatabase/neon.git
synced 2025-12-22 21:59:59 +00:00
utils: move ShardStripeSize into shard module (#12640)
## Problem `ShardStripeSize` will be used in the compute spec and internally in the communicator. It shouldn't require pulling in all of `pageserver_api`. ## Summary of changes Move `ShardStripeSize` into `utils::shard`, along with other basic shard types. Also remove the `Default` implementation, to discourage clients from falling back to a default (it's generally a footgun). The type is still re-exported from `pageserver_api::shard`, along with all the other shard types.
This commit is contained in:
@@ -65,7 +65,6 @@ use jsonwebtoken::jwk::{
|
|||||||
OctetKeyPairParameters, OctetKeyPairType, PublicKeyUse,
|
OctetKeyPairParameters, OctetKeyPairType, PublicKeyUse,
|
||||||
};
|
};
|
||||||
use nix::sys::signal::{Signal, kill};
|
use nix::sys::signal::{Signal, kill};
|
||||||
use pageserver_api::shard::ShardStripeSize;
|
|
||||||
use pem::Pem;
|
use pem::Pem;
|
||||||
use reqwest::header::CONTENT_TYPE;
|
use reqwest::header::CONTENT_TYPE;
|
||||||
use safekeeper_api::PgMajorVersion;
|
use safekeeper_api::PgMajorVersion;
|
||||||
@@ -77,6 +76,7 @@ use spki::{SubjectPublicKeyInfo, SubjectPublicKeyInfoRef};
|
|||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
use url::Host;
|
use url::Host;
|
||||||
use utils::id::{NodeId, TenantId, TimelineId};
|
use utils::id::{NodeId, TenantId, TimelineId};
|
||||||
|
use utils::shard::ShardStripeSize;
|
||||||
|
|
||||||
use crate::local_env::LocalEnv;
|
use crate::local_env::LocalEnv;
|
||||||
use crate::postgresql_conf::PostgresConf;
|
use crate::postgresql_conf::PostgresConf;
|
||||||
|
|||||||
@@ -69,22 +69,6 @@ impl Hash for ShardIdentity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stripe size in number of pages
|
|
||||||
#[derive(Clone, Copy, Serialize, Deserialize, Eq, PartialEq, Debug)]
|
|
||||||
pub struct ShardStripeSize(pub u32);
|
|
||||||
|
|
||||||
impl Default for ShardStripeSize {
|
|
||||||
fn default() -> Self {
|
|
||||||
DEFAULT_STRIPE_SIZE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Display for ShardStripeSize {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
self.0.fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Layout version: for future upgrades where we might change how the key->shard mapping works
|
/// Layout version: for future upgrades where we might change how the key->shard mapping works
|
||||||
#[derive(Clone, Copy, Serialize, Deserialize, Eq, PartialEq, Hash, Debug)]
|
#[derive(Clone, Copy, Serialize, Deserialize, Eq, PartialEq, Hash, Debug)]
|
||||||
pub struct ShardLayout(u8);
|
pub struct ShardLayout(u8);
|
||||||
|
|||||||
@@ -25,6 +25,12 @@ pub struct ShardIndex {
|
|||||||
pub shard_count: ShardCount,
|
pub shard_count: ShardCount,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Stripe size as number of pages.
|
||||||
|
///
|
||||||
|
/// NB: don't implement Default, so callers don't lazily use it by mistake. See DEFAULT_STRIPE_SIZE.
|
||||||
|
#[derive(Clone, Copy, Serialize, Deserialize, Eq, PartialEq, Debug)]
|
||||||
|
pub struct ShardStripeSize(pub u32);
|
||||||
|
|
||||||
/// Formatting helper, for generating the `shard_id` label in traces.
|
/// Formatting helper, for generating the `shard_id` label in traces.
|
||||||
pub struct ShardSlug<'a>(&'a TenantShardId);
|
pub struct ShardSlug<'a>(&'a TenantShardId);
|
||||||
|
|
||||||
@@ -177,6 +183,12 @@ impl std::fmt::Display for ShardCount {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for ShardStripeSize {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
self.0.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for ShardSlug<'_> {
|
impl std::fmt::Display for ShardSlug<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use anyhow::anyhow;
|
|||||||
use arc_swap::ArcSwap;
|
use arc_swap::ArcSwap;
|
||||||
use futures::stream::FuturesUnordered;
|
use futures::stream::FuturesUnordered;
|
||||||
use futures::{FutureExt as _, StreamExt as _};
|
use futures::{FutureExt as _, StreamExt as _};
|
||||||
|
use pageserver_api::shard::DEFAULT_STRIPE_SIZE;
|
||||||
use tonic::codec::CompressionEncoding;
|
use tonic::codec::CompressionEncoding;
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
use utils::logging::warn_slow;
|
use utils::logging::warn_slow;
|
||||||
@@ -16,10 +17,9 @@ use crate::pool::{ChannelPool, ClientGuard, ClientPool, StreamGuard, StreamPool}
|
|||||||
use crate::retry::Retry;
|
use crate::retry::Retry;
|
||||||
use crate::split::GetPageSplitter;
|
use crate::split::GetPageSplitter;
|
||||||
use compute_api::spec::PageserverProtocol;
|
use compute_api::spec::PageserverProtocol;
|
||||||
use pageserver_api::shard::ShardStripeSize;
|
|
||||||
use pageserver_page_api as page_api;
|
use pageserver_page_api as page_api;
|
||||||
use utils::id::{TenantId, TimelineId};
|
use utils::id::{TenantId, TimelineId};
|
||||||
use utils::shard::{ShardCount, ShardIndex, ShardNumber};
|
use utils::shard::{ShardCount, ShardIndex, ShardNumber, ShardStripeSize};
|
||||||
|
|
||||||
/// Max number of concurrent clients per channel (i.e. TCP connection). New channels will be spun up
|
/// Max number of concurrent clients per channel (i.e. TCP connection). New channels will be spun up
|
||||||
/// when full.
|
/// when full.
|
||||||
@@ -418,7 +418,7 @@ impl ShardSpec {
|
|||||||
if stripe_size.is_none() && !count.is_unsharded() {
|
if stripe_size.is_none() && !count.is_unsharded() {
|
||||||
return Err(anyhow!("stripe size must be given for sharded tenants"));
|
return Err(anyhow!("stripe size must be given for sharded tenants"));
|
||||||
}
|
}
|
||||||
let stripe_size = stripe_size.unwrap_or_default();
|
let stripe_size = stripe_size.unwrap_or(DEFAULT_STRIPE_SIZE);
|
||||||
|
|
||||||
// Validate the shard spec.
|
// Validate the shard spec.
|
||||||
for (shard_id, url) in &urls {
|
for (shard_id, url) in &urls {
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ use std::collections::HashMap;
|
|||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
|
||||||
use pageserver_api::key::rel_block_to_key;
|
use pageserver_api::key::rel_block_to_key;
|
||||||
use pageserver_api::shard::{ShardStripeSize, key_to_shard_number};
|
use pageserver_api::shard::key_to_shard_number;
|
||||||
use pageserver_page_api as page_api;
|
use pageserver_page_api as page_api;
|
||||||
use utils::shard::{ShardCount, ShardIndex, ShardNumber};
|
use utils::shard::{ShardCount, ShardIndex, ShardNumber, ShardStripeSize};
|
||||||
|
|
||||||
/// Splits GetPageRequests that straddle shard boundaries and assembles the responses.
|
/// Splits GetPageRequests that straddle shard boundaries and assembles the responses.
|
||||||
/// TODO: add tests for this.
|
/// TODO: add tests for this.
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use anyhow::Context;
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use pageserver_api::key::Key;
|
use pageserver_api::key::Key;
|
||||||
use pageserver_api::reltag::{BlockNumber, RelTag, SlruKind};
|
use pageserver_api::reltag::{BlockNumber, RelTag, SlruKind};
|
||||||
use pageserver_api::shard::{ShardCount, ShardStripeSize};
|
use pageserver_api::shard::{DEFAULT_STRIPE_SIZE, ShardCount, ShardStripeSize};
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
pub(super) struct DescribeKeyCommand {
|
pub(super) struct DescribeKeyCommand {
|
||||||
@@ -128,7 +128,9 @@ impl DescribeKeyCommand {
|
|||||||
// seeing the sharding placement might be confusing, so leave it out unless shard
|
// seeing the sharding placement might be confusing, so leave it out unless shard
|
||||||
// count was given.
|
// count was given.
|
||||||
|
|
||||||
let stripe_size = stripe_size.map(ShardStripeSize).unwrap_or_default();
|
let stripe_size = stripe_size
|
||||||
|
.map(ShardStripeSize)
|
||||||
|
.unwrap_or(DEFAULT_STRIPE_SIZE);
|
||||||
println!(
|
println!(
|
||||||
"# placement with shard_count: {} and stripe_size: {}:",
|
"# placement with shard_count: {} and stripe_size: {}:",
|
||||||
shard_count.0, stripe_size.0
|
shard_count.0, stripe_size.0
|
||||||
|
|||||||
@@ -2912,9 +2912,8 @@ static ZERO_PAGE: Bytes = Bytes::from_static(&[0u8; BLCKSZ as usize]);
|
|||||||
mod tests {
|
mod tests {
|
||||||
use hex_literal::hex;
|
use hex_literal::hex;
|
||||||
use pageserver_api::models::ShardParameters;
|
use pageserver_api::models::ShardParameters;
|
||||||
use pageserver_api::shard::ShardStripeSize;
|
|
||||||
use utils::id::TimelineId;
|
use utils::id::TimelineId;
|
||||||
use utils::shard::{ShardCount, ShardNumber};
|
use utils::shard::{ShardCount, ShardNumber, ShardStripeSize};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::DEFAULT_PG_VERSION;
|
use crate::DEFAULT_PG_VERSION;
|
||||||
|
|||||||
@@ -328,7 +328,7 @@ fn emergency_generations(
|
|||||||
LocationMode::Attached(alc) => TenantStartupMode::Attached((
|
LocationMode::Attached(alc) => TenantStartupMode::Attached((
|
||||||
alc.attach_mode,
|
alc.attach_mode,
|
||||||
alc.generation,
|
alc.generation,
|
||||||
ShardStripeSize::default(),
|
lc.shard.stripe_size,
|
||||||
)),
|
)),
|
||||||
LocationMode::Secondary(_) => TenantStartupMode::Secondary,
|
LocationMode::Secondary(_) => TenantStartupMode::Secondary,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use pageserver_api::shard::ShardStripeSize;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use utils::id::TimelineId;
|
use utils::id::TimelineId;
|
||||||
use utils::lsn::Lsn;
|
use utils::lsn::Lsn;
|
||||||
|
use utils::shard::ShardStripeSize;
|
||||||
|
|
||||||
/// Tenant shard manifest, stored in remote storage. Contains offloaded timelines and other tenant
|
/// Tenant shard manifest, stored in remote storage. Contains offloaded timelines and other tenant
|
||||||
/// shard-wide information that must be persisted in remote storage.
|
/// shard-wide information that must be persisted in remote storage.
|
||||||
|
|||||||
@@ -654,7 +654,7 @@ mod tests {
|
|||||||
use pageserver_api::key::{DBDIR_KEY, Key, rel_block_to_key};
|
use pageserver_api::key::{DBDIR_KEY, Key, rel_block_to_key};
|
||||||
use pageserver_api::models::ShardParameters;
|
use pageserver_api::models::ShardParameters;
|
||||||
use pageserver_api::reltag::RelTag;
|
use pageserver_api::reltag::RelTag;
|
||||||
use pageserver_api::shard::ShardStripeSize;
|
use pageserver_api::shard::DEFAULT_STRIPE_SIZE;
|
||||||
use utils::shard::ShardCount;
|
use utils::shard::ShardCount;
|
||||||
use utils::sync::gate::GateGuard;
|
use utils::sync::gate::GateGuard;
|
||||||
|
|
||||||
@@ -955,7 +955,7 @@ mod tests {
|
|||||||
});
|
});
|
||||||
let child_params = ShardParameters {
|
let child_params = ShardParameters {
|
||||||
count: ShardCount(2),
|
count: ShardCount(2),
|
||||||
stripe_size: ShardStripeSize::default(),
|
stripe_size: DEFAULT_STRIPE_SIZE,
|
||||||
};
|
};
|
||||||
let child0 = Arc::new_cyclic(|myself| StubTimeline {
|
let child0 = Arc::new_cyclic(|myself| StubTimeline {
|
||||||
gate: Default::default(),
|
gate: Default::default(),
|
||||||
|
|||||||
@@ -742,7 +742,7 @@ mod tests {
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use pageserver_api::shard::{ShardIdentity, ShardStripeSize};
|
use pageserver_api::shard::{DEFAULT_STRIPE_SIZE, ShardIdentity};
|
||||||
use postgres_ffi::{MAX_SEND_SIZE, PgMajorVersion};
|
use postgres_ffi::{MAX_SEND_SIZE, PgMajorVersion};
|
||||||
use tokio::sync::mpsc::error::TryRecvError;
|
use tokio::sync::mpsc::error::TryRecvError;
|
||||||
use utils::id::{NodeId, TenantTimelineId};
|
use utils::id::{NodeId, TenantTimelineId};
|
||||||
@@ -786,19 +786,13 @@ mod tests {
|
|||||||
MAX_SEND_SIZE,
|
MAX_SEND_SIZE,
|
||||||
);
|
);
|
||||||
|
|
||||||
let shard_0 = ShardIdentity::new(
|
let shard_0 =
|
||||||
ShardNumber(0),
|
ShardIdentity::new(ShardNumber(0), ShardCount(SHARD_COUNT), DEFAULT_STRIPE_SIZE)
|
||||||
ShardCount(SHARD_COUNT),
|
.unwrap();
|
||||||
ShardStripeSize::default(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let shard_1 = ShardIdentity::new(
|
let shard_1 =
|
||||||
ShardNumber(1),
|
ShardIdentity::new(ShardNumber(1), ShardCount(SHARD_COUNT), DEFAULT_STRIPE_SIZE)
|
||||||
ShardCount(SHARD_COUNT),
|
.unwrap();
|
||||||
ShardStripeSize::default(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut shards = HashMap::new();
|
let mut shards = HashMap::new();
|
||||||
|
|
||||||
@@ -806,7 +800,7 @@ mod tests {
|
|||||||
let shard_id = ShardIdentity::new(
|
let shard_id = ShardIdentity::new(
|
||||||
ShardNumber(shard_number),
|
ShardNumber(shard_number),
|
||||||
ShardCount(SHARD_COUNT),
|
ShardCount(SHARD_COUNT),
|
||||||
ShardStripeSize::default(),
|
DEFAULT_STRIPE_SIZE,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let (tx, rx) = tokio::sync::mpsc::channel::<Batch>(MSG_COUNT * 2);
|
let (tx, rx) = tokio::sync::mpsc::channel::<Batch>(MSG_COUNT * 2);
|
||||||
@@ -934,12 +928,9 @@ mod tests {
|
|||||||
MAX_SEND_SIZE,
|
MAX_SEND_SIZE,
|
||||||
);
|
);
|
||||||
|
|
||||||
let shard_0 = ShardIdentity::new(
|
let shard_0 =
|
||||||
ShardNumber(0),
|
ShardIdentity::new(ShardNumber(0), ShardCount(SHARD_COUNT), DEFAULT_STRIPE_SIZE)
|
||||||
ShardCount(SHARD_COUNT),
|
.unwrap();
|
||||||
ShardStripeSize::default(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
struct Sender {
|
struct Sender {
|
||||||
tx: Option<tokio::sync::mpsc::Sender<Batch>>,
|
tx: Option<tokio::sync::mpsc::Sender<Batch>>,
|
||||||
@@ -1088,19 +1079,13 @@ mod tests {
|
|||||||
WAL_READER_BATCH_SIZE,
|
WAL_READER_BATCH_SIZE,
|
||||||
);
|
);
|
||||||
|
|
||||||
let shard_0 = ShardIdentity::new(
|
let shard_0 =
|
||||||
ShardNumber(0),
|
ShardIdentity::new(ShardNumber(0), ShardCount(SHARD_COUNT), DEFAULT_STRIPE_SIZE)
|
||||||
ShardCount(SHARD_COUNT),
|
.unwrap();
|
||||||
ShardStripeSize::default(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let shard_1 = ShardIdentity::new(
|
let shard_1 =
|
||||||
ShardNumber(1),
|
ShardIdentity::new(ShardNumber(1), ShardCount(SHARD_COUNT), DEFAULT_STRIPE_SIZE)
|
||||||
ShardCount(SHARD_COUNT),
|
.unwrap();
|
||||||
ShardStripeSize::default(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut shards = HashMap::new();
|
let mut shards = HashMap::new();
|
||||||
|
|
||||||
@@ -1108,7 +1093,7 @@ mod tests {
|
|||||||
let shard_id = ShardIdentity::new(
|
let shard_id = ShardIdentity::new(
|
||||||
ShardNumber(shard_number),
|
ShardNumber(shard_number),
|
||||||
ShardCount(SHARD_COUNT),
|
ShardCount(SHARD_COUNT),
|
||||||
ShardStripeSize::default(),
|
DEFAULT_STRIPE_SIZE,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let (tx, rx) = tokio::sync::mpsc::channel::<Batch>(MSG_COUNT * 2);
|
let (tx, rx) = tokio::sync::mpsc::channel::<Batch>(MSG_COUNT * 2);
|
||||||
|
|||||||
@@ -981,7 +981,7 @@ mod tests {
|
|||||||
use pageserver_api::models::utilization::test_utilization;
|
use pageserver_api::models::utilization::test_utilization;
|
||||||
use pageserver_api::shard::ShardIdentity;
|
use pageserver_api::shard::ShardIdentity;
|
||||||
use utils::id::TenantId;
|
use utils::id::TenantId;
|
||||||
use utils::shard::{ShardCount, ShardNumber, TenantShardId};
|
use utils::shard::{ShardCount, ShardNumber, ShardStripeSize, TenantShardId};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::tenant_shard::IntentState;
|
use crate::tenant_shard::IntentState;
|
||||||
@@ -1337,7 +1337,7 @@ mod tests {
|
|||||||
let shard_identity = ShardIdentity::new(
|
let shard_identity = ShardIdentity::new(
|
||||||
tenant_shard_id.shard_number,
|
tenant_shard_id.shard_number,
|
||||||
tenant_shard_id.shard_count,
|
tenant_shard_id.shard_count,
|
||||||
pageserver_api::shard::ShardStripeSize(1),
|
ShardStripeSize(1),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut shard = TenantShard::new(
|
let mut shard = TenantShard::new(
|
||||||
@@ -1411,7 +1411,7 @@ mod tests {
|
|||||||
let shard_identity = ShardIdentity::new(
|
let shard_identity = ShardIdentity::new(
|
||||||
tenant_shard_id.shard_number,
|
tenant_shard_id.shard_number,
|
||||||
tenant_shard_id.shard_count,
|
tenant_shard_id.shard_count,
|
||||||
pageserver_api::shard::ShardStripeSize(1),
|
ShardStripeSize(1),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut shard = TenantShard::new(
|
let mut shard = TenantShard::new(
|
||||||
@@ -1573,7 +1573,7 @@ mod tests {
|
|||||||
let shard_identity = ShardIdentity::new(
|
let shard_identity = ShardIdentity::new(
|
||||||
tenant_shard_id.shard_number,
|
tenant_shard_id.shard_number,
|
||||||
tenant_shard_id.shard_count,
|
tenant_shard_id.shard_count,
|
||||||
pageserver_api::shard::ShardStripeSize(1),
|
ShardStripeSize(1),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
// 1 attached and 1 secondary.
|
// 1 attached and 1 secondary.
|
||||||
|
|||||||
Reference in New Issue
Block a user