Bài 5: Cài đặt PostgreSQL

Cài đặt PostgreSQL từ package repository hoặc source, cấu hình postgresql.conf và pg_hba.conf trên cả 3 nodes trong cluster.

8 min read
XDEV ASIA

Bài 5: Cài đặt PostgreSQL

Mục tiêu

Sau bài học này, bạn sẽ:

  • Cài đặt PostgreSQL từ package repository
  • Hiểu cách cài đặt PostgreSQL từ source (optional)
  • Cấu hình postgresql.conf cơ bản cho HA
  • Hiểu về pg_hba.conf và authentication
  • Chuẩn bị PostgreSQL trên 3 nodes cho Patroni cluster

1. Cài đặt PostgreSQL từ Package Repository

1.1. Chuẩn bị

Trước khi cài đặt PostgreSQL, cần setup package repository chính thức của PostgreSQL (PGDG - PostgreSQL Global Development Group).

Ưu điểm của PGDG repository:

  • ✅ Phiên bản PostgreSQL mới nhất
  • ✅ Cập nhật bảo mật nhanh chóng
  • ✅ Nhiều extensions có sẵn
  • ✅ Support nhiều distros

1.2. Cài đặt trên Ubuntu/Debian

Bước 1: Thêm PGDG repository

# Import repository signing key
sudo apt install -y wget gnupg2

sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'

wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -

# Update package list
sudo apt update

Bước 2: Cài đặt PostgreSQL

# Cài PostgreSQL 18 (khuyến nghị cho production)
sudo apt install -y postgresql-18 postgresql-contrib-15 postgresql-server-dev-15

# Kiểm tra version
psql --version
# Output: psql (PostgreSQL) 15.5

Bước 3: Kiểm tra service

# Kiểm tra status
sudo systemctl status postgresql

# Output:
# ● postgresql.service - PostgreSQL RDBMS
#      Loaded: loaded (/lib/systemd/system/postgresql.service; enabled)
#      Active: active (exited) since ...

Bước 4: Dừng và disable PostgreSQL default cluster

# Patroni sẽ quản lý PostgreSQL, nên ta disable service mặc định
sudo systemctl stop postgresql
sudo systemctl disable postgresql

# Xóa cluster mặc định (Patroni sẽ tạo cluster mới)
sudo pg_dropcluster 15 main --stop

# Kiểm tra
pg_lsclusters
# Output: (empty - no clusters)

1.3. Cài đặt trên CentOS/RHEL/Rocky Linux

Bước 1: Thêm PGDG repository

# Cài đặt EPEL (Extra Packages for Enterprise Linux)
sudo dnf install -y epel-release

# Thêm PostgreSQL 18 repository
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm

# Disable built-in PostgreSQL module
sudo dnf -qy module disable postgresql

Bước 2: Cài đặt PostgreSQL

# Cài PostgreSQL 18
sudo dnf install -y postgresql15-server postgresql15-contrib postgresql15-devel

# Kiểm tra
/usr/pgsql-15/bin/postgres --version
# Output: postgres (PostgreSQL) 15.5
# Tạo symlink cho các binary vào PATH
sudo alternatives --install /usr/bin/psql psql /usr/pgsql-15/bin/psql 1
sudo alternatives --install /usr/bin/pg_config pg_config /usr/pgsql-15/bin/pg_config 1
sudo alternatives --install /usr/bin/pg_basebackup pg_basebackup /usr/pgsql-15/bin/pg_basebackup 1

Bước 4: Không khởi tạo database (Patroni sẽ làm)

# KHÔNG chạy:
# sudo /usr/pgsql-15/bin/postgresql-18-setup initdb

# KHÔNG enable service:
# sudo systemctl enable postgresql-18

2. Cài đặt PostgreSQL từ Source (Optional - Advanced)

Cài từ source cho phép custom compile options, nhưng phức tạp hơn và khó maintain.

2.1. Khi nào cần cài từ source?

  • 🔧 Cần custom features không có trong binary package
  • 🔧 Testing với development version
  • 🔧 Tối ưu cho hardware cụ thể
  • 🔧 Apply custom patches

2.2. Quy trình cài từ source

Bước 1: Cài dependencies

# Ubuntu/Debian
sudo apt install -y build-essential libreadline-dev zlib1g-dev \
  flex bison libxml2-dev libxslt-dev libssl-dev libxml2-utils \
  xsltproc libkrb5-dev libldap2-dev libpam0g-dev libperl-dev \
  python3-dev tcl-dev libsystemd-dev

# CentOS/RHEL
sudo dnf install -y gcc make readline-devel zlib-devel openssl-devel \
  libxml2-devel libxslt-devel systemd-devel perl-ExtUtils-Embed \
  python3-devel

Bước 2: Download source

cd /usr/local/src
sudo wget https://ftp.postgresql.org/pub/source/v15.5/postgresql-18.5.tar.gz
sudo tar -xzf postgresql-18.5.tar.gz
cd postgresql-18.5

Bước 3: Configure và compile

# Configure với options
sudo ./configure \
  --prefix=/usr/local/pgsql-15 \
  --with-openssl \
  --with-libxml \
  --with-systemd \
  --with-readline \
  --enable-nls

# Compile (sử dụng nhiều cores)
sudo make -j$(nproc)

# Chạy tests (optional)
sudo make check

# Install
sudo make install

# Install contrib modules
cd contrib
sudo make install

Bước 4: Setup environment

# Thêm vào ~/.bashrc
export PATH=/usr/local/pgsql-15/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/pgsql-15/lib:$LD_LIBRARY_PATH

source ~/.bashrc

Lưu ý: Cài từ source không tự động có systemd service, cần tạo manually.

3. Cấu hình postgresql.conf cơ bản

Patroni sẽ quản lý hầu hết cấu hình PostgreSQL thông qua DCS. Tuy nhiên, cần hiểu các parameters quan trọng.

3.1. Cấu trúc file postgresql.conf

# /etc/postgresql/18/main/postgresql.conf
# hoặc: /var/lib/pgsql/15/data/postgresql.conf

#------------------------------------------------------------------------------
# FILE LOCATIONS
#------------------------------------------------------------------------------
data_directory = '/var/lib/postgresql/18/main'
hba_file = '/etc/postgresql/18/main/pg_hba.conf'
ident_file = '/etc/postgresql/18/main/pg_ident.conf'

#------------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION
#------------------------------------------------------------------------------
listen_addresses = '*'          # Lắng nghe trên tất cả interfaces
port = 5432
max_connections = 100           # Số connections tối đa

3.2. Parameters quan trọng cho HA

Replication Settings

#------------------------------------------------------------------------------
# WRITE-AHEAD LOG (WAL)
#------------------------------------------------------------------------------
wal_level = replica              # Mức độ thông tin trong WAL
                                 # minimal, replica, hoặc logical

fsync = on                       # Đảm bảo WAL được flush to disk
synchronous_commit = on          # Wait cho WAL write confirmation

wal_log_hints = on              # Cần cho pg_rewind

#------------------------------------------------------------------------------
# REPLICATION
#------------------------------------------------------------------------------
max_wal_senders = 10            # Số standby servers tối đa
max_replication_slots = 10      # Số replication slots

# WAL keep settings
wal_keep_size = 1GB             # Giữ ít nhất 1GB WAL files
                                # (PG 13+, thay thế wal_keep_segments)

# Archive settings (để PITR)
archive_mode = on
archive_command = 'cp %p /var/lib/postgresql/18/archive/%f'
archive_timeout = 300           # Archive mỗi 5 phút

Memory Settings

#------------------------------------------------------------------------------
# RESOURCE USAGE (MEMORY)
#------------------------------------------------------------------------------
shared_buffers = 2GB            # RAM dành cho PostgreSQL cache
                                # Khuyến nghị: 25% của RAM

effective_cache_size = 6GB      # Ước tính tổng cache (OS + PG)
                                # Khuyến nghị: 50-75% của RAM

work_mem = 16MB                 # RAM cho mỗi query operation
                                # Tổng có thể dùng: work_mem × max_connections

maintenance_work_mem = 512MB    # RAM cho maintenance operations
                                # (VACUUM, CREATE INDEX, etc.)

Checkpoint Settings

#------------------------------------------------------------------------------
# WRITE-AHEAD LOG (Checkpoints)
#------------------------------------------------------------------------------
checkpoint_timeout = 10min      # Tần suất checkpoint tối đa
max_wal_size = 2GB             # WAL size trigger checkpoint
min_wal_size = 1GB             # Giữ ít nhất 1GB WAL

checkpoint_completion_target = 0.9  # Spread checkpoint I/O
                                    # (90% của checkpoint_timeout)

Logging Settings

#------------------------------------------------------------------------------
# REPORTING AND LOGGING
#------------------------------------------------------------------------------
log_destination = 'stderr'
logging_collector = on

log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_rotation_age = 1d
log_rotation_size = 100MB

log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '
log_timezone = 'UTC'

# Log slow queries
log_min_duration_statement = 1000  # Log queries > 1 second

# Log connections/disconnections
log_connections = on
log_disconnections = on

# Log checkpoints (useful for tuning)
log_checkpoints = on

3.3. Patroni sẽ override các settings

Patroni quản lý các parameters sau thông qua DCS, KHÔNG nên set trong postgresql.conf:

# ❌ KHÔNG set trong postgresql.conf khi dùng Patroni
# hot_standby = on
# primary_conninfo = '...'
# restore_command = '...'
# recovery_target_timeline = 'latest'

Patroni sẽ tự động set chúng trong postgresql.auto.conf.

4. Hiểu về pg_hba.conf

pg_hba.conf (Host-Based Authentication) kiểm soát client authentication.

4.1. Cấu trúc của pg_hba.conf

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     peer

# IPv4 local connections:
host    all             all             127.0.0.1/32            scram-sha-256

# IPv4 connections from anywhere (for replication)
host    all             all             0.0.0.0/0               scram-sha-256

# Replication connections
host    replication     replicator      10.0.1.0/24             scram-sha-256

4.2. Các columns

  1. TYPE:
    • local: Unix socket connections
    • host: TCP/IP (clear text or SSL)
    • hostssl: TCP/IP with SSL only
    • hostnossl: TCP/IP without SSL
  2. DATABASE:
    • Database name
    • all: tất cả databases
    • replication: replication connections
  3. USER:
    • Username
    • all: tất cả users
  4. ADDRESS:
    • IP/netmask: 10.0.1.0/24
    • Hostname
    • 0.0.0.0/0: anywhere (không khuyến khích)
  5. METHOD:
    • trust: Không cần password (chỉ dùng local dev)
    • md5: MD5 hashed password (deprecated)
    • scram-sha-256: Modern, secure (khuyến nghị)
    • peer: Unix username = PostgreSQL username
    • cert: SSL certificate authentication

4.3. pg_hba.conf cho Patroni Cluster

# /etc/postgresql/18/main/pg_hba.conf

# Local connections
local   all             postgres                                peer
local   all             all                                     md5

# Localhost
host    all             all             127.0.0.1/32            scram-sha-256
host    all             all             ::1/128                 scram-sha-256

# Application connections
host    all             app_user        10.0.1.0/24             scram-sha-256

# Patroni REST API health checks (optional database connection)
host    postgres        patroni_user    10.0.1.0/24             scram-sha-256

# Replication connections (Patroni nodes)
host    replication     replicator      10.0.1.11/32            scram-sha-256
host    replication     replicator      10.0.1.12/32            scram-sha-256
host    replication     replicator      10.0.1.13/32            scram-sha-256

# Monitoring connections (Prometheus exporter)
host    postgres        exporter        10.0.1.0/24             scram-sha-256

4.4. Best practices cho pg_hba.conf

✅ Specific is better: Không dùng 0.0.0.0/0 nếu không cần

✅ Use scram-sha-256: Modern authentication method

✅ Separate users: User khác nhau cho app, replication, monitoring

✅ Document: Comment cho mỗi rule

✅ Restrict replication: Chỉ cho phép replication user từ IP của Patroni nodes

❌ Avoid trust method: Kể cả trong dev environment

5. Tạo users và databases cần thiết

5.1. Tạo replication user

# Sau khi Patroni bootstrap cluster, connect đến primary:
sudo -u postgres psql -h localhost -p 5432

# Trong psql:
CREATE ROLE replicator WITH REPLICATION LOGIN ENCRYPTED PASSWORD 'your_strong_password';

# Kiểm tra
\du replicator

5.2. Tạo Patroni monitoring user

-- User cho Patroni health checks
CREATE USER patroni_user WITH ENCRYPTED PASSWORD 'patroni_password';
GRANT CONNECT ON DATABASE postgres TO patroni_user;

5.3. Tạo application database và user

-- Tạo database
CREATE DATABASE myapp;

-- Tạo user
CREATE USER app_user WITH ENCRYPTED PASSWORD 'app_password';

-- Grant permissions
GRANT ALL PRIVILEGES ON DATABASE myapp TO app_user;

-- Connect to myapp database
\c myapp

-- Grant schema permissions
GRANT ALL ON SCHEMA public TO app_user;

6. Lab: Cài đặt PostgreSQL trên 3 nodes

6.1. Môi trường Lab

node1 (pg-node1): 10.0.1.11  - Primary (sau khi bootstrap)
node2 (pg-node2): 10.0.1.12  - Replica
node3 (pg-node3): 10.0.1.13  - Replica

6.2. Thực hiện trên TẤT CẢ 3 nodes

Bước 1: Update system

sudo apt update && sudo apt upgrade -y

Bước 2: Cài PostgreSQL 18

# Thêm repo
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'

wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -

sudo apt update

# Cài đặt
sudo apt install -y postgresql-18 postgresql-contrib-15 postgresql-server-dev-15

Bước 3: Stop và disable default cluster

sudo systemctl stop postgresql
sudo systemctl disable postgresql

sudo pg_dropcluster 15 main --stop

# Verify
pg_lsclusters
# Output: (should be empty)

Bước 4: Tạo thư mục cho PostgreSQL data

# Patroni sẽ quản lý data directory, nhưng ta tạo structure
sudo mkdir -p /var/lib/postgresql/18/data
sudo mkdir -p /var/lib/postgresql/18/archive

sudo chown -R postgres:postgres /var/lib/postgresql
sudo chmod 700 /var/lib/postgresql/18/data

Bước 5: Kiểm tra PostgreSQL binary

# Kiểm tra version
postgres --version
# Output: postgres (PostgreSQL) 15.5

# Kiểm tra các tools
which psql pg_basebackup pg_rewind

6.3. Verify trên mỗi node

# Node name
hostname

# PostgreSQL version
postgres --version

# Directories
ls -ld /var/lib/postgresql/18/data
ls -ld /var/lib/postgresql/18/archive

# PostgreSQL service
systemctl status postgresql
# Output: inactive (dead) ✓

6.4. Troubleshooting

Issue 1: Permission denied trên data directory

# Fix ownership
sudo chown -R postgres:postgres /var/lib/postgresql
sudo chmod 700 /var/lib/postgresql/18/data

Issue 2: PostgreSQL service vẫn running

# Stop forcefully
sudo systemctl stop postgresql@15-main
sudo systemctl disable postgresql@15-main

# Kill processes nếu cần
sudo pkill -9 postgres

Issue 3: Port 5432 đã bị sử dụng

# Kiểm tra process sử dụng port
sudo lsof -i :5432

# Hoặc
sudo netstat -tlnp | grep 5432

7. Tổng kết

Key Takeaways

✅ Package repository: Cài PostgreSQL từ PGDG repo để có version mới nhất

✅ Disable default service: Patroni sẽ quản lý PostgreSQL, không dùng systemd service mặc định

✅ postgresql.conf: Hiểu các parameters quan trọng cho HA và replication

✅ pg_hba.conf: Cấu hình authentication cho connections và replication

✅ Không khởi tạo cluster: Patroni sẽ bootstrap cluster tự động

Checklist sau Lab

  •  PostgreSQL 18 đã cài trên cả 3 nodes
  •  Default cluster đã xóa
  •  PostgreSQL service đã disable
  •  Data directories đã tạo với permissions đúng
  •  Binary paths đã có trong $PATH

Chuẩn bị cho Bài 6

Bài tiếp theo sẽ cài đặt và cấu hình etcd cluster - DCS layer cho Patroni.

postgresql-install postgresql-config pg_hba database-setup lab

Đánh dấu hoàn thành (Bài 5: Cài đặt PostgreSQL)