Log File Để Làm Gì

Vũ Huy Tâm

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.




Tags:

5 Comments
Posted on 31/10/2014 | Categories: Bên trong SQL Server, Database Administration

Các bài viết tương tự

Comments
  • nguoihanoi (15/11/2014 2:26 am)

    Lâu ngày gặp lại, thấy chủ đề mà choáng.

    Cái này thuộc loại ngâm kíu rồi, có lẽ chỉ dành cho những anh kiếng cận, dân ta chỉ khoái loại sớm gieo chiều gặt, nên chắc chủ đề này ít người hứng thú. Để thêm phần náo nhiệt, tui xin lạm bàn chút, không qua sách vở nào cả, chỉ đoán mò.

    Theo tui, chủ xị sót 1 phần quan trọng, gọi tên là gì thì tui không biết nên tạm gọi là “đồng chí X” :) . Nó có tác dụng gần tương tự cái trang dữ liệu trong bộ nhớ, chỉ khác là nó áp dụng cho tập tin log, chứ không phải tập tin của dữ liệu. Trong quá trình sửa đổi, đồng chí X lưu trữ dữ liệu trước khi sửa. Xong rồi nó mới áp dụng sửa đổi mới cho trang dữ liệu trong bộ nhớ. Sau đó mới nhập dữ liệu cho tập tin log. Tập tin log nhập lệnh commit. Các khóa ở trang dữ liệu trong bộ nhớ sẽ được dỡ bỏ. Công việc coi như xong. Còn khi nào thì áp dụng những thay đổi này cho tập tin dữ liệu thì chủ xị đã đề cập.

    Xin đừng hỏi tui “đồng chí X” là ai nhé. Nhiều người không biết chứ chẳng riêng gì tui. Chỉ biết ổng tồn tại. há há.

    Để xác định sự tồn tại của “đồng chí X”, các thánh hãy đặt câu hỏi : bằng cách nào, dựa vào đâu để hệ thống có thể rollback khi gặp sự cố giữa đường như vi phạm ràng buộc khóa ngoại? Xin đừng bảo dựa vào tập tin log nhé. Anh Bill lẫn anh Larry và các anh khác đều không làm thế. Tại sao ? Các thánh hỏi tui thì tui hỏi ai đây ? :)

  • Red Devilic (15/11/2014 8:21 am)

    Trên Oracle thì mình gọi tên được “đồng chí X” này. SQL Server thì chịu, nhường sân cho các cao thủ :D

  • nguoihanoi (15/11/2014 11:24 am)

    Chào bác đỏ, lâu ngày quá. Bác giải thích thêm về chuyện log này của Oracle đi, nghe đâu nó rắc rối hơn nhiều.

    Nhân đây tui có 1 vấn đề gặp phải trong quá trình kiếm cơm, mà dân ta gọi nôm na là trong quá trình “phục vụ nhân dân” :)

    Một lần làm việc tối ưu hóa tôi gặp đoạn mã sau (đại khái) :

    if exists (select top 1 from (select truongA, count(*) from bangX where truongA=’giaTriNaoDo’ group by truongA having count(*) > 0 ) x)
    begin
    declare @dem int = 0
    select @dem = count(*) from (select truongA, count(*) from bangX where truongA=’giaTriNaoDo’ group by truongA having count(*) > 0) x
    – thực hiện tiếp công việc khác
    end

    Mục đích của đoạn mã là tìm sự trùng lặp trong bảng. Nếu có dữ liệu trùng thì làm 1 số việc, còn không có thì thôi.

    Tui cho rằng chỉ cần thực hiện

    declare @dem int = 0
    select @dem = count(*) from (select truongA, count(*) from bangX where truongA=’giaTriNaoDo’ group by truongA having count(*) > 0) x
    if @dem > 0
    begin
    – thực hiện tiếp công việc khác
    end

    Nhưng người ta không đồng ý, bảo rằng đoạn mã của họ được viết bởi 1 giảng viên đại học nổi tiếng, trong 1 lần hợp đồng tối ưu hóa ở công ty họ. Nên họ không thể chấp nhận đề nghị thay đổi của 1 thằng đấm bóp dạo như tui.

    Ý kiến các bác thế nào ?

    Lưu ý : đoạn mã trên có thể không chính xác 100%, thậm chí sai cú pháp, chỉ là ý tưởng : truy xuất bảng 2 lần, nhưng lần đầu thì áp dụng top.

    • Red Devilic (27/11/2014 12:01 pm)

      Trên Oracle nếu tui không nhầm thì nó gọi là Undo Tablespace. ý nghĩa của nó y hệt như bác nói vậy, còn hoạt động cụ thể ra sao, liên quan đến các process nào thì phải ngâm cứu thêm, đại khái tui nhớ vậy thôi :D

      :D Ví dụ của bác thì kinh điển rồi, kể cả nguyên tắc lập trình cũng vậy thôi, hạn chế tính toán lại, lưu giá trị tính. Đến DW còn được xây dựng như thế nữa là…

      Người viết câu trên giống hệt tui hồi đi làm trong trường ĐH, exp mới có 1 năm tưởng mình biết hết về CSDL, đến giờ đã 6 năm càng học càng làm càng thấy hồi xưa mình kém thế nào :D

  • thucungcuatoi (06/08/2015 4:28 am)

    Nghĩa là cái Transaction Log này nó sẽ lưu mọi thứ trước và sau khi update, delete,… Việc lưu trữ này nhằm mục đích phục hồi dữ liệu cho data file? Nếu mình shink file log này thì sẽ ảnh hưởng gì đến hệ thống không ngoài việc sẽ mất đi history của transaction? Mính có 1 DB và file LDF của nó đang hơn 30GB?

Leave a Reply

Hướng dẫn: Để nhập mã T-SQL bạn dùng thẻ <pre lang="tsql"> và </pre>.
Ví dụ: <pre lang="tsql">SELECT * FROM MyTable</pre>