1. Vấn đề thực tế: Cuộc gọi lúc 2 giờ sáng và bài toán cứu dữ liệu
Chuông điện thoại reo dồn dập lúc 02:15 sáng. Đầu dây bên kia, kỹ sư trực ca thông báo ngắn gọn: lệnh migration vừa chạy nhầm đã xoá sạch bảng orders trên cụm PostgreSQL production lúc 01:47:30. Database nặng 850GB với hơn 1.200 transaction mỗi giây.
Nếu dùng bản pg_dump tạo lúc 00:00, toàn bộ giao dịch trong gần 2 tiếng sẽ biến mất. Chưa kể, việc nạp lại file SQL 850GB sẽ ngốn ít nhất 4 đến 5 tiếng. Cam kết RTO và RPO coi như vỡ trận. Lựa chọn duy nhất của chúng tôi là tua ngược database về đúng mốc 01:46:59 — một giây trước khi thảm họa xảy ra.
2. Vì sao các phương pháp backup truyền thống hụt hơi?
Khi database vượt mốc vài trăm GB, những cách làm quen thuộc nhanh chóng chạm trần giới hạn:
- pg_dump / pg_restore: Đây là logical backup dạng đơn luồng. Quá trình xuất và nạp dữ liệu ngốn nhiều CPU lẫn RAM, kéo theo thời gian rebuild index kéo dài hàng giờ. Quan trọng nhất: phương pháp này không hỗ trợ Point-in-Time Recovery (PITR).
- pg_basebackup mặc định: Tuy sao lưu ở tầng physical nhưng công cụ này không có sẵn cơ chế nén đa tiến trình. Bạn không thể đẩy trực tiếp dữ liệu lên S3 hay MinIO nếu không mount ổ đĩa trung gian để chứa file tạm.
- Script đẩy WAL thủ công: Đoạn lệnh
archive_commanddùngaws s3 cprất dễ nghẽn I/O vào các đợt cao điểm tải ghi. Khi việc đẩy file chậm lại, WAL tích tụ làm đầy đĩa hoặc rớt file, làm đứt gãy hoàn toàn chuỗi khôi phục.
3. So sánh các phương án xử lý
Trước bài toán sao lưu hệ thống lớn, đội ngũ vận hành thường cân nhắc 3 hướng đi:
- Tự viết shell script (pg_basebackup + AWS CLI): Dễ triển khai ban đầu nhưng khó bảo trì. Script tự chế thiếu cơ chế resume khi rớt mạng và không tự động verify checksum từng block dữ liệu.
- Dùng WAL-G: Tốc độ đẩy lên S3 rất tốt. Tuy nhiên, cú pháp cấu hình còn phân mảnh và việc quản lý nhiều cụm database (stanzas) tương đối phức tạp khi cần theo dõi tập trung.
- Triển khai pgBackRest: Giải pháp physical backup chuẩn production hiện nay. pgBackRest hỗ trợ multi-process, nén Zstandard tốc độ cao, stream trực tiếp lên S3 không qua disk tạm, kiểm tra checksum SHA-256 từng block và thực hiện PITR chuẩn xác đến từng mili-giây.
4. Các bước thiết lập pgBackRest: Backup S3 và khôi phục PITR
Bước 1: Cài đặt pgBackRest trên máy chủ PostgreSQL
Cài đặt gói pgBackRest chính thức từ kho PGDG trên Ubuntu/Debian:
sudo apt-get update
sudo apt-get install -y pgbackrest
Bước 2: Cấu hình WAL Archiving trên PostgreSQL
Mở file postgresql.conf để bàn giao luồng ghi WAL liên tục cho pgBackRest xử lý:
# Cấu hình WAL cho pgBackRest
wal_level = replica
archive_mode = on
archive_command = 'pgbackrest --stanza=db-prod archive-push %p'
archive_timeout = 300
max_wal_senders = 5
Khởi động lại PostgreSQL để các thông số nhận hiệu lực:
sudo systemctl restart postgresql
Bước 3: Cấu hình pgBackRest kết nối AWS S3
Chỉnh sửa file /etc/pgbackrest/pgbackrest.conf:
[global]
# Cấu hình Repository lưu trữ Amazon S3
repo1-type=s3
repo1-s3-bucket=prod-postgres-backups-bucket
repo1-s3-endpoint=s3.ap-southeast-1.amazonaws.com
repo1-s3-region=ap-southeast-1
repo1-s3-key=AKIAIOSFODNN7EXAMPLE
repo1-s3-key-secret=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
repo1-path=/pgbackrest-repo
# Tối ưu hiệu năng: Xử lý 4 tiến trình song song và nén Zstandard
process-max=4
compress-type=zst
compress-level=3
# Chính sách lưu trữ (Retention Policy)
repo1-retention-full=2
repo1-retention-diff=7
# Cấu hình Stanza cho cụm DB
[db-prod]
pg1-path=/var/lib/postgresql/16/main
pg1-user=postgres
Bước 4: Khởi tạo Stanza và kiểm tra kết nối
Tạo metadata và kiểm tra đường truyền sang S3 bằng user postgres:
sudo -u postgres pgbackrest --stanza=db-prod stanza-create
sudo -u postgres pgbackrest --stanza=db-prod check
Nếu terminal trả về dòng INFO: check command end: completed successfully, quá trình bắt tay giữa database, archive log và S3 bucket đã hoàn tất.
Bước 5: Chạy backup song song (Full & Differential)
Thực hiện bản full backup đầu tiên:
sudo -u postgres pgbackrest --stanza=db-prod --type=full backup
Với process-max=4 và thuật toán nén zst, pgBackRest tận dụng 4 worker core để đọc dữ liệu song song rồi đẩy thẳng lên S3 qua luồng mạng. Dữ liệu 850GB nén lại chỉ còn khoảng 190GB trên S3, thời gian hoàn thành rút ngắn từ 3,5 tiếng xuống còn 42 phút.
Mẹo đối soát: Khi cần trích xuất nhanh cấu trúc bảng hoặc lọc log CSV ra JSON để debug trong lúc khôi phục dữ liệu, bạn có thể dùng công cụ tại toolcraft.app/vi/tools/data/csv-to-json — dữ liệu xử lý trực tiếp trên browser nên đảm bảo an toàn.
Bước 6: Thực hành khôi phục Point-in-Time Recovery (PITR)
Để kéo database về thời điểm 2026-10-02 01:46:59+07 ngay trước lệnh migration lỗi, thực hiện lần lượt 4 bước:
- Dừng service PostgreSQL:
sudo systemctl stop postgresql - Dọn dẹp thư mục data directory hiện tại:
sudo rm -rf /var/lib/postgresql/16/main/* - Chạy lệnh restore PITR qua pgBackRest:
sudo -u postgres pgbackrest --stanza=db-prod \ --type=time \ --target="2026-10-02 01:46:59+07" \ --target-action=promote \ restore - Bật lại PostgreSQL:
sudo systemctl start postgresql
PostgreSQL sẽ tự động tải bản base backup từ S3, sau đó replay toàn bộ WAL record cần thiết đến đúng mốc thời gian chỉ định rồi mở cổng nhận write traffic trở lại.
5. Đúc kết thực tế
Cấu hình pgBackRest kết hợp lưu trữ S3 giúp loại bỏ nỗi lo nghẽn đĩa và rút ngắn thời gian backup đáng kể. Quan trọng hơn cả, khả năng tua ngược thời gian PITR chính xác đến từng giây chính là tấm lưới bảo hiểm vững chắc nhất cho dữ liệu production của bạn.

