diff --git a/charts/postgres-operator/crds/postgresqls.yaml b/charts/postgres-operator/crds/postgresqls.yaml index 667c58efa..206c5320e 100644 --- a/charts/postgres-operator/crds/postgresqls.yaml +++ b/charts/postgres-operator/crds/postgresqls.yaml @@ -493,6 +493,8 @@ spec: type: string standby_port: type: string + standby_primary_slot_name: + type: string oneOf: - required: - s3_wal_path diff --git a/docs/reference/cluster_manifest.md b/docs/reference/cluster_manifest.md index aab3b818f..994367da1 100644 --- a/docs/reference/cluster_manifest.md +++ b/docs/reference/cluster_manifest.md @@ -477,6 +477,10 @@ Note that `s3_wal_path` and `gs_wal_path` are mutually exclusive. TCP port on which the primary is listening for connections. Patroni will use `"5432"` if not set. +* **standby_primary_slot_name** + name of the replication slot to use on the primary server when streaming + from a remote primary. Optional. + ## Volume properties Those parameters are grouped under the `volume` top-level key and define the diff --git a/manifests/postgresql.crd.yaml b/manifests/postgresql.crd.yaml index db8efabe6..c8bf1b07d 100644 --- a/manifests/postgresql.crd.yaml +++ b/manifests/postgresql.crd.yaml @@ -3949,6 +3949,8 @@ spec: type: string standby_port: type: string + standby_primary_slot_name: + type: string type: object streams: items: diff --git a/pkg/apis/acid.zalan.do/v1/postgresql_type.go b/pkg/apis/acid.zalan.do/v1/postgresql_type.go index cffaf6fd6..b304db652 100644 --- a/pkg/apis/acid.zalan.do/v1/postgresql_type.go +++ b/pkg/apis/acid.zalan.do/v1/postgresql_type.go @@ -250,10 +250,11 @@ type Patroni struct { // standby_host can be specified alone or together with either s3_wal_path OR gs_wal_path (mutually exclusive). // At least one field must be specified. s3_wal_path and gs_wal_path are mutually exclusive. type StandbyDescription struct { - S3WalPath string `json:"s3_wal_path,omitempty"` - GSWalPath string `json:"gs_wal_path,omitempty"` - StandbyHost string `json:"standby_host,omitempty"` - StandbyPort string `json:"standby_port,omitempty"` + S3WalPath string `json:"s3_wal_path,omitempty"` + GSWalPath string `json:"gs_wal_path,omitempty"` + StandbyHost string `json:"standby_host,omitempty"` + StandbyPort string `json:"standby_port,omitempty"` + StandbyPrimarySlotName string `json:"standby_primary_slot_name,omitempty"` } // TLSDescription specs TLS properties diff --git a/pkg/cluster/k8sres.go b/pkg/cluster/k8sres.go index 638f752e4..224ef26f6 100644 --- a/pkg/cluster/k8sres.go +++ b/pkg/cluster/k8sres.go @@ -2207,6 +2207,12 @@ func (c *Cluster) generateStandbyEnvironment(description *acidv1.StandbyDescript Value: description.StandbyPort, }) } + if description.StandbyPrimarySlotName != "" { + result = append(result, v1.EnvVar{ + Name: "STANDBY_PRIMARY_SLOT_NAME", + Value: description.StandbyPrimarySlotName, + }) + } } // WAL archive can be specified with or without standby_host @@ -2226,10 +2232,6 @@ func (c *Cluster) generateStandbyEnvironment(description *acidv1.StandbyDescript }) result = append(result, v1.EnvVar{Name: "STANDBY_METHOD", Value: "STANDBY_WITH_WALE"}) result = append(result, v1.EnvVar{Name: "STANDBY_WAL_BUCKET_SCOPE_PREFIX", Value: ""}) - } else if description.StandbyHost == "" { - // Neither WAL path nor standby_host specified - c.logger.Error("no WAL path or standby_host specified in standby section") - return result } return result diff --git a/pkg/cluster/k8sres_test.go b/pkg/cluster/k8sres_test.go index 8674a25c8..e39e18cd5 100644 --- a/pkg/cluster/k8sres_test.go +++ b/pkg/cluster/k8sres_test.go @@ -1382,6 +1382,19 @@ func TestStandbyEnv(t *testing.T) { envPos: 0, envLen: 4, }, + { + subTest: "verify S3 WAL env with standby host", + standbyOpts: &acidv1.StandbyDescription{ + S3WalPath: "s3://some/path/", + StandbyHost: "remote-primary", + }, + env: v1.EnvVar{ + Name: "STANDBY_WALE_S3_PREFIX", + Value: "s3://some/path/", + }, + envPos: 1, + envLen: 4, + }, { subTest: "from remote primary with GCS WAL path", standbyOpts: &acidv1.StandbyDescription{ @@ -1395,6 +1408,19 @@ func TestStandbyEnv(t *testing.T) { envPos: 0, envLen: 4, }, + { + subTest: "from remote primary with slot name", + standbyOpts: &acidv1.StandbyDescription{ + StandbyHost: "remote-primary", + StandbyPrimarySlotName: "my_slot", + }, + env: v1.EnvVar{ + Name: "STANDBY_PRIMARY_SLOT_NAME", + Value: "my_slot", + }, + envPos: 1, + envLen: 2, + }, } var cluster = New(