J'ai une question concernant le journal des transactions (appelons-le de cela LDF pour courte durée). 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 à la base de données (en mode de récupération complète). Comment est-il différent de la journalisation pendant BEGIN TRAN; COMMAND(s); COMMIT
? Je vous demande car apparemment, vous pouvez faire rouler des transactions, mais vous ne pouvez pas rouler les commandes standard (en mode de récupération complète).
Je suppose que pendant la transaction, le contenu étant connecté dans le fichier LDF est différent de la journalisation normale de récupération complète. Est-ce correct? Comment est-ce différent? N'est-ce que l'inclusion d'opérations "annuler" pour chaque action?
Sur une note connexe, j'ai entendu dire qu'il existe des outils commerciaux sur les requêtes standard "Rollback/Annuler" à l'aide de fichiers LDF de récupération complet. Comment font-ils? Est-ce qu'ils analysent le contenu du LDF et essaient de venir avec des opérations inverse/annuler?
La différence est que ce que vous appelez des "commandes standard" ont des transactions implicites (comme dans "Non explicite" et non réelles transactions implicites qui signifient quelque chose de différent ), donc chaque fois que vous émettez un INSERT
Commande sans transaction explicite, il ouvrira une transaction, insérera les données et s'engagera automatiquement. Ceci s'appelle une transaction d'autocommande.
C'est aussi pourquoi vous ne pouvez pas annuler cette annulation INSERT
: c'est déjà engagé. La règle est donc la même que celle des transactions explicites: , vous ne pouvez pas resserrer une fois qu'ils ont été commis .
Vous pouvez voir ce que je veux dire directement à partir de SQL Server.
Microsoft Ships SQL Server avec un DMF appelé sys.fn_dblog
qui peut être utilisé pour regarder à l'intérieur du journal de transaction d'une base de données donnée.
Pour cette expérience simple, je vais utiliser la base de données AventureWorks:
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 inserts: un avec et un sans transaction explicite.
Dans le fichier journal, vous pouvez voir qu'il n'y a absolument aucune différence entre les deux:
Le rouge est le INSERT
dans une transaction d'autocommande et le bleu est le INSERT
avec une transaction explicite.
En ce qui concerne les outils de 3ème partie que vous avez mentionnés, 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. En normal, je veux dire qu'ils ne font rien de spécial autre que de générer un script qui aura pour effet de faire exactement le contraire de ce qui se trouve dans le fichier journal.
Je vais expliquer comment fonctionnent les outils commerciaux, sur l'exemple de journal Apexsql
Et sur la note connexe, j'ai entendu dire qu'il existe des outils commerciaux sur les requêtes standard "Rollback/Annuler" à l'aide du fichier LDF de récupération complète. Comment font-ils? Est-ce qu'ils analysent le contenu du LDF et essaient de venir avec des opérations inverse/annuler?
Oui, ils ont lu le fichier LDF (en ligne ou détaché) et les fichiers TRN (sauvegardes de journal de transaction), trouvent quelle transaction s'est produite et crée un script qui fera de même, ou le contraire.
Notez toutefois que le script annuler et redo ne doit pas être exactement identique à celui exécuté, 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 de la table avec les valeurs de colonne 9, 'Nouveau LOC22', "41BC2FF6-F0FC-475F-8EB9-CEC1805AA0F6", et '2002/06/01 00: 00: 00.000' est supprimé. À partir de la structure de la table, l'outil lira que la clé principale est la colonne Adressype et créera le script de Redo suivant:
DELETE FROM [Person].[AddressType] WHERE [AddressTypeID] = 9
Notez que la transaction est liée à la colonne Touche principale, non à la colonne utilisée dans l'original où la clause. 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')
Disclaimer: Je travaille pour Apexsql en tant qu'ingénieur de support