Conteúdo do arquivo de log de transações com mais detalhes


11

Eu tenho uma pergunta sobre o conteúdo do log de transações (vamos chamá-lo de LDF para abreviar). Estou assumindo um banco de dados com o modelo de recuperação completa.

Eu li que o arquivo LDF contém (logs) todas as operações no banco de dados (que está no modo de recuperação total). Como é diferente do registro durante BEGIN TRAN; COMMAND(s); COMMIT? Estou perguntando, porque aparentemente você pode reverter transações, mas não pode reverter comandos padrão (no modo de recuperação total).

Eu acho que durante a transação o conteúdo que está sendo registrado no arquivo LDF é diferente do registro regular de recuperação completa. Isso está certo? Como é diferente? É apenas a inclusão de operações "desfazer" para cada ação?

Em uma nota relacionada, ouvi dizer que existem ferramentas comerciais para "reverter / desfazer" consultas padrão usando o arquivo LDF de recuperação completa. Como eles fazem isso? Eles analisam o conteúdo do LDF e tentam criar operações inversas / desfazer?


Respostas:


11

A diferença é que o que você chama de "comandos padrão" tem transações implícitas (como em "não explícitas" e não implícitas, que significam algo diferente ). Portanto, toda vez que você emitir um INSERTcomando sem uma transação explícita, ela abrirá uma transação, insira os dados e confirme automaticamente. Isso é chamado de transação de confirmação automática.

É também por isso que você não pode reverter isso INSERT: já está confirmado. Portanto, a regra é a mesma que transações explícitas: você não pode reverter uma vez que elas foram confirmadas .

Você pode ver o que quero dizer diretamente de dentro do SQL Server.

A Microsoft envia ao SQL Server um DMF chamado sys.fn_dblogque pode ser usado para examinar o log de transações de um determinado banco de dados.

Para esse experimento simples, vou usar o banco de dados AdventureWorks:

USE AdventureWorks2008;
GO

SELECT TOP 10 *
FROM dbo.Person;
GO

INSERT INTO dbo.Person (FirstName, MiddleName, LastName, Gender, Date)
VALUES ('Never', 'Stop', 'Learning', 'M', GETDATE());
COMMIT;

BEGIN TRAN;
INSERT INTO dbo.Person (FirstName, MiddleName, LastName, Gender, Date)
VALUES ('Never', 'Stop', 'Learning', 'M', GETDATE());
COMMIT;
GO

SELECT *
FROM sys.fn_dblog(NULL, NULL);
GO

Aqui estou fazendo duas inserções: uma com e uma sem uma transação explícita.

No arquivo de log, você pode ver que não há absolutamente nenhuma diferença entre os dois:

Confirmação automática versus transações explícitas

O vermelho é o de INSERTuma transação de confirmação automática e o azul é o de INSERTuma transação explícita.

Quanto às ferramentas de terceiros mencionadas, sim, elas analisam o log do banco de dados e geram código T-SQL normal para "desfazer" ou "refazer" as operações. Normalmente, quero dizer que eles não fazem nada de especial além de gerar um script que terá o efeito de fazer exatamente o oposto do que está no arquivo de log.


7

Vou explicar como as ferramentas comerciais funcionam, no exemplo do ApexSQL Log

E em nota relacionada, ouvi dizer que existem ferramentas comerciais para "reverter / desfazer" consultas padrão usando o arquivo LDF de recuperação completa. Como eles fazem isso? Eles analisam o conteúdo do LDF e tentam criar operações inversas / desfazer?

Sim, eles lêem o arquivo LDF (online ou desanexado) e os arquivos trn (backups do log de transações), descobrem qual transação ocorreu e criam um script que fará o mesmo ou o contrário.

Observe, no entanto, que o script de desfazer e refazer não precisa ser exatamente o mesmo que o executado, mas o efeito será exatamente o mesmo.

Por exemplo, se o script executado foi:

DELETE FROM [Person].[AddressType] WHERE Name  = 'New Loc22'

O log de transações registrará que a linha da tabela com os valores da coluna 9, 'Novo Loc22', '41BC2FF6-F0FC-475F-8EB9-CEC1805AA0F6' e '2002/06/01 00: 00: 00.000' é excluída. Na estrutura da tabela, a ferramenta lerá que a chave Primária é a coluna AddressType e criará o seguinte script refazer:

DELETE FROM [Person].[AddressType] WHERE [AddressTypeID] = 9

Observe que a transação está vinculada à coluna Chave primária, não à coluna usada na cláusula where original. Da mesma forma, o script de desfazer será:

INSERT INTO [Person].[AddressType] ([AddressTypeID], [Name], [rowguid], [ModifiedDate]) VALUES (9, N'New loc22' COLLATE SQL_Latin1_General_CP1_CI_AS, '41bc2ff6-f0fc-475f-8eb9-cec1805aa0f6', '20020601 00:00:00.000')

insira a descrição da imagem aqui

Isenção de responsabilidade: trabalho para o ApexSQL como engenheiro de suporte

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.