diff --git a/deploy/cr.yaml b/deploy/cr.yaml index 47c629bb4..b96283517 100644 --- a/deploy/cr.yaml +++ b/deploy/cr.yaml @@ -469,6 +469,7 @@ spec: # dynamicConfiguration: # postgresql: # parameters: +# restore_command: "pgbackrest --stanza=db archive-get %f \"%p\"" # max_parallel_workers: 2 # max_worker_processes: 2 # shared_buffers: 1GB diff --git a/internal/pgbackrest/postgres.go b/internal/pgbackrest/postgres.go index c8236a3f2..a8bce592f 100644 --- a/internal/pgbackrest/postgres.go +++ b/internal/pgbackrest/postgres.go @@ -37,7 +37,14 @@ func PostgreSQL( archive += ` if [ ! -z ${timestamp} ]; then echo ${timestamp} > /pgdata/latest_commit_timestamp.txt; fi` outParameters.Mandatory.Add("archive_mode", "on") - outParameters.Mandatory.Add("archive_command", archive) + + if backupsEnabled { + outParameters.Mandatory.Add("archive_command", archive) + } else { + // If backups are disabled, keep archive_mode on (to avoid a Postgres restart) + // and throw away WAL. + outParameters.Mandatory.Add("archive_command", `true`) + } // K8SPG-518: This parameter is required to ensure that the commit timestamp is // included in the WAL file. This is necessary for the WAL watcher to @@ -63,6 +70,18 @@ func PostgreSQL( // - https://pgbackrest.org/command.html#command-archive-get // - https://www.postgresql.org/docs/current/runtime-config-wal.html restore := `pgbackrest --stanza=` + DefaultStanzaName + ` archive-get %f "%p"` + if inCluster.Spec.Patroni != nil && inCluster.Spec.Patroni.DynamicConfiguration != nil { + postgresql, ok := inCluster.Spec.Patroni.DynamicConfiguration["postgresql"].(map[string]any) + if ok { + params, ok := postgresql["parameters"].(map[string]any) + if ok { + restore_command, ok := params["restore_command"].(string) + if ok { + restore = restore_command + } + } + } + } outParameters.Mandatory.Add("restore_command", restore) if inCluster.Spec.Standby != nil && inCluster.Spec.Standby.Enabled && inCluster.Spec.Standby.RepoName != "" { diff --git a/internal/pgbackrest/postgres_test.go b/internal/pgbackrest/postgres_test.go index b518e6edd..48ce0e5e0 100644 --- a/internal/pgbackrest/postgres_test.go +++ b/internal/pgbackrest/postgres_test.go @@ -39,10 +39,40 @@ func TestPostgreSQLParameters(t *testing.T) { "archive_timeout": "60s", }) + dynamic := map[string]any{ + "postgresql": map[string]any{ + "parameters": map[string]any{ + "restore_command": "/bin/true", + }, + }, + } + if cluster.Spec.Patroni == nil { + cluster.Spec.Patroni = &v1beta1.PatroniSpec{} + } + cluster.Spec.Patroni.DynamicConfiguration = dynamic + + PostgreSQL(cluster, parameters, true) + assert.DeepEqual(t, parameters.Mandatory.AsMap(), map[string]string{ + "archive_mode": "on", + "archive_command": strings.Join([]string{ + `pgbackrest --stanza=db archive-push "%p" `, + `&& timestamp=$(pg_waldump "%p" | `, + `grep -oP "COMMIT \K[^;]+" | `, + `sed -E "s/([0-9]{4}-[0-9]{2}-[0-9]{2}) ([0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{6}) (UTC|[\\+\\-][0-9]{2})/\1T\2\3/" | `, + `sed "s/UTC/Z/" | `, + "tail -n 1 | ", + `grep -E "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{6}(Z|[\+\-][0-9]{2})$"); `, + "if [ ! -z ${timestamp} ]; then echo ${timestamp} > /pgdata/latest_commit_timestamp.txt; fi", + }, ""), + "restore_command": "/bin/true", + "track_commit_timestamp": "true", + }) + cluster.Spec.Standby = &v1beta1.PostgresStandbySpec{ Enabled: true, RepoName: "repo99", } + cluster.Spec.Patroni.DynamicConfiguration = nil PostgreSQL(cluster, parameters, true) assert.DeepEqual(t, parameters.Mandatory.AsMap(), map[string]string{