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
- Client ghi 6 bản ghi. Mỗi bản được append vào log trên đĩa, xong là trả ack ngay.
- Bảng dữ liệu (đang trong RAM) cập nhật chậm hơn: mới có 3 bản.
- Mất điện. Phần trong RAM mất sạch; log trên đĩa vẫn đủ 6.
- 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ếp | Ghi WAL trước |
|---|---|
| Ghi ngẫu nhiên vào nhiều trang dữ liệu — chậm | Ghi 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_commitbậ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.