Incremental backup native của PostgreSQL giảm lượng data phải truyền bằng cách chỉ lấy các block quan hệ đã thay đổi kể từ backup tham chiếu. Đổi lại, một bản incremental không tự đứng độc lập: khi phục hồi phải có toàn bộ chuỗi phụ thuộc, ghép chúng thành synthetic full bằng pg_combinebackup, rồi mới thực hiện recovery và WAL replay.
Bài viết xây quy trình production bằng pg_basebackup, pg_combinebackup, pg_verifybackup và continuous archiving/PITR. Tính năng incremental xuất hiện từ PostgreSQL 17; hãy dùng tài liệu và binary đúng major version đang vận hành.
1. Native incremental backup giải quyết bài toán nào?
Full base backup sao chép toàn cluster. Với database nhiều terabyte nhưng chỉ một phần nhỏ block thay đổi mỗi ngày, cửa sổ truyền và storage có thể rất lớn. Incremental backup dùng WAL summaries để xác định block quan hệ thay đổi kể từ backup tham chiếu; non-relation files vẫn có thể được lấy đầy đủ.
Nó phù hợp khi database lớn, phần lớn dữ liệu tương đối lạnh và đội vận hành chấp nhận quản lý dependency chain. Database nhỏ hoặc gần như toàn bộ block thay đổi thường được phục vụ tốt hơn bằng full backup đơn giản.
2. Bốn thành phần không thể thay thế nhau
| Thành phần | Vai trò | Không chứng minh |
|---|---|---|
| Full/incremental base backup | Ảnh file-level của toàn cluster | Không tự cung cấp mọi WAL cho PITR |
| WAL summaries | Cho server biết block nào đổi để tạo incremental | Không phải WAL archive để recovery |
| WAL archive | Replay tới điểm khôi phục mục tiêu | Không thay thế base backup |
| Backup manifest | Mô tả file/checksum và làm mốc incremental | Không thay thế restore drill hay trust anchor |
Nhầm WAL summaries với archived WAL là lỗi thiết kế nguy hiểm. Summary phục vụ chọn block trong lần backup kế tiếp; recovery vẫn cần chuỗi WAL phù hợp theo RPO/PITR policy.
3. Điều kiện server và WAL summarization
# postgresql.conf — ví dụ khái niệm, không phải archive command hoàn chỉnh
wal_level = replica
summarize_wal = on
wal_summary_keep_time = '14d'
archive_mode = on
archive_command = '/usr/local/sbin/archive-wal %p %f'
# Cần đủ cho backup connection và WAL streaming
max_wal_senders = 10
summarize_wal bật WAL summarizer. Summary trong pg_wal/summaries phải phủ toàn bộ LSN từ start LSN của backup tham chiếu đến start LSN của backup mới; thiếu summary thì incremental thất bại. Đặt wal_summary_keep_time cao hơn thoải mái khoảng cách tối đa giữa các lần backup phụ thuộc.
wal_level=minimal không đủ. Các setting có context reload/restart khác nhau theo version; kiểm tra pg_settings.context, rollout trong maintenance plan và xác minh giá trị effective thay vì chỉ đọc file.
4. Tạo full backup gốc
pg_basebackup \
--dbname='host=db-primary.example port=5432 user=backup dbname=postgres' \
--pgdata=/backup/chain-a/full-2026-10-01 \
--format=plain \
--wal-method=stream \
--checkpoint=spread \
--manifest-checksums=SHA256 \
--progress
User cần quyền REPLICATION hoặc superuser và pg_hba.conf phải cho phép replication connection. Không đặt password trên command line; dùng passfile/secret injection có quyền chặt. Backup luôn bao phủ toàn cluster, không chọn một database riêng như pg_dump.
--wal-method=stream giữ WAL cần trong lúc backup qua connection thứ hai. Nó không thay thế continuous WAL archive cho PITR sau thời điểm backup. Tránh --no-sync trên production vì command có thể trả về trước khi data được sync bền vững.
5. Tạo incremental từ manifest tham chiếu
pg_basebackup \
--dbname='host=db-primary.example port=5432 user=backup dbname=postgres' \
--pgdata=/backup/chain-a/inc-2026-10-02 \
--format=plain \
--wal-method=stream \
--incremental=/backup/chain-a/full-2026-10-01/backup_manifest \
--manifest-checksums=SHA256 \
--progress
Lần sau có thể tham chiếu manifest của incremental gần nhất để tạo chain:
--incremental=/backup/chain-a/inc-2026-10-02/backup_manifest
--pgdata=/backup/chain-a/inc-2026-10-03
Manifest được upload cho server để quyết định phạm vi thay đổi. Bảo vệ manifest cùng metadata chain; nếu mất manifest hoặc xóa một ancestor cần thiết, descendant có thể không còn phục hồi được.
6. Lưu dependency graph thay vì đoán theo tên thư mục
{
"backup_id": "chain-a-inc-2026-10-03",
"type": "incremental",
"parent_id": "chain-a-inc-2026-10-02",
"server_system_identifier": "<cluster identity>",
"postgres_major": 18,
"started_at": "2026-10-03T01:00:00Z",
"status": "verified",
"manifest_object": "immutable://.../backup_manifest"
}
pg_combinebackup kiểm tra các directory đưa vào có tạo chain hợp lệ hay không, nhưng PostgreSQL không cung cấp catalog retention để tự biết backup nào còn là ancestor. Lưu parent, cluster identity, major version, timeline/LSN, object location, checksum và trạng thái verify/restore-test trong inventory riêng.
Tên có timestamp chỉ hỗ trợ con người; nó không phải dependency model. Ngăn hai cluster ghi vào cùng prefix và không cho job retention xóa object khi vẫn còn descendant được giữ.
7. Xác minh từng backup ngay sau khi tạo
pg_verifybackup /backup/chain-a/full-2026-10-01
pg_verifybackup /backup/chain-a/inc-2026-10-02
pg_verifybackup /backup/chain-a/inc-2026-10-03
Manifest mặc định dùng CRC32C cho file; ví dụ chọn SHA-256 để có digest mạnh hơn, đổi lại tốn CPU. Nếu threat model có attacker sửa cả backup và manifest, checksum không đủ — lưu/ký manifest ở trust domain riêng.
pg_verifybackup chứng minh file khớp manifest và kiểm tra một số yêu cầu WAL; nó không chứng minh application khởi động, extension tồn tại, credential hoạt động hay target timestamp khôi phục đúng. Verify là cổng đầu tiên, không phải restore test.
8. Ghép chain thành synthetic full
# Kiểm tra chain và kế hoạch trước
pg_combinebackup --dry-run --debug \
/backup/chain-a/full-2026-10-01 \
/backup/chain-a/inc-2026-10-02 \
/backup/chain-a/inc-2026-10-03 \
--output=/restore/chain-a-2026-10-03
# Tạo output thật, theo thứ tự cũ nhất đến mới nhất
pg_combinebackup \
/backup/chain-a/full-2026-10-01 \
/backup/chain-a/inc-2026-10-02 \
/backup/chain-a/inc-2026-10-03 \
--output=/restore/chain-a-2026-10-03 \
--manifest-checksums=SHA256
pg_verifybackup /restore/chain-a-2026-10-03
Incremental directory không được dùng trực tiếp làm PGDATA. Output combine là một synthetic full, có thể dùng cho restore hoặc làm base của lần combine tương lai.
Mặc định copy là dễ hiểu nhất. --clone dùng reflink khi filesystem hỗ trợ. --link dùng hard link và nguy hiểm nếu input/output bị sửa hoặc server được start từ đó; chỉ dùng với bản sao disposable theo contract rất chặt.
9. Restore cần WAL và recovery configuration
Sau combine, đặt synthetic full vào target cô lập với đúng owner/mode, map tablespace, cấu hình restore_command, tạo recovery.signal và chọn recovery target nếu cần PITR. Không mở traffic ứng dụng trước khi kiểm tra data.
# Trong cấu hình recovery của bản restore cô lập
restore_command = '/usr/local/sbin/restore-wal %f %p'
recovery_target_time = '2026-10-03 08:15:00+00'
recovery_target_action = 'promote'
WAL archive phải chứa chuỗi liên tục cần thiết; timeline history cũng phải sẵn sàng. Configuration file như postgresql.conf, pg_hba.conf và secret ngoài database cần backup riêng vì WAL replay không khôi phục mọi thay đổi cấu hình thủ công.
10. Retention phải xóa theo cả chain
Ví dụ giữ full Chủ nhật và incremental hằng ngày: không được xóa full khi bất kỳ incremental retained nào còn phụ thuộc nó; cũng không xóa incremental giữa chuỗi. WAL retention còn phải thỏa restore point lâu nhất và mọi base backup retained.
Để giới hạn chain length và RTO, định kỳ tạo full mới hoặc tạo synthetic full đã verify rồi chuyển dependency root có kiểm soát. Không xóa chain cũ cho tới khi:
- backup root mới đã verify;
- restore drill hoàn tất;
- WAL coverage được chứng minh;
- retention grace period đã qua;
- inventory không còn descendant tham chiếu chain cũ.
11. Backup từ standby và các edge case
pg_basebackup có thể chạy từ standby nếu cấu hình replication phù hợp và primary bật full_page_writes. Nhưng incremental trên standby có thể thất bại khi ít activity vì chưa có restartpoint mới hơn backup trước. Backup cũng thất bại nếu standby được promote giữa chừng.
Nếu checksum state của cluster thay đổi giữa các backup, pg_combinebackup có giới hạn vì nó không tự tính lại page checksum cho output. Sau khi dùng pg_checksums thay đổi trạng thái, lựa chọn an toàn là tạo full backup mới và bắt đầu chain mới.
Tablespace mapping phải được thiết kế cả lúc backup/combine/restore. Test trên filesystem đích thật, không chỉ volume đơn giản không có tablespace.
12. RPO, RTO và quan sát
Incremental giảm thời gian/lưu lượng backup nhưng có thể tăng RTO vì cần tải nhiều object, combine rồi replay WAL. Đo riêng:
- backup duration, bytes transferred và changed-block ratio;
- WAL summary lag/availability và backup failure;
- WAL archive lag, failed count và archive storage growth;
- thời gian tải chain, combine, verify, replay và application validation;
- chain length, ancestor count và restore point cũ nhất còn đạt được.
Theo dõi pg_stat_progress_basebackup khi job chạy và pg_stat_archiver cho archive pipeline. Thành công của cron không đủ nếu object chưa replicate, manifest chưa verify hoặc WAL có gap.
13. Restore drill là acceptance test
Ít nhất theo lịch phù hợp với mức quan trọng, dựng môi trường cô lập từ một restore point ngẫu nhiên: resolve dependency graph, tải đủ chain, chạy combine và verify, replay WAL, khởi động đúng major binary, rồi test business invariant.
Kiểm tra row count không đủ. Chạy checksum/application query quan trọng, login role, extension, sequence, job scheduler và một read/write smoke test nếu môi trường cho phép. Ghi RTO thực tế, lượng thao tác thủ công và mọi secret/config bị thiếu.
Checklist production
- PostgreSQL/server/tooling hỗ trợ native incremental và dùng đúng major version.
summarize_walbật; summary retention dài hơn khoảng cách backup tối đa.- WAL archiving hoạt động và được giám sát độc lập với WAL summaries.
- Full đầu chain và mọi incremental đều có manifest, verify và immutable storage.
- Inventory lưu parent, cluster identity, version, LSN/timeline và object location.
- Retention không xóa ancestor hoặc WAL còn cần cho restore point retained.
pg_combinebackupnhận chain theo thứ tự cũ nhất đến mới nhất.- Không start PostgreSQL trực tiếp từ incremental hoặc hard-linked backup input.
- Checksum-state change tạo chain full mới; tablespace mapping đã test.
- Restore drill đo đủ combine, WAL replay và application validation.
Kết luận
Native incremental backup của PostgreSQL có thể giảm đáng kể khối lượng truyền cho cluster lớn, ít thay đổi, nhưng chi phí quản trị chuyển sang dependency chain và recovery. Thiết kế tốt phải giữ WAL summaries đủ lâu để tạo backup, WAL archive đủ lâu để phục hồi, manifest được bảo vệ, từng member được verify và toàn chain được restore-test. Khi synthetic full và PITR được diễn tập định kỳ, incremental mới là chiến lược backup; nếu không, nó chỉ là một tập file nhỏ hơn chưa được chứng minh.




Chưa có bình luận. Hãy là người đầu tiên chia sẻ ý kiến.