This is the multi-page printable view of this section. .
Administration
- 1: Managing PostgreSQL Clusters
- 2: Managing PostgreSQL Users
- 3: Managing PostgreSQL Databases
- 4: Patroni HA Management
- 5: Managing PostgreSQL HBA Rules
- 6: Pgbouncer Connection Pooling
- 7: Managing PostgreSQL Component Services
- 8: Manage PostgreSQL Cron Jobs
- 9: Managing PostgreSQL Extensions
- 10: Upgrading PostgreSQL Major/Minor Versions
1 - Managing PostgreSQL Clusters
Quick Reference
| Action | Command | Description |
|---|---|---|
| Create Cluster | bin/pgsql-add <cls> | Create a new PostgreSQL cluster |
| Expand Cluster | bin/pgsql-add <cls> <ip...> | Add replica to existing cluster |
| Shrink Cluster | bin/pgsql-rm <cls> <ip...> | Remove instance from cluster |
| Remove Cluster | bin/pgsql-rm <cls> | Destroy entire PostgreSQL cluster |
| Reload Service | bin/pgsql-svc <cls> [ip...] | Reload cluster load balancer config |
| Reload HBA | bin/pgsql-hba <cls> [ip...] | Reload cluster HBA access rules |
| Clone Cluster | - | Clone via standby cluster or PITR |
For other management tasks, see: HA Management, Manage Users, Manage Databases.
Create Cluster
To create a PostgreSQL cluster, first define the cluster in the inventory. Then add nodes and initialize them:
Create the cluster on the managed nodes.
Run the pgsql.yml playbook on the <cls> group:
Example: Create 3-node PG cluster pg-test
demo/pgsql.cast — /demo/pgsql.cast
If you repeat cluster creation, Pigsty keeps existing data files.
However, it overwrites service configurations and restarts the cluster.
It also runs any baseline SQL from the database definition again.
If that SQL deletes or overwrites data, data loss can occur.
Expand Cluster
To add a replica to an existing PostgreSQL cluster, add its instance definition to the inventory.
Use all.children.<cls>.hosts:
Scale out with a procedure similar to cluster creation. First add the new node to Pigsty:
Then install the PGSQL module on the new node.
Use the same pg_cluster value as the existing cluster:
After you scale out, reload the service to add the new member to the load balancer.
Example: Add replica 10.10.10.13 to 2-node cluster pg-test
demo/pgsql-append.cast — /demo/pgsql-append.cast
Shrink Cluster
To remove a replica from an existing PostgreSQL cluster, remove its instance definition.
Update all.children.<cls>.hosts in the inventory.
By default, scaling in stops the instance and deletes its data directory.
First run pig pg list <cls> and pig pb info.
Verify that the target is not the primary and that a recent restorable backup exists.
Then have the operator enter the exact <ip>.
Run the removal only after confirmation.
First uninstall the PGSQL module from the target node.
Run pgsql-rm.yml on <ip>:
After you remove the PGSQL module, you can remove the node from Pigsty:
After you scale in, remove the instance from the inventory. Then reload the service to remove the instance from the load balancer.
Example: Remove replica 10.10.10.13 from 3-node cluster pg-test
demo/pgsql-shrink.cast — /demo/pgsql-shrink.cast
Remove Cluster
To destroy a cluster, uninstall the PGSQL module from all its nodes.
Run pgsql-rm.yml on <cls>:
This operation permanently deletes data.
Inspect pig pg list <cls> and pig pb info.
Verify a recent backup and any independent copy that you must keep.
Have the operator enter the exact cluster name.
The following commands destroy that cluster directly.
After you destroy PGSQL, you can remove all its nodes from Pigsty. You can keep nodes that run other services:
After removal, delete the entire cluster definition from inventory.
Example: Destroy 3-node PG cluster pg-test
demo/pgsql-rm.cast — /demo/pgsql-rm.cast
If pg_safeguard is true for the cluster or globally, pgsql-rm.yml stops to prevent accidental removal.
To force removal, override this setting on the playbook command line.
By default, removal also deletes the cluster backup repository.
To keep backups, such as a centralized repository, set pg_rm_backup=false:
Reload Service
PostgreSQL clusters expose services through HAProxy on host nodes. Reload services when service definitions, instance weights, or cluster membership change, including scale-out and scale-in. The reload updates the static HAProxy member configuration. The default Primary and Replica services detect current roles through Patroni REST API health checks. Thus, ordinary switchover or failover redirects traffic automatically. These role changes do not require a new HAProxy configuration.
To reload service configuration, run the pg_service subtask of pgsql.yml.
Target <cls> for the whole cluster or <ip> for specific instances:
If you use a dedicated load balancer cluster, set
pg_service_provider. In this configuration, only a reload on the cluster primary updates the load balancer configuration.
Example: Reload pg-test cluster service config
demo/pgsql-svc.cast — /demo/pgsql-svc.cast
Reload HBA
When HBA configuration changes, reload the pg_hba_rules and pgb_hba_rules rules.
Some HBA rules depend on inventory roles or address ranges that refer to cluster member aliases.
For these rules, reload HBA after you change pg_role labels or scale the cluster.
Role selectors use static inventory variables.
They do not change automatically after a Patroni switchover.
To reload PostgreSQL and Pgbouncer HBA rules, run the HBA subtasks of pgsql.yml.
Target <cls> for the whole cluster or <ip> for specific instances:
Example: Reload pg-test cluster HBA rules
demo/pgsql-hba.cast — /demo/pgsql-hba.cast
Config Cluster
Patroni manages PostgreSQL configuration parameters.
The Patroni configuration template supplies the initial values.
After cluster initialization, Patroni dynamically manages and synchronizes the configuration stored in Etcd.
Use patronictl to change most Patroni configuration parameters.
Use subtasks for other parameters, such as etcd DCS, logging, and REST API configuration.
For example, refresh Patroni configuration after etcd cluster membership changes:
You can override Patroni-managed defaults at different levels: specify params per instance, specify params per user, or specify params per database.
Clone Cluster
You can clone a cluster with a Standby Cluster or Point-in-Time Recovery. A standby cluster is simple and does not require a backup repository. It requires a reachable replication upstream and can copy only the latest state. PITR requires a centralized backup repository, such as Silo. It can clone the cluster to any point within the retention period.
| Method | Pros | Cons | Use Cases |
|---|---|---|---|
| Standby Cluster | No backup repository needed | Requires reachable upstream; latest state only | DR, read-write separation, migration |
| PITR | Recover to any point | Requires centralized backup | Undo mistakes, data audit |
Clone via Standby Cluster
A standby cluster continuously synchronizes from the upstream cluster through streaming replication.
This is the simplest cloning method.
Set pg_upstream on the new cluster primary to pull data automatically from the upstream.
Create standby cluster with:
The standby cluster follows the upstream and keeps its data synchronized. You can promote it to an independent cluster at any time:
Via Config Cluster, remove standby_cluster config to promote:
After promotion, pg-test2 becomes independent cluster accepting writes, forked from pg-test.
If upstream cluster switchover occurs, change standby cluster upstream via Config Cluster:
Clone via PITR
Point-in-Time Recovery (PITR) can recover to any point within the backup retention period. It requires a centralized backup repository, such as Silo or S3. It gives more recovery options than a standby cluster.
To clone with PITR, add pg_pitr and specify the recovery target:
Execute clone with pgsql-pitr.yml playbook:
PITR supports multiple recovery target types:
| Target Type | Example | Description |
|---|---|---|
| Time | time: "2025-01-10 10:00:00+00" | Recover to specific timestamp |
| XID | xid: "250000" | Recover to before/after txn |
| Name | name: "before_migration" | Recover to named restore point |
| LSN | lsn: "0/4001C80" | Recover to specific WAL pos |
| Latest | pg_pitr: {} | Recover to end of WAL archive |
Pigsty v4.5 PITR keeps archiving enabled by default (archive: true). If you explicitly set archive: false for exploratory recovery, reset archive_mode, restart the cluster, and perform a new full backup after confirming the recovered data is correct:
For detailed PITR usage, see Restore Operations documentation.
2 - Managing PostgreSQL Users
Quick Start
Pigsty manages users declaratively.
First define users in the inventory.
Then run bin/pgsql-user <cls> <username> to create or modify them.
For the complete user definition reference, see User Configuration. See Access Control for roles and privileges, and Authentication for credential management.
pgsql-user.yml uses name to find a user definition.
The playbook does not rename roles.
To rename a role, create a replacement role.
Migrate ownership, memberships, and client credentials, then validate the change before you remove the old role.
Deletion followed by creation is not a lossless rename.
| Action | Command | Description |
|---|---|---|
| Create User | bin/pgsql-user <cls> <user> | Create new business user or role |
| Modify User | bin/pgsql-user <cls> <user> | Modify existing user properties |
| Delete User | bin/pgsql-user <cls> <user> | Dependency-aware destructive deletion (state: absent) |
demo/pgsql-user.cast — /demo/pgsql-user.cast
Create User
During PostgreSQL cluster creation, the pg_user task automatically creates users defined in pg_users.
To create a user on an existing cluster, add its definition to all.children.<cls>.pg_users.
Then run:
Example: Create business user dbuser_app
Result: Pigsty creates dbuser_app on the primary, sets its password, and grants it the dbrole_readwrite role.
It adds the user to the Pgbouncer pool and reloads Pgbouncer configuration on all instances.
For manual user creation, you must ensure Pgbouncer user list sync yourself.
Modify User
Use the same command as for creation. The playbook is idempotent. If the target user exists, Pigsty changes its properties to match the configuration.
Not directly mutable: name is the identity key in the declarative definition.
The playbook does not rename an existing role.
Create a replacement role, then migrate ownership, privileges, and clients.
Validate the change before you remove the old role.
All other properties can be modified. Common examples:
Modify password: Change the password field.
Pigsty temporarily disables logging during the change to prevent password disclosure.
Modify privilege attributes: Configure boolean flags for user privileges.
Modify expiration: Use expire_in for expiration after N days, or expire_at for a fixed date.
expire_in takes priority.
Each playbook run recalculates its expiration date.
Use it for temporary users that need periodic renewal.
Modify role membership: Use the roles array with simple or extended definitions.
Membership changes are additive: Pigsty keeps existing memberships that the array does not declare.
To revoke a membership explicitly, use state: absent.
Manage user parameters: Use the parameters dictionary for user-level parameters.
Pigsty generates ALTER USER ... SET commands.
Use DEFAULT to reset a parameter.
Connection pool config: Set pgbouncer: true to add the user to the pool.
You can also set pool_mode and pool_connlimit.
Delete User
User deletion terminates sessions, transfers object ownership, revokes grants, and runs DROP ROLE.
This operation is irreversible.
Confirm the exact cluster, role, successor owner, and a recent backup.
Then set the user to state: absent and apply the change.
Config example:
Deletion process: On the primary, the task runs pg-drop-role <user> postgres --force.
It disables login and terminates active sessions.
It transfers database and tablespace ownership, and objects in each connectable database, to postgres.
It runs DROP OWNED to remove grants, revokes role memberships, then runs DROP ROLE.
Before changes, it writes an audit snapshot to /tmp/pg_drop_role_<user>_<timestamp>.log.
Protection: The Ansible task skips postgres and the replication, administration, and monitoring usernames configured in the inventory.
Direct calls to pg-drop-role protect only the fixed default names: postgres, replicator, dbuser_dba, and dbuser_monitor.
The script does not recognize renamed system accounts automatically.
If REASSIGN OWNED fails in a database, pg-drop-role skips DROP OWNED in that database.
However, the procedure across databases is not one transaction.
A failure partway through can leave the role NOLOGIN, transfer only some ownership, or leave dependencies.
The v4.5 Ansible task also uses ignore_errors.
Thus, a successful playbook result does not prove complete deletion.
Afterward, verify role absence, successor ownership, application migration, and the audit log.
In v4.5, pgsql-user.yml reloads Pgbouncer.
However, it does not reliably remove a deleted role from /etc/pgbouncer/userlist.txt.
Check every cluster instance after deletion:
If the exact Pgbouncer entry remains, remove only that line through the change control procedure. Reload Pgbouncer and validate application connections. Do not delete entries with a broad pattern.
Manual Deletion
For manual user deletion, use pg-drop-role script directly:
Common Use Cases
Common user configuration examples:
Basic business user
Read-only user
Admin user (can execute DDL)
Temp user (expires in 30 days)
Role (no login, for permission grouping)
User with advanced role options (PG16+)
Query Users
Common SQL queries for user info:
List all users
View user role membership
View user-level parameters
View expiring users
Connection Pool Management
Connection pool params in user definitions are applied to Pgbouncer when creating/modifying users.
Pigsty adds users with pgbouncer: true to /etc/pgbouncer/userlist.txt.
It sets user-level pool_mode and pool_connlimit in /etc/pgbouncer/useropts.txt.
As the postgres operating system user, use the pgb alias to access the Pgbouncer administration database.
For more operations, see Pgbouncer Management.
Manage Default-User Passwords
For a business user, follow Modify User.
Save the new password in its pg_users definition, preview the playbook for that user, then apply it.
The three default users need extra coordination because other services use their credentials.
| Parameter | Default | Role | Consumers |
|---|---|---|---|
pg_admin_password | DBUser.DBA | dbuser_dba | Admin clients, Pgbouncer, Infra service files, pgAdmin |
pg_monitor_password | DBUser.Monitor | dbuser_monitor | Exporters, Pgbouncer, Grafana data sources |
pg_replication_password | DBUser.Replicator | replicator | Patroni replication and .pgpass files |
These accounts belong to pg_default_roles, not pg_users.
pgsql-user.yml searches only pg_users.
Do not change a default password by overriding pg_users on the command line.
This changes the business-user list for that run and exposes plaintext passwords in shell history.
Rotate one account at a time:
- Save the new parameter in
pigsty.ymlor the active inventory. Never put the plaintext password on the command line. - On the current primary, open interactive
psqlas a superuser. Run\password <username>to enter the secret interactively. - Verify the
-lcluster or node scope, then run the corresponding refresh playbooks below. - Keep the current administration session open. Verify direct PostgreSQL, Pgbouncer, replication, exporters, and Grafana data sources before you change another account.
Refresh every consumer for the account. Replace <cls> and constrain infra to the actual targets:
If replication credentials differ between the role and Patroni nodes, new replication connections fail. Change this credential during a maintenance window and validate it promptly. VIBE or another module may have generated an administration connection string in its workspace context. If so, generate that module’s files again.
In v4.5, env_pgpass adds the new line with lineinfile; it does not remove older lines by username. Because libpq uses the first matching line, inspect every target Infra node after the refresh and remove obsolete entries through controlled editing without printing secrets:
patroni_password protects the Patroni REST API.
It is not a PostgreSQL role password.
After you change it in the inventory, refresh the target PostgreSQL cluster and the Infra administration configuration separately:
Then validate authentication and cluster state with patronictl or pig pg list <cls>.
3 - Managing PostgreSQL Databases
Quick Start
Pigsty manages databases declaratively.
First define databases in the inventory.
Then run bin/pgsql-db <cls> <dbname> to create or modify them.
For the complete database definition reference, see Database Configuration. For database access permissions, see Access Control: Database Isolation.
You can set some parameters only at creation time.
To change these parameters, recreate the database with state: recreate.
| Action | Command | Description |
|---|---|---|
| Create Database | bin/pgsql-db <cls> <db> | Create new business database |
| Modify Database | bin/pgsql-db <cls> <db> | Modify existing database properties |
| Delete Database | bin/pgsql-db <cls> <db> | Delete database (requires state: absent) |
| Rebuild Database | bin/pgsql-db <cls> <db> | Drop and recreate (requires state: recreate) |
| Clone Database | bin/pgsql-db <cls> <db> | Clone database using template |
demo/pgsql-db.cast — /demo/pgsql-db.cast
Create Database
During PostgreSQL cluster creation, the pg_db task automatically creates databases defined in pg_databases.
To create a database on an existing cluster, add its definition to all.children.<cls>.pg_databases.
Then run:
Example: Create business database myapp
Result: Pigsty creates myapp on the primary with dbuser_myapp as its owner.
It creates the app schema and enables the pg_trgm and btree_gin extensions.
It also adds the database to the Pgbouncer pool and registers a Grafana data source.
For manual database creation, you must ensure Pgbouncer pool and Grafana datasource sync yourself.
Modify Database
Use the same command as for creation.
The playbook is idempotent when no baseline SQL is defined.
If the target database exists, Pigsty changes its properties to match the configuration. However, you can set some properties only at creation.
Immutable properties: To change these properties after creation, use state: recreate:
name(database name),template,strategy(clone strategy)encoding,locale/lc_collate/lc_ctype,locale_provider/icu_locale/icu_rules/builtin_locale
All other properties can be modified. Common examples:
Modify owner: Change the owner field.
Pigsty runs ALTER DATABASE ... OWNER TO and grants permissions.
Modify connection limit: Use connlimit to limit max connections.
Revoke public connect: Set revokeconn: true to revoke the PUBLIC CONNECT privilege.
Only the owner, DBA, monitor, and replication users can then connect.
Manage parameters: Use the parameters dictionary to set database-level parameters.
Pigsty generates ALTER DATABASE ... SET commands.
Use the special value DEFAULT to reset a parameter.
Manage schemas: Use the schemas array with simple or extended definitions.
To drop a schema with CASCADE, set state: absent.
Manage extensions: Use the extensions array with simple or extended definitions.
To uninstall an extension with CASCADE, set state: absent.
Schema deletion and extension removal use CASCADE.
This deletes all dependent objects.
Understand the effect before you run these operations.
Connection pool config: By default, Pigsty adds all databases to Pgbouncer.
Configure pooling with pgbouncer, pool_mode, pool_size, pool_reserve, pool_size_min, pool_connlimit, and pool_auth_user.
Since Pigsty
v4.1.0, usepool_reserveandpool_connlimitfor database pool fields. These names replace the legacy aliasespool_size_reserveandpool_max_db_conn.
Delete Database
To delete a database, set state to absent and execute:
Config example:
Deletion process: If is_template: true, Pigsty first runs ALTER DATABASE ... IS_TEMPLATE false.
It then uses DROP DATABASE ... WITH (FORCE) (PG13+) to delete the database and terminate all its connections.
It removes the database from the Pgbouncer pool and unregisters its Grafana data source.
Protection: Pigsty cannot delete the system databases postgres, template0, and template1.
Deletion runs only on the primary.
Streaming replication sends the change to replicas.
Database deletion is irreversible and permanently deletes all data. Before deletion, verify that a recent backup exists. Confirm that no business uses the database, and notify stakeholders. Pigsty is not responsible for any data loss from database deletion. Use at your own risk.
Rebuild Database
recreate state rebuilds database (drop then create):
Config example:
Use cases: Test environment reset, clear dev database, modify immutable properties (encoding, locale), restore to initial state.
Difference from manual DROP + CREATE: One command performs the operation.
It preserves Pgbouncer and Grafana configuration automatically.
It also loads the baseline initialization script automatically.
Clone Database
Use the PostgreSQL template mechanism to clone a database. The template database must have no active connections during cloning.
Config example:
Instant Clone (PG18+): For PostgreSQL 18+, Pigsty configures file_copy_method by default.
With strategy: FILE_COPY, cloning takes about 200ms and does not copy data files.
For example, a 30GB database takes 18s with normal cloning and 200ms with instant cloning.
Manual clone: Ensure all connections to template are terminated:
Limitations: Instant cloning requires a supported filesystem: xfs, btrfs, zfs, or apfs.
Do not use the postgres database as a template.
In high-concurrency environments, clear all template connections within the cloning window of about 200ms.
Connection Pool Management
Connection pool params in database definitions are applied to Pgbouncer when creating/modifying databases.
By default, Pigsty adds all databases to the Pgbouncer pool (pgbouncer: true).
It adds their definitions to /etc/pgbouncer/database.txt.
This file also holds database-level pool parameters: pool_auth_user, pool_mode, pool_size, pool_reserve, pool_size_min, and pool_connlimit.
As the postgres operating system user, use the pgb alias to access the Pgbouncer administration database.
For more operations, see Pgbouncer Management.
4 - Patroni HA Management
Overview
Pigsty uses Patroni to manage PostgreSQL clusters. It handles configuration changes, status checks, switchovers, restarts, replica reinitialization, and other operations.
To manage clusters with Patroni, use one of these identities:
- On an INFRA node, use an administration user to manage all clusters in the environment.
- On a PGSQL node, use
pg_dbsu, which defaults topostgres, to manage only the current cluster.
Patroni provides the patronictl administration CLI.
Pigsty provides the pg wrapper alias to simplify its use.
Available Commands
| Command | Function | Description |
|---|---|---|
edit-config | Edit Config | Interactively edit cluster Patroni/PostgreSQL config |
list | List Status | List cluster members and their status |
switchover | Switchover | Switch primary role to specified replica (planned) |
failover | Failover | Force failover to specified replica (emergency) |
restart | Restart | Restart PostgreSQL instance to apply restart-required params |
reload | Reload | Reload Patroni config (no restart needed) |
reinit | Reinit Replica | Reinitialize replica (wipe data and re-clone) |
pause | Pause Auto-Failover | Pause Patroni automatic failover |
resume | Resume Auto-Failover | Resume Patroni automatic failover |
history | View History | Show cluster failover history |
show-config | Show Config | Display current cluster config (read-only) |
query | Execute Query | Execute SQL query on cluster members |
topology | View Topology | Display cluster replication topology |
version | View Version | Display Patroni version info |
remove | Remove Member | Remove cluster member from DCS (dangerous) |
Edit Config
Use edit-config to edit cluster Patroni and PostgreSQL configuration interactively.
The command opens an editor for configuration stored in DCS.
It applies changes automatically to all members.
You can change Patroni parameters, such as ttl, loop_wait, and synchronous_mode.
You can also change PostgreSQL parameters in postgresql.parameters.
demo/pgsql-config.cast — /demo/pgsql-config.cast
Common config modification examples:
Some parameter changes require a PostgreSQL restart.
Run pg list to find instances marked with *.
These instances need a restart.
Run pg restart to apply the changes.
You can also call the Patroni REST API with curl or a program:
List Status
Use list to view cluster members and their status.
The output shows each instance name, host, role, state, timeline, and replication lag.
This is the most common command for cluster health checks.
Example output:
The output columns have these meanings:
- Member: The instance name, formed from
pg_cluster-pg_seq. - Host: The instance IP address.
- Role: Leader (primary), Replica, Sync Standby, or Standby Leader (cascade primary).
- State: The running state, such as
running,streaming,in archive recovery,starting, orstopped. - TL: The timeline number, which increases after each switchover.
- Lag in MB: Replication lag in MB. This value is not shown for the primary.
Instances requiring restart show * after the name:
Switchover
Use switchover for a planned primary-replica role change.
Patroni first verifies that the replica is fully synchronized.
It then demotes the primary and promotes the target replica.
The operation takes seconds, with a short interruption to writes.
Use it for primary host maintenance, upgrades, or migration of the primary to a better node.
Before a switchover, verify that all replicas are healthy (running or streaming).
Verify that replication lag is acceptable, and notify stakeholders.
After switchover, use pg list to confirm new cluster topology.
Failover
Use failover for emergency recovery when the primary is unavailable.
It promotes a replica directly, without confirmation from the original primary.
Replicas may not be fully synchronized, so failover may cause minor data loss.
For operations that are not emergencies, use switchover.
Failover examples:
Switchover vs Failover: Switchover supports planned maintenance and requires the original primary to be online. It waits for full synchronization and prevents data loss. Failover supports emergency recovery when the original primary can be offline. It promotes a replica directly and may lose data that has not replicated. Use Switchover for routine maintenance and upgrades. Use Failover only when the primary is completely down and cannot recover.
The built-in Patroni
failoversubcommand currently has no--leaderoption. Useswitchover --leader ...to validate or name the old primary during a planned switchover. Failover accepts only the candidate replica.
Restart
Use restart to restart PostgreSQL instances, usually after changes to parameters that require a restart.
For a whole cluster, patronictl submits each selected member in turn.
It does not guarantee that replicas restart before the leader.
If this order matters, restart replicas by role first.
Then restart the leader separately.
After modifying restart-required params (shared_buffers, shared_preload_libraries, max_connections, max_worker_processes, etc.), use this command.
Reload
Use reload to reload Patroni configuration without a PostgreSQL restart.
It reads configuration files again and applies parameters through pg_reload_conf().
It causes less disruption than restart: connections and running queries continue.
Most PostgreSQL parameter changes apply through reload.
Only parameters with postmaster context require a restart, such as shared_buffers, max_connections, shared_preload_libraries, and archive_mode.
Reinit Replica
Use reinit to reinitialize a replica.
This deletes all replica data and rebuilds it in the order specified by Patroni create_replica_methods.
By default, Pigsty tries basebackup (pg_basebackup) first.
If a remote pgBackRest repository is enabled, Pigsty also configures pgbackrest as a fallback.
Use reinitialization for corrupted replica data, missing WAL after excessive lag, or a required replica configuration reset.
Warning: This operation deletes all data on the target instance. You can run it only on replicas, not on the primary.
During rebuild, use pg list to check progress. Replica state shows creating replica:
Pause
Use pause to pause Patroni automatic failover.
While paused, Patroni does not promote replicas automatically, even if the primary fails.
Pause during planned maintenance to prevent accidental failover.
You can also pause for debugging to prevent cluster state changes, or to control manual switchover timing.
Warning: While paused, the cluster will not recover automatically if the primary fails. Run
resumeafter maintenance.
Resume
Use resume to resume Patroni automatic failover.
Run it immediately after maintenance so the cluster can recover automatically from a primary failure.
History
Use history to view cluster failover history.
Each automatic or manual switchover creates a timeline record.
The history columns have these meanings:
- TL: The timeline number. It increases after each switchover to distinguish primary histories.
- LSN: The Log Sequence Number at switchover, which identifies the WAL position.
- Reason:
switchover to xxxfor a manual operation,failover to xxxfor a failure, orno recovery target specifiedfor initialization. - Timestamp: The time of the switchover.
Show Config
Use show-config to view the current cluster configuration in DCS.
This command only reads configuration.
To change it, use edit-config.
Query
Use query to run SQL quickly on cluster members during debugging.
For complex production queries, use psql or an application.
Topology
Use topology to view cluster replication topology as a tree.
It shows primary-replica relationships more clearly than list, especially for cascading replication.
For cascading replication, the topology shows the replication hierarchy.
For example, pg-test-3 replicates from pg-test-2, which replicates from the primary pg-test-1.
Version
Use version to view patronictl version.
Remove
Use remove to remove cluster or member metadata from DCS.
This operation is dangerous.
It removes only DCS metadata; it does not stop PostgreSQL or delete data files.
Incorrect use can make cluster state inconsistent.
Normally, you do not need this command.
To remove a cluster or instance, use bin/pgsql-rm or pgsql-rm.yml.
Consider remove only for orphaned DCS metadata after physical node removal, or metadata left after cluster destruction by other means.
5 - Managing PostgreSQL HBA Rules
Quick Start
Pigsty manages HBA rules declaratively.
First define HBA rules in the inventory.
Then run bin/pgsql-hba <cls> to refresh them.
For rule syntax, see HBA Configuration. For authentication methods, default boundaries, and credential management, see Authentication.
| Action | Description | Risk |
|---|---|---|
| Refresh HBA Rules | Re-render config files and reload service | Low |
| Verify HBA Rules | View current rules, test connection auth | Read |
| Common Scenarios | Add rules, block IP, role-based, post-expansion | Low |
| Troubleshooting | Connection rejected, auth failed, rules not applied | - |
| Pgbouncer HBA | Pgbouncer connection pool HBA management | Low |
demo/pgsql-hba.cast — /demo/pgsql-hba.cast
Refresh HBA Rules
After you change HBA rules in pigsty.yml, generate the configuration files again and reload the services.
Result: Pigsty generates PostgreSQL and Pgbouncer HBA configuration files from inventory definitions. It then reloads the services to apply the rules.
Config file locations
| Service | Config File Path | Template File |
|---|---|---|
| PostgreSQL | /pg/data/pg_hba.conf | roles/pgsql/templates/pg_hba.conf |
| Pgbouncer | /etc/pgbouncer/pgb_hba.conf | roles/pgsql/templates/pgbouncer.hba |
Direct changes to /pg/data/pg_hba.conf or /etc/pgbouncer/pgb_hba.conf work temporarily.
The next Ansible playbook run overwrites them.
Make all HBA rule changes in pigsty.yml, then run bin/pgsql-hba to refresh the rules.
Related Tags
| Tag | Description |
|---|---|
pg_hba | Render PostgreSQL HBA config file |
pg_reload | Reload PostgreSQL config (needs pg_reload=true) |
pgbouncer_hba | Render Pgbouncer HBA config file |
pgbouncer_reload | Reload Pgbouncer config |
Verify HBA Rules
After you refresh HBA rules, verify that the configuration applies correctly.
View current HBA rules
Check HBA config syntax
Common Scenarios
Add New HBA Rule
Add the rule to pg_hba_rules in the cluster configuration.
Then refresh the rules:
Emergency IP Block
If you detect a malicious IP address, add a deny rule with high priority (order: 0):
Role-Based Rules
Configure different HBA rules for primary and replica using role parameter:
After a refresh, the instance pg_role determines which rules are enabled.
Refresh HBA After Expansion
After you add cluster instances, refresh rules that use addr: cluster.
The refreshed rules include the new members:
Refresh HBA After Failover
After a Patroni failover, instance roles may differ from pg_role values in the configuration.
If HBA rules filter by role, update the configuration and refresh the rules:
Troubleshooting
Connection Rejected
Symptom: FATAL: no pg_hba.conf entry for host "x.x.x.x", user "xxx", database "xxx"
Steps:
- Check current HBA rules, confirm if matching rule exists:
Confirm client IP, username, database matches any rule
Check rule order (HBA uses first-match-wins)
Add corresponding rule and refresh:
Authentication Failed
Symptom: FATAL: password authentication failed for user "xxx"
Steps:
- Confirm password is correct
- Check password encryption method (
pg_pwd_enc) compatibility with client - Check if user exists:
HBA Rules Not Applied
Steps:
- Confirm refresh command was executed
- Check if Ansible execution succeeded
- Confirm PostgreSQL reloaded:
- Check if config file was updated:
Rule Order Issues
HBA uses the first matching rule. If rules do not work as expected:
- Check
ordervalues in rule definitions - Use
psql -c "TABLE pg_hba_file_rules"to view actual order - Adjust
ordervalues (lower numbers = higher priority)
Pgbouncer HBA
Pgbouncer HBA management is similar to PostgreSQL, with some differences.
Config differences
| Difference | PostgreSQL | Pgbouncer |
|---|---|---|
| Config file | /pg/data/pg_hba.conf | /etc/pgbouncer/pgb_hba.conf |
| Replication | Supports db: replication | Not supported |
| Local auth | Uses ident | Uses peer |
Refresh Pgbouncer HBA
Best Practices
- Manage rules in the inventory: Make all changes in
pigsty.yml. Do not editpg_hba.confdirectly. - Test first: Verify HBA changes in a test environment first. Changes can cause connection problems.
- Set rule priority: Use
order: 0for blocklist rules to match them first. - Refresh promptly: Refresh HBA after you add or remove instances, or after failover.
- Grant minimum access: Allow only necessary access. Avoid
addr: worldwithauth: trust. - Monitor authentication failures: Check
pg_stat_activityfor authentication failures. - Back up configuration: Back up
pigsty.ymlbefore important changes.
Related Documentation
- HBA Configuration: HBA rule config syntax and parameter details
- User Management: User and role management operations
- Access Control: Role system and permission model
- Authentication: Authentication methods, default boundaries, and credential management
- Encrypted Communication: TLS and client certificate verification
6 - Pgbouncer Connection Pooling
Overview
Pigsty uses Pgbouncer for PostgreSQL connection pooling.
By default, it listens on port 6432 and proxies connections to local PostgreSQL on port 5432.
This component is optional. If you do not need many connections, transaction pooling, or query metrics, you can disable it. You can also connect directly to the database or leave Pgbouncer unused.
User & Database Management
Pigsty automatically manages Pgbouncer users and databases. When you create databases or users, it applies the database configuration and user configuration.
Database Management: By default, Pigsty adds databases from pg_databases to Pgbouncer.
To exclude a database, set pgbouncer: false.
User Management: To add a user from pg_users to the pool user list, explicitly set pgbouncer: true.
Since Pigsty
v4.1.0, usepool_reserveandpool_connlimitfor database pool fields. These names replace the legacy aliasespool_size_reserveandpool_max_db_conn.
Service Management
By default, the PostgreSQL Primary Service and Replica Service connect to Pgbouncer on port 6432.
To connect directly to PostgreSQL, customize pg_services.
Alternatively, set pg_default_service_dest to postgres.
Config Management
Pgbouncer config files are in /etc/pgbouncer/, generated and managed by Pigsty:
| File | Description |
|---|---|
pgbouncer.ini | Main config, pool-level params |
database.txt | Database list, database-level params |
userlist.txt | User password list |
useropts.txt | User-level pool params |
pgb_hba.conf | HBA access control rules |
Pigsty automatically manages database.txt and userlist.txt.
It updates them when you create databases or users.
You can edit configuration manually, then run RELOAD to apply the changes:
Pool Management
Pgbouncer runs as the same dbsu as PostgreSQL.
The default is the postgres operating system user.
Pigsty provides the pgb alias for administration:
On database nodes, use pgb to connect to the Pgbouncer administration console.
You can then run administration commands and monitoring queries.
| Command | Function | Description |
|---|---|---|
PAUSE | Pause | Pause database, wait for txn completion then disconnect |
RESUME | Resume | Resume database paused by PAUSE/KILL/SUSPEND |
DISABLE | Disable | Reject new client connections for database |
ENABLE | Enable | Allow new client connections for database |
RECONNECT | Reconnect | Gracefully close and rebuild server connections |
KILL | Kill | Immediately disconnect all client and server connections |
KILL_CLIENT | Kill Client | Terminate specific client connection |
SUSPEND | Suspend | Flush buffers and stop listening, for online restart |
SHUTDOWN | Shutdown | Shutdown Pgbouncer process |
RELOAD | Reload | Reload config files |
WAIT_CLOSE | Wait Close | Wait for server connections to close after RECONNECT/RELOAD |
| Monitor Commands | Monitor | View pool status, clients, servers, etc. |
PAUSE
Use PAUSE to pause database connections.
Pgbouncer waits for the active transaction or session to finish, according to the pool mode.
It then disconnects server connections.
New client requests wait until RESUME.
Typical use cases:
- Online backend database switch (e.g., update connection target after switchover)
- Maintenance operations requiring all connections disconnected
- Combined with
SUSPENDfor Pgbouncer online restart
After pause, SHOW DATABASES shows paused status:
RESUME
Use RESUME to restore databases paused by PAUSE, KILL, or SUSPEND.
This allows new connections and resumes normal service.
DISABLE
Use DISABLE to reject all new client connections for a database.
Existing connections continue.
Typical use cases:
- Temporarily offline a database for maintenance
- Block new connections for safe database migration
- Gradually decommission a database being removed
ENABLE
Use ENABLE to enable a database that DISABLE stopped.
The database accepts new client connections again.
RECONNECT
Use RECONNECT to rebuild server connections gracefully.
Pgbouncer closes connections when they return to the pool.
It creates new connections as needed.
Typical use cases:
- Refresh connections after backend database IP change
- Reroute traffic after switchover
- Rebuild connections after DNS update
After RECONNECT, use WAIT_CLOSE to wait for old connections to fully release.
KILL
Use KILL to disconnect all client and server connections for a database immediately.
Unlike PAUSE, it does not wait for transactions to finish.
After KILL, new connections are blocked until RESUME.
KILL_CLIENT
Use KILL_CLIENT to terminate a specific client connection.
Get the client ID from SHOW CLIENTS.
SUSPEND
Use SUSPEND to suspend Pgbouncer.
It flushes all socket buffers and stops listening until RESUME.
SUSPEND is mainly for Pgbouncer online restart (zero-downtime upgrade):
SHUTDOWN
Use SHUTDOWN to stop the Pgbouncer process.
The command supports several shutdown modes:
| Mode | Description |
|---|---|
SHUTDOWN | Immediately shutdown Pgbouncer |
WAIT_FOR_SERVERS | Stop accepting new connections, wait for server release |
WAIT_FOR_CLIENTS | Stop accepting new connections, wait for all clients disconnect, for rolling restart |
RELOAD
Use RELOAD to read the Pgbouncer configuration files again.
It dynamically updates most parameters without a process restart.
Pigsty provides playbook task to reload Pgbouncer config:
WAIT_CLOSE
Use WAIT_CLOSE to wait until server connections finish closing.
Usually, run it after RECONNECT or RELOAD to verify that old connections have closed.
Monitoring
Pgbouncer provides these SHOW commands to monitor pool status:
| Command | Description |
|---|---|
SHOW HELP | Show available commands |
SHOW DATABASES | Show database config and status |
SHOW POOLS | Show pool statistics |
SHOW CLIENTS | Show client connection list |
SHOW SERVERS | Show server connection list |
SHOW USERS | Show user config |
SHOW STATS | Show statistics (requests, bytes) |
SHOW STATS_TOTALS | Show cumulative statistics |
SHOW STATS_AVERAGES | Show average statistics |
SHOW CONFIG | Show current config params |
SHOW MEM | Show memory usage |
SHOW DNS_HOSTS | Show DNS cached hostnames |
SHOW DNS_ZONES | Show DNS cached zones |
SHOW SOCKETS | Show open socket info |
SHOW ACTIVE_SOCKETS | Show active sockets |
SHOW LISTS | Show internal list counts |
SHOW FDS | Show file descriptor usage |
SHOW STATE | Show Pgbouncer running state |
SHOW VERSION | Show Pgbouncer version |
Common monitoring examples:
For more monitoring command details, see Pgbouncer official docs.
Unix Signals
Use Unix signals to control Pgbouncer when the administration console is unavailable:
| Signal | Equivalent Command | Description |
|---|---|---|
SIGHUP | RELOAD | Reload config files |
SIGTERM | SHUTDOWN WAIT_FOR_CLIENTS | Graceful shutdown, wait clients |
SIGINT | SHUTDOWN WAIT_FOR_SERVERS | Graceful shutdown, wait servers |
SIGQUIT | SHUTDOWN | Immediate shutdown |
SIGUSR1 | PAUSE | Pause all databases |
SIGUSR2 | RESUME | Resume all databases |
Traffic Switching
Pigsty stores managed database routes in /etc/pgbouncer/database.txt.
To move Pgbouncer traffic for one database to another node, edit this file and reload the configuration.
Then drain and rebuild the existing server connections:
The
pgb-routefunction currently shipped in the source edits only/etc/pgbouncer/pgbouncer.ini. That file includesdatabase.txtbut does not contain the generatedhost=routes for each database. Thus, the function does not change managed database backends. Use the procedure above instead.
7 - Managing PostgreSQL Component Services
Overview
The Pigsty PGSQL module has multiple components. Each component runs as a systemd service on nodes, except pgBackRest.
To maintain production PostgreSQL clusters, learn how these components work and how to manage them.
| Component | Port | Service Name | Description |
|---|---|---|---|
| Patroni | 8008 | patroni | HA manager, manages PostgreSQL lifecycle |
| PostgreSQL | 5432 | postgres | Placeholder service, not used, for emergency |
| Pgbouncer | 6432 | pgbouncer | Connection pooling middleware, traffic entry |
| PgBackRest | - | - | pgBackRest has no daemon service |
| HAProxy | 543x | haproxy | Load balancer, exposes database services |
| pg_exporter | 9630 | pg_exporter | PostgreSQL metrics exporter |
| pgbouncer_exporter | 9631 | pgbouncer_exporter | Pgbouncer metrics exporter |
| vip-manager | - | vip-manager | Optional, manages L2 VIP address floating |
Do not manage the PostgreSQL service directly with systemctl.
Patroni manages PostgreSQL. Use patronictl commands.
Direct PostgreSQL operations can make Patroni state inconsistent and trigger an unexpected failover.
Use the postgres service only for emergencies when Patroni fails.
Quick Reference
| Operation | Command |
|---|---|
| Start | systemctl start <service> |
| Stop | systemctl stop <service> |
| Restart | systemctl restart <service> |
| Reload | systemctl reload <service> |
| Status | systemctl status <service> |
| Logs | journalctl -u <service> -f |
| Enable | systemctl enable <service> |
| Disable | systemctl disable <service> |
Common service names: patroni, pgbouncer, haproxy, pg_exporter, pgbouncer_exporter, vip-manager
Patroni
Patroni manages PostgreSQL high availability. It controls startup, shutdown, failure detection, and automatic failover. It is the core component of the PGSQL module and manages the PostgreSQL process. Do not manage the postgres service directly with systemctl.
Start Patroni
After startup, Patroni automatically starts PostgreSQL. On the first startup, the instance role determines the action:
- Primary: Initialize or recover the data directory.
- Replica: Clone data from the primary and establish replication.
Stop Patroni
Stopping Patroni shuts down PostgreSQL gracefully. If the instance is the primary and automatic failover is active, this operation may trigger a failover.
Restart Patroni
A restart causes a short service interruption.
For production clusters, use pg restart for a rolling restart.
Reload Patroni
A reload reads the configuration file again. It applies parameters that PostgreSQL can change without a restart.
View Status & Logs
Config file: /etc/patroni/patroni.yml
Best Practice: Use
patronictlinstead of systemctl to manage PostgreSQL clusters.
Pgbouncer
Pgbouncer provides lightweight PostgreSQL connection pooling. Business traffic usually goes through Pgbouncer on port 6432, rather than directly to PostgreSQL on port 5432. This reuses connections and protects the database.
Start Pgbouncer
Stop Pgbouncer
Note: Stopping Pgbouncer disconnects all pooled business connections.
Restart Pgbouncer
A restart disconnects all existing connections.
To apply only configuration changes, use reload.
Reload Pgbouncer
A reload reads configuration files, such as user lists and pool parameters, again. It does not disconnect existing connections.
View Status & Logs
Config files:
- Main config:
/etc/pgbouncer/pgbouncer.ini - HBA rules:
/etc/pgbouncer/pgb_hba.conf - User list:
/etc/pgbouncer/userlist.txt - Database list:
/etc/pgbouncer/database.txt
Admin Console
Common admin commands:
HAProxy
HAProxy is a high-performance load balancer. It routes traffic to the correct PostgreSQL instances. Pigsty uses HAProxy to expose services. HAProxy routes traffic by instance role (primary or replica) and health status.
Start HAProxy
Stop HAProxy
Note: Stopping HAProxy disconnects all load-balanced connections.
Restart HAProxy
Reload HAProxy
HAProxy can reload without disconnecting existing connections.
Use reload to apply configuration changes.
View Status & Logs
Config files: The main configuration is /etc/haproxy/haproxy.cfg.
Pigsty stores generated service fragments in /etc/haproxy/conf.d/.
Admin Interface
HAProxy provides a web admin interface, default port 9101:
The default administration username is admin.
Set its password with haproxy_admin_password.
pg_exporter
pg_exporter exports PostgreSQL performance metrics for Prometheus.
Start pg_exporter
Stop pg_exporter
After you stop the exporter, Prometheus cannot collect PostgreSQL metrics from this instance.
Restart pg_exporter
View Status & Logs
Config file: /etc/pg_exporter.yml
Verify Metrics
pgbouncer_exporter
pgbouncer_exporter is Pgbouncer’s Prometheus metrics exporter.
Start/Stop/Restart
View Status & Logs
Verify Metrics
vip-manager
vip-manager is an optional component that moves an L2 VIP between nodes.
When pg_vip_enabled is enabled, vip-manager binds the VIP to the current primary node.
Start vip-manager
Stop vip-manager
After you stop vip-manager, it releases the VIP address from the current node.
Restart vip-manager
View Status & Logs
Config file: /etc/default/vip-manager
Verify VIP Binding
Startup Order & Dependencies
Recommended PGSQL module component startup order:
Stop the components in reverse order. Pigsty playbooks handle these dependencies automatically.
Batch Start All Services
Batch Stop All Services
Common Troubleshooting
Service Startup Failure
Patroni Won’t Start
| Symptom | Possible Cause | Solution |
|---|---|---|
| Can’t connect to etcd | etcd cluster unavailable | Check etcd service status |
| Data dir permission error | File ownership not postgres | chown -R postgres:postgres /pg/data |
| Port in use | Leftover PostgreSQL process | pg_ctl stop -D /pg/data or kill |
Pgbouncer Won’t Start
| Symptom | Possible Cause | Solution |
|---|---|---|
| Config syntax error | INI format error | Check /etc/pgbouncer/pgbouncer.ini |
| Port in use | Port 6432 already used | lsof -i :6432 |
| userlist.txt permissions | Incorrect file permissions | chmod 600 /etc/pgbouncer/userlist.txt |
HAProxy Won’t Start
| Symptom | Possible Cause | Solution |
|---|---|---|
| Config syntax error | Invalid main configuration or service fragment | haproxy -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d -c -q |
| Port in use | Service port conflict | lsof -i :5433 |
Related Documentation
- Patroni Management: Manage PostgreSQL HA with patronictl
- Cluster Management: Create, scale, destroy clusters
- Service Configuration: HAProxy service definition and config
- Monitoring System: PostgreSQL monitoring and alerting
8 - Manage PostgreSQL Cron Jobs
Pigsty uses crontab to schedule routine backups, transaction freezing, and reorganization of bloated tables and indexes.
Quick Reference
| Operation | Quick Command | Description |
|---|---|---|
| Configure Cron Jobs | ./pgsql.yml -t pg_crontab -l <cls> | Apply pg_crontab config |
| View Cron Jobs | crontab -l | View as postgres user |
| Physical Backup | pg-backup [full|diff|incr] | Execute backup with pgBackRest |
| Transaction Freeze | pg-vacuum [database...] | Freeze aging transactions, prevent XID wraparound |
| Bloat Maintenance | pg-repack [database...] | Online reorganize bloated tables and indexes |
For other management tasks, see: Backup Management, Monitoring System, HA Management.
Configure Cron Jobs
Use pg_crontab to configure cron jobs for the PostgreSQL database superuser.
The pg_dbsu parameter selects this user; the default is postgres.
Example Configuration
The following pg-meta configuration schedules a full backup daily at 1:00 AM.
The pg-test configuration schedules a full backup on Monday and incremental backups on other days.
Recommended Maintenance Schedule
| Task | Frequency | Timing | Description |
|---|---|---|---|
pg-backup | Daily | Early morning | Full or incremental backup, depending on business needs |
pg-vacuum | Weekly | Sunday early morning | Freeze aging transactions, prevent XID wraparound |
pg-repack | Weekly/Monthly | Off-peak hours | Reorganize bloated tables/indexes, reclaim space |
The pg-backup, pg-vacuum, and pg-repack scripts detect the current node role automatically.
They run only on the primary. Replicas exit immediately.
Thus, you can configure the same cron jobs on all nodes.
After failover, the new primary automatically continues the scheduled maintenance tasks.
Apply Cron Jobs
The pg_crontab task in pgsql.yml writes cron jobs to the default location for the operating system:
- EL (RHEL/Rocky/Alma):
/var/spool/cron/postgres - Debian/Ubuntu:
/var/spool/cron/crontabs/postgres
Each playbook execution will fully overwrite the cron job configuration.
View Cron Jobs
Execute the following command as the pg_dbsu OS user to view cron jobs:
For explanations of crontab syntax, see Crontab Guru.
pg-backup
pg-backup is the Pigsty physical backup script.
It uses pgBackRest and supports full, differential, and incremental backups.
Basic Usage
Backup Types
| Type | Parameter | Description |
|---|---|---|
| Full Backup | full | Complete backup of all data, only this backup needed for recovery |
| Differential | diff | Backup changes since last full backup, recovery needs full + diff |
| Incremental | incr | Backup changes since last any backup, recovery needs complete chain |
Execution Requirements
- Script must run on primary as postgres user
- Script auto-detects current node role, exits (exit 1) when run on replica
- Auto-retrieves stanza name from
/etc/pgbackrest/pgbackrest.conf
Common Cron Configurations
For more backup and recovery operations, see the Backup Management section.
pg-vacuum
pg-vacuum is the Pigsty transaction freeze script.
It runs VACUUM FREEZE to prevent database shutdown caused by transaction ID (XID) wraparound.
Basic Usage
Command Options
| Option | Description | Default |
|---|---|---|
-h, --help | Show help message | - |
-n, --dry-run | Dry run mode, display only | false |
-a, --age | Age threshold, tables exceeding need freeze | 100000000 |
-r, --ratio | Aging ratio threshold, full freeze if exceeded (%) | 40 |
Logic
- Check the database
datfrozenxidage. Skip the database if its age is below the threshold. - Calculate the aging page ratio: table pages above the age threshold as a percentage of all pages.
- If the aging ratio exceeds 40%, run
VACUUM FREEZE ANALYZEon the full database. - Otherwise, run
VACUUM FREEZE ANALYZEonly on tables above the age threshold.
Script sets vacuum_cost_limit = 10000 and vacuum_cost_delay = 1ms to control I/O impact.
Execution Requirements
- Script must run on primary as postgres user
- Uses file lock
/tmp/pg-vacuum.lockto prevent concurrent execution - Auto-skips
template0,template1,postgressystem databases
Common Cron Configuration
pg-repack
pg-repack is the Pigsty bloat maintenance script.
It uses the pg_repack extension to reorganize bloated tables and indexes online.
Basic Usage
Command Options
| Option | Description | Default |
|---|---|---|
-h, --help | Show help message | - |
-n, --dry-run | Dry run mode, display only | false |
-t, --table | Reorganize tables only | false |
-i, --index | Reorganize indexes only | false |
-T, --timeout | Lock wait timeout (seconds) | 10 |
-j, --jobs | Parallel jobs | 2 |
Auto-Selection Thresholds
Script auto-selects objects to reorganize based on table/index size and bloat ratio:
Table Bloat Thresholds
| Size Range | Bloat Threshold | Max Count |
|---|---|---|
| < 256MB | > 40% | 64 |
| 256MB - 2GB | > 30% | 16 |
| 2GB - 8GB | > 20% | 4 |
| 8GB - 64GB | > 15% | 1 |
Index Bloat Thresholds
| Size Range | Bloat Threshold | Max Count |
|---|---|---|
| < 128MB | > 40% | 64 |
| 128MB - 1GB | > 35% | 16 |
| 1GB - 8GB | > 30% | 4 |
| 8GB - 64GB | > 20% | 1 |
The script skips tables and indexes larger than 64GB and shows a warning. Handle these objects manually.
Execution Requirements
- Script must run on primary as postgres user
- Requires
pg_repackextension installed (installed by default in Pigsty) - Requires
pg_table_bloatandpg_index_bloatviews inmonitorschema - Uses file lock
/tmp/pg-repack.lockto prevent concurrent execution - Auto-skips
template0,template1,postgressystem databases
Normal reads and writes continue during reorganization. However, the final switch requires an AccessExclusive lock on the table, which blocks all access. For high-throughput workloads, run the script during off-peak hours or maintenance windows.
Common Cron Configuration
Use the PGCAT Database - Table Bloat panel to check database bloat. Then select tables and indexes with high bloat for reorganization.
For more details see: Managing Relation Bloat
Remove Cron Jobs
When pgsql-rm.yml removes a PostgreSQL cluster, it automatically deletes the postgres user crontab file.
Related Documentation
- Backup Management: PostgreSQL backup and recovery
- Monitoring System: PostgreSQL monitoring and alerting
- Cluster Management: Cluster creation, scaling, and teardown
- Patroni Management: HA cluster management
9 - Managing PostgreSQL Extensions
Quick Start
Pigsty provides 600 extensions. To use an extension, complete four steps: download, install, configure, and enable.
For complete extension reference, see Extensions. For available extensions, see Extension Catalog.
| Action | Command | Description |
|---|---|---|
| Download Extensions | ./infra.yml -t repo_build | Download extensions to local repo |
| Install Extensions | bin/pgsql-ext <cls> | Install extension packages on cluster |
| Configure Extensions | pg edit-config <cls> -p | Add to preload libs (requires restart) |
| Enable Extensions | psql -c 'CREATE EXT ...' | Create extension objects in database |
| Update Extensions | ALTER EXTENSION UPDATE | Update packages and extension objects |
| Remove Extensions | DROP EXTENSION | Drop extension objects, uninstall pkgs |
demo/pgsql-ext.cast — /demo/pgsql-ext.cast
Install Extensions
During PostgreSQL cluster creation, the pg_extension task automatically installs extensions from pg_extensions.
To install extensions on an existing cluster, add them to all.children.<cls>.pg_extensions.
Then run:
Example: Install PostGIS, TimescaleDB and PGVector on cluster
Result: Pigsty installs extension packages on all cluster nodes. It translates package aliases to package names for the operating system and PostgreSQL version.
Before installation, verify that the nodes have the correct software repositories. Download extensions to the local repository or configure upstream repositories.
Manual Install
To install extensions without managing them in Pigsty configuration, pass the extension list on the command line:
You can also use the pig package manager CLI to install extensions on one node. It resolves package aliases automatically.
You can also use the operating system package manager directly (apt/dnf).
You must know the exact RPM or DEB package name for your operating system and PostgreSQL version:
Download Extensions
Before installation, verify that the node can get the extension from its software repositories:
- Standalone installation: The node already has the upstream repositories.
- Offline installation: The offline package contains most extensions. A few require online installation.
- Production deployment on multiple nodes with a local repository: The extension may already be downloaded. This applies if
repo_packagesorrepo_extra_packagesincluded it when you created the repository. Otherwise, download it first or configure upstream repositories for online installation.
The default Pigsty configuration downloads common extensions during installation.
For additional extensions, add them to repo_extra_packages and rebuild the repository:
Configure Repos
You can configure all nodes to install directly from upstream extension repositories. This skips the local download step. It is not recommended for production:
Configure Extensions
Some extensions must be in shared_preload_libraries.
Changes to this parameter require a database restart.
Use pg_libs to set the default list of preload extensions.
This value applies only during cluster initialization.
Changes to this value have no effect after initialization.
For existing clusters, refer to Modify Config to modify shared_preload_libraries:
Before you add preload configuration, verify that the extension packages are installed correctly.
If an extension in shared_preload_libraries is missing or cannot load, PostgreSQL will not start.
Manage cluster configuration changes through Patroni.
Avoid ALTER SYSTEM or pg_parameters for separate instance configuration changes.
Different primary and replica configurations can cause startup failure or interrupt replication.
Enable Extensions
After you install the packages, run CREATE EXTENSION in the database to enable extension features.
Enable during cluster init
Declare extensions to enable in database definition via extensions array:
Manual enable
Result: Pigsty creates extension objects in the database, such as functions, types, operators, and index methods. You can then use the extension features.
Update Extensions
Extension updates involve two layers: package update and extension object update.
Update packages
Update extension objects
Back up the database before you update extensions. Preloaded extensions may require a PostgreSQL restart after an update. Some version upgrades may be incompatible. Check the extension documentation.
Remove Extensions
Removing extensions involves two layers: drop extension objects and uninstall packages.
Drop extension objects
Remove from preload
For preloaded extensions, remove from shared_preload_libraries and restart:
Uninstall packages (optional)
CASCADE also deletes all objects that depend on the extension, such as tables, indexes, and views.
Check dependencies before you run the command.
Query Extensions
Common SQL queries for extension info:
View enabled extensions
View available extensions
Check if extension is available
View extension dependencies
View extension objects
psql shortcuts
Add Repos
To install directly from upstream, manually add repos.
Using Pigsty playbook
YUM repos (EL systems)
APT repos (Debian/Ubuntu)
FAQ
Difference between extension name and package name
| Name | Description | Example |
|---|---|---|
| Extension name | Name used with CREATE EXTENSION | vector |
| Package alias | Standardized name in Pigsty config | pgvector |
| Package name | Actual OS package name | pgvector_18* or postgresql-18-pgvector |
Preloaded extension prevents startup
If an extension in shared_preload_libraries is missing or cannot load, PostgreSQL will not start.
Use one of these solutions:
- Ensure extension package is correctly installed
- Or remove extension from
shared_preload_libraries(edit/pg/data/postgresql.conf)
Extension dependencies
Some extensions depend on other extensions.
Create the dependencies first, or use CASCADE:
Extension version incompatibility
View extension versions supported by current PostgreSQL:
Related Resources
- Extensions: Detailed extension management documentation
- Extension Catalog: Browse 600 available extensions
- pig Package Manager: Extension installation CLI tool
- Database Management: Enable extensions in databases
10 - Upgrading PostgreSQL Major/Minor Versions
Quick Start
PostgreSQL has two types of version upgrade: minor and major. Their risk and complexity differ substantially.
| Type | Example | Downtime | Data Compatibility | Risk |
|---|---|---|---|---|
| Minor upgrade | 17.2 → 17.3 | Seconds (rolling) | Fully compatible | Low |
| Major upgrade | 17 → 18 | Minutes | Requires data dir upgrade | Medium |
For detailed online migration process, see Online Migration documentation.
| Action | Description | Risk |
|---|---|---|
| Minor Version Upgrade | Update packages, rolling restart | Low |
| Minor Version Downgrade | Rollback to previous minor version | Low |
| Major Version Upgrade | Logical replication or pg_upgrade | Medium |
| Extension Upgrade | Upgrade extension packages and objects | Low |
Minor Version Upgrade
Minor version upgrades, such as 17.2 → 17.3, are the most common upgrade type. They usually contain security patches and bug fixes. The data directory remains fully compatible. Apply the upgrade with a rolling restart.
Strategy: Use a rolling upgrade to minimize service interruption. Upgrade replicas first. Then switch the primary role and upgrade the original primary.
Step 1: Prepare packages
Verify that the local software repository has the latest PostgreSQL packages. Then refresh the node package cache:
Step 2: Upgrade replicas
Upgrade packages on all replicas and verify version:
Restart all replicas to apply new version:
Step 3: Switchover
Execute switchover to transfer primary role to upgraded replica:
Step 4: Upgrade original primary
The original primary is now a replica. Upgrade its packages and restart it:
Step 5: Verify
Confirm all instances have consistent version:
Minor Version Downgrade
In rare cases, you may need to return to the previous PostgreSQL version. For example, the new version may introduce bugs.
Step 1: Get old version packages
Step 2: Execute downgrade
Step 3: Restart cluster
Major Version Upgrade
Major version upgrades, such as 17 → 18, change the data format. They require specialized data migration tools.
| Method | Downtime | Complexity | Use Case |
|---|---|---|---|
| Logical Replication Migration | Seconds (switch) | High | Production, minimal downtime required |
| pg_upgrade In-Place Upgrade | Minutes~Hours | Medium | Test env, smaller data |
For production, use logical replication migration. Create a cluster with the new version and synchronize data through logical replication. Then switch traffic from the old cluster to the new cluster. This gives the shortest downtime and supports rollback. See Online Migration.
Logical Replication Migration
Logical replication is the recommended approach for production major version upgrades. Core steps:
Step 1: Create new version cluster
Step 2: Configure logical replication
Step 3: Wait for sync completion
Step 4: Switch traffic
After you verify that data synchronization is complete, stop application writes to the source. Wait for final synchronization, then move application connections to the new cluster. Drop the subscription and decommission the source:
For detailed migration process, see Online Migration documentation.
pg_upgrade In-Place Upgrade
pg_upgrade is the official PostgreSQL tool for major version upgrades.
Use it for test environments or when longer downtime is acceptable.
An in-place upgrade causes longer downtime and is difficult to roll back. For production, prefer logical replication migration.
Step 1: Install new version packages
Step 2: Stop Patroni
Step 3: Run pg_upgrade
Step 4: Update links and start
Step 5: Post-processing
Extension Upgrade
When you upgrade PostgreSQL, you usually also need to upgrade its extensions.
Upgrade extension packages
Upgrade extension objects
After package upgrade, execute extension upgrade in database:
Before a major version upgrade, verify that all extensions support the target PostgreSQL version. Some extensions may require removal and reinstallation. Check the extension documentation.
Important Notes
- Back up first: Make a complete backup before every upgrade.
- Test first: Verify the upgrade procedure in a test environment.
- Check extensions: Verify that all extensions support the target version.
- Plan rollback: Prepare a rollback plan, especially for major upgrades.
- Monitor closely: Monitor database performance and error logs after the upgrade.
- Keep records: Record all operations and problems during the upgrade.
Related Documentation
- Online Migration: Zero-downtime migration using logical replication
- Patroni Management: Manage cluster with patronictl
- Cluster Management: Cluster creation, scaling, destruction
- Backup Recovery: PostgreSQL backup and recovery
- Extension Management: Extension installation and management