Skip to content

Commit 2c23f63

Browse files
committed
CheckSchema: Verify intermediate schema upgrades
When skipping a version for an Icinga DB upgrade, all intermediate upgrade steps must be taken. While this is already stated in the documentation, it might be overlooked. This happened for one community user, upgrading from v1.1.0 to v1.2.0, skipping the intermediate schema upgrade for v1.1.1. > https://community.icinga.com/t/icingadb-failing-exactly-5-minutes-after-start/13955 First, the necessity for all upgrades in their release order was made more prominent in the documentation, hoping that less users would ignore this when skimming the upgrade docs. However, the real change here is adding another check to the CheckSchema function, verifying that all schema upgrades between the lowest known version and the highest known version in the icingadb_schema table exists. If an intermediate schema upgrade was skipped, as in the thread above, this raises a descriptive error.
1 parent 277a61d commit 2c23f63

File tree

2 files changed

+22
-6
lines changed

2 files changed

+22
-6
lines changed

doc/04-Upgrading.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# Upgrading Icinga DB
22

33
Specific version upgrades are described below. Please note that version upgrades are incremental.
4-
If you are upgrading across multiple versions, make sure to follow the steps for each of them.
4+
5+
If you are upgrading across multiple versions, make sure to follow the steps for each version in order of release.
6+
For example, when upgrading from 1.1.0 to 1.2.0,
7+
follow all instructions for upgrading to 1.1.1, then all for 1.2.0, including schema upgrades.
58

69
## Upgrading to Icinga DB v1.2.0
710

pkg/icingadb/schema.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ func CheckSchema(ctx context.Context, db *database.DB) error {
2525
expectedDbSchemaVersion = expectedPostgresSchemaVersion
2626
}
2727

28-
var version uint16
28+
var versions []uint16
2929

3030
err := retry.WithBackoff(
3131
ctx,
3232
func(ctx context.Context) (err error) {
33-
query := "SELECT version FROM icingadb_schema ORDER BY id DESC LIMIT 1"
34-
err = db.QueryRowxContext(ctx, query).Scan(&version)
33+
query := "SELECT version FROM icingadb_schema ORDER BY version ASC"
34+
err = db.SelectContext(ctx, &versions, query)
3535
if err != nil {
3636
err = database.CantPerformQuery(err, query)
3737
}
@@ -44,13 +44,26 @@ func CheckSchema(ctx context.Context, db *database.DB) error {
4444
return errors.Wrap(err, "can't check database schema version")
4545
}
4646

47-
if version != expectedDbSchemaVersion {
47+
if len(versions) == 0 {
48+
return fmt.Errorf("no database schema version is stored in the database")
49+
}
50+
51+
for i := 0; i < len(versions)-1; i++ {
52+
if versions[i] != versions[i+1]-1 {
53+
return fmt.Errorf(
54+
"incomplete database schema upgrade: intermediate version v%d is missing,"+
55+
" please make sure you have applied all database migrations after upgrading Icinga DB",
56+
versions[i]+1)
57+
}
58+
}
59+
60+
if latestVersion := versions[len(versions)-1]; latestVersion != expectedDbSchemaVersion {
4861
// Since these error messages are trivial and mostly caused by users, we don't need
4962
// to print a stack trace here. However, since errors.Errorf() does this automatically,
5063
// we need to use fmt instead.
5164
return fmt.Errorf(
5265
"unexpected database schema version: v%d (expected v%d), please make sure you have applied all database"+
53-
" migrations after upgrading Icinga DB", version, expectedDbSchemaVersion,
66+
" migrations after upgrading Icinga DB", latestVersion, expectedDbSchemaVersion,
5467
)
5568
}
5669

0 commit comments

Comments
 (0)