From 510fa5931b07a9c4be9fd219c3188176520ac478 Mon Sep 17 00:00:00 2001 From: Mayank Shah Date: Thu, 12 Feb 2026 17:01:39 +0530 Subject: [PATCH 1/7] allow overridding wal_level parameter Signed-off-by: Mayank Shah --- internal/postgres/parameters.go | 15 ++++++++------- internal/postgres/parameters_test.go | 3 +-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/internal/postgres/parameters.go b/internal/postgres/parameters.go index bbb80b0ac1..bd4c62571b 100644 --- a/internal/postgres/parameters.go +++ b/internal/postgres/parameters.go @@ -21,13 +21,6 @@ func NewParameters() Parameters { // PostgreSQL must be restarted when changing this value. parameters.Mandatory.Add("unix_socket_directories", SocketDirectory) - // Enable logical replication in addition to streaming and WAL archiving. - // PostgreSQL must be restarted when changing this value. - // - https://www.postgresql.org/docs/current/runtime-config-wal.html#GUC-WAL-LEVEL - // - https://www.postgresql.org/docs/current/runtime-config-replication.html - // - https://www.postgresql.org/docs/current/logical-replication.html - parameters.Mandatory.Add("wal_level", "logical") - // Always enable SSL/TLS. // PostgreSQL must be reloaded when changing this value. // - https://www.postgresql.org/docs/current/ssl-tcp.html @@ -36,6 +29,14 @@ func NewParameters() Parameters { parameters.Mandatory.Add("ssl_key_file", "/pgconf/tls/tls.key") parameters.Mandatory.Add("ssl_ca_file", "/pgconf/tls/ca.crt") + // Enable logical replication in addition to streaming and WAL archiving. + // Can be overridden via spec.patroni.dynamicConfiguration.postgresql.parameters. + // PostgreSQL must be restarted when changing this value. + // - https://www.postgresql.org/docs/current/runtime-config-wal.html#GUC-WAL-LEVEL + // - https://www.postgresql.org/docs/current/runtime-config-replication.html + // - https://www.postgresql.org/docs/current/logical-replication.html + parameters.Default.Add("wal_level", "logical") + // Just-in-Time compilation can degrade performance unexpectedly. Allow // users to enable it for appropriate workloads. // - https://www.postgresql.org/docs/current/jit.html diff --git a/internal/postgres/parameters_test.go b/internal/postgres/parameters_test.go index 0720d8b42a..146f17efaa 100644 --- a/internal/postgres/parameters_test.go +++ b/internal/postgres/parameters_test.go @@ -20,13 +20,12 @@ func TestNewParameters(t *testing.T) { "ssl_key_file": "/pgconf/tls/tls.key", "unix_socket_directories": "/tmp/postgres", - - "wal_level": "logical", }) assert.DeepEqual(t, parameters.Default.AsMap(), map[string]string{ "jit": "off", "password_encryption": "scram-sha-256", + "wal_level": "logical", }) } From 03485b508484582320bb61ce041e5a620faefde9 Mon Sep 17 00:00:00 2001 From: Mayank Shah Date: Thu, 12 Feb 2026 17:50:42 +0530 Subject: [PATCH 2/7] add e2e test Signed-off-by: Mayank Shah --- .../dynamic-configuration/00-assert.yaml | 24 ++++ .../00-deploy-operator.yaml | 13 +++ .../dynamic-configuration/01-assert.yaml | 110 ++++++++++++++++++ .../01-create-cluster.yaml | 12 ++ .../02-apply-configuration.yaml | 14 +++ .../dynamic-configuration/03-assert.yaml | 7 ++ .../dynamic-configuration/03-verify.yaml | 21 ++++ .../99-remove-cluster-gracefully.yaml | 21 ++++ 8 files changed, 222 insertions(+) create mode 100644 e2e-tests/tests/dynamic-configuration/00-assert.yaml create mode 100644 e2e-tests/tests/dynamic-configuration/00-deploy-operator.yaml create mode 100644 e2e-tests/tests/dynamic-configuration/01-assert.yaml create mode 100644 e2e-tests/tests/dynamic-configuration/01-create-cluster.yaml create mode 100644 e2e-tests/tests/dynamic-configuration/02-apply-configuration.yaml create mode 100644 e2e-tests/tests/dynamic-configuration/03-assert.yaml create mode 100644 e2e-tests/tests/dynamic-configuration/03-verify.yaml create mode 100644 e2e-tests/tests/dynamic-configuration/99-remove-cluster-gracefully.yaml diff --git a/e2e-tests/tests/dynamic-configuration/00-assert.yaml b/e2e-tests/tests/dynamic-configuration/00-assert.yaml new file mode 100644 index 0000000000..ae5a062d84 --- /dev/null +++ b/e2e-tests/tests/dynamic-configuration/00-assert.yaml @@ -0,0 +1,24 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +timeout: 120 +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: perconapgclusters.pgv2.percona.com +spec: + group: pgv2.percona.com + names: + kind: PerconaPGCluster + listKind: PerconaPGClusterList + plural: perconapgclusters + singular: perconapgcluster + scope: Namespaced +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +metadata: + name: check-operator-deploy-status +timeout: 120 +commands: + - script: kubectl assert exist-enhanced deployment percona-postgresql-operator -n ${OPERATOR_NS:-$NAMESPACE} --field-selector status.readyReplicas=1 diff --git a/e2e-tests/tests/dynamic-configuration/00-deploy-operator.yaml b/e2e-tests/tests/dynamic-configuration/00-deploy-operator.yaml new file mode 100644 index 0000000000..1aaca58be2 --- /dev/null +++ b/e2e-tests/tests/dynamic-configuration/00-deploy-operator.yaml @@ -0,0 +1,13 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +timeout: 10 +commands: + - script: |- + set -o errexit + set -o xtrace + + source ../../functions + init_temp_dir # do this only in the first TestStep + + deploy_operator + deploy_client diff --git a/e2e-tests/tests/dynamic-configuration/01-assert.yaml b/e2e-tests/tests/dynamic-configuration/01-assert.yaml new file mode 100644 index 0000000000..b04ca7d97a --- /dev/null +++ b/e2e-tests/tests/dynamic-configuration/01-assert.yaml @@ -0,0 +1,110 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +timeout: 480 +--- +kind: StatefulSet +apiVersion: apps/v1 +metadata: + labels: + postgres-operator.crunchydata.com/cluster: cluster1 + postgres-operator.crunchydata.com/data: postgres + postgres-operator.crunchydata.com/instance-set: instance1 + ownerReferences: + - apiVersion: postgres-operator.crunchydata.com/v1beta1 + kind: PostgresCluster + name: cluster1 + controller: true + blockOwnerDeletion: true +status: + observedGeneration: 1 + replicas: 1 + readyReplicas: 1 + currentReplicas: 1 + updatedReplicas: 1 + collisionCount: 0 +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: cluster1-pgbouncer + labels: + postgres-operator.crunchydata.com/cluster: cluster1 + postgres-operator.crunchydata.com/role: pgbouncer + annotations: + deployment.kubernetes.io/revision: '1' + ownerReferences: + - apiVersion: postgres-operator.crunchydata.com/v1beta1 + kind: PostgresCluster + name: cluster1 + controller: true + blockOwnerDeletion: true +status: + observedGeneration: 1 + replicas: 3 + updatedReplicas: 3 + readyReplicas: 3 +--- +kind: Job +apiVersion: batch/v1 +metadata: + labels: + postgres-operator.crunchydata.com/cluster: cluster1 + postgres-operator.crunchydata.com/pgbackrest: '' + postgres-operator.crunchydata.com/pgbackrest-backup: replica-create + postgres-operator.crunchydata.com/pgbackrest-repo: repo1 + ownerReferences: + - apiVersion: pgv2.percona.com/v2 + kind: PerconaPGBackup + controller: true + blockOwnerDeletion: true +status: + succeeded: 1 +--- +apiVersion: postgres-operator.crunchydata.com/v1beta1 +kind: PostgresCluster +metadata: + name: cluster1 + ownerReferences: + - apiVersion: pgv2.percona.com/v2 + kind: PerconaPGCluster + name: cluster1 + controller: true + blockOwnerDeletion: true + finalizers: + - postgres-operator.crunchydata.com/finalizer +status: + instances: + - name: instance1 + readyReplicas: 3 + replicas: 3 + updatedReplicas: 3 + observedGeneration: 1 + pgbackrest: + repos: + - name: repo1 + stanzaCreated: true + proxy: + pgBouncer: + readyReplicas: 3 + replicas: 3 +--- +apiVersion: pgv2.percona.com/v2 +kind: PerconaPGCluster +metadata: + name: cluster1 +status: + pgbackrest: + repos: + - name: repo1 + stanzaCreated: true + pgbouncer: + ready: 3 + size: 3 + postgres: + instances: + - name: instance1 + ready: 3 + size: 3 + ready: 3 + size: 3 + state: ready diff --git a/e2e-tests/tests/dynamic-configuration/01-create-cluster.yaml b/e2e-tests/tests/dynamic-configuration/01-create-cluster.yaml new file mode 100644 index 0000000000..7185cfcbfe --- /dev/null +++ b/e2e-tests/tests/dynamic-configuration/01-create-cluster.yaml @@ -0,0 +1,12 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +timeout: 20 +commands: + - script: |- + set -o errexit + set -o xtrace + + source ../../functions + + get_cr "cluster1" ${RANDOM} \ + | kubectl -n "${NAMESPACE}" apply -f - diff --git a/e2e-tests/tests/dynamic-configuration/02-apply-configuration.yaml b/e2e-tests/tests/dynamic-configuration/02-apply-configuration.yaml new file mode 100644 index 0000000000..4ad4c6e71f --- /dev/null +++ b/e2e-tests/tests/dynamic-configuration/02-apply-configuration.yaml @@ -0,0 +1,14 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +timeout: 20 +--- +apiVersion: pgv2.percona.com/v2 +kind: PerconaPGCluster +metadata: + name: cluster1 +spec: + dynamicConfiguration: + postgresql: + parameters: + wal_level: "replica" + restore_command: "exit 1" \ No newline at end of file diff --git a/e2e-tests/tests/dynamic-configuration/03-assert.yaml b/e2e-tests/tests/dynamic-configuration/03-assert.yaml new file mode 100644 index 0000000000..12a1e637c9 --- /dev/null +++ b/e2e-tests/tests/dynamic-configuration/03-assert.yaml @@ -0,0 +1,7 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: 03-pg-settings +data: + wal_level: 'replica' + restore_command: 'exit 1' diff --git a/e2e-tests/tests/dynamic-configuration/03-verify.yaml b/e2e-tests/tests/dynamic-configuration/03-verify.yaml new file mode 100644 index 0000000000..62155dd69e --- /dev/null +++ b/e2e-tests/tests/dynamic-configuration/03-verify.yaml @@ -0,0 +1,21 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +timeout: 30 +commands: + - script: |- + set -o errexit + set -o xtrace + + source ../../functions + + sleep 30 # wait for the operator to apply it via pod exec + + uri="postgres:$(get_psql_user_pass cluster1-pguser-postgres)@$(get_psql_user_host cluster1-pguser-postgres)" + uri_replicas="postgres:$(get_psql_user_pass cluster1-pguser-postgres)@cluster1-replicas" + + wal_level=$(run_psql_local 'SHOW wal_level;' "$uri" | xargs) + restore_command=$(run_psql_local 'SHOW restore_command;' "$uri_replicas" | xargs) + + kubectl create configmap -n "${NAMESPACE}" 03-pg-settings \ + --from-literal=wal_level="${wal_level}" \ + --from-literal=restore_command="${restore_command}" diff --git a/e2e-tests/tests/dynamic-configuration/99-remove-cluster-gracefully.yaml b/e2e-tests/tests/dynamic-configuration/99-remove-cluster-gracefully.yaml new file mode 100644 index 0000000000..640eb09688 --- /dev/null +++ b/e2e-tests/tests/dynamic-configuration/99-remove-cluster-gracefully.yaml @@ -0,0 +1,21 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +delete: +- apiVersion: pgv2.percona.com/v2 + kind: PerconaPGCluster + metadata: + name: cluster1 +- apiVersion: postgres-operator.crunchydata.com/v1beta1 + kind: PostgresCluster + metadata: + name: cluster1 +commands: + - script: |- + set -o errexit + set -o xtrace + + source ../../functions + + remove_all_finalizers + destroy_operator + timeout: 60 From fd808d3bf7d323df9aa371c679ca8a0702b93181 Mon Sep 17 00:00:00 2001 From: Mayank Shah Date: Thu, 12 Feb 2026 18:10:51 +0530 Subject: [PATCH 3/7] formatting Signed-off-by: Mayank Shah --- internal/postgres/parameters_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/postgres/parameters_test.go b/internal/postgres/parameters_test.go index 146f17efaa..64538cbc12 100644 --- a/internal/postgres/parameters_test.go +++ b/internal/postgres/parameters_test.go @@ -25,7 +25,7 @@ func TestNewParameters(t *testing.T) { "jit": "off", "password_encryption": "scram-sha-256", - "wal_level": "logical", + "wal_level": "logical", }) } From 4cb0e0f32a5764447442f855ce239bd033bf55f1 Mon Sep 17 00:00:00 2001 From: Mayank Shah Date: Fri, 13 Feb 2026 11:10:37 +0530 Subject: [PATCH 4/7] fix tests Signed-off-by: Mayank Shah --- .../references/dynamic-configuration.md | 116 ++++++++++++++++++ .../02-apply-configuration.yaml | 15 +-- 2 files changed, 122 insertions(+), 9 deletions(-) create mode 100644 docs/content/references/dynamic-configuration.md diff --git a/docs/content/references/dynamic-configuration.md b/docs/content/references/dynamic-configuration.md new file mode 100644 index 0000000000..997f6abdb4 --- /dev/null +++ b/docs/content/references/dynamic-configuration.md @@ -0,0 +1,116 @@ +--- +title: Dynamic Configuration Reference +draft: false +weight: 110 +--- + +# Dynamic Configuration Reference + +This document describes which PostgreSQL and Patroni settings can and cannot be configured by users via `spec.patroni.dynamicConfiguration` in the PerconaPGCluster cluster custom resource. + +## Overview + +The operator uses Patroni's dynamic configuration to manage PostgreSQL cluster settings. Users can override many settings through `dynamicConfiguration`, but some parameters are **mandatory** and always enforced by the operator for security, replication, backups, and monitoring. + +## Configurable Settings + +The following PostgreSQL parameters have operator-defined defaults but **can be overridden** via `spec.patroni.dynamicConfiguration.postgresql.parameters`: + +| Parameter | Default | Description | +|-----------|---------|-------------| +| `wal_level` | `logical` | Enables logical replication, streaming replication, and WAL archiving | +| `jit` | `off` | Just-in-Time compilation for query execution | +| `password_encryption` | `scram-sha-256` | Password hashing algorithm | +| `archive_timeout` | `60s` | Forces a WAL file switch after this many seconds | +| `huge_pages` | `try` or `off` | Depends on instance resource requests | + +**Example:** + +```yaml +spec: + patroni: + dynamicConfiguration: + postgresql: + parameters: + wal_level: "replica" + shared_buffers: "256MB" +``` + +Users can also add any other PostgreSQL parameter not listed in the non-configurable sections below. + +## Non-Configurable PostgreSQL Parameters + +These parameters are always set by the operator and **cannot be overridden** via dynamicConfiguration: + +### Core Security & Connectivity + +| Parameter | Value | Purpose | +|-----------|-------|---------| +| `unix_socket_directories` | `/tmp/postgres` | UNIX socket location for local connections | +| `ssl` | `on` | TLS/SSL always enabled | +| `ssl_cert_file` | `/pgconf/tls/tls.crt` | Server certificate path | +| `ssl_key_file` | `/pgconf/tls/tls.key` | Server private key path | +| `ssl_ca_file` | `/pgconf/tls/ca.crt` | Certificate authority path | + +### Backup & Recovery (pgBackRest) + +| Parameter | Value | Purpose | +|-----------|-------|---------| +| `archive_mode` | `on` | WAL archiving required for backups | +| `archive_command` | pgBackRest command or `true` | How WAL files are shipped to archive | +| `restore_command` | pgBackRest command | How WAL files are fetched during recovery | + +**Note:** On standby clusters with `spec.standby.repoName` configured, `restore_command` is always set by the operator. On primary clusters, users can override `restore_command` via dynamicConfiguration if needed. + +### Optional: Track Restorable Time + +| Parameter | Condition | Value | +|-----------|-----------|-------| +| `track_commit_timestamp` | When `spec.backups.trackLatestRestorableTime` is enabled, or operator version < 2.8.0 | `true` | + +### Extensions & Monitoring + +When the following extensions are enabled, their parameters cannot be removed or overridden: + +| Extension | Non-Configurable Parameters | +|-----------|-----------------------------| +| pg_stat_statements | `shared_preload_libraries` (pg_stat_statements), `pg_stat_statements.track` = `all` | +| pg_stat_monitor | `shared_preload_libraries` (pg_stat_monitor), `pg_stat_monitor.pgsm_query_max_len` = `2048` | +| pgaudit | `shared_preload_libraries` (pgaudit) | +| Exporter (pgMonitor) | `shared_preload_libraries` (pg_stat_statements, pgnodemx), `pgnodemx.kdapi_path` | + +**shared_preload_libraries:** Users can add custom libraries via dynamicConfiguration; they are prepended to the list. However, mandatory libraries required by enabled extensions are always appended and cannot be removed. + +## Non-Configurable Patroni/DCS Settings + +These Patroni settings are derived from the cluster spec or hardcoded and cannot be set via dynamicConfiguration: + +| Setting | Source | Description | +|---------|--------|-------------| +| `ttl` | `spec.patroni.leaderLeaseDurationSeconds` | Leader lease TTL in DCS | +| `loop_wait` | `spec.patroni.syncPeriodSeconds` | How often Patroni checks DCS | +| `postgresql.use_slots` | Hardcoded | Always `false` | +| `postgresql.use_pg_rewind` | `spec.postgresVersion` | `true` when PostgreSQL version > 10 | +| `postgresql.bin_name.pg_rewind` | TDE configuration | Set to `/tmp/pg_rewind_tde.sh` when TDE is enabled | + +## pg_hba Configuration + +Users can add custom authentication rules via `spec.patroni.dynamicConfiguration.postgresql.pg_hba`. However, **mandatory rules** are always prepended by the operator and cannot be removed: + +- Local `postgres` user (peer auth) +- Replication user (TLS certificate auth) +- Monitoring user rules (when exporter is enabled) +- PgBouncer and PMM rules (when those components are enabled) +- TLS-only rules (when `spec.tlsOnly` is true) + +Custom rules from dynamicConfiguration are appended after the mandatory rules. + +## Standby Clusters + +For standby clusters (`spec.standby.enabled: true`), the `standby_cluster` section is populated by the operator. Critical fields such as `restore_command` are overridden when `spec.standby.repoName` is set. User-provided standby_cluster settings are merged where applicable, but operator-managed fields take precedence. + +## Summary + +- **Configurable:** Default parameters (`wal_level`, `jit`, `password_encryption`, `archive_timeout`, `huge_pages`) and any parameter not listed as mandatory. +- **Not configurable:** Security (SSL, sockets), backup/archive commands, extension parameters when extensions are enabled, and Patroni DCS settings (`ttl`, `loop_wait`, `use_slots`, `use_pg_rewind`). +- **Partially configurable:** `pg_hba` (add rules only), `shared_preload_libraries` (add libraries only), `restore_command` on primary clusters (overridden on standby with RepoName). diff --git a/e2e-tests/tests/dynamic-configuration/02-apply-configuration.yaml b/e2e-tests/tests/dynamic-configuration/02-apply-configuration.yaml index 4ad4c6e71f..58fda7c614 100644 --- a/e2e-tests/tests/dynamic-configuration/02-apply-configuration.yaml +++ b/e2e-tests/tests/dynamic-configuration/02-apply-configuration.yaml @@ -1,14 +1,11 @@ -apiVersion: kuttl.dev/v1beta1 -kind: TestStep -timeout: 20 ---- apiVersion: pgv2.percona.com/v2 kind: PerconaPGCluster metadata: name: cluster1 spec: - dynamicConfiguration: - postgresql: - parameters: - wal_level: "replica" - restore_command: "exit 1" \ No newline at end of file + patroni: + dynamicConfiguration: + postgresql: + parameters: + wal_level: "replica" + restore_command: "exit 1" From 5177bb8a327311dd01e66028eccdb300a171ea96 Mon Sep 17 00:00:00 2001 From: Mayank Shah Date: Fri, 13 Feb 2026 11:12:21 +0530 Subject: [PATCH 5/7] update test runs Signed-off-by: Mayank Shah --- e2e-tests/run-pr.csv | 1 + e2e-tests/run-release.csv | 1 + 2 files changed, 2 insertions(+) diff --git a/e2e-tests/run-pr.csv b/e2e-tests/run-pr.csv index 5253b4a97f..6d0dc01895 100644 --- a/e2e-tests/run-pr.csv +++ b/e2e-tests/run-pr.csv @@ -5,6 +5,7 @@ custom-extensions custom-tls database-init-sql demand-backup +dynamic-configuration finalizers init-deploy huge-pages diff --git a/e2e-tests/run-release.csv b/e2e-tests/run-release.csv index 24f64d8906..ff0cb68a53 100644 --- a/e2e-tests/run-release.csv +++ b/e2e-tests/run-release.csv @@ -5,6 +5,7 @@ custom-extensions custom-tls database-init-sql demand-backup +dynamic-configuration finalizers init-deploy huge-pages From 85ba1b1040ee7cf48a1e5614583fe4d1d9c0a30a Mon Sep 17 00:00:00 2001 From: Mayank Shah Date: Fri, 13 Feb 2026 11:17:22 +0530 Subject: [PATCH 6/7] remove file Signed-off-by: Mayank Shah --- .../references/dynamic-configuration.md | 116 ------------------ 1 file changed, 116 deletions(-) delete mode 100644 docs/content/references/dynamic-configuration.md diff --git a/docs/content/references/dynamic-configuration.md b/docs/content/references/dynamic-configuration.md deleted file mode 100644 index 997f6abdb4..0000000000 --- a/docs/content/references/dynamic-configuration.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: Dynamic Configuration Reference -draft: false -weight: 110 ---- - -# Dynamic Configuration Reference - -This document describes which PostgreSQL and Patroni settings can and cannot be configured by users via `spec.patroni.dynamicConfiguration` in the PerconaPGCluster cluster custom resource. - -## Overview - -The operator uses Patroni's dynamic configuration to manage PostgreSQL cluster settings. Users can override many settings through `dynamicConfiguration`, but some parameters are **mandatory** and always enforced by the operator for security, replication, backups, and monitoring. - -## Configurable Settings - -The following PostgreSQL parameters have operator-defined defaults but **can be overridden** via `spec.patroni.dynamicConfiguration.postgresql.parameters`: - -| Parameter | Default | Description | -|-----------|---------|-------------| -| `wal_level` | `logical` | Enables logical replication, streaming replication, and WAL archiving | -| `jit` | `off` | Just-in-Time compilation for query execution | -| `password_encryption` | `scram-sha-256` | Password hashing algorithm | -| `archive_timeout` | `60s` | Forces a WAL file switch after this many seconds | -| `huge_pages` | `try` or `off` | Depends on instance resource requests | - -**Example:** - -```yaml -spec: - patroni: - dynamicConfiguration: - postgresql: - parameters: - wal_level: "replica" - shared_buffers: "256MB" -``` - -Users can also add any other PostgreSQL parameter not listed in the non-configurable sections below. - -## Non-Configurable PostgreSQL Parameters - -These parameters are always set by the operator and **cannot be overridden** via dynamicConfiguration: - -### Core Security & Connectivity - -| Parameter | Value | Purpose | -|-----------|-------|---------| -| `unix_socket_directories` | `/tmp/postgres` | UNIX socket location for local connections | -| `ssl` | `on` | TLS/SSL always enabled | -| `ssl_cert_file` | `/pgconf/tls/tls.crt` | Server certificate path | -| `ssl_key_file` | `/pgconf/tls/tls.key` | Server private key path | -| `ssl_ca_file` | `/pgconf/tls/ca.crt` | Certificate authority path | - -### Backup & Recovery (pgBackRest) - -| Parameter | Value | Purpose | -|-----------|-------|---------| -| `archive_mode` | `on` | WAL archiving required for backups | -| `archive_command` | pgBackRest command or `true` | How WAL files are shipped to archive | -| `restore_command` | pgBackRest command | How WAL files are fetched during recovery | - -**Note:** On standby clusters with `spec.standby.repoName` configured, `restore_command` is always set by the operator. On primary clusters, users can override `restore_command` via dynamicConfiguration if needed. - -### Optional: Track Restorable Time - -| Parameter | Condition | Value | -|-----------|-----------|-------| -| `track_commit_timestamp` | When `spec.backups.trackLatestRestorableTime` is enabled, or operator version < 2.8.0 | `true` | - -### Extensions & Monitoring - -When the following extensions are enabled, their parameters cannot be removed or overridden: - -| Extension | Non-Configurable Parameters | -|-----------|-----------------------------| -| pg_stat_statements | `shared_preload_libraries` (pg_stat_statements), `pg_stat_statements.track` = `all` | -| pg_stat_monitor | `shared_preload_libraries` (pg_stat_monitor), `pg_stat_monitor.pgsm_query_max_len` = `2048` | -| pgaudit | `shared_preload_libraries` (pgaudit) | -| Exporter (pgMonitor) | `shared_preload_libraries` (pg_stat_statements, pgnodemx), `pgnodemx.kdapi_path` | - -**shared_preload_libraries:** Users can add custom libraries via dynamicConfiguration; they are prepended to the list. However, mandatory libraries required by enabled extensions are always appended and cannot be removed. - -## Non-Configurable Patroni/DCS Settings - -These Patroni settings are derived from the cluster spec or hardcoded and cannot be set via dynamicConfiguration: - -| Setting | Source | Description | -|---------|--------|-------------| -| `ttl` | `spec.patroni.leaderLeaseDurationSeconds` | Leader lease TTL in DCS | -| `loop_wait` | `spec.patroni.syncPeriodSeconds` | How often Patroni checks DCS | -| `postgresql.use_slots` | Hardcoded | Always `false` | -| `postgresql.use_pg_rewind` | `spec.postgresVersion` | `true` when PostgreSQL version > 10 | -| `postgresql.bin_name.pg_rewind` | TDE configuration | Set to `/tmp/pg_rewind_tde.sh` when TDE is enabled | - -## pg_hba Configuration - -Users can add custom authentication rules via `spec.patroni.dynamicConfiguration.postgresql.pg_hba`. However, **mandatory rules** are always prepended by the operator and cannot be removed: - -- Local `postgres` user (peer auth) -- Replication user (TLS certificate auth) -- Monitoring user rules (when exporter is enabled) -- PgBouncer and PMM rules (when those components are enabled) -- TLS-only rules (when `spec.tlsOnly` is true) - -Custom rules from dynamicConfiguration are appended after the mandatory rules. - -## Standby Clusters - -For standby clusters (`spec.standby.enabled: true`), the `standby_cluster` section is populated by the operator. Critical fields such as `restore_command` are overridden when `spec.standby.repoName` is set. User-provided standby_cluster settings are merged where applicable, but operator-managed fields take precedence. - -## Summary - -- **Configurable:** Default parameters (`wal_level`, `jit`, `password_encryption`, `archive_timeout`, `huge_pages`) and any parameter not listed as mandatory. -- **Not configurable:** Security (SSL, sockets), backup/archive commands, extension parameters when extensions are enabled, and Patroni DCS settings (`ttl`, `loop_wait`, `use_slots`, `use_pg_rewind`). -- **Partially configurable:** `pg_hba` (add rules only), `shared_preload_libraries` (add libraries only), `restore_command` on primary clusters (overridden on standby with RepoName). From c392067e6f328569602ea8ec0b46f920764e1132 Mon Sep 17 00:00:00 2001 From: Mayank Shah Date: Fri, 13 Feb 2026 15:08:43 +0530 Subject: [PATCH 7/7] change restore command in test Signed-off-by: Mayank Shah --- .../tests/dynamic-configuration/02-apply-configuration.yaml | 2 +- e2e-tests/tests/dynamic-configuration/03-assert.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e-tests/tests/dynamic-configuration/02-apply-configuration.yaml b/e2e-tests/tests/dynamic-configuration/02-apply-configuration.yaml index 58fda7c614..578c47fba4 100644 --- a/e2e-tests/tests/dynamic-configuration/02-apply-configuration.yaml +++ b/e2e-tests/tests/dynamic-configuration/02-apply-configuration.yaml @@ -8,4 +8,4 @@ spec: postgresql: parameters: wal_level: "replica" - restore_command: "exit 1" + restore_command: "/bin/true" diff --git a/e2e-tests/tests/dynamic-configuration/03-assert.yaml b/e2e-tests/tests/dynamic-configuration/03-assert.yaml index 12a1e637c9..c80e19822b 100644 --- a/e2e-tests/tests/dynamic-configuration/03-assert.yaml +++ b/e2e-tests/tests/dynamic-configuration/03-assert.yaml @@ -4,4 +4,4 @@ metadata: name: 03-pg-settings data: wal_level: 'replica' - restore_command: 'exit 1' + restore_command: '/bin/true'