Skip to content

Commit 1b43a0a

Browse files
authored
Add DB tables & models for blueprint clickhouse clusters (#6591)
1 parent 40fc383 commit 1b43a0a

File tree

10 files changed

+214
-7
lines changed

10 files changed

+214
-7
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nexus/db-model/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ omicron-rpaths.workspace = true
1414
anyhow.workspace = true
1515
camino.workspace = true
1616
chrono.workspace = true
17+
clickhouse-admin-types.workspace = true
1718
derive-where.workspace = true
1819
diesel = { workspace = true, features = ["postgres", "r2d2", "chrono", "serde_json", "network-address", "uuid"] }
1920
hex.workspace = true

nexus/db-model/src/deployment.rs

Lines changed: 98 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
use crate::inventory::ZoneType;
99
use crate::omicron_zone_config::{self, OmicronZoneNic};
1010
use crate::schema::{
11-
blueprint, bp_omicron_physical_disk, bp_omicron_zone, bp_omicron_zone_nic,
12-
bp_sled_omicron_physical_disks, bp_sled_omicron_zones, bp_sled_state,
13-
bp_target,
11+
blueprint, bp_clickhouse_cluster_config,
12+
bp_clickhouse_keeper_zone_id_to_node_id,
13+
bp_clickhouse_server_zone_id_to_node_id, bp_omicron_physical_disk,
14+
bp_omicron_zone, bp_omicron_zone_nic, bp_sled_omicron_physical_disks,
15+
bp_sled_omicron_zones, bp_sled_state, bp_target,
1416
};
1517
use crate::typed_uuid::DbTypedUuid;
1618
use crate::{
@@ -19,6 +21,7 @@ use crate::{
1921
};
2022
use anyhow::{anyhow, bail, Context, Result};
2123
use chrono::{DateTime, Utc};
24+
use clickhouse_admin_types::{KeeperId, ServerId};
2225
use ipnetwork::IpNetwork;
2326
use nexus_sled_agent_shared::inventory::OmicronZoneDataset;
2427
use nexus_types::deployment::BlueprintTarget;
@@ -27,7 +30,7 @@ use nexus_types::deployment::BlueprintZoneDisposition;
2730
use nexus_types::deployment::BlueprintZonesConfig;
2831
use nexus_types::deployment::CockroachDbPreserveDowngrade;
2932
use nexus_types::deployment::{
30-
blueprint_zone_type, BlueprintPhysicalDisksConfig,
33+
blueprint_zone_type, BlueprintPhysicalDisksConfig, ClickhouseClusterConfig,
3134
};
3235
use nexus_types::deployment::{BlueprintPhysicalDiskConfig, BlueprintZoneType};
3336
use nexus_types::deployment::{
@@ -37,10 +40,10 @@ use nexus_types::deployment::{
3740
use omicron_common::api::internal::shared::NetworkInterface;
3841
use omicron_common::disk::DiskIdentity;
3942
use omicron_common::zpool_name::ZpoolName;
40-
use omicron_uuid_kinds::SledUuid;
4143
use omicron_uuid_kinds::ZpoolUuid;
4244
use omicron_uuid_kinds::{ExternalIpKind, SledKind, ZpoolKind};
4345
use omicron_uuid_kinds::{ExternalIpUuid, GenericUuid, OmicronZoneUuid};
46+
use omicron_uuid_kinds::{OmicronZoneKind, SledUuid};
4447
use std::net::{IpAddr, SocketAddrV6};
4548
use uuid::Uuid;
4649

@@ -803,6 +806,96 @@ impl From<BpOmicronZoneNic> for OmicronZoneNic {
803806
}
804807
}
805808

809+
#[derive(Queryable, Clone, Debug, Selectable, Insertable)]
810+
#[diesel(table_name = bp_clickhouse_cluster_config)]
811+
pub struct BpClickhouseClusterConfig {
812+
pub blueprint_id: Uuid,
813+
pub generation: Generation,
814+
pub max_used_server_id: i64,
815+
pub max_used_keeper_id: i64,
816+
pub cluster_name: String,
817+
pub cluster_secret: String,
818+
pub highest_seen_keeper_leader_committed_log_index: i64,
819+
}
820+
821+
impl BpClickhouseClusterConfig {
822+
pub fn new(
823+
blueprint_id: Uuid,
824+
config: &ClickhouseClusterConfig,
825+
) -> anyhow::Result<BpClickhouseClusterConfig> {
826+
Ok(BpClickhouseClusterConfig {
827+
blueprint_id,
828+
generation: Generation(config.generation),
829+
max_used_server_id: config
830+
.max_used_server_id
831+
.0
832+
.try_into()
833+
.context("more than 2^63 IDs in use")?,
834+
max_used_keeper_id: config
835+
.max_used_keeper_id
836+
.0
837+
.try_into()
838+
.context("more than 2^63 IDs in use")?,
839+
cluster_name: config.cluster_name.clone(),
840+
cluster_secret: config.cluster_secret.clone(),
841+
highest_seen_keeper_leader_committed_log_index: config
842+
.highest_seen_keeper_leader_committed_log_index
843+
.try_into()
844+
.context("more than 2^63 IDs in use")?,
845+
})
846+
}
847+
}
848+
849+
#[derive(Queryable, Clone, Debug, Selectable, Insertable)]
850+
#[diesel(table_name = bp_clickhouse_keeper_zone_id_to_node_id)]
851+
pub struct BpClickhouseKeeperZoneIdToNodeId {
852+
pub blueprint_id: Uuid,
853+
pub omicron_zone_id: DbTypedUuid<OmicronZoneKind>,
854+
pub keeper_id: i64,
855+
}
856+
857+
impl BpClickhouseKeeperZoneIdToNodeId {
858+
pub fn new(
859+
blueprint_id: Uuid,
860+
omicron_zone_id: OmicronZoneUuid,
861+
keeper_id: KeeperId,
862+
) -> anyhow::Result<BpClickhouseKeeperZoneIdToNodeId> {
863+
Ok(BpClickhouseKeeperZoneIdToNodeId {
864+
blueprint_id,
865+
omicron_zone_id: omicron_zone_id.into(),
866+
keeper_id: keeper_id
867+
.0
868+
.try_into()
869+
.context("more than 2^63 IDs in use")?,
870+
})
871+
}
872+
}
873+
874+
#[derive(Queryable, Clone, Debug, Selectable, Insertable)]
875+
#[diesel(table_name = bp_clickhouse_server_zone_id_to_node_id)]
876+
pub struct BpClickhouseServerZoneIdToNodeId {
877+
pub blueprint_id: Uuid,
878+
pub omicron_zone_id: DbTypedUuid<OmicronZoneKind>,
879+
pub server_id: i64,
880+
}
881+
882+
impl BpClickhouseServerZoneIdToNodeId {
883+
pub fn new(
884+
blueprint_id: Uuid,
885+
omicron_zone_id: OmicronZoneUuid,
886+
server_id: ServerId,
887+
) -> anyhow::Result<BpClickhouseServerZoneIdToNodeId> {
888+
Ok(BpClickhouseServerZoneIdToNodeId {
889+
blueprint_id,
890+
omicron_zone_id: omicron_zone_id.into(),
891+
server_id: server_id
892+
.0
893+
.try_into()
894+
.context("more than 2^63 IDs in use")?,
895+
})
896+
}
897+
}
898+
806899
mod diesel_util {
807900
use crate::{
808901
schema::bp_omicron_zone::disposition, to_db_bp_zone_disposition,

nexus/db-model/src/schema.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1628,6 +1628,34 @@ table! {
16281628
}
16291629
}
16301630

1631+
table! {
1632+
bp_clickhouse_cluster_config (blueprint_id) {
1633+
blueprint_id -> Uuid,
1634+
generation -> Int8,
1635+
max_used_server_id -> Int8,
1636+
max_used_keeper_id -> Int8,
1637+
cluster_name -> Text,
1638+
cluster_secret -> Text,
1639+
highest_seen_keeper_leader_committed_log_index -> Int8,
1640+
}
1641+
}
1642+
1643+
table! {
1644+
bp_clickhouse_keeper_zone_id_to_node_id (blueprint_id, omicron_zone_id, keeper_id) {
1645+
blueprint_id -> Uuid,
1646+
omicron_zone_id -> Uuid,
1647+
keeper_id -> Int8,
1648+
}
1649+
}
1650+
1651+
table! {
1652+
bp_clickhouse_server_zone_id_to_node_id (blueprint_id, omicron_zone_id, server_id) {
1653+
blueprint_id -> Uuid,
1654+
omicron_zone_id -> Uuid,
1655+
server_id -> Int8,
1656+
}
1657+
}
1658+
16311659
table! {
16321660
cockroachdb_zone_id_to_node_id (omicron_zone_id, crdb_node_id) {
16331661
omicron_zone_id -> Uuid,

nexus/db-model/src/schema_versions.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use std::collections::BTreeMap;
1717
///
1818
/// This must be updated when you change the database schema. Refer to
1919
/// schema/crdb/README.adoc in the root of this repository for details.
20-
pub const SCHEMA_VERSION: SemverVersion = SemverVersion::new(98, 0, 0);
20+
pub const SCHEMA_VERSION: SemverVersion = SemverVersion::new(99, 0, 0);
2121

2222
/// List of all past database schema versions, in *reverse* order
2323
///
@@ -29,6 +29,7 @@ static KNOWN_VERSIONS: Lazy<Vec<KnownVersion>> = Lazy::new(|| {
2929
// | leaving the first copy as an example for the next person.
3030
// v
3131
// KnownVersion::new(next_int, "unique-dirname-with-the-sql-files"),
32+
KnownVersion::new(99, "blueprint-add-clickhouse-tables"),
3233
KnownVersion::new(98, "oximeter-add-time-expunged"),
3334
KnownVersion::new(97, "lookup-region-snapshot-by-region-id"),
3435
KnownVersion::new(96, "inv-dataset"),

nexus/types/src/deployment/planning_input.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,12 @@ pub struct Policy {
737737
/// Policy for replicated clickhouse setups
738738
#[derive(Debug, Clone, Serialize, Deserialize)]
739739
pub struct ClickhousePolicy {
740+
/// Should we run the single-node cluster alongside the replicated cluster?
741+
/// This is stage 1 of our deployment plan as laid out in RFD 468
742+
///
743+
/// If this is set to false, then we will only deploy replicated clusters.
744+
pub deploy_with_standalone: bool,
745+
740746
/// Desired number of clickhouse servers
741747
pub target_servers: usize,
742748

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CREATE TABLE IF NOT EXISTS omicron.public.bp_clickhouse_cluster_config (
2+
blueprint_id UUID PRIMARY KEY,
3+
generation INT8 NOT NULL,
4+
max_used_server_id INT8 NOT NULL,
5+
max_used_keeper_id INT8 NOT NULL,
6+
cluster_name TEXT NOT NULL,
7+
cluster_secret TEXT NOT NULL,
8+
highest_seen_keeper_leader_committed_log_index INT8 NOT NULL
9+
);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CREATE TABLE IF NOT EXISTS omicron.public.bp_clickhouse_keeper_zone_id_to_node_id (
2+
blueprint_id UUID NOT NULL,
3+
omicron_zone_id UUID NOT NULL,
4+
keeper_id INT8 NOT NULL,
5+
PRIMARY KEY (blueprint_id, omicron_zone_id, keeper_id)
6+
);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CREATE TABLE IF NOT EXISTS omicron.public.bp_clickhouse_server_zone_id_to_node_id (
2+
blueprint_id UUID NOT NULL,
3+
omicron_zone_id UUID NOT NULL,
4+
server_id INT8 NOT NULL,
5+
PRIMARY KEY (blueprint_id, omicron_zone_id, server_id)
6+
);

schema/crdb/dbinit.sql

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3640,6 +3640,62 @@ CREATE TABLE IF NOT EXISTS omicron.public.bp_omicron_zone_nic (
36403640
PRIMARY KEY (blueprint_id, id)
36413641
);
36423642

3643+
-- Blueprint information related to clickhouse cluster management
3644+
--
3645+
-- Rows for this table will only exist for deployments with an existing
3646+
-- `ClickhousePolicy` as part of the fleet `Policy`. In the limit, this will be
3647+
-- all deployments.
3648+
CREATE TABLE IF NOT EXISTS omicron.public.bp_clickhouse_cluster_config (
3649+
-- Foreign key into the `blueprint` table
3650+
blueprint_id UUID PRIMARY KEY,
3651+
-- Generation number to track changes to the cluster state.
3652+
-- Used as optimizitic concurrency control.
3653+
generation INT8 NOT NULL,
3654+
3655+
-- Clickhouse server and keeper ids can never be reused. We hand them out
3656+
-- monotonically and keep track of the last one used here.
3657+
max_used_server_id INT8 NOT NULL,
3658+
max_used_keeper_id INT8 NOT NULL,
3659+
3660+
-- Each clickhouse cluster has a unique name and secret value. These are set
3661+
-- once and shared among all nodes for the lifetime of the fleet.
3662+
cluster_name TEXT NOT NULL,
3663+
cluster_secret TEXT NOT NULL,
3664+
3665+
-- A recording of an inventory value that serves as a marker to inform the
3666+
-- reconfigurator when a collection of a raft configuration is recent.
3667+
highest_seen_keeper_leader_committed_log_index INT8 NOT NULL
3668+
);
3669+
3670+
-- Mapping of an Omicron zone ID to Clickhouse Keeper node ID in a specific
3671+
-- blueprint.
3672+
--
3673+
-- This can logically be considered a subtable of `bp_clickhouse_cluster_config`
3674+
CREATE TABLE IF NOT EXISTS omicron.public.bp_clickhouse_keeper_zone_id_to_node_id (
3675+
-- Foreign key into the `blueprint` table
3676+
blueprint_id UUID NOT NULL,
3677+
3678+
omicron_zone_id UUID NOT NULL,
3679+
keeper_id INT8 NOT NULL,
3680+
3681+
PRIMARY KEY (blueprint_id, omicron_zone_id, keeper_id)
3682+
);
3683+
3684+
-- Mapping of an Omicron zone ID to Clickhouse Server node ID in a specific
3685+
-- blueprint.
3686+
--
3687+
-- This can logically be considered a subtable of `bp_clickhouse_cluster_config`
3688+
CREATE TABLE IF NOT EXISTS omicron.public.bp_clickhouse_server_zone_id_to_node_id (
3689+
-- Foreign key into the `blueprint` table
3690+
blueprint_id UUID NOT NULL,
3691+
3692+
omicron_zone_id UUID NOT NULL,
3693+
server_id INT8 NOT NULL,
3694+
3695+
PRIMARY KEY (blueprint_id, omicron_zone_id, server_id)
3696+
);
3697+
3698+
36433699
-- Mapping of Omicron zone ID to CockroachDB node ID. This isn't directly used
36443700
-- by the blueprint tables above, but is used by the more general Reconfigurator
36453701
-- system along with them (e.g., to decommission expunged CRDB nodes).
@@ -4299,7 +4355,7 @@ INSERT INTO omicron.public.db_metadata (
42994355
version,
43004356
target_version
43014357
) VALUES
4302-
(TRUE, NOW(), NOW(), '98.0.0', NULL)
4358+
(TRUE, NOW(), NOW(), '99.0.0', NULL)
43034359
ON CONFLICT DO NOTHING;
43044360

43054361
COMMIT;

0 commit comments

Comments
 (0)