1. WAL là gì?
Write-ahead log (WAL) là một tính năng hết sức quan trọng của PostgreSQL. Nó được hiểu là cơ chế đảm bảo tính nhất quán của cơ sở dữ liệu và phục vụ mục đích khôi phục lại database trong tình huống PostgreSQL bị sập đột ngột (có thể do máy chủ mất điện, process postmaster bị kill, …).
Cơ chế này hoạt động dựa trên nguyên tắc ghi nhật ký hay lưu trữ lại trước mô tả sự thay đổi trước khi sự thay đổi này được thực thi trên dữ liệu thực tế.
2. Những đặc điểm của cơ chế WAL
2.1. Ghi nhật ký trước
- Mỗi thay đổi dữ liệu (như chèn, cập nhật, xóa) sẽ được ghi lại trong một tệp nhật ký (WAL) trước khi các thay đổi này được áp dụng lên dữ liệu thực tế trong cơ sở dữ liệu.
- Điều này đảm bảo rằng trong trường hợp sự cố (như mất điện), dữ liệu có thể được khôi phục lại từ nhật ký WAL mà không bị mất mát.
2.2. Tính nhất quán
- WAL giúp duy trì tính nhất quán của cơ sở dữ liệu bằng cách đảm bảo rằng tất cả các thay đổi được ghi lại theo thứ tự và không bị mất mát.
- Khi một giao dịch được commit, các thay đổi của giao dịch đó được ghi vào WAL, đảm bảo rằng các thay đổi này sẽ không bị mất ngay cả khi có sự cố ngay sau đó.
2.3. Khôi phục dữ liệu
- Trong trường hợp sự cố, PostgreSQL có thể sử dụng các tệp WAL để khôi phục dữ liệu về trạng thái nhất quán.
- Quá trình khôi phục sẽ áp dụng lại các thay đổi từ nhật ký WAL để đảm bảo rằng tất cả các thay đổi đã được commit trước khi sự cố xảy ra sẽ được áp dụng đầy đủ.
2.4. Sao lưu và phục hồi
- WAL cũng hỗ trợ các kỹ thuật sao lưu và phục hồi dữ liệu, như sao lưu toàn bộ cơ sở dữ liệu và sao lưu gia tăng (incremental backup).
- Sao lưu toàn bộ cơ sở dữ liệu kết hợp với sao lưu các tệp WAL giúp khôi phục cơ sở dữ liệu về bất kỳ thời điểm nào trước đó.
2.5. Cấu hình WAL
- PostgreSQL cung cấp các tham số cấu hình để điều chỉnh hành vi của WAL, như kích thước tệp WAL, khoảng thời gian ghi nhật ký, và các tùy chọn khác để tối ưu hiệu năng và đảm bảo an toàn dữ liệu.
3. Cơ chế hoạt động
Khi một giao dịch bắt đầu thực hiện các thay đổi trên cơ sở dữ liệu, các thay đổi này không được ghi ngay lập tức vào các tệp dữ liệu chính. Thay vào đó, chúng được ghi vào một tệp WAL trước.
Ví dụ, khi một hàng mới được chèn vào bảng, các thông tin chi tiết về thay đổi này (như giá trị của các cột) sẽ được ghi vào WAL trước khi dữ liệu thực tế được cập nhật trong bảng.
Ghi vào bộ đệm WAL:
- Các thay đổi được ghi vào bộ đệm WAL (WAL buffer), một vùng nhớ đệm trong RAM.
- Bộ đệm WAL được định kỳ ghi ra đĩa (flushed) để đảm bảo rằng dữ liệu trong bộ đệm này không bị mất nếu hệ thống gặp sự cố.
Ghi tệp WAL ra đĩa:
Quá trình này thường diễn ra đồng thời với việc ghi nhật ký vào bộ đệm WAL, đảm bảo rằng các thay đổi được bảo vệ ngay khi chúng xảy ra.
Sau khi các thay đổi đã được ghi vào bộ đệm WAL, chúng sẽ được ghi ra đĩa thành các tệp WAL (wal segments).
Nhờ cơ chế WAL, PostgreSQL có thể đảm bảo tính nhất quán và khả năng khôi phục dữ liệu cao, giúp bảo vệ dữ liệu trong các tình huống sự cố hệ thống.
4. Tại sao PostgreSQL không ghi trực tiếp vào đĩa mà lại ghi vào WAL?
Điểm kiểm tra là các điểm trong chuỗi giao dịch mà tại đó dữ liệu được đảm bảo đã được ghi vào đĩa.
Hoạt động của điểm kiểm tra bị hạn chế vì việc ghi vào đĩa là một tác vụ tốn nhiều tài nguyên và thực sự gây nhiều áp lực lên I/O của đĩa.
Tần suất của điểm kiểm tra thường được kiểm soát bởi hai cấu hình chính, tức là checkpoint_timeout hoặc max_wal_size , tùy theo cấu hình nào đến trước, hoạt động của điểm kiểm tra sẽ được kích hoạt.
Mặc định cho cả hai cấu hình là 5 phút và 1 GB.
Vì vậy, nếu bạn thấy các điểm kiểm tra diễn ra nhanh hơn 5 phút, thì đó là dấu hiệu rõ ràng cho thấy có một lượng lớn dữ liệu được ghi vào WAL. Trong trường hợp này, bạn cần quan sát I/O đĩa của mình và tăng max_wal_size cho phù hợp.
Trong trường hợp không có WAL nào được ghi kể từ điểm kiểm tra trước đó, các điểm kiểm tra mới sẽ bị bỏ qua.
5. Sự phổ biến
Khái niệm Write-Ahead Log (WAL) không chỉ giới hạn ở PostgreSQL mà còn được sử dụng trong nhiều hệ thống cơ sở dữ liệu khác. Dưới đây là một số ví dụ về nơi WAL hoặc các cơ chế dựa trên nhật ký tương tự được sử dụng:
- Cơ sở dữ liệu Oracle:
- Cơ sở dữ liệu Oracle triển khai một khái niệm tương tự được gọi là “Nhật ký làm lại” (Redo Log). Nhật ký làm lại ghi lại tất cả các thay đổi đã được thực hiện để đảm bảo khả năng phục hồi và tính nhất quán của dữ liệu.
- Microsoft SQL Server:
- SQL Server sử dụng “Nhật ký giao dịch” (Transaction Log), đóng vai trò là triển khai cơ chế ghi nhật ký ghi trước. Nhật ký giao dịch ghi lại tất cả các thay đổi đối với dữ liệu và duy trì tính toàn vẹn của cơ sở dữ liệu.
- MySQL:
- InnoDB, công cụ lưu trữ mặc định trong MySQL, sử dụng “Nhật ký giao dịch” (Transaction Log) được gọi là “Nhật ký InnoDB” (InnoDB Log) hoặc “Nhật ký làm lại” (Redo Log). Nó tuân theo nguyên tắc tương tự như WAL, trong đó các thay đổi được ghi vào nhật ký trước khi áp dụng vào các tệp dữ liệu.
- MongoDB:
- MongoDB, một cơ sở dữ liệu NoSQL, sử dụng nhật ký ghi trước chỉ thêm vào được gọi là “Oplog” (Operation Log). Oplog ghi lại tất cả các hoạt động ghi trong một bộ sưu tập có giới hạn, giúp đồng bộ hóa và khôi phục dữ liệu.
- Apache Kafka:
- Kafka, một nền tảng phát trực tuyến phân tán, sử dụng nhật ký ghi trước để cung cấp khả năng chịu lỗi và độ bền cho hệ thống nhắn tin của mình. Nhật ký này được gọi là “Nhật ký Kafka” (Kafka Log) hoặc “Kafka WAL”, ghi lại tất cả các tin nhắn đã xuất bản và đảm bảo tính bền vững của chúng.
Các cơ chế dựa trên nhật ký này đều tuân theo nguyên tắc ghi nhật ký trước khi thực hiện thay đổi lên dữ liệu thực tế, đảm bảo tính toàn vẹn và khả năng khôi phục dữ liệu trong các hệ thống cơ sở dữ liệu và nền tảng phát trực tuyến.