PostgreSQL Cluster Management at CosmoTech Inc.
Welcome to CosmoTech Inc.! You've just joined as a Database Administrator. The company is expanding rapidly and needs you to install PostgreSQL 16 and set up multiple database environments.
Your mission:
- Install PostgreSQL 16 from the official repository
- Set up four PostgreSQL clusters for different environments
| Cluster | Purpose | Port | Data Directory |
|---|---|---|---|
| cosmodev | Development | 5445 | /pgdata/16/cosmodev |
| cosmouat | UAT Testing | 5446 | /pgdata/16/cosmouat |
| cosmoprod | Production | 5447 | /pgdata/16/cosmoprod |
| cosmobackup | Backup/Archive | 5448 | /pgdata/16/cosmobackup |
📖 THEORY SECTION - DO NOT PRACTICE YET
The next section explains important concepts about PostgreSQL repositories, pg_ctl, and initdb.
Please READ and UNDERSTAND these concepts first.
The hands-on practice section starts later with a clear "START PRACTICING HERE" marker.
Understanding the Basics
Before we begin the installation, let's understand the key concepts and tools we'll be using.
PostgreSQL Repository (PGDG)
What is a Repository? A repository is a storage location from which your system retrieves and installs software packages. Think of it as an app store for Linux.
Why do we need the PostgreSQL Repository?
- Rocky Linux comes with built-in repositories, but they contain older versions of PostgreSQL
- The official PostgreSQL Global Development Group (PGDG) repository provides the latest versions
- PGDG repository is maintained by the PostgreSQL community
- It ensures you get the most recent features, performance improvements, and security patches
What happens when you install the repository?
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
This command:
- Downloads the repository configuration file
- Installs it to
/etc/yum.repos.d/ - Tells your system where to find PostgreSQL packages
- Enables access to multiple PostgreSQL versions (12, 13, 14, 15, 16, 17)
Why disable the built-in PostgreSQL module?
sudo dnf -qy module disable postgresql
Rocky Linux 9 has a built-in PostgreSQL module that conflicts with PGDG packages. Disabling it ensures the system uses PGDG versions instead.
pg_ctl - PostgreSQL Control Utility
What is pg_ctl?pg_ctl is PostgreSQL's built-in control utility that directly manages the PostgreSQL server process.
What does it do?
- Starts and stops the PostgreSQL server
- Initializes database clusters
- Reloads configuration
- Promotes standbys to primary
- Direct control without systemd
Basic pg_ctl syntax:
/usr/pgsql-16/bin/pg_ctl -D /path/to/data/directory <action>
Common pg_ctl commands:
# Start PostgreSQL
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmodev start
# Stop PostgreSQL (3 shutdown modes)
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmodev stop -m smart # Wait for clients to disconnect
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmodev stop -m fast # Disconnect clients gracefully
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmodev stop -m immediate # Force shutdown (emergency)
# Restart PostgreSQL
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmodev restart
# Reload configuration (no restart needed)
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmodev reload
# Check status
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmodev status
Shutdown modes explained:
| Mode | Flag | Behavior | Use Case |
|---|---|---|---|
| Smart | -m smart | Waits for all clients to disconnect | Safest, but slowest |
| Fast | -m fast | Disconnects clients, rolls back transactions | Recommended for most situations |
| Immediate | -m immediate | Kills all processes immediately | Emergency only! |
initdb - Database Cluster Initialization
What is initdb?initdb creates a new database cluster. A cluster is a collection of databases managed by a single PostgreSQL server instance.
What does initdb create?
- System Catalogs: Internal tables that track databases, users, tables
- Template Databases: template0, template1, postgres
- Configuration Files: postgresql.conf, pg_hba.conf
- Directory Structure: All necessary subdirectories
- Initial WAL Files: Write-Ahead Log for transactions
Running initdb:
/usr/pgsql-16/bin/initdb -D /pgdata/16/cosmodev
- Creates cluster in custom location
- Uses default port 5432 (we'll change this)
- Requires manual configuration
Dynamic vs Static Parameters
PostgreSQL has two types of configuration parameters:
| Type | Reload OK? | Restart Required? | Examples |
|---|---|---|---|
| Dynamic | ✅ Yes | No | log_statement, work_mem |
| Static | ❌ No | Yes | shared_buffers, max_connections, port |
🚀 START PRACTICING HERE
You have completed the theory section. Now begin the hands-on installation!
Follow the instructions below step by step.
Part 1: Install PostgreSQL Repository
First, we need to add the official PostgreSQL repository to get the latest version.
Step 1.1: Add the PGDG Repository
# Download and install the PostgreSQL repository configuration
# This tells Rocky Linux where to find PostgreSQL packages
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
Step 1.2: Disable the Built-in PostgreSQL Module
# Rocky Linux has a built-in PostgreSQL module that conflicts with PGDG
# We need to disable it to use the newer version from PGDG
sudo dnf -qy module disable postgresql
Step 1.3: Verify the Repository is Installed
# Check that the repository package is installed
rpm -qa | grep pgdg-redhat-repo
You should see something like: pgdg-redhat-repo-42.0-38PGDG.noarch
Part 2: Install PostgreSQL 16 Packages
Now we can install PostgreSQL 16 from the PGDG repository.
Step 2.1: Install PostgreSQL Server and Client
# Install PostgreSQL 16 server, client, and contrib packages
# -server: The database server itself
# (base package): Client tools like psql
# -contrib: Additional useful extensions and utilities
sudo dnf install -y postgresql16-server postgresql16 postgresql16-contrib
Step 2.2: Verify the Installation
# List all installed PostgreSQL 16 packages
rpm -qa | grep postgresql16
You should see packages like:
postgresql16-server-16.xpostgresql16-16.xpostgresql16-contrib-16.x
Step 2.3: Check PostgreSQL Binary Location
# Verify the PostgreSQL binaries are installed
ls /usr/pgsql-16/bin/
You should see tools like: initdb, pg_ctl, psql, postgres
Part 3: Create the Base Directory Structure
Before creating clusters, we need to prepare the directory structure where all our PostgreSQL data will live.
Step 3.1: Create the Parent Directory
# Create the parent directory for all PostgreSQL cluster data
# The -p flag creates parent directories if they don't exist
sudo mkdir -p /pgdata/16
Step 3.2: Set Ownership
# Change ownership to postgres user and group
# PostgreSQL runs as 'postgres' user, so it needs to own these directories
sudo chown postgres:postgres /pgdata/16
Step 3.3: Set Permissions
# Set permissions to 700 (owner can read/write/execute, no one else)
# This is a security requirement - PostgreSQL won't start if permissions are too open
sudo chmod 700 /pgdata/16
Step 3.4: Verify the Directory
# List directory details to confirm ownership and permissions
# Should show: drwx------ postgres postgres
ls -ld /pgdata/16
Step 3.5: Switch to postgres User
# Switch to the postgres user
# All PostgreSQL operations should be done as this user
sudo su - postgres
Important: From this point forward, all commands should be run as the postgres user unless otherwise specified.
Part 4: Cluster Initialization - cosmodev (Port 5445)
Scenario: CosmoTech is setting up a development environment for testing new features.
Step 4.1: Initialize the Cluster
# Initialize a new PostgreSQL cluster in the cosmodev directory
# initdb creates the database cluster structure including:
# - Configuration files (postgresql.conf, pg_hba.conf)
# - System catalogs
# - Template databases
/usr/pgsql-16/bin/initdb -D /pgdata/16/cosmodev
You should see output ending with:
Success. You can now start the database server using:
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmodev start
Step 4.2: Navigate to the Cluster Directory
# Change to the cluster's data directory
# This is where all configuration files are located
cd /pgdata/16/cosmodev
# List the files to see what initdb created
ls -la
You should see files including postgresql.conf, pg_hba.conf, and directories like base, global, etc.
Step 4.3: Edit postgresql.conf to Change the Port
# Open the main PostgreSQL configuration file in vi editor
vi postgresql.conf
Inside vi, follow these steps:
- Press
/to enter search mode - Type
portand press Enter to find the port setting - You should see a line like:
#port = 5432 - Press
ito enter insert mode - Remove the
#at the beginning (this uncomments the line) - Change
5432to5445 - The line should now read:
port = 5445 - Press
Escto exit insert mode - Type
:wqand press Enter to save and quit
vi Quick Reference:
/text- Search for "text"i- Enter insert modeEsc- Exit insert mode:wq- Save and quit:q!- Quit without saving
Step 4.4: Verify the Port Change
# Confirm the port was changed correctly
# grep searches for lines containing "port" in the file
# The ^ means "start of line" to avoid matching commented lines
grep "^port" postgresql.conf
Expected output: port = 5445
Step 4.5: Configure Logging
# Create a directory to store PostgreSQL log files
# Keeping logs organized helps with troubleshooting
mkdir -p /pgdata/16/cosmodev/logs
# Open postgresql.conf again to configure logging
vi postgresql.conf
Inside vi, add these lines at the end of the file:
- Press Shift +
Gto go to the end of the file - Press
oto create a new line and enter insert mode - Add these lines:
# Enable the logging collector process
logging_collector = on
# Directory where log files will be stored
log_directory = 'logs'
# Log filename pattern with date
log_filename = 'postgresql-%Y-%m-%d.log'
- Press
Escthen type:wqto save and quit
Step 4.6: Start the Cluster
# Start the PostgreSQL cluster
# -D specifies the data directory
# -l specifies the log file location
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmodev -l /pgdata/16/cosmodev/logs/postgresql.log start
You should see: server started
Step 4.7: Verify the Cluster is Running
# Check the status of the cluster
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmodev status
# Connect to the database and verify the version
# -p specifies the port to connect to
psql -p 5445 -c "SELECT version();"
# Verify we're connected on the correct port
psql -p 5445 -c "SHOW port;"
Part 5: Cluster Initialization - cosmouat (Port 5446)
Scenario: The UAT environment requires a cluster with slow query logging enabled. Any query taking longer than 500ms should be logged for performance analysis.
Step 5.1: Initialize the Cluster
# Initialize the UAT cluster
# Each cluster needs its own data directory
/usr/pgsql-16/bin/initdb -D /pgdata/16/cosmouat
Step 5.2: Navigate to the Cluster Directory
# Change to the UAT cluster directory
cd /pgdata/16/cosmouat
Step 5.3: Edit postgresql.conf for Port and Slow Query Logging
# Open the configuration file
vi postgresql.conf
Inside vi:
- Search for port: Press
/, typeport, press Enter - Uncomment and change to:
port = 5446 - Press Shift +
Gto go to end of file - Press
oto add new lines:
# Logging configuration for UAT
logging_collector = on
log_directory = 'logs'
log_filename = 'postgresql-%Y-%m-%d.log'
# SLOW QUERY LOGGING
# Log any query that takes longer than 500 milliseconds
# This helps identify performance problems
log_min_duration_statement = 500
- Press
Escthen:wqto save
Step 5.4: Verify Configuration
# Check the port setting
grep "^port" postgresql.conf
# Check the slow query logging setting
grep "^log_min_duration" postgresql.conf
Step 5.5: Create Logs Directory and Start
# Create the logs directory
mkdir -p /pgdata/16/cosmouat/logs
# Start the UAT cluster
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmouat -l /pgdata/16/cosmouat/logs/postgresql.log start
Step 5.6: Verify
# Check if cluster is running
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmouat status
# Verify slow query logging is enabled
psql -p 5446 -c "SHOW log_min_duration_statement;"
Expected output: 500ms
Part 6: Cluster Initialization - cosmoprod (Port 5447)
Scenario: The production environment requires maximum stability with daily log rotation to manage disk space.
Step 6.1: Initialize the Cluster
# Initialize the production cluster
/usr/pgsql-16/bin/initdb -D /pgdata/16/cosmoprod
Step 6.2: Navigate and Edit Configuration
# Change to the production cluster directory
cd /pgdata/16/cosmoprod
# Open the configuration file
vi postgresql.conf
Inside vi:
- Search for port:
/portthen Enter - Uncomment and change to:
port = 5447 - Go to end of file: Shift +
G - Add new lines:
o
# Production logging with daily rotation
logging_collector = on
log_directory = 'logs'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
# LOG ROTATION SETTINGS
# Rotate log files every 1 day
# This prevents log files from growing too large
log_rotation_age = 1d
# Set to 0 to disable size-based rotation (only use time-based)
log_rotation_size = 0
- Save and quit:
Escthen:wq
Step 6.3: Create Logs Directory and Start
# Create logs directory for production
mkdir -p /pgdata/16/cosmoprod/logs
# Start the production cluster
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmoprod -l /pgdata/16/cosmoprod/logs/postgresql.log start
Step 6.4: Verify
# Check cluster status
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmoprod status
# Verify log rotation setting
psql -p 5447 -c "SHOW log_rotation_age;"
Expected output: 1d
Part 7: Cluster Initialization - cosmobackup (Port 5448)
Scenario: A dedicated cluster for backup operations with archive mode enabled. For this cluster, we'll demonstrate using sed to edit configuration and set up the bash profile for convenience.
Step 7.1: Initialize the Cluster
# Initialize the backup cluster
/usr/pgsql-16/bin/initdb -D /pgdata/16/cosmobackup
Step 7.2: Use sed to Change the Port (Alternative Method)
Instead of manually editing with vi, we can use sed (stream editor) to make changes automatically:
# Use sed to uncomment and change the port in one command
# Explanation:
# sed -i = Edit file in-place (modify the actual file)
# "s/old/new/" = Substitute 'old' with 'new'
# #port = 5432 = The original commented line
# port = 5448 = What we want it to become
sed -i "s/#port = 5432/port = 5448/" /pgdata/16/cosmobackup/postgresql.conf
# Verify the change worked
grep "^port" /pgdata/16/cosmobackup/postgresql.conf
Expected output: port = 5448
When to use sed vs vi:
- sed: Great for automated scripts and single-line changes
- vi: Better for manual editing and complex changes
Step 7.3: Add Logging and Archive Configuration with vi
# Navigate to the cluster directory
cd /pgdata/16/cosmobackup
# Create logs directory
mkdir -p logs
# Open configuration for remaining settings
vi postgresql.conf
Inside vi, add at the end:
# Logging configuration
logging_collector = on
log_directory = 'logs'
# ARCHIVE MODE CONFIGURATION
# Enable WAL (Write-Ahead Log) archiving
# This is essential for point-in-time recovery
archive_mode = on
# Archive command - what to do with completed WAL files
# '/bin/true' is a placeholder that always succeeds
# In production, you would use: archive_command = 'cp %p /archive/%f'
archive_command = '/bin/true'
Save and quit: Esc then :wq
Step 7.4: Start the Cluster
# Start the backup cluster
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmobackup -l /pgdata/16/cosmobackup/logs/postgresql.log start
Step 7.5: Verify
# Check cluster status
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmobackup status
# Verify archive mode is enabled
psql -p 5448 -c "SHOW archive_mode;"
Expected output: on
Part 8: Setting Up Bash Profile for Convenience
Typing the full path /usr/pgsql-16/bin/pg_ctl every time is tedious. Let's set up the bash profile so we can just type pg_ctl directly.
Step 8.1: Edit the Bash Profile
# Open the postgres user's bash profile
# This file runs every time you log in as postgres
vi ~/.bash_profile
Add these lines at the end of the file:
# PostgreSQL 16 Environment Variables
# These settings make it easier to work with PostgreSQL
# Add PostgreSQL binaries to PATH
# This lets us run pg_ctl, psql, etc. without full path
export PATH=/usr/pgsql-16/bin:$PATH
# Set default data directory for pg_ctl
# Now pg_ctl knows which cluster to manage by default
export PGDATA=/pgdata/16/cosmobackup
# Set default port
# psql will connect to this port by default
export PGPORT=5448
# Optional: Set default database
export PGDATABASE=postgres
Save and quit: Esc then :wq
Step 8.2: Apply the Changes
# Source the profile to apply changes immediately
# Without this, you'd have to log out and back in
source ~/.bash_profile
Step 8.3: Verify the Setup
# Check that PATH is updated
echo $PATH | grep pgsql
# Now we can use pg_ctl without the full path!
pg_ctl status
# And psql connects to the default port automatically
psql -c "SHOW port;"
Congratulations! With the bash profile configured, you can now:
- Use
pg_ctlinstead of/usr/pgsql-16/bin/pg_ctl - Use
psqlwithout specifying-p 5448 - Use
initdbinstead of/usr/pgsql-16/bin/initdb
Part 9: Port Verification - All Clusters
Let's verify all four clusters are running on their designated ports.
Step 9.1: Check All Ports with ss
# Use ss (socket statistics) to show listening ports
# -t = TCP connections
# -u = UDP connections
# -l = Listening sockets
# -n = Show port numbers (not service names)
# -p = Show process using the socket
ss -tulnp | grep postgres
You should see all four ports: 5445, 5446, 5447, 5448
Step 9.2: Test Connectivity to Each Cluster
# Test each cluster by connecting and showing its port
# We need to specify -p for clusters that aren't the default
echo "=== Testing cosmodev (5445) ==="
psql -p 5445 -c "SELECT 'cosmodev' as cluster, current_setting('port') as port;"
echo "=== Testing cosmouat (5446) ==="
psql -p 5446 -c "SELECT 'cosmouat' as cluster, current_setting('port') as port;"
echo "=== Testing cosmoprod (5447) ==="
psql -p 5447 -c "SELECT 'cosmoprod' as cluster, current_setting('port') as port;"
echo "=== Testing cosmobackup (5448) ==="
psql -p 5448 -c "SELECT 'cosmobackup' as cluster, current_setting('port') as port;"
Part 10: Dynamic Parameter Update - cosmodev
Scenario: Developers need verbose logging. Set log_statement = 'all' to log every SQL statement.
Dynamic vs Static Parameters:
- Dynamic parameters can be changed with
reload(no restart needed) - Static parameters require a full cluster
restart log_statementis dynamic,shared_buffersis static
Step 10.1: Navigate and Edit Configuration
# Change to cosmodev directory
cd /pgdata/16/cosmodev
# Open configuration file
vi postgresql.conf
Add at the end of the file:
# LOG ALL SQL STATEMENTS
# Options: none, ddl, mod, all
# 'all' logs every statement - useful for debugging
log_statement = 'all'
Save and quit: Esc then :wq
Step 10.2: Reload Configuration (No Restart Needed!)
# Reload configuration without stopping the cluster
# This only works for dynamic parameters
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmodev reload
You should see: server signaled
Step 10.3: Verify the Change
# Connect and check the setting
psql -p 5445 -c "SHOW log_statement;"
Expected output: all
Part 11: Static Parameter Update - cosmouat
Scenario: The UAT team needs more memory for performance testing. Increase shared_buffers to 1GB.
Important: shared_buffers is a static parameter. The cluster must be restarted for changes to take effect. A simple reload will NOT work!
Step 11.1: Check Current Value
# See current shared_buffers setting
psql -p 5446 -c "SHOW shared_buffers;"
This will likely show a small value like 128MB.
Step 11.2: Edit Configuration
# Change to cosmouat directory
cd /pgdata/16/cosmouat
# Open configuration file
vi postgresql.conf
Add at the end of the file:
# MEMORY CONFIGURATION
# shared_buffers: Memory for caching data
# Recommended: 25% of total RAM, but not more than 8GB
# This is a STATIC parameter - requires restart!
shared_buffers = 1GB
Save and quit: Esc then :wq
Step 11.3: Restart the Cluster (Required for Static Parameters!)
# Restart the cluster - reload won't work for static parameters!
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmouat -l /pgdata/16/cosmouat/logs/postgresql.log restart
Step 11.4: Verify the Change
# Connect and verify the new setting
psql -p 5446 -c "SHOW shared_buffers;"
Expected output: 1GB
Part 12: Stopping and Starting cosmoprod (Maintenance)
Scenario: Scheduled maintenance requires safely stopping the production cluster.
Step 12.1: Check for Active Connections
# Before stopping, check if anyone is connected
# This query shows all active connections
psql -p 5447 -c "SELECT pid, usename, application_name, state, query
FROM pg_stat_activity
WHERE state != 'idle';"
Step 12.2: Stop the Cluster
# Stop the production cluster using fast mode
# Shutdown modes:
# smart - Wait for clients to disconnect (safest, slowest)
# fast - Disconnect clients, rollback transactions (recommended)
# immediate - Kill all processes immediately (emergency only!)
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmoprod stop -m fast
You should see: server stopped
Step 12.3: Verify the Cluster is Stopped
# Check status - should show "no server running"
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmoprod status
Step 12.4: Check the Logs for Clean Shutdown
# Look at the last few lines of the log
# Should see "database system is shut down"
tail -10 /pgdata/16/cosmoprod/logs/postgresql.log
Step 12.5: Start the Cluster Again
# Start production back up after maintenance
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmoprod -l /pgdata/16/cosmoprod/logs/postgresql.log start
Step 12.6: Verify It's Running
# Confirm the cluster is running
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmoprod status
# Test connectivity
psql -p 5447 -c "SELECT 'Production is ONLINE!' as status, now() as current_time;"
Part 13: Creating a New Database - cosmodev
Scenario: A new microservice needs its own database called cosmodb.
Step 13.1: Connect and Create the Database
# Connect to cosmodev cluster and create a new database
# CREATE DATABASE creates a new database by copying template1
psql -p 5445 -c "CREATE DATABASE cosmodb;"
You should see: CREATE DATABASE
Step 13.2: Verify the Database Exists
# Query the system catalog to confirm the database was created
psql -p 5445 -c "SELECT datname, datdba, encoding FROM pg_database WHERE datname = 'cosmodb';"
Step 13.3: Connect to the New Database
# Connect directly to the new database
# -d specifies the database name
psql -p 5445 -d cosmodb -c "SELECT current_database();"
Expected output: cosmodb
Part 14: Comprehensive Maintenance - cosmoprod
Scenario: Full maintenance cycle - update work_mem to 64MB for better sort performance.
About work_mem:
- Memory used for sort operations and hash tables
- This is per-operation, not per-connection!
- If 100 connections each run complex queries, memory usage = 100 × 64MB
work_memis a dynamic parameter - reload works!
Step 14.1: Check Current Value
# See current work_mem setting
psql -p 5447 -c "SHOW work_mem;"
Default is usually 4MB.
Step 14.2: Edit Configuration
# Change to cosmoprod directory
cd /pgdata/16/cosmoprod
# Open configuration file
vi postgresql.conf
Add at the end of the file:
# WORK MEMORY
# Memory for internal sort operations and hash tables
# Higher values = faster sorts, but uses more memory
# Be careful: this is PER OPERATION, not per connection!
work_mem = 64MB
Save and quit: Esc then :wq
Step 14.3: Reload Configuration
# Reload - work_mem is dynamic so no restart needed
/usr/pgsql-16/bin/pg_ctl -D /pgdata/16/cosmoprod reload
Step 14.4: Verify the Change
# Confirm the new setting
psql -p 5447 -c "SHOW work_mem;"
Expected output: 64MB
Step 14.5: Check Logs for Any Issues
# Always check logs after configuration changes
tail -20 /pgdata/16/cosmoprod/logs/postgresql.log
Summary
Congratulations! You've completed the CosmoTech PostgreSQL Cluster Management training!
What You Accomplished
| Cluster | Port | Key Configurations |
|---|---|---|
| cosmodev | 5445 | log_statement = 'all', cosmodb database |
| cosmouat | 5446 | slow query logging (500ms), shared_buffers = 1GB |
| cosmoprod | 5447 | daily log rotation, work_mem = 64MB |
| cosmobackup | 5448 | archive_mode = on, bash profile configured |
Skills Mastered
- ✅ PostgreSQL 16 installation from PGDG repository
- ✅ Cluster initialization with
initdb - ✅ Manual configuration editing with
vi - ✅ Automated editing with
sed - ✅ Understanding dynamic vs static parameters
- ✅ Cluster lifecycle with
pg_ctl(start, stop, restart, reload) - ✅ Bash profile configuration for convenience
- ✅ Database creation
- ✅ Production maintenance procedures
Quick Reference
pg_ctl Commands
| Command | Description |
|---|---|
pg_ctl -D <path> start | Start the cluster |
pg_ctl -D <path> stop | Stop (smart mode) |
pg_ctl -D <path> stop -m fast | Stop (fast mode) |
pg_ctl -D <path> restart | Restart the cluster |
pg_ctl -D <path> reload | Reload configuration |
pg_ctl -D <path> status | Check if running |
Dynamic vs Static Parameters
| Dynamic (reload OK) | Static (restart required) |
|---|---|
| log_statement | shared_buffers |
| work_mem | max_connections |
| log_min_duration_statement | port |
| log_min_messages | archive_mode |
Port Assignments
cosmodev → 5445
cosmouat → 5446
cosmoprod → 5447
cosmobackup → 5448
vi Quick Reference
| Command | Action |
|---|---|
i | Enter insert mode |
Esc | Exit insert mode |
/text | Search for "text" |
G | Go to end of file |
gg | Go to beginning |
:wq | Save and quit |
:q! | Quit without saving |
About the Author
More tutorials you might like

How Container Filesystem Works: Building a Docker-like Container From Scratch
Learn how Linux containers are built from the ground up. Starting with the mount namespace and a root filesystem, see why PID, cgroup, UTS, and network namespaces naturally follow - and how this foundation makes concepts like bind mounts, volumes, and persistence in Docker or Kubernetes much easier to grasp.

How Container Networking Works: Building a Bridge Network From Scratch
Begin with the basics to understand Docker and Kubernetes networking: learn how to create and interconnect Linux network namespaces using only command-line tools.

How Servers Work: A Hands-On Introduction to TCP Sockets
Learn how servers actually work by building a tiny TCP server and client from scratch. A hands-on introduction to sockets, TCP, and the network programming model every backend, DevOps, and platform engineer should go through at least once.

Controlling Process Resources with Linux Control Groups
Learn how to limit process resources using Linux cgroups - from the most basic and labour-intensive cgroupfs manipulation to the handiest systemd-run command.
Learn by doing, not just by reading or watching
Sign up for a free account to start a VM playground right on this page, track your progress, and get notified about new learning materials.