Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

ROLLBACK TRUNCATE dans SQL Server

Avez-vous déjà accidentellement exécuté la commande TRUNCATE commande sur une mauvaise table ? Cela conduira à toutes les pertes de données. Le pire, c'est que vous n'aurez aucune chance de récupérer vos données. Dans cet article, nous allons voir comment éviter de telles situations et avoir une chance de ROLLBACK TRUNCATE .

Vous ne pouvez pas ROLLBACK TRUNCATE

Simplement, vous ne pouvez pas annuler une transaction si elle est déjà validée, mais vous pouvez faire autre chose pour récupérer les données (ou au moins certaines parties de celles-ci).

Lorsque vous exécutez la commande TRUNCATE déclaration, vos données sont toujours dans le fichier MDF. Cependant, il n'est pas visible car SQL Server le traite comme de l'espace libre (TRUNCATE demande à SQL Server de désallouer les pages de données).

La seule façon de récupérer les données est de lire d'une manière ou d'une autre les pages de données désallouées et de les convertir en données lisibles.

Vous devez agir rapidement car l'espace libre sera écrasé par de nouvelles données si ce n'est pas déjà fait. Si vous pouvez arrêter votre instance SQL Server et faire une copie des fichiers MDF et LDF, cela vous fera gagner du temps.

Certains outils peuvent effectuer ce type de restauration.

Vous pouvez ROLLBACK TRUNCATE

TRUNCATE est une opération enregistrée, mais SQL Server n'enregistre pas chaque ligne car il TRUNCATE la table. SQL Server enregistre uniquement le fait que le TRUNCATE l'opération a eu lieu. Il enregistre également les informations sur les pages et les étendues qui ont été désallouées. Cependant, il y a suffisamment d'informations pour revenir en arrière, en réattribuant simplement ces pages. Une sauvegarde de journal n'a besoin que des informations que le TRUNCATE TABLE s'est produit. Pour restaurer la TRUNCATE TABLE , l'opération est juste réappliquée. Les données impliquées ne sont pas nécessaires pendant RESTORE (comme ce serait le cas pour une véritable opération "minimalement enregistrée" comme un BULK INSERT ).

SQL Server sait quelles pages appartenaient à la table dans la mesure où elles sont verrouillées avec un verrou exclusif et, comme tous les verrous X, elles sont conservées jusqu'à la fin de la transaction. C'est pourquoi les pages ou les étendues ne peuvent pas être désallouées et ne peuvent certainement pas être réutilisées.

Voici un exemple :

Nous avons un décompte de 504 lignes et un certain nombre de pages. Nous allons maintenant examiner le nombre de lignes et les pages appartenant au tableau.

BEGIN TRAN
TRUNCATE TABLE dbo.Products;
SELECT COUNT(*) FROM dbo.Products;
 
DBCC IND('AdventureWorks', 'Products', -1);
DBCC EXTENTINFO('AdventureWorks', 'Products', -1);
 
SELECT resource_type, resource_description,
        request_mode FROM sys.dm_tran_locks
WHERE  resource_type IN ('EXTENT', 'PAGE')
AND   resource_database_id = DB_ID('AdventureWorks');

Vous ne verrez aucune ligne de DBCC IND , et 0 lignes de count(*). Les informations sur les verrous renvoient ce qui suit :

type_ressource description_ressource mode_demande
————- ——————– ————
EXTENT 1:33352 X
PAGE 1:42486 X
EXTENT 1:42488 X
PAGE 1:42487 X
PAGE 1:42488 X
PAGE 1:42489 X
PAGE 1:23027 X
PAGE 1:23030 X
PAGE 1:23029 X
PAGE 1:26992 X
PAGE 1:26993 X

Les verrous d'étendue et de page incluent toutes les pages que nous avons vues dans DBCC IND production. Seulement après avoir ROLLBACK la transaction, les verrous seront libérés, et vous devriez revoir toutes les lignes et les pages sur la table.

ROLLBACK TRAN;
GO
SELECT COUNT(*) FROM dbo.Products;
DBCC IND('AdventureWorks', 'Products', -1);
GO

Soyez prudent et encapsulez toujours l'instruction de table TRUNCATE dans la transaction.