PostgreSQL
PostgreSQL is a powerful open-source relational database management system known for its reliability, data integrity, and rich feature set. This article covers installing PostgreSQL on EL-based distributions, initializing the database, configuring authentication, user and database management, psql usage, backup and recovery, and remote access.
Versions Across Distributions
Section titled “Versions Across Distributions”Install PostgreSQL
Section titled “Install PostgreSQL”Using the System Default Repository (EL 9)
Section titled “Using the System Default Repository (EL 9)”EL 9 AppStream manages PostgreSQL versions through modularity. The usual default stream is 13, and other streams such as 15, 16, and 18 can be enabled as well (check dnf module list postgresql for what your repositories provide):
sudo dnf module list postgresqlsudo dnf install postgresql-server postgresql -yUsing the PostgreSQL Official Repository (Recommended, EL 9 & 10)
Section titled “Using the PostgreSQL Official Repository (Recommended, EL 9 & 10)”The official repository provides the latest stable version (currently PostgreSQL 18), and the URL adapts to your EL release automatically:
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# EL 9 only — disable the built-in module first:sudo dnf -qy module disable postgresqlsudo dnf install -y postgresql18-server postgresql18sudo dnf install -y postgresql18-server postgresql18Initialize the Database (initdb)
Section titled “Initialize the Database (initdb)”After installation, the database cluster must be initialized before the service can be started.
System Repository Version Initialization
Section titled “System Repository Version Initialization”sudo postgresql-setup --initdbOfficial Repository Version Initialization
Section titled “Official Repository Version Initialization”sudo /usr/pgsql-18/bin/postgresql-18-setup initdbStart the Service
Section titled “Start the Service”sudo systemctl start postgresqlsudo systemctl enable postgresqlsudo systemctl status postgresqlsudo systemctl start postgresql-18sudo systemctl enable postgresql-18sudo systemctl status postgresql-18Data Directory Reference
Section titled “Data Directory Reference”| Version | Data Directory | Configuration Directory |
|---|---|---|
| System repository | /var/lib/pgsql/data/ | /var/lib/pgsql/data/ |
| Official repository (18) | /var/lib/pgsql/18/data/ | /var/lib/pgsql/18/data/ |
Configure pg_hba.conf
Section titled “Configure pg_hba.conf”pg_hba.conf (Host-Based Authentication) controls client connection authentication and is the core of PostgreSQL security configuration.
sudo -u postgres psql -c "SHOW hba_file;"Authentication Methods
Section titled “Authentication Methods”| Method | Description |
|---|---|
peer | Matches the OS username to the database user (local Unix connections only) |
ident | Similar to peer, verifies via ident server (TCP connections) |
md5 | MD5-encrypted password verification |
scram-sha-256 | SCRAM-SHA-256 encrypted verification (recommended) |
trust | No password required, direct trust (test environments only) |
reject | Reject connection |
Edit pg_hba.conf
Section titled “Edit pg_hba.conf”sudo vi /var/lib/pgsql/data/pg_hba.confTypical configuration example:
# TYPE DATABASE USER ADDRESS METHOD
# Local Unix socket connectionslocal all postgres peerlocal all all scram-sha-256
# Local IPv4 connectionshost all all 127.0.0.1/32 scram-sha-256
# Local IPv6 connectionshost all all ::1/128 scram-sha-256
# Allow remote connections from a specific subnethost all all 192.168.1.0/24 scram-sha-256
# Allow a specific user to connect to a specific databasehost mydb myuser 10.0.0.0/8 scram-sha-256Reload the configuration after changes:
sudo systemctl reload postgresqlCreate Users and Databases
Section titled “Create Users and Databases”Using Command-Line Tools
Section titled “Using Command-Line Tools”sudo -u postgres createuser --interactive --pwprompt myusersudo -u postgres createdb --owner=myuser mydbUsing SQL Statements
Section titled “Using SQL Statements”sudo -u postgres psql-- Create a userCREATE USER myuser WITH PASSWORD 'StrongPassword123!';
-- Create a database with a specified ownerCREATE DATABASE mydb OWNER myuser;
-- Set character encodingCREATE DATABASE mydb_utf8 OWNER myuser ENCODING 'UTF8' LC_COLLATE 'zh_CN.UTF-8' LC_CTYPE 'zh_CN.UTF-8' TEMPLATE template0;
-- Grant database connection privilegeGRANT CONNECT ON DATABASE mydb TO myuser;
-- Grant schema privileges\c mydbGRANT USAGE ON SCHEMA public TO myuser;GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO myuser;User Management
Section titled “User Management”-- View all users\du
-- Change user passwordALTER USER myuser WITH PASSWORD 'NewPassword456!';
-- Grant superuser privileges (use with caution)ALTER USER myuser WITH SUPERUSER;
-- Revoke superuser privilegesALTER USER myuser WITH NOSUPERUSER;
-- Drop a user (must first revoke owned objects)DROP OWNED BY myuser;DROP USER myuser;psql Basic Operations
Section titled “psql Basic Operations”psql is the interactive terminal tool for PostgreSQL.
Connect to a Database
Section titled “Connect to a Database”# Log in as the postgres system usersudo -u postgres psql
# Specify user and databasepsql -U myuser -d mydb
# Connect with a specified hostpsql -U myuser -d mydb -h 127.0.0.1 -p 5432Common psql Meta-Commands
Section titled “Common psql Meta-Commands”\l -- List all databases\c dbname -- Switch database\dt -- List all tables in the current database\d tablename -- View table structure\du -- List all users/roles\dn -- List all schemas\df -- List all functions\di -- List all indexes\dx -- List installed extensions\timing -- Toggle query timing\x -- Toggle expanded display mode\q -- Quit psql\? -- Show help\h SQL_CMD -- Show SQL command helpBasic SQL Operations
Section titled “Basic SQL Operations”-- Create a tableCREATE TABLE articles ( id SERIAL PRIMARY KEY, title VARCHAR(200) NOT NULL, content TEXT, author VARCHAR(50), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
-- Insert dataINSERT INTO articles (title, content, author) VALUES ('Getting Started with PostgreSQL', 'This is a beginner tutorial...', 'Zhang San'), ('Database Optimization', 'Optimization tips summary...', 'Li Si');
-- Query dataSELECT * FROM articles;SELECT title, author FROM articles WHERE author = 'Zhang San';
-- Update dataUPDATE articles SET title = 'Advanced PostgreSQL' WHERE id = 1;
-- Delete dataDELETE FROM articles WHERE id = 2;
-- View table sizeSELECT pg_size_pretty(pg_total_relation_size('articles'));pg_dump Backup and Recovery
Section titled “pg_dump Backup and Recovery”Back Up a Single Database
Section titled “Back Up a Single Database”pg_dump -U postgres mydb > /backup/mydb_$(date +%Y%m%d_%H%M%S).sqlpg_dump -U postgres -Fc mydb > /backup/mydb_$(date +%Y%m%d_%H%M%S).dumpBack Up All Databases
Section titled “Back Up All Databases”pg_dumpall -U postgres > /backup/all_databases_$(date +%Y%m%d_%H%M%S).sqlBack Up Schema Only
Section titled “Back Up Schema Only”pg_dump -U postgres --schema-only mydb > /backup/mydb_schema.sqlBack Up Data Only
Section titled “Back Up Data Only”pg_dump -U postgres --data-only mydb > /backup/mydb_data.sqlRestore a Database
Section titled “Restore a Database”# Create the target database firstsudo -u postgres createdb mydb_restored
# Restorepsql -U postgres mydb_restored < /backup/mydb_20260324.sqlpg_restore -U postgres -d mydb_restored /backup/mydb_20260324.dumppg_restore -U postgres -d mydb --clean --if-exists /backup/mydb_20260324.dumpAutomated Backup Script
Section titled “Automated Backup Script”sudo tee /usr/local/bin/pg-backup.sh << 'SCRIPT'#!/bin/bashBACKUP_DIR="/backup/postgresql"DATE=$(date +%Y%m%d_%H%M%S)RETENTION_DAYS=7
mkdir -p "$BACKUP_DIR"
# Back up all databases (custom compressed format)for DB in $(sudo -u postgres psql -t -c "SELECT datname FROM pg_database WHERE datistemplate = false AND datname != 'postgres';"); do sudo -u postgres pg_dump -Fc "$DB" > "${BACKUP_DIR}/${DB}_${DATE}.dump"done
# Back up global objects (roles, tablespaces)sudo -u postgres pg_dumpall --globals-only > "${BACKUP_DIR}/globals_${DATE}.sql"
# Clean up old backupsfind "$BACKUP_DIR" -name "*.dump" -mtime +${RETENTION_DAYS} -deletefind "$BACKUP_DIR" -name "*.sql" -mtime +${RETENTION_DAYS} -delete
echo "PostgreSQL backup completed at ${DATE}"SCRIPT
sudo chmod +x /usr/local/bin/pg-backup.shecho "0 3 * * * root /usr/local/bin/pg-backup.sh" | sudo tee /etc/cron.d/pg-backupRemote Access Configuration
Section titled “Remote Access Configuration”Modify postgresql.conf
Section titled “Modify postgresql.conf”Change the PostgreSQL listen address:
sudo sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/" /var/lib/pgsql/data/postgresql.confIf you only need to listen on a specific IP:
sudo sed -i "s/#listen_addresses = 'localhost'/listen_addresses = 'localhost,192.168.1.10'/" /var/lib/pgsql/data/postgresql.confModify pg_hba.conf
Section titled “Modify pg_hba.conf”Add a remote access rule in pg_hba.conf:
echo "host all all 192.168.1.0/24 scram-sha-256" | sudo tee -a /var/lib/pgsql/data/pg_hba.confRestart the Service and Open the Firewall
Section titled “Restart the Service and Open the Firewall”sudo systemctl restart postgresqlsudo firewall-cmd --permanent --add-service=postgresqlsudo firewall-cmd --reloadVerify the Listening Port
Section titled “Verify the Listening Port”ss -tlnp | grep 5432Test the Remote Connection
Section titled “Test the Remote Connection”psql -U myuser -d mydb -h server_IP_address -p 5432Security Recommendations
Section titled “Security Recommendations”- Precisely specify allowed IP ranges in
pg_hba.conf; avoid using0.0.0.0/0 - Use
scram-sha-256authentication instead ofmd5 - Consider connecting via SSH tunnel to avoid directly exposing port 5432
- Enable SSL connection encryption
# Create a tunnel locallyssh -L 5432:127.0.0.1:5432 user@server_IP_address
# Connect through the tunnelpsql -U myuser -d mydb -h 127.0.0.1Common Operations Quick Reference
Section titled “Common Operations Quick Reference”# Start / Stop / Restart / Reloadsudo systemctl start postgresqlsudo systemctl stop postgresqlsudo systemctl restart postgresqlsudo systemctl reload postgresql
# View versionpsql --version
# View database sizessudo -u postgres psql -c "SELECT pg_database.datname, pg_size_pretty(pg_database_size(pg_database.datname)) FROM pg_database ORDER BY pg_database_size(pg_database.datname) DESC;"
# View active connectionssudo -u postgres psql -c "SELECT pid, usename, datname, client_addr, state, query FROM pg_stat_activity WHERE state = 'active';"
# View configuration file locationssudo -u postgres psql -c "SHOW config_file;"sudo -u postgres psql -c "SHOW hba_file;"
# View current connection countsudo -u postgres psql -c "SELECT count(*) FROM pg_stat_activity;"Further Reading
Section titled “Further Reading”- MySQL / MariaDB — Another popular database
- Firewall — Configure database access rules
EL 10 Notes
Section titled “EL 10 Notes”EL 10 and EL 9 differ in how system repository versions are managed:
| Version | EL 9 system repo | EL 10 system repo |
|---|---|---|
| PostgreSQL | 13 (usual default stream); 15 / 16 / 18 streams can be enabled | 16 (no modularity, install directly) |
When using the PostgreSQL official repository (recommended), version selection is more flexible — the current latest stable release is PostgreSQL 18:
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpmThe official repo URL uses %{rhel} and automatically adapts for EL 10.