@@ -61,6 +61,7 @@ func RunMigrations(db shared.DB) error {
6161 cfg .MinConns = 0
6262 db = NewGormDB (NewPgxConnPool (cfg ))
6363 }
64+
6465 // Get the underlying sql.DB from GORM
6566 migrator , err := getMigrator (db )
6667 if err != nil {
@@ -79,16 +80,20 @@ func RunMigrations(db shared.DB) error {
7980 return nil
8081 }
8182 // Release the migrator's connection (advisory lock + any open tx) before
82- // touching schema_migrations on the same pool — with MaxOpenConns=1 this
83- // would otherwise deadlock .
83+ // touching schema_migrations — migrator.Close() also closes the underlying
84+ // sql.DB it was given, so we need a fresh connection for the reset .
8485 migrator .Close ()
8586 // clear dirty flag and restore version so the migration can be retried — safe in postgres since DDL is transactional
86- sqlDB , dbErr := db .DB ()
87- if dbErr == nil {
88- _ , err = sqlDB .Exec ("UPDATE schema_migrations SET dirty = false, version = $1" , versionBefore )
89- if err != nil {
87+ resetCfg := GetPoolConfigFromEnv ()
88+ resetCfg .MaxOpenConns = 1
89+ resetCfg .MinConns = 0
90+ resetDB := NewGormDB (NewPgxConnPool (resetCfg ))
91+ if resetSQLDB , dbErr := resetDB .DB (); dbErr == nil {
92+ defer resetSQLDB .Close ()
93+ if _ , err = resetSQLDB .Exec ("UPDATE schema_migrations SET dirty = false, version = $1" , versionBefore ); err != nil {
9094 monitoring .Alert ("failed to reset migration state after failed migration" , err )
9195 }
96+ slog .Info ("successfully reset migration state - feel free to try again" )
9297 }
9398 return fmt .Errorf ("failed to run migrations: %w" , migrateErr )
9499 }
0 commit comments