Skip to content

Commit cb3090b

Browse files
authored
Remove sled_resource_vmm records without a VMM record (#7898)
Fixes #7896
1 parent f3cb67f commit cb3090b

File tree

4 files changed

+115
-3
lines changed

4 files changed

+115
-3
lines changed

nexus/db-model/src/schema_versions.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::{collections::BTreeMap, sync::LazyLock};
1616
///
1717
/// This must be updated when you change the database schema. Refer to
1818
/// schema/crdb/README.adoc in the root of this repository for details.
19-
pub const SCHEMA_VERSION: Version = Version::new(132, 0, 0);
19+
pub const SCHEMA_VERSION: Version = Version::new(133, 0, 0);
2020

2121
/// List of all past database schema versions, in *reverse* order
2222
///
@@ -28,6 +28,7 @@ static KNOWN_VERSIONS: LazyLock<Vec<KnownVersion>> = LazyLock::new(|| {
2828
// | leaving the first copy as an example for the next person.
2929
// v
3030
// KnownVersion::new(next_int, "unique-dirname-with-the-sql-files"),
31+
KnownVersion::new(133, "delete-defunct-reservations"),
3132
KnownVersion::new(132, "bp-omicron-zone-filesystem-pool-not-null"),
3233
KnownVersion::new(131, "tuf-generation"),
3334
KnownVersion::new(130, "bp-sled-agent-generation"),

nexus/tests/integration_tests/schema.rs

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1754,6 +1754,106 @@ fn after_125_0_0<'a>(ctx: &'a MigrationContext<'a>) -> BoxFuture<'a, ()> {
17541754
})
17551755
}
17561756

1757+
fn before_133_0_0<'a>(ctx: &'a MigrationContext<'a>) -> BoxFuture<'a, ()> {
1758+
Box::pin(async {
1759+
// This VMM will have a sled_resource_vmm record and a VMM record
1760+
let vmm1_id: Uuid =
1761+
"00000000-0000-0000-0000-000000000001".parse().unwrap();
1762+
// This VMM will have a sled_resource_vmm record only
1763+
let vmm2_id: Uuid =
1764+
"00000000-0000-0000-0000-000000000002".parse().unwrap();
1765+
1766+
let sled_id = Uuid::new_v4();
1767+
let instance1_id = Uuid::new_v4();
1768+
let instance2_id = Uuid::new_v4();
1769+
1770+
ctx.client
1771+
.batch_execute(&format!(
1772+
"
1773+
INSERT INTO sled_resource_vmm (
1774+
id,
1775+
sled_id,
1776+
hardware_threads,
1777+
rss_ram,
1778+
reservoir_ram,
1779+
instance_id
1780+
) VALUES
1781+
(
1782+
'{vmm1_id}', '{sled_id}', 1, 0, 0, '{instance1_id}'
1783+
),
1784+
(
1785+
'{vmm2_id}', '{sled_id}', 1, 0, 0, '{instance2_id}'
1786+
);
1787+
1788+
"
1789+
))
1790+
.await
1791+
.expect("inserted record");
1792+
1793+
// Only insert a vmm record for one of these reservations
1794+
ctx.client
1795+
.batch_execute(&format!(
1796+
"
1797+
INSERT INTO vmm (
1798+
id,
1799+
time_created,
1800+
time_deleted,
1801+
instance_id,
1802+
time_state_updated,
1803+
state_generation,
1804+
sled_id,
1805+
propolis_ip,
1806+
propolis_port,
1807+
state
1808+
) VALUES (
1809+
'{vmm1_id}',
1810+
now(),
1811+
NULL,
1812+
'{instance1_id}',
1813+
now(),
1814+
1,
1815+
'{sled_id}',
1816+
'fd00:1122:3344:104::1',
1817+
12400,
1818+
'running'
1819+
);
1820+
"
1821+
))
1822+
.await
1823+
.expect("inserted record");
1824+
})
1825+
}
1826+
1827+
fn after_133_0_0<'a>(ctx: &'a MigrationContext<'a>) -> BoxFuture<'a, ()> {
1828+
Box::pin(async {
1829+
// This record should still have a sled_resource_vmm, and be the only
1830+
// one.
1831+
let vmm1_id: Uuid =
1832+
"00000000-0000-0000-0000-000000000001".parse().unwrap();
1833+
1834+
let rows = ctx
1835+
.client
1836+
.query(
1837+
r#"
1838+
SELECT id FROM sled_resource_vmm
1839+
"#,
1840+
&[],
1841+
)
1842+
.await
1843+
.expect("loaded sled_resource_vmm rows");
1844+
1845+
let records = process_rows(&rows);
1846+
1847+
assert_eq!(records.len(), 1, "{records:?}");
1848+
1849+
assert_eq!(
1850+
records[0].values,
1851+
vec![ColumnValue::new("id", vmm1_id),],
1852+
"Unexpected sled_resource_vmm record value",
1853+
);
1854+
})
1855+
}
1856+
17571857
// Lazily initializes all migration checks. The combination of Rust function
17581858
// pointers and async makes defining a static table fairly painful, so we're
17591859
// using lazy initialization instead.
@@ -1802,7 +1902,10 @@ fn get_migration_checks() -> BTreeMap<Version, DataMigrationFns> {
18021902
Version::new(125, 0, 0),
18031903
DataMigrationFns::new().before(before_125_0_0).after(after_125_0_0),
18041904
);
1805-
1905+
map.insert(
1906+
Version::new(133, 0, 0),
1907+
DataMigrationFns::new().before(before_133_0_0).after(after_133_0_0),
1908+
);
18061909
map
18071910
}
18081911

schema/crdb/dbinit.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5001,7 +5001,7 @@ INSERT INTO omicron.public.db_metadata (
50015001
version,
50025002
target_version
50035003
) VALUES
5004-
(TRUE, NOW(), NOW(), '132.0.0', NULL)
5004+
(TRUE, NOW(), NOW(), '133.0.0', NULL)
50055005
ON CONFLICT DO NOTHING;
50065006

50075007
COMMIT;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
SET LOCAL disallow_full_table_scans = off;
2+
DELETE FROM sled_resource_vmm
3+
WHERE NOT EXISTS (
4+
SELECT 1
5+
FROM vmm
6+
WHERE vmm.id = sled_resource_vmm.id
7+
);
8+
SET LOCAL disallow_full_table_scans = on;

0 commit comments

Comments
 (0)