Postgres backups under the hood

Bài tóm tắt PlanetScale 2026 3. Quy mô lớn Độ khó: Khó

PlanetScale · 2026 · 3. Quy mô lớn · Độ khó: Khó — bài gốc

Bài giải thích kỹ thuật của nhà cung cấp, phần lớn là cơ chế chung của Postgres; phần về cách PlanetScale chạy backup (chu kỳ 12 giờ, node dùng một lần, Neki) là theo PlanetScale.

Bối cảnh

  • Postgres có ba cách backup: logical (pg_dump), file system, và continuous archiving (file system + WAL). Bài so sánh ba cách khi database lên hàng chục TB.

Thay đổi chính (ba cách và cách PlanetScale làm)

  • pg_dump: xuất snapshot nhất quán dưới dạng lệnh dựng lại dữ liệu; nhỏ (không có dead tuple, index), hợp cho migration. Nhưng ở cỡ 30 TB thì tranh CPU và I/O với query của người dùng, không có PITR, và nguy hiểm hơn: nó giữ một snapshot giao dịch suốt thời gian dump, chặn autovacuum freeze; nếu có thêm khoảng 2 tỉ giao dịch trong lúc đó thì chạm transaction wraparound và Postgres chuyển sang chỉ đọc. Kết luận của bài: không dùng pg_dump cho backup định kỳ ở cỡ lớn.
  • File system backup: nhanh hơn nhiều, nhưng phải tắt database (trừ khi file system có snapshot nguyên tử), và không có thay đổi sau thời điểm backup.
  • Continuous archiving: WAL được stream liên tục lên S3 (ở PlanetScale mỗi primary có sidecar wal-g). Base backup chụp lúc database đang chạy nên file bị "nhoè" (trang có thể cũ, mới, hoặc hỏng giữa chừng); không sao, vì full_page_writes ghi ảnh nguyên trang vào WAL ở lần sửa đầu sau mỗi checkpoint, và lúc restore Postgres phát lại WAL từ start_lsn tới end_lsn để sửa mọi trang. Bản restore là trạng thái lúc backup kết thúc, không phải lúc bắt đầu; dừng giữa hai mốc đó là dữ liệu hỏng.
  • PITR: restore backup gần nhất rồi phát lại WAL tới thời điểm bất kỳ. Phát lại WAL đắt hơn chép file, nên PlanetScale backup mỗi 12 giờ để giới hạn lượng WAL phải phát lại.
  • Backup không đụng primary: lấy backup gần nhất, dựng lên một node dùng một lần, phát lại WAL, stream nốt thay đổi từ primary cho bắt kịp, rồi chụp file system của node đó làm backup mới. Cùng quy trình dùng cho đổi cỡ cluster (node mới → chép backup hoặc gắn volume EBS → phát lại WAL → stream → cutover).
  • Ở quy mô rất lớn: backup của database khổng lồ có thể mất hơn 12 giờ, restore mất nhiều ngày. Hướng của PlanetScale: Neki chia Postgres thành shard để mỗi shard backup và restore độc lập (cùng ý với bài Vitess trước đó của họ).

Vì sao

  • Backup không chỉ cần "có", mà cần restore nhanh và không làm hại primary trong lúc chụp; ba yêu cầu này đẩy dần từ pg_dump sang continuous archiving rồi sang chia nhỏ dữ liệu.

Bài học cho SWE

  • Phân biệt backup để migration (logical) với backup để khôi phục thảm hoạ (physical + WAL) (Failover, replica và dự phòng dữ liệu).
  • Một transaction dài là rủi ro vận hành (chặn vacuum, tiến tới wraparound), kể cả transaction chỉ đọc của công cụ backup.
  • Thời gian restore tỉ lệ với cỡ dữ liệu và lượng WAL: chu kỳ backup là núm vặn RTO; khi một máy quá lớn để restore kịp, sharding cũng là giải pháp cho backup (Sharding và tách database).
  • Chụp backup trên node phụ dựng từ backup cũ để không tranh tài nguyên với primary.

Liên quan