O log do SQL Server registra operações não confirmadas?

12

Costumo ver instruções como registros de log do servidor sql a cada transação e operação.

Mas eu estou confuso sobre o que acontece quando uma transação é finalmente rolou para trás .

Diga uma transação explícita tem 3 afirmações: statement A, statement B, statement C, e finalmente um rollback statement D.

Agora diga que quando a execução não atingir o rollback statement D, as modificações resultantes serão statements A through Cregistradas no log do servidor sql?

Compreensão 1 :

As frases A a D são todas gravadas. O SQL Server registra tudo, não importa o quê.

Noções sobre 2 : As modificações são armazenadas apenas em algum lugar da memória e registradas apenas para o log quando o SQL Server vê uma commitinstrução. Se for uma rollbackdeclaração, o SQL Server simplesmente ignora a transação, nenhuma gravação no log acontece porque não serve para nada. Em outras palavras, o SQL Server registra quando há um resultado líquido antes e depois das transações.

Ambos parecem lógicos, pelo menos para mim, mas eles não podem estar certos. Obrigado por qualquer ajuda.

John Smith
fonte
Oi, Tente [ systoolsgroup.com/sql-log-analyzer.html] (SQL Log Analyzer) para analisar o que está acontecendo no arquivo de log. Você pode experimentar a versão gratuita do SysTools SQL Log Analyzer para visualizar apenas os dados de log do SQL. Espero que funcione para voce.
precisa saber é o seguinte

Respostas:

13

O entendimento 1 está correto. O SQL Server registra todas as operações que alteram dados para o log de transações. Uma reversão é uma alteração nos dados, portanto, ela também registra isso no log de transações. Como a instrução A run, ela grava dados no log de transações e também reserva os dados no log de transações, caso a instrução A precise ser revertida. O mesmo vale para B e C. Quando você reverte a transação, mais informações serão gravadas no log.

Existem várias maneiras de ver isso em ação. Abaixo, uma demonstração rápida. Aqui está a consulta que usarei para ver o que foi gravado no log:

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;

Minha mesa:

create table TLOGDEMO (FLUFF VARCHAR(1000));

BEGIN TRANSACTION

A consulta A usa log mínimo:

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

Após um:

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

A consulta B não usa log mínimo:

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

Depois de B:

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

A consulta C altera menos dados:

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

Após C:

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

Agora vou emitir um ROLLBACKe consultar o DMV enquanto a reversão acontece. Abaixo está uma tabela com alguns instantâneos:

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

Durante o ROLLBACK, os bytes usados ​​aumentam e o número reservado de bytes diminui. Isso ocorre porque o SQL Server está usando o espaço reservado anteriormente para desfazer a transação. Para desfazer a transação, ele deve alterar os dados para gravar mais dados no log.

Joe Obbish
fonte
8

As modificações nas tabelas do banco de dados são gravadas primeiro no arquivo de log, depois nas próprias tabelas, primeiro na memória e, em seguida, com um processo assíncrono chamado CHECKPOINT, no disco. Esse mecanismo é conhecido como WAL (Write-Ahead Logging) e é comum a todos os bancos de dados relacionais.

O próprio log é gravado primeiro na memória (no buffer do log, precisamente) e depois no disco, mas nada é tocado nas tabelas do banco de dados até que o log seja gravado no disco.

Esse mecanismo permite reverter transações confirmadas e reverter transações não confirmadas durante o processo de recuperação. Em relação ao seu exemplo, se algo ruim acontecesse depois statement Ce você tivesse um em commitvez de um rollback(você não pode saber isso com antecedência), sem salvar todas as etapas da transação, o RDBMS não teria como recuperar o banco de dados de maneira consistente. e a transação não atenderia a D(durabilidade) emACID .

Quando algumas operações são revertidas, é o arquivo de dados que recebe as alterações líquidas (via CHECKPOINT), não o arquivo de log.

spaghettidba
fonte
5

O entendimento 1 está correto, e spaghettidba e Joe têm boas explicações.

Se você estiver interessado em testar você mesmo (em uma instância de teste), use o script abaixo:

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

Você verá que o SQL Server registra tudo, até as etapas executadas para desfazer operações.

Forrest
fonte