Contenu du fichier journal des transactions plus en détail


11

J'ai une question concernant le contenu du journal des transactions (appelons-le simplement LDF). Je suppose une base de données avec un modèle de récupération complète.

J'ai lu que le fichier LDF contient (journaux) chaque opération dans la base de données (qui est en mode de récupération complète). En quoi est-ce différent de la journalisation pendant BEGIN TRAN; COMMAND(s); COMMIT? Je demande parce qu'apparemment, vous pouvez annuler les transactions, mais vous ne pouvez pas annuler les commandes standard (en mode de récupération complète).

Je suppose que pendant la transaction, le contenu connecté au fichier LDF est différent de celui de la journalisation de récupération complète régulière. Est-ce correct? En quoi est-ce différent? S'agit-il uniquement de l'inclusion d'opérations «annuler» pour chaque action?

Sur une note connexe, j'ai entendu dire qu'il existe des outils commerciaux pour "annuler / annuler" les requêtes standard en utilisant le fichier LDF de récupération complète. Comment font-ils? Analysent-ils le contenu LDF et tentent-ils de proposer des opérations inverses / annulées?


Réponses:


11

La différence est que ce que vous appelez des "commandes standard" ont des transactions implicites (comme dans les transactions implicites "non explicites" et non réelles qui signifient quelque chose de différent ), donc chaque fois que vous exécutez une INSERTcommande sans transaction explicite, elle ouvrira une transaction, insérez les données et validez automatiquement. Cela s'appelle une transaction de validation automatique.

C'est aussi pourquoi vous ne pouvez pas annuler cela INSERT: il est déjà engagé. La règle est donc la même que pour les transactions explicites: vous ne pouvez pas revenir en arrière une fois qu'elles ont été validées .

Vous pouvez voir ce que je veux dire directement depuis l'intérieur de SQL Server.

Microsoft expédie SQL Server avec un DMF appelé sys.fn_dblogqui peut être utilisé pour regarder à l'intérieur du journal des transactions d'une base de données donnée.

Pour cette expérience simple, je vais utiliser la base de données 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

Ici, je fais deux insertions: une avec et une sans transaction explicite.

Dans le fichier journal, vous pouvez voir qu'il n'y a absolument aucune différence entre les deux:

Autocommit vs transactions explicites

Le rouge correspond INSERTà une transaction de validation automatique et le bleu INSERTà une transaction explicite.

Quant aux outils tiers que vous mentionnez, oui, ils analysent le journal de la base de données et génèrent du code T-SQL normal pour "annuler" ou "refaire" les opérations. Par normal, je veux dire qu'ils ne font rien d'autre que de générer un script qui aura pour effet de faire exactement le contraire de ce qui est dans le fichier journal.


7

Je vais vous expliquer comment fonctionnent les outils commerciaux, sur l'exemple de journal ApexSQL

Et sur une note connexe, j'ai entendu dire qu'il existe des outils commerciaux pour «annuler / annuler» les requêtes standard en utilisant le fichier LDF de récupération complète. Comment font-ils? Analysent-ils le contenu LDF et tentent-ils de proposer des opérations inverses / annulées?

Oui, ils lisent le fichier LDF (en ligne ou détaché) et les fichiers trn (sauvegardes du journal des transactions), trouvent quelle transaction s'est produite et créent un script qui fera la même chose, ou l'inverse.

Notez cependant que les scripts d'annulation et de rétablissement ne doivent pas être exactement les mêmes que ceux exécutés, mais l'effet sera exactement le même.

Par exemple, si le script exécuté était:

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

Le journal des transactions enregistrera que la ligne du tableau avec les valeurs de colonne 9, «New Loc22», «41BC2FF6-F0FC-475F-8EB9-CEC1805AA0F6» et «2002/06/01 00: 00: 00.000» est supprimée. À partir de la structure de la table, l'outil lira que la clé primaire est la colonne AddressType et créera le script de rétablissement suivant:

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

Notez que la transaction est liée à la colonne Clé primaire et non à la colonne utilisée dans la clause where d'origine. De même, le script d'annulation sera:

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

entrez la description de l'image ici

Avertissement: je travaille pour ApexSQL en tant qu'ingénieur de support

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.