postgresql #235

Supports: focal bionic xenial


PostgreSQL is a powerful, open source object-relational database system. It has more than 15 years of active development and a proven architecture that has earned it a strong reputation for reliability, data integrity, and correctness. It is fully ACID compliant, has full support for foreign keys, joins, views, triggers, and stored procedures (in multiple languages). It includes most SQL:2008 data types, including INTEGER, NUMERIC, BOOLEAN, CHAR, VARCHAR, DATE, INTERVAL, and TIMESTAMP. It also supports storage of binary large objects, including pictures, sounds, or video. It has native programming interfaces for C/C++, Java, .Net, Perl, Python, Ruby, Tcl, ODBC, among others, and exceptional documentation (


excerpt from

PostgreSQL is a powerful, open source object-relational database system. It has more than 15 years of active development and a proven architecture that has earned it a strong reputation for reliability, data integrity, and correctness. It is fully ACID compliant, has full support for foreign keys, joins, views, triggers, and stored procedures (in multiple languages). It includes most SQL:2008 data types, including INTEGER, NUMERIC, BOOLEAN, CHAR, VARCHAR, DATE, INTERVAL, and TIMESTAMP. It also supports storage of binary large objects, including pictures, sounds, or video. It has native programming interfaces for C/C++, Java, .Net, Perl, Python, Ruby, Tcl, ODBC, among others, and exceptional documentation.

An enterprise class database, PostgreSQL boasts sophisticated features such as Multi-Version Concurrency Control (MVCC), point in time recovery, tablespaces, asynchronous replication, nested transactions (savepoints), online/hot backups, a sophisticated query planner/optimizer, and write ahead logging for fault tolerance. It supports international character sets, multibyte character encodings, Unicode, and it is locale-aware for sorting, case-sensitivity, and formatting. It is highly scalable both in the sheer quantity of data it can manage and in the number of concurrent users it can accommodate. There are active PostgreSQL systems in production environments that manage in excess of 4 terabytes of data.


This charm can deploy a single standalone PostgreSQL unit, or a service containing a single master unit and one or more replicas.

To setup a single 'standalone' service:

juju deploy postgresql pg-a

Scale Out Usage

To add a replica to an existing service:

juju add-unit pg-a

To deploy a new service containing a master and two hot standby replicas:

juju deploy -n 3 postgresql pg-b

You can remove units as normal. If the master unit is removed, failover occurs and the most up to date hot standby is promoted to the master. The 'db-relation-changed' and 'db-admin-relation-changed' hooks are fired, letting clients adjust:

juju remove-unit pg-b/0

To setup a client using a PostgreSQL database, in this case a vanilla Django installation listening on port 8080:

juju deploy postgresql
juju deploy python-django
juju deploy gunicorn
juju add-relation python-django postgresql:db
juju add-relation python-django gunicorn
juju expose python-django

Interacting with the PostgreSQL Service

Client Charms

Python client charms should be composed using interface:pgsql, which provides an easy way of navigating the complexities of the client interface. See for details.

The PostgreSQL charm provides two client relations. The db relation provides a normal account to the requested database. The database may be shared with other Juju Applications, allowing data to be shared. The db-admin relation provides administrative access to all databases on the PostgreSQL units.

Note that due to the asynchronous nature of Juju and the relation model, you may be provided connection strings to PostgreSQL units that are not yet ready to accept connections from your client. Your charm and application should handle connection failures and retry later, like it would any other network outage.

Non-Python Client Charms

Your charm may optionally set the following attributes on the db and db-admin relations in the relation-joined hook:

  • database - The requested database name
  • roles - A comma separated list of PostgreSQL roles to grant this relation's user. Roles will be created if they do not already exist.
  • extensions - A comma separated list of PostgreSQL extensions to install into the requested database.

The PostgreSQL units will eventually provide the following attributes on the db and db-admin relations:

  • master - The libpq connection string to the master database
  • standbys - A newline-separated list of libpq connection strings to the standby databases. This will be empty if there is only a single master unit.

Database Permissions and Disaster Recovery

⚠ These two topics are entwined, because failing to follow best practice with your database permissions will make your life difficult when you need to recover after failure.

PostgreSQL has comprehensive database security, including ownership and permissions on database objects. By default, any objects a client service creates will be owned by a user with the same name as the client service and inaccessible to other users. To share data, it is best to create new roles, grant the relevant permissions and object ownership to the new roles and finally grant these roles to the users your services can connect as. This also makes disaster recovery easier. If you restore a database into an identical Juju environment, then the service names and usernames will be the same and database permissions will match. However, if you restore a database into an environment with different client service names then the usernames will not match and the new users not have access to your data.

Learn about the SQL GRANT statement in the excellent PostgreSQL reference guide.


PostgreSQL dumps, such as those that can be scheduled in the charm, can be recovered on a new unit by using 'juju ssh' to connect to the new unit and using the standard PostgreSQL pg_restore(1) tool. This new unit must be standalone, or the master unit. Any hot standbys will replicate the recovered data from the master.

You will need to use pg_restore(1) with the --no-owner option, as users that existed in the old service will not exist in the new service.


If you had configured WAL-E, you can recover a WAL-E backup and replay to a point in time of your choosing using the wal-e tool. This will recover the whole database cluster, so all databases will be replaced.

If there are any hot standby units, they will need to be destroyed and recreated after the PITR recovery.

Point In Time Recovery

The PostgreSQL charm has support for log shipping and point in time recovery using the wal-e2 tool. This feature requires access to either Amazon S3 (or compatible storage), Microsoft Azure Block Storage, Swift or the local file system. GCE support is available in wal-e, but not yet enabled in the charm.

/!\ It has only been tested with Swift, and other cloud storage should be considered experimental. Please let me know if it works for you with other providers.

The charm can be configured to perform regular filesystem backups and ship WAL files to the object store. Hot standbys will make use of the archived WAL files, allowing them to resync after extended netsplits or even let you turn off streaming replication entirely.

With a base backup and the WAL archive you can perform point in time recovery, but this is still a manual process and the charm does not yet help you do it. The simplest approach would be to create a new PostgreSQL service containing a single unit, 'juju ssh' in and use wal-e to replace the database after shutting it down, create a recovery.conf to replay the archived WAL files using wal-e, restart the database and wait for it to recover. Once recovered, new hot standby units can be added and client services related to the new database service.

To enable the experimental wal-e support with Swift, you will need to and set the service configuration settings similar to the following:

    wal_e_storage_uri: swift://mycontainer
    os_username: my_swift_username
    os_password: my_swift_password
    os_tenant_name: my_tenant_name

Development and Contributions

The PostgreSQL Charm is maintained on Launchpad4 using git. The 'master' branch is a Reactive Framework Layer, and generates a deployable Charm using the 'charm build' command provided by charm-tools.

The latest stable source layer is in the 'master' branch in the git+ssh:// repository. Merge proposals should be made against the 'master' branch. Do not make merge proposals against the old Bazaar branches or the 'built' branch.


Bug reports can be made at Queries can be made in any of the major Juju forums, such as the main Juju mailing list or the #juju channel on Freenode IRC.

Latest Stable

The latest tested, stable release of this charm can be found at and deployed with juju using the URI cs:postgresql. It is also available as the 'built' git branch in the git+ssh:// repository:

git clone -b built \ postgresql
juju deploy ./postgresql



(string) A comma-separated list of IP Addresses (or single IP) admin tools like pgAdmin3 will connect from. The IP addresses added here will be included in the pg_hba.conf file allowing ip connections to all databases on the server from the given IP addresses using md5 password encryption. IP address ranges are also supported, using the standard format described in the PostgreSQL reference guide.
(int) DEPRECATED and ignored.
(string) DEPRECATED. Use extra_pg_conf.
(boolean) DEPRECATED. Use extra_pg_conf.
(boolean) DEPRECATED. Use extra_pg_conf.
(float) DEPRECATED. Use extra_pg_conf.
(int) DEPRECATED. Use extra_pg_conf.
(string) DEPRECATED. Use extra_pg_conf.
(float) DEPRECATED. Use extra_pg_conf.
(string) EXPERIMENTAL. Amazon AWS access key id.
(string) EXPERIMENTAL. Amazon AWS region (eg. us-east-1)
(string) EXPERIMENTAL. Amazon AWS secret access key.
(string) Directory to place backups in.
(int) Number of backups to retain.
(string) Cron-formatted schedule for regular database backups.
13 4 * * *
(float) DEPRECATED. Use extra_pg_conf.
(int) DEPRECATED. Use extra_pg_conf.
(string) DEPRECATED. Use extra_pg_conf.
(int) DEPRECATED. Use extra_pg_conf.
(int) DEPRECATED. Use extra_pg_conf.
(string) DEPRECATED. Use extra_pg_conf.
(string) Default encoding used to store text in this service. Can only be set when deploying the first unit of a service.
(string) DEPRECATED. Use extra_packages.
(string) Space separated list of extra deb packages to install.
(string) A extra pg_hba.conf auth rules. This will be included as-is into the pg_hba.conf file. Note that this should not be needed as db relations already create those rules the right way. Use this feature to allow clients to connect from outside the environment, or to configure replication between unrelated PostgreSQL services using the manual_replication option.
(string) postgresql.conf settings, one per line in standard key=value PostgreSQL format. These settings will generally override any values selected by the charm. The charm however will attempt to ensure minimum requirements for the charm's operation are met.
# Additional service specific postgresql.conf settings. listen_addresses='*' ssl=true # log_timezone=UTC Bug #1580331 log_checkpoints=true log_connections=true log_disconnections=true log_autovacuum_min_duration=-1 log_line_prefix='%t [%p]: [%l-1] db=%d,user=%u ' archive_mode=on archive_command='/bin/true' hot_standby=true max_wal_senders=10 # max_wal_senders=num_units * 2 + 5 # wal_level=hot_standby (<9.4) or logical (>=9.4) # shared_buffers=total_ram*0.25 # effective_cache_size=total_ram*0.75 default_statistics_target=250 from_collapse_limit=16 join_collapse_limit=16 wal_buffers=-1 checkpoint_completion_target=0.9 # password_encryption=true max_connections=100
(boolean) DEPRECATED. Use extra_pg_conf.
(boolean) DEPRECATED. Use extra_pg_conf.
(boolean) DEPRECATED. Use extra_pg_conf.
(boolean) DEPRECATED. Use extra_pg_conf.
(int) Terminate transactions that have been idle more than this many seconds. While this may seem harsh, in most environments it is preferable to allowing them to create database bloat and hold locks needed by well behaved transactions. Set to 0 to disable.
(string) List of signing keys for install_sources package sources, per charmhelpers standard format (a yaml list of strings encoded as a string). The keys should be the full ASCII armoured GPG public keys. While GPG key ids are also supported and looked up on a keyserver, operators should be aware that this mechanism is insecure. null can be used if a standard package signing key is used that will already be installed on the machine, and for PPA sources where the package signing key is securely retrieved from Launchpad.
(string) List of extra apt sources, per charm-helpers standard format (a yaml list of strings encoded as a string). Each source may be either a line that can be added directly to sources.list(5), or in the form ppa:<user>/<ppa-name> for adding Personal Package Archives, or a distribution component to enable.
(int) DEPRECATED and ignored.
(int) DEPRECATED and ignored.
(int) DEPRECATED. Use extra_pg_conf.
(string) Locale of service, defining language, default collation order, and default formatting of numbers, currency, dates & times. Can only be set when deploying the first unit of a service.
(int) DEPRECATED. Use extra_pg_conf.
(boolean) DEPRECATED. Use extra_pg_conf.
(boolean) DEPRECATED. Use extra_pg_conf.
(boolean) DEPRECATED. Use extra_pg_conf.
(string) DEPRECATED. Use extra_pg_conf.
%t [%p]: [%l-1] db=%d,user=%u
(boolean) DEPRECATED. Use extra_pg_conf.
(int) DEPRECATED. Use extra_pg_conf.
(string) DEPRECATED. Use extra_pg_conf.
(string) DEPRECATED. Use extra_pg_conf.
(string) DEPRECATED. Use extra_pg_conf.
(boolean) Enable or disable charm managed replication. When manual_replication is True, the operator is responsible for maintaining recovery.conf and performing any necessary database mirroring. The charm will still advertise the unit as standalone, master or hot standby to relations based on whether the system is in recovery mode or not. Note that this option makes it possible to create a PostgreSQL service with multiple master units, which is a very silly thing to do unless you are also using multi-master software like BDR.
(int) DEPRECATED. Use extra_pg_conf.
(int) DEPRECATED. Use extra_pg_conf.
(int) DEPRECATED. Use extra_pg_conf.
(string) Prefix for metrics. Special value $UNIT can be used to include the name of the unit in the prefix.
(int) Period for metrics cron job to run in minutes
(string) Destination for statsd-format metrics, format "host:port". If not present and valid, metrics disabled.
(string) Used by the nrpe subordinate charms. A string that will be prepended to instance name to set the host name in nagios. So for instance the hostname would be something like: juju-myservice-0 If you're running multiple environments with the same services in them this allows you to differentiate between them.
(string) A comma-separated list of nagios servicegroups. If left empty, the nagios_context will be used as the servicegroup
(string) OpenStack Swift authentication URL.
(string) OpenStack authentication protocol version.
(string) OpenStack Swift password.
(string) OpenStack Swift domain name or ID containing project.
(string) OpenStack Swift project name.
(string) OpenStack Swift authentication region name.
(string) OpenStack Swift tenant name.
(string) OpenStack Swift domain name or ID containing user.
(string) OpenStack Swift username.
(string) The status of service-affecting packages will be set to this value in the dpkg database. Valid values are "install" and "hold".
(string) DEPRECATED AND IGNORED. The pgtune project has been abandoned and the packages dropped from Debian and Ubuntu. The charm still performs some basic tuning, which users can tweak using extra_pg_config.
(boolean) Enable the PostgreSQL Global Development Group APT repository ( This package source provides official PostgreSQL packages for Ubuntu LTS releases beyond those provided by the main Ubuntu archive.
(float) DEPRECATED. Use extra_pg_conf.
(string) A comma-separated list of database privileges to grant to relation users on their databases. The defaults allow to connect to the database (CONNECT), create objects such as tables (CREATE), and create temporary tables (TEMPORARY). Client charms that create objects in the database are responsible to granting suitable access on those objects to other roles and users (or PUBLIC) using standard GRANT statements.
(int) DEPRECATED. Use extra_pg_conf.
(string) DEPRECATED. Use extra_pg_conf.
(string) DEPRECATED. Use extra_pg_conf.
(string) How often snapd handles updates for installed snaps. The default (an empty string) is 4x per day. Set to "max" to check once per month based on the charm deployment date. You may also set a custom string as described in the 'refresh.timer' section here:
(string) DEPRECATED. Use extra_pg_conf.
(boolean) DEPRECATED. Use extra_pg_conf.
(boolean) Enable streaming replication. Normally, streaming replication is always used, and any log shipping configured is used as a fallback. Turning this off without configuring log shipping is an error.
(boolean) DEPRECATED. Use extra_pg_conf.
(string) DEPRECATED. Use extra_pg_conf.
(string) Version of PostgreSQL that we want to install. Supported versions are "9.5", "9.6", "10", "11" & "12". The default version for the deployed Ubuntu release is used when the version is unspecified.
(string) EXPERIMENTAL. Windows Azure access key.
(string) EXPERIMENTAL. Windows Azure account name.
(int) How many seconds the oldest un-uploaded WAL database backup can be before the Nagios check will issue a critical error.
(int) How many seconds the oldest un-uploaded WAL database backup can be before the Nagios check will issue a warning.
(string) DEPRECATED. Use extra_pg_conf.
(int) Number of recent base backups and WAL files to retain. You need enough space for this many backups plus one more, as an old backup will only be removed after a new one has been successfully made to replace it.
(string) Cron-formatted schedule for WAL-E database backups. If wal_e_backup_schedule is unset, WAL files will never be removed from WAL-E storage.
13 0 * * *
(string) Specify storage to be used by WAL-E. Every PostgreSQL service must use a unique URI. Backups will be unrecoverable if it is not unique. The URI's scheme must be one of 'swift' (OpenStack Swift), 's3' (Amazon AWS), 'wabs' (Windows Azure) or a local folder. For example: 'swift://some-container/directory/or/whatever' 's3://some-bucket/directory/or/whatever' 'wabs://some-bucket/directory/or/whatever' 'file://localhost/backups/pg' Setting the wal_e_storage_uri enables regular WAL-E filesystem level backups (per wal_e_backup_schedule), and log shipping to the configured storage. Point-in-time recovery becomes possible, as is disabling the streaming_replication configuration item and relying solely on log shipping for replication.
(int) DEPRECATED. Use extra_pg_conf.
(string) DEPRECATED. Use extra_pg_conf.
(string) DEPRECATED. Use extra_pg_conf.