Skip to content

Commit 2a147ad

Browse files
authored
[!] add schema migration support for PostgreSQL sinks, closes #1110 (#1111)
- Add `admin.migration` table and migration infrastructure to sink - Implement `Migrate()` and `NeedsMigration()` for `PostgresWriter` and `MultiWriter` - Add migration checks during sink initialization with error messages - Extend `config init/upgrade` commands to support sink migrations - `NewWriterFromPostgresConn` now returns nil writer on errors - Add comprehensive test coverage for migration happy/unhappy paths - Update docs to document sink database migration support Migration pattern follows existing metrics database approach, ensuring both config and sink databases can be upgraded independently using the same `pgwatch config upgrade` command.
1 parent 00ede3a commit 2a147ad

19 files changed

Lines changed: 965 additions & 134 deletions

docs/howto/config_db_bootstrap.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ Or you can use the `config init` command with the `--metrics` flag, since metric
5050
pgwatch --metrics=postgresql://pgwatch:pgwatchadmin@localhost/pgwatch config init
5151
```
5252

53+
If you're using a PostgreSQL sink for storing measurements, you can also initialize the sink database schema:
54+
55+
```terminal
56+
pgwatch --sink=postgresql://pgwatch:pgwatchadmin@localhost/measurements config init
57+
```
58+
5359
## Usage
5460

5561
You can now configure pgwatch to use the `pgwatch` database as the configuration database for storing monitored sources,

docs/reference/cli_env.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ title: Command-Line Options & Environment Variables
88
pgwatch [OPTIONS] [config | metric | source]
99
```
1010

11-
When no command is specified, pgwatch starts the monitoring process.
11+
When no command is specified, pgwatch starts the monitoring process.
1212
It reads the configuration from the specified sources and metrics, then begins collecting measurements from the resolved databases.
1313

1414
## Options
@@ -194,16 +194,19 @@ It reads the configuration from the specified sources and metrics, then begins c
194194
```
195195

196196
!!! info
197-
To use `config` command, you need to specify the `-s`, `--sources` and\or `-m`, `--metrics` options.
197+
To use `config` command, you need to specify at least one of the following: `-s`, `--sources`, `-m`, `--metrics`, or `--sink` options.
198198

199199
- `init`
200200

201-
Initialize the configuration database with the required tables and functions. If file is used, it will
202-
be created in the specified location and filled with built-in defaults.
201+
Initialize the configuration and/or sink database with the required tables and functions. If file is used, it will
202+
be created in the specified location and filled with built-in defaults. Works with PostgreSQL-based sources,
203+
metrics, and sink databases.
203204

204205
- `upgrade`
205206

206-
Upgrade the database to the latest version. File or folder based configurations are not supported yet.
207+
Upgrade the configuration and/or sink database to the latest version by applying all pending migrations.
208+
File or folder based configurations are not supported. The command will automatically detect which
209+
databases (sources, metrics, sinks) require migrations and apply them.
207210

208211
### Manage metrics
209212

docs/tutorial/upgrading.md

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ There are no update or migration scripts for the built-in Grafana
8989
dashboards as it would break possible user applied changes. If you know
9090
that there are no user changes, then one can just delete or rename the
9191
existing ones in bulk and import the latest JSON definitions.
92-
See [here](../concept/long_term_installations.md) for
93-
some more advice on how to manage dashboards.
92+
See [some more advice](../concept/long_term_installations.md) on how to
93+
manage dashboards.
9494

9595
### Updating the config / metrics DB version
9696

@@ -105,31 +105,38 @@ problem-free, consisting of running something like:
105105
sudo systemctl restart postgresql
106106

107107
For PostgreSQL major version upgrades one should read through the
108-
according release notes (e.g.
109-
[here](https://www.postgresql.org/docs/17/release-17.html#id-1.11.6.5.4))
108+
according [release notes](https://www.postgresql.org/docs/current/release.html)
110109
and be prepared for the unavoidable downtime.
111110

112111
### Updating the pgwatch schema
113112

114113
This is the pgwatch specific part, with some coupling between the
115-
following components - Configuration DB SQL schema and pgwatch binary.
114+
following components - Configuration DB SQL schema,
115+
Sink DB SQL schema (if using PostgreSQL sink), and pgwatch binary.
116116

117117
First of all, the pgwatch binary needs to be updated to a newer version.
118118
Then try to run the pgwatch as usual:
119119

120120
pgwatch --sources=postgresql://pgwatch:pgwatchadmin@localhost/pgwatch --sink=postgresql://pgwatch:pgwatchadmin@localhost/pgwatch_metrics
121121

122-
[ERROR] configuration needs upgrade, use "config upgrade" command
122+
[ERROR] config database schema is outdated, please run migrations using `pgwatch config upgrade` command
123123
exit status 4
124124

125125
If you see the above error message, then the pgwatch schema needs updating.
126126
This is done by running the following command, which will apply all
127-
the necessary SQL migrations to the configuration database:
127+
the necessary SQL migrations to the configuration database and sink database:
128128

129-
pgwatch --sources=postgresql://pgwatch:pgwatchadmin@localhost/pgwatch config upgrade
129+
pgwatch --sources=postgresql://pgwatch:pgwatchadmin@localhost/pgwatch --sink=postgresql://pgwatch:pgwatchadmin@localhost/pgwatch_metrics config upgrade
130130

131+
[INFO] Applying migration to config database...
131132
[INFO] Applying migration named '00824 Refactor recommendations'...
132133
[INFO] Applied migration named '00824 Refactor recommendations'
134+
[INFO] Applying migration to sink database...
135+
[INFO] All migrations applied successfully
136+
137+
!!! info
138+
The `config upgrade` command will automatically detect which databases (sources, metrics, sinks) need migrations and apply them.
139+
You only need to provide the connection strings for the databases you're using.
133140

134141
### Updating the metrics collector
135142

go.mod

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/cybertec-postgresql/pgwatch/v3
33
go 1.25.0
44

55
require (
6-
github.com/cybertec-postgresql/pgx-migrator v1.2.0
6+
github.com/cybertec-postgresql/pgx-migrator v1.3.0
77
github.com/golang-jwt/jwt/v5 v5.3.0
88
github.com/gorilla/websocket v1.5.3
99
github.com/jackc/pgx/v5 v5.8.0
@@ -54,23 +54,23 @@ require (
5454
github.com/gogo/protobuf v1.3.2 // indirect
5555
github.com/golang/protobuf v1.5.4 // indirect
5656
github.com/google/uuid v1.6.0 // indirect
57-
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect
57+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.4 // indirect
5858
github.com/jackc/pgpassfile v1.0.0 // indirect
5959
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
6060
github.com/jackc/puddle/v2 v2.2.2 // indirect
61-
github.com/klauspost/compress v1.18.1 // indirect
61+
github.com/klauspost/compress v1.18.2 // indirect
6262
github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect
6363
github.com/magiconair/properties v1.8.10 // indirect
6464
github.com/moby/docker-image-spec v1.3.1 // indirect
65-
github.com/moby/go-archive v0.1.0 // indirect
65+
github.com/moby/go-archive v0.2.0 // indirect
6666
github.com/moby/patternmatcher v0.6.0 // indirect
6767
github.com/moby/sys/sequential v0.6.0 // indirect
6868
github.com/moby/sys/user v0.4.0 // indirect
6969
github.com/moby/sys/userns v0.1.0 // indirect
7070
github.com/moby/term v0.5.2 // indirect
7171
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
7272
github.com/modern-go/reflect2 v1.0.2 // indirect
73-
github.com/morikuni/aec v1.0.0 // indirect
73+
github.com/morikuni/aec v1.1.0 // indirect
7474
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
7575
github.com/opencontainers/go-digest v1.0.0 // indirect
7676
github.com/opencontainers/image-spec v1.1.1 // indirect
@@ -86,20 +86,20 @@ require (
8686
go.etcd.io/etcd/api/v3 v3.6.7 // indirect
8787
go.etcd.io/etcd/client/pkg/v3 v3.6.7 // indirect
8888
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
89-
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect
90-
go.opentelemetry.io/otel v1.38.0 // indirect
89+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 // indirect
90+
go.opentelemetry.io/otel v1.39.0 // indirect
9191
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect
92-
go.opentelemetry.io/otel/metric v1.38.0 // indirect
93-
go.opentelemetry.io/otel/trace v1.38.0 // indirect
92+
go.opentelemetry.io/otel/metric v1.39.0 // indirect
93+
go.opentelemetry.io/otel/trace v1.39.0 // indirect
9494
go.opentelemetry.io/proto/otlp v1.7.0 // indirect
9595
go.uber.org/multierr v1.11.0 // indirect
9696
go.yaml.in/yaml/v2 v2.4.3 // indirect
97-
golang.org/x/crypto v0.45.0 // indirect
98-
golang.org/x/net v0.47.0 // indirect
99-
golang.org/x/sync v0.18.0 // indirect
100-
golang.org/x/sys v0.38.0 // indirect
101-
golang.org/x/text v0.31.0 // indirect
97+
golang.org/x/crypto v0.46.0 // indirect
98+
golang.org/x/net v0.48.0 // indirect
99+
golang.org/x/sync v0.19.0 // indirect
100+
golang.org/x/sys v0.39.0 // indirect
101+
golang.org/x/text v0.32.0 // indirect
102102
golang.org/x/time v0.12.0 // indirect
103-
google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba // indirect
104-
google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect
103+
google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b // indirect
104+
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect
105105
)

0 commit comments

Comments
 (0)