Postgres Configuration
These parameters control how the Postgres service operates, including software versions, installation directories, and listening ports.
pg_version
- Type: Integer
- Default:
17 - Description: This parameter specifies the Postgres major version to install.
In the following example, the inventory specifies Postgres version 17:
pg_version: 17
pg_port
- Type: Integer
- Default:
5432 - Description: This parameter specifies the port where Postgres listens for connections.
In the following example, the inventory specifies a non-standard Postgres port:
pg_port: 5433
pg_home
- Type: String
- Default: OS-dependent
-
Description: This parameter specifies the home directory of the
postgresOS user. The value primarily determines defaults for other path variables. Override this parameter only when your system uses a non-standard location. -
For RHEL-family systems, the default is
/var/lib/pgsql. - For Debian-family systems, the default is
/var/lib/postgresql.
In the following example, the inventory specifies a custom home directory:
pg_home: /home/postgres
pg_path
- Type: String
- Default: OS-dependent
-
Description: This parameter specifies the directory containing Postgres binaries and libraries. Override this parameter only for custom installations.
-
For RHEL-family systems, the default is
/usr/pgsql-{{ pg_version }}. - For Debian-family systems, the default is
/usr/lib/postgresql/{{ pg_version }}.
In the following example, the inventory specifies a custom binary path:
pg_path: /opt/postgresql/17
pg_data
- Type: String
- Default: OS-dependent
-
Description: This parameter specifies the Postgres data directory. Override this parameter only for custom installation locations.
-
For RHEL-family systems, the default is
{{ pg_home }}/{{ pg_version }}/data. - For Debian-family systems, the default is
{{ pg_home }}/{{ pg_version }}/main.
In the following example, the inventory specifies a custom data directory:
pg_data: /data/postgresql
custom_hba_rules
- Type: List of dictionaries
- Default:
[] -
Description: This parameter provides a list of additional rules to append to the default
pg_hba.confrule set. The default rules use a least-privilege model and only include entries for known users and database combinations. Each rule dictionary accepts the following fields: -
contypespecifies the connection type such aslocal,host, orhostssl; the default ishost. usersspecifies a comma-separated list of database users; the default ispostgres.databasesspecifies a comma-separated list of databases; the default ispostgres.methodspecifies the authentication method; the default isscram-sha-256.sourcespecifies the IP address and mask or hostname of allowed connections; the default is127.0.0.1/32.
In the following example, the inventory adds a custom HBA rule for SSL connections from a specific network:
custom_hba_rules:
- contype: hostssl
users: analyst
databases: reporting
source: 10.0.0.0/8
pg_parameters
- Type: Dictionary
- Default:
{} -
Description: This parameter sets Postgres configuration parameters, by name. The collection applies the values on top of its own defaults, so you only need to name the parameters you want to change. The parameters work the same way on a simple cluster and on an Ultra-HA cluster.
-
Names are matched without regard to case, as Postgres matches them, so
TimeZoneoverrides the collection's defaulttimezone. - YAML booleans become
onandoff. Numbers are written as numbers, and every other value as a quoted string, sowork_mem: 64MBworks as written. - A
nullvalue removes a collection default, and Postgres then uses its built-in value. shared_preload_librariesaccepts a list or a comma-separated string, and its libraries are added to the ones the collection loads.spockandsnowflakealways load first, followed bypg_stat_statements. Settingshared_preload_librariestonulldropspg_stat_statementsbut neverspockorsnowflake.- Removing a parameter from
pg_parametersremoves it from the cluster at the next run.
In the following example, the inventory tunes memory, logs slow statements,
and loads auto_explain beside the collection's libraries:
pg_parameters:
work_mem: 64MB
maintenance_work_mem: 1GB
log_min_duration_statement: 1000
jit: off
shared_preload_libraries: auto_explain
Parameters the Collection Controls
Spock needs some parameters set to particular values, and some parameters
follow other settings in the inventory or are set by Patroni. init_server
rejects an inventory that sets any of them in pg_parameters, and the error
names the setting to change instead.
| Parameter | Controlled by |
|---|---|
port |
pg_port |
listen_addresses |
The collection; Postgres listens on every address. |
ssl_cert_file, ssl_key_file |
The collection, which issues the certificate. |
wal_level, track_commit_timestamp |
The collection; Spock requires logical and on. |
archive_mode, archive_command, restore_command |
The backup settings, as described in Backup Configuration. |
snowflake.node |
zone |
spock.exception_behaviour |
exception_behaviour |
output_plugin_libraries |
The collection, on Postgres releases that support the parameter. |
hot_standby, cluster_name |
Patroni |
data_directory |
pg_data |
hba_file |
custom_hba_rules |
config_file, ident_file, unix_socket_directories |
The collection. |
The collection's other defaults can be overridden. These defaults include
ssl, timezone, hot_standby_feedback and the Spock conflict and DDL
settings. pg_default_parameters in the role_config role's variables lists
them all. The defaults for max_worker_processes, max_replication_slots,
max_wal_senders and, on Postgres 18 and later,
max_active_replication_origins are calculated from the cluster, as described
in the next section.
Worker and Replication Sizing
Spock needs background workers, walsenders, replication slots and replication
origins on every node. The number of each grows with the number of zones and
with the number of databases in db_names. Postgres sets aside a fixed number
of each when it starts, so a cluster that outgrows them does not slow down. It
stops replicating. Spock cannot start the worker it needs, logs an error, and
retries in a loop, and a subscription never leaves the initializing state.
To prevent this, the collection calculates these four parameters from the inventory instead of using fixed values. The formulas come from the Spock documentation's sizing guide, which explains each term in detail. They use the following values:
Nis the number of zones. Every zone holds one Spock node, however many members it has.Dis the number of databases that accept connections: the databases indb_names, pluspostgresandtemplate1. Spock starts a manager worker in each, whether it replicates or not.Sis the number of subscriptions on each node: the number of databases indb_namesmultiplied byN - 1.Pis the number of physical standbys in the node's zone: one less than the zone's members in an Ultra-HA cluster, and zero otherwise.Wismax_parallel_workersfrompg_parameters, or8, its Postgres default. Parallel queries draw on the same worker pool as Spock.
The collection calculates the defaults with the following formulas:
max_worker_processes = 1 + 1 + D + 2 * S + W + 2, rounded up to a multiple of 4
max_replication_slots = 2 * S + P + 2, but no less than 16
max_wal_senders = max_replication_slots
max_active_replication_origins = max_replication_slots (Postgres 18 and later)
The worker formula counts a supervisor, a slot synchronization worker, one
manager for each database, an apply worker and a table synchronization worker
for each subscription, the parallel query workers, and two spare workers. The
slot formula counts an apply slot and a table synchronization slot for each
subscription, a slot for each standby, and two spare slots for tools such as
pg_basebackup. Earlier releases set max_replication_slots and
max_wal_senders to a fixed 16, and the calculated values never go below it.
If Postgres finds more replication slots on disk than max_replication_slots
allows, it refuses to start, so these values must never shrink on an existing
cluster.
The following table shows the calculated values for clusters that replicate a single database:
| Cluster | max_worker_processes |
max_replication_slots, max_wal_senders |
|---|---|---|
| 2 zones | 20 | 16 |
| 3 zones | 20 | 16 |
| 4 zones | 24 | 16 |
| 5 zones | 24 | 16 |
| 8 zones | 32 | 16 |
Each additional database raises both values. For example, a 3-zone cluster that replicates ten databases needs 64 workers and 42 slots.
The calculation changes whenever the cluster does. Adding a zone or a database
to db_names raises the values on every node, and the next run applies them.
Every one of these parameters requires a restart, so pg_allow_restart decides
whether the run restarts each node or leaves the restart pending.
Removing a zone or a database from db_names lowers the values just as
readily, but the collection does not drop the subscriptions and replication
slots the removed zone or database leaves behind. If those slots outnumber the
new max_replication_slots, Postgres refuses to start after the next restart.
Before you remove a zone or a database, either drop its subscriptions and slots
on every remaining node, or set the parameters in pg_parameters to their
current values until you have.
Overriding the calculated values
You can set any of these parameters in pg_parameters, and your value
replaces the calculation completely. The collection does not raise it as the
cluster grows. If you set one, calculate it yourself with the formulas
above, and recalculate it whenever you add a zone or a database. The
formulas cannot account for databases created outside db_names, or for
extensions that start their own background workers, such as pg_cron. If
your nodes have either, add them to the totals yourself.
init_server refuses an inventory where pg_parameters sets one of these
parameters below the calculated value, or sets it to null, which falls
back to Postgres's smaller built-in default. A pool that small eventually
keeps Spock from starting a worker it needs, and replication stops. Raise
the value, or remove it from pg_parameters to use the calculated one.
Ultra-HA Clusters
In an Ultra-HA cluster, Patroni keeps each zone's Postgres configuration in its configuration store, and every member of the zone shares it. This has the following consequences:
- Every node in a zone must have the same
pg_parameters. Set the parameter on thepgedgegroup, or on a group that holds just the zone's nodes. Different zones may use different values.init_serverrejects a zone whose nodes disagree. setup_patroniupdates the store on every run, not only when it bootstraps the zone. The collection owns the store's parameters. A parameter that is in the store but not in the collection's configuration is removed, so a change made by hand withpatronictl edit-configlasts only until the next run.- A Debian node's local logging settings (
logging_collector,log_directoryandlog_filename) normally take precedence over the store. The collection drops each one thatpg_parameterssets, so your value applies.
pg_allow_restart
- Type: Boolean
- Default:
true - Description: This parameter controls whether the collection restarts Postgres
to apply parameters that only take effect on restart, such as
shared_preload_librariesormax_worker_processes. The collection restarts only nodes that Postgres or Patroni report as waiting on a restart, and only one node at a time. In an Ultra-HA zone it restarts replicas before the leader. When this parameter isfalse, the run applies everything a reload can apply and reports the nodes that still need a restart, so you can restart them in a maintenance window or with a rolling-restart playbook of your own. The parameter does not apply to a new Ultra-HA zone: the primary is always restarted once after Patroni takes it over, because Postgres starts before Patroni and only a restart gives it the zone's full configuration.
In the following example, the inventory leaves restarts to the operator:
pg_allow_restart: false
Internal Path Variables
The role_config role computes the following additional path variables. These
are available for reference when modifying or extending collection roles.
The following table shows the values by OS family:
| Variable | Debian value | RHEL value | Description |
|---|---|---|---|
| pg_config_dir | /etc/postgresql/VERSION/main | pg_data | Path to the PostgreSQL configuration directory. |
| pg_service_name | postgresql@VERSION-main | postgresql-VERSION | Systemd service name for PostgreSQL. |
| patroni_service_name | patroni@VERSION-main | patroni | Systemd service name for Patroni. |
| nodes_in_zone | (computed) | (computed) | List of all pgedge hosts in the same zone as the current node. |
| pg_supports_output_plugin_libraries | (detected) | (detected) | Whether the installed Postgres release recognizes output_plugin_libraries. |