PostgreSQL Installation and Configuration: Complete Guide for Rocky Linux 9.6

Table of Contents
PostgreSQL Installation and Configuration: A Production-Ready Setup Guide⌗
Setting up PostgreSQL correctly from the beginning can save you countless hours of troubleshooting later. Whether you’re a developer setting up your first database or a DBA preparing a production environment, this comprehensive guide covers everything you need to know about PostgreSQL installation, directory structure, permissions, and performance optimization.
VBoxManage ^
snapshot rocky-linux-db-lab ^
take ver.1 ^
--uniquename timestamp ^
--description "Snapshot taken right after VM setup"
VBoxManage ^
startvm rocky-linux-db-lab ^
--type headless
Table of Contents
- Pre-Installation Planning
- Installation Methods
- Directory Structure and Permissions
- Initial Configuration for Performance
- Security Hardening
- Post-Installation Steps
- Performance Testing
- Maintenance and Monitoring
Pre-Installation Planning⌗
Before diving into the installation, let’s plan our setup properly. A well-planned PostgreSQL installation considers data location, backup strategies, and future scaling needs.
Optimizing for Rocky Linux 9.6 with Limited Resources⌗
Our target environment:
- Operating System: Rocky Linux 9.6 on Oracle VM
- RAM: 4 GiB (requires careful memory tuning)
- Storage: 40 GiB with XFS file system on
/var
- Administrative User: dbadmin (root disabled for security)
Storage layout optimization:
# Leveraging the existing disk partitioning
/var/lib/postgresql/ # Main data directory (20 GiB /var mount)
/var/log/postgresql/ # Log files (same /var mount)
/tmp/postgresql_backup/ # Temporary backup location (2 GiB /tmp)
/home/dbadmin/scripts/ # Administrative scripts
Why this setup works well:
- XFS file system provides excellent performance for database workloads
- 20 GiB
/var
mount gives plenty of space for data growth - Separate
/tmp
mount prevents backup operations from filling root partition
Installation Methods⌗
Package Manager Installation (Recommended)⌗
Rocky Linux 9.6:
sudo su -
# Install PostgreSQL repository for RHEL 9 compatible
dnf --assumeyes install https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
# Disable the built-in PostgreSQL module:
dnf --quiet --assumeyes module disable postgresql
# Install PostgreSQL:
dnf install -y postgresql17-server
# Optionally initialize the database and enable automatic start:
/usr/pgsql-17/bin/postgresql-17-setup initdb
systemctl enable --now postgresql-17
# Install PostgreSQL 15 (recommended for Rocky Linux 9.6)
sudo dnf install -y postgresql15-server postgresql15-contrib
# Initialize database with custom data directory in /var
sudo /usr/pgsql-15/bin/postgresql-15-setup initdb
# Enable and start the service
sudo systemctl enable --now postgresql-15
# Verify installation
systemctl status postgresql-15
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
sudo dnf -qy module disable postgresql
sudo dnf install -y postgresql17-server
sudo /usr/pgsql-17/bin/postgresql-17-setup initdb
sudo systemctl enable postgresql-17
sudo systemctl start postgresql-17
Source Compilation (Advanced)⌗
For custom builds or specific requirements:
# Download and extract source
wget https://ftp.postgresql.org/pub/source/v15.4/postgresql-15.4.tar.gz
tar -xzf postgresql-15.4.tar.gz
cd postgresql-15.4
# Configure with optimizations
./configure --prefix=/usr/local/pgsql --with-openssl --with-libxml --with-libxslt
make -j$(nproc)
sudo make install
Directory Structure and Permissions⌗
Understanding PostgreSQL’s directory structure is crucial for proper administration.
Standard Directory Layout⌗
/var/lib/postgresql/15/main/
├── base/ # Database files
├── global/ # Cluster-wide tables
├── pg_wal/ # Write-Ahead Log files
├── pg_xact/ # Transaction status data
├── pg_log/ # Server log files
├── postgresql.conf # Main configuration file
├── pg_hba.conf # Host-based authentication
├── pg_ident.conf # User name mapping
└── postmaster.pid # Process ID file
Setting Correct Permissions⌗
Critical security setup for Rocky Linux with dbadmin user:
# PostgreSQL user already created by package installation
# Ensure correct ownership (dbadmin can manage through sudo)
sudo chown -R postgres:postgres /var/lib/pgsql/15/
sudo chmod 700 /var/lib/pgsql/15/data/
# Grant dbadmin user necessary sudo permissions
sudo usermod -aG wheel dbadmin
echo 'dbadmin ALL=(postgres) NOPASSWD: ALL' | sudo tee /etc/sudoers.d/dbadmin-postgres
# Secure configuration files
sudo chmod 640 /var/lib/pgsql/15/data/postgresql.conf
sudo chmod 640 /var/lib/pgsql/15/data/pg_hba.conf
# Create directories for scripts and backups
sudo mkdir -p /home/dbadmin/scripts
sudo mkdir -p /tmp/postgresql_backup
sudo chown dbadmin:dbadmin /home/dbadmin/scripts
sudo chown postgres:postgres /tmp/postgresql_backup
Initial Configuration for Performance⌗
Memory Configuration for 4 GiB RAM System⌗
In /var/lib/pgsql/15/data/postgresql.conf:
# Memory settings optimized for 4GB RAM system
shared_buffers = 1GB # 25% of total RAM (conservative)
effective_cache_size = 2GB # 50% of total RAM (OS needs memory too)
work_mem = 16MB # Conservative for limited RAM
maintenance_work_mem = 256MB # For maintenance operations
# Connection settings (important for limited memory)
max_connections = 50 # Reduced for memory efficiency
Important for 4GB systems:
- Keep
shared_buffers
conservative to leave memory for OS and other processes - Lower
max_connections
to prevent memory exhaustion - Monitor swap usage to avoid performance degradation
Write-Ahead Logging (WAL) Optimization for Limited Disk⌗
# WAL settings optimized for 20GB /var partition
wal_buffers = 32MB # Conservative for 4GB RAM
checkpoint_completion_target = 0.9
max_wal_size = 1GB # Smaller for limited space
min_wal_size = 256MB # Reduced for space conservation
# Archive settings using /tmp for temporary backup storage
wal_level = replica
archive_mode = on
archive_command = 'test ! -f /tmp/postgresql_backup/wal/%f && cp %p /tmp/postgresql_backup/wal/%f'
# Create WAL archive directory
# Run as dbadmin: sudo mkdir -p /tmp/postgresql_backup/wal && sudo chown postgres:postgres /tmp/postgresql_backup/wal
Query Optimization Settings⌗
# Query planner settings optimized for XFS and limited resources
random_page_cost = 1.1 # For SSD/fast storage
effective_io_concurrency = 100 # Conservative for VM environment
seq_page_cost = 1.0
# Logging for performance analysis (be careful with disk space)
log_min_duration_statement = 2000 # Log queries taking 2+ seconds
log_checkpoints = on
log_connections = off # Disabled to save disk space
log_disconnections = off # Disabled to save disk space
log_lock_waits = on # Important for debugging
Security Hardening⌗
Authentication Configuration⌗
pg_hba.conf setup:
# TYPE DATABASE USER ADDRESS METHOD
# Local connections
local all postgres peer
local all all md5
# Remote connections (be specific about IP ranges)
host myapp_db myapp_user 192.168.1.0/24 md5
host all all 127.0.0.1/32 md5
# Reject all other connections
host all all 0.0.0.0/0 reject
SSL Configuration⌗
# In postgresql.conf
ssl = on
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
ssl_ca_file = 'root.crt'
ssl_prefer_server_ciphers = on
Post-Installation Steps⌗
1. Create Application Database and User⌗
-- Connect as superuser (dbadmin can use sudo)
sudo -u postgres psql
-- Create database with locale compatible with Rocky Linux 9.6
CREATE DATABASE myapp_db
WITH ENCODING='UTF8'
LC_COLLATE='C.UTF-8'
LC_CTYPE='C.UTF-8'
TEMPLATE=template0;
-- Create user with limited privileges
CREATE USER myapp_user WITH PASSWORD 'secure_password_here';
GRANT CONNECT ON DATABASE myapp_db TO myapp_user;
GRANT USAGE ON SCHEMA public TO myapp_user;
GRANT CREATE ON SCHEMA public TO myapp_user;
2. Set Up Backup Strategy for Limited Disk Space⌗
# Create backup script for dbadmin user
cat > /home/dbadmin/scripts/pg_backup.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/tmp/postgresql_backup"
DATE=$(date +%Y%m%d_%H%M%S)
MAX_BACKUPS=3 # Keep only 3 backups due to space limitations
# Ensure backup directory exists
mkdir -p "$BACKUP_DIR"
# Full database backup with compression to save space
sudo -u postgres pg_dump -h localhost myapp_db | gzip > "$BACKUP_DIR/myapp_db_$DATE.sql.gz"
# Remove old backups, keep only the most recent ones
ls -t "$BACKUP_DIR"/myapp_db_*.sql.gz | tail -n +$((MAX_BACKUPS + 1)) | xargs -r rm
# Log backup completion
echo "$(date): Backup completed - $BACKUP_DIR/myapp_db_$DATE.sql.gz" >> /var/log/postgresql/backup.log
EOF
chmod +x /home/dbadmin/scripts/pg_backup.sh
# Test the backup script
/home/dbadmin/scripts/pg_backup.sh
# Add to dbadmin's crontab for daily backups at 2 AM
(crontab -u dbadmin -l 2>/dev/null; echo "0 2 * * * /home/dbadmin/scripts/pg_backup.sh") | crontab -u dbadmin -
3. Monitoring Setup⌗
-- Enable pg_stat_statements for query analysis
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
-- Check configuration
SELECT name, setting FROM pg_settings WHERE name LIKE 'shared_preload%';
Performance Testing on Limited Resources⌗
Verify your installation with scaled performance tests suitable for 4GB RAM:
# Initialize pgbench with smaller scale for limited resources
sudo -u postgres pgbench -i -s 10 myapp_db # Reduced from 100 to 10
# Run performance test with reduced connections
sudo -u postgres pgbench -c 5 -j 2 -t 500 myapp_db # Conservative settings
# Monitor system resources during testing
# In another terminal as dbadmin:
watch -n 1 'free -m && echo "---" && df -h /var'
Common Pitfalls to Avoid in Resource-Constrained Environments⌗
- Never exceed 25% of RAM for shared_buffers on 4GB systems
- Monitor swap usage - PostgreSQL performance degrades severely with swapping
- Don’t set max_connections too high - each connection uses ~2-4MB RAM
- Always compress backups to save disk space in /tmp
- Use
VACUUM
regularly to prevent table bloat in limited disk space - Monitor /var disk usage - 20GB can fill up quickly with logs and data
Rocky Linux 9.6 Specific Considerations⌗
# Configure firewall for PostgreSQL (if enabled)
sudo firewall-cmd --permanent --add-port=5432/tcp
sudo firewall-cmd --reload
# SELinux considerations (if enforcing)
sudo setsebool -P postgresql_can_rsync on
# Check system limits for postgres user
sudo -u postgres ulimit -a
Maintenance Tasks for Resource-Constrained Systems⌗
Create a maintenance checklist optimized for your 4GB/20GB setup:
# Daily tasks (automated via cron)
# Monitor disk space
df -h /var >> /var/log/postgresql/disk_usage.log
# Weekly tasks (run as dbadmin)
sudo -u postgres psql -d myapp_db -c "VACUUM ANALYZE;"
# Monthly tasks
# Backup verification and cleanup
/home/dbadmin/scripts/pg_backup.sh
# Log file rotation (automatically handled by Rocky Linux logrotate)
# Quarterly tasks
# Extension updates and minor version upgrades
sudo dnf update postgresql15*
Conclusion⌗
A properly configured PostgreSQL installation is the foundation of any robust database system. By following this guide, you’ve set up a secure, performant, and maintainable PostgreSQL environment optimized for Rocky Linux 9.6 with limited resources. Remember to monitor your system regularly and adjust configurations based on your specific workload patterns.
Next Steps: Now that you have a solid PostgreSQL installation, you can focus on advanced topics like index optimization, query tuning, and scaling strategies to maximize your database performance.
Related Articles⌗
- PostgreSQL Index Optimization Techniques
- Database Performance Monitoring on Linux
- PostgreSQL Backup and Recovery Strategies
Frequently Asked Questions⌗
Q: Can I increase shared_buffers beyond 1GB on a 4GB system? A: It’s not recommended. Leave sufficient memory for the OS and other processes to avoid swapping, which severely impacts PostgreSQL performance.
Q: How often should I run VACUUM on my database? A: For active databases, run VACUUM ANALYZE weekly. For high-transaction systems, consider enabling autovacuum with custom settings.
Q: What’s the minimum disk space required for PostgreSQL on Rocky Linux 9.6?
A: The installation requires about 500MB, but plan for at least 10GB for data, logs, and growth. Our 20GB /var
partition provides comfortable headroom.
This installation guide provides a production-ready PostgreSQL setup optimized for Rocky Linux 9.6 in resource-constrained environments. Always test configuration changes in a development environment before applying them to production systems.
Keywords: PostgreSQL installation, Rocky Linux database setup, PostgreSQL configuration, database performance tuning, PostgreSQL security, Linux database administration