Query the PostgreSQL Configuration
Your PostgreSQL Configuration
PostgreSQL 12 finished a set of SQL functions that list the contents of the server's own directories: pg_ls_waldir() and pg_ls_logdir() arrived in version 10, and pg_ls_archive_statusdir() and pg_ls_tmpdir() followed in 12. Combined with current_setting() for the paths themselves, a single session can report where the configuration files, data directory, sockets, logs and WAL live, and what is inside them, without shell access to the host.
Purpose and Overview
On a server you did not build, the first questions are usually about location. Which postgresql.conf is the running server reading? Where is pg_hba.conf? Is the data directory on the volume that backups cover? Where do the logs go, and what is the name of the log file being written right now? Packaged installs, containers and managed clusters each put these in different places, and a path remembered from another machine is often wrong.
The server already knows the answers. Every file location is a configuration parameter, so current_setting('config_file') returns the main configuration file the running server was started with, and the other parameters work the same way. The pg_ls_* functions then list the files in the WAL, log, archive status and temporary directories with their size and last modification time.
The queries below are grouped the way a DBA works through an unfamiliar server: configuration files, then the data directory, sockets, logging, and finally the contents of the working directories. The same parameters are also available as rows in pg_settings, which is covered in Understanding PostgreSQL pg_settings and pg_file_settings.
Sample Code
PostgreSQL 12 and later:
1SELECT
2 current_setting('config_file') AS config_file,
3 current_setting('hba_file') AS hba_file,
4 current_setting('ident_file') AS ident_file;
5
6SELECT
7 current_setting('data_directory') AS data_directory,
8 current_setting('external_pid_file') AS external_pid_file;
9
10SELECT
11 current_setting('unix_socket_directories') AS unix_socket_directories,
12 current_setting('unix_socket_permissions') AS unix_socket_permissions,
13 current_setting('unix_socket_group') AS unix_socket_group;
14
15SELECT
16 pg_current_logfile() AS current_logfile,
17 current_setting('log_directory') AS log_directory,
18 current_setting('log_filename') AS log_filename;
19
20SELECT * FROM pg_ls_waldir() ORDER BY modification DESC LIMIT 5;
21SELECT * FROM pg_ls_archive_statusdir() ORDER BY modification DESC LIMIT 5;
22SELECT count(*) AS temp_files, pg_size_pretty(sum(size)) AS temp_size
23FROM pg_ls_tmpdir();
PostgreSQL 10 and 11 run the same first four statements. The last three differ: keep pg_ls_waldir() and drop the pg_ls_archive_statusdir() and pg_ls_tmpdir() statements, which do not exist before 12. pg_ls_logdir() is also available from version 10:
1SELECT * FROM pg_ls_waldir() ORDER BY modification DESC LIMIT 5;
2SELECT * FROM pg_ls_logdir() ORDER BY modification DESC LIMIT 5;
Before PostgreSQL 10, only the parameter lookups are available. Remove pg_current_logfile() from the logging statement and use no pg_ls_* function:
1SELECT
2 current_setting('config_file') AS config_file,
3 current_setting('hba_file') AS hba_file,
4 current_setting('ident_file') AS ident_file,
5 current_setting('data_directory') AS data_directory,
6 current_setting('log_directory') AS log_directory,
7 current_setting('log_filename') AS log_filename,
8 current_setting('unix_socket_permissions') AS unix_socket_permissions;
The same parameters can be read from pg_settings, with the source of each value:
1SELECT name, setting, source
2FROM pg_settings
3WHERE name IN ('config_file', 'hba_file', 'ident_file', 'data_directory',
4 'log_directory', 'log_filename')
5ORDER BY name;
Notes: unix_socket_directories exists from PostgreSQL 9.3, where it replaced the single-directory unix_socket_directory; on 9.2 and earlier query the old name. Some configuration parameters are normally visible only to superusers. A role that holds pg_read_all_settings can read them, and the pg_ls_* functions and pg_current_logfile() are restricted to superusers and members of pg_monitor unless EXECUTE is granted.
Code Breakdown
The first group of statements reads configuration parameters, and the second group lists directories.
Configuration files
config_file is the main server configuration file, customarily called postgresql.conf, and it can only be set on the postgres command line. hba_file is the host-based authentication file, customarily pg_hba.conf. ident_file is the user name mapping file, customarily pg_ident.conf. In a default installation none of the three is set explicitly: the files are found inside the data directory, so read the returned path instead of assuming one.
data_directory and external_pid_file
data_directory is where the cluster stores its data. If the configuration files were moved outside it, data_directory in postgresql.conf points at the real data location, and it overrides -D and PGDATA for that purpose but not for the configuration files themselves. external_pid_file names an additional process-ID file that the server creates for administration programs. It is only populated when it has been configured.
Unix-domain sockets
unix_socket_directories lists the directories where the server creates its sockets; several can be given, separated by commas. An empty value means the server does not listen on any Unix-domain socket and only TCP/IP connections work. unix_socket_permissions is a numeric mode with a default of 0777, and unix_socket_group sets the owning group; an empty string means the default group of the server user. Together they act as a second layer of access control for local connections.
Logging
log_directory and log_filename only apply when logging_collector is enabled. The directory defaults to log, relative to the data directory, and the file name is a strftime pattern whose default is postgresql-%Y-%m-%d_%H%M%S.log. pg_current_logfile() returns the path of the file in use, including the directory, and returns NULL when the logging collector is disabled. With the collector off, expect NULL: the server logs somewhere else.
The pg_ls functions
pg_ls_waldir(), pg_ls_logdir(), pg_ls_archive_statusdir() and pg_ls_tmpdir() each return name, size and modification time for every ordinary file in their directory. Dot-files, subdirectories and special files are skipped. pg_ls_archive_statusdir() reads pg_wal/archive_status. pg_ls_tmpdir() takes an optional tablespace OID and defaults to pg_default. Ordering by modification puts the newest files first, which is usually what you want.
Key File Location Parameters
A handful of parameters decide where everything lives, and the order in which they interact explains the output.
-D, PGDATA and data_directory
Without any explicit setting, the data directory comes from the -D option or the PGDATA environment variable, and the configuration files are expected inside it. Setting data_directory lets the configuration files live elsewhere, for example under /etc, with -D or PGDATA pointing at the directory that holds them. When all three of config_file, hba_file and ident_file plus data_directory are set, neither -D nor PGDATA is needed.
Relative paths
A relative path in data_directory, config_file, hba_file or ident_file is interpreted against the directory in which postgres was started. log_directory is different: a relative value, including the default log, is relative to the data directory, so combine it with data_directory before looking for log files on disk.
Parameters that need a restart
data_directory, hba_file and ident_file can only be set at server start, and config_file only on the command line. Changing them is a restart-level operation, which is why checking the current values first is part of any migration plan.
Practical Applications
These lookups answer concrete questions during routine administration.
Taking over an unfamiliar server
Run the first two statements to find the configuration files and the data directory, then read pg_hba.conf and postgresql.conf from the paths returned instead of guessing. On hosts with several PostgreSQL versions installed, the paths also confirm which cluster you are actually connected to.
Backup and restore planning
The data directory and the WAL listing show what a file-level backup has to cover and how much WAL is currently retained. If pg_ls_waldir() returns far more files than expected, find out why before scheduling a backup that depends on archiving.
Finding the log file during an incident
During an outage the question is which log file holds the error. pg_current_logfile() returns the path directly, and on version 10 or later pg_ls_logdir() lists the recent files by modification time, so there is no need to read the naming pattern by hand.
Checking local connection access
When a local client cannot connect through a socket, the three socket parameters show the directory to point psql at, the mode, and the owning group. A restrictive mode such as 0770 with a group the client does not belong to explains the failure.
Version Compatibility
The current_setting() lookups of the file-location parameters work on all supported versions. The differences are in the functions around them. PostgreSQL 9.3 replaced unix_socket_directory with unix_socket_directories. PostgreSQL 10 added pg_current_logfile(), pg_ls_logdir() and pg_ls_waldir(), so earlier servers have no dedicated function for listing the WAL or log directory.
PostgreSQL 12 added pg_ls_archive_statusdir() and pg_ls_tmpdir(); neither exists in 10 or 11. A statement that calls one of them fails with an undefined function error on an older server, which is why the sample code is split by version instead of being one script. Access to the pg_ls_* functions and pg_current_logfile() is limited to superusers and pg_monitor members by default; a monitoring account that should run them without full privileges needs EXECUTE granted on each function.
Best Practices
- Record the paths in your runbook — store the output of the first two statements with each cluster's documentation so incident responders do not guess.
- Use
pg_monitorfor monitoring accounts — it covers thepg_ls_*functions andpg_current_logfile()without superuser rights. - Match the script to the version — keep a separate statement set for servers older than 12 so a single copy-paste does not fail halfway.
- Check
logging_collectorfirst — a NULL frompg_current_logfile()is expected when it is off, and the logs are elsewhere. - Confirm where a value came from — the
sourcefileandsourcelinecolumns ofpg_settingsshow which file set it before you edit anything. - Watch the WAL and temporary directories over time — a one-time listing says little; repeat it and compare.
References
- PostgreSQL: File Locations —
data_directory,config_file,hba_file,ident_fileandexternal_pid_file, and how they interact with-DandPGDATA. - PostgreSQL: Connections and Authentication —
unix_socket_directories,unix_socket_permissionsandunix_socket_group. - PostgreSQL: Error Reporting and Logging —
logging_collector,log_directoryandlog_filenamewith their defaults. - PostgreSQL: System Information Functions —
current_setting()andpg_current_logfile(). - PostgreSQL: System Administration Functions —
pg_ls_waldir(),pg_ls_logdir(),pg_ls_archive_statusdir()andpg_ls_tmpdir(). - PostgreSQL 12 Release Notes — Introduction of
pg_ls_archive_statusdir()andpg_ls_tmpdir(). - PostgreSQL 10 Release Notes — Introduction of
pg_ls_logdir(),pg_ls_waldir()andpg_current_logfile(). - HariSekhon/SQL-scripts: postgres_dirs.sql — Original directory query the scripts above are adapted from.
- HariSekhon/SQL-scripts LICENSE (MIT) — Copyright 2020 Hari Sekhon. The script in this post is used under the MIT License.
Posts in this series
- How Many Connections Can Your PostgreSQL Database Handle?
- PostgreSQL Backend Connections via pg_stat_database
- pg_blocking_pids — Find Blocking Queries in PostgreSQL
- List PostgreSQL Databases by Size with Access Check
- Assess PostgreSQL Database Sizes Quickly and Easily
- Unveiling Your PostgreSQL Server - A Diagnostic Powerhouse
- Keep Your PostgreSQL Database Clean, Identify Idle Connections
- Query the PostgreSQL Configuration
- pg_is_in_recovery — Monitor PostgreSQL Standby Status
- ALTER SEQUENCE RESTART WITH in PostgreSQL — Examples
- Monitor Running Queries in PostgreSQL using pg_stat_activity
- Monitor PostgreSQL Active Sessions with pg_stat_activity
- PostgreSQL Error Handling Settings via pg_settings
- PostgreSQL File Location Settings Query via pg_settings
- Inspect PostgreSQL Lock Management Settings with pg_settings
- PostgreSQL Logging Configuration Query via pg_settings
- Monitor PostgreSQL Memory Settings with pg_settings
- PostgreSQL Table Row Count Estimates with SQL
- List PostgreSQL Tables by Size with SQL
- PostgreSQL WAL Settings Query Guide
- log_parser_stats, log_planner_stats, log_executor_stats — PostgreSQL
- PostgreSQL SSL Settings Query Guide
- PostgreSQL Resource Settings Query Guide
- PostgreSQL Replication Settings Query Guide
- PostgreSQL Query Planning Settings Query Guide
- PostgreSQL Preset Options Settings Query Guide
- PostgreSQL Miscellaneous Settings Query Guide
- Count PostgreSQL Sessions by State with SQL
- Kill Idle PostgreSQL Sessions with SQL
- GRANT SELECT on All Tables in PostgreSQL — with Examples
- pg_stat_user_tables — Find Insert-Only Tables in PostgreSQL
- Detect Soft Delete Patterns in PostgreSQL
- List PostgreSQL Object Comments with SQL
- List Foreign Key Constraints in PostgreSQL
- List PostgreSQL Enum Types and Their Values with SQL
- List All Views in a PostgreSQL Database with SQL
- Find PostgreSQL Tables Without a Primary Key
- List PostgreSQL Partitioned Tables with SQL
- List All Schemas in Your PostgreSQL Database
- pg_stat_database — Query PostgreSQL Database Statistics
- List PostgreSQL Roles and Their Privileges
- Scrubbing Email PII in PostgreSQL for GDPR Compliance
- List Installed Extensions in PostgreSQL
- List PostgreSQL Collations with pg_collation and ICU
- PostgreSQL Replica Identity for Logical Replication
- Monitor PostgreSQL Vacuum Progress with pg_stat_progress_vacuum
- Monitor PostgreSQL Wait Events Using pg_stat_activity
- Monitor PostgreSQL Replication Lag with pg_stat_replication
- List PostgreSQL Wait Events with the pg_wait_events View
- PostgreSQL Column-Level Permissions Audit Query
- List All PostgreSQL Triggers with Their State
- timestamptz and tzdata: Avoid Shifted PostgreSQL Timestamps
- Inspect PostgreSQL Sequences with the pg_sequences View
- List PostgreSQL Functions with pg_proc
- Query PostgreSQL Tablespace Info with pg_tablespace
- Audit PostgreSQL Authentication with pg_hba_file_rules
- List PostgreSQL Materialized Views with pg_matviews
- Audit Row-Level Security Policies with pg_policies