Hiểu 1 là đúng. SQL Server ghi lại mọi hoạt động thay đổi dữ liệu vào nhật ký giao dịch. Phục hồi là một thay đổi đối với dữ liệu, do đó, nó cũng ghi lại vào nhật ký giao dịch. Khi câu lệnh A chạy, nó sẽ ghi dữ liệu vào nhật ký giao dịch và cũng sẽ dự trữ dữ liệu trong nhật ký giao dịch trong trường hợp câu lệnh A cần được khôi phục. Điều tương tự cũng đúng với B và C. Khi bạn quay lại giao dịch, nhiều thông tin sẽ được ghi vào nhật ký.
Có rất nhiều cách để thấy điều này trong thực tế, vì vậy dưới đây là một bản demo nhanh. Đây là truy vấn mà tôi sẽ sử dụng để xem những gì đã được ghi vào nhật ký:
SELECT
COUNT(*) transaction_count
, SUM(database_transaction_log_bytes_used) used_bytes
, SUM(database_transaction_log_bytes_reserved) reserved_bytes
FROM sys.dm_tran_database_transactions
where database_id = 10;
Bảng của tôi:
create table TLOGDEMO (FLUFF VARCHAR(1000));
BEGIN TRANSACTION
Truy vấn A sử dụng ghi nhật ký tối thiểu:
INSERT INTO TLOGDEMO WITH (TABLOCK)
SELECT REPLICATE('A', 1000)
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
Sau một:
╔═══════════════════╦════════════╦════════════════╗
║ transaction_count ║ used_bytes ║ reserved_bytes ║
╠═══════════════════╬════════════╬════════════════╣
║ 1 ║ 24006640 ║ 175429451 ║
╚═══════════════════╩════════════╩════════════════╝
Truy vấn B không sử dụng ghi nhật ký tối thiểu:
INSERT INTO TLOGDEMO
SELECT REPLICATE('B', 1000)
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
Sau B:
╔═══════════════════╦════════════╦════════════════╗
║ transaction_count ║ used_bytes ║ reserved_bytes ║
╠═══════════════════╬════════════╬════════════════╣
║ 1 ║ 7352935708 ║ 1613986255 ║
╚═══════════════════╩════════════╩════════════════╝
Truy vấn C thay đổi ít dữ liệu hơn:
INSERT INTO TLOGDEMO
SELECT REPLICATE('C', 1000)
FROM master..spt_values c;
Sau c:
╔═══════════════════╦════════════╦════════════════╗
║ transaction_count ║ used_bytes ║ reserved_bytes ║
╠═══════════════════╬════════════╬════════════════╣
║ 1 ║ 7355821748 ║ 1614545331 ║
╚═══════════════════╩════════════╩════════════════╝
Bây giờ tôi sẽ đưa ra một ROLLBACK
và truy vấn DMV trong khi việc khôi phục xảy ra. Dưới đây là bảng của một vài ảnh chụp nhanh:
╔═══════════════════╦════════════╦════════════════╗
║ transaction_count ║ used_bytes ║ reserved_bytes ║
╠═══════════════════╬════════════╬════════════════╣
║ 1 ║ 7393305528 ║ 1573797677 ║
║ 1 ║ 7458767420 ║ 1502635737 ║
║ 1 ║ 7682482356 ║ 1259440979 ║
║ 1 ║ 7803881368 ║ 1127471233 ║
║ ... ║ ... ║ ... ║
╚═══════════════════╩════════════╩════════════════╝
Trong thời gian ROLLBACK
, các byte được sử dụng tăng lên và số lượng byte dự trữ giảm. Đó là bởi vì SQL Server đang sử dụng không gian mà nó dành riêng trước đó để hoàn tác giao dịch. Để hoàn tác giao dịch, nó phải thay đổi dữ liệu để ghi nhiều dữ liệu hơn vào nhật ký.