Hướng dẫn cài đặt và cấu hình PostgreSQL Streaming Replication: Đồng bộ dữ liệu real-time giữa Primary và Standby

Database tutorial - IT technology blog
Database tutorial - IT technology blog

Bối cảnh & Tại sao cần Streaming Replication?

Chào các bạn! Trong môi trường công nghệ hiện đại, dữ liệu đóng vai trò cực kỳ quan trọng đối với mọi ứng dụng. Dù bạn đang phát triển một website thương mại điện tử, một hệ thống quản lý nội bộ hay một ứng dụng di động, việc đảm bảo dữ liệu luôn có sẵn và không bị mất mát là ưu tiên số một.

Tôi từng làm việc với nhiều cơ sở dữ liệu như MySQL, PostgreSQL và MongoDB. Mỗi loại đều có thế mạnh riêng, phù hợp với từng nhu cầu cụ thể. Tuy nhiên, bất kể lựa chọn là gì, chúng ta đều cần một giải pháp bảo vệ dữ liệu mạnh mẽ để phòng tránh những sự cố bất ngờ.

Hãy thử tưởng tượng: nếu server chính gặp sự cố, việc khôi phục dữ liệu từ bản backup có thể kéo dài vài giờ, thậm chí cả ngày. Trong khoảng thời gian đó, ứng dụng ngừng hoạt động. Điều này có thể khiến một website thương mại điện tử mất hàng trăm triệu đồng doanh thu mỗi giờ, chưa kể ảnh hưởng tiêu cực đến trải nghiệm và lòng tin của người dùng. Đây chính là lý do các giải pháp High Availability (HA – Tính sẵn sàng cao) và Disaster Recovery (DR – Phục hồi thảm họa) trở nên cực kỳ quan trọng.

PostgreSQL Streaming Replication là một giải pháp cực kỳ hiệu quả để giải quyết thách thức này. Thay vì chỉ dựa vào các bản backup định kỳ, Streaming Replication cho phép bạn duy trì một hoặc nhiều máy chủ phụ (Standby) luôn được đồng bộ hóa gần như ngay lập tức với máy chủ chính (Primary).

Mọi thay đổi trên Primary sẽ được truyền đến Standby liên tục. Nhờ đó, khi Primary gặp sự cố, Standby có thể nhanh chóng tiếp quản, giảm thiểu thời gian ngừng hoạt động xuống mức tối thiểu, có thể chỉ vài phút hoặc thậm chí vài chục giây.

Trong hướng dẫn này, chúng tôi sẽ cùng bạn thực hiện từng bước cài đặt và cấu hình PostgreSQL Streaming Replication. Mục tiêu là giúp bạn tự xây dựng một hệ thống database vững chắc, đảm bảo hoạt động liên tục.

Cài đặt (Chuẩn bị môi trường)

Trước khi đi sâu vào cấu hình, chúng ta cần chuẩn bị môi trường. Giả định bạn đã có hai máy chủ Linux (ví dụ Ubuntu Server): một đóng vai trò Primary và một làm Standby. Cả hai máy đều phải cài đặt PostgreSQL.

Yêu cầu tối thiểu:

  • Hai máy chủ Linux (ví dụ Ubuntu 22.04 LTS).
  • PostgreSQL phiên bản 14 trở lên đã được cài đặt trên cả hai máy.
  • Kết nối mạng giữa Primary và Standby.

Để cài đặt PostgreSQL trên Ubuntu, các bạn có thể dùng lệnh sau (nếu chưa cài):

sudo apt update
sudo apt install postgresql postgresql-contrib -y

Giả sử địa chỉ IP của Primary Server là 192.168.1.100 và Standby Server là 192.168.1.101. Chúng ta sẽ sử dụng các địa chỉ này trong suốt quá trình cấu hình.

Kiểm tra dịch vụ PostgreSQL:

Đảm bảo dịch vụ PostgreSQL đang chạy trên cả hai máy:

sudo systemctl status postgresql

Nếu dịch vụ chưa chạy, hãy khởi động nó:

sudo systemctl start postgresql

Đồng thời, cần chắc chắn rằng không có firewall nào chặn cổng 5432 (cổng mặc định của PostgreSQL) giữa Primary và Standby. Nếu có, các bạn cần mở cổng này:

sudo ufw allow 5432/tcp
sudo ufw enable

Lưu ý: Tất cả các lệnh cấu hình dưới đây sẽ được thực hiện với quyền postgres user hoặc sudo -u postgres. Phiên bản PostgreSQL của mình là 14, nên đường dẫn cấu hình sẽ là /etc/postgresql/14/main/ và thư mục dữ liệu là /var/lib/postgresql/14/main/. Các bạn hãy điều chỉnh theo phiên bản PostgreSQL của mình nhé.

Cấu hình chi tiết PostgreSQL Streaming Replication

Đây là trọng tâm của hướng dẫn, nơi chúng ta sẽ tùy chỉnh các file cấu hình để thiết lập Streaming Replication.

3.1. Cấu hình trên Primary Server (192.168.1.100)

Đầu tiên, chúng ta sẽ cấu hình Primary Server.

Bước 1: Chỉnh sửa postgresql.conf

Mở file cấu hình chính của PostgreSQL:

sudo nano /etc/postgresql/14/main/postgresql.conf

Tìm và sửa (hoặc thêm) các dòng sau:

  • listen_addresses: Cho phép PostgreSQL lắng nghe kết nối từ mọi địa chỉ IP, hoặc chỉ định IP cụ thể của Standby.

    listen_addresses = '*'
  • wal_level: Giá trị này phải là replica để kích hoạt chế độ Replication.

    wal_level = replica
  • max_wal_senders: Số lượng tiến trình gửi WAL tối đa. Đặt giá trị này đủ lớn để đáp ứng số lượng Standby bạn có (ví dụ: 5-10).

    max_wal_senders = 5
  • wal_keep_size: Dung lượng WAL (MB) mà Primary giữ lại cho Standby. Đặt đủ lớn để Standby có thể đồng bộ lại sau thời gian ngắn bị ngắt kết nối. Giá trị 1024 (1GB) là một điểm khởi đầu tốt.

    wal_keep_size = 1024
  • archive_mode: Bật chế độ lưu trữ WAL, hữu ích cho Point-In-Time Recovery (PITR) và đảm bảo an toàn dữ liệu hơn.

    archive_mode = on
  • archive_command: Lệnh để sao chép WAL đã hoàn thành. Ví dụ dưới đây sẽ sao chép vào thư mục /var/lib/postgresql/14/main/archive. Bạn cần tạo thư mục này và cấp quyền trước:

    sudo mkdir -p /var/lib/postgresql/14/main/archive
    sudo chown -R postgres:postgres /var/lib/postgresql/14/main/archive

    Sau đó thêm vào postgresql.conf:

    archive_command = 'cp %p /var/lib/postgresql/14/main/archive/%f'

Bước 2: Chỉnh sửa pg_hba.conf

File pg_hba.conf kiểm soát việc xác thực kết nối đến PostgreSQL. Chúng ta cần cho phép Standby Server kết nối với Primary bằng user replication.

Mở file:

sudo nano /etc/postgresql/14/main/pg_hba.conf

Thêm dòng sau vào cuối file, thay 192.168.1.101/32 bằng địa chỉ IP của Standby Server:

host    replication     repuser         192.168.1.101/32        scram-sha-256

Bước 3: Tạo Replication User

Chúng ta cần tạo một user đặc biệt trên Primary Server để Standby có thể kết nối và đồng bộ dữ liệu.

Đăng nhập vào psql console trên Primary:

sudo -u postgres psql

Tạo user repuser với quyền REPLICATION và đặt mật khẩu:

CREATE USER repuser REPLICATION LOGIN CONNECTION LIMIT -1 ENCRYPTED PASSWORD 'your_secure_password_here';
\q

(Thay your_secure_password_here bằng mật khẩu mạnh của bạn.)

Bước 4: Khởi động lại Primary Server

Để các thay đổi cấu hình có hiệu lực, chúng ta cần khởi động lại dịch vụ PostgreSQL trên Primary:

sudo systemctl restart postgresql

3.2. Cấu hình trên Standby Server (192.168.1.101)

Bây giờ, chúng ta chuyển sang cấu hình Standby Server.

Bước 1: Dừng dịch vụ PostgreSQL trên Standby

Trước khi sao chép dữ liệu, hãy đảm bảo PostgreSQL trên Standby đã dừng:

sudo systemctl stop postgresql

Bước 2: Xóa dữ liệu cũ (nếu có)

Thư mục dữ liệu trên Standby phải trống hoặc không tồn tại trước khi thực hiện pg_basebackup. Nếu bạn đã cài PostgreSQL và có dữ liệu mặc định, hãy xóa nó đi:

sudo rm -rf /var/lib/postgresql/14/main/*

Bước 3: Sao chép dữ liệu gốc (Base Backup) từ Primary

Chúng ta sẽ sử dụng lệnh pg_basebackup để sao chép toàn bộ dữ liệu từ Primary sang Standby. Lệnh này tạo bản sao chính xác thư mục dữ liệu trên Primary, đồng thời tự động tạo file postgresql.auto.conf cần thiết cho replication.

Chạy lệnh này trên Standby Server:

sudo -u postgres pg_basebackup -h 192.168.1.100 -p 5432 -U repuser -D /var/lib/postgresql/14/main -F p -Xs -P -R -W

Giải thích các tùy chọn:

  • -h 192.168.1.100: Địa chỉ IP của Primary Server.
  • -p 5432: Cổng của Primary Server.
  • -U repuser: User replication đã tạo ở Primary.
  • -D /var/lib/postgresql/14/main: Thư mục đích trên Standby để lưu trữ dữ liệu sao chép.
  • -F p: Định dạng output là “plain” (không nén tar).
  • -Xs: Bao gồm các file WAL cần thiết trong bản backup.
  • -P: Hiển thị tiến độ sao chép.
  • -R: Tự động tạo file standby.signalpostgresql.auto.conf với primary_conninfo phù hợp. Đây là tùy chọn cực kỳ hữu ích!
  • -W: Yêu cầu mật khẩu của user repuser.

Khi chạy lệnh, hệ thống sẽ hỏi mật khẩu của repuser mà bạn đã thiết lập ở Primary.

Bước 4: Chỉnh sửa postgresql.conf trên Standby

Sau khi pg_basebackup hoàn tất, một file postgresql.auto.conf sẽ tự động được tạo trong thư mục dữ liệu. File này chứa dòng primary_conninfo quan trọng. Giờ đây, bạn chỉ cần chỉnh thêm một tham số trong postgresql.conf.

Mở file:

sudo nano /etc/postgresql/14/main/postgresql.conf

Tìm và đảm bảo rằng hot_standby được bật (tham số này cho phép Standby nhận các truy vấn đọc):

hot_standby = on

Bước 5: Khởi động lại Standby Server

Khởi động dịch vụ PostgreSQL trên Standby để nó bắt đầu kết nối và đồng bộ với Primary:

sudo systemctl start postgresql

Đến đây là các bạn đã hoàn tất việc cấu hình rồi đó!

Kiểm tra & Monitoring Replication

Hoàn tất cấu hình, bước tiếp theo là kiểm tra xem replication có hoạt động chính xác như kỳ vọng hay không. Đây là một bước cực kỳ quan trọng.

4.1. Kiểm tra trạng thái Replication trên Primary Server

Đăng nhập vào psql trên Primary (192.168.1.100) với user postgres:

sudo -u postgres psql -c "SELECT pid, usename, application_name, client_addr, state, sync_state, sync_priority, write_lag, flush_lag, replay_lag FROM pg_stat_replication;"

Các bạn sẽ thấy một bảng với thông tin chi tiết về các Standby server đang kết nối. Một số cột quan trọng:

  • usename: Tên user replication (ví dụ repuser).
  • application_name: Tên của ứng dụng kết nối.
  • client_addr: Địa chỉ IP của Standby Server.
  • state: Trạng thái của kết nối replication. streaming nghĩa là mọi thứ đang hoạt động bình thường.
  • sync_state: Trạng thái đồng bộ. async (bất đồng bộ) là mặc định và thường dùng.
  • write_lag, flush_lag, replay_lag: Độ trễ giữa Primary và Standby. Lý tưởng nhất là các giá trị này rất nhỏ (gần 0) hoặc bằng 0.

Nếu bạn không thấy dòng nào hoặc trạng thái không phải streaming, hãy kiểm tra lại các bước cấu hình và log lỗi của PostgreSQL.

4.2. Kiểm tra trạng thái Replication trên Standby Server

Đăng nhập vào psql trên Standby (192.168.1.101) với user postgres:

sudo -u postgres psql -c "SELECT status, receive_start_lsn, latest_end_lsn, latest_end_time, conninfo FROM pg_stat_wal_receiver;"

Các cột cần chú ý:

  • status: Trạng thái của wal receiver. streaming là dấu hiệu tốt.
  • latest_end_lsn: Vị trí LSN (Log Sequence Number) cuối cùng mà Standby đã nhận được và replay.
  • latest_end_time: Thời gian của LSN cuối cùng đó.
  • conninfo: Thông tin kết nối tới Primary.

4.3. Kiểm tra đồng bộ dữ liệu thực tế

Cách tốt nhất để kiểm tra là thử ghi dữ liệu vào Primary và xem nó có xuất hiện trên Standby không.

Trên Primary Server:

sudo -u postgres psql -c "CREATE DATABASE test_replication; \c test_replication; CREATE TABLE my_data (id SERIAL PRIMARY KEY, value TEXT, created_at TIMESTAMP DEFAULT NOW()); INSERT INTO my_data (value) VALUES ('Hello from Primary');"

Trên Standby Server:

Sau vài giây, các bạn thử truy vấn trên Standby (lưu ý là Standby chỉ cho phép đọc, không ghi):

sudo -u postgres psql -c "\c test_replication; SELECT * FROM my_data;"

Nếu bạn thấy dòng Hello from Primary xuất hiện trên Standby, thì chúc mừng, Streaming Replication của bạn đã hoạt động thành công!

4.4. Monitoring cơ bản

Để đảm bảo hệ thống ổn định lâu dài, việc monitoring là không thể thiếu. Các bạn có thể:

  • Kiểm tra logs của PostgreSQL: Các file log của PostgreSQL (thường ở /var/log/postgresql/postgresql-14-main.log) chứa thông tin quý giá về trạng thái replication, các lỗi nếu có.
  • Sử dụng các công cụ monitoring: Đối với các hệ thống production, mình thường tích hợp với Prometheus và Grafana để theo dõi các chỉ số như write_lag, replay_lag, dung lượng đĩa, CPU, RAM… Điều này giúp mình phát hiện sớm các vấn đề tiềm ẩn.

4.5. Cơ chế Failover (Chuyển đổi dự phòng)

Dù chúng ta đã thiết lập Streaming Replication, quá trình chuyển đổi từ Primary sang Standby (Failover) khi có sự cố sẽ không tự động với cấu hình này. Đây là một quy trình thủ công. Để tự động hóa, bạn sẽ cần các công cụ quản lý cluster chuyên dụng như Patroni, repmgr hay pg_auto_failover.

Khi Primary Server gặp sự cố, để kích hoạt Standby lên làm Primary mới, chúng ta sẽ cần:

  1. Đảm bảo Primary cũ đã dừng hoàn toàn hoặc bị cô lập khỏi mạng.
  2. Trên Standby Server, sử dụng lệnh pg_ctl promote.
sudo -u postgres pg_ctl -D /var/lib/postgresql/14/main promote

Sau khi promote, Standby sẽ trở thành Primary mới và bắt đầu chấp nhận các truy vấn ghi. Tuy nhiên, việc này cần được lên kế hoạch và thực hành cẩn thận trong môi trường staging trước khi áp dụng vào production.

Share: