sql >> Databasteknik >  >> RDS >> Sqlserver

ROLLBACK TRUNCATE i SQL Server

Har du någonsin av misstag utfört TRUNCATE kommando på fel bord? Detta kommer att leda till all dataförlust. Det värsta är att du inte kommer att ha en chans att få tillbaka din data. I den här artikeln kommer vi att ta en titt på hur man undviker sådana situationer och har en chans att ROLLBACK TRUNCATE .

Du kan inte ROLLBACK TRUNCATE

Du kan helt enkelt inte återställa en transaktion om den redan är genomförd, men du kan göra något annat för att få tillbaka data (eller åtminstone vissa delar av den).

När du kör TRUNCATE uttalande finns dina data fortfarande i MDF-filen. Det är dock inte synligt eftersom SQL Server behandlar detta som ledigt utrymme (TRUNCATE säger åt SQL Server att deallokera datasidor).

Det enda sättet att få tillbaka data är att på något sätt läsa avallokerade datasidor och konvertera dem till läsbara data.

Du måste agera snabbt eftersom ledigt utrymme kommer att skrivas över med ny data om inte redan. Om du kan stoppa din SQL Server-instans och göra en kopia av MDF- och LDF-filer så skulle du behöva mer tid.

Det finns några verktyg som kan göra den här typen av återställning.

Du kan ROLLBACK TRUNCATE

TRUNCATE är en loggad operation, men SQL Server loggar inte varje enskild rad eftersom den TRUNKERAR tabellen. SQL Server loggar bara det faktum att TRUNCATE operation hände. Den loggar också informationen om sidorna och omfattningen som tilldelades. Det finns dock tillräckligt med information för att rulla tillbaka genom att bara omfördela dessa sidor. En loggbackup behöver bara den information som TRUNCATE TABLE inträffade. För att återställa TRUNCATE TABLE , operationen tillämpas bara igen. Datan som är involverad behövs inte under ÅTERSTÄLLNING (som det skulle vara för en verklig "minimalloggad" operation som en BULK INSERT ).

SQL Server vet vilka sidor som hörde till tabellen så långt som de är låsta med ett exklusivt lås, och precis som alla X-lås hålls de till slutet av transaktionen. Det är därför sidor eller omfattningar inte kan deallokeras, och definitivt inte kan återanvändas.

Här är ett exempel:

Vi fick ett antal 504 rader och ett antal sidor. Nu ska vi titta på antalet rader och sidorna som hör till 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 kommer inte att se några rader från DBCC IND , och 0 rader från count(*). Låsinformationen returnerar följande:

resurstyp resource_description request_mode
————- ——————– ————
EXTENT 1:33352 X
SIDA 1:42486 X
EXTENT 1:42488 X
SIDA 1:42487 X
SIDA 1:42488 X
SIDA 1:42489 X
SIDA 1:23027 X
SIDA 1:23030 X
SIDA 1:23029 X
SIDA 1:26992 X
SIDA 1:26993 X

Omfattningen och sidlåsningarna inkluderar alla sidor som vi såg i DBCC IND produktion. Först efter att du ROLLBACK transaktionen kommer låsen att släppas, och du bör se alla rader och sidor på tabellen igen.

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

Var försiktig och linda alltid TRUNCATE-tabellsatsen i transaktionen.


  1. MySQL VÄLJ GILLA eller REGEXP för att matcha flera ord i en post

  2. SQL DROP DATABASE Syntax – Listad av DBMS

  3. SQL Server dynamisk PIVOT-fråga?

  4. hur får man start- och slutdatum för alla veckor mellan två datum i SQL-servern?