sql >> Database teknologi >  >> RDS >> Sqlserver

ROLLBACK TRUNCATE i SQL Server

Har du nogensinde ved et uheld udført TRUNCATE kommando på et forkert bord? Dette vil føre til alt datatab. Det værste er, at du ikke vil have en chance for at få dine data tilbage. I denne artikel vil vi se, hvordan man undgår sådanne situationer og har en chance for at RULLBAGE TRUNCATE .

Du kan ikke ROLLBACK TRUNCATE

Du kan simpelthen ikke rulle en transaktion tilbage, hvis den allerede er begået, men du kan gøre noget andet for at få dataene tilbage (eller i det mindste nogle dele af dem).

Når du udfører TRUNCATE erklæring, er dine data stadig i MDF-filen. Det er dog ikke synligt, fordi SQL Server behandler dette som ledig plads (TRUNCATE beder SQL Server om at deallokere datasider).

Den eneste måde at få data tilbage på er at læse deallokerede datasider og konvertere dem til læsbare data.

Du skal handle hurtigt, fordi ledig plads vil blive overskrevet med nye data, hvis ikke allerede. Hvis du kan stoppe din SQL Server-instans og lave en kopi af MDF- og LDF-filer, vil det give dig mere tid.

Der er nogle værktøjer, der kan udføre denne form for gendannelse.

Du kan TILBAGE TRUNCATE

TRUNCATE er en logget operation, men SQL Server logger ikke hver eneste række, da den TRUNCATE tabellen. SQL Server logger kun det faktum, at TRUNCATE operation skete. Det logger også oplysningerne om de sider og omfang, der blev deallokeret. Der er dog nok information til at rulle tilbage ved blot at genallokere disse sider. En log backup behøver kun de oplysninger, som TRUNCATE TABLE fandt sted. For at gendanne TRUNCATE TABLE , er operationen bare genanvendt. De involverede data er ikke nødvendige under RESTORE (som det ville være for en ægte 'minimalt logget' operation som en BULK INSERT ).

SQL Server ved, hvilke sider der tilhørte tabellen, så vidt de er låst med en eksklusiv lås, og ligesom alle X-låse, holdes de indtil slutningen af ​​transaktionen. Det er grunden til, at sider eller omfang ikke kan deallokeres, og bestemt ikke kan genbruges.

Her er et eksempel:

Vi fik en optælling på 504 rækker og et antal sider. Nu skal vi se på antallet af rækker og de sider, der hører til tabellen.

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

Du vil ikke se nogen rækker fra DBCC IND , og 0 rækker fra count(*). Låseoplysningerne returnerer følgende:

ressourcetype resource_description request_mode
————- ——————— ————
EXTENT 1:33352 X
SIDE 1:42486 X
EXTENT 1:42488 X
SIDE 1:42487 X
SIDE 1:42488 X
SIDE 1:42489 X
SIDE 1:23027 X
SIDE 1:23030 X
SIDE 1:23029 X
SIDE 1:26992 X
SIDE 1:26993 X

Omfanget og sidelåsene inkluderer alle de sider, vi så i DBCC IND produktion. Først efter du har ROLLBACK transaktionen vil låsene blive frigivet, og du skulle se alle rækker og sider tilbage på bordet igen.

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

Vær forsigtig og indpak altid TRUNCATE-tabelerklæringen i transaktionen.


  1. Hvordan bruger jeg Psycopg2's LoggingConnection?

  2. 2 måder at liste alle lagrede procedurer i MySQL

  3. Blanding af ANSI 1992 JOINs og COMMAs i en forespørgsel

  4. Neo4j - Valg af data med MATCH ved hjælp af Cypher