Skip to content

Commit

Permalink
Support Postgres Upgrades (#48)
Browse files Browse the repository at this point in the history
  • Loading branch information
majst01 committed Aug 22, 2023
1 parent 15588a4 commit 0cdb888
Show file tree
Hide file tree
Showing 16 changed files with 1,056 additions and 36 deletions.
30 changes: 20 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,30 @@ Probably, it does not make sense to use this project with large databases. Howev

## Supported Databases

| Database | Image | Status |
| --------- | --------- | ------ |
| postgres | 12-alpine | alpha |
| rethinkdb | >= 2.4.0 | alpha |
| ETCD | >= 3.5 | alpha |
| Database | Image | Status | Upgrade Support |
| --------- | ------------ | :----: | :-------------: |
| postgres | >= 12-alpine | beta ||
| rethinkdb | >= 2.4.0 | beta ||
| ETCD | >= 3.5 | alpha ||

## Database Upgrades

### Postgres

Postgres requires special treatment if a major version upgrade is planned. `pg_upgrade` needs to be called with the old and new binaries, also the old data directory and a already initialized data directory which was initialized with the new binary, e.g. `initdb <new directory>`.

To make this process as smooth as possible, backup-restore-sidecar will detect if the version of the database files and the version of the postgres binary. If the binary is newer than the database files it will start the upgrade process. Strict validation to ensure all prerequisites are met is done before actually starting the upgrade process.

To achieve this, `backup-restore-sidecar` saves the postgres binaries in the database directory in the form of `pg-bin-v12` for postgres 12. If later the database version is upgraded, the previous postgres binaries are present for doing the actual upgrade.

## Supported Compression Methods

With `--compression-method` you can define how generated backups are compressed before stored at the storage provider. Available compression methods are:

| compression-method | suffix | comments |
| ------------------ | -------- | -------- |
| tar | .tar | no compression, best suited for already compressed content |
| targz | .tar.gz | tar and gzip, most commonly used, best compression ratio, average performance |
| compression-method | suffix | comments |
|--------------------|----------|----------------------------------------------------------------------------------------------|
| tar | .tar | no compression, best suited for already compressed content |
| targz | .tar.gz | tar and gzip, most commonly used, best compression ratio, average performance |
| tarlz4 | .tar.lz4 | tar and lz4, very fast compression/decompression speed compared to gz, slightly bigger files |

## Supported Storage Providers
Expand All @@ -32,7 +42,7 @@ With `--compression-method` you can define how generated backups are compressed

## How it works

![Sequence Diagram](docs/sequence.png)
![Sequence Diagram](docs/sequence.drawio.svg)

## Limitations

Expand Down
34 changes: 19 additions & 15 deletions api/v1/initializer.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions cmd/internal/database/contract.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
package database

type DatabaseInitializer interface {
// Check indicates whether a restore of the database is required or not.
Check() (bool, error)

// Recover performs a restore of the database.
Recover() error

// Upgrade performs an upgrade of the database in case a newer version of the database is detected.
//
// The function aborts the update without returning an error as long as the old data stays unmodified and only logs the error.
// This behavior is intended to reduce unnecessary downtime caused by misconfigurations.
//
// Once the upgrade was made, any error condition will require to recover the database from backup.
Upgrade() error
}

type DatabaseProber interface {
// Probe figures out if the database is running and available for taking backups.
Probe() error

// Backup creates a backup of the database.
Backup() error
}

Expand Down
7 changes: 6 additions & 1 deletion cmd/internal/database/etcd/etcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ func (db *Etcd) Recover() error {
return nil
}

// Probe indicates whether the database is running
// Probe figures out if the database is running and available for taking backups.
func (db *Etcd) Probe() error {
out, err := db.etcdctl(true, "get", "foo")
if err != nil {
Expand All @@ -136,6 +136,11 @@ func (db *Etcd) Probe() error {
return nil
}

// Upgrade performs an upgrade of the database in case a newer version of the database is detected.
func (db *Etcd) Upgrade() error {
return nil
}

func (db *Etcd) etcdctl(withConnectionArgs bool, args ...string) (string, error) {
var (
etcdctlEnvs []string
Expand Down
4 changes: 2 additions & 2 deletions cmd/internal/database/postgres/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,12 @@ func (db *Postgres) Recover() error {

db.log.Debugw("restored postgres pg_wal backup", "output", out)

db.log.Infow("successfully restored postgres database")
db.log.Info("successfully restored postgres database")

return nil
}

// Probe indicates whether the database is running
// Probe figures out if the database is running and available for taking backups.
func (db *Postgres) Probe() error {
conn, err := net.DialTimeout("tcp", net.JoinHostPort(db.host, strconv.Itoa(db.port)), connectionTimeout)
if err != nil {
Expand Down
Loading

0 comments on commit 0cdb888

Please sign in to comment.