PostgreSQL Database Setup: Complete Guide
Table of Contents
1. [Introduction](#introduction) 2. [Installation Methods](#installation-methods) 3. [Post-Installation Configuration](#post-installation-configuration) 4. [Database Creation and Management](#database-creation-and-management) 5. [User Management and Security](#user-management-and-security) 6. [Configuration Files](#configuration-files) 7. [Basic Operations](#basic-operations) 8. [Performance Tuning](#performance-tuning) 9. [Backup and Recovery](#backup-and-recovery) 10. [Troubleshooting](#troubleshooting)Introduction
PostgreSQL is an advanced, enterprise-class, and open-source relational database system. PostgreSQL supports both SQL (relational) and JSON (non-relational) querying. It is a highly stable database management system, backed by more than 20 years of community development which has contributed to its high levels of resilience, integrity, and correctness.
Key Features
| Feature | Description | |---------|-------------| | ACID Compliance | Ensures database transactions are processed reliably | | Multi-Version Concurrency Control | Allows multiple transactions to access the same data simultaneously | | Extensibility | Supports custom data types, operators, and functions | | Standards Compliance | Follows SQL standards more closely than most databases | | Cross-Platform | Runs on all major operating systems | | Scalability | Handles workloads ranging from single machines to data warehouses |
Installation Methods
Method 1: Package Manager Installation
#### Ubuntu/Debian Systems
`bash
Update package index
sudo apt updateInstall PostgreSQL and additional utilities
sudo apt install postgresql postgresql-contribInstall specific version (example: PostgreSQL 15)
sudo apt install postgresql-15 postgresql-contrib-15`Command Explanation:
- postgresql: Core PostgreSQL server package
- postgresql-contrib: Additional utilities and extensions
- postgresql-15: Specific version installation
#### CentOS/RHEL/Fedora Systems
`bash
Install PostgreSQL repository
sudo dnf install postgresql-server postgresql-contribInitialize database cluster
sudo postgresql-setup --initdbEnable and start PostgreSQL service
sudo systemctl enable postgresql sudo systemctl start postgresql`#### macOS with Homebrew
`bash
Install PostgreSQL
brew install postgresqlStart PostgreSQL service
brew services start postgresqlCreate initial database
initdb /usr/local/var/postgres`Method 2: Docker Installation
`bash
Pull PostgreSQL image
docker pull postgres:15Run PostgreSQL container
docker run --name postgres-db \ -e POSTGRES_PASSWORD=mypassword \ -e POSTGRES_DB=mydatabase \ -p 5432:5432 \ -v postgres-data:/var/lib/postgresql/data \ -d postgres:15`Docker Parameters Explanation:
| Parameter | Description |
|-----------|-------------|
| --name postgres-db | Container name |
| -e POSTGRES_PASSWORD | Sets superuser password |
| -e POSTGRES_DB | Creates initial database |
| -p 5432:5432 | Port mapping (host:container) |
| -v postgres-data | Volume for data persistence |
| -d | Run in detached mode |
Method 3: Source Code Compilation
`bash
Download source code
wget https://ftp.postgresql.org/pub/source/v15.4/postgresql-15.4.tar.gz tar -xzf postgresql-15.4.tar.gz cd postgresql-15.4Configure build
./configure --prefix=/usr/local/pgsql --with-opensslCompile and install
make sudo make installCreate postgres user
sudo adduser postgresInitialize database
sudo -u postgres /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data`Post-Installation Configuration
Service Management
#### SystemD Systems (Most Linux Distributions)
`bash
Check service status
sudo systemctl status postgresqlStart PostgreSQL service
sudo systemctl start postgresqlEnable auto-start on boot
sudo systemctl enable postgresqlRestart service
sudo systemctl restart postgresqlStop service
sudo systemctl stop postgresql`#### Service Configuration Table
| Command | Purpose | When to Use |
|---------|---------|-------------|
| systemctl status | Check service status | Troubleshooting |
| systemctl start | Start service | After installation |
| systemctl enable | Enable auto-start | Production systems |
| systemctl restart | Restart service | After configuration changes |
| systemctl stop | Stop service | Maintenance or shutdown |
Initial Database Setup
`bash
Switch to postgres user
sudo -i -u postgresAccess PostgreSQL prompt
psqlAlternative: Connect directly
sudo -u postgres psql`Setting Up Superuser Password
`sql
-- Set password for postgres user
ALTER USER postgres PASSWORD 'your_secure_password';
-- Create new superuser CREATE USER admin WITH SUPERUSER PASSWORD 'admin_password';
-- Exit psql
\q
`
Database Creation and Management
Creating Databases
`sql
-- Create a new database
CREATE DATABASE myapp_database;
-- Create database with specific owner CREATE DATABASE myapp_database OWNER myuser;
-- Create database with encoding and locale
CREATE DATABASE myapp_database
WITH ENCODING 'UTF8'
LC_COLLATE='en_US.UTF-8'
LC_CTYPE='en_US.UTF-8'
TEMPLATE=template0;
`
Database Management Commands
| SQL Command | Purpose | Example |
|-------------|---------|---------|
| CREATE DATABASE | Create new database | CREATE DATABASE shop; |
| DROP DATABASE | Delete database | DROP DATABASE shop; |
| ALTER DATABASE | Modify database | ALTER DATABASE shop RENAME TO store; |
| \l | List databases | \l |
| \c database_name | Connect to database | \c shop |
Command Line Database Operations
`bash
Create database from command line
createdb myapp_databaseCreate database with owner
createdb -O myuser myapp_databaseDrop database
dropdb myapp_databaseList all databases
psql -l`User Management and Security
Creating Users and Roles
`sql
-- Create a regular user
CREATE USER app_user WITH PASSWORD 'secure_password';
-- Create user with specific privileges CREATE USER app_user WITH PASSWORD 'secure_password' CREATEDB LOGIN;
-- Create role (group of privileges) CREATE ROLE app_role;
-- Grant role to user
GRANT app_role TO app_user;
`
Permission Management
`sql
-- Grant database access
GRANT CONNECT ON DATABASE myapp_database TO app_user;
-- Grant schema usage GRANT USAGE ON SCHEMA public TO app_user;
-- Grant table permissions GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_user;
-- Grant sequence permissions (for auto-increment) GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app_user;
-- Set default privileges for future tables
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO app_user;
`
User Management Commands Reference
| Command | Purpose | Syntax |
|---------|---------|---------|
| CREATE USER | Create new user | CREATE USER username WITH PASSWORD 'password'; |
| ALTER USER | Modify user | ALTER USER username WITH CREATEDB; |
| DROP USER | Delete user | DROP USER username; |
| GRANT | Grant permissions | GRANT SELECT ON table TO user; |
| REVOKE | Remove permissions | REVOKE SELECT ON table FROM user; |
| \du | List users and roles | \du |
Configuration Files
Main Configuration Files
| File | Location | Purpose |
|------|----------|---------|
| postgresql.conf | /etc/postgresql/15/main/ | Main configuration |
| pg_hba.conf | /etc/postgresql/15/main/ | Authentication settings |
| pg_ident.conf | /etc/postgresql/15/main/ | User mapping |
Note: Paths may vary by installation method and operating system.
Key postgresql.conf Settings
`bash
Find configuration file location
sudo -u postgres psql -c "SHOW config_file;"Edit configuration file
sudo nano /etc/postgresql/15/main/postgresql.conf`#### Important Configuration Parameters
`conf
Connection settings
listen_addresses = 'localhost' # IP addresses to listen on port = 5432 # TCP port max_connections = 100 # Maximum concurrent connectionsMemory settings
shared_buffers = 256MB # Shared memory buffers effective_cache_size = 1GB # OS cache size estimate work_mem = 4MB # Memory for query operationsWrite-ahead logging
wal_level = replica # WAL level max_wal_size = 1GB # Maximum WAL size min_wal_size = 80MB # Minimum WAL sizeLogging
log_destination = 'stderr' # Log destination logging_collector = on # Enable log collector log_directory = 'log' # Log directory log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # Log filename pattern`Authentication Configuration (pg_hba.conf)
`conf
TYPE DATABASE USER ADDRESS METHOD
Local connections
local all postgres peer local all all md5IPv4 local connections
host all all 127.0.0.1/32 md5IPv6 local connections
host all all ::1/128 md5Remote connections (example)
host myapp_database app_user 192.168.1.0/24 md5`#### Authentication Methods
| Method | Description | Use Case |
|--------|-------------|----------|
| trust | No password required | Development only |
| md5 | MD5 password authentication | Standard authentication |
| scram-sha-256 | SCRAM-SHA-256 authentication | Enhanced security |
| peer | OS user authentication | Local connections |
| ident | Ident server authentication | Trusted networks |
Applying Configuration Changes
`bash
Reload configuration without restart
sudo systemctl reload postgresqlOr from psql
SELECT pg_reload_conf();Restart for major changes
sudo systemctl restart postgresql`Basic Operations
Connecting to PostgreSQL
`bash
Connect as postgres user
sudo -u postgres psqlConnect to specific database
psql -h localhost -p 5432 -U username -d database_nameConnect with password prompt
psql -h localhost -p 5432 -U username -d database_name -W`Essential psql Commands
| Command | Description | Example |
|---------|-------------|---------|
| \l | List databases | \l |
| \c database | Connect to database | \c myapp |
| \dt | List tables | \dt |
| \d table | Describe table | \d users |
| \du | List users | \du |
| \q | Quit psql | \q |
| \? | Help | \? |
| \h SQL_COMMAND | SQL command help | \h CREATE TABLE |
Basic SQL Operations
`sql
-- Create a sample table
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Insert data INSERT INTO users (username, email) VALUES ('john_doe', 'john@example.com');
-- Query data SELECT * FROM users;
-- Update data UPDATE users SET email = 'newemail@example.com' WHERE id = 1;
-- Delete data
DELETE FROM users WHERE id = 1;
`
Index Management
`sql
-- Create index
CREATE INDEX idx_users_email ON users(email);
-- Create unique index CREATE UNIQUE INDEX idx_users_username ON users(username);
-- Create partial index CREATE INDEX idx_active_users ON users(username) WHERE active = true;
-- List indexes \di
-- Drop index
DROP INDEX idx_users_email;
`
Performance Tuning
Memory Configuration
`conf
Calculate shared_buffers (25% of RAM for dedicated server)
shared_buffers = 2GBCalculate effective_cache_size (75% of RAM)
effective_cache_size = 6GBWork memory per operation
work_mem = 256MBMaintenance work memory
maintenance_work_mem = 1GB`Performance Monitoring Queries
`sql
-- Check database size
SELECT pg_size_pretty(pg_database_size('database_name'));
-- Check table sizes SELECT schemaname, tablename, pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) as size FROM pg_tables ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;
-- Check active connections SELECT count(*) FROM pg_stat_activity;
-- Check slow queries
SELECT query, mean_time, calls
FROM pg_stat_statements
ORDER BY mean_time DESC
LIMIT 10;
`
Query Optimization
`sql
-- Analyze query performance
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com';
-- Update table statistics ANALYZE users;
-- Vacuum table VACUUM users;
-- Full vacuum (requires exclusive lock)
VACUUM FULL users;
`
Backup and Recovery
Logical Backups with pg_dump
`bash
Backup single database
pg_dump -h localhost -U username -d database_name > backup.sqlBackup with compression
pg_dump -h localhost -U username -d database_name | gzip > backup.sql.gzBackup in custom format
pg_dump -h localhost -U username -d database_name -Fc > backup.dumpBackup all databases
pg_dumpall -h localhost -U postgres > all_databases.sql`Backup Options
| Option | Description | Example |
|--------|-------------|---------|
| -h | Host | -h localhost |
| -p | Port | -p 5432 |
| -U | Username | -U postgres |
| -d | Database | -d myapp |
| -Fc | Custom format | -Fc |
| -t | Specific table | -t users |
| --schema-only | Schema without data | --schema-only |
| --data-only | Data without schema | --data-only |
Restore Operations
`bash
Restore from SQL dump
psql -h localhost -U username -d database_name < backup.sqlRestore from compressed dump
gunzip -c backup.sql.gz | psql -h localhost -U username -d database_nameRestore from custom format
pg_restore -h localhost -U username -d database_name backup.dumpRestore with clean option (drop existing objects)
pg_restore -h localhost -U username -d database_name -c backup.dump`Automated Backup Script
`bash
#!/bin/bash
backup_script.sh
Configuration
DB_HOST="localhost" DB_PORT="5432" DB_USER="postgres" DB_NAME="myapp_database" BACKUP_DIR="/var/backups/postgresql" DATE=$(date +%Y%m%d_%H%M%S) BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${DATE}.sql.gz"Create backup directory
mkdir -p ${BACKUP_DIR}Create backup
pg_dump -h ${DB_HOST} -p ${DB_PORT} -U ${DB_USER} -d ${DB_NAME} | gzip > ${BACKUP_FILE}Remove backups older than 7 days
find ${BACKUP_DIR} -name "*.sql.gz" -mtime +7 -deleteecho "Backup completed: ${BACKUP_FILE}"
`
Setting Up Automated Backups
`bash
Make script executable
chmod +x backup_script.shAdd to crontab for daily backup at 2 AM
crontab -e 0 2 * /path/to/backup_script.sh`Troubleshooting
Common Issues and Solutions
#### Connection Issues
`bash
Check if PostgreSQL is running
sudo systemctl status postgresqlCheck listening ports
sudo netstat -tlnp | grep 5432Test connection
telnet localhost 5432`#### Authentication Issues
`bash
Check pg_hba.conf configuration
sudo cat /etc/postgresql/15/main/pg_hba.confReload configuration
sudo systemctl reload postgresqlCheck user exists
sudo -u postgres psql -c "\du"`#### Performance Issues
`sql
-- Check active queries
SELECT pid, now() - pg_stat_activity.query_start AS duration, query
FROM pg_stat_activity
WHERE (now() - pg_stat_activity.query_start) > interval '5 minutes';
-- Kill long-running query SELECT pg_terminate_backend(pid);
-- Check locks
SELECT * FROM pg_locks WHERE NOT granted;
`
Log Analysis
`bash
Find log location
sudo -u postgres psql -c "SHOW log_directory;"View recent logs
sudo tail -f /var/log/postgresql/postgresql-15-main.logSearch for errors
sudo grep ERROR /var/log/postgresql/postgresql-15-main.log`Diagnostic Queries
`sql
-- Check database connections
SELECT datname, usename, client_addr, state
FROM pg_stat_activity
WHERE datname IS NOT NULL;
-- Check database sizes SELECT datname, pg_size_pretty(pg_database_size(datname)) FROM pg_database ORDER BY pg_database_size(datname) DESC;
-- Check table bloat
SELECT schemaname, tablename,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) as size,
pg_size_pretty(pg_relation_size(schemaname||'.'||tablename)) as table_size
FROM pg_tables
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;
`
Recovery Scenarios
#### Recovering from Corruption
`bash
Check database integrity
sudo -u postgres pg_checksums -D /var/lib/postgresql/15/mainRepair minor corruption
sudo -u postgres vacuumdb --all --analyzeRestore from backup if corruption is severe
pg_restore -h localhost -U postgres -d database_name backup.dump`#### Point-in-Time Recovery
`bash
Stop PostgreSQL
sudo systemctl stop postgresqlRestore base backup
tar -xzf base_backup.tar.gz -C /var/lib/postgresql/15/main/Configure recovery
echo "restore_command = 'cp /var/lib/postgresql/15/archive/%f %p'" > /var/lib/postgresql/15/main/recovery.conf echo "recovery_target_time = '2023-12-01 12:00:00'" >> /var/lib/postgresql/15/main/recovery.confStart PostgreSQL
sudo systemctl start postgresql`This comprehensive guide covers the essential aspects of setting up and managing a PostgreSQL database system. The information provided includes installation methods, configuration options, user management, performance tuning, backup strategies, and troubleshooting procedures that will help you establish a robust PostgreSQL environment for your applications.