Skip to content
This repository was archived by the owner on Apr 2, 2024. It is now read-only.

Commit efe8eb5

Browse files
committed
Wrap extension upgrades in a transaction
In some cases, an extension upgrade is a multistep process. This change wraps some of those steps in an explicit transaction. Specifically, we don't want a failure to result in the extension being left at version 0.0.0
1 parent b60be95 commit efe8eb5

File tree

2 files changed

+51
-9
lines changed

2 files changed

+51
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ We use the following categories for changes:
3434
- Do not collect telemetry if `timescaledb.telemetry_level=off` [#1612]
3535
- Fix broken cache eviction in clockcache [#1603]
3636
- Possible goroutine leak due to unbuffered channel in select block [#1604]
37+
- Wrap extension upgrades in an explicit transaction [#1665]
3738

3839
## [0.14.0] - 2022-08-30
3940

pkg/pgmodel/new_migrate.go

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -141,23 +141,64 @@ func Migrate(conn *pgx.Conn, appVersion VersionInfo, leaseLock *util.PgAdvisoryL
141141
return fmt.Errorf("failed to determine whether the prom_schema_migrations table existed: %w", err)
142142
}
143143
if schemaMigrationTableExists {
144-
mig := NewMigrator(conn, migrations.MigrationFiles, TableOfContents)
145-
if err = mig.Migrate(appSemver); err != nil {
146-
return fmt.Errorf("Error encountered during migration: %w", err)
144+
if err = upgradeThroughAllBalls(conn, appSemver, extOptions); err != nil {
145+
return err
147146
}
148-
if err = removeOldExtensionIfExists(conn); err != nil {
149-
return fmt.Errorf("error while dropping old promscale extension: %w", err)
150-
}
151-
if err = installExtensionAllBalls(conn); err != nil {
152-
return fmt.Errorf("error while installing promscale extension version 0.0.0: %w", err)
147+
} else {
148+
if err = installUpgradePromscaleExtension(conn, extOptions); err != nil {
149+
return err
153150
}
154-
log.Info("msg", "upgrading old version of Promscale to version 0.11.0, the Promscale database extension is required moving forward")
155151
}
152+
return nil
153+
}
156154

155+
func upgradeThroughAllBalls(conn *pgx.Conn, appSemver semver.Version, extOptions extension.ExtensionMigrateOptions) error {
156+
var err error
157+
ctx := context.Background()
158+
// apply any pending migrations from the "old" way
159+
mig := NewMigrator(conn, migrations.MigrationFiles, TableOfContents)
160+
if err = mig.Migrate(appSemver); err != nil {
161+
return fmt.Errorf("Error encountered during migration: %w", err)
162+
}
163+
// now that we're up-to-date, remove the old extension, install version 0.0.0, and then upgrade to latest
164+
if _, err := conn.Exec(ctx, "BEGIN"); err != nil {
165+
return fmt.Errorf("unable to start transaction: %w", err)
166+
}
167+
defer func() {
168+
_, _ = conn.Exec(ctx, "ROLLBACK")
169+
}()
170+
if err = removeOldExtensionIfExists(conn); err != nil {
171+
return fmt.Errorf("error while dropping old promscale extension: %w", err)
172+
}
173+
if err = installExtensionAllBalls(conn); err != nil {
174+
return fmt.Errorf("error while installing promscale extension version 0.0.0: %w", err)
175+
}
176+
log.Info("msg", "upgrading old version of Promscale to version 0.11.0, the Promscale database extension is required moving forward")
157177
err = extension.InstallUpgradePromscaleExtensions(conn, extOptions)
158178
if err != nil {
159179
return fmt.Errorf("failed to install/upgrade promscale extension: %w", err)
160180
}
181+
if _, err := conn.Exec(ctx, "COMMIT"); err != nil {
182+
return fmt.Errorf("unable to commit migration transaction: %w", err)
183+
}
184+
return nil
185+
}
161186

187+
func installUpgradePromscaleExtension(conn *pgx.Conn, extOptions extension.ExtensionMigrateOptions) error {
188+
var err error
189+
ctx := context.Background()
190+
if _, err := conn.Exec(ctx, "BEGIN"); err != nil {
191+
return fmt.Errorf("unable to start transaction: %w", err)
192+
}
193+
defer func() {
194+
_, _ = conn.Exec(ctx, "ROLLBACK")
195+
}()
196+
err = extension.InstallUpgradePromscaleExtensions(conn, extOptions)
197+
if err != nil {
198+
return fmt.Errorf("failed to install/upgrade promscale extension: %w", err)
199+
}
200+
if _, err := conn.Exec(ctx, "COMMIT"); err != nil {
201+
return fmt.Errorf("unable to commit migration transaction: %w", err)
202+
}
162203
return nil
163204
}

0 commit comments

Comments
 (0)