From 28faf8cd712657394e889bc02255af8ee8000230 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 10 Nov 2025 16:12:41 +0100 Subject: [PATCH] db: add defensive removal of old indicies Signed-off-by: Kristoffer Dalby --- hscontrol/db/db.go | 28 +++++++++++++++++++ ...ump_schema-to-0.27.0-old-table-cleanup.sql | 11 ++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/hscontrol/db/db.go b/hscontrol/db/db.go index 2035ec41..4eefee91 100644 --- a/hscontrol/db/db.go +++ b/hscontrol/db/db.go @@ -952,6 +952,34 @@ AND auth_key_id NOT IN ( return nil }, }, + { + // Drop all indices that are no longer in use and has existed. + // They potentially still present from broken migrations in the past. + // They should all be cleaned up by the db engine, but we are a bit + // conservative to ensure all our previous mess is cleaned up. + ID: "202511101554-drop-old-idx", + Migrate: func(tx *gorm.DB) error { + for _, oldIdx := range []struct{ name, table string }{ + {"idx_namespaces_deleted_at", "namespaces"}, + {"idx_routes_deleted_at", "routes"}, + {"idx_shared_machines_deleted_at", "shared_machines"}, + } { + err := tx.Migrator().DropIndex(oldIdx.table, oldIdx.name) + if err != nil { + log.Trace(). + Str("index", oldIdx.name). + Str("table", oldIdx.table). + Err(err). + Msg("Error dropping old index, continuing...") + } + } + + return nil + }, + Rollback: func(tx *gorm.DB) error { + return nil + }, + }, // Migrations **above** this points will be REMOVED in version **0.29.0** // This is to clean up a lot of old migrations that is seldom used diff --git a/hscontrol/db/testdata/sqlite/headscale_0.26.1_dump_schema-to-0.27.0-old-table-cleanup.sql b/hscontrol/db/testdata/sqlite/headscale_0.26.1_dump_schema-to-0.27.0-old-table-cleanup.sql index 388fefbc..d911e960 100644 --- a/hscontrol/db/testdata/sqlite/headscale_0.26.1_dump_schema-to-0.27.0-old-table-cleanup.sql +++ b/hscontrol/db/testdata/sqlite/headscale_0.26.1_dump_schema-to-0.27.0-old-table-cleanup.sql @@ -31,10 +31,15 @@ CREATE UNIQUE INDEX idx_name_provider_identifier ON users (name,provider_identif CREATE UNIQUE INDEX idx_name_no_provider_identifier ON users (name) WHERE provider_identifier IS NULL; -- Create all the old tables we have had and ensure they are clean up. -CREATE TABLE `namespaces` (`id` text,PRIMARY KEY (`id`)); +CREATE TABLE `namespaces` (`id` text,`deleted_at` datetime,PRIMARY KEY (`id`)); CREATE TABLE `machines` (`id` text,PRIMARY KEY (`id`)); CREATE TABLE `kvs` (`id` text,PRIMARY KEY (`id`)); -CREATE TABLE `shared_machines` (`id` text,PRIMARY KEY (`id`)); +CREATE TABLE `shared_machines` (`id` text,`deleted_at` datetime,PRIMARY KEY (`id`)); CREATE TABLE `pre_auth_key_acl_tags` (`id` text,PRIMARY KEY (`id`)); -CREATE TABLE `routes` (`id` text,PRIMARY KEY (`id`)); +CREATE TABLE `routes` (`id` text,`deleted_at` datetime,PRIMARY KEY (`id`)); + +CREATE INDEX `idx_routes_deleted_at` ON `routes`(`deleted_at`); +CREATE INDEX `idx_namespaces_deleted_at` ON `namespaces`(`deleted_at`); +CREATE INDEX `idx_shared_machines_deleted_at` ON `shared_machines`(`deleted_at`); + COMMIT;