SQL Server có ghi lại các hoạt động không được cam kết không?


12

Tôi thường thấy các câu lệnh như bản ghi nhật ký máy chủ sql ghi lại mọi chuyển đổi và hoạt động.

Nhưng tôi bối rối về những gì xảy ra khi một giao dịch cuối cùng được khôi phục .

Nói một giao dịch rõ ràng có 3 báo cáo: statement A, statement B, statement C, và cuối cùng là một rollback statement D.

Bây giờ hãy nói rằng khi việc thực thi chưa đạt đến rollback statement D, liệu các sửa đổi statements A through Ccó được ghi lại từ nhật ký máy chủ sql không?

Hiểu 1 :

Báo cáo từ A đến D đều được ghi lại. SQL Server ghi lại mọi thứ, không có vấn đề gì.

Hiểu 2 : Sửa đổi chỉ được lưu trữ ở đâu đó trong bộ nhớ và chỉ được ghi lại để ghi nhật ký khi SQL Server thấy một commitcâu lệnh. Nếu nó trở thành một rollbackcâu lệnh, SQL Server chỉ cần bỏ qua transacrion, không có ghi để ghi nhật ký vì nó không phục vụ mục đích. Nói cách khác, SQL Server đăng nhập khi có một mạng lưới kết quả trướcsau khi giao dịch.

Cả hai đều có vẻ hợp lý, ít nhất là với tôi nhưng cả hai đều không thể đúng. Cảm ơn vì bất kì sự giúp đỡ.


Xin chào, Hãy thử [ systoolsgroup.com/sql-log-analyzer.html] (Trình phân tích nhật ký SQL) để phân tích những gì đang diễn ra trong tệp nhật ký. Bạn có thể thử phiên bản miễn phí của Trình phân tích nhật ký SQL SysTools để chỉ xem trước Dữ liệu nhật ký SQL. Hy vọng điều này làm việc cho bạn.
Rylan08

Câu trả lời:


13

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 ROLLBACKvà 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ý.


8

Sửa đổi các bảng cơ sở dữ liệu được ghi trước tiên vào tệp nhật ký, sau đó đến chính các bảng, trước tiên là trong bộ nhớ và sau đó, với một quy trình không đồng bộ được gọi CHECKPOINT, vào đĩa. Cơ chế này được gọi là WAL (Ghi nhật ký trước) và phổ biến cho tất cả các cơ sở dữ liệu quan hệ.

Bản thân nhật ký đầu tiên được ghi vào bộ nhớ (chính xác vào bộ đệm nhật ký) và sau đó vào đĩa, nhưng không có gì được chạm vào các bảng cơ sở dữ liệu cho đến khi nhật ký được ghi vào đĩa.

Cơ chế này cho phép cả hai chuyển tiếp các giao dịch đã cam kết và khôi phục các giao dịch không được cam kết trong quá trình phục hồi. Về ví dụ của bạn, nếu có điều gì đó tồi tệ xảy ra sau đó statement Cvà bạn đã committhay thế rollback(bạn không thể biết trước điều này), nếu không lưu từng bước trong giao dịch, RDBMS sẽ không có cách nào để khôi phục cơ sở dữ liệu một cách nhất quán cách và giao dịch sẽ không đáp ứng D(độ bền) trong ACID.

Khi một số thao tác được khôi phục, đó là tệp dữ liệu nhận thay đổi thuần (thông qua CHECKPOINT), không phải tệp nhật ký.


5

Hiểu 1 là chính xác, và spaghettidba và Joe có lời giải thích tốt.

Nếu bạn muốn tự mình kiểm tra (trong trường hợp kiểm tra), bạn có thể sử dụng tập lệnh bên dưới:

--create a database and table for testing
USE master
GO
CREATE DATABASE tranlogtest
GO
USE tranlogtest
GO
CREATE TABLE t1
(junk char(1))

CHECKPOINT
GO

BEGIN TRAN
INSERT t1 VALUES ('a')
INSERT t1 VALUES ('b')
INSERT t1 VALUES ('c')

ROLLBACK
INSERT t1 VALUES ('d')

SELECT *
FROM fn_dblog(NULL,NULL)

Bạn sẽ thấy rằng SQL Server ghi lại mọi thứ, ngay cả các bước được thực hiện để hoàn tác các hoạt động.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.