Skip to content

postgresql

PostgreSQL: an application controller type, version 1. A controller of this type is written under controllers.application with type: postgresql.

Its connectivity test identifies the system it reaches by postgres:<system identifier>@<host>:<port>: the system identifier names the cluster, which a primary and its standbys share, so that a second controller for the same system is warned of.

Connection

In the controller’s connection:

  • host (string, required): the server’s name or address, reached over SQL from the site’s orchestrators
  • port (int, default 5432): the server’s port
  • database (string, default postgres): the database qfence’s own connection uses for what concerns the whole server: replication state, settings, the list of databases
  • server_certificate_sha256 (string): the SHA-256 fingerprint of the certificate the server presents, pinned at registration: the connectivity test shows it until it is set. TLS is required
  • next_server_certificate_sha256 (string): the SHA-256 fingerprint of the certificate that will replace the pinned one, trusted as it is: pin it before the server changes certificates, so the change leaves no gap
  • cluster_manager (string, default none, one of none, patroni, repmgr): the cluster manager that runs this server, if any. Where one runs, qfence only observes: it never fences or promotes a server a manager would undo or race (ADR 0013 §5)
  • connect_timeout (duration, default 10s): how long connecting and the TLS handshake may take; each call is bounded by its own deadline
  • max_connections (int, default 2): connections qfence keeps open to each database it uses; more calls wait within their deadline

Auth methods

The controller’s auth.method is one of these. A field marked secret comes only from the secret auth.credentials_ref names; the others are set in auth.config, or in that secret.

basic

A role and its password, sent only over the pinned TLS connection. The role is never superuser (ADR 0013 §7).

  • username (string, required): the role qfence logs in as, e.g. qfence
  • password (string, required, secret)

mtls

A role and the client certificate it logs in with (pg_hba.conf method cert). The role is never superuser (ADR 0013 §7).

  • username (string, required): the role qfence logs in as, e.g. qfence
  • tls_cert (pem, required, secret)
  • tls_key (pem, required, secret)

Capabilities

The controller enables each it uses in its capabilities list.

db.health

Run the binding’s query in a read-only transaction in the database: HEALTHY when it succeeds, and at the owner site only on a writable primary; UNHEALTHY when the server refuses or fails it, or at the owner is read-only or in recovery; UNKNOWN when the server does not answer.

Category: observation; bound as health; resource database.

Per binding, in its params:

  • query (string, default select 1): one SQL statement, run in a read-only transaction: it passes when it runs without an error

Validation checks: tls.pinned, privileges.

replica.lag

Ready while the server is a standby and its lag, counted from what the primary last reported, is within max_replication_lag. Once the primary is gone the lag keeps growing from its last message: the bound on what a promotion could lose. Lag that cannot be read is not ready. The binding’s database only names the server.

Category: observation; bound as readiness; resource database.

Per binding, in its params:

  • max_replication_lag (duration, required): the most lag that still allows promotion, e.g. 30s

Validation checks: tls.pinned, privileges, rewind-ready, same-cluster, wal-receiver-timeout.

db.readonly

Make the server refuse writes: default_transaction_read_only on in its configuration (ALTER SYSTEM, then a reload), and every application session ended. FENCED while that holds and no application session holds a transaction ID; it survives a restart. Unfence resets it. Soft: a session can still BEGIN READ WRITE until the server stops, so it never proves a site. Withdrawn where a cluster manager runs. The binding’s database only names the server.

Category: actuator; bound as fence; fencing level application; resource database.

Validation checks: tls.pinned, privileges, no-cluster-manager.

db.promote

Promote the standby with pg_promote, waiting for it, then reset any read-only setting it inherited. Refused unless its lag, measured as replica.lag measures it, is within max_replication_lag or the data loss an operator accepted for this failover; a server already promoted reports success. Withdrawn where a cluster manager runs. The binding’s database only names the server.

Category: actuator; bound as switchover; resource database.

Per binding, in its params:

  • max_replication_lag (duration, required): the most lag that still allows promotion, as for replica.lag, e.g. 30s

Strategies, which a binding picks with its strategy param:

  • graceful: make the old primary read-only and verify it, wait until this standby has replayed every byte of its WAL, then fence it and promote: no committed transaction is lost
  • fence-then-promote: fence the old primary and promote, as a failover does

Validation checks: tls.pinned, privileges, no-cluster-manager.

databases.list

The server’s databases that accept connections, by name, with their owner.

Category: discovery; resource database.

Validation checks: tls.pinned.

Addresses

Every address the type contacts. A secret’s scope (-scope-host) is checked against each that receives credentials.

  • connection.host (port connection.port, receives credentials): the server, over SQL