Cài PostgreSQL trên VPS thường là bước hạ tầng đầu tiên khi một dự án lớn dần và muốn tách database khỏi nền tảng managed hoặc khỏi chung máy với ứng dụng. Bạn có tài nguyên ổn định, toàn quyền cấu hình và cài extension, và đặt được database ngay cạnh ứng dụng. Đổi lại, bạn tự chịu trách nhiệm tinh chỉnh, bảo mật và sao lưu. Bài này đi qua từng việc theo đúng thứ tự bạn sẽ gặp, kèm lệnh cho Ubuntu để chạy trên một máy chủ mới.
Trước khi thuê VPS: vài câu hỏi cần trả lời
Trả lời mấy câu này trước khi chọn cấu hình. Chúng quyết định nhiều hơn bất kỳ tham số tinh chỉnh nào.
- Ứng dụng chạy ở đâu? Đặt database cùng thành phố với máy chủ ứng dụng. Mỗi truy vấn đều phải trả giá cho một vòng đi về, và một trang chạy năm mươi truy vấn sẽ nhân con số đó lên năm mươi lần. Hướng dẫn chọn vị trí đặt VPS liệt kê đủ 14 quốc gia và các thành phố của Cloudj.
- Dữ liệu "nóng" lớn cỡ nào? Phần dữ liệu và index được truy cập thường xuyên nên nằm vừa trong RAM. Database lớn hơn RAM nhiều lần vẫn ổn nếu phần lớn là dữ liệu ít dùng.
- Tải đều hay theo đợt? Database rất kỵ tranh chấp CPU. Với tải truy vấn đều đặn, hãy chọn máy chủ CPU dedicated, tức có nhân CPU riêng. CPU shared chấp nhận được cho môi trường dev và công cụ nội bộ ít truy cập.
- Bạn chấp nhận mất bao nhiêu dữ liệu? Nếu câu trả lời là "vài phút", bạn cần lưu trữ WAL liên tục chứ không chỉ một bản dump mỗi đêm.
Điểm khởi đầu hợp lý cho một database production nhỏ là 2 vCPU dedicated và 4 đến 8 GB RAM, ổ đĩa đủ cho dữ liệu, index, WAL và phần tăng trưởng. Bạn có thể tăng CPU, RAM và mở rộng ổ đĩa sau trong console, nên không cần mua trước cấu hình của năm sau. Tham khảo các lựa chọn máy chủ cloud để biết các loại CPU, và xem giá hiện hành theo từng vị trí.
Cài PostgreSQL trên VPS Ubuntu
Kho gói của Ubuntu đã có sẵn một phiên bản được hỗ trợ. Nếu muốn bản major mới nhất, hãy dùng kho apt chính thức của PostgreSQL:
sudo apt update
sudo apt install -y postgresql-common
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
sudo apt install -y postgresql
Kiểm tra phiên bản và cluster đã cài:
pg_lsclusters
Kết quả hiển thị số phiên bản và thư mục dữ liệu. Các đường dẫn bên dưới dùng phiên bản 16; hãy thay bằng phiên bản của bạn. Tạo role và database cho ứng dụng:
sudo -u postgres createuser --pwprompt appuser
sudo -u postgres createdb --owner=appuser appdb
Tinh chỉnh bộ nhớ theo cấu hình máy
Giá trị mặc định cố tình để rất dè dặt. Sửa file /etc/postgresql/16/main/postgresql.conf (hoặc thêm file vào thư mục conf.d/). Các giá trị dưới đây giả định máy 8 GB RAM chỉ chạy PostgreSQL:
shared_buffers = 2GB # khoảng 25% RAM
effective_cache_size = 6GB # khoảng 75% RAM; chỉ là gợi ý cho planner, không cấp phát thật
work_mem = 16MB # cho mỗi thao tác sort/hash trong mỗi truy vấn; để vừa phải
maintenance_work_mem = 512MB # dùng cho VACUUM và tạo index
random_page_cost = 1.1 # ổ SSD
max_connections = 100
work_mem là tham số hay gây rắc rối nhất: một truy vấn phức tạp có thể dùng nó nhiều lần, và mỗi kết nối đều có thể chạy truy vấn như vậy. Nếu cần hàng trăm kết nối từ client, hãy đặt PgBouncer phía trước thay vì tăng max_connections. Khởi động lại và kiểm tra:
sudo systemctl restart postgresql
sudo -u postgres psql -c "SHOW shared_buffers;"
Bật ghi log truy vấn chậm để tinh chỉnh dựa trên số liệu thật:
log_min_duration_statement = 500ms
Chỉ cho máy chủ ứng dụng kết nối
Đừng bao giờ để cổng 5432 mở ra Internet. Hãy kết hợp ba lớp bảo vệ.
Thứ nhất, chỉ định giao diện mạng mà PostgreSQL lắng nghe. Trong postgresql.conf:
listen_addresses = 'localhost,198.51.100.5' # IP của chính máy chủ này
Thứ hai, chỉ cho phép đúng các client đã biết trong /etc/postgresql/16/main/pg_hba.conf, dùng mật khẩu SCRAM và TLS:
hostssl appdb appuser 203.0.113.10/32 scram-sha-256
hostssl appdb appuser 203.0.113.11/32 scram-sha-256
Gói của Ubuntu tự tạo chứng chỉ tự ký và bật ssl = on sẵn; tài liệu PostgreSQL về SSL hướng dẫn cách thay bằng chứng chỉ của bạn.
Thứ ba, lọc ở firewall để chỉ máy chủ ứng dụng chạm được tới cổng:
sudo ufw allow OpenSSH
sudo ufw allow from 203.0.113.10 to any port 5432 proto tcp
sudo ufw allow from 203.0.113.11 to any port 5432 proto tcp
sudo ufw enable
sudo systemctl reload postgresql
Bài cấu hình firewall UFW giải thích thứ tự rule và cách tránh tự khóa mình ở ngoài.
Sao lưu: hai lớp, cả hai đều nằm ngoài máy chủ
Bản sao lưu nằm cùng ổ đĩa với database chỉ là một bản copy, chưa phải bản sao lưu. Hãy chuẩn bị hai lớp.
Dump logic bằng pg_dump
Đơn giản, chuyển được giữa các phiên bản, hợp với database nhỏ hoặc làm thêm một lớp an toàn trước khi migrate:
sudo -u postgres pg_dump -Fc appdb > /var/backups/appdb-$(date +%F).dump
Khôi phục vào một database trống bằng pg_restore -d appdb file.dump. Đặt lịch bằng cron và chép file ra ngoài máy chủ.
Lưu trữ liên tục bằng pgBackRest
Để khôi phục về một thời điểm bất kỳ, pgBackRest tạo bản sao lưu full và incremental, đồng thời đẩy WAL liên tục lên một bucket tương thích S3. Cài bằng sudo apt install -y pgbackrest rồi tạo file /etc/pgbackrest.conf:
[global]
repo1-type=s3
repo1-s3-endpoint=s3.example-storage.com
repo1-s3-bucket=db-backups
repo1-s3-region=eu-central
repo1-s3-key=ACCESS_KEY
repo1-s3-key-secret=SECRET_KEY
repo1-path=/pgbackrest
repo1-retention-full=2
[main]
pg1-path=/var/lib/postgresql/16/main
Bật lưu trữ WAL trong postgresql.conf, khởi động lại rồi tạo bản full đầu tiên:
archive_mode = on
archive_command = 'pgbackrest --stanza=main archive-push %p'
sudo systemctl restart postgresql
sudo -u postgres pgbackrest --stanza=main stanza-create
sudo -u postgres pgbackrest --stanza=main --type=full backup
sudo -u postgres pgbackrest --stanza=main info
Hãy chọn bucket ở vị trí khác với database. Cloudj có trang object storage để bạn tham khảo; cấu hình trên dùng được với mọi dịch vụ tương thích S3.
Thử khôi phục thật
Mỗi tháng một lần, tạo một máy chủ thuê theo giờ, khôi phục bản sao lưu mới nhất, chạy vài truy vấn kiểm tra rồi xóa máy. Máy chủ theo giờ bị tính tiền chừng nào còn tồn tại, nên xóa ngay sau khi thử sẽ giữ chi phí chỉ ở số giờ bạn đã dùng.
Áp dụng vào bài toán thực tế
Hệ thống giao dịch là ví dụ điển hình: một bot ghi lại lệnh khớp và vị thế cần database nằm sát bot, không phải ở bên kia đại dương. Các bài về bot giao dịch crypto ở Singapore, VPS forex ở London và VPS forex ở New York cho thấy vị trí máy chủ đi theo khối lượng công việc thế nào, và database cũng theo đúng logic đó.
Câu hỏi thường gặp
Nên dùng CPU shared hay dedicated cho PostgreSQL?
Dedicated cho production có tải đều, vì độ trễ truy vấn tăng khi phải tranh chấp CPU. Shared ổn cho dev, staging và công cụ nội bộ nhỏ.
Database managed có tốt hơn PostgreSQL tự cài trên VPS không?
Dịch vụ managed lo phần vá lỗi, failover và sao lưu cho bạn. VPS cho bạn toàn quyền với phiên bản, extension và cấu hình, đổi lại bạn tự làm những việc đó. Nếu trong đội không ai nhận trách nhiệm sao lưu và nâng cấp, dịch vụ managed là lựa chọn an toàn hơn.
Nên chạy pg_dump bao lâu một lần?
Mỗi ngày một lần là mức cơ bản phổ biến cho database nhỏ. Nếu không chấp nhận mất dữ liệu cả ngày, hãy thêm lưu trữ WAL liên tục bằng pgBackRest.
Sau này nâng cấu hình máy được không?
Được. Bạn có thể tăng CPU, RAM và mở rộng ổ đĩa trong console. Hãy lên lịch một khoảng bảo trì ngắn cho lần khởi động lại.
Khởi chạy máy chủ database của bạn
Đặt database cạnh ứng dụng, bắt đầu với CPU dedicated và đủ RAM cho dữ liệu nóng, rồi chứng minh bản sao lưu dùng được bằng một lần khôi phục thật. Console Cloudj hiển thị giá chính xác cho từng cấu hình trước khi bạn triển khai, và bạn có thể nạp tiền vào số dư bằng chuyển khoản ngân hàng bằng VND.