Log File SQL Để Làm Gì

Khi bạn dùng Microsoft Word, bạn để ý thấy có một file tạm nằm cùng trong folder với file chính. Nếu windows bị shutdown đột ngột file tạm vẫn nằm ở đó, còn khi bạn soạn thảo xong và đóng Word lại thì file đó tự động bị xóa. File tạm này dùng cho các chức năng như autosave, recovery khi bị đóng đột ngột, undo… Log file trong SQL Server cũng có chức năng giống như file tạm đó, nhưng ở mức tinh vi hơn. Nó đóng góp rất nhiều vai trò trong tính năng ACID của hệ thống (ACID = Atom – nguyên tử, Consistency – toàn vẹn, Isolation – cô lập, và Durability – bền bỉ). Với Word thì đó chỉ là tính năng tiện lợi cho người dùng, còn với SQL Server thì đó là cam kết của hệ thống đối với dữ liệu và các giao dịch thực hiện trên nó.
Khi nhận được một lệnh cập nhật dữ liệu, các bước sau sẽ xảy ra bên trong hệ thống:
- Các trang chứa các bản ghi bị ảnh hưởng được tải vào bộ nhớ. Trong trường hợp đối với INSERT thì các trang được tạo ngay trong bộ nhớ vì lúc này chưa có dữ liệu ở đĩa. Bước này được thực hiện giống hệt như đối với một lệnh SELECT, vì thế index giúp tăng hiệu năng câu truy vấn SELECT như thế nào thì nó cũng giúp câu lệnh UPDATE/DELETE như thế.
- Dữ liệu được cập nhật trong memory page (các trang trong bộ nhớ). Nếu là DELETE thì bản ghi được đánh dấu xóa. Các memory page được đánh dấu là “bẩn” (dirty page).
- Đồng thời, nội dung giao dịch được ghi vào log file. Mỗi bản ghi dữ liệu bị ảnh hưởng sẽ có một bản ghi tương ứng trong log file, và bản ghi trong log file bao gồm chi tiết hành động (UPDATE, DELETE, hay INSERT), dữ liệu trước khi xảy ra hành động, và dữ liệu sau khi xảy ra hành động. Đến thời điểm này, chưa có gì xảy ra đối với data file. Cơ chế này gọi là Write-Ahead-Log (hay gọi tắt là WAL), nghĩa là các thao tác đều được lưu vào log file trước tiên.
- Trong SQL Server có một tiến trình độc lập gọi là checkpoint. Tiến trình này định kỳ quét bộ nhớ và ghi các trang bẩn ra đĩa (data file) và đánh dấu chúng lại là “sạch”. Nếu lệnh cập nhật ở trên kéo dài, checkpoint có thể xảy ra trong khi lệnh vẫn đang được thực hiện. Điều này không có gì bất ổn và các trang bẩn tại thời điểm đó được đẩy ra đĩa. Checkpoint giúp tăng hiệu năng I/O của hệ thống vì nó đẩy các trang bẩn ra đĩa thành từng bó 32 trang. Nếu mỗi trang bẩn đều tự động được đẩy ra đĩa tức thì, I/O sẽ trở nên quá bận bịu với các yêu cầu ghi đơn lẻ. Checkpoint cũng tạo một bản ghi trong log file, tất nhiên với nội dung là “CHECKPOINT”. Điều này cực kỳ quan trọng vì nó cần cho quá trình khôi phục (recovery) mà tôi sẽ nói thêm ở phần dưới.
- Nếu câu lệnh cập nhật kết thúc tốt đẹp, log file được tạo thêm một bản ghi với nội dung “COMMIT” để xác nhận giao dịch đã được COMMIT. Vai trò của log file đến đây là xong, cho dù dữ liệu mới cập nhật chưa được ghi hết ra data file. Checkpoint sẽ làm nốt việc đó. Nếu có một câu truy vấn khác động đến các bản ghi này, nó sẽ đọc thẳng từ bộ nhớ và không cần đụng đến đĩa.
- Nếu có sự cố nào đó (ví dụ gặp một bản ghi vi phạm ràng buộc khóa ngoại), toàn bộ lệnh cập nhật sẽ được ROLLBACK. Việc ROLLABACK đơn giản là lấy mỗi bản ghi trong log file và cập nhật lại giá trị cũ vào data file, và các trang bẩn được reset lại thành sạch.

Bạn để ý trong bước 3 ở trên, kể cả sau khi câu lệnh thực hiện xong và dữ liệu đã được COMMIT, dữ liệu mới chưa hẳn đã được ghi hết ra data file vì chưa đến kỳ checkpoint. Vậy điều gì sẽ xảy ra nếu hệ thống bị shutdown đột ngột (ví dụ mất điện)? Đây chính là yếu tố D – Durability trong ACID, theo đó hệ thống cam kết rằng một khi giao dịch của quí vị đã được COMMIT thì dữ liệu của quí vị sẽ nằm trong đĩa kể cả khi bị cúp điện ngang lưng. Khi hệ thống khởi động trở lại, tiến trình Recovery sẽ rà soát các log record trong log file, và tất cả các bản ghi của các giao dịch đã được COMMIT xảy ra sau lần checkpoint cuối cùng sẽ được cập nhật sang data file. Khi bạn thấy database ở chế độ RECOVERY sau khi hệ thống khởi động lại đột ngột, chính là để nó hoàn tất các cập nhật này, và bạn không truy cập được database cho đến khi recovery xong.

Trong bài này tôi chỉ nêu ví dụ với các lệnh cập nhật dữ liệu, nhưng cơ chế cũng giống như vậy với các lệnh về cấu trúc database như CREATE TABLE hay ALTER INDEX. Vì log file cần phải chứa toàn bộ dữ liệu trước và sau giao dịch, nên nó có thể phình rất to nếu câu lệnh (hoặc nhiều câu lệnh gom trong một transaction) tác động đến một lượng dữ liệu lớn. Thời gian rollback khi gặp sự cố cũng kéo dài hơn. Do đó khi viết chương trình bạn nên giảm tối thiểu kích thước transaction có thể được.