Регистрирует ли журнал SQL Server незафиксированные операции?

12

Я часто вижу такие заявления, как записи в журнале sql server при каждой операции и операции.

Но я путать о том, что происходит , когда транзакция в конце концов проката назад .

Скажем явная транзакция имеет 3 положения: statement A, statement B, statement C, и , наконец rollback statement D.

Теперь скажите, что когда выполнение еще не достигнуто rollback statement D, будут statements A through Cли внесенные в журнал изменения записаны в журнал сервера sql?

Понимание 1 :

Заявления от A до D все записываются. SQL Server записывает все, несмотря ни на что.

Понимание 2. Изменения хранятся только где-то в памяти и записываются в журнал только тогда, когда SQL Server видит commitоператор. Если это rollbackутверждение, SQL Server просто игнорирует транзакцию, запись в журнал не происходит, потому что это не имеет смысла. Другими словами, SQL Server регистрирует, когда есть чистый результат до и после транзакций.

И то, и другое кажется логичным, по крайней мере, мне, но они не могут быть правы. Спасибо за любую помощь.

Джон Смит
источник
Здравствуйте, Попробуйте [ systoolsgroup.com/sql-log-analyzer.html] (анализатор журнала SQL), чтобы проанализировать, что происходит в файле журнала. Вы можете попробовать бесплатную версию SysTools SQL Log Analyzer только для предварительного просмотра данных журнала SQL. Надеюсь, что это работает для вас.
Rylan08

Ответы:

13

Понимание 1 правильно. SQL Server записывает каждую операцию, которая изменяет данные, в журнал транзакций. Откат - это изменение данных, поэтому он также записывает это в журнал транзакций. При выполнении оператора A он записывает данные в журнал транзакций, а также резервирует данные в журнале транзакций на случай, если необходимо выполнить откат оператора A. То же самое верно для B и C. При откате транзакции дополнительная информация будет записана в журнал.

Есть много способов увидеть это в действии, поэтому ниже приведена краткая демонстрация. Вот запрос, который я буду использовать, чтобы увидеть, что было записано в журнал:

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;

Мой стол:

create table TLOGDEMO (FLUFF VARCHAR(1000));

BEGIN TRANSACTION

Запрос A использует минимальное ведение журнала:

INSERT INTO TLOGDEMO WITH (TABLOCK)
SELECT REPLICATE('A', 1000)
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

После:

╔═══════════════════╦════════════╦════════════════╗
 transaction_count  used_bytes  reserved_bytes 
╠═══════════════════╬════════════╬════════════════╣
                 1    24006640       175429451 
╚═══════════════════╩════════════╩════════════════╝

Запрос B не использует минимальное ведение журнала:

INSERT INTO TLOGDEMO
SELECT REPLICATE('B', 1000)
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

После Б:

╔═══════════════════╦════════════╦════════════════╗
 transaction_count  used_bytes  reserved_bytes 
╠═══════════════════╬════════════╬════════════════╣
                 1  7352935708      1613986255 
╚═══════════════════╩════════════╩════════════════╝

Запрос C изменяет меньше данных:

INSERT INTO TLOGDEMO
SELECT REPLICATE('C', 1000)
FROM master..spt_values c;

После C:

╔═══════════════════╦════════════╦════════════════╗
 transaction_count  used_bytes  reserved_bytes 
╠═══════════════════╬════════════╬════════════════╣
                 1  7355821748      1614545331 
╚═══════════════════╩════════════╩════════════════╝

Теперь я буду выдавать ROLLBACKи запрашивать DMV, пока происходит откат. Ниже приведена таблица с несколькими снимками:

╔═══════════════════╦════════════╦════════════════╗
 transaction_count  used_bytes  reserved_bytes 
╠═══════════════════╬════════════╬════════════════╣
 1                  7393305528  1573797677     
 1                  7458767420  1502635737     
 1                  7682482356  1259440979     
 1                  7803881368  1127471233     
 ...                ...         ...            
╚═══════════════════╩════════════╩════════════════╝

В течение ROLLBACKэтого времени используемые байты увеличиваются, а зарезервированное количество байтов уменьшается. Это связано с тем, что SQL Server использует пространство, отведенное ранее для отмены транзакции. Чтобы отменить транзакцию, она должна изменить данные, чтобы записать больше данных в журнал.

Джо Оббиш
источник
8

Изменения в таблицах базы данных сначала записываются в файл журнала, затем в сами таблицы, сначала в память, а затем с помощью асинхронного процесса CHECKPOINTна диск. Этот механизм известен как WAL (запись в журнал записи) и является общим для всех реляционных баз данных.

Сам журнал сначала записывается в память (точнее в буфер журнала), а затем на диск, но ничего не затрагивается таблицами базы данных, пока журнал не будет записан на диск.

Этот механизм позволяет как откатывать зафиксированные транзакции, так и откатывать незафиксированные транзакции в процессе восстановления. Что касается вашего примера, если после чего-то случилось что-то плохое statement Cи у вас было commitвместо rollback(вы не можете знать об этом заранее), не сохраняя каждый шаг в транзакции, СУБД не имела бы способа восстановить базу данных в согласованном виде. Таким образом, и сделка не будет соответствовать D(долговечность) в ACID.

Когда некоторые операции откатываются, это файл данных, который получает сетевые изменения (через CHECKPOINT), а не файл журнала.

spaghettidba
источник
5

Понимание 1 правильно, и спагеттидба и Джо имеют хорошие объяснения.

Если вы заинтересованы в тестировании для себя (на тестовом экземпляре, пожалуйста), вы можете использовать следующий скрипт:

--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)

Вы увидите, что SQL Server записывает все, даже шаги, предпринятые для отмены операций.

Форрест
источник