Read PostgreSQL Cluster Control Data Without Changing the Cluster
You will finish with a safe way to inspect PostgreSQL's cluster-wide control data, including WAL and checkpoint information, and a clear diagnosis when the command cannot read the data directory. This guide uses the installed PostgreSQL 16.15 utility, packaged here as pg_controldata (PostgreSQL) 16.15 (Ubuntu 16.15-0ubuntu0.24.04.1).
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes. You need a shell, the pg_controldata binary, and read access as the user who initialised the cluster. The command is read-only: it does not start PostgreSQL, force a checkpoint, edit configuration or repair control data.
1. Confirm the installed interface
Check the utility before pointing it at a real cluster:
$ /usr/lib/postgresql/16/bin/pg_controldata --version
pg_controldata (PostgreSQL) 16.15 (Ubuntu 16.15-0ubuntu0.24.04.1)
$ /usr/lib/postgresql/16/bin/pg_controldata --help
pg_controldata displays control information of a PostgreSQL database cluster.
The executable may already be on your PATH; command -v pg_controldata tells you where. The installed command accepts a data directory either as the final argument or through -D/--pgdata. It also supports -V/--version and -?/--help.
Checkpoint
Record the version. PostgreSQL utilities are versioned with the server family, and the fields and wording in their output can differ between major releases.
2. Identify the correct data directory
pg_controldata needs the cluster directory, not a database name, socket directory or parent directory containing several clusters. A valid directory contains the cluster's PG_VERSION file. If your service definition sets PGDATA, inspect that value without changing it:
$ printf 'PGDATA=%s\n' "${PGDATA:-<not set>}"
$ test -n "${PGDATA:-}" && printf 'PG_VERSION=%s\n' "$(cat "$PGDATA/PG_VERSION")"
When PGDATA is unset, pass the directory explicitly. Replace the placeholder below with the directory belonging to the cluster you intend to inspect:
$ /usr/lib/postgresql/16/bin/pg_controldata \
--pgdata=/path/to/postgresql/data
Do not guess between similarly named directories. Check the service configuration or the cluster owner first. On a Debian or Ubuntu installation, the directory is often beneath /var/lib/postgresql/<major>/, but that is a convention, not a promise.
3. Print the control data
Run the command as the operating-system user that initialised the cluster:
$ /usr/lib/postgresql/16/bin/pg_controldata \
--pgdata=/path/to/postgresql/data
Expected output is a labelled report containing values such as the PostgreSQL catalogue version, database system identifier, timeline, WAL segment size, checkpoint location and checkpoint timestamp. The exact values depend on the cluster, so do not copy a report from another machine into an incident record as if it were local evidence.
This is cluster-wide metadata. It does not describe one database, table or query. It is useful when recording the state of a cluster before an investigation, comparing control information with WAL files, or checking which timeline and checkpoint state a data directory reports.
Checkpoint
Save the command, timestamp and directory alongside the output. The output is a snapshot, not a live monitor, and a later checkpoint or recovery event can change relevant fields.
4. Use PGDATA when it is deliberate
If the environment already identifies the intended cluster, the short form avoids repeating the path:
$ PGDATA=/path/to/postgresql/data \
/usr/lib/postgresql/16/bin/pg_controldata
This assignment applies only to that command. It does not configure PostgreSQL or alter the shell's persistent environment. A separately exported value also works:
$ export PGDATA=/path/to/postgresql/data
$ /usr/lib/postgresql/16/bin/pg_controldata
Afterward, remove the temporary shell setting if it could make later PostgreSQL commands target the wrong cluster:
$ unset PGDATA
The manpage also documents an environment setting for diagnostic message colour. It accepts always, auto or never and does not change the control data itself. If a script needs predictable diagnostics, set that environment value to never for the invocation.
5. Diagnose failures without making changes
Capture the exit status immediately if a run fails:
$ /usr/lib/postgresql/16/bin/pg_controldata --pgdata=/path/to/postgresql/data
$ status=$?
$ printf 'pg_controldata exit status: %s\n' "$status"
The common causes are a wrong path, a directory that is not a PostgreSQL cluster, or insufficient read permission. Check those facts directly:
$ test -d /path/to/postgresql/data && echo 'directory exists'
$ test -r /path/to/postgresql/data/PG_VERSION && echo 'PG_VERSION is readable'
$ id
$ stat -c 'owner=%U group=%G mode=%A' /path/to/postgresql/data
A failure does not justify running the command as root by default. First correct the path or run it as the cluster owner. If your operational policy permits an elevated read-only check, use the smallest scoped command and record that it ran with sudo:
$ sudo -u POSTGRES_OWNER /usr/lib/postgresql/16/bin/pg_controldata \
--pgdata=/path/to/postgresql/data
Replace POSTGRES_OWNER with the actual owner. Do not put a password, access token or other secret in the path or in a command copied into an issue. Never point this utility at a directory you are considering deleting or restoring until its identity is verified.
6. Keep the result in context
pg_controldata reports what is stored in the control file. It is not a substitute for PostgreSQL logs, a SQL query, a server-readiness check, or a backup verification. A plausible report proves that this user could read this directory; it does not prove that the server is running, accepting connections, or that every WAL file is present.
Do not edit the control file when a value looks surprising. Control-file repair or WAL recovery is a high-risk, service-disrupting operation and belongs to a documented recovery procedure with a verified backup. This guide makes no state-changing call, so undo is simply to leave the cluster untouched and discard any temporary PGDATA assignment with unset PGDATA.
Done means
- You confirmed the installed
pg_controldataversion and supported options. - You identified the intended cluster directory and checked its readable
PG_VERSION. - You ran the utility as the cluster owner, using
-Dor an intentionalPGDATAvalue. - You recorded the report as a point-in-time, cluster-wide observation.
- You diagnosed path and permission errors before considering any elevated command.
- You changed no PostgreSQL files, settings, services or recovery state.