Skip to content

Commit c7717c8

Browse files
authored
storcon,pageserver: use persisted stripe size when loading unsharded tenants (#11193)
## Problem When the storage controller and Pageserver loads tenants from persisted storage, it uses `ShardIdentity::unsharded()` for unsharded tenants. However, this replaces the persisted stripe size of unsharded tenants with the default stripe size. This doesn't really matter for practical purposes, since the stripe size is meaningless for unsharded tenants anyway, but can cause consistency check failures if the persisted stripe size differs from the default. This was seen in #11168, where we change the default stripe size. Touches #11168. ## Summary of changes Carry over the persisted stripe size from `TenantShardPersistence` for unsharded tenants, and from `LocationConf` on Pageservers. Also add bounds checks for type casts when loading persisted shard metadata.
1 parent 1436b84 commit c7717c8

File tree

3 files changed

+48
-8
lines changed

3 files changed

+48
-8
lines changed

libs/pageserver_api/src/shard.rs

+10
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,16 @@ impl ShardIdentity {
112112
}
113113
}
114114

115+
/// An unsharded identity with the given stripe size (if non-zero). This is typically used to
116+
/// carry over a stripe size for an unsharded tenant from persistent storage.
117+
pub fn unsharded_with_stripe_size(stripe_size: ShardStripeSize) -> Self {
118+
let mut shard_identity = Self::unsharded();
119+
if stripe_size.0 > 0 {
120+
shard_identity.stripe_size = stripe_size;
121+
}
122+
shard_identity
123+
}
124+
115125
/// A broken instance of this type is only used for `TenantState::Broken` tenants,
116126
/// which are constructed in code paths that don't have access to proper configuration.
117127
///

pageserver/src/tenant/config.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,11 @@ impl LocationConf {
219219
};
220220

221221
let shard = if conf.shard_count == 0 {
222-
ShardIdentity::unsharded()
222+
// NB: carry over the persisted stripe size instead of using the default. This doesn't
223+
// matter for most practical purposes, since unsharded tenants don't use the stripe
224+
// size, but can cause inconsistencies between storcon and Pageserver and cause manual
225+
// splits without `new_stripe_size` to use an unintended stripe size.
226+
ShardIdentity::unsharded_with_stripe_size(ShardStripeSize(conf.shard_stripe_size))
223227
} else {
224228
ShardIdentity::new(
225229
ShardNumber(conf.shard_number),

storage_controller/src/persistence.rs

+33-7
Original file line numberDiff line numberDiff line change
@@ -1613,23 +1613,49 @@ pub(crate) struct TenantShardPersistence {
16131613
}
16141614

16151615
impl TenantShardPersistence {
1616+
fn get_shard_count(&self) -> Result<ShardCount, ShardConfigError> {
1617+
self.shard_count
1618+
.try_into()
1619+
.map(ShardCount)
1620+
.map_err(|_| ShardConfigError::InvalidCount)
1621+
}
1622+
1623+
fn get_shard_number(&self) -> Result<ShardNumber, ShardConfigError> {
1624+
self.shard_number
1625+
.try_into()
1626+
.map(ShardNumber)
1627+
.map_err(|_| ShardConfigError::InvalidNumber)
1628+
}
1629+
1630+
fn get_stripe_size(&self) -> Result<ShardStripeSize, ShardConfigError> {
1631+
self.shard_stripe_size
1632+
.try_into()
1633+
.map(ShardStripeSize)
1634+
.map_err(|_| ShardConfigError::InvalidStripeSize)
1635+
}
1636+
16161637
pub(crate) fn get_shard_identity(&self) -> Result<ShardIdentity, ShardConfigError> {
16171638
if self.shard_count == 0 {
1618-
Ok(ShardIdentity::unsharded())
1639+
// NB: carry over the stripe size from the persisted record, to avoid consistency check
1640+
// failures if the persisted value differs from the default stripe size. The stripe size
1641+
// doesn't really matter for unsharded tenants anyway.
1642+
Ok(ShardIdentity::unsharded_with_stripe_size(
1643+
self.get_stripe_size()?,
1644+
))
16191645
} else {
16201646
Ok(ShardIdentity::new(
1621-
ShardNumber(self.shard_number as u8),
1622-
ShardCount::new(self.shard_count as u8),
1623-
ShardStripeSize(self.shard_stripe_size as u32),
1647+
self.get_shard_number()?,
1648+
self.get_shard_count()?,
1649+
self.get_stripe_size()?,
16241650
)?)
16251651
}
16261652
}
16271653

1628-
pub(crate) fn get_tenant_shard_id(&self) -> Result<TenantShardId, hex::FromHexError> {
1654+
pub(crate) fn get_tenant_shard_id(&self) -> anyhow::Result<TenantShardId> {
16291655
Ok(TenantShardId {
16301656
tenant_id: TenantId::from_str(self.tenant_id.as_str())?,
1631-
shard_number: ShardNumber(self.shard_number as u8),
1632-
shard_count: ShardCount::new(self.shard_count as u8),
1657+
shard_number: self.get_shard_number()?,
1658+
shard_count: self.get_shard_count()?,
16331659
})
16341660
}
16351661
}

0 commit comments

Comments
 (0)