sql >> Database >  >> RDS >> Sqlserver

ROLLBACK TRUNCATE in SQL Server

Heeft u ooit per ongeluk de TRUNCATE . uitgevoerd commando op een verkeerde tafel? Dit zal leiden tot al het gegevensverlies. Het ergste is dat u geen kans krijgt om uw gegevens terug te krijgen. In dit artikel bekijken we hoe we dergelijke situaties kunnen vermijden en maken we kans op ROLLBACK TRUNCATE .

U kunt niet ROLLBACK TRUNCATE

U kunt een transactie eenvoudigweg niet terugdraaien als deze al is vastgelegd, maar u kunt wel iets anders doen om de gegevens (of in ieder geval sommige delen ervan) terug te krijgen.

Wanneer u de TRUNCATE . uitvoert verklaring staan ​​uw gegevens nog in het MDF-bestand. Het is echter niet zichtbaar omdat SQL Server dit als vrije ruimte behandelt (TRUNCATE vertelt SQL Server om de toewijzing van gegevenspagina's ongedaan te maken).

De enige manier om de gegevens terug te krijgen, is door op de een of andere manier niet-toegewezen gegevenspagina's te lezen en deze om te zetten in leesbare gegevens.

U moet snel handelen omdat vrije ruimte zal worden overschreven met nieuwe gegevens, als dat nog niet het geval is. Als u uw SQL Server-instantie kunt stoppen en een kopie van MDF- en LDF-bestanden kunt maken, zou u meer tijd winnen.

Er zijn enkele tools die dit soort herstel kunnen uitvoeren.

U kunt ROLLBACK TRUNCATE

AFKNOP is een gelogde bewerking, maar SQL Server registreert niet elke rij omdat het de tabel TRUNCATES. SQL Server registreert alleen het feit dat de TRUNCATE operatie gebeurd. Het registreert ook de informatie over de pagina's en domeinen waarvan de toewijzing ongedaan is gemaakt. Er is echter voldoende informatie om terug te draaien door die pagina's gewoon opnieuw toe te wijzen. Een logback-up heeft alleen de informatie nodig die de TRUNCATE TABLE heeft plaatsgevonden. De TRUNCATE TABLE herstellen , wordt de bewerking gewoon opnieuw toegepast. De betrokken gegevens zijn niet nodig tijdens HERSTEL (zoals het zou zijn voor een echte 'minimaal gelogde' bewerking zoals een BULK INSERT ).

SQL Server weet welke pagina's bij de tabel hoorden voor zover ze zijn vergrendeld met een exclusieve vergrendeling en net als alle X-vergrendelingen worden ze vastgehouden tot het einde van de transactie. Dat is de reden waarom pagina's of extensies niet kunnen worden ongedaan gemaakt, en zeker niet opnieuw kunnen worden gebruikt.

Hier is een voorbeeld:

We hebben een telling van 504 rijen en een aantal pagina's. Nu gaan we kijken naar het aantal rijen en de pagina's die bij de tabel horen.

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

U ziet geen rijen van DBCC IND , en 0 rijen van count(*). De vergrendelingsinfo geeft het volgende terug:

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

De omvang en paginavergrendelingen omvatten alle pagina's die we hebben gezien in de DBCC IND uitvoer. Pas nadat je ROLLBACK hebt gedaan de transactie worden de vergrendelingen vrijgegeven en u zou alle rijen en pagina's weer op de tafel moeten zien.

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

Wees voorzichtig en stop altijd het TRUNCATE-tabelstatement in de transactie.


  1. Plezier met (columnstore) compressie op een hele grote tafel – deel 2

  2. SELECTEER DISTINCT Werkt niet Android SQLite

  3. Hoe JAR-bestand in Oracle Database te laden?

  4. PGLogical 1.1-pakketten voor PostgreSQL 9.6beta1