Skip to content

fix: guard ConfigureDbContext() Migrate() with IHistoryRepository (Galera-safe)#1594

Merged
renemadsen merged 1 commit into
stablefrom
feat/ef-migration-helm-job
Jun 2, 2026
Merged

fix: guard ConfigureDbContext() Migrate() with IHistoryRepository (Galera-safe)#1594
renemadsen merged 1 commit into
stablefrom
feat/ef-migration-helm-job

Conversation

@renemadsen
Copy link
Copy Markdown
Member

Summary

  • Wrap Database.Migrate() in ConfigureDbContext() with an IHistoryRepository.Exists() guard to eliminate unnecessary DDL on every API pod restart

Why

On a MariaDB 11.4 Galera cluster with ~250 tenants, Database.Migrate() issues DDL (CREATE TABLE IF NOT EXISTS __EFMigrationsHistory, GET_LOCK) on every app restart even when the schema is already current. With multiple pods per tenant this causes cluster-wide desync/resync on every rolling update.

The guard pattern:

  • IHistoryRepository.Exists() — safe information_schema read, returns false if history table is absent
  • GetPendingMigrations().Any() — only called when the table exists
  • Database.Migrate() — called only when needed: fresh install, or pending migrations

In production (schema current): no DDL, no GET_LOCK. On fresh plugin activation: falls through and creates the schema.

Test Plan

  • Plugin activates from UI correctly (schema created on first activation)
  • Subsequent pod restarts do not trigger DDL when schema is current

🤖 Generated with Claude Code

Avoids DDL on every API pod restart when plugin schemas are current (Galera-safe).
Falls back to Migrate() on fresh install or when migrations are pending.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 2, 2026 15:59
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Guards EF Core startup migrations for the TimePlanning plugin by checking the migrations history table and pending migrations before calling Database.Migrate(), aiming to avoid unnecessary DDL/locks on every pod restart (Galera-friendly).

Changes:

  • Add EF Core infrastructure/migrations dependencies to access IHistoryRepository.
  • Replace unconditional Database.Migrate() with an IHistoryRepository.Exists() + GetPendingMigrations().Any() guard.
  • Keep behavior for fresh installs by still running Migrate() when the history table is absent.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 191 to +195
var contextFactory = new TimePlanningPnContextFactory();
var context = contextFactory.CreateDbContext(new[] { connectionString });
Console.WriteLine("Starting to migrate TimePlanningPnDbContext to latest version");
context.Database.Migrate();
var historyRepo = context.GetService<IHistoryRepository>();
if (!historyRepo.Exists() || context.Database.GetPendingMigrations().Any())
{
context.Database.Migrate();
}
Console.WriteLine("TimePlanningPnDbContext migrated to latest version");
@renemadsen renemadsen merged commit 4ffb3a9 into stable Jun 2, 2026
39 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants