Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allocate Crucible regions randomly across zpools #3650

Merged
merged 4 commits into from
Jul 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 25 additions & 21 deletions nexus/db-model/src/queries/region_allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,6 @@ table! {
}
}

table! {
candidate_zpools {
id -> Uuid,
total_size -> Int8,
}
}

table! {
candidate_regions {
id -> Uuid,
Expand All @@ -69,13 +62,6 @@ table! {
}
}

table! {
zpool_size_delta (pool_id) {
pool_id -> Uuid,
size_used_delta -> Numeric,
}
}

table! {
proposed_dataset_changes {
id -> Uuid,
Expand All @@ -92,8 +78,8 @@ table! {
}

table! {
proposed_datasets_fit (fits) {
fits -> Bool,
candidate_zpools (pool_id) {
pool_id -> Uuid
}
}

Expand Down Expand Up @@ -136,8 +122,6 @@ table! {
}
}

diesel::allow_tables_to_appear_in_same_query!(candidate_datasets, zpool,);

diesel::allow_tables_to_appear_in_same_query!(
proposed_dataset_changes,
dataset,
Expand All @@ -150,12 +134,9 @@ diesel::allow_tables_to_appear_in_same_query!(
zpool,
);

diesel::allow_tables_to_appear_in_same_query!(candidate_zpools, dataset,);

diesel::allow_tables_to_appear_in_same_query!(
old_zpool_usage,
zpool,
zpool_size_delta,
proposed_dataset_changes,
);

Expand All @@ -165,3 +146,26 @@ diesel::allow_tables_to_appear_in_same_query!(
inserted_regions,
updated_datasets,
);

diesel::allow_tables_to_appear_in_same_query!(candidate_zpools, dataset,);
diesel::allow_tables_to_appear_in_same_query!(candidate_zpools, zpool,);

// == Needed for random region allocation ==

pub mod cockroach_md5 {
pub mod functions {
use diesel::sql_types::*;
diesel::sql_function!(fn md5(x: Bytea) -> Bytea);
}

pub mod helper_types {
pub type Md5<Expr> = super::functions::md5::HelperType<Expr>;
}

pub mod dsl {
pub use super::functions::*;
pub use super::helper_types::*;
}
}

// == End random region allocation dependencies ==
19 changes: 11 additions & 8 deletions nexus/db-model/src/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ pub struct Region {
volume_id: Uuid,

block_size: ByteCount,

// These are i64 only so that we can derive a diesel table from them. We
// never expect them to be negative.
blocks_per_extent: i64,
extent_count: i64,
}
Expand All @@ -42,16 +45,16 @@ impl Region {
dataset_id: Uuid,
volume_id: Uuid,
block_size: ByteCount,
blocks_per_extent: i64,
extent_count: i64,
blocks_per_extent: u64,
extent_count: u64,
) -> Self {
Self {
identity: RegionIdentity::new(Uuid::new_v4()),
dataset_id,
volume_id,
block_size,
blocks_per_extent,
extent_count,
blocks_per_extent: blocks_per_extent as i64,
extent_count: extent_count as i64,
}
}

Expand All @@ -64,11 +67,11 @@ impl Region {
pub fn block_size(&self) -> external::ByteCount {
self.block_size.0
}
pub fn blocks_per_extent(&self) -> i64 {
self.blocks_per_extent
pub fn blocks_per_extent(&self) -> u64 {
self.blocks_per_extent as u64
}
pub fn extent_count(&self) -> i64 {
self.extent_count
pub fn extent_count(&self) -> u64 {
self.extent_count as u64
}
pub fn encrypted(&self) -> bool {
// Per RFD 29, data is always encrypted at rest, and support for
Expand Down
62 changes: 62 additions & 0 deletions nexus/db-queries/src/db/cast_uuid_as_bytea.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//! Cast UUID to BYTES

use diesel::expression::ValidGrouping;
use diesel::pg::Pg;
use diesel::query_builder::AstPass;
use diesel::query_builder::QueryFragment;
use diesel::query_builder::QueryId;
use diesel::Expression;
use diesel::SelectableExpression;

/// Cast an expression which evaluates to a Uuid and cast it to a Bytea. It's
/// that simple!
#[derive(ValidGrouping, QueryId)]
pub struct CastUuidToBytea<E> {
expression: E,
}

impl<E> CastUuidToBytea<E>
where
E: Expression<SqlType = diesel::sql_types::Uuid>,
{
pub const fn new(expression: E) -> Self {
Self { expression }
}
}

impl<E> Expression for CastUuidToBytea<E>
where
E: Expression,
{
type SqlType = diesel::sql_types::Bytea;
}

impl<E, QS> diesel::AppearsOnTable<QS> for CastUuidToBytea<E> where
E: diesel::AppearsOnTable<QS>
{
}

impl<E, T> SelectableExpression<T> for CastUuidToBytea<E> where
E: SelectableExpression<T>
{
}

impl<E> QueryFragment<Pg> for CastUuidToBytea<E>
where
E: QueryFragment<Pg>,
{
fn walk_ast<'a>(
&'a self,
mut out: AstPass<'_, 'a, Pg>,
) -> diesel::QueryResult<()> {
out.push_sql("CAST(");
self.expression.walk_ast(out.reborrow())?;
out.push_sql(" as BYTEA)");

Ok(())
}
}
Loading