System Design

Write-Ahead Log: database báo ghi xong rồi mất điện, dữ liệu còn không?

Tóm tắt

Với Write-Ahead Log (WAL), mỗi thay đổi được ghi nối tiếp vào log trên đĩa trước rồi mới trả “OK” cho client. Bảng dữ liệu được cập nhật sau. Nếu mất điện, database đọc lại log khi khởi động để khôi phục đủ mọi thay đổi đã xác nhận.

Diễn biến

  1. Client ghi 6 bản ghi. Mỗi bản được append vào log trên đĩa, xong là trả ack ngay.
  2. Bảng dữ liệu (đang trong RAM) cập nhật chậm hơn: mới có 3 bản.
  3. Mất điện. Phần trong RAM mất sạch; log trên đĩa vẫn đủ 6.
  4. Khởi động lại: database replay log từ bản 1 đến 6 vào bảng. Không mất bản nào.

Vì sao nhanh mà vẫn an toàn?

Ghi vào bảng trực tiếpGhi WAL trước
Ghi ngẫu nhiên vào nhiều trang dữ liệu — chậmGhi nối tiếp (sequential) vào cuối log — nhanh
Mất điện giữa chừng có thể làm trang dữ liệu hỏng dởLog là nguồn sự thật để phục hồi
Còn được dùng cho replication và point-in-time recovery

Áp dụng thế nào?

  • Hiểu “ack” nghĩa là gì: trong PostgreSQL, ack đến từ WAL đã flush xuống đĩa (khi synchronous_commit bật), không phải từ bảng.
  • Cân nhắc đánh đổi: tắt flush đồng bộ để nhanh hơn đồng nghĩa có thể mất vài giao dịch cuối khi sự cố.
  • Vận hành: theo dõi dung lượng WAL và archive WAL để phục vụ backup và khôi phục theo thời điểm.